From 64aece121a186247bfbf55ce66a5d67e18ed57c7 Mon Sep 17 00:00:00 2001 From: David Rose Date: Mon, 2 Aug 2004 21:34:46 +0000 Subject: [PATCH] robustify light interface further --- panda/src/display/graphicsStateGuardian.I | 6 +- panda/src/display/graphicsStateGuardian.cxx | 25 +- panda/src/display/graphicsStateGuardian.h | 13 +- .../glstuff/glGraphicsStateGuardian_src.cxx | 39 ++- .../src/glstuff/glGraphicsStateGuardian_src.h | 9 +- panda/src/gobj/geom.cxx | 1 - panda/src/gsgbase/graphicsStateGuardianBase.h | 10 +- panda/src/pgraph/ambientLight.cxx | 2 +- panda/src/pgraph/ambientLight.h | 3 +- panda/src/pgraph/directionalLight.cxx | 4 +- panda/src/pgraph/directionalLight.h | 3 +- panda/src/pgraph/light.h | 4 +- panda/src/pgraph/lightAttrib.I | 15 +- panda/src/pgraph/lightAttrib.cxx | 134 +++++---- panda/src/pgraph/lightAttrib.h | 19 +- panda/src/pgraph/nodePath.cxx | 270 +++++------------- panda/src/pgraph/nodePath.h | 12 - panda/src/pgraph/pointLight.cxx | 4 +- panda/src/pgraph/pointLight.h | 3 +- panda/src/pgraph/spotlight.cxx | 4 +- panda/src/pgraph/spotlight.h | 3 +- panda/src/pgraph/textureAttrib.I | 3 +- 22 files changed, 239 insertions(+), 347 deletions(-) diff --git a/panda/src/display/graphicsStateGuardian.I b/panda/src/display/graphicsStateGuardian.I index 027c804fff..32d5e85fed 100644 --- a/panda/src/display/graphicsStateGuardian.I +++ b/panda/src/display/graphicsStateGuardian.I @@ -484,11 +484,11 @@ get_coordinate_system() const { // Function: GraphicsStateGuardian::get_light // Access: Protected // Description: Returns the Light object that is bound to the -// indicated id, or NULL if no Light is bound. +// indicated id, or empty NodePath if no Light is bound. //////////////////////////////////////////////////////////////////// -INLINE Light *GraphicsStateGuardian:: +INLINE NodePath GraphicsStateGuardian:: get_light(int light_id) const { - nassertr(light_id >= 0 && light_id < (int)_light_info.size(), (Light *)NULL); + nassertr(light_id >= 0 && light_id < (int)_light_info.size(), NodePath::fail()); return _light_info[light_id]._light; } diff --git a/panda/src/display/graphicsStateGuardian.cxx b/panda/src/display/graphicsStateGuardian.cxx index ae9da26082..c70be6466f 100644 --- a/panda/src/display/graphicsStateGuardian.cxx +++ b/panda/src/display/graphicsStateGuardian.cxx @@ -335,7 +335,7 @@ begin_frame() { enable_light(i, false); _light_info[i]._enabled = false; } - _light_info[i]._light = (Light *)NULL; + _light_info[i]._light = NodePath(); } // Also force the lighting state to unlit, so that issue_light() @@ -683,8 +683,9 @@ issue_light(const LightAttrib *attrib) { int num_enabled = 0; int num_on_lights = attrib->get_num_on_lights(); for (int li = 0; li < num_on_lights; li++) { - Light *light = attrib->get_on_light(li); - nassertv(light != (Light *)NULL); + NodePath light = attrib->get_on_light(li); + nassertv(!light.is_empty() && light.node()->as_light() != (Light *)NULL); + Light *light_obj = light.node()->as_light(); num_enabled++; @@ -693,10 +694,10 @@ issue_light(const LightAttrib *attrib) { _lighting_enabled = true; _lighting_enabled_this_frame = true; - if (light->get_type() == AmbientLight::get_class_type()) { + if (light_obj->get_type() == AmbientLight::get_class_type()) { // Ambient lights don't require specific light ids; simply add // in the ambient contribution to the current total - cur_ambient_light += light->get_color(); + cur_ambient_light += light_obj->get_color(); } else { // Check to see if this light has already been bound to an id @@ -716,7 +717,7 @@ issue_light(const LightAttrib *attrib) { // See if there are any unbound light ids if (cur_light_id == -1) { for (i = 0; i < max_lights; i++) { - if (_light_info[i]._light == (Light *)NULL) { + if (_light_info[i]._light.is_empty()) { _light_info[i]._light = light; cur_light_id = i; break; @@ -728,7 +729,7 @@ issue_light(const LightAttrib *attrib) { // a currently unused but previously bound id if (cur_light_id == -1) { for (i = 0; i < max_lights; i++) { - if (!attrib->has_light(_light_info[i]._light)) { + if (!attrib->has_on_light(_light_info[i]._light)) { _light_info[i]._light = light; cur_light_id = i; break; @@ -758,11 +759,11 @@ issue_light(const LightAttrib *attrib) { // This is the first time this frame that this light has been // bound to this particular id. - light->bind(this, cur_light_id); + light_obj->bind(this, light, cur_light_id); } else if (cur_light_id == -1) { gsg_cat.warning() - << "Failed to bind " << *light << " to id.\n"; + << "Failed to bind " << light << " to id.\n"; } } } @@ -949,7 +950,7 @@ issue_clip_plane(const ClipPlaneAttrib *attrib) { // properties. //////////////////////////////////////////////////////////////////// void GraphicsStateGuardian:: -bind_light(PointLight *light, int light_id) { +bind_light(PointLight *light_obj, const NodePath &light, int light_id) { } //////////////////////////////////////////////////////////////////// @@ -961,7 +962,7 @@ bind_light(PointLight *light, int light_id) { // properties. //////////////////////////////////////////////////////////////////// void GraphicsStateGuardian:: -bind_light(DirectionalLight *light, int light_id) { +bind_light(DirectionalLight *light_obj, const NodePath &light, int light_id) { } //////////////////////////////////////////////////////////////////// @@ -973,7 +974,7 @@ bind_light(DirectionalLight *light, int light_id) { // properties. //////////////////////////////////////////////////////////////////// void GraphicsStateGuardian:: -bind_light(Spotlight *light, int light_id) { +bind_light(Spotlight *light_obj, const NodePath &light, int light_id) { } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/display/graphicsStateGuardian.h b/panda/src/display/graphicsStateGuardian.h index bb6d5eefb3..c41fabc03d 100644 --- a/panda/src/display/graphicsStateGuardian.h +++ b/panda/src/display/graphicsStateGuardian.h @@ -165,12 +165,15 @@ public: virtual void issue_color_blend(const ColorBlendAttrib *attrib); virtual void issue_clip_plane(const ClipPlaneAttrib *attrib); - virtual void bind_light(PointLight *light, int light_id); - virtual void bind_light(DirectionalLight *light, int light_id); - virtual void bind_light(Spotlight *light, int light_id); + virtual void bind_light(PointLight *light_obj, const NodePath &light, + int light_id); + virtual void bind_light(DirectionalLight *light_obj, const NodePath &light, + int light_id); + virtual void bind_light(Spotlight *light_obj, const NodePath &light, + int light_id); protected: - INLINE Light *get_light(int light_id) const; + INLINE NodePath get_light(int light_id) const; virtual bool slot_new_light(int light_id); virtual void enable_lighting(bool enable); virtual void set_ambient_light(const Colorf &color); @@ -301,7 +304,7 @@ private: class LightInfo { public: INLINE LightInfo(); - PT(Light) _light; + NodePath _light; bool _enabled; bool _next_enabled; }; diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 5192351181..5e8574ba77 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -2728,18 +2728,17 @@ issue_depth_offset(const DepthOffsetAttrib *attrib) { // properties. //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: -bind_light(PointLight *light, int light_id) { +bind_light(PointLight *light_obj, const NodePath &light, int light_id) { GLenum id = get_light_id(light_id); static const Colorf black(0.0f, 0.0f, 0.0f, 1.0f); GLP(Lightfv)(id, GL_AMBIENT, black.get_data()); - GLP(Lightfv)(id, GL_DIFFUSE, light->get_color().get_data()); - GLP(Lightfv)(id, GL_SPECULAR, light->get_specular_color().get_data()); + GLP(Lightfv)(id, GL_DIFFUSE, light_obj->get_color().get_data()); + GLP(Lightfv)(id, GL_SPECULAR, light_obj->get_specular_color().get_data()); // Position needs to specify x, y, z, and w // w == 1 implies non-infinite position - NodePath light_np(light); - const LMatrix4f &light_mat = light_np.get_mat(_scene_setup->get_scene_root()); - LPoint3f pos = light->get_point() * light_mat; + const LMatrix4f &light_mat = light.get_mat(_scene_setup->get_scene_root()); + LPoint3f pos = light_obj->get_point() * light_mat; LPoint4f fpos(pos[0], pos[1], pos[2], 1.0f); GLP(Lightfv)(id, GL_POSITION, fpos.get_data()); @@ -2752,7 +2751,7 @@ bind_light(PointLight *light, int light_id) { // Cutoff == 180 means uniform point light source GLP(Lightf)(id, GL_SPOT_CUTOFF, 180.0f); - const LVecBase3f &att = light->get_attenuation(); + const LVecBase3f &att = light_obj->get_attenuation(); GLP(Lightf)(id, GL_CONSTANT_ATTENUATION, att[0]); GLP(Lightf)(id, GL_LINEAR_ATTENUATION, att[1]); GLP(Lightf)(id, GL_QUADRATIC_ATTENUATION, att[2]); @@ -2769,18 +2768,17 @@ bind_light(PointLight *light, int light_id) { // properties. //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: -bind_light(DirectionalLight *light, int light_id) { +bind_light(DirectionalLight *light_obj, const NodePath &light, int light_id) { GLenum id = get_light_id( light_id ); static const Colorf black(0.0f, 0.0f, 0.0f, 1.0f); GLP(Lightfv)(id, GL_AMBIENT, black.get_data()); - GLP(Lightfv)(id, GL_DIFFUSE, light->get_color().get_data()); - GLP(Lightfv)(id, GL_SPECULAR, light->get_specular_color().get_data()); + GLP(Lightfv)(id, GL_DIFFUSE, light_obj->get_color().get_data()); + GLP(Lightfv)(id, GL_SPECULAR, light_obj->get_specular_color().get_data()); // Position needs to specify x, y, z, and w. // w == 0 implies light is at infinity - NodePath light_np(light); - const LMatrix4f &light_mat = light_np.get_mat(_scene_setup->get_scene_root()); - LVector3f dir = light->get_direction() * light_mat; + const LMatrix4f &light_mat = light.get_mat(_scene_setup->get_scene_root()); + LVector3f dir = light_obj->get_direction() * light_mat; LPoint4f fdir(-dir[0], -dir[1], -dir[2], 0); GLP(Lightfv)(id, GL_POSITION, fdir.get_data()); @@ -2811,20 +2809,19 @@ bind_light(DirectionalLight *light, int light_id) { // properties. //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: -bind_light(Spotlight *light, int light_id) { - Lens *lens = light->get_lens(); +bind_light(Spotlight *light_obj, const NodePath &light, int light_id) { + Lens *lens = light_obj->get_lens(); nassertv(lens != (Lens *)NULL); GLenum id = get_light_id(light_id); static const Colorf black(0.0f, 0.0f, 0.0f, 1.0f); GLP(Lightfv)(id, GL_AMBIENT, black.get_data()); - GLP(Lightfv)(id, GL_DIFFUSE, light->get_color().get_data()); - GLP(Lightfv)(id, GL_SPECULAR, light->get_specular_color().get_data()); + GLP(Lightfv)(id, GL_DIFFUSE, light_obj->get_color().get_data()); + GLP(Lightfv)(id, GL_SPECULAR, light_obj->get_specular_color().get_data()); // Position needs to specify x, y, z, and w // w == 1 implies non-infinite position - NodePath light_np(light); - const LMatrix4f &light_mat = light_np.get_mat(_scene_setup->get_scene_root()); + const LMatrix4f &light_mat = light.get_mat(_scene_setup->get_scene_root()); LPoint3f pos = lens->get_nodal_point() * light_mat; LVector3f dir = lens->get_view_vector() * light_mat; @@ -2832,10 +2829,10 @@ bind_light(Spotlight *light, int light_id) { GLP(Lightfv)(id, GL_POSITION, fpos.get_data()); GLP(Lightfv)(id, GL_SPOT_DIRECTION, dir.get_data()); - GLP(Lightf)(id, GL_SPOT_EXPONENT, light->get_exponent()); + GLP(Lightf)(id, GL_SPOT_EXPONENT, light_obj->get_exponent()); GLP(Lightf)(id, GL_SPOT_CUTOFF, lens->get_hfov()); - const LVecBase3f &att = light->get_attenuation(); + const LVecBase3f &att = light_obj->get_attenuation(); GLP(Lightf)(id, GL_CONSTANT_ATTENUATION, att[0]); GLP(Lightf)(id, GL_LINEAR_ATTENUATION, att[1]); GLP(Lightf)(id, GL_QUADRATIC_ATTENUATION, att[2]); diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.h b/panda/src/glstuff/glGraphicsStateGuardian_src.h index 9c2eec4c90..61742b663c 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.h +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.h @@ -112,9 +112,12 @@ public: virtual void issue_cg_shader_bind(const CgShaderAttrib *attrib); // virtual void issue_stencil(const StencilAttrib *attrib); - virtual void bind_light(PointLight *light, int light_id); - virtual void bind_light(DirectionalLight *light, int light_id); - virtual void bind_light(Spotlight *light, int light_id); + virtual void bind_light(PointLight *light_obj, const NodePath &light, + int light_id); + virtual void bind_light(DirectionalLight *light_obj, const NodePath &light, + int light_id); + virtual void bind_light(Spotlight *light_obj, const NodePath &light, + int light_id); virtual bool wants_texcoords(void) const; diff --git a/panda/src/gobj/geom.cxx b/panda/src/gobj/geom.cxx index c8e9a9b564..4064b5911b 100644 --- a/panda/src/gobj/geom.cxx +++ b/panda/src/gobj/geom.cxx @@ -1200,7 +1200,6 @@ fillin(DatagramIterator& scan, BamReader* manager) { // read the multitexture data int num_texcoords_by_names = scan.get_uint8(); // read the TexCoordsByName pointers of num_texcoords_by_names - TexCoordsByName::const_iterator tci; _temp_texcoord_set.reserve(num_texcoords_by_names); for (int i=0; iread_pointer(scan); diff --git a/panda/src/gsgbase/graphicsStateGuardianBase.h b/panda/src/gsgbase/graphicsStateGuardianBase.h index 6bbc79746f..d1a7196dbc 100644 --- a/panda/src/gsgbase/graphicsStateGuardianBase.h +++ b/panda/src/gsgbase/graphicsStateGuardianBase.h @@ -28,6 +28,7 @@ class RenderBuffer; class GraphicsWindow; +class NodePath; class GeomContext; class GeomNode; @@ -197,9 +198,12 @@ public: virtual void issue_stencil(const StencilAttrib *) { } virtual void issue_clip_plane(const ClipPlaneAttrib *) { } - virtual void bind_light(PointLight *light, int light_id) { } - virtual void bind_light(DirectionalLight *light, int light_id) { } - virtual void bind_light(Spotlight *light, int light_id) { } + virtual void bind_light(PointLight *light_obj, const NodePath &light, + int light_id) { } + virtual void bind_light(DirectionalLight *light_obj, const NodePath &light, + int light_id) { } + virtual void bind_light(Spotlight *light_obj, const NodePath &light, + int light_id) { } PUBLISHED: static TypeHandle get_class_type() { diff --git a/panda/src/pgraph/ambientLight.cxx b/panda/src/pgraph/ambientLight.cxx index 051fd8b30d..e5f5c89744 100644 --- a/panda/src/pgraph/ambientLight.cxx +++ b/panda/src/pgraph/ambientLight.cxx @@ -80,7 +80,7 @@ write(ostream &out, int indent_level) const { // Description: //////////////////////////////////////////////////////////////////// void AmbientLight:: -bind(GraphicsStateGuardianBase *, int) { +bind(GraphicsStateGuardianBase *, const NodePath &, int) { // AmbientLights aren't bound to light id's; this function should // never be called. nassertv(false); diff --git a/panda/src/pgraph/ambientLight.h b/panda/src/pgraph/ambientLight.h index 2be3f807f2..4f8248fa54 100644 --- a/panda/src/pgraph/ambientLight.h +++ b/panda/src/pgraph/ambientLight.h @@ -42,7 +42,8 @@ public: virtual void write(ostream &out, int indent_level) const; public: - virtual void bind(GraphicsStateGuardianBase *gsg, int light_id); + virtual void bind(GraphicsStateGuardianBase *gsg, const NodePath &light, + int light_id); public: static void register_with_read_factory(); diff --git a/panda/src/pgraph/directionalLight.cxx b/panda/src/pgraph/directionalLight.cxx index 113590e616..1fa2ace751 100644 --- a/panda/src/pgraph/directionalLight.cxx +++ b/panda/src/pgraph/directionalLight.cxx @@ -139,8 +139,8 @@ write(ostream &out, int indent_level) const { // Description: //////////////////////////////////////////////////////////////////// void DirectionalLight:: -bind(GraphicsStateGuardianBase *gsg, int light_id) { - gsg->bind_light(this, light_id); +bind(GraphicsStateGuardianBase *gsg, const NodePath &light, int light_id) { + gsg->bind_light(this, light, light_id); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/pgraph/directionalLight.h b/panda/src/pgraph/directionalLight.h index fd4a593859..79a98b4d05 100644 --- a/panda/src/pgraph/directionalLight.h +++ b/panda/src/pgraph/directionalLight.h @@ -51,7 +51,8 @@ PUBLISHED: INLINE void set_direction(const LVector3f &direction); public: - virtual void bind(GraphicsStateGuardianBase *gsg, int light_id); + virtual void bind(GraphicsStateGuardianBase *gsg, const NodePath &light, + int light_id); private: // This is the data that must be cycled between pipeline stages. diff --git a/panda/src/pgraph/light.h b/panda/src/pgraph/light.h index 08b8a5cf9f..5842992b94 100644 --- a/panda/src/pgraph/light.h +++ b/panda/src/pgraph/light.h @@ -29,6 +29,7 @@ #include "pipelineCycler.h" #include "geomNode.h" +class NodePath; class PandaNode; class GraphicsStateGuardianBase; @@ -58,7 +59,8 @@ PUBLISHED: public: virtual void output(ostream &out) const=0; virtual void write(ostream &out, int indent_level) const=0; - virtual void bind(GraphicsStateGuardianBase *gsg, int light_id)=0; + virtual void bind(GraphicsStateGuardianBase *gsg, const NodePath &light, + int light_id)=0; GeomNode *get_viz(); diff --git a/panda/src/pgraph/lightAttrib.I b/panda/src/pgraph/lightAttrib.I index 53f99fc50c..7d9641496a 100644 --- a/panda/src/pgraph/lightAttrib.I +++ b/panda/src/pgraph/lightAttrib.I @@ -60,9 +60,9 @@ get_num_on_lights() const { // Description: Returns the nth light turned on by the attribute, // sorted in render order. //////////////////////////////////////////////////////////////////// -INLINE Light *LightAttrib:: +INLINE NodePath LightAttrib:: get_on_light(int n) const { - nassertr(n >= 0 && n < (int)_on_lights.size(), (Light *)NULL); + nassertr(n >= 0 && n < (int)_on_lights.size(), NodePath::fail()); return _on_lights[n]; } @@ -73,7 +73,7 @@ get_on_light(int n) const { // the attrib, false otherwise. //////////////////////////////////////////////////////////////////// INLINE bool LightAttrib:: -has_on_light(Light *light) const { +has_on_light(const NodePath &light) const { return _on_lights.find(light) != _on_lights.end(); } @@ -94,9 +94,9 @@ get_num_off_lights() const { // Description: Returns the nth light turned off by the attribute, // sorted in arbitrary (pointer) order. //////////////////////////////////////////////////////////////////// -INLINE Light *LightAttrib:: +INLINE NodePath LightAttrib:: get_off_light(int n) const { - nassertr(n >= 0 && n < (int)_off_lights.size(), (Light *)NULL); + nassertr(n >= 0 && n < (int)_off_lights.size(), NodePath::fail()); return _off_lights[n]; } @@ -107,8 +107,9 @@ get_off_light(int n) const { // the attrib, false otherwise. //////////////////////////////////////////////////////////////////// INLINE bool LightAttrib:: -has_off_light(Light *light) const { - return _off_all_lights || _off_lights.find(light) != _off_lights.end(); +has_off_light(const NodePath &light) const { + return _off_lights.find(light) != _off_lights.end() || + (_off_all_lights && !has_on_light(light)); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/pgraph/lightAttrib.cxx b/panda/src/pgraph/lightAttrib.cxx index daf33a08cf..22eff993aa 100644 --- a/panda/src/pgraph/lightAttrib.cxx +++ b/panda/src/pgraph/lightAttrib.cxx @@ -44,17 +44,17 @@ make(LightAttrib::Operation op, Light *light) { switch (op) { case O_set: attrib = make_all_off(); - attrib = DCAST(LightAttrib, attrib)->add_on_light(light); + attrib = DCAST(LightAttrib, attrib)->add_on_light(NodePath(light->as_node())); return attrib; case O_add: attrib = make(); - attrib = DCAST(LightAttrib, attrib)->add_on_light(light); + attrib = DCAST(LightAttrib, attrib)->add_on_light(NodePath(light->as_node())); return attrib; case O_remove: attrib = make(); - attrib = DCAST(LightAttrib, attrib)->add_off_light(light); + attrib = DCAST(LightAttrib, attrib)->add_off_light(NodePath(light->as_node())); return attrib; } @@ -78,20 +78,20 @@ make(LightAttrib::Operation op, Light *light1, Light *light2) { switch (op) { case O_set: attrib = make_all_off(); - attrib = DCAST(LightAttrib, attrib)->add_on_light(light1); - attrib = DCAST(LightAttrib, attrib)->add_on_light(light2); + attrib = DCAST(LightAttrib, attrib)->add_on_light(NodePath(light1->as_node())); + attrib = DCAST(LightAttrib, attrib)->add_on_light(NodePath(light2->as_node())); return attrib; case O_add: attrib = make(); - attrib = DCAST(LightAttrib, attrib)->add_on_light(light1); - attrib = DCAST(LightAttrib, attrib)->add_on_light(light2); + attrib = DCAST(LightAttrib, attrib)->add_on_light(NodePath(light1->as_node())); + attrib = DCAST(LightAttrib, attrib)->add_on_light(NodePath(light2->as_node())); return attrib; case O_remove: attrib = make(); - attrib = DCAST(LightAttrib, attrib)->add_off_light(light1); - attrib = DCAST(LightAttrib, attrib)->add_off_light(light2); + attrib = DCAST(LightAttrib, attrib)->add_off_light(NodePath(light1->as_node())); + attrib = DCAST(LightAttrib, attrib)->add_off_light(NodePath(light2->as_node())); return attrib; } @@ -116,23 +116,23 @@ make(LightAttrib::Operation op, Light *light1, Light *light2, switch (op) { case O_set: attrib = make_all_off(); - attrib = DCAST(LightAttrib, attrib)->add_on_light(light1); - attrib = DCAST(LightAttrib, attrib)->add_on_light(light2); - attrib = DCAST(LightAttrib, attrib)->add_on_light(light3); + attrib = DCAST(LightAttrib, attrib)->add_on_light(NodePath(light1->as_node())); + attrib = DCAST(LightAttrib, attrib)->add_on_light(NodePath(light2->as_node())); + attrib = DCAST(LightAttrib, attrib)->add_on_light(NodePath(light3->as_node())); return attrib; case O_add: attrib = make(); - attrib = DCAST(LightAttrib, attrib)->add_on_light(light1); - attrib = DCAST(LightAttrib, attrib)->add_on_light(light2); - attrib = DCAST(LightAttrib, attrib)->add_on_light(light3); + attrib = DCAST(LightAttrib, attrib)->add_on_light(NodePath(light1->as_node())); + attrib = DCAST(LightAttrib, attrib)->add_on_light(NodePath(light2->as_node())); + attrib = DCAST(LightAttrib, attrib)->add_on_light(NodePath(light3->as_node())); return attrib; case O_remove: attrib = make(); - attrib = DCAST(LightAttrib, attrib)->add_off_light(light1); - attrib = DCAST(LightAttrib, attrib)->add_off_light(light2); - attrib = DCAST(LightAttrib, attrib)->add_off_light(light3); + attrib = DCAST(LightAttrib, attrib)->add_off_light(NodePath(light1->as_node())); + attrib = DCAST(LightAttrib, attrib)->add_off_light(NodePath(light2->as_node())); + attrib = DCAST(LightAttrib, attrib)->add_off_light(NodePath(light3->as_node())); return attrib; } @@ -157,26 +157,26 @@ make(LightAttrib::Operation op, Light *light1, Light *light2, switch (op) { case O_set: attrib = make_all_off(); - attrib = DCAST(LightAttrib, attrib)->add_on_light(light1); - attrib = DCAST(LightAttrib, attrib)->add_on_light(light2); - attrib = DCAST(LightAttrib, attrib)->add_on_light(light3); - attrib = DCAST(LightAttrib, attrib)->add_on_light(light4); + attrib = DCAST(LightAttrib, attrib)->add_on_light(NodePath(light1->as_node())); + attrib = DCAST(LightAttrib, attrib)->add_on_light(NodePath(light2->as_node())); + attrib = DCAST(LightAttrib, attrib)->add_on_light(NodePath(light3->as_node())); + attrib = DCAST(LightAttrib, attrib)->add_on_light(NodePath(light4->as_node())); return attrib; case O_add: attrib = make(); - attrib = DCAST(LightAttrib, attrib)->add_on_light(light1); - attrib = DCAST(LightAttrib, attrib)->add_on_light(light2); - attrib = DCAST(LightAttrib, attrib)->add_on_light(light3); - attrib = DCAST(LightAttrib, attrib)->add_on_light(light4); + attrib = DCAST(LightAttrib, attrib)->add_on_light(NodePath(light1->as_node())); + attrib = DCAST(LightAttrib, attrib)->add_on_light(NodePath(light2->as_node())); + attrib = DCAST(LightAttrib, attrib)->add_on_light(NodePath(light3->as_node())); + attrib = DCAST(LightAttrib, attrib)->add_on_light(NodePath(light4->as_node())); return attrib; case O_remove: attrib = make(); - attrib = DCAST(LightAttrib, attrib)->add_off_light(light1); - attrib = DCAST(LightAttrib, attrib)->add_off_light(light2); - attrib = DCAST(LightAttrib, attrib)->add_off_light(light3); - attrib = DCAST(LightAttrib, attrib)->add_off_light(light4); + attrib = DCAST(LightAttrib, attrib)->add_off_light(NodePath(light1->as_node())); + attrib = DCAST(LightAttrib, attrib)->add_off_light(NodePath(light2->as_node())); + attrib = DCAST(LightAttrib, attrib)->add_off_light(NodePath(light3->as_node())); + attrib = DCAST(LightAttrib, attrib)->add_off_light(NodePath(light4->as_node())); return attrib; } @@ -235,7 +235,7 @@ get_num_lights() const { //////////////////////////////////////////////////////////////////// // Function: LightAttrib::get_light // Access: Published -// Description: Returns the nth lights listed in the attribute. +// Description: Returns the nth light listed in the attribute. // // This method is now deprecated. LightAttribs nowadays // have a separate list of on_lights and off_lights, so @@ -245,9 +245,9 @@ get_num_lights() const { Light *LightAttrib:: get_light(int n) const { if (get_num_off_lights() == 0) { - return get_on_light(n); + return get_on_light(n).node()->as_light(); } else { - return get_off_light(n); + return get_off_light(n).node()->as_light(); } } @@ -265,9 +265,9 @@ get_light(int n) const { bool LightAttrib:: has_light(Light *light) const { if (get_num_off_lights() == 0) { - return has_on_light(light); + return has_on_light(NodePath(light->as_node())); } else { - return has_off_light(light); + return has_off_light(NodePath(light->as_node())); } } @@ -283,9 +283,9 @@ has_light(Light *light) const { CPT(RenderAttrib) LightAttrib:: add_light(Light *light) const { if (get_num_off_lights() == 0) { - return add_on_light(light); + return add_on_light(NodePath(light->as_node())); } else { - return add_off_light(light); + return add_off_light(NodePath(light->as_node())); } } @@ -302,9 +302,9 @@ add_light(Light *light) const { CPT(RenderAttrib) LightAttrib:: remove_light(Light *light) const { if (get_num_off_lights() == 0) { - return remove_on_light(light); + return remove_on_light(NodePath(light->as_node())); } else { - return remove_off_light(light); + return remove_off_light(NodePath(light->as_node())); } } @@ -352,7 +352,8 @@ make_all_off() { // turned on by this attrib. //////////////////////////////////////////////////////////////////// CPT(RenderAttrib) LightAttrib:: -add_on_light(Light *light) const { +add_on_light(const NodePath &light) const { + nassertr(!light.is_empty() && light.node()->as_light() != (Light *)NULL, this); LightAttrib *attrib = new LightAttrib(*this); attrib->_on_lights.insert(light); attrib->_off_lights.erase(light); @@ -375,7 +376,8 @@ add_on_light(Light *light) const { // lights turned on by this attrib. //////////////////////////////////////////////////////////////////// CPT(RenderAttrib) LightAttrib:: -remove_on_light(Light *light) const { +remove_on_light(const NodePath &light) const { + nassertr(!light.is_empty() && light.node()->as_light() != (Light *)NULL, this); LightAttrib *attrib = new LightAttrib(*this); attrib->_on_lights.erase(light); return return_new(attrib); @@ -389,7 +391,8 @@ remove_on_light(Light *light) const { // turned off by this attrib. //////////////////////////////////////////////////////////////////// CPT(RenderAttrib) LightAttrib:: -add_off_light(Light *light) const { +add_off_light(const NodePath &light) const { + nassertr(!light.is_empty() && light.node()->as_light() != (Light *)NULL, this); LightAttrib *attrib = new LightAttrib(*this); if (!_off_all_lights) { attrib->_off_lights.insert(light); @@ -406,7 +409,8 @@ add_off_light(Light *light) const { // lights turned off by this attrib. //////////////////////////////////////////////////////////////////// CPT(RenderAttrib) LightAttrib:: -remove_off_light(Light *light) const { +remove_off_light(const NodePath &light) const { + nassertr(!light.is_empty() && light.node()->as_light() != (Light *)NULL, this); LightAttrib *attrib = new LightAttrib(*this); attrib->_off_lights.erase(light); return return_new(attrib); @@ -453,8 +457,8 @@ output(ostream &out) const { out << "off"; Lights::const_iterator fi; for (fi = _off_lights.begin(); fi != _off_lights.end(); ++fi) { - Light *light = (*fi); - out << " " << *light; + NodePath light = (*fi); + out << " " << light; } if (!_on_lights.empty()) { @@ -464,8 +468,8 @@ output(ostream &out) const { Lights::const_iterator li; for (li = _on_lights.begin(); li != _on_lights.end(); ++li) { - Light *light = (*li); - out << " " << *light; + NodePath light = (*li); + out << " " << light; } } @@ -497,11 +501,12 @@ compare_to_impl(const RenderAttrib *other) const { Lights::const_iterator oli = ta->_on_lights.begin(); while (li != _on_lights.end() && oli != ta->_on_lights.end()) { - Light *light = (*li); - Light *other_light = (*oli); + NodePath light = (*li); + NodePath other_light = (*oli); - if (light != other_light) { - return light < other_light ? -1 : 1; + int compare = light.compare_to(other_light); + if (compare != 0) { + return compare; } ++li; @@ -519,11 +524,12 @@ compare_to_impl(const RenderAttrib *other) const { Lights::const_iterator ofi = ta->_off_lights.begin(); while (fi != _off_lights.end() && ofi != ta->_off_lights.end()) { - Light *light = (*fi); - Light *other_light = (*ofi); + NodePath light = (*fi); + NodePath other_light = (*ofi); - if (light != other_light) { - return light < other_light ? -1 : 1; + int compare = light.compare_to(other_light); + if (compare != 0) { + return compare; } ++fi; @@ -612,7 +618,7 @@ compose_impl(const RenderAttrib *other) const { } else { // (*bi) == (*ai) // Here is a light we have in both. - *result = *ai; + *result = *bi; ++ai; ++bi; ++result; @@ -636,7 +642,7 @@ compose_impl(const RenderAttrib *other) const { } else { // Here is a light we have in both. - *result = *ai; + *result = *bi; ++ai; ++bi; ++result; @@ -740,8 +746,10 @@ write_datagram(BamWriter *manager, Datagram &dg) { // write the off lights pointers if any Lights::const_iterator fi; for (fi = _off_lights.begin(); fi != _off_lights.end(); ++fi) { - Light *light = (*fi); - manager->write_pointer(dg, light->as_node()); + NodePath light = (*fi); + + // Whoops, we don't have a way to write out a NodePath right now. + manager->write_pointer(dg, light.node()); } // write the number of on lights @@ -749,8 +757,8 @@ write_datagram(BamWriter *manager, Datagram &dg) { // write the on lights pointers if any Lights::const_iterator nti; for (nti = _on_lights.begin(); nti != _on_lights.end(); ++nti) { - Light *light = (*nti); - manager->write_pointer(dg, light->as_node()); + NodePath light = (*nti); + manager->write_pointer(dg, light.node()); } } @@ -769,7 +777,7 @@ complete_pointers(TypedWritable **p_list, BamReader *manager) { while (ci != _off_lights.end()) { PandaNode *node; DCAST_INTO_R(node, p_list[pi++], pi); - (*ci) = node->as_light(); + (*ci) = NodePath(node); ++ci; } @@ -777,7 +785,7 @@ complete_pointers(TypedWritable **p_list, BamReader *manager) { while (ci != _on_lights.end()) { PandaNode *node; DCAST_INTO_R(node, p_list[pi++], pi); - (*ci) = node->as_light(); + (*ci) = NodePath(node); ++ci; } diff --git a/panda/src/pgraph/lightAttrib.h b/panda/src/pgraph/lightAttrib.h index f25c78c275..1a931597c6 100644 --- a/panda/src/pgraph/lightAttrib.h +++ b/panda/src/pgraph/lightAttrib.h @@ -24,6 +24,7 @@ #include "light.h" #include "renderAttrib.h" #include "ordered_vector.h" +#include "nodePath.h" //////////////////////////////////////////////////////////////////// // Class : LightAttrib @@ -74,20 +75,20 @@ PUBLISHED: static CPT(RenderAttrib) make_all_off(); INLINE int get_num_on_lights() const; - INLINE Light *get_on_light(int n) const; - INLINE bool has_on_light(Light *light) const; + INLINE NodePath get_on_light(int n) const; + INLINE bool has_on_light(const NodePath &light) const; INLINE int get_num_off_lights() const; - INLINE Light *get_off_light(int n) const; - INLINE bool has_off_light(Light *light) const; + INLINE NodePath get_off_light(int n) const; + INLINE bool has_off_light(const NodePath &light) const; INLINE bool has_all_off() const; INLINE bool is_identity() const; - CPT(RenderAttrib) add_on_light(Light *light) const; - CPT(RenderAttrib) remove_on_light(Light *light) const; - CPT(RenderAttrib) add_off_light(Light *light) const; - CPT(RenderAttrib) remove_off_light(Light *light) const; + CPT(RenderAttrib) add_on_light(const NodePath &light) const; + CPT(RenderAttrib) remove_on_light(const NodePath &light) const; + CPT(RenderAttrib) add_off_light(const NodePath &light) const; + CPT(RenderAttrib) remove_off_light(const NodePath &light) const; public: virtual void issue(GraphicsStateGuardianBase *gsg) const; @@ -100,7 +101,7 @@ protected: virtual RenderAttrib *make_default_impl() const; private: - typedef ov_set< PT(Light) > Lights; + typedef ov_set Lights; Lights _on_lights, _off_lights; bool _off_all_lights; diff --git a/panda/src/pgraph/nodePath.cxx b/panda/src/pgraph/nodePath.cxx index ae115ec8e4..5e8be69fc0 100644 --- a/panda/src/pgraph/nodePath.cxx +++ b/panda/src/pgraph/nodePath.cxx @@ -2024,54 +2024,6 @@ get_color_scale() const { return ident_scale; } -//////////////////////////////////////////////////////////////////// -// Function: NodePath::set_light -// Access: Published -// Description: Adds the indicated Light to the list of lights that -// illuminate geometry at this node and below. The -// light itself should be parented into the scene graph -// elsewhere, to represent the light's position in -// space; but until set_light() is called it will -// illuminate no geometry. -//////////////////////////////////////////////////////////////////// -void NodePath:: -set_light(Light *light, int priority) { - nassertv_always(!is_empty()); - - const RenderAttrib *attrib = - node()->get_attrib(LightAttrib::get_class_type()); - if (attrib != (const RenderAttrib *)NULL) { - priority = max(priority, - node()->get_state()->get_override(LightAttrib::get_class_type())); - const LightAttrib *la = DCAST(LightAttrib, attrib); - - // Modify the existing LightAttrib to add the indicated - // light. - node()->set_attrib(la->add_on_light(light), priority); - - } else { - // Create a new LightAttrib for this node. - CPT(LightAttrib) la = DCAST(LightAttrib, LightAttrib::make()); - node()->set_attrib(la->add_on_light(light), priority); - } -} - -//////////////////////////////////////////////////////////////////// -// Function: NodePath::set_light -// Access: Published -// Description: Adds a PolylightEffect to the geometry at this node -// and below. This makes the geometry at this point in -// the scene graph grow brighter or dimmer according to -// its proximity to the indicated PolylightNode; this is -// an effect similar to lighting, but is not related to -// traditional hardware T&L. -//////////////////////////////////////////////////////////////////// -void NodePath:: -set_light(PolylightNode *) { - // Not yet implemented. - nassertv(false); -} - //////////////////////////////////////////////////////////////////// // Function: NodePath::set_light // Access: Published @@ -2084,11 +2036,26 @@ set_light(PolylightNode *) { //////////////////////////////////////////////////////////////////// void NodePath:: set_light(const NodePath &light, int priority) { + nassertv_always(!is_empty()); if (!light.is_empty()) { - PandaNode *node = light.node(); - Light *light_obj = node->as_light(); + Light *light_obj = light.node()->as_light(); if (light_obj != (Light *)NULL) { - set_light(light_obj, priority); + const RenderAttrib *attrib = + node()->get_attrib(LightAttrib::get_class_type()); + if (attrib != (const RenderAttrib *)NULL) { + priority = max(priority, + node()->get_state()->get_override(LightAttrib::get_class_type())); + const LightAttrib *la = DCAST(LightAttrib, attrib); + + // Modify the existing LightAttrib to add the indicated + // light. + node()->set_attrib(la->add_on_light(light), priority); + + } else { + // Create a new LightAttrib for this node. + CPT(LightAttrib) la = DCAST(LightAttrib, LightAttrib::make()); + node()->set_attrib(la->add_on_light(light), priority); + } return; } } @@ -2115,40 +2082,6 @@ set_light_off(int priority) { node()->set_attrib(LightAttrib::make_all_off(), priority); } -//////////////////////////////////////////////////////////////////// -// Function: NodePath::set_light_off -// Access: Published -// Description: Sets the geometry at this level and below to render -// using without the indicated Light. This is different -// from not specifying the Light; rather, this -// specifically contradicts set_light() at a higher node -// level (or, with a priority, overrides a set_light() -// at a lower level). -//////////////////////////////////////////////////////////////////// -void NodePath:: -set_light_off(Light *light, int priority) { - nassertv_always(!is_empty()); - - const RenderAttrib *attrib = - node()->get_attrib(LightAttrib::get_class_type()); - if (attrib != (const RenderAttrib *)NULL) { - priority = max(priority, - node()->get_state()->get_override(LightAttrib::get_class_type())); - const LightAttrib *la = DCAST(LightAttrib, attrib); - - // Modify the existing LightAttrib to add the indicated light - // to the "off" list. This also, incidentally, removes it from - // the "on" list if it is there. - node()->set_attrib(la->add_off_light(light), priority); - - } else { - // Create a new LightAttrib for this node that turns off the - // indicated light. - CPT(LightAttrib) la = DCAST(LightAttrib, LightAttrib::make()); - node()->set_attrib(la->add_off_light(light), priority); - } -} - //////////////////////////////////////////////////////////////////// // Function: NodePath::set_light_off // Access: Published @@ -2164,11 +2097,29 @@ set_light_off(Light *light, int priority) { //////////////////////////////////////////////////////////////////// void NodePath:: set_light_off(const NodePath &light, int priority) { + nassertv_always(!is_empty()); + if (!light.is_empty()) { - PandaNode *node = light.node(); - Light *light_obj = node->as_light(); + Light *light_obj = light.node()->as_light(); if (light_obj != (Light *)NULL) { - set_light_off(light_obj, priority); + const RenderAttrib *attrib = + node()->get_attrib(LightAttrib::get_class_type()); + if (attrib != (const RenderAttrib *)NULL) { + priority = max(priority, + node()->get_state()->get_override(LightAttrib::get_class_type())); + const LightAttrib *la = DCAST(LightAttrib, attrib); + + // Modify the existing LightAttrib to add the indicated light + // to the "off" list. This also, incidentally, removes it from + // the "on" list if it is there. + node()->set_attrib(la->add_off_light(light), priority); + + } else { + // Create a new LightAttrib for this node that turns off the + // indicated light. + CPT(LightAttrib) la = DCAST(LightAttrib, LightAttrib::make()); + node()->set_attrib(la->add_off_light(light), priority); + } return; } } @@ -2189,45 +2140,6 @@ clear_light() { node()->clear_effect(PolylightEffect::get_class_type()); } -//////////////////////////////////////////////////////////////////// -// Function: NodePath::clear_light -// Access: Published -// Description: Removes any reference to the indicated Light -// from the NodePath. -//////////////////////////////////////////////////////////////////// -void NodePath:: -clear_light(Light *light) { - nassertv_always(!is_empty()); - - const RenderAttrib *attrib = - node()->get_attrib(LightAttrib::get_class_type()); - if (attrib != (const RenderAttrib *)NULL) { - CPT(LightAttrib) la = DCAST(LightAttrib, attrib); - la = DCAST(LightAttrib, la->remove_on_light(light)); - la = DCAST(LightAttrib, la->remove_off_light(light)); - - if (la->is_identity()) { - node()->clear_attrib(LightAttrib::get_class_type()); - - } else { - int priority = node()->get_state()->get_override(LightAttrib::get_class_type()); - node()->set_attrib(la, priority); - } - } -} - -//////////////////////////////////////////////////////////////////// -// Function: NodePath::clear_light -// Access: Published -// Description: Removes the indicated PolylightEffect from the -// geometry. This undoes a previous set_light() call. -//////////////////////////////////////////////////////////////////// -void NodePath:: -clear_light(PolylightNode *) { - // Not yet implemented. - nassertv(false); -} - //////////////////////////////////////////////////////////////////// // Function: NodePath::clear_light // Access: Published @@ -2236,54 +2148,32 @@ clear_light(PolylightNode *) { //////////////////////////////////////////////////////////////////// void NodePath:: clear_light(const NodePath &light) { + nassertv_always(!is_empty()); + if (!light.is_empty()) { - PandaNode *node = light.node(); - Light *light_obj = node->as_light(); + Light *light_obj = light.node()->as_light(); if (light_obj != (Light *)NULL) { - clear_light(light_obj); + const RenderAttrib *attrib = + node()->get_attrib(LightAttrib::get_class_type()); + if (attrib != (const RenderAttrib *)NULL) { + CPT(LightAttrib) la = DCAST(LightAttrib, attrib); + la = DCAST(LightAttrib, la->remove_on_light(light)); + la = DCAST(LightAttrib, la->remove_off_light(light)); + + if (la->is_identity()) { + node()->clear_attrib(LightAttrib::get_class_type()); + + } else { + int priority = node()->get_state()->get_override(LightAttrib::get_class_type()); + node()->set_attrib(la, priority); + } + } return; } } nassert_raise("Not a Light object."); } -//////////////////////////////////////////////////////////////////// -// Function: NodePath::has_light -// Access: Published -// Description: Returns true if the indicated Light has been -// specifically enabled on this particular node. This -// means that someone called set_light() on this node -// with the indicated light. -//////////////////////////////////////////////////////////////////// -bool NodePath:: -has_light(Light *light) const { - nassertr_always(!is_empty(), false); - - const RenderAttrib *attrib = - node()->get_attrib(LightAttrib::get_class_type()); - if (attrib != (const RenderAttrib *)NULL) { - const LightAttrib *la = DCAST(LightAttrib, attrib); - return la->has_on_light(light); - } - - return false; -} - -//////////////////////////////////////////////////////////////////// -// Function: NodePath::has_light -// Access: Published -// Description: Returns true if the indicated PolylightNode has been -// specifically enabled on this particular node. This -// means that someone called set_light() on this node -// with the indicated light. -//////////////////////////////////////////////////////////////////// -bool NodePath:: -has_light(PolylightNode *) const { - // Not yet implemented. - nassertr(false, false); - return false; -} - //////////////////////////////////////////////////////////////////// // Function: NodePath::has_light // Access: Published @@ -2294,11 +2184,17 @@ has_light(PolylightNode *) const { //////////////////////////////////////////////////////////////////// bool NodePath:: has_light(const NodePath &light) const { + nassertr_always(!is_empty(), false); + if (!light.is_empty()) { - PandaNode *node = light.node(); - Light *light_obj = node->as_light(); + Light *light_obj = light.node()->as_light(); if (light_obj != (Light *)NULL) { - return has_light(light_obj); + const RenderAttrib *attrib = + node()->get_attrib(LightAttrib::get_class_type()); + if (attrib != (const RenderAttrib *)NULL) { + const LightAttrib *la = DCAST(LightAttrib, attrib); + return la->has_on_light(light); + } } } nassert_raise("Not a Light object."); @@ -2316,6 +2212,7 @@ has_light(const NodePath &light) const { bool NodePath:: has_light_off() const { nassertr_always(!is_empty(), false); + const RenderAttrib *attrib = node()->get_attrib(LightAttrib::get_class_type()); if (attrib != (const RenderAttrib *)NULL) { @@ -2326,28 +2223,6 @@ has_light_off() const { return false; } -//////////////////////////////////////////////////////////////////// -// Function: NodePath::has_light_off -// Access: Published -// Description: Returns true if the indicated Light has been -// specifically disabled on this particular node. This -// means that someone called set_light_off() on this -// node with the indicated light. -//////////////////////////////////////////////////////////////////// -bool NodePath:: -has_light_off(Light *light) const { - nassertr_always(!is_empty(), false); - - const RenderAttrib *attrib = - node()->get_attrib(LightAttrib::get_class_type()); - if (attrib != (const RenderAttrib *)NULL) { - const LightAttrib *la = DCAST(LightAttrib, attrib); - return la->has_off_light(light); - } - - return false; -} - //////////////////////////////////////////////////////////////////// // Function: NodePath::has_light_off // Access: Published @@ -2361,11 +2236,16 @@ has_light_off(Light *light) const { //////////////////////////////////////////////////////////////////// bool NodePath:: has_light_off(const NodePath &light) const { + nassertr_always(!is_empty(), false); if (!light.is_empty()) { - PandaNode *node = light.node(); - Light *light_obj = node->as_light(); + Light *light_obj = light.node()->as_light(); if (light_obj != (Light *)NULL) { - return has_light(light_obj); + const RenderAttrib *attrib = + node()->get_attrib(LightAttrib::get_class_type()); + if (attrib != (const RenderAttrib *)NULL) { + const LightAttrib *la = DCAST(LightAttrib, attrib); + return la->has_off_light(light); + } } } nassert_raise("Not a Light object."); diff --git a/panda/src/pgraph/nodePath.h b/panda/src/pgraph/nodePath.h index f0889ca233..aa303044cb 100644 --- a/panda/src/pgraph/nodePath.h +++ b/panda/src/pgraph/nodePath.h @@ -487,25 +487,13 @@ PUBLISHED: INLINE float get_sb() const; INLINE float get_sa() const; - void set_light(Light *light, int priority = 0); - void set_light(PolylightNode *light); void set_light(const NodePath &light, int priority = 0); - void set_light_off(int priority = 0); - void set_light_off(Light *light, int priority = 0); void set_light_off(const NodePath &light, int priority = 0); - void clear_light(); - void clear_light(Light *light); - void clear_light(PolylightNode *light); void clear_light(const NodePath &light); - - bool has_light(Light *light) const; - bool has_light(PolylightNode *light) const; bool has_light(const NodePath &light) const; - bool has_light_off() const; - bool has_light_off(Light *light) const; bool has_light_off(const NodePath &light) const; void set_bin(const string &bin_name, int draw_order, int priority = 0); diff --git a/panda/src/pgraph/pointLight.cxx b/panda/src/pgraph/pointLight.cxx index 5e6b032d04..21a8599f73 100644 --- a/panda/src/pgraph/pointLight.cxx +++ b/panda/src/pgraph/pointLight.cxx @@ -138,8 +138,8 @@ write(ostream &out, int indent_level) const { // Description: //////////////////////////////////////////////////////////////////// void PointLight:: -bind(GraphicsStateGuardianBase *gsg, int light_id) { - gsg->bind_light(this, light_id); +bind(GraphicsStateGuardianBase *gsg, const NodePath &light, int light_id) { + gsg->bind_light(this, light, light_id); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/pgraph/pointLight.h b/panda/src/pgraph/pointLight.h index b2592f6fc7..47ffe4c538 100644 --- a/panda/src/pgraph/pointLight.h +++ b/panda/src/pgraph/pointLight.h @@ -51,7 +51,8 @@ PUBLISHED: INLINE void set_point(const LPoint3f &point); public: - virtual void bind(GraphicsStateGuardianBase *gsg, int light_id); + virtual void bind(GraphicsStateGuardianBase *gsg, const NodePath &light, + int light_id); private: // This is the data that must be cycled between pipeline stages. diff --git a/panda/src/pgraph/spotlight.cxx b/panda/src/pgraph/spotlight.cxx index 9a8b499394..46bc09fe69 100644 --- a/panda/src/pgraph/spotlight.cxx +++ b/panda/src/pgraph/spotlight.cxx @@ -146,8 +146,8 @@ write(ostream &out, int indent_level) const { // Description: //////////////////////////////////////////////////////////////////// void Spotlight:: -bind(GraphicsStateGuardianBase *gsg, int light_id) { - gsg->bind_light(this, light_id); +bind(GraphicsStateGuardianBase *gsg, const NodePath &light, int light_id) { + gsg->bind_light(this, light, light_id); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/pgraph/spotlight.h b/panda/src/pgraph/spotlight.h index 8853c26e44..577bea8e18 100644 --- a/panda/src/pgraph/spotlight.h +++ b/panda/src/pgraph/spotlight.h @@ -62,7 +62,8 @@ PUBLISHED: INLINE void set_attenuation(const LVecBase3f &attenuation); public: - virtual void bind(GraphicsStateGuardianBase *gsg, int light_id); + virtual void bind(GraphicsStateGuardianBase *gsg, const NodePath &light, + int light_id); bool make_image(Texture *texture, float radius); diff --git a/panda/src/pgraph/textureAttrib.I b/panda/src/pgraph/textureAttrib.I index 88c926832b..0197827d90 100644 --- a/panda/src/pgraph/textureAttrib.I +++ b/panda/src/pgraph/textureAttrib.I @@ -160,7 +160,8 @@ get_off_stage(int n) const { //////////////////////////////////////////////////////////////////// INLINE bool TextureAttrib:: has_off_stage(TextureStage *stage) const { - return _off_all_stages || _off_stages.find(stage) != _off_stages.end(); + return _off_stages.find(stage) != _off_stages.end() || + (_off_all_stages && !has_on_stage(stage)); } ////////////////////////////////////////////////////////////////////