From 8ab41304fdbc56efaf3aa6096715dee4741a9aad Mon Sep 17 00:00:00 2001 From: David Rose Date: Wed, 12 Jun 2002 20:10:29 +0000 Subject: [PATCH] support decals on M_dual objects --- panda/src/pgraph/cullResult.cxx | 52 ++++++++++++++++++++++++++++++- panda/src/pgraph/cullResult.h | 1 + panda/src/pgraph/cullableObject.I | 12 ++++++- panda/src/pgraph/cullableObject.h | 2 ++ 4 files changed, 65 insertions(+), 2 deletions(-) diff --git a/panda/src/pgraph/cullResult.cxx b/panda/src/pgraph/cullResult.cxx index e5060d7f76..a78ab5823c 100644 --- a/panda/src/pgraph/cullResult.cxx +++ b/panda/src/pgraph/cullResult.cxx @@ -87,7 +87,10 @@ add_object(CullableObject *object) { #endif { CullableObject *transparent_part = new CullableObject(*object); - transparent_part->_state = state->compose(get_dual_transparent_state()); + CPT(RenderState) transparent_state = object->has_decals() ? + get_dual_transparent_state_decals() : + get_dual_transparent_state(); + transparent_part->_state = state->compose(transparent_state); CullBin *bin = get_bin(transparent_part->_state->get_bin_index()); nassertv(bin != (CullBin *)NULL); bin->add_object(transparent_part); @@ -219,16 +222,63 @@ static const double m_dual_flash_rate = 1.0; // 1 state change per second // Access: Private // Description: Returns a RenderState that renders only the // transparent parts of an object, in support of M_dual. +// This state is suitable only for objects that do not +// contain decals. //////////////////////////////////////////////////////////////////// CPT(RenderState) CullResult:: get_dual_transparent_state() { static CPT(RenderState) state = NULL; if (state == (const RenderState *)NULL) { + // The alpha test for > 0 prevents us from drawing empty pixels, + // and hence filling up the depth buffer with large empty spaces + // that may obscure other things. However, this does mean we draw + // pixels twice where the alpha == 1.0 (since they were already + // drawn in the opaque pass). This is not normally a problem, + // except when we are using decals; in the case of decals, we + // don't want to draw the 1.0 pixels again, since these are the + // ones that may have been decaled onto. state = RenderState::make(AlphaTestAttrib::make(AlphaTestAttrib::M_greater, 0.0f), TransparencyAttrib::make(TransparencyAttrib::M_alpha), RenderState::get_max_priority()); } +#ifndef NDEBUG + if (m_dual_flash) { + int cycle = (int)(ClockObject::get_global_clock()->get_real_time() * m_dual_flash_rate); + if ((cycle & 1) == 0) { + static CPT(RenderState) flash_state = NULL; + if (flash_state == (const RenderState *)NULL) { + flash_state = state->add_attrib(ColorScaleAttrib::make(LVecBase4f(0.8f, 0.2f, 0.2f, 1.0f))); + flash_state = flash_state->add_attrib(AlphaTestAttrib::make(AlphaTestAttrib::M_less, 1.0f)); + } + return flash_state; + } + } +#endif // NDEBUG + + return state; +} + +//////////////////////////////////////////////////////////////////// +// Function: CullResult::get_dual_transparent_state_decals +// Access: Private +// Description: Returns a RenderState that renders only the +// transparent parts of an object, but suitable for +// objects that contain decals. +//////////////////////////////////////////////////////////////////// +CPT(RenderState) CullResult:: +get_dual_transparent_state_decals() { + static CPT(RenderState) state = NULL; + if (state == (const RenderState *)NULL) { + // This is exactly the same as above except here we make the alpha + // test of < 1.0 instead of > 0.0. This makes us draw big empty + // pixels where the alpha values are 0.0, but we don't overwrite + // the decals where the pixels are 1.0. + state = RenderState::make(AlphaTestAttrib::make(AlphaTestAttrib::M_less, 1.0f), + TransparencyAttrib::make(TransparencyAttrib::M_alpha), + RenderState::get_max_priority()); + } + #ifndef NDEBUG if (m_dual_flash) { int cycle = (int)(ClockObject::get_global_clock()->get_real_time() * m_dual_flash_rate); diff --git a/panda/src/pgraph/cullResult.h b/panda/src/pgraph/cullResult.h index d5086333bf..1bf60c0c63 100644 --- a/panda/src/pgraph/cullResult.h +++ b/panda/src/pgraph/cullResult.h @@ -65,6 +65,7 @@ private: static CPT(RenderState) get_binary_state(); static CPT(RenderState) get_dual_transparent_state(); + static CPT(RenderState) get_dual_transparent_state_decals(); static CPT(RenderState) get_dual_opaque_state(); GraphicsStateGuardianBase *_gsg; diff --git a/panda/src/pgraph/cullableObject.I b/panda/src/pgraph/cullableObject.I index 129b666013..d93f6ac092 100644 --- a/panda/src/pgraph/cullableObject.I +++ b/panda/src/pgraph/cullableObject.I @@ -81,7 +81,6 @@ CullableObject(const CullableObject ©) : //////////////////////////////////////////////////////////////////// // Function: CullableObject::Copy Assignment Operator -// Access: Private // Access: Public // Description: Copies the CullableObject, but does not copy its // children (decals). @@ -93,6 +92,17 @@ operator = (const CullableObject ©) { _transform = copy._transform; } +//////////////////////////////////////////////////////////////////// +// Function: CullableObject::has_decals +// Access: Public +// Description: Returns true if the object has one or more decals +// placed on it, false otherwise. +//////////////////////////////////////////////////////////////////// +INLINE bool CullableObject:: +has_decals() const { + return (_next != (CullableObject *)NULL); +} + //////////////////////////////////////////////////////////////////// // Function: CullableObject::operator new // Access: Public diff --git a/panda/src/pgraph/cullableObject.h b/panda/src/pgraph/cullableObject.h index e7c59c3435..dff50731a2 100644 --- a/panda/src/pgraph/cullableObject.h +++ b/panda/src/pgraph/cullableObject.h @@ -49,6 +49,8 @@ public: INLINE CullableObject(const CullableObject ©); INLINE void operator = (const CullableObject ©); + INLINE bool has_decals() const; + public: ~CullableObject();