Panda3D
 All Classes Functions Variables Enumerations
renderAttribRegistry.cxx
00001 // Filename: renderAttribRegistry.cxx
00002 // Created by:  drose (13Nov08)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "renderAttribRegistry.h"
00016 #include "renderAttrib.h"
00017 #include "renderState.h"
00018 #include "deletedChain.h"
00019 
00020 RenderAttribRegistry *RenderAttribRegistry::_global_ptr;
00021 
00022 ////////////////////////////////////////////////////////////////////
00023 //     Function: RenderAttribRegistry::Constructor
00024 //       Access: Private
00025 //  Description:
00026 ////////////////////////////////////////////////////////////////////
00027 RenderAttribRegistry::
00028 RenderAttribRegistry() {
00029   ConfigVariableInt max_attribs
00030     ("max-attribs", SlotMask::get_max_num_bits(),
00031      PRC_DESC("This specifies the maximum number of different RenderAttrib "
00032               "types that may be defined at runtime.  Normally you should "
00033               "never need to change this, but if the default value is too "
00034               "low for the number of attribs that Panda actually defines, "
00035               "you may need to raise this number."));
00036 
00037   // Assign this number once, at startup, and never change it again.
00038   _max_slots = max((int)max_attribs, 1);
00039   if (_max_slots > SlotMask::get_max_num_bits()) {
00040     pgraph_cat->warning()
00041       << "Value for max-attribs too large: cannot exceed " 
00042       << SlotMask::get_max_num_bits()
00043       << " in this build.  To raise this limit, change the typedef "
00044       << "for SlotMask in renderAttribRegistry.h and recompile.\n";
00045       
00046     _max_slots = SlotMask::get_max_num_bits();
00047   }
00048 
00049   // Get a DeletedBufferChain to manage the arrays of RenderAttribs that are
00050   // allocated within each RenderState object.
00051   init_memory_hook();
00052   _array_chain = memory_hook->get_deleted_chain(_max_slots * sizeof(RenderState::Attribute));
00053 
00054   // Reserve slot 0 for TypeHandle::none(), and for types that exceed
00055   // max_slots.
00056   RegistryNode node;
00057   node._sort = 0;
00058   node._make_default_func = NULL;
00059   _registry.push_back(node);
00060 }
00061 
00062 ////////////////////////////////////////////////////////////////////
00063 //     Function: RenderAttribRegistry::Destructor
00064 //       Access: Private
00065 //  Description:
00066 ////////////////////////////////////////////////////////////////////
00067 RenderAttribRegistry::
00068 ~RenderAttribRegistry() {
00069 }
00070 
00071 ////////////////////////////////////////////////////////////////////
00072 //     Function: RenderAttribRegistry::register_slot
00073 //       Access: Public
00074 //  Description: Adds the indicated TypeHandle to the registry, if it
00075 //               is not there already, and returns a unique slot
00076 //               number in the range 0 < slot < get_max_slots().
00077 //
00078 //               The sort value is an arbitrary integer.  In general,
00079 //               the RenderAttribs will be sorted in order from lowest
00080 //               sort value to highest sort value, when they are
00081 //               traversed via the get_num_sorted_slots() /
00082 //               get_sorted_slot() methods.  This will be used to sort
00083 //               render states, so that heavier RenderAttribs are
00084 //               changed less frequently.  In general, you should
00085 //               choose sort values such that the heavier
00086 //               RenderAttribs (that is, those which are more
00087 //               expensive to change) have lower sort values.
00088 //
00089 //               The make_default_func pointer is a function that may
00090 //               be called to generate a default RenderAttrib to apply
00091 //               in the absence of any other attrib of this type.
00092 //
00093 //               register_slot() is intended to be called at
00094 //               application start for each different RenderAttrib
00095 //               type in the system, to assign a different integer
00096 //               slot number to each one.
00097 ////////////////////////////////////////////////////////////////////
00098 int RenderAttribRegistry::
00099 register_slot(TypeHandle type_handle, int sort,
00100               RenderAttribRegistry::MakeDefaultFunc *make_default_func) {
00101   int type_index = type_handle.get_index();
00102   while (type_index >= (int)_slots_by_type.size()) {
00103     _slots_by_type.push_back(0);
00104   }
00105 
00106   if (_slots_by_type[type_index] != 0) {
00107     // This type has already been registered.
00108     return _slots_by_type[type_index];
00109   }
00110 
00111   int slot = (int)_registry.size();
00112   if (slot >= _max_slots) {
00113     pgraph_cat->error()
00114       << "Too many registered RenderAttribs; not registering " 
00115       << type_handle << "\n";
00116     nassertr(false, 0);
00117     return 0;
00118   }
00119 
00120   _slots_by_type[type_index] = slot;
00121 
00122   RegistryNode node;
00123   node._type = type_handle;
00124   node._sort = sort;
00125   node._make_default_func = make_default_func;
00126   _registry.push_back(node);
00127 
00128   _sorted_slots.push_back(slot);
00129   ::sort(_sorted_slots.begin(), _sorted_slots.end(), SortSlots(this));
00130 
00131   return slot;
00132 }
00133 
00134 ////////////////////////////////////////////////////////////////////
00135 //     Function: RenderAttribRegistry::set_slot_sort
00136 //       Access: Published
00137 //  Description: Changes the sort number associated with slot n.
00138 ////////////////////////////////////////////////////////////////////
00139 void RenderAttribRegistry::
00140 set_slot_sort(int slot, int sort) {
00141   nassertv(slot >= 0 && slot < (int)_registry.size());
00142   _registry[slot]._sort = sort;
00143 
00144   // Re-sort the slot list.
00145   _sorted_slots.clear();
00146   _sorted_slots.reserve(_registry.size() - 1);
00147   for (int i = 1; i < (int)_registry.size(); ++i) {
00148     _sorted_slots.push_back(i);
00149   }
00150   ::sort(_sorted_slots.begin(), _sorted_slots.end(), SortSlots(this));
00151 }
00152 
00153 ////////////////////////////////////////////////////////////////////
00154 //     Function: RenderAttribRegistry::get_slot_default
00155 //       Access: Published
00156 //  Description: Returns the default RenderAttrib object associated
00157 //               with slot n.  This is the attrib that should be
00158 //               applied in the absence of any other attrib of this
00159 //               type.
00160 ////////////////////////////////////////////////////////////////////
00161 CPT(RenderAttrib) RenderAttribRegistry::
00162 get_slot_default(int slot) const {
00163   nassertr(slot >= 0 && slot < (int)_registry.size(), 0);
00164   return (*_registry[slot]._make_default_func)();
00165 }
00166 
00167 ////////////////////////////////////////////////////////////////////
00168 //     Function: RenderAttribRegistry::init_global_ptr
00169 //       Access: Private, Static
00170 //  Description:
00171 ////////////////////////////////////////////////////////////////////
00172 void RenderAttribRegistry::
00173 init_global_ptr() {
00174   _global_ptr = new RenderAttribRegistry;
00175 }
 All Classes Functions Variables Enumerations