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 if (_one_shot) { 00176 prepare_for_deletion(); 00177 } 00178 clear_cube_map_selection(); 00179 restore_bitplanes(); 00180 } 00181 } 00182 00183 //////////////////////////////////////////////////////////////////// 00184 // Function: wdxGraphicsBuffer9::save_bitplanes 00185 // Access: Public 00186 // Description: After rendering, d3d_device will need to be restored 00187 // to its initial state. This function saves the state. 00188 //////////////////////////////////////////////////////////////////// 00189 bool wdxGraphicsBuffer9:: 00190 save_bitplanes() { 00191 HRESULT hr; 00192 DWORD render_target_index; 00193 00194 render_target_index = 0; 00195 00196 hr = _dxgsg -> _d3d_device -> GetRenderTarget (render_target_index, &_saved_color_buffer); 00197 if (!SUCCEEDED (hr)) { 00198 dxgsg9_cat.error ( ) << "GetRenderTarget " << D3DERRORSTRING(hr) FL; 00199 return false; 00200 } 00201 00202 _saved_depth_buffer = 0; 00203 hr = _dxgsg -> _d3d_device -> GetDepthStencilSurface (&_saved_depth_buffer); 00204 if (hr == D3DERR_NOTFOUND) { 00205 // this case is actually ok 00206 } 00207 else { 00208 if (!SUCCEEDED (hr)) { 00209 dxgsg9_cat.error ( ) << "GetDepthStencilSurface " << D3DERRORSTRING(hr) FL; 00210 return false; 00211 } 00212 } 00213 return true; 00214 } 00215 00216 //////////////////////////////////////////////////////////////////// 00217 // Function: wdxGraphicsBuffer9::restore_bitplanes 00218 // Access: Public 00219 // Description: After rendering, d3d_device will need to be restored 00220 // to its initial state. This function restores the state. 00221 //////////////////////////////////////////////////////////////////// 00222 void wdxGraphicsBuffer9:: 00223 restore_bitplanes() { 00224 DXGraphicsStateGuardian9 *dxgsg; 00225 DCAST_INTO_V(dxgsg, _gsg); 00226 00227 HRESULT hr; 00228 DWORD render_target_index; 00229 00230 render_target_index = 0; 00231 00232 hr = dxgsg -> _d3d_device -> 00233 SetRenderTarget (render_target_index, _saved_color_buffer); 00234 if (!SUCCEEDED (hr)) { 00235 dxgsg9_cat.error ( ) << "SetRenderTarget " << D3DERRORSTRING(hr) FL; 00236 } 00237 if (_saved_depth_buffer) { 00238 hr = _dxgsg -> _d3d_device -> SetDepthStencilSurface (_saved_depth_buffer); 00239 if (!SUCCEEDED (hr)) { 00240 dxgsg9_cat.error ( ) << "SetDepthStencilSurface " << D3DERRORSTRING(hr) FL; 00241 } 00242 } 00243 00244 // clear all render targets, except for the main render target 00245 for (int i = 1; i<count_textures(); i++) { 00246 hr = _dxgsg -> _d3d_device -> SetRenderTarget (i, NULL); 00247 if (!SUCCEEDED (hr)) { 00248 dxgsg9_cat.error ( ) << "SetRenderTarget " << i << " " << D3DERRORSTRING(hr) FL; 00249 } 00250 } 00251 00252 _saved_color_buffer->Release(); 00253 if (_saved_depth_buffer) { 00254 _saved_depth_buffer->Release(); 00255 } 00256 _saved_color_buffer = NULL; 00257 _saved_depth_buffer = NULL; 00258 } 00259 00260 00261 00262 //////////////////////////////////////////////////////////////////// 00263 // Function: wdxGraphicsBuffer9::rebuild_bitplanes 00264 // Access: Public 00265 // Description: If necessary, reallocates (or allocates) the 00266 // bitplanes for the buffer. 00267 //////////////////////////////////////////////////////////////////// 00268 bool wdxGraphicsBuffer9:: 00269 rebuild_bitplanes() { 00270 HRESULT hr; 00271 Texture *color_tex = 0; 00272 Texture *depth_tex = 0; 00273 DXTextureContext9 *color_ctx = 0; 00274 DXTextureContext9 *depth_ctx = 0; 00275 IDirect3DTexture9 *color_d3d_tex = 0; 00276 IDirect3DTexture9 *depth_d3d_tex = 0; 00277 IDirect3DCubeTexture9 *color_cube = 0; 00278 IDirect3DCubeTexture9 *depth_cube = 0; 00279 IDirect3DSurface9 *color_surf = 0; 00280 IDirect3DSurface9 *depth_surf = 0; 00281 DWORD render_target_index; 00282 00283 render_target_index = 0; 00284 00285 // Decide how big the bitplanes should be. 00286 00287 if ((_host != 0)&&(_creation_flags & GraphicsPipe::BF_size_track_host)) { 00288 if ((_host->get_x_size() != _x_size)|| 00289 (_host->get_y_size() != _y_size)) { 00290 set_size_and_recalc(_host->get_x_size(), 00291 _host->get_y_size()); 00292 } 00293 } 00294 int bitplane_x = _x_size; 00295 int bitplane_y = _y_size; 00296 if (Texture::get_textures_power_2() != ATS_none) { 00297 bitplane_x = Texture::up_to_power_2(bitplane_x); 00298 bitplane_y = Texture::up_to_power_2(bitplane_y); 00299 } 00300 00301 // Find the color and depth textures. Either may be present, 00302 // or neither. 00303 // 00304 // NOTE: Currently, depth-stencil textures are not implemented, 00305 // but since it's coming soon, we're structuring for it. 00306 00307 int color_tex_index = -1; 00308 int depth_tex_index = -1; 00309 for (int i=0; i<count_textures(); i++) { 00310 if (get_rtm_mode(i) == RTM_bind_or_copy) { 00311 RenderTexturePlane plane = get_texture_plane(i); 00312 00313 switch (plane) { 00314 case RTP_color: 00315 color_tex_index = i; 00316 break; 00317 case RTP_aux_rgba_0: 00318 case RTP_aux_rgba_1: 00319 case RTP_aux_rgba_2: 00320 case RTP_aux_rgba_3: 00321 case RTP_aux_hrgba_0: 00322 case RTP_aux_hrgba_1: 00323 case RTP_aux_hrgba_2: 00324 case RTP_aux_hrgba_3: 00325 case RTP_aux_float_0: 00326 case RTP_aux_float_1: 00327 case RTP_aux_float_2: 00328 case RTP_aux_float_3: 00329 _textures[i]._rtm_mode = RTM_none; 00330 break; 00331 default: 00332 _textures[i]._rtm_mode = RTM_copy_texture; 00333 break; 00334 } 00335 } 00336 } 00337 00338 if (color_tex_index < 0) { 00339 // Maintain the backing color surface. 00340 if ((_color_backing_store)&& 00341 ((bitplane_x != _backing_sizex)||(bitplane_y != _backing_sizey))) { 00342 _color_backing_store->Release(); 00343 _color_backing_store = NULL; 00344 } 00345 if (!_color_backing_store) { 00346 hr = _dxgsg -> _d3d_device -> 00347 CreateOffscreenPlainSurface(bitplane_x, bitplane_y, _saved_color_desc.Format, 00348 D3DPOOL_DEFAULT, &_color_backing_store, NULL); 00349 if (!SUCCEEDED(hr)) { 00350 dxgsg9_cat.error ( ) << "CreateImageSurface " << D3DERRORSTRING(hr) FL; 00351 } 00352 } 00353 color_surf = _color_backing_store; 00354 } else { 00355 // Maintain the color texture. 00356 if (_color_backing_store) { 00357 _color_backing_store->Release(); 00358 _color_backing_store = NULL; 00359 } 00360 color_tex = get_texture(color_tex_index); 00361 color_tex->set_size_padded(_x_size, _y_size); 00362 // color_tex->set_format(Texture::F_rgba); 00363 color_ctx = 00364 DCAST(DXTextureContext9, 00365 color_tex->prepare_now(_gsg->get_prepared_objects(), _gsg)); 00366 00367 if (color_ctx) { 00368 if (!color_ctx->create_texture(*_dxgsg->_screen)) { 00369 dxgsg9_cat.error() 00370 << "Unable to re-create texture " << *color_ctx->get_texture() << endl; 00371 return false; 00372 } 00373 if (color_tex->get_texture_type() == Texture::TT_2d_texture) { 00374 color_d3d_tex = color_ctx->_d3d_2d_texture; 00375 nassertr(color_d3d_tex != 0, false); 00376 hr = color_d3d_tex -> GetSurfaceLevel(0, &color_surf); 00377 if (!SUCCEEDED(hr)) { 00378 dxgsg9_cat.error ( ) << "GetSurfaceLevel " << D3DERRORSTRING(hr) FL; 00379 } 00380 } 00381 if (color_tex->get_texture_type() == Texture::TT_cube_map) { 00382 color_cube = color_ctx->_d3d_cube_texture; 00383 nassertr(color_cube != 0, false); 00384 00385 if (_cube_map_index >= 0 && _cube_map_index < 6) { 00386 hr = color_cube -> GetCubeMapSurface ((D3DCUBEMAP_FACES) _cube_map_index, 0, &color_surf); 00387 if (!SUCCEEDED(hr)) { 00388 dxgsg9_cat.error ( ) << "GetCubeMapSurface " << D3DERRORSTRING(hr) FL; 00389 } 00390 } 00391 } 00392 } 00393 } 00394 00395 bool release_depth; 00396 00397 release_depth = true; 00398 if (depth_tex_index < 0) { 00399 if (_shared_depth_buffer) { 00400 if (_shared_depth_buffer -> _depth_backing_store) { 00401 if (_debug) { 00402 printf ("SHARE DEPTH BUFFER\n"); 00403 } 00404 depth_surf = _shared_depth_buffer -> _depth_backing_store; 00405 release_depth = false; 00406 } 00407 } 00408 if (depth_surf == 0) { 00409 // Maintain the backing depth surface. 00410 if ((_depth_backing_store)&& 00411 ((bitplane_x != _backing_sizex)||(bitplane_y != _backing_sizey))) { 00412 _depth_backing_store->Release(); 00413 _depth_backing_store = NULL; 00414 } 00415 if (!_depth_backing_store) { 00416 hr = _dxgsg -> _d3d_device -> 00417 CreateDepthStencilSurface (bitplane_x, bitplane_y, _saved_depth_desc.Format, 00418 _saved_depth_desc.MultiSampleType, _saved_depth_desc.MultiSampleQuality, 00419 false, &_depth_backing_store, NULL); 00420 if (!SUCCEEDED(hr)) { 00421 dxgsg9_cat.error ( ) << "CreateDepthStencilSurface " << D3DERRORSTRING(hr) FL; 00422 } 00423 } 00424 depth_surf = _depth_backing_store; 00425 } 00426 } else { 00427 // Maintain the depth texture. 00428 if (_depth_backing_store) { 00429 _depth_backing_store->Release(); 00430 _depth_backing_store = NULL; 00431 } 00432 00433 if (_shared_depth_buffer) { 00434 depth_tex = _shared_depth_buffer -> get_texture(depth_tex_index); 00435 } 00436 if (depth_tex == 0) { 00437 depth_tex = get_texture(depth_tex_index); 00438 } 00439 00440 depth_tex->set_size_padded(_x_size, _y_size); 00441 depth_tex->set_format(Texture::F_depth_stencil); 00442 depth_ctx = 00443 DCAST(DXTextureContext9, 00444 depth_tex->prepare_now(_gsg->get_prepared_objects(), _gsg)); 00445 if (depth_ctx) { 00446 if (!depth_ctx->create_texture(*_dxgsg->_screen)) { 00447 dxgsg9_cat.error() 00448 << "Unable to re-create texture " << *color_ctx->get_texture() << endl; 00449 return false; 00450 } 00451 if (depth_tex->get_texture_type() == Texture::TT_2d_texture) { 00452 depth_d3d_tex = depth_ctx->_d3d_2d_texture; 00453 nassertr(depth_d3d_tex != 0, false); 00454 hr = color_d3d_tex -> GetSurfaceLevel(0, &depth_surf); 00455 if (!SUCCEEDED(hr)) { 00456 dxgsg9_cat.error ( ) << "GetSurfaceLevel " << D3DERRORSTRING(hr) FL; 00457 } 00458 } 00459 if (depth_tex->get_texture_type() == Texture::TT_cube_map) { 00460 depth_cube = depth_ctx->_d3d_cube_texture; 00461 nassertr(depth_cube != 0, false); 00462 hr = depth_cube -> GetCubeMapSurface ((D3DCUBEMAP_FACES) _cube_map_index, 0, &depth_surf); 00463 if (!SUCCEEDED(hr)) { 00464 dxgsg9_cat.error ( ) << "GetCubeMapSurface " << D3DERRORSTRING(hr) FL; 00465 } 00466 } 00467 } 00468 } 00469 00470 _backing_sizex = bitplane_x; 00471 _backing_sizey = bitplane_y; 00472 00473 // Load up the bitplanes. 00474 if (color_surf) { 00475 hr = _dxgsg -> _d3d_device -> SetRenderTarget (render_target_index, color_surf); 00476 if (!SUCCEEDED (hr)) { 00477 dxgsg9_cat.error ( ) << "SetRenderTarget " << D3DERRORSTRING(hr) FL; 00478 } 00479 } 00480 00481 if (depth_surf) { 00482 hr = _dxgsg -> _d3d_device -> SetDepthStencilSurface (depth_surf); 00483 if (!SUCCEEDED (hr)) { 00484 dxgsg9_cat.error ( ) << "SetDepthStencilSurface " << D3DERRORSTRING(hr) FL; 00485 } 00486 } 00487 00488 render_target_index = 1; 00489 for (int i=0; i<count_textures(); i++) { 00490 00491 Texture *tex = get_texture(i); 00492 RenderTexturePlane plane = get_texture_plane(i); 00493 00494 if (_debug) { 00495 // printf ("i = %d, RenderTexturePlane = %d \n", i, plane); 00496 } 00497 00498 switch (plane) { 00499 case RTP_color: 00500 break; 00501 case RTP_aux_rgba_0: 00502 case RTP_aux_rgba_1: 00503 case RTP_aux_rgba_2: 00504 case RTP_aux_rgba_3: 00505 case RTP_aux_hrgba_0: 00506 case RTP_aux_hrgba_1: 00507 case RTP_aux_hrgba_2: 00508 case RTP_aux_hrgba_3: 00509 case RTP_aux_float_0: 00510 case RTP_aux_float_1: 00511 case RTP_aux_float_2: 00512 case RTP_aux_float_3: 00513 { 00514 DXTextureContext9 *color_ctx = 0; 00515 IDirect3DTexture9 *color_d3d_tex = 0; 00516 IDirect3DSurface9 *color_surf = 0; 00517 IDirect3DCubeTexture9 *color_cube = 0; 00518 00519 color_ctx = DCAST(DXTextureContext9, tex->prepare_now(_gsg->get_prepared_objects(), _gsg)); 00520 if (color_ctx) { 00521 if (!color_ctx->create_texture(*_dxgsg->_screen)) { 00522 dxgsg9_cat.error() 00523 << "Unable to re-create texture " << *color_ctx->get_texture() << endl; 00524 return false; 00525 } 00526 if (tex->get_texture_type() == Texture::TT_2d_texture) { 00527 color_d3d_tex = color_ctx->_d3d_2d_texture; 00528 nassertr(color_d3d_tex != 0, false); 00529 00530 hr = color_d3d_tex -> GetSurfaceLevel(0, &color_surf); 00531 if (!SUCCEEDED(hr)) { 00532 dxgsg9_cat.error ( ) << "GetSurfaceLevel " << D3DERRORSTRING(hr) FL; 00533 } 00534 if (color_surf) { 00535 hr = _dxgsg -> _d3d_device -> SetRenderTarget (render_target_index, color_surf); 00536 if (SUCCEEDED (hr)) { 00537 render_target_index++; 00538 } else { 00539 dxgsg9_cat.error ( ) << "SetRenderTarget " << render_target_index << " " << D3DERRORSTRING(hr) FL; 00540 } 00541 color_surf->Release(); 00542 } 00543 } 00544 } 00545 } 00546 break; 00547 00548 default: 00549 break; 00550 } 00551 } 00552 00553 // Decrement the reference counts on these surfaces. The refcounts 00554 // were incremented earlier when we called GetSurfaceLevel. 00555 00556 if ((color_surf != 0)&&(color_surf != _color_backing_store)) { 00557 color_surf->Release(); 00558 } 00559 00560 if (release_depth) { 00561 if ((depth_surf != 0)&&(depth_surf != _depth_backing_store)) { 00562 depth_surf->Release(); 00563 } 00564 } 00565 00566 return true; 00567 } 00568 00569 //////////////////////////////////////////////////////////////////// 00570 // Function: wdxGraphicsBuffer9::select_cube_map 00571 // Access: Public, Virtual 00572 // Description: Called internally when the window is in 00573 // render-to-a-texture mode and we are in the process of 00574 // rendering the six faces of a cube map. This should 00575 // do whatever needs to be done to switch the buffer to 00576 // the indicated face. 00577 //////////////////////////////////////////////////////////////////// 00578 void wdxGraphicsBuffer9:: 00579 select_cube_map(int cube_map_index) { 00580 00581 DWORD render_target_index; 00582 00583 render_target_index = 0; 00584 00585 _cube_map_index = cube_map_index; 00586 00587 HRESULT hr; 00588 Texture *color_tex = 0; 00589 DXTextureContext9 *color_ctx = 0; 00590 IDirect3DCubeTexture9 *color_cube = 0; 00591 IDirect3DSurface9 *color_surf = 0; 00592 int color_tex_index = -1; 00593 00594 for (int i=0; i<count_textures(); i++) { 00595 if (get_rtm_mode(i) == RTM_bind_or_copy) { 00596 if ((get_texture(i)->get_format() != Texture::F_depth_stencil)&& 00597 (get_texture(i)->get_format() != Texture::F_depth_component)&& 00598 (color_tex_index < 0)) { 00599 color_tex_index = i; 00600 } else { 00601 _textures[i]._rtm_mode = RTM_copy_texture; 00602 } 00603 } 00604 } 00605 00606 color_tex = get_texture(color_tex_index); 00607 if (color_tex) { 00608 color_ctx = 00609 DCAST(DXTextureContext9, 00610 color_tex->prepare_now(_gsg->get_prepared_objects(), _gsg)); 00611 color_cube = color_ctx->_d3d_cube_texture; 00612 if (color_cube && _cube_map_index >= 0 && _cube_map_index < 6) { 00613 hr = color_cube -> GetCubeMapSurface ((D3DCUBEMAP_FACES) _cube_map_index, 0, &color_surf); 00614 if (!SUCCEEDED(hr)) { 00615 dxgsg9_cat.error ( ) << "GetCubeMapSurface " << D3DERRORSTRING(hr) FL; 00616 } 00617 00618 hr = _dxgsg -> _d3d_device -> SetRenderTarget (render_target_index, color_surf); 00619 if (!SUCCEEDED (hr)) { 00620 dxgsg9_cat.error ( ) << "SetRenderTarget " << D3DERRORSTRING(hr) FL; 00621 } 00622 else { 00623 color_surf->Release(); 00624 } 00625 } 00626 } 00627 00628 render_target_index = 1; 00629 for (int i=0; i<count_textures(); i++) { 00630 00631 Texture *tex = get_texture(i); 00632 RenderTexturePlane plane = get_texture_plane(i); 00633 00634 switch (plane) { 00635 case RTP_color: 00636 break; 00637 case RTP_aux_rgba_0: 00638 case RTP_aux_rgba_1: 00639 case RTP_aux_rgba_2: 00640 case RTP_aux_rgba_3: 00641 case RTP_aux_hrgba_0: 00642 case RTP_aux_hrgba_1: 00643 case RTP_aux_hrgba_2: 00644 case RTP_aux_hrgba_3: 00645 case RTP_aux_float_0: 00646 case RTP_aux_float_1: 00647 case RTP_aux_float_2: 00648 case RTP_aux_float_3: 00649 { 00650 DXTextureContext9 *color_ctx = 0; 00651 IDirect3DSurface9 *color_surf = 0; 00652 IDirect3DCubeTexture9 *color_cube = 0; 00653 00654 color_ctx = DCAST(DXTextureContext9, tex->prepare_now(_gsg->get_prepared_objects(), _gsg)); 00655 if (color_ctx) { 00656 if (tex->get_texture_type() == Texture::TT_cube_map) { 00657 00658 if (_debug) { 00659 printf ("CUBEMAP i = %d, RenderTexturePlane = %d, _cube_map_index %d \n", i, plane, _cube_map_index); 00660 } 00661 00662 color_cube = color_ctx->_d3d_cube_texture; 00663 if (color_cube && _cube_map_index >= 0 && _cube_map_index < 6) { 00664 hr = color_cube -> GetCubeMapSurface ((D3DCUBEMAP_FACES) _cube_map_index, 0, &color_surf); 00665 if (!SUCCEEDED(hr)) { 00666 dxgsg9_cat.error ( ) << "GetCubeMapSurface " << D3DERRORSTRING(hr) FL; 00667 } 00668 if (color_surf) { 00669 hr = _dxgsg -> _d3d_device -> SetRenderTarget (render_target_index, color_surf); 00670 if (SUCCEEDED (hr)) { 00671 render_target_index++; 00672 } else { 00673 dxgsg9_cat.error ( ) << "cube map SetRenderTarget " << render_target_index << " " << D3DERRORSTRING(hr) FL; 00674 } 00675 color_surf->Release(); 00676 } 00677 } 00678 } 00679 } 00680 } 00681 break; 00682 00683 default: 00684 break; 00685 } 00686 } 00687 } 00688 00689 //////////////////////////////////////////////////////////////////// 00690 // Function: wdxGraphicsBuffer9::process_events 00691 // Access: Public, Virtual 00692 // Description: Do whatever processing is necessary to ensure that 00693 // the window responds to user events. Also, honor any 00694 // requests recently made via request_properties() 00695 // 00696 // This function is called only within the window 00697 // thread. 00698 //////////////////////////////////////////////////////////////////// 00699 void wdxGraphicsBuffer9:: 00700 process_events() { 00701 GraphicsBuffer::process_events(); 00702 00703 MSG msg; 00704 00705 // Handle all the messages on the queue in a row. Some of these 00706 // might be for another window, but they will get dispatched 00707 // appropriately. 00708 while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) { 00709 process_1_event(); 00710 } 00711 } 00712 00713 //////////////////////////////////////////////////////////////////// 00714 // Function: wdxGraphicsBuffer9::close_buffer 00715 // Access: Protected, Virtual 00716 // Description: Closes the buffer right now. Called from the window 00717 // thread. 00718 //////////////////////////////////////////////////////////////////// 00719 void wdxGraphicsBuffer9:: 00720 close_buffer() { 00721 00722 if (_color_backing_store) { 00723 _color_backing_store->Release(); 00724 _color_backing_store = NULL; 00725 } 00726 if (_depth_backing_store) { 00727 _depth_backing_store->Release(); 00728 _depth_backing_store = NULL; 00729 } 00730 00731 _active = false; 00732 _cube_map_index = -1; 00733 _is_valid = false; 00734 } 00735 00736 //////////////////////////////////////////////////////////////////// 00737 // Function: wdxGraphicsBuffer9::open_buffer 00738 // Access: Protected, Virtual 00739 // Description: Opens the window right now. Called from the window 00740 // thread. Returns true if the window is successfully 00741 // opened, or false if there was a problem. 00742 //////////////////////////////////////////////////////////////////// 00743 bool wdxGraphicsBuffer9:: 00744 open_buffer() { 00745 00746 // GSG creation/initialization. 00747 if (_gsg == 0) { 00748 // The code below doesn't support creating a GSG on the fly. 00749 // Just error out for now. 00750 //_dxgsg = new DXGraphicsStateGuardian9(_engine, _pipe); 00751 //_gsg = _dxgsg; 00752 return false; 00753 } 00754 00755 DCAST_INTO_R(_dxgsg, _gsg, false); 00756 00757 if (!save_bitplanes()) { 00758 return false; 00759 } 00760 00761 HRESULT hr; 00762 hr = _saved_color_buffer -> GetDesc (&_saved_color_desc); 00763 if (!SUCCEEDED (hr)) { 00764 dxgsg9_cat.error ( ) << "GetDesc " << D3DERRORSTRING(hr) FL; 00765 return false; 00766 } 00767 hr = _saved_depth_buffer -> GetDesc (&_saved_depth_desc); 00768 if (!SUCCEEDED (hr)) { 00769 dxgsg9_cat.error ( ) << "GetDesc " << D3DERRORSTRING(hr) FL; 00770 return false; 00771 } 00772 _fb_properties = _dxgsg-> 00773 calc_fb_properties(_saved_color_desc.Format, 00774 _saved_depth_desc.Format, 00775 _saved_depth_desc.MultiSampleType, 00776 _saved_depth_desc.MultiSampleQuality); 00777 _fb_properties.set_force_hardware(1); // Wild guess. 00778 00779 00780 if (!rebuild_bitplanes()) { 00781 restore_bitplanes(); 00782 return false; 00783 } 00784 00785 restore_bitplanes(); 00786 return true; 00787 } 00788 00789 //////////////////////////////////////////////////////////////////// 00790 // Function: wdxGraphicsBuffer9::process_1_event 00791 // Access: Private, Static 00792 // Description: Handles one event from the message queue. 00793 //////////////////////////////////////////////////////////////////// 00794 void wdxGraphicsBuffer9:: 00795 process_1_event() { 00796 MSG msg; 00797 00798 if (!GetMessage(&msg, NULL, 0, 0)) { 00799 // WM_QUIT received. We need a cleaner way to deal with this. 00800 // DestroyAllWindows(false); 00801 exit(msg.wParam); // this will invoke AtExitFn 00802 } 00803 00804 // Translate virtual key messages 00805 TranslateMessage(&msg); 00806 // Call window_proc 00807 DispatchMessage(&msg); 00808 } 00809 00810 00811 00812 00813 //////////////////////////////////////////////////////////////////// 00814 // Function: wdxGraphicsBuffer9::share_depth_buffer 00815 // Access: Published 00816 // Description: Will attempt to use the depth buffer of the input 00817 // graphics_output. The buffer sizes must be exactly 00818 // the same. 00819 //////////////////////////////////////////////////////////////////// 00820 bool wdxGraphicsBuffer9:: 00821 share_depth_buffer(GraphicsOutput *graphics_output) { 00822 00823 bool state; 00824 wdxGraphicsBuffer9 *input_graphics_output; 00825 00826 state = false; 00827 input_graphics_output = DCAST (wdxGraphicsBuffer9, graphics_output); 00828 if (this != input_graphics_output && input_graphics_output) { 00829 00830 state = true; 00831 this -> unshare_depth_buffer(); 00832 00833 if (_debug) { 00834 printf ("share_depth_buffer\n"); 00835 } 00836 00837 // check buffer sizes 00838 if (this -> get_x_size() != input_graphics_output -> get_x_size()) { 00839 if (_debug) { 00840 printf ("ERROR: share_depth_buffer: non matching width \n"); 00841 } 00842 state = false; 00843 } 00844 00845 if (this -> get_y_size() != input_graphics_output -> get_y_size()) { 00846 if (_debug) { 00847 printf ("ERROR: share_depth_buffer: non matching height \n"); 00848 } 00849 state = false; 00850 } 00851 00852 if (state) { 00853 // let the input GraphicsOutput know that there is an object 00854 // sharing its depth buffer 00855 input_graphics_output -> register_shared_depth_buffer(this); 00856 _shared_depth_buffer = input_graphics_output; 00857 state = true; 00858 } 00859 } 00860 00861 return state; 00862 } 00863 00864 //////////////////////////////////////////////////////////////////// 00865 // Function: wdxGraphicsBuffer9::unshare_depth_buffer 00866 // Access: Published 00867 // Description: Discontinue sharing the depth buffer. 00868 //////////////////////////////////////////////////////////////////// 00869 void wdxGraphicsBuffer9:: 00870 unshare_depth_buffer() { 00871 if (_shared_depth_buffer) { 00872 if (_debug) { 00873 printf ("wdxGraphicsBuffer9 unshare_depth_buffer \n"); 00874 } 00875 00876 // let the GraphicsOutput know that this object is no longer 00877 // sharing its depth buffer 00878 _shared_depth_buffer -> unregister_shared_depth_buffer(this); 00879 _shared_depth_buffer = 0; 00880 } 00881 } 00882 00883 //////////////////////////////////////////////////////////////////// 00884 // Function: wdxGraphicsBuffer9::register_shared_depth_buffer 00885 // Access: Public 00886 // Description: Register/save who is sharing the depth buffer. 00887 //////////////////////////////////////////////////////////////////// 00888 void wdxGraphicsBuffer9:: 00889 register_shared_depth_buffer(GraphicsOutput *graphics_output) { 00890 wdxGraphicsBuffer9 *input_graphics_output; 00891 00892 input_graphics_output = DCAST (wdxGraphicsBuffer9, graphics_output); 00893 if (input_graphics_output) { 00894 // add to list 00895 _shared_depth_buffer_list.push_back(input_graphics_output); 00896 } 00897 } 00898 00899 //////////////////////////////////////////////////////////////////// 00900 // Function: wdxGraphicsBuffer9::unregister_shared_depth_buffer 00901 // Access: Public 00902 // Description: Unregister who is sharing the depth buffer. 00903 //////////////////////////////////////////////////////////////////// 00904 void wdxGraphicsBuffer9:: 00905 unregister_shared_depth_buffer(GraphicsOutput *graphics_output) { 00906 wdxGraphicsBuffer9 *input_graphics_output; 00907 00908 input_graphics_output = DCAST (wdxGraphicsBuffer9, graphics_output); 00909 if (input_graphics_output) { 00910 // remove from list 00911 _shared_depth_buffer_list.remove(input_graphics_output); 00912 } 00913 }