diff --git a/panda/src/egg2pg/qpeggLoader.cxx b/panda/src/egg2pg/qpeggLoader.cxx index 5a6a2672bb..0cc431bb6f 100644 --- a/panda/src/egg2pg/qpeggLoader.cxx +++ b/panda/src/egg2pg/qpeggLoader.cxx @@ -26,11 +26,11 @@ #include "textureAttrib.h" #include "textureApplyAttrib.h" #include "texturePool.h" -#include "billboardAttrib.h" +#include "billboardEffect.h" #include "cullFaceAttrib.h" #include "cullBinAttrib.h" #include "transparencyAttrib.h" -#include "decalAttrib.h" +#include "decalEffect.h" #include "depthTestAttrib.h" #include "depthWriteAttrib.h" #include "materialAttrib.h" @@ -197,8 +197,8 @@ reparent_decals() { } } - // Finally, set the DecalAttrib on the base geometry. - geom_parent.node()->set_attrib(DecalAttrib::make()); + // Finally, set the DecalEffect on the base geometry. + geom_parent.node()->set_effect(DecalEffect::make()); } } } @@ -1428,15 +1428,15 @@ create_group_arc(EggGroup *egg_group, PandaNode *parent, PandaNode *node) { // If the group has a billboard flag, apply that. switch (egg_group->get_billboard_type()) { case EggGroup::BT_point_camera_relative: - node->set_attrib(BillboardAttrib::make_point_eye()); + node->set_effect(BillboardEffect::make_point_eye()); break; case EggGroup::BT_point_world_relative: - node->set_attrib(BillboardAttrib::make_point_world()); + node->set_effect(BillboardEffect::make_point_world()); break; case EggGroup::BT_axis: - node->set_attrib(BillboardAttrib::make_axis()); + node->set_effect(BillboardEffect::make_axis()); break; case EggGroup::BT_none: diff --git a/panda/src/pgraph/Sources.pp b/panda/src/pgraph/Sources.pp index 9222afc3a8..044fca5cc0 100644 --- a/panda/src/pgraph/Sources.pp +++ b/panda/src/pgraph/Sources.pp @@ -6,7 +6,7 @@ #define TARGET pgraph #define SOURCES \ - billboardAttrib.h billboardAttrib.I \ + billboardEffect.h billboardEffect.I \ binCullHandler.h binCullHandler.I \ qpcamera.h qpcamera.I \ colorAttrib.h colorAttrib.I \ @@ -23,7 +23,7 @@ qpcullTraverser.h qpcullTraverser.I \ cullTraverserData.h cullTraverserData.I \ cullableObject.h cullableObject.I \ - decalAttrib.h decalAttrib.I \ + decalEffect.h decalEffect.I \ depthTestAttrib.h depthTestAttrib.I \ depthWriteAttrib.h depthWriteAttrib.I \ drawCullHandler.h drawCullHandler.I \ @@ -39,6 +39,8 @@ qpnodePathComponent.h qpnodePathComponent.I \ pandaNode.h pandaNode.I \ renderAttrib.h renderAttrib.I \ + renderEffect.h renderEffect.I \ + renderEffects.h renderEffects.I \ renderState.h renderState.I \ selectiveChildNode.h selectiveChildNode.I \ qpsequenceNode.h qpsequenceNode.I \ @@ -49,7 +51,7 @@ #define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx #define INCLUDED_SOURCES \ - billboardAttrib.cxx \ + billboardEffect.cxx \ binCullHandler.cxx \ qpcamera.cxx \ colorAttrib.cxx \ @@ -66,7 +68,7 @@ qpcullTraverser.cxx \ cullTraverserData.cxx \ cullableObject.cxx \ - decalAttrib.cxx \ + decalEffect.cxx \ depthTestAttrib.cxx \ depthWriteAttrib.cxx \ drawCullHandler.cxx \ @@ -82,6 +84,8 @@ qpnodePathComponent.cxx \ pandaNode.cxx \ renderAttrib.cxx \ + renderEffect.cxx \ + renderEffects.cxx \ renderState.cxx \ selectiveChildNode.cxx \ qpsequenceNode.cxx \ @@ -97,7 +101,7 @@ #endif #define INSTALL_HEADERS \ - billboardAttrib.h billboardAttrib.I \ + billboardEffect.h billboardEffect.I \ binCullHandler.h binCullHandler.I \ qpcamera.h qpcamera.I \ colorAttrib.h colorAttrib.I \ @@ -114,7 +118,7 @@ qpcullTraverser.h qpcullTraverser.I \ cullTraverserData.h cullTraverserData.I \ cullableObject.h cullableObject.I \ - decalAttrib.h decalAttrib.I \ + decalEffect.h decalEffect.I \ depthTestAttrib.h depthTestAttrib.I \ depthWriteAttrib.h depthWriteAttrib.I \ drawCullHandler.h drawCullHandler.I \ @@ -127,6 +131,8 @@ qpnodePathComponent.h qpnodePathComponent.I \ pandaNode.h pandaNode.I \ renderAttrib.h renderAttrib.I \ + renderEffect.h renderEffect.I \ + renderEffects.h renderEffects.I \ renderState.h renderState.I \ selectiveChildNode.h selectiveChildNode.I \ qpsequenceNode.h qpsequenceNode.I \ diff --git a/panda/src/pgraph/billboardAttrib.I b/panda/src/pgraph/billboardEffect.I similarity index 78% rename from panda/src/pgraph/billboardAttrib.I rename to panda/src/pgraph/billboardEffect.I index 7596b7f16c..8322561178 100644 --- a/panda/src/pgraph/billboardAttrib.I +++ b/panda/src/pgraph/billboardEffect.I @@ -1,5 +1,5 @@ -// Filename: billboardAttrib.I -// Created by: drose (27Feb02) +// Filename: billboardEffect.I +// Created by: drose (14Mar02) // //////////////////////////////////////////////////////////////////// // @@ -18,136 +18,136 @@ //////////////////////////////////////////////////////////////////// -// Function: BillboardAttrib::Constructor +// Function: BillboardEffect::Constructor // Access: Private -// Description: Use BillboardAttrib::make() to construct a new -// BillboardAttrib object. +// Description: Use BillboardEffect::make() to construct a new +// BillboardEffect object. //////////////////////////////////////////////////////////////////// -INLINE BillboardAttrib:: -BillboardAttrib() { +INLINE BillboardEffect:: +BillboardEffect() { _off = true; } //////////////////////////////////////////////////////////////////// -// Function: BillboardAttrib::make_axis +// Function: BillboardEffect::make_axis // Access: Published, Static // Description: A convenience function to make a typical // axis-rotating billboard. //////////////////////////////////////////////////////////////////// -INLINE CPT(RenderAttrib) BillboardAttrib:: +INLINE CPT(RenderEffect) BillboardEffect:: make_axis() { return make(LVector3f::up(), false, true, 0.0f, qpNodePath(), LPoint3f(0.0f, 0.0f, 0.0f)); } //////////////////////////////////////////////////////////////////// -// Function: BillboardAttrib::make_point_eye +// Function: BillboardEffect::make_point_eye // Access: Published, Static // Description: A convenience function to make a typical // eye-relative point-rotating billboard. //////////////////////////////////////////////////////////////////// -INLINE CPT(RenderAttrib) BillboardAttrib:: +INLINE CPT(RenderEffect) BillboardEffect:: make_point_eye() { return make(LVector3f::up(), true, false, 0.0f, qpNodePath(), LPoint3f(0.0f, 0.0f, 0.0f)); } //////////////////////////////////////////////////////////////////// -// Function: BillboardAttrib::make_point_world +// Function: BillboardEffect::make_point_world // Access: Published, Static // Description: A convenience function to make a typical // world-relative point-rotating billboard. //////////////////////////////////////////////////////////////////// -INLINE CPT(RenderAttrib) BillboardAttrib:: +INLINE CPT(RenderEffect) BillboardEffect:: make_point_world() { return make(LVector3f::up(), false, false, 0.0f, qpNodePath(), LPoint3f(0.0f, 0.0f, 0.0f)); } //////////////////////////////////////////////////////////////////// -// Function: BillboardAttrib::is_off +// Function: BillboardEffect::is_off // Access: Published -// Description: Returns true if the BillboardAttrib is an 'off' -// BillboardAttrib, indicating that it does not enable -// billboarding. This kind of BillboardAttrib isn't +// Description: Returns true if the BillboardEffect is an 'off' +// BillboardEffect, indicating that it does not enable +// billboarding. This kind of BillboardEffect isn't // particularly useful and isn't normally created or // stored in the graph; it might be implicitly // discovered as the result of a // qpNodePath::get_rel_state(). //////////////////////////////////////////////////////////////////// -INLINE bool BillboardAttrib:: +INLINE bool BillboardEffect:: is_off() const { return _off; } //////////////////////////////////////////////////////////////////// -// Function: BillboardAttrib::get_up_vector +// Function: BillboardEffect::get_up_vector // Access: Published // Description: Returns the up vector in effect for this billboard. //////////////////////////////////////////////////////////////////// -INLINE const LVector3f &BillboardAttrib:: +INLINE const LVector3f &BillboardEffect:: get_up_vector() const { return _up_vector; } //////////////////////////////////////////////////////////////////// -// Function: BillboardAttrib::get_eye_relative +// Function: BillboardEffect::get_eye_relative // Access: Published // Description: Returns true if this billboard interprets the up // vector relative to the camera, or false if it is // relative to the world. //////////////////////////////////////////////////////////////////// -INLINE bool BillboardAttrib:: +INLINE bool BillboardEffect:: get_eye_relative() const { return _eye_relative; } //////////////////////////////////////////////////////////////////// -// Function: BillboardAttrib::get_axial_rotate +// Function: BillboardEffect::get_axial_rotate // Access: Published // Description: Returns true if this billboard rotates only around // the axis of the up vector, or false if it rotates // freely in three dimensions. //////////////////////////////////////////////////////////////////// -INLINE bool BillboardAttrib:: +INLINE bool BillboardEffect:: get_axial_rotate() const { return _axial_rotate; } //////////////////////////////////////////////////////////////////// -// Function: BillboardAttrib::get_offset +// Function: BillboardEffect::get_offset // Access: Published // Description: Returns the distance toward the camera (or the // look_at_point) the billboard is moved towards, after // rotating. This can be used to ensure the billboard // is not obscured by nearby geometry. //////////////////////////////////////////////////////////////////// -INLINE float BillboardAttrib:: +INLINE float BillboardEffect:: get_offset() const { return _offset; } //////////////////////////////////////////////////////////////////// -// Function: BillboardAttrib::get_look_at +// Function: BillboardEffect::get_look_at // Access: Published // Description: Returns the node this billboard will rotate to look // towards. If this is empty, it means the billboard // will rotate towards the current camera node, wherever // that might be. //////////////////////////////////////////////////////////////////// -INLINE const qpNodePath &BillboardAttrib:: +INLINE const qpNodePath &BillboardEffect:: get_look_at() const { return _look_at; } //////////////////////////////////////////////////////////////////// -// Function: BillboardAttrib::get_look_at_point +// Function: BillboardEffect::get_look_at_point // Access: Published // Description: Returns the point, relative to the look_at node, // towards which the billboard will rotate. Normally // this is (0, 0, 0). //////////////////////////////////////////////////////////////////// -INLINE const LPoint3f &BillboardAttrib:: +INLINE const LPoint3f &BillboardEffect:: get_look_at_point() const { return _look_at_point; } diff --git a/panda/src/pgraph/billboardAttrib.cxx b/panda/src/pgraph/billboardEffect.cxx similarity index 73% rename from panda/src/pgraph/billboardAttrib.cxx rename to panda/src/pgraph/billboardEffect.cxx index 3ea196472f..d6d0a8639b 100644 --- a/panda/src/pgraph/billboardAttrib.cxx +++ b/panda/src/pgraph/billboardEffect.cxx @@ -1,5 +1,5 @@ -// Filename: billboardAttrib.cxx -// Created by: drose (27Feb02) +// Filename: billboardEffect.cxx +// Created by: drose (14Mar02) // //////////////////////////////////////////////////////////////////// // @@ -16,42 +16,54 @@ // //////////////////////////////////////////////////////////////////// -#include "billboardAttrib.h" +#include "billboardEffect.h" #include "look_at.h" #include "bamReader.h" #include "bamWriter.h" #include "datagram.h" #include "datagramIterator.h" -TypeHandle BillboardAttrib::_type_handle; +TypeHandle BillboardEffect::_type_handle; //////////////////////////////////////////////////////////////////// -// Function: BillboardAttrib::make +// Function: BillboardEffect::make // Access: Published, Static -// Description: Constructs a new BillboardAttrib object with the +// Description: Constructs a new BillboardEffect object with the // indicated properties. //////////////////////////////////////////////////////////////////// -CPT(RenderAttrib) BillboardAttrib:: +CPT(RenderEffect) BillboardEffect:: make(const LVector3f &up_vector, bool eye_relative, bool axial_rotate, float offset, const qpNodePath &look_at, const LPoint3f &look_at_point) { - BillboardAttrib *attrib = new BillboardAttrib; - attrib->_up_vector = up_vector; - attrib->_eye_relative = eye_relative; - attrib->_axial_rotate = axial_rotate; - attrib->_offset = offset; - attrib->_look_at = look_at; - attrib->_look_at_point = look_at_point; - attrib->_off = false; - return return_new(attrib); + BillboardEffect *effect = new BillboardEffect; + effect->_up_vector = up_vector; + effect->_eye_relative = eye_relative; + effect->_axial_rotate = axial_rotate; + effect->_offset = offset; + effect->_look_at = look_at; + effect->_look_at_point = look_at_point; + effect->_off = false; + return return_new(effect); } //////////////////////////////////////////////////////////////////// -// Function: BillboardAttrib::output +// Function: BillboardEffect::safe_to_combine +// Access: Public, Virtual +// Description: Returns true if this kind of effect can safely be +// combined with sibling nodes that share the exact same +// effect, or false if this is not a good idea. +//////////////////////////////////////////////////////////////////// +bool BillboardEffect:: +safe_to_combine() const { + return true; +} + +//////////////////////////////////////////////////////////////////// +// Function: BillboardEffect::output // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void BillboardAttrib:: +void BillboardEffect:: output(ostream &out) const { out << get_type() << ":"; if (is_off()) { @@ -82,13 +94,13 @@ output(ostream &out) const { } //////////////////////////////////////////////////////////////////// -// Function: BillboardAttrib::do_billboard +// Function: BillboardEffect::do_billboard // Access: Public // Description: Computes the appropriate transform to apply to the // billboarded geometry, given its current net // transform, and the camera's inverse net transform. //////////////////////////////////////////////////////////////////// -CPT(TransformState) BillboardAttrib:: +CPT(TransformState) BillboardEffect:: do_billboard(const TransformState *net_transform, const TransformState *camera_transform) const { // Determine the relative transform to our camera (or other look_at @@ -141,23 +153,23 @@ do_billboard(const TransformState *net_transform, } //////////////////////////////////////////////////////////////////// -// Function: BillboardAttrib::compare_to_impl +// Function: BillboardEffect::compare_to_impl // Access: Protected, Virtual -// Description: Intended to be overridden by derived BillboardAttrib +// Description: Intended to be overridden by derived BillboardEffect // types to return a unique number indicating whether -// this BillboardAttrib is equivalent to the other one. +// this BillboardEffect is equivalent to the other one. // -// This should return 0 if the two BillboardAttrib objects +// This should return 0 if the two BillboardEffect objects // are equivalent, a number less than zero if this one // should be sorted before the other one, and a number // greater than zero otherwise. // -// This will only be called with two BillboardAttrib +// This will only be called with two BillboardEffect // objects whose get_type() functions return the same. //////////////////////////////////////////////////////////////////// -int BillboardAttrib:: -compare_to_impl(const RenderAttrib *other) const { - const BillboardAttrib *ta; +int BillboardEffect:: +compare_to_impl(const RenderEffect *other) const { + const BillboardEffect *ta; DCAST_INTO_R(ta, other, 0); if (_axial_rotate != ta->_axial_rotate) { @@ -185,41 +197,41 @@ compare_to_impl(const RenderAttrib *other) const { } //////////////////////////////////////////////////////////////////// -// Function: BillboardAttrib::make_default_impl +// Function: BillboardEffect::make_default_impl // Access: Protected, Virtual -// Description: Intended to be overridden by derived BillboardAttrib +// Description: Intended to be overridden by derived BillboardEffect // types to specify what the default property for a -// BillboardAttrib of this type should be. +// BillboardEffect of this type should be. // -// This should return a newly-allocated BillboardAttrib of +// This should return a newly-allocated BillboardEffect of // the same type that corresponds to whatever the -// standard default for this kind of BillboardAttrib is. +// standard default for this kind of BillboardEffect is. //////////////////////////////////////////////////////////////////// -RenderAttrib *BillboardAttrib:: +RenderEffect *BillboardEffect:: make_default_impl() const { - return new BillboardAttrib; + return new BillboardEffect; } //////////////////////////////////////////////////////////////////// -// Function: BillboardAttrib::register_with_read_factory +// Function: BillboardEffect::register_with_read_factory // Access: Public, Static // Description: Tells the BamReader how to create objects of type -// BillboardAttrib. +// BillboardEffect. //////////////////////////////////////////////////////////////////// -void BillboardAttrib:: +void BillboardEffect:: register_with_read_factory() { BamReader::get_factory()->register_factory(get_class_type(), make_from_bam); } //////////////////////////////////////////////////////////////////// -// Function: BillboardAttrib::write_datagram +// Function: BillboardEffect::write_datagram // Access: Public, Virtual // Description: Writes the contents of this object to the datagram // for shipping out to a Bam file. //////////////////////////////////////////////////////////////////// -void BillboardAttrib:: +void BillboardEffect:: write_datagram(BamWriter *manager, Datagram &dg) { - RenderAttrib::write_datagram(manager, dg); + RenderEffect::write_datagram(manager, dg); dg.add_bool(_off); _up_vector.write_datagram(dg); @@ -233,35 +245,35 @@ write_datagram(BamWriter *manager, Datagram &dg) { } //////////////////////////////////////////////////////////////////// -// Function: BillboardAttrib::make_from_bam +// Function: BillboardEffect::make_from_bam // Access: Protected, Static // Description: This function is called by the BamReader's factory -// when a new object of type BillboardAttrib is encountered -// in the Bam file. It should create the BillboardAttrib +// when a new object of type BillboardEffect is encountered +// in the Bam file. It should create the BillboardEffect // and extract its information from the file. //////////////////////////////////////////////////////////////////// -TypedWritable *BillboardAttrib:: +TypedWritable *BillboardEffect:: make_from_bam(const FactoryParams ¶ms) { - BillboardAttrib *attrib = new BillboardAttrib; + BillboardEffect *effect = new BillboardEffect; DatagramIterator scan; BamReader *manager; parse_params(params, scan, manager); - attrib->fillin(scan, manager); + effect->fillin(scan, manager); - return attrib; + return effect; } //////////////////////////////////////////////////////////////////// -// Function: BillboardAttrib::fillin +// Function: BillboardEffect::fillin // Access: Protected // Description: This internal function is called by make_from_bam to // read in all of the relevant data from the BamFile for -// the new BillboardAttrib. +// the new BillboardEffect. //////////////////////////////////////////////////////////////////// -void BillboardAttrib:: +void BillboardEffect:: fillin(DatagramIterator &scan, BamReader *manager) { - RenderAttrib::fillin(scan, manager); + RenderEffect::fillin(scan, manager); _off = scan.get_bool(); _up_vector.read_datagram(scan); diff --git a/panda/src/pgraph/billboardAttrib.h b/panda/src/pgraph/billboardEffect.h similarity index 76% rename from panda/src/pgraph/billboardAttrib.h rename to panda/src/pgraph/billboardEffect.h index 69085d355e..144cbe6f01 100644 --- a/panda/src/pgraph/billboardAttrib.h +++ b/panda/src/pgraph/billboardEffect.h @@ -1,5 +1,5 @@ -// Filename: billboardAttrib.h -// Created by: drose (27Feb02) +// Filename: billboardEffect.h +// Created by: drose (14Mar02) // //////////////////////////////////////////////////////////////////// // @@ -16,35 +16,35 @@ // //////////////////////////////////////////////////////////////////// -#ifndef BILLBOARDATTRIB_H -#define BILLBOARDATTRIB_H +#ifndef BILLBOARDEFFECT_H +#define BILLBOARDEFFECT_H #include "pandabase.h" -#include "renderAttrib.h" +#include "renderEffect.h" #include "luse.h" #include "qpnodePath.h" //////////////////////////////////////////////////////////////////// -// Class : BillboardAttrib +// Class : BillboardEffect // Description : Indicates that geometry at this node should // automatically rotate to face the camera, or any other // arbitrary node. //////////////////////////////////////////////////////////////////// -class EXPCL_PANDA BillboardAttrib : public RenderAttrib { +class EXPCL_PANDA BillboardEffect : public RenderEffect { private: - INLINE BillboardAttrib(); + INLINE BillboardEffect(); PUBLISHED: - static CPT(RenderAttrib) make(const LVector3f &up_vector, + static CPT(RenderEffect) make(const LVector3f &up_vector, bool eye_relative, bool axial_rotate, float offset, const qpNodePath &look_at, const LPoint3f &look_at_point); - INLINE static CPT(RenderAttrib) make_axis(); - INLINE static CPT(RenderAttrib) make_point_eye(); - INLINE static CPT(RenderAttrib) make_point_world(); + INLINE static CPT(RenderEffect) make_axis(); + INLINE static CPT(RenderEffect) make_point_eye(); + INLINE static CPT(RenderEffect) make_point_world(); INLINE bool is_off() const; INLINE const LVector3f &get_up_vector() const; @@ -55,14 +55,15 @@ PUBLISHED: INLINE const LPoint3f &get_look_at_point() const; public: + virtual bool safe_to_combine() const; virtual void output(ostream &out) const; CPT(TransformState) do_billboard(const TransformState *net_transform, const TransformState *camera_transform) const; protected: - virtual int compare_to_impl(const RenderAttrib *other) const; - virtual RenderAttrib *make_default_impl() const; + virtual int compare_to_impl(const RenderEffect *other) const; + virtual RenderEffect *make_default_impl() const; private: bool _off; @@ -86,9 +87,9 @@ public: return _type_handle; } static void init_type() { - RenderAttrib::init_type(); - register_type(_type_handle, "BillboardAttrib", - RenderAttrib::get_class_type()); + RenderEffect::init_type(); + register_type(_type_handle, "BillboardEffect", + RenderEffect::get_class_type()); } virtual TypeHandle get_type() const { return get_class_type(); @@ -99,7 +100,7 @@ private: static TypeHandle _type_handle; }; -#include "billboardAttrib.I" +#include "billboardEffect.I" #endif diff --git a/panda/src/pgraph/config_pgraph.cxx b/panda/src/pgraph/config_pgraph.cxx index 927c70da91..15a11261e3 100644 --- a/panda/src/pgraph/config_pgraph.cxx +++ b/panda/src/pgraph/config_pgraph.cxx @@ -18,7 +18,7 @@ #include "config_pgraph.h" -#include "billboardAttrib.h" +#include "billboardEffect.h" #include "qpcamera.h" #include "colorAttrib.h" #include "colorWriteAttrib.h" @@ -29,7 +29,7 @@ #include "cullBinUnsorted.h" #include "qpcullTraverser.h" #include "cullableObject.h" -#include "decalAttrib.h" +#include "decalEffect.h" #include "depthTestAttrib.h" #include "depthWriteAttrib.h" #include "qpgeomNode.h" @@ -40,6 +40,8 @@ #include "qpnodePathComponent.h" #include "pandaNode.h" #include "renderAttrib.h" +#include "renderEffect.h" +#include "renderEffects.h" #include "renderState.h" #include "selectiveChildNode.h" #include "qpsequenceNode.h" @@ -79,7 +81,7 @@ init_libpgraph() { } initialized = true; - BillboardAttrib::init_type(); + BillboardEffect::init_type(); qpCamera::init_type(); ColorAttrib::init_type(); ColorWriteAttrib::init_type(); @@ -90,7 +92,7 @@ init_libpgraph() { CullBinUnsorted::init_type(); qpCullTraverser::init_type(); CullableObject::init_type(); - DecalAttrib::init_type(); + DecalEffect::init_type(); DepthTestAttrib::init_type(); DepthWriteAttrib::init_type(); qpGeomNode::init_type(); @@ -101,6 +103,8 @@ init_libpgraph() { qpNodePathComponent::init_type(); PandaNode::init_type(); RenderAttrib::init_type(); + RenderEffect::init_type(); + RenderEffects::init_type(); RenderState::init_type(); SelectiveChildNode::init_type(); qpSequenceNode::init_type(); @@ -109,13 +113,13 @@ init_libpgraph() { TransformState::init_type(); TransparencyAttrib::init_type(); - BillboardAttrib::register_with_read_factory(); + BillboardEffect::register_with_read_factory(); qpCamera::register_with_read_factory(); ColorAttrib::register_with_read_factory(); ColorWriteAttrib::register_with_read_factory(); CullBinAttrib::register_with_read_factory(); CullFaceAttrib::register_with_read_factory(); - DecalAttrib::register_with_read_factory(); + DecalEffect::register_with_read_factory(); DepthTestAttrib::register_with_read_factory(); DepthWriteAttrib::register_with_read_factory(); qpGeomNode::register_with_read_factory(); @@ -123,6 +127,7 @@ init_libpgraph() { qpLODNode::register_with_read_factory(); MaterialAttrib::register_with_read_factory(); PandaNode::register_with_read_factory(); + RenderEffects::register_with_read_factory(); RenderState::register_with_read_factory(); qpSequenceNode::register_with_read_factory(); TextureApplyAttrib::register_with_read_factory(); diff --git a/panda/src/pgraph/cullTraverserData.cxx b/panda/src/pgraph/cullTraverserData.cxx index dbb0b56c2c..c91406d5ba 100644 --- a/panda/src/pgraph/cullTraverserData.cxx +++ b/panda/src/pgraph/cullTraverserData.cxx @@ -22,6 +22,7 @@ #include "pandaNode.h" #include "colorAttrib.h" #include "textureAttrib.h" +#include "billboardEffect.h" //////////////////////////////////////////////////////////////////// // Function: CullTraverserData::apply_transform_and_state @@ -67,11 +68,11 @@ apply_transform_and_state(qpCullTraverser *trav, PandaNode *node) { } } - const RenderState *node_state = node->get_state(); - _state = _state->compose(node_state); + _state = _state->compose(node->get_state()); - const BillboardAttrib *billboard = node_state->get_billboard(); - if (billboard != (const BillboardAttrib *)NULL) { + const RenderEffects *node_effects = node->get_effects(); + const BillboardEffect *billboard = node_effects->get_billboard(); + if (billboard != (const BillboardEffect *)NULL) { // Got to apply a billboard transform here. CPT(TransformState) billboard_transform = billboard->do_billboard(_net_transform, trav->get_camera_transform()); diff --git a/panda/src/pgraph/decalAttrib.I b/panda/src/pgraph/decalEffect.I similarity index 76% rename from panda/src/pgraph/decalAttrib.I rename to panda/src/pgraph/decalEffect.I index 83f1fccf9b..3d8a2419d0 100644 --- a/panda/src/pgraph/decalAttrib.I +++ b/panda/src/pgraph/decalEffect.I @@ -1,5 +1,5 @@ -// Filename: decalAttrib.I -// Created by: drose (04Mar02) +// Filename: decalEffect.I +// Created by: drose (14Mar02) // //////////////////////////////////////////////////////////////////// // @@ -18,11 +18,11 @@ //////////////////////////////////////////////////////////////////// -// Function: DecalAttrib::Constructor +// Function: DecalEffect::Constructor // Access: Private -// Description: Use DecalAttrib::make() to construct a new -// DecalAttrib object. +// Description: Use DecalEffect::make() to construct a new +// DecalEffect object. //////////////////////////////////////////////////////////////////// -INLINE DecalAttrib:: -DecalAttrib() { +INLINE DecalEffect:: +DecalEffect() { } diff --git a/panda/src/pgraph/decalAttrib.cxx b/panda/src/pgraph/decalEffect.cxx similarity index 64% rename from panda/src/pgraph/decalAttrib.cxx rename to panda/src/pgraph/decalEffect.cxx index 7b87d3aca2..6579ea12a0 100644 --- a/panda/src/pgraph/decalAttrib.cxx +++ b/panda/src/pgraph/decalEffect.cxx @@ -1,5 +1,5 @@ -// Filename: decalAttrib.cxx -// Created by: drose (04Mar02) +// Filename: decalEffect.cxx +// Created by: drose (14Mar02) // //////////////////////////////////////////////////////////////////// // @@ -16,113 +16,113 @@ // //////////////////////////////////////////////////////////////////// -#include "decalAttrib.h" +#include "decalEffect.h" #include "bamReader.h" #include "bamWriter.h" #include "datagram.h" #include "datagramIterator.h" -TypeHandle DecalAttrib::_type_handle; +TypeHandle DecalEffect::_type_handle; //////////////////////////////////////////////////////////////////// -// Function: DecalAttrib::make +// Function: DecalEffect::make // Access: Published, Static -// Description: Constructs a new DecalAttrib object. +// Description: Constructs a new DecalEffect object. //////////////////////////////////////////////////////////////////// -CPT(RenderAttrib) DecalAttrib:: +CPT(RenderEffect) DecalEffect:: make() { - DecalAttrib *attrib = new DecalAttrib; - return return_new(attrib); + DecalEffect *effect = new DecalEffect; + return return_new(effect); } //////////////////////////////////////////////////////////////////// -// Function: DecalAttrib::compare_to_impl +// Function: DecalEffect::compare_to_impl // Access: Protected, Virtual -// Description: Intended to be overridden by derived DecalAttrib +// Description: Intended to be overridden by derived DecalEffect // types to return a unique number indicating whether -// this DecalAttrib is equivalent to the other one. +// this DecalEffect is equivalent to the other one. // -// This should return 0 if the two DecalAttrib objects +// This should return 0 if the two DecalEffect objects // are equivalent, a number less than zero if this one // should be sorted before the other one, and a number // greater than zero otherwise. // -// This will only be called with two DecalAttrib +// This will only be called with two DecalEffect // objects whose get_type() functions return the same. //////////////////////////////////////////////////////////////////// -int DecalAttrib:: -compare_to_impl(const RenderAttrib *other) const { - // All DecalAttribs are equivalent--there are no properties to +int DecalEffect:: +compare_to_impl(const RenderEffect *other) const { + // All DecalEffects are equivalent--there are no properties to // store. return 0; } //////////////////////////////////////////////////////////////////// -// Function: DecalAttrib::make_default_impl +// Function: DecalEffect::make_default_impl // Access: Protected, Virtual -// Description: Intended to be overridden by derived DecalAttrib +// Description: Intended to be overridden by derived DecalEffect // types to specify what the default property for a -// DecalAttrib of this type should be. +// DecalEffect of this type should be. // -// This should return a newly-allocated DecalAttrib of +// This should return a newly-allocated DecalEffect of // the same type that corresponds to whatever the -// standard default for this kind of DecalAttrib is. +// standard default for this kind of DecalEffect is. //////////////////////////////////////////////////////////////////// -RenderAttrib *DecalAttrib:: +RenderEffect *DecalEffect:: make_default_impl() const { - return new DecalAttrib; + return new DecalEffect; } //////////////////////////////////////////////////////////////////// -// Function: DecalAttrib::register_with_read_factory +// Function: DecalEffect::register_with_read_factory // Access: Public, Static // Description: Tells the BamReader how to create objects of type -// DecalAttrib. +// DecalEffect. //////////////////////////////////////////////////////////////////// -void DecalAttrib:: +void DecalEffect:: register_with_read_factory() { BamReader::get_factory()->register_factory(get_class_type(), make_from_bam); } //////////////////////////////////////////////////////////////////// -// Function: DecalAttrib::write_datagram +// Function: DecalEffect::write_datagram // Access: Public, Virtual // Description: Writes the contents of this object to the datagram // for shipping out to a Bam file. //////////////////////////////////////////////////////////////////// -void DecalAttrib:: +void DecalEffect:: write_datagram(BamWriter *manager, Datagram &dg) { - RenderAttrib::write_datagram(manager, dg); + RenderEffect::write_datagram(manager, dg); } //////////////////////////////////////////////////////////////////// -// Function: DecalAttrib::make_from_bam +// Function: DecalEffect::make_from_bam // Access: Protected, Static // Description: This function is called by the BamReader's factory -// when a new object of type DecalAttrib is encountered -// in the Bam file. It should create the DecalAttrib +// when a new object of type DecalEffect is encountered +// in the Bam file. It should create the DecalEffect // and extract its information from the file. //////////////////////////////////////////////////////////////////// -TypedWritable *DecalAttrib:: +TypedWritable *DecalEffect:: make_from_bam(const FactoryParams ¶ms) { - DecalAttrib *attrib = new DecalAttrib; + DecalEffect *effect = new DecalEffect; DatagramIterator scan; BamReader *manager; parse_params(params, scan, manager); - attrib->fillin(scan, manager); + effect->fillin(scan, manager); - return attrib; + return effect; } //////////////////////////////////////////////////////////////////// -// Function: DecalAttrib::fillin +// Function: DecalEffect::fillin // Access: Protected // Description: This internal function is called by make_from_bam to // read in all of the relevant data from the BamFile for -// the new DecalAttrib. +// the new DecalEffect. //////////////////////////////////////////////////////////////////// -void DecalAttrib:: +void DecalEffect:: fillin(DatagramIterator &scan, BamReader *manager) { - RenderAttrib::fillin(scan, manager); + RenderEffect::fillin(scan, manager); } diff --git a/panda/src/pgraph/decalAttrib.h b/panda/src/pgraph/decalEffect.h similarity index 74% rename from panda/src/pgraph/decalAttrib.h rename to panda/src/pgraph/decalEffect.h index 8969e87e50..a7e5de3ff9 100644 --- a/panda/src/pgraph/decalAttrib.h +++ b/panda/src/pgraph/decalEffect.h @@ -1,5 +1,5 @@ -// Filename: decalAttrib.h -// Created by: drose (04Mar02) +// Filename: decalEffect.h +// Created by: drose (14Mar02) // //////////////////////////////////////////////////////////////////// // @@ -16,29 +16,29 @@ // //////////////////////////////////////////////////////////////////// -#ifndef DECALATTRIB_H -#define DECALATTRIB_H +#ifndef DECALEFFECT_H +#define DECALEFFECT_H #include "pandabase.h" -#include "renderAttrib.h" +#include "renderEffect.h" //////////////////////////////////////////////////////////////////// -// Class : DecalAttrib +// Class : DecalEffect // Description : Applied to a GeomNode to indicate that the children // of this GeomNode are coplanar and should be drawn as // decals (eliminating Z-fighting). //////////////////////////////////////////////////////////////////// -class EXPCL_PANDA DecalAttrib : public RenderAttrib { +class EXPCL_PANDA DecalEffect : public RenderEffect { private: - INLINE DecalAttrib(); + INLINE DecalEffect(); PUBLISHED: - static CPT(RenderAttrib) make(); + static CPT(RenderEffect) make(); protected: - virtual int compare_to_impl(const RenderAttrib *other) const; - virtual RenderAttrib *make_default_impl() const; + virtual int compare_to_impl(const RenderEffect *other) const; + virtual RenderEffect *make_default_impl() const; public: static void register_with_read_factory(); @@ -53,9 +53,9 @@ public: return _type_handle; } static void init_type() { - RenderAttrib::init_type(); - register_type(_type_handle, "DecalAttrib", - RenderAttrib::get_class_type()); + RenderEffect::init_type(); + register_type(_type_handle, "DecalEffect", + RenderEffect::get_class_type()); } virtual TypeHandle get_type() const { return get_class_type(); @@ -66,7 +66,7 @@ private: static TypeHandle _type_handle; }; -#include "decalAttrib.I" +#include "decalEffect.I" #endif diff --git a/panda/src/pgraph/pandaNode.I b/panda/src/pgraph/pandaNode.I index 3c406446ba..2e515166e8 100644 --- a/panda/src/pgraph/pandaNode.I +++ b/panda/src/pgraph/pandaNode.I @@ -106,6 +106,7 @@ get_parent() const { INLINE PandaNode::CData:: CData() { _state = RenderState::make_empty(); + _effects = RenderEffects::make_empty(); _transform = TransformState::make_identity(); _draw_mask = DrawMask::all_on(); } @@ -122,6 +123,7 @@ CData(const PandaNode::CData ©) : _up(copy._up), _paths(copy._paths), _state(copy._state), + _effects(copy._effects), _transform(copy._transform), _draw_mask(copy._draw_mask) { @@ -409,6 +411,61 @@ clear_attrib(TypeHandle type) { cdata->_state = cdata->_state->remove_attrib(type); } +//////////////////////////////////////////////////////////////////// +// Function: PandaNode::set_effect +// Access: Published +// Description: Adds the indicated render effect to the scene +// graph on this node. If there was already an effect +// of the same type, it is replaced. +//////////////////////////////////////////////////////////////////// +INLINE void PandaNode:: +set_effect(const RenderEffect *effect) { + CDWriter cdata(_cycler); + cdata->_effects = cdata->_effects->add_effect(effect); +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaNode::get_effect +// Access: Published +// Description: Returns the render effect of the indicated type, +// if it is defined on the node, or NULL if it is not. +//////////////////////////////////////////////////////////////////// +INLINE const RenderEffect *PandaNode:: +get_effect(TypeHandle type) const { + CDReader cdata(_cycler); + int index = cdata->_effects->find_effect(type); + if (index >= 0) { + return cdata->_effects->get_effect(index); + } + return NULL; +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaNode::has_effect +// Access: Published +// Description: Returns true if there is a render effect of the +// indicated type defined on this node, or false if +// there is not. +//////////////////////////////////////////////////////////////////// +INLINE bool PandaNode:: +has_effect(TypeHandle type) const { + CDReader cdata(_cycler); + int index = cdata->_effects->find_effect(type); + return (index >= 0); +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaNode::clear_effect +// Access: Published +// Description: Removes the render effect of the given type from +// this node. +//////////////////////////////////////////////////////////////////// +INLINE void PandaNode:: +clear_effect(TypeHandle type) { + CDWriter cdata(_cycler); + cdata->_effects = cdata->_effects->remove_effect(type); +} + //////////////////////////////////////////////////////////////////// // Function: PandaNode::set_state // Access: Published @@ -454,6 +511,43 @@ clear_state() { cdata->_state = RenderState::make_empty(); } +//////////////////////////////////////////////////////////////////// +// Function: PandaNode::set_effects +// Access: Published +// Description: Sets the complete RenderEffects that will be applied +// this node. This completely replaces whatever has +// been set on this node via repeated calls to +// set_attrib(). +//////////////////////////////////////////////////////////////////// +INLINE void PandaNode:: +set_effects(const RenderEffects *effects) { + CDWriter cdata(_cycler); + cdata->_effects = effects; +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaNode::get_effects +// Access: Published +// Description: Returns the complete RenderEffects that will be +// applied to this node. +//////////////////////////////////////////////////////////////////// +INLINE const RenderEffects *PandaNode:: +get_effects() const { + CDReader cdata(_cycler); + return cdata->_effects; +} + +//////////////////////////////////////////////////////////////////// +// Function: PandaNode::clear_effects +// Access: Published +// Description: Resets this node to have no render effects. +//////////////////////////////////////////////////////////////////// +INLINE void PandaNode:: +clear_effects() { + CDWriter cdata(_cycler); + cdata->_effects = RenderEffects::make_empty(); +} + //////////////////////////////////////////////////////////////////// // Function: PandaNode::set_transform // Access: Published @@ -463,10 +557,8 @@ clear_state() { //////////////////////////////////////////////////////////////////// INLINE void PandaNode:: set_transform(const TransformState *transform) { - { - CDWriter cdata(_cycler); - cdata->_transform = transform; - } + CDWriter cdata(_cycler); + cdata->_transform = transform; mark_bound_stale(); } diff --git a/panda/src/pgraph/pandaNode.cxx b/panda/src/pgraph/pandaNode.cxx index 713f8dbc35..b8469b5e96 100644 --- a/panda/src/pgraph/pandaNode.cxx +++ b/panda/src/pgraph/pandaNode.cxx @@ -47,6 +47,7 @@ make_copy() const { void PandaNode::CData:: write_datagram(BamWriter *manager, Datagram &dg) const { manager->write_pointer(dg, _state); + manager->write_pointer(dg, _effects); manager->write_pointer(dg, _transform); dg.add_uint32(_draw_mask.get_word()); @@ -67,10 +68,12 @@ int PandaNode::CData:: complete_pointers(TypedWritable **p_list, BamReader *manager) { int pi = CycleData::complete_pointers(p_list, manager); - // Get the state and transform pointers. + // Get the state, effects, and transform pointers. _state = DCAST(RenderState, p_list[pi++]); + _effects = DCAST(RenderEffects, p_list[pi++]); _transform = DCAST(TransformState, p_list[pi++]); + // Get the parent and child pointers. pi += complete_up_list(_up, p_list + pi, manager); pi += complete_down_list(_down, p_list + pi, manager); pi += complete_down_list(_stashed, p_list + pi, manager); @@ -87,12 +90,14 @@ complete_pointers(TypedWritable **p_list, BamReader *manager) { //////////////////////////////////////////////////////////////////// void PandaNode::CData:: fillin(DatagramIterator &scan, BamReader *manager) { - // Read the state and transform pointers. + // Read the state, effects, and transform pointers. + manager->read_pointer(scan); manager->read_pointer(scan); manager->read_pointer(scan); _draw_mask.set_word(scan.get_uint32()); + // Read the parent and child pointers. fillin_up_list(_up, scan, manager); fillin_down_list(_down, scan, manager); fillin_down_list(_stashed, scan, manager); @@ -304,6 +309,7 @@ PandaNode(const PandaNode ©) : CDReader copy_cdata(copy._cycler); CDWriter cdata(_cycler); cdata->_state = copy_cdata->_state; + cdata->_effects = copy_cdata->_effects; cdata->_transform = copy_cdata->_transform; } @@ -989,6 +995,9 @@ write(ostream &out, int indent_level) const { if (!cdata->_state->is_empty()) { out << " " << *cdata->_state; } + if (!cdata->_effects->is_empty()) { + out << " " << *cdata->_effects; + } out << "\n"; } @@ -1159,8 +1168,6 @@ r_copy_subgraph(PandaNode::InstanceMap &inst_map) const { } copy->r_copy_children(this, inst_map); - copy->set_state(get_state()); - copy->set_transform(get_transform()); return copy; } @@ -1528,6 +1535,9 @@ r_list_descendants(ostream &out, int indent_level) const { if (!cdata->_state->is_empty()) { out << " " << *cdata->_state; } + if (!cdata->_effects->is_empty()) { + out << " " << *cdata->_effects; + } out << "\n"; Down::const_iterator di; diff --git a/panda/src/pgraph/pandaNode.h b/panda/src/pgraph/pandaNode.h index 5205faf07a..0389dc7ba5 100644 --- a/panda/src/pgraph/pandaNode.h +++ b/panda/src/pgraph/pandaNode.h @@ -26,6 +26,7 @@ #include "cycleDataWriter.h" #include "pipelineCycler.h" #include "renderState.h" +#include "renderEffects.h" #include "transformState.h" #include "drawMask.h" #include "typedWritable.h" @@ -106,10 +107,19 @@ PUBLISHED: INLINE bool has_attrib(TypeHandle type) const; INLINE void clear_attrib(TypeHandle type); + INLINE void set_effect(const RenderEffect *effect); + INLINE const RenderEffect *get_effect(TypeHandle type) const; + INLINE bool has_effect(TypeHandle type) const; + INLINE void clear_effect(TypeHandle type); + INLINE void set_state(const RenderState *state); INLINE const RenderState *get_state() const; INLINE void clear_state(); + INLINE void set_effects(const RenderEffects *effects); + INLINE const RenderEffects *get_effects() const; + INLINE void clear_effects(); + INLINE void set_transform(const TransformState *transform); INLINE const TransformState *get_transform() const; INLINE void clear_transform(); @@ -245,6 +255,7 @@ private: Paths _paths; CPT(RenderState) _state; + CPT(RenderEffects) _effects; CPT(TransformState) _transform; DrawMask _draw_mask; }; diff --git a/panda/src/pgraph/pgraph_composite1.cxx b/panda/src/pgraph/pgraph_composite1.cxx index 5c3eb2abe0..60d3996fe9 100644 --- a/panda/src/pgraph/pgraph_composite1.cxx +++ b/panda/src/pgraph/pgraph_composite1.cxx @@ -1,4 +1,4 @@ -#include "billboardAttrib.cxx" +#include "billboardEffect.cxx" #include "binCullHandler.cxx" #include "qpcamera.cxx" #include "colorAttrib.cxx" diff --git a/panda/src/pgraph/pgraph_composite2.cxx b/panda/src/pgraph/pgraph_composite2.cxx index 68a3146f85..08d1fce4d3 100644 --- a/panda/src/pgraph/pgraph_composite2.cxx +++ b/panda/src/pgraph/pgraph_composite2.cxx @@ -1,4 +1,4 @@ -#include "decalAttrib.cxx" +#include "decalEffect.cxx" #include "depthTestAttrib.cxx" #include "depthWriteAttrib.cxx" #include "drawCullHandler.cxx" @@ -14,6 +14,8 @@ #include "qpnodePathComponent.cxx" #include "pandaNode.cxx" #include "renderAttrib.cxx" +#include "renderEffect.cxx" +#include "renderEffects.cxx" #include "renderState.cxx" #include "selectiveChildNode.cxx" #include "qpsequenceNode.cxx" diff --git a/panda/src/pgraph/qpcullTraverser.cxx b/panda/src/pgraph/qpcullTraverser.cxx index 57904e4995..eda8ff418c 100644 --- a/panda/src/pgraph/qpcullTraverser.cxx +++ b/panda/src/pgraph/qpcullTraverser.cxx @@ -20,7 +20,6 @@ #include "cullTraverserData.h" #include "transformState.h" #include "renderState.h" -#include "billboardAttrib.h" #include "cullHandler.h" #include "dcast.h" #include "qpgeomNode.h" @@ -116,8 +115,8 @@ traverse(PandaNode *node, const CullTraverserData &data) { //////////////////////////////////////////////////////////////////// void qpCullTraverser:: traverse_below(PandaNode *node, const CullTraverserData &data) { - const RenderState *node_state = node->get_state(); - if (node_state->has_decal()) { + const RenderEffects *node_effects = node->get_effects(); + if (node_effects->has_decal()) { start_decal(node, data); } else { @@ -161,7 +160,7 @@ void qpCullTraverser:: start_decal(PandaNode *node, const CullTraverserData &data) { if (!node->is_geom_node()) { pgraph_cat.error() - << "DecalAttrib applied to " << *node << ", not a GeomNode.\n"; + << "DecalEffect applied to " << *node << ", not a GeomNode.\n"; return; } diff --git a/panda/src/pgraph/qpnodePath.cxx b/panda/src/pgraph/qpnodePath.cxx index 8e07f08e70..ac43cce9d6 100644 --- a/panda/src/pgraph/qpnodePath.cxx +++ b/panda/src/pgraph/qpnodePath.cxx @@ -27,7 +27,7 @@ #include "textureAttrib.h" #include "materialAttrib.h" #include "cullFaceAttrib.h" -#include "billboardAttrib.h" +#include "billboardEffect.h" #include "transparencyAttrib.h" #include "materialPool.h" #include "look_at.h" @@ -1981,10 +1981,10 @@ do_billboard_point_world(const qpNodePath &camera, float offset) { void qpNodePath:: set_billboard_axis(float offset) { nassertv(!is_empty()); - CPT(RenderAttrib) billboard = BillboardAttrib::make + CPT(RenderEffect) billboard = BillboardEffect::make (LVector3f::up(), false, true, offset, qpNodePath(), LPoint3f(0.0f, 0.0f, 0.0f)); - node()->set_attrib(billboard); + node()->set_effect(billboard); } //////////////////////////////////////////////////////////////////// @@ -1998,10 +1998,10 @@ set_billboard_axis(float offset) { void qpNodePath:: set_billboard_point_eye(float offset) { nassertv(!is_empty()); - CPT(RenderAttrib) billboard = BillboardAttrib::make + CPT(RenderEffect) billboard = BillboardEffect::make (LVector3f::up(), true, false, offset, qpNodePath(), LPoint3f(0.0f, 0.0f, 0.0f)); - node()->set_attrib(billboard); + node()->set_effect(billboard); } //////////////////////////////////////////////////////////////////// @@ -2014,33 +2014,33 @@ set_billboard_point_eye(float offset) { void qpNodePath:: set_billboard_point_world(float offset) { nassertv(!is_empty()); - CPT(RenderAttrib) billboard = BillboardAttrib::make + CPT(RenderEffect) billboard = BillboardEffect::make (LVector3f::up(), false, false, offset, qpNodePath(), LPoint3f(0.0f, 0.0f, 0.0f)); - node()->set_attrib(billboard); + node()->set_effect(billboard); } //////////////////////////////////////////////////////////////////// // Function: qpNodePath::clear_billboard // Access: Published -// Description: Removes any billboard attributes from the node. +// Description: Removes any billboard effect from the node. //////////////////////////////////////////////////////////////////// void qpNodePath:: clear_billboard() { nassertv(!is_empty()); - node()->clear_attrib(BillboardAttrib::get_class_type()); + node()->clear_effect(BillboardEffect::get_class_type()); } //////////////////////////////////////////////////////////////////// // Function: qpNodePath::has_billboard // Access: Published -// Description: Returns true if there is any billboard attribute on +// Description: Returns true if there is any billboard effect on // the node. //////////////////////////////////////////////////////////////////// bool qpNodePath:: has_billboard() const { nassertr(!is_empty(), false); - return node()->has_attrib(BillboardAttrib::get_class_type()); + return node()->has_effect(BillboardEffect::get_class_type()); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/pgraph/renderAttrib.h b/panda/src/pgraph/renderAttrib.h index c0ccc0651e..953ee982b9 100644 --- a/panda/src/pgraph/renderAttrib.h +++ b/panda/src/pgraph/renderAttrib.h @@ -36,6 +36,16 @@ class GraphicsStateGuardianBase; // geometry. This includes TextureAttrib, ColorAttrib, // etc. // +// RenderAttrib represents render attributes that always +// propagate down to the leaves without regard to the +// particular node they are assigned to. A RenderAttrib +// will have the same effect on a leaf node whether it +// is assigned to the graph at the leaf or several nodes +// above. This is different from RenderEffect, which +// represents a particular render property that is +// applied immediately to the node on which it is +// encountered, like billboarding or decaling. +// // You should not attempt to create or modify a // RenderAttrib directly; instead, use the make() method // of the appropriate kind of attrib you want. This diff --git a/panda/src/pgraph/renderEffect.I b/panda/src/pgraph/renderEffect.I new file mode 100644 index 0000000000..9e089df269 --- /dev/null +++ b/panda/src/pgraph/renderEffect.I @@ -0,0 +1,44 @@ +// Filename: renderEffect.I +// Created by: drose (14Mar02) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://www.panda3d.org/license.txt . +// +// To contact the maintainers of this program write to +// panda3d@yahoogroups.com . +// +//////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffect::compare_to +// Access: Public +// Description: Provides an arbitrary ordering among all unique +// RenderEffects, so we can store the essentially +// different ones in a big set and throw away the rest. +// +// This method is not needed outside of the RenderEffect +// class because all equivalent RenderEffect objects are +// guaranteed to share the same pointer; thus, a pointer +// comparison is always sufficient. +//////////////////////////////////////////////////////////////////// +INLINE int RenderEffect:: +compare_to(const RenderEffect &other) const { + // First, we compare the types; if they are of different types then + // they sort differently. + TypeHandle type = get_type(); + TypeHandle other_type = other.get_type(); + if (type != other_type) { + return type.get_index() - other_type.get_index(); + } + + // We only call compare_to_impl() if they have the same type. + return compare_to_impl(&other); +} diff --git a/panda/src/pgraph/renderEffect.cxx b/panda/src/pgraph/renderEffect.cxx new file mode 100644 index 0000000000..5fca33d1e1 --- /dev/null +++ b/panda/src/pgraph/renderEffect.cxx @@ -0,0 +1,257 @@ +// Filename: renderEffect.cxx +// Created by: drose (14Mar02) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://www.panda3d.org/license.txt . +// +// To contact the maintainers of this program write to +// panda3d@yahoogroups.com . +// +//////////////////////////////////////////////////////////////////// + +#include "renderEffect.h" +#include "bamReader.h" +#include "indent.h" + +RenderEffect::Effects RenderEffect::_effects; +TypeHandle RenderEffect::_type_handle; + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffect::Constructor +// Access: Protected +// Description: +//////////////////////////////////////////////////////////////////// +RenderEffect:: +RenderEffect() { + _saved_entry = _effects.end(); +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffect::Copy Constructor +// Access: Private +// Description: RenderEffects are not meant to be copied. +//////////////////////////////////////////////////////////////////// +RenderEffect:: +RenderEffect(const RenderEffect &) { + nassertv(false); +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffect::Copy Assignment Operator +// Access: Private +// Description: RenderEffects are not meant to be copied. +//////////////////////////////////////////////////////////////////// +void RenderEffect:: +operator = (const RenderEffect &) { + nassertv(false); +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffect::Destructor +// Access: Public, Virtual +// Description: The destructor is responsible for removing the +// RenderEffect from the global set if it is there. +//////////////////////////////////////////////////////////////////// +RenderEffect:: +~RenderEffect() { + if (_saved_entry != _effects.end()) { + _effects.erase(_saved_entry); + _saved_entry = _effects.end(); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffect::safe_to_transform +// Access: Public, Virtual +// Description: Returns true if it is generally safe to transform +// this particular kind of RenderEffect by calling the +// xform() method, false otherwise. For instance, it's +// usually a bad idea to attempt to xform a Character. +//////////////////////////////////////////////////////////////////// +bool RenderEffect:: +safe_to_transform() const { + return true; +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffect::safe_to_combine +// Access: Public, Virtual +// Description: Returns true if this kind of effect can safely be +// combined with sibling nodes that share the exact same +// effect, or false if this is not a good idea. +//////////////////////////////////////////////////////////////////// +bool RenderEffect:: +safe_to_combine() const { + return false; +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffect::xform +// Access: Public, Virtual +// Description: Returns a new RenderEffect transformed by the +// indicated matrix. +//////////////////////////////////////////////////////////////////// +CPT(RenderEffect) RenderEffect:: +xform(const LMatrix4f &) const { + return this; +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffect::output +// Access: Published, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +void RenderEffect:: +output(ostream &out) const { + out << get_type(); +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffect::write +// Access: Published, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +void RenderEffect:: +write(ostream &out, int indent_level) const { + indent(out, indent_level) << *this << "\n"; +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffect::return_new +// Access: Protected, Static +// Description: This function is used by derived RenderEffect types +// to share a common RenderEffect pointer for all +// equivalent RenderEffect objects. +// +// The make() function of the derived type should create +// a new RenderEffect and pass it through return_new(), +// which will either save the pointer and return it +// unchanged (if this is the first similar such object) +// or delete it and return an equivalent pointer (if +// there was already a similar object saved). +//////////////////////////////////////////////////////////////////// +CPT(RenderEffect) RenderEffect:: +return_new(RenderEffect *effect) { + nassertr(effect != (RenderEffect *)NULL, effect); + + // This should be a newly allocated pointer, not one that was used + // for anything else. + nassertr(effect->_saved_entry == _effects.end(), effect); + + // Save the effect in a local PointerTo so that it will be freed at + // the end of this function if no one else uses it. + CPT(RenderEffect) pt_effect = effect; + + pair result = _effects.insert(effect); + if (result.second) { + // The effect was inserted; save the iterator and return the + // input effect. + effect->_saved_entry = result.first; + return pt_effect; + } + + // The effect was not inserted; there must be an equivalent one + // already in the set. Return that one. + return *(result.first); +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffect::compare_to_impl +// Access: Protected, Virtual +// Description: Intended to be overridden by derived RenderEffect +// types to return a unique number indicating whether +// this RenderEffect is equivalent to the other one. +// +// This should return 0 if the two RenderEffect objects +// are equivalent, a number less than zero if this one +// should be sorted before the other one, and a number +// greater than zero otherwise. +// +// This will only be called with two RenderEffect +// objects whose get_type() functions return the same. +//////////////////////////////////////////////////////////////////// +int RenderEffect:: +compare_to_impl(const RenderEffect *other) const { + return 0; +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffect::write_datagram +// Access: Public, Virtual +// Description: Writes the contents of this object to the datagram +// for shipping out to a Bam file. +//////////////////////////////////////////////////////////////////// +void RenderEffect:: +write_datagram(BamWriter *manager, Datagram &dg) { + TypedWritable::write_datagram(manager, dg); +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffect::change_this +// Access: Public, Static +// Description: Called immediately after complete_pointers(), this +// gives the object a chance to adjust its own pointer +// if desired. Most objects don't change pointers after +// completion, but some need to. +// +// Once this function has been called, the old pointer +// will no longer be accessed. +//////////////////////////////////////////////////////////////////// +TypedWritable *RenderEffect:: +change_this(TypedWritable *old_ptr, BamReader *manager) { + // First, uniquify the pointer. + RenderEffect *effect = DCAST(RenderEffect, old_ptr); + CPT(RenderEffect) pointer = return_new(effect); + + // But now we have a problem, since we have to hold the reference + // count and there's no way to return a TypedWritable while still + // holding the reference count! We work around this by explicitly + // upping the count, and also setting a finalize() callback to down + // it later. + if (pointer == effect) { + pointer->ref(); + manager->register_finalize(effect); + } + + // We have to cast the pointer back to non-const, because the bam + // reader expects that. + return (RenderEffect *)pointer.p(); +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffect::finalize +// Access: Public, Virtual +// Description: Method to ensure that any necessary clean up tasks +// that have to be performed by this object are performed +//////////////////////////////////////////////////////////////////// +void RenderEffect:: +finalize() { + // Unref the pointer that we explicitly reffed in make_from_bam(). + unref(); + + // We should never get back to zero after unreffing our own count, + // because we expect to have been stored in a pointer somewhere. If + // we do get to zero, it's a memory leak; the way to avoid this is + // to call unref_delete() above instead of unref(), but this is + // dangerous to do from within a virtual function. + nassertv(get_ref_count() != 0); +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffect::fillin +// Access: Protected +// Description: This internal function is called by make_from_bam to +// read in all of the relevant data from the BamFile for +// the new RenderEffect. +//////////////////////////////////////////////////////////////////// +void RenderEffect:: +fillin(DatagramIterator &scan, BamReader *manager) { + TypedWritable::fillin(scan, manager); +} diff --git a/panda/src/pgraph/renderEffect.h b/panda/src/pgraph/renderEffect.h new file mode 100644 index 0000000000..ce288a9935 --- /dev/null +++ b/panda/src/pgraph/renderEffect.h @@ -0,0 +1,120 @@ +// Filename: renderEffect.h +// Created by: drose (14Mar02) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://www.panda3d.org/license.txt . +// +// To contact the maintainers of this program write to +// panda3d@yahoogroups.com . +// +//////////////////////////////////////////////////////////////////// + +#ifndef RENDEREFFECT_H +#define RENDEREFFECT_H + +#include "pandabase.h" + +#include "typedWritableReferenceCount.h" +#include "indirectCompareTo.h" +#include "pointerTo.h" +#include "pset.h" +#include "luse.h" + +//////////////////////////////////////////////////////////////////// +// Class : RenderEffect +// Description : This is the base class for a number of special render +// effects that may be set on scene graph nodes to +// change the way they render. This includes +// BillboardEffect, DecalEffect, etc. +// +// RenderEffect represents render properties that must +// be applied as soon as they are encountered in the +// scene graph, rather than propagating down to the +// leaves. This is different from RenderAttrib, which +// represents properties like color and texture that +// don't do anything until they propagate down to a +// GeomNode. +// +// You should not attempt to create or modify a +// RenderEffect directly; instead, use the make() method +// of the appropriate kind of effect you want. This +// will allocate and return a new RenderEffect of the +// appropriate type, and it may share pointers if +// possible. Do not modify the new RenderEffect if you +// wish to change its properties; instead, create a new +// one. +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDA RenderEffect : public TypedWritableReferenceCount { +protected: + RenderEffect(); +private: + RenderEffect(const RenderEffect ©); + void operator = (const RenderEffect ©); + +public: + virtual ~RenderEffect(); + + INLINE int compare_to(const RenderEffect &other) const; + + virtual bool safe_to_transform() const; + virtual bool safe_to_combine() const; + virtual CPT(RenderEffect) xform(const LMatrix4f &mat) const; + +PUBLISHED: + virtual void output(ostream &out) const; + virtual void write(ostream &out, int indent_level) const; + +protected: + static CPT(RenderEffect) return_new(RenderEffect *effect); + + virtual int compare_to_impl(const RenderEffect *other) const; + +private: + typedef pset > Effects; + static Effects _effects; + + Effects::iterator _saved_entry; + +public: + virtual void write_datagram(BamWriter *manager, Datagram &dg); + static TypedWritable *change_this(TypedWritable *old_ptr, BamReader *manager); + virtual void finalize(); + +protected: + static TypedWritable *new_from_bam(RenderEffect *effect, BamReader *manager); + void fillin(DatagramIterator &scan, BamReader *manager); + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + TypedWritableReferenceCount::init_type(); + register_type(_type_handle, "RenderEffect", + TypedWritableReferenceCount::get_class_type()); + } + virtual TypeHandle get_type() const { + return get_class_type(); + } + virtual TypeHandle force_init_type() {init_type(); return get_class_type();} + +private: + static TypeHandle _type_handle; +}; + +INLINE ostream &operator << (ostream &out, const RenderEffect &effect) { + effect.output(out); + return out; +} + +#include "renderEffect.I" + +#endif + diff --git a/panda/src/pgraph/renderEffects.I b/panda/src/pgraph/renderEffects.I new file mode 100644 index 0000000000..396bc2b6d5 --- /dev/null +++ b/panda/src/pgraph/renderEffects.I @@ -0,0 +1,182 @@ +// Filename: renderEffects.I +// Created by: drose (14Mar02) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://www.panda3d.org/license.txt . +// +// To contact the maintainers of this program write to +// panda3d@yahoogroups.com . +// +//////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffects::Effect::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE RenderEffects::Effect:: +Effect(const RenderEffect *effect) : + _type(effect->get_type()), + _effect(effect) +{ +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffects::Effect::Constructor +// Access: Public +// Description: This constructor is only used when reading the +// RenderEffects from a bam file. At this point, the +// effect pointer is unknown. +//////////////////////////////////////////////////////////////////// +INLINE RenderEffects::Effect:: +Effect() { +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffects::Effect::Constructor +// Access: Public +// Description: This constructor makes an invalid Effect with no +// RenderEffect pointer; its purpose is just to make an +// object we can use to look up a particular type in the +// Effect set. +//////////////////////////////////////////////////////////////////// +INLINE RenderEffects::Effect:: +Effect(TypeHandle type) : + _type(type), + _effect(NULL) +{ +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffects::Effect::Copy Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE RenderEffects::Effect:: +Effect(const Effect ©) : + _type(copy._type), + _effect(copy._effect) +{ +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffects::Effect::Copy Assignment Operator +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void RenderEffects::Effect:: +operator = (const Effect ©) { + _type = copy._type; + _effect = copy._effect; +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffects::Effect::operator < +// Access: Public +// Description: This is used by the Effects set to uniquify +// RenderEffects by type. Only one RenderEffect of a +// given type is allowed in the set. This ordering must +// also match the ordering reported by compare_to(). +//////////////////////////////////////////////////////////////////// +INLINE bool RenderEffects::Effect:: +operator < (const Effect &other) const { + return _type < other._type; +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffects::Effect::compare_to +// Access: Public +// Description: Provides an indication of whether a particular +// effect is equivalent to another one, for purposes +// of generating unique RenderEffectss. This should +// compare all properties of the Effect, but it is +// important that the type is compared first, to be +// consistent with the ordering defined by operator <. +//////////////////////////////////////////////////////////////////// +INLINE int RenderEffects::Effect:: +compare_to(const Effect &other) const { + if (_type != other._type) { + return _type.get_index() - other._type.get_index(); + } + return _effect - other._effect; +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffects::is_empty +// Access: Published +// Description: Returns true if the state is empty, false otherwise. +//////////////////////////////////////////////////////////////////// +INLINE bool RenderEffects:: +is_empty() const { + return _effects.empty(); +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffects::get_num_effects +// Access: Published +// Description: Returns the number of separate effects indicated +// in the state. +//////////////////////////////////////////////////////////////////// +INLINE int RenderEffects:: +get_num_effects() const { + return _effects.size(); +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffects::get_effect +// Access: Published +// Description: Returns the nth effect in the state. +//////////////////////////////////////////////////////////////////// +INLINE const RenderEffect *RenderEffects:: +get_effect(int n) const { + nassertr(n >= 0 && n < (int)_effects.size(), NULL); + return _effects[n]._effect; +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffects::get_billboard +// Access: Public +// Description: This function is provided as an optimization, to +// speed up the render-time checking for the existance +// of a BillboardEffect on this state. It returns a +// pointer to the BillboardEffect, if there is one, or +// NULL if there is not. +//////////////////////////////////////////////////////////////////// +INLINE const BillboardEffect *RenderEffects:: +get_billboard() const { + if ((_flags & F_checked_billboard) == 0) { + // We pretend this function is const, even though it transparently + // modifies the internal billboard cache. + ((RenderEffects *)this)->determine_billboard(); + } + return _billboard; +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffects::has_decal +// Access: Public +// Description: This function is provided as an optimization, to +// speed up the render-time checking for the existance +// of a DecalEffect on this state. It returns true if a +// DecalEffect exists, false otherwise. Note that since +// there is no additional information stored on the +// DecalEffect, there's no point in returning it if it +// exists. +//////////////////////////////////////////////////////////////////// +INLINE bool RenderEffects:: +has_decal() const { + if ((_flags & F_checked_decal) == 0) { + // We pretend this function is const, even though it transparently + // modifies the internal decal cache. + ((RenderEffects *)this)->determine_decal(); + } + return ((_flags & F_has_decal) != 0); +} diff --git a/panda/src/pgraph/renderEffects.cxx b/panda/src/pgraph/renderEffects.cxx new file mode 100644 index 0000000000..9aa197f5a6 --- /dev/null +++ b/panda/src/pgraph/renderEffects.cxx @@ -0,0 +1,618 @@ +// Filename: renderEffects.cxx +// Created by: drose (14Mar02) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://www.panda3d.org/license.txt . +// +// To contact the maintainers of this program write to +// panda3d@yahoogroups.com . +// +//////////////////////////////////////////////////////////////////// + +#include "renderEffects.h" +#include "billboardEffect.h" +#include "decalEffect.h" +#include "config_pgraph.h" +#include "bamReader.h" +#include "bamWriter.h" +#include "datagramIterator.h" +#include "indent.h" +#include "compareTo.h" + +RenderEffects::States RenderEffects::_states; +CPT(RenderEffects) RenderEffects::_empty_state; +TypeHandle RenderEffects::_type_handle; + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffects::Constructor +// Access: Protected +// Description: Actually, this could be a private constructor, since +// no one inherits from RenderEffects, but gcc gives us a +// spurious warning if all constructors are private. +//////////////////////////////////////////////////////////////////// +RenderEffects:: +RenderEffects() { + _saved_entry = _states.end(); + _flags = 0; +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffects::Copy Constructor +// Access: Private +// Description: RenderEffectss are not meant to be copied. +//////////////////////////////////////////////////////////////////// +RenderEffects:: +RenderEffects(const RenderEffects &) { + nassertv(false); +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffects::Copy Assignment Operator +// Access: Private +// Description: RenderEffectss are not meant to be copied. +//////////////////////////////////////////////////////////////////// +void RenderEffects:: +operator = (const RenderEffects &) { + nassertv(false); +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffects::Destructor +// Access: Public, Virtual +// Description: The destructor is responsible for removing the +// RenderEffects from the global set if it is there. +//////////////////////////////////////////////////////////////////// +RenderEffects:: +~RenderEffects() { + // Remove the deleted RenderEffects object from the global pool. + if (_saved_entry != _states.end()) { + _states.erase(_saved_entry); + _saved_entry = _states.end(); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffects::operator < +// Access: Public +// Description: Provides an arbitrary ordering among all unique +// RenderEffectss, so we can store the essentially +// different ones in a big set and throw away the rest. +// +// This method is not needed outside of the RenderEffects +// class because all equivalent RenderEffects objects are +// guaranteed to share the same pointer; thus, a pointer +// comparison is always sufficient. +//////////////////////////////////////////////////////////////////// +bool RenderEffects:: +operator < (const RenderEffects &other) const { + // We must compare all the properties of the effects, not just + // the type; thus, we compare them one at a time using compare_to(). + return lexicographical_compare(_effects.begin(), _effects.end(), + other._effects.begin(), other._effects.end(), + CompareTo()); +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffects::safe_to_transform +// Access: Public +// Description: Returns true if all of the effects in this set can +// safely be transformed, and therefore the complete set +// can be transformed, by calling xform(). +//////////////////////////////////////////////////////////////////// +bool RenderEffects:: +safe_to_transform() const { + Effects::const_iterator ai; + for (ai = _effects.begin(); ai != _effects.end(); ++ai) { + const Effect &effect = (*ai); + if (!effect._effect->safe_to_transform()) { + return false; + } + } + + return true; +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffects::safe_to_combine +// Access: Public +// Description: Returns true if all of the effects in this set can +// safely be shared with a sibling node that has the +// exact same set of effects, or false if this would be +// bad for any of the effects. +//////////////////////////////////////////////////////////////////// +bool RenderEffects:: +safe_to_combine() const { + Effects::const_iterator ai; + for (ai = _effects.begin(); ai != _effects.end(); ++ai) { + const Effect &effect = (*ai); + if (!effect._effect->safe_to_combine()) { + return false; + } + } + + return true; +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffects::xform +// Access: Public, Virtual +// Description: Returns a new RenderEffects transformed by the +// indicated matrix. +//////////////////////////////////////////////////////////////////// +CPT(RenderEffects) RenderEffects:: +xform(const LMatrix4f &mat) const { + if (is_empty()) { + return this; + } + + RenderEffects *new_state = new RenderEffects; + back_insert_iterator result = + back_inserter(new_state->_effects); + + Effects::const_iterator ai; + for (ai = _effects.begin(); ai != _effects.end(); ++ai) { + const Effect &effect = (*ai); + Effect new_effect(effect); + new_effect._effect = effect._effect->xform(mat); + *result = new_effect; + ++result; + } + + return return_new(new_state); +} + + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffects::find_effect +// Access: Published +// Description: Searches for an effect with the indicated type in +// the state, and returns its index if it is found, or +// -1 if it is not. +//////////////////////////////////////////////////////////////////// +int RenderEffects:: +find_effect(TypeHandle type) const { + Effects::const_iterator ai = _effects.find(Effect(type)); + if (ai == _effects.end()) { + return -1; + } + return ai - _effects.begin(); +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffects::make_empty +// Access: Published, Static +// Description: Returns a RenderEffects with no effects set. +//////////////////////////////////////////////////////////////////// +CPT(RenderEffects) RenderEffects:: +make_empty() { + // The empty state is asked for so often, we make it a special case + // and store a pointer forever once we find it the first time. + if (_empty_state == (RenderEffects *)NULL) { + RenderEffects *state = new RenderEffects; + _empty_state = return_new(state); + } + + return _empty_state; +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffects::make +// Access: Published, Static +// Description: Returns a RenderEffects with one effect set. +//////////////////////////////////////////////////////////////////// +CPT(RenderEffects) RenderEffects:: +make(const RenderEffect *effect) { + RenderEffects *state = new RenderEffects; + state->_effects.reserve(1); + state->_effects.insert(Effect(effect)); + return return_new(state); +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffects::make +// Access: Published, Static +// Description: Returns a RenderEffects with two effects set. +//////////////////////////////////////////////////////////////////// +CPT(RenderEffects) RenderEffects:: +make(const RenderEffect *effect1, + const RenderEffect *effect2) { + RenderEffects *state = new RenderEffects; + state->_effects.reserve(2); + state->_effects.push_back(Effect(effect1)); + state->_effects.push_back(Effect(effect2)); + state->_effects.sort(); + return return_new(state); +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffects::make +// Access: Published, Static +// Description: Returns a RenderEffects with three effects set. +//////////////////////////////////////////////////////////////////// +CPT(RenderEffects) RenderEffects:: +make(const RenderEffect *effect1, + const RenderEffect *effect2, + const RenderEffect *effect3) { + RenderEffects *state = new RenderEffects; + state->_effects.reserve(2); + state->_effects.push_back(Effect(effect1)); + state->_effects.push_back(Effect(effect2)); + state->_effects.push_back(Effect(effect3)); + state->_effects.sort(); + return return_new(state); +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffects::make +// Access: Published, Static +// Description: Returns a RenderEffects with four effects set. +//////////////////////////////////////////////////////////////////// +CPT(RenderEffects) RenderEffects:: +make(const RenderEffect *effect1, + const RenderEffect *effect2, + const RenderEffect *effect3, + const RenderEffect *effect4) { + RenderEffects *state = new RenderEffects; + state->_effects.reserve(2); + state->_effects.push_back(Effect(effect1)); + state->_effects.push_back(Effect(effect2)); + state->_effects.push_back(Effect(effect3)); + state->_effects.push_back(Effect(effect4)); + state->_effects.sort(); + return return_new(state); +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffects::add_effect +// Access: Published +// Description: Returns a new RenderEffects object that represents the +// same as the source state, with the new RenderEffect +// added. If there is already a RenderEffect with the +// same type, it is replaced. +//////////////////////////////////////////////////////////////////// +CPT(RenderEffects) RenderEffects:: +add_effect(const RenderEffect *effect) const { + RenderEffects *new_state = new RenderEffects; + back_insert_iterator result = + back_inserter(new_state->_effects); + + Effect new_effect(effect); + Effects::const_iterator ai = _effects.begin(); + + while (ai != _effects.end() && (*ai) < new_effect) { + *result = *ai; + ++ai; + ++result; + } + *result = new_effect; + ++result; + + if (ai != _effects.end() && !(new_effect < (*ai))) { + // At this point we know: + // !((*ai) < new_effect) && !(new_effect < (*ai)) + // which means (*ai) == new_effect--so we should leave it out, + // to avoid duplicating effects in the set. + ++ai; + } + + while (ai != _effects.end()) { + *result = *ai; + ++ai; + ++result; + } + + return return_new(new_state); +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffects::remove_effect +// Access: Published +// Description: Returns a new RenderEffects object that represents the +// same as the source state, with the indicated +// RenderEffect removed. +//////////////////////////////////////////////////////////////////// +CPT(RenderEffects) RenderEffects:: +remove_effect(TypeHandle type) const { + RenderEffects *new_state = new RenderEffects; + back_insert_iterator result = + back_inserter(new_state->_effects); + + Effects::const_iterator ai = _effects.begin(); + + while (ai != _effects.end()) { + if ((*ai)._type != type) { + *result = *ai; + ++result; + } + ++ai; + } + + return return_new(new_state); +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffects::get_effect +// Access: Published, Virtual +// Description: Looks for a RenderEffect of the indicated type in the +// state, and returns it if it is found, or NULL if it +// is not. +//////////////////////////////////////////////////////////////////// +const RenderEffect *RenderEffects:: +get_effect(TypeHandle type) const { + Effects::const_iterator ai; + ai = _effects.find(Effect(type)); + if (ai != _effects.end()) { + return (*ai)._effect; + } + return NULL; +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffects::output +// Access: Published, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +void RenderEffects:: +output(ostream &out) const { + out << "E:"; + if (_effects.empty()) { + out << "(empty)"; + + } else { + Effects::const_iterator ai = _effects.begin(); + out << "(" << (*ai)._type; + ++ai; + while (ai != _effects.end()) { + out << " " << (*ai)._type; + ++ai; + } + out << ")"; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffects::write +// Access: Published, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +void RenderEffects:: +write(ostream &out, int indent_level) const { + indent(out, indent_level) << _effects.size() << " effects:\n"; + Effects::const_iterator ai; + for (ai = _effects.begin(); ai != _effects.end(); ++ai) { + const Effect &effect = (*ai); + effect._effect->write(out, indent_level + 2); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffects::return_new +// Access: Private, Static +// Description: This function is used to share a common RenderEffects +// pointer for all equivalent RenderEffects objects. +// +// See the similar logic in RenderEffect. The idea is +// to create a new RenderEffects object and pass it +// through this function, which will share the pointer +// with a previously-created RenderEffects object if it is +// equivalent. +//////////////////////////////////////////////////////////////////// +CPT(RenderEffects) RenderEffects:: +return_new(RenderEffects *state) { + nassertr(state != (RenderEffects *)NULL, state); + + // This should be a newly allocated pointer, not one that was used + // for anything else. + nassertr(state->_saved_entry == _states.end(), state); + + // Save the state in a local PointerTo so that it will be freed at + // the end of this function if no one else uses it. + CPT(RenderEffects) pt_state = state; + + pair result = _states.insert(state); + if (result.second) { + // The state was inserted; save the iterator and return the + // input state. + state->_saved_entry = result.first; + return pt_state; + } + + // The state was not inserted; there must be an equivalent one + // already in the set. Return that one. + return *(result.first); +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffects::determine_billboard +// Access: Private +// Description: This is the private implementation of +// get_billboard(). +//////////////////////////////////////////////////////////////////// +void RenderEffects:: +determine_billboard() { + const RenderEffect *effect = get_effect(BillboardEffect::get_class_type()); + _billboard = (const BillboardEffect *)NULL; + if (effect != (const RenderEffect *)NULL) { + _billboard = DCAST(BillboardEffect, effect); + } + _flags |= F_checked_billboard; +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffects::determine_decal +// Access: Private +// Description: This is the private implementation of has_decal(). +//////////////////////////////////////////////////////////////////// +void RenderEffects:: +determine_decal() { + const RenderEffect *effect = get_effect(DecalEffect::get_class_type()); + if (effect != (const RenderEffect *)NULL) { + _flags |= F_has_decal; + } + _flags |= F_checked_decal; +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffects::register_with_read_factory +// Access: Public, Static +// Description: Tells the BamReader how to create objects of type +// RenderEffects. +//////////////////////////////////////////////////////////////////// +void RenderEffects:: +register_with_read_factory() { + BamReader::get_factory()->register_factory(get_class_type(), make_from_bam); +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffects::write_datagram +// Access: Public, Virtual +// Description: Writes the contents of this object to the datagram +// for shipping out to a Bam file. +//////////////////////////////////////////////////////////////////// +void RenderEffects:: +write_datagram(BamWriter *manager, Datagram &dg) { + TypedWritable::write_datagram(manager, dg); + + int num_effects = _effects.size(); + nassertv(num_effects == (int)(PN_uint16)num_effects); + dg.add_uint16(num_effects); + + Effects::const_iterator ai; + for (ai = _effects.begin(); ai != _effects.end(); ++ai) { + const Effect &effect = (*ai); + + manager->write_pointer(dg, effect._effect); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffects::complete_pointers +// Access: Public, Virtual +// Description: Receives an array of pointers, one for each time +// manager->read_pointer() was called in fillin(). +// Returns the number of pointers processed. +//////////////////////////////////////////////////////////////////// +int RenderEffects:: +complete_pointers(TypedWritable **p_list, BamReader *manager) { + int pi = TypedWritable::complete_pointers(p_list, manager); + + // Get the effect pointers. + Effects::iterator ai; + for (ai = _effects.begin(); ai != _effects.end(); ++ai) { + Effect &effect = (*ai); + + effect._effect = DCAST(RenderEffect, p_list[pi++]); + nassertr(effect._effect != (RenderEffect *)NULL, pi); + effect._type = effect._effect->get_type(); + } + + // Now make sure the array is properly sorted. (It won't + // necessarily preserve its correct sort after being read from bam, + // because the sort is based on TypeHandle indices, which can change + // from session to session.) + _effects.sort(); + + return pi; +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffects::change_this +// Access: Public, Static +// Description: Called immediately after complete_pointers(), this +// gives the object a chance to adjust its own pointer +// if desired. Most objects don't change pointers after +// completion, but some need to. +// +// Once this function has been called, the old pointer +// will no longer be accessed. +//////////////////////////////////////////////////////////////////// +TypedWritable *RenderEffects:: +change_this(TypedWritable *old_ptr, BamReader *manager) { + // First, uniquify the pointer. + RenderEffects *state = DCAST(RenderEffects, old_ptr); + CPT(RenderEffects) pointer = return_new(state); + + // But now we have a problem, since we have to hold the reference + // count and there's no way to return a TypedWritable while still + // holding the reference count! We work around this by explicitly + // upping the count, and also setting a finalize() callback to down + // it later. + if (pointer == state) { + pointer->ref(); + manager->register_finalize(state); + } + + // We have to cast the pointer back to non-const, because the bam + // reader expects that. + return (RenderEffects *)pointer.p(); +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffects::finalize +// Access: Public, Virtual +// Description: Called by the BamReader to perform any final actions +// needed for setting up the object after all objects +// have been read and all pointers have been completed. +//////////////////////////////////////////////////////////////////// +void RenderEffects:: +finalize() { + // Unref the pointer that we explicitly reffed in make_from_bam(). + unref(); + + // We should never get back to zero after unreffing our own count, + // because we expect to have been stored in a pointer somewhere. If + // we do get to zero, it's a memory leak; the way to avoid this is + // to call unref_delete() above instead of unref(), but this is + // dangerous to do from within a virtual function. + nassertv(get_ref_count() != 0); +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffects::make_from_bam +// Access: Protected, Static +// Description: This function is called by the BamReader's factory +// when a new object of type RenderEffects is encountered +// in the Bam file. It should create the RenderEffects +// and extract its information from the file. +//////////////////////////////////////////////////////////////////// +TypedWritable *RenderEffects:: +make_from_bam(const FactoryParams ¶ms) { + RenderEffects *state = new RenderEffects; + DatagramIterator scan; + BamReader *manager; + + parse_params(params, scan, manager); + state->fillin(scan, manager); + manager->register_change_this(change_this, state); + + return state; +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderEffects::fillin +// Access: Protected +// Description: This internal function is called by make_from_bam to +// read in all of the relevant data from the BamFile for +// the new RenderEffects. +//////////////////////////////////////////////////////////////////// +void RenderEffects:: +fillin(DatagramIterator &scan, BamReader *manager) { + TypedWritable::fillin(scan, manager); + + int num_effects = scan.get_uint16(); + + // Push back a NULL pointer for each effect for now, until we get + // the actual list of pointers later in complete_pointers(). + _effects.reserve(num_effects); + for (int i = 0; i < num_effects; i++) { + manager->read_pointer(scan); + _effects.push_back(Effect()); + } +} diff --git a/panda/src/pgraph/renderEffects.h b/panda/src/pgraph/renderEffects.h new file mode 100644 index 0000000000..b6101944a8 --- /dev/null +++ b/panda/src/pgraph/renderEffects.h @@ -0,0 +1,174 @@ +// Filename: renderEffects.h +// Created by: drose (14Mar02) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://www.panda3d.org/license.txt . +// +// To contact the maintainers of this program write to +// panda3d@yahoogroups.com . +// +//////////////////////////////////////////////////////////////////// + +#ifndef RENDEREFFECTS_H +#define RENDEREFFECTS_H + +#include "pandabase.h" + +#include "renderEffect.h" +#include "typedWritableReferenceCount.h" +#include "pointerTo.h" +#include "indirectLess.h" +#include "ordered_vector.h" + +class BillboardEffect; + +//////////////////////////////////////////////////////////////////// +// Class : RenderEffects +// Description : This represents a unique collection of RenderEffect +// objects that correspond to a particular renderable +// state. +// +// You should not attempt to create or modify a +// RenderEffects object directly. Instead, call one of +// the make() functions to create one for you. And +// instead of modifying a RenderEffects object, create a +// new one. +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDA RenderEffects : public TypedWritableReferenceCount { +protected: + RenderEffects(); + +private: + RenderEffects(const RenderEffects ©); + void operator = (const RenderEffects ©); + +public: + virtual ~RenderEffects(); + + bool operator < (const RenderEffects &other) const; + + bool safe_to_transform() const; + bool safe_to_combine() const; + CPT(RenderEffects) xform(const LMatrix4f &mat) const; + +PUBLISHED: + INLINE bool is_empty() const; + INLINE int get_num_effects() const; + INLINE const RenderEffect *get_effect(int n) const; + + int find_effect(TypeHandle type) const; + + static CPT(RenderEffects) make_empty(); + static CPT(RenderEffects) make(const RenderEffect *effect); + static CPT(RenderEffects) make(const RenderEffect *effect1, + const RenderEffect *effect2); + static CPT(RenderEffects) make(const RenderEffect *effect1, + const RenderEffect *effect2, + const RenderEffect *effect3); + static CPT(RenderEffects) make(const RenderEffect *effect1, + const RenderEffect *effect2, + const RenderEffect *effect3, + const RenderEffect *effect4); + + CPT(RenderEffects) add_effect(const RenderEffect *effect) const; + CPT(RenderEffects) remove_effect(TypeHandle type) const; + + const RenderEffect *get_effect(TypeHandle type) const; + + void output(ostream &out) const; + void write(ostream &out, int indent_level) const; + +public: + INLINE const BillboardEffect *get_billboard() const; + INLINE bool has_decal() const; + +private: + static CPT(RenderEffects) return_new(RenderEffects *state); + void determine_billboard(); + void determine_decal(); + +private: + typedef pset > States; + static States _states; + static CPT(RenderEffects) _empty_state; + + // This iterator records the entry corresponding to this RenderEffects + // object in the above global set. We keep the iterator around so + // we can remove it when the RenderEffects destructs. + States::iterator _saved_entry; + +private: + // This is the actual data within the RenderEffects: a set of + // RenderEffects. + class Effect { + public: + INLINE Effect(const RenderEffect *effect); + INLINE Effect(); + INLINE Effect(TypeHandle type); + INLINE Effect(const Effect ©); + INLINE void operator = (const Effect ©); + INLINE bool operator < (const Effect &other) const; + INLINE int compare_to(const Effect &other) const; + + TypeHandle _type; + CPT(RenderEffect) _effect; + }; + typedef ov_set Effects; + Effects _effects; + + // We cache the pointer to the some critical effects stored in + // the state, if they exist. + const BillboardEffect *_billboard; + + enum Flags { + F_checked_billboard = 0x0001, + F_checked_decal = 0x0002, + F_has_decal = 0x0004, + }; + short _flags; + +public: + static void register_with_read_factory(); + virtual void write_datagram(BamWriter *manager, Datagram &dg); + virtual int complete_pointers(TypedWritable **plist, BamReader *manager); + static TypedWritable *change_this(TypedWritable *old_ptr, BamReader *manager); + virtual void finalize(); + +protected: + static TypedWritable *make_from_bam(const FactoryParams ¶ms); + void fillin(DatagramIterator &scan, BamReader *manager); + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + TypedWritableReferenceCount::init_type(); + register_type(_type_handle, "RenderEffects", + TypedWritableReferenceCount::get_class_type()); + } + virtual TypeHandle get_type() const { + return get_class_type(); + } + virtual TypeHandle force_init_type() {init_type(); return get_class_type();} + +private: + static TypeHandle _type_handle; +}; + +INLINE ostream &operator << (ostream &out, const RenderEffects &state) { + state.output(out); + return out; +} + +#include "renderEffects.I" + +#endif + diff --git a/panda/src/pgraph/renderState.I b/panda/src/pgraph/renderState.I index 80fae74760..01c684bf62 100644 --- a/panda/src/pgraph/renderState.I +++ b/panda/src/pgraph/renderState.I @@ -162,54 +162,14 @@ get_override(int n) const { return _attributes[n]._override; } -//////////////////////////////////////////////////////////////////// -// Function: RenderState::get_billboard -// Access: Public -// Description: This function is provided as an optimization, to -// speed up the render-time checking for the existance -// of a BillboardAttrib on this state. It returns a -// pointer to the BillboardAttrib, if there is one, or -// NULL if there is not. -//////////////////////////////////////////////////////////////////// -INLINE const BillboardAttrib *RenderState:: -get_billboard() const { - if ((_flags & F_checked_billboard) == 0) { - // We pretend this function is const, even though it transparently - // modifies the internal billboard cache. - ((RenderState *)this)->determine_billboard(); - } - return _billboard; -} - -//////////////////////////////////////////////////////////////////// -// Function: RenderState::has_decal -// Access: Public -// Description: This function is provided as an optimization, to -// speed up the render-time checking for the existance -// of a DecalAttrib on this state. It returns true if a -// DecalAttrib exists, false otherwise. Note that since -// there is no additional information stored on the -// DecalAttrib, there's no point in returning it if it -// exists. -//////////////////////////////////////////////////////////////////// -INLINE bool RenderState:: -has_decal() const { - if ((_flags & F_checked_decal) == 0) { - // We pretend this function is const, even though it transparently - // modifies the internal decal cache. - ((RenderState *)this)->determine_decal(); - } - return ((_flags & F_has_decal) != 0); -} - //////////////////////////////////////////////////////////////////// // Function: RenderState::get_bin_index // Access: Public // Description: Returns the bin index indicated by the CullBinAttrib, // if any, associated by this state (or the default bin -// index if there is no CullBinAttrib). As in -// get_billboard(), above, this function is provided as -// an optimization. +// index if there is no CullBinAttrib). This function +// is provided as an optimization for determining this +// at render time. //////////////////////////////////////////////////////////////////// INLINE int RenderState:: get_bin_index() const { diff --git a/panda/src/pgraph/renderState.cxx b/panda/src/pgraph/renderState.cxx index 19cf0a4327..973759ae0e 100644 --- a/panda/src/pgraph/renderState.cxx +++ b/panda/src/pgraph/renderState.cxx @@ -17,7 +17,6 @@ //////////////////////////////////////////////////////////////////// #include "renderState.h" -#include "billboardAttrib.h" #include "transparencyAttrib.h" #include "cullBinAttrib.h" #include "cullBinManager.h" @@ -868,36 +867,6 @@ do_invert_compose(const RenderState *other) const { return return_new(new_state); } -//////////////////////////////////////////////////////////////////// -// Function: RenderState::determine_billboard -// Access: Private -// Description: This is the private implementation of -// get_billboard(). -//////////////////////////////////////////////////////////////////// -void RenderState:: -determine_billboard() { - const RenderAttrib *attrib = get_attrib(BillboardAttrib::get_class_type()); - _billboard = (const BillboardAttrib *)NULL; - if (attrib != (const RenderAttrib *)NULL) { - _billboard = DCAST(BillboardAttrib, attrib); - } - _flags |= F_checked_billboard; -} - -//////////////////////////////////////////////////////////////////// -// Function: RenderState::determine_decal -// Access: Private -// Description: This is the private implementation of has_decal(). -//////////////////////////////////////////////////////////////////// -void RenderState:: -determine_decal() { - const RenderAttrib *attrib = get_attrib(DecalAttrib::get_class_type()); - if (attrib != (const RenderAttrib *)NULL) { - _flags |= F_has_decal; - } - _flags |= F_checked_decal; -} - //////////////////////////////////////////////////////////////////// // Function: RenderState::determine_bin_index // Access: Private diff --git a/panda/src/pgraph/renderState.h b/panda/src/pgraph/renderState.h index 2990ffed8d..b98ea75a84 100644 --- a/panda/src/pgraph/renderState.h +++ b/panda/src/pgraph/renderState.h @@ -28,7 +28,6 @@ #include "ordered_vector.h" class GraphicsStateGuardianBase; -class BillboardAttrib; //////////////////////////////////////////////////////////////////// // Class : RenderState @@ -89,8 +88,6 @@ PUBLISHED: void write(ostream &out, int indent_level) const; public: - INLINE const BillboardAttrib *get_billboard() const; - INLINE bool has_decal() const; INLINE int get_bin_index() const; INLINE int get_draw_order() const; @@ -105,8 +102,6 @@ private: static CPT(RenderState) return_new(RenderState *state); CPT(RenderState) do_compose(const RenderState *other) const; CPT(RenderState) do_invert_compose(const RenderState *other) const; - void determine_billboard(); - void determine_decal(); void determine_bin_index(); private: @@ -161,19 +156,13 @@ private: typedef ov_set Attributes; Attributes _attributes; - // We cache the pointer to the some critical attributes stored in - // the state, if they exist. - const BillboardAttrib *_billboard; - - // We also cache the index to the associated GeomBin. + // We cache the index to the associated CullBin, if there happens to + // be a CullBinAttrib in the state. int _bin_index; int _draw_order; enum Flags { - F_checked_billboard = 0x0001, - F_checked_bin_index = 0x0002, - F_checked_decal = 0x0004, - F_has_decal = 0x0008, + F_checked_bin_index = 0x0001, }; short _flags;