panda3d/panda/src/pgraph/shaderAttrib.cxx

771 lines
28 KiB
C++
Executable File

// Filename: shaderAttrib.cxx
// Created by: sshodhan (10Jul04)
// Updated by: fperazzi, PandaSE (06Apr10) (added more overloads
// for set_shader_input)
// Updated by: weifengh, PandaSE(15Apr10) (added overload for
// set_shader_auto)
//
////////////////////////////////////////////////////////////////////
//
// 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."
//
////////////////////////////////////////////////////////////////////
#include "pandabase.h"
#include "shaderAttrib.h"
#include "graphicsStateGuardianBase.h"
#include "bamReader.h"
#include "bamWriter.h"
#include "datagram.h"
#include "datagramIterator.h"
TypeHandle ShaderAttrib::_type_handle;
int ShaderAttrib::_attrib_slot;
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::make_off
// Access: Published, Static
// Description: Constructs a new ShaderAttrib object that disables
// the use of shaders (it does not clear out all shader
// data, however.)
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
make_off() {
static CPT(RenderAttrib) _off_attrib;
if (_off_attrib == 0) {
ShaderAttrib *attrib = new ShaderAttrib;
attrib->_has_shader = true;
_off_attrib = return_new(attrib);
}
return _off_attrib;
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::make
// Access: Published, Static
// Description: Constructs a new ShaderAttrib object with nothing
// set.
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
make(const Shader *shader) {
static CPT(RenderAttrib) _null_attrib;
if (_null_attrib == 0) {
ShaderAttrib *attrib = new ShaderAttrib;
_null_attrib = return_new(attrib);
}
if (shader == NULL) {
return _null_attrib;
} else {
return DCAST(ShaderAttrib, _null_attrib)->set_shader(shader);
}
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::make_default
// Access: Published, Static
// Description: Returns a RenderAttrib that corresponds to whatever
// the standard default properties for render attributes
// of this type ought to be.
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
make_default() {
return return_new(new ShaderAttrib);
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::set_shader
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
set_shader(const Shader *s, int priority) const {
ShaderAttrib *result = new ShaderAttrib(*this);
result->_shader = s;
result->_shader_priority = priority;
result->_auto_shader = false;
result->_has_shader = true;
return return_new(result);
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::set_shader_off
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
set_shader_off(int priority) const {
ShaderAttrib *result = new ShaderAttrib(*this);
result->_shader = NULL;
result->_shader_priority = priority;
result->_auto_shader = false;
result->_auto_normal_on = false;
result->_auto_glow_on = false;
result->_auto_gloss_on = false;
result->_auto_ramp_on = false;
result->_auto_shadow_on = false;
result->_has_shader = true;
return return_new(result);
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::set_shader_auto
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
set_shader_auto(int priority) const {
ShaderAttrib *result = new ShaderAttrib(*this);
result->_shader = NULL;
result->_shader_priority = priority;
result->_auto_shader = true;
result->_has_shader = true;
result->_auto_normal_on = true;
result->_auto_glow_on = true;
result->_auto_gloss_on = true;
result->_auto_ramp_on = true;
result->_auto_shadow_on = true;
return return_new(result);
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::set_shader_auto
// Access: Published
// Description: Set auto shader with bitmask to customize use,
// e.g., to keep normal, glow, etc., on or off
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
set_shader_auto(BitMask32 shader_switch, int priority) const {
ShaderAttrib *result = new ShaderAttrib(*this);
result->_shader = NULL;
result->_shader_priority = priority;
result->_auto_shader = true;
result->_has_shader = true;
result->_auto_normal_on = shader_switch.get_bit(Shader::bit_AutoShaderNormal);
result->_auto_glow_on = shader_switch.get_bit(Shader::bit_AutoShaderGlow);
result->_auto_gloss_on = shader_switch.get_bit(Shader::bit_AutoShaderGloss);
result->_auto_ramp_on = shader_switch.get_bit(Shader::bit_AutoShaderRamp);
result->_auto_shadow_on = shader_switch.get_bit(Shader::bit_AutoShaderShadow);
return return_new(result);
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::clear_shader
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
clear_shader() const {
ShaderAttrib *result = new ShaderAttrib(*this);
result->_shader = NULL;
result->_shader_priority = 0;
result->_auto_shader = false;
result->_has_shader = false;
result->_auto_normal_on = false;
result->_auto_glow_on = false;
result->_auto_gloss_on = false;
result->_auto_ramp_on = false;
result->_auto_shadow_on = false;
return return_new(result);
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::set_flag
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
set_flag(int flag, bool value) const {
ShaderAttrib *result = new ShaderAttrib(*this);
int bit = 1<<flag;
if (value) {
result->_flags |= bit;
} else {
result->_flags &= ~bit;
}
result->_has_flags |= bit;
return return_new(result);
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::clear_flag
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
clear_flag(int flag) const {
ShaderAttrib *result = new ShaderAttrib(*this);
int bit = 1<<flag;
result->_flags &= ~bit;
result->_has_flags &= ~bit;
return return_new(result);
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::set_shader_input
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
set_shader_input(const ShaderInput *input) const {
ShaderAttrib *result = new ShaderAttrib(*this);
Inputs::iterator i = result->_inputs.find(input->get_name());
if (i == result->_inputs.end()) {
result->_inputs.insert(Inputs::value_type(input->get_name(),input));
} else {
i->second = input;
}
return return_new(result);
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::set_shader_input
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
set_shader_input(const InternalName *id, const PTA_float &v, int priority) const {
return set_shader_input(new ShaderInput(id,v,priority));
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::set_shader_input
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
set_shader_input(const InternalName *id, const PTA_double &v, int priority) const {
return set_shader_input(new ShaderInput(id,v,priority));
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::set_shader_input
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
set_shader_input(const InternalName *id, const PTA_LVecBase4 &v, int priority) const {
return set_shader_input(new ShaderInput(id,v,priority));
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::set_shader_input
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
set_shader_input(const InternalName *id, const PTA_LVecBase3 &v, int priority) const {
return set_shader_input(new ShaderInput(id,v,priority));
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::set_shader_input
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
set_shader_input(const InternalName *id, const PTA_LVecBase2 &v, int priority) const {
return set_shader_input(new ShaderInput(id,v,priority));
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::set_shader_input
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
set_shader_input(const InternalName *id, const LVecBase4 &v, int priority) const {
return set_shader_input(new ShaderInput(id,v,priority));
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::set_shader_input
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
set_shader_input(const InternalName *id, const LVecBase3 &v, int priority) const {
return set_shader_input(new ShaderInput(id,v,priority));
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::set_shader_input
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
set_shader_input(const InternalName *id, const LVecBase2 &v, int priority) const {
return set_shader_input(new ShaderInput(id,v,priority));
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::set_shader_input
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
set_shader_input(const InternalName *id, const PTA_LMatrix4 &v, int priority) const {
return set_shader_input(new ShaderInput(id,v,priority));
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::set_shader_input
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
set_shader_input(const InternalName *id, const PTA_LMatrix3 &v, int priority) const {
return set_shader_input(new ShaderInput(id,v,priority));
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::set_shader_input
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
set_shader_input(const InternalName *id, const LMatrix4 &v, int priority) const {
return set_shader_input(new ShaderInput(id,v,priority));
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::set_shader_input
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
set_shader_input(const InternalName *id, const LMatrix3 &v, int priority) const {
return set_shader_input(new ShaderInput(id,v,priority));
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::set_shader_input
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
set_shader_input(const InternalName *id, Texture *tex, int priority) const {
return set_shader_input(new ShaderInput(id,tex,priority));
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::set_shader_input
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
set_shader_input(const InternalName *id, const NodePath &np, int priority) const {
return set_shader_input(new ShaderInput(id,np,priority));
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::set_shader_input
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
set_shader_input(const InternalName *id, double n1, double n2, double n3, double n4, int priority) const {
return set_shader_input(new ShaderInput(id, LVecBase4(n1,n2,n3,n4), priority));
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::set_instance_count
// Access: Published
// Description: Sets the geometry instance count. Do not confuse
// this with instanceTo, which is used for animation
// instancing, and has nothing to do with this.
// A value of 0 means not to use instancing at all.
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
set_instance_count(int instance_count) const {
ShaderAttrib *result = new ShaderAttrib(*this);
result->_instance_count = instance_count;
return return_new(result);
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::clear_shader_input
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
clear_shader_input(const InternalName *id) const {
ShaderAttrib *result = new ShaderAttrib(*this);
result->_inputs.erase(id);
return return_new(result);
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::clear_shader_input
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
clear_shader_input(const string &id) const {
return clear_shader_input(InternalName::make(id));
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::clear_all_shader_inputs
// Access: Published
// Description: Clears all the shader inputs on the attrib.
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
clear_all_shader_inputs() const {
ShaderAttrib *result = new ShaderAttrib(*this);
result->_inputs.clear();
return return_new(result);
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::get_shader_input
// Access: Published
// Description: Returns the ShaderInput of the given name. If
// no such name is found, this function does not return
// NULL --- it returns the "blank" ShaderInput.
////////////////////////////////////////////////////////////////////
const ShaderInput *ShaderAttrib::
get_shader_input(const InternalName *id) const {
Inputs::const_iterator i = _inputs.find(id);
if (i == _inputs.end()) {
return ShaderInput::get_blank();
} else {
return (*i).second;
}
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::get_shader_input
// Access: Published
// Description: Returns the ShaderInput of the given name. If
// no such name is found, this function does not return
// NULL --- it returns the "blank" ShaderInput.
////////////////////////////////////////////////////////////////////
const ShaderInput *ShaderAttrib::
get_shader_input(const string &id) const {
return get_shader_input(InternalName::make(id));
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::get_shader_input_nodepath
// Access: Published
// Description: Returns the ShaderInput as a nodepath. Assertion
// fails if there is none, or if it is not a nodepath.
////////////////////////////////////////////////////////////////////
const NodePath &ShaderAttrib::
get_shader_input_nodepath(const InternalName *id) const {
static NodePath resfail;
Inputs::const_iterator i = _inputs.find(id);
if (i == _inputs.end()) {
ostringstream strm;
strm << "Shader input " << id->get_name() << " is not present.\n";
nassert_raise(strm.str());
return resfail;
} else {
const ShaderInput *p = (*i).second;
if (p->get_value_type() != ShaderInput::M_nodepath) {
ostringstream strm;
strm << "Shader input " << id->get_name() << " is not a nodepath.\n";
nassert_raise(strm.str());
return resfail;
}
return p->get_nodepath();
}
// Satisfy compiler.
return resfail;
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::get_shader_input_vector
// Access: Published
// Description: Returns the ShaderInput as a vector. Assertion
// fails if there is none, or if it is not a vector.
////////////////////////////////////////////////////////////////////
const LVecBase4 &ShaderAttrib::
get_shader_input_vector(InternalName *id) const {
static LVecBase4 resfail(0,0,0,0);
Inputs::const_iterator i = _inputs.find(id);
if (i == _inputs.end()) {
ostringstream strm;
strm << "Shader input " << id->get_name() << " is not present.\n";
nassert_raise(strm.str());
return resfail;
} else {
const ShaderInput *p = (*i).second;
if (p->get_value_type() != ShaderInput::M_numeric) {
ostringstream strm;
strm << "Shader input " << id->get_name() << " is not a vector.\n";
nassert_raise(strm.str());
return resfail;
}
return p->get_vector();
}
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::get_shader_input_ptr
// Access: Published
// Description: Returns the ShaderInput as a ShaderPtrData struct.
// Assertion fails if there is none. or if it is not
// a PTA(double/float)
////////////////////////////////////////////////////////////////////
const Shader::ShaderPtrData *ShaderAttrib::
get_shader_input_ptr(const InternalName *id) const {
Inputs::const_iterator i = _inputs.find(id);
if (i == _inputs.end()) {
ostringstream strm;
strm << "Shader input " << id->get_name() << " is not present.\n";
nassert_raise(strm.str());
return NULL;
} else {
const ShaderInput *p = (*i).second;
if (p->get_value_type() != ShaderInput::M_numeric) {
ostringstream strm;
strm << "Shader input " << id->get_name() << " is not a PTA(float/double) type.\n";
nassert_raise(strm.str());
return NULL;
}
return &(p->get_ptr());
}
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::get_shader_input_texture
// Access: Published
// Description: Returns the ShaderInput as a texture. Assertion
// fails if there is none, or if it is not a texture.
////////////////////////////////////////////////////////////////////
Texture *ShaderAttrib::
get_shader_input_texture(const InternalName *id) const {
Inputs::const_iterator i = _inputs.find(id);
if (i == _inputs.end()) {
ostringstream strm;
strm << "Shader input " << id->get_name() << " is not present.\n";
nassert_raise(strm.str());
return NULL;
} else {
const ShaderInput *p = (*i).second;
if (p->get_value_type() != ShaderInput::M_texture) {
ostringstream strm;
strm << "Shader input " << id->get_name() << " is not a texture.\n";
nassert_raise(strm.str());
return NULL;
}
return p->get_texture();
}
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::get_shader
// Access: Published
// Description: Returns the shader object associated with the node.
// If get_override returns true, but get_shader
// returns NULL, that means that this attribute should
// disable the shader.
////////////////////////////////////////////////////////////////////
const Shader *ShaderAttrib::
get_shader() const {
return _shader;
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::compare_to_impl
// Access: Protected, Virtual
// Description: Intended to be overridden by derived ShaderAttrib
// types to return a unique number indicating whether
// this ShaderAttrib is equivalent to the other one.
//
// This should return 0 if the two ShaderAttrib objects
// are equivalent, a number less than zero if this one
// should be sorted before the other one, and a number
// greater than zero otherwise.
//
// This will only be called with two ShaderAttrib
// objects whose get_type() functions return the same.
////////////////////////////////////////////////////////////////////
int ShaderAttrib::
compare_to_impl(const RenderAttrib *other) const {
const ShaderAttrib *that;
DCAST_INTO_R(that, other, 0);
if (this->_shader != that->_shader) {
return (this->_shader < that->_shader) ? -1 : 1;
}
if (this->_shader_priority != that->_shader_priority) {
return (this->_shader_priority < that->_shader_priority) ? -1 : 1;
}
if (this->_auto_shader != that->_auto_shader) {
return (this->_auto_shader < that->_auto_shader) ? -1 : 1;
}
if (this->_has_shader != that->_has_shader) {
return (this->_has_shader < that->_has_shader) ? -1 : 1;
}
if (this->_flags != that->_flags) {
return (this->_flags < that->_flags) ? -1 : 1;
}
if (this->_has_flags != that->_has_flags) {
return (this->_has_flags < that->_has_flags) ? -1 : 1;
}
if (this->_instance_count != that->_instance_count) {
return (this->_instance_count < that->_instance_count) ? -1 : 1;
}
if (this->_auto_normal_on != that->_auto_normal_on) {
return (this->_auto_normal_on < that->_auto_normal_on) ? -1 : 1;
}
if (this->_auto_glow_on != that->_auto_glow_on) {
return (this->_auto_glow_on < that->_auto_glow_on) ? -1 : 1;
}
if (this->_auto_gloss_on != that->_auto_gloss_on) {
return (this->_auto_gloss_on < that->_auto_gloss_on) ? -1 : 1;
}
if (this->_auto_ramp_on != that->_auto_ramp_on) {
return (this->_auto_ramp_on < that->_auto_ramp_on) ? -1 : 1;
}
if (this->_auto_shadow_on != that->_auto_shadow_on) {
return (this->_auto_shadow_on < that->_auto_shadow_on) ? -1 : 1;
}
Inputs::const_iterator i1 = this->_inputs.begin();
Inputs::const_iterator i2 = that->_inputs.begin();
while ((i1 != this->_inputs.end()) && (i2 != that->_inputs.end())) {
if (i1->second != i2->second) {
return (i1->second < i2->second) ? -1 : 1;
}
++i1;
++i2;
}
if (i1 != this->_inputs.end()) {
return 1;
}
if (i2 != that->_inputs.end()) {
return -1;
}
return 0;
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::get_hash_impl
// Access: Protected, Virtual
// Description: Intended to be overridden by derived RenderAttrib
// types to return a unique hash for these particular
// properties. RenderAttribs that compare the same with
// compare_to_impl(), above, should return the same
// hash; RenderAttribs that compare differently should
// return a different hash.
////////////////////////////////////////////////////////////////////
size_t ShaderAttrib::
get_hash_impl() const {
size_t hash = 0;
hash = pointer_hash::add_hash(hash, _shader);
hash = int_hash::add_hash(hash, _shader_priority);
hash = int_hash::add_hash(hash, (int)_auto_shader);
hash = int_hash::add_hash(hash, (int)_has_shader);
hash = int_hash::add_hash(hash, _flags);
hash = int_hash::add_hash(hash, _has_flags);
hash = int_hash::add_hash(hash, _instance_count);
hash = int_hash::add_hash(hash, (int)_auto_normal_on);
hash = int_hash::add_hash(hash, (int)_auto_glow_on);
hash = int_hash::add_hash(hash, (int)_auto_gloss_on);
hash = int_hash::add_hash(hash, (int)_auto_shadow_on);
Inputs::const_iterator ii;
for (ii = _inputs.begin(); ii != _inputs.end(); ++ii) {
hash = pointer_hash::add_hash(hash, (*ii).first);
hash = pointer_hash::add_hash(hash, (*ii).second);
}
return hash;
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::compose_impl
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
compose_impl(const RenderAttrib *other) const {
ShaderAttrib *attr = new ShaderAttrib(*this);
const ShaderAttrib *over;
DCAST_INTO_R(over, other, 0);
// Update the shader portion.
if (over->_has_shader) {
if ((attr->_has_shader == false) ||
(over->_shader_priority >= attr->_shader_priority)) {
attr->_shader = over->_shader;
attr->_shader_priority = over->_shader_priority;
attr->_auto_shader = over->_auto_shader;
attr->_has_shader = over->_has_shader;
attr->_auto_normal_on = over->_auto_normal_on;
attr->_auto_glow_on = over->_auto_glow_on;
attr->_auto_gloss_on = over->_auto_gloss_on;
attr->_auto_ramp_on = over->_auto_ramp_on;
attr->_auto_shadow_on = over->_auto_shadow_on;
}
}
// Update the shader-data portion.
Inputs::const_iterator iover;
for (iover=over->_inputs.begin(); iover!=over->_inputs.end(); ++iover) {
const InternalName *id = (*iover).first;
const ShaderInput *dover = (*iover).second;
Inputs::iterator iattr = attr->_inputs.find(id);
if (iattr == attr->_inputs.end()) {
attr->_inputs.insert(Inputs::value_type(id,dover));
} else {
const ShaderInput *dattr = (*iattr).second;
if (dattr->get_priority() <= dover->get_priority()) {
iattr->second = iover->second;
}
}
}
// Just copy the instance count.
attr->_instance_count = over->_instance_count;
// Update the flags.
attr->_flags &= ~(over->_has_flags);
attr->_flags |= over->_flags;
attr->_has_flags |= (over->_has_flags);
return return_new(attr);
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::get_auto_shader_attrib_impl
// Access: Protected, Virtual
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
get_auto_shader_attrib_impl(const RenderState *state) const {
// For a ShaderAttrib, we only need to preserve the auto-shader
// flags. Custom shaders, and custom shader inputs, aren't relevant
// to the shader generator.
ShaderAttrib *attrib = new ShaderAttrib;
attrib->_auto_shader = _auto_shader;
attrib->_has_shader = _has_shader;
attrib->_auto_normal_on = _auto_normal_on;
attrib->_auto_glow_on = _auto_glow_on;
attrib->_auto_gloss_on = _auto_gloss_on;
attrib->_auto_ramp_on = _auto_ramp_on;
attrib->_auto_shadow_on = _auto_shadow_on;
return return_new(attrib);
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::register_with_read_factory
// Access: Public, Static
// Description: Factory method to generate a Shader object
////////////////////////////////////////////////////////////////////
void ShaderAttrib::
register_with_read_factory() {
// IMPLEMENT ME
}