Panda3D
|
00001 // Filename: wdxGraphicsBuffer8.cxx 00002 // Created by: drose (08Feb04) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #include "wdxGraphicsPipe9.h" 00016 #include "wdxGraphicsBuffer9.h" 00017 #include "dxGraphicsStateGuardian9.h" 00018 #include "pStatTimer.h" 00019 00020 00021 #define FL << "\n" << __FILE__ << " " << __LINE__ << "\n" 00022 00023 TypeHandle wdxGraphicsBuffer9::_type_handle; 00024 00025 00026 //////////////////////////////////////////////////////////////////// 00027 // Function: wdxGraphicsBuffer9::Constructor 00028 // Access: Public 00029 // Description: 00030 //////////////////////////////////////////////////////////////////// 00031 wdxGraphicsBuffer9:: 00032 wdxGraphicsBuffer9(GraphicsEngine *engine, GraphicsPipe *pipe, 00033 const string &name, 00034 const FrameBufferProperties &fb_prop, 00035 const WindowProperties &win_prop, 00036 int flags, 00037 GraphicsStateGuardian *gsg, 00038 GraphicsOutput *host): 00039 GraphicsBuffer(engine, pipe, name, fb_prop, win_prop, flags, gsg, host) 00040 { 00041 // initialize all class members 00042 _cube_map_index = -1; 00043 _saved_color_buffer = NULL; 00044 _saved_depth_buffer = NULL; 00045 _color_backing_store = NULL; 00046 _depth_backing_store = NULL; 00047 00048 // is this correct ??? 00049 // Since the pbuffer never gets flipped, we get screenshots from the 00050 // same buffer we draw into. 00051 _screenshot_buffer_type = _draw_buffer_type; 00052 00053 _shared_depth_buffer = 0; 00054 _debug = 0; 00055 _this = 0; 00056 00057 if (_debug) { 00058 cout << "+++++ wdxGraphicsBuffer9 constructor " << this << " " << this -> get_name ( ) << "\n"; 00059 } 00060 00061 if (_gsg) { 00062 // save to GSG list to handle device lost issues 00063 DXGraphicsStateGuardian9 *dxgsg; 00064 00065 dxgsg = DCAST (DXGraphicsStateGuardian9, _gsg); 00066 _this = new (wdxGraphicsBuffer9 *); 00067 *_this = this; 00068 dxgsg -> _graphics_buffer_list.push_back(_this); 00069 } 00070 } 00071 00072 //////////////////////////////////////////////////////////////////// 00073 // Function: wdxGraphicsBuffer9::Destructor 00074 // Access: Public, Virtual 00075 // Description: 00076 //////////////////////////////////////////////////////////////////// 00077 wdxGraphicsBuffer9:: 00078 ~wdxGraphicsBuffer9() { 00079 00080 if (_debug) { 00081 cout << "----- wdxGraphicsBuffer9 destructor " << this << " " << this -> get_name ( ) << "\n"; 00082 } 00083 00084 if (_gsg) { 00085 // remove from GSG list 00086 DXGraphicsStateGuardian9 *dxgsg; 00087 00088 dxgsg = DCAST (DXGraphicsStateGuardian9, _gsg); 00089 if (_this) { 00090 dxgsg -> _graphics_buffer_list.remove(_this); 00091 } 00092 _this = 0; 00093 _gsg.clear(); 00094 _gsg = 0; 00095 } 00096 00097 // unshare shared depth buffer if any 00098 this -> unshare_depth_buffer(); 00099 00100 // unshare all buffers that are sharing this object's depth buffer 00101 { 00102 wdxGraphicsBuffer9 *graphics_buffer; 00103 list <wdxGraphicsBuffer9 *>::iterator graphics_buffer_iterator; 00104 00105 graphics_buffer_iterator = _shared_depth_buffer_list.begin( ); 00106 while (graphics_buffer_iterator != _shared_depth_buffer_list.end( )) { 00107 graphics_buffer = (*graphics_buffer_iterator); 00108 if (graphics_buffer) { 00109 // this call removes the entry from the list 00110 graphics_buffer -> unshare_depth_buffer(); 00111 } 00112 graphics_buffer_iterator = _shared_depth_buffer_list.begin( ); 00113 } 00114 } 00115 00116 this -> close_buffer ( ); 00117 } 00118 00119 //////////////////////////////////////////////////////////////////// 00120 // Function: wdxGraphicsBuffer9::begin_frame 00121 // Access: Public, Virtual 00122 // Description: This function will be called within the draw thread 00123 // before beginning rendering for a given frame. It 00124 // should do whatever setup is required, and return true 00125 // if the frame should be rendered, or false if it 00126 // should be skipped. 00127 //////////////////////////////////////////////////////////////////// 00128 bool wdxGraphicsBuffer9:: 00129 begin_frame(FrameMode mode, Thread *current_thread) { 00130 00131 begin_frame_spam(mode); 00132 if (_gsg == (GraphicsStateGuardian *)NULL) { 00133 return false; 00134 } 00135 if (_dxgsg -> _d3d_device == 0) { 00136 return false; 00137 } 00138 00139 if (mode == FM_render) { 00140 if (!save_bitplanes()) { 00141 return false; 00142 } 00143 if (!rebuild_bitplanes()) { 00144 restore_bitplanes(); 00145 return false; 00146 } 00147 clear_cube_map_selection(); 00148 } 00149 00150 _gsg->set_current_properties(&get_fb_properties()); 00151 return _gsg->begin_frame(current_thread); 00152 } 00153 00154 //////////////////////////////////////////////////////////////////// 00155 // Function: wdxGraphicsBuffer9::end_frame 00156 // Access: Public, Virtual 00157 // Description: This function will be called within the draw thread 00158 // after rendering is completed for a given frame. It 00159 // should do whatever finalization is required. 00160 //////////////////////////////////////////////////////////////////// 00161 void wdxGraphicsBuffer9:: 00162 end_frame(FrameMode mode, Thread *current_thread) { 00163 00164 end_frame_spam(mode); 00165 nassertv(_gsg != (GraphicsStateGuardian *)NULL); 00166 00167 if (mode == FM_render) { 00168 copy_to_textures(); 00169 } 00170 00171 _gsg->end_frame(current_thread); 00172 00173 if (mode == FM_render) { 00174 trigger_flip(); 00175 clear_cube_map_selection(); 00176 restore_bitplanes(); 00177 } 00178 } 00179 00180 //////////////////////////////////////////////////////////////////// 00181 // Function: wdxGraphicsBuffer9::save_bitplanes 00182 // Access: Public 00183 // Description: After rendering, d3d_device will need to be restored 00184 // to its initial state. This function saves the state. 00185 //////////////////////////////////////////////////////////////////// 00186 bool wdxGraphicsBuffer9:: 00187 save_bitplanes() { 00188 HRESULT hr; 00189 DWORD render_target_index; 00190 00191 render_target_index = 0; 00192 00193 hr = _dxgsg -> _d3d_device -> GetRenderTarget (render_target_index, &_saved_color_buffer); 00194 if (!SUCCEEDED (hr)) { 00195 dxgsg9_cat.error ( ) << "GetRenderTarget " << D3DERRORSTRING(hr) FL; 00196 return false; 00197 } 00198 00199 _saved_depth_buffer = 0; 00200 hr = _dxgsg -> _d3d_device -> GetDepthStencilSurface (&_saved_depth_buffer); 00201 if (hr == D3DERR_NOTFOUND) { 00202 // this case is actually ok 00203 } 00204 else { 00205 if (!SUCCEEDED (hr)) { 00206 dxgsg9_cat.error ( ) << "GetDepthStencilSurface " << D3DERRORSTRING(hr) FL; 00207 return false; 00208 } 00209 } 00210 return true; 00211 } 00212 00213 //////////////////////////////////////////////////////////////////// 00214 // Function: wdxGraphicsBuffer9::restore_bitplanes 00215 // Access: Public 00216 // Description: After rendering, d3d_device will need to be restored 00217 // to its initial state. This function restores the state. 00218 //////////////////////////////////////////////////////////////////// 00219 void wdxGraphicsBuffer9:: 00220 restore_bitplanes() { 00221 DXGraphicsStateGuardian9 *dxgsg; 00222 DCAST_INTO_V(dxgsg, _gsg); 00223 00224 HRESULT hr; 00225 DWORD render_target_index; 00226 00227 render_target_index = 0; 00228 00229 hr = dxgsg -> _d3d_device -> 00230 SetRenderTarget (render_target_index, _saved_color_buffer); 00231 if (!SUCCEEDED (hr)) { 00232 dxgsg9_cat.error ( ) << "SetRenderTarget " << D3DERRORSTRING(hr) FL; 00233 } 00234 if (_saved_depth_buffer) { 00235 hr = _dxgsg -> _d3d_device -> SetDepthStencilSurface (_saved_depth_buffer); 00236 if (!SUCCEEDED (hr)) { 00237 dxgsg9_cat.error ( ) << "SetDepthStencilSurface " << D3DERRORSTRING(hr) FL; 00238 } 00239 } 00240 00241 // clear all render targets, except for the main render target 00242 for (int i = 1; i<count_textures(); i++) { 00243 hr = _dxgsg -> _d3d_device -> SetRenderTarget (i, NULL); 00244 if (!SUCCEEDED (hr)) { 00245 dxgsg9_cat.error ( ) << "SetRenderTarget " << i << " " << D3DERRORSTRING(hr) FL; 00246 } 00247 } 00248 00249 _saved_color_buffer->Release(); 00250 if (_saved_depth_buffer) { 00251 _saved_depth_buffer->Release(); 00252 } 00253 _saved_color_buffer = NULL; 00254 _saved_depth_buffer = NULL; 00255 } 00256 00257 00258 00259 //////////////////////////////////////////////////////////////////// 00260 // Function: wdxGraphicsBuffer9::rebuild_bitplanes 00261 // Access: Public 00262 // Description: If necessary, reallocates (or allocates) the 00263 // bitplanes for the buffer. 00264 //////////////////////////////////////////////////////////////////// 00265 bool wdxGraphicsBuffer9:: 00266 rebuild_bitplanes() { 00267 HRESULT hr; 00268 Texture *color_tex = 0; 00269 Texture *depth_tex = 0; 00270 DXTextureContext9 *color_ctx = 0; 00271 DXTextureContext9 *depth_ctx = 0; 00272 IDirect3DTexture9 *color_d3d_tex = 0; 00273 IDirect3DTexture9 *depth_d3d_tex = 0; 00274 IDirect3DCubeTexture9 *color_cube = 0; 00275 IDirect3DCubeTexture9 *depth_cube = 0; 00276 IDirect3DSurface9 *color_surf = 0; 00277 IDirect3DSurface9 *depth_surf = 0; 00278 DWORD render_target_index; 00279 00280 render_target_index = 0; 00281 00282 // Decide how big the bitplanes should be. 00283 00284 if ((_host != 0)&&(_creation_flags & GraphicsPipe::BF_size_track_host)) { 00285 if ((_host->get_x_size() != _x_size)|| 00286 (_host->get_y_size() != _y_size)) { 00287 set_size_and_recalc(_host->get_x_size(), 00288 _host->get_y_size()); 00289 } 00290 } 00291 int bitplane_x = _x_size; 00292 int bitplane_y = _y_size; 00293 if (Texture::get_textures_power_2() != ATS_none) { 00294 bitplane_x = Texture::up_to_power_2(bitplane_x); 00295 bitplane_y = Texture::up_to_power_2(bitplane_y); 00296 } 00297 00298 // Find the color and depth textures. Either may be present, 00299 // or neither. 00300 // 00301 // NOTE: Currently, depth-stencil textures are not implemented, 00302 // but since it's coming soon, we're structuring for it. 00303 00304 int color_tex_index = -1; 00305 int depth_tex_index = -1; 00306 { 00307 CDLockedReader cdata(_cycler); 00308 for (size_t i = 0; i != cdata->_textures.size(); ++i) { 00309 const RenderTexture &rt = cdata->_textures[i]; 00310 RenderTextureMode rtm_mode = rt._rtm_mode; 00311 if (rtm_mode == RTM_bind_or_copy) { 00312 RenderTexturePlane plane = rt._plane; 00313 00314 switch (plane) { 00315 case RTP_color: 00316 color_tex_index = i; 00317 break; 00318 00319 case RTP_aux_rgba_0: 00320 case RTP_aux_rgba_1: 00321 case RTP_aux_rgba_2: 00322 case RTP_aux_rgba_3: 00323 case RTP_aux_hrgba_0: 00324 case RTP_aux_hrgba_1: 00325 case RTP_aux_hrgba_2: 00326 case RTP_aux_hrgba_3: 00327 case RTP_aux_float_0: 00328 case RTP_aux_float_1: 00329 case RTP_aux_float_2: 00330 case RTP_aux_float_3: 00331 { 00332 CDWriter cdataw(_cycler, cdata, false); 00333 nassertr(cdata->_textures.size() == cdataw->_textures.size(), false); 00334 cdataw->_textures[i]._rtm_mode = RTM_none; 00335 } 00336 break; 00337 default: 00338 { 00339 CDWriter cdataw(_cycler, cdata, false); 00340 nassertr(cdata->_textures.size() == cdataw->_textures.size(), false); 00341 cdataw->_textures[i]._rtm_mode = RTM_copy_texture; 00342 } 00343 break; 00344 } 00345 } 00346 } 00347 } 00348 00349 if (color_tex_index < 0) { 00350 // Maintain the backing color surface. 00351 if ((_color_backing_store)&& 00352 ((bitplane_x != _backing_sizex)||(bitplane_y != _backing_sizey))) { 00353 _color_backing_store->Release(); 00354 _color_backing_store = NULL; 00355 } 00356 if (!_color_backing_store) { 00357 hr = _dxgsg -> _d3d_device -> 00358 CreateOffscreenPlainSurface(bitplane_x, bitplane_y, _saved_color_desc.Format, 00359 D3DPOOL_DEFAULT, &_color_backing_store, NULL); 00360 if (!SUCCEEDED(hr)) { 00361 dxgsg9_cat.error ( ) << "CreateImageSurface " << D3DERRORSTRING(hr) FL; 00362 } 00363 } 00364 color_surf = _color_backing_store; 00365 } else { 00366 // Maintain the color texture. 00367 if (_color_backing_store) { 00368 _color_backing_store->Release(); 00369 _color_backing_store = NULL; 00370 } 00371 color_tex = get_texture(color_tex_index); 00372 color_tex->set_size_padded(_x_size, _y_size); 00373 // color_tex->set_format(Texture::F_rgba); 00374 color_ctx = 00375 DCAST(DXTextureContext9, 00376 color_tex->prepare_now(0, _gsg->get_prepared_objects(), _gsg)); 00377 00378 if (color_ctx) { 00379 if (!color_ctx->create_texture(*_dxgsg->_screen)) { 00380 dxgsg9_cat.error() 00381 << "Unable to re-create texture " << *color_ctx->get_texture() << endl; 00382 return false; 00383 } 00384 if (color_tex->get_texture_type() == Texture::TT_2d_texture) { 00385 color_d3d_tex = color_ctx->_d3d_2d_texture; 00386 nassertr(color_d3d_tex != 0, false); 00387 hr = color_d3d_tex -> GetSurfaceLevel(0, &color_surf); 00388 if (!SUCCEEDED(hr)) { 00389 dxgsg9_cat.error ( ) << "GetSurfaceLevel " << D3DERRORSTRING(hr) FL; 00390 } 00391 } 00392 if (color_tex->get_texture_type() == Texture::TT_cube_map) { 00393 color_cube = color_ctx->_d3d_cube_texture; 00394 nassertr(color_cube != 0, false); 00395 00396 if (_cube_map_index >= 0 && _cube_map_index < 6) { 00397 hr = color_cube -> GetCubeMapSurface ((D3DCUBEMAP_FACES) _cube_map_index, 0, &color_surf); 00398 if (!SUCCEEDED(hr)) { 00399 dxgsg9_cat.error ( ) << "GetCubeMapSurface " << D3DERRORSTRING(hr) FL; 00400 } 00401 } 00402 } 00403 } 00404 } 00405 00406 bool release_depth; 00407 00408 release_depth = true; 00409 if (depth_tex_index < 0) { 00410 if (_shared_depth_buffer) { 00411 if (_shared_depth_buffer -> _depth_backing_store) { 00412 if (_debug) { 00413 printf ("SHARE DEPTH BUFFER\n"); 00414 } 00415 depth_surf = _shared_depth_buffer -> _depth_backing_store; 00416 release_depth = false; 00417 } 00418 } 00419 if (depth_surf == 0) { 00420 // Maintain the backing depth surface. 00421 if ((_depth_backing_store)&& 00422 ((bitplane_x != _backing_sizex)||(bitplane_y != _backing_sizey))) { 00423 _depth_backing_store->Release(); 00424 _depth_backing_store = NULL; 00425 } 00426 if (!_depth_backing_store) { 00427 hr = _dxgsg -> _d3d_device -> 00428 CreateDepthStencilSurface (bitplane_x, bitplane_y, _saved_depth_desc.Format, 00429 _saved_depth_desc.MultiSampleType, _saved_depth_desc.MultiSampleQuality, 00430 false, &_depth_backing_store, NULL); 00431 if (!SUCCEEDED(hr)) { 00432 dxgsg9_cat.error ( ) << "CreateDepthStencilSurface " << D3DERRORSTRING(hr) FL; 00433 } 00434 } 00435 depth_surf = _depth_backing_store; 00436 } 00437 } else { 00438 // Maintain the depth texture. 00439 if (_depth_backing_store) { 00440 _depth_backing_store->Release(); 00441 _depth_backing_store = NULL; 00442 } 00443 00444 if (_shared_depth_buffer) { 00445 depth_tex = _shared_depth_buffer -> get_texture(depth_tex_index); 00446 } 00447 if (depth_tex == 0) { 00448 depth_tex = get_texture(depth_tex_index); 00449 } 00450 00451 depth_tex->set_size_padded(_x_size, _y_size); 00452 depth_tex->set_format(Texture::F_depth_stencil); 00453 depth_ctx = 00454 DCAST(DXTextureContext9, 00455 depth_tex->prepare_now(0, _gsg->get_prepared_objects(), _gsg)); 00456 if (depth_ctx) { 00457 if (!depth_ctx->create_texture(*_dxgsg->_screen)) { 00458 dxgsg9_cat.error() 00459 << "Unable to re-create texture " << *color_ctx->get_texture() << endl; 00460 return false; 00461 } 00462 if (depth_tex->get_texture_type() == Texture::TT_2d_texture) { 00463 depth_d3d_tex = depth_ctx->_d3d_2d_texture; 00464 nassertr(depth_d3d_tex != 0, false); 00465 hr = color_d3d_tex -> GetSurfaceLevel(0, &depth_surf); 00466 if (!SUCCEEDED(hr)) { 00467 dxgsg9_cat.error ( ) << "GetSurfaceLevel " << D3DERRORSTRING(hr) FL; 00468 } 00469 } 00470 if (depth_tex->get_texture_type() == Texture::TT_cube_map) { 00471 depth_cube = depth_ctx->_d3d_cube_texture; 00472 nassertr(depth_cube != 0, false); 00473 hr = depth_cube -> GetCubeMapSurface ((D3DCUBEMAP_FACES) _cube_map_index, 0, &depth_surf); 00474 if (!SUCCEEDED(hr)) { 00475 dxgsg9_cat.error ( ) << "GetCubeMapSurface " << D3DERRORSTRING(hr) FL; 00476 } 00477 } 00478 } 00479 } 00480 00481 _backing_sizex = bitplane_x; 00482 _backing_sizey = bitplane_y; 00483 00484 // Load up the bitplanes. 00485 if (color_surf) { 00486 hr = _dxgsg -> _d3d_device -> SetRenderTarget (render_target_index, color_surf); 00487 if (!SUCCEEDED (hr)) { 00488 dxgsg9_cat.error ( ) << "SetRenderTarget " << D3DERRORSTRING(hr) FL; 00489 } 00490 } 00491 00492 if (depth_surf) { 00493 hr = _dxgsg -> _d3d_device -> SetDepthStencilSurface (depth_surf); 00494 if (!SUCCEEDED (hr)) { 00495 dxgsg9_cat.error ( ) << "SetDepthStencilSurface " << D3DERRORSTRING(hr) FL; 00496 } 00497 } 00498 00499 render_target_index = 1; 00500 for (int i=0; i<count_textures(); i++) { 00501 00502 Texture *tex = get_texture(i); 00503 RenderTexturePlane plane = get_texture_plane(i); 00504 00505 if (_debug) { 00506 // printf ("i = %d, RenderTexturePlane = %d \n", i, plane); 00507 } 00508 00509 switch (plane) { 00510 case RTP_color: 00511 break; 00512 case RTP_aux_rgba_0: 00513 case RTP_aux_rgba_1: 00514 case RTP_aux_rgba_2: 00515 case RTP_aux_rgba_3: 00516 case RTP_aux_hrgba_0: 00517 case RTP_aux_hrgba_1: 00518 case RTP_aux_hrgba_2: 00519 case RTP_aux_hrgba_3: 00520 case RTP_aux_float_0: 00521 case RTP_aux_float_1: 00522 case RTP_aux_float_2: 00523 case RTP_aux_float_3: 00524 { 00525 DXTextureContext9 *color_ctx = 0; 00526 IDirect3DTexture9 *color_d3d_tex = 0; 00527 IDirect3DSurface9 *color_surf = 0; 00528 IDirect3DCubeTexture9 *color_cube = 0; 00529 00530 color_ctx = DCAST(DXTextureContext9, tex->prepare_now(0, _gsg->get_prepared_objects(), _gsg)); 00531 if (color_ctx) { 00532 if (!color_ctx->create_texture(*_dxgsg->_screen)) { 00533 dxgsg9_cat.error() 00534 << "Unable to re-create texture " << *color_ctx->get_texture() << endl; 00535 return false; 00536 } 00537 if (tex->get_texture_type() == Texture::TT_2d_texture) { 00538 color_d3d_tex = color_ctx->_d3d_2d_texture; 00539 nassertr(color_d3d_tex != 0, false); 00540 00541 hr = color_d3d_tex -> GetSurfaceLevel(0, &color_surf); 00542 if (!SUCCEEDED(hr)) { 00543 dxgsg9_cat.error ( ) << "GetSurfaceLevel " << D3DERRORSTRING(hr) FL; 00544 } 00545 if (color_surf) { 00546 hr = _dxgsg -> _d3d_device -> SetRenderTarget (render_target_index, color_surf); 00547 if (SUCCEEDED (hr)) { 00548 render_target_index++; 00549 } else { 00550 dxgsg9_cat.error ( ) << "SetRenderTarget " << render_target_index << " " << D3DERRORSTRING(hr) FL; 00551 } 00552 color_surf->Release(); 00553 } 00554 } 00555 } 00556 } 00557 break; 00558 00559 default: 00560 break; 00561 } 00562 } 00563 00564 // Decrement the reference counts on these surfaces. The refcounts 00565 // were incremented earlier when we called GetSurfaceLevel. 00566 00567 if ((color_surf != 0)&&(color_surf != _color_backing_store)) { 00568 color_surf->Release(); 00569 } 00570 00571 if (release_depth) { 00572 if ((depth_surf != 0)&&(depth_surf != _depth_backing_store)) { 00573 depth_surf->Release(); 00574 } 00575 } 00576 00577 return true; 00578 } 00579 00580 //////////////////////////////////////////////////////////////////// 00581 // Function: wdxGraphicsBuffer9::select_cube_map 00582 // Access: Public, Virtual 00583 // Description: Called internally when the window is in 00584 // render-to-a-texture mode and we are in the process of 00585 // rendering the six faces of a cube map. This should 00586 // do whatever needs to be done to switch the buffer to 00587 // the indicated face. 00588 //////////////////////////////////////////////////////////////////// 00589 void wdxGraphicsBuffer9:: 00590 select_cube_map(int cube_map_index) { 00591 00592 DWORD render_target_index; 00593 00594 render_target_index = 0; 00595 00596 _cube_map_index = cube_map_index; 00597 00598 HRESULT hr; 00599 Texture *color_tex = 0; 00600 DXTextureContext9 *color_ctx = 0; 00601 IDirect3DCubeTexture9 *color_cube = 0; 00602 IDirect3DSurface9 *color_surf = 0; 00603 int color_tex_index = -1; 00604 00605 { 00606 CDLockedReader cdata(_cycler); 00607 for (size_t i = 0; i != cdata->_textures.size(); ++i) { 00608 const RenderTexture &rt = cdata->_textures[i]; 00609 RenderTextureMode rtm_mode = rt._rtm_mode; 00610 if (rtm_mode == RTM_bind_or_copy) { 00611 Texture *tex = rt._texture; 00612 if ((tex->get_format() != Texture::F_depth_stencil)&& 00613 (tex->get_format() != Texture::F_depth_component)&& 00614 (color_tex_index < 0)) { 00615 color_tex_index = i; 00616 } else { 00617 CDWriter cdataw(_cycler, cdata, false); 00618 nassertv(cdata->_textures.size() == cdataw->_textures.size()); 00619 cdataw->_textures[i]._rtm_mode = RTM_copy_texture; 00620 } 00621 } 00622 } 00623 } 00624 00625 color_tex = get_texture(color_tex_index); 00626 if (color_tex) { 00627 color_ctx = 00628 DCAST(DXTextureContext9, 00629 color_tex->prepare_now(0, _gsg->get_prepared_objects(), _gsg)); 00630 color_cube = color_ctx->_d3d_cube_texture; 00631 if (color_cube && _cube_map_index >= 0 && _cube_map_index < 6) { 00632 hr = color_cube -> GetCubeMapSurface ((D3DCUBEMAP_FACES) _cube_map_index, 0, &color_surf); 00633 if (!SUCCEEDED(hr)) { 00634 dxgsg9_cat.error ( ) << "GetCubeMapSurface " << D3DERRORSTRING(hr) FL; 00635 } 00636 00637 hr = _dxgsg -> _d3d_device -> SetRenderTarget (render_target_index, color_surf); 00638 if (!SUCCEEDED (hr)) { 00639 dxgsg9_cat.error ( ) << "SetRenderTarget " << D3DERRORSTRING(hr) FL; 00640 } 00641 else { 00642 color_surf->Release(); 00643 } 00644 } 00645 } 00646 00647 render_target_index = 1; 00648 for (int i=0; i<count_textures(); i++) { 00649 00650 Texture *tex = get_texture(i); 00651 RenderTexturePlane plane = get_texture_plane(i); 00652 00653 switch (plane) { 00654 case RTP_color: 00655 break; 00656 case RTP_aux_rgba_0: 00657 case RTP_aux_rgba_1: 00658 case RTP_aux_rgba_2: 00659 case RTP_aux_rgba_3: 00660 case RTP_aux_hrgba_0: 00661 case RTP_aux_hrgba_1: 00662 case RTP_aux_hrgba_2: 00663 case RTP_aux_hrgba_3: 00664 case RTP_aux_float_0: 00665 case RTP_aux_float_1: 00666 case RTP_aux_float_2: 00667 case RTP_aux_float_3: 00668 { 00669 DXTextureContext9 *color_ctx = 0; 00670 IDirect3DSurface9 *color_surf = 0; 00671 IDirect3DCubeTexture9 *color_cube = 0; 00672 00673 color_ctx = DCAST(DXTextureContext9, tex->prepare_now(0, _gsg->get_prepared_objects(), _gsg)); 00674 if (color_ctx) { 00675 if (tex->get_texture_type() == Texture::TT_cube_map) { 00676 00677 if (_debug) { 00678 printf ("CUBEMAP i = %d, RenderTexturePlane = %d, _cube_map_index %d \n", i, plane, _cube_map_index); 00679 } 00680 00681 color_cube = color_ctx->_d3d_cube_texture; 00682 if (color_cube && _cube_map_index >= 0 && _cube_map_index < 6) { 00683 hr = color_cube -> GetCubeMapSurface ((D3DCUBEMAP_FACES) _cube_map_index, 0, &color_surf); 00684 if (!SUCCEEDED(hr)) { 00685 dxgsg9_cat.error ( ) << "GetCubeMapSurface " << D3DERRORSTRING(hr) FL; 00686 } 00687 if (color_surf) { 00688 hr = _dxgsg -> _d3d_device -> SetRenderTarget (render_target_index, color_surf); 00689 if (SUCCEEDED (hr)) { 00690 render_target_index++; 00691 } else { 00692 dxgsg9_cat.error ( ) << "cube map SetRenderTarget " << render_target_index << " " << D3DERRORSTRING(hr) FL; 00693 } 00694 color_surf->Release(); 00695 } 00696 } 00697 } 00698 } 00699 } 00700 break; 00701 00702 default: 00703 break; 00704 } 00705 } 00706 } 00707 00708 //////////////////////////////////////////////////////////////////// 00709 // Function: wdxGraphicsBuffer9::process_events 00710 // Access: Public, Virtual 00711 // Description: Do whatever processing is necessary to ensure that 00712 // the window responds to user events. Also, honor any 00713 // requests recently made via request_properties() 00714 // 00715 // This function is called only within the window 00716 // thread. 00717 //////////////////////////////////////////////////////////////////// 00718 void wdxGraphicsBuffer9:: 00719 process_events() { 00720 GraphicsBuffer::process_events(); 00721 00722 MSG msg; 00723 00724 // Handle all the messages on the queue in a row. Some of these 00725 // might be for another window, but they will get dispatched 00726 // appropriately. 00727 while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) { 00728 process_1_event(); 00729 } 00730 } 00731 00732 //////////////////////////////////////////////////////////////////// 00733 // Function: wdxGraphicsBuffer9::close_buffer 00734 // Access: Protected, Virtual 00735 // Description: Closes the buffer right now. Called from the window 00736 // thread. 00737 //////////////////////////////////////////////////////////////////// 00738 void wdxGraphicsBuffer9:: 00739 close_buffer() { 00740 00741 if (_color_backing_store) { 00742 _color_backing_store->Release(); 00743 _color_backing_store = NULL; 00744 } 00745 if (_depth_backing_store) { 00746 _depth_backing_store->Release(); 00747 _depth_backing_store = NULL; 00748 } 00749 00750 _cube_map_index = -1; 00751 _is_valid = false; 00752 } 00753 00754 //////////////////////////////////////////////////////////////////// 00755 // Function: wdxGraphicsBuffer9::open_buffer 00756 // Access: Protected, Virtual 00757 // Description: Opens the window right now. Called from the window 00758 // thread. Returns true if the window is successfully 00759 // opened, or false if there was a problem. 00760 //////////////////////////////////////////////////////////////////// 00761 bool wdxGraphicsBuffer9:: 00762 open_buffer() { 00763 00764 // GSG creation/initialization. 00765 if (_gsg == 0) { 00766 // The code below doesn't support creating a GSG on the fly. 00767 // Just error out for now. 00768 //_dxgsg = new DXGraphicsStateGuardian9(_engine, _pipe); 00769 //_gsg = _dxgsg; 00770 return false; 00771 } 00772 00773 DCAST_INTO_R(_dxgsg, _gsg, false); 00774 00775 if (!save_bitplanes()) { 00776 return false; 00777 } 00778 00779 HRESULT hr; 00780 hr = _saved_color_buffer -> GetDesc (&_saved_color_desc); 00781 if (!SUCCEEDED (hr)) { 00782 dxgsg9_cat.error ( ) << "GetDesc " << D3DERRORSTRING(hr) FL; 00783 return false; 00784 } 00785 hr = _saved_depth_buffer -> GetDesc (&_saved_depth_desc); 00786 if (!SUCCEEDED (hr)) { 00787 dxgsg9_cat.error ( ) << "GetDesc " << D3DERRORSTRING(hr) FL; 00788 return false; 00789 } 00790 _fb_properties = _dxgsg-> 00791 calc_fb_properties(_saved_color_desc.Format, 00792 _saved_depth_desc.Format, 00793 _saved_depth_desc.MultiSampleType, 00794 _saved_depth_desc.MultiSampleQuality); 00795 _fb_properties.set_force_hardware(1); // Wild guess. 00796 00797 00798 if (!rebuild_bitplanes()) { 00799 restore_bitplanes(); 00800 return false; 00801 } 00802 00803 restore_bitplanes(); 00804 return true; 00805 } 00806 00807 //////////////////////////////////////////////////////////////////// 00808 // Function: wdxGraphicsBuffer9::process_1_event 00809 // Access: Private, Static 00810 // Description: Handles one event from the message queue. 00811 //////////////////////////////////////////////////////////////////// 00812 void wdxGraphicsBuffer9:: 00813 process_1_event() { 00814 MSG msg; 00815 00816 if (!GetMessage(&msg, NULL, 0, 0)) { 00817 // WM_QUIT received. We need a cleaner way to deal with this. 00818 // DestroyAllWindows(false); 00819 exit(msg.wParam); // this will invoke AtExitFn 00820 } 00821 00822 // Translate virtual key messages 00823 TranslateMessage(&msg); 00824 // Call window_proc 00825 DispatchMessage(&msg); 00826 } 00827 00828 00829 00830 00831 //////////////////////////////////////////////////////////////////// 00832 // Function: wdxGraphicsBuffer9::share_depth_buffer 00833 // Access: Published 00834 // Description: Will attempt to use the depth buffer of the input 00835 // graphics_output. The buffer sizes must be exactly 00836 // the same. 00837 //////////////////////////////////////////////////////////////////// 00838 bool wdxGraphicsBuffer9:: 00839 share_depth_buffer(GraphicsOutput *graphics_output) { 00840 00841 bool state; 00842 wdxGraphicsBuffer9 *input_graphics_output; 00843 00844 state = false; 00845 input_graphics_output = DCAST (wdxGraphicsBuffer9, graphics_output); 00846 if (this != input_graphics_output && input_graphics_output) { 00847 00848 state = true; 00849 this -> unshare_depth_buffer(); 00850 00851 if (_debug) { 00852 printf ("share_depth_buffer\n"); 00853 } 00854 00855 // check buffer sizes 00856 if (this -> get_x_size() != input_graphics_output -> get_x_size()) { 00857 if (_debug) { 00858 printf ("ERROR: share_depth_buffer: non matching width \n"); 00859 } 00860 state = false; 00861 } 00862 00863 if (this -> get_y_size() != input_graphics_output -> get_y_size()) { 00864 if (_debug) { 00865 printf ("ERROR: share_depth_buffer: non matching height \n"); 00866 } 00867 state = false; 00868 } 00869 00870 if (state) { 00871 // let the input GraphicsOutput know that there is an object 00872 // sharing its depth buffer 00873 input_graphics_output -> register_shared_depth_buffer(this); 00874 _shared_depth_buffer = input_graphics_output; 00875 state = true; 00876 } 00877 } 00878 00879 return state; 00880 } 00881 00882 //////////////////////////////////////////////////////////////////// 00883 // Function: wdxGraphicsBuffer9::unshare_depth_buffer 00884 // Access: Published 00885 // Description: Discontinue sharing the depth buffer. 00886 //////////////////////////////////////////////////////////////////// 00887 void wdxGraphicsBuffer9:: 00888 unshare_depth_buffer() { 00889 if (_shared_depth_buffer) { 00890 if (_debug) { 00891 printf ("wdxGraphicsBuffer9 unshare_depth_buffer \n"); 00892 } 00893 00894 // let the GraphicsOutput know that this object is no longer 00895 // sharing its depth buffer 00896 _shared_depth_buffer -> unregister_shared_depth_buffer(this); 00897 _shared_depth_buffer = 0; 00898 } 00899 } 00900 00901 //////////////////////////////////////////////////////////////////// 00902 // Function: wdxGraphicsBuffer9::register_shared_depth_buffer 00903 // Access: Public 00904 // Description: Register/save who is sharing the depth buffer. 00905 //////////////////////////////////////////////////////////////////// 00906 void wdxGraphicsBuffer9:: 00907 register_shared_depth_buffer(GraphicsOutput *graphics_output) { 00908 wdxGraphicsBuffer9 *input_graphics_output; 00909 00910 input_graphics_output = DCAST (wdxGraphicsBuffer9, graphics_output); 00911 if (input_graphics_output) { 00912 // add to list 00913 _shared_depth_buffer_list.push_back(input_graphics_output); 00914 } 00915 } 00916 00917 //////////////////////////////////////////////////////////////////// 00918 // Function: wdxGraphicsBuffer9::unregister_shared_depth_buffer 00919 // Access: Public 00920 // Description: Unregister who is sharing the depth buffer. 00921 //////////////////////////////////////////////////////////////////// 00922 void wdxGraphicsBuffer9:: 00923 unregister_shared_depth_buffer(GraphicsOutput *graphics_output) { 00924 wdxGraphicsBuffer9 *input_graphics_output; 00925 00926 input_graphics_output = DCAST (wdxGraphicsBuffer9, graphics_output); 00927 if (input_graphics_output) { 00928 // remove from list 00929 _shared_depth_buffer_list.remove(input_graphics_output); 00930 } 00931 }