refinements to multitexReducer

This commit is contained in:
David Rose 2004-12-10 22:38:21 +00:00
parent 11a5aa7a00
commit 1a6e7ff58b
7 changed files with 114 additions and 21 deletions

View File

@ -17,6 +17,26 @@
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: MultitexReducer::scan
// Access: Published
// Description: Starts scanning the hierarchy beginning at the
// indicated node. Any GeomNodes discovered in the
// hierarchy with multitexture will be added to internal
// structures in the MultitexReducer so that a future
// call to flatten() will operate on all of these at
// once.
//
// This version of this method does not accumulate state
// from the parents of the indicated node; thus, only
// multitexture effects that have been applied at node
// and below will be considered.
////////////////////////////////////////////////////////////////////
INLINE void MultitexReducer::
scan(const NodePath &node) {
scan(node.node(), RenderState::make_empty(), TransformState::make_identity());
}
////////////////////////////////////////////////////////////////////
// Function: MultitexReducer::scan
// Access: Published
@ -29,19 +49,20 @@
//
// The second parameter represents the NodePath from
// which to accumulate the state that is considered for
// the multitexture. The default is to accumulate all
// the state from the root of the graph, but you may
// specify some other node here in order to not consider
// nodes above that as contributing to the state to be
// flattened. This is particularly useful if you have
// some texture stage which is applied globally to a
// scene (for instance, a caustics effect), which you
// don't want to be considered for flattening by the
// MultitexReducer.
// the multitexture. Pass an empty NodePath to
// accumulate all the state from the root of the graph,
// or you may specify some other node here in order to
// not consider nodes above that as contributing to the
// state to be flattened. This is particularly useful
// if you have some texture stage which is applied
// globally to a scene (for instance, a caustics
// effect), which you don't want to be considered for
// flattening by the MultitexReducer.
////////////////////////////////////////////////////////////////////
INLINE void MultitexReducer::
scan(const NodePath &node, const NodePath &state_from) {
scan(node.node(), node.get_state(state_from), node.get_transform(state_from));
scan(node.node(), node.get_parent().get_state(state_from),
node.get_parent().get_transform(state_from));
}
////////////////////////////////////////////////////////////////////

View File

@ -30,6 +30,7 @@
#include "colorAttrib.h"
#include "colorScaleAttrib.h"
#include "colorBlendAttrib.h"
#include "textureAttrib.h"
#include "config_grutil.h"
#include "config_gobj.h"
#include "dcast.h"
@ -83,9 +84,20 @@ clear() {
////////////////////////////////////////////////////////////////////
void MultitexReducer::
scan(PandaNode *node, const RenderState *state, const TransformState *transform) {
if (grutil_cat.is_debug()) {
grutil_cat.debug()
<< "scan(" << *node << ", " << *state << ", " << *transform << ")\n";
}
CPT(RenderState) next_state = state->compose(node->get_state());
CPT(TransformState) next_transform = transform->compose(node->get_transform());
// We must turn off any textures we come across in the scan()
// operation, since the flattened texture will be applied to the
// Geoms after the flatten() operation, and we don't want to still
// have a multitexture specified.
node->set_state(node->get_state()->remove_attrib(TextureAttrib::get_class_type()));
if (node->is_geom_node()) {
scan_geom_node(DCAST(GeomNode, node), next_state, next_transform);
}
@ -271,6 +283,7 @@ flatten(GraphicsOutput *window) {
render.set_bin("unsorted", 0);
render.set_depth_test(false);
render.set_depth_write(false);
render.set_two_sided(1);
NodePath cam = render.attach_new_node(cam_node);
dr->set_camera(cam);
@ -317,7 +330,18 @@ flatten(GraphicsOutput *window) {
// disable coloring on the new fragment (the color has been
// baked into the texture).
geom_state = geom_state->add_attrib(ColorAttrib::make_flat(Colorf(1.0f, 1.0f, 1.0f, 1.0f)));
geom_state = geom_state->add_attrib(ColorScaleAttrib::make_off());
// And we invent a ColorScaleAttrib to undo the effect of any
// color scale we're getting from above. This is not the same
// thing as a ColorScaleAttrib::make_off(), since that would
// prohibit any future changes to the color scale.
const RenderAttrib *attrib =
geom_info._geom_net_state->get_attrib(ColorScaleAttrib::get_class_type());
if (attrib != (const RenderAttrib *)NULL) {
geom_state = geom_state->add_attrib
(attrib->invert_compose(ColorScaleAttrib::make_identity()));
}
}
// Determine what tex matrix should be on the Geom.
@ -739,11 +763,11 @@ transfer_geom(GeomNode *geom_node, const TexCoordName *texcoord_name,
// Be sure to preserve whatever colors are on the geom.
const RenderAttrib *ca = geom_info._geom_net_state->get_attrib(ColorAttrib::get_class_type());
if (ca != (const RenderAttrib *)NULL) {
geom_state->add_attrib(ca);
geom_state = geom_state->add_attrib(ca);
}
const RenderAttrib *csa = geom_info._geom_net_state->get_attrib(ColorScaleAttrib::get_class_type());
if (csa != (const RenderAttrib *)NULL) {
geom_state->add_attrib(csa);
geom_state = geom_state->add_attrib(csa);
}
}

View File

@ -59,7 +59,8 @@ PUBLISHED:
~MultitexReducer();
void clear();
INLINE void scan(const NodePath &node, const NodePath &state_from = NodePath());
INLINE void scan(const NodePath &node);
INLINE void scan(const NodePath &node, const NodePath &state_from);
void scan(PandaNode *node, const RenderState *state,
const TransformState *transform);

View File

@ -59,11 +59,24 @@ is_off() const {
return _off;
}
////////////////////////////////////////////////////////////////////
// Function: ColorScaleAttrib::is_identity
// Access: Published
// Description: Returns true if the ColorScaleAttrib is an identity
// attrib, false if it is either an off attrib or it has
// a scale.
////////////////////////////////////////////////////////////////////
INLINE bool ColorScaleAttrib::
is_identity() const {
return !_off && !_has_scale;
}
////////////////////////////////////////////////////////////////////
// Function: ColorScaleAttrib::has_scale
// Access: Published
// Description: Returns true if the ColorScaleAttrib has a
// non-identity scale, false otherwise.
// non-identity scale, false otherwise (in which case it
// might be an off attrib or an identity attrib).
////////////////////////////////////////////////////////////////////
INLINE bool ColorScaleAttrib::
has_scale() const {

View File

@ -26,6 +26,24 @@
#include "config_pgraph.h"
TypeHandle ColorScaleAttrib::_type_handle;
CPT(RenderAttrib) ColorScaleAttrib::_identity_attrib;
////////////////////////////////////////////////////////////////////
// Function: ColorScaleAttrib::make_identity
// Access: Published, Static
// Description: Constructs an identity scale attrib.
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ColorScaleAttrib::
make_identity() {
// We make identity a special case and store a pointer forever once
// we find it the first time.
if (_identity_attrib == (ColorScaleAttrib *)NULL) {
ColorScaleAttrib *attrib = new ColorScaleAttrib(false, LVecBase4f(1.0f, 1.0f, 1.0f, 1.0f));;
_identity_attrib = return_new(attrib);
}
return _identity_attrib;
}
////////////////////////////////////////////////////////////////////
// Function: ColorScaleAttrib::make
@ -95,6 +113,9 @@ output(ostream &out) const {
}
if (has_scale()) {
out << "(" << get_scale() << ")";
} else if (!is_off()) {
out << "identity";
}
}

View File

@ -37,10 +37,12 @@ protected:
INLINE ColorScaleAttrib(const ColorScaleAttrib &copy);
PUBLISHED:
static CPT(RenderAttrib) make_identity();
static CPT(RenderAttrib) make(const LVecBase4f &scale);
static CPT(RenderAttrib) make_off();
INLINE bool is_off() const;
INLINE bool is_identity() const;
INLINE bool has_scale() const;
INLINE const LVecBase4f &get_scale() const;
CPT(RenderAttrib) set_scale(const LVecBase4f &scale) const;
@ -59,6 +61,7 @@ private:
bool _off;
bool _has_scale;
LVecBase4f _scale;
static CPT(RenderAttrib) _identity_attrib;
public:
static void register_with_read_factory();

View File

@ -108,14 +108,24 @@ event_2(CPT_Event event, void *) {
void
event_0(CPT_Event event, void *) {
// 0: run hacky test.
MultitexReducer mr;
mr.set_use_geom(true);
static bool first = true;
mr.scan(framework.get_models());
if (first) {
cerr << "applying scale\n";
framework.get_models().set_color_scale(0.7, 0.7, 0.1, 1.0);
first = false;
WindowFramework *wf = framework.get_window(0);
GraphicsWindow *win = wf->get_graphics_window();
mr.flatten(win);
} else {
cerr << "flattening\n";
MultitexReducer mr;
mr.set_use_geom(true);
mr.scan(framework.get_models());
WindowFramework *wf = framework.get_window(0);
GraphicsWindow *win = wf->get_graphics_window();
mr.flatten(win);
}
}
void