366 lines
7.8 KiB
Text
366 lines
7.8 KiB
Text
|
/**
|
||
|
* PANDA 3D SOFTWARE
|
||
|
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||
|
*
|
||
|
* All use of this software is subject to the terms of the revised BSD
|
||
|
* license. You should have received a copy of this license along
|
||
|
* with this source code in a file named "LICENSE."
|
||
|
*
|
||
|
* @file material.I
|
||
|
* @author mike
|
||
|
* @date 1999-02-05
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
*
|
||
|
*/
|
||
|
INLINE Material::
|
||
|
Material(const std::string &name) : Namable(name) {
|
||
|
_base_color.set(1.0f, 1.0f, 1.0f, 1.0f);
|
||
|
_ambient.set(1.0f, 1.0f, 1.0f, 1.0f);
|
||
|
_diffuse.set(1.0f, 1.0f, 1.0f, 1.0f);
|
||
|
_specular.set(0.0f, 0.0f, 0.0f, 1.0f);
|
||
|
_emission.set(0.0f, 0.0f, 0.0f, 1.0f);
|
||
|
_shininess = 0;
|
||
|
_roughness = 1;
|
||
|
_metallic = 0;
|
||
|
_refractive_index = 1;
|
||
|
_flags = 0;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*
|
||
|
*/
|
||
|
INLINE Material::
|
||
|
Material(const Material ©) :
|
||
|
Namable(copy) ,
|
||
|
_base_color(copy._base_color),
|
||
|
_ambient(copy._ambient),
|
||
|
_diffuse(copy._diffuse),
|
||
|
_specular(copy._specular),
|
||
|
_emission(copy._emission),
|
||
|
_shininess(copy._shininess),
|
||
|
_roughness(copy._roughness),
|
||
|
_metallic(copy._metallic),
|
||
|
_refractive_index(copy._refractive_index),
|
||
|
_flags(copy._flags & ~(F_attrib_lock | F_used_by_auto_shader)) {
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*
|
||
|
*/
|
||
|
INLINE Material::
|
||
|
~Material() {
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the default material.
|
||
|
*/
|
||
|
INLINE Material *Material::
|
||
|
get_default() {
|
||
|
if (_default == 0) {
|
||
|
_default = new Material("default");
|
||
|
}
|
||
|
return _default;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns true if the base color has been explicitly set for this material,
|
||
|
* false otherwise.
|
||
|
*/
|
||
|
INLINE bool Material::
|
||
|
has_base_color() const {
|
||
|
return (_flags & F_base_color) != 0;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the base_color color setting, if it has been set. If neither the
|
||
|
* base color nor the metallic have been set, this returns the diffuse color.
|
||
|
*/
|
||
|
INLINE const LColor &Material::
|
||
|
get_base_color() const {
|
||
|
if (!has_base_color() && !has_metallic()) {
|
||
|
return _diffuse;
|
||
|
} else {
|
||
|
return _base_color;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 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;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 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 LColor &Material::
|
||
|
get_ambient() const {
|
||
|
return _ambient;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Removes the explicit ambient color from the material.
|
||
|
*/
|
||
|
INLINE void Material::
|
||
|
clear_ambient() {
|
||
|
if (has_ambient() && is_used_by_auto_shader()) {
|
||
|
GraphicsStateGuardianBase::mark_rehash_generated_shaders();
|
||
|
}
|
||
|
_flags &= ~F_ambient;
|
||
|
_ambient = _base_color;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 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;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the diffuse color setting, if it has been set. Returns (1,1,1,1)
|
||
|
* if the diffuse color has not been set.
|
||
|
*/
|
||
|
INLINE const LColor &Material::
|
||
|
get_diffuse() const {
|
||
|
return _diffuse;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Removes the explicit diffuse color from the material.
|
||
|
*/
|
||
|
INLINE void Material::
|
||
|
clear_diffuse() {
|
||
|
if (has_diffuse() && is_used_by_auto_shader()) {
|
||
|
GraphicsStateGuardianBase::mark_rehash_generated_shaders();
|
||
|
}
|
||
|
_flags &= ~F_diffuse;
|
||
|
_diffuse = _base_color * (1 - _metallic);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 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;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the specular color setting, if it has been set. Returns (0,0,0,0)
|
||
|
* if the specular color has not been set.
|
||
|
*/
|
||
|
INLINE const LColor &Material::
|
||
|
get_specular() const {
|
||
|
return _specular;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns true if the emission color has been explicitly set for this
|
||
|
* material, false otherwise.
|
||
|
*/
|
||
|
INLINE bool Material::
|
||
|
has_emission() const {
|
||
|
return (_flags & F_emission) != 0;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the emission color setting, if it has been set. Returns (0,0,0,0)
|
||
|
* if the emission color has not been set.
|
||
|
*/
|
||
|
INLINE const LColor &Material::
|
||
|
get_emission() const {
|
||
|
return _emission;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Removes the explicit emission color from the material.
|
||
|
*/
|
||
|
INLINE void Material::
|
||
|
clear_emission() {
|
||
|
if (has_emission() && is_used_by_auto_shader()) {
|
||
|
GraphicsStateGuardianBase::mark_rehash_generated_shaders();
|
||
|
}
|
||
|
_flags &= ~F_emission;
|
||
|
_emission.set(0.0f, 0.0f, 0.0f, 0.0f);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the shininess exponent of the material.
|
||
|
*/
|
||
|
INLINE PN_stdfloat Material::
|
||
|
get_shininess() const {
|
||
|
return _shininess;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns true if the roughness has been explicitly set for this material,
|
||
|
* false otherwise.
|
||
|
*/
|
||
|
INLINE bool Material::
|
||
|
has_roughness() const {
|
||
|
return (_flags & F_roughness) != 0;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns true if the metallic has been explicitly set for this material,
|
||
|
* false otherwise.
|
||
|
*/
|
||
|
INLINE bool Material::
|
||
|
has_metallic() const {
|
||
|
return (_flags & F_metallic) != 0;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the metallic setting, if it has been set. Returns 0 if it has not
|
||
|
* been set.
|
||
|
*/
|
||
|
INLINE PN_stdfloat Material::
|
||
|
get_metallic() const {
|
||
|
return _metallic;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns true if a refractive index has explicitly been specified for this
|
||
|
* material.
|
||
|
*/
|
||
|
INLINE bool Material::
|
||
|
has_refractive_index() const {
|
||
|
return (_flags & F_refractive_index) != 0;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the index of refraction, or 1 if none has been set for this
|
||
|
* material.
|
||
|
*/
|
||
|
INLINE PN_stdfloat Material::
|
||
|
get_refractive_index() const {
|
||
|
return _refractive_index;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the local viewer flag. Set set_local().
|
||
|
*/
|
||
|
INLINE bool Material::
|
||
|
get_local() const {
|
||
|
return (_flags & F_local) != 0;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Sets the local viewer flag. Set this true to enable camera-relative
|
||
|
* specular highlights, or false to use orthogonal specular highlights. The
|
||
|
* default value is true. Applications that use orthogonal projection should
|
||
|
* specify false.
|
||
|
*/
|
||
|
INLINE void Material::
|
||
|
set_local(bool local) {
|
||
|
if (is_used_by_auto_shader() && get_local() != local) {
|
||
|
GraphicsStateGuardianBase::mark_rehash_generated_shaders();
|
||
|
}
|
||
|
if (local) {
|
||
|
_flags |= F_local;
|
||
|
} else {
|
||
|
_flags &= ~F_local;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the state of the two-sided lighting flag. See set_twoside().
|
||
|
*/
|
||
|
INLINE bool Material::
|
||
|
get_twoside() const {
|
||
|
return (_flags & F_twoside) != 0;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Set this true to enable two-sided lighting. When two-sided lighting is on,
|
||
|
* both sides of a polygon will be lit by this material. The default is for
|
||
|
* two-sided lighting to be off, in which case only the front surface is lit.
|
||
|
*/
|
||
|
INLINE void Material::
|
||
|
set_twoside(bool twoside) {
|
||
|
if (is_used_by_auto_shader() && get_twoside() != twoside) {
|
||
|
GraphicsStateGuardianBase::mark_rehash_generated_shaders();
|
||
|
}
|
||
|
if (twoside) {
|
||
|
_flags |= F_twoside;
|
||
|
} else {
|
||
|
_flags &= ~F_twoside;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*
|
||
|
*/
|
||
|
INLINE bool Material::
|
||
|
operator == (const Material &other) const {
|
||
|
return compare_to(other) == 0;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*
|
||
|
*/
|
||
|
INLINE bool Material::
|
||
|
operator != (const Material &other) const {
|
||
|
return compare_to(other) != 0;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*
|
||
|
*/
|
||
|
INLINE bool Material::
|
||
|
operator < (const Material &other) const {
|
||
|
return compare_to(other) < 0;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @deprecated This no longer has any meaning in 1.10.
|
||
|
*/
|
||
|
INLINE bool Material::
|
||
|
is_attrib_locked() const {
|
||
|
return (_flags & F_attrib_lock) != 0;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @deprecated This no longer has any meaning in 1.10.
|
||
|
*/
|
||
|
INLINE void Material::
|
||
|
set_attrib_lock() {
|
||
|
_flags |= F_attrib_lock;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Internal. Returns true if a shader has been generated that uses this.
|
||
|
*/
|
||
|
INLINE bool Material::
|
||
|
is_used_by_auto_shader() const {
|
||
|
return (_flags & F_attrib_lock) != 0;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Called by the shader generator to indicate that a shader has been generated
|
||
|
* that uses this material.
|
||
|
*/
|
||
|
INLINE void Material::
|
||
|
mark_used_by_auto_shader() {
|
||
|
_flags |= F_used_by_auto_shader;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*
|
||
|
*/
|
||
|
INLINE int Material::
|
||
|
get_flags() const {
|
||
|
// F_used_by_auto_shader is an internal flag, ignore it.
|
||
|
return _flags & ~F_used_by_auto_shader;
|
||
|
}
|