Fixes for the fact that render states were no longer sticking around in the cache between frames

This commit is contained in:
rdb 2015-07-28 21:29:13 +02:00
parent 1ee8c5f6d2
commit b9d45ccc04
3 changed files with 61 additions and 33 deletions

View File

@ -123,12 +123,9 @@ add_object(CullableObject *object, const CullTraverser *traverser) {
Thread *current_thread = traverser->get_current_thread(); Thread *current_thread = traverser->get_current_thread();
CullBinManager *bin_manager = CullBinManager::get_global_ptr(); CullBinManager *bin_manager = CullBinManager::get_global_ptr();
const RenderState *state = object->_state;
nassertv(state != (const RenderState *)NULL);
// This is probably a good time to check for an auto rescale setting. // This is probably a good time to check for an auto rescale setting.
const RescaleNormalAttrib *rescale; const RescaleNormalAttrib *rescale;
state->get_attrib_def(rescale); object->_state->get_attrib_def(rescale);
if (rescale->get_mode() == RescaleNormalAttrib::M_auto) { if (rescale->get_mode() == RescaleNormalAttrib::M_auto) {
RescaleNormalAttrib::Mode mode; RescaleNormalAttrib::Mode mode;
@ -140,24 +137,23 @@ add_object(CullableObject *object, const CullTraverser *traverser) {
mode = RescaleNormalAttrib::M_normalize; mode = RescaleNormalAttrib::M_normalize;
} }
state = state->set_attrib(RescaleNormalAttrib::make(mode)); object->_state = object->_state->compose(get_rescale_normal_state(mode));
object->_state = state;
} }
// Check to see if there's a special transparency setting. // Check to see if there's a special transparency setting.
const TransparencyAttrib *trans; const TransparencyAttrib *trans;
if (state->get_attrib(trans)) { if (object->_state->get_attrib(trans)) {
switch (trans->get_mode()) { switch (trans->get_mode()) {
case TransparencyAttrib::M_alpha: case TransparencyAttrib::M_alpha:
// M_alpha implies an alpha-write test, so we don't waste time // M_alpha implies an alpha-write test, so we don't waste time
// writing 0-valued pixels. // writing 0-valued pixels.
object->_state = state->compose(get_alpha_state()); object->_state = object->_state->compose(get_alpha_state());
check_flash_transparency(object->_state, flash_alpha_color); check_flash_transparency(object->_state, flash_alpha_color);
break; break;
case TransparencyAttrib::M_binary: case TransparencyAttrib::M_binary:
// M_binary is implemented by explicitly setting the alpha test. // M_binary is implemented by explicitly setting the alpha test.
object->_state = state->compose(get_binary_state()); object->_state = object->_state->compose(get_binary_state());
check_flash_transparency(object->_state, flash_binary_color); check_flash_transparency(object->_state, flash_binary_color);
break; break;
@ -166,7 +162,7 @@ add_object(CullableObject *object, const CullTraverser *traverser) {
// The multisample modes are implemented using M_binary if the // The multisample modes are implemented using M_binary if the
// GSG in use doesn't support multisample. // GSG in use doesn't support multisample.
if (!_gsg->get_supports_multisample()) { if (!_gsg->get_supports_multisample()) {
object->_state = state->compose(get_binary_state()); object->_state = object->_state->compose(get_binary_state());
} }
check_flash_transparency(object->_state, flash_multisample_color); check_flash_transparency(object->_state, flash_multisample_color);
break; break;
@ -174,7 +170,6 @@ add_object(CullableObject *object, const CullTraverser *traverser) {
case TransparencyAttrib::M_dual: case TransparencyAttrib::M_dual:
#ifndef NDEBUG #ifndef NDEBUG
check_flash_transparency(object->_state, flash_dual_color); check_flash_transparency(object->_state, flash_dual_color);
state = object->_state;
#endif #endif
if (!m_dual) { if (!m_dual) {
// If m_dual is configured off, it becomes M_alpha. // If m_dual is configured off, it becomes M_alpha.
@ -188,10 +183,8 @@ add_object(CullableObject *object, const CullTraverser *traverser) {
// explicit bin already applied; otherwise, M_dual falls back // explicit bin already applied; otherwise, M_dual falls back
// to M_alpha. // to M_alpha.
{ {
const CullBinAttrib *bin_attrib = (const CullBinAttrib *) const CullBinAttrib *bin_attrib;
state->get_attrib(CullBinAttrib::get_class_slot()); if (!object->_state->get_attrib(bin_attrib) ||
if (bin_attrib == (CullBinAttrib *)NULL ||
bin_attrib->get_bin_name().empty()) { bin_attrib->get_bin_name().empty()) {
// We make a copy of the object to draw the transparent part; // We make a copy of the object to draw the transparent part;
// this gets placed in the transparent bin. // this gets placed in the transparent bin.
@ -201,7 +194,7 @@ add_object(CullableObject *object, const CullTraverser *traverser) {
{ {
CullableObject *transparent_part = new CullableObject(*object); CullableObject *transparent_part = new CullableObject(*object);
CPT(RenderState) transparent_state = get_dual_transparent_state(); CPT(RenderState) transparent_state = get_dual_transparent_state();
transparent_part->_state = state->compose(transparent_state); transparent_part->_state = object->_state->compose(transparent_state);
if (transparent_part->munge_geom if (transparent_part->munge_geom
(_gsg, _gsg->get_geom_munger(transparent_part->_state, current_thread), (_gsg, _gsg->get_geom_munger(transparent_part->_state, current_thread),
traverser, force)) { traverser, force)) {
@ -217,7 +210,7 @@ add_object(CullableObject *object, const CullTraverser *traverser) {
// Now we can draw the opaque part. This will end up in // Now we can draw the opaque part. This will end up in
// the opaque bin. // the opaque bin.
object->_state = state->compose(get_dual_opaque_state()); object->_state = object->_state->compose(get_dual_opaque_state());
#ifndef NDEBUG #ifndef NDEBUG
if (!m_dual_opaque) { if (!m_dual_opaque) {
delete object; delete object;
@ -255,7 +248,7 @@ add_object(CullableObject *object, const CullTraverser *traverser) {
delete wireframe_part; delete wireframe_part;
} }
object->_state = object->_state->set_attrib(RenderModeAttrib::make(RenderModeAttrib::M_filled)); object->_state = object->_state->compose(get_wireframe_filled_state());
} }
} }
@ -404,13 +397,29 @@ make_new_bin(int bin_index) {
return bin_ptr; return bin_ptr;
} }
////////////////////////////////////////////////////////////////////
// Function: CullResult::get_rescale_normal_state
// Access: Private
// Description: Returns a RenderState containing the given rescale
// normal attribute.
////////////////////////////////////////////////////////////////////
const RenderState *CullResult::
get_rescale_normal_state(RescaleNormalAttrib::Mode mode) {
static CPT(RenderState) states[RescaleNormalAttrib::M_auto + 1];
if (states[mode].is_null()) {
states[mode] = RenderState::make(RescaleNormalAttrib::make(mode),
RenderState::get_max_priority());
}
return states[mode].p();
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: CullResult::get_alpha_state // Function: CullResult::get_alpha_state
// Access: Private // Access: Private
// Description: Returns a RenderState that changes the alpha test to // Description: Returns a RenderState that changes the alpha test to
// > 0, for implementing M_alpha. // > 0, for implementing M_alpha.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
CPT(RenderState) CullResult:: const RenderState *CullResult::
get_alpha_state() { get_alpha_state() {
static CPT(RenderState) state = NULL; static CPT(RenderState) state = NULL;
if (state == (const RenderState *)NULL) { if (state == (const RenderState *)NULL) {
@ -418,7 +427,7 @@ get_alpha_state() {
// user to override this if he desires. // user to override this if he desires.
state = RenderState::make(AlphaTestAttrib::make(AlphaTestAttrib::M_greater, 0.0f)); state = RenderState::make(AlphaTestAttrib::make(AlphaTestAttrib::M_greater, 0.0f));
} }
return state; return state.p();
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -427,7 +436,7 @@ get_alpha_state() {
// Description: Returns a RenderState that applies the effects of // Description: Returns a RenderState that applies the effects of
// M_binary. // M_binary.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
CPT(RenderState) CullResult:: const RenderState *CullResult::
get_binary_state() { get_binary_state() {
static CPT(RenderState) state = NULL; static CPT(RenderState) state = NULL;
if (state == (const RenderState *)NULL) { if (state == (const RenderState *)NULL) {
@ -435,7 +444,7 @@ get_binary_state() {
TransparencyAttrib::make(TransparencyAttrib::M_none), TransparencyAttrib::make(TransparencyAttrib::M_none),
RenderState::get_max_priority()); RenderState::get_max_priority());
} }
return state; return state.p();
} }
#ifndef NDEBUG #ifndef NDEBUG
@ -465,7 +474,7 @@ apply_flash_color(CPT(RenderState) &state, const LColor &flash_color) {
// Description: Returns a RenderState that renders only the // Description: Returns a RenderState that renders only the
// transparent parts of an object, in support of M_dual. // transparent parts of an object, in support of M_dual.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
CPT(RenderState) CullResult:: const RenderState *CullResult::
get_dual_transparent_state() { get_dual_transparent_state() {
static CPT(RenderState) state = NULL; static CPT(RenderState) state = NULL;
if (state == (const RenderState *)NULL) { if (state == (const RenderState *)NULL) {
@ -495,12 +504,12 @@ get_dual_transparent_state() {
flash_state = flash_state->add_attrib(AlphaTestAttrib::make(AlphaTestAttrib::M_less, 1.0f), flash_state = flash_state->add_attrib(AlphaTestAttrib::make(AlphaTestAttrib::M_less, 1.0f),
RenderState::get_max_priority()); RenderState::get_max_priority());
} }
return flash_state; return flash_state.p();
} }
} }
#endif // NDEBUG #endif // NDEBUG
return state; return state.p();
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -509,7 +518,7 @@ get_dual_transparent_state() {
// Description: Returns a RenderState that renders only the // Description: Returns a RenderState that renders only the
// opaque parts of an object, in support of M_dual. // opaque parts of an object, in support of M_dual.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
CPT(RenderState) CullResult:: const RenderState *CullResult::
get_dual_opaque_state() { get_dual_opaque_state() {
static CPT(RenderState) state = NULL; static CPT(RenderState) state = NULL;
if (state == (const RenderState *)NULL) { if (state == (const RenderState *)NULL) {
@ -530,12 +539,26 @@ get_dual_opaque_state() {
RenderState::get_max_priority()); RenderState::get_max_priority());
} }
return flash_state; return flash_state.p();
} }
} }
#endif // NDEBUG #endif // NDEBUG
return state; return state.p();
}
////////////////////////////////////////////////////////////////////
// Function: CullResult::get_wireframe_filled_state
// Access: Private
// Description: Returns a RenderState that is composed with the
// filled part of an M_filled_wireframe model.
////////////////////////////////////////////////////////////////////
const RenderState *CullResult::
get_wireframe_filled_state() {
static CPT(RenderState) state = RenderState::make(
RenderModeAttrib::make(RenderModeAttrib::M_filled),
RenderState::get_max_priority());
return state.p();
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -26,6 +26,7 @@
#include "pvector.h" #include "pvector.h"
#include "pset.h" #include "pset.h"
#include "pmap.h" #include "pmap.h"
#include "rescaleNormalAttrib.h"
class CullTraverser; class CullTraverser;
class GraphicsStateGuardianBase; class GraphicsStateGuardianBase;
@ -74,10 +75,12 @@ private:
void apply_flash_color(CPT(RenderState) &state, const LColor &flash_color); void apply_flash_color(CPT(RenderState) &state, const LColor &flash_color);
#endif #endif
static CPT(RenderState) get_alpha_state(); static const RenderState *get_rescale_normal_state(RescaleNormalAttrib::Mode mode);
static CPT(RenderState) get_binary_state(); static const RenderState *get_alpha_state();
static CPT(RenderState) get_dual_transparent_state(); static const RenderState *get_binary_state();
static CPT(RenderState) get_dual_opaque_state(); static const RenderState *get_dual_transparent_state();
static const RenderState *get_dual_opaque_state();
static const RenderState *get_wireframe_filled_state();
static CPT(RenderState) get_wireframe_overlay_state(const RenderModeAttrib *rmode); static CPT(RenderState) get_wireframe_overlay_state(const RenderModeAttrib *rmode);
GraphicsStateGuardianBase *_gsg; GraphicsStateGuardianBase *_gsg;

View File

@ -136,7 +136,9 @@ munge_geom(GraphicsStateGuardianBase *gsg,
if (_state->get_attrib(sattr) && sattr->auto_shader()) { if (_state->get_attrib(sattr) && sattr->auto_shader()) {
GeomVertexDataPipelineReader data_reader(_munged_data, current_thread); GeomVertexDataPipelineReader data_reader(_munged_data, current_thread);
if (data_reader.get_format()->get_animation().get_animation_type() == Geom::AT_hardware) { if (data_reader.get_format()->get_animation().get_animation_type() == Geom::AT_hardware) {
_state = _state->set_attrib(sattr->set_flag(ShaderAttrib::F_hardware_skinning, true)); static CPT(RenderState) state = RenderState::make(
DCAST(ShaderAttrib, ShaderAttrib::make())->set_flag(ShaderAttrib::F_hardware_skinning, true));
_state = _state->compose(state);
} }
} }