00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "renderState.h"
00020 #include "transparencyAttrib.h"
00021 #include "cullBinAttrib.h"
00022 #include "cullBinManager.h"
00023 #include "fogAttrib.h"
00024 #include "transparencyAttrib.h"
00025 #include "config_pgraph.h"
00026 #include "bamReader.h"
00027 #include "bamWriter.h"
00028 #include "datagramIterator.h"
00029 #include "indent.h"
00030 #include "compareTo.h"
00031
00032 RenderState::States *RenderState::_states = NULL;
00033 CPT(RenderState) RenderState::_empty_state;
00034 TypeHandle RenderState::_type_handle;
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 RenderState::
00045 RenderState() {
00046 if (_states == (States *)NULL) {
00047
00048
00049
00050
00051
00052 _states = new States;
00053 }
00054 _saved_entry = _states->end();
00055 _self_compose = (RenderState *)NULL;
00056 _flags = 0;
00057 }
00058
00059
00060
00061
00062
00063
00064 RenderState::
00065 RenderState(const RenderState &) {
00066 nassertv(false);
00067 }
00068
00069
00070
00071
00072
00073
00074 void RenderState::
00075 operator = (const RenderState &) {
00076 nassertv(false);
00077 }
00078
00079
00080
00081
00082
00083
00084
00085 RenderState::
00086 ~RenderState() {
00087
00088 nassertv(!is_destructing());
00089 set_destructing();
00090
00091 if (_saved_entry != _states->end()) {
00092 nassertv(_states->find(this) == _saved_entry);
00093 _states->erase(_saved_entry);
00094 _saved_entry = _states->end();
00095 }
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118 while (!_composition_cache.empty()) {
00119 CompositionCache::iterator ci = _composition_cache.begin();
00120
00121
00122
00123
00124
00125
00126
00127
00128 RenderState *other = (RenderState *)(*ci).first;
00129
00130
00131
00132 nassertv(other != this);
00133
00134
00135
00136
00137 Composition comp = (*ci).second;
00138
00139
00140
00141
00142
00143 _composition_cache.erase(ci);
00144
00145 CompositionCache::iterator oci = other->_composition_cache.find(this);
00146
00147
00148
00149
00150 if (oci != other->_composition_cache.end()) {
00151
00152 Composition ocomp = (*oci).second;
00153
00154
00155
00156
00157 other->_composition_cache.erase(oci);
00158 }
00159
00160
00161
00162
00163
00164 }
00165
00166
00167 while (!_invert_composition_cache.empty()) {
00168 CompositionCache::iterator ci = _invert_composition_cache.begin();
00169 RenderState *other = (RenderState *)(*ci).first;
00170 nassertv(other != this);
00171 Composition comp = (*ci).second;
00172 _invert_composition_cache.erase(ci);
00173 CompositionCache::iterator oci =
00174 other->_invert_composition_cache.find(this);
00175 if (oci != other->_invert_composition_cache.end()) {
00176 Composition ocomp = (*oci).second;
00177 other->_invert_composition_cache.erase(oci);
00178 }
00179 }
00180
00181
00182
00183
00184 if (_self_compose != (RenderState *)NULL && _self_compose != this) {
00185 unref_delete((RenderState *)_self_compose);
00186 }
00187 }
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201 bool RenderState::
00202 operator < (const RenderState &other) const {
00203
00204
00205 return lexicographical_compare(_attributes.begin(), _attributes.end(),
00206 other._attributes.begin(), other._attributes.end(),
00207 CompareTo<Attribute>());
00208 }
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218 int RenderState::
00219 find_attrib(TypeHandle type) const {
00220 Attributes::const_iterator ai = _attributes.find(Attribute(type));
00221 if (ai == _attributes.end()) {
00222 return -1;
00223 }
00224 return ai - _attributes.begin();
00225 }
00226
00227
00228
00229
00230
00231
00232 CPT(RenderState) RenderState::
00233 make_empty() {
00234
00235
00236 if (_empty_state == (RenderState *)NULL) {
00237 RenderState *state = new RenderState;
00238 _empty_state = return_new(state);
00239 }
00240
00241 return _empty_state;
00242 }
00243
00244
00245
00246
00247
00248
00249 CPT(RenderState) RenderState::
00250 make(const RenderAttrib *attrib, int override) {
00251 RenderState *state = new RenderState;
00252 state->_attributes.reserve(1);
00253 state->_attributes.insert(Attribute(attrib, override));
00254 return return_new(state);
00255 }
00256
00257
00258
00259
00260
00261
00262 CPT(RenderState) RenderState::
00263 make(const RenderAttrib *attrib1,
00264 const RenderAttrib *attrib2, int override) {
00265 RenderState *state = new RenderState;
00266 state->_attributes.reserve(2);
00267 state->_attributes.push_back(Attribute(attrib1, override));
00268 state->_attributes.push_back(Attribute(attrib2, override));
00269 state->_attributes.sort();
00270 return return_new(state);
00271 }
00272
00273
00274
00275
00276
00277
00278 CPT(RenderState) RenderState::
00279 make(const RenderAttrib *attrib1,
00280 const RenderAttrib *attrib2,
00281 const RenderAttrib *attrib3, int override) {
00282 RenderState *state = new RenderState;
00283 state->_attributes.reserve(3);
00284 state->_attributes.push_back(Attribute(attrib1, override));
00285 state->_attributes.push_back(Attribute(attrib2, override));
00286 state->_attributes.push_back(Attribute(attrib3, override));
00287 state->_attributes.sort();
00288 return return_new(state);
00289 }
00290
00291
00292
00293
00294
00295
00296 CPT(RenderState) RenderState::
00297 make(const RenderAttrib *attrib1,
00298 const RenderAttrib *attrib2,
00299 const RenderAttrib *attrib3,
00300 const RenderAttrib *attrib4, int override) {
00301 RenderState *state = new RenderState;
00302 state->_attributes.reserve(4);
00303 state->_attributes.push_back(Attribute(attrib1, override));
00304 state->_attributes.push_back(Attribute(attrib2, override));
00305 state->_attributes.push_back(Attribute(attrib3, override));
00306 state->_attributes.push_back(Attribute(attrib4, override));
00307 state->_attributes.sort();
00308 return return_new(state);
00309 }
00310
00311
00312
00313
00314
00315
00316 CPT(RenderState) RenderState::
00317 make(const RenderAttrib * const *attrib, int num_attribs, int override) {
00318 RenderState *state = new RenderState;
00319 state->_attributes.reserve(num_attribs);
00320 for (int i = 0; i < num_attribs; i++) {
00321 state->_attributes.push_back(Attribute(attrib[i], override));
00322 }
00323 return return_new(state);
00324 }
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339 CPT(RenderState) RenderState::
00340 compose(const RenderState *other) const {
00341
00342
00343
00344
00345
00346 if (is_empty()) {
00347 return other;
00348 }
00349 if (other->is_empty()) {
00350 return this;
00351 }
00352
00353 if (other == this) {
00354
00355
00356 if (_self_compose != (RenderState *)NULL) {
00357 return _self_compose;
00358 }
00359 CPT(RenderState) result = do_compose(this);
00360 ((RenderState *)this)->_self_compose = result;
00361
00362 if (result != (const RenderState *)this) {
00363
00364
00365
00366 _self_compose->ref();
00367
00368
00369
00370
00371 }
00372 return _self_compose;
00373 }
00374
00375
00376 CompositionCache::const_iterator ci = _composition_cache.find(other);
00377 if (ci != _composition_cache.end()) {
00378 const Composition &comp = (*ci).second;
00379 if (comp._result == (const RenderState *)NULL) {
00380
00381
00382
00383 ((Composition &)comp)._result = do_compose(other);
00384 }
00385
00386 return comp._result;
00387 }
00388
00389
00390
00391
00392
00393
00394
00395
00396 CPT(RenderState) result = do_compose(other);
00397
00398 ((RenderState *)other)->_composition_cache[this]._result = NULL;
00399 ((RenderState *)this)->_composition_cache[other]._result = result;
00400
00401 return result;
00402 }
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415 CPT(RenderState) RenderState::
00416 invert_compose(const RenderState *other) const {
00417
00418
00419
00420
00421
00422 if (is_empty()) {
00423 return other;
00424 }
00425
00426
00427
00428 if (other == this) {
00429
00430 return make_empty();
00431 }
00432
00433
00434 CompositionCache::const_iterator ci = _invert_composition_cache.find(other);
00435 if (ci != _invert_composition_cache.end()) {
00436 const Composition &comp = (*ci).second;
00437 if (comp._result == (const RenderState *)NULL) {
00438
00439
00440
00441 ((Composition &)comp)._result = do_invert_compose(other);
00442 }
00443
00444 return comp._result;
00445 }
00446
00447
00448
00449
00450
00451
00452
00453
00454 CPT(RenderState) result = do_invert_compose(other);
00455
00456 ((RenderState *)other)->_invert_composition_cache[this]._result = NULL;
00457 ((RenderState *)this)->_invert_composition_cache[other]._result = result;
00458
00459 return result;
00460 }
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470 CPT(RenderState) RenderState::
00471 add_attrib(const RenderAttrib *attrib, int override) const {
00472 RenderState *new_state = new RenderState;
00473 back_insert_iterator<Attributes> result =
00474 back_inserter(new_state->_attributes);
00475
00476 Attribute new_attribute(attrib, override);
00477 Attributes::const_iterator ai = _attributes.begin();
00478
00479 while (ai != _attributes.end() && (*ai) < new_attribute) {
00480 *result = *ai;
00481 ++ai;
00482 ++result;
00483 }
00484 *result = new_attribute;
00485 ++result;
00486
00487 if (ai != _attributes.end() && !(new_attribute < (*ai))) {
00488
00489
00490
00491
00492 ++ai;
00493 }
00494
00495 while (ai != _attributes.end()) {
00496 *result = *ai;
00497 ++ai;
00498 ++result;
00499 }
00500
00501 return return_new(new_state);
00502 }
00503
00504
00505
00506
00507
00508
00509
00510
00511 CPT(RenderState) RenderState::
00512 remove_attrib(TypeHandle type) const {
00513 RenderState *new_state = new RenderState;
00514 back_insert_iterator<Attributes> result =
00515 back_inserter(new_state->_attributes);
00516
00517 Attributes::const_iterator ai = _attributes.begin();
00518
00519 while (ai != _attributes.end()) {
00520 if ((*ai)._type != type) {
00521 *result = *ai;
00522 ++result;
00523 }
00524 ++ai;
00525 }
00526
00527 return return_new(new_state);
00528 }
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539 CPT(RenderState) RenderState::
00540 adjust_all_priorities(int adjustment) const {
00541 RenderState *new_state = new RenderState;
00542 new_state->_attributes.reserve(_attributes.size());
00543
00544 Attributes::const_iterator ai;
00545 for (ai = _attributes.begin(); ai != _attributes.end(); ++ai) {
00546 Attribute attrib = *ai;
00547 attrib._override = max(attrib._override + adjustment, 0);
00548 new_state->_attributes.push_back(attrib);
00549 }
00550
00551 return return_new(new_state);
00552 }
00553
00554
00555
00556
00557
00558
00559
00560
00561 const RenderAttrib *RenderState::
00562 get_attrib(TypeHandle type) const {
00563 Attributes::const_iterator ai;
00564 ai = _attributes.find(Attribute(type));
00565 if (ai != _attributes.end()) {
00566 return (*ai)._attrib;
00567 }
00568 return NULL;
00569 }
00570
00571
00572
00573
00574
00575
00576 void RenderState::
00577 output(ostream &out) const {
00578 out << "S:";
00579 if (_attributes.empty()) {
00580 out << "(empty)";
00581
00582 } else {
00583 Attributes::const_iterator ai = _attributes.begin();
00584 out << "(" << (*ai)._type;
00585 ++ai;
00586 while (ai != _attributes.end()) {
00587 out << " " << (*ai)._type;
00588 ++ai;
00589 }
00590 out << ")";
00591 }
00592 }
00593
00594
00595
00596
00597
00598
00599 void RenderState::
00600 write(ostream &out, int indent_level) const {
00601 indent(out, indent_level) << _attributes.size() << " attribs:\n";
00602 Attributes::const_iterator ai;
00603 for (ai = _attributes.begin(); ai != _attributes.end(); ++ai) {
00604 const Attribute &attribute = (*ai);
00605 attribute._attrib->write(out, indent_level + 2);
00606 }
00607 }
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619 int RenderState::
00620 get_max_priority() {
00621 return 1000000000;
00622 }
00623
00624
00625
00626
00627
00628
00629
00630
00631 int RenderState::
00632 get_num_states() {
00633 if (_states == (States *)NULL) {
00634 return 0;
00635 }
00636 return _states->size();
00637 }
00638
00639
00640
00641
00642
00643
00644
00645
00646 int RenderState::
00647 get_num_unused_states() {
00648 if (_states == (States *)NULL) {
00649 return 0;
00650 }
00651
00652 int num_unused = 0;
00653
00654
00655
00656 typedef pmap<const RenderState *, int> StateCount;
00657 StateCount state_count;
00658
00659 States::iterator si;
00660 for (si = _states->begin(); si != _states->end(); ++si) {
00661 const RenderState *state = (*si);
00662
00663 CompositionCache::const_iterator ci;
00664 for (ci = state->_composition_cache.begin();
00665 ci != state->_composition_cache.end();
00666 ++ci) {
00667 const RenderState *result = (*ci).second._result;
00668 if (result != (const RenderState *)NULL) {
00669
00670
00671 pair<StateCount::iterator, bool> ir =
00672 state_count.insert(StateCount::value_type(result, 1));
00673 if (!ir.second) {
00674
00675
00676 (*(ir.first)).second++;
00677 }
00678 }
00679 }
00680 for (ci = state->_invert_composition_cache.begin();
00681 ci != state->_invert_composition_cache.end();
00682 ++ci) {
00683 const RenderState *result = (*ci).second._result;
00684 if (result != (const RenderState *)NULL) {
00685 pair<StateCount::iterator, bool> ir =
00686 state_count.insert(StateCount::value_type(result, 1));
00687 if (!ir.second) {
00688 (*(ir.first)).second++;
00689 }
00690 }
00691 }
00692
00693
00694
00695 if (state->_self_compose != (const RenderState *)NULL &&
00696 state->_self_compose != state) {
00697 const RenderState *result = state->_self_compose;
00698 if (result != (const RenderState *)NULL) {
00699 pair<StateCount::iterator, bool> ir =
00700 state_count.insert(StateCount::value_type(result, 1));
00701 if (!ir.second) {
00702 (*(ir.first)).second++;
00703 }
00704 }
00705 }
00706
00707 }
00708
00709
00710
00711
00712 StateCount::iterator sci;
00713 for (sci = state_count.begin(); sci != state_count.end(); ++sci) {
00714 const RenderState *state = (*sci).first;
00715 int count = (*sci).second;
00716 nassertr(count <= state->get_ref_count(), num_unused);
00717 if (count == state->get_ref_count()) {
00718 num_unused++;
00719 }
00720 }
00721
00722 return num_unused;
00723 }
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750 int RenderState::
00751 clear_cache() {
00752 if (_states == (States *)NULL) {
00753 return 0;
00754 }
00755
00756 int orig_size = _states->size();
00757
00758
00759
00760
00761
00762 {
00763 typedef pvector< CPT(RenderState) > TempStates;
00764 TempStates temp_states;
00765 temp_states.reserve(orig_size);
00766
00767 copy(_states->begin(), _states->end(),
00768 back_inserter(temp_states));
00769
00770
00771
00772
00773 TempStates::iterator ti;
00774 for (ti = temp_states.begin(); ti != temp_states.end(); ++ti) {
00775 RenderState *state = (RenderState *)(*ti).p();
00776 state->_composition_cache.clear();
00777 state->_invert_composition_cache.clear();
00778 if (state->_self_compose != (RenderState *)NULL &&
00779 state->_self_compose != state) {
00780 unref_delete((RenderState *)state->_self_compose);
00781 state->_self_compose = (RenderState *)NULL;
00782 }
00783 }
00784
00785
00786
00787
00788 }
00789
00790 int new_size = _states->size();
00791 return orig_size - new_size;
00792 }
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804 CPT(RenderState) RenderState::
00805 issue_delta_modify(const RenderState *other,
00806 GraphicsStateGuardianBase *gsg) const {
00807 if (other->is_empty()) {
00808
00809 return this;
00810 }
00811
00812
00813
00814 Attributes::const_iterator ai = _attributes.begin();
00815 Attributes::const_iterator bi = other->_attributes.begin();
00816
00817
00818 RenderState *new_state = new RenderState;
00819 back_insert_iterator<Attributes> result =
00820 back_inserter(new_state->_attributes);
00821
00822 bool any_changed = false;
00823
00824 while (ai != _attributes.end() && bi != other->_attributes.end()) {
00825 if ((*ai) < (*bi)) {
00826
00827
00828 *result = *ai;
00829 ++ai;
00830 ++result;
00831 } else if ((*bi) < (*ai)) {
00832
00833
00834 (*bi)._attrib->issue(gsg);
00835 *result = *bi;
00836 ++bi;
00837 ++result;
00838 any_changed = true;
00839 } else {
00840
00841
00842 if ((*ai)._attrib != (*bi)._attrib) {
00843 any_changed = true;
00844 (*bi)._attrib->issue(gsg);
00845 }
00846 *result = *bi;
00847 ++ai;
00848 ++bi;
00849 ++result;
00850 }
00851 }
00852
00853 while (ai != _attributes.end()) {
00854 *result = *ai;
00855 ++ai;
00856 ++result;
00857 }
00858
00859 while (bi != other->_attributes.end()) {
00860 (*bi)._attrib->issue(gsg);
00861 *result = *bi;
00862 ++bi;
00863 ++result;
00864 any_changed = true;
00865 }
00866
00867 if (any_changed) {
00868 return return_new(new_state);
00869 } else {
00870 delete new_state;
00871 return this;
00872 }
00873 }
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886 CPT(RenderState) RenderState::
00887 issue_delta_set(const RenderState *other,
00888 GraphicsStateGuardianBase *gsg) const {
00889 if (other == this) {
00890
00891 return other;
00892 }
00893
00894 Attributes::const_iterator ai = _attributes.begin();
00895 Attributes::const_iterator bi = other->_attributes.begin();
00896
00897 while (ai != _attributes.end() && bi != other->_attributes.end()) {
00898 if ((*ai) < (*bi)) {
00899
00900
00901 (*ai)._attrib->make_default()->issue(gsg);
00902 ++ai;
00903
00904 } else if ((*bi) < (*ai)) {
00905
00906
00907 (*bi)._attrib->issue(gsg);
00908 ++bi;
00909
00910 } else {
00911
00912
00913 if ((*ai)._attrib != (*bi)._attrib) {
00914 (*bi)._attrib->issue(gsg);
00915 }
00916 ++ai;
00917 ++bi;
00918 }
00919 }
00920
00921 while (ai != _attributes.end()) {
00922 (*ai)._attrib->make_default()->issue(gsg);
00923 ++ai;
00924 }
00925
00926 while (bi != other->_attributes.end()) {
00927 (*bi)._attrib->issue(gsg);
00928 ++bi;
00929 }
00930
00931 return other;
00932 }
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942 void RenderState::
00943 bin_removed(int bin_index) {
00944
00945 nassertv(false);
00946 }
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960 CPT(RenderState) RenderState::
00961 return_new(RenderState *state) {
00962 nassertr(state != (RenderState *)NULL, state);
00963
00964
00965
00966 nassertr(state->_saved_entry == _states->end(), state);
00967
00968
00969
00970 CPT(RenderState) pt_state = state;
00971
00972 pair<States::iterator, bool> result = _states->insert(state);
00973
00974 if (result.second) {
00975
00976
00977 state->_saved_entry = result.first;
00978 return pt_state;
00979 }
00980
00981
00982
00983 return *(result.first);
00984 }
00985
00986
00987
00988
00989
00990
00991
00992
00993 CPT(RenderState) RenderState::
00994 do_compose(const RenderState *other) const {
00995
00996
00997 Attributes::const_iterator ai = _attributes.begin();
00998 Attributes::const_iterator bi = other->_attributes.begin();
00999
01000
01001 RenderState *new_state = new RenderState;
01002 back_insert_iterator<Attributes> result =
01003 back_inserter(new_state->_attributes);
01004
01005 while (ai != _attributes.end() && bi != other->_attributes.end()) {
01006 if ((*ai) < (*bi)) {
01007
01008
01009 *result = *ai;
01010 ++ai;
01011 ++result;
01012 } else if ((*bi) < (*ai)) {
01013
01014
01015 *result = *bi;
01016 ++bi;
01017 ++result;
01018 } else {
01019
01020
01021 const Attribute &a = (*ai);
01022 const Attribute &b = (*bi);
01023 if (a._override < b._override) {
01024
01025 *result = *bi;
01026
01027 } else if (b._override < a._override) {
01028
01029 *result = *ai;
01030
01031 } else {
01032
01033 *result = Attribute(a._attrib->compose(b._attrib), b._override);
01034 }
01035 ++ai;
01036 ++bi;
01037 ++result;
01038 }
01039 }
01040
01041 while (ai != _attributes.end()) {
01042 *result = *ai;
01043 ++ai;
01044 ++result;
01045 }
01046
01047 while (bi != other->_attributes.end()) {
01048 *result = *bi;
01049 ++bi;
01050 ++result;
01051 }
01052
01053 return return_new(new_state);
01054 }
01055
01056
01057
01058
01059
01060
01061 CPT(RenderState) RenderState::
01062 do_invert_compose(const RenderState *other) const {
01063 Attributes::const_iterator ai = _attributes.begin();
01064 Attributes::const_iterator bi = other->_attributes.begin();
01065
01066
01067 RenderState *new_state = new RenderState;
01068 back_insert_iterator<Attributes> result =
01069 back_inserter(new_state->_attributes);
01070
01071 while (ai != _attributes.end() && bi != other->_attributes.end()) {
01072 if ((*ai) < (*bi)) {
01073
01074
01075 *result = Attribute((*ai)._attrib->invert_compose((*ai)._attrib->make_default()), 0);
01076 ++ai;
01077 ++result;
01078 } else if ((*bi) < (*ai)) {
01079
01080
01081 *result = *bi;
01082 ++bi;
01083 ++result;
01084 } else {
01085
01086
01087 *result = Attribute((*ai)._attrib->invert_compose((*bi)._attrib), (*bi)._override);
01088 ++ai;
01089 ++bi;
01090 ++result;
01091 }
01092 }
01093
01094 while (ai != _attributes.end()) {
01095 *result = Attribute((*ai)._attrib->invert_compose((*ai)._attrib->make_default()), 0);
01096 ++ai;
01097 ++result;
01098 }
01099
01100 while (bi != other->_attributes.end()) {
01101 *result = *bi;
01102 ++bi;
01103 ++result;
01104 }
01105
01106 return return_new(new_state);
01107 }
01108
01109
01110
01111
01112
01113
01114
01115 void RenderState::
01116 determine_bin_index() {
01117 string bin_name;
01118 _draw_order = 0;
01119
01120 const CullBinAttrib *bin_attrib = get_bin();
01121 if (bin_attrib != (const CullBinAttrib *)NULL) {
01122 bin_name = bin_attrib->get_bin_name();
01123 _draw_order = bin_attrib->get_draw_order();
01124 }
01125
01126 if (bin_name.empty()) {
01127
01128
01129
01130 bin_name = "opaque";
01131 const TransparencyAttrib *trans = get_transparency();
01132 if (trans != (const TransparencyAttrib *)NULL) {
01133 switch (trans->get_mode()) {
01134 case TransparencyAttrib::M_alpha:
01135 case TransparencyAttrib::M_alpha_sorted:
01136 case TransparencyAttrib::M_dual:
01137
01138 bin_name = "transparent";
01139 break;
01140
01141 default:
01142 break;
01143 }
01144 }
01145 }
01146
01147 CullBinManager *bin_manager = CullBinManager::get_global_ptr();
01148 _bin_index = bin_manager->find_bin(bin_name);
01149 if (_bin_index == -1) {
01150 pgraph_cat.warning()
01151 << "No bin named " << bin_name << "; creating default bin.\n";
01152 _bin_index = bin_manager->add_bin(bin_name, CullBinManager::BT_unsorted, 0);
01153 }
01154 _flags |= F_checked_bin_index;
01155 }
01156
01157
01158
01159
01160
01161
01162 void RenderState::
01163 determine_fog() {
01164 const RenderAttrib *attrib = get_attrib(FogAttrib::get_class_type());
01165 _fog = (const FogAttrib *)NULL;
01166 if (attrib != (const RenderAttrib *)NULL) {
01167 _fog = DCAST(FogAttrib, attrib);
01168 }
01169 _flags |= F_checked_fog;
01170 }
01171
01172
01173
01174
01175
01176
01177 void RenderState::
01178 determine_bin() {
01179 const RenderAttrib *attrib = get_attrib(CullBinAttrib::get_class_type());
01180 _bin = (const CullBinAttrib *)NULL;
01181 if (attrib != (const RenderAttrib *)NULL) {
01182 _bin = DCAST(CullBinAttrib, attrib);
01183 }
01184 _flags |= F_checked_bin;
01185 }
01186
01187
01188
01189
01190
01191
01192 void RenderState::
01193 determine_transparency() {
01194 const RenderAttrib *attrib =
01195 get_attrib(TransparencyAttrib::get_class_type());
01196 _transparency = (const TransparencyAttrib *)NULL;
01197 if (attrib != (const RenderAttrib *)NULL) {
01198 _transparency = DCAST(TransparencyAttrib, attrib);
01199 }
01200 _flags |= F_checked_transparency;
01201 }
01202
01203
01204
01205
01206
01207
01208
01209 void RenderState::
01210 register_with_read_factory() {
01211 BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
01212 }
01213
01214
01215
01216
01217
01218
01219
01220 void RenderState::
01221 write_datagram(BamWriter *manager, Datagram &dg) {
01222 TypedWritable::write_datagram(manager, dg);
01223
01224 int num_attribs = _attributes.size();
01225 nassertv(num_attribs == (int)(PN_uint16)num_attribs);
01226 dg.add_uint16(num_attribs);
01227
01228
01229
01230 Attributes::const_iterator ai;
01231 for (ai = _attributes.begin(); ai != _attributes.end(); ++ai) {
01232 const Attribute &attribute = (*ai);
01233
01234 manager->write_pointer(dg, attribute._attrib);
01235 dg.add_int32(attribute._override);
01236 }
01237 }
01238
01239
01240
01241
01242
01243
01244
01245
01246 int RenderState::
01247 complete_pointers(TypedWritable **p_list, BamReader *manager) {
01248 int pi = TypedWritable::complete_pointers(p_list, manager);
01249
01250
01251 Attributes::iterator ai;
01252 for (ai = _attributes.begin(); ai != _attributes.end(); ++ai) {
01253 Attribute &attribute = (*ai);
01254
01255 attribute._attrib = DCAST(RenderAttrib, p_list[pi++]);
01256 nassertr(attribute._attrib != (RenderAttrib *)NULL, pi);
01257 attribute._type = attribute._attrib->get_type();
01258 }
01259
01260
01261
01262
01263
01264 _attributes.sort();
01265
01266 return pi;
01267 }
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280 TypedWritable *RenderState::
01281 change_this(TypedWritable *old_ptr, BamReader *manager) {
01282
01283 RenderState *state = DCAST(RenderState, old_ptr);
01284 CPT(RenderState) pointer = return_new(state);
01285
01286
01287
01288
01289
01290
01291 if (pointer == state) {
01292 pointer->ref();
01293 manager->register_finalize(state);
01294 }
01295
01296
01297
01298 return (RenderState *)pointer.p();
01299 }
01300
01301
01302
01303
01304
01305
01306
01307
01308 void RenderState::
01309 finalize() {
01310
01311 unref();
01312
01313
01314
01315
01316
01317
01318 nassertv(get_ref_count() != 0);
01319 }
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329 TypedWritable *RenderState::
01330 make_from_bam(const FactoryParams ¶ms) {
01331 RenderState *state = new RenderState;
01332 DatagramIterator scan;
01333 BamReader *manager;
01334
01335 parse_params(params, scan, manager);
01336 state->fillin(scan, manager);
01337 manager->register_change_this(change_this, state);
01338
01339 return state;
01340 }
01341
01342
01343
01344
01345
01346
01347
01348
01349 void RenderState::
01350 fillin(DatagramIterator &scan, BamReader *manager) {
01351 TypedWritable::fillin(scan, manager);
01352
01353 int num_attribs = scan.get_uint16();
01354
01355
01356
01357 _attributes.reserve(num_attribs);
01358 for (int i = 0; i < num_attribs; i++) {
01359 manager->read_pointer(scan);
01360 int override = scan.get_int32();
01361 _attributes.push_back(Attribute(override));
01362 }
01363 }