Panda3D
 All Classes Functions Variables Enumerations
texGenAttrib.cxx
00001 // Filename: texGenAttrib.cxx
00002 // Created by:  masad (21Jun04)
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 "texGenAttrib.h"
00016 #include "texturePool.h"
00017 #include "graphicsStateGuardianBase.h"
00018 #include "bamReader.h"
00019 #include "bamWriter.h"
00020 #include "datagram.h"
00021 #include "datagramIterator.h"
00022 #include "dcast.h"
00023 
00024 CPT(RenderAttrib) TexGenAttrib::_empty_attrib;
00025 TypeHandle TexGenAttrib::_type_handle;
00026 int TexGenAttrib::_attrib_slot;
00027 
00028 ////////////////////////////////////////////////////////////////////
00029 //     Function: TexGenAttrib::Destructor
00030 //       Access: Public, Virtual
00031 //  Description: 
00032 ////////////////////////////////////////////////////////////////////
00033 TexGenAttrib::
00034 ~TexGenAttrib() {
00035 }
00036 
00037 ////////////////////////////////////////////////////////////////////
00038 //     Function: TexGenAttrib::make
00039 //       Access: Published, Static
00040 //  Description: Constructs a TexGenAttrib that generates no stages at
00041 //               all.
00042 ////////////////////////////////////////////////////////////////////
00043 CPT(RenderAttrib) TexGenAttrib::
00044 make() {
00045   // We make it a special case and store a pointer to the empty attrib
00046   // forever once we find it the first time, as an optimization.
00047   if (_empty_attrib == (RenderAttrib *)NULL) {
00048     _empty_attrib = return_new(new TexGenAttrib);
00049   }
00050 
00051   return _empty_attrib;
00052 }
00053 
00054 ////////////////////////////////////////////////////////////////////
00055 //     Function: TexGenAttrib::make
00056 //       Access: Published, Static
00057 //  Description: Constructs a TexGenAttrib that generates just the
00058 //               indicated stage.
00059 ////////////////////////////////////////////////////////////////////
00060 CPT(RenderAttrib) TexGenAttrib::
00061 make(TextureStage *stage, TexGenAttrib::Mode mode) {
00062   return DCAST(TexGenAttrib, make())->add_stage(stage, mode);
00063 }
00064 
00065 ////////////////////////////////////////////////////////////////////
00066 //     Function: TexGenAttrib::make_default
00067 //       Access: Published, Static
00068 //  Description: Returns a RenderAttrib that corresponds to whatever
00069 //               the standard default properties for render attributes
00070 //               of this type ought to be.
00071 ////////////////////////////////////////////////////////////////////
00072 CPT(RenderAttrib) TexGenAttrib::
00073 make_default() {
00074   return return_new(new TexGenAttrib);
00075 }
00076 
00077 ////////////////////////////////////////////////////////////////////
00078 //     Function: TexGenAttrib::add_stage
00079 //       Access: Published, Static
00080 //  Description: Returns a new TexGenAttrib just like this one,
00081 //               with the indicated generation mode for the given
00082 //               stage.  If this stage already exists, its mode is
00083 //               replaced.
00084 ////////////////////////////////////////////////////////////////////
00085 CPT(RenderAttrib) TexGenAttrib::
00086 add_stage(TextureStage *stage, TexGenAttrib::Mode mode) const {
00087   nassertr(mode != M_light_vector && mode != M_constant, this);
00088 
00089   CPT(RenderAttrib) removed = remove_stage(stage);
00090   TexGenAttrib *attrib = new TexGenAttrib(*DCAST(TexGenAttrib, removed));
00091 
00092   ModeDef &mode_def = attrib->_stages[stage];
00093   mode_def._mode = mode;
00094   attrib->record_stage(stage, mode_def);
00095 
00096   return return_new(attrib);
00097 }
00098 
00099 ////////////////////////////////////////////////////////////////////
00100 //     Function: TexGenAttrib::add_stage
00101 //       Access: Published, Static
00102 //  Description: Returns a new TexGenAttrib just like this one,
00103 //               with the indicated generation mode for the given
00104 //               stage.  If this stage already exists, its mode is
00105 //               replaced.
00106 //
00107 //               This variant also accepts source_name and light,
00108 //               which are only meaningful if mode is M_light_vector.
00109 ////////////////////////////////////////////////////////////////////
00110 CPT(RenderAttrib) TexGenAttrib::
00111 add_stage(TextureStage *stage, TexGenAttrib::Mode mode, 
00112           const string &source_name, const NodePath &light) const {
00113   nassertr(mode == M_light_vector, this);
00114 
00115   CPT(RenderAttrib) removed = remove_stage(stage);
00116   TexGenAttrib *attrib = new TexGenAttrib(*DCAST(TexGenAttrib, removed));
00117 
00118   ModeDef &mode_def = attrib->_stages[stage];
00119   mode_def._mode = mode;
00120   mode_def._source_name = source_name;
00121   mode_def._light = light;
00122   attrib->record_stage(stage, mode_def);
00123 
00124   return return_new(attrib);
00125 }
00126 
00127 ////////////////////////////////////////////////////////////////////
00128 //     Function: TexGenAttrib::add_stage
00129 //       Access: Published, Static
00130 //  Description: Returns a new TexGenAttrib just like this one,
00131 //               with the indicated generation mode for the given
00132 //               stage.  If this stage already exists, its mode is
00133 //               replaced.
00134 //
00135 //               This variant also accepts constant_value, which is
00136 //               only meaningful if mode is M_constant.
00137 ////////////////////////////////////////////////////////////////////
00138 CPT(RenderAttrib) TexGenAttrib::
00139 add_stage(TextureStage *stage, TexGenAttrib::Mode mode, 
00140           const LTexCoord3 &constant_value) const {
00141   nassertr(mode == M_constant, this);
00142 
00143   CPT(RenderAttrib) removed = remove_stage(stage);
00144   TexGenAttrib *attrib = new TexGenAttrib(*DCAST(TexGenAttrib, removed));
00145 
00146   ModeDef &mode_def = attrib->_stages[stage];
00147   mode_def._mode = mode;
00148   mode_def._constant_value = constant_value;
00149   attrib->record_stage(stage, mode_def);
00150 
00151   return return_new(attrib);
00152 }
00153 
00154 ////////////////////////////////////////////////////////////////////
00155 //     Function: TexGenAttrib::remove_stage
00156 //       Access: Published, Static
00157 //  Description: Returns a new TexGenAttrib just like this one,
00158 //               with the indicated stage removed.
00159 ////////////////////////////////////////////////////////////////////
00160 CPT(RenderAttrib) TexGenAttrib::
00161 remove_stage(TextureStage *stage) const {
00162   Stages::const_iterator si;
00163   si = _stages.find(stage);
00164   if (si == _stages.end()) {
00165     return this;
00166   }
00167 
00168   Mode mode = (*si).second._mode;
00169   TexGenAttrib *attrib = new TexGenAttrib(*this);
00170   attrib->_stages.erase(stage);
00171   attrib->_no_texcoords.erase(stage);
00172   if (mode == M_point_sprite) {
00173     attrib->_num_point_sprites--;
00174     if (attrib->_num_point_sprites == 0) {
00175       attrib->_point_geom_rendering &= ~Geom::GR_point_sprite;
00176     }
00177   } else if (mode == M_light_vector) {
00178     attrib->_light_vectors.erase(stage);
00179     attrib->_num_light_vectors--;
00180     if (attrib->_num_light_vectors == 0) {
00181       attrib->_geom_rendering &= ~Geom::GR_texcoord_light_vector;
00182     }
00183   }
00184   return return_new(attrib);
00185 }
00186 
00187 ////////////////////////////////////////////////////////////////////
00188 //     Function: TexGenAttrib::is_empty
00189 //       Access: Published
00190 //  Description: Returns true if no stages are defined in the
00191 //               TexGenAttrib, false if at least one is.
00192 ////////////////////////////////////////////////////////////////////
00193 bool TexGenAttrib::
00194 is_empty() const {
00195   return _stages.empty();
00196 }
00197 
00198 ////////////////////////////////////////////////////////////////////
00199 //     Function: TexGenAttrib::has_stage
00200 //       Access: Published
00201 //  Description: Returns true if there is a mode associated with
00202 //               the indicated stage, or false otherwise (in which
00203 //               case get_transform(stage) will return M_off).
00204 ////////////////////////////////////////////////////////////////////
00205 bool TexGenAttrib::
00206 has_stage(TextureStage *stage) const {
00207   Stages::const_iterator mi = _stages.find(stage);
00208   return (mi != _stages.end());
00209 }
00210 
00211 ////////////////////////////////////////////////////////////////////
00212 //     Function: TexGenAttrib::get_mode
00213 //       Access: Published
00214 //  Description: Returns the generation mode associated with
00215 //               the named texture stage, or M_off if
00216 //               nothing is associated with the indicated stage.
00217 ////////////////////////////////////////////////////////////////////
00218 TexGenAttrib::Mode TexGenAttrib::
00219 get_mode(TextureStage *stage) const {
00220   Stages::const_iterator mi = _stages.find(stage);
00221   if (mi != _stages.end()) {
00222     return (*mi).second._mode;
00223   }
00224   return M_off;
00225 }
00226 
00227 ////////////////////////////////////////////////////////////////////
00228 //     Function: TexGenAttrib::has_gen_texcoord_stage
00229 //       Access: Published
00230 //  Description: Returns true if the indicated TextureStage will have
00231 //               texture coordinates generated for it automatically
00232 //               (and thus there is no need to upload the texture
00233 //               coordinates encoded in the vertices).
00234 ////////////////////////////////////////////////////////////////////
00235 bool TexGenAttrib::
00236 has_gen_texcoord_stage(TextureStage *stage) const {
00237   NoTexCoordStages::const_iterator mi = _no_texcoords.find(stage);
00238   return (mi != _no_texcoords.end());
00239 }
00240 
00241 ////////////////////////////////////////////////////////////////////
00242 //     Function: TexGenAttrib::get_source_name
00243 //       Access: Published
00244 //  Description: Returns the source name associated with the named
00245 //               texture stage, or the empty string if no name is
00246 //               associated with the indicated stage.  This is only
00247 //               meaningful if the mode is M_light_vector, in which
00248 //               case it indicates the name of the source texture
00249 //               coordinate set from which the tangent and binormal
00250 //               are derived.
00251 ////////////////////////////////////////////////////////////////////
00252 string TexGenAttrib::
00253 get_source_name(TextureStage *stage) const {
00254   Stages::const_iterator mi = _stages.find(stage);
00255   if (mi != _stages.end()) {
00256     return (*mi).second._source_name;
00257   }
00258   return string();
00259 }
00260 
00261 ////////////////////////////////////////////////////////////////////
00262 //     Function: TexGenAttrib::get_light
00263 //       Access: Published
00264 //  Description: Returns the Light associated with the named texture
00265 //               stage, or the empty NodePath if no light is
00266 //               associated with the indicated stage.  This is only
00267 //               meaningful if the mode is M_light_vector.
00268 ////////////////////////////////////////////////////////////////////
00269 NodePath TexGenAttrib::
00270 get_light(TextureStage *stage) const {
00271   Stages::const_iterator mi = _stages.find(stage);
00272   if (mi != _stages.end()) {
00273     return (*mi).second._light;
00274   }
00275   return NodePath();
00276 }
00277 
00278 ////////////////////////////////////////////////////////////////////
00279 //     Function: TexGenAttrib::get_constant_value
00280 //       Access: Published
00281 //  Description: Returns the constant value associated with the named
00282 //               texture stage.  This is only meaningful if the mode
00283 //               is M_constant.
00284 ////////////////////////////////////////////////////////////////////
00285 const LTexCoord3 &TexGenAttrib::
00286 get_constant_value(TextureStage *stage) const {
00287   Stages::const_iterator mi = _stages.find(stage);
00288   if (mi != _stages.end()) {
00289     return (*mi).second._constant_value;
00290   }
00291   return LTexCoord3::zero();
00292 }
00293 
00294 ////////////////////////////////////////////////////////////////////
00295 //     Function: TexGenAttrib::output
00296 //       Access: Public, Virtual
00297 //  Description: 
00298 ////////////////////////////////////////////////////////////////////
00299 void TexGenAttrib::
00300 output(ostream &out) const {
00301   out << get_type() << ":";
00302 
00303   Stages::const_iterator mi;
00304   for (mi = _stages.begin(); mi != _stages.end(); ++mi) {
00305     TextureStage *stage = (*mi).first;
00306     const ModeDef &mode_def = (*mi).second;
00307     out << " " << stage->get_name() << "(";
00308     switch (mode_def._mode) {
00309     case M_off:
00310       out << "off";
00311       break;
00312 
00313     case M_eye_sphere_map:
00314       out << "eye_sphere_map";
00315       break;
00316 
00317     case M_world_cube_map:
00318       out << "world_cube_map";
00319       break;
00320     case M_eye_cube_map:
00321       out << "eye_cube_map";
00322       break;
00323 
00324     case M_world_normal:
00325       out << "world_normal";
00326       break;
00327     case M_eye_normal:
00328       out << "eye_normal";
00329       break;
00330 
00331     case M_world_position:
00332       out << "world_position";
00333       break;
00334     case M_eye_position:
00335       out << "eye_position";
00336       break;
00337 
00338     case M_point_sprite:
00339       out << "point_sprite";
00340       break;
00341 
00342     case M_light_vector:
00343       out << "light_vector: \"" << mode_def._source_name << "\", "
00344           << mode_def._light;
00345       break;
00346 
00347     case M_constant:
00348       out << "constant: " << mode_def._constant_value;
00349       break;
00350 
00351     case M_unused:
00352       break;
00353     }
00354     out << ")";
00355   }
00356 }
00357 
00358 ////////////////////////////////////////////////////////////////////
00359 //     Function: TexGenAttrib::compare_to_impl
00360 //       Access: Protected, Virtual
00361 //  Description: Intended to be overridden by derived TexGenAttrib
00362 //               types to return a unique number indicating whether
00363 //               this TexGenAttrib is equivalent to the other one.
00364 //
00365 //               This should return 0 if the two TexGenAttrib objects
00366 //               are equivalent, a number less than zero if this one
00367 //               should be sorted before the other one, and a number
00368 //               greater than zero otherwise.
00369 //
00370 //               This will only be called with two TexGenAttrib
00371 //               objects whose get_type() functions return the same.
00372 ////////////////////////////////////////////////////////////////////
00373 int TexGenAttrib::
00374 compare_to_impl(const RenderAttrib *other) const {
00375   const TexGenAttrib *ta;
00376   DCAST_INTO_R(ta, other, 0);
00377   
00378   Stages::const_iterator ai, bi;
00379   ai = _stages.begin();
00380   bi = ta->_stages.begin();
00381   while (ai != _stages.end() && bi != ta->_stages.end()) {
00382     if ((*ai).first < (*bi).first) {
00383       // This stage is in a but not in b.
00384       return -1;
00385 
00386     } else if ((*bi).first < (*ai).first) {
00387       // This stage is in b but not in a.
00388       return 1;
00389 
00390     } else {
00391       // This stage is in both; compare the stages.
00392       int compare = (*ai).second.compare_to((*bi).second);
00393       if (compare != 0) {
00394         return compare;
00395       }
00396       ++ai;
00397       ++bi;
00398     }
00399   }
00400 
00401   if (bi != ta->_stages.end()) {
00402     // a ran out first; b was longer.
00403     return -1;
00404   }
00405 
00406   if (ai != _stages.end()) {
00407     // b ran out first; a was longer.
00408     return 1;
00409   }
00410 
00411   return 0;
00412 }
00413 
00414 ////////////////////////////////////////////////////////////////////
00415 //     Function: TexGenAttrib::get_hash_impl
00416 //       Access: Protected, Virtual
00417 //  Description: Intended to be overridden by derived RenderAttrib
00418 //               types to return a unique hash for these particular
00419 //               properties.  RenderAttribs that compare the same with
00420 //               compare_to_impl(), above, should return the same
00421 //               hash; RenderAttribs that compare differently should
00422 //               return a different hash.
00423 ////////////////////////////////////////////////////////////////////
00424 size_t TexGenAttrib::
00425 get_hash_impl() const {
00426   size_t hash = 0;
00427   Stages::const_iterator ri;
00428   for (ri = _stages.begin(); ri != _stages.end(); ++ri) {
00429     const TextureStage *stage = (*ri).first;
00430     const ModeDef &mode_def = (*ri).second;
00431 
00432     hash = pointer_hash::add_hash(hash, stage);
00433     hash = int_hash::add_hash(hash, (int)mode_def._mode);
00434     hash = string_hash::add_hash(hash, mode_def._source_name);
00435     hash = mode_def._light.add_hash(hash);
00436     hash = mode_def._constant_value.add_hash(hash);
00437   }
00438 
00439   return hash;
00440 }
00441 
00442 ////////////////////////////////////////////////////////////////////
00443 //     Function: TexGenAttrib::compose_impl
00444 //       Access: Protected, Virtual
00445 //  Description: Intended to be overridden by derived RenderAttrib
00446 //               types to specify how two consecutive RenderAttrib
00447 //               objects of the same type interact.
00448 //
00449 //               This should return the result of applying the other
00450 //               RenderAttrib to a node in the scene graph below this
00451 //               RenderAttrib, which was already applied.  In most
00452 //               cases, the result is the same as the other
00453 //               RenderAttrib (that is, a subsequent RenderAttrib
00454 //               completely replaces the preceding one).  On the other
00455 //               hand, some kinds of RenderAttrib (for instance,
00456 //               ColorTransformAttrib) might combine in meaningful
00457 //               ways.
00458 ////////////////////////////////////////////////////////////////////
00459 CPT(RenderAttrib) TexGenAttrib::
00460 compose_impl(const RenderAttrib *other) const {
00461   const TexGenAttrib *ta;
00462   DCAST_INTO_R(ta, other, 0);
00463 
00464   // The composition is the union of the two attribs.  In the case
00465   // when a stage is in both attribs, we compose the stages.
00466 
00467   TexGenAttrib *attrib = new TexGenAttrib;
00468 
00469   Stages::const_iterator ai, bi;
00470   ai = _stages.begin();
00471   bi = ta->_stages.begin();
00472   while (ai != _stages.end() && bi != ta->_stages.end()) {
00473     if ((*ai).first < (*bi).first) {
00474       // This stage is in a but not in b.
00475       attrib->_stages.insert(attrib->_stages.end(), *ai);
00476       ++ai;
00477 
00478     } else if ((*bi).first < (*ai).first) {
00479       // This stage is in b but not in a.
00480       attrib->_stages.insert(attrib->_stages.end(), *bi);
00481       ++bi;
00482 
00483     } else {
00484       // This stage is in both; b wins.
00485       attrib->_stages.insert(attrib->_stages.end(), *bi);
00486       ++bi;
00487       ++ai;
00488     }
00489   }
00490 
00491   while (ai != _stages.end()) {
00492     // This stage is in a but not in b.
00493     attrib->_stages.insert(attrib->_stages.end(), *ai);
00494     ++ai;
00495   }
00496 
00497   while (bi != ta->_stages.end()) {
00498     // This stage is in b but not in a.
00499     attrib->_stages.insert(attrib->_stages.end(), *bi);
00500     ++bi;
00501   }
00502 
00503   attrib->filled_stages();
00504 
00505   return return_new(attrib);
00506 }
00507 
00508 ////////////////////////////////////////////////////////////////////
00509 //     Function: TexGenAttrib::invert_compose_impl
00510 //       Access: Protected, Virtual
00511 //  Description: Intended to be overridden by derived RenderAttrib
00512 //               types to specify how two consecutive RenderAttrib
00513 //               objects of the same type interact.
00514 //
00515 //               See invert_compose() and compose_impl().
00516 ////////////////////////////////////////////////////////////////////
00517 CPT(RenderAttrib) TexGenAttrib::
00518 invert_compose_impl(const RenderAttrib *other) const {
00519   const TexGenAttrib *ta;
00520   DCAST_INTO_R(ta, other, 0);
00521 
00522   // The inverse composition works a lot like the composition, except
00523   // we invert the ai stages.
00524 
00525   TexGenAttrib *attrib = new TexGenAttrib;
00526 
00527   Stages::const_iterator ai, bi;
00528   ai = _stages.begin();
00529   bi = ta->_stages.begin();
00530   while (ai != _stages.end() && bi != ta->_stages.end()) {
00531     if ((*ai).first < (*bi).first) {
00532       // This stage is in a but not in b.  Turn a off.
00533       attrib->_stages.insert(attrib->_stages.end(), Stages::value_type((*ai).first, ModeDef()));
00534       ++ai;
00535 
00536     } else if ((*bi).first < (*ai).first) {
00537       // This stage is in b but not in a.
00538       attrib->_stages.insert(attrib->_stages.end(), *bi);
00539       ++bi;
00540 
00541     } else {
00542       // This stage is in both; b wins.
00543       attrib->_stages.insert(attrib->_stages.end(), *bi);
00544       ++bi;
00545       ++ai;
00546     }
00547   }
00548 
00549   while (ai != _stages.end()) {
00550     // This stage is in a but not in b.
00551     attrib->_stages.insert(attrib->_stages.end(), Stages::value_type((*ai).first, ModeDef()));
00552     ++ai;
00553   }
00554 
00555   while (bi != ta->_stages.end()) {
00556     // This stage is in b but not in a.
00557     attrib->_stages.insert(attrib->_stages.end(), *bi);
00558     ++bi;
00559   }
00560 
00561   attrib->filled_stages();
00562 
00563   return return_new(attrib);
00564 }
00565 
00566 ////////////////////////////////////////////////////////////////////
00567 //     Function: TexGenAttrib::get_auto_shader_attrib_impl
00568 //       Access: Protected, Virtual
00569 //  Description: 
00570 ////////////////////////////////////////////////////////////////////
00571 CPT(RenderAttrib) TexGenAttrib::
00572 get_auto_shader_attrib_impl(const RenderState *state) const {
00573   return this;
00574 }
00575 
00576 ////////////////////////////////////////////////////////////////////
00577 //     Function: TexGenAttrib::filled_stages
00578 //       Access: Private
00579 //  Description: This method is to be called after the _stages map has
00580 //               been built up internally through some artificial
00581 //               means; it copies the appropriate settings to
00582 //               _no_texcoords and updates other internal cache values
00583 //               appropriately.
00584 ////////////////////////////////////////////////////////////////////
00585 void TexGenAttrib::
00586 filled_stages() {
00587   Stages::iterator ri;
00588   for (ri = _stages.begin(); ri != _stages.end(); ++ri) {
00589     TextureStage *stage = (*ri).first;
00590     ModeDef &mode_def = (*ri).second;
00591     record_stage(stage, mode_def);
00592   }
00593 }
00594 
00595 ////////////////////////////////////////////////////////////////////
00596 //     Function: TexGenAttrib::record_stage
00597 //       Access: Private
00598 //  Description: Updates the appropriate internal caches before adding
00599 //               the indicated stage with the given mode to the
00600 //               _stages map.
00601 ////////////////////////////////////////////////////////////////////
00602 void TexGenAttrib::
00603 record_stage(TextureStage *stage, TexGenAttrib::ModeDef &mode_def) {
00604   switch (mode_def._mode) {
00605   case M_point_sprite:
00606     _no_texcoords.insert(stage);
00607     _point_geom_rendering |= Geom::GR_point_sprite;
00608     _num_point_sprites++;
00609     break;
00610 
00611   case M_light_vector:
00612     {
00613       if (!mode_def._light.is_empty()) {
00614         Light *light_obj = mode_def._light.node()->as_light();
00615         if (light_obj == (Light *)NULL) {
00616 #ifndef NDEBUG
00617           ostringstream strm;
00618           strm << "Not a light: " << mode_def._light;
00619           nassert_raise(strm.str());
00620 #endif
00621           mode_def._light = NodePath();
00622         }
00623       }
00624 
00625       _light_vectors.insert(stage);
00626       _geom_rendering |= Geom::GR_texcoord_light_vector;
00627       _num_light_vectors++;
00628     }
00629     break;
00630 
00631   case M_off:
00632     break;
00633 
00634   default:
00635     _no_texcoords.insert(stage);
00636   }
00637 }
00638 
00639 ////////////////////////////////////////////////////////////////////
00640 //     Function: TexGenAttrib::register_with_read_factory
00641 //       Access: Public, Static
00642 //  Description: Tells the BamReader how to create objects of type
00643 //               TexGenAttrib.
00644 ////////////////////////////////////////////////////////////////////
00645 void TexGenAttrib::
00646 register_with_read_factory() {
00647   BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
00648 }
00649 
00650 ////////////////////////////////////////////////////////////////////
00651 //     Function: TexGenAttrib::write_datagram
00652 //       Access: Public, Virtual
00653 //  Description: Writes the contents of this object to the datagram
00654 //               for shipping out to a Bam file.
00655 ////////////////////////////////////////////////////////////////////
00656 void TexGenAttrib::
00657 write_datagram(BamWriter *manager, Datagram &dg) {
00658   RenderAttrib::write_datagram(manager, dg);
00659 
00660   dg.add_uint16(_stages.size());
00661 
00662   Stages::const_iterator si;
00663   for (si = _stages.begin(); si != _stages.end(); ++si) {
00664     TextureStage *stage = (*si).first;
00665     Mode mode = (*si).second._mode;
00666 
00667     manager->write_pointer(dg, stage);
00668     dg.add_uint8((unsigned int)mode);
00669   }
00670 }
00671 
00672 ////////////////////////////////////////////////////////////////////
00673 //     Function: TexGenAttrib::complete_pointers
00674 //       Access: Public, Virtual
00675 //  Description: Receives an array of pointers, one for each time
00676 //               manager->read_pointer() was called in fillin().
00677 //               Returns the number of pointers processed.
00678 ////////////////////////////////////////////////////////////////////
00679 int TexGenAttrib::
00680 complete_pointers(TypedWritable **p_list, BamReader *manager) {
00681   int pi = RenderAttrib::complete_pointers(p_list, manager);
00682 
00683   pvector<Mode>::const_iterator mi;
00684   for (mi = _read_modes.begin(); mi != _read_modes.end(); ++mi) {
00685     Mode mode = (*mi);
00686 
00687     TextureStage *stage = DCAST(TextureStage, p_list[pi++]);
00688     _stages[stage]._mode = mode;
00689   }
00690 
00691   filled_stages();
00692 
00693   return pi;
00694 }
00695 
00696 ////////////////////////////////////////////////////////////////////
00697 //     Function: TexGenAttrib::make_from_bam
00698 //       Access: Protected, Static
00699 //  Description: This function is called by the BamReader's factory
00700 //               when a new object of type TexGenAttrib is encountered
00701 //               in the Bam file.  It should create the TexGenAttrib
00702 //               and extract its information from the file.
00703 ////////////////////////////////////////////////////////////////////
00704 TypedWritable *TexGenAttrib::
00705 make_from_bam(const FactoryParams &params) {
00706   TexGenAttrib *attrib = new TexGenAttrib;
00707   DatagramIterator scan;
00708   BamReader *manager;
00709 
00710   parse_params(params, scan, manager);
00711   attrib->fillin(scan, manager);
00712 
00713   return attrib;
00714 }
00715 
00716 ////////////////////////////////////////////////////////////////////
00717 //     Function: TexGenAttrib::fillin
00718 //       Access: Protected
00719 //  Description: This internal function is called by make_from_bam to
00720 //               read in all of the relevant data from the BamFile for
00721 //               the new TexGenAttrib.
00722 ////////////////////////////////////////////////////////////////////
00723 void TexGenAttrib::
00724 fillin(DatagramIterator &scan, BamReader *manager) {
00725   RenderAttrib::fillin(scan, manager);
00726 
00727   size_t num_stages = scan.get_uint16();
00728 
00729   // For now, read in a linear list of the modes we will assign to
00730   // each associated TextureStage pointer.  Later, in
00731   // complete_pointers, we'll fill up the map the with appropriate
00732   // TextureStage/Mode pairing.
00733   _read_modes.clear();
00734   _read_modes.reserve(num_stages);
00735   for (size_t i = 0; i < num_stages; i++) {
00736     manager->read_pointer(scan);
00737     Mode mode = (Mode)scan.get_uint8();
00738     _read_modes.push_back(mode);
00739   }
00740 }
 All Classes Functions Variables Enumerations