15 #include "wdxGraphicsPipe9.h"
16 #include "wdxGraphicsBuffer9.h"
17 #include "dxGraphicsStateGuardian9.h"
18 #include "pStatTimer.h"
21 #define FL << "\n" << __FILE__ << " " << __LINE__ << "\n"
39 GraphicsBuffer(engine, pipe, name, fb_prop, win_prop, flags, gsg, host)
43 _saved_color_buffer = NULL;
44 _saved_depth_buffer = NULL;
45 _color_backing_store = NULL;
46 _depth_backing_store = NULL;
51 _screenshot_buffer_type = _draw_buffer_type;
53 _shared_depth_buffer = 0;
58 cout <<
"+++++ wdxGraphicsBuffer9 constructor " <<
this <<
" " <<
this -> get_name ( ) <<
"\n";
68 dxgsg -> _graphics_buffer_list.push_back(_this);
78 ~wdxGraphicsBuffer9() {
81 cout <<
"----- wdxGraphicsBuffer9 destructor " <<
this <<
" " <<
this ->
get_name ( ) <<
"\n";
90 dxgsg -> _graphics_buffer_list.remove(_this);
103 list <wdxGraphicsBuffer9 *>::iterator graphics_buffer_iterator;
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) {
112 graphics_buffer_iterator = _shared_depth_buffer_list.begin( );
116 this -> close_buffer ( );
131 begin_frame_spam(mode);
135 if (_dxgsg -> _d3d_device == 0) {
139 if (mode == FM_render) {
140 if (!save_bitplanes()) {
143 if (!rebuild_bitplanes()) {
147 clear_cube_map_selection();
151 return _gsg->begin_frame(current_thread);
164 end_frame_spam(mode);
167 if (mode == FM_render) {
171 _gsg->end_frame(current_thread);
173 if (mode == FM_render) {
175 clear_cube_map_selection();
186 bool wdxGraphicsBuffer9::
189 DWORD render_target_index;
191 render_target_index = 0;
193 hr = _dxgsg -> _d3d_device -> GetRenderTarget (render_target_index, &_saved_color_buffer);
194 if (!SUCCEEDED (hr)) {
195 dxgsg9_cat.error ( ) <<
"GetRenderTarget " << D3DERRORSTRING(hr) FL;
199 _saved_depth_buffer = 0;
200 hr = _dxgsg -> _d3d_device -> GetDepthStencilSurface (&_saved_depth_buffer);
201 if (hr == D3DERR_NOTFOUND) {
205 if (!SUCCEEDED (hr)) {
206 dxgsg9_cat.error ( ) <<
"GetDepthStencilSurface " << D3DERRORSTRING(hr) FL;
220 restore_bitplanes() {
222 DCAST_INTO_V(dxgsg, _gsg);
225 DWORD render_target_index;
227 render_target_index = 0;
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;
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;
243 hr = _dxgsg -> _d3d_device -> SetRenderTarget (i, NULL);
244 if (!SUCCEEDED (hr)) {
245 dxgsg9_cat.error ( ) <<
"SetRenderTarget " << i <<
" " << D3DERRORSTRING(hr) FL;
249 _saved_color_buffer->Release();
250 if (_saved_depth_buffer) {
251 _saved_depth_buffer->Release();
253 _saved_color_buffer = NULL;
254 _saved_depth_buffer = NULL;
265 bool wdxGraphicsBuffer9::
266 rebuild_bitplanes() {
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;
280 render_target_index = 0;
284 if ((_host != 0)&&(_creation_flags & GraphicsPipe::BF_size_track_host)) {
285 if (_host->get_size() != _size) {
287 _host->get_y_size());
303 int color_tex_index = -1;
304 int depth_tex_index = -1;
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;
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:
331 CDWriter cdataw(_cycler, cdata,
false);
332 nassertr(cdata->_textures.size() == cdataw->_textures.size(),
false);
333 cdataw->_textures[i]._rtm_mode = RTM_none;
338 CDWriter cdataw(_cycler, cdata,
false);
339 nassertr(cdata->_textures.size() == cdataw->_textures.size(),
false);
340 cdataw->_textures[i]._rtm_mode = RTM_copy_texture;
348 if (color_tex_index < 0) {
350 if ((_color_backing_store)&&
351 ((bitplane_x != _backing_sizex)||(bitplane_y != _backing_sizey))) {
352 _color_backing_store->Release();
353 _color_backing_store = NULL;
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,
361 &_color_backing_store,
363 if (!SUCCEEDED(hr)) {
364 dxgsg9_cat.error ( ) <<
"CreateRenderTarget " << D3DERRORSTRING(hr) FL;
367 color_surf = _color_backing_store;
370 if (_color_backing_store) {
371 _color_backing_store->Release();
372 _color_backing_store = NULL;
379 color_tex->
prepare_now(0, _gsg->get_prepared_objects(), _gsg));
384 <<
"Unable to re-create texture " << *color_ctx->
get_texture() << endl;
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;
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);
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;
411 release_depth = true;
412 if (depth_tex_index < 0) {
413 if (_shared_depth_buffer) {
414 if (_shared_depth_buffer -> _depth_backing_store) {
416 printf (
"SHARE DEPTH BUFFER\n");
418 depth_surf = _shared_depth_buffer -> _depth_backing_store;
419 release_depth =
false;
422 if (depth_surf == 0) {
424 if ((_depth_backing_store)&&
425 ((bitplane_x != _backing_sizex)||(bitplane_y != _backing_sizey))) {
426 _depth_backing_store->Release();
427 _depth_backing_store = NULL;
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;
438 depth_surf = _depth_backing_store;
442 if (_depth_backing_store) {
443 _depth_backing_store->Release();
444 _depth_backing_store = NULL;
447 if (_shared_depth_buffer) {
448 depth_tex = _shared_depth_buffer ->
get_texture(depth_tex_index);
450 if (depth_tex == 0) {
455 depth_tex->
set_format(Texture::F_depth_stencil);
458 depth_tex->
prepare_now(0, _gsg->get_prepared_objects(), _gsg));
462 <<
"Unable to re-create texture " << *depth_ctx->
get_texture() << endl;
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;
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;
484 _backing_sizex = bitplane_x;
485 _backing_sizey = bitplane_y;
489 hr = _dxgsg -> _d3d_device -> SetRenderTarget (render_target_index, color_surf);
490 if (!SUCCEEDED (hr)) {
491 dxgsg9_cat.error ( ) <<
"SetRenderTarget " << D3DERRORSTRING(hr) FL;
496 hr = _dxgsg -> _d3d_device -> SetDepthStencilSurface (depth_surf);
497 if (!SUCCEEDED (hr)) {
498 dxgsg9_cat.error ( ) <<
"SetDepthStencilSurface " << D3DERRORSTRING(hr) FL;
502 render_target_index = 1;
503 for (
int i=0; i<count_textures(); i++) {
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:
529 IDirect3DTexture9 *color_d3d_tex = 0;
530 IDirect3DSurface9 *color_surf = 0;
531 IDirect3DCubeTexture9 *color_cube = 0;
537 <<
"Unable to re-create texture " << *color_ctx->
get_texture() << endl;
541 color_d3d_tex = color_ctx->_d3d_2d_texture;
542 nassertr(color_d3d_tex != 0,
false);
544 hr = color_d3d_tex -> GetSurfaceLevel(0, &color_surf);
545 if (!SUCCEEDED(hr)) {
546 dxgsg9_cat.error ( ) <<
"GetSurfaceLevel " << D3DERRORSTRING(hr) FL;
549 hr = _dxgsg -> _d3d_device -> SetRenderTarget (render_target_index, color_surf);
550 if (SUCCEEDED (hr)) {
551 render_target_index++;
553 dxgsg9_cat.error ( ) <<
"SetRenderTarget " << render_target_index <<
" " << D3DERRORSTRING(hr) FL;
555 color_surf->Release();
570 if ((color_surf != 0)&&(color_surf != _color_backing_store)) {
571 color_surf->Release();
575 if ((depth_surf != 0)&&(depth_surf != _depth_backing_store)) {
576 depth_surf->Release();
595 DWORD render_target_index;
597 render_target_index = 0;
599 _cube_map_index = page;
604 IDirect3DCubeTexture9 *color_cube = 0;
605 IDirect3DSurface9 *color_surf = 0;
606 int color_tex_index = -1;
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) {
615 if ((tex->
get_format() != Texture::F_depth_stencil)&&
616 (tex->
get_format() != Texture::F_depth_component)&&
617 (color_tex_index < 0)) {
620 CDWriter cdataw(_cycler, cdata,
false);
621 nassertv(cdata->_textures.size() == cdataw->_textures.size());
622 cdataw->_textures[i]._rtm_mode = RTM_copy_texture;
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;
640 hr = _dxgsg -> _d3d_device -> SetRenderTarget (render_target_index, color_surf);
641 if (!SUCCEEDED (hr)) {
642 dxgsg9_cat.error ( ) <<
"SetRenderTarget " << D3DERRORSTRING(hr) FL;
645 color_surf->Release();
650 render_target_index = 1;
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:
673 IDirect3DSurface9 *color_surf = 0;
674 IDirect3DCubeTexture9 *color_cube = 0;
681 printf (
"CUBEMAP i = %d, RenderTexturePlane = %d, _cube_map_index %d \n", i, plane, _cube_map_index);
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;
691 hr = _dxgsg -> _d3d_device -> SetRenderTarget (render_target_index, color_surf);
692 if (SUCCEEDED (hr)) {
693 render_target_index++;
695 dxgsg9_cat.error ( ) <<
"cube map SetRenderTarget " << render_target_index <<
" " << D3DERRORSTRING(hr) FL;
697 color_surf->Release();
730 while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) {
741 void wdxGraphicsBuffer9::
744 if (_color_backing_store) {
745 _color_backing_store->Release();
746 _color_backing_store = NULL;
748 if (_depth_backing_store) {
749 _depth_backing_store->Release();
750 _depth_backing_store = NULL;
753 _cube_map_index = -1;
764 bool wdxGraphicsBuffer9::
776 DCAST_INTO_R(_dxgsg, _gsg,
false);
778 if (!save_bitplanes()) {
783 hr = _saved_color_buffer -> GetDesc (&_saved_color_desc);
784 if (!SUCCEEDED (hr)) {
785 dxgsg9_cat.error ( ) <<
"GetDesc " << D3DERRORSTRING(hr) FL;
788 hr = _saved_depth_buffer -> GetDesc (&_saved_depth_desc);
789 if (!SUCCEEDED (hr)) {
790 dxgsg9_cat.error ( ) <<
"GetDesc " << D3DERRORSTRING(hr) FL;
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);
801 if (!rebuild_bitplanes()) {
815 void wdxGraphicsBuffer9::
819 if (!GetMessage(&msg, NULL, 0, 0)) {
826 TranslateMessage(&msg);
828 DispatchMessage(&msg);
849 if (
this != input_graphics_output && input_graphics_output) {
855 printf (
"share_depth_buffer\n");
861 printf (
"ERROR: share_depth_buffer: non matching width \n");
868 printf (
"ERROR: share_depth_buffer: non matching height \n");
877 _shared_depth_buffer = input_graphics_output;
892 if (_shared_depth_buffer) {
894 printf (
"wdxGraphicsBuffer9 unshare_depth_buffer \n");
900 _shared_depth_buffer = 0;
914 if (input_graphics_output) {
916 _shared_depth_buffer_list.push_back(input_graphics_output);
930 if (input_graphics_output) {
932 _shared_depth_buffer_list.remove(input_graphics_output);
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...
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-...
void set_format(Format format)
Changes the format value for the texture components.
bool create_texture(DXScreenData &scrn)
Use panda texture's pixelbuffer to create a texture for the specified device.
virtual void select_target_tex_page(int page)
Called internally when the window is in render-to-a-texture mode and we are in the process of renderi...
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...
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...
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.
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.
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.
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.
A thread; that is, a lightweight process.
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.
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.