33using std::ostringstream;
36int ShaderAttrib::_attrib_slot;
45 if (_off_attrib ==
nullptr) {
47 attrib->_has_shader =
true;
48 _off_attrib = return_new(attrib);
57make(
const Shader *shader,
int priority) {
59 if (_null_attrib ==
nullptr) {
61 _null_attrib = return_new(attrib);
64 if (shader ==
nullptr) {
67 return DCAST(
ShaderAttrib, _null_attrib)->set_shader(shader, priority);
84set_shader(
const Shader *s,
int priority)
const {
87 result->_shader_priority = priority;
88 result->_auto_shader =
false;
89 result->_has_shader =
true;
90 return return_new(result);
97set_shader_off(
int priority)
const {
99 result->_shader =
nullptr;
100 result->_shader_priority = priority;
101 result->_auto_shader =
false;
102 result->_auto_normal_on =
false;
103 result->_auto_glow_on =
false;
104 result->_auto_gloss_on =
false;
105 result->_auto_ramp_on =
false;
106 result->_auto_shadow_on =
false;
108 result->_has_shader =
true;
109 return return_new(result);
116set_shader_auto(
int priority)
const {
118 result->_shader =
nullptr;
119 result->_shader_priority = priority;
120 result->_auto_shader =
true;
121 result->_has_shader =
true;
122 result->_auto_normal_on =
true;
123 result->_auto_glow_on =
true;
124 result->_auto_gloss_on =
true;
125 result->_auto_ramp_on =
true;
126 result->_auto_shadow_on =
true;
127 return return_new(result);
135set_shader_auto(
BitMask32 shader_switch,
int priority)
const {
138 result->_shader =
nullptr;
139 result->_shader_priority = priority;
140 result->_auto_shader =
true;
141 result->_has_shader =
true;
142 result->_auto_normal_on = shader_switch.
get_bit(Shader::bit_AutoShaderNormal);
143 result->_auto_glow_on = shader_switch.
get_bit(Shader::bit_AutoShaderGlow);
144 result->_auto_gloss_on = shader_switch.
get_bit(Shader::bit_AutoShaderGloss);
145 result->_auto_ramp_on = shader_switch.
get_bit(Shader::bit_AutoShaderRamp);
146 result->_auto_shadow_on = shader_switch.
get_bit(Shader::bit_AutoShaderShadow);
148 return return_new(result);
155clear_shader()
const {
157 result->_shader =
nullptr;
158 result->_shader_priority = 0;
159 result->_auto_shader =
false;
160 result->_has_shader =
false;
161 result->_auto_normal_on =
false;
162 result->_auto_glow_on =
false;
163 result->_auto_gloss_on =
false;
164 result->_auto_ramp_on =
false;
165 result->_auto_shadow_on =
false;
166 return return_new(result);
173set_flag(
int flag,
bool value)
const {
177 result->_flags |= bit;
179 result->_flags &= ~bit;
181 result->_has_flags |= bit;
182 return return_new(result);
189clear_flag(
int flag)
const {
192 result->_flags &= ~bit;
193 result->_has_flags &= ~bit;
194 return return_new(result);
203 Inputs::iterator i = result->_inputs.find(input.get_name());
204 if (i == result->_inputs.end()) {
205 result->_inputs.insert(Inputs::value_type(input.get_name(), input));
209 return return_new(result);
218 Inputs::iterator i = result->_inputs.find(input.get_name());
219 if (i == result->_inputs.end()) {
220 result->_inputs.insert(Inputs::value_type(input.get_name(), std::move(input)));
222 i->second = std::move(input);
224 return return_new(result);
233set_instance_count(
int instance_count)
const {
235 result->_instance_count = instance_count;
236 return return_new(result);
245 result->_inputs.erase(
id);
246 return return_new(result);
253clear_shader_input(
const std::string &
id)
const {
254 return clear_shader_input(InternalName::make(
id));
261clear_all_shader_inputs()
const {
263 result->_inputs.clear();
264 return return_new(result);
273 Inputs::const_iterator i = _inputs.find(
id);
274 if (i != _inputs.end()) {
286get_shader_input(
const std::string &
id)
const {
287 return get_shader_input(InternalName::make(
id));
295get_shader_input_nodepath(
const InternalName *
id)
const {
297 Inputs::const_iterator i = _inputs.find(
id);
298 if (i != _inputs.end()) {
300 if (p.get_value_type() == ShaderInput::M_nodepath) {
304 strm <<
"Shader input " <<
id->get_name() <<
" is not a nodepath.\n";
305 nassert_raise(strm.str());
310 strm <<
"Shader input " <<
id->get_name() <<
" is not present.\n";
311 nassert_raise(strm.str());
323LVecBase4 ShaderAttrib::
325 static LVecBase4 resfail(0,0,0,0);
326 Inputs::const_iterator i = _inputs.find(
id);
327 if (i != _inputs.end()) {
330 if (p.get_value_type() == ShaderInput::M_vector) {
331 return p.get_vector();
333 }
else if (p.get_value_type() == ShaderInput::M_numeric && p.get_ptr()._size <= 4) {
337 case Shader::SPT_float:
340 memcpy(&vectorf[0], ptr._ptr,
sizeof(
float) * ptr._size);
341 return LCAST(PN_stdfloat, vectorf);
343 case Shader::SPT_double:
346 memcpy(&vectord[0], ptr._ptr,
sizeof(
double) * ptr._size);
347 return LCAST(PN_stdfloat, vectord);
352 strm <<
"Shader input " <<
id->get_name() <<
" does not contain floating-point data.\n";
353 nassert_raise(strm.str());
358 }
else if (p.get_value_type() == ShaderInput::M_param) {
361 if (param !=
nullptr && param->
is_of_type(ParamVecBase4::get_class_type())) {
367 strm <<
"Shader input " <<
id->get_name() <<
" is not a vector.\n";
368 nassert_raise(strm.str());
371 strm <<
"Shader input " <<
id->get_name() <<
" is not present.\n";
372 nassert_raise(strm.str());
383 Inputs::const_iterator i = _inputs.find(
id);
384 if (i != _inputs.end()) {
386 if (p.get_value_type() != ShaderInput::M_numeric &&
387 p.get_value_type() != ShaderInput::M_vector) {
389 strm <<
"Shader input " <<
id->get_name() <<
" is not a PTA(float/double) type.\n";
390 nassert_raise(strm.str());
393 return &(p.get_ptr());
396 strm <<
"Shader input " <<
id->get_name() <<
" is not present.\n";
397 nassert_raise(strm.str());
411 Inputs::const_iterator i = _inputs.find(
id);
412 if (i != _inputs.end()) {
414 switch (p.get_value_type()) {
415 case ShaderInput::M_texture:
424 case ShaderInput::M_texture_sampler:
435 strm <<
"Shader input " <<
id->get_name() <<
" is not a texture.\n";
436 nassert_raise(strm.str());
442 strm <<
"Shader input " <<
id->get_name() <<
" is not present.\n";
443 nassert_raise(strm.str());
452const LMatrix4 &ShaderAttrib::
453get_shader_input_matrix(
const InternalName *
id, LMatrix4 &matrix)
const {
454 Inputs::const_iterator i = _inputs.find(
id);
455 if (i != _inputs.end()) {
458 if (p.get_value_type() == ShaderInput::M_nodepath) {
460 nassertr(!np.
is_empty(), LMatrix4::ident_mat());
463 }
else if (p.get_value_type() == ShaderInput::M_numeric &&
464 p.get_ptr()._size >= 16 && (p.get_ptr()._size & 15) == 0) {
468 case Shader::SPT_float: {
470 memcpy(&matrixf(0, 0), ptr._ptr,
sizeof(
float) * 16);
471 matrix = LCAST(PN_stdfloat, matrixf);
474 case Shader::SPT_double: {
476 memcpy(&matrixd(0, 0), ptr._ptr,
sizeof(
double) * 16);
477 matrix = LCAST(PN_stdfloat, matrixd);
482 strm <<
"Shader input " <<
id->get_name() <<
" does not contain floating-point data.\n";
483 nassert_raise(strm.str());
484 return LMatrix4::ident_mat();
490 strm <<
"Shader input " <<
id->get_name() <<
" is not a NodePath, LMatrix4 or PTA_LMatrix4.\n";
491 nassert_raise(strm.str());
492 return LMatrix4::ident_mat();
495 strm <<
"Shader input " <<
id->get_name() <<
" is not present.\n";
496 nassert_raise(strm.str());
497 return LMatrix4::ident_mat();
507 Inputs::const_iterator i = _inputs.find(
id);
508 if (i == _inputs.end()) {
510 strm <<
"Shader input " <<
id->get_name() <<
" is not present.\n";
511 nassert_raise(strm.str());
516 if (p.get_value_type() == ShaderInput::M_buffer) {
518 DCAST_INTO_R(value, p._value,
nullptr);
523 strm <<
"Shader input " <<
id->get_name() <<
" is not a ShaderBuffer.\n";
524 nassert_raise(strm.str());
534const Shader *ShaderAttrib::
543output(ostream &out)
const {
544 out <<
"ShaderAttrib:";
549 }
else if (_has_shader) {
550 if (_shader ==
nullptr) {
553 out << _shader->get_filename().get_basename();
557 out <<
"," << _inputs.size() <<
" inputs";
575 if (this->_shader != that->_shader) {
576 return (this->_shader < that->_shader) ? -1 : 1;
578 if (this->_shader_priority != that->_shader_priority) {
579 return (this->_shader_priority < that->_shader_priority) ? -1 : 1;
581 if (this->_auto_shader != that->_auto_shader) {
582 return (this->_auto_shader < that->_auto_shader) ? -1 : 1;
584 if (this->_has_shader != that->_has_shader) {
585 return (this->_has_shader < that->_has_shader) ? -1 : 1;
587 if (this->_flags != that->_flags) {
588 return (this->_flags < that->_flags) ? -1 : 1;
590 if (this->_has_flags != that->_has_flags) {
591 return (this->_has_flags < that->_has_flags) ? -1 : 1;
593 if (this->_instance_count != that->_instance_count) {
594 return (this->_instance_count < that->_instance_count) ? -1 : 1;
596 if (this->_auto_normal_on != that->_auto_normal_on) {
597 return (this->_auto_normal_on < that->_auto_normal_on) ? -1 : 1;
599 if (this->_auto_glow_on != that->_auto_glow_on) {
600 return (this->_auto_glow_on < that->_auto_glow_on) ? -1 : 1;
602 if (this->_auto_gloss_on != that->_auto_gloss_on) {
603 return (this->_auto_gloss_on < that->_auto_gloss_on) ? -1 : 1;
605 if (this->_auto_ramp_on != that->_auto_ramp_on) {
606 return (this->_auto_ramp_on < that->_auto_ramp_on) ? -1 : 1;
608 if (this->_auto_shadow_on != that->_auto_shadow_on) {
609 return (this->_auto_shadow_on < that->_auto_shadow_on) ? -1 : 1;
612 Inputs::const_iterator i1 = this->_inputs.begin();
613 Inputs::const_iterator i2 = that->_inputs.begin();
614 while ((i1 != this->_inputs.end()) && (i2 != that->_inputs.end())) {
615 if (i1->second != i2->second) {
616 return (i1->second < i2->second) ? -1 : 1;
621 if (i1 != this->_inputs.end()) {
624 if (i2 != that->_inputs.end()) {
638get_hash_impl()
const {
652 Inputs::const_iterator ii;
653 for (ii = _inputs.begin(); ii != _inputs.end(); ++ii) {
654 hash = (*ii).second.add_hash(hash);
669 if (over->_has_shader) {
670 if ((attr->_has_shader ==
false) ||
671 (over->_shader_priority >= attr->_shader_priority)) {
672 attr->_shader = over->_shader;
673 attr->_shader_priority = over->_shader_priority;
674 attr->_auto_shader = over->_auto_shader;
675 attr->_has_shader = over->_has_shader;
676 attr->_auto_normal_on = over->_auto_normal_on;
677 attr->_auto_glow_on = over->_auto_glow_on;
678 attr->_auto_gloss_on = over->_auto_gloss_on;
679 attr->_auto_ramp_on = over->_auto_ramp_on;
680 attr->_auto_shadow_on = over->_auto_shadow_on;
684 Inputs::const_iterator iover;
685 for (iover=over->_inputs.begin(); iover!=over->_inputs.end(); ++iover) {
688 Inputs::iterator iattr = attr->_inputs.find(
id);
689 if (iattr == attr->_inputs.end()) {
690 attr->_inputs.insert(Inputs::value_type(
id,dover));
693 if (dattr.get_priority() <= dover.get_priority()) {
694 iattr->second = iover->second;
700 if (attr->_instance_count == 0) {
701 attr->_instance_count = over->_instance_count;
706 if (over->_instance_count > 0) {
707 attr->_instance_count = over->_instance_count;
712 attr->_flags &= ~(over->_has_flags);
713 attr->_flags |= over->_flags;
714 attr->_has_flags |= (over->_has_flags);
715 return return_new(attr);
722register_with_read_factory() {
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool get_bit(int index) const
Returns true if the nth bit is set, false if it is cleared.
Encodes a string name in a hash table, mapping it to a pointer.
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
bool is_empty() const
Returns true if the NodePath contains no nodes.
const TransformState * get_transform(Thread *current_thread=Thread::get_current_thread()) const
Returns the complete transform object set on this node.
A class object for storing a NodePath as a parameter.
A class object for storing a pointer to a Texture along with a sampler state that indicates how to to...
get_texture
Retrieves the texture stored in the parameter.
get_sampler
Retrieves the sampler state stored in the parameter.
A handy class object for storing simple values (like integers or strings) passed along with an Event ...
This is the base class for a number of render attributes (other than transform) that may be set on sc...
Represents a set of settings that indicate how a texture is sampled.
This is a generic buffer object that lives in graphics memory.
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
get_default_sampler
This returns the default sampler state for this texture, containing the wrap and filter properties sp...
TypeHandle is the identifier used to differentiate C++ class types.
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
A base class for things which need to inherit from both TypedWritable and from ReferenceCount.
static size_t add_hash(size_t start, const Key &key)
Adds the indicated key into a running hash.
static size_t add_hash(size_t start, const void *key)
Adds the indicated key into a running hash.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.