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"
16 #include "dxGraphicsStateGuardian9.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,
37 GraphicsStateGuardian *gsg,
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
62 DXGraphicsStateGuardian9 *dxgsg;
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
83 DXGraphicsStateGuardian9 *dxgsg;
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 */
122 bool wdxGraphicsBuffer9::
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 */
153 void wdxGraphicsBuffer9::
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() {
209 DXGraphicsStateGuardian9 *dxgsg;
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 */
576 void wdxGraphicsBuffer9::
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 */
702 void wdxGraphicsBuffer9::
703 process_events() {
704 GraphicsBuffer::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 */
809 bool wdxGraphicsBuffer9::
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 */
856 void wdxGraphicsBuffer9::
857 unshare_depth_buffer() {
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 */
873 void wdxGraphicsBuffer9::
874 register_shared_depth_buffer(GraphicsOutput *graphics_output) {
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 */
887 void wdxGraphicsBuffer9::
888 unregister_shared_depth_buffer(GraphicsOutput *graphics_output) {
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 }
CycleDataLockedReader
This template class calls PipelineCycler::read() in the constructor and PipelineCycler::release_read(...
Definition: cycleDataLockedReader.h:40
CycleDataWriter
This template class calls PipelineCycler::write() in the constructor and PipelineCycler::release_writ...
Definition: cycleDataWriter.h:34
DXGraphicsStateGuardian9
A GraphicsStateGuardian for rendering into DirectX9 contexts.
Definition: dxGraphicsStateGuardian9.h:57
DXTextureContext9
Definition: dxTextureContext9.h:24
DXTextureContext9::create_texture
bool create_texture(DXScreenData &scrn)
Use panda texture's pixelbuffer to create a texture for the specified device.
Definition: dxTextureContext9.cxx:101
FrameBufferProperties
A container for the various kinds of properties we might ask to have on a graphics frameBuffer before...
Definition: frameBufferProperties.h:26
GraphicsBuffer
An offscreen buffer for rendering into.
Definition: graphicsBuffer.h:27
GraphicsBuffer::process_events
virtual void process_events()
Honor any requests recently made via request_open() or request_close().
Definition: graphicsBuffer.cxx:103
GraphicsEngine
This class is the main interface to controlling the render process.
Definition: graphicsEngine.h:53
GraphicsOutput
This is a base class for the various different classes that represent the result of a frame of render...
Definition: graphicsOutput.h:63
GraphicsOutput::count_textures
int count_textures() const
If the GraphicsOutput is set to render into a texture, returns the number of textures that are being ...
Definition: graphicsOutput.I:63
GraphicsOutput::get_fb_properties
const FrameBufferProperties & get_fb_properties() const
Returns the framebuffer properties of the window.
Definition: graphicsOutput.I:413
GraphicsOutput::get_texture_plane
RenderTexturePlane get_texture_plane(int i=0) const
Returns the RenderTexturePlane associated with the nth render-texture.
Definition: graphicsOutput.I:100
GraphicsOutput::set_size_and_recalc
void set_size_and_recalc(int x, int y)
Changes the x_size and y_size, then recalculates structures that depend on size.
Definition: graphicsOutput.cxx:1111
GraphicsOutput::get_y_size
int get_y_size() const
Returns the visible height of the window or buffer, if it is known.
Definition: graphicsOutput.I:159
GraphicsOutput::get_name
get_name
Returns the name that was passed to the GraphicsOutput constructor.
Definition: graphicsOutput.h:120
GraphicsOutput::get_x_size
int get_x_size() const
Returns the visible width of the window or buffer, if it is known.
Definition: graphicsOutput.I:145
GraphicsOutput::clear
virtual void clear(Thread *current_thread)
Clears the entire framebuffer before rendering, according to the settings of get_color_clear_active()...
Definition: graphicsOutput.cxx:1140
GraphicsOutput::get_texture
virtual Texture * get_texture(int i=0) const
Returns the nth texture into which the GraphicsOutput renders.
Definition: graphicsOutput.I:87
GraphicsPipe
An object to create GraphicsOutputs that share a particular 3-D API.
Definition: graphicsPipe.h:52
GraphicsStateGuardian
Encapsulates all the communication with a particular instance of a given rendering backend.
Definition: graphicsStateGuardian.h:65
TextureContext::get_texture
Texture * get_texture() const
Returns the pointer to the associated Texture object.
Definition: textureContext.I:29
Texture
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
Texture::get_format
get_format
Returns the format of the texture, which represents both the semantic meaning of the texels and,...
Definition: texture.h:370
Texture::prepare_now
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
Texture::get_texture_type
get_texture_type
Returns the overall interpretation of the texture.
Definition: texture.h:365
Texture::set_format
set_format
Changes the format value for the texture components.
Definition: texture.h:370
Texture::up_to_power_2
static int up_to_power_2(int value)
Returns the smallest power of 2 greater than or equal to value.
Definition: texture.cxx:2008
Texture::get_textures_power_2
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
Texture::set_size_padded
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
Thread
A thread; that is, a lightweight process.
Definition: thread.h:46
TypeHandle
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
WindowProperties
A container for the various kinds of properties we might ask to have on a graphics window before we o...
Definition: windowProperties.h:29
wdxGraphicsBuffer9
An offscreen render buffer.
Definition: wdxGraphicsBuffer9.h:29
wdxGraphicsBuffer9::unregister_shared_depth_buffer
void unregister_shared_depth_buffer(GraphicsOutput *graphics_output)
Unregister who is sharing the depth buffer.
Definition: wdxGraphicsBuffer9.cxx:888
wdxGraphicsBuffer9::unshare_depth_buffer
virtual void unshare_depth_buffer()
Discontinue sharing the depth buffer.
Definition: wdxGraphicsBuffer9.cxx:857
wdxGraphicsBuffer9::select_target_tex_page
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...
Definition: wdxGraphicsBuffer9.cxx:577
wdxGraphicsBuffer9::end_frame
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.
Definition: wdxGraphicsBuffer9.cxx:154
wdxGraphicsBuffer9::register_shared_depth_buffer
void register_shared_depth_buffer(GraphicsOutput *graphics_output)
Register/save who is sharing the depth buffer.
Definition: wdxGraphicsBuffer9.cxx:874
wdxGraphicsBuffer9::process_events
virtual void process_events()
Do whatever processing is necessary to ensure that the window responds to user events.
Definition: wdxGraphicsBuffer9.cxx:703
wdxGraphicsBuffer9::share_depth_buffer
virtual bool share_depth_buffer(GraphicsOutput *graphics_output)
Will attempt to use the depth buffer of the input graphics_output.
Definition: wdxGraphicsBuffer9.cxx:810
wdxGraphicsBuffer9::begin_frame
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.
Definition: wdxGraphicsBuffer9.cxx:123
dxGraphicsStateGuardian9.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
pStatTimer.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
wdxGraphicsBuffer9.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
wdxGraphicsPipe9.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.