Browse Source

add issue_alpha_test

cxgeorge 23 years ago
parent
commit
60e4872650

+ 17 - 17
panda/src/dxgsg/dxGraphicsStateGuardian.I

@@ -186,53 +186,53 @@ 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 )

+ 25 - 26
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

+ 3 - 3
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;

+ 17 - 15
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
   }
 }
 

+ 24 - 28
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:

+ 4 - 3
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;

+ 68 - 72
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_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_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_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.

+ 1 - 1
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();

+ 2 - 0
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 *) { }

+ 4 - 4
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;
 }

+ 10 - 36
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();
 }

+ 6 - 18
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();

+ 2 - 2
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;
 }

+ 3 - 39
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();
 }

+ 4 - 17
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();

+ 66 - 1
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;

+ 11 - 6
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;

+ 6 - 0
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

+ 13 - 1
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<const RenderAttrib *, IndirectCompareTo<RenderAttrib> > Attribs;