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