diff --git a/panda/src/dxgsg/dxGraphicsStateGuardian.I b/panda/src/dxgsg/dxGraphicsStateGuardian.I index e67688a1d3..92ed351fc3 100644 --- a/panda/src/dxgsg/dxGraphicsStateGuardian.I +++ b/panda/src/dxgsg/dxGraphicsStateGuardian.I @@ -186,54 +186,54 @@ call_dxLightModelAmbient( const Colorf& color) } } - //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::call_glAlphaFunc +// Function: DXGraphicsStateGuardian::call_dxAlphaFunc // Access: // Description: //////////////////////////////////////////////////////////////////// INLINE void DXGraphicsStateGuardian:: -call_dxAlphaFunc(D3DCMPFUNC func, DWORD ref) -{ - if (_alpha_func != func || _alpha_func_ref != ref) { +call_dxAlphaFunc(D3DCMPFUNC func, float reference_alpha) { + if (_alpha_func != func) { _alpha_func = func; - _alpha_func_ref = ref; #ifdef GSG_VERBOSE dxgsg_cat.debug() << "dxAlphaFunc("; switch (func) { case D3DCMP_NEVER: - dxgsg_cat.debug(false) << "D3DCMP_NEVER, "; + dxgsg_cat.debug(false) << "D3DCMP_NEVER"; break; case D3DCMP_LESS: - dxgsg_cat.debug(false) << "D3DCMP_LESS, "; + dxgsg_cat.debug(false) << "D3DCMP_LESS"; break; case D3DCMP_EQUAL: - dxgsg_cat.debug(false) << "D3DCMP_EQUAL, "; + dxgsg_cat.debug(false) << "D3DCMP_EQUAL"; break; case D3DCMP_LEQUAL: - dxgsg_cat.debug(false) << "D3DCMP_LEQUAL, "; + dxgsg_cat.debug(false) << "D3DCMP_LEQUAL"; break; case D3DCMP_GREATER: - dxgsg_cat.debug(false) << "D3DCMP_GREATER, "; + dxgsg_cat.debug(false) << "D3DCMP_GREATER"; break; case D3DCMP_NOTEQUAL: - dxgsg_cat.debug(false) << "D3DCMP_NOTEQUAL, "; + dxgsg_cat.debug(false) << "D3DCMP_NOTEQUAL"; break; case D3DCMP_GEQUAL: - dxgsg_cat.debug(false) << "D3DCMP_GEQUAL, "; + dxgsg_cat.debug(false) << "D3DCMP_GEQUAL"; break; case D3DCMP_ALWAYS: - dxgsg_cat.debug(false) << "D3DCMP_ALWAYS, "; + dxgsg_cat.debug(false) << "D3DCMP_ALWAYS"; break; } - dxgsg_cat.debug() << ref << ")" << endl; + dxgsg_cat.debug() << " , " << reference_alpha << ")" << endl; #endif scrn.pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHAFUNC, func); - scrn.pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHAREF, ref); + } + + if(_alpha_func_refval != reference_alpha) { + _alpha_func_refval = reference_alpha; + scrn.pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHAREF, (UINT) (reference_alpha*255.0f)); //d3d uses 0x0-0xFF, not a float } } - INLINE void DXGraphicsStateGuardian:: call_dxBlendFunc(D3DBLEND sfunc, D3DBLEND dfunc ) { diff --git a/panda/src/dxgsg/dxGraphicsStateGuardian.cxx b/panda/src/dxgsg/dxGraphicsStateGuardian.cxx index 16f05e34a9..7e08dd01f7 100644 --- a/panda/src/dxgsg/dxGraphicsStateGuardian.cxx +++ b/panda/src/dxgsg/dxGraphicsStateGuardian.cxx @@ -36,6 +36,7 @@ #include "lightAttrib.h" #include "cullFaceAttrib.h" #include "transparencyAttrib.h" +#include "alphaTestAttrib.h" #include "depthTestAttrib.h" #include "depthWriteAttrib.h" #include "colorWriteAttrib.h" @@ -802,9 +803,9 @@ dx_init( void) { #endif _alpha_func = D3DCMP_ALWAYS; - _alpha_func_ref = 0; + _alpha_func_refval = 1.0f; scrn.pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHAFUNC, _alpha_func); - scrn.pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHAREF, _alpha_func_ref); + scrn.pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHAREF, _alpha_func_refval); _alpha_test_enabled = false; scrn.pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHATESTENABLE, _alpha_test_enabled); @@ -4136,14 +4137,31 @@ issue_texture_apply(const TextureApplyAttrib *attrib) { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: issue_depth_test(const DepthTestAttrib *attrib) { - DepthTestAttrib::Mode mode = attrib->get_mode(); + DepthTestAttrib::PandaCompareFunc mode = attrib->get_mode(); if (mode == DepthTestAttrib::M_none) { _depth_test_enabled = false; scrn.pD3DDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, D3DZB_FALSE); } else { _depth_test_enabled = true; scrn.pD3DDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, D3DZB_TRUE); - scrn.pD3DDevice->SetRenderState(D3DRENDERSTATE_ZFUNC, get_depth_func_type(mode)); + scrn.pD3DDevice->SetRenderState(D3DRENDERSTATE_ZFUNC, (D3DCMPFUNC) mode); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: DXGraphicsStateGuardian::issue_alpha_test +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +void DXGraphicsStateGuardian:: +issue_alpha_test(const AlphaTestAttrib *attrib) { + AlphaTestAttrib::PandaCompareFunc mode = attrib->get_mode(); + if (mode == AlphaTestAttrib::M_none) { + enable_alpha_test(false); + } else { + // AlphaTestAttrib::PandaCompareFunc === D3DCMPFUNC + call_dxAlphaFunc((D3DCMPFUNC)mode, attrib->get_reference_alpha()); + enable_alpha_test(true); } } @@ -4422,6 +4440,9 @@ end_frame() { WRITE_FPS_UV(uval2,0.0f); WRITE_FPS_UV(uval1,0.0f); } + + // dont have to muck with World Transform since D3DFVF_XYZRHW type bypasses it + // Just deals with current ProjectMat tho // is this blending fn expensive? if so, can just overwrite everything @@ -4793,28 +4814,6 @@ get_texture_wrap_mode(Texture::WrapMode wm) const { return D3DTADDRESS_WRAP; } -//////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::get_depth_func_type -// Access: Protected -// Description: Maps from the depth func modes to gl version -//////////////////////////////////////////////////////////////////// -INLINE D3DCMPFUNC DXGraphicsStateGuardian:: -get_depth_func_type(DepthTestAttrib::Mode m) const { - switch (m) { - case DepthTestAttrib::M_never: return D3DCMP_NEVER; - case DepthTestAttrib::M_less: return D3DCMP_LESS; - case DepthTestAttrib::M_equal: return D3DCMP_EQUAL; - case DepthTestAttrib::M_less_equal: return D3DCMP_LESSEQUAL; - case DepthTestAttrib::M_greater: return D3DCMP_GREATER; - case DepthTestAttrib::M_not_equal: return D3DCMP_NOTEQUAL; - case DepthTestAttrib::M_greater_equal: return D3DCMP_GREATEREQUAL; - case DepthTestAttrib::M_always: return D3DCMP_ALWAYS; - } - dxgsg_cat.error() - << "Invalid DepthTestAttrib::Mode value" << endl; - return D3DCMP_LESS; -} - //////////////////////////////////////////////////////////////////// // Function: DXGraphicsStateGuardian::get_fog_mode_type // Access: Protected diff --git a/panda/src/dxgsg/dxGraphicsStateGuardian.h b/panda/src/dxgsg/dxGraphicsStateGuardian.h index c097089e1b..88f84761d9 100644 --- a/panda/src/dxgsg/dxGraphicsStateGuardian.h +++ b/panda/src/dxgsg/dxGraphicsStateGuardian.h @@ -116,6 +116,7 @@ public: virtual void issue_material(const MaterialAttrib *attrib); virtual void issue_render_mode(const RenderModeAttrib *attrib); virtual void issue_texture_apply(const TextureApplyAttrib *attrib); + virtual void issue_alpha_test(const AlphaTestAttrib *attrib); virtual void issue_depth_test(const DepthTestAttrib *attrib); virtual void issue_depth_write(const DepthWriteAttrib *attrib); virtual void issue_cull_face(const CullFaceAttrib *attrib); @@ -205,7 +206,6 @@ protected: INLINE void set_shademode(D3DSHADEMODE val); INLINE D3DTEXTUREADDRESS get_texture_wrap_mode(Texture::WrapMode wm) const; - INLINE D3DCMPFUNC get_depth_func_type(DepthTestAttrib::Mode m) const; INLINE D3DFOGMODE get_fog_mode_type(Fog::Mode m) const; INLINE void enable_primitive_clipping(bool val); @@ -215,7 +215,7 @@ protected: INLINE void enable_point_smooth(bool val); INLINE void enable_texturing(bool val); INLINE void call_dxLightModelAmbient(const Colorf& color); - INLINE void call_dxAlphaFunc(D3DCMPFUNC func, DWORD ref); + INLINE void call_dxAlphaFunc(D3DCMPFUNC func, float ref); INLINE void call_dxBlendFunc(D3DBLEND sfunc, D3DBLEND dfunc); INLINE void enable_dither(bool val); INLINE void enable_stencil_test(bool val); @@ -277,7 +277,7 @@ protected: TODO: cache fog state float _fog_start,_fog_end,_fog_density,float _fog_color; */ - float _alpha_func_ref; + float _alpha_func_refval; D3DCMPFUNC _alpha_func; D3DBLEND _blend_source_func; diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.I b/panda/src/dxgsg8/dxGraphicsStateGuardian8.I index f2e58337d7..d1513a4f6e 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.I +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.I @@ -264,48 +264,50 @@ call_dxLightModelAmbient( const Colorf& color) //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::call_glAlphaFunc +// Function: DXGraphicsStateGuardian::call_dxAlphaFunc // Access: // Description: //////////////////////////////////////////////////////////////////// INLINE void DXGraphicsStateGuardian:: -call_dxAlphaFunc(D3DCMPFUNC func, DWORD ref) -{ - if (_alpha_func != func || _alpha_func_ref != ref) { +call_dxAlphaFunc(D3DCMPFUNC func, float reference_alpha) { + if (_alpha_func != func) { _alpha_func = func; - _alpha_func_ref = ref; #ifdef GSG_VERBOSE dxgsg_cat.debug() << "dxAlphaFunc("; switch (func) { case D3DCMP_NEVER: - dxgsg_cat.debug(false) << "D3DCMP_NEVER, "; + dxgsg_cat.debug(false) << "D3DCMP_NEVER"; break; case D3DCMP_LESS: - dxgsg_cat.debug(false) << "D3DCMP_LESS, "; + dxgsg_cat.debug(false) << "D3DCMP_LESS"; break; case D3DCMP_EQUAL: - dxgsg_cat.debug(false) << "D3DCMP_EQUAL, "; + dxgsg_cat.debug(false) << "D3DCMP_EQUAL"; break; case D3DCMP_LEQUAL: - dxgsg_cat.debug(false) << "D3DCMP_LEQUAL, "; + dxgsg_cat.debug(false) << "D3DCMP_LEQUAL"; break; case D3DCMP_GREATER: - dxgsg_cat.debug(false) << "D3DCMP_GREATER, "; + dxgsg_cat.debug(false) << "D3DCMP_GREATER"; break; case D3DCMP_NOTEQUAL: - dxgsg_cat.debug(false) << "D3DCMP_NOTEQUAL, "; + dxgsg_cat.debug(false) << "D3DCMP_NOTEQUAL"; break; case D3DCMP_GEQUAL: - dxgsg_cat.debug(false) << "D3DCMP_GEQUAL, "; + dxgsg_cat.debug(false) << "D3DCMP_GEQUAL"; break; case D3DCMP_ALWAYS: - dxgsg_cat.debug(false) << "D3DCMP_ALWAYS, "; + dxgsg_cat.debug(false) << "D3DCMP_ALWAYS"; break; } - dxgsg_cat.debug() << ref << ")" << endl; + dxgsg_cat.debug() << " , " << reference_alpha << ")" << endl; #endif scrn.pD3DDevice->SetRenderState(D3DRS_ALPHAFUNC, func); - scrn.pD3DDevice->SetRenderState(D3DRS_ALPHAREF, ref); + } + + if(_alpha_func_refval != reference_alpha) { + _alpha_func_refval = reference_alpha; + scrn.pD3DDevice->SetRenderState(D3DRS_ALPHAREF, (UINT) (reference_alpha*255.0f)); //d3d uses 0x0-0xFF, not a float } } diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx index bf4289b382..44ce8d2562 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx @@ -36,6 +36,7 @@ #include "lightAttrib.h" #include "cullFaceAttrib.h" #include "transparencyAttrib.h" +#include "alphaTestAttrib.h" #include "depthTestAttrib.h" #include "depthWriteAttrib.h" #include "colorWriteAttrib.h" @@ -841,14 +842,14 @@ dx_init(HCURSOR hMouseCursor) { #endif _alpha_func = D3DCMP_ALWAYS; - _alpha_func_ref = 0; + _alpha_func_refval = 1.0f; scrn.pD3DDevice->SetRenderState(D3DRS_ALPHAFUNC, _alpha_func); - scrn.pD3DDevice->SetRenderState(D3DRS_ALPHAREF, _alpha_func_ref); + scrn.pD3DDevice->SetRenderState(D3DRS_ALPHAREF, (UINT)(_alpha_func_refval*255.0f)); _alpha_test_enabled = false; scrn.pD3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, _alpha_test_enabled); // this is a new DX8 state that lets you do additional operations other than ADD (e.g. subtract/max/min) - // must check (scrn.d3dcaps.PrimitiveMiscCaps & D3DPMISCCAPS_BLENDOP) (yes on GF2/Radeon85, no on TNT) + // must check (scrn.d3dcaps.PrimitiveMiscCaps & D3DPMISCCAPS_BLENDOP) (yes on GF2/Radeon8500, no on TNT) scrn.pD3DDevice->SetRenderState(D3DRS_BLENDOP,D3DBLENDOP_ADD); if((scrn.pProps->_fullscreen) && dx_use_dx_cursor) { @@ -3763,14 +3764,31 @@ issue_texture_apply(const TextureApplyAttrib *attrib) { //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian:: issue_depth_test(const DepthTestAttrib *attrib) { - DepthTestAttrib::Mode mode = attrib->get_mode(); + DepthTestAttrib::PandaCompareFunc mode = attrib->get_mode(); if (mode == DepthTestAttrib::M_none) { _depth_test_enabled = false; scrn.pD3DDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE); } else { _depth_test_enabled = true; scrn.pD3DDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE); - scrn.pD3DDevice->SetRenderState(D3DRS_ZFUNC, get_depth_func_type(mode)); + scrn.pD3DDevice->SetRenderState(D3DRS_ZFUNC, (D3DCMPFUNC) mode); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: DXGraphicsStateGuardian::issue_alpha_test +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +void DXGraphicsStateGuardian:: +issue_alpha_test(const AlphaTestAttrib *attrib) { + AlphaTestAttrib::PandaCompareFunc mode = attrib->get_mode(); + if (mode == AlphaTestAttrib::M_none) { + enable_alpha_test(false); + } else { + // AlphaTestAttrib::PandaCompareFunc === D3DCMPFUNC + call_dxAlphaFunc((D3DCMPFUNC)mode, attrib->get_reference_alpha()); + enable_alpha_test(true); } } @@ -4288,28 +4306,6 @@ get_texture_wrap_mode(Texture::WrapMode wm) const { return PandaTexWrapMode_to_D3DTexWrapMode[wm]; } -//////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::get_depth_func_type -// Access: Protected -// Description: Maps from the depth func modes to gl version -//////////////////////////////////////////////////////////////////// -INLINE D3DCMPFUNC DXGraphicsStateGuardian:: -get_depth_func_type(DepthTestAttrib::Mode m) const { - switch (m) { - case DepthTestAttrib::M_never: return D3DCMP_NEVER; - case DepthTestAttrib::M_less: return D3DCMP_LESS; - case DepthTestAttrib::M_equal: return D3DCMP_EQUAL; - case DepthTestAttrib::M_less_equal: return D3DCMP_LESSEQUAL; - case DepthTestAttrib::M_greater: return D3DCMP_GREATER; - case DepthTestAttrib::M_not_equal: return D3DCMP_NOTEQUAL; - case DepthTestAttrib::M_greater_equal: return D3DCMP_GREATEREQUAL; - case DepthTestAttrib::M_always: return D3DCMP_ALWAYS; - } - dxgsg_cat.error() - << "Invalid DepthTestAttrib::Mode value" << endl; - return D3DCMP_LESS; -} - //////////////////////////////////////////////////////////////////// // Function: DXGraphicsStateGuardian::get_fog_mode_type // Access: Protected @@ -4441,7 +4437,7 @@ set_blend_mode(ColorWriteAttrib::Mode color_write_mode, case TransparencyAttrib::M_binary: enable_blend(false); enable_alpha_test(true); - call_dxAlphaFunc(D3DCMP_EQUAL, 1); + call_dxAlphaFunc(D3DCMP_EQUAL, 1.0f); return; default: diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.h b/panda/src/dxgsg8/dxGraphicsStateGuardian8.h index a00e83afaa..cd644525fa 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.h +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.h @@ -123,6 +123,7 @@ public: virtual void issue_material(const MaterialAttrib *attrib); virtual void issue_render_mode(const RenderModeAttrib *attrib); virtual void issue_texture_apply(const TextureApplyAttrib *attrib); + virtual void issue_alpha_test(const AlphaTestAttrib *attrib); virtual void issue_depth_test(const DepthTestAttrib *attrib); virtual void issue_depth_write(const DepthWriteAttrib *attrib); virtual void issue_cull_face(const CullFaceAttrib *attrib); @@ -203,7 +204,6 @@ protected: INLINE void set_vertex_format(DWORD NewFvfType); INLINE D3DTEXTUREADDRESS get_texture_wrap_mode(Texture::WrapMode wm) const; - INLINE D3DCMPFUNC get_depth_func_type(DepthTestAttrib::Mode m) const; INLINE D3DFOGMODE get_fog_mode_type(Fog::Mode m) const; INLINE void enable_primitive_clipping(bool val); @@ -213,7 +213,7 @@ protected: INLINE void enable_point_smooth(bool val); INLINE void enable_texturing(bool val); INLINE void call_dxLightModelAmbient(const Colorf& color); - INLINE void call_dxAlphaFunc(D3DCMPFUNC func, DWORD ref); + INLINE void call_dxAlphaFunc(D3DCMPFUNC func, float refval); INLINE void call_dxBlendFunc(D3DBLEND sfunc, D3DBLEND dfunc); INLINE void enable_dither(bool val); INLINE void enable_stencil_test(bool val); @@ -279,7 +279,8 @@ protected: TODO: cache fog state float _fog_start,_fog_end,_fog_density,float _fog_color; */ - float _alpha_func_ref; + + float _alpha_func_refval; // d3d stores UINT, panda stores this as float. we store float D3DCMPFUNC _alpha_func; D3DBLEND _blend_source_func; diff --git a/panda/src/glgsg/glGraphicsStateGuardian.cxx b/panda/src/glgsg/glGraphicsStateGuardian.cxx index 11189e82f7..71a680b583 100644 --- a/panda/src/glgsg/glGraphicsStateGuardian.cxx +++ b/panda/src/glgsg/glGraphicsStateGuardian.cxx @@ -39,6 +39,7 @@ #include "lightAttrib.h" #include "cullFaceAttrib.h" #include "transparencyAttrib.h" +#include "alphaTestAttrib.h" #include "depthTestAttrib.h" #include "depthWriteAttrib.h" #include "colorWriteAttrib.h" @@ -2142,6 +2143,9 @@ issue_color_write(const ColorWriteAttrib *attrib) { report_errors(); } +// PandaCompareFunc - 1 + 0x200 === GL_NEVER, etc. order is sequential +#define PANDA_TO_GL_COMPAREFUNC(PANDACMPFUNC) (PANDACMPFUNC-1 +0x200) + //////////////////////////////////////////////////////////////////// // Function: GLGraphicsStateGuardian::issue_depth_test // Access: Public, Virtual @@ -2149,16 +2153,33 @@ issue_color_write(const ColorWriteAttrib *attrib) { //////////////////////////////////////////////////////////////////// void GLGraphicsStateGuardian:: issue_depth_test(const DepthTestAttrib *attrib) { - DepthTestAttrib::Mode mode = attrib->get_mode(); + DepthTestAttrib::PandaCompareFunc mode = attrib->get_mode(); if (mode == DepthTestAttrib::M_none) { enable_depth_test(false); } else { enable_depth_test(true); - glDepthFunc(get_depth_func_type(mode)); + glDepthFunc(PANDA_TO_GL_COMPAREFUNC(mode)); } report_errors(); } +//////////////////////////////////////////////////////////////////// +// Function: GLGraphicsStateGuardian::issue_alpha_test +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +void GLGraphicsStateGuardian:: +issue_alpha_test(const AlphaTestAttrib *attrib) { + AlphaTestAttrib::PandaCompareFunc mode = attrib->get_mode(); + if (mode == AlphaTestAttrib::M_none) { + enable_alpha_test(false); + } else { + assert(GL_NEVER==(AlphaTestAttrib::M_never-1+0x200)); + call_glAlphaFunc(PANDA_TO_GL_COMPAREFUNC(mode), attrib->get_reference_alpha()); + enable_alpha_test(true); + } +} + //////////////////////////////////////////////////////////////////// // Function: GLGraphicsStateGuardian::issue_depth_write // Access: Public, Virtual @@ -3249,31 +3270,6 @@ get_texture_apply_mode_type(TextureApplyAttrib::Mode am) const { return GL_MODULATE; } -//////////////////////////////////////////////////////////////////// -// Function: GLGraphicsStateGuardian::get_depth_func_type -// Access: Protected -// Description: Maps from the depth func modes to gl version -//////////////////////////////////////////////////////////////////// -GLenum GLGraphicsStateGuardian:: -get_depth_func_type(DepthTestAttrib::Mode m) const -{ - switch(m) { - case DepthTestAttrib::M_never: return GL_NEVER; - case DepthTestAttrib::M_less: return GL_LESS; - case DepthTestAttrib::M_equal: return GL_EQUAL; - case DepthTestAttrib::M_less_equal: return GL_LEQUAL; - case DepthTestAttrib::M_greater: return GL_GREATER; - case DepthTestAttrib::M_not_equal: return GL_NOTEQUAL; - case DepthTestAttrib::M_greater_equal: return GL_GEQUAL; - case DepthTestAttrib::M_always: return GL_ALWAYS; - - default: - glgsg_cat.error() - << "Invalid DepthTestAttrib::Mode value" << endl; - return GL_LESS; - } -} - //////////////////////////////////////////////////////////////////// // Function: GLGraphicsStateGuardian::get_fog_mode_type // Access: Protected @@ -3526,51 +3522,51 @@ set_blend_mode(ColorWriteAttrib::Mode color_write_mode, // No color blend; is there a transparency set? switch (transparency_mode) { - case TransparencyAttrib::M_none: - break; + case TransparencyAttrib::M_none: + break; + + case TransparencyAttrib::M_alpha: + case TransparencyAttrib::M_alpha_sorted: + // Should we really have an "alpha" and an "alpha_sorted" mode, + // like Performer does? (The difference is that "alpha" is with + // the write to the depth buffer disabled.) Or should we just use + // the separate depth write transition to control this? Doing it + // implicitly requires a bit more logic here and in the state + // management; for now we require the user to explicitly turn off + // the depth write. + enable_multisample_alpha_one(false); + enable_multisample_alpha_mask(false); + enable_blend(true); + enable_alpha_test(false); + call_glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + return; - case TransparencyAttrib::M_alpha: - case TransparencyAttrib::M_alpha_sorted: - // Should we really have an "alpha" and an "alpha_sorted" mode, - // like Performer does? (The difference is that "alpha" is with - // the write to the depth buffer disabled.) Or should we just use - // the separate depth write transition to control this? Doing it - // implicitly requires a bit more logic here and in the state - // management; for now we require the user to explicitly turn off - // the depth write. - enable_multisample_alpha_one(false); - enable_multisample_alpha_mask(false); - enable_blend(true); - enable_alpha_test(false); - call_glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - return; - - case TransparencyAttrib::M_multisample: - enable_multisample_alpha_one(true); - enable_multisample_alpha_mask(true); - enable_blend(false); - enable_alpha_test(false); - return; - - case TransparencyAttrib::M_multisample_mask: - enable_multisample_alpha_one(false); - enable_multisample_alpha_mask(true); - enable_blend(false); - enable_alpha_test(false); - return; - - case TransparencyAttrib::M_binary: - enable_multisample_alpha_one(false); - enable_multisample_alpha_mask(false); - enable_blend(false); - enable_alpha_test(true); - call_glAlphaFunc(GL_EQUAL, 1); - return; - - default: - glgsg_cat.error() - << "invalid transparency mode " << (int)transparency_mode << endl; - break; + case TransparencyAttrib::M_binary: + enable_multisample_alpha_one(false); + enable_multisample_alpha_mask(false); + enable_blend(false); + enable_alpha_test(true); + call_glAlphaFunc(GL_EQUAL, 1); + return; + + case TransparencyAttrib::M_multisample: + enable_multisample_alpha_one(true); + enable_multisample_alpha_mask(true); + enable_blend(false); + enable_alpha_test(false); + return; + + case TransparencyAttrib::M_multisample_mask: + enable_multisample_alpha_one(false); + enable_multisample_alpha_mask(true); + enable_blend(false); + enable_alpha_test(false); + return; + + default: + glgsg_cat.error() + << "invalid transparency mode " << (int)transparency_mode << endl; + break; } // Nothing's set, so disable blending. diff --git a/panda/src/glgsg/glGraphicsStateGuardian.h b/panda/src/glgsg/glGraphicsStateGuardian.h index 8556415409..6d60b52f85 100644 --- a/panda/src/glgsg/glGraphicsStateGuardian.h +++ b/panda/src/glgsg/glGraphicsStateGuardian.h @@ -117,6 +117,7 @@ public: virtual void issue_texture_apply(const TextureApplyAttrib *attrib); virtual void issue_color_write(const ColorWriteAttrib *attrib); virtual void issue_depth_test(const DepthTestAttrib *attrib); + virtual void issue_alpha_test(const AlphaTestAttrib *attrib); virtual void issue_depth_write(const DepthWriteAttrib *attrib); virtual void issue_cull_face(const CullFaceAttrib *attrib); virtual void issue_fog(const FogAttrib *attrib); @@ -240,7 +241,6 @@ protected: GLenum get_external_image_format(PixelBuffer::Format format); GLenum get_internal_image_format(PixelBuffer::Format format); GLint get_texture_apply_mode_type(TextureApplyAttrib::Mode am) const; - GLenum get_depth_func_type(DepthTestAttrib::Mode m) const; GLenum get_fog_mode_type(Fog::Mode m) const; static CPT(RenderState) get_untextured_state(); diff --git a/panda/src/gsgbase/graphicsStateGuardianBase.h b/panda/src/gsgbase/graphicsStateGuardianBase.h index 2f42cf3d18..94d49f61e6 100644 --- a/panda/src/gsgbase/graphicsStateGuardianBase.h +++ b/panda/src/gsgbase/graphicsStateGuardianBase.h @@ -62,6 +62,7 @@ class RenderModeAttrib; class ColorBlendAttrib; class TextureApplyAttrib; class ColorWriteAttrib; +class AlphaTestAttrib; class DepthTestAttrib; class DepthWriteAttrib; class TexGenAttrib; @@ -170,6 +171,7 @@ public: virtual void apply_material(const Material *material)=0; virtual void issue_transform(const TransformState *) { } + virtual void issue_alpha_test(const AlphaTestAttrib *) { } virtual void issue_color_scale(const ColorScaleAttrib *) { } virtual void issue_color(const ColorAttrib *) { } virtual void issue_tex_matrix(const TexMatrixAttrib *) { } diff --git a/panda/src/pgraph/alphaTestAttrib.I b/panda/src/pgraph/alphaTestAttrib.I index 3b085bfee4..430fbc977e 100644 --- a/panda/src/pgraph/alphaTestAttrib.I +++ b/panda/src/pgraph/alphaTestAttrib.I @@ -24,7 +24,7 @@ // AlphaTestAttrib object. //////////////////////////////////////////////////////////////////// INLINE AlphaTestAttrib:: -AlphaTestAttrib(AlphaTestAttrib::Mode mode,unsigned int reference_alpha) : +AlphaTestAttrib(AlphaTestAttrib::PandaCompareFunc mode,float reference_alpha) : _mode(mode), _reference_alpha(reference_alpha) { } @@ -34,8 +34,8 @@ AlphaTestAttrib(AlphaTestAttrib::Mode mode,unsigned int reference_alpha) : // Access: Published // Description: Returns the alpha write mode. //////////////////////////////////////////////////////////////////// -INLINE AlphaTestAttrib::Mode AlphaTestAttrib:: -get_mode() const { +INLINE AlphaTestAttrib::PandaCompareFunc AlphaTestAttrib:: +get_mode(void) const { return _mode; } @@ -44,7 +44,7 @@ get_mode() const { // Access: Published // Description: Returns the alpha reference value. //////////////////////////////////////////////////////////////////// -INLINE unsigned int AlphaTestAttrib:: +INLINE float AlphaTestAttrib:: get_reference_alpha(void) const { return _reference_alpha; } diff --git a/panda/src/pgraph/alphaTestAttrib.cxx b/panda/src/pgraph/alphaTestAttrib.cxx index 3071e8334f..98fd5b307c 100644 --- a/panda/src/pgraph/alphaTestAttrib.cxx +++ b/panda/src/pgraph/alphaTestAttrib.cxx @@ -32,7 +32,8 @@ TypeHandle AlphaTestAttrib::_type_handle; // Description: Constructs a new AlphaTestAttrib object. //////////////////////////////////////////////////////////////////// CPT(RenderAttrib) AlphaTestAttrib:: -make(AlphaTestAttrib::Mode mode, unsigned int reference_value) { +make(PandaCompareFunc mode, float reference_value) { + assert((reference_value >=0.0f) && (reference_value <=1.0f)); AlphaTestAttrib *attrib = new AlphaTestAttrib(mode,reference_value); return return_new(attrib); } @@ -59,39 +60,7 @@ issue(GraphicsStateGuardianBase *gsg) const { void AlphaTestAttrib:: output(ostream &out) const { out << get_type() << ":"; - switch (get_mode()) { - case M_always: - out << "always"; - break; - - case M_never: - out << "never"; - break; - - case M_less: - out << "less"; - break; - - case M_equal: - out << "equal"; - break; - - case M_less_equal: - out << "less_equal"; - break; - - case M_greater: - out << "greater"; - break; - - case M_not_equal: - out << "not_equal"; - break; - - case M_greater_equal: - out << "greater_equal"; - break; - } + output_comparefunc(out,_mode); } //////////////////////////////////////////////////////////////////// @@ -113,7 +82,10 @@ int AlphaTestAttrib:: compare_to_impl(const RenderAttrib *other) const { const AlphaTestAttrib *ta; DCAST_INTO_R(ta, other, 0); - return (int)_mode - (int)ta->_mode; + int compare_result = ((int)_mode - (int)ta->_mode) ; + if(compare_result!=0) + return compare_result; + else return (int) (255.0f*(_reference_alpha - ta->_reference_alpha)); } //////////////////////////////////////////////////////////////////// @@ -154,6 +126,7 @@ write_datagram(BamWriter *manager, Datagram &dg) { RenderAttrib::write_datagram(manager, dg); dg.add_int8(_mode); + dg.add_float32(_reference_alpha); } //////////////////////////////////////////////////////////////////// @@ -187,5 +160,6 @@ void AlphaTestAttrib:: fillin(DatagramIterator &scan, BamReader *manager) { RenderAttrib::fillin(scan, manager); - _mode = (Mode)scan.get_int8(); + _mode = (PandaCompareFunc)scan.get_int8(); + _reference_alpha = scan.get_float32(); } diff --git a/panda/src/pgraph/alphaTestAttrib.h b/panda/src/pgraph/alphaTestAttrib.h index 93bf062ff7..bedb7092e6 100644 --- a/panda/src/pgraph/alphaTestAttrib.h +++ b/panda/src/pgraph/alphaTestAttrib.h @@ -28,25 +28,13 @@ // based on its alpha value relative to a reference alpha value //////////////////////////////////////////////////////////////////// class EXPCL_PANDA AlphaTestAttrib : public RenderAttrib { -PUBLISHED: - enum Mode { // defined to match D3DCMPFUNC - M_never=1, // Never draw. - M_less, // incoming < reference_alpha - M_equal, // incoming == reference_alpha - M_less_equal, // incoming <= reference_alpha - M_greater, // incoming > reference_alpha - M_not_equal, // incoming != reference_alpha - M_greater_equal, // incoming >= reference_alpha - M_always // Always draw. - }; - private: - INLINE AlphaTestAttrib(Mode mode = M_always,unsigned int reference_alpha = 0xFF); + INLINE AlphaTestAttrib(PandaCompareFunc mode = M_always,float reference_alpha = 1.0f); PUBLISHED: - static CPT(RenderAttrib) make(Mode mode,unsigned int reference_alpha); - INLINE unsigned int get_reference_alpha() const; - INLINE Mode get_mode() const; + static CPT(RenderAttrib) make(PandaCompareFunc mode,float reference_alpha); + INLINE float get_reference_alpha() const; + INLINE PandaCompareFunc get_mode() const; public: virtual void issue(GraphicsStateGuardianBase *gsg) const; @@ -57,8 +45,8 @@ protected: virtual RenderAttrib *make_default_impl() const; private: - Mode _mode; - unsigned int _reference_alpha; + PandaCompareFunc _mode; + float _reference_alpha; // should be in range [0.0-1.0] public: static void register_with_read_factory(); diff --git a/panda/src/pgraph/depthTestAttrib.I b/panda/src/pgraph/depthTestAttrib.I index 6caf644e45..a299798740 100644 --- a/panda/src/pgraph/depthTestAttrib.I +++ b/panda/src/pgraph/depthTestAttrib.I @@ -24,7 +24,7 @@ // DepthTestAttrib object. //////////////////////////////////////////////////////////////////// INLINE DepthTestAttrib:: -DepthTestAttrib(DepthTestAttrib::Mode mode) : +DepthTestAttrib(DepthTestAttrib::PandaCompareFunc mode) : _mode(mode) { } @@ -34,7 +34,7 @@ DepthTestAttrib(DepthTestAttrib::Mode mode) : // Access: Published // Description: Returns the depth write mode. //////////////////////////////////////////////////////////////////// -INLINE DepthTestAttrib::Mode DepthTestAttrib:: +INLINE DepthTestAttrib::PandaCompareFunc DepthTestAttrib:: get_mode() const { return _mode; } diff --git a/panda/src/pgraph/depthTestAttrib.cxx b/panda/src/pgraph/depthTestAttrib.cxx index cafa2818b6..5332b0f423 100644 --- a/panda/src/pgraph/depthTestAttrib.cxx +++ b/panda/src/pgraph/depthTestAttrib.cxx @@ -32,7 +32,7 @@ TypeHandle DepthTestAttrib::_type_handle; // Description: Constructs a new DepthTestAttrib object. //////////////////////////////////////////////////////////////////// CPT(RenderAttrib) DepthTestAttrib:: -make(DepthTestAttrib::Mode mode) { +make(DepthTestAttrib::PandaCompareFunc mode) { DepthTestAttrib *attrib = new DepthTestAttrib(mode); return return_new(attrib); } @@ -59,43 +59,7 @@ issue(GraphicsStateGuardianBase *gsg) const { void DepthTestAttrib:: output(ostream &out) const { out << get_type() << ":"; - switch (get_mode()) { - case M_none: - out << "none"; - break; - - case M_never: - out << "never"; - break; - - case M_less: - out << "less"; - break; - - case M_equal: - out << "equal"; - break; - - case M_less_equal: - out << "less_equal"; - break; - - case M_greater: - out << "greater"; - break; - - case M_not_equal: - out << "not_equal"; - break; - - case M_greater_equal: - out << "greater_equal"; - break; - - case M_always: - out << "always"; - break; - } + output_comparefunc(out,_mode); } //////////////////////////////////////////////////////////////////// @@ -191,5 +155,5 @@ void DepthTestAttrib:: fillin(DatagramIterator &scan, BamReader *manager) { RenderAttrib::fillin(scan, manager); - _mode = (Mode)scan.get_int8(); + _mode = (PandaCompareFunc)scan.get_int8(); } diff --git a/panda/src/pgraph/depthTestAttrib.h b/panda/src/pgraph/depthTestAttrib.h index 7fde73810e..afdb683e6b 100644 --- a/panda/src/pgraph/depthTestAttrib.h +++ b/panda/src/pgraph/depthTestAttrib.h @@ -28,26 +28,13 @@ // Description : Enables or disables writing to the depth buffer. //////////////////////////////////////////////////////////////////// class EXPCL_PANDA DepthTestAttrib : public RenderAttrib { -PUBLISHED: - enum Mode { - M_none, // No depth test; may still write to depth buffer. - M_never, // Never draw. - M_less, // incoming < stored - M_equal, // incoming == stored - M_less_equal, // incoming <= stored - M_greater, // incoming > stored - M_not_equal, // incoming != stored - M_greater_equal, // incoming >= stored - M_always // Always draw. Same effect as none, more expensive. - }; - private: - INLINE DepthTestAttrib(Mode mode = M_less); + INLINE DepthTestAttrib(PandaCompareFunc mode = M_less); PUBLISHED: - static CPT(RenderAttrib) make(Mode mode); + static CPT(RenderAttrib) make(PandaCompareFunc mode); - INLINE Mode get_mode() const; + INLINE PandaCompareFunc get_mode() const; public: virtual void issue(GraphicsStateGuardianBase *gsg) const; @@ -58,7 +45,7 @@ protected: virtual RenderAttrib *make_default_impl() const; private: - Mode _mode; + PandaCompareFunc _mode; public: static void register_with_read_factory(); diff --git a/panda/src/pgraph/nodePath.cxx b/panda/src/pgraph/nodePath.cxx index e23019a298..a18293c40b 100644 --- a/panda/src/pgraph/nodePath.cxx +++ b/panda/src/pgraph/nodePath.cxx @@ -30,6 +30,7 @@ #include "fogAttrib.h" #include "renderModeAttrib.h" #include "cullFaceAttrib.h" +#include "alphaTestAttrib.h" #include "depthTestAttrib.h" #include "depthWriteAttrib.h" #include "billboardEffect.h" @@ -1978,6 +1979,70 @@ get_two_sided() const { return false; } +//////////////////////////////////////////////////////////////////// +// Function: NodePath::set_alpha_test +// Access: Published +// Description: Specifically sets or disables the testing of the +// alpha buffer on this particular node. This is +// normally on in the 3-d scene graph and off in the 2-d +// scene graph; it should be on for rendering most 3-d +// objects properly. +//////////////////////////////////////////////////////////////////// +void NodePath:: +set_alpha_test(RenderAttrib::PandaCompareFunc alpha_test_mode,float reference_alpha, int priority) { + nassertv_always(!is_empty()); + node()->set_attrib(AlphaTestAttrib::make(alpha_test_mode,reference_alpha), priority); +} + +//////////////////////////////////////////////////////////////////// +// Function: NodePath::clear_alpha_test +// Access: Published +// Description: Completely removes any alpha-test adjustment that +// may have been set on this node via set_alpha_test(). +//////////////////////////////////////////////////////////////////// +void NodePath:: +clear_alpha_test() { + nassertv_always(!is_empty()); + node()->clear_attrib(AlphaTestAttrib::get_class_type()); +} + +//////////////////////////////////////////////////////////////////// +// Function: NodePath::has_alpha_test +// Access: Published +// Description: Returns true if a alpha-test adjustment has been +// explicitly set on this particular node via +// set_alpha_test(). If this returns true, then +// get_alpha_test() may be called to determine which has +// been set. +//////////////////////////////////////////////////////////////////// +bool NodePath:: +has_alpha_test() const { + nassertr_always(!is_empty(), false); + return node()->has_attrib(AlphaTestAttrib::get_class_type()); +} + +//////////////////////////////////////////////////////////////////// +// Function: NodePath::get_alpha_test +// Access: Published +// Description: Returns true if alpha-test rendering has been +// specifically set on this node via set_alpha_test(), or +// false if alpha-test rendering has been specifically +// disabled, or if nothing has been specifically set. See +// also has_alpha_test(). +//////////////////////////////////////////////////////////////////// +bool NodePath:: +get_alpha_test() const { + nassertr_always(!is_empty(), false); + const RenderAttrib *attrib = + node()->get_attrib(AlphaTestAttrib::get_class_type()); + if (attrib != (const RenderAttrib *)NULL) { + const AlphaTestAttrib *dta = DCAST(AlphaTestAttrib, attrib); + return (dta->get_mode() != AlphaTestAttrib::M_none); + } + + return false; +} + //////////////////////////////////////////////////////////////////// // Function: NodePath::set_depth_test // Access: Published @@ -1991,7 +2056,7 @@ void NodePath:: set_depth_test(bool depth_test, int priority) { nassertv_always(!is_empty()); - DepthTestAttrib::Mode mode = + DepthTestAttrib::PandaCompareFunc mode = depth_test ? DepthTestAttrib::M_less : DepthTestAttrib::M_none; diff --git a/panda/src/pgraph/nodePath.h b/panda/src/pgraph/nodePath.h index 5c812e4ddb..1f9291a957 100644 --- a/panda/src/pgraph/nodePath.h +++ b/panda/src/pgraph/nodePath.h @@ -271,9 +271,9 @@ PUBLISHED: const LVecBase3f &hpr); INLINE void set_hpr_scale(float h, float p, float r, - float sx, float sy, float sz); + float sx, float sy, float sz); void set_hpr_scale(const LVecBase3f &hpr, - const LVecBase3f &scale); + const LVecBase3f &scale); INLINE void set_pos_hpr_scale(float x, float y, float z, float h, float p, float r, float sx, float sy, float sz); @@ -347,11 +347,11 @@ PUBLISHED: const LVecBase3f &pos, const LVecBase3f &hpr); INLINE void set_hpr_scale(const NodePath &other, - float h, float p, float r, - float sx, float sy, float sz); + float h, float p, float r, + float sx, float sy, float sz); void set_hpr_scale(const NodePath &other, - const LVecBase3f &hpr, - const LVecBase3f &scale); + const LVecBase3f &hpr, + const LVecBase3f &scale); INLINE void set_pos_hpr_scale(const NodePath &other, float x, float y, float z, float h, float p, float r, @@ -431,6 +431,11 @@ PUBLISHED: bool has_two_sided() const; bool get_two_sided() const; + void set_alpha_test(RenderAttrib::PandaCompareFunc alpha_test_mode,float reference_alpha,int priority = 0); + void clear_alpha_test(); + bool has_alpha_test() const; + bool get_alpha_test() const; + void set_depth_test(bool depth_test, int priority = 0); void clear_depth_test(); bool has_depth_test() const; diff --git a/panda/src/pgraph/renderAttrib.cxx b/panda/src/pgraph/renderAttrib.cxx index 3dcb3d6518..988767a81a 100644 --- a/panda/src/pgraph/renderAttrib.cxx +++ b/panda/src/pgraph/renderAttrib.cxx @@ -112,6 +112,12 @@ output(ostream &out) const { out << get_type(); } +void RenderAttrib:: +output_comparefunc(ostream &out,PandaCompareFunc fn) const { + static char *FuncStrs[M_always+1] = {"none","never","less","equal", "less or equal","greater","not equal","greater or equal","always"}; + out << FuncStrs[fn]; +} + //////////////////////////////////////////////////////////////////// // Function: RenderAttrib::write // Access: Published, Virtual diff --git a/panda/src/pgraph/renderAttrib.h b/panda/src/pgraph/renderAttrib.h index cb348a2712..939a85461d 100644 --- a/panda/src/pgraph/renderAttrib.h +++ b/panda/src/pgraph/renderAttrib.h @@ -75,13 +75,25 @@ PUBLISHED: virtual void output(ostream &out) const; virtual void write(ostream &out, int indent_level) const; + enum PandaCompareFunc { // intentionally defined to match D3DCMPFUNC + M_none=0, // alpha-test disabled (always-draw) + M_never, // Never draw. + M_less, // incoming < reference_alpha + M_equal, // incoming == reference_alpha + M_less_equal, // incoming <= reference_alpha + M_greater, // incoming > reference_alpha + M_not_equal, // incoming != reference_alpha + M_greater_equal, // incoming >= reference_alpha + M_always // Always draw. + }; + protected: static CPT(RenderAttrib) return_new(RenderAttrib *attrib); - virtual int compare_to_impl(const RenderAttrib *other) const; virtual CPT(RenderAttrib) compose_impl(const RenderAttrib *other) const; virtual CPT(RenderAttrib) invert_compose_impl(const RenderAttrib *other) const; virtual RenderAttrib *make_default_impl() const=0; + void output_comparefunc(ostream &out,PandaCompareFunc fn) const; private: typedef pset > Attribs;