From b4e6656f499ba106f8e022c75d8260ae92a943d6 Mon Sep 17 00:00:00 2001 From: David Rose Date: Wed, 4 Jan 2006 22:10:58 +0000 Subject: [PATCH] cleanly disable texturing before rendering to a texture --- panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx | 232 ++++++++++-------- panda/src/dxgsg9/dxGraphicsStateGuardian9.h | 2 + panda/src/dxgsg9/wdxGraphicsBuffer9.cxx | 7 +- 3 files changed, 130 insertions(+), 111 deletions(-) diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx index 8251bad8e1..3a62ef2e22 100755 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx @@ -3114,12 +3114,12 @@ do_issue_texture() { } else { LMatrix4f m = tex_mat->get_mat(); _d3d_device->SetTransform(get_tex_mat_sym(i), (D3DMATRIX *)m.get_data()); - DWORD transform_flags = texcoord_dimensions; - if (m.get_col(3) != LVecBase4f(0.0f, 0.0f, 0.0f, 1.0f)) { - // If we have a projected texture matrix, we also need to - // set D3DTTFF_COUNT4. - transform_flags = D3DTTFF_COUNT4 | D3DTTFF_PROJECTED; - } + DWORD transform_flags = texcoord_dimensions; + if (m.get_col(3) != LVecBase4f(0.0f, 0.0f, 0.0f, 1.0f)) { + // If we have a projected texture matrix, we also need to + // set D3DTTFF_COUNT4. + transform_flags = D3DTTFF_COUNT4 | D3DTTFF_PROJECTED; + } _d3d_device->SetTextureStageState(i, D3DTSS_TEXTURETRANSFORMFLAGS, transform_flags); } @@ -3137,9 +3137,119 @@ do_issue_texture() { // Disable the texture stages that are no longer used. for (i = num_stages; i < num_old_stages; i++) { _d3d_device->SetTextureStageState(i, D3DTSS_COLOROP, D3DTOP_DISABLE); + _d3d_device->SetTexture(i, NULL); } } +//////////////////////////////////////////////////////////////////// +// Function: DXGraphicsStateGuardian9::do_issue_blending +// Access: Protected, Virtual +// Description: Called after any of the things that might change +// blending state have changed, this function is +// responsible for setting the appropriate color +// blending mode based on the current properties. +//////////////////////////////////////////////////////////////////// +void DXGraphicsStateGuardian9:: +do_issue_blending() { + // Handle the color_write attrib. If color_write is off, then + // all the other blending-related stuff doesn't matter. If the + // device doesn't support color-write, we use blending tricks + // to effectively disable color write. + if (_target._color_write->get_channels() == ColorWriteAttrib::C_off) { + if (_target._color_write != _state._color_write) { + if (_screen->_can_direct_disable_color_writes) { + _d3d_device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + _d3d_device->SetRenderState(D3DRS_COLORWRITEENABLE, (DWORD)0x0); + } else { + _d3d_device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + _d3d_device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO); + _d3d_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE); + } + } + return; + } else { + if (_target._color_write != _state._color_write) { + if (_screen->_can_direct_disable_color_writes) { + _d3d_device->SetRenderState(D3DRS_COLORWRITEENABLE, _target._color_write->get_channels()); + } + } + } + + CPT(ColorBlendAttrib) color_blend = _target._color_blend; + ColorBlendAttrib::Mode color_blend_mode = _target._color_blend->get_mode(); + TransparencyAttrib::Mode transparency_mode = _target._transparency->get_mode(); + + // Is there a color blend set? + if (color_blend_mode != ColorBlendAttrib::M_none) { + _d3d_device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + + switch (color_blend_mode) { + case ColorBlendAttrib::M_add: + _d3d_device->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD); + break; + + case ColorBlendAttrib::M_subtract: + _d3d_device->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_SUBTRACT); + break; + + case ColorBlendAttrib::M_inv_subtract: + _d3d_device->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_REVSUBTRACT); + break; + + case ColorBlendAttrib::M_min: + _d3d_device->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_MIN); + break; + + case ColorBlendAttrib::M_max: + _d3d_device->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_MAX); + break; + } + + _d3d_device->SetRenderState(D3DRS_SRCBLEND, + get_blend_func(color_blend->get_operand_a())); + _d3d_device->SetRenderState(D3DRS_DESTBLEND, + get_blend_func(color_blend->get_operand_b())); + return; + } + + // No color blend; is there a transparency set? + switch (transparency_mode) { + case TransparencyAttrib::M_none: + case TransparencyAttrib::M_binary: + break; + + case TransparencyAttrib::M_alpha: + case TransparencyAttrib::M_multisample: + case TransparencyAttrib::M_multisample_mask: + case TransparencyAttrib::M_dual: + _d3d_device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + _d3d_device->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD); + _d3d_device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + _d3d_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + return; + + default: + dxgsg9_cat.error() + << "invalid transparency mode " << (int)transparency_mode << endl; + break; + } + + // Nothing's set, so disable blending. + _d3d_device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); +} + +//////////////////////////////////////////////////////////////////// +// Function: DXGraphicsStateGuardian9::disable_texturing +// Access: Protected +// Description: Turns off any texturing that is currently enabled. +//////////////////////////////////////////////////////////////////// +void DXGraphicsStateGuardian9:: +disable_texturing() { + _target._texture = DCAST(TextureAttrib, TextureAttrib::make_off()); + do_issue_texture(); + _state._texture = _target._texture; +} + //////////////////////////////////////////////////////////////////// // Function: DXGraphicsStateGuardian9::enable_lighting // Access: Protected, Virtual @@ -3236,104 +3346,6 @@ bind_clip_plane(const NodePath &plane, int plane_id) { } } -//////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian9::set_blend_mode -// Access: Protected, Virtual -// Description: Called after any of the things that might change -// blending state have changed, this function is -// responsible for setting the appropriate color -// blending mode based on the current properties. -//////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian9:: -do_issue_blending() { - - // Handle the color_write attrib. If color_write is off, then - // all the other blending-related stuff doesn't matter. If the - // device doesn't support color-write, we use blending tricks - // to effectively disable color write. - if (_target._color_write->get_channels() == ColorWriteAttrib::C_off) { - if (_target._color_write != _state._color_write) { - if (_screen->_can_direct_disable_color_writes) { - _d3d_device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - _d3d_device->SetRenderState(D3DRS_COLORWRITEENABLE, (DWORD)0x0); - } else { - _d3d_device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); - _d3d_device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO); - _d3d_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE); - } - } - return; - } else { - if (_target._color_write != _state._color_write) { - if (_screen->_can_direct_disable_color_writes) { - _d3d_device->SetRenderState(D3DRS_COLORWRITEENABLE, _target._color_write->get_channels()); - } - } - } - - CPT(ColorBlendAttrib) color_blend = _target._color_blend; - ColorBlendAttrib::Mode color_blend_mode = _target._color_blend->get_mode(); - TransparencyAttrib::Mode transparency_mode = _target._transparency->get_mode(); - - // Is there a color blend set? - if (color_blend_mode != ColorBlendAttrib::M_none) { - _d3d_device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); - - switch (color_blend_mode) { - case ColorBlendAttrib::M_add: - _d3d_device->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD); - break; - - case ColorBlendAttrib::M_subtract: - _d3d_device->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_SUBTRACT); - break; - - case ColorBlendAttrib::M_inv_subtract: - _d3d_device->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_REVSUBTRACT); - break; - - case ColorBlendAttrib::M_min: - _d3d_device->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_MIN); - break; - - case ColorBlendAttrib::M_max: - _d3d_device->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_MAX); - break; - } - - _d3d_device->SetRenderState(D3DRS_SRCBLEND, - get_blend_func(color_blend->get_operand_a())); - _d3d_device->SetRenderState(D3DRS_DESTBLEND, - get_blend_func(color_blend->get_operand_b())); - return; - } - - // No color blend; is there a transparency set? - switch (transparency_mode) { - case TransparencyAttrib::M_none: - case TransparencyAttrib::M_binary: - break; - - case TransparencyAttrib::M_alpha: - case TransparencyAttrib::M_multisample: - case TransparencyAttrib::M_multisample_mask: - case TransparencyAttrib::M_dual: - _d3d_device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); - _d3d_device->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD); - _d3d_device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); - _d3d_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); - return; - - default: - dxgsg9_cat.error() - << "invalid transparency mode " << (int)transparency_mode << endl; - break; - } - - // Nothing's set, so disable blending. - _d3d_device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); -} - //////////////////////////////////////////////////////////////////// // Function: DXGraphicsStateGuardian9::free_nondx_resources // Access: Public @@ -3359,14 +3371,18 @@ free_d3d_device() { _dx_is_ready = false; - if (_d3d_device != NULL) - for(int i = 0;iSetTexture(i, NULL); // d3d should release this stuff internally anyway, but whatever + if (_d3d_device != NULL) { + for(int i = 0; i < D3D_MAXTEXTURESTAGES; i++) { + // d3d should release this stuff internally anyway, but whatever + _d3d_device->SetTexture(i, NULL); + } + } release_all(); - if (_d3d_device != NULL) + if (_d3d_device != NULL) { RELEASE(_d3d_device, dxgsg9, "d3dDevice", RELEASE_DOWN_TO_ZERO); + } free_nondx_resources(); diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.h b/panda/src/dxgsg9/dxGraphicsStateGuardian9.h index fcfd937220..aeedb5aa51 100755 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.h +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.h @@ -137,6 +137,8 @@ protected: void do_issue_texture(); void do_issue_blending(); + void disable_texturing(); + virtual void enable_lighting(bool enable); virtual void set_ambient_light(const Colorf &color); virtual void enable_light(int light_id, bool enable); diff --git a/panda/src/dxgsg9/wdxGraphicsBuffer9.cxx b/panda/src/dxgsg9/wdxGraphicsBuffer9.cxx index bed79c7488..6486cc7570 100644 --- a/panda/src/dxgsg9/wdxGraphicsBuffer9.cxx +++ b/panda/src/dxgsg9/wdxGraphicsBuffer9.cxx @@ -158,9 +158,10 @@ DBG_S dxgsg9_cat.error ( ) << "wdxGraphicsBuffer9::begin_render_texture\n"; DBG_ direct_3d_texture = dx_texture_context9 -> _d3d_2d_texture; if (direct_3d_texture) { - -hr = dxgsg -> _d3d_device -> SetTexture (0, NULL); -hr = dxgsg -> _d3d_device -> SetTexture (1, NULL); + // Make sure texturing is fully disabled (and all of our + // textures are therefore unbound in the GSG) before we try + // to render to this texture. + dxgsg->disable_texturing(); hr = direct_3d_texture -> GetSurfaceLevel (mipmap_level, &_direct_3d_surface); if (SUCCEEDED (hr)) {