Panda3D
shaderAttrib.cxx
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file shaderAttrib.cxx
10  * @author sshodhan
11  * @date 2004-07-10
12  * @author fperazzi, PandaSE
13  * @date 2010-04-06
14  * for set_shader_input)
15  * @author weifengh, PandaSE
16  * @date 2010-04-15
17  * set_shader_auto)
18  */
19 
20 #include "pandabase.h"
21 #include "shaderAttrib.h"
23 #include "bamReader.h"
24 #include "bamWriter.h"
25 #include "datagram.h"
26 #include "datagramIterator.h"
27 #include "nodePath.h"
28 #include "paramNodePath.h"
29 #include "paramTexture.h"
30 #include "shaderBuffer.h"
31 
32 using std::ostream;
33 using std::ostringstream;
34 
35 TypeHandle ShaderAttrib::_type_handle;
36 int ShaderAttrib::_attrib_slot;
37 
38 /**
39  * Constructs a new ShaderAttrib object that disables the use of shaders (it
40  * does not clear out all shader data, however.)
41  */
42 CPT(RenderAttrib) ShaderAttrib::
43 make_off() {
44  static CPT(RenderAttrib) _off_attrib;
45  if (_off_attrib == nullptr) {
46  ShaderAttrib *attrib = new ShaderAttrib;
47  attrib->_has_shader = true;
48  _off_attrib = return_new(attrib);
49  }
50  return _off_attrib;
51 }
52 
53 /**
54  * Constructs a new ShaderAttrib object with nothing set.
55  */
56 CPT(RenderAttrib) ShaderAttrib::
57 make(const Shader *shader, int priority) {
58  static CPT(RenderAttrib) _null_attrib;
59  if (_null_attrib == nullptr) {
60  ShaderAttrib *attrib = new ShaderAttrib;
61  _null_attrib = return_new(attrib);
62  }
63 
64  if (shader == nullptr) {
65  return _null_attrib;
66  } else {
67  return DCAST(ShaderAttrib, _null_attrib)->set_shader(shader, priority);
68  }
69 }
70 
71 /**
72  * Returns a RenderAttrib that corresponds to whatever the standard default
73  * properties for render attributes of this type ought to be.
74  */
75 CPT(RenderAttrib) ShaderAttrib::
76 make_default() {
77  return return_new(new ShaderAttrib);
78 }
79 
80 /**
81  *
82  */
83 CPT(RenderAttrib) ShaderAttrib::
84 set_shader(const Shader *s, int priority) const {
85  ShaderAttrib *result = new ShaderAttrib(*this);
86  result->_shader = s;
87  result->_shader_priority = priority;
88  result->_auto_shader = false;
89  result->_has_shader = true;
90  return return_new(result);
91 }
92 
93 /**
94  *
95  */
96 CPT(RenderAttrib) ShaderAttrib::
97 set_shader_off(int priority) const {
98  ShaderAttrib *result = new ShaderAttrib(*this);
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;
107 
108  result->_has_shader = true;
109  return return_new(result);
110 }
111 
112 /**
113  *
114  */
115 CPT(RenderAttrib) ShaderAttrib::
116 set_shader_auto(int priority) const {
117  ShaderAttrib *result = new ShaderAttrib(*this);
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);
128 }
129 
130 /**
131  * Set auto shader with bitmask to customize use, e.g., to keep normal, glow,
132  * etc., on or off
133  */
134 CPT(RenderAttrib) ShaderAttrib::
135 set_shader_auto(BitMask32 shader_switch, int priority) const {
136 
137  ShaderAttrib *result = new ShaderAttrib(*this);
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);
147 
148  return return_new(result);
149 }
150 
151 /**
152  *
153  */
154 CPT(RenderAttrib) ShaderAttrib::
155 clear_shader() const {
156  ShaderAttrib *result = new ShaderAttrib(*this);
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);
167 }
168 
169 /**
170  *
171  */
172 CPT(RenderAttrib) ShaderAttrib::
173 set_flag(int flag, bool value) const {
174  ShaderAttrib *result = new ShaderAttrib(*this);
175  int bit = 1<<flag;
176  if (value) {
177  result->_flags |= bit;
178  } else {
179  result->_flags &= ~bit;
180  }
181  result->_has_flags |= bit;
182  return return_new(result);
183 }
184 
185 /**
186  *
187  */
188 CPT(RenderAttrib) ShaderAttrib::
189 clear_flag(int flag) const {
190  ShaderAttrib *result = new ShaderAttrib(*this);
191  int bit = 1<<flag;
192  result->_flags &= ~bit;
193  result->_has_flags &= ~bit;
194  return return_new(result);
195 }
196 
197 /**
198  *
199  */
200 CPT(RenderAttrib) ShaderAttrib::
201 set_shader_input(const ShaderInput &input) const {
202  ShaderAttrib *result = new ShaderAttrib(*this);
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));
206  } else {
207  i->second = input;
208  }
209  return return_new(result);
210 }
211 
212 /**
213  *
214  */
215 CPT(RenderAttrib) ShaderAttrib::
216 set_shader_input(ShaderInput &&input) const {
217  ShaderAttrib *result = new ShaderAttrib(*this);
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)));
221  } else {
222  i->second = std::move(input);
223  }
224  return return_new(result);
225 }
226 
227 /**
228  * Sets the geometry instance count. Do not confuse this with instanceTo,
229  * which is used for animation instancing, and has nothing to do with this. A
230  * value of 0 means not to use instancing at all.
231  */
232 CPT(RenderAttrib) ShaderAttrib::
233 set_instance_count(int instance_count) const {
234  ShaderAttrib *result = new ShaderAttrib(*this);
235  result->_instance_count = instance_count;
236  return return_new(result);
237 }
238 
239 /**
240  *
241  */
242 CPT(RenderAttrib) ShaderAttrib::
243 clear_shader_input(const InternalName *id) const {
244  ShaderAttrib *result = new ShaderAttrib(*this);
245  result->_inputs.erase(id);
246  return return_new(result);
247 }
248 
249 /**
250  *
251  */
252 CPT(RenderAttrib) ShaderAttrib::
253 clear_shader_input(const std::string &id) const {
254  return clear_shader_input(InternalName::make(id));
255 }
256 
257 /**
258  * Clears all the shader inputs on the attrib.
259  */
260 CPT(RenderAttrib) ShaderAttrib::
261 clear_all_shader_inputs() const {
262  ShaderAttrib *result = new ShaderAttrib(*this);
263  result->_inputs.clear();
264  return return_new(result);
265 }
266 
267 /**
268  * Returns the ShaderInput of the given name. If no such name is found, this
269  * function does not return NULL --- it returns the "blank" ShaderInput.
270  */
271 const ShaderInput &ShaderAttrib::
272 get_shader_input(const InternalName *id) const {
273  Inputs::const_iterator i = _inputs.find(id);
274  if (i != _inputs.end()) {
275  return (*i).second;
276  } else {
277  return ShaderInput::get_blank();
278  }
279 }
280 
281 /**
282  * Returns the ShaderInput of the given name. If no such name is found, this
283  * function does not return NULL --- it returns the "blank" ShaderInput.
284  */
285 const ShaderInput &ShaderAttrib::
286 get_shader_input(const std::string &id) const {
287  return get_shader_input(InternalName::make(id));
288 }
289 
290 /**
291  * Returns the ShaderInput as a nodepath. Assertion fails if there is none,
292  * or if it is not a nodepath.
293  */
294 const NodePath &ShaderAttrib::
295 get_shader_input_nodepath(const InternalName *id) const {
296  static NodePath resfail;
297  Inputs::const_iterator i = _inputs.find(id);
298  if (i != _inputs.end()) {
299  const ShaderInput &p = (*i).second;
300  if (p.get_value_type() == ShaderInput::M_nodepath) {
301  return ((const ParamNodePath *)p.get_value())->get_value();
302  } else {
303  ostringstream strm;
304  strm << "Shader input " << id->get_name() << " is not a nodepath.\n";
305  nassert_raise(strm.str());
306  return resfail;
307  }
308  } else {
309  ostringstream strm;
310  strm << "Shader input " << id->get_name() << " is not present.\n";
311  nassert_raise(strm.str());
312  return resfail;
313  }
314 
315  // Satisfy compiler.
316  return resfail;
317 }
318 
319 /**
320  * Returns the ShaderInput as a vector. Assertion fails if there is none, or
321  * if it is not a vector.
322  */
323 LVecBase4 ShaderAttrib::
324 get_shader_input_vector(InternalName *id) const {
325  static LVecBase4 resfail(0,0,0,0);
326  Inputs::const_iterator i = _inputs.find(id);
327  if (i != _inputs.end()) {
328  const ShaderInput &p = (*i).second;
329 
330  if (p.get_value_type() == ShaderInput::M_vector) {
331  return p.get_vector();
332 
333  } else if (p.get_value_type() == ShaderInput::M_numeric && p.get_ptr()._size <= 4) {
334  const Shader::ShaderPtrData &ptr = p.get_ptr();
335 
336  switch (ptr._type) {
337  case Shader::SPT_float:
338  {
339  LVector4f vectorf;
340  memcpy(&vectorf[0], ptr._ptr, sizeof(float) * ptr._size);
341  return LCAST(PN_stdfloat, vectorf);
342  }
343  case Shader::SPT_double:
344  {
345  LVector4d vectord;
346  memcpy(&vectord[0], ptr._ptr, sizeof(double) * ptr._size);
347  return LCAST(PN_stdfloat, vectord);
348  }
349  default:
350  {
351  ostringstream strm;
352  strm << "Shader input " << id->get_name() << " does not contain floating-point data.\n";
353  nassert_raise(strm.str());
354  return resfail;
355  }
356  }
357 
358  } else if (p.get_value_type() == ShaderInput::M_param) {
359  // Temporary solution until the new param system
360  TypedWritableReferenceCount *param = p.get_value();
361  if (param != nullptr && param->is_of_type(ParamVecBase4::get_class_type())) {
362  return ((const ParamVecBase4 *)param)->get_value();
363  }
364  }
365 
366  ostringstream strm;
367  strm << "Shader input " << id->get_name() << " is not a vector.\n";
368  nassert_raise(strm.str());
369  } else {
370  ostringstream strm;
371  strm << "Shader input " << id->get_name() << " is not present.\n";
372  nassert_raise(strm.str());
373  }
374  return resfail;
375 }
376 
377 /**
378  * Returns the ShaderInput as a ShaderPtrData struct. Assertion fails if
379  * there is none. or if it is not a PTA(double/float)
380  */
381 const Shader::ShaderPtrData *ShaderAttrib::
382 get_shader_input_ptr(const InternalName *id) const {
383  Inputs::const_iterator i = _inputs.find(id);
384  if (i != _inputs.end()) {
385  const ShaderInput &p = (*i).second;
386  if (p.get_value_type() != ShaderInput::M_numeric &&
387  p.get_value_type() != ShaderInput::M_vector) {
388  ostringstream strm;
389  strm << "Shader input " << id->get_name() << " is not a PTA(float/double) type.\n";
390  nassert_raise(strm.str());
391  return nullptr;
392  }
393  return &(p.get_ptr());
394  } else {
395  ostringstream strm;
396  strm << "Shader input " << id->get_name() << " is not present.\n";
397  nassert_raise(strm.str());
398  return nullptr;
399  }
400 }
401 
402 /**
403  * Returns the ShaderInput as a texture. Assertion fails if there is none, or
404  * if it is not a texture.
405  *
406  * If sampler is not NULL, the sampler state to use for this texture is
407  * assigned to it.
408  */
409 Texture *ShaderAttrib::
410 get_shader_input_texture(const InternalName *id, SamplerState *sampler) const {
411  Inputs::const_iterator i = _inputs.find(id);
412  if (i != _inputs.end()) {
413  const ShaderInput &p = (*i).second;
414  switch (p.get_value_type()) {
415  case ShaderInput::M_texture:
416  {
417  Texture *tex = (Texture *)p.get_value();
418  if (sampler) {
419  *sampler = tex->get_default_sampler();
420  }
421  return tex;
422  }
423 
424  case ShaderInput::M_texture_sampler:
425  {
426  const ParamTextureSampler *param = (const ParamTextureSampler *)p.get_value();
427  if (sampler) {
428  *sampler = param->get_sampler();
429  }
430  return param->get_texture();
431  }
432 
433  default:
434  ostringstream strm;
435  strm << "Shader input " << id->get_name() << " is not a texture.\n";
436  nassert_raise(strm.str());
437  return nullptr;
438  }
439 
440  } else {
441  ostringstream strm;
442  strm << "Shader input " << id->get_name() << " is not present.\n";
443  nassert_raise(strm.str());
444  return nullptr;
445  }
446 }
447 
448 /**
449  * Returns the ShaderInput as a matrix. Assertion fails if there is none, or
450  * if it is not a matrix or NodePath.
451  */
452 const LMatrix4 &ShaderAttrib::
453 get_shader_input_matrix(const InternalName *id, LMatrix4 &matrix) const {
454  Inputs::const_iterator i = _inputs.find(id);
455  if (i != _inputs.end()) {
456  const ShaderInput &p = (*i).second;
457 
458  if (p.get_value_type() == ShaderInput::M_nodepath) {
459  const NodePath &np = p.get_nodepath();
460  nassertr(!np.is_empty(), LMatrix4::ident_mat());
461  return np.get_transform()->get_mat();
462 
463  } else if (p.get_value_type() == ShaderInput::M_numeric &&
464  p.get_ptr()._size >= 16 && (p.get_ptr()._size & 15) == 0) {
465  const Shader::ShaderPtrData &ptr = p.get_ptr();
466 
467  switch (ptr._type) {
468  case Shader::SPT_float: {
469  LMatrix4f matrixf;
470  memcpy(&matrixf(0, 0), ptr._ptr, sizeof(float) * 16);
471  matrix = LCAST(PN_stdfloat, matrixf);
472  return matrix;
473  }
474  case Shader::SPT_double: {
475  LMatrix4d matrixd;
476  memcpy(&matrixd(0, 0), ptr._ptr, sizeof(double) * 16);
477  matrix = LCAST(PN_stdfloat, matrixd);
478  return matrix;
479  }
480  default: {
481  ostringstream strm;
482  strm << "Shader input " << id->get_name() << " does not contain floating-point data.\n";
483  nassert_raise(strm.str());
484  return LMatrix4::ident_mat();
485  }
486  }
487  }
488 
489  ostringstream strm;
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();
493  } else {
494  ostringstream strm;
495  strm << "Shader input " << id->get_name() << " is not present.\n";
496  nassert_raise(strm.str());
497  return LMatrix4::ident_mat();
498  }
499 }
500 
501 /**
502  * Returns the ShaderInput as a ShaderBuffer. Assertion fails if there is
503  * none, or if it is not a ShaderBuffer.
504  */
505 ShaderBuffer *ShaderAttrib::
506 get_shader_input_buffer(const InternalName *id) const {
507  Inputs::const_iterator i = _inputs.find(id);
508  if (i == _inputs.end()) {
509  ostringstream strm;
510  strm << "Shader input " << id->get_name() << " is not present.\n";
511  nassert_raise(strm.str());
512  return nullptr;
513  } else {
514  const ShaderInput &p = (*i).second;
515 
516  if (p.get_value_type() == ShaderInput::M_buffer) {
517  ShaderBuffer *value;
518  DCAST_INTO_R(value, p._value, nullptr);
519  return value;
520  }
521 
522  ostringstream strm;
523  strm << "Shader input " << id->get_name() << " is not a ShaderBuffer.\n";
524  nassert_raise(strm.str());
525  return nullptr;
526  }
527 }
528 
529 /**
530  * Returns the shader object associated with the node. If get_override
531  * returns true, but get_shader returns NULL, that means that this attribute
532  * should disable the shader.
533  */
534 const Shader *ShaderAttrib::
535 get_shader() const {
536  return _shader;
537 }
538 
539 /**
540  *
541  */
542 void ShaderAttrib::
543 output(ostream &out) const {
544  out << "ShaderAttrib:";
545 
546  if (_auto_shader) {
547  out << "auto";
548  return;
549  } else if (_has_shader) {
550  if (_shader == nullptr) {
551  out << "off";
552  } else {
553  out << _shader->get_filename().get_basename();
554  }
555  }
556 
557  out << "," << _inputs.size() << " inputs";
558 }
559 
560 /**
561  * Intended to be overridden by derived ShaderAttrib types to return a unique
562  * number indicating whether this ShaderAttrib is equivalent to the other one.
563  *
564  * This should return 0 if the two ShaderAttrib objects are equivalent, a
565  * number less than zero if this one should be sorted before the other one,
566  * and a number greater than zero otherwise.
567  *
568  * This will only be called with two ShaderAttrib objects whose get_type()
569  * functions return the same.
570  */
571 int ShaderAttrib::
572 compare_to_impl(const RenderAttrib *other) const {
573  const ShaderAttrib *that = (const ShaderAttrib *)other;
574 
575  if (this->_shader != that->_shader) {
576  return (this->_shader < that->_shader) ? -1 : 1;
577  }
578  if (this->_shader_priority != that->_shader_priority) {
579  return (this->_shader_priority < that->_shader_priority) ? -1 : 1;
580  }
581  if (this->_auto_shader != that->_auto_shader) {
582  return (this->_auto_shader < that->_auto_shader) ? -1 : 1;
583  }
584  if (this->_has_shader != that->_has_shader) {
585  return (this->_has_shader < that->_has_shader) ? -1 : 1;
586  }
587  if (this->_flags != that->_flags) {
588  return (this->_flags < that->_flags) ? -1 : 1;
589  }
590  if (this->_has_flags != that->_has_flags) {
591  return (this->_has_flags < that->_has_flags) ? -1 : 1;
592  }
593  if (this->_instance_count != that->_instance_count) {
594  return (this->_instance_count < that->_instance_count) ? -1 : 1;
595  }
596  if (this->_auto_normal_on != that->_auto_normal_on) {
597  return (this->_auto_normal_on < that->_auto_normal_on) ? -1 : 1;
598  }
599  if (this->_auto_glow_on != that->_auto_glow_on) {
600  return (this->_auto_glow_on < that->_auto_glow_on) ? -1 : 1;
601  }
602  if (this->_auto_gloss_on != that->_auto_gloss_on) {
603  return (this->_auto_gloss_on < that->_auto_gloss_on) ? -1 : 1;
604  }
605  if (this->_auto_ramp_on != that->_auto_ramp_on) {
606  return (this->_auto_ramp_on < that->_auto_ramp_on) ? -1 : 1;
607  }
608  if (this->_auto_shadow_on != that->_auto_shadow_on) {
609  return (this->_auto_shadow_on < that->_auto_shadow_on) ? -1 : 1;
610  }
611 
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;
617  }
618  ++i1;
619  ++i2;
620  }
621  if (i1 != this->_inputs.end()) {
622  return 1;
623  }
624  if (i2 != that->_inputs.end()) {
625  return -1;
626  }
627 
628  return 0;
629 }
630 
631 /**
632  * Intended to be overridden by derived RenderAttrib types to return a unique
633  * hash for these particular properties. RenderAttribs that compare the same
634  * with compare_to_impl(), above, should return the same hash; RenderAttribs
635  * that compare differently should return a different hash.
636  */
637 size_t ShaderAttrib::
638 get_hash_impl() const {
639  size_t hash = 0;
640  hash = pointer_hash::add_hash(hash, _shader);
641  hash = int_hash::add_hash(hash, _shader_priority);
642  hash = int_hash::add_hash(hash, (int)_auto_shader);
643  hash = int_hash::add_hash(hash, (int)_has_shader);
644  hash = int_hash::add_hash(hash, _flags);
645  hash = int_hash::add_hash(hash, _has_flags);
646  hash = int_hash::add_hash(hash, _instance_count);
647  hash = int_hash::add_hash(hash, (int)_auto_normal_on);
648  hash = int_hash::add_hash(hash, (int)_auto_glow_on);
649  hash = int_hash::add_hash(hash, (int)_auto_gloss_on);
650  hash = int_hash::add_hash(hash, (int)_auto_shadow_on);
651 
652  Inputs::const_iterator ii;
653  for (ii = _inputs.begin(); ii != _inputs.end(); ++ii) {
654  hash = (*ii).second.add_hash(hash);
655  }
656 
657  return hash;
658 }
659 
660 /**
661  *
662  */
663 CPT(RenderAttrib) ShaderAttrib::
664 compose_impl(const RenderAttrib *other) const {
665  ShaderAttrib *attr = new ShaderAttrib(*this);
666  const ShaderAttrib *over = (const ShaderAttrib *)other;
667 
668  // Update the shader portion.
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;
681  }
682  }
683  // Update the shader-data portion.
684  Inputs::const_iterator iover;
685  for (iover=over->_inputs.begin(); iover!=over->_inputs.end(); ++iover) {
686  const InternalName *id = (*iover).first;
687  const ShaderInput &dover = (*iover).second;
688  Inputs::iterator iattr = attr->_inputs.find(id);
689  if (iattr == attr->_inputs.end()) {
690  attr->_inputs.insert(Inputs::value_type(id,dover));
691  } else {
692  const ShaderInput &dattr = (*iattr).second;
693  if (dattr.get_priority() <= dover.get_priority()) {
694  iattr->second = iover->second;
695  }
696  }
697  }
698 
699  // In case no instance count is set, just copy it.
700  if (attr->_instance_count == 0) {
701  attr->_instance_count = over->_instance_count;
702  } else {
703  // If an instance count is set, check if the other attrib has an instance
704  // count set, if so, override it, otherwise just keep the current instance
705  // count
706  if (over->_instance_count > 0) {
707  attr->_instance_count = over->_instance_count;
708  }
709  }
710 
711  // Update the flags.
712  attr->_flags &= ~(over->_has_flags);
713  attr->_flags |= over->_flags;
714  attr->_has_flags |= (over->_has_flags);
715  return return_new(attr);
716 }
717 
718 /**
719  * Factory method to generate a Shader object
720  */
721 void ShaderAttrib::
722 register_with_read_factory() {
723  // IMPLEMENT ME
724 }
static size_t add_hash(size_t start, const void *key)
Adds the indicated key into a running hash.
Definition: stl_compares.I:110
This is a generic buffer object that lives in graphics memory.
Definition: shaderBuffer.h:33
This is the base class for a number of render attributes (other than transform) that may be set on sc...
Definition: renderAttrib.h:51
A class object for storing a NodePath as a parameter.
Definition: paramNodePath.h:24
bool is_empty() const
Returns true if the NodePath contains no nodes.
Definition: nodePath.I:188
const NodePath & get_nodepath() const
Warning: no error checking is done.
Definition: shaderInput.cxx:93
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
Definition: texture.h:71
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
CPT(RenderAttrib) ShaderAttrib
Constructs a new ShaderAttrib object that disables the use of shaders (it does not clear out all shad...
Definition: shader.h:49
Filename get_filename(ShaderType type=ST_none) const
Return the Shader's filename for the given shader type.
Definition: shader.I:20
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is a small container class that can hold any one of the value types that can be passed as input ...
Definition: shaderInput.h:40
A handy class object for storing simple values (like integers or strings) passed along with an Event ...
Definition: paramValue.h:103
get_mat
Returns the matrix that describes the transform.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_default_sampler
This returns the default sampler state for this texture, containing the wrap and filter properties sp...
Definition: texture.h:413
static size_t add_hash(size_t start, const Key &key)
Adds the indicated key into a running hash.
Definition: stl_compares.I:101
bool get_bit(int index) const
Returns true if the nth bit is set, false if it is cleared.
Definition: bitMask.I:109
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_name
Returns the name of the referenced node.
Definition: nodePath.h:946
get_texture
Retrieves the texture stored in the parameter.
Definition: paramTexture.h:37
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A base class for things which need to inherit from both TypedWritable and from ReferenceCount.
Encodes a string name in a hash table, mapping it to a pointer.
Definition: internalName.h:38
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
std::string get_basename() const
Returns the basename part of the filename.
Definition: filename.I:367
Represents a set of settings that indicate how a texture is sampled.
Definition: samplerState.h:36
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
static const ShaderInput & get_blank()
Returns a static ShaderInput object with name NULL, priority zero, type INVALID, and all value-fields...
Definition: shaderInput.cxx:23
A class object for storing a pointer to a Texture along with a sampler state that indicates how to to...
Definition: paramTexture.h:26
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
Definition: typedObject.I:28
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
const TransformState * get_transform(Thread *current_thread=Thread::get_current_thread()) const
Returns the complete transform object set on this node.
Definition: nodePath.cxx:758
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
Definition: nodePath.h:161
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_sampler
Retrieves the sampler state stored in the parameter.
Definition: paramTexture.h:38