From 7f23c901a5b3a8cb88417882cfeb76169e247919 Mon Sep 17 00:00:00 2001 From: David Rose Date: Tue, 1 May 2001 02:18:22 +0000 Subject: [PATCH] *** empty log message *** --- panda/src/collide/collisionSphere.cxx | 51 ++- panda/src/collide/collisionSphere.h | 9 +- panda/src/dxgsg/dxGraphicsStateGuardian.cxx | 8 +- panda/src/dxgsg/dxGraphicsStateGuardian.h | 2 +- panda/src/egg/eggMaterial.I | 153 ++++++++- panda/src/egg/eggMaterial.cxx | 8 +- panda/src/egg/eggMaterial.h | 33 +- panda/src/egg/parser.yxx | 46 ++- panda/src/glgsg/glGraphicsStateGuardian.I | 144 --------- panda/src/glgsg/glGraphicsStateGuardian.cxx | 58 ++-- panda/src/glgsg/glGraphicsStateGuardian.h | 10 +- panda/src/gobj/Sources.pp | 5 +- panda/src/gobj/config_gobj.cxx | 1 + panda/src/gobj/material.I | 302 ++++++++++++++---- panda/src/gobj/material.cxx | 178 ++++++++--- panda/src/gobj/material.h | 106 +++--- panda/src/graph/nodeRelation.cxx | 2 +- panda/src/gsgbase/graphicsStateGuardianBase.h | 2 +- panda/src/sgattrib/materialAttribute.I | 6 +- panda/src/sgattrib/materialAttribute.cxx | 6 +- panda/src/sgattrib/materialAttribute.h | 7 +- panda/src/sgattrib/materialTransition.I | 8 +- panda/src/sgattrib/materialTransition.cxx | 90 +++++- panda/src/sgattrib/materialTransition.h | 22 +- panda/src/sgattrib/textureTransition.cxx | 57 ++-- panda/src/sgattrib/textureTransition.h | 7 +- panda/src/sgmanip/nodePath.I | 15 +- panda/src/sgmanip/nodePath.cxx | 73 +++++ panda/src/sgmanip/nodePath.h | 7 + 29 files changed, 987 insertions(+), 429 deletions(-) diff --git a/panda/src/collide/collisionSphere.cxx b/panda/src/collide/collisionSphere.cxx index 128cbe7351..0a52eca905 100644 --- a/panda/src/collide/collisionSphere.cxx +++ b/panda/src/collide/collisionSphere.cxx @@ -339,6 +339,16 @@ intersects_line(double &t1, double &t2, return true; } +//////////////////////////////////////////////////////////////////// +// Function: CollisionSphere::register_with_read_factory +// Access: Public, Static +// Description: Factory method to generate a CollisionSphere object +//////////////////////////////////////////////////////////////////// +void CollisionSphere:: +register_with_read_factory() { + BamReader::get_factory()->register_factory(get_class_type(), make_CollisionSphere); +} + //////////////////////////////////////////////////////////////////// // Function: CollisionSphere::write_datagram // Access: Public @@ -346,37 +356,19 @@ intersects_line(double &t1, double &t2, // the particular object to a Datagram //////////////////////////////////////////////////////////////////// void CollisionSphere:: -write_datagram(BamWriter *manager, Datagram &me) -{ +write_datagram(BamWriter *manager, Datagram &me) { CollisionSolid::write_datagram(manager, me); _center.write_datagram(me); me.add_float32(_radius); } -//////////////////////////////////////////////////////////////////// -// Function: CollisionSphere::fillin -// Access: Protected -// Description: Function that reads out of the datagram (or asks -// manager to read) all of the data that is needed to -// re-create this object and stores it in the appropiate -// place -//////////////////////////////////////////////////////////////////// -void CollisionSphere:: -fillin(DatagramIterator& scan, BamReader* manager) -{ - CollisionSolid::fillin(scan, manager); - _center.read_datagram(scan); - _radius = scan.get_float32(); -} - //////////////////////////////////////////////////////////////////// // Function: CollisionSphere::make_CollisionSphere // Access: Protected // Description: Factory method to generate a CollisionSphere object //////////////////////////////////////////////////////////////////// -TypedWriteable* CollisionSphere:: -make_CollisionSphere(const FactoryParams ¶ms) -{ +TypedWriteable *CollisionSphere:: +make_CollisionSphere(const FactoryParams ¶ms) { CollisionSphere *me = new CollisionSphere; BamReader *manager; Datagram packet; @@ -389,13 +381,16 @@ make_CollisionSphere(const FactoryParams ¶ms) } //////////////////////////////////////////////////////////////////// -// Function: CollisionSphere::register_with_factory -// Access: Public, Static -// Description: Factory method to generate a CollisionSphere object +// Function: CollisionSphere::fillin +// Access: Protected +// Description: Function that reads out of the datagram (or asks +// manager to read) all of the data that is needed to +// re-create this object and stores it in the appropiate +// place //////////////////////////////////////////////////////////////////// void CollisionSphere:: -register_with_read_factory(void) -{ - BamReader::get_factory()->register_factory(get_class_type(), make_CollisionSphere); +fillin(DatagramIterator& scan, BamReader* manager) { + CollisionSolid::fillin(scan, manager); + _center.read_datagram(scan); + _radius = scan.get_float32(); } - diff --git a/panda/src/collide/collisionSphere.h b/panda/src/collide/collisionSphere.h index f4e408765a..f54e887016 100644 --- a/panda/src/collide/collisionSphere.h +++ b/panda/src/collide/collisionSphere.h @@ -66,13 +66,12 @@ private: float _radius; public: - static void register_with_read_factory(void); - virtual void write_datagram(BamWriter* manager, Datagram &me); - - static TypedWriteable *make_CollisionSphere(const FactoryParams ¶ms); + static void register_with_read_factory(); + virtual void write_datagram(BamWriter *manager, Datagram &me); protected: - void fillin(DatagramIterator& scan, BamReader* manager); + static TypedWriteable *make_CollisionSphere(const FactoryParams ¶ms); + void fillin(DatagramIterator &scan, BamReader *manager); public: static TypeHandle get_class_type() { diff --git a/panda/src/dxgsg/dxGraphicsStateGuardian.cxx b/panda/src/dxgsg/dxGraphicsStateGuardian.cxx index a70fbe1e56..0a36b0e5b0 100644 --- a/panda/src/dxgsg/dxGraphicsStateGuardian.cxx +++ b/panda/src/dxgsg/dxGraphicsStateGuardian.cxx @@ -3648,7 +3648,7 @@ draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr, // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian::apply_material( Material* material ) { +void DXGraphicsStateGuardian::apply_material( const Material* material ) { D3DMATERIAL7 cur_material; cur_material.dcvDiffuse = *(D3DCOLORVALUE *)(material->get_diffuse().get_data()); cur_material.dcvAmbient = *(D3DCOLORVALUE *)(material->get_ambient().get_data()); @@ -4131,9 +4131,9 @@ void DXGraphicsStateGuardian:: issue_material(const MaterialAttribute *attrib) { activate(); if (attrib->is_on()) { - Material *material = attrib->get_material(); - nassertv(material != (Material *)NULL); - material->apply(this); + const Material *material = attrib->get_material(); + nassertv(material != (const Material *)NULL); + apply_material(material); } } diff --git a/panda/src/dxgsg/dxGraphicsStateGuardian.h b/panda/src/dxgsg/dxGraphicsStateGuardian.h index 805e67a460..ee4c7f2def 100644 --- a/panda/src/dxgsg/dxGraphicsStateGuardian.h +++ b/panda/src/dxgsg/dxGraphicsStateGuardian.h @@ -132,7 +132,7 @@ public: const RenderBuffer &rb, const NodeAttributes& na=NodeAttributes()); - virtual void apply_material(Material* material); + virtual void apply_material(const Material *material); virtual void apply_fog(Fog *fog); virtual void apply_light(PointLight* light); diff --git a/panda/src/egg/eggMaterial.I b/panda/src/egg/eggMaterial.I index 72c199606f..142a789c95 100644 --- a/panda/src/egg/eggMaterial.I +++ b/panda/src/egg/eggMaterial.I @@ -10,9 +10,9 @@ // Description: //////////////////////////////////////////////////////////////////// INLINE void EggMaterial:: -set_diff(const Colorf &diff) { +set_diff(const RGBColorf &diff) { _diff = diff; - _has_diff = true; + _flags |= F_diff; } //////////////////////////////////////////////////////////////////// @@ -22,7 +22,7 @@ set_diff(const Colorf &diff) { //////////////////////////////////////////////////////////////////// INLINE void EggMaterial:: clear_diff() { - _has_diff = false; + _flags &= ~F_diff; } //////////////////////////////////////////////////////////////////// @@ -32,7 +32,7 @@ clear_diff() { //////////////////////////////////////////////////////////////////// INLINE bool EggMaterial:: has_diff() const { - return _has_diff; + return (_flags & F_diff) != 0; } //////////////////////////////////////////////////////////////////// @@ -42,11 +42,152 @@ has_diff() const { // false. If so, it simply returns the default diff // color. //////////////////////////////////////////////////////////////////// -INLINE Colorf EggMaterial:: +INLINE RGBColorf EggMaterial:: get_diff() const { if (has_diff()) { return _diff; } else { - return Colorf(1.0, 1.0, 1.0, 1.0); + return RGBColorf(1.0, 1.0, 1.0); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: EggMaterial::set_amb +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void EggMaterial:: +set_amb(const RGBColorf &amb) { + _amb = amb; + _flags |= F_amb; +} + +//////////////////////////////////////////////////////////////////// +// Function: EggMaterial::clear_amb +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void EggMaterial:: +clear_amb() { + _flags &= ~F_amb; +} + +//////////////////////////////////////////////////////////////////// +// Function: EggMaterial::has_amb +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE bool EggMaterial:: +has_amb() const { + return (_flags & F_amb) != 0; +} + +//////////////////////////////////////////////////////////////////// +// Function: EggMaterial::get_amb +// Access: Public +// Description: It is legal to call this even if has_amb() returns +// false. If so, it simply returns the default amb +// color. +//////////////////////////////////////////////////////////////////// +INLINE RGBColorf EggMaterial:: +get_amb() const { + if (has_amb()) { + return _amb; + } else { + return RGBColorf(1.0, 1.0, 1.0); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: EggMaterial::set_emit +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void EggMaterial:: +set_emit(const RGBColorf &emit) { + _emit = emit; + _flags |= F_emit; +} + +//////////////////////////////////////////////////////////////////// +// Function: EggMaterial::clear_emit +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void EggMaterial:: +clear_emit() { + _flags &= ~F_emit; +} + +//////////////////////////////////////////////////////////////////// +// Function: EggMaterial::has_emit +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE bool EggMaterial:: +has_emit() const { + return (_flags & F_emit) != 0; +} + +//////////////////////////////////////////////////////////////////// +// Function: EggMaterial::get_emit +// Access: Public +// Description: It is legal to call this even if has_emit() returns +// false. If so, it simply returns the default emit +// color. +//////////////////////////////////////////////////////////////////// +INLINE RGBColorf EggMaterial:: +get_emit() const { + if (has_emit()) { + return _emit; + } else { + return RGBColorf(1.0, 1.0, 1.0); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: EggMaterial::set_spec +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void EggMaterial:: +set_spec(const RGBColorf &spec) { + _spec = spec; + _flags |= F_spec; +} + +//////////////////////////////////////////////////////////////////// +// Function: EggMaterial::clear_spec +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void EggMaterial:: +clear_spec() { + _flags &= ~F_spec; +} + +//////////////////////////////////////////////////////////////////// +// Function: EggMaterial::has_spec +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE bool EggMaterial:: +has_spec() const { + return (_flags & F_spec) != 0; +} + +//////////////////////////////////////////////////////////////////// +// Function: EggMaterial::get_spec +// Access: Public +// Description: It is legal to call this even if has_spec() returns +// false. If so, it simply returns the default spec +// color. +//////////////////////////////////////////////////////////////////// +INLINE RGBColorf EggMaterial:: +get_spec() const { + if (has_spec()) { + return _spec; + } else { + return RGBColorf(1.0, 1.0, 1.0); } } diff --git a/panda/src/egg/eggMaterial.cxx b/panda/src/egg/eggMaterial.cxx index 234f6cf7f5..88beda4b7d 100644 --- a/panda/src/egg/eggMaterial.cxx +++ b/panda/src/egg/eggMaterial.cxx @@ -19,8 +19,7 @@ EggMaterial:: EggMaterial(const string &mref_name) : EggNode(mref_name) { - _diff.set(1.0, 1.0, 1.0, 1.0); - _has_diff = false; + _flags = 0; } //////////////////////////////////////////////////////////////////// @@ -31,8 +30,9 @@ EggMaterial(const string &mref_name) EggMaterial:: EggMaterial(const EggMaterial ©) : EggNode(copy), - _has_diff(copy._has_diff), - _diff(copy._diff) { + _diff(copy._diff), + _flags(copy._flags) +{ } diff --git a/panda/src/egg/eggMaterial.h b/panda/src/egg/eggMaterial.h index f74229409c..5a44e40f7f 100644 --- a/panda/src/egg/eggMaterial.h +++ b/panda/src/egg/eggMaterial.h @@ -23,14 +23,39 @@ public: virtual void write(ostream &out, int indent_level) const; - INLINE void set_diff(const Colorf &diff); + INLINE void set_diff(const RGBColorf &diff); INLINE void clear_diff(); INLINE bool has_diff() const; - INLINE Colorf get_diff() const; + INLINE RGBColorf get_diff() const; + + INLINE void set_amb(const RGBColorf &amb); + INLINE void clear_amb(); + INLINE bool has_amb() const; + INLINE RGBColorf get_amb() const; + + INLINE void set_emit(const RGBColorf &emit); + INLINE void clear_emit(); + INLINE bool has_emit() const; + INLINE RGBColorf get_emit() const; + + INLINE void set_spec(const RGBColorf &spec); + INLINE void clear_spec(); + INLINE bool has_spec() const; + INLINE RGBColorf get_spec() const; private: - bool _has_diff; - Colorf _diff; + enum Flags { + F_diff = 0x001, + F_amb = 0x002, + F_emit = 0x004, + F_spec = 0x008 + }; + + RGBColorf _diff; + RGBColorf _amb; + RGBColorf _emit; + RGBColorf _spec; + int _flags; public: diff --git a/panda/src/egg/parser.yxx b/panda/src/egg/parser.yxx index cbe5e7b0e3..34a7d92710 100644 --- a/panda/src/egg/parser.yxx +++ b/panda/src/egg/parser.yxx @@ -465,17 +465,57 @@ material_body: double value = $<_number>5; if (cmp_nocase_uh(name, "diffr") == 0) { - Colorf diff = material->get_diff(); + RGBColorf diff = material->get_diff(); diff[0] = value; material->set_diff(diff); } else if (cmp_nocase_uh(name, "diffg") == 0) { - Colorf diff = material->get_diff(); + RGBColorf diff = material->get_diff(); diff[1] = value; material->set_diff(diff); } else if (cmp_nocase_uh(name, "diffb") == 0) { - Colorf diff = material->get_diff(); + RGBColorf diff = material->get_diff(); diff[2] = value; material->set_diff(diff); + + } else if (cmp_nocase_uh(name, "ambr") == 0) { + RGBColorf amb = material->get_amb(); + amb[0] = value; + material->set_amb(amb); + } else if (cmp_nocase_uh(name, "ambg") == 0) { + RGBColorf amb = material->get_amb(); + amb[1] = value; + material->set_amb(amb); + } else if (cmp_nocase_uh(name, "ambb") == 0) { + RGBColorf amb = material->get_amb(); + amb[2] = value; + material->set_amb(amb); + + } else if (cmp_nocase_uh(name, "emitr") == 0) { + RGBColorf emit = material->get_emit(); + emit[0] = value; + material->set_emit(emit); + } else if (cmp_nocase_uh(name, "emitg") == 0) { + RGBColorf emit = material->get_emit(); + emit[1] = value; + material->set_emit(emit); + } else if (cmp_nocase_uh(name, "emitb") == 0) { + RGBColorf emit = material->get_emit(); + emit[2] = value; + material->set_emit(emit); + + } else if (cmp_nocase_uh(name, "specr") == 0) { + RGBColorf spec = material->get_spec(); + spec[0] = value; + material->set_spec(spec); + } else if (cmp_nocase_uh(name, "specg") == 0) { + RGBColorf spec = material->get_spec(); + spec[1] = value; + material->set_spec(spec); + } else if (cmp_nocase_uh(name, "specb") == 0) { + RGBColorf spec = material->get_spec(); + spec[2] = value; + material->set_spec(spec); + } else { eggyywarning("Unsupported material scalar: " + name); } diff --git a/panda/src/glgsg/glGraphicsStateGuardian.I b/panda/src/glgsg/glGraphicsStateGuardian.I index f12618e297..e7b43a27f0 100644 --- a/panda/src/glgsg/glGraphicsStateGuardian.I +++ b/panda/src/glgsg/glGraphicsStateGuardian.I @@ -253,125 +253,6 @@ call_glLightModelTwoSide(GLboolean twoside) } } -//////////////////////////////////////////////////////////////////// -// Function: GLGraphicsStateGuardian::call_glMaterialAmbient -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -INLINE void GLGraphicsStateGuardian:: -call_glMaterialAmbient( bool twoside, const Colorf& color ) -{ - if (_material_ambient != color) { - _material_ambient = color; - if (twoside) { -#ifdef GSG_VERBOSE - glgsg_cat.debug() - << "glMaterial(GL_FRONT_AND_BACK, GL_AMBIENT, " - << color << ")" << endl; -#endif - glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT, color.get_data() ); - } else { -#ifdef GSG_VERBOSE - glgsg_cat.debug() - << "glMaterial(GL_FRONT, GL_AMBIENT, " << color << ")" << endl; -#endif - glMaterialfv( GL_FRONT, GL_AMBIENT, color.get_data() ); - } - } -} - -//////////////////////////////////////////////////////////////////// -// Function: GLGraphicsStateGuardian::call_glMaterialDiffuse -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -INLINE void GLGraphicsStateGuardian:: -call_glMaterialDiffuse( bool twoside, const Colorf& color ) -{ - if ( _material_diffuse != color ) - { - _material_diffuse = color; - if ( twoside ) - glMaterialfv( GL_FRONT_AND_BACK, GL_DIFFUSE, color.get_data() ); - else - glMaterialfv( GL_FRONT, GL_DIFFUSE, color.get_data() ); - } -} - -//////////////////////////////////////////////////////////////////// -// Function: GLGraphicsStateGuardian::call_glMaterialAmbientDiffuse -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -INLINE void GLGraphicsStateGuardian:: -call_glMaterialAmbientDiffuse( bool twoside, const Colorf& color ) -{ - if ( _material_ambient != color || _material_diffuse != color ) - { - _material_ambient = color; - _material_diffuse = color; - if ( twoside ) - glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, - color.get_data() ); - else - glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color.get_data() ); - } -} - -//////////////////////////////////////////////////////////////////// -// Function: GLGraphicsStateGuardian::call_glMaterialSpecular -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -INLINE void GLGraphicsStateGuardian:: -call_glMaterialSpecular( bool twoside, const Colorf& color ) -{ - if ( _material_specular != color ) - { - _material_specular = color; - if ( twoside ) - glMaterialfv( GL_FRONT_AND_BACK, GL_SPECULAR, color.get_data() ); - else - glMaterialfv( GL_FRONT, GL_SPECULAR, color.get_data() ); - } -} - -//////////////////////////////////////////////////////////////////// -// Function: GLGraphicsStateGuardian::call_glMaterialShininess -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -INLINE void GLGraphicsStateGuardian:: -call_glMaterialShininess( bool twoside, float shininess ) -{ - if ( _material_shininess != shininess ) - { - _material_shininess = shininess; - if ( twoside ) - glMaterialf( GL_FRONT_AND_BACK, GL_SHININESS, shininess ); - else - glMaterialf( GL_FRONT, GL_SHININESS, shininess ); - } -} - -//////////////////////////////////////////////////////////////////// -// Function: GLGraphicsStateGuardian::call_glMaterialEmision -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -INLINE void GLGraphicsStateGuardian:: -call_glMaterialEmission( bool twoside, const Colorf& color ) -{ - if ( _material_emission != color ) - { - _material_emission = color; - if ( twoside ) - glMaterialfv( GL_FRONT_AND_BACK, GL_EMISSION, color.get_data() ); - else - glMaterialfv( GL_FRONT, GL_EMISSION, color.get_data() ); - } -} - //////////////////////////////////////////////////////////////////// // Function: GLGraphicsStateGuardian::call_glStencilFunc // Access: @@ -1002,31 +883,6 @@ INLINE void GLGraphicsStateGuardian::enable_light(int light, bool val) } } -//////////////////////////////////////////////////////////////////// -// Function: GLGraphicsStateGuardian::enable_color_material -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -INLINE void GLGraphicsStateGuardian:: -enable_color_material(bool val) { - if (_color_material_enabled != val) { - _color_material_enabled = val; - if (val) { -#ifdef GSG_VERBOSE - glgsg_cat.debug() - << "glEnable(GL_COLOR_MATERIAL)" << endl; -#endif - glEnable(GL_COLOR_MATERIAL); - } else { -#ifdef GSG_VERBOSE - glgsg_cat.debug() - << "glDisable(GL_COLOR_MATERIAL)" << endl; -#endif - glDisable(GL_COLOR_MATERIAL); - } - } -} - //////////////////////////////////////////////////////////////////// // Function: GLGraphicsStateGuardian::enable_texturing // Access: diff --git a/panda/src/glgsg/glGraphicsStateGuardian.cxx b/panda/src/glgsg/glGraphicsStateGuardian.cxx index 2b0cf805b9..132151363c 100644 --- a/panda/src/glgsg/glGraphicsStateGuardian.cxx +++ b/panda/src/glgsg/glGraphicsStateGuardian.cxx @@ -248,7 +248,6 @@ reset() { _multisample_enabled = false; _line_smooth_enabled = false; _point_smooth_enabled = false; - _color_material_enabled = false; _scissor_enabled = false; _lighting_enabled = false; _normals_enabled = false; @@ -2081,7 +2080,6 @@ draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr, set_state(state, false); - enable_color_material(false); set_unpack_alignment(1); glMatrixMode( GL_PROJECTION ); @@ -2153,19 +2151,43 @@ draw_pixel_buffer(PixelBuffer *pb, const DisplayRegion *dr, // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -void GLGraphicsStateGuardian::apply_material( Material* material ) -{ - call_glMaterialAmbient( material->get_twoside(), material->get_ambient() ); - call_glMaterialDiffuse( material->get_twoside(), material->get_diffuse() ); - call_glMaterialSpecular( material->get_twoside(), - material->get_specular() ); - call_glMaterialShininess( material->get_twoside(), - material->get_shininess() ); - call_glMaterialEmission( material->get_twoside(), - material->get_emission() ); +void GLGraphicsStateGuardian::apply_material(const Material *material) { + GLenum face = material->get_twoside() ? GL_FRONT_AND_BACK : GL_FRONT; - call_glLightModelLocal( material->get_local() ); - call_glLightModelTwoSide( material->get_twoside() ); + if (material->has_ambient() && material->has_diffuse()) { + // The material has both an ambient and diffuse specified. This + // means we do not need glMaterialColor(). + glMaterialfv(face, GL_AMBIENT, material->get_ambient().get_data()); + glMaterialfv(face, GL_DIFFUSE, material->get_diffuse().get_data()); + glDisable(GL_COLOR_MATERIAL); + + } else if (material->has_ambient()) { + // The material specifies an ambient, but not a diffuse component. + // The diffuse component comes from the object's color. + glMaterialfv(face, GL_AMBIENT, material->get_ambient().get_data()); + glColorMaterial(face, GL_DIFFUSE); + glEnable(GL_COLOR_MATERIAL); + + } else if (material->has_diffuse()) { + // The material specifies a diffuse, but not an ambient component. + // The ambient component comes from the object's color. + glMaterialfv(face, GL_AMBIENT, material->get_ambient().get_data()); + glColorMaterial(face, GL_AMBIENT); + glEnable(GL_COLOR_MATERIAL); + + } else { + // The material specifies neither a diffuse nor an ambient + // component. Both components come from the object's color. + glColorMaterial(face, GL_AMBIENT_AND_DIFFUSE); + glEnable(GL_COLOR_MATERIAL); + } + + glMaterialfv(face, GL_SPECULAR, material->get_specular().get_data()); + glMaterialfv(face, GL_EMISSION, material->get_emission().get_data()); + glMaterialf(face, GL_SHININESS, material->get_shininess()); + + call_glLightModelLocal(material->get_local()); + call_glLightModelTwoSide(material->get_twoside()); } //////////////////////////////////////////////////////////////////// @@ -2563,9 +2585,9 @@ void GLGraphicsStateGuardian:: issue_material(const MaterialAttribute *attrib) { // activate(); if (attrib->is_on()) { - Material *material = attrib->get_material(); - nassertv(material != (Material *)NULL); - material->apply(this); + const Material *material = attrib->get_material(); + nassertv(material != (const Material *)NULL); + apply_material(material); } } @@ -2707,10 +2729,8 @@ void GLGraphicsStateGuardian::issue_light(const LightAttribute *attrib ) // If no lights were enabled, disable lighting if (num_enabled == 0) { enable_lighting(false); - enable_color_material(false); } else { call_glLightModelAmbient(_cur_ambient_light); - enable_color_material(true); } } diff --git a/panda/src/glgsg/glGraphicsStateGuardian.h b/panda/src/glgsg/glGraphicsStateGuardian.h index 547b2bdafe..0a984c93b0 100644 --- a/panda/src/glgsg/glGraphicsStateGuardian.h +++ b/panda/src/glgsg/glGraphicsStateGuardian.h @@ -108,7 +108,7 @@ public: const RenderBuffer &rb, const NodeAttributes& na=NodeAttributes()); - virtual void apply_material(Material* material); + virtual void apply_material(const Material *material); virtual void apply_fog(Fog *fog); virtual void apply_light(PointLight* light); @@ -184,12 +184,6 @@ protected: INLINE void call_glLightModelAmbient(const Colorf& color); INLINE void call_glLightModelLocal(GLboolean local); INLINE void call_glLightModelTwoSide(GLboolean twoside); - INLINE void call_glMaterialAmbient(bool twoside, const Colorf& color); - INLINE void call_glMaterialDiffuse(bool twoside, const Colorf& color); - INLINE void call_glMaterialAmbientDiffuse(bool twoside, const Colorf& color); - INLINE void call_glMaterialSpecular(bool twoside, const Colorf& color); - INLINE void call_glMaterialShininess(bool twoside, float shininess); - INLINE void call_glMaterialEmission(bool twoside, const Colorf& color); INLINE void call_glStencilFunc(GLenum func); INLINE void call_glStencilOp(GLenum op); INLINE void call_glClipPlane(GLenum plane, const double equation[4]); @@ -212,7 +206,6 @@ protected: INLINE void enable_point_smooth(bool val); INLINE void enable_lighting(bool val); INLINE void enable_light(int light, bool val); - INLINE void enable_color_material(bool val); INLINE void enable_texturing(bool val); INLINE void enable_scissor(bool val); INLINE void enable_dither(bool val); @@ -300,7 +293,6 @@ protected: bool _line_smooth_enabled; bool _point_smooth_enabled; bool* _light_enabled; // bool[_max_lights] - bool _color_material_enabled; bool _scissor_enabled; bool _lighting_enabled; bool _texturing_enabled; diff --git a/panda/src/gobj/Sources.pp b/panda/src/gobj/Sources.pp index b653f14ada..8646e2f0d4 100644 --- a/panda/src/gobj/Sources.pp +++ b/panda/src/gobj/Sources.pp @@ -15,7 +15,9 @@ geomSprite.cxx geomSprite.h geomTri.cxx geomTri.h geomTrifan.cxx \ geomTrifan.h geomTristrip.cxx geomTristrip.h \ imageBuffer.I imageBuffer.cxx \ - imageBuffer.h material.I material.cxx material.h orthoProjection.I \ + imageBuffer.h material.I material.cxx material.h \ + materialPool.I materialPool.h materialPool.cxx \ + orthoProjection.I \ orthoProjection.cxx orthoProjection.h perspectiveProjection.I \ perspectiveProjection.cxx perspectiveProjection.h pixelBuffer.I \ pixelBuffer.N pixelBuffer.cxx pixelBuffer.h projection.cxx \ @@ -28,6 +30,7 @@ geomLinestrip.h geomPoint.h geomPolygon.h geomQuad.h geomSphere.h \ geomSprite.I geomSprite.h geomTri.h geomTrifan.h geomTristrip.h \ geomprimitives.h imageBuffer.I imageBuffer.h material.I material.h \ + materialPool.I materialPool.h \ orthoProjection.I orthoProjection.h perspectiveProjection.I \ perspectiveProjection.h pixelBuffer.I pixelBuffer.h projection.h \ texture.I texture.h texturePool.I texturePool.h diff --git a/panda/src/gobj/config_gobj.cxx b/panda/src/gobj/config_gobj.cxx index de4342b022..ee4b38358f 100644 --- a/panda/src/gobj/config_gobj.cxx +++ b/panda/src/gobj/config_gobj.cxx @@ -150,5 +150,6 @@ ConfigureFn(config_gobj) { GeomTristrip::register_with_read_factory(); GeomTrifan::register_with_read_factory(); GeomSphere::register_with_read_factory(); + Material::register_with_read_factory(); Texture::register_with_read_factory(); } diff --git a/panda/src/gobj/material.I b/panda/src/gobj/material.I index a63fb2a294..9f05ddc694 100644 --- a/panda/src/gobj/material.I +++ b/panda/src/gobj/material.I @@ -5,103 +5,267 @@ //////////////////////////////////////////////////////////////////// -// Function: Material::get_ambient +// Function: Material::Constructor // Access: Public // Description: //////////////////////////////////////////////////////////////////// -INLINE Colorf Material::get_ambient( void ) const -{ - return _ambient; +INLINE Material:: +Material() { + _flags = 0; + _shininess = 0.0; +} + +//////////////////////////////////////////////////////////////////// +// Function: Material::Copy Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE Material:: +Material(const Material ©) { + operator = (copy); +} + +//////////////////////////////////////////////////////////////////// +// Function: Material::Destructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE Material:: +~Material() { +} + +//////////////////////////////////////////////////////////////////// +// Function: Material::has_ambient +// Access: Public +// Description: Returns true if the ambient color has been explicitly +// set for this material, false otherwise. +//////////////////////////////////////////////////////////////////// +INLINE bool Material:: +has_ambient() const { + return (_flags & F_ambient) != 0; +} + +//////////////////////////////////////////////////////////////////// +// Function: Material::get_ambient +// Access: Public +// Description: Returns the ambient color setting, if it has been +// set. Returns (0,0,0,0) if the ambient color has not +// been set. +//////////////////////////////////////////////////////////////////// +INLINE const Colorf &Material:: +get_ambient() const { + return (_flags & F_ambient) != 0 ? _ambient : Colorf::zero(); } //////////////////////////////////////////////////////////////////// // Function: Material::set_ambient // Access: Public -// Description: +// Description: Specifies the ambient color setting of the material. +// This will be the multiplied by any ambient lights in +// effect on the material to set its base color. +// +// This is the color of the object as it appears in the +// absence of direct light. +// +// If this is not set, the object color will be used. //////////////////////////////////////////////////////////////////// -INLINE void Material::set_ambient( const Colorf& color ) -{ - _ambient = color; +INLINE void Material:: +set_ambient(const Colorf &color) { + _ambient = color; + _flags |= F_ambient; +} + +//////////////////////////////////////////////////////////////////// +// Function: Material::clear_ambient +// Access: Public +// Description: Removes the explicit ambient color from the material. +//////////////////////////////////////////////////////////////////// +INLINE void Material:: +clear_ambient() { + _flags &= ~F_ambient; +} + +//////////////////////////////////////////////////////////////////// +// Function: Material::has_diffuse +// Access: Public +// Description: Returns true if the diffuse color has been explicitly +// set for this material, false otherwise. +//////////////////////////////////////////////////////////////////// +INLINE bool Material:: +has_diffuse() const { + return (_flags & F_diffuse) != 0; } //////////////////////////////////////////////////////////////////// // Function: Material::get_diffuse // Access: Public -// Description: +// Description: Returns the diffuse color setting, if it has been +// set. Returns (0,0,0,0) if the diffuse color has not +// been set. //////////////////////////////////////////////////////////////////// -INLINE Colorf Material::get_diffuse( void ) const -{ - return _diffuse; +INLINE const Colorf &Material:: +get_diffuse() const { + return (_flags & F_diffuse) != 0 ? _diffuse : Colorf::zero(); } //////////////////////////////////////////////////////////////////// // Function: Material::set_diffuse // Access: Public -// Description: +// Description: Specifies the diffuse color setting of the material. +// This will be multiplied by any lights in effect on +// the material to get the color in the parts of the +// object illuminated by the lights. +// +// This is the primary color of an object; the color of +// the object as it appears in direct light, in the +// absence of highlights. +// +// If this is not set, the object color will be used. //////////////////////////////////////////////////////////////////// -INLINE void Material::set_diffuse( const Colorf& color ) -{ - _diffuse = color; +INLINE void Material:: +set_diffuse(const Colorf &color) { + _diffuse = color; + _flags |= F_diffuse; +} + +//////////////////////////////////////////////////////////////////// +// Function: Material::clear_diffuse +// Access: Public +// Description: Removes the explicit diffuse color from the material. +//////////////////////////////////////////////////////////////////// +INLINE void Material:: +clear_diffuse() { + _flags &= ~F_diffuse; +} + +//////////////////////////////////////////////////////////////////// +// Function: Material::has_specular +// Access: Public +// Description: Returns true if the specular color has been explicitly +// set for this material, false otherwise. +//////////////////////////////////////////////////////////////////// +INLINE bool Material:: +has_specular() const { + return (_flags & F_specular) != 0; } //////////////////////////////////////////////////////////////////// // Function: Material::get_specular // Access: Public -// Description: +// Description: Returns the specular color setting, if it has been +// set. Returns (0,0,0,0) if the specular color has not +// been set. //////////////////////////////////////////////////////////////////// -INLINE Colorf Material::get_specular( void ) const -{ - return _specular; +INLINE const Colorf &Material:: +get_specular() const { + return (_flags & F_specular) != 0 ? _specular : Colorf::zero(); } //////////////////////////////////////////////////////////////////// // Function: Material::set_specular // Access: Public -// Description: +// Description: Specifies the diffuse color setting of the material. +// This will be multiplied by any lights in effect on +// the material to compute the color of specular +// highlights on the object. +// +// This is the highlight color of an object: the color +// of small highlight reflections. +// +// If this is not set, highlights will not appear. //////////////////////////////////////////////////////////////////// -INLINE void Material::set_specular( const Colorf& color ) -{ - _specular = color; +INLINE void Material:: +set_specular(const Colorf &color) { + _specular = color; + _flags |= F_specular; } //////////////////////////////////////////////////////////////////// -// Function: Material::get_shininess +// Function: Material::clear_specular // Access: Public -// Description: +// Description: Removes the explicit specular color from the material. //////////////////////////////////////////////////////////////////// -INLINE float Material::get_shininess( void ) const -{ - return _shininess; +INLINE void Material:: +clear_specular() { + _flags &= ~F_specular; } //////////////////////////////////////////////////////////////////// -// Function: Material::set_shininess +// Function: Material::has_emission // Access: Public -// Description: +// Description: Returns true if the emission color has been explicitly +// set for this material, false otherwise. //////////////////////////////////////////////////////////////////// -INLINE void Material::set_shininess( float shininess ) -{ - _shininess = shininess; +INLINE bool Material:: +has_emission() const { + return (_flags & F_emission) != 0; } //////////////////////////////////////////////////////////////////// // Function: Material::get_emission // Access: Public -// Description: +// Description: Returns the emmission color setting, if it has been +// set. Returns (0,0,0,0) if the emmission color has not +// been set. //////////////////////////////////////////////////////////////////// -INLINE Colorf Material::get_emission( void ) const -{ - return _emission; +INLINE const Colorf &Material:: +get_emission() const { + return (_flags & F_emission) != 0 ? _emission : Colorf::zero(); } //////////////////////////////////////////////////////////////////// // Function: Material::set_emission // Access: Public -// Description: +// Description: Specifies the emission color setting of the material. +// This is the color of the object as it appears in the +// absence of any light whatsover, including ambient +// light. It is as if the object is glowing by this +// color (although of course it will not illuminate +// neighboring objects). +// +// If this is not set, the object will not glow by its +// own light and will only appear visible in the +// presence of one or more lights. //////////////////////////////////////////////////////////////////// -INLINE void Material::set_emission( const Colorf& color ) -{ - _emission = color; +INLINE void Material:: +set_emission(const Colorf &color) { + _emission = color; + _flags |= F_emission; +} + +//////////////////////////////////////////////////////////////////// +// Function: Material::clear_emission +// Access: Public +// Description: Removes the explicit emission color from the material. +//////////////////////////////////////////////////////////////////// +INLINE void Material:: +clear_emission() { + _flags &= ~F_emission; +} + +//////////////////////////////////////////////////////////////////// +// Function: Material::get_shininess +// Access: Public +// Description: Returns the shininess exponent of the material. +//////////////////////////////////////////////////////////////////// +INLINE float Material:: +get_shininess() const { + return _shininess; +} + +//////////////////////////////////////////////////////////////////// +// Function: Material::set_shininess +// Access: Public +// Description: Sets the shininess exponent of the material. This +// controls the size of the specular highlight spot. In +// general, larger number produce a smaller specular +// highlight, which makes the object appear shinier. +// Smaller numbers produce a larger highlight, which +// makes the object appear less shiny. +//////////////////////////////////////////////////////////////////// +INLINE void Material:: +set_shininess(float shininess) { + _shininess = shininess; } //////////////////////////////////////////////////////////////////// @@ -109,9 +273,9 @@ INLINE void Material::set_emission( const Colorf& color ) // Access: Public // Description: //////////////////////////////////////////////////////////////////// -INLINE bool Material::get_local( void ) const -{ - return _local; +INLINE bool Material:: +get_local() const { + return (_flags & F_local) != 0; } //////////////////////////////////////////////////////////////////// @@ -119,9 +283,9 @@ INLINE bool Material::get_local( void ) const // Access: Public // Description: //////////////////////////////////////////////////////////////////// -INLINE void Material::set_local( bool local ) -{ - _local = local; +INLINE void Material:: +set_local(bool local) { + _flags |= F_local; } //////////////////////////////////////////////////////////////////// @@ -129,9 +293,9 @@ INLINE void Material::set_local( bool local ) // Access: Public // Description: //////////////////////////////////////////////////////////////////// -INLINE bool Material::get_twoside( void ) const -{ - return _twoside; +INLINE bool Material:: +get_twoside() const { + return (_flags & F_twoside) != 0; } //////////////////////////////////////////////////////////////////// @@ -139,7 +303,37 @@ INLINE bool Material::get_twoside( void ) const // Access: Public // Description: //////////////////////////////////////////////////////////////////// -INLINE void Material::set_twoside( bool twoside ) -{ - _twoside = twoside; +INLINE void Material:: +set_twoside(bool twoside) { + _flags = F_twoside; +} + +//////////////////////////////////////////////////////////////////// +// Function: Material::operator == +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE bool Material:: +operator == (const Material &other) const { + return compare_to(other) == 0; +} + +//////////////////////////////////////////////////////////////////// +// Function: Material::operator != +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE bool Material:: +operator != (const Material &other) const { + return compare_to(other) != 0; +} + +//////////////////////////////////////////////////////////////////// +// Function: Material::operator < +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE bool Material:: +operator < (const Material &other) const { + return compare_to(other) < 0; } diff --git a/panda/src/gobj/material.cxx b/panda/src/gobj/material.cxx index a45624809e..df94cede95 100644 --- a/panda/src/gobj/material.cxx +++ b/panda/src/gobj/material.cxx @@ -2,14 +2,15 @@ // Created by: mike (09Jan97) // //////////////////////////////////////////////////////////////////// -// -//////////////////////////////////////////////////////////////////// -// Includes -//////////////////////////////////////////////////////////////////// + #include #include "material.h" #include +#include +#include +#include +#include #include @@ -19,57 +20,142 @@ TypeHandle Material::_type_handle; //////////////////////////////////////////////////////////////////// -// Function: Constructor -// Access: -// Description: +// Function: Material::Copy Assignment Operator +// Access: Public +// Description: //////////////////////////////////////////////////////////////////// -Material::Material( void ) -{ - set_ambient( Colorf( 0.2, 0.2, 0.2, 1 ) ); - set_diffuse( Colorf( 0.8, 0.8, 0.8, 1 ) ); - set_specular( Colorf( 0, 0, 0, 1 ) ); - set_shininess( 0.0 ); - set_emission( Colorf( 0, 0, 0, 1 ) ); - - set_local( false ); - set_twoside( false ); +void Material:: +operator = (const Material ©) { + _ambient = copy._ambient; + _diffuse = copy._diffuse; + _specular = copy._specular; + _emission = copy._emission; + _shininess = copy._shininess; + _flags = copy._flags; } //////////////////////////////////////////////////////////////////// -// Function: Destructor -// Access: -// Description: +// Function: Material::compare_to +// Access: Public +// Description: Returns a number less than zero if this material +// sorts before the other one, greater than zero if it +// sorts after, or zero if they are equivalent. The +// sorting order is arbitrary and largely meaningless, +// except to differentiate different materials. //////////////////////////////////////////////////////////////////// -Material::~Material( void ) -{ -} +int Material:: +compare_to(const Material &other) const { + if (_flags != other._flags) { + return _flags - other._flags; + } + if (has_ambient() && get_ambient() != other.get_ambient()) { + return get_ambient().compare_to(other.get_ambient()); + } + if (has_diffuse() && get_diffuse() != other.get_diffuse()) { + return get_diffuse().compare_to(other.get_diffuse()); + } + if (has_specular() && get_specular() != other.get_specular()) { + return get_specular().compare_to(other.get_specular()); + } + if (has_emission() && get_emission() != other.get_emission()) { + return get_emission().compare_to(other.get_emission()); + } + if (get_shininess() != other.get_shininess()) { + return get_shininess() < other.get_shininess() ? -1 : 1; + } - -//////////////////////////////////////////////////////////////////// -// Function: output -// Access: -// Description: -//////////////////////////////////////////////////////////////////// -void Material::output( ostream &out ) const -{ - out << "a" << _ambient[0] << ",d" << _diffuse[0] - << ",s" << _specular[0] << ",s" << _shininess - << ",e" << _emission[0] << ",l" << _local - << ",t" << _twoside; + return 0; } //////////////////////////////////////////////////////////////////// -// Function: write -// Access: +// Function: Material::output +// Access: Public // Description: //////////////////////////////////////////////////////////////////// -void Material::write( ostream &out, int indent_level ) const -{ - indent(out, indent_level) << "ambient = " << _ambient << "\n"; - indent(out, indent_level) << "diffuse = " << _diffuse << "\n"; - indent(out, indent_level) << "specular = " << _specular << "\n"; - indent(out, indent_level) << "shininess = " << _shininess << "\n"; - indent(out, indent_level) << "emission = " << _emission << "\n"; - indent(out, indent_level) << "local = " << _local << "\n"; - indent(out, indent_level) << "twoside = " << _twoside << "\n"; +void Material:: +output(ostream &out) const { + out << "a" << get_ambient()[0] << ",d" << get_diffuse()[0] + << ",s" << get_specular()[0] << ",e" << get_emission()[0] + << ",s" << get_shininess() << ",l" << get_local() + << ",t" << get_twoside(); +} + +//////////////////////////////////////////////////////////////////// +// Function: Material::write +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +void Material:: +write(ostream &out, int indent_level) const { + indent(out, indent_level) << "ambient = " << get_ambient() << "\n"; + indent(out, indent_level) << "diffuse = " << get_diffuse() << "\n"; + indent(out, indent_level) << "specular = " << get_specular() << "\n"; + indent(out, indent_level) << "emission = " << get_emission() << "\n"; + indent(out, indent_level) << "shininess = " << get_shininess() << "\n"; + indent(out, indent_level) << "local = " << get_local() << "\n"; + indent(out, indent_level) << "twoside = " << get_twoside() << "\n"; +} + + + +//////////////////////////////////////////////////////////////////// +// Function: Material::register_with_read_factory +// Access: Public, Static +// Description: Factory method to generate a Material object +//////////////////////////////////////////////////////////////////// +void Material:: +register_with_read_factory() { + BamReader::get_factory()->register_factory(get_class_type(), make_Material); +} + +//////////////////////////////////////////////////////////////////// +// Function: Material::write_datagram +// Access: Public +// Description: Function to write the important information in +// the particular object to a Datagram +//////////////////////////////////////////////////////////////////// +void Material:: +write_datagram(BamWriter *manager, Datagram &me) { + _ambient.write_datagram(me); + _diffuse.write_datagram(me); + _specular.write_datagram(me); + _emission.write_datagram(me); + me.add_float32(_shininess); + me.add_int32(_flags); +} + +//////////////////////////////////////////////////////////////////// +// Function: Material::make_Material +// Access: Protected +// Description: Factory method to generate a Material object +//////////////////////////////////////////////////////////////////// +TypedWriteable *Material:: +make_Material(const FactoryParams ¶ms) { + Material *me = new Material; + BamReader *manager; + Datagram packet; + + parse_params(params, manager, packet); + DatagramIterator scan(packet); + + me->fillin(scan, manager); + return me; +} + +//////////////////////////////////////////////////////////////////// +// Function: Material::fillin +// Access: Protected +// Description: Function that reads out of the datagram (or asks +// manager to read) all of the data that is needed to +// re-create this object and stores it in the appropiate +// place +//////////////////////////////////////////////////////////////////// +void Material:: +fillin(DatagramIterator& scan, BamReader* manager) { + _ambient.read_datagram(scan); + _diffuse.read_datagram(scan); + _specular.read_datagram(scan); + _emission.read_datagram(scan); + _shininess = scan.get_float32(); + _flags = scan.get_int32(); } diff --git a/panda/src/gobj/material.h b/panda/src/gobj/material.h index 6d4ad74eb9..edfca3a369 100644 --- a/panda/src/gobj/material.h +++ b/panda/src/gobj/material.h @@ -11,68 +11,92 @@ //////////////////////////////////////////////////////////////////// #include -#include -#include +#include #include -//////////////////////////////////////////////////////////////////// -// Defines -//////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////// // Class : Material -// Description : +// Description : Defines the way an object appears in the presence of +// lighting. A material is only necessary if lighting +// is to be enabled; otherwise, the material isn't used. //////////////////////////////////////////////////////////////////// -class EXPCL_PANDA Material : public TypedReferenceCount -{ - public: +class EXPCL_PANDA Material : public TypedWriteableReferenceCount { +PUBLISHED: + INLINE Material(); + INLINE Material(const Material ©); + void operator = (const Material ©); + INLINE ~Material(); - Material( void ); - ~Material( void ); + INLINE bool has_ambient() const; + INLINE const Colorf &get_ambient() const; + INLINE void set_ambient(const Colorf &color); + INLINE void clear_ambient(); - void apply( GraphicsStateGuardianBase *gsg ) { - gsg->apply_material( this ); - } + INLINE bool has_diffuse() const; + INLINE const Colorf &get_diffuse() const; + INLINE void set_diffuse(const Colorf &color); + INLINE void clear_diffuse(); - INLINE Colorf get_ambient( void ) const; - INLINE void set_ambient( const Colorf& color ); - INLINE Colorf get_diffuse( void ) const; - INLINE void set_diffuse( const Colorf& color ); - INLINE Colorf get_specular( void ) const; - INLINE void set_specular( const Colorf& color ); - INLINE float get_shininess( void ) const; - INLINE void set_shininess( float shininess ); - INLINE Colorf get_emission( void ) const; - INLINE void set_emission( const Colorf& color ); + INLINE bool has_specular() const; + INLINE const Colorf &get_specular() const; + INLINE void set_specular(const Colorf &color); + INLINE void clear_specular(); - INLINE bool get_local( void ) const; - INLINE void set_local( bool local ); - INLINE bool get_twoside( void ) const; - INLINE void set_twoside( bool twoside ); + INLINE bool has_emission() const; + INLINE const Colorf &get_emission() const; + INLINE void set_emission(const Colorf &color); + INLINE void clear_emission(); - void output( ostream &out ) const; - void write( ostream &out, int indent = 0 ) const; + INLINE float get_shininess() const; + INLINE void set_shininess(float shininess); + + INLINE bool get_local() const; + INLINE void set_local(bool local); + INLINE bool get_twoside() const; + INLINE void set_twoside(bool twoside); - protected: + INLINE bool operator == (const Material &other) const; + INLINE bool operator != (const Material &other) const; + INLINE bool operator < (const Material &other) const; - Colorf _ambient; - Colorf _diffuse; - Colorf _specular; - float _shininess; - Colorf _emission; + int compare_to(const Material &other) const; + + void output(ostream &out) const; + void write(ostream &out, int indent) const; - bool _local; - bool _twoside; +private: + Colorf _ambient; + Colorf _diffuse; + Colorf _specular; + Colorf _emission; + float _shininess; + + enum Flags { + F_ambient = 0x001, + F_diffuse = 0x002, + F_specular = 0x004, + F_emission = 0x008, + F_local = 0x010, + F_twoside = 0x020, + }; + int _flags; public: + static void register_with_read_factory(); + virtual void write_datagram(BamWriter *manager, Datagram &me); +protected: + static TypedWriteable *make_Material(const FactoryParams ¶ms); + void fillin(DatagramIterator &scan, BamReader *manager); + +public: static TypeHandle get_class_type() { return _type_handle; } static void init_type() { - TypedReferenceCount::init_type(); + TypedWriteableReferenceCount::init_type(); register_type(_type_handle, "Material", - TypedReferenceCount::get_class_type()); + TypedWriteableReferenceCount::get_class_type()); } virtual TypeHandle get_type() const { return get_class_type(); diff --git a/panda/src/graph/nodeRelation.cxx b/panda/src/graph/nodeRelation.cxx index c0d52b1707..e6554c3039 100644 --- a/panda/src/graph/nodeRelation.cxx +++ b/panda/src/graph/nodeRelation.cxx @@ -967,7 +967,7 @@ fillin(DatagramIterator& scan, BamReader* manager) } //////////////////////////////////////////////////////////////////// -// Function: NodeRelation::register_with_factory +// Function: NodeRelation::register_with_read_factory // Access: Public, Static // Description: Factory method to generate a NodeRelation object //////////////////////////////////////////////////////////////////// diff --git a/panda/src/gsgbase/graphicsStateGuardianBase.h b/panda/src/gsgbase/graphicsStateGuardianBase.h index f21840f2d1..9228d35c24 100644 --- a/panda/src/gsgbase/graphicsStateGuardianBase.h +++ b/panda/src/gsgbase/graphicsStateGuardianBase.h @@ -133,7 +133,7 @@ public: const RenderBuffer &rb, const NodeAttributes& na=NodeAttributes())=0; - virtual void apply_material(Material *material)=0; + virtual void apply_material(const Material *material)=0; virtual void apply_fog(Fog *fog)=0; virtual void apply_light(PointLight *light)=0; diff --git a/panda/src/sgattrib/materialAttribute.I b/panda/src/sgattrib/materialAttribute.I index 387d6eae7d..9e32b1592b 100644 --- a/panda/src/sgattrib/materialAttribute.I +++ b/panda/src/sgattrib/materialAttribute.I @@ -18,8 +18,8 @@ MaterialAttribute() { // Description: //////////////////////////////////////////////////////////////////// INLINE void MaterialAttribute:: -set_on(Material *material) { - nassertv(material != (Material *)NULL); +set_on(const Material *material) { + nassertv(material != (const Material *)NULL); _value = material; OnOffAttribute::set_on(); } @@ -31,7 +31,7 @@ set_on(Material *material) { // represents. It is only valid to call this if is_on() // has returned true. //////////////////////////////////////////////////////////////////// -INLINE PT(Material) MaterialAttribute:: +INLINE const Material *MaterialAttribute:: get_material() const { nassertr(is_on(), NULL); return _value; diff --git a/panda/src/sgattrib/materialAttribute.cxx b/panda/src/sgattrib/materialAttribute.cxx index 40fd0ba72c..cfe6871088 100644 --- a/panda/src/sgattrib/materialAttribute.cxx +++ b/panda/src/sgattrib/materialAttribute.cxx @@ -68,7 +68,7 @@ set_value_from(const OnOffTransition *other) { const MaterialTransition *ot; DCAST_INTO_V(ot, other); _value = ot->_value; - nassertv(_value != (Material *)NULL); + nassertv(_value != (const Material *)NULL); } //////////////////////////////////////////////////////////////////// @@ -90,7 +90,7 @@ compare_values(const OnOffAttribute *other) const { //////////////////////////////////////////////////////////////////// void MaterialAttribute:: output_value(ostream &out) const { - nassertv(_value != (Material *)NULL); + nassertv(_value != (const Material *)NULL); out << *_value; } @@ -102,6 +102,6 @@ output_value(ostream &out) const { //////////////////////////////////////////////////////////////////// void MaterialAttribute:: write_value(ostream &out, int indent_level) const { - nassertv(_value != (Material *)NULL); + nassertv(_value != (const Material *)NULL); indent(out, indent_level) << *_value << "\n"; } diff --git a/panda/src/sgattrib/materialAttribute.h b/panda/src/sgattrib/materialAttribute.h index 6354642524..440be3a248 100644 --- a/panda/src/sgattrib/materialAttribute.h +++ b/panda/src/sgattrib/materialAttribute.h @@ -10,6 +10,7 @@ #include #include +#include //////////////////////////////////////////////////////////////////// // Class : MaterialAttribute @@ -19,8 +20,8 @@ class EXPCL_PANDA MaterialAttribute : public OnOffAttribute { public: INLINE MaterialAttribute(); - INLINE void set_on(Material *material); - INLINE PT(Material) get_material() const; + INLINE void set_on(const Material *material); + INLINE const Material *get_material() const; virtual TypeHandle get_handle() const; virtual NodeAttribute *make_copy() const; @@ -34,7 +35,7 @@ protected: virtual void output_value(ostream &out) const; virtual void write_value(ostream &out, int indent_level) const; - PT(Material) _value; + CPT(Material) _value; public: virtual TypeHandle get_type() const { diff --git a/panda/src/sgattrib/materialTransition.I b/panda/src/sgattrib/materialTransition.I index 22f7157de3..7508faa2e0 100644 --- a/panda/src/sgattrib/materialTransition.I +++ b/panda/src/sgattrib/materialTransition.I @@ -18,7 +18,7 @@ MaterialTransition() { // Description: //////////////////////////////////////////////////////////////////// INLINE MaterialTransition:: -MaterialTransition(Material *material) : +MaterialTransition(const Material *material) : OnOffTransition(TD_on), _value(material) { @@ -43,8 +43,8 @@ off() { // Description: //////////////////////////////////////////////////////////////////// INLINE void MaterialTransition:: -set_on(Material *material) { - nassertv(material != (Material *)NULL); +set_on(const Material *material) { + nassertv(material != (const Material *)NULL); _value = material; OnOffTransition::set_on(); } @@ -56,7 +56,7 @@ set_on(Material *material) { // represents. It is only valid to call this if is_on() // has returned true. //////////////////////////////////////////////////////////////////// -INLINE PT(Material) MaterialTransition:: +INLINE const Material *MaterialTransition:: get_material() const { nassertr(is_on(), NULL); return _value; diff --git a/panda/src/sgattrib/materialTransition.cxx b/panda/src/sgattrib/materialTransition.cxx index 85ede6a7ed..4cb873a694 100644 --- a/panda/src/sgattrib/materialTransition.cxx +++ b/panda/src/sgattrib/materialTransition.cxx @@ -5,8 +5,13 @@ #include "materialTransition.h" #include "materialAttribute.h" +#include "config_sgattrib.h" #include +#include +#include +#include +#include TypeHandle MaterialTransition::_type_handle; @@ -42,7 +47,7 @@ set_value_from(const OnOffTransition *other) { const MaterialTransition *ot; DCAST_INTO_V(ot, other); _value = ot->_value; - nassertv(_value != (Material *)NULL); + nassertv(_value != (const Material *)NULL); } //////////////////////////////////////////////////////////////////// @@ -64,7 +69,7 @@ compare_values(const OnOffTransition *other) const { //////////////////////////////////////////////////////////////////// void MaterialTransition:: output_value(ostream &out) const { - nassertv(_value != (Material *)NULL); + nassertv(_value != (const Material *)NULL); out << *_value; } @@ -76,6 +81,85 @@ output_value(ostream &out) const { //////////////////////////////////////////////////////////////////// void MaterialTransition:: write_value(ostream &out, int indent_level) const { - nassertv(_value != (Material *)NULL); + nassertv(_value != (const Material *)NULL); indent(out, indent_level) << *_value << "\n"; } + +//////////////////////////////////////////////////////////////////// +// Function: MaterialTransition::register_with_read_factory +// Access: Public, Static +// Description: Factory method to generate a MaterialTransition object +//////////////////////////////////////////////////////////////////// +void MaterialTransition:: +register_with_read_factory() { + BamReader::get_factory()->register_factory(get_class_type(), make_MaterialTransition); +} + +//////////////////////////////////////////////////////////////////// +// Function: MaterialTransition::write_datagram +// Access: Public +// Description: Function to write the important information in +// the particular object to a Datagram +//////////////////////////////////////////////////////////////////// +void MaterialTransition:: +write_datagram(BamWriter *manager, Datagram &me) { + OnOffTransition::write_datagram(manager, me); + manager->write_pointer(me, _value); +} + +//////////////////////////////////////////////////////////////////// +// Function: MaterialTransition::complete_pointers +// Access: Public +// Description: Takes in a vector of pointes to TypedWriteable +// objects that correspond to all the requests for +// pointers that this object made to BamReader. +//////////////////////////////////////////////////////////////////// +int MaterialTransition:: +complete_pointers(vector_typedWriteable &plist, BamReader *) { + if (plist[0] == TypedWriteable::Null) { + if (sgattrib_cat->is_debug()) { + sgattrib_cat->debug() + << get_type().get_name() << " received null Material," + << " turning off" << endl; + } + _value = (const Material *)NULL; + set_off(); + + } else { + _value = DCAST(Material, plist[0]); + } + + return 1; +} + +//////////////////////////////////////////////////////////////////// +// Function: MaterialTransition::make_MaterialTransition +// Access: Protected +// Description: Factory method to generate a MaterialTransition object +//////////////////////////////////////////////////////////////////// +TypedWriteable* MaterialTransition:: +make_MaterialTransition(const FactoryParams ¶ms) { + MaterialTransition *me = new MaterialTransition; + BamReader *manager; + Datagram packet; + + parse_params(params, manager, packet); + DatagramIterator scan(packet); + + me->fillin(scan, manager); + return me; +} + +//////////////////////////////////////////////////////////////////// +// Function: MaterialTransition::fillin +// Access: Protected +// Description: Function that reads out of the datagram (or asks +// manager to read) all of the data that is needed to +// re-create this object and stores it in the appropiate +// place +//////////////////////////////////////////////////////////////////// +void MaterialTransition:: +fillin(DatagramIterator& scan, BamReader* manager) { + OnOffTransition::fillin(scan, manager); + manager->read_pointer(scan, this); +} diff --git a/panda/src/sgattrib/materialTransition.h b/panda/src/sgattrib/materialTransition.h index 70b893c078..98cc847cb0 100644 --- a/panda/src/sgattrib/materialTransition.h +++ b/panda/src/sgattrib/materialTransition.h @@ -10,6 +10,7 @@ #include #include +#include //////////////////////////////////////////////////////////////////// // Class : MaterialTransition @@ -19,12 +20,13 @@ class EXPCL_PANDA MaterialTransition : public OnOffTransition { public: INLINE MaterialTransition(); - INLINE MaterialTransition(Material *material); + INLINE MaterialTransition(const Material *material); INLINE static MaterialTransition off(); - INLINE void set_on(Material *material); - INLINE PT(Material) get_material() const; - + INLINE void set_on(const Material *material); + INLINE const Material *get_material() const; + +public: virtual NodeTransition *make_copy() const; virtual NodeAttribute *make_attrib() const; @@ -34,7 +36,17 @@ protected: virtual void output_value(ostream &out) const; virtual void write_value(ostream &out, int indent_level) const; - PT(Material) _value; + CPT(Material) _value; + +public: + static void register_with_read_factory(); + virtual void write_datagram(BamWriter *manager, Datagram &me); + virtual int complete_pointers(vector_typedWriteable &plist, + BamReader *manager); + +protected: + static TypedWriteable *make_MaterialTransition(const FactoryParams ¶ms); + void fillin(DatagramIterator& scan, BamReader* manager); public: virtual TypeHandle get_type() const { diff --git a/panda/src/sgattrib/textureTransition.cxx b/panda/src/sgattrib/textureTransition.cxx index 9cf37ad5de..194de06d2a 100644 --- a/panda/src/sgattrib/textureTransition.cxx +++ b/panda/src/sgattrib/textureTransition.cxx @@ -86,6 +86,16 @@ write_value(ostream &out, int indent_level) const { indent(out, indent_level) << *_value << "\n"; } +//////////////////////////////////////////////////////////////////// +// Function: TextureTransition::register_with_read_factory +// Access: Public, Static +// Description: Factory method to generate a TextureTransition object +//////////////////////////////////////////////////////////////////// +void TextureTransition:: +register_with_read_factory() { + BamReader::get_factory()->register_factory(get_class_type(), make_TextureTransition); +} + //////////////////////////////////////////////////////////////////// // Function: TextureTransition::write_datagram // Access: Public @@ -93,27 +103,11 @@ write_value(ostream &out, int indent_level) const { // the particular object to a Datagram //////////////////////////////////////////////////////////////////// void TextureTransition:: -write_datagram(BamWriter *manager, Datagram &me) -{ +write_datagram(BamWriter *manager, Datagram &me) { OnOffTransition::write_datagram(manager, me); manager->write_pointer(me, _value); } -//////////////////////////////////////////////////////////////////// -// Function: TextureTransition::fillin -// Access: Protected -// Description: Function that reads out of the datagram (or asks -// manager to read) all of the data that is needed to -// re-create this object and stores it in the appropiate -// place -//////////////////////////////////////////////////////////////////// -void TextureTransition:: -fillin(DatagramIterator& scan, BamReader* manager) -{ - OnOffTransition::fillin(scan, manager); - manager->read_pointer(scan, this); -} - //////////////////////////////////////////////////////////////////// // Function: TextureTransition::complete_pointers // Access: Public @@ -122,10 +116,8 @@ fillin(DatagramIterator& scan, BamReader* manager) // pointers that this object made to BamReader. //////////////////////////////////////////////////////////////////// int TextureTransition:: -complete_pointers(vector_typedWriteable &plist, BamReader*) -{ - if(plist[0] == TypedWriteable::Null) - { +complete_pointers(vector_typedWriteable &plist, BamReader *) { + if (plist[0] == TypedWriteable::Null) { if (sgattrib_cat->is_debug()) { sgattrib_cat->debug() << get_type().get_name() << " received null Texture," @@ -133,9 +125,8 @@ complete_pointers(vector_typedWriteable &plist, BamReader*) } _value = (Texture *)NULL; set_off(); - } - else - { + + } else { _value = DCAST(Texture, plist[0]); } @@ -148,8 +139,7 @@ complete_pointers(vector_typedWriteable &plist, BamReader*) // Description: Factory method to generate a TextureTransition object //////////////////////////////////////////////////////////////////// TypedWriteable* TextureTransition:: -make_TextureTransition(const FactoryParams ¶ms) -{ +make_TextureTransition(const FactoryParams ¶ms) { TextureTransition *me = new TextureTransition; BamReader *manager; Datagram packet; @@ -162,12 +152,15 @@ make_TextureTransition(const FactoryParams ¶ms) } //////////////////////////////////////////////////////////////////// -// Function: TextureTransition::register_with_factory -// Access: Public, Static -// Description: Factory method to generate a TextureTransition object +// Function: TextureTransition::fillin +// Access: Protected +// Description: Function that reads out of the datagram (or asks +// manager to read) all of the data that is needed to +// re-create this object and stores it in the appropiate +// place //////////////////////////////////////////////////////////////////// void TextureTransition:: -register_with_read_factory(void) -{ - BamReader::get_factory()->register_factory(get_class_type(), make_TextureTransition); +fillin(DatagramIterator& scan, BamReader* manager) { + OnOffTransition::fillin(scan, manager); + manager->read_pointer(scan, this); } diff --git a/panda/src/sgattrib/textureTransition.h b/panda/src/sgattrib/textureTransition.h index 72439fc92d..a28bbd9cf3 100644 --- a/panda/src/sgattrib/textureTransition.h +++ b/panda/src/sgattrib/textureTransition.h @@ -51,14 +51,13 @@ protected: PT(Texture) _value; public: - static void register_with_read_factory(void); - virtual void write_datagram(BamWriter* manager, Datagram &me); + static void register_with_read_factory(); + virtual void write_datagram(BamWriter *manager, Datagram &me); virtual int complete_pointers(vector_typedWriteable &plist, BamReader *manager); - static TypedWriteable *make_TextureTransition(const FactoryParams ¶ms); - protected: + static TypedWriteable *make_TextureTransition(const FactoryParams ¶ms); void fillin(DatagramIterator& scan, BamReader* manager); public: diff --git a/panda/src/sgmanip/nodePath.I b/panda/src/sgmanip/nodePath.I index 2c766ddedd..08e6b72b5f 100644 --- a/panda/src/sgmanip/nodePath.I +++ b/panda/src/sgmanip/nodePath.I @@ -1099,7 +1099,7 @@ has_color() const { INLINE void NodePath:: clear_bin() { nassertv(has_arcs()); - arc()->clear_transition(TextureTransition::get_class_type()); + arc()->clear_transition(GeomBinTransition::get_class_type()); } //////////////////////////////////////////////////////////////////// @@ -1130,6 +1130,19 @@ clear_texture() { arc()->clear_transition(TextureTransition::get_class_type()); } +//////////////////////////////////////////////////////////////////// +// Function: NodePath::clear_material +// Access: Public +// Description: Completely removes any material adjustment that may +// have been set via set_material() from this particular +// arc. +//////////////////////////////////////////////////////////////////// +INLINE void NodePath:: +clear_material() { + nassertv(has_arcs()); + arc()->clear_transition(MaterialTransition::get_class_type()); +} + //////////////////////////////////////////////////////////////////// // Function: NodePath::clear_fog // Access: Public diff --git a/panda/src/sgmanip/nodePath.cxx b/panda/src/sgmanip/nodePath.cxx index 323cf60169..6ea2b29387 100644 --- a/panda/src/sgmanip/nodePath.cxx +++ b/panda/src/sgmanip/nodePath.cxx @@ -25,6 +25,7 @@ #include #include #include +#include #include @@ -2013,6 +2014,78 @@ get_texture() const { return NULL; } +//////////////////////////////////////////////////////////////////// +// Function: NodePath::set_material +// Access: Public +// Description: Sets the geometry at this level and below to render +// using the indicated material. +// +// This operation copies the given material pointer. If +// the material structure is changed later, it must be +// reapplied via another call to set_material(). +//////////////////////////////////////////////////////////////////// +void NodePath:: +set_material(Material *mat, int priority) { + nassertv(has_arcs()); + nassertv(mat != NULL); + + // We create a temporary Material pointer, a copy of the one we are + // given, to allow the user to monkey with the material and set it + // again later, with the desired effect. If we stored the user's + // pointer directly, it would be bad if the user later modified the + // values within the Material. + PT(Material) temp = new Material(*mat); + const Material *mp = MaterialPool::get_material(temp); + + MaterialTransition *mat_trans = new MaterialTransition(mp); + arc()->set_transition(mat_trans, priority); +} + +//////////////////////////////////////////////////////////////////// +// Function: NodePath::has_material +// Access: Public +// Description: Returns true if a material has been applied to this +// particular arc via set_material(), false otherwise. +//////////////////////////////////////////////////////////////////// +bool NodePath:: +has_material() const { + nassertr(has_arcs(), false); + + const MaterialTransition *mt; + if (get_transition_into(mt, arc())) { + return mt->is_on(); + } + + return false; +} + +//////////////////////////////////////////////////////////////////// +// Function: NodePath::get_material +// Access: Public +// Description: Returns the material that has been set on this +// particular arc, or NULL if no material has been set. +// This is not necessarily the material that will be +// applied to the geometry at or below this level, as +// another material at a higher or lower level may +// override. +// +// This function returns a copy of the given material, +// to allow changes, if desired. Once changes are made, +// they should be reapplied via set_material(). +//////////////////////////////////////////////////////////////////// +PT(Material) NodePath:: +get_material() const { + nassertr(has_arcs(), NULL); + + const MaterialTransition *mt; + if (get_transition_into(mt, arc())) { + if (mt->is_on()) { + return new Material(*mt->get_material()); + } + } + return NULL; +} + //////////////////////////////////////////////////////////////////// // Function: NodePath::set_fog // Access: Public diff --git a/panda/src/sgmanip/nodePath.h b/panda/src/sgmanip/nodePath.h index cb6aac626f..02a338f3d6 100644 --- a/panda/src/sgmanip/nodePath.h +++ b/panda/src/sgmanip/nodePath.h @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include #include #include @@ -408,6 +410,11 @@ PUBLISHED: bool has_texture_off() const; Texture *get_texture() const; + void set_material(Material *tex, int priority = 0); + INLINE void clear_material(); + bool has_material() const; + PT(Material) get_material() const; + void set_fog(Fog *fog, int priority = 0); void set_fog_off(int priority = 0); INLINE void clear_fog();