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