Panda3D

shaderAttrib.cxx

00001 // Filename: shaderAttrib.cxx
00002 // Created by:  sshodhan (10Jul04)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "pandabase.h"
00016 #include "shaderAttrib.h"
00017 #include "graphicsStateGuardianBase.h"
00018 #include "bamReader.h"
00019 #include "bamWriter.h"
00020 #include "datagram.h"
00021 #include "datagramIterator.h"
00022 
00023 TypeHandle ShaderAttrib::_type_handle;
00024 int ShaderAttrib::_attrib_slot;
00025 
00026 ////////////////////////////////////////////////////////////////////
00027 //     Function: ShaderAttrib::make_off
00028 //       Access: Published, Static
00029 //  Description: Constructs a new ShaderAttrib object that disables
00030 //               the use of shaders (it does not clear out all shader
00031 //               data, however.)
00032 ////////////////////////////////////////////////////////////////////
00033 CPT(RenderAttrib) ShaderAttrib::
00034 make_off() {
00035   static CPT(RenderAttrib) _off_attrib;
00036   if (_off_attrib == 0) {
00037     ShaderAttrib *attrib = new ShaderAttrib;
00038     attrib->_has_shader = true;
00039     _off_attrib = return_new(attrib);
00040   }
00041   return _off_attrib;
00042 }
00043 
00044 ////////////////////////////////////////////////////////////////////
00045 //     Function: ShaderAttrib::make
00046 //       Access: Published, Static
00047 //  Description: Constructs a new ShaderAttrib object with nothing
00048 //               set.
00049 ////////////////////////////////////////////////////////////////////
00050 CPT(RenderAttrib) ShaderAttrib::
00051 make() {
00052   static CPT(RenderAttrib) _null_attrib;
00053   if (_null_attrib == 0) {
00054     ShaderAttrib *attrib = new ShaderAttrib;
00055     _null_attrib = return_new(attrib);
00056   }
00057   return _null_attrib;
00058 }
00059 
00060 ////////////////////////////////////////////////////////////////////
00061 //     Function: ShaderAttrib::make_default
00062 //       Access: Published, Static
00063 //  Description: Returns a RenderAttrib that corresponds to whatever
00064 //               the standard default properties for render attributes
00065 //               of this type ought to be.
00066 ////////////////////////////////////////////////////////////////////
00067 CPT(RenderAttrib) ShaderAttrib::
00068 make_default() {
00069   return return_new(new ShaderAttrib);
00070 }
00071 
00072 ////////////////////////////////////////////////////////////////////
00073 //     Function: ShaderAttrib::set_shader
00074 //       Access: Published
00075 //  Description: 
00076 ////////////////////////////////////////////////////////////////////
00077 CPT(RenderAttrib) ShaderAttrib::
00078 set_shader(const Shader *s, int priority) const {
00079   ShaderAttrib *result = new ShaderAttrib(*this);
00080   result->_shader = s;
00081   result->_shader_priority = priority;
00082   result->_auto_shader = false;
00083   result->_has_shader = true;
00084   return return_new(result);
00085 }
00086 
00087 ////////////////////////////////////////////////////////////////////
00088 //     Function: ShaderAttrib::set_shader_off
00089 //       Access: Published
00090 //  Description: 
00091 ////////////////////////////////////////////////////////////////////
00092 CPT(RenderAttrib) ShaderAttrib::
00093 set_shader_off(int priority) const {
00094   ShaderAttrib *result = new ShaderAttrib(*this);
00095   result->_shader = NULL;
00096   result->_shader_priority = priority;
00097   result->_auto_shader = false;
00098   result->_has_shader = true;
00099   return return_new(result);
00100 }
00101 
00102 ////////////////////////////////////////////////////////////////////
00103 //     Function: ShaderAttrib::set_shader_auto
00104 //       Access: Published
00105 //  Description: 
00106 ////////////////////////////////////////////////////////////////////
00107 CPT(RenderAttrib) ShaderAttrib::
00108 set_shader_auto(int priority) const {
00109   ShaderAttrib *result = new ShaderAttrib(*this);
00110   result->_shader = NULL;
00111   result->_shader_priority = priority;
00112   result->_auto_shader = true;
00113   result->_has_shader = true;
00114   return return_new(result);
00115 }
00116 
00117 ////////////////////////////////////////////////////////////////////
00118 //     Function: ShaderAttrib::clear_shader
00119 //       Access: Published
00120 //  Description: 
00121 ////////////////////////////////////////////////////////////////////
00122 CPT(RenderAttrib) ShaderAttrib::
00123 clear_shader() const {
00124   ShaderAttrib *result = new ShaderAttrib(*this);
00125   result->_shader = NULL;
00126   result->_shader_priority = 0;
00127   result->_auto_shader = false;
00128   result->_has_shader = false;
00129   return return_new(result);
00130 }
00131 
00132 ////////////////////////////////////////////////////////////////////
00133 //     Function: ShaderAttrib::set_flag
00134 //       Access: Published
00135 //  Description: 
00136 ////////////////////////////////////////////////////////////////////
00137 CPT(RenderAttrib) ShaderAttrib::
00138 set_flag(int flag, bool value) const {
00139   ShaderAttrib *result = new ShaderAttrib(*this);
00140   int bit = 1<<flag;
00141   if (value) {
00142     result->_flags |= bit;
00143   } else {
00144     result->_flags &= ~bit;
00145   }
00146   result->_has_flags |= bit;
00147   return return_new(result);
00148 }
00149   
00150 ////////////////////////////////////////////////////////////////////
00151 //     Function: ShaderAttrib::clear_flag
00152 //       Access: Published
00153 //  Description: 
00154 ////////////////////////////////////////////////////////////////////
00155 CPT(RenderAttrib) ShaderAttrib::
00156 clear_flag(int flag) const {
00157   ShaderAttrib *result = new ShaderAttrib(*this);
00158   int bit = 1<<flag;
00159   result->_flags &= ~bit;
00160   result->_has_flags &= ~bit;
00161   return return_new(result);
00162 }
00163 
00164 ////////////////////////////////////////////////////////////////////
00165 //     Function: ShaderAttrib::set_shader_input
00166 //       Access: Published
00167 //  Description: 
00168 ////////////////////////////////////////////////////////////////////
00169 CPT(RenderAttrib) ShaderAttrib::
00170 set_shader_input(const ShaderInput *input) const {
00171   ShaderAttrib *result = new ShaderAttrib(*this);
00172   Inputs::iterator i = result->_inputs.find(input->get_name());
00173   if (i == result->_inputs.end()) {
00174     result->_inputs.insert(Inputs::value_type(input->get_name(),input));
00175   } else {
00176     i->second = input;
00177   }
00178   return return_new(result);
00179 }
00180 
00181 ////////////////////////////////////////////////////////////////////
00182 //     Function: ShaderAttrib::set_shader_input
00183 //       Access: Published
00184 //  Description: 
00185 ////////////////////////////////////////////////////////////////////
00186 CPT(RenderAttrib) ShaderAttrib::
00187 set_shader_input(InternalName *id, Texture *tex, int priority) const {
00188   return set_shader_input(new ShaderInput(id, tex, priority));
00189 }
00190 
00191 ////////////////////////////////////////////////////////////////////
00192 //     Function: ShaderAttrib::set_shader_input
00193 //       Access: Published
00194 //  Description: 
00195 ////////////////////////////////////////////////////////////////////
00196 CPT(RenderAttrib) ShaderAttrib::
00197 set_shader_input(InternalName *id, const NodePath &np, int priority) const {
00198   return set_shader_input(new ShaderInput(id, np, priority));
00199 }
00200 
00201 ////////////////////////////////////////////////////////////////////
00202 //     Function: ShaderAttrib::set_shader_input
00203 //       Access: Published
00204 //  Description: 
00205 ////////////////////////////////////////////////////////////////////
00206 CPT(RenderAttrib) ShaderAttrib::
00207 set_shader_input(InternalName *id, const LVector4f &v, int priority) const {
00208   return set_shader_input(new ShaderInput(id, v, priority));
00209 }
00210 
00211 ////////////////////////////////////////////////////////////////////
00212 //     Function: ShaderAttrib::set_shader_input
00213 //       Access: Published
00214 //  Description: 
00215 ////////////////////////////////////////////////////////////////////
00216 CPT(RenderAttrib) ShaderAttrib::
00217 set_shader_input(InternalName *id, double n1, double n2, double n3, double n4, int priority) const {
00218   return set_shader_input(new ShaderInput(id, LVector4f(n1,n2,n3,n4), priority));
00219 }
00220 
00221 ////////////////////////////////////////////////////////////////////
00222 //     Function: ShaderAttrib::set_shader_input
00223 //       Access: Published
00224 //  Description: 
00225 ////////////////////////////////////////////////////////////////////
00226 CPT(RenderAttrib) ShaderAttrib::
00227 set_shader_input(const string &id, Texture *tex, int priority) const {
00228   return set_shader_input(new ShaderInput(InternalName::make(id), tex, priority));
00229 }
00230 
00231 ////////////////////////////////////////////////////////////////////
00232 //     Function: ShaderAttrib::set_shader_input
00233 //       Access: Published
00234 //  Description: 
00235 ////////////////////////////////////////////////////////////////////
00236 CPT(RenderAttrib) ShaderAttrib::
00237 set_shader_input(const string &id, const NodePath &np, int priority) const {
00238   return set_shader_input(new ShaderInput(InternalName::make(id), np, priority));
00239 }
00240 
00241 ////////////////////////////////////////////////////////////////////
00242 //     Function: ShaderAttrib::set_shader_input
00243 //       Access: Published
00244 //  Description: 
00245 ////////////////////////////////////////////////////////////////////
00246 CPT(RenderAttrib) ShaderAttrib::
00247 set_shader_input(const string &id, const LVector4f &v, int priority) const {
00248   return set_shader_input(new ShaderInput(InternalName::make(id), v, priority));
00249 }
00250 
00251 ////////////////////////////////////////////////////////////////////
00252 //     Function: ShaderAttrib::set_shader_input
00253 //       Access: Published
00254 //  Description: 
00255 ////////////////////////////////////////////////////////////////////
00256 CPT(RenderAttrib) ShaderAttrib::
00257 set_shader_input(const string &id, double n1, double n2, double n3, double n4, int priority) const {
00258   return set_shader_input(new ShaderInput(InternalName::make(id), LVector4f(n1,n2,n3,n4), priority));
00259 }
00260 
00261 ////////////////////////////////////////////////////////////////////
00262 //     Function: ShaderAttrib::set_instance_count
00263 //       Access: Published
00264 //  Description: Sets the geometry instance count. Do not confuse
00265 //               this with instanceTo, which is used for animation
00266 //               instancing, and has nothing to do with this.
00267 //               A value of 0 means not to use instancing at all.
00268 ////////////////////////////////////////////////////////////////////
00269 CPT(RenderAttrib) ShaderAttrib::
00270 set_instance_count(int instance_count) const {
00271   ShaderAttrib *result = new ShaderAttrib(*this);
00272   result->_instance_count = instance_count;
00273   return return_new(result);
00274 }
00275 
00276 ////////////////////////////////////////////////////////////////////
00277 //     Function: ShaderAttrib::clear_shader_input
00278 //       Access: Published
00279 //  Description: 
00280 ////////////////////////////////////////////////////////////////////
00281 CPT(RenderAttrib) ShaderAttrib::
00282 clear_shader_input(InternalName *id) const {
00283   ShaderAttrib *result = new ShaderAttrib(*this);
00284   result->_inputs.erase(id);
00285   return return_new(result);
00286 }
00287 
00288 ////////////////////////////////////////////////////////////////////
00289 //     Function: ShaderAttrib::clear_shader_input
00290 //       Access: Published
00291 //  Description: 
00292 ////////////////////////////////////////////////////////////////////
00293 CPT(RenderAttrib) ShaderAttrib::
00294 clear_shader_input(const string &id) const {
00295   return clear_shader_input(InternalName::make(id));
00296 }
00297 
00298 ////////////////////////////////////////////////////////////////////
00299 //     Function: ShaderAttrib::clear_all_shader_inputs
00300 //       Access: Published
00301 //  Description: Clears all the shader inputs on the attrib.
00302 ////////////////////////////////////////////////////////////////////
00303 CPT(RenderAttrib) ShaderAttrib::
00304 clear_all_shader_inputs() const {
00305   ShaderAttrib *result = new ShaderAttrib(*this);
00306   result->_inputs.clear();
00307   return return_new(result);
00308 }
00309 
00310 ////////////////////////////////////////////////////////////////////
00311 //     Function: ShaderAttrib::get_shader_input
00312 //       Access: Published
00313 //  Description: Returns the ShaderInput of the given name.  If
00314 //               no such name is found, this function does not return
00315 //               NULL --- it returns the "blank" ShaderInput.
00316 ////////////////////////////////////////////////////////////////////
00317 const ShaderInput *ShaderAttrib::
00318 get_shader_input(InternalName *id) const {
00319   Inputs::const_iterator i = _inputs.find(id);
00320   if (i == _inputs.end()) {
00321     return ShaderInput::get_blank();
00322   } else {
00323     return (*i).second;
00324   }
00325 }
00326 
00327 ////////////////////////////////////////////////////////////////////
00328 //     Function: ShaderAttrib::get_shader_input
00329 //       Access: Published
00330 //  Description: Returns the ShaderInput of the given name.  If
00331 //               no such name is found, this function does not return
00332 //               NULL --- it returns the "blank" ShaderInput.
00333 ////////////////////////////////////////////////////////////////////
00334 const ShaderInput *ShaderAttrib::
00335 get_shader_input(const string &id) const {
00336   return get_shader_input(InternalName::make(id));
00337 }
00338 
00339 ////////////////////////////////////////////////////////////////////
00340 //     Function: ShaderAttrib::get_shader_input_nodepath
00341 //       Access: Published
00342 //  Description: Returns the ShaderInput as a nodepath.  Assertion 
00343 //               fails if there is none, or if it is not a nodepath.
00344 ////////////////////////////////////////////////////////////////////
00345 const NodePath &ShaderAttrib::
00346 get_shader_input_nodepath(InternalName *id) const {
00347   static NodePath resfail;
00348   Inputs::const_iterator i = _inputs.find(id);
00349   if (i == _inputs.end()) {
00350     ostringstream strm;
00351     strm << "Shader input " << id->get_name() << " is not present.\n";
00352     nassert_raise(strm.str());
00353     return resfail;
00354   } else {
00355     const ShaderInput *p = (*i).second;
00356     if (p->get_value_type() != ShaderInput::M_nodepath) {
00357       ostringstream strm;
00358       strm << "Shader input " << id->get_name() << " is not a nodepath.\n";
00359       nassert_raise(strm.str());
00360       return resfail;
00361     }
00362     return p->get_nodepath();
00363   }
00364 
00365   // Satisfy compiler.
00366   return resfail;
00367 }
00368 
00369 ////////////////////////////////////////////////////////////////////
00370 //     Function: ShaderAttrib::get_shader_input_vector
00371 //       Access: Published
00372 //  Description: Returns the ShaderInput as a vector.  Assertion 
00373 //               fails if there is none, or if it is not a vector.
00374 ////////////////////////////////////////////////////////////////////
00375 const LVector4f &ShaderAttrib::
00376 get_shader_input_vector(InternalName *id) const {
00377   static LVector4f resfail(0,0,0,0);
00378   Inputs::const_iterator i = _inputs.find(id);
00379   if (i == _inputs.end()) {
00380     ostringstream strm;
00381     strm << "Shader input " << id->get_name() << " is not present.\n";
00382     nassert_raise(strm.str());
00383     return resfail;
00384   } else {
00385     const ShaderInput *p = (*i).second;
00386     if (p->get_value_type() != ShaderInput::M_vector) {
00387       ostringstream strm;
00388       strm << "Shader input " << id->get_name() << " is not a vector.\n";
00389       nassert_raise(strm.str());
00390       return resfail;
00391     }
00392     return p->get_vector();
00393   }
00394 }
00395 
00396 ////////////////////////////////////////////////////////////////////
00397 //     Function: ShaderAttrib::get_shader_input_texture
00398 //       Access: Published
00399 //  Description: Returns the ShaderInput as a texture.  Assertion 
00400 //               fails if there is none, or if it is not a texture.
00401 ////////////////////////////////////////////////////////////////////
00402 Texture *ShaderAttrib::
00403 get_shader_input_texture(InternalName *id) const {
00404   Inputs::const_iterator i = _inputs.find(id);
00405   if (i == _inputs.end()) {
00406     ostringstream strm;
00407     strm << "Shader input " << id->get_name() << " is not present.\n";
00408     nassert_raise(strm.str());
00409     return NULL;
00410   } else {
00411     const ShaderInput *p = (*i).second;
00412     if (p->get_value_type() != ShaderInput::M_texture) {
00413       ostringstream strm;
00414       strm <<  "Shader input " << id->get_name() << " is not a texture.\n";
00415       nassert_raise(strm.str());
00416       return NULL;
00417     }
00418     return p->get_texture();
00419   }
00420 }
00421 
00422 ////////////////////////////////////////////////////////////////////
00423 //     Function: ShaderAttrib::get_shader
00424 //       Access: Published
00425 //  Description: Returns the shader object associated with the node.
00426 //               If get_override returns true, but get_shader 
00427 //               returns NULL, that means that this attribute should
00428 //               disable the shader.
00429 ////////////////////////////////////////////////////////////////////
00430 const Shader *ShaderAttrib::
00431 get_shader() const {
00432   return _shader;
00433 }
00434 
00435 ////////////////////////////////////////////////////////////////////
00436 //     Function: ShaderAttrib::compare_to_impl
00437 //       Access: Protected, Virtual
00438 //  Description: Intended to be overridden by derived ShaderAttrib
00439 //               types to return a unique number indicating whether
00440 //               this ShaderAttrib is equivalent to the other one.
00441 //
00442 //               This should return 0 if the two ShaderAttrib objects
00443 //               are equivalent, a number less than zero if this one
00444 //               should be sorted before the other one, and a number
00445 //               greater than zero otherwise.
00446 //
00447 //               This will only be called with two ShaderAttrib
00448 //               objects whose get_type() functions return the same.
00449 ////////////////////////////////////////////////////////////////////
00450 int ShaderAttrib::
00451 compare_to_impl(const RenderAttrib *other) const {
00452   const ShaderAttrib *that;
00453   DCAST_INTO_R(that, other, 0);
00454   
00455   if (this->_shader != that->_shader) {
00456     return (this->_shader < that->_shader) ? -1 : 1;
00457   }
00458   if (this->_shader_priority != that->_shader_priority) {
00459     return (this->_shader_priority < that->_shader_priority) ? -1 : 1;
00460   }
00461   if (this->_auto_shader != that->_auto_shader) {
00462     return (this->_auto_shader < that->_auto_shader) ? -1 : 1;
00463   }
00464   if (this->_has_shader != that->_has_shader) {
00465     return (this->_has_shader < that->_has_shader) ? -1 : 1;
00466   }
00467   if (this->_flags != that->_flags) {
00468     return (this->_flags < that->_flags) ? -1 : 1;
00469   }
00470   if (this->_has_flags != that->_has_flags) {
00471     return (this->_has_flags < that->_has_flags) ? -1 : 1;
00472   }
00473   if (this->_instance_count != that->_instance_count) {
00474     return (this->_instance_count < that->_instance_count) ? -1 : 1;
00475   }
00476   
00477   Inputs::const_iterator i1 = this->_inputs.begin();
00478   Inputs::const_iterator i2 = that->_inputs.begin();
00479   while ((i1 != this->_inputs.end()) && (i2 != that->_inputs.end())) {
00480     if (i1->second != i2->second) {
00481       return (i1->second < i2->second) ? -1 : 1;
00482     }
00483     ++i1;
00484     ++i2;
00485   }
00486   if (i1 != this->_inputs.end()) {
00487     return 1;
00488   }
00489   if (i2 != that->_inputs.end()) {
00490     return -1;
00491   }
00492   
00493   return 0;
00494 }
00495 
00496 ////////////////////////////////////////////////////////////////////
00497 //     Function: ShaderAttrib::compose_impl
00498 //       Access: Public, Virtual
00499 //  Description:
00500 ////////////////////////////////////////////////////////////////////
00501 CPT(RenderAttrib) ShaderAttrib::
00502 compose_impl(const RenderAttrib *other) const {
00503   ShaderAttrib *attr = new ShaderAttrib(*this);
00504   const ShaderAttrib *over;
00505   DCAST_INTO_R(over, other, 0);
00506   // Update the shader portion.
00507   if (over->_has_shader) {
00508     if ((attr->_has_shader == false) ||
00509         (over->_shader_priority >= attr->_shader_priority)) {
00510       attr->_shader = over->_shader;
00511       attr->_shader_priority = over->_shader_priority;
00512       attr->_auto_shader = over->_auto_shader;
00513       attr->_has_shader = over->_has_shader;
00514     }
00515   }
00516   // Update the shader-data portion.
00517   Inputs::const_iterator iover;
00518   for (iover=over->_inputs.begin(); iover!=over->_inputs.end(); ++iover) {
00519     const InternalName *id = (*iover).first;
00520     const ShaderInput *dover = (*iover).second;
00521     Inputs::iterator iattr = attr->_inputs.find(id);
00522     if (iattr == attr->_inputs.end()) {
00523       attr->_inputs.insert(Inputs::value_type(id,dover));
00524     } else {
00525       const ShaderInput *dattr = (*iattr).second;
00526       if (dattr->get_priority() <= dover->get_priority()) {
00527         iattr->second = iover->second;
00528       }
00529     }
00530   }
00531   // Just copy the instance count.
00532   attr->_instance_count = over->_instance_count;
00533   // Update the flags.
00534   attr->_flags &= ~(over->_has_flags);
00535   attr->_flags |= over->_flags;
00536   attr->_has_flags |= (over->_has_flags);
00537   return return_new(attr);
00538 }
00539 
00540 ////////////////////////////////////////////////////////////////////
00541 //     Function: ShaderAttrib::register_with_read_factory
00542 //       Access: Public, Static
00543 //  Description: Factory method to generate a Shader object
00544 ////////////////////////////////////////////////////////////////////
00545 void ShaderAttrib::
00546 register_with_read_factory() {
00547   // IMPLEMENT ME
00548 }
00549 
 All Classes Functions Variables Enumerations