Panda3D

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 TexCoord3f &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 TexCoord3f &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 TexCoord3f::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::compose_impl
00416 //       Access: Protected, Virtual
00417 //  Description: Intended to be overridden by derived RenderAttrib
00418 //               types to specify how two consecutive RenderAttrib
00419 //               objects of the same type interact.
00420 //
00421 //               This should return the result of applying the other
00422 //               RenderAttrib to a node in the scene graph below this
00423 //               RenderAttrib, which was already applied.  In most
00424 //               cases, the result is the same as the other
00425 //               RenderAttrib (that is, a subsequent RenderAttrib
00426 //               completely replaces the preceding one).  On the other
00427 //               hand, some kinds of RenderAttrib (for instance,
00428 //               ColorTransformAttrib) might combine in meaningful
00429 //               ways.
00430 ////////////////////////////////////////////////////////////////////
00431 CPT(RenderAttrib) TexGenAttrib::
00432 compose_impl(const RenderAttrib *other) const {
00433   const TexGenAttrib *ta;
00434   DCAST_INTO_R(ta, other, 0);
00435 
00436   // The composition is the union of the two attribs.  In the case
00437   // when a stage is in both attribs, we compose the stages.
00438 
00439   TexGenAttrib *attrib = new TexGenAttrib;
00440 
00441   Stages::const_iterator ai, bi;
00442   ai = _stages.begin();
00443   bi = ta->_stages.begin();
00444   while (ai != _stages.end() && bi != ta->_stages.end()) {
00445     if ((*ai).first < (*bi).first) {
00446       // This stage is in a but not in b.
00447       attrib->_stages.insert(attrib->_stages.end(), *ai);
00448       ++ai;
00449 
00450     } else if ((*bi).first < (*ai).first) {
00451       // This stage is in b but not in a.
00452       attrib->_stages.insert(attrib->_stages.end(), *bi);
00453       ++bi;
00454 
00455     } else {
00456       // This stage is in both; b wins.
00457       attrib->_stages.insert(attrib->_stages.end(), *bi);
00458       ++bi;
00459       ++ai;
00460     }
00461   }
00462 
00463   while (ai != _stages.end()) {
00464     // This stage is in a but not in b.
00465     attrib->_stages.insert(attrib->_stages.end(), *ai);
00466     ++ai;
00467   }
00468 
00469   while (bi != ta->_stages.end()) {
00470     // This stage is in b but not in a.
00471     attrib->_stages.insert(attrib->_stages.end(), *bi);
00472     ++bi;
00473   }
00474 
00475   attrib->filled_stages();
00476 
00477   return return_new(attrib);
00478 }
00479 
00480 ////////////////////////////////////////////////////////////////////
00481 //     Function: TexGenAttrib::invert_compose_impl
00482 //       Access: Protected, Virtual
00483 //  Description: Intended to be overridden by derived RenderAttrib
00484 //               types to specify how two consecutive RenderAttrib
00485 //               objects of the same type interact.
00486 //
00487 //               See invert_compose() and compose_impl().
00488 ////////////////////////////////////////////////////////////////////
00489 CPT(RenderAttrib) TexGenAttrib::
00490 invert_compose_impl(const RenderAttrib *other) const {
00491   const TexGenAttrib *ta;
00492   DCAST_INTO_R(ta, other, 0);
00493 
00494   // The inverse composition works a lot like the composition, except
00495   // we invert the ai stages.
00496 
00497   TexGenAttrib *attrib = new TexGenAttrib;
00498 
00499   Stages::const_iterator ai, bi;
00500   ai = _stages.begin();
00501   bi = ta->_stages.begin();
00502   while (ai != _stages.end() && bi != ta->_stages.end()) {
00503     if ((*ai).first < (*bi).first) {
00504       // This stage is in a but not in b.  Turn a off.
00505       attrib->_stages.insert(attrib->_stages.end(), Stages::value_type((*ai).first, ModeDef()));
00506       ++ai;
00507 
00508     } else if ((*bi).first < (*ai).first) {
00509       // This stage is in b but not in a.
00510       attrib->_stages.insert(attrib->_stages.end(), *bi);
00511       ++bi;
00512 
00513     } else {
00514       // This stage is in both; b wins.
00515       attrib->_stages.insert(attrib->_stages.end(), *bi);
00516       ++bi;
00517       ++ai;
00518     }
00519   }
00520 
00521   while (ai != _stages.end()) {
00522     // This stage is in a but not in b.
00523     attrib->_stages.insert(attrib->_stages.end(), Stages::value_type((*ai).first, ModeDef()));
00524     ++ai;
00525   }
00526 
00527   while (bi != ta->_stages.end()) {
00528     // This stage is in b but not in a.
00529     attrib->_stages.insert(attrib->_stages.end(), *bi);
00530     ++bi;
00531   }
00532 
00533   attrib->filled_stages();
00534 
00535   return return_new(attrib);
00536 }
00537 
00538 ////////////////////////////////////////////////////////////////////
00539 //     Function: TexGenAttrib::filled_stages
00540 //       Access: Private
00541 //  Description: This method is to be called after the _stages map has
00542 //               been built up internally through some artificial
00543 //               means; it copies the appropriate settings to
00544 //               _no_texcoords and updates other internal cache values
00545 //               appropriately.
00546 ////////////////////////////////////////////////////////////////////
00547 void TexGenAttrib::
00548 filled_stages() {
00549   Stages::iterator ri;
00550   for (ri = _stages.begin(); ri != _stages.end(); ++ri) {
00551     TextureStage *stage = (*ri).first;
00552     ModeDef &mode_def = (*ri).second;
00553     record_stage(stage, mode_def);
00554   }
00555 }
00556 
00557 ////////////////////////////////////////////////////////////////////
00558 //     Function: TexGenAttrib::record_stage
00559 //       Access: Private
00560 //  Description: Updates the appropriate internal caches before adding
00561 //               the indicated stage with the given mode to the
00562 //               _stages map.
00563 ////////////////////////////////////////////////////////////////////
00564 void TexGenAttrib::
00565 record_stage(TextureStage *stage, TexGenAttrib::ModeDef &mode_def) {
00566   switch (mode_def._mode) {
00567   case M_point_sprite:
00568     _no_texcoords.insert(stage);
00569     _point_geom_rendering |= Geom::GR_point_sprite;
00570     _num_point_sprites++;
00571     break;
00572 
00573   case M_light_vector:
00574     {
00575       if (!mode_def._light.is_empty()) {
00576         Light *light_obj = mode_def._light.node()->as_light();
00577         if (light_obj == (Light *)NULL) {
00578 #ifndef NDEBUG
00579           ostringstream strm;
00580           strm << "Not a light: " << mode_def._light;
00581           nassert_raise(strm.str());
00582 #endif
00583           mode_def._light = NodePath();
00584         }
00585       }
00586 
00587       _light_vectors.insert(stage);
00588       _geom_rendering |= Geom::GR_texcoord_light_vector;
00589       _num_light_vectors++;
00590     }
00591     break;
00592 
00593   case M_off:
00594     break;
00595 
00596   default:
00597     _no_texcoords.insert(stage);
00598   }
00599 }
00600 
00601 ////////////////////////////////////////////////////////////////////
00602 //     Function: TexGenAttrib::register_with_read_factory
00603 //       Access: Public, Static
00604 //  Description: Tells the BamReader how to create objects of type
00605 //               TexGenAttrib.
00606 ////////////////////////////////////////////////////////////////////
00607 void TexGenAttrib::
00608 register_with_read_factory() {
00609   BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
00610 }
00611 
00612 ////////////////////////////////////////////////////////////////////
00613 //     Function: TexGenAttrib::write_datagram
00614 //       Access: Public, Virtual
00615 //  Description: Writes the contents of this object to the datagram
00616 //               for shipping out to a Bam file.
00617 ////////////////////////////////////////////////////////////////////
00618 void TexGenAttrib::
00619 write_datagram(BamWriter *manager, Datagram &dg) {
00620   RenderAttrib::write_datagram(manager, dg);
00621 
00622   dg.add_uint16(_stages.size());
00623 
00624   Stages::const_iterator si;
00625   for (si = _stages.begin(); si != _stages.end(); ++si) {
00626     TextureStage *stage = (*si).first;
00627     Mode mode = (*si).second._mode;
00628 
00629     manager->write_pointer(dg, stage);
00630     dg.add_uint8((unsigned int)mode);
00631   }
00632 }
00633 
00634 ////////////////////////////////////////////////////////////////////
00635 //     Function: TexGenAttrib::complete_pointers
00636 //       Access: Public, Virtual
00637 //  Description: Receives an array of pointers, one for each time
00638 //               manager->read_pointer() was called in fillin().
00639 //               Returns the number of pointers processed.
00640 ////////////////////////////////////////////////////////////////////
00641 int TexGenAttrib::
00642 complete_pointers(TypedWritable **p_list, BamReader *manager) {
00643   int pi = RenderAttrib::complete_pointers(p_list, manager);
00644 
00645   pvector<Mode>::const_iterator mi;
00646   for (mi = _read_modes.begin(); mi != _read_modes.end(); ++mi) {
00647     Mode mode = (*mi);
00648 
00649     TextureStage *stage = DCAST(TextureStage, p_list[pi++]);
00650     _stages[stage]._mode = mode;
00651   }
00652 
00653   filled_stages();
00654 
00655   return pi;
00656 }
00657 
00658 ////////////////////////////////////////////////////////////////////
00659 //     Function: TexGenAttrib::make_from_bam
00660 //       Access: Protected, Static
00661 //  Description: This function is called by the BamReader's factory
00662 //               when a new object of type TexGenAttrib is encountered
00663 //               in the Bam file.  It should create the TexGenAttrib
00664 //               and extract its information from the file.
00665 ////////////////////////////////////////////////////////////////////
00666 TypedWritable *TexGenAttrib::
00667 make_from_bam(const FactoryParams &params) {
00668   TexGenAttrib *attrib = new TexGenAttrib;
00669   DatagramIterator scan;
00670   BamReader *manager;
00671 
00672   parse_params(params, scan, manager);
00673   attrib->fillin(scan, manager);
00674 
00675   return attrib;
00676 }
00677 
00678 ////////////////////////////////////////////////////////////////////
00679 //     Function: TexGenAttrib::fillin
00680 //       Access: Protected
00681 //  Description: This internal function is called by make_from_bam to
00682 //               read in all of the relevant data from the BamFile for
00683 //               the new TexGenAttrib.
00684 ////////////////////////////////////////////////////////////////////
00685 void TexGenAttrib::
00686 fillin(DatagramIterator &scan, BamReader *manager) {
00687   RenderAttrib::fillin(scan, manager);
00688 
00689   size_t num_stages = scan.get_uint16();
00690 
00691   // For now, read in a linear list of the modes we will assign to
00692   // each associated TextureStage pointer.  Later, in
00693   // complete_pointers, we'll fill up the map the with appropriate
00694   // TextureStage/Mode pairing.
00695   _read_modes.clear();
00696   _read_modes.reserve(num_stages);
00697   for (size_t i = 0; i < num_stages; i++) {
00698     manager->read_pointer(scan);
00699     Mode mode = (Mode)scan.get_uint8();
00700     _read_modes.push_back(mode);
00701   }
00702 }
 All Classes Functions Variables Enumerations