Panda3D

Loading...
Searching...
No Matches
texGenAttrib.cxx
Go to the documentation of this file.
1/**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file texGenAttrib.cxx
10 * @author masad
11 * @date 2004-06-21
12 */
13
14#include "texGenAttrib.h"
15#include "texturePool.h"
16#include "graphicsStateGuardianBase.h"
17#include "bamReader.h"
18#include "bamWriter.h"
19#include "datagram.h"
20#include "datagramIterator.h"
21#include "dcast.h"
22
23CPT(RenderAttrib) TexGenAttrib::_empty_attrib;
24 TypeHandle TexGenAttrib::_type_handle;
25 int TexGenAttrib::_attrib_slot;
26
27/**
28 *
29 */
30TexGenAttrib::
31~TexGenAttrib() {
32}
33
34/**
35 * Constructs a TexGenAttrib that generates no stages at all.
36 */
37CPT(RenderAttrib) TexGenAttrib::
38 make() {
39 // We make it a special case and store a pointer to the empty attrib forever
40 // once we find it the first time, as an optimization.
41 if (_empty_attrib == nullptr) {
42 _empty_attrib = return_new(new TexGenAttrib);
43 }
44
45 return _empty_attrib;
46}
47
48/**
49 * Constructs a TexGenAttrib that generates just the indicated stage.
50 */
51CPT(RenderAttrib) TexGenAttrib::
52 make(TextureStage *stage, TexGenAttrib::Mode mode) {
53 return DCAST(TexGenAttrib, make())->add_stage(stage, mode);
54}
55
56/**
57 * Returns a RenderAttrib that corresponds to whatever the standard default
58 * properties for render attributes of this type ought to be.
59 */
60CPT(RenderAttrib) TexGenAttrib::
61 make_default() {
62 return return_new(new TexGenAttrib);
63}
64
65/**
66 * Returns a new TexGenAttrib just like this one, with the indicated
67 * generation mode for the given stage. If this stage already exists, its
68 * mode is replaced.
69 */
70CPT(RenderAttrib) TexGenAttrib::
71 add_stage(TextureStage *stage, TexGenAttrib::Mode mode) const {
72 nassertr(mode != M_constant, this);
73
74 CPT(RenderAttrib) removed = remove_stage(stage);
75 TexGenAttrib *attrib = new TexGenAttrib(*DCAST(TexGenAttrib, removed));
76
77 ModeDef &mode_def = attrib->_stages[stage];
78 mode_def._mode = mode;
79 attrib->record_stage(stage, mode_def);
80
81 return return_new(attrib);
82}
83
84/**
85 * Returns a new TexGenAttrib just like this one, with the indicated
86 * generation mode for the given stage. If this stage already exists, its
87 * mode is replaced.
88 *
89 * This variant also accepts constant_value, which is only meaningful if mode
90 * is M_constant.
91 */
92CPT(RenderAttrib) TexGenAttrib::
93 add_stage(TextureStage *stage, TexGenAttrib::Mode mode,
94 const LTexCoord3 &constant_value) const {
95 nassertr(mode == M_constant, this);
96
97 CPT(RenderAttrib) removed = remove_stage(stage);
98 TexGenAttrib *attrib = new TexGenAttrib(*DCAST(TexGenAttrib, removed));
99
100 ModeDef &mode_def = attrib->_stages[stage];
101 mode_def._mode = mode;
102 mode_def._constant_value = constant_value;
103 attrib->record_stage(stage, mode_def);
104
105 return return_new(attrib);
106}
107
108/**
109 * Returns a new TexGenAttrib just like this one, with the indicated stage
110 * removed.
111 */
112CPT(RenderAttrib) TexGenAttrib::
113 remove_stage(TextureStage *stage) const {
114 Stages::const_iterator si;
115 si = _stages.find(stage);
116 if (si == _stages.end()) {
117 return this;
118 }
119
120 Mode mode = (*si).second._mode;
121 TexGenAttrib *attrib = new TexGenAttrib(*this);
122 attrib->_stages.erase(stage);
123 attrib->_no_texcoords.erase(stage);
124 if (mode == M_point_sprite) {
125 attrib->_num_point_sprites--;
126 if (attrib->_num_point_sprites == 0) {
127 attrib->_point_geom_rendering &= ~Geom::GR_point_sprite;
128 }
129 }
130 return return_new(attrib);
131}
132
133/**
134 * Returns true if no stages are defined in the TexGenAttrib, false if at
135 * least one is.
136 */
137 bool TexGenAttrib::
138 is_empty() const {
139 return _stages.empty();
140}
141
142/**
143 * Returns true if there is a mode associated with the indicated stage, or
144 * false otherwise (in which case get_transform(stage) will return M_off).
145 */
146 bool TexGenAttrib::
147 has_stage(TextureStage *stage) const {
148 Stages::const_iterator mi = _stages.find(stage);
149 return (mi != _stages.end());
150}
151
152/**
153 * Returns the generation mode associated with the named texture stage, or
154 * M_off if nothing is associated with the indicated stage.
155 */
156TexGenAttrib::Mode TexGenAttrib::
157 get_mode(TextureStage *stage) const {
158 Stages::const_iterator mi = _stages.find(stage);
159 if (mi != _stages.end()) {
160 return (*mi).second._mode;
161 }
162 return M_off;
163}
164
165/**
166 * Returns true if the indicated TextureStage will have texture coordinates
167 * generated for it automatically (and thus there is no need to upload the
168 * texture coordinates encoded in the vertices).
169 */
170 bool TexGenAttrib::
171 has_gen_texcoord_stage(TextureStage *stage) const {
172 NoTexCoordStages::const_iterator mi = _no_texcoords.find(stage);
173 return (mi != _no_texcoords.end());
174}
175
176/**
177 * Returns the constant value associated with the named texture stage. This
178 * is only meaningful if the mode is M_constant.
179 */
180 const LTexCoord3 &TexGenAttrib::
181 get_constant_value(TextureStage *stage) const {
182 Stages::const_iterator mi = _stages.find(stage);
183 if (mi != _stages.end()) {
184 return (*mi).second._constant_value;
185 }
186 return LTexCoord3::zero();
187}
188
189/**
190 *
191 */
192 void TexGenAttrib::
193output(std::ostream &out) const {
194 out << get_type() << ":";
195
196 Stages::const_iterator mi;
197 for (mi = _stages.begin(); mi != _stages.end(); ++mi) {
198 TextureStage *stage = (*mi).first;
199 const ModeDef &mode_def = (*mi).second;
200 out << " " << stage->get_name() << "(";
201 switch (mode_def._mode) {
202 case M_off:
203 out << "off";
204 break;
205
206 case M_eye_sphere_map:
207 out << "eye_sphere_map";
208 break;
209
210 case M_world_cube_map:
211 out << "world_cube_map";
212 break;
213 case M_eye_cube_map:
214 out << "eye_cube_map";
215 break;
216
217 case M_world_normal:
218 out << "world_normal";
219 break;
220 case M_eye_normal:
221 out << "eye_normal";
222 break;
223
224 case M_world_position:
225 out << "world_position";
226 break;
227 case M_eye_position:
228 out << "eye_position";
229 break;
230
231 case M_point_sprite:
232 out << "point_sprite";
233 break;
234
235 case M_constant:
236 out << "constant: " << mode_def._constant_value;
237 break;
238
239 case M_unused:
240 case M_unused2:
241 break;
242 }
243 out << ")";
244 }
245}
246
247/**
248 * Intended to be overridden by derived TexGenAttrib types to return a unique
249 * number indicating whether this TexGenAttrib is equivalent to the other one.
250 *
251 * This should return 0 if the two TexGenAttrib objects are equivalent, a
252 * number less than zero if this one should be sorted before the other one,
253 * and a number greater than zero otherwise.
254 *
255 * This will only be called with two TexGenAttrib objects whose get_type()
256 * functions return the same.
257 */
258 int TexGenAttrib::
259compare_to_impl(const RenderAttrib *other) const {
260 const TexGenAttrib *ta = (const TexGenAttrib *)other;
261
262 Stages::const_iterator ai, bi;
263 ai = _stages.begin();
264 bi = ta->_stages.begin();
265 while (ai != _stages.end() && bi != ta->_stages.end()) {
266 if ((*ai).first < (*bi).first) {
267 // This stage is in a but not in b.
268 return -1;
269
270 } else if ((*bi).first < (*ai).first) {
271 // This stage is in b but not in a.
272 return 1;
273
274 } else {
275 // This stage is in both; compare the stages.
276 int compare = (*ai).second.compare_to((*bi).second);
277 if (compare != 0) {
278 return compare;
279 }
280 ++ai;
281 ++bi;
282 }
283 }
284
285 if (bi != ta->_stages.end()) {
286 // a ran out first; b was longer.
287 return -1;
288 }
289
290 if (ai != _stages.end()) {
291 // b ran out first; a was longer.
292 return 1;
293 }
294
295 return 0;
296}
297
298/**
299 * Intended to be overridden by derived RenderAttrib types to return a unique
300 * hash for these particular properties. RenderAttribs that compare the same
301 * with compare_to_impl(), above, should return the same hash; RenderAttribs
302 * that compare differently should return a different hash.
303 */
304 size_t TexGenAttrib::
305get_hash_impl() const {
306 size_t hash = 0;
307 Stages::const_iterator ri;
308 for (ri = _stages.begin(); ri != _stages.end(); ++ri) {
309 const TextureStage *stage = (*ri).first;
310 const ModeDef &mode_def = (*ri).second;
311
312 hash = pointer_hash::add_hash(hash, stage);
313 hash = int_hash::add_hash(hash, (int)mode_def._mode);
314 hash = string_hash::add_hash(hash, mode_def._source_name);
315 hash = mode_def._light.add_hash(hash);
316 hash = mode_def._constant_value.add_hash(hash);
317 }
318
319 return hash;
320}
321
322/**
323 * Intended to be overridden by derived RenderAttrib types to specify how two
324 * consecutive RenderAttrib objects of the same type interact.
325 *
326 * This should return the result of applying the other RenderAttrib to a node
327 * in the scene graph below this RenderAttrib, which was already applied. In
328 * most cases, the result is the same as the other RenderAttrib (that is, a
329 * subsequent RenderAttrib completely replaces the preceding one). On the
330 * other hand, some kinds of RenderAttrib (for instance, ColorTransformAttrib)
331 * might combine in meaningful ways.
332 */
333CPT(RenderAttrib) TexGenAttrib::
334compose_impl(const RenderAttrib *other) const {
335 const TexGenAttrib *ta = (const TexGenAttrib *)other;
336
337 // The composition is the union of the two attribs. In the case when a
338 // stage is in both attribs, we compose the stages.
339
340 TexGenAttrib *attrib = new TexGenAttrib;
341
342 Stages::const_iterator ai, bi;
343 ai = _stages.begin();
344 bi = ta->_stages.begin();
345 while (ai != _stages.end() && bi != ta->_stages.end()) {
346 if ((*ai).first < (*bi).first) {
347 // This stage is in a but not in b.
348 attrib->_stages.insert(attrib->_stages.end(), *ai);
349 ++ai;
350
351 } else if ((*bi).first < (*ai).first) {
352 // This stage is in b but not in a.
353 attrib->_stages.insert(attrib->_stages.end(), *bi);
354 ++bi;
355
356 } else {
357 // This stage is in both; b wins.
358 attrib->_stages.insert(attrib->_stages.end(), *bi);
359 ++bi;
360 ++ai;
361 }
362 }
363
364 while (ai != _stages.end()) {
365 // This stage is in a but not in b.
366 attrib->_stages.insert(attrib->_stages.end(), *ai);
367 ++ai;
368 }
369
370 while (bi != ta->_stages.end()) {
371 // This stage is in b but not in a.
372 attrib->_stages.insert(attrib->_stages.end(), *bi);
373 ++bi;
374 }
375
376 attrib->filled_stages();
377
378 return return_new(attrib);
379}
380
381/**
382 * Intended to be overridden by derived RenderAttrib types to specify how two
383 * consecutive RenderAttrib objects of the same type interact.
384 *
385 * See invert_compose() and compose_impl().
386 */
387CPT(RenderAttrib) TexGenAttrib::
388invert_compose_impl(const RenderAttrib *other) const {
389 const TexGenAttrib *ta = (const TexGenAttrib *)other;
390
391 // The inverse composition works a lot like the composition, except we
392 // invert the ai stages.
393
394 TexGenAttrib *attrib = new TexGenAttrib;
395
396 Stages::const_iterator ai, bi;
397 ai = _stages.begin();
398 bi = ta->_stages.begin();
399 while (ai != _stages.end() && bi != ta->_stages.end()) {
400 if ((*ai).first < (*bi).first) {
401 // This stage is in a but not in b. Turn a off.
402 attrib->_stages.insert(attrib->_stages.end(), Stages::value_type((*ai).first, ModeDef()));
403 ++ai;
404
405 } else if ((*bi).first < (*ai).first) {
406 // This stage is in b but not in a.
407 attrib->_stages.insert(attrib->_stages.end(), *bi);
408 ++bi;
409
410 } else {
411 // This stage is in both; b wins.
412 attrib->_stages.insert(attrib->_stages.end(), *bi);
413 ++bi;
414 ++ai;
415 }
416 }
417
418 while (ai != _stages.end()) {
419 // This stage is in a but not in b.
420 attrib->_stages.insert(attrib->_stages.end(), Stages::value_type((*ai).first, ModeDef()));
421 ++ai;
422 }
423
424 while (bi != ta->_stages.end()) {
425 // This stage is in b but not in a.
426 attrib->_stages.insert(attrib->_stages.end(), *bi);
427 ++bi;
428 }
429
430 attrib->filled_stages();
431
432 return return_new(attrib);
433}
434
435/**
436 * This method is to be called after the _stages map has been built up
437 * internally through some artificial means; it copies the appropriate
438 * settings to _no_texcoords and updates other internal cache values
439 * appropriately.
440 */
441 void TexGenAttrib::
442filled_stages() {
443 Stages::iterator ri;
444 for (ri = _stages.begin(); ri != _stages.end(); ++ri) {
445 TextureStage *stage = (*ri).first;
446 ModeDef &mode_def = (*ri).second;
447 record_stage(stage, mode_def);
448 }
449}
450
451/**
452 * Updates the appropriate internal caches before adding the indicated stage
453 * with the given mode to the _stages map.
454 */
455 void TexGenAttrib::
456record_stage(TextureStage *stage, TexGenAttrib::ModeDef &mode_def) {
457 switch (mode_def._mode) {
458 case M_point_sprite:
459 _no_texcoords.insert(stage);
460 _point_geom_rendering |= Geom::GR_point_sprite;
461 _num_point_sprites++;
462 break;
463
464 case M_off:
465 break;
466
467 default:
468 _no_texcoords.insert(stage);
469 }
470}
471
472/**
473 * Tells the BamReader how to create objects of type TexGenAttrib.
474 */
475 void TexGenAttrib::
476 register_with_read_factory() {
477 BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
478}
479
480/**
481 * Writes the contents of this object to the datagram for shipping out to a
482 * Bam file.
483 */
484 void TexGenAttrib::
485 write_datagram(BamWriter *manager, Datagram &dg) {
486 RenderAttrib::write_datagram(manager, dg);
487
488 dg.add_uint16(_stages.size());
489
490 Stages::const_iterator si;
491 for (si = _stages.begin(); si != _stages.end(); ++si) {
492 TextureStage *stage = (*si).first;
493 Mode mode = (*si).second._mode;
494
495 manager->write_pointer(dg, stage);
496 dg.add_uint8((unsigned int)mode);
497 }
498}
499
500/**
501 * Receives an array of pointers, one for each time manager->read_pointer()
502 * was called in fillin(). Returns the number of pointers processed.
503 */
504 int TexGenAttrib::
505 complete_pointers(TypedWritable **p_list, BamReader *manager) {
506 int pi = RenderAttrib::complete_pointers(p_list, manager);
507
508 pvector<Mode>::const_iterator mi;
509 for (mi = _read_modes.begin(); mi != _read_modes.end(); ++mi) {
510 Mode mode = (*mi);
511
512 TextureStage *stage = DCAST(TextureStage, p_list[pi++]);
513 _stages[stage]._mode = mode;
514 }
515
516 filled_stages();
517
518 return pi;
519}
520
521/**
522 * This function is called by the BamReader's factory when a new object of
523 * type TexGenAttrib is encountered in the Bam file. It should create the
524 * TexGenAttrib and extract its information from the file.
525 */
526 TypedWritable *TexGenAttrib::
527make_from_bam(const FactoryParams &params) {
528 TexGenAttrib *attrib = new TexGenAttrib;
529 DatagramIterator scan;
530 BamReader *manager;
531
532 parse_params(params, scan, manager);
533 attrib->fillin(scan, manager);
534
535 return attrib;
536}
537
538/**
539 * This internal function is called by make_from_bam to read in all of the
540 * relevant data from the BamFile for the new TexGenAttrib.
541 */
542 void TexGenAttrib::
543fillin(DatagramIterator &scan, BamReader *manager) {
544 RenderAttrib::fillin(scan, manager);
545
546 size_t num_stages = scan.get_uint16();
547
548 // For now, read in a linear list of the modes we will assign to each
549 // associated TextureStage pointer. Later, in complete_pointers, we'll fill
550 // up the map the with appropriate TextureStageMode pairing.
551 _read_modes.clear();
552 _read_modes.reserve(num_stages);
553 for (size_t i = 0; i < num_stages; i++) {
554 manager->read_pointer(scan);
555 Mode mode = (Mode)scan.get_uint8();
556 _read_modes.push_back(mode);
557 }
558}
bamReader.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
parse_params
void parse_params(const FactoryParams &params, DatagramIterator &scan, BamReader *&manager)
Takes in a FactoryParams, passed from a WritableFactory into any TypedWritable's make function,...
Definition bamReader.I:275
bamWriter.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
BamReader
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition bamReader.h:110
BamReader::read_pointer
bool read_pointer(DatagramIterator &scan)
The interface for reading a pointer to another object from a Bam file.
Definition bamReader.cxx:610
BamReader::get_factory
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
Definition bamReader.I:177
BamWriter::write_pointer
void write_pointer(Datagram &packet, const TypedWritable *dest)
The interface for writing a pointer to another object to a Bam file.
Definition bamWriter.cxx:317
DatagramIterator
A class to retrieve the individual data elements previously stored in a Datagram.
Definition datagramIterator.h:30
DatagramIterator::get_uint8
uint8_t get_uint8()
Extracts an unsigned 8-bit integer.
Definition datagramIterator.I:72
DatagramIterator::get_uint16
uint16_t get_uint16()
Extracts an unsigned 16-bit integer.
Definition datagramIterator.I:145
Datagram
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition datagram.h:38
Datagram::add_uint8
void add_uint8(uint8_t value)
Adds an unsigned 8-bit integer to the datagram.
Definition datagram.I:50
Datagram::add_uint16
void add_uint16(uint16_t value)
Adds an unsigned 16-bit integer to the datagram.
Definition datagram.I:85
FactoryParams
An instance of this class is passed to the Factory when requesting it to do its business and construc...
Definition factoryParams.h:36
Factory::register_factory
void register_factory(TypeHandle handle, CreateFunc *func, void *user_data=nullptr)
Registers a new kind of thing the Factory will be able to create.
Definition factory.I:73
Geom
A container for geometry primitives.
Definition geom.h:54
RenderAttrib
This is the base class for a number of render attributes (other than transform) that may be set on sc...
Definition renderAttrib.h:51
RenderAttrib::write_datagram
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
Definition renderAttrib.cxx:527
TexGenAttrib
Computes texture coordinates for geometry automatically based on vertex position and/or normal.
Definition texGenAttrib.h:32
TexGenAttrib::write_datagram
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
Definition texGenAttrib.cxx:485
TexGenAttrib::has_gen_texcoord_stage
bool has_gen_texcoord_stage(TextureStage *stage) const
Returns true if the indicated TextureStage will have texture coordinates generated for it automatical...
Definition texGenAttrib.cxx:171
TexGenAttrib::remove_stage
ConstPointerTo< RenderAttrib > remove_stage(TextureStage *stage) const
Returns a new TexGenAttrib just like this one, with the indicated stage removed.
Definition texGenAttrib.cxx:113
TexGenAttrib::make_default
static ConstPointerTo< RenderAttrib > make_default()
Returns a RenderAttrib that corresponds to whatever the standard default properties for render attrib...
Definition texGenAttrib.cxx:61
TexGenAttrib::has_stage
bool has_stage(TextureStage *stage) const
Returns true if there is a mode associated with the indicated stage, or false otherwise (in which cas...
Definition texGenAttrib.cxx:147
TexGenAttrib::get_mode
Mode get_mode(TextureStage *stage) const
Returns the generation mode associated with the named texture stage, or M_off if nothing is associate...
Definition texGenAttrib.cxx:157
TexGenAttrib::register_with_read_factory
static void register_with_read_factory()
Tells the BamReader how to create objects of type TexGenAttrib.
Definition texGenAttrib.cxx:476
TexGenAttrib::complete_pointers
virtual int complete_pointers(TypedWritable **plist, BamReader *manager)
Receives an array of pointers, one for each time manager->read_pointer() was called in fillin().
Definition texGenAttrib.cxx:505
TexGenAttrib::is_empty
bool is_empty() const
Returns true if no stages are defined in the TexGenAttrib, false if at least one is.
Definition texGenAttrib.cxx:138
TexGenAttrib::make
static ConstPointerTo< RenderAttrib > make()
Constructs a TexGenAttrib that generates no stages at all.
Definition texGenAttrib.cxx:38
TexGenAttrib::add_stage
ConstPointerTo< RenderAttrib > add_stage(TextureStage *stage, Mode mode) const
Returns a new TexGenAttrib just like this one, with the indicated generation mode for the given stage...
Definition texGenAttrib.cxx:71
TexGenAttrib::get_constant_value
const LTexCoord3 & get_constant_value(TextureStage *stage) const
Returns the constant value associated with the named texture stage.
Definition texGenAttrib.cxx:181
TextureStage
Defines the properties of a named stage of the multitexture pipeline.
Definition textureStage.h:35
TextureStage::get_name
get_name
Returns the name of this texture stage.
Definition textureStage.h:194
TypeHandle
TypeHandle is the identifier used to differentiate C++ class types.
Definition typeHandle.h:81
TypedWritable
Base class for objects that can be written to and read from Bam files.
Definition typedWritable.h:35
TypedWritable::complete_pointers
virtual int complete_pointers(TypedWritable **p_list, BamReader *manager)
Receives an array of pointers, one for each time manager->read_pointer() was called in fillin().
Definition typedWritable.cxx:81
integer_hash< int >::add_hash
static size_t add_hash(size_t start, const int &key)
pointer_hash::add_hash
static size_t add_hash(size_t start, const void *key)
Adds the indicated key into a running hash.
Definition stl_compares.I:110
sequence_hash< std::string >::add_hash
static size_t add_hash(size_t start, const std::string &key)
datagramIterator.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
datagram.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
dcast.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
graphicsStateGuardianBase.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
texGenAttrib.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
texturePool.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.