Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   Related Pages  

sglCull.hpp

00001 /*****************************************************************************
00002  * SGL: A Scene Graph Library
00003  *
00004  * Copyright (C) 1997-2001  Scott McMillan   All Rights Reserved.
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Library General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Library General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Library General Public
00017  * License along with this library; if not, write to the Free
00018  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019  *****************************************************************************
00020  *     File: sglCull.hpp (was sglTraversal.hpp)
00021  *  Created: 13 February 1999
00022  *  Summary: contains the traversal state for cull traversals
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 // This is the object stored in the transparency bin contains a pointer to a
00047 // geoset/geostate/texcoord triplet with transparency enabled, the range (used
00048 // for ordering), and any other state information needed to draw it
00049 
00050 class sglRangeObject;
00051 typedef sglRangeObject* sglRangeObjectPtr; // readability
00052 
00053 
00054 class SGL_DLL_API sglRangeObject
00055 {
00056 public:
00057    sglRangeObject() {};
00058    virtual ~sglRangeObject() {};
00059 
00060    // Smaller range means lower priority for the transparency bin.
00061    // This SmallerRange function is used by the sort on the transparency bin
00062    // to determine proper ordering of objects
00063    static bool smallerRange(const sglRangeObjectPtr &x,
00064                             const sglRangeObjectPtr &y);
00065 
00066    // This GreaterRange function is used by the sort on the occlusion bin
00067    // to determine proper ordering of objects
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: // not implemented
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 // This is the object stored in the occlusion bin.  An occlusiong test
00097 // is done before attempting to draw.
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: // not implemented
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: // not implemented
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          // For best rendering results antialiased primitives need to be
00190          // sorted due to the blending.
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             // compute the range to ?the center of the bounding box?
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:  // not implemented
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: // not implemented
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: // not implemented
00475    sglStatsCull(const sglStatsCull &);
00476    sglStatsCull& operator=(const sglStatsCull &);
00477 
00478 protected:
00479    sglStats  m_stats;
00480 };
00481 
00482 //----------------------------------------------------------------------------
00483 // convenience types:
00484 //    template class 'should' only be float or double
00485 
00486 typedef sglCull<float>       sglCullf;
00487 typedef sglCull<double>      sglCulld;
00488 typedef sglStatsCull<float>  sglStatsCullf;
00489 typedef sglStatsCull<double> sglStatsCulld;
00490 
00491 #endif

Generated at Mon Jul 1 18:00:04 2002 for SGL by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001