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();
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.
const RescaleNormalAttrib *rescale;
state->get_attrib_def(rescale);
object->_state->get_attrib_def(rescale);
if (rescale->get_mode() == RescaleNormalAttrib::M_auto) {
RescaleNormalAttrib::Mode mode;
@ -140,24 +137,23 @@ add_object(CullableObject *object, const CullTraverser *traverser) {
mode = RescaleNormalAttrib::M_normalize;
}
state = state->set_attrib(RescaleNormalAttrib::make(mode));
object->_state = state;
object->_state = object->_state->compose(get_rescale_normal_state(mode));
}
// Check to see if there's a special transparency setting.
const TransparencyAttrib *trans;
if (state->get_attrib(trans)) {
if (object->_state->get_attrib(trans)) {
switch (trans->get_mode()) {
case TransparencyAttrib::M_alpha:
// M_alpha implies an alpha-write test, so we don't waste time
// 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);
break;
case TransparencyAttrib::M_binary:
// 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);
break;
@ -166,7 +162,7 @@ add_object(CullableObject *object, const CullTraverser *traverser) {
// The multisample modes are implemented using M_binary if the
// GSG in use doesn't support 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);
break;
@ -174,7 +170,6 @@ add_object(CullableObject *object, const CullTraverser *traverser) {
case TransparencyAttrib::M_dual:
#ifndef NDEBUG
check_flash_transparency(object->_state, flash_dual_color);
state = object->_state;
#endif
if (!m_dual) {
// 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
// to M_alpha.
{
const CullBinAttrib *bin_attrib = (const CullBinAttrib *)
state->get_attrib(CullBinAttrib::get_class_slot());
if (bin_attrib == (CullBinAttrib *)NULL ||
const CullBinAttrib *bin_attrib;
if (!object->_state->get_attrib(bin_attrib) ||
bin_attrib->get_bin_name().empty()) {
// We make a copy of the object to draw the transparent part;
// this gets placed in the transparent bin.
@ -201,7 +194,7 @@ add_object(CullableObject *object, const CullTraverser *traverser) {
{
CullableObject *transparent_part = new CullableObject(*object);
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
(_gsg, _gsg->get_geom_munger(transparent_part->_state, current_thread),
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
// the opaque bin.
object->_state = state->compose(get_dual_opaque_state());
object->_state = object->_state->compose(get_dual_opaque_state());
#ifndef NDEBUG
if (!m_dual_opaque) {
delete object;
@ -255,7 +248,7 @@ add_object(CullableObject *object, const CullTraverser *traverser) {
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;
}
////////////////////////////////////////////////////////////////////
// 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
// Access: Private
// Description: Returns a RenderState that changes the alpha test to
// > 0, for implementing M_alpha.
////////////////////////////////////////////////////////////////////
CPT(RenderState) CullResult::
const RenderState *CullResult::
get_alpha_state() {
static CPT(RenderState) state = NULL;
if (state == (const RenderState *)NULL) {
@ -418,7 +427,7 @@ get_alpha_state() {
// user to override this if he desires.
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
// M_binary.
////////////////////////////////////////////////////////////////////
CPT(RenderState) CullResult::
const RenderState *CullResult::
get_binary_state() {
static CPT(RenderState) state = NULL;
if (state == (const RenderState *)NULL) {
@ -435,7 +444,7 @@ get_binary_state() {
TransparencyAttrib::make(TransparencyAttrib::M_none),
RenderState::get_max_priority());
}
return state;
return state.p();
}
#ifndef NDEBUG
@ -465,7 +474,7 @@ apply_flash_color(CPT(RenderState) &state, const LColor &flash_color) {
// Description: Returns a RenderState that renders only the
// transparent parts of an object, in support of M_dual.
////////////////////////////////////////////////////////////////////
CPT(RenderState) CullResult::
const RenderState *CullResult::
get_dual_transparent_state() {
static CPT(RenderState) state = 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),
RenderState::get_max_priority());
}
return flash_state;
return flash_state.p();
}
}
#endif // NDEBUG
return state;
return state.p();
}
////////////////////////////////////////////////////////////////////
@ -509,7 +518,7 @@ get_dual_transparent_state() {
// Description: Returns a RenderState that renders only the
// opaque parts of an object, in support of M_dual.
////////////////////////////////////////////////////////////////////
CPT(RenderState) CullResult::
const RenderState *CullResult::
get_dual_opaque_state() {
static CPT(RenderState) state = NULL;
if (state == (const RenderState *)NULL) {
@ -530,12 +539,26 @@ get_dual_opaque_state() {
RenderState::get_max_priority());
}
return flash_state;
return flash_state.p();
}
}
#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 "pset.h"
#include "pmap.h"
#include "rescaleNormalAttrib.h"
class CullTraverser;
class GraphicsStateGuardianBase;
@ -74,10 +75,12 @@ private:
void apply_flash_color(CPT(RenderState) &state, const LColor &flash_color);
#endif
static CPT(RenderState) get_alpha_state();
static CPT(RenderState) get_binary_state();
static CPT(RenderState) get_dual_transparent_state();
static CPT(RenderState) get_dual_opaque_state();
static const RenderState *get_rescale_normal_state(RescaleNormalAttrib::Mode mode);
static const RenderState *get_alpha_state();
static const RenderState *get_binary_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);
GraphicsStateGuardianBase *_gsg;

View File

@ -136,7 +136,9 @@ munge_geom(GraphicsStateGuardianBase *gsg,
if (_state->get_attrib(sattr) && sattr->auto_shader()) {
GeomVertexDataPipelineReader data_reader(_munged_data, current_thread);
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);
}
}