texGenAttrib.cxx 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
  1. // Filename: texGenAttrib.cxx
  2. // Created by: masad (21Jun04)
  3. //
  4. ////////////////////////////////////////////////////////////////////
  5. //
  6. // PANDA 3D SOFTWARE
  7. // Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
  8. //
  9. // All use of this software is subject to the terms of the Panda 3d
  10. // Software license. You should have received a copy of this license
  11. // along with this source code; you will also find a current copy of
  12. // the license at http://etc.cmu.edu/panda3d/docs/license/ .
  13. //
  14. // To contact the maintainers of this program write to
  15. // [email protected] .
  16. //
  17. ////////////////////////////////////////////////////////////////////
  18. #include "texGenAttrib.h"
  19. #include "texturePool.h"
  20. #include "graphicsStateGuardianBase.h"
  21. #include "bamReader.h"
  22. #include "bamWriter.h"
  23. #include "datagram.h"
  24. #include "datagramIterator.h"
  25. CPT(RenderAttrib) TexGenAttrib::_empty_attrib;
  26. TypeHandle TexGenAttrib::_type_handle;
  27. ////////////////////////////////////////////////////////////////////
  28. // Function: TexGenAttrib::Destructor
  29. // Access: Public, Virtual
  30. // Description:
  31. ////////////////////////////////////////////////////////////////////
  32. TexGenAttrib::
  33. ~TexGenAttrib() {
  34. }
  35. ////////////////////////////////////////////////////////////////////
  36. // Function: TexGenAttrib::make
  37. // Access: Published, Static
  38. // Description: Constructs a TexGenAttrib that generates no stages at
  39. // all.
  40. ////////////////////////////////////////////////////////////////////
  41. CPT(RenderAttrib) TexGenAttrib::
  42. make() {
  43. // We make it a special case and store a pointer to the empty attrib
  44. // forever once we find it the first time, as an optimization.
  45. if (_empty_attrib == (RenderAttrib *)NULL) {
  46. _empty_attrib = return_new(new TexGenAttrib);
  47. }
  48. return _empty_attrib;
  49. }
  50. ////////////////////////////////////////////////////////////////////
  51. // Function: TexGenAttrib::add_stage
  52. // Access: Published, Static
  53. // Description: Returns a new TexGenAttrib just like this one,
  54. // with the indicated generation mode for the given
  55. // stage. If this stage already exists, its mode is
  56. // replaced.
  57. ////////////////////////////////////////////////////////////////////
  58. CPT(RenderAttrib) TexGenAttrib::
  59. add_stage(TextureStage *stage, TexGenAttrib::Mode mode) const {
  60. TexGenAttrib *attrib = new TexGenAttrib(*this);
  61. attrib->_stages[stage] = mode;
  62. if (mode != M_off) {
  63. attrib->_no_texcoords.insert(stage);
  64. }
  65. return return_new(attrib);
  66. }
  67. ////////////////////////////////////////////////////////////////////
  68. // Function: TexGenAttrib::remove_stage
  69. // Access: Published, Static
  70. // Description: Returns a new TexGenAttrib just like this one,
  71. // with the indicated stage removed.
  72. ////////////////////////////////////////////////////////////////////
  73. CPT(RenderAttrib) TexGenAttrib::
  74. remove_stage(TextureStage *stage) const {
  75. TexGenAttrib *attrib = new TexGenAttrib(*this);
  76. attrib->_stages.erase(stage);
  77. attrib->_no_texcoords.erase(stage);
  78. return return_new(attrib);
  79. }
  80. ////////////////////////////////////////////////////////////////////
  81. // Function: TexGenAttrib::is_empty
  82. // Access: Published
  83. // Description: Returns true if no stages are defined in the
  84. // TexGenAttrib, false if at least one is.
  85. ////////////////////////////////////////////////////////////////////
  86. bool TexGenAttrib::
  87. is_empty() const {
  88. return _stages.empty();
  89. }
  90. ////////////////////////////////////////////////////////////////////
  91. // Function: TexGenAttrib::has_stage
  92. // Access: Published
  93. // Description: Returns true if there is a mode associated with
  94. // the indicated stage, or false otherwise (in which
  95. // case get_transform(stage) will return M_off).
  96. ////////////////////////////////////////////////////////////////////
  97. bool TexGenAttrib::
  98. has_stage(TextureStage *stage) const {
  99. Stages::const_iterator mi = _stages.find(stage);
  100. return (mi != _stages.end());
  101. }
  102. ////////////////////////////////////////////////////////////////////
  103. // Function: TexGenAttrib::get_mode
  104. // Access: Published
  105. // Description: Returns the generation mode associated with
  106. // the named texture stage, or M_off if
  107. // nothing is associated with the indicated stage.
  108. ////////////////////////////////////////////////////////////////////
  109. TexGenAttrib::Mode TexGenAttrib::
  110. get_mode(TextureStage *stage) const {
  111. Stages::const_iterator mi = _stages.find(stage);
  112. if (mi != _stages.end()) {
  113. return (*mi).second;
  114. }
  115. return M_off;
  116. }
  117. ////////////////////////////////////////////////////////////////////
  118. // Function: TexGenAttrib::issue
  119. // Access: Public, Virtual
  120. // Description: Calls the appropriate method on the indicated GSG
  121. // to issue the graphics commands appropriate to the
  122. // given attribute. This is normally called
  123. // (indirectly) only from
  124. // GraphicsStateGuardian::set_state() or modify_state().
  125. ////////////////////////////////////////////////////////////////////
  126. void TexGenAttrib::
  127. issue(GraphicsStateGuardianBase *gsg) const {
  128. gsg->issue_tex_gen(this);
  129. }
  130. ////////////////////////////////////////////////////////////////////
  131. // Function: TexGenAttrib::output
  132. // Access: Public, Virtual
  133. // Description:
  134. ////////////////////////////////////////////////////////////////////
  135. void TexGenAttrib::
  136. output(ostream &out) const {
  137. out << get_type() << ":";
  138. Stages::const_iterator mi;
  139. for (mi = _stages.begin(); mi != _stages.end(); ++mi) {
  140. TextureStage *stage = (*mi).first;
  141. Mode mode = (*mi).second;
  142. out << " " << stage->get_name() << "(";
  143. switch (mode) {
  144. case M_off:
  145. out << "off";
  146. break;
  147. case M_sphere_map:
  148. out << "sphere_map";
  149. break;
  150. case M_cube_map:
  151. out << "cube_map";
  152. break;
  153. case M_world_position:
  154. out << "world_position";
  155. break;
  156. case M_object_position:
  157. out << "object_position";
  158. break;
  159. case M_eye_position:
  160. out << "eye_position";
  161. break;
  162. }
  163. out << ")";
  164. }
  165. }
  166. ////////////////////////////////////////////////////////////////////
  167. // Function: TexGenAttrib::compare_to_impl
  168. // Access: Protected, Virtual
  169. // Description: Intended to be overridden by derived TexGenAttrib
  170. // types to return a unique number indicating whether
  171. // this TexGenAttrib is equivalent to the other one.
  172. //
  173. // This should return 0 if the two TexGenAttrib objects
  174. // are equivalent, a number less than zero if this one
  175. // should be sorted before the other one, and a number
  176. // greater than zero otherwise.
  177. //
  178. // This will only be called with two TexGenAttrib
  179. // objects whose get_type() functions return the same.
  180. ////////////////////////////////////////////////////////////////////
  181. int TexGenAttrib::
  182. compare_to_impl(const RenderAttrib *other) const {
  183. const TexGenAttrib *ta;
  184. DCAST_INTO_R(ta, other, 0);
  185. Stages::const_iterator ai, bi;
  186. ai = _stages.begin();
  187. bi = ta->_stages.begin();
  188. while (ai != _stages.end() && bi != ta->_stages.end()) {
  189. if ((*ai).first < (*bi).first) {
  190. // This stage is in a but not in b.
  191. return -1;
  192. } else if ((*bi).first < (*ai).first) {
  193. // This stage is in b but not in a.
  194. return 1;
  195. } else {
  196. // This stage is in both; compare the stages.
  197. if ((*ai).second != (*bi).second) {
  198. return (int)(*ai).second < (int)(*bi).second ? -1 : 1;
  199. }
  200. ++ai;
  201. ++bi;
  202. }
  203. }
  204. if (bi != _stages.end()) {
  205. // a ran out first; b was longer.
  206. return -1;
  207. }
  208. if (ai != _stages.end()) {
  209. // b ran out first; a was longer.
  210. return 1;
  211. }
  212. return 0;
  213. }
  214. ////////////////////////////////////////////////////////////////////
  215. // Function: TexGenAttrib::compose_impl
  216. // Access: Protected, Virtual
  217. // Description: Intended to be overridden by derived RenderAttrib
  218. // types to specify how two consecutive RenderAttrib
  219. // objects of the same type interact.
  220. //
  221. // This should return the result of applying the other
  222. // RenderAttrib to a node in the scene graph below this
  223. // RenderAttrib, which was already applied. In most
  224. // cases, the result is the same as the other
  225. // RenderAttrib (that is, a subsequent RenderAttrib
  226. // completely replaces the preceding one). On the other
  227. // hand, some kinds of RenderAttrib (for instance,
  228. // ColorTransformAttrib) might combine in meaningful
  229. // ways.
  230. ////////////////////////////////////////////////////////////////////
  231. CPT(RenderAttrib) TexGenAttrib::
  232. compose_impl(const RenderAttrib *other) const {
  233. const TexGenAttrib *ta;
  234. DCAST_INTO_R(ta, other, 0);
  235. // The composition is the union of the two attribs. In the case
  236. // when a stage is in both attribs, we compose the stages.
  237. TexGenAttrib *attrib = new TexGenAttrib;
  238. Stages::const_iterator ai, bi;
  239. ai = _stages.begin();
  240. bi = ta->_stages.begin();
  241. while (ai != _stages.end() && bi != ta->_stages.end()) {
  242. if ((*ai).first < (*bi).first) {
  243. // This stage is in a but not in b.
  244. attrib->_stages.insert(attrib->_stages.end(), *ai);
  245. ++ai;
  246. } else if ((*bi).first < (*ai).first) {
  247. // This stage is in b but not in a.
  248. attrib->_stages.insert(attrib->_stages.end(), *bi);
  249. ++bi;
  250. } else {
  251. // This stage is in both; b wins.
  252. attrib->_stages.insert(attrib->_stages.end(), *bi);
  253. ++bi;
  254. ++ai;
  255. }
  256. }
  257. while (ai != _stages.end()) {
  258. // This stage is in a but not in b.
  259. attrib->_stages.insert(attrib->_stages.end(), *ai);
  260. ++ai;
  261. }
  262. while (bi != ta->_stages.end()) {
  263. // This stage is in b but not in a.
  264. attrib->_stages.insert(attrib->_stages.end(), *bi);
  265. ++bi;
  266. }
  267. // Now copy from _stages to _no_texcoords.
  268. Stages::const_iterator ri;
  269. for (ri = attrib->_stages.begin(); ri != attrib->_stages.end(); ++ri) {
  270. if ((*ri).second != M_off) {
  271. attrib->_no_texcoords.insert((*ri).first);
  272. }
  273. }
  274. return return_new(attrib);
  275. }
  276. ////////////////////////////////////////////////////////////////////
  277. // Function: TexGenAttrib::invert_compose_impl
  278. // Access: Protected, Virtual
  279. // Description: Intended to be overridden by derived RenderAttrib
  280. // types to specify how two consecutive RenderAttrib
  281. // objects of the same type interact.
  282. //
  283. // See invert_compose() and compose_impl().
  284. ////////////////////////////////////////////////////////////////////
  285. CPT(RenderAttrib) TexGenAttrib::
  286. invert_compose_impl(const RenderAttrib *other) const {
  287. const TexGenAttrib *ta;
  288. DCAST_INTO_R(ta, other, 0);
  289. // The inverse composition works a lot like the composition, except
  290. // we invert the ai stages.
  291. TexGenAttrib *attrib = new TexGenAttrib;
  292. Stages::const_iterator ai, bi;
  293. ai = _stages.begin();
  294. bi = ta->_stages.begin();
  295. while (ai != _stages.end() && bi != ta->_stages.end()) {
  296. if ((*ai).first < (*bi).first) {
  297. // This stage is in a but not in b. Turn a off.
  298. attrib->_stages.insert(attrib->_stages.end(), Stages::value_type((*ai).first, M_off));
  299. ++ai;
  300. } else if ((*bi).first < (*ai).first) {
  301. // This stage is in b but not in a.
  302. attrib->_stages.insert(attrib->_stages.end(), *bi);
  303. ++bi;
  304. } else {
  305. // This stage is in both; b wins.
  306. attrib->_stages.insert(attrib->_stages.end(), *bi);
  307. ++bi;
  308. ++ai;
  309. }
  310. }
  311. while (ai != _stages.end()) {
  312. // This stage is in a but not in b.
  313. attrib->_stages.insert(attrib->_stages.end(), Stages::value_type((*ai).first, M_off));
  314. ++ai;
  315. }
  316. while (bi != ta->_stages.end()) {
  317. // This stage is in b but not in a.
  318. attrib->_stages.insert(attrib->_stages.end(), *bi);
  319. ++bi;
  320. }
  321. // Now copy from _stages to _no_texcoords.
  322. Stages::const_iterator ri;
  323. for (ri = attrib->_stages.begin(); ri != attrib->_stages.end(); ++ri) {
  324. if ((*ri).second != M_off) {
  325. attrib->_no_texcoords.insert((*ri).first);
  326. }
  327. }
  328. return return_new(attrib);
  329. }
  330. ////////////////////////////////////////////////////////////////////
  331. // Function: TexGenAttrib::make_default_impl
  332. // Access: Protected, Virtual
  333. // Description: Intended to be overridden by derived TexGenAttrib
  334. // types to specify what the default property for a
  335. // TexGenAttrib of this type should be.
  336. //
  337. // This should return a newly-allocated TexGenAttrib of
  338. // the same type that corresponds to whatever the
  339. // standard default for this kind of TexGenAttrib is.
  340. ////////////////////////////////////////////////////////////////////
  341. RenderAttrib *TexGenAttrib::
  342. make_default_impl() const {
  343. return new TexGenAttrib;
  344. }
  345. ////////////////////////////////////////////////////////////////////
  346. // Function: TexGenAttrib::register_with_read_factory
  347. // Access: Public, Static
  348. // Description: Tells the BamReader how to create objects of type
  349. // TexGenAttrib.
  350. ////////////////////////////////////////////////////////////////////
  351. void TexGenAttrib::
  352. register_with_read_factory() {
  353. BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
  354. }
  355. ////////////////////////////////////////////////////////////////////
  356. // Function: TexGenAttrib::write_datagram
  357. // Access: Public, Virtual
  358. // Description: Writes the contents of this object to the datagram
  359. // for shipping out to a Bam file.
  360. ////////////////////////////////////////////////////////////////////
  361. void TexGenAttrib::
  362. write_datagram(BamWriter *manager, Datagram &dg) {
  363. RenderAttrib::write_datagram(manager, dg);
  364. dg.add_uint16(_stages.size());
  365. Stages::const_iterator si;
  366. for (si = _stages.begin(); si != _stages.end(); ++si) {
  367. TextureStage *stage = (*si).first;
  368. Mode mode = (*si).second;
  369. manager->write_pointer(dg, stage);
  370. dg.add_uint8((unsigned int)mode);
  371. }
  372. }
  373. ////////////////////////////////////////////////////////////////////
  374. // Function: TexGenAttrib::complete_pointers
  375. // Access: Public, Virtual
  376. // Description: Receives an array of pointers, one for each time
  377. // manager->read_pointer() was called in fillin().
  378. // Returns the number of pointers processed.
  379. ////////////////////////////////////////////////////////////////////
  380. int TexGenAttrib::
  381. complete_pointers(TypedWritable **p_list, BamReader *manager) {
  382. int pi = RenderAttrib::complete_pointers(p_list, manager);
  383. pvector<Mode>::const_iterator mi;
  384. for (mi = _read_modes.begin(); mi != _read_modes.end(); ++mi) {
  385. Mode mode = (*mi);
  386. TextureStage *stage = DCAST(TextureStage, p_list[pi++]);
  387. _stages[stage] = mode;
  388. if (mode != M_off) {
  389. _no_texcoords.insert(stage);
  390. }
  391. }
  392. return pi;
  393. }
  394. ////////////////////////////////////////////////////////////////////
  395. // Function: TexGenAttrib::make_from_bam
  396. // Access: Protected, Static
  397. // Description: This function is called by the BamReader's factory
  398. // when a new object of type TexGenAttrib is encountered
  399. // in the Bam file. It should create the TexGenAttrib
  400. // and extract its information from the file.
  401. ////////////////////////////////////////////////////////////////////
  402. TypedWritable *TexGenAttrib::
  403. make_from_bam(const FactoryParams &params) {
  404. TexGenAttrib *attrib = new TexGenAttrib;
  405. DatagramIterator scan;
  406. BamReader *manager;
  407. parse_params(params, scan, manager);
  408. attrib->fillin(scan, manager);
  409. return attrib;
  410. }
  411. ////////////////////////////////////////////////////////////////////
  412. // Function: TexGenAttrib::fillin
  413. // Access: Protected
  414. // Description: This internal function is called by make_from_bam to
  415. // read in all of the relevant data from the BamFile for
  416. // the new TexGenAttrib.
  417. ////////////////////////////////////////////////////////////////////
  418. void TexGenAttrib::
  419. fillin(DatagramIterator &scan, BamReader *manager) {
  420. RenderAttrib::fillin(scan, manager);
  421. size_t num_stages = scan.get_uint16();
  422. // For now, read in a linear list of the modes we will assign to
  423. // each associated TextureStage pointer. Later, in
  424. // complete_pointers, we'll fill up the map the with appropriate
  425. // TextureStage/Mode pairing.
  426. _read_modes.clear();
  427. _read_modes.reserve(num_stages);
  428. for (size_t i = 0; i < num_stages; i++) {
  429. manager->read_pointer(scan);
  430. Mode mode = (Mode)scan.get_uint8();
  431. _read_modes.push_back(mode);
  432. }
  433. }