00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef __SGL_CULL_HPP
00026 #define __SGL_CULL_HPP
00027
00028 #include <sgl.h>
00029 #include <sglTraverser.hpp>
00030 #include <sglMat4.hpp>
00031
00032 #include <vector>
00033 #include <deque>
00034
00035 #include <sglDrawable.hpp>
00036 #include <sglObjPool.hpp>
00037 #include <sglCurrState.hpp>
00038 #include <sglDrawablePool.hpp>
00039 #include <sglLightProcessor.hpp>
00040
00041 template <class T> class sglFrustum;
00042 class sglLight;
00043
00044
00045
00046
00047
00048
00049
00050 class sglRangeObject;
00051 typedef sglRangeObject* sglRangeObjectPtr;
00052
00053
00054 class SGL_DLL_API sglRangeObject
00055 {
00056 public:
00057 sglRangeObject() {};
00058 virtual ~sglRangeObject() {};
00059
00060
00061
00062
00063 static bool smallerRange(const sglRangeObjectPtr &x,
00064 const sglRangeObjectPtr &y);
00065
00066
00067
00068 static bool greaterRange(const sglRangeObjectPtr &x,
00069 const sglRangeObjectPtr &y);
00070
00071 const sglFullState *getState() const { return m_fullstate; }
00072
00073 void set(const sglDrawable *drawable,
00074 const sglFullState *state,
00075 float range)
00076 {
00077 m_range = range;
00078 m_fullstate = state;
00079 m_drawable = drawable;
00080 }
00081
00082 virtual void draw(sglCurrState *curr_state) const;
00083 virtual void statsDraw(sglCurrState *curr_state, sglStats &stats) const;
00084
00085 private:
00086 sglRangeObject(const sglRangeObject &);
00087 sglRangeObject& operator=(const sglRangeObject &);
00088
00089 protected:
00090 float m_range;
00091 const sglFullState *m_fullstate;
00092 const sglDrawable *m_drawable;
00093 };
00094
00095
00096
00097
00098
00099 class SGL_DLL_API sglOcclusionObject : public sglRangeObject
00100 {
00101 public:
00102 sglOcclusionObject() {};
00103 ~sglOcclusionObject() {};
00104
00105 virtual void draw(sglCurrState *curr_state) const;
00106 virtual void statsDraw(sglCurrState *curr_state, sglStats &stats) const;
00107
00108 private:
00109 sglOcclusionObject(const sglOcclusionObject &);
00110 sglOcclusionObject& operator=(const sglOcclusionObject &);
00111 };
00112
00113
00114
00115
00116 class SGL_DLL_API sglTransformStateletBase : public sglStatelet
00117 {
00118 public:
00119 sglTransformStateletBase() : sglStatelet(eTRANSFORM_MATRIX) {}
00120 virtual ~sglTransformStateletBase() {}
00121 virtual void mul(const sglVec3f &in, sglVec4f &out) const = 0;
00122 };
00123
00124 template <class T>
00125 class SGL_DLL_API sglTransformStatelet : public sglTransformStateletBase
00126 {
00127 public:
00128 sglTransformStatelet() {}
00129 virtual ~sglTransformStatelet() {}
00130
00131 void setMatrix(const sglMat4<T>& matrix) { m_matrix = matrix; }
00132 const sglMat4<T>& getMatrix() const { return m_matrix; }
00133
00134 void setRescale(bool rescale_flag) { m_rescale_flag = rescale_flag; }
00135 bool getRescale() const { return m_rescale_flag; }
00136
00137 void setNormalize(bool normalize_flag) { m_normalize_flag = normalize_flag;}
00138 bool getNormalize() const { return m_normalize_flag; }
00139
00140 virtual void mul(const sglVec3f &in, sglVec4f &out) const
00141 { ::mul(in, 1.0f, m_matrix, out); }
00142
00143 void setIndex(unsigned int indx) { m_index = indx; }
00144
00145 void apply(sglCurrState*) const;
00146
00147 private:
00148 sglTransformStatelet(const sglTransformStatelet &);
00149 sglTransformStatelet& operator=(const sglTransformStatelet &);
00150
00151 private:
00152 sglMat4<T> m_matrix;
00153 bool m_rescale_flag;
00154 bool m_normalize_flag;
00155 };
00156
00157
00158
00159 class SGL_DLL_API sglCullDrawablePool : public sglDrawablePool
00160 {
00161 public:
00162 sglCullDrawablePool(sglDrawablePoolSources &sources)
00163 : m_opaque_bin(NULL),
00164 m_transparency_sorted_flag(true),
00165 m_transparency_bin(),
00166 m_occlusion_sorted_flag(true),
00167 m_occlusion_bin(),
00168 m_range_pool(100, 100),
00169 m_occlusion_pool(0, 10),
00170 m_drawable_pair_pool(100, 100),
00171 m_drawable_pool_sources(sources) {};
00172
00173 virtual ~sglCullDrawablePool() { delete m_opaque_bin; }
00174
00175 void clear();
00176
00177 void insert(const sglDrawable *geom, sglFullState *full_state)
00178 {
00179 bool occlusion_cull =
00180 static_cast<const sglOcclusionCull*>(
00181 full_state->m_statelet[sglStatelet::eOCCLUSION_CULL])
00182 ->isEnabled();
00183 bool transparency =
00184 static_cast<const sglTransparency*>(
00185 full_state->m_statelet[sglStatelet::eTRANSPARENCY])
00186 ->isEnabled();
00187
00188 #if 1
00189
00190
00191 transparency |=
00192 (static_cast<const sglAntiAliasPoint*>(
00193 full_state->m_statelet[sglStatelet::eANTI_ALIAS_POINT])
00194 ->isEnabled() && geom->getAAType() == sglDrawable::ePOINT_AA) ||
00195 (!sgl::s_multisample_capable &&
00196 static_cast<const sglAntiAliasLine*>(
00197 full_state->m_statelet[sglStatelet::eANTI_ALIAS_LINE])
00198 ->isEnabled() && geom->getAAType() == sglDrawable::eLINE_AA);
00199 #endif
00200
00201 if (occlusion_cull || transparency)
00202 {
00203
00204 sglVec3f center(geom->getPrevBound().getMax());
00205 center += geom->getPrevBound().getMin();
00206 center *= 0.5;
00207
00208 sglVec4f offset;
00209 static_cast<const sglTransformStateletBase*>(
00210 full_state->m_statelet[sglStatelet::eTRANSFORM_MATRIX])->mul(
00211 center, offset);
00212
00213 float range = (offset[0]*offset[0] +
00214 offset[1]*offset[1] +
00215 offset[2]*offset[2]);
00216
00217 if (occlusion_cull)
00218 {
00219 if (transparency)
00220 {
00221 sglRangeObject *obj = m_occlusion_pool.newObject();
00222 obj->set(geom, full_state, range);
00223 m_transparency_bin.push_back(obj);
00224 m_transparency_sorted_flag = false;
00225 }
00226 else
00227 {
00228 sglRangeObject *obj = m_occlusion_pool.newObject();
00229 obj->set(geom, full_state, range);
00230 m_occlusion_bin.push_back(obj);
00231 m_occlusion_sorted_flag = false;
00232 }
00233 }
00234 else
00235 {
00236 sglRangeObject *obj = m_range_pool.newObject();
00237 obj->set(geom, full_state, range);
00238 m_transparency_bin.push_back(obj);
00239 m_transparency_sorted_flag = false;
00240 }
00241 }
00242 else
00243 {
00244 sglDrawablePair* d_pair = m_drawable_pair_pool.newObject();
00245 d_pair->set(geom, full_state);
00246 m_opaque_bin->insert(d_pair);
00247 }
00248 }
00249
00250 void insert(sglDrawItem *d_item);
00251
00252 void sortBins();
00253
00254 void draw(sglCurrState *curr_state) const;
00255
00256 void statsDraw(sglCurrState *curr_state, sglStats &stats) const;
00257
00258 const sglFullState* getFirstState() const;
00259
00260 sglDrawablePair* getDrawablePair()
00261 { return m_drawable_pair_pool.newObject(); }
00262
00263 void setSortOrder(const vector<unsigned int> &sort_order);
00264
00265 const vector<unsigned int>& getSortOrder() const
00266 { return m_sort_order; }
00267
00268 void setupSort(const vector<const sglStatelet*> &statelets);
00269
00270 private:
00271 sglCullDrawablePool(const sglCullDrawablePool &);
00272 sglCullDrawablePool &operator=(const sglCullDrawablePool &);
00273
00274 private:
00275 sglDrawablePool *m_opaque_bin;
00276
00277 bool m_transparency_sorted_flag;
00278 vector<sglRangeObjectPtr> m_transparency_bin;
00279
00280 bool m_occlusion_sorted_flag;
00281 vector<sglRangeObjectPtr> m_occlusion_bin;
00282
00283 sglObjPool< sglRangeObject > m_range_pool;
00284 sglObjPool< sglOcclusionObject > m_occlusion_pool;
00285 sglObjPool< sglDrawablePair > m_drawable_pair_pool;
00286
00287 vector<unsigned int> m_sort_order;
00288 sglDrawablePoolSources &m_drawable_pool_sources;
00289 };
00290
00291
00292
00293
00297 template <class T>
00298 class SGL_DLL_API sglCull : public sglTraverser
00299 {
00300 public:
00302 sglCull();
00304 virtual ~sglCull();
00305
00307 void setSortOrder(const vector<unsigned int> &sort_order)
00308 { m_default_bin.setSortOrder(sort_order); }
00310 const vector<unsigned int>& getSortOrder() const
00311 { return m_default_bin.getSortOrder(); }
00312
00314 void initialize(float lod_scale,
00315 unsigned int discriminator_mask,
00316 unsigned int state_mask,
00317 const sglMat4<T> &view_matrix,
00318 const sglFrustum<T> &frustum,
00319 unsigned int viewport_x, unsigned int viewport_y,
00320 const vector<const sglStatelet*> &default_statelets,
00321 const deque<const sglStatelet*> &override_statelets,
00322 unsigned int frame_count,
00323 const sglTimespec &frame_time);
00324
00326 unsigned int getStateMask() const { return m_state_mask; }
00327
00329 void getViewportSize(unsigned int &x, unsigned int &y)
00330 { x = m_viewport_x; y = m_viewport_y; }
00331
00333 sglFrustum<T> &getOrigFrustum() { return m_orig_frustum; }
00335 sglFrustum<T> &getFrustum() { return m_current_frustum; }
00336
00337 void pushModelViewMatrix(const sglMat4<T>& matrix,
00338 bool rescale, bool normalize)
00339 {
00340 sglTransformStatelet<T>* trans = m_transform_pool.newObject();
00341 trans->setMatrix(matrix);
00342
00343 trans->setRescale(
00344 m_current_matrix_statelet.back()->getRescale() || rescale);
00345 trans->setNormalize(
00346 m_current_matrix_statelet.back()->getNormalize() || normalize);
00347 trans->setIndex(m_num_matrices++);
00348
00349 m_current_matrix_statelet.push_back(trans);
00350
00351 m_statelet[sglStatelet::eTRANSFORM_MATRIX] = trans;
00352 }
00353 const sglMat4<T> &getModelViewMatrix()
00354 {
00355 return m_current_matrix_statelet.back()->getMatrix();
00356 }
00357 void popModelViewMatrix()
00358 {
00359 m_current_matrix_statelet.pop_back();
00360 m_statelet[sglStatelet::eTRANSFORM_MATRIX] =
00361 m_current_matrix_statelet.back();
00362 }
00363
00364 void pushDefaultStatelet(const sglStatelet *state);
00365 void popDefaultStatelet();
00366 void pushOverrideStatelet(const sglStatelet *state);
00367 void popOverrideStatelet();
00368
00369 void addDrawable(const sglDrawable *geom,
00370 const sglDrawable::StateElement *state)
00371 {
00372 if (!geom->isValid()) return;
00373
00374 sglFullState* full_state = m_state_pool.newObject();
00375 full_state->m_tex_coords = state->getTexCoordListPtr();
00376 full_state->m_dlist = state->getDisplayList();
00377
00378 for (unsigned int ii = 0; ii < sgl::s_num_statelet_types; ++ii)
00379 full_state->m_statelet[ii] = m_statelet[ii];
00380
00381 vector<sglStatelet*>::const_iterator end =
00382 state->getStatelets().end();
00383 for (vector<sglStatelet*>::const_iterator jj =
00384 state->getStatelets().begin(); jj != end; ++jj)
00385 {
00386 unsigned int statelet_type = (*jj)->getType();
00387 if (statelet_type < sgl::s_num_statelet_types &&
00388 !m_override[statelet_type])
00389 full_state->m_statelet[statelet_type] = *jj;
00390 }
00391
00392 if (m_drawable_pool_stack.empty())
00393 {
00394 m_default_bin.insert(geom, full_state);
00395 }
00396 else
00397 {
00398 sglDrawablePair *d_pair = m_default_bin.getDrawablePair();
00399 d_pair->set(geom, full_state);
00400 m_drawable_pool_stack.back()->insert(d_pair);
00401 }
00402 }
00403
00404 sglDrawablePool* pushDrawablePool();
00405 void popDrawablePool();
00406
00407 void addLight(const sglLight* light)
00408 { m_light_processor->addLight(getModelViewMatrix(), light); }
00409
00417 void setLightProcessor(sglLightProcessor *light_processor);
00418
00422 sglLightProcessor *getLightProcessor() const
00423 { return m_light_processor; }
00424
00426 virtual void draw();
00427
00428 protected:
00429 bool initState();
00430
00431 private:
00432 sglCull(const sglCull &);
00433 sglCull& operator=(const sglCull &);
00434
00435 protected:
00436 unsigned int m_state_mask;
00437 unsigned int m_viewport_x;
00438 unsigned int m_viewport_y;
00439 sglFrustum<T> m_orig_frustum;
00440 sglFrustum<T> m_current_frustum;
00441 vector<sglTransformStatelet<T>*> m_current_matrix_statelet;
00442 unsigned int m_num_matrices;
00443
00444 vector<const sglStatelet*> m_statelet;
00445 vector<bool> m_override;
00446 vector<const sglStatelet*> m_default_state_stack;
00447 vector<const sglStatelet*> m_override_state_stack;
00448
00449 sglCurrState m_curr_state;
00450
00451 sglDrawablePoolSources m_drawable_pool_sources;
00452 sglCullDrawablePool m_default_bin;
00453 vector< sglDrawablePool* > m_drawable_pool_stack;
00454
00455 sglObjPool< sglTransformStatelet<T> > m_transform_pool;
00456 sglObjPool< sglFullState > m_state_pool;
00457
00458 sglLightProcessor *m_light_processor;
00459 };
00460
00461
00462
00463 template <class T>
00464 class SGL_DLL_API sglStatsCull : public sglCull<T>
00465 {
00466 public:
00467 sglStatsCull() : sglCull<T>() {};
00468 virtual ~sglStatsCull() {};
00469
00470 sglStats& getStats() { return m_stats; }
00471
00472 virtual void draw();
00473
00474 private:
00475 sglStatsCull(const sglStatsCull &);
00476 sglStatsCull& operator=(const sglStatsCull &);
00477
00478 protected:
00479 sglStats m_stats;
00480 };
00481
00482
00483
00484
00485
00486 typedef sglCull<float> sglCullf;
00487 typedef sglCull<double> sglCulld;
00488 typedef sglStatsCull<float> sglStatsCullf;
00489 typedef sglStatsCull<double> sglStatsCulld;
00490
00491 #endif