Panda3D
wdxGraphicsBuffer9.cxx
1 // Filename: wdxGraphicsBuffer8.cxx
2 // Created by: drose (08Feb04)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "wdxGraphicsPipe9.h"
16 #include "wdxGraphicsBuffer9.h"
17 #include "dxGraphicsStateGuardian9.h"
18 #include "pStatTimer.h"
19 
20 
21 #define FL << "\n" << __FILE__ << " " << __LINE__ << "\n"
22 
23 TypeHandle wdxGraphicsBuffer9::_type_handle;
24 
25 
26 ////////////////////////////////////////////////////////////////////
27 // Function: wdxGraphicsBuffer9::Constructor
28 // Access: Public
29 // Description:
30 ////////////////////////////////////////////////////////////////////
31 wdxGraphicsBuffer9::
32 wdxGraphicsBuffer9(GraphicsEngine *engine, GraphicsPipe *pipe,
33  const string &name,
34  const FrameBufferProperties &fb_prop,
35  const WindowProperties &win_prop,
36  int flags,
38  GraphicsOutput *host):
39  GraphicsBuffer(engine, pipe, name, fb_prop, win_prop, flags, gsg, host)
40 {
41  // initialize all class members
42  _cube_map_index = -1;
43  _saved_color_buffer = NULL;
44  _saved_depth_buffer = NULL;
45  _color_backing_store = NULL;
46  _depth_backing_store = NULL;
47 
48  // is this correct ???
49  // Since the pbuffer never gets flipped, we get screenshots from the
50  // same buffer we draw into.
51  _screenshot_buffer_type = _draw_buffer_type;
52 
53  _shared_depth_buffer = 0;
54  _debug = 0;
55  _this = 0;
56 
57  if (_debug) {
58  cout << "+++++ wdxGraphicsBuffer9 constructor " << this << " " << this -> get_name ( ) << "\n";
59  }
60 
61  if (_gsg) {
62  // save to GSG list to handle device lost issues
64 
65  dxgsg = DCAST (DXGraphicsStateGuardian9, _gsg);
66  _this = new (wdxGraphicsBuffer9 *);
67  *_this = this;
68  dxgsg -> _graphics_buffer_list.push_back(_this);
69  }
70 }
71 
72 ////////////////////////////////////////////////////////////////////
73 // Function: wdxGraphicsBuffer9::Destructor
74 // Access: Public, Virtual
75 // Description:
76 ////////////////////////////////////////////////////////////////////
77 wdxGraphicsBuffer9::
78 ~wdxGraphicsBuffer9() {
79 
80  if (_debug) {
81  cout << "----- wdxGraphicsBuffer9 destructor " << this << " " << this -> get_name ( ) << "\n";
82  }
83 
84  if (_gsg) {
85  // remove from GSG list
87 
88  dxgsg = DCAST (DXGraphicsStateGuardian9, _gsg);
89  if (_this) {
90  dxgsg -> _graphics_buffer_list.remove(_this);
91  }
92  _this = 0;
93  _gsg.clear();
94  _gsg = 0;
95  }
96 
97  // unshare shared depth buffer if any
98  this -> unshare_depth_buffer();
99 
100  // unshare all buffers that are sharing this object's depth buffer
101  {
102  wdxGraphicsBuffer9 *graphics_buffer;
103  list <wdxGraphicsBuffer9 *>::iterator graphics_buffer_iterator;
104 
105  graphics_buffer_iterator = _shared_depth_buffer_list.begin( );
106  while (graphics_buffer_iterator != _shared_depth_buffer_list.end( )) {
107  graphics_buffer = (*graphics_buffer_iterator);
108  if (graphics_buffer) {
109  // this call removes the entry from the list
110  graphics_buffer -> unshare_depth_buffer();
111  }
112  graphics_buffer_iterator = _shared_depth_buffer_list.begin( );
113  }
114  }
115 
116  this -> close_buffer ( );
117 }
118 
119 ////////////////////////////////////////////////////////////////////
120 // Function: wdxGraphicsBuffer9::begin_frame
121 // Access: Public, Virtual
122 // Description: This function will be called within the draw thread
123 // before beginning rendering for a given frame. It
124 // should do whatever setup is required, and return true
125 // if the frame should be rendered, or false if it
126 // should be skipped.
127 ////////////////////////////////////////////////////////////////////
129 begin_frame(FrameMode mode, Thread *current_thread) {
130 
131  begin_frame_spam(mode);
132  if (_gsg == (GraphicsStateGuardian *)NULL) {
133  return false;
134  }
135  if (_dxgsg -> _d3d_device == 0) {
136  return false;
137  }
138 
139  if (mode == FM_render) {
140  if (!save_bitplanes()) {
141  return false;
142  }
143  if (!rebuild_bitplanes()) {
144  restore_bitplanes();
145  return false;
146  }
147  clear_cube_map_selection();
148  }
149 
150  _gsg->set_current_properties(&get_fb_properties());
151  return _gsg->begin_frame(current_thread);
152 }
153 
154 ////////////////////////////////////////////////////////////////////
155 // Function: wdxGraphicsBuffer9::end_frame
156 // Access: Public, Virtual
157 // Description: This function will be called within the draw thread
158 // after rendering is completed for a given frame. It
159 // should do whatever finalization is required.
160 ////////////////////////////////////////////////////////////////////
162 end_frame(FrameMode mode, Thread *current_thread) {
163 
164  end_frame_spam(mode);
165  nassertv(_gsg != (GraphicsStateGuardian *)NULL);
166 
167  if (mode == FM_render) {
168  copy_to_textures();
169  }
170 
171  _gsg->end_frame(current_thread);
172 
173  if (mode == FM_render) {
174  trigger_flip();
175  clear_cube_map_selection();
176  restore_bitplanes();
177  }
178 }
179 
180 ////////////////////////////////////////////////////////////////////
181 // Function: wdxGraphicsBuffer9::save_bitplanes
182 // Access: Public
183 // Description: After rendering, d3d_device will need to be restored
184 // to its initial state. This function saves the state.
185 ////////////////////////////////////////////////////////////////////
186 bool wdxGraphicsBuffer9::
187 save_bitplanes() {
188  HRESULT hr;
189  DWORD render_target_index;
190 
191  render_target_index = 0;
192 
193  hr = _dxgsg -> _d3d_device -> GetRenderTarget (render_target_index, &_saved_color_buffer);
194  if (!SUCCEEDED (hr)) {
195  dxgsg9_cat.error ( ) << "GetRenderTarget " << D3DERRORSTRING(hr) FL;
196  return false;
197  }
198 
199  _saved_depth_buffer = 0;
200  hr = _dxgsg -> _d3d_device -> GetDepthStencilSurface (&_saved_depth_buffer);
201  if (hr == D3DERR_NOTFOUND) {
202  // this case is actually ok
203  }
204  else {
205  if (!SUCCEEDED (hr)) {
206  dxgsg9_cat.error ( ) << "GetDepthStencilSurface " << D3DERRORSTRING(hr) FL;
207  return false;
208  }
209  }
210  return true;
211 }
212 
213 ////////////////////////////////////////////////////////////////////
214 // Function: wdxGraphicsBuffer9::restore_bitplanes
215 // Access: Public
216 // Description: After rendering, d3d_device will need to be restored
217 // to its initial state. This function restores the state.
218 ////////////////////////////////////////////////////////////////////
219 void wdxGraphicsBuffer9::
220 restore_bitplanes() {
222  DCAST_INTO_V(dxgsg, _gsg);
223 
224  HRESULT hr;
225  DWORD render_target_index;
226 
227  render_target_index = 0;
228 
229  hr = dxgsg -> _d3d_device ->
230  SetRenderTarget (render_target_index, _saved_color_buffer);
231  if (!SUCCEEDED (hr)) {
232  dxgsg9_cat.error ( ) << "SetRenderTarget " << D3DERRORSTRING(hr) FL;
233  }
234  if (_saved_depth_buffer) {
235  hr = _dxgsg -> _d3d_device -> SetDepthStencilSurface (_saved_depth_buffer);
236  if (!SUCCEEDED (hr)) {
237  dxgsg9_cat.error ( ) << "SetDepthStencilSurface " << D3DERRORSTRING(hr) FL;
238  }
239  }
240 
241  // clear all render targets, except for the main render target
242  for (int i = 1; i<count_textures(); i++) {
243  hr = _dxgsg -> _d3d_device -> SetRenderTarget (i, NULL);
244  if (!SUCCEEDED (hr)) {
245  dxgsg9_cat.error ( ) << "SetRenderTarget " << i << " " << D3DERRORSTRING(hr) FL;
246  }
247  }
248 
249  _saved_color_buffer->Release();
250  if (_saved_depth_buffer) {
251  _saved_depth_buffer->Release();
252  }
253  _saved_color_buffer = NULL;
254  _saved_depth_buffer = NULL;
255 }
256 
257 
258 
259 ////////////////////////////////////////////////////////////////////
260 // Function: wdxGraphicsBuffer9::rebuild_bitplanes
261 // Access: Public
262 // Description: If necessary, reallocates (or allocates) the
263 // bitplanes for the buffer.
264 ////////////////////////////////////////////////////////////////////
265 bool wdxGraphicsBuffer9::
266 rebuild_bitplanes() {
267  HRESULT hr;
268  Texture *color_tex = 0;
269  Texture *depth_tex = 0;
270  DXTextureContext9 *color_ctx = 0;
271  DXTextureContext9 *depth_ctx = 0;
272  IDirect3DTexture9 *color_d3d_tex = 0;
273  IDirect3DTexture9 *depth_d3d_tex = 0;
274  IDirect3DCubeTexture9 *color_cube = 0;
275  IDirect3DCubeTexture9 *depth_cube = 0;
276  IDirect3DSurface9 *color_surf = 0;
277  IDirect3DSurface9 *depth_surf = 0;
278  DWORD render_target_index;
279 
280  render_target_index = 0;
281 
282  // Decide how big the bitplanes should be.
283 
284  if ((_host != 0)&&(_creation_flags & GraphicsPipe::BF_size_track_host)) {
285  if (_host->get_size() != _size) {
286  set_size_and_recalc(_host->get_x_size(),
287  _host->get_y_size());
288  }
289  }
290  int bitplane_x = get_x_size();
291  int bitplane_y = get_y_size();
292  if (Texture::get_textures_power_2() != ATS_none) {
293  bitplane_x = Texture::up_to_power_2(bitplane_x);
294  bitplane_y = Texture::up_to_power_2(bitplane_y);
295  }
296 
297  // Find the color and depth textures. Either may be present,
298  // or neither.
299  //
300  // NOTE: Currently, depth-stencil textures are not implemented,
301  // but since it's coming soon, we're structuring for it.
302 
303  int color_tex_index = -1;
304  int depth_tex_index = -1;
305  {
306  CDLockedReader cdata(_cycler);
307  for (size_t i = 0; i != cdata->_textures.size(); ++i) {
308  const RenderTexture &rt = cdata->_textures[i];
309  RenderTextureMode rtm_mode = rt._rtm_mode;
310  if (rtm_mode == RTM_bind_or_copy) {
311  RenderTexturePlane plane = rt._plane;
312 
313  switch (plane) {
314  case RTP_color:
315  color_tex_index = i;
316  break;
317 
318  case RTP_aux_rgba_0:
319  case RTP_aux_rgba_1:
320  case RTP_aux_rgba_2:
321  case RTP_aux_rgba_3:
322  case RTP_aux_hrgba_0:
323  case RTP_aux_hrgba_1:
324  case RTP_aux_hrgba_2:
325  case RTP_aux_hrgba_3:
326  case RTP_aux_float_0:
327  case RTP_aux_float_1:
328  case RTP_aux_float_2:
329  case RTP_aux_float_3:
330  {
331  CDWriter cdataw(_cycler, cdata, false);
332  cdataw->_textures[i]._rtm_mode = RTM_none;
333  }
334  // Creating the CDWriter invalidated the CDLockedReader.
335  cdata = CDLockedReader(_cycler);
336  break;
337  default:
338  {
339  CDWriter cdataw(_cycler, cdata, false);
340  cdataw->_textures[i]._rtm_mode = RTM_copy_texture;
341  }
342  // Creating the CDWriter invalidated the CDLockedReader.
343  cdata = CDLockedReader(_cycler);
344  break;
345  }
346  }
347  }
348  }
349 
350  if (color_tex_index < 0) {
351  // Maintain the backing color surface.
352  if ((_color_backing_store)&&
353  ((bitplane_x != _backing_sizex)||(bitplane_y != _backing_sizey))) {
354  _color_backing_store->Release();
355  _color_backing_store = NULL;
356  }
357  if (!_color_backing_store) {
358  hr = _dxgsg->_d3d_device->CreateRenderTarget(bitplane_x, bitplane_y,
359  _saved_color_desc.Format,
360  _saved_color_desc.MultiSampleType,
361  _saved_color_desc.MultiSampleQuality,
362  FALSE,
363  &_color_backing_store,
364  NULL);
365  if (!SUCCEEDED(hr)) {
366  dxgsg9_cat.error ( ) << "CreateRenderTarget " << D3DERRORSTRING(hr) FL;
367  }
368  }
369  color_surf = _color_backing_store;
370  } else {
371  // Maintain the color texture.
372  if (_color_backing_store) {
373  _color_backing_store->Release();
374  _color_backing_store = NULL;
375  }
376  color_tex = get_texture(color_tex_index);
377  color_tex->set_size_padded(get_x_size(), get_y_size());
378 // color_tex->set_format(Texture::F_rgba);
379  color_ctx =
380  DCAST(DXTextureContext9,
381  color_tex->prepare_now(0, _gsg->get_prepared_objects(), _gsg));
382 
383  if (color_ctx) {
384  if (!color_ctx->create_texture(*_dxgsg->_screen)) {
385  dxgsg9_cat.error()
386  << "Unable to re-create texture " << *color_ctx->get_texture() << endl;
387  return false;
388  }
389  if (color_tex->get_texture_type() == Texture::TT_2d_texture) {
390  color_d3d_tex = color_ctx->_d3d_2d_texture;
391  nassertr(color_d3d_tex != 0, false);
392  hr = color_d3d_tex -> GetSurfaceLevel(0, &color_surf);
393  if (!SUCCEEDED(hr)) {
394  dxgsg9_cat.error ( ) << "GetSurfaceLevel " << D3DERRORSTRING(hr) FL;
395  }
396  }
397  if (color_tex->get_texture_type() == Texture::TT_cube_map) {
398  color_cube = color_ctx->_d3d_cube_texture;
399  nassertr(color_cube != 0, false);
400 
401  if (_cube_map_index >= 0 && _cube_map_index < 6) {
402  hr = color_cube -> GetCubeMapSurface ((D3DCUBEMAP_FACES) _cube_map_index, 0, &color_surf);
403  if (!SUCCEEDED(hr)) {
404  dxgsg9_cat.error ( ) << "GetCubeMapSurface " << D3DERRORSTRING(hr) FL;
405  }
406  }
407  }
408  }
409  }
410 
411  bool release_depth;
412 
413  release_depth = true;
414  if (depth_tex_index < 0) {
415  if (_shared_depth_buffer) {
416  if (_shared_depth_buffer -> _depth_backing_store) {
417  if (_debug) {
418  printf ("SHARE DEPTH BUFFER\n");
419  }
420  depth_surf = _shared_depth_buffer -> _depth_backing_store;
421  release_depth = false;
422  }
423  }
424  if (depth_surf == 0) {
425  // Maintain the backing depth surface.
426  if ((_depth_backing_store)&&
427  ((bitplane_x != _backing_sizex)||(bitplane_y != _backing_sizey))) {
428  _depth_backing_store->Release();
429  _depth_backing_store = NULL;
430  }
431  if (!_depth_backing_store) {
432  hr = _dxgsg -> _d3d_device ->
433  CreateDepthStencilSurface (bitplane_x, bitplane_y, _saved_depth_desc.Format,
434  _saved_depth_desc.MultiSampleType, _saved_depth_desc.MultiSampleQuality,
435  false, &_depth_backing_store, NULL);
436  if (!SUCCEEDED(hr)) {
437  dxgsg9_cat.error ( ) << "CreateDepthStencilSurface " << D3DERRORSTRING(hr) FL;
438  }
439  }
440  depth_surf = _depth_backing_store;
441  }
442  } else {
443  // Maintain the depth texture.
444  if (_depth_backing_store) {
445  _depth_backing_store->Release();
446  _depth_backing_store = NULL;
447  }
448 
449  if (_shared_depth_buffer) {
450  depth_tex = _shared_depth_buffer -> get_texture(depth_tex_index);
451  }
452  if (depth_tex == 0) {
453  depth_tex = get_texture(depth_tex_index);
454  }
455 
456  depth_tex->set_size_padded(get_x_size(), get_y_size());
457  depth_tex->set_format(Texture::F_depth_stencil);
458  depth_ctx =
459  DCAST(DXTextureContext9,
460  depth_tex->prepare_now(0, _gsg->get_prepared_objects(), _gsg));
461  if (depth_ctx) {
462  if (!depth_ctx->create_texture(*_dxgsg->_screen)) {
463  dxgsg9_cat.error()
464  << "Unable to re-create texture " << *depth_ctx->get_texture() << endl;
465  return false;
466  }
467  if (depth_tex->get_texture_type() == Texture::TT_2d_texture) {
468  depth_d3d_tex = depth_ctx->_d3d_2d_texture;
469  nassertr(depth_d3d_tex != 0, false);
470  hr = depth_d3d_tex -> GetSurfaceLevel(0, &depth_surf);
471  if (!SUCCEEDED(hr)) {
472  dxgsg9_cat.error ( ) << "GetSurfaceLevel " << D3DERRORSTRING(hr) FL;
473  }
474  }
475  if (depth_tex->get_texture_type() == Texture::TT_cube_map) {
476  depth_cube = depth_ctx->_d3d_cube_texture;
477  nassertr(depth_cube != 0, false);
478  hr = depth_cube -> GetCubeMapSurface ((D3DCUBEMAP_FACES) _cube_map_index, 0, &depth_surf);
479  if (!SUCCEEDED(hr)) {
480  dxgsg9_cat.error ( ) << "GetCubeMapSurface " << D3DERRORSTRING(hr) FL;
481  }
482  }
483  }
484  }
485 
486  _backing_sizex = bitplane_x;
487  _backing_sizey = bitplane_y;
488 
489  // Load up the bitplanes.
490  if (color_surf) {
491  hr = _dxgsg -> _d3d_device -> SetRenderTarget (render_target_index, color_surf);
492  if (!SUCCEEDED (hr)) {
493  dxgsg9_cat.error ( ) << "SetRenderTarget " << D3DERRORSTRING(hr) FL;
494  }
495  }
496 
497  if (depth_surf) {
498  hr = _dxgsg -> _d3d_device -> SetDepthStencilSurface (depth_surf);
499  if (!SUCCEEDED (hr)) {
500  dxgsg9_cat.error ( ) << "SetDepthStencilSurface " << D3DERRORSTRING(hr) FL;
501  }
502  }
503 
504  render_target_index = 1;
505  for (int i=0; i<count_textures(); i++) {
506 
507  Texture *tex = get_texture(i);
508  RenderTexturePlane plane = get_texture_plane(i);
509 
510  if (_debug) {
511 // printf ("i = %d, RenderTexturePlane = %d \n", i, plane);
512  }
513 
514  switch (plane) {
515  case RTP_color:
516  break;
517  case RTP_aux_rgba_0:
518  case RTP_aux_rgba_1:
519  case RTP_aux_rgba_2:
520  case RTP_aux_rgba_3:
521  case RTP_aux_hrgba_0:
522  case RTP_aux_hrgba_1:
523  case RTP_aux_hrgba_2:
524  case RTP_aux_hrgba_3:
525  case RTP_aux_float_0:
526  case RTP_aux_float_1:
527  case RTP_aux_float_2:
528  case RTP_aux_float_3:
529  {
530  DXTextureContext9 *color_ctx = 0;
531  IDirect3DTexture9 *color_d3d_tex = 0;
532  IDirect3DSurface9 *color_surf = 0;
533  IDirect3DCubeTexture9 *color_cube = 0;
534 
535  color_ctx = DCAST(DXTextureContext9, tex->prepare_now(0, _gsg->get_prepared_objects(), _gsg));
536  if (color_ctx) {
537  if (!color_ctx->create_texture(*_dxgsg->_screen)) {
538  dxgsg9_cat.error()
539  << "Unable to re-create texture " << *color_ctx->get_texture() << endl;
540  return false;
541  }
542  if (tex->get_texture_type() == Texture::TT_2d_texture) {
543  color_d3d_tex = color_ctx->_d3d_2d_texture;
544  nassertr(color_d3d_tex != 0, false);
545 
546  hr = color_d3d_tex -> GetSurfaceLevel(0, &color_surf);
547  if (!SUCCEEDED(hr)) {
548  dxgsg9_cat.error ( ) << "GetSurfaceLevel " << D3DERRORSTRING(hr) FL;
549  }
550  if (color_surf) {
551  hr = _dxgsg -> _d3d_device -> SetRenderTarget (render_target_index, color_surf);
552  if (SUCCEEDED (hr)) {
553  render_target_index++;
554  } else {
555  dxgsg9_cat.error ( ) << "SetRenderTarget " << render_target_index << " " << D3DERRORSTRING(hr) FL;
556  }
557  color_surf->Release();
558  }
559  }
560  }
561  }
562  break;
563 
564  default:
565  break;
566  }
567  }
568 
569  // Decrement the reference counts on these surfaces. The refcounts
570  // were incremented earlier when we called GetSurfaceLevel.
571 
572  if ((color_surf != 0)&&(color_surf != _color_backing_store)) {
573  color_surf->Release();
574  }
575 
576  if (release_depth) {
577  if ((depth_surf != 0)&&(depth_surf != _depth_backing_store)) {
578  depth_surf->Release();
579  }
580  }
581 
582  return true;
583 }
584 
585 ////////////////////////////////////////////////////////////////////
586 // Function: wdxGraphicsBuffer9::select_target_tex_page
587 // Access: Public, Virtual
588 // Description: Called internally when the window is in
589 // render-to-a-texture mode and we are in the process of
590 // rendering the six faces of a cube map. This should
591 // do whatever needs to be done to switch the buffer to
592 // the indicated face.
593 ////////////////////////////////////////////////////////////////////
596 
597  DWORD render_target_index;
598 
599  render_target_index = 0;
600 
601  _cube_map_index = page;
602 
603  HRESULT hr;
604  Texture *color_tex = 0;
605  DXTextureContext9 *color_ctx = 0;
606  IDirect3DCubeTexture9 *color_cube = 0;
607  IDirect3DSurface9 *color_surf = 0;
608  int color_tex_index = -1;
609 
610  {
611  CDLockedReader cdata(_cycler);
612  for (size_t i = 0; i != cdata->_textures.size(); ++i) {
613  const RenderTexture &rt = cdata->_textures[i];
614  RenderTextureMode rtm_mode = rt._rtm_mode;
615  if (rtm_mode == RTM_bind_or_copy) {
616  Texture *tex = rt._texture;
617  if ((tex->get_format() != Texture::F_depth_stencil)&&
618  (tex->get_format() != Texture::F_depth_component)&&
619  (color_tex_index < 0)) {
620  color_tex_index = i;
621  } else {
622  CDWriter cdataw(_cycler, cdata, false);
623  nassertv(cdata->_textures.size() == cdataw->_textures.size());
624  cdataw->_textures[i]._rtm_mode = RTM_copy_texture;
625  }
626  }
627  }
628  }
629 
630  color_tex = get_texture(color_tex_index);
631  if (color_tex) {
632  color_ctx =
633  DCAST(DXTextureContext9,
634  color_tex->prepare_now(0, _gsg->get_prepared_objects(), _gsg));
635  color_cube = color_ctx->_d3d_cube_texture;
636  if (color_cube && _cube_map_index >= 0 && _cube_map_index < 6) {
637  hr = color_cube -> GetCubeMapSurface ((D3DCUBEMAP_FACES) _cube_map_index, 0, &color_surf);
638  if (!SUCCEEDED(hr)) {
639  dxgsg9_cat.error ( ) << "GetCubeMapSurface " << D3DERRORSTRING(hr) FL;
640  }
641 
642  hr = _dxgsg -> _d3d_device -> SetRenderTarget (render_target_index, color_surf);
643  if (!SUCCEEDED (hr)) {
644  dxgsg9_cat.error ( ) << "SetRenderTarget " << D3DERRORSTRING(hr) FL;
645  }
646  else {
647  color_surf->Release();
648  }
649  }
650  }
651 
652  render_target_index = 1;
653  for (int i=0; i<count_textures(); i++) {
654 
655  Texture *tex = get_texture(i);
656  RenderTexturePlane plane = get_texture_plane(i);
657 
658  switch (plane) {
659  case RTP_color:
660  break;
661  case RTP_aux_rgba_0:
662  case RTP_aux_rgba_1:
663  case RTP_aux_rgba_2:
664  case RTP_aux_rgba_3:
665  case RTP_aux_hrgba_0:
666  case RTP_aux_hrgba_1:
667  case RTP_aux_hrgba_2:
668  case RTP_aux_hrgba_3:
669  case RTP_aux_float_0:
670  case RTP_aux_float_1:
671  case RTP_aux_float_2:
672  case RTP_aux_float_3:
673  {
674  DXTextureContext9 *color_ctx = 0;
675  IDirect3DSurface9 *color_surf = 0;
676  IDirect3DCubeTexture9 *color_cube = 0;
677 
678  color_ctx = DCAST(DXTextureContext9, tex->prepare_now(0, _gsg->get_prepared_objects(), _gsg));
679  if (color_ctx) {
680  if (tex->get_texture_type() == Texture::TT_cube_map) {
681 
682  if (_debug) {
683  printf ("CUBEMAP i = %d, RenderTexturePlane = %d, _cube_map_index %d \n", i, plane, _cube_map_index);
684  }
685 
686  color_cube = color_ctx->_d3d_cube_texture;
687  if (color_cube && _cube_map_index >= 0 && _cube_map_index < 6) {
688  hr = color_cube -> GetCubeMapSurface ((D3DCUBEMAP_FACES) _cube_map_index, 0, &color_surf);
689  if (!SUCCEEDED(hr)) {
690  dxgsg9_cat.error ( ) << "GetCubeMapSurface " << D3DERRORSTRING(hr) FL;
691  }
692  if (color_surf) {
693  hr = _dxgsg -> _d3d_device -> SetRenderTarget (render_target_index, color_surf);
694  if (SUCCEEDED (hr)) {
695  render_target_index++;
696  } else {
697  dxgsg9_cat.error ( ) << "cube map SetRenderTarget " << render_target_index << " " << D3DERRORSTRING(hr) FL;
698  }
699  color_surf->Release();
700  }
701  }
702  }
703  }
704  }
705  break;
706 
707  default:
708  break;
709  }
710  }
711 }
712 
713 ////////////////////////////////////////////////////////////////////
714 // Function: wdxGraphicsBuffer9::process_events
715 // Access: Public, Virtual
716 // Description: Do whatever processing is necessary to ensure that
717 // the window responds to user events. Also, honor any
718 // requests recently made via request_properties()
719 //
720 // This function is called only within the window
721 // thread.
722 ////////////////////////////////////////////////////////////////////
726 
727  MSG msg;
728 
729  // Handle all the messages on the queue in a row. Some of these
730  // might be for another window, but they will get dispatched
731  // appropriately.
732  while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) {
733  process_1_event();
734  }
735 }
736 
737 ////////////////////////////////////////////////////////////////////
738 // Function: wdxGraphicsBuffer9::close_buffer
739 // Access: Protected, Virtual
740 // Description: Closes the buffer right now. Called from the window
741 // thread.
742 ////////////////////////////////////////////////////////////////////
743 void wdxGraphicsBuffer9::
744 close_buffer() {
745 
746  if (_color_backing_store) {
747  _color_backing_store->Release();
748  _color_backing_store = NULL;
749  }
750  if (_depth_backing_store) {
751  _depth_backing_store->Release();
752  _depth_backing_store = NULL;
753  }
754 
755  _cube_map_index = -1;
756  _is_valid = false;
757 }
758 
759 ////////////////////////////////////////////////////////////////////
760 // Function: wdxGraphicsBuffer9::open_buffer
761 // Access: Protected, Virtual
762 // Description: Opens the window right now. Called from the window
763 // thread. Returns true if the window is successfully
764 // opened, or false if there was a problem.
765 ////////////////////////////////////////////////////////////////////
766 bool wdxGraphicsBuffer9::
767 open_buffer() {
768 
769  // GSG creation/initialization.
770  if (_gsg == 0) {
771  // The code below doesn't support creating a GSG on the fly.
772  // Just error out for now.
773  //_dxgsg = new DXGraphicsStateGuardian9(_engine, _pipe);
774  //_gsg = _dxgsg;
775  return false;
776  }
777 
778  DCAST_INTO_R(_dxgsg, _gsg, false);
779 
780  if (!save_bitplanes()) {
781  return false;
782  }
783 
784  HRESULT hr;
785  hr = _saved_color_buffer -> GetDesc (&_saved_color_desc);
786  if (!SUCCEEDED (hr)) {
787  dxgsg9_cat.error ( ) << "GetDesc " << D3DERRORSTRING(hr) FL;
788  return false;
789  }
790  hr = _saved_depth_buffer -> GetDesc (&_saved_depth_desc);
791  if (!SUCCEEDED (hr)) {
792  dxgsg9_cat.error ( ) << "GetDesc " << D3DERRORSTRING(hr) FL;
793  return false;
794  }
795  _fb_properties = _dxgsg->
796  calc_fb_properties(_saved_color_desc.Format,
797  _saved_depth_desc.Format,
798  _saved_depth_desc.MultiSampleType,
799  _saved_depth_desc.MultiSampleQuality);
800  _fb_properties.set_force_hardware(1); // Wild guess.
801 
802 
803  if (!rebuild_bitplanes()) {
804  restore_bitplanes();
805  return false;
806  }
807 
808  restore_bitplanes();
809  return true;
810 }
811 
812 ////////////////////////////////////////////////////////////////////
813 // Function: wdxGraphicsBuffer9::process_1_event
814 // Access: Private, Static
815 // Description: Handles one event from the message queue.
816 ////////////////////////////////////////////////////////////////////
817 void wdxGraphicsBuffer9::
818 process_1_event() {
819  MSG msg;
820 
821  if (!GetMessage(&msg, NULL, 0, 0)) {
822  // WM_QUIT received. We need a cleaner way to deal with this.
823  // DestroyAllWindows(false);
824  exit(msg.wParam); // this will invoke AtExitFn
825  }
826 
827  // Translate virtual key messages
828  TranslateMessage(&msg);
829  // Call window_proc
830  DispatchMessage(&msg);
831 }
832 
833 
834 
835 
836 ////////////////////////////////////////////////////////////////////
837 // Function: wdxGraphicsBuffer9::share_depth_buffer
838 // Access: Published
839 // Description: Will attempt to use the depth buffer of the input
840 // graphics_output. The buffer sizes must be exactly
841 // the same.
842 ////////////////////////////////////////////////////////////////////
845 
846  bool state;
847  wdxGraphicsBuffer9 *input_graphics_output;
848 
849  state = false;
850  input_graphics_output = DCAST (wdxGraphicsBuffer9, graphics_output);
851  if (this != input_graphics_output && input_graphics_output) {
852 
853  state = true;
854  this -> unshare_depth_buffer();
855 
856  if (_debug) {
857  printf ("share_depth_buffer\n");
858  }
859 
860  // check buffer sizes
861  if (this -> get_x_size() != input_graphics_output -> get_x_size()) {
862  if (_debug) {
863  printf ("ERROR: share_depth_buffer: non matching width \n");
864  }
865  state = false;
866  }
867 
868  if (this -> get_y_size() != input_graphics_output -> get_y_size()) {
869  if (_debug) {
870  printf ("ERROR: share_depth_buffer: non matching height \n");
871  }
872  state = false;
873  }
874 
875  if (state) {
876  // let the input GraphicsOutput know that there is an object
877  // sharing its depth buffer
878  input_graphics_output -> register_shared_depth_buffer(this);
879  _shared_depth_buffer = input_graphics_output;
880  state = true;
881  }
882  }
883 
884  return state;
885 }
886 
887 ////////////////////////////////////////////////////////////////////
888 // Function: wdxGraphicsBuffer9::unshare_depth_buffer
889 // Access: Published
890 // Description: Discontinue sharing the depth buffer.
891 ////////////////////////////////////////////////////////////////////
894  if (_shared_depth_buffer) {
895  if (_debug) {
896  printf ("wdxGraphicsBuffer9 unshare_depth_buffer \n");
897  }
898 
899  // let the GraphicsOutput know that this object is no longer
900  // sharing its depth buffer
901  _shared_depth_buffer -> unregister_shared_depth_buffer(this);
902  _shared_depth_buffer = 0;
903  }
904 }
905 
906 ////////////////////////////////////////////////////////////////////
907 // Function: wdxGraphicsBuffer9::register_shared_depth_buffer
908 // Access: Public
909 // Description: Register/save who is sharing the depth buffer.
910 ////////////////////////////////////////////////////////////////////
913  wdxGraphicsBuffer9 *input_graphics_output;
914 
915  input_graphics_output = DCAST (wdxGraphicsBuffer9, graphics_output);
916  if (input_graphics_output) {
917  // add to list
918  _shared_depth_buffer_list.push_back(input_graphics_output);
919  }
920 }
921 
922 ////////////////////////////////////////////////////////////////////
923 // Function: wdxGraphicsBuffer9::unregister_shared_depth_buffer
924 // Access: Public
925 // Description: Unregister who is sharing the depth buffer.
926 ////////////////////////////////////////////////////////////////////
929  wdxGraphicsBuffer9 *input_graphics_output;
930 
931  input_graphics_output = DCAST (wdxGraphicsBuffer9, graphics_output);
932  if (input_graphics_output) {
933  // remove from list
934  _shared_depth_buffer_list.remove(input_graphics_output);
935  }
936 }
void unregister_shared_depth_buffer(GraphicsOutput *graphics_output)
Unregister who is sharing the depth buffer.
A GraphicsStateGuardian for rendering into DirectX9 contexts.
Format get_format() const
Returns the format of the texture, which represents both the semantic meaning of the texels and...
Definition: texture.I:872
Texture * get_texture() const
Returns the pointer to the associated Texture object.
void set_size_and_recalc(int x, int y)
Changes the x_size and y_size, then recalculates structures that depend on size.
virtual bool share_depth_buffer(GraphicsOutput *graphics_output)
Will attempt to use the depth buffer of the input graphics_output.
virtual Texture * get_texture(int i=0) const
Returns the nth texture into which the GraphicsOutput renders.
TextureType get_texture_type() const
Returns the overall interpretation of the texture.
Definition: texture.I:859
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
Definition: texture.h:75
int get_y_size() const
Returns the visible height of the window or buffer, if it is known.
void set_format(Format format)
Changes the format value for the texture components.
Definition: texture.I:2440
bool create_texture(DXScreenData &scrn)
Use panda texture&#39;s pixelbuffer to create a texture for the specified device.
virtual void select_target_tex_page(int page)
Called internally when the window is in render-to-a-texture mode and we are in the process of renderi...
virtual void end_frame(FrameMode mode, Thread *current_thread)
This function will be called within the draw thread after rendering is completed for a given frame...
virtual void process_events()
Honor any requests recently made via request_open() or request_close().
void set_size_padded(int x=1, int y=1, int z=1)
Changes the size of the texture, padding if necessary, and setting the pad region as well...
Definition: texture.cxx:1759
static AutoTextureScale get_textures_power_2()
This flag returns ATS_none, ATS_up, or ATS_down and controls the scaling of textures in general...
Definition: texture.I:2232
A container for the various kinds of properties we might ask to have on a graphics window before we o...
void clear(Thread *current_thread)
Clears the entire framebuffer before rendering, according to the settings of get_color_clear_active()...
An offscreen render buffer.
An offscreen buffer for rendering into.
An object to create GraphicsOutputs that share a particular 3-D API.
Definition: graphicsPipe.h:58
virtual void process_events()
Do whatever processing is necessary to ensure that the window responds to user events.
This template class calls PipelineCycler::read() in the constructor and PipelineCycler::release_read(...
int count_textures() const
If the GraphicsOutput is set to render into a texture, returns the number of textures that are being ...
This template class calls PipelineCycler::write() in the constructor and PipelineCycler::release_writ...
This is a base class for the various different classes that represent the result of a frame of render...
int get_x_size() const
Returns the visible width of the window or buffer, if it is known.
TextureContext * prepare_now(int view, PreparedGraphicsObjects *prepared_objects, GraphicsStateGuardianBase *gsg)
Creates a context for the texture on the particular GSG, if it does not already exist.
Definition: texture.cxx:1815
virtual bool begin_frame(FrameMode mode, Thread *current_thread)
This function will be called within the draw thread before beginning rendering for a given frame...
static int up_to_power_2(int value)
Returns the smallest power of 2 greater than or equal to value.
Definition: texture.cxx:1845
A thread; that is, a lightweight process.
Definition: thread.h:51
Encapsulates all the communication with a particular instance of a given rendering backend...
const string & get_name() const
Returns the name that was passed to the GraphicsOutput constructor.
virtual void unshare_depth_buffer()
Discontinue sharing the depth buffer.
This class is the main interface to controlling the render process.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
A container for the various kinds of properties we might ask to have on a graphics frameBuffer before...
RenderTexturePlane get_texture_plane(int i=0) const
Returns the RenderTexturePlane associated with the nth render-texture.
const FrameBufferProperties & get_fb_properties() const
Returns the framebuffer properties of the window.
void register_shared_depth_buffer(GraphicsOutput *graphics_output)
Register/save who is sharing the depth buffer.