27 int TextureAttrib::_attrib_slot;
45 return make_all_off();
55 if (_empty_attrib ==
nullptr) {
70 if (_all_off_attrib ==
nullptr) {
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);
112 Stages::iterator si = attrib->_on_stages.insert(StageNode(stage)).first;
113 (*si)._override =
override;
114 (*si)._texture = tex;
115 (*si)._implicit_sort = attrib->_next_implicit_sort;
116 (*si)._has_sampler =
false;
117 ++(attrib->_next_implicit_sort);
119 return return_new(attrib);
128 nassertr(tex !=
nullptr,
this);
131 Stages::iterator si = attrib->_on_stages.insert(StageNode(stage)).first;
132 (*si)._override =
override;
133 (*si)._texture = tex;
134 (*si)._sampler = sampler;
135 (*si)._implicit_sort = attrib->_next_implicit_sort;
136 (*si)._has_sampler =
true;
137 ++(attrib->_next_implicit_sort);
139 return return_new(attrib);
150 Stages::iterator si = attrib->_on_stages.find(StageNode(stage));
151 if (si != attrib->_on_stages.
end()) {
152 attrib->_on_stages.erase(si);
155 return return_new(attrib);
163 add_off_stage(
TextureStage *stage,
int override)
const {
165 if (!_off_all_stages) {
167 Stages::iterator sfi = attrib->_off_stages.insert(sn).first;
168 (*sfi)._override =
override;
171 Stages::iterator si = attrib->_on_stages.find(sn);
172 if (si != attrib->_on_stages.
end()) {
173 attrib->_on_stages.erase(si);
176 return return_new(attrib);
186 attrib->_off_stages.erase(StageNode(stage));
187 return return_new(attrib);
199 attrib->_off_all_stages = _off_all_stages;
200 bool any_changed =
false;
202 Stages::const_iterator si;
203 for (si = _on_stages.
begin(); si != _on_stages.
end(); ++si) {
211 Stages::iterator osi = attrib->_on_stages.insert(StageNode(this_stage)).first;
212 (*osi)._texture = (*si)._texture;
213 (*osi)._ff_tc_index = (*si)._ff_tc_index;
214 (*osi)._implicit_sort = (*si)._implicit_sort;
215 (*osi)._override = (*si)._override;
218 attrib->_next_implicit_sort = _next_implicit_sort;
220 Stages::const_iterator fsi;
221 for (fsi = _off_stages.
begin(); fsi != _off_stages.
end(); ++fsi) {
224 if (this_stage != stage &&
230 attrib->_off_stages.insert(StageNode(this_stage));
237 return return_new(attrib);
250 for (
size_t i = 0; i < _on_stages.
size(); ++i) {
251 const StageNode &sn = _on_stages[i];
252 if (sn._texture == tex) {
253 if (attrib ==
nullptr) {
257 attrib->_on_stages[i]._texture = new_tex;
261 if (attrib !=
nullptr) {
262 return return_new(attrib);
274 filter_to_max(
int max_texture_stages)
const {
275 if ((
int)_on_stages.
size() <= max_texture_stages) {
285 Filtered::const_iterator fi;
286 fi = _filtered.find(max_texture_stages);
287 if (fi != _filtered.end()) {
298 RenderStages priority_stages = _render_stages;
301 sort(priority_stages.begin(), priority_stages.end(),
302 CompareTextureStagePriorities());
305 priority_stages.erase(priority_stages.begin() + max_texture_stages,
306 priority_stages.end());
311 RenderStages::const_iterator ri;
312 for (ri = priority_stages.begin(); ri != priority_stages.end(); ++ri) {
313 attrib->_on_stages.insert(*(*ri));
316 attrib->_next_implicit_sort = _next_implicit_sort;
326 ((
TextureAttrib *)
this)->_filtered[max_texture_stages] = tex_attrib;
363 output(std::ostream &out)
const {
366 out << get_type() <<
":";
367 if (_off_stages.
empty()) {
368 if (_on_stages.
empty()) {
369 if (_off_all_stages) {
375 if (_off_all_stages) {
384 Stages::const_iterator fi;
385 for (fi = _off_stages.
begin(); fi != _off_stages.
end(); ++fi) {
388 if ((*fi)._override != 0) {
389 out <<
"^" << (*fi)._override;
393 if (!_on_stages.
empty()) {
398 RenderStages::const_iterator ri;
399 for (ri = _render_stages.begin(); ri != _render_stages.end(); ++ri) {
400 const StageNode &sn = *(*ri);
404 if (tex !=
nullptr) {
405 out <<
":" << tex->get_name();
407 if (sn._override != 0) {
408 out <<
"^" << sn._override;
420 Stages::const_iterator si;
421 for (si = _on_stages.
begin(); si != _on_stages.
end(); ++si) {
422 Texture *texture = (*si)._texture;
442 Stages::const_iterator si;
443 for (si = _on_stages.
begin(); si != _on_stages.
end(); ++si) {
444 Texture *texture = (*si)._texture;
469 if (_off_all_stages != ta->_off_all_stages) {
470 return (
int)_off_all_stages - (int)ta->_off_all_stages;
473 Stages::const_iterator si = _on_stages.
begin();
474 Stages::const_iterator osi = ta->_on_stages.
begin();
476 while (si != _on_stages.
end() && osi != ta->_on_stages.
end()) {
480 if (stage != other_stage) {
481 return stage < other_stage ? -1 : 1;
484 Texture *texture = (*si)._texture;
485 Texture *other_texture = (*osi)._texture;
487 if (texture != other_texture) {
488 return texture < other_texture ? -1 : 1;
491 int implicit_sort = (*si)._implicit_sort;
492 int other_implicit_sort = (*osi)._implicit_sort;
494 if (implicit_sort != other_implicit_sort) {
495 return implicit_sort < other_implicit_sort ? -1 : 1;
498 int override = (*si)._override;
499 int other_override = (*osi)._override;
501 if (
override != other_override) {
502 return override < other_override ? -1 : 1;
505 int has_sampler = (*si)._has_sampler;
506 int other_has_sampler = (*osi)._has_sampler;
508 if (has_sampler != other_has_sampler) {
509 return has_sampler < other_has_sampler ? -1 : 1;
516 if (sampler != other_sampler) {
517 return sampler < other_sampler ? -1 : 1;
525 if (si != _on_stages.
end()) {
528 if (osi != ta->_on_stages.
end()) {
533 Stages::const_iterator fi = _off_stages.
begin();
534 Stages::const_iterator ofi = ta->_off_stages.
begin();
536 while (fi != _off_stages.
end() && ofi != ta->_off_stages.
end()) {
540 if (stage != other_stage) {
541 return stage < other_stage ? -1 : 1;
544 int override = (*fi)._override;
545 int other_override = (*ofi)._override;
547 if (
override != other_override) {
548 return override < other_override ? -1 : 1;
555 if (fi != _off_stages.
end()) {
558 if (ofi != ta->_off_stages.
end()) {
571 size_t TextureAttrib::
572 get_hash_impl()
const {
576 Stages::const_iterator si;
577 for (si = _on_stages.
begin(); si != _on_stages.
end(); ++si) {
578 const StageNode &sn = (*si);
590 for (si = _off_stages.
begin(); si != _off_stages.
end(); ++si) {
591 const StageNode &sn = (*si);
615 if (ta->_off_all_stages) {
623 Stages::const_iterator ai = _on_stages.
begin();
624 Stages::const_iterator bi = ta->_on_stages.
begin();
625 Stages::const_iterator ci = ta->_off_stages.
begin();
630 while (ai != _on_stages.
end() &&
631 bi != ta->_on_stages.
end() &&
632 ci != ta->_off_stages.
end()) {
633 if ((*ai)._stage < (*bi)._stage) {
634 if ((*ai)._stage < (*ci)._stage) {
637 attrib->_on_stages.insert(attrib->_on_stages.
end(), *ai);
640 }
else if ((*ci)._stage < (*ai)._stage) {
648 if ((*ai)._override > (*ci)._override) {
650 attrib->_on_stages.insert(attrib->_on_stages.
end(), *ai);
657 }
else if ((*bi)._stage < (*ai)._stage) {
660 attrib->_on_stages.insert(attrib->_on_stages.
end(), *bi);
665 if ((*ai)._override > (*bi)._override) {
666 attrib->_on_stages.insert(attrib->_on_stages.
end(), *ai);
668 attrib->_on_stages.insert(attrib->_on_stages.
end(), *bi);
675 while (ai != _on_stages.
end() && bi != ta->_on_stages.
end()) {
676 if ((*ai)._stage < (*bi)._stage) {
679 attrib->_on_stages.insert(attrib->_on_stages.
end(), *ai);
682 }
else if ((*bi)._stage < (*ai)._stage) {
685 attrib->_on_stages.insert(attrib->_on_stages.
end(), *bi);
690 if ((*ai)._override > (*bi)._override) {
691 attrib->_on_stages.insert(attrib->_on_stages.
end(), *ai);
693 attrib->_on_stages.insert(attrib->_on_stages.
end(), *bi);
700 while (ai != _on_stages.
end() && ci != ta->_off_stages.
end()) {
701 if ((*ai)._stage < (*ci)._stage) {
704 attrib->_on_stages.insert(attrib->_on_stages.
end(), *ai);
707 }
else if ((*ci)._stage < (*ai)._stage) {
715 if ((*ai)._override > (*ci)._override) {
717 attrib->_on_stages.insert(attrib->_on_stages.
end(), *ai);
724 while (ai != _on_stages.
end()) {
725 attrib->_on_stages.insert(attrib->_on_stages.
end(), *ai);
729 while (bi != ta->_on_stages.
end()) {
730 attrib->_on_stages.insert(attrib->_on_stages.
end(), *bi);
734 attrib->_next_implicit_sort = _next_implicit_sort + ta->_next_implicit_sort;
735 attrib->_sort_seq = UpdateSeq::old();
736 attrib->_filtered_seq = UpdateSeq::old();
738 return return_new(attrib);
759 register_with_read_factory() {
774 Stages::const_iterator fi;
775 for (fi = _off_stages.
begin(); fi != _off_stages.
end(); ++fi) {
782 Stages::const_iterator si;
783 for (si = _on_stages.
begin(); si != _on_stages.
end(); ++si) {
786 nassertv(tex !=
nullptr);
798 if ((*si)._has_sampler) {
799 (*si)._sampler.write_datagram(dg);
814 for (ci = _off_stages.
begin(); ci != _off_stages.
end(); ++ci) {
820 while (sni < _on_stages.
size()) {
829 if (tex !=
nullptr) {
830 StageNode &sn = _on_stages[sni];
839 _on_stages.erase(_on_stages.
begin() + sni);
844 _sort_seq = UpdateSeq::old();
845 _filtered_seq = UpdateSeq::old();
862 attrib->fillin(scan, manager);
873 RenderAttrib::fillin(scan, manager);
882 _off_stages.
reserve(num_off_stages);
883 for (i = 0; i < num_off_stages; i++) {
885 _off_stages.
push_back(StageNode(
nullptr));
893 _on_stages.
reserve(num_on_stages);
894 _next_implicit_sort = 0;
895 for (i = 0; i < num_on_stages; i++) {
898 unsigned int implicit_sort;
902 implicit_sort = (
unsigned int)i;
909 _next_implicit_sort = std::max(_next_implicit_sort, implicit_sort + 1);
910 Stages::iterator si =
911 _on_stages.insert_nonunique(StageNode(
nullptr, _next_implicit_sort,
override));
912 ++_next_implicit_sort;
915 (*si)._has_sampler = scan.
get_bool();
916 if ((*si)._has_sampler) {
917 (*si)._sampler.read_datagram(scan, manager);
931 UsedTexcoordIndex used_texcoord_index;
933 _render_stages.clear();
934 _render_ff_stages.clear();
937 for (si = _on_stages.
begin(); si != _on_stages.
end(); ++si) {
938 StageNode &sn = (*si);
940 Texture *texture = sn._texture;
941 nassertv(stage !=
nullptr);
942 nassertv(texture !=
nullptr);
950 UsedTexcoordIndex::iterator ti = used_texcoord_index.insert(UsedTexcoordIndex::value_type(name, (
int)used_texcoord_index.size())).first;
951 (*si)._ff_tc_index = (*ti).second;
953 _render_ff_stages.push_back(&sn);
955 (*si)._ff_tc_index = -1;
958 _render_stages.push_back(&sn);
961 sort(_render_stages.begin(), _render_stages.end(), CompareTextureStageSort());
962 sort(_render_ff_stages.begin(), _render_ff_stages.end(), CompareTextureStageSort());