15 #include "cullBinManager.h"
16 #include "renderState.h"
17 #include "cullResult.h"
18 #include "config_pgraph.h"
19 #include "string_utils.h"
20 #include "configVariableColor.h"
35 _bins_are_sorted =
true;
36 _unused_bin_index =
false;
60 add_bin(
const string &name, BinType type,
int sort) {
61 BinsByName::const_iterator bni = _bins_by_name.find(name);
62 if (bni != _bins_by_name.end()) {
65 int bin_index = (*bni).second;
66 nassertr(bin_index >= 0 && bin_index < (
int)_bin_definitions.size(), -1);
67 const BinDefinition &def = _bin_definitions[bin_index];
68 nassertr(def._in_use, -1);
69 if (def._type == type && def._sort == sort) {
75 <<
"Cannot create a bin named " << name
76 <<
"; already have a bin by that name.\n";
82 int new_bin_index = -1;
83 if (_unused_bin_index) {
87 for (i = 0; i < (int)_bin_definitions.size() && new_bin_index == -1; i++) {
88 if (!_bin_definitions[i]._in_use) {
93 if (new_bin_index == -1) {
95 _unused_bin_index =
false;
99 if (new_bin_index == -1) {
101 new_bin_index = _bin_definitions.size();
102 _bin_definitions.push_back(BinDefinition());
105 BinDefinition &def = _bin_definitions[new_bin_index];
115 (
"flash-bin-" + name,
"",
"", ConfigVariable::F_dynamic);
117 def._flash_active =
false;
119 def._flash_active =
true;
120 def._flash_color = flash_bin.
get_value();
124 _bins_by_name.insert(BinsByName::value_type(name, new_bin_index));
125 _sorted_bins.push_back(new_bin_index);
126 _bins_are_sorted =
false;
128 return new_bin_index;
144 nassertv(bin_index >= 0 && bin_index < (
int)_bin_definitions.size());
145 nassertv(_bin_definitions[bin_index]._in_use);
147 _bin_definitions[bin_index]._in_use =
false;
148 SortedBins::iterator si =
149 find(_sorted_bins.begin(), _sorted_bins.end(), bin_index);
150 nassertv(si != _sorted_bins.end());
151 _sorted_bins.erase(si);
152 _bins_by_name.erase(_bin_definitions[bin_index]._name);
174 BinsByName::const_iterator bni;
175 bni = _bins_by_name.find(name);
176 if (bni != _bins_by_name.end()) {
177 return (*bni).second;
187 void CullBinManager::
188 write(ostream &out)
const {
189 if (!_bins_are_sorted) {
192 SortedBins::const_iterator sbi;
193 for (sbi = _sorted_bins.begin(); sbi != _sorted_bins.end(); ++sbi) {
194 int bin_index = (*sbi);
211 nassertr(bin_index >= 0 && bin_index < (
int)_bin_definitions.size(), NULL);
212 nassertr(_bin_definitions[bin_index]._in_use, NULL);
213 string name = get_bin_name(bin_index);
215 BinType type = _bin_definitions[bin_index]._type;
216 BinConstructors::const_iterator ci = _bin_constructors.find(type);
217 if (ci != _bin_constructors.end()) {
218 BinConstructor *constructor = (*ci).second;
219 return constructor(name, gsg, draw_region_pcollector);
223 nassertr(
false, NULL);
235 bool inserted = _bin_constructors.insert(BinConstructors::value_type(type, constructor)).second;
245 void CullBinManager::
247 sort(_sorted_bins.begin(), _sorted_bins.end(), SortBins(
this));
248 _bins_are_sorted =
true;
258 void CullBinManager::
259 setup_initial_bins() {
262 PRC_DESC(
"Creates a new cull bin by name, with the specified properties. "
263 "This is a string in three tokens, separated by whitespace: "
264 "'bin_name sort type'."));
267 int num_bins = cull_bin.get_num_unique_values();
269 for (
int bi = 0; bi < num_bins; bi++) {
270 string def = cull_bin.get_unique_value(bi);
276 extract_words(def, words);
278 if (words.size() != 3) {
280 <<
"Invalid cull-bin definition: " << def <<
"\n"
281 <<
"Definition should be three words: bin_name sort type\n";
284 if (!string_to_int(words[1], sort)) {
286 <<
"Invalid cull-bin definition: " << def <<
"\n"
287 <<
"Sort token " << words[1] <<
" is not an integer.\n";
290 BinType type = parse_bin_type(words[2]);
291 if (type == BT_invalid) {
293 <<
"Invalid cull-bin definition: " << def <<
"\n"
294 <<
"Bin type " << words[2] <<
" is not known.\n";
305 add_bin(
"background", BT_fixed, 10);
308 add_bin(
"opaque", BT_state_sorted, 20);
310 if (
find_bin(
"transparent") == -1) {
311 add_bin(
"transparent", BT_back_to_front, 30);
314 add_bin(
"fixed", BT_fixed, 40);
317 add_bin(
"unsorted", BT_unsorted, 50);
328 CullBinManager::BinType CullBinManager::
329 parse_bin_type(
const string &bin_type) {
330 if (cmp_nocase_uh(bin_type,
"unsorted") == 0) {
333 }
else if (cmp_nocase_uh(bin_type,
"state_sorted") == 0) {
334 return BT_state_sorted;
336 }
else if (cmp_nocase_uh(bin_type,
"fixed") == 0) {
339 }
else if (cmp_nocase_uh(bin_type,
"back_to_front") == 0) {
340 return BT_back_to_front;
342 }
else if (cmp_nocase_uh(bin_type,
"front_to_back") == 0) {
343 return BT_front_to_back;
355 operator << (ostream &out, CullBinManager::BinType bin_type) {
357 case CullBinManager::BT_invalid:
358 return out <<
"invalid";
360 case CullBinManager::BT_unsorted:
361 return out <<
"unsorted";
363 case CullBinManager::BT_state_sorted:
364 return out <<
"state_sorted";
366 case CullBinManager::BT_back_to_front:
367 return out <<
"back_to_front";
369 case CullBinManager::BT_front_to_back:
370 return out <<
"front_to_back";
372 case CullBinManager::BT_fixed:
373 return out <<
"fixed";
376 return out <<
"**invalid BinType(" << (int)bin_type <<
")**";
int get_num_words() const
Returns the number of words in the variable's value.
A collection of Geoms and their associated state, for a particular scene.
BinType get_bin_type(int bin_index) const
Returns the type of the bin with the indicated bin_index (where bin_index was retrieved by get_bin() ...
This is a convenience class to specialize ConfigVariable as a set of floating-point types representin...
This class is similar to ConfigVariable, but it reports its value as a list of strings.
int find_bin(const string &name) const
Returns the bin_index associated with the bin of the given name, or -1 if no bin has that name...
A lightweight class that represents a single element that may be timed and/or counted via stats...
string get_bin_name(int bin_index) const
Returns the name of the bin with the indicated bin_index (where bin_index was retrieved by get_bin() ...
void register_bin_type(BinType type, BinConstructor *constructor)
Intended to be called at startup type by each CullBin type, to register the constructor for each type...
const LColor & get_value() const
Returns the variable's value.
static void bin_removed(int bin_index)
Intended to be called by CullBinManager::remove_bin(), this informs all the CullResults in the world ...
This is a base class for the GraphicsStateGuardian class, which is itself a base class for the variou...
int add_bin(const string &name, BinType type, int sort)
Defines a new bin with the indicated name, and returns the new bin_index.
int get_bin_sort(int bin_index) const
Returns the sort order of the bin with the indicated bin_index (where bin_index was retrieved by get_...
void remove_bin(int bin_index)
Permanently removes the indicated bin.
This is a global object that maintains the collection of named CullBins in the world.
static void bin_removed(int bin_index)
Intended to be called by CullBinManager::remove_bin(), this informs all the RenderStates in the world...