fixes to MultitexReducer
This commit is contained in:
parent
c963a1c645
commit
b7fd641aa9
|
|
@ -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;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
Loading…
Reference in New Issue