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  */
577 select_target_tex_page(int page) {
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  */
703 process_events() {
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  */
810 share_depth_buffer(GraphicsOutput *graphics_output) {
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 }
This template class calls PipelineCycler::read() in the constructor and PipelineCycler::release_read(...
This template class calls PipelineCycler::write() in the constructor and PipelineCycler::release_writ...
A GraphicsStateGuardian for rendering into DirectX9 contexts.
bool create_texture(DXScreenData &scrn)
Use panda texture's pixelbuffer to create a texture for the specified device.
A container for the various kinds of properties we might ask to have on a graphics frameBuffer before...
An offscreen buffer for rendering into.
virtual void process_events()
Honor any requests recently made via request_open() or request_close().
This class is the main interface to controlling the render process.
This is a base class for the various different classes that represent the result of a frame of render...
int count_textures() const
If the GraphicsOutput is set to render into a texture, returns the number of textures that are being ...
const FrameBufferProperties & get_fb_properties() const
Returns the framebuffer properties of the window.
RenderTexturePlane get_texture_plane(int i=0) const
Returns the RenderTexturePlane associated with the nth render-texture.
void set_size_and_recalc(int x, int y)
Changes the x_size and y_size, then recalculates structures that depend on size.
int get_y_size() const
Returns the visible height of the window or buffer, if it is known.
get_name
Returns the name that was passed to the GraphicsOutput constructor.
int get_x_size() const
Returns the visible width of the window or buffer, if it is known.
virtual void clear(Thread *current_thread)
Clears the entire framebuffer before rendering, according to the settings of get_color_clear_active()...
virtual Texture * get_texture(int i=0) const
Returns the nth texture into which the GraphicsOutput renders.
An object to create GraphicsOutputs that share a particular 3-D API.
Definition: graphicsPipe.h:52
Encapsulates all the communication with a particular instance of a given rendering backend.
Texture * get_texture() const
Returns the pointer to the associated Texture object.
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
get_format
Returns the format of the texture, which represents both the semantic meaning of the texels and,...
Definition: texture.h:370
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:1981
get_texture_type
Returns the overall interpretation of the texture.
Definition: texture.h:365
set_format
Changes the format value for the texture components.
Definition: texture.h:370
static int up_to_power_2(int value)
Returns the smallest power of 2 greater than or equal to value.
Definition: texture.cxx:2008
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
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:1932
A thread; that is, a lightweight process.
Definition: thread.h:46
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 window before we o...
An offscreen render buffer.
void unregister_shared_depth_buffer(GraphicsOutput *graphics_output)
Unregister who is sharing the depth buffer.
virtual void unshare_depth_buffer()
Discontinue sharing the depth buffer.
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.
void register_shared_depth_buffer(GraphicsOutput *graphics_output)
Register/save who is sharing the depth buffer.
virtual void process_events()
Do whatever processing is necessary to ensure that the window responds to user events.
virtual bool share_depth_buffer(GraphicsOutput *graphics_output)
Will attempt to use the depth buffer of the input graphics_output.
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.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.