Panda3D
|
00001 // Filename: shaderAttrib.cxx 00002 // Created by: sshodhan (10Jul04) 00003 // Updated by: fperazzi, PandaSE (06Apr10) (added more overloads 00004 // for set_shader_input) 00005 // Updated by: weifengh, PandaSE(15Apr10) (added overload for 00006 // set_shader_auto) 00007 // 00008 //////////////////////////////////////////////////////////////////// 00009 // 00010 // PANDA 3D SOFTWARE 00011 // Copyright (c) Carnegie Mellon University. All rights reserved. 00012 // 00013 // All use of this software is subject to the terms of the revised BSD 00014 // license. You should have received a copy of this license along 00015 // with this source code in a file named "LICENSE." 00016 // 00017 //////////////////////////////////////////////////////////////////// 00018 00019 #include "pandabase.h" 00020 #include "shaderAttrib.h" 00021 #include "graphicsStateGuardianBase.h" 00022 #include "bamReader.h" 00023 #include "bamWriter.h" 00024 #include "datagram.h" 00025 #include "datagramIterator.h" 00026 00027 TypeHandle ShaderAttrib::_type_handle; 00028 int ShaderAttrib::_attrib_slot; 00029 00030 //////////////////////////////////////////////////////////////////// 00031 // Function: ShaderAttrib::make_off 00032 // Access: Published, Static 00033 // Description: Constructs a new ShaderAttrib object that disables 00034 // the use of shaders (it does not clear out all shader 00035 // data, however.) 00036 //////////////////////////////////////////////////////////////////// 00037 CPT(RenderAttrib) ShaderAttrib:: 00038 make_off() { 00039 static CPT(RenderAttrib) _off_attrib; 00040 if (_off_attrib == 0) { 00041 ShaderAttrib *attrib = new ShaderAttrib; 00042 attrib->_has_shader = true; 00043 _off_attrib = return_new(attrib); 00044 } 00045 return _off_attrib; 00046 } 00047 00048 //////////////////////////////////////////////////////////////////// 00049 // Function: ShaderAttrib::make 00050 // Access: Published, Static 00051 // Description: Constructs a new ShaderAttrib object with nothing 00052 // set. 00053 //////////////////////////////////////////////////////////////////// 00054 CPT(RenderAttrib) ShaderAttrib:: 00055 make() { 00056 static CPT(RenderAttrib) _null_attrib; 00057 if (_null_attrib == 0) { 00058 ShaderAttrib *attrib = new ShaderAttrib; 00059 _null_attrib = return_new(attrib); 00060 } 00061 return _null_attrib; 00062 } 00063 00064 //////////////////////////////////////////////////////////////////// 00065 // Function: ShaderAttrib::make_default 00066 // Access: Published, Static 00067 // Description: Returns a RenderAttrib that corresponds to whatever 00068 // the standard default properties for render attributes 00069 // of this type ought to be. 00070 //////////////////////////////////////////////////////////////////// 00071 CPT(RenderAttrib) ShaderAttrib:: 00072 make_default() { 00073 return return_new(new ShaderAttrib); 00074 } 00075 00076 //////////////////////////////////////////////////////////////////// 00077 // Function: ShaderAttrib::set_shader 00078 // Access: Published 00079 // Description: 00080 //////////////////////////////////////////////////////////////////// 00081 CPT(RenderAttrib) ShaderAttrib:: 00082 set_shader(const Shader *s, int priority) const { 00083 ShaderAttrib *result = new ShaderAttrib(*this); 00084 result->_shader = s; 00085 result->_shader_priority = priority; 00086 result->_auto_shader = false; 00087 result->_has_shader = true; 00088 return return_new(result); 00089 } 00090 00091 //////////////////////////////////////////////////////////////////// 00092 // Function: ShaderAttrib::set_shader_off 00093 // Access: Published 00094 // Description: 00095 //////////////////////////////////////////////////////////////////// 00096 CPT(RenderAttrib) ShaderAttrib:: 00097 set_shader_off(int priority) const { 00098 ShaderAttrib *result = new ShaderAttrib(*this); 00099 result->_shader = NULL; 00100 result->_shader_priority = priority; 00101 result->_auto_shader = false; 00102 result->_auto_normal_on = false; 00103 result->_auto_glow_on = false; 00104 result->_auto_gloss_on = false; 00105 result->_auto_ramp_on = false; 00106 result->_auto_shadow_on = false; 00107 00108 result->_has_shader = true; 00109 return return_new(result); 00110 } 00111 00112 //////////////////////////////////////////////////////////////////// 00113 // Function: ShaderAttrib::set_shader_auto 00114 // Access: Published 00115 // Description: 00116 //////////////////////////////////////////////////////////////////// 00117 CPT(RenderAttrib) ShaderAttrib:: 00118 set_shader_auto(int priority) const { 00119 ShaderAttrib *result = new ShaderAttrib(*this); 00120 result->_shader = NULL; 00121 result->_shader_priority = priority; 00122 result->_auto_shader = true; 00123 result->_has_shader = true; 00124 result->_auto_normal_on = true; 00125 result->_auto_glow_on = true; 00126 result->_auto_gloss_on = true; 00127 result->_auto_ramp_on = true; 00128 result->_auto_shadow_on = true; 00129 return return_new(result); 00130 } 00131 00132 //////////////////////////////////////////////////////////////////// 00133 // Function: ShaderAttrib::set_shader_auto 00134 // Access: Published 00135 // Description: Set auto shader with bitmask to customize use, 00136 // e.g., to keep normal, glow, etc., on or off 00137 //////////////////////////////////////////////////////////////////// 00138 CPT(RenderAttrib) ShaderAttrib:: 00139 set_shader_auto(BitMask32 shader_switch, int priority) const { 00140 00141 ShaderAttrib *result = new ShaderAttrib(*this); 00142 result->_shader = NULL; 00143 result->_shader_priority = priority; 00144 result->_auto_shader = true; 00145 result->_has_shader = true; 00146 result->_auto_normal_on = shader_switch.get_bit(Shader::bit_AutoShaderNormal); 00147 result->_auto_glow_on = shader_switch.get_bit(Shader::bit_AutoShaderGlow); 00148 result->_auto_gloss_on = shader_switch.get_bit(Shader::bit_AutoShaderGloss); 00149 result->_auto_ramp_on = shader_switch.get_bit(Shader::bit_AutoShaderRamp); 00150 result->_auto_shadow_on = shader_switch.get_bit(Shader::bit_AutoShaderShadow); 00151 00152 return return_new(result); 00153 } 00154 00155 //////////////////////////////////////////////////////////////////// 00156 // Function: ShaderAttrib::clear_shader 00157 // Access: Published 00158 // Description: 00159 //////////////////////////////////////////////////////////////////// 00160 CPT(RenderAttrib) ShaderAttrib:: 00161 clear_shader() const { 00162 ShaderAttrib *result = new ShaderAttrib(*this); 00163 result->_shader = NULL; 00164 result->_shader_priority = 0; 00165 result->_auto_shader = false; 00166 result->_has_shader = false; 00167 result->_auto_normal_on = false; 00168 result->_auto_glow_on = false; 00169 result->_auto_gloss_on = false; 00170 result->_auto_ramp_on = false; 00171 result->_auto_shadow_on = false; 00172 return return_new(result); 00173 } 00174 00175 //////////////////////////////////////////////////////////////////// 00176 // Function: ShaderAttrib::set_flag 00177 // Access: Published 00178 // Description: 00179 //////////////////////////////////////////////////////////////////// 00180 CPT(RenderAttrib) ShaderAttrib:: 00181 set_flag(int flag, bool value) const { 00182 ShaderAttrib *result = new ShaderAttrib(*this); 00183 int bit = 1<<flag; 00184 if (value) { 00185 result->_flags |= bit; 00186 } else { 00187 result->_flags &= ~bit; 00188 } 00189 result->_has_flags |= bit; 00190 return return_new(result); 00191 } 00192 00193 //////////////////////////////////////////////////////////////////// 00194 // Function: ShaderAttrib::clear_flag 00195 // Access: Published 00196 // Description: 00197 //////////////////////////////////////////////////////////////////// 00198 CPT(RenderAttrib) ShaderAttrib:: 00199 clear_flag(int flag) const { 00200 ShaderAttrib *result = new ShaderAttrib(*this); 00201 int bit = 1<<flag; 00202 result->_flags &= ~bit; 00203 result->_has_flags &= ~bit; 00204 return return_new(result); 00205 } 00206 00207 //////////////////////////////////////////////////////////////////// 00208 // Function: ShaderAttrib::set_shader_input 00209 // Access: Published 00210 // Description: 00211 //////////////////////////////////////////////////////////////////// 00212 CPT(RenderAttrib) ShaderAttrib:: 00213 set_shader_input(const ShaderInput *input) const { 00214 ShaderAttrib *result = new ShaderAttrib(*this); 00215 Inputs::iterator i = result->_inputs.find(input->get_name()); 00216 if (i == result->_inputs.end()) { 00217 result->_inputs.insert(Inputs::value_type(input->get_name(),input)); 00218 } else { 00219 i->second = input; 00220 } 00221 return return_new(result); 00222 } 00223 00224 //////////////////////////////////////////////////////////////////// 00225 // Function: ShaderAttrib::set_shader_input 00226 // Access: Published 00227 // Description: 00228 //////////////////////////////////////////////////////////////////// 00229 CPT(RenderAttrib) ShaderAttrib:: 00230 set_shader_input(const InternalName *id, const PTA_float &v, int priority) const { 00231 return set_shader_input(new ShaderInput(id,v,priority)); 00232 } 00233 00234 //////////////////////////////////////////////////////////////////// 00235 // Function: ShaderAttrib::set_shader_input 00236 // Access: Published 00237 // Description: 00238 //////////////////////////////////////////////////////////////////// 00239 CPT(RenderAttrib) ShaderAttrib:: 00240 set_shader_input(const InternalName *id, const PTA_double &v, int priority) const { 00241 return set_shader_input(new ShaderInput(id,v,priority)); 00242 } 00243 00244 //////////////////////////////////////////////////////////////////// 00245 // Function: ShaderAttrib::set_shader_input 00246 // Access: Published 00247 // Description: 00248 //////////////////////////////////////////////////////////////////// 00249 CPT(RenderAttrib) ShaderAttrib:: 00250 set_shader_input(const InternalName *id, const PTA_LVecBase4 &v, int priority) const { 00251 return set_shader_input(new ShaderInput(id,v,priority)); 00252 } 00253 00254 //////////////////////////////////////////////////////////////////// 00255 // Function: ShaderAttrib::set_shader_input 00256 // Access: Published 00257 // Description: 00258 //////////////////////////////////////////////////////////////////// 00259 CPT(RenderAttrib) ShaderAttrib:: 00260 set_shader_input(const InternalName *id, const PTA_LVecBase3 &v, int priority) const { 00261 return set_shader_input(new ShaderInput(id,v,priority)); 00262 } 00263 00264 00265 //////////////////////////////////////////////////////////////////// 00266 // Function: ShaderAttrib::set_shader_input 00267 // Access: Published 00268 // Description: 00269 //////////////////////////////////////////////////////////////////// 00270 CPT(RenderAttrib) ShaderAttrib:: 00271 set_shader_input(const InternalName *id, const PTA_LVecBase2 &v, int priority) const { 00272 return set_shader_input(new ShaderInput(id,v,priority)); 00273 } 00274 00275 //////////////////////////////////////////////////////////////////// 00276 // Function: ShaderAttrib::set_shader_input 00277 // Access: Published 00278 // Description: 00279 //////////////////////////////////////////////////////////////////// 00280 CPT(RenderAttrib) ShaderAttrib:: 00281 set_shader_input(const InternalName *id, const LVecBase4 &v, int priority) const { 00282 return set_shader_input(new ShaderInput(id,v,priority)); 00283 } 00284 00285 //////////////////////////////////////////////////////////////////// 00286 // Function: ShaderAttrib::set_shader_input 00287 // Access: Published 00288 // Description: 00289 //////////////////////////////////////////////////////////////////// 00290 CPT(RenderAttrib) ShaderAttrib:: 00291 set_shader_input(const InternalName *id, const LVecBase3 &v, int priority) const { 00292 return set_shader_input(new ShaderInput(id,v,priority)); 00293 } 00294 00295 //////////////////////////////////////////////////////////////////// 00296 // Function: ShaderAttrib::set_shader_input 00297 // Access: Published 00298 // Description: 00299 //////////////////////////////////////////////////////////////////// 00300 CPT(RenderAttrib) ShaderAttrib:: 00301 set_shader_input(const InternalName *id, const LVecBase2 &v, int priority) const { 00302 return set_shader_input(new ShaderInput(id,v,priority)); 00303 } 00304 00305 //////////////////////////////////////////////////////////////////// 00306 // Function: ShaderAttrib::set_shader_input 00307 // Access: Published 00308 // Description: 00309 //////////////////////////////////////////////////////////////////// 00310 CPT(RenderAttrib) ShaderAttrib:: 00311 set_shader_input(const InternalName *id, const PTA_LMatrix4 &v, int priority) const { 00312 return set_shader_input(new ShaderInput(id,v,priority)); 00313 } 00314 00315 //////////////////////////////////////////////////////////////////// 00316 // Function: ShaderAttrib::set_shader_input 00317 // Access: Published 00318 // Description: 00319 //////////////////////////////////////////////////////////////////// 00320 CPT(RenderAttrib) ShaderAttrib:: 00321 set_shader_input(const InternalName *id, const PTA_LMatrix3 &v, int priority) const { 00322 return set_shader_input(new ShaderInput(id,v,priority)); 00323 } 00324 00325 //////////////////////////////////////////////////////////////////// 00326 // Function: ShaderAttrib::set_shader_input 00327 // Access: Published 00328 // Description: 00329 //////////////////////////////////////////////////////////////////// 00330 CPT(RenderAttrib) ShaderAttrib:: 00331 set_shader_input(const InternalName *id, const LMatrix4 &v, int priority) const { 00332 return set_shader_input(new ShaderInput(id,v,priority)); 00333 } 00334 00335 //////////////////////////////////////////////////////////////////// 00336 // Function: ShaderAttrib::set_shader_input 00337 // Access: Published 00338 // Description: 00339 //////////////////////////////////////////////////////////////////// 00340 CPT(RenderAttrib) ShaderAttrib:: 00341 set_shader_input(const InternalName *id, const LMatrix3 &v, int priority) const { 00342 return set_shader_input(new ShaderInput(id,v,priority)); 00343 } 00344 00345 //////////////////////////////////////////////////////////////////// 00346 // Function: ShaderAttrib::set_shader_input 00347 // Access: Published 00348 // Description: 00349 //////////////////////////////////////////////////////////////////// 00350 CPT(RenderAttrib) ShaderAttrib:: 00351 set_shader_input(const InternalName *id, Texture *tex, int priority) const { 00352 return set_shader_input(new ShaderInput(id,tex,priority)); 00353 } 00354 00355 //////////////////////////////////////////////////////////////////// 00356 // Function: ShaderAttrib::set_shader_input 00357 // Access: Published 00358 // Description: 00359 //////////////////////////////////////////////////////////////////// 00360 CPT(RenderAttrib) ShaderAttrib:: 00361 set_shader_input(const InternalName *id, const NodePath &np, int priority) const { 00362 return set_shader_input(new ShaderInput(id,np,priority)); 00363 } 00364 00365 //////////////////////////////////////////////////////////////////// 00366 // Function: ShaderAttrib::set_shader_input 00367 // Access: Published 00368 // Description: 00369 //////////////////////////////////////////////////////////////////// 00370 CPT(RenderAttrib) ShaderAttrib:: 00371 set_shader_input(const InternalName *id, double n1, double n2, double n3, double n4, int priority) const { 00372 return set_shader_input(new ShaderInput(id, LVecBase4(n1,n2,n3,n4), priority)); 00373 } 00374 00375 //////////////////////////////////////////////////////////////////// 00376 // Function: ShaderAttrib::set_instance_count 00377 // Access: Published 00378 // Description: Sets the geometry instance count. Do not confuse 00379 // this with instanceTo, which is used for animation 00380 // instancing, and has nothing to do with this. 00381 // A value of 0 means not to use instancing at all. 00382 //////////////////////////////////////////////////////////////////// 00383 CPT(RenderAttrib) ShaderAttrib:: 00384 set_instance_count(int instance_count) const { 00385 ShaderAttrib *result = new ShaderAttrib(*this); 00386 result->_instance_count = instance_count; 00387 return return_new(result); 00388 } 00389 00390 //////////////////////////////////////////////////////////////////// 00391 // Function: ShaderAttrib::clear_shader_input 00392 // Access: Published 00393 // Description: 00394 //////////////////////////////////////////////////////////////////// 00395 CPT(RenderAttrib) ShaderAttrib:: 00396 clear_shader_input(const InternalName *id) const { 00397 ShaderAttrib *result = new ShaderAttrib(*this); 00398 result->_inputs.erase(id); 00399 return return_new(result); 00400 } 00401 00402 //////////////////////////////////////////////////////////////////// 00403 // Function: ShaderAttrib::clear_shader_input 00404 // Access: Published 00405 // Description: 00406 //////////////////////////////////////////////////////////////////// 00407 CPT(RenderAttrib) ShaderAttrib:: 00408 clear_shader_input(const string &id) const { 00409 return clear_shader_input(InternalName::make(id)); 00410 } 00411 00412 //////////////////////////////////////////////////////////////////// 00413 // Function: ShaderAttrib::clear_all_shader_inputs 00414 // Access: Published 00415 // Description: Clears all the shader inputs on the attrib. 00416 //////////////////////////////////////////////////////////////////// 00417 CPT(RenderAttrib) ShaderAttrib:: 00418 clear_all_shader_inputs() const { 00419 ShaderAttrib *result = new ShaderAttrib(*this); 00420 result->_inputs.clear(); 00421 return return_new(result); 00422 } 00423 00424 //////////////////////////////////////////////////////////////////// 00425 // Function: ShaderAttrib::get_shader_input 00426 // Access: Published 00427 // Description: Returns the ShaderInput of the given name. If 00428 // no such name is found, this function does not return 00429 // NULL --- it returns the "blank" ShaderInput. 00430 //////////////////////////////////////////////////////////////////// 00431 const ShaderInput *ShaderAttrib:: 00432 get_shader_input(const InternalName *id) const { 00433 Inputs::const_iterator i = _inputs.find(id); 00434 if (i == _inputs.end()) { 00435 return ShaderInput::get_blank(); 00436 } else { 00437 return (*i).second; 00438 } 00439 } 00440 00441 //////////////////////////////////////////////////////////////////// 00442 // Function: ShaderAttrib::get_shader_input 00443 // Access: Published 00444 // Description: Returns the ShaderInput of the given name. If 00445 // no such name is found, this function does not return 00446 // NULL --- it returns the "blank" ShaderInput. 00447 //////////////////////////////////////////////////////////////////// 00448 const ShaderInput *ShaderAttrib:: 00449 get_shader_input(const string &id) const { 00450 return get_shader_input(InternalName::make(id)); 00451 } 00452 00453 //////////////////////////////////////////////////////////////////// 00454 // Function: ShaderAttrib::get_shader_input_nodepath 00455 // Access: Published 00456 // Description: Returns the ShaderInput as a nodepath. Assertion 00457 // fails if there is none, or if it is not a nodepath. 00458 //////////////////////////////////////////////////////////////////// 00459 const NodePath &ShaderAttrib:: 00460 get_shader_input_nodepath(const InternalName *id) const { 00461 static NodePath resfail; 00462 Inputs::const_iterator i = _inputs.find(id); 00463 if (i == _inputs.end()) { 00464 ostringstream strm; 00465 strm << "Shader input " << id->get_name() << " is not present.\n"; 00466 nassert_raise(strm.str()); 00467 return resfail; 00468 } else { 00469 const ShaderInput *p = (*i).second; 00470 if (p->get_value_type() != ShaderInput::M_nodepath) { 00471 ostringstream strm; 00472 strm << "Shader input " << id->get_name() << " is not a nodepath.\n"; 00473 nassert_raise(strm.str()); 00474 return resfail; 00475 } 00476 return p->get_nodepath(); 00477 } 00478 00479 // Satisfy compiler. 00480 return resfail; 00481 } 00482 00483 //////////////////////////////////////////////////////////////////// 00484 // Function: ShaderAttrib::get_shader_input_vector 00485 // Access: Published 00486 // Description: Returns the ShaderInput as a vector. Assertion 00487 // fails if there is none, or if it is not a vector. 00488 //////////////////////////////////////////////////////////////////// 00489 const LVecBase4 &ShaderAttrib:: 00490 get_shader_input_vector(InternalName *id) const { 00491 static LVecBase4 resfail(0,0,0,0); 00492 Inputs::const_iterator i = _inputs.find(id); 00493 if (i == _inputs.end()) { 00494 ostringstream strm; 00495 strm << "Shader input " << id->get_name() << " is not present.\n"; 00496 nassert_raise(strm.str()); 00497 return resfail; 00498 } else { 00499 const ShaderInput *p = (*i).second; 00500 if (p->get_value_type() != ShaderInput::M_numeric) { 00501 ostringstream strm; 00502 strm << "Shader input " << id->get_name() << " is not a vector.\n"; 00503 nassert_raise(strm.str()); 00504 return resfail; 00505 } 00506 return p->get_vector(); 00507 } 00508 } 00509 00510 //////////////////////////////////////////////////////////////////// 00511 // Function: ShaderAttrib::get_shader_input_ptr 00512 // Access: Published 00513 // Description: Returns the ShaderInput as a ShaderPtrData struct. 00514 // Assertion fails if there is none. or if it is not 00515 // a PTA(double/float) 00516 //////////////////////////////////////////////////////////////////// 00517 const Shader::ShaderPtrData *ShaderAttrib:: 00518 get_shader_input_ptr(const InternalName *id) const { 00519 Inputs::const_iterator i = _inputs.find(id); 00520 if (i == _inputs.end()) { 00521 ostringstream strm; 00522 strm << "Shader input " << id->get_name() << " is not present.\n"; 00523 nassert_raise(strm.str()); 00524 return NULL; 00525 } else { 00526 const ShaderInput *p = (*i).second; 00527 if (p->get_value_type() != ShaderInput::M_numeric) { 00528 ostringstream strm; 00529 strm << "Shader input " << id->get_name() << " is not a PTA(float/double) type.\n"; 00530 nassert_raise(strm.str()); 00531 return NULL; 00532 } 00533 return &(p->get_ptr()); 00534 } 00535 } 00536 00537 //////////////////////////////////////////////////////////////////// 00538 // Function: ShaderAttrib::get_shader_input_texture 00539 // Access: Published 00540 // Description: Returns the ShaderInput as a texture. Assertion 00541 // fails if there is none, or if it is not a texture. 00542 //////////////////////////////////////////////////////////////////// 00543 Texture *ShaderAttrib:: 00544 get_shader_input_texture(const InternalName *id) const { 00545 Inputs::const_iterator i = _inputs.find(id); 00546 if (i == _inputs.end()) { 00547 ostringstream strm; 00548 strm << "Shader input " << id->get_name() << " is not present.\n"; 00549 nassert_raise(strm.str()); 00550 return NULL; 00551 } else { 00552 const ShaderInput *p = (*i).second; 00553 if (p->get_value_type() != ShaderInput::M_texture) { 00554 ostringstream strm; 00555 strm << "Shader input " << id->get_name() << " is not a texture.\n"; 00556 nassert_raise(strm.str()); 00557 return NULL; 00558 } 00559 return p->get_texture(); 00560 } 00561 } 00562 00563 //////////////////////////////////////////////////////////////////// 00564 // Function: ShaderAttrib::get_shader 00565 // Access: Published 00566 // Description: Returns the shader object associated with the node. 00567 // If get_override returns true, but get_shader 00568 // returns NULL, that means that this attribute should 00569 // disable the shader. 00570 //////////////////////////////////////////////////////////////////// 00571 const Shader *ShaderAttrib:: 00572 get_shader() const { 00573 return _shader; 00574 } 00575 00576 //////////////////////////////////////////////////////////////////// 00577 // Function: ShaderAttrib::compare_to_impl 00578 // Access: Protected, Virtual 00579 // Description: Intended to be overridden by derived ShaderAttrib 00580 // types to return a unique number indicating whether 00581 // this ShaderAttrib is equivalent to the other one. 00582 // 00583 // This should return 0 if the two ShaderAttrib objects 00584 // are equivalent, a number less than zero if this one 00585 // should be sorted before the other one, and a number 00586 // greater than zero otherwise. 00587 // 00588 // This will only be called with two ShaderAttrib 00589 // objects whose get_type() functions return the same. 00590 //////////////////////////////////////////////////////////////////// 00591 int ShaderAttrib:: 00592 compare_to_impl(const RenderAttrib *other) const { 00593 const ShaderAttrib *that; 00594 DCAST_INTO_R(that, other, 0); 00595 00596 if (this->_shader != that->_shader) { 00597 return (this->_shader < that->_shader) ? -1 : 1; 00598 } 00599 if (this->_shader_priority != that->_shader_priority) { 00600 return (this->_shader_priority < that->_shader_priority) ? -1 : 1; 00601 } 00602 if (this->_auto_shader != that->_auto_shader) { 00603 return (this->_auto_shader < that->_auto_shader) ? -1 : 1; 00604 } 00605 if (this->_has_shader != that->_has_shader) { 00606 return (this->_has_shader < that->_has_shader) ? -1 : 1; 00607 } 00608 if (this->_flags != that->_flags) { 00609 return (this->_flags < that->_flags) ? -1 : 1; 00610 } 00611 if (this->_has_flags != that->_has_flags) { 00612 return (this->_has_flags < that->_has_flags) ? -1 : 1; 00613 } 00614 if (this->_instance_count != that->_instance_count) { 00615 return (this->_instance_count < that->_instance_count) ? -1 : 1; 00616 } 00617 if (this->_auto_normal_on != that->_auto_normal_on) { 00618 return (this->_auto_normal_on < that->_auto_normal_on) ? -1 : 1; 00619 } 00620 if (this->_auto_glow_on != that->_auto_glow_on) { 00621 return (this->_auto_glow_on < that->_auto_glow_on) ? -1 : 1; 00622 } 00623 if (this->_auto_gloss_on != that->_auto_gloss_on) { 00624 return (this->_auto_gloss_on < that->_auto_gloss_on) ? -1 : 1; 00625 } 00626 if (this->_auto_ramp_on != that->_auto_ramp_on) { 00627 return (this->_auto_ramp_on < that->_auto_ramp_on) ? -1 : 1; 00628 } 00629 if (this->_auto_shadow_on != that->_auto_shadow_on) { 00630 return (this->_auto_shadow_on < that->_auto_shadow_on) ? -1 : 1; 00631 } 00632 00633 Inputs::const_iterator i1 = this->_inputs.begin(); 00634 Inputs::const_iterator i2 = that->_inputs.begin(); 00635 while ((i1 != this->_inputs.end()) && (i2 != that->_inputs.end())) { 00636 if (i1->second != i2->second) { 00637 return (i1->second < i2->second) ? -1 : 1; 00638 } 00639 ++i1; 00640 ++i2; 00641 } 00642 if (i1 != this->_inputs.end()) { 00643 return 1; 00644 } 00645 if (i2 != that->_inputs.end()) { 00646 return -1; 00647 } 00648 00649 return 0; 00650 } 00651 00652 //////////////////////////////////////////////////////////////////// 00653 // Function: ShaderAttrib::get_hash_impl 00654 // Access: Protected, Virtual 00655 // Description: Intended to be overridden by derived RenderAttrib 00656 // types to return a unique hash for these particular 00657 // properties. RenderAttribs that compare the same with 00658 // compare_to_impl(), above, should return the same 00659 // hash; RenderAttribs that compare differently should 00660 // return a different hash. 00661 //////////////////////////////////////////////////////////////////// 00662 size_t ShaderAttrib:: 00663 get_hash_impl() const { 00664 size_t hash = 0; 00665 hash = pointer_hash::add_hash(hash, _shader); 00666 hash = int_hash::add_hash(hash, _shader_priority); 00667 hash = int_hash::add_hash(hash, (int)_auto_shader); 00668 hash = int_hash::add_hash(hash, (int)_has_shader); 00669 hash = int_hash::add_hash(hash, _flags); 00670 hash = int_hash::add_hash(hash, _has_flags); 00671 hash = int_hash::add_hash(hash, _instance_count); 00672 hash = int_hash::add_hash(hash, (int)_auto_normal_on); 00673 hash = int_hash::add_hash(hash, (int)_auto_glow_on); 00674 hash = int_hash::add_hash(hash, (int)_auto_gloss_on); 00675 hash = int_hash::add_hash(hash, (int)_auto_shadow_on); 00676 00677 Inputs::const_iterator ii; 00678 for (ii = _inputs.begin(); ii != _inputs.end(); ++ii) { 00679 hash = pointer_hash::add_hash(hash, (*ii).first); 00680 hash = pointer_hash::add_hash(hash, (*ii).second); 00681 } 00682 00683 return hash; 00684 } 00685 00686 //////////////////////////////////////////////////////////////////// 00687 // Function: ShaderAttrib::compose_impl 00688 // Access: Public, Virtual 00689 // Description: 00690 //////////////////////////////////////////////////////////////////// 00691 CPT(RenderAttrib) ShaderAttrib:: 00692 compose_impl(const RenderAttrib *other) const { 00693 ShaderAttrib *attr = new ShaderAttrib(*this); 00694 const ShaderAttrib *over; 00695 DCAST_INTO_R(over, other, 0); 00696 // Update the shader portion. 00697 if (over->_has_shader) { 00698 if ((attr->_has_shader == false) || 00699 (over->_shader_priority >= attr->_shader_priority)) { 00700 attr->_shader = over->_shader; 00701 attr->_shader_priority = over->_shader_priority; 00702 attr->_auto_shader = over->_auto_shader; 00703 attr->_has_shader = over->_has_shader; 00704 attr->_auto_normal_on = over->_auto_normal_on; 00705 attr->_auto_glow_on = over->_auto_glow_on; 00706 attr->_auto_gloss_on = over->_auto_gloss_on; 00707 attr->_auto_ramp_on = over->_auto_ramp_on; 00708 attr->_auto_shadow_on = over->_auto_shadow_on; 00709 } 00710 } 00711 // Update the shader-data portion. 00712 Inputs::const_iterator iover; 00713 for (iover=over->_inputs.begin(); iover!=over->_inputs.end(); ++iover) { 00714 const InternalName *id = (*iover).first; 00715 const ShaderInput *dover = (*iover).second; 00716 Inputs::iterator iattr = attr->_inputs.find(id); 00717 if (iattr == attr->_inputs.end()) { 00718 attr->_inputs.insert(Inputs::value_type(id,dover)); 00719 } else { 00720 const ShaderInput *dattr = (*iattr).second; 00721 if (dattr->get_priority() <= dover->get_priority()) { 00722 iattr->second = iover->second; 00723 } 00724 } 00725 } 00726 // Just copy the instance count. 00727 attr->_instance_count = over->_instance_count; 00728 // Update the flags. 00729 attr->_flags &= ~(over->_has_flags); 00730 attr->_flags |= over->_flags; 00731 attr->_has_flags |= (over->_has_flags); 00732 return return_new(attr); 00733 } 00734 00735 //////////////////////////////////////////////////////////////////// 00736 // Function: ShaderAttrib::get_auto_shader_attrib_impl 00737 // Access: Protected, Virtual 00738 // Description: 00739 //////////////////////////////////////////////////////////////////// 00740 CPT(RenderAttrib) ShaderAttrib:: 00741 get_auto_shader_attrib_impl(const RenderState *state) const { 00742 // For a ShaderAttrib, we only need to preserve the auto-shader 00743 // flags. Custom shaders, and custom shader inputs, aren't relevant 00744 // to the shader generator. 00745 ShaderAttrib *attrib = new ShaderAttrib; 00746 attrib->_auto_shader = _auto_shader; 00747 attrib->_has_shader = _has_shader; 00748 attrib->_auto_normal_on = _auto_normal_on; 00749 attrib->_auto_glow_on = _auto_glow_on; 00750 attrib->_auto_gloss_on = _auto_gloss_on; 00751 attrib->_auto_ramp_on = _auto_ramp_on; 00752 attrib->_auto_shadow_on = _auto_shadow_on; 00753 return return_new(attrib); 00754 } 00755 00756 //////////////////////////////////////////////////////////////////// 00757 // Function: ShaderAttrib::register_with_read_factory 00758 // Access: Public, Static 00759 // Description: Factory method to generate a Shader object 00760 //////////////////////////////////////////////////////////////////// 00761 void ShaderAttrib:: 00762 register_with_read_factory() { 00763 // IMPLEMENT ME 00764 } 00765