Panda3D
 All Classes Functions Variables Enumerations
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  nassertr(cdata->_textures.size() == cdataw->_textures.size(), false);
333  cdataw->_textures[i]._rtm_mode = RTM_none;
334  }
335  break;
336  default:
337  {
338  CDWriter cdataw(_cycler, cdata, false);
339  nassertr(cdata->_textures.size() == cdataw->_textures.size(), false);
340  cdataw->_textures[i]._rtm_mode = RTM_copy_texture;
341  }
342  break;
343  }
344  }
345  }
346  }
347 
348  if (color_tex_index < 0) {
349  // Maintain the backing color surface.
350  if ((_color_backing_store)&&
351  ((bitplane_x != _backing_sizex)||(bitplane_y != _backing_sizey))) {
352  _color_backing_store->Release();
353  _color_backing_store = NULL;
354  }
355  if (!_color_backing_store) {
356  hr = _dxgsg->_d3d_device->CreateRenderTarget(bitplane_x, bitplane_y,
357  _saved_color_desc.Format,
358  _saved_color_desc.MultiSampleType,
359  _saved_color_desc.MultiSampleQuality,
360  FALSE,
361  &_color_backing_store,
362  NULL);
363  if (!SUCCEEDED(hr)) {
364  dxgsg9_cat.error ( ) << "CreateRenderTarget " << D3DERRORSTRING(hr) FL;
365  }
366  }
367  color_surf = _color_backing_store;
368  } else {
369  // Maintain the color texture.
370  if (_color_backing_store) {
371  _color_backing_store->Release();
372  _color_backing_store = NULL;
373  }
374  color_tex = get_texture(color_tex_index);
375  color_tex->set_size_padded(get_x_size(), get_y_size());
376 // color_tex->set_format(Texture::F_rgba);
377  color_ctx =
378  DCAST(DXTextureContext9,
379  color_tex->prepare_now(0, _gsg->get_prepared_objects(), _gsg));
380 
381  if (color_ctx) {
382  if (!color_ctx->create_texture(*_dxgsg->_screen)) {
383  dxgsg9_cat.error()
384  << "Unable to re-create texture " << *color_ctx->get_texture() << endl;
385  return false;
386  }
387  if (color_tex->get_texture_type() == Texture::TT_2d_texture) {
388  color_d3d_tex = color_ctx->_d3d_2d_texture;
389  nassertr(color_d3d_tex != 0, false);
390  hr = color_d3d_tex -> GetSurfaceLevel(0, &color_surf);
391  if (!SUCCEEDED(hr)) {
392  dxgsg9_cat.error ( ) << "GetSurfaceLevel " << D3DERRORSTRING(hr) FL;
393  }
394  }
395  if (color_tex->get_texture_type() == Texture::TT_cube_map) {
396  color_cube = color_ctx->_d3d_cube_texture;
397  nassertr(color_cube != 0, false);
398 
399  if (_cube_map_index >= 0 && _cube_map_index < 6) {
400  hr = color_cube -> GetCubeMapSurface ((D3DCUBEMAP_FACES) _cube_map_index, 0, &color_surf);
401  if (!SUCCEEDED(hr)) {
402  dxgsg9_cat.error ( ) << "GetCubeMapSurface " << D3DERRORSTRING(hr) FL;
403  }
404  }
405  }
406  }
407  }
408 
409  bool release_depth;
410 
411  release_depth = true;
412  if (depth_tex_index < 0) {
413  if (_shared_depth_buffer) {
414  if (_shared_depth_buffer -> _depth_backing_store) {
415  if (_debug) {
416  printf ("SHARE DEPTH BUFFER\n");
417  }
418  depth_surf = _shared_depth_buffer -> _depth_backing_store;
419  release_depth = false;
420  }
421  }
422  if (depth_surf == 0) {
423  // Maintain the backing depth surface.
424  if ((_depth_backing_store)&&
425  ((bitplane_x != _backing_sizex)||(bitplane_y != _backing_sizey))) {
426  _depth_backing_store->Release();
427  _depth_backing_store = NULL;
428  }
429  if (!_depth_backing_store) {
430  hr = _dxgsg -> _d3d_device ->
431  CreateDepthStencilSurface (bitplane_x, bitplane_y, _saved_depth_desc.Format,
432  _saved_depth_desc.MultiSampleType, _saved_depth_desc.MultiSampleQuality,
433  false, &_depth_backing_store, NULL);
434  if (!SUCCEEDED(hr)) {
435  dxgsg9_cat.error ( ) << "CreateDepthStencilSurface " << D3DERRORSTRING(hr) FL;
436  }
437  }
438  depth_surf = _depth_backing_store;
439  }
440  } else {
441  // Maintain the depth texture.
442  if (_depth_backing_store) {
443  _depth_backing_store->Release();
444  _depth_backing_store = NULL;
445  }
446 
447  if (_shared_depth_buffer) {
448  depth_tex = _shared_depth_buffer -> get_texture(depth_tex_index);
449  }
450  if (depth_tex == 0) {
451  depth_tex = get_texture(depth_tex_index);
452  }
453 
454  depth_tex->set_size_padded(get_x_size(), get_y_size());
455  depth_tex->set_format(Texture::F_depth_stencil);
456  depth_ctx =
457  DCAST(DXTextureContext9,
458  depth_tex->prepare_now(0, _gsg->get_prepared_objects(), _gsg));
459  if (depth_ctx) {
460  if (!depth_ctx->create_texture(*_dxgsg->_screen)) {
461  dxgsg9_cat.error()
462  << "Unable to re-create texture " << *depth_ctx->get_texture() << endl;
463  return false;
464  }
465  if (depth_tex->get_texture_type() == Texture::TT_2d_texture) {
466  depth_d3d_tex = depth_ctx->_d3d_2d_texture;
467  nassertr(depth_d3d_tex != 0, false);
468  hr = depth_d3d_tex -> GetSurfaceLevel(0, &depth_surf);
469  if (!SUCCEEDED(hr)) {
470  dxgsg9_cat.error ( ) << "GetSurfaceLevel " << D3DERRORSTRING(hr) FL;
471  }
472  }
473  if (depth_tex->get_texture_type() == Texture::TT_cube_map) {
474  depth_cube = depth_ctx->_d3d_cube_texture;
475  nassertr(depth_cube != 0, false);
476  hr = depth_cube -> GetCubeMapSurface ((D3DCUBEMAP_FACES) _cube_map_index, 0, &depth_surf);
477  if (!SUCCEEDED(hr)) {
478  dxgsg9_cat.error ( ) << "GetCubeMapSurface " << D3DERRORSTRING(hr) FL;
479  }
480  }
481  }
482  }
483 
484  _backing_sizex = bitplane_x;
485  _backing_sizey = bitplane_y;
486 
487  // Load up the bitplanes.
488  if (color_surf) {
489  hr = _dxgsg -> _d3d_device -> SetRenderTarget (render_target_index, color_surf);
490  if (!SUCCEEDED (hr)) {
491  dxgsg9_cat.error ( ) << "SetRenderTarget " << D3DERRORSTRING(hr) FL;
492  }
493  }
494 
495  if (depth_surf) {
496  hr = _dxgsg -> _d3d_device -> SetDepthStencilSurface (depth_surf);
497  if (!SUCCEEDED (hr)) {
498  dxgsg9_cat.error ( ) << "SetDepthStencilSurface " << D3DERRORSTRING(hr) FL;
499  }
500  }
501 
502  render_target_index = 1;
503  for (int i=0; i<count_textures(); i++) {
504 
505  Texture *tex = get_texture(i);
506  RenderTexturePlane plane = get_texture_plane(i);
507 
508  if (_debug) {
509 // printf ("i = %d, RenderTexturePlane = %d \n", i, plane);
510  }
511 
512  switch (plane) {
513  case RTP_color:
514  break;
515  case RTP_aux_rgba_0:
516  case RTP_aux_rgba_1:
517  case RTP_aux_rgba_2:
518  case RTP_aux_rgba_3:
519  case RTP_aux_hrgba_0:
520  case RTP_aux_hrgba_1:
521  case RTP_aux_hrgba_2:
522  case RTP_aux_hrgba_3:
523  case RTP_aux_float_0:
524  case RTP_aux_float_1:
525  case RTP_aux_float_2:
526  case RTP_aux_float_3:
527  {
528  DXTextureContext9 *color_ctx = 0;
529  IDirect3DTexture9 *color_d3d_tex = 0;
530  IDirect3DSurface9 *color_surf = 0;
531  IDirect3DCubeTexture9 *color_cube = 0;
532 
533  color_ctx = DCAST(DXTextureContext9, tex->prepare_now(0, _gsg->get_prepared_objects(), _gsg));
534  if (color_ctx) {
535  if (!color_ctx->create_texture(*_dxgsg->_screen)) {
536  dxgsg9_cat.error()
537  << "Unable to re-create texture " << *color_ctx->get_texture() << endl;
538  return false;
539  }
540  if (tex->get_texture_type() == Texture::TT_2d_texture) {
541  color_d3d_tex = color_ctx->_d3d_2d_texture;
542  nassertr(color_d3d_tex != 0, false);
543 
544  hr = color_d3d_tex -> GetSurfaceLevel(0, &color_surf);
545  if (!SUCCEEDED(hr)) {
546  dxgsg9_cat.error ( ) << "GetSurfaceLevel " << D3DERRORSTRING(hr) FL;
547  }
548  if (color_surf) {
549  hr = _dxgsg -> _d3d_device -> SetRenderTarget (render_target_index, color_surf);
550  if (SUCCEEDED (hr)) {
551  render_target_index++;
552  } else {
553  dxgsg9_cat.error ( ) << "SetRenderTarget " << render_target_index << " " << D3DERRORSTRING(hr) FL;
554  }
555  color_surf->Release();
556  }
557  }
558  }
559  }
560  break;
561 
562  default:
563  break;
564  }
565  }
566 
567  // Decrement the reference counts on these surfaces. The refcounts
568  // were incremented earlier when we called GetSurfaceLevel.
569 
570  if ((color_surf != 0)&&(color_surf != _color_backing_store)) {
571  color_surf->Release();
572  }
573 
574  if (release_depth) {
575  if ((depth_surf != 0)&&(depth_surf != _depth_backing_store)) {
576  depth_surf->Release();
577  }
578  }
579 
580  return true;
581 }
582 
583 ////////////////////////////////////////////////////////////////////
584 // Function: wdxGraphicsBuffer9::select_target_tex_page
585 // Access: Public, Virtual
586 // Description: Called internally when the window is in
587 // render-to-a-texture mode and we are in the process of
588 // rendering the six faces of a cube map. This should
589 // do whatever needs to be done to switch the buffer to
590 // the indicated face.
591 ////////////////////////////////////////////////////////////////////
594 
595  DWORD render_target_index;
596 
597  render_target_index = 0;
598 
599  _cube_map_index = page;
600 
601  HRESULT hr;
602  Texture *color_tex = 0;
603  DXTextureContext9 *color_ctx = 0;
604  IDirect3DCubeTexture9 *color_cube = 0;
605  IDirect3DSurface9 *color_surf = 0;
606  int color_tex_index = -1;
607 
608  {
609  CDLockedReader cdata(_cycler);
610  for (size_t i = 0; i != cdata->_textures.size(); ++i) {
611  const RenderTexture &rt = cdata->_textures[i];
612  RenderTextureMode rtm_mode = rt._rtm_mode;
613  if (rtm_mode == RTM_bind_or_copy) {
614  Texture *tex = rt._texture;
615  if ((tex->get_format() != Texture::F_depth_stencil)&&
616  (tex->get_format() != Texture::F_depth_component)&&
617  (color_tex_index < 0)) {
618  color_tex_index = i;
619  } else {
620  CDWriter cdataw(_cycler, cdata, false);
621  nassertv(cdata->_textures.size() == cdataw->_textures.size());
622  cdataw->_textures[i]._rtm_mode = RTM_copy_texture;
623  }
624  }
625  }
626  }
627 
628  color_tex = get_texture(color_tex_index);
629  if (color_tex) {
630  color_ctx =
631  DCAST(DXTextureContext9,
632  color_tex->prepare_now(0, _gsg->get_prepared_objects(), _gsg));
633  color_cube = color_ctx->_d3d_cube_texture;
634  if (color_cube && _cube_map_index >= 0 && _cube_map_index < 6) {
635  hr = color_cube -> GetCubeMapSurface ((D3DCUBEMAP_FACES) _cube_map_index, 0, &color_surf);
636  if (!SUCCEEDED(hr)) {
637  dxgsg9_cat.error ( ) << "GetCubeMapSurface " << D3DERRORSTRING(hr) FL;
638  }
639 
640  hr = _dxgsg -> _d3d_device -> SetRenderTarget (render_target_index, color_surf);
641  if (!SUCCEEDED (hr)) {
642  dxgsg9_cat.error ( ) << "SetRenderTarget " << D3DERRORSTRING(hr) FL;
643  }
644  else {
645  color_surf->Release();
646  }
647  }
648  }
649 
650  render_target_index = 1;
651  for (int i=0; i<count_textures(); i++) {
652 
653  Texture *tex = get_texture(i);
654  RenderTexturePlane plane = get_texture_plane(i);
655 
656  switch (plane) {
657  case RTP_color:
658  break;
659  case RTP_aux_rgba_0:
660  case RTP_aux_rgba_1:
661  case RTP_aux_rgba_2:
662  case RTP_aux_rgba_3:
663  case RTP_aux_hrgba_0:
664  case RTP_aux_hrgba_1:
665  case RTP_aux_hrgba_2:
666  case RTP_aux_hrgba_3:
667  case RTP_aux_float_0:
668  case RTP_aux_float_1:
669  case RTP_aux_float_2:
670  case RTP_aux_float_3:
671  {
672  DXTextureContext9 *color_ctx = 0;
673  IDirect3DSurface9 *color_surf = 0;
674  IDirect3DCubeTexture9 *color_cube = 0;
675 
676  color_ctx = DCAST(DXTextureContext9, tex->prepare_now(0, _gsg->get_prepared_objects(), _gsg));
677  if (color_ctx) {
678  if (tex->get_texture_type() == Texture::TT_cube_map) {
679 
680  if (_debug) {
681  printf ("CUBEMAP i = %d, RenderTexturePlane = %d, _cube_map_index %d \n", i, plane, _cube_map_index);
682  }
683 
684  color_cube = color_ctx->_d3d_cube_texture;
685  if (color_cube && _cube_map_index >= 0 && _cube_map_index < 6) {
686  hr = color_cube -> GetCubeMapSurface ((D3DCUBEMAP_FACES) _cube_map_index, 0, &color_surf);
687  if (!SUCCEEDED(hr)) {
688  dxgsg9_cat.error ( ) << "GetCubeMapSurface " << D3DERRORSTRING(hr) FL;
689  }
690  if (color_surf) {
691  hr = _dxgsg -> _d3d_device -> SetRenderTarget (render_target_index, color_surf);
692  if (SUCCEEDED (hr)) {
693  render_target_index++;
694  } else {
695  dxgsg9_cat.error ( ) << "cube map SetRenderTarget " << render_target_index << " " << D3DERRORSTRING(hr) FL;
696  }
697  color_surf->Release();
698  }
699  }
700  }
701  }
702  }
703  break;
704 
705  default:
706  break;
707  }
708  }
709 }
710 
711 ////////////////////////////////////////////////////////////////////
712 // Function: wdxGraphicsBuffer9::process_events
713 // Access: Public, Virtual
714 // Description: Do whatever processing is necessary to ensure that
715 // the window responds to user events. Also, honor any
716 // requests recently made via request_properties()
717 //
718 // This function is called only within the window
719 // thread.
720 ////////////////////////////////////////////////////////////////////
724 
725  MSG msg;
726 
727  // Handle all the messages on the queue in a row. Some of these
728  // might be for another window, but they will get dispatched
729  // appropriately.
730  while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) {
731  process_1_event();
732  }
733 }
734 
735 ////////////////////////////////////////////////////////////////////
736 // Function: wdxGraphicsBuffer9::close_buffer
737 // Access: Protected, Virtual
738 // Description: Closes the buffer right now. Called from the window
739 // thread.
740 ////////////////////////////////////////////////////////////////////
741 void wdxGraphicsBuffer9::
742 close_buffer() {
743 
744  if (_color_backing_store) {
745  _color_backing_store->Release();
746  _color_backing_store = NULL;
747  }
748  if (_depth_backing_store) {
749  _depth_backing_store->Release();
750  _depth_backing_store = NULL;
751  }
752 
753  _cube_map_index = -1;
754  _is_valid = false;
755 }
756 
757 ////////////////////////////////////////////////////////////////////
758 // Function: wdxGraphicsBuffer9::open_buffer
759 // Access: Protected, Virtual
760 // Description: Opens the window right now. Called from the window
761 // thread. Returns true if the window is successfully
762 // opened, or false if there was a problem.
763 ////////////////////////////////////////////////////////////////////
764 bool wdxGraphicsBuffer9::
765 open_buffer() {
766 
767  // GSG creation/initialization.
768  if (_gsg == 0) {
769  // The code below doesn't support creating a GSG on the fly.
770  // Just error out for now.
771  //_dxgsg = new DXGraphicsStateGuardian9(_engine, _pipe);
772  //_gsg = _dxgsg;
773  return false;
774  }
775 
776  DCAST_INTO_R(_dxgsg, _gsg, false);
777 
778  if (!save_bitplanes()) {
779  return false;
780  }
781 
782  HRESULT hr;
783  hr = _saved_color_buffer -> GetDesc (&_saved_color_desc);
784  if (!SUCCEEDED (hr)) {
785  dxgsg9_cat.error ( ) << "GetDesc " << D3DERRORSTRING(hr) FL;
786  return false;
787  }
788  hr = _saved_depth_buffer -> GetDesc (&_saved_depth_desc);
789  if (!SUCCEEDED (hr)) {
790  dxgsg9_cat.error ( ) << "GetDesc " << D3DERRORSTRING(hr) FL;
791  return false;
792  }
793  _fb_properties = _dxgsg->
794  calc_fb_properties(_saved_color_desc.Format,
795  _saved_depth_desc.Format,
796  _saved_depth_desc.MultiSampleType,
797  _saved_depth_desc.MultiSampleQuality);
798  _fb_properties.set_force_hardware(1); // Wild guess.
799 
800 
801  if (!rebuild_bitplanes()) {
802  restore_bitplanes();
803  return false;
804  }
805 
806  restore_bitplanes();
807  return true;
808 }
809 
810 ////////////////////////////////////////////////////////////////////
811 // Function: wdxGraphicsBuffer9::process_1_event
812 // Access: Private, Static
813 // Description: Handles one event from the message queue.
814 ////////////////////////////////////////////////////////////////////
815 void wdxGraphicsBuffer9::
816 process_1_event() {
817  MSG msg;
818 
819  if (!GetMessage(&msg, NULL, 0, 0)) {
820  // WM_QUIT received. We need a cleaner way to deal with this.
821  // DestroyAllWindows(false);
822  exit(msg.wParam); // this will invoke AtExitFn
823  }
824 
825  // Translate virtual key messages
826  TranslateMessage(&msg);
827  // Call window_proc
828  DispatchMessage(&msg);
829 }
830 
831 
832 
833 
834 ////////////////////////////////////////////////////////////////////
835 // Function: wdxGraphicsBuffer9::share_depth_buffer
836 // Access: Published
837 // Description: Will attempt to use the depth buffer of the input
838 // graphics_output. The buffer sizes must be exactly
839 // the same.
840 ////////////////////////////////////////////////////////////////////
843 
844  bool state;
845  wdxGraphicsBuffer9 *input_graphics_output;
846 
847  state = false;
848  input_graphics_output = DCAST (wdxGraphicsBuffer9, graphics_output);
849  if (this != input_graphics_output && input_graphics_output) {
850 
851  state = true;
852  this -> unshare_depth_buffer();
853 
854  if (_debug) {
855  printf ("share_depth_buffer\n");
856  }
857 
858  // check buffer sizes
859  if (this -> get_x_size() != input_graphics_output -> get_x_size()) {
860  if (_debug) {
861  printf ("ERROR: share_depth_buffer: non matching width \n");
862  }
863  state = false;
864  }
865 
866  if (this -> get_y_size() != input_graphics_output -> get_y_size()) {
867  if (_debug) {
868  printf ("ERROR: share_depth_buffer: non matching height \n");
869  }
870  state = false;
871  }
872 
873  if (state) {
874  // let the input GraphicsOutput know that there is an object
875  // sharing its depth buffer
876  input_graphics_output -> register_shared_depth_buffer(this);
877  _shared_depth_buffer = input_graphics_output;
878  state = true;
879  }
880  }
881 
882  return state;
883 }
884 
885 ////////////////////////////////////////////////////////////////////
886 // Function: wdxGraphicsBuffer9::unshare_depth_buffer
887 // Access: Published
888 // Description: Discontinue sharing the depth buffer.
889 ////////////////////////////////////////////////////////////////////
892  if (_shared_depth_buffer) {
893  if (_debug) {
894  printf ("wdxGraphicsBuffer9 unshare_depth_buffer \n");
895  }
896 
897  // let the GraphicsOutput know that this object is no longer
898  // sharing its depth buffer
899  _shared_depth_buffer -> unregister_shared_depth_buffer(this);
900  _shared_depth_buffer = 0;
901  }
902 }
903 
904 ////////////////////////////////////////////////////////////////////
905 // Function: wdxGraphicsBuffer9::register_shared_depth_buffer
906 // Access: Public
907 // Description: Register/save who is sharing the depth buffer.
908 ////////////////////////////////////////////////////////////////////
911  wdxGraphicsBuffer9 *input_graphics_output;
912 
913  input_graphics_output = DCAST (wdxGraphicsBuffer9, graphics_output);
914  if (input_graphics_output) {
915  // add to list
916  _shared_depth_buffer_list.push_back(input_graphics_output);
917  }
918 }
919 
920 ////////////////////////////////////////////////////////////////////
921 // Function: wdxGraphicsBuffer9::unregister_shared_depth_buffer
922 // Access: Public
923 // Description: Unregister who is sharing the depth buffer.
924 ////////////////////////////////////////////////////////////////////
927  wdxGraphicsBuffer9 *input_graphics_output;
928 
929  input_graphics_output = DCAST (wdxGraphicsBuffer9, graphics_output);
930  if (input_graphics_output) {
931  // remove from list
932  _shared_depth_buffer_list.remove(input_graphics_output);
933  }
934 }
void unregister_shared_depth_buffer(GraphicsOutput *graphics_output)
Unregister who is sharing the depth buffer.
Format get_format() const
Returns the format of the texture, which represents both the semantic meaning of the texels and...
Definition: texture.I:872
A GraphicsStateGuardian for rendering into DirectX9 contexts.
void set_size_and_recalc(int x, int y)
Changes the x_size and y_size, then recalculates structures that depend on size.
virtual Texture * get_texture(int i=0) const
Returns the nth texture into which the GraphicsOutput renders.
virtual bool share_depth_buffer(GraphicsOutput *graphics_output)
Will attempt to use the depth buffer of the input graphics_output.
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
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...
Texture * get_texture() const
Returns the pointer to the associated Texture object.
int get_y_size() const
Returns the visible height of the window or buffer, if it is known.
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:1752
RenderTexturePlane get_texture_plane(int i=0) const
Returns the RenderTexturePlane associated with the nth render-texture.
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(...
This template class calls PipelineCycler::write() in the constructor and PipelineCycler::release_writ...
TextureType get_texture_type() const
Returns the overall interpretation of the texture.
Definition: texture.I:859
This is a base class for the various different classes that represent the result of a frame of render...
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:1808
int count_textures() const
If the GraphicsOutput is set to render into a texture, returns the number of textures that are being ...
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...
int get_x_size() const
Returns the visible width of the window or buffer, if it is known.
static int up_to_power_2(int value)
Returns the smallest power of 2 greater than or equal to value.
Definition: texture.cxx:1838
A thread; that is, a lightweight process.
Definition: thread.h:51
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.
const FrameBufferProperties & get_fb_properties() const
Returns the framebuffer properties of the window.
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...
const string & get_name() const
Returns the name that was passed to the GraphicsOutput constructor.
void register_shared_depth_buffer(GraphicsOutput *graphics_output)
Register/save who is sharing the depth buffer.