15 #include "textureAttrib.h" 16 #include "graphicsStateGuardianBase.h" 17 #include "internalName.h" 18 #include "bamReader.h" 19 #include "bamWriter.h" 21 #include "datagramIterator.h" 23 #include "textureStagePool.h" 28 int TextureAttrib::_attrib_slot;
51 return make_all_off();
83 attrib->_off_all_stages =
true;
84 _all_off_attrib = return_new(attrib);
87 return _all_off_attrib;
112 Stages::const_iterator si = _on_stages.find(StageNode(stage));
113 if (si != _on_stages.
end()) {
114 return (
int)(si - _on_stages.
begin());
130 Stages::iterator si = attrib->_on_stages.insert(StageNode(stage)).first;
131 (*si)._override =
override;
132 (*si)._texture = tex;
133 (*si)._implicit_sort = attrib->_next_implicit_sort;
134 (*si)._has_sampler =
false;
135 ++(attrib->_next_implicit_sort);
141 return return_new(attrib);
154 Stages::iterator si = attrib->_on_stages.insert(StageNode(stage)).first;
155 (*si)._override =
override;
156 (*si)._texture = tex;
157 (*si)._sampler = sampler;
158 (*si)._implicit_sort = attrib->_next_implicit_sort;
159 (*si)._has_sampler =
true;
160 ++(attrib->_next_implicit_sort);
166 return return_new(attrib);
180 Stages::iterator si = attrib->_on_stages.find(StageNode(stage));
181 if (si != attrib->_on_stages.
end()) {
182 attrib->_on_stages.erase(si);
188 return return_new(attrib);
199 add_off_stage(
TextureStage *stage,
int override)
const {
201 if (!_off_all_stages) {
203 Stages::iterator sfi = attrib->_off_stages.insert(sn).first;
204 (*sfi)._override =
override;
207 Stages::iterator si = attrib->_on_stages.find(sn);
208 if (si != attrib->_on_stages.
end()) {
209 attrib->_on_stages.erase(si);
214 return return_new(attrib);
227 attrib->_off_stages.erase(StageNode(stage));
228 return return_new(attrib);
243 attrib->_off_all_stages = _off_all_stages;
244 bool any_changed =
false;
246 Stages::const_iterator si;
247 for (si = _on_stages.
begin(); si != _on_stages.
end(); ++si) {
255 Stages::iterator osi = attrib->_on_stages.insert(StageNode(this_stage)).first;
256 (*osi)._texture = (*si)._texture;
257 (*osi)._ff_tc_index = (*si)._ff_tc_index;
258 (*osi)._implicit_sort = (*si)._implicit_sort;
259 (*osi)._override = (*si)._override;
262 attrib->_next_implicit_sort = _next_implicit_sort;
264 Stages::const_iterator fsi;
265 for (fsi = _off_stages.
begin(); fsi != _off_stages.
end(); ++fsi) {
268 if (this_stage != stage &&
274 attrib->_off_stages.insert(StageNode(this_stage));
281 return return_new(attrib);
293 filter_to_max(
int max_texture_stages)
const {
294 if ((
int)_on_stages.
size() <= max_texture_stages) {
304 Filtered::const_iterator fi;
305 fi = _filtered.find(max_texture_stages);
306 if (fi != _filtered.end()) {
320 sort(priority_stages.begin(), priority_stages.end(),
321 CompareTextureStagePriorities());
324 priority_stages.erase(priority_stages.begin() + max_texture_stages,
325 priority_stages.end());
330 RenderStages::const_iterator ri;
331 for (ri = priority_stages.begin(); ri != priority_stages.end(); ++ri) {
332 attrib->_on_stages.insert(*(*ri));
335 attrib->_next_implicit_sort = _next_implicit_sort;
346 ((
TextureAttrib *)
this)->_filtered[max_texture_stages] = tex_attrib;
394 output(ostream &out)
const {
397 out << get_type() <<
":";
398 if (_off_stages.
empty()) {
399 if (_on_stages.
empty()) {
400 if (_off_all_stages) {
406 if (_off_all_stages) {
415 Stages::const_iterator fi;
416 for (fi = _off_stages.
begin(); fi != _off_stages.
end(); ++fi) {
419 if ((*fi)._override != 0) {
420 out <<
"^" << (*fi)._override;
424 if (!_on_stages.
empty()) {
429 RenderStages::const_iterator ri;
430 for (ri = _render_stages.begin(); ri != _render_stages.end(); ++ri) {
431 const StageNode &sn = *(*ri);
435 out <<
" " << stage->
get_name() <<
":" << tex->get_name();
439 if (sn._override != 0) {
440 out <<
"^" << sn._override;
456 Stages::const_iterator si;
457 for (si = _on_stages.
begin(); si != _on_stages.
end(); ++si) {
458 Texture *texture = (*si)._texture;
482 Stages::const_iterator si;
483 for (si = _on_stages.
begin(); si != _on_stages.
end(); ++si) {
484 Texture *texture = (*si)._texture;
511 DCAST_INTO_R(ta, other, 0);
513 if (_off_all_stages != ta->_off_all_stages) {
514 return (
int)_off_all_stages - (int)ta->_off_all_stages;
517 Stages::const_iterator si = _on_stages.
begin();
518 Stages::const_iterator osi = ta->_on_stages.
begin();
520 while (si != _on_stages.
end() && osi != ta->_on_stages.
end()) {
524 if (stage != other_stage) {
525 return stage < other_stage ? -1 : 1;
528 Texture *texture = (*si)._texture;
529 Texture *other_texture = (*osi)._texture;
531 if (texture != other_texture) {
532 return texture < other_texture ? -1 : 1;
535 int implicit_sort = (*si)._implicit_sort;
536 int other_implicit_sort = (*osi)._implicit_sort;
538 if (implicit_sort != other_implicit_sort) {
539 return implicit_sort < other_implicit_sort ? -1 : 1;
542 int override = (*si)._override;
543 int other_override = (*osi)._override;
545 if (
override != other_override) {
546 return override < other_override ? -1 : 1;
549 int has_sampler = (*si)._has_sampler;
550 int other_has_sampler = (*osi)._has_sampler;
552 if (has_sampler != other_has_sampler) {
553 return has_sampler < other_has_sampler ? -1 : 1;
560 if (sampler != other_sampler) {
561 return sampler < other_sampler ? -1 : 1;
569 if (si != _on_stages.
end()) {
572 if (osi != ta->_on_stages.
end()) {
577 Stages::const_iterator fi = _off_stages.
begin();
578 Stages::const_iterator ofi = ta->_off_stages.
begin();
580 while (fi != _off_stages.
end() && ofi != ta->_off_stages.
end()) {
584 if (stage != other_stage) {
585 return stage < other_stage ? -1 : 1;
588 int override = (*fi)._override;
589 int other_override = (*ofi)._override;
591 if (
override != other_override) {
592 return override < other_override ? -1 : 1;
599 if (fi != _off_stages.
end()) {
602 if (ofi != ta->_off_stages.
end()) {
619 size_t TextureAttrib::
620 get_hash_impl()
const {
624 Stages::const_iterator si;
625 for (si = _on_stages.
begin(); si != _on_stages.
end(); ++si) {
626 const StageNode &sn = (*si);
638 for (si = _off_stages.
begin(); si != _off_stages.
end(); ++si) {
639 const StageNode &sn = (*si);
668 DCAST_INTO_R(ta, other, 0);
670 if (ta->_off_all_stages) {
679 Stages::const_iterator ai = _on_stages.
begin();
680 Stages::const_iterator bi = ta->_on_stages.
begin();
681 Stages::const_iterator ci = ta->_off_stages.
begin();
686 while (ai != _on_stages.
end() &&
687 bi != ta->_on_stages.
end() &&
688 ci != ta->_off_stages.
end()) {
689 if ((*ai)._stage < (*bi)._stage) {
690 if ((*ai)._stage < (*ci)._stage) {
693 attrib->_on_stages.insert(attrib->_on_stages.
end(), *ai);
696 }
else if ((*ci)._stage < (*ai)._stage) {
704 if ((*ai)._override > (*ci)._override) {
706 attrib->_on_stages.insert(attrib->_on_stages.
end(), *ai);
713 }
else if ((*bi)._stage < (*ai)._stage) {
716 attrib->_on_stages.insert(attrib->_on_stages.
end(), *bi);
721 if ((*ai)._override > (*bi)._override) {
722 attrib->_on_stages.insert(attrib->_on_stages.
end(), *ai);
724 attrib->_on_stages.insert(attrib->_on_stages.
end(), *bi);
731 while (ai != _on_stages.
end() && bi != ta->_on_stages.
end()) {
732 if ((*ai)._stage < (*bi)._stage) {
735 attrib->_on_stages.insert(attrib->_on_stages.
end(), *ai);
738 }
else if ((*bi)._stage < (*ai)._stage) {
741 attrib->_on_stages.insert(attrib->_on_stages.
end(), *bi);
746 if ((*ai)._override > (*bi)._override) {
747 attrib->_on_stages.insert(attrib->_on_stages.
end(), *ai);
749 attrib->_on_stages.insert(attrib->_on_stages.
end(), *bi);
756 while (ai != _on_stages.
end() && ci != ta->_off_stages.
end()) {
757 if ((*ai)._stage < (*ci)._stage) {
760 attrib->_on_stages.insert(attrib->_on_stages.
end(), *ai);
763 }
else if ((*ci)._stage < (*ai)._stage) {
771 if ((*ai)._override > (*ci)._override) {
773 attrib->_on_stages.insert(attrib->_on_stages.
end(), *ai);
780 while (ai != _on_stages.
end()) {
781 attrib->_on_stages.insert(attrib->_on_stages.
end(), *ai);
785 while (bi != ta->_on_stages.
end()) {
786 attrib->_on_stages.insert(attrib->_on_stages.
end(), *bi);
790 attrib->_next_implicit_sort = _next_implicit_sort + ta->_next_implicit_sort;
794 return return_new(attrib);
820 get_auto_shader_attrib_impl(
const RenderState *state)
const {
831 register_with_read_factory() {
848 Stages::const_iterator fi;
849 for (fi = _off_stages.
begin(); fi != _off_stages.
end(); ++fi) {
856 Stages::const_iterator si;
857 for (si = _on_stages.
begin(); si != _on_stages.
end(); ++si) {
860 nassertv(tex != (
Texture *)NULL);
867 if ((*si)._has_sampler) {
868 (*si)._sampler.write_datagram(dg);
885 for (ci = _off_stages.
begin(); ci != _off_stages.
end(); ++ci) {
891 while (sni < _on_stages.
size()) {
901 StageNode &sn = _on_stages[sni];
910 _on_stages.erase(_on_stages.
begin() + sni);
934 parse_params(params, scan, manager);
935 attrib->fillin(scan, manager);
949 RenderAttrib::fillin(scan, manager);
958 _off_stages.
reserve(num_off_stages);
959 for (i = 0; i < num_off_stages; i++) {
970 _on_stages.
reserve(num_on_stages);
971 _next_implicit_sort = 0;
972 for (i = 0; i < num_on_stages; i++) {
975 unsigned int implicit_sort;
979 implicit_sort = (
unsigned int)i;
986 _next_implicit_sort = max(_next_implicit_sort, implicit_sort + 1);
987 Stages::iterator si =
988 _on_stages.insert_nonunique(StageNode(NULL, _next_implicit_sort,
override));
989 ++_next_implicit_sort;
992 (*si)._has_sampler = scan.
get_bool();
993 if ((*si)._has_sampler) {
994 (*si)._sampler.read_datagram(scan, manager);
1007 void TextureAttrib::
1010 UsedTexcoordIndex used_texcoord_index;
1012 _render_stages.clear();
1013 _render_ff_stages.clear();
1015 Stages::iterator si;
1016 for (si = _on_stages.
begin(); si != _on_stages.
end(); ++si) {
1017 StageNode &sn = (*si);
1019 Texture *texture = sn._texture;
1020 nassertv(stage != NULL);
1021 nassertv(texture != NULL);
1029 UsedTexcoordIndex::iterator ti = used_texcoord_index.insert(UsedTexcoordIndex::value_type(name, (
int)used_texcoord_index.size())).first;
1030 (*si)._ff_tc_index = (*ti).second;
1032 _render_ff_stages.push_back(&sn);
1034 (*si)._ff_tc_index = -1;
1037 _render_stages.push_back(&sn);
1040 sort(_render_stages.begin(), _render_stages.end(), CompareTextureStageSort());
1041 sort(_render_ff_stages.begin(), _render_ff_stages.end(), CompareTextureStageSort());
static size_t add_hash(size_t start, const void *key)
Adds the indicated key into a running hash.
This is our own Panda specialization on the default STL map.
bool get_bool()
Extracts a boolean value.
This is the base class for a number of render attributes (other than transform) that may be set on sc...
TextureType get_texture_type() const
Returns the overall interpretation of the texture.
static UpdateSeq get_sort_seq()
Returns a global sequence number that is incremented any time any TextureStage in the world changes s...
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
size_type_0 size() const
Returns the number of elements in the ordered vector.
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
Base class for objects that can be written to and read from Bam files.
iterator_0 begin()
Returns the iterator that marks the first element in the ordered vector.
This collects together the pieces of data that are accumulated for each node while walking the scene ...
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
iterator_0 end()
Returns the iterator that marks the end of the ordered vector.
PN_int32 get_int32()
Extracts a signed 32-bit integer.
void reserve(size_type_0 n)
Informs the vector of a planned change in size; ensures that the capacity of the vector is greater th...
bool empty() const
Returns true if the ordered vector is empty, false otherwise.
virtual bool lower_attrib_can_override() const
Intended to be overridden by derived RenderAttrib types to specify how two consecutive RenderAttrib o...
int get_file_minor_ver() const
Returns the minor version number of the Bam file currently being read.
PN_uint16 get_uint16()
Extracts an unsigned 16-bit integer.
virtual bool has_cull_callback() const
Should be overridden by derived classes to return true if cull_callback() has been defined...
Indicates the set of TextureStages and their associated Textures that should be applied to (or remove...
This is our own Panda specialization on the default STL vector.
static size_t add_hash(size_t start, const Key &key)
Adds the indicated key into a running hash.
virtual int complete_pointers(TypedWritable **plist, BamReader *manager)
Receives an array of pointers, one for each time manager->read_pointer() was called in fillin()...
virtual bool cull_callback(CullTraverser *trav, const CullTraverserData &data) const
If has_cull_callback() returns true, this function will be called during the cull traversal to perfor...
virtual bool cull_callback(CullTraverser *trav, const CullTraverserData &data) const
If has_cull_callback() returns true, this function will be called during the cull traversal to perfor...
void add_bool(bool value)
Adds a boolean value to the 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.
int find_on_stage(const TextureStage *stage) const
Returns the index number of the indicated TextureStage within the list of on_stages, or -1 if the indicated stage is not listed.
int get_num_off_stages() const
Returns the number of stages that are turned off by the attribute.
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()...
bool is_fixed_function() const
Returns true if the TextureStage is relevant to the classic fixed function pipeline.
void sort()
Maps to sort_unique().
An instance of this class is passed to the Factory when requesting it to do its business and construc...
InternalName * get_texcoord_name() const
See set_texcoord_name.
void push_back(const value_type_0 &key)
Adds the new element to the end of the vector without regard for proper sorting.
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
void register_factory(TypeHandle handle, CreateFunc *func)
Registers a new kind of thing the Factory will be able to create.
void add_uint16(PN_uint16 value)
Adds an unsigned 16-bit integer to the datagram.
static UpdateSeq old()
Returns an UpdateSeq in the 'old' state.
Represents a set of settings that indicate how a texture is sampled.
const string & get_name() const
Returns the name of this texture stage.
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
int get_num_on_stages() const
Returns the number of stages that are turned on by the attribute.
void add_int32(PN_int32 value)
Adds a signed 32-bit integer to the datagram.
A class to retrieve the individual data elements previously stored in a Datagram. ...
TypeHandle is the identifier used to differentiate C++ class types.
static TextureStage * get_default()
Returns the default TextureStage that will be used for all texturing that does not name a particular ...
Defines the properties of a named stage of the multitexture pipeline.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
This object performs a depth-first traversal of the scene graph, with optional view-frustum culling...
virtual bool has_cull_callback() const
Should be overridden by derived classes to return true if cull_callback() has been defined...
static TextureStage * get_stage(TextureStage *temp)
Returns a TextureStage pointer that represents the same TextureStage described by temp...
void write_pointer(Datagram &packet, const TypedWritable *dest)
The interface for writing a pointer to another object to a Bam file.
void read_pointer(DatagramIterator &scan)
The interface for reading a pointer to another object from a Bam file.