mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-05 03:15:07 -04:00
saner treatment of ColorAttrib
This commit is contained in:
parent
cb2819a5d7
commit
e0c65512aa
@ -40,10 +40,7 @@ ColorAttrib(ColorAttrib::Type type, const Colorf &color) :
|
|||||||
// ColorAttrib for all geometry. You can get this
|
// ColorAttrib for all geometry. You can get this
|
||||||
// color via get_color().
|
// color via get_color().
|
||||||
//
|
//
|
||||||
// T_off - do not issue any color commands at all.
|
// T_off - use the color white.
|
||||||
// This is generally used only in contexts where the
|
|
||||||
// color is meaningless, e.g. when drawing directly to
|
|
||||||
// the depth buffer.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE ColorAttrib::Type ColorAttrib::
|
INLINE ColorAttrib::Type ColorAttrib::
|
||||||
get_color_type() const {
|
get_color_type() const {
|
||||||
@ -53,9 +50,9 @@ get_color_type() const {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: ColorAttrib::get_color
|
// Function: ColorAttrib::get_color
|
||||||
// Access: Published
|
// Access: Published
|
||||||
// Description: If the type is T_flat, this returns the color that
|
// Description: If the type is T_flat or T_off, this returns the
|
||||||
// will be applied to geometry. If the type is anything
|
// color that will be applied to geometry. If the type
|
||||||
// else, this is meaningless.
|
// is T_vertex, this is meaningless.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE const Colorf &ColorAttrib::
|
INLINE const Colorf &ColorAttrib::
|
||||||
get_color() const {
|
get_color() const {
|
||||||
|
@ -37,7 +37,7 @@ make_vertex() {
|
|||||||
if (_vertex != 0) {
|
if (_vertex != 0) {
|
||||||
return _vertex;
|
return _vertex;
|
||||||
}
|
}
|
||||||
ColorAttrib *attrib = new ColorAttrib(T_vertex);
|
ColorAttrib *attrib = new ColorAttrib(T_vertex, Colorf::zero());
|
||||||
_vertex = return_new(attrib);
|
_vertex = return_new(attrib);
|
||||||
return _vertex;
|
return _vertex;
|
||||||
}
|
}
|
||||||
@ -58,15 +58,14 @@ make_flat(const Colorf &color) {
|
|||||||
// Function: ColorAttrib::make_off
|
// Function: ColorAttrib::make_off
|
||||||
// Access: Published, Static
|
// Access: Published, Static
|
||||||
// Description: Constructs a new ColorAttrib object that indicates
|
// Description: Constructs a new ColorAttrib object that indicates
|
||||||
// geometry should be rendered without any color
|
// geometry should be rendered in white.
|
||||||
// commands at all.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
CPT(RenderAttrib) ColorAttrib::
|
CPT(RenderAttrib) ColorAttrib::
|
||||||
make_off() {
|
make_off() {
|
||||||
if (_off != 0) {
|
if (_off != 0) {
|
||||||
return _off;
|
return _off;
|
||||||
}
|
}
|
||||||
ColorAttrib *attrib = new ColorAttrib(T_off);
|
ColorAttrib *attrib = new ColorAttrib(T_off, Colorf(1.0f, 1.0f, 1.0f, 1.0f));
|
||||||
_off = return_new(attrib);
|
_off = return_new(attrib);
|
||||||
return _off;
|
return _off;
|
||||||
}
|
}
|
||||||
@ -80,7 +79,7 @@ make_off() {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
CPT(RenderAttrib) ColorAttrib::
|
CPT(RenderAttrib) ColorAttrib::
|
||||||
make_default() {
|
make_default() {
|
||||||
return make_flat(Colorf(1.0f, 1.0f, 1.0f, 1.0f));
|
return make_off();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -143,10 +142,22 @@ compare_to_impl(const RenderAttrib *other) const {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void ColorAttrib::
|
void ColorAttrib::
|
||||||
quantize_color() {
|
quantize_color() {
|
||||||
|
switch (_type) {
|
||||||
|
case T_flat:
|
||||||
_color[0] = cfloor(_color[0] * 1000.0f + 0.5f) * 0.001f;
|
_color[0] = cfloor(_color[0] * 1000.0f + 0.5f) * 0.001f;
|
||||||
_color[1] = cfloor(_color[1] * 1000.0f + 0.5f) * 0.001f;
|
_color[1] = cfloor(_color[1] * 1000.0f + 0.5f) * 0.001f;
|
||||||
_color[2] = cfloor(_color[2] * 1000.0f + 0.5f) * 0.001f;
|
_color[2] = cfloor(_color[2] * 1000.0f + 0.5f) * 0.001f;
|
||||||
_color[3] = cfloor(_color[3] * 1000.0f + 0.5f) * 0.001f;
|
_color[3] = cfloor(_color[3] * 1000.0f + 0.5f) * 0.001f;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case T_off:
|
||||||
|
_color.set(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case T_vertex:
|
||||||
|
_color.set(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -184,7 +195,7 @@ write_datagram(BamWriter *manager, Datagram &dg) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
TypedWritable *ColorAttrib::
|
TypedWritable *ColorAttrib::
|
||||||
make_from_bam(const FactoryParams ¶ms) {
|
make_from_bam(const FactoryParams ¶ms) {
|
||||||
ColorAttrib *attrib = new ColorAttrib;
|
ColorAttrib *attrib = new ColorAttrib(T_off, Colorf::zero());
|
||||||
DatagramIterator scan;
|
DatagramIterator scan;
|
||||||
BamReader *manager;
|
BamReader *manager;
|
||||||
|
|
||||||
|
@ -34,8 +34,7 @@ PUBLISHED:
|
|||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
INLINE ColorAttrib(Type type = T_vertex,
|
INLINE ColorAttrib(Type type, const Colorf &color);
|
||||||
const Colorf &color = Colorf(0.0f, 0.0f, 0.0f, 1.0f));
|
|
||||||
|
|
||||||
PUBLISHED:
|
PUBLISHED:
|
||||||
static CPT(RenderAttrib) make_vertex();
|
static CPT(RenderAttrib) make_vertex();
|
||||||
|
@ -134,17 +134,12 @@ apply_attribs_to_vertices(const AccumulatedAttribs &attribs, int attrib_types,
|
|||||||
|
|
||||||
if ((attrib_types & SceneGraphReducer::TT_color) != 0) {
|
if ((attrib_types & SceneGraphReducer::TT_color) != 0) {
|
||||||
CPT(RenderAttrib) ra = geom_attribs._color;
|
CPT(RenderAttrib) ra = geom_attribs._color;
|
||||||
|
if (ra != (const RenderAttrib *)NULL) {
|
||||||
int override = geom_attribs._color_override;
|
int override = geom_attribs._color_override;
|
||||||
if (ra == (const RenderAttrib *)NULL) {
|
|
||||||
// If we don't have a color attrib, implicitly apply the
|
|
||||||
// "off" attrib. But use an override of -1, so we don't
|
|
||||||
// replace a color attrib already on the Geom state.
|
|
||||||
ra = ColorAttrib::make_off();
|
|
||||||
override = -1;
|
|
||||||
}
|
|
||||||
entry->_state = entry->_state->add_attrib(ra, override);
|
entry->_state = entry->_state->add_attrib(ra, override);
|
||||||
|
}
|
||||||
|
|
||||||
ra = entry->_state->get_attrib(ColorAttrib::get_class_slot());
|
ra = entry->_state->get_attrib_def(ColorAttrib::get_class_slot());
|
||||||
const ColorAttrib *ca = DCAST(ColorAttrib, ra);
|
const ColorAttrib *ca = DCAST(ColorAttrib, ra);
|
||||||
if (ca->get_color_type() != ColorAttrib::T_vertex) {
|
if (ca->get_color_type() != ColorAttrib::T_vertex) {
|
||||||
if (transformer.remove_column(new_geom, InternalName::get_color())) {
|
if (transformer.remove_column(new_geom, InternalName::get_color())) {
|
||||||
@ -160,8 +155,7 @@ apply_attribs_to_vertices(const AccumulatedAttribs &attribs, int attrib_types,
|
|||||||
// Now, if we have an "off" or "flat" color attribute, we
|
// Now, if we have an "off" or "flat" color attribute, we
|
||||||
// simply modify the color attribute, and leave the
|
// simply modify the color attribute, and leave the
|
||||||
// vertices alone.
|
// vertices alone.
|
||||||
const RenderAttrib *ra = entry->_state->get_attrib(ColorAttrib::get_class_slot());
|
const RenderAttrib *ra = entry->_state->get_attrib_def(ColorAttrib::get_class_slot());
|
||||||
if (ra != (const RenderAttrib *)NULL) {
|
|
||||||
const ColorAttrib *ca = DCAST(ColorAttrib, ra);
|
const ColorAttrib *ca = DCAST(ColorAttrib, ra);
|
||||||
if (ca->get_color_type() == ColorAttrib::T_off) {
|
if (ca->get_color_type() == ColorAttrib::T_off) {
|
||||||
entry->_state = entry->_state->set_attrib(ColorAttrib::make_vertex());
|
entry->_state = entry->_state->set_attrib(ColorAttrib::make_vertex());
|
||||||
@ -188,7 +182,6 @@ apply_attribs_to_vertices(const AccumulatedAttribs &attribs, int attrib_types,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if ((attrib_types & SceneGraphReducer::TT_tex_matrix) != 0) {
|
if ((attrib_types & SceneGraphReducer::TT_tex_matrix) != 0) {
|
||||||
if (geom_attribs._tex_matrix != (const RenderAttrib *)NULL) {
|
if (geom_attribs._tex_matrix != (const RenderAttrib *)NULL) {
|
||||||
|
@ -819,26 +819,6 @@ remove_column(GeomNode *node, const InternalName *column) {
|
|||||||
// RenderStates the same. It does this by
|
// RenderStates the same. It does this by
|
||||||
// canonicalizing the ColorAttribs, and in the future,
|
// canonicalizing the ColorAttribs, and in the future,
|
||||||
// possibly other attribs.
|
// possibly other attribs.
|
||||||
//
|
|
||||||
// This implementation is not very smart yet. It
|
|
||||||
// unnecessarily canonicalizes ColorAttribs even if
|
|
||||||
// this will not yield compatible RenderStates. A
|
|
||||||
// better algorithm would:
|
|
||||||
//
|
|
||||||
// - each geom already starts with an original
|
|
||||||
// RenderState. In addition to this, calculate for
|
|
||||||
// each geom a canonical RenderState.
|
|
||||||
//
|
|
||||||
// - maintain a table mapping canonical RenderState
|
|
||||||
// to a list of geoms.
|
|
||||||
//
|
|
||||||
// - for each group of geoms with the same
|
|
||||||
// canonical renderstate, see if they already have
|
|
||||||
// matching RenderStates.
|
|
||||||
//
|
|
||||||
// - If they have differing RenderStates, then
|
|
||||||
// actually canonicalize the geoms.
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool GeomTransformer::
|
bool GeomTransformer::
|
||||||
make_compatible_state(GeomNode *node) {
|
make_compatible_state(GeomNode *node) {
|
||||||
@ -851,14 +831,15 @@ make_compatible_state(GeomNode *node) {
|
|||||||
PT(GeomNode::GeomList) geoms = cdata->modify_geoms();
|
PT(GeomNode::GeomList) geoms = cdata->modify_geoms();
|
||||||
|
|
||||||
// For each geom, calculate a canonicalized RenderState, and
|
// For each geom, calculate a canonicalized RenderState, and
|
||||||
// classify all the geoms according to that.
|
// classify all the geoms according to that. By "canonicalize"
|
||||||
|
// here, we simply mean removing the ColorAttrib.
|
||||||
|
|
||||||
typedef pmap <CPT(RenderState), pvector<int> > StateTable;
|
typedef pmap <CPT(RenderState), pvector<int> > StateTable;
|
||||||
StateTable state_table;
|
StateTable state_table;
|
||||||
|
|
||||||
for (int i = 0; i < (int)geoms->size(); i++) {
|
for (int i = 0; i < (int)geoms->size(); i++) {
|
||||||
GeomNode::GeomEntry &entry = (*geoms)[i];
|
GeomNode::GeomEntry &entry = (*geoms)[i];
|
||||||
CPT(RenderState) canon = entry._state->add_attrib(ColorAttrib::make_vertex(), -1);
|
CPT(RenderState) canon = entry._state->remove_attrib(ColorAttrib::get_class_slot());
|
||||||
state_table[canon].push_back(i);
|
state_table[canon].push_back(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -871,7 +852,7 @@ make_compatible_state(GeomNode *node) {
|
|||||||
// If the geoms in the group already have the same RenderStates,
|
// If the geoms in the group already have the same RenderStates,
|
||||||
// then nothing needs to be done to this group.
|
// then nothing needs to be done to this group.
|
||||||
|
|
||||||
pvector<int> &indices = (*si).second;
|
const pvector<int> &indices = (*si).second;
|
||||||
bool mismatch = false;
|
bool mismatch = false;
|
||||||
for (int i = 1; i < (int)indices.size(); i++) {
|
for (int i = 1; i < (int)indices.size(); i++) {
|
||||||
if ((*geoms)[indices[i]]._state != (*geoms)[indices[0]]._state) {
|
if ((*geoms)[indices[i]]._state != (*geoms)[indices[0]]._state) {
|
||||||
@ -884,15 +865,13 @@ make_compatible_state(GeomNode *node) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The geoms do not have the same RenderState, but they could,
|
// The geoms do not have the same RenderState, but they could,
|
||||||
// since their canonicalized states are the same. Canonicalize them.
|
// since their canonicalized states are the same. Canonicalize
|
||||||
|
// them, by applying the colors to the vertices.
|
||||||
|
|
||||||
const RenderState *canon_state = (*si).first;
|
const RenderState *canon_state = (*si).first;
|
||||||
for (int i = 0; i < (int)indices.size(); i++) {
|
for (int i = 0; i < (int)indices.size(); i++) {
|
||||||
GeomNode::GeomEntry &entry = (*geoms)[indices[i]];
|
GeomNode::GeomEntry &entry = (*geoms)[indices[i]];
|
||||||
const RenderAttrib *ra = entry._state->get_attrib(ColorAttrib::get_class_slot());
|
const RenderAttrib *ra = entry._state->get_attrib_def(ColorAttrib::get_class_slot());
|
||||||
if (ra == (RenderAttrib *)NULL) {
|
|
||||||
ra = ColorAttrib::make_off();
|
|
||||||
}
|
|
||||||
const ColorAttrib *ca = DCAST(ColorAttrib, ra);
|
const ColorAttrib *ca = DCAST(ColorAttrib, ra);
|
||||||
if (ca->get_color_type() == ColorAttrib::T_vertex) {
|
if (ca->get_color_type() == ColorAttrib::T_vertex) {
|
||||||
// All we need to do is ensure that the geom has a color column.
|
// All we need to do is ensure that the geom has a color column.
|
||||||
@ -900,23 +879,21 @@ make_compatible_state(GeomNode *node) {
|
|||||||
PT(Geom) new_geom = entry._geom.get_read_pointer()->make_copy();
|
PT(Geom) new_geom = entry._geom.get_read_pointer()->make_copy();
|
||||||
if (set_color(new_geom, Colorf(1,1,1,1))) {
|
if (set_color(new_geom, Colorf(1,1,1,1))) {
|
||||||
entry._geom = new_geom;
|
entry._geom = new_geom;
|
||||||
any_changed = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Colorf c(1,1,1,1);
|
// A flat color (or "off", which is white). Set the vertices
|
||||||
if (ca->get_color_type() == ColorAttrib::T_flat) {
|
// to the indicated flat color.
|
||||||
c = ca->get_color();
|
Colorf c = ca->get_color();
|
||||||
}
|
|
||||||
PT(Geom) new_geom = entry._geom.get_read_pointer()->make_copy();
|
PT(Geom) new_geom = entry._geom.get_read_pointer()->make_copy();
|
||||||
if (set_color(new_geom, c)) {
|
if (set_color(new_geom, c)) {
|
||||||
entry._geom = new_geom;
|
entry._geom = new_geom;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
entry._state = canon_state->add_attrib(ColorAttrib::make_vertex());
|
||||||
any_changed = true;
|
any_changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
entry._state = canon_state;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return any_changed;
|
return any_changed;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user