From cd3a6ec5a812a4582181978370b68ce6a732b8e3 Mon Sep 17 00:00:00 2001 From: David Rose Date: Tue, 10 Oct 2006 21:15:33 +0000 Subject: [PATCH] add alpha-scale-via-texture to dx8/9, also hack around lack of depthbias support on certain dx9 drivers --- panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx | 52 ++++++--- panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx | 107 ++++++++++++------ panda/src/dxgsg9/dxGraphicsStateGuardian9.h | 5 +- .../glstuff/glGraphicsStateGuardian_src.cxx | 4 - 4 files changed, 110 insertions(+), 58 deletions(-) diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx index 47b3ec2bf3..ee7b6c2e44 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx @@ -2234,16 +2234,6 @@ set_state_and_transform(const RenderState *target, _state._shader = _target._shader; } - if (_target._tex_gen != _state._tex_gen) { - _state._texture = 0; - _state._tex_gen = _target._tex_gen; - } - - if (_target._tex_matrix != _state._tex_matrix) { - _state._texture = 0; - _state._tex_matrix = _target._tex_matrix; - } - if ((_target._transparency != _state._transparency)|| (_target._color_write != _state._color_write)|| (_target._color_blend != _state._color_blend)) { @@ -2253,9 +2243,17 @@ set_state_and_transform(const RenderState *target, _state._color_blend = _target._color_blend; } - if (_target._texture != _state._texture) { + if (_target._tex_matrix != _state._tex_matrix) { + _state._texture = 0; + _state._tex_matrix = _target._tex_matrix; + } + + if (_target._texture != _state._texture || + _target._tex_gen != _state._tex_gen) { + determine_effective_texture(); do_issue_texture(); _state._texture = _target._texture; + _state._tex_gen = _target._tex_gen; } if (_target._material != _state._material) { @@ -2516,7 +2514,7 @@ void DXGraphicsStateGuardian8:: do_issue_texture() { DO_PSTATS_STUFF(_texture_state_pcollector.add_level(1)); - int num_stages = _target._texture->get_num_on_stages(); + int num_stages = _effective_texture->get_num_on_stages(); int num_old_stages = _max_texture_stages; if (_state._texture != (TextureAttrib *)NULL) { num_old_stages = _state._texture->get_num_on_stages(); @@ -2537,8 +2535,8 @@ do_issue_texture() { int i; for (i = 0; i < num_stages; i++) { - TextureStage *stage = _target._texture->get_on_stage(i); - Texture *texture = _target._texture->get_on_texture(stage); + TextureStage *stage = _effective_texture->get_on_stage(i); + Texture *texture = _effective_texture->get_on_texture(stage); nassertv(texture != (Texture *)NULL); const InternalName *name = stage->get_texcoord_name(); @@ -2564,7 +2562,7 @@ do_issue_texture() { } // Issue the texgen mode. - TexGenAttrib::Mode mode = _state._tex_gen->get_mode(stage); + TexGenAttrib::Mode mode = _effective_tex_gen->get_mode(stage); bool any_point_sprite = false; switch (mode) { @@ -2656,6 +2654,30 @@ do_issue_texture() { _d3d_device->SetTextureStageState(i, D3DTSS_TEXCOORDINDEX, texcoord_index); any_point_sprite = true; break; + + case TexGenAttrib::M_constant: + // To generate a constant UV(w) coordinate everywhere, we use + // CAMERASPACEPOSITION coordinates, but we construct a special + // matrix that flattens the existing values to zero and then + // adds our desired value. + + // The only reason we need to specify CAMERASPACEPOSITION at + // all, instead of using whatever texture coordinates (if any) + // happen to be on the vertices, is because we need to guarantee + // that there are 3-d texture coordinates, because of the + // 3-component texture coordinate in get_constant_value(). + { + _d3d_device->SetTextureStageState(i, D3DTSS_TEXCOORDINDEX, + texcoord_index | D3DTSS_TCI_CAMERASPACEPOSITION); + texcoord_dimensions = 3; + + const TexCoord3f &v = _effective_tex_gen->get_constant_value(stage); + CPT(TransformState) squash = + TransformState::make_pos_hpr_scale(v, LVecBase3f::zero(), + LVecBase3f::zero()); + tex_mat = tex_mat->compose(squash); + } + break; } _d3d_device->SetRenderState(D3DRS_POINTSPRITEENABLE, any_point_sprite); diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx index c6c9bab3da..6006497919 100755 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx @@ -793,11 +793,12 @@ prepare_display_region(DisplayRegionPipelineReader *dr, int l, u, w, h; dr->get_region_pixels_i(l, u, w, h); - DBG_S dxgsg9_cat.debug ( ) << "display_region " << l << " " << u << " " << w << " " << h << "\n"; DBG_E + DBG_S dxgsg9_cat.debug ( ) << "display_region " << l << " " << u << " " << w << " " << h << "\n"; DBG_E; // Create the viewport D3DVIEWPORT9 vp = { l, u, w, h, 0.0f, 1.0f }; - HRESULT hr = _d3d_device->SetViewport(&vp); + _current_viewport = vp; + HRESULT hr = _d3d_device->SetViewport(&_current_viewport); if (FAILED(hr)) { dxgsg9_cat.error() << "_screen->_swap_chain = " << _screen->_swap_chain << " _swap_chain = " << _swap_chain << "\n"; @@ -2426,6 +2427,8 @@ reset() { _supports_stencil_wrap = (d3d_caps.StencilCaps & D3DSTENCILCAPS_INCR) && (d3d_caps.StencilCaps & D3DSTENCILCAPS_DECR); _supports_two_sided_stencil = ((d3d_caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) != 0); + _supports_depth_bias = ((d3d_caps.RasterCaps & D3DPRASTERCAPS_DEPTHBIAS) != 0); + if (dxgsg9_cat.is_debug()) { dxgsg9_cat.debug() << "\nHwTransformAndLight = " << ((d3d_caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) != 0) @@ -2448,6 +2451,8 @@ reset() { << "\nD3DTEXOPCAPS_MULTIPLYADD = " << ((d3d_caps.TextureOpCaps & D3DTEXOPCAPS_MULTIPLYADD) != 0) << "\nD3DTEXOPCAPS_LERP = " << ((d3d_caps.TextureOpCaps & D3DTEXOPCAPS_LERP) != 0) << "\nD3DPMISCCAPS_TSSARGTEMP = " << ((d3d_caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP) != 0) + << "\nD3DPRASTERCAPS_DEPTHBIAS = " << ((d3d_caps.RasterCaps & D3DPRASTERCAPS_DEPTHBIAS) != 0) + << "\nD3DPRASTERCAPS_SLOPESCALEDEPTHBIAS = " << ((d3d_caps.RasterCaps & D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS) != 0) << "\nVertexShaderVersion = " << _vertex_shader_version_major << "." << _vertex_shader_version_minor << "\nPixelShaderVersion = " << _pixel_shader_version_major << "." << _pixel_shader_version_minor << "\nMaxVertexShaderConst = " << _vertex_shader_maximum_constants @@ -2491,9 +2496,21 @@ reset() { vertex_profile = cgD3D9GetLatestVertexProfile( ); pixel_profile = cgD3D9GetLatestPixelProfile( ); + const char *vertex_profile_str = + cgGetProfileString(vertex_profile); + const char *pixel_profile_str = + cgGetProfileString(pixel_profile); + + if (vertex_profile_str == NULL) { + vertex_profile_str = "(null)"; + } + if (pixel_profile_str == NULL) { + pixel_profile_str = "(null)"; + } + dxgsg9_cat.debug() - << "\nCg vertex profile = " << cgGetProfileString(vertex_profile) << " id = " << vertex_profile - << "\nCg pixel profile = " << cgGetProfileString(pixel_profile) << " id = " << pixel_profile + << "\nCg vertex profile = " << vertex_profile_str << " id = " << vertex_profile + << "\nCg pixel profile = " << pixel_profile_str << " id = " << pixel_profile << "\nshader model = " << _shader_model << "\n"; } @@ -3126,9 +3143,19 @@ do_issue_depth_offset() { const DepthOffsetAttrib *attrib = _target._depth_offset; int offset = attrib->get_offset(); -/* ***** DX9 ??? D3DRS_ZBIAS NOT IN DX9 ??? RENAMED D3DRS_DEPTHBIAS ??? */ - set_render_state(D3DRS_DEPTHBIAS, offset); + if (_supports_depth_bias) { + set_render_state(D3DRS_DEPTHBIAS, offset); + } else { + // DirectX depth bias isn't directly supported by the driver. + // Cheese a depth bias effect by sliding the viewport backward a + // bit. + static const float bias_scale = 0.0001; + D3DVIEWPORT9 vp = _current_viewport; + vp.MinZ -= bias_scale * offset; + vp.MaxZ -= bias_scale * offset; + _d3d_device->SetViewport(&vp); + } } //////////////////////////////////////////////////////////////////// @@ -3192,10 +3219,6 @@ set_state_and_transform(const RenderState *target, target->store_into_slots(&_target); _state_rs = 0; - // There might be some physical limits to the actual target - // attributes we issue. Impose them now. - _target._texture = _target._texture->filter_to_max(_max_texture_stages); - if (_target._alpha_test != _state._alpha_test) { do_issue_alpha_test(); _state._alpha_test = _target._alpha_test; @@ -3261,16 +3284,6 @@ set_state_and_transform(const RenderState *target, _state._shade_model = _target._shade_model; } - if (_target._tex_gen != _state._tex_gen) { - _state._texture = 0; - _state._tex_gen = _target._tex_gen; - } - - if (_target._tex_matrix != _state._tex_matrix) { - _state._texture = 0; - _state._tex_matrix = _target._tex_matrix; - } - if ((_target._transparency != _state._transparency)|| (_target._color_write != _state._color_write)|| (_target._color_blend != _state._color_blend)) { @@ -3286,9 +3299,17 @@ set_state_and_transform(const RenderState *target, _state._texture = 0; } - if (_target._texture != _state._texture) { + if (_target._tex_matrix != _state._tex_matrix) { + _state._texture = 0; + _state._tex_matrix = _target._tex_matrix; + } + + if (_target._texture != _state._texture || + _target._tex_gen != _state._tex_gen) { + determine_effective_texture(); do_issue_texture(); _state._texture = _target._texture; + _state._tex_gen = _target._tex_gen; } if (_target._material != _state._material) { @@ -3605,7 +3626,7 @@ void DXGraphicsStateGuardian9:: update_standard_texture_bindings() { DO_PSTATS_STUFF(_texture_state_pcollector.add_level(1)); - int num_stages = _target._texture->get_num_on_stages(); + int num_stages = _effective_texture->get_num_on_stages(); int num_old_stages = _max_texture_stages; if (_state._texture != (TextureAttrib *)NULL) { num_old_stages = _state._texture->get_num_on_stages(); @@ -3626,8 +3647,8 @@ update_standard_texture_bindings() { int i; for (i = 0; i < num_stages; i++) { - TextureStage *stage = _target._texture->get_on_stage(i); - Texture *texture = _target._texture->get_on_texture(stage); + TextureStage *stage = _effective_texture->get_on_stage(i); + Texture *texture = _effective_texture->get_on_texture(stage); nassertv(texture != (Texture *)NULL); const InternalName *name = stage->get_texcoord_name(); @@ -3653,7 +3674,7 @@ update_standard_texture_bindings() { } // Issue the texgen mode. - TexGenAttrib::Mode mode = _state._tex_gen->get_mode(stage); + TexGenAttrib::Mode mode = _effective_tex_gen->get_mode(stage); bool any_point_sprite = false; switch (mode) { @@ -3745,6 +3766,30 @@ update_standard_texture_bindings() { set_texture_stage_state(i, D3DTSS_TEXCOORDINDEX, texcoord_index); any_point_sprite = true; break; + + case TexGenAttrib::M_constant: + // To generate a constant UV(w) coordinate everywhere, we use + // CAMERASPACEPOSITION coordinates, but we construct a special + // matrix that flattens the existing values to zero and then + // adds our desired value. + + // The only reason we need to specify CAMERASPACEPOSITION at + // all, instead of using whatever texture coordinates (if any) + // happen to be on the vertices, is because we need to guarantee + // that there are 3-d texture coordinates, because of the + // 3-component texture coordinate in get_constant_value(). + { + set_texture_stage_state(i, D3DTSS_TEXCOORDINDEX, + texcoord_index | D3DTSS_TCI_CAMERASPACEPOSITION); + texcoord_dimensions = 3; + + const TexCoord3f &v = _effective_tex_gen->get_constant_value(stage); + CPT(TransformState) squash = + TransformState::make_pos_hpr_scale(v, LVecBase3f::zero(), + LVecBase3f::zero()); + tex_mat = tex_mat->compose(squash); + } + break; } set_render_state(D3DRS_POINTSPRITEENABLE, any_point_sprite); @@ -3889,18 +3934,6 @@ do_issue_blending() { set_render_state(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 diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.h b/panda/src/dxgsg9/dxGraphicsStateGuardian9.h index 2aa179056f..a4764c200a 100755 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.h +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.h @@ -178,8 +178,6 @@ protected: void do_issue_blending(); void do_issue_stencil(); - 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); @@ -285,6 +283,9 @@ protected: }; DxgsgFogType _do_fog_type; + D3DVIEWPORT9 _current_viewport; + bool _supports_depth_bias; + DWORD _clip_plane_bits; CullFaceAttrib::Mode _cull_face_mode; RenderModeAttrib::Mode _current_fill_mode; //point/wireframe/solid diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 6ec756c3b3..180db9a644 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -5592,10 +5592,6 @@ set_state_and_transform(const RenderState *target, target->store_into_slots(&_target); _state_rs = 0; - // There might be some physical limits to the actual target - // attributes we issue. Impose them now. - _target._texture = _target._texture->filter_to_max(_max_texture_stages); - if (_target._alpha_test != _state._alpha_test) { do_issue_alpha_test(); _state._alpha_test = _target._alpha_test;