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 }
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.
Definition: bitMask.I:109
std::string get_basename() const
Returns the basename part of the filename.
Definition: filename.I:367
Encodes a string name in a hash table, mapping it to a pointer.
Definition: internalName.h:38
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
Definition: nodePath.h:159
bool is_empty() const
Returns true if the NodePath contains no nodes.
Definition: nodePath.I:188
const TransformState * get_transform(Thread *current_thread=Thread::get_current_thread()) const
Returns the complete transform object set on this node.
Definition: nodePath.cxx:795
get_name
Returns the name of the referenced node.
Definition: nodePath.h:945
A class object for storing a NodePath as a parameter.
Definition: paramNodePath.h:24
A class object for storing a pointer to a Texture along with a sampler state that indicates how to to...
Definition: paramTexture.h:26
get_texture
Retrieves the texture stored in the parameter.
Definition: paramTexture.h:37
get_sampler
Retrieves the sampler state stored in the parameter.
Definition: paramTexture.h:38
A handy class object for storing simple values (like integers or strings) passed along with an Event ...
Definition: paramValue.h:103
This is the base class for a number of render attributes (other than transform) that may be set on sc...
Definition: renderAttrib.h:51
Represents a set of settings that indicate how a texture is sampled.
Definition: samplerState.h:36
This is a generic buffer object that lives in graphics memory.
Definition: shaderBuffer.h:33
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
const NodePath & get_nodepath() const
Warning: no error checking is done.
Definition: shaderInput.cxx:93
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
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
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
get_default_sampler
This returns the default sampler state for this texture, containing the wrap and filter properties sp...
Definition: texture.h:421
get_mat
Returns the matrix that describes the transform.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
Definition: typedObject.I:28
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.
Definition: stl_compares.I:101
static size_t add_hash(size_t start, const void *key)
Adds the indicated key into a running hash.
Definition: stl_compares.I:110
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.
CPT(RenderAttrib) ShaderAttrib
Constructs a new ShaderAttrib object that disables the use of shaders (it does not clear out all shad...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.