Panda3D

wdxGraphicsBuffer9.cxx

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 }
 All Classes Functions Variables Enumerations