Panda3D

shaderAttrib.cxx

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 
 All Classes Functions Variables Enumerations