Panda3D
|
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 ¶ms) { 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 }