27int TextureAttrib::_attrib_slot;
55 if (_empty_attrib ==
nullptr) {
56 _empty_attrib = return_new(
new TextureAttrib);
70 if (_all_off_attrib ==
nullptr) {
71 TextureAttrib *attrib =
new TextureAttrib;
72 attrib->_off_all_stages =
true;
73 _all_off_attrib = return_new(attrib);
76 return _all_off_attrib;
95 Stages::const_iterator si = _on_stages.find(StageNode(stage));
96 if (si != _on_stages.end()) {
97 return (
int)(si - _on_stages.begin());
109 nassertr(tex !=
nullptr,
this);
111 TextureAttrib *attrib =
new TextureAttrib(*
this);
112 auto result = attrib->_on_stages.insert(StageNode(stage));
113 StageNode &sn = *result.first;
114 sn._override =
override;
116 sn._has_sampler =
false;
120 if (result.second || sn._implicit_sort + 1 != attrib->_next_implicit_sort) {
121 sn._implicit_sort = attrib->_next_implicit_sort;
122 ++(attrib->_next_implicit_sort);
125 return return_new(attrib);
134 nassertr(tex !=
nullptr,
this);
136 TextureAttrib *attrib =
new TextureAttrib(*
this);
137 auto result = attrib->_on_stages.insert(StageNode(stage));
138 StageNode &sn = *result.first;
139 sn._override =
override;
141 sn._sampler = sampler;
142 sn._has_sampler =
true;
146 if (result.second || sn._implicit_sort + 1 != attrib->_next_implicit_sort) {
147 sn._implicit_sort = attrib->_next_implicit_sort;
148 ++(attrib->_next_implicit_sort);
151 return return_new(attrib);
160 TextureAttrib *attrib =
new TextureAttrib(*
this);
162 Stages::iterator si = attrib->_on_stages.find(StageNode(stage));
163 if (si != attrib->_on_stages.
end()) {
164 attrib->_on_stages.erase(si);
167 return return_new(attrib);
176 TextureAttrib *attrib =
new TextureAttrib(*
this);
177 if (!_off_all_stages) {
179 Stages::iterator sfi = attrib->_off_stages.insert(sn).first;
180 (*sfi)._override =
override;
183 Stages::iterator si = attrib->_on_stages.find(sn);
184 if (si != attrib->_on_stages.
end()) {
185 attrib->_on_stages.erase(si);
188 return return_new(attrib);
197 TextureAttrib *attrib =
new TextureAttrib(*
this);
198 attrib->_off_stages.erase(StageNode(stage));
199 return return_new(attrib);
209 PT(TextureAttrib) attrib =
new TextureAttrib;
211 attrib->_off_all_stages = _off_all_stages;
212 bool any_changed =
false;
214 Stages::const_iterator si;
215 for (si = _on_stages.begin(); si != _on_stages.end(); ++si) {
223 Stages::iterator osi = attrib->_on_stages.insert(StageNode(this_stage)).first;
224 (*osi)._texture = (*si)._texture;
225 (*osi)._ff_tc_index = (*si)._ff_tc_index;
226 (*osi)._implicit_sort = (*si)._implicit_sort;
227 (*osi)._override = (*si)._override;
230 attrib->_next_implicit_sort = _next_implicit_sort;
232 Stages::const_iterator fsi;
233 for (fsi = _off_stages.begin(); fsi != _off_stages.end(); ++fsi) {
236 if (this_stage != stage &&
242 attrib->_off_stages.insert(StageNode(this_stage));
249 return return_new(attrib);
262 TextureAttrib *attrib =
nullptr;
265 for (
size_t i = 0; i < _on_stages.size(); ++i) {
266 const StageNode &sn = _on_stages[i];
267 if (sn._texture == tex) {
268 if (attrib ==
nullptr) {
269 attrib =
new TextureAttrib(*
this);
272 if (new_tex !=
nullptr) {
273 attrib->_on_stages[j]._texture = new_tex;
275 attrib->_on_stages.erase(attrib->_on_stages.
begin() + j);
282 if (attrib !=
nullptr) {
283 return return_new(attrib);
296 if ((
int)_on_stages.size() <= max_texture_stages) {
302 ((TextureAttrib *)
this)->_filtered.clear();
306 Filtered::const_iterator fi;
307 fi = _filtered.find(max_texture_stages);
308 if (fi != _filtered.end()) {
319 RenderStages priority_stages = _render_stages;
322 sort(priority_stages.begin(), priority_stages.end(),
323 CompareTextureStagePriorities());
326 priority_stages.erase(priority_stages.begin() + max_texture_stages,
327 priority_stages.end());
330 PT(TextureAttrib) attrib =
new TextureAttrib;
332 RenderStages::const_iterator ri;
333 for (ri = priority_stages.begin(); ri != priority_stages.end(); ++ri) {
334 attrib->_on_stages.insert(*(*ri));
337 attrib->_next_implicit_sort = _next_implicit_sort;
339 CPT(RenderAttrib) new_attrib = return_new(attrib);
346 CPT(TextureAttrib) tex_attrib = (
const TextureAttrib *)new_attrib.p();
347 ((TextureAttrib *)
this)->_filtered[max_texture_stages] = tex_attrib;
384output(std::ostream &out)
const {
387 out << get_type() <<
":";
388 if (_off_stages.
empty()) {
389 if (_on_stages.
empty()) {
390 if (_off_all_stages) {
396 if (_off_all_stages) {
405 Stages::const_iterator fi;
406 for (fi = _off_stages.begin(); fi != _off_stages.end(); ++fi) {
407 TextureStage *stage = (*fi)._stage;
409 if ((*fi)._override != 0) {
410 out <<
"^" << (*fi)._override;
414 if (!_on_stages.empty()) {
419 RenderStages::const_iterator ri;
420 for (ri = _render_stages.begin(); ri != _render_stages.end(); ++ri) {
421 const StageNode &sn = *(*ri);
422 TextureStage *stage = sn._stage;
423 Texture *tex = sn._texture;
425 if (tex !=
nullptr) {
426 out <<
":" << tex->get_name();
428 if (sn._override != 0) {
429 out <<
"^" << sn._override;
441 Stages::const_iterator si;
442 for (si = _on_stages.begin(); si != _on_stages.end(); ++si) {
443 Texture *texture = (*si)._texture;
463 Stages::const_iterator si;
464 for (si = _on_stages.begin(); si != _on_stages.end(); ++si) {
465 Texture *texture = (*si)._texture;
490 if (_off_all_stages != ta->_off_all_stages) {
491 return (
int)_off_all_stages - (int)ta->_off_all_stages;
494 Stages::const_iterator si = _on_stages.begin();
495 Stages::const_iterator osi = ta->_on_stages.
begin();
497 while (si != _on_stages.end() && osi != ta->_on_stages.
end()) {
498 TextureStage *stage = (*si)._stage;
499 TextureStage *other_stage = (*osi)._stage;
501 if (stage != other_stage) {
502 return stage < other_stage ? -1 : 1;
505 Texture *texture = (*si)._texture;
506 Texture *other_texture = (*osi)._texture;
508 if (texture != other_texture) {
509 return texture < other_texture ? -1 : 1;
512 int implicit_sort = (*si)._implicit_sort;
513 int other_implicit_sort = (*osi)._implicit_sort;
515 if (implicit_sort != other_implicit_sort) {
516 return implicit_sort < other_implicit_sort ? -1 : 1;
519 int override = (*si)._override;
520 int other_override = (*osi)._override;
522 if (
override != other_override) {
523 return override < other_override ? -1 : 1;
526 int has_sampler = (*si)._has_sampler;
527 int other_has_sampler = (*osi)._has_sampler;
529 if (has_sampler != other_has_sampler) {
530 return has_sampler < other_has_sampler ? -1 : 1;
534 const SamplerState &sampler = (*si)._sampler;
535 const SamplerState &other_sampler = (*osi)._sampler;
537 if (sampler != other_sampler) {
538 return sampler < other_sampler ? -1 : 1;
546 if (si != _on_stages.end()) {
549 if (osi != ta->_on_stages.
end()) {
554 Stages::const_iterator fi = _off_stages.begin();
555 Stages::const_iterator ofi = ta->_off_stages.
begin();
557 while (fi != _off_stages.end() && ofi != ta->_off_stages.
end()) {
558 TextureStage *stage = (*fi)._stage;
559 TextureStage *other_stage = (*ofi)._stage;
561 if (stage != other_stage) {
562 return stage < other_stage ? -1 : 1;
565 int override = (*fi)._override;
566 int other_override = (*ofi)._override;
568 if (
override != other_override) {
569 return override < other_override ? -1 : 1;
576 if (fi != _off_stages.end()) {
579 if (ofi != ta->_off_stages.
end()) {
592size_t TextureAttrib::
593get_hash_impl()
const {
597 Stages::const_iterator si;
598 for (si = _on_stages.begin(); si != _on_stages.end(); ++si) {
599 const StageNode &sn = (*si);
611 for (si = _off_stages.begin(); si != _off_stages.end(); ++si) {
612 const StageNode &sn = (*si);
634 const TextureAttrib *ta = (
const TextureAttrib *)other;
636 if (ta->_off_all_stages) {
644 Stages::const_iterator ai = _on_stages.begin();
645 Stages::const_iterator bi = ta->_on_stages.
begin();
646 Stages::const_iterator ci = ta->_off_stages.
begin();
649 TextureAttrib *attrib =
new TextureAttrib;
651 while (ai != _on_stages.end() &&
652 bi != ta->_on_stages.
end() &&
653 ci != ta->_off_stages.
end()) {
654 if ((*ai)._stage < (*bi)._stage) {
655 if ((*ai)._stage < (*ci)._stage) {
658 attrib->_on_stages.insert(attrib->_on_stages.
end(), *ai);
661 }
else if ((*ci)._stage < (*ai)._stage) {
669 if ((*ai)._override > (*ci)._override) {
671 attrib->_on_stages.insert(attrib->_on_stages.
end(), *ai);
678 }
else if ((*bi)._stage < (*ai)._stage) {
681 attrib->_on_stages.insert(attrib->_on_stages.
end(), *bi);
686 if ((*ai)._override > (*bi)._override) {
687 attrib->_on_stages.insert(attrib->_on_stages.
end(), *ai);
689 attrib->_on_stages.insert(attrib->_on_stages.
end(), *bi);
696 while (ai != _on_stages.end() && bi != ta->_on_stages.
end()) {
697 if ((*ai)._stage < (*bi)._stage) {
700 attrib->_on_stages.insert(attrib->_on_stages.
end(), *ai);
703 }
else if ((*bi)._stage < (*ai)._stage) {
706 attrib->_on_stages.insert(attrib->_on_stages.
end(), *bi);
711 if ((*ai)._override > (*bi)._override) {
712 attrib->_on_stages.insert(attrib->_on_stages.
end(), *ai);
714 attrib->_on_stages.insert(attrib->_on_stages.
end(), *bi);
721 while (ai != _on_stages.end() && ci != ta->_off_stages.
end()) {
722 if ((*ai)._stage < (*ci)._stage) {
725 attrib->_on_stages.insert(attrib->_on_stages.
end(), *ai);
728 }
else if ((*ci)._stage < (*ai)._stage) {
736 if ((*ai)._override > (*ci)._override) {
738 attrib->_on_stages.insert(attrib->_on_stages.
end(), *ai);
745 while (ai != _on_stages.end()) {
746 attrib->_on_stages.insert(attrib->_on_stages.
end(), *ai);
750 while (bi != ta->_on_stages.
end()) {
751 attrib->_on_stages.insert(attrib->_on_stages.
end(), *bi);
755 attrib->_next_implicit_sort = _next_implicit_sort + ta->_next_implicit_sort;
756 attrib->_sort_seq = UpdateSeq::old();
757 attrib->_filtered_seq = UpdateSeq::old();
759 return return_new(attrib);
795 Stages::const_iterator fi;
796 for (fi = _off_stages.begin(); fi != _off_stages.end(); ++fi) {
803 Stages::const_iterator si;
804 for (si = _on_stages.begin(); si != _on_stages.end(); ++si) {
807 nassertv(tex !=
nullptr);
819 if ((*si)._has_sampler) {
820 (*si)._sampler.write_datagram(dg);
835 for (ci = _off_stages.begin(); ci != _off_stages.end(); ++ci) {
841 while (sni < _on_stages.size()) {
850 if (tex !=
nullptr) {
851 StageNode &sn = _on_stages[sni];
859 _off_stages.push_back(StageNode(ts));
860 _on_stages.erase(_on_stages.begin() + sni);
865 _sort_seq = UpdateSeq::old();
866 _filtered_seq = UpdateSeq::old();
883 attrib->fillin(scan, manager);
894 RenderAttrib::fillin(scan, manager);
903 _off_stages.reserve(num_off_stages);
904 for (i = 0; i < num_off_stages; i++) {
906 _off_stages.push_back(StageNode(
nullptr));
914 _on_stages.reserve(num_on_stages);
915 _next_implicit_sort = 0;
916 for (i = 0; i < num_on_stages; i++) {
919 unsigned int implicit_sort;
923 implicit_sort = (
unsigned int)i;
930 _next_implicit_sort = std::max(_next_implicit_sort, implicit_sort + 1);
931 Stages::iterator si =
932 _on_stages.insert_nonunique(StageNode(
nullptr, _next_implicit_sort,
override));
933 ++_next_implicit_sort;
936 (*si)._has_sampler = scan.
get_bool();
937 if ((*si)._has_sampler) {
938 (*si)._sampler.read_datagram(scan, manager);
951 typedef pmap<const InternalName *, int> UsedTexcoordIndex;
952 UsedTexcoordIndex used_texcoord_index;
954 _render_stages.clear();
955 _render_ff_stages.clear();
958 for (si = _on_stages.begin(); si != _on_stages.end(); ++si) {
959 StageNode &sn = (*si);
960 TextureStage *stage = sn._stage;
961 Texture *texture = sn._texture;
962 nassertv(stage !=
nullptr);
963 nassertv(texture !=
nullptr);
971 UsedTexcoordIndex::iterator ti = used_texcoord_index.insert(UsedTexcoordIndex::value_type(name, (
int)used_texcoord_index.size())).first;
972 (*si)._ff_tc_index = (*ti).second;
974 _render_ff_stages.push_back(&sn);
976 (*si)._ff_tc_index = -1;
979 _render_stages.push_back(&sn);
982 sort(_render_stages.begin(), _render_stages.end(), CompareTextureStageSort());
983 sort(_render_ff_stages.begin(), _render_ff_stages.end(), CompareTextureStageSort());
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void parse_params(const FactoryParams ¶ms, DatagramIterator &scan, BamReader *&manager)
Takes in a FactoryParams, passed from a WritableFactory into any TypedWritable's make function,...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
bool read_pointer(DatagramIterator &scan)
The interface for reading a pointer to another object from a Bam file.
int get_file_minor_ver() const
Returns the minor version number of the Bam file currently being read.
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
void write_pointer(Datagram &packet, const TypedWritable *dest)
The interface for writing a pointer to another object to a Bam file.
int get_file_minor_ver() const
Returns the minor version number of the Bam file currently being written.
This collects together the pieces of data that are accumulated for each node while walking the scene ...
This object performs a depth-first traversal of the scene graph, with optional view-frustum culling,...
A class to retrieve the individual data elements previously stored in a Datagram.
uint16_t get_uint16()
Extracts an unsigned 16-bit integer.
bool get_bool()
Extracts a boolean value.
int32_t get_int32()
Extracts a signed 32-bit integer.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
void add_int32(int32_t value)
Adds a signed 32-bit integer to the datagram.
void add_bool(bool value)
Adds a boolean value to the datagram.
void add_uint16(uint16_t value)
Adds an unsigned 16-bit integer to the datagram.
An instance of this class is passed to the Factory when requesting it to do its business and construc...
void register_factory(TypeHandle handle, CreateFunc *func, void *user_data=nullptr)
Registers a new kind of thing the Factory will be able to create.
This is the base class for a number of render attributes (other than transform) that may be set on sc...
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
Represents a set of settings that indicate how a texture is sampled.
Indicates the set of TextureStages and their associated Textures that should be applied to (or remove...
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
ConstPointerTo< TextureAttrib > filter_to_max(int max_texture_stages) const
Returns a new TextureAttrib, very much like this one, but with the number of on_stages reduced to be ...
ConstPointerTo< RenderAttrib > unify_texture_stages(TextureStage *stage) const
Returns a new TextureAttrib, just like this one, but with any included TextureAttribs that happen to ...
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...
get_num_on_stages
Returns the number of stages that are turned on by the attribute.
ConstPointerTo< RenderAttrib > remove_off_stage(TextureStage *stage) const
Returns a new TextureAttrib, just like this one, but with the indicated stage removed from the list o...
static void register_with_read_factory()
Tells the BamReader how to create objects of type TextureAttrib.
int find_on_stage(const TextureStage *stage) const
Returns the index number of the indicated TextureStage within the list of on_stages,...
ConstPointerTo< RenderAttrib > add_off_stage(TextureStage *stage, int override=0) const
Returns a new TextureAttrib, just like this one, but with the indicated stage added to the list of st...
static ConstPointerTo< RenderAttrib > make_all_off()
Constructs a new TextureAttrib object that turns off all stages (and hence disables texturing).
virtual int complete_pointers(TypedWritable **plist, BamReader *manager)
Receives an array of pointers, one for each time manager->read_pointer() was called in fillin().
static ConstPointerTo< RenderAttrib > make_default()
Returns a RenderAttrib that corresponds to whatever the standard default properties for render attrib...
virtual bool has_cull_callback() const
Should be overridden by derived classes to return true if cull_callback() has been defined.
static ConstPointerTo< RenderAttrib > make()
Constructs a new TextureAttrib object that does nothing.
virtual bool lower_attrib_can_override() const
Intended to be overridden by derived RenderAttrib types to specify how two consecutive RenderAttrib o...
ConstPointerTo< RenderAttrib > replace_texture(Texture *tex, Texture *new_tex) const
Returns a new TextureAttrib, just like this one, but with all references to the given texture replace...
ConstPointerTo< RenderAttrib > add_on_stage(TextureStage *stage, Texture *tex, int override=0) const
Returns a new TextureAttrib, just like this one, but with the indicated stage added to the list of st...
static ConstPointerTo< RenderAttrib > make_off()
Constructs a new TextureAttrib object suitable for rendering untextured geometry.
ConstPointerTo< RenderAttrib > remove_on_stage(TextureStage *stage) const
Returns a new TextureAttrib, just like this one, but with the indicated stage removed from the list o...
get_num_off_stages
Returns the number of stages that are turned off by the attribute.
static TextureStage * get_stage(TextureStage *temp)
Returns a TextureStage pointer that represents the same TextureStage described by temp,...
Defines the properties of a named stage of the multitexture pipeline.
get_default
Returns the default TextureStage that will be used for all texturing that does not name a particular ...
get_name
Returns the name of this texture stage.
bool is_fixed_function() const
Returns true if the TextureStage is relevant to the classic fixed function pipeline.
static UpdateSeq get_sort_seq()
Returns a global sequence number that is incremented any time any TextureStage in the world changes s...
get_texcoord_name
See set_texcoord_name.
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
get_texture_type
Returns the overall interpretation of the texture.
virtual bool has_cull_callback() const
Should be overridden by derived classes to return true if cull_callback() has been defined.
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...
TypeHandle is the identifier used to differentiate C++ class types.
Base class for objects that can be written to and read from Bam files.
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().
static size_t add_hash(size_t start, const int &key)
iterator_0 begin()
Returns the iterator that marks the first element in the ordered vector.
bool empty() const
Returns true if the ordered vector is empty, false otherwise.
iterator_0 end()
Returns the iterator that marks the end of the ordered vector.
static size_t add_hash(size_t start, const void *key)
Adds the indicated key into a running hash.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.