fixes to MultitexReducer

This commit is contained in:
David Rose 2006-03-08 00:24:31 +00:00
parent c963a1c645
commit b7fd641aa9
10 changed files with 110 additions and 21 deletions

View File

@ -410,7 +410,7 @@ make_polyset(EggBin *egg_bin, PandaNode *parent, const LMatrix4d *transform,
////////////////////////////////////////////////////////////////////
// Function: EggLoader::make_transform
// Access: Public, Static
// Access: Public
// Description: Creates a TransformState object corresponding to the
// indicated EggTransform.
////////////////////////////////////////////////////////////////////
@ -525,7 +525,19 @@ make_transform(const EggTransform *egg_transform) {
}
}
return ts;
if (ts->components_given()) {
return ts;
}
// Finally, we uniquify all the matrix-based TransformStates we
// create by complete matrix value. The TransformState class
// doesn't normally go this far, because of the cost of this
// additional uniquification step, but this is the egg loader so we
// don't mind spending a little bit of extra time here to get a more
// optimal result.
TransformStates::iterator tsi = _transform_states.insert(TransformStates::value_type(ts->get_mat(), ts)).first;
return (*tsi).second;
}
////////////////////////////////////////////////////////////////////

View File

@ -81,7 +81,7 @@ public:
const LMatrix4d *transform, bool is_dynamic,
CharacterMaker *character_maker);
static CPT(TransformState) make_transform(const EggTransform *egg_transform);
CPT(TransformState) make_transform(const EggTransform *egg_transform);
private:
class TextureDef {
@ -228,6 +228,9 @@ private:
typedef pmap<VertexPoolTransform, PT(GeomVertexData) > VertexPoolData;
VertexPoolData _vertex_pool_data;
typedef pmap<LMatrix4f, CPT(TransformState) > TransformStates;
TransformStates _transform_states;
DeferredNodes _deferred_nodes;
public:

View File

@ -527,7 +527,7 @@ get_tex_gen(const EggTexture *egg_tex) {
////////////////////////////////////////////////////////////////////
// Function: EggRenderState::apply_tex_mat
// Access: Private, Static
// Access: Private
// Description: Applies the texture matrix from the indicated egg
// texture to the given TexMatrixAttrib, and returns the
// new attrib.
@ -536,7 +536,7 @@ CPT(RenderAttrib) EggRenderState::
apply_tex_mat(CPT(RenderAttrib) tex_mat_attrib,
TextureStage *stage, const EggTexture *egg_tex) {
if (egg_tex->has_transform()) {
CPT(TransformState) transform = EggLoader::make_transform(egg_tex);
CPT(TransformState) transform = _loader.make_transform(egg_tex);
if (tex_mat_attrib == (const RenderAttrib *)NULL) {
tex_mat_attrib = TexMatrixAttrib::make();

View File

@ -57,7 +57,7 @@ private:
bool bface);
static TexGenAttrib::Mode get_tex_gen(const EggTexture *egg_tex);
static CPT(RenderAttrib)
CPT(RenderAttrib)
apply_tex_mat(CPT(RenderAttrib) tex_mat_attrib,
TextureStage *stage, const EggTexture *egg_tex);

View File

@ -79,7 +79,7 @@ operator < (const MultitexReducer::StageInfo &other) const {
return _tex < other._tex;
}
if (_tex_mat != other._tex_mat) {
return _tex_mat < other._tex_mat;
return _tex_mat->sorts_less(*other._tex_mat, true);
}
return false;

View File

@ -328,7 +328,7 @@ flatten(GraphicsOutput *window) {
// for the first texture layer to apply onto.
CardMaker cm("background");
cm.set_frame(0.0f, 1.0f, 0.0f, 1.0f);
cm.set_frame(min_uv[0], max_uv[0], min_uv[1], max_uv[1]);
if (bake_in_color) {
cm.set_color(geom_color);
}
@ -348,7 +348,8 @@ flatten(GraphicsOutput *window) {
for (si = stage_list.begin(); si != stage_list.end(); ++si) {
const StageInfo &stage_info = (*si);
make_texture_layer(render, stage_info, geom_list, force_use_geom);
make_texture_layer(render, stage_info, geom_list,
min_uv, max_uv, force_use_geom);
}
// Now modify the geometry to apply the new texture, instead of
@ -362,7 +363,8 @@ flatten(GraphicsOutput *window) {
CPT(RenderState) geom_state =
geom_info._geom_node->get_geom_state(geom_info._index);
geom_state = geom_state->add_attrib(new_ta);
int override = geom_info._geom_net_state->get_override(TextureAttrib::get_class_type());
geom_state = geom_state->add_attrib(new_ta, override);
if (bake_in_color) {
// If we have baked the color into the texture, we have to be
@ -475,8 +477,9 @@ scan_geom_node(GeomNode *node, const RenderState *state,
// Just a single texture on the Geom; we don't really need to do
// anything to flatten the textures, then. But we should ensure
// that the correct TextureAttrib is applied to the Geom.
int override = geom_net_state->get_override(TextureAttrib::get_class_type());
CPT(RenderState) geom_state = node->get_geom_state(gi);
geom_state = geom_state->add_attrib(ta);
geom_state = geom_state->add_attrib(ta, override);
node->set_geom_state(gi, geom_state);
} else {
@ -734,6 +737,7 @@ void MultitexReducer::
make_texture_layer(const NodePath &render,
const MultitexReducer::StageInfo &stage_info,
const MultitexReducer::GeomList &geom_list,
const TexCoordf &min_uv, const TexCoordf &max_uv,
bool force_use_geom) {
CPT(RenderAttrib) cba;
@ -768,11 +772,56 @@ make_texture_layer(const NodePath &render,
break;
case TextureStage::M_combine:
// We don't support the texture combiner here right now. For now,
// this is the same as modulate.
cba = ColorBlendAttrib::make
(ColorBlendAttrib::M_add, ColorBlendAttrib::O_fbuffer_color,
ColorBlendAttrib::O_zero);
// We only support certain modes of M_combine.
switch (stage_info._stage->get_combine_rgb_mode()) {
case TextureStage::CM_modulate:
{
TextureStage::CombineSource source0 = stage_info._stage->get_combine_rgb_source0();
TextureStage::CombineOperand operand0 = stage_info._stage->get_combine_rgb_operand0();
TextureStage::CombineSource source1 = stage_info._stage->get_combine_rgb_source1();
TextureStage::CombineOperand operand1 = stage_info._stage->get_combine_rgb_operand1();
// Since modulate doesn't care about order, let's establish
// the convention that the lowest-numbered source
// operand is in slot 0 (just for purposes of comparison).
if (source1 < source0) {
source0 = stage_info._stage->get_combine_rgb_source1();
operand0 = stage_info._stage->get_combine_rgb_operand1();
source1 = stage_info._stage->get_combine_rgb_source0();
operand1 = stage_info._stage->get_combine_rgb_operand0();
}
if (source0 == TextureStage::CS_primary_color &&
source1 == TextureStage::CS_previous) {
// This is just a trick to re-apply the vertex (lighting)
// color on the top of the texture stack. We can ignore it,
// since the flattened texture will do this anyway.
return;
} else if (source0 == TextureStage::CS_texture &&
source1 == TextureStage::CS_constant) {
// Scaling the texture by a flat color.
cba = ColorBlendAttrib::make
(ColorBlendAttrib::M_add, ColorBlendAttrib::O_constant_color,
ColorBlendAttrib::O_zero, stage_info._stage->get_color());
} else if (source0 == TextureStage::CS_texture &&
source1 == TextureStage::CS_previous) {
// Just an ordinary modulate.
cba = ColorBlendAttrib::make
(ColorBlendAttrib::M_add, ColorBlendAttrib::O_fbuffer_color,
ColorBlendAttrib::O_zero);
} else {
// Some other kind of modulate; we don't support it.
return;
}
}
break;
default:
// Ignore this stage; we don't support it.
return;
}
break;
case TextureStage::M_blend_color_scale:
@ -790,9 +839,9 @@ make_texture_layer(const NodePath &render,
// If this TextureStage uses the target texcoords, we can just
// generate a simple card the fills the entire buffer.
CardMaker cm(stage_info._tex->get_name());
cm.set_uv_range(TexCoordf(0.0f, 0.0f), TexCoordf(1.0f, 1.0f));
cm.set_uv_range(min_uv, max_uv);
cm.set_has_uvs(true);
cm.set_frame(0.0f, 1.0f, 0.0f, 1.0f);
cm.set_frame(min_uv[0], max_uv[0], min_uv[1], max_uv[1]);
geom = render.attach_new_node(cm.generate());

View File

@ -138,6 +138,7 @@ private:
void make_texture_layer(const NodePath &render,
const StageInfo &stage_info,
const GeomList &geom_list,
const TexCoordf &min_uv, const TexCoordf &max_uv,
bool force_use_geom);
void transfer_geom(GeomNode *geom_node, const InternalName *texcoord_name,
const GeomList &geom_list, bool preserve_color);

View File

@ -17,6 +17,22 @@
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: TransformState::operator <
// Access: Published
// Description: Provides an arbitrary ordering among all unique
// TransformStates, so we can store the essentially
// different ones in a big set and throw away the rest.
//
// This is the same as sorts_less(), except the
// uniquify_matrix value is implicit from the Config.prc
// file.
////////////////////////////////////////////////////////////////////
INLINE bool TransformState::
operator < (const TransformState &other) const {
return sorts_less(other, uniquify_matrix);
}
////////////////////////////////////////////////////////////////////
// Function: TransformState::make_pos
// Access: Published, Static

View File

@ -110,14 +110,20 @@ TransformState::
}
////////////////////////////////////////////////////////////////////
// Function: TransformState::operator <
// Function: TransformState::sorts_less
// Access: Published
// Description: Provides an arbitrary ordering among all unique
// TransformStates, so we can store the essentially
// different ones in a big set and throw away the rest.
//
// If uniquify_matrix is true, then matrix-defined
// TransformStates are also uniqified. If
// uniquify_matrix is false, then only component-defined
// TransformStates are uniquified, which is less
// expensive.
////////////////////////////////////////////////////////////////////
bool TransformState::
operator < (const TransformState &other) const {
sorts_less(const TransformState &other, bool uniquify_matrix) const {
static const int significant_flags =
(F_is_invalid | F_is_identity | F_components_given | F_hpr_given | F_quat_given | F_is_2d);

View File

@ -30,6 +30,7 @@
#include "pStatCollector.h"
#include "geomEnums.h"
#include "reMutex.h"
#include "config_pgraph.h"
class GraphicsStateGuardianBase;
class FactoryParams;
@ -68,7 +69,8 @@ public:
virtual ~TransformState();
PUBLISHED:
bool operator < (const TransformState &other) const;
INLINE bool operator < (const TransformState &other) const;
bool sorts_less(const TransformState &other, bool uniquify_matrix) const;
size_t get_hash() const;
static CPT(TransformState) make_identity();