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 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);
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);
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);
175 add_off_stage(
TextureStage *stage,
int override)
const {
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);
198 attrib->_off_stages.erase(StageNode(stage));
199 return return_new(attrib);
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 for (
size_t i = 0; i < _on_stages.
size(); ++i) {
263 const StageNode &sn = _on_stages[i];
264 if (sn._texture == tex) {
265 if (attrib ==
nullptr) {
269 attrib->_on_stages[i]._texture = new_tex;
273 if (attrib !=
nullptr) {
274 return return_new(attrib);
286 filter_to_max(
int max_texture_stages)
const {
287 if ((
int)_on_stages.
size() <= max_texture_stages) {
297 Filtered::const_iterator fi;
298 fi = _filtered.find(max_texture_stages);
299 if (fi != _filtered.end()) {
310 RenderStages priority_stages = _render_stages;
313 sort(priority_stages.begin(), priority_stages.end(),
314 CompareTextureStagePriorities());
317 priority_stages.erase(priority_stages.begin() + max_texture_stages,
318 priority_stages.end());
323 RenderStages::const_iterator ri;
324 for (ri = priority_stages.begin(); ri != priority_stages.end(); ++ri) {
325 attrib->_on_stages.insert(*(*ri));
328 attrib->_next_implicit_sort = _next_implicit_sort;
338 ((
TextureAttrib *)
this)->_filtered[max_texture_stages] = tex_attrib;
375 output(std::ostream &out)
const {
378 out << get_type() <<
":";
379 if (_off_stages.
empty()) {
380 if (_on_stages.
empty()) {
381 if (_off_all_stages) {
387 if (_off_all_stages) {
396 Stages::const_iterator fi;
397 for (fi = _off_stages.
begin(); fi != _off_stages.
end(); ++fi) {
400 if ((*fi)._override != 0) {
401 out <<
"^" << (*fi)._override;
405 if (!_on_stages.
empty()) {
410 RenderStages::const_iterator ri;
411 for (ri = _render_stages.begin(); ri != _render_stages.end(); ++ri) {
412 const StageNode &sn = *(*ri);
416 if (tex !=
nullptr) {
417 out <<
":" << tex->get_name();
419 if (sn._override != 0) {
420 out <<
"^" << sn._override;
432 Stages::const_iterator si;
433 for (si = _on_stages.
begin(); si != _on_stages.
end(); ++si) {
434 Texture *texture = (*si)._texture;
454 Stages::const_iterator si;
455 for (si = _on_stages.
begin(); si != _on_stages.
end(); ++si) {
456 Texture *texture = (*si)._texture;
481 if (_off_all_stages != ta->_off_all_stages) {
482 return (
int)_off_all_stages - (int)ta->_off_all_stages;
485 Stages::const_iterator si = _on_stages.
begin();
486 Stages::const_iterator osi = ta->_on_stages.
begin();
488 while (si != _on_stages.
end() && osi != ta->_on_stages.
end()) {
492 if (stage != other_stage) {
493 return stage < other_stage ? -1 : 1;
496 Texture *texture = (*si)._texture;
497 Texture *other_texture = (*osi)._texture;
499 if (texture != other_texture) {
500 return texture < other_texture ? -1 : 1;
503 int implicit_sort = (*si)._implicit_sort;
504 int other_implicit_sort = (*osi)._implicit_sort;
506 if (implicit_sort != other_implicit_sort) {
507 return implicit_sort < other_implicit_sort ? -1 : 1;
510 int override = (*si)._override;
511 int other_override = (*osi)._override;
513 if (
override != other_override) {
514 return override < other_override ? -1 : 1;
517 int has_sampler = (*si)._has_sampler;
518 int other_has_sampler = (*osi)._has_sampler;
520 if (has_sampler != other_has_sampler) {
521 return has_sampler < other_has_sampler ? -1 : 1;
528 if (sampler != other_sampler) {
529 return sampler < other_sampler ? -1 : 1;
537 if (si != _on_stages.
end()) {
540 if (osi != ta->_on_stages.
end()) {
545 Stages::const_iterator fi = _off_stages.
begin();
546 Stages::const_iterator ofi = ta->_off_stages.
begin();
548 while (fi != _off_stages.
end() && ofi != ta->_off_stages.
end()) {
552 if (stage != other_stage) {
553 return stage < other_stage ? -1 : 1;
556 int override = (*fi)._override;
557 int other_override = (*ofi)._override;
559 if (
override != other_override) {
560 return override < other_override ? -1 : 1;
567 if (fi != _off_stages.
end()) {
570 if (ofi != ta->_off_stages.
end()) {
583 size_t TextureAttrib::
584 get_hash_impl()
const {
588 Stages::const_iterator si;
589 for (si = _on_stages.
begin(); si != _on_stages.
end(); ++si) {
590 const StageNode &sn = (*si);
602 for (si = _off_stages.
begin(); si != _off_stages.
end(); ++si) {
603 const StageNode &sn = (*si);
627 if (ta->_off_all_stages) {
635 Stages::const_iterator ai = _on_stages.
begin();
636 Stages::const_iterator bi = ta->_on_stages.
begin();
637 Stages::const_iterator ci = ta->_off_stages.
begin();
642 while (ai != _on_stages.
end() &&
643 bi != ta->_on_stages.
end() &&
644 ci != ta->_off_stages.
end()) {
645 if ((*ai)._stage < (*bi)._stage) {
646 if ((*ai)._stage < (*ci)._stage) {
649 attrib->_on_stages.insert(attrib->_on_stages.
end(), *ai);
652 }
else if ((*ci)._stage < (*ai)._stage) {
660 if ((*ai)._override > (*ci)._override) {
662 attrib->_on_stages.insert(attrib->_on_stages.
end(), *ai);
669 }
else if ((*bi)._stage < (*ai)._stage) {
672 attrib->_on_stages.insert(attrib->_on_stages.
end(), *bi);
677 if ((*ai)._override > (*bi)._override) {
678 attrib->_on_stages.insert(attrib->_on_stages.
end(), *ai);
680 attrib->_on_stages.insert(attrib->_on_stages.
end(), *bi);
687 while (ai != _on_stages.
end() && bi != ta->_on_stages.
end()) {
688 if ((*ai)._stage < (*bi)._stage) {
691 attrib->_on_stages.insert(attrib->_on_stages.
end(), *ai);
694 }
else if ((*bi)._stage < (*ai)._stage) {
697 attrib->_on_stages.insert(attrib->_on_stages.
end(), *bi);
702 if ((*ai)._override > (*bi)._override) {
703 attrib->_on_stages.insert(attrib->_on_stages.
end(), *ai);
705 attrib->_on_stages.insert(attrib->_on_stages.
end(), *bi);
712 while (ai != _on_stages.
end() && ci != ta->_off_stages.
end()) {
713 if ((*ai)._stage < (*ci)._stage) {
716 attrib->_on_stages.insert(attrib->_on_stages.
end(), *ai);
719 }
else if ((*ci)._stage < (*ai)._stage) {
727 if ((*ai)._override > (*ci)._override) {
729 attrib->_on_stages.insert(attrib->_on_stages.
end(), *ai);
736 while (ai != _on_stages.
end()) {
737 attrib->_on_stages.insert(attrib->_on_stages.
end(), *ai);
741 while (bi != ta->_on_stages.
end()) {
742 attrib->_on_stages.insert(attrib->_on_stages.
end(), *bi);
746 attrib->_next_implicit_sort = _next_implicit_sort + ta->_next_implicit_sort;
747 attrib->_sort_seq = UpdateSeq::old();
748 attrib->_filtered_seq = UpdateSeq::old();
750 return return_new(attrib);
771 register_with_read_factory() {
786 Stages::const_iterator fi;
787 for (fi = _off_stages.
begin(); fi != _off_stages.
end(); ++fi) {
794 Stages::const_iterator si;
795 for (si = _on_stages.
begin(); si != _on_stages.
end(); ++si) {
798 nassertv(tex !=
nullptr);
810 if ((*si)._has_sampler) {
811 (*si)._sampler.write_datagram(dg);
826 for (ci = _off_stages.
begin(); ci != _off_stages.
end(); ++ci) {
832 while (sni < _on_stages.
size()) {
841 if (tex !=
nullptr) {
842 StageNode &sn = _on_stages[sni];
851 _on_stages.erase(_on_stages.
begin() + sni);
856 _sort_seq = UpdateSeq::old();
857 _filtered_seq = UpdateSeq::old();
874 attrib->fillin(scan, manager);
885 RenderAttrib::fillin(scan, manager);
894 _off_stages.
reserve(num_off_stages);
895 for (i = 0; i < num_off_stages; i++) {
897 _off_stages.
push_back(StageNode(
nullptr));
905 _on_stages.
reserve(num_on_stages);
906 _next_implicit_sort = 0;
907 for (i = 0; i < num_on_stages; i++) {
910 unsigned int implicit_sort;
914 implicit_sort = (
unsigned int)i;
921 _next_implicit_sort = std::max(_next_implicit_sort, implicit_sort + 1);
922 Stages::iterator si =
923 _on_stages.insert_nonunique(StageNode(
nullptr, _next_implicit_sort,
override));
924 ++_next_implicit_sort;
927 (*si)._has_sampler = scan.
get_bool();
928 if ((*si)._has_sampler) {
929 (*si)._sampler.read_datagram(scan, manager);
943 UsedTexcoordIndex used_texcoord_index;
945 _render_stages.clear();
946 _render_ff_stages.clear();
949 for (si = _on_stages.
begin(); si != _on_stages.
end(); ++si) {
950 StageNode &sn = (*si);
952 Texture *texture = sn._texture;
953 nassertv(stage !=
nullptr);
954 nassertv(texture !=
nullptr);
962 UsedTexcoordIndex::iterator ti = used_texcoord_index.insert(UsedTexcoordIndex::value_type(name, (
int)used_texcoord_index.size())).first;
963 (*si)._ff_tc_index = (*ti).second;
965 _render_ff_stages.push_back(&sn);
967 (*si)._ff_tc_index = -1;
970 _render_stages.push_back(&sn);
973 sort(_render_stages.begin(), _render_stages.end(), CompareTextureStageSort());
974 sort(_render_ff_stages.begin(), _render_ff_stages.end(), CompareTextureStageSort());