Changeset 2802


Ignore:
Timestamp:
06/28/08 16:12:59 (17 years ago)
Author:
mattausch
Message:

worked on renderqueue

Location:
GTP/trunk/App/Demos/Vis/FriendlyCulling
Files:
2 deleted
14 edited

Legend:

Unmodified
Added
Removed
  • GTP/trunk/App/Demos/Vis/FriendlyCulling/src/AxisAlignedBox3.cpp

    r2793 r2802  
    987987} 
    988988 
    989 //int AxisAlignedBox3::GetIndexFarthestVertex(const Vector3 &vecPlaneNormal) 
     989 
    990990int AxisAlignedBox3::GetIndexNearestVertex(const Vector3 &vecPlaneNormal) 
    991991{ 
     
    10001000 
    10011001 
    1002 //int AxisAlignedBox3::GetIndexNearestVertex(const Vector3 &vecPlaneNormal) 
    10031002int AxisAlignedBox3::GetIndexFarthestVertex(const Vector3 &vecPlaneNormal) 
    10041003{ 
     
    10101009         
    10111010        return 4 * x + 2 * y + z; 
    1012  
    1013         /*int index; 
    1014  
    1015         if (vecPlaneNormal.x <= 0.0f) 
    1016                 index = (vecPlaneNormal.y <= 0.0f) ? 0 : 3; 
    1017         else 
    1018                 index = (vecPlaneNormal.y <= 0.0f) ? 1 : 2; 
    1019  
    1020         return (vecPlaneNormal.z <= 0.0f) ? index : 7 - index;*/ 
    10211011} 
    10221012 
  • GTP/trunk/App/Demos/Vis/FriendlyCulling/src/AxisAlignedBox3.h

    r2782 r2802  
    341341        Vector3 mmin(MAXFLOAT); 
    342342        Vector3 mmax(-MAXFLOAT); 
    343  
     343         
    344344        AxisAlignedBox3 ret(mmin, mmax); 
     345         
    345346        ret.Include(tform * Vector3(box.mMin.x, box.mMin.y, box.mMin.z)); 
    346347        ret.Include(tform * Vector3(box.mMin.x, box.mMin.y, box.mMax.z)); 
     
    351352        ret.Include(tform * Vector3(box.mMax.x, box.mMax.y, box.mMin.z)); 
    352353        ret.Include(tform * Vector3(box.mMax.x, box.mMax.y, box.mMax.z)); 
     354         
    353355        return ret; 
    354356} 
  • GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Bvh.cpp

    r2800 r2802  
    154154        } 
    155155 
    156         //cout << "scene box: " << mBox << endl; 
     156        cout << "scene box: " << mBox << endl; 
    157157} 
    158158 
  • GTP/trunk/App/Demos/Vis/FriendlyCulling/src/CHCPlusPlusTraverser.cpp

    r2800 r2802  
    1515void CHCPlusPlusTraverser::HandleQueryResult(OcclusionQuery *query) 
    1616{ 
    17         waitTimer.Entry(); 
    18  
    1917        // wait until result available 
    2018        const int visible = query->GetQueryResult() > mVisibilityThreshold; 
    21  
    22         waitTimer.Exit(); 
    2319 
    2420        // multiquery 
     
    199195        if (mUseRenderQueue) ApplyRenderQueue(); 
    200196 
    201         restTimer.Entry(); 
    202197 
    203198        ////////////// 
     
    220215                HandleQueryResult(query); 
    221216        } 
    222  
    223         restTimer.Exit(); 
    224217} 
    225218 
  • GTP/trunk/App/Demos/Vis/FriendlyCulling/src/FrustumCullingTraverser.cpp

    r2795 r2802  
    11#include "FrustumCullingTraverser.h" 
    22#include "SceneEntity.h" 
    3  
    4 using namespace std; 
    53 
    64 
     
    2018                mDistanceQueue.pop(); 
    2119         
    22                 // interesting for the visualization, so rest and set 
    23                 node->SetVisible(false); 
    24  
    2520                if (mBvh->IsWithinViewFrustum(node)) 
    2621                { 
    27                         // update node's visited flag => needed for rendering 
    28                         // so set it also here 
    29                         //node->SetLastVisited(mFrameID); 
    30                         node->SetVisible(true); 
    3122                        TraverseNode(node); 
    3223                } 
  • GTP/trunk/App/Demos/Vis/FriendlyCulling/src/RenderQueue.cpp

    r2801 r2802  
    44#include "Texture.h" 
    55#include "Material.h" 
     6#include "Camera.h" 
     7 
    68 
    79using namespace std; 
     
    1315{ 
    1416 
     17static Camera *sCam = NULL; 
    1518 
    16 inline static bool CompTexture(SceneEntity *ent1, SceneEntity *ent2) 
     19 
     20inline static bool CompDist(SceneEntity *e1, SceneEntity *e2) 
    1721{ 
    18         // group by texture size 
    19         Texture *t1 = ent1->GetMaterial()->GetTexture(); 
    20         Texture *t2 = ent2->GetMaterial()->GetTexture(); 
    21  
    22         int tsize1 = t1 ? t1->GetByteSize() : 0; 
    23         int tsize2 = t2 ? t2->GetByteSize() : 0; 
    24  
    25         return tsize1 > tsize2; 
     22        return  
     23                (SqrMagnitude(e1->GetBoundingBox().Center() - sCam->GetPosition()) < 
     24                 SqrMagnitude(e2->GetBoundingBox().Center() - sCam->GetPosition())); 
    2625} 
    2726 
    2827 
    29 #ifdef SORT_ALPHA 
    30  
    31 inline static bool CompMat(SceneEntity *ent1, SceneEntity *ent2) 
    32 {  
    33         return ent1->GetMaterial()->IsAlphaTestEnabled() < ent2->GetMaterial()->IsAlphaTestEnabled(); 
     28inline static bool CompDist2(RenderQueueBucket *b1, RenderQueueBucket *b2) 
     29{ 
     30        return (b1->mMinDistance < b2->mMinDistance); 
    3431} 
    3532 
    36 #else 
    3733 
    38 inline static bool CompMat(SceneEntity *ent1, SceneEntity *ent2) 
    39 { 
    40         return ent1->GetMaterial() < ent2->GetMaterial(); 
    41 } 
    42  
    43 #endif 
    44  
    45  
    46 RenderQueue::RenderQueue(): mState(NULL), mMinSizeForSorting(3) 
     34RenderQueue::RenderQueue():  
     35mState(NULL),  
     36mMinSizeForSorting(3), 
     37mCamera(NULL), 
     38mSize(0) 
    4739{ 
    4840} 
    4941 
    5042 
    51 RenderQueue::RenderQueue(RenderState *state): 
    52 mState(state), mMinSizeForSorting(3) 
     43RenderQueue::RenderQueue(RenderState *state, Camera *cam): 
     44mState(state),  
     45mMinSizeForSorting(3), 
     46mCamera(cam), 
     47mSize(0) 
    5348{ 
     49        sCam = cam; 
     50} 
     51 
     52 
     53RenderQueue::~RenderQueue() 
     54{ 
     55        for (size_t i = 0; i < mBuckets.size(); ++ i) 
     56        { 
     57                DEL_PTR(mBuckets[i]); 
     58        } 
     59} 
     60 
     61 
     62bool RenderQueue::FitsInBucket(SceneEntity *ent, size_t idx) const 
     63{ 
     64        Material *mat = ent->GetMaterial(); 
     65 
     66        // test if entity  
     67        if (mat->IsAlphaTestEnabled() != mBuckets[idx]->mAlphaTestEnabled) 
     68                return false; 
     69 
     70        int tsize = mat->GetTexture() ? mat->GetTexture()->GetByteSize() : 0; 
     71        if (tsize != mBuckets[idx]->mTextureSize) 
     72                return false; 
     73 
     74        return true; 
    5475} 
    5576 
     
    5778void RenderQueue::Enqueue(SceneEntity *entity) 
    5879{ 
    59         mEntities.push_back(entity); 
     80        RenderQueueBucket *bucket; 
     81        ++ mSize; 
     82 
     83        if (entity->mRenderQueueBucket) 
     84        { 
     85                bucket = entity->mRenderQueueBucket; 
     86        } 
     87        else 
     88        { 
     89                bool bucketFound = false; 
     90 
     91                size_t i = 0; 
     92 
     93                for (; i < mBuckets.size(); ++ i) 
     94                { 
     95                        if (bucketFound = FitsInBucket(entity, i)) 
     96                                break; 
     97                } 
     98 
     99                // create new bucket 
     100                if (!bucketFound) 
     101                { 
     102                        RenderQueueBucket *bucket = new RenderQueueBucket(); 
     103 
     104                        Material *mat = entity->GetMaterial(); 
     105 
     106                        bucket->mAlphaTestEnabled = mat->IsAlphaTestEnabled(); 
     107                        bucket->mTextureSize = mat->GetTexture() ? mat->GetTexture()->GetByteSize() : 0; 
     108 
     109                        mBuckets.push_back(bucket); 
     110 
     111                        // assume that the incoming nodes are ordered by distance => set min dist 
     112                        // on first incoming node 
     113                        float dist = SqrMagnitude(entity->GetBoundingBox().Center() - mCamera->GetPosition()); 
     114                        mBuckets[i]->mMinDistance = dist; 
     115 
     116                        //cout << "num buckets: " << (int)mBuckets.size() << endl; 
     117                } 
     118 
     119                bucket = mBuckets[i]; 
     120                entity->mRenderQueueBucket = bucket; 
     121        } 
     122 
     123        bucket->mEntities.push_back(entity); 
    60124} 
    61          
     125 
    62126 
    63127void RenderQueue::Clear() 
    64128{ 
    65         mEntities.clear(); 
     129        for (size_t i = 0; i < mBuckets.size(); ++ i) 
     130                mBuckets[i]->mEntities.clear(); 
    66131 
     132        mSize = 0; 
    67133} 
    68134 
     
    76142void RenderQueue::Render() 
    77143{ 
    78         if (mEntities.size() >= mMinSizeForSorting) 
     144        Sort(); 
     145         
     146        // render all buckets 
     147        for (size_t i = 0; i < mBuckets.size(); ++ i) 
    79148        { 
    80                 sortTimer.Entry(); 
    81                 Sort(); 
    82                 sortTimer.Exit(); 
    83         } 
    84          
    85         SceneEntityContainer::const_iterator sit, sit_end = mEntities.end(); 
    86  
    87         for (sit = mEntities.begin(); sit != sit_end; ++ sit) 
    88         { 
    89                 SceneEntity *ent = *sit; 
    90                 ent->Render(mState); 
     149                SceneEntityContainer::const_iterator sit, sit_end = mBuckets[i]->mEntities.end(); 
     150                for (sit = mBuckets[i]->mEntities.begin(); sit != sit_end; ++ sit) 
     151                { 
     152                        SceneEntity *ent = *sit; 
     153                        ent->Render(mState); 
     154                } 
    91155        } 
    92156 
     
    97161void RenderQueue::Print() 
    98162{ 
    99         SceneEntityContainer::const_iterator sit, sit_end = mEntities.end(); 
     163        for (size_t i = 0; i < mBuckets.size(); ++ i) 
     164        { 
     165                Debug << "\n******\nbucket " << i << endl; 
    100166 
    101         Debug << "\nrq size: " << GetSize() << endl; 
    102         Debug << "texture size: " << endl; 
     167                SceneEntityContainer::const_iterator sit, sit_end = mBuckets[i]->mEntities.end(); 
    103168 
    104         // show ordering by texture size 
    105         for (sit = mEntities.begin(); sit != sit_end; ++ sit) 
    106         { 
    107                 SceneEntity *ent = *sit; 
    108                 Texture *t = ent->GetMaterial()->GetTexture(); 
     169                for (sit = mBuckets[i]->mEntities.begin(); sit != sit_end; ++ sit) 
     170                { 
     171                        SceneEntity *ent = *sit; 
    109172         
    110                 int tsize = t ? t->GetByteSize() : 0; 
    111                 Debug << tsize << " "; 
    112         } 
    113  
    114         // show ordering by material 
    115         Debug << "\nmaterial: " << endl; 
    116          
    117         for (sit = mEntities.begin(); sit != sit_end; ++ sit) 
    118         { 
    119 #ifdef SORT_ALPHA 
    120                 Debug << (*sit)->GetMaterial()->IsAlphaTestEnabled() << " "; 
    121 #else 
    122                 Debug << (*sit)->GetMaterial() << " "; 
    123 #endif 
     173                        Material *mat = ent->GetMaterial(); 
     174                        int tsize = mat->GetTexture() ? mat->GetTexture()->GetByteSize() : 0; 
     175                        float dist = SqrMagnitude(ent->GetBoundingBox().Center() - mCamera->GetPosition()); 
     176                        Debug << "e: " << ent << " a: " << mat->IsAlphaTestEnabled() << " s: " << tsize << " d: " << dist << " " << ent->GetBoundingBox() << " g: " << ent->GetGeometry() << " t: " << ent->GetTransformation() << " m: " << ent->GetMaterial() << endl; 
     177                } 
    124178        } 
    125179} 
     
    135189void RenderQueue::Sort() 
    136190{ 
    137 #ifdef SORT_ALPHA 
    138         // sort by texture size 
    139         sort(mEntities.begin(), mEntities.end(), CompTexture); 
    140         // sort by alpha test enabled 
    141         stable_sort(mEntities.begin(), mEntities.end(), CompMat); 
    142 #else 
    143         // sort by material 
    144         sort(mEntities.begin(), mEntities.end(), CompMat); 
    145         // sort by texture size 
    146         stable_sort(mEntities.begin(), mEntities.end(), CompTexture); 
    147 #endif 
     191        // sort buckets itself 
     192        sort(mBuckets.begin(), mBuckets.end(), CompDist2); 
    148193} 
    149194 
  • GTP/trunk/App/Demos/Vis/FriendlyCulling/src/RenderQueue.h

    r2801 r2802  
    1010 
    1111class RenderState; 
     12class Camera; 
    1213 
    1314 
    14 /** This class implements a render queue that sorts entities according to 
    15         their materials. 
     15/** Defines a bucket for scene entities that have the same properties. 
     16*/ 
     17struct RenderQueueBucket 
     18{ 
     19        /** should be full texture format, but we as use the same format for all textures 
     20            they differ only in size, and we implicitly assume that textures with the same  
     21            size have exactly the same format 
     22        */ 
     23        int mTextureSize; 
     24        bool mAlphaTestEnabled; 
     25 
     26        /// minimal distance to the camera 
     27        float mMinDistance; 
     28 
     29        SceneEntityContainer mEntities; 
     30}; 
     31 
     32 
     33/** This class implements a render queue that sorts renderable geometry in order 
     34        to minimize state changes while approximately keeping front-to-back order 
     35        The implementation roughly follows the suggested implemenation on Tom Forsyth's article 
     36        on render state changes. It requires sorting only on bucket level and therefore has very 
     37        low overhead 
    1638*/ 
    1739class RenderQueue 
     
    2446        /** Constructor taking a render queue 
    2547        */ 
    26         RenderQueue(RenderState *state); 
    27         /** Enqueues an entity 
     48        RenderQueue(RenderState *state, Camera *cam); 
     49 
     50        ~RenderQueue(); 
     51        /** Enqueues an entity. 
    2852        */ 
    2953        void Enqueue(SceneEntity *entity); 
     54        /** Sets the current render state 
     55        */ 
     56        void SetRenderState(RenderState *state); 
     57        /** Sets the current render state 
     58        */ 
     59        void SetCamera(Camera *cam); 
     60        /** Returns the number entities currently in the queue. 
     61        */ 
     62        inline int GetSize() const { return (int)mSize; } 
     63        /** Renders and clears the queue. 
     64        */ 
     65        void Apply(); 
     66 
     67 
     68protected: 
     69 
     70        inline bool FitsInBucket(SceneEntity *ent, size_t idx) const; 
     71 
     72        /** Sorts the render queue by materials / textures. 
     73        */ 
     74        void Sort(); 
     75        /** Clears the render queue 
     76        */ 
     77        void Clear(); 
    3078        /** Renders the contents of the render queue. 
    3179        */ 
    3280        void Render(); 
    33         /** Sets the current render state 
    34         */ 
    35         void SetRenderState(RenderState *state); 
    36         /** Clears the render queue 
    37         */ 
    38         void Clear(); 
    39         /** Returns the number entities currently in the queue. 
    40         */ 
    41         inline int GetSize() const { return (int)mEntities.size(); } 
    42         /** Renders and clears the queue. 
    43         */ 
    44         void Apply(); 
    4581        /** Prints the current state of the render queue. 
    4682        */ 
    4783        void Print(); 
    4884 
    49 protected: 
    50  
    51         /** Sorts the render queue by materials / textures. 
    52         */ 
    53         void Sort(); 
    54  
    55  
    5685        /////////// 
    5786 
    5887        RenderState *mState; 
    59         SceneEntityContainer mEntities; 
     88        Camera *mCamera; 
     89        //SceneEntityContainer mEntities; 
    6090        int mMinSizeForSorting; 
     91 
     92        /// each bucket contains objects with similar materials that don't cause a hard state change 
     93        std::vector<RenderQueueBucket *> mBuckets; 
     94 
     95        int mSize; 
    6196}; 
    62  
    63 /// measures sort time for detailed benchmarks 
    64 static PerfTimer sortTimer; 
    6597 
    6698 
  • GTP/trunk/App/Demos/Vis/FriendlyCulling/src/RenderTraverser.cpp

    r2801 r2802  
    168168        glDisableClientState(GL_VERTEX_ARRAY); 
    169169        glDisableClientState(GL_NORMAL_ARRAY); 
    170          
    171  
    172 #ifdef PRINT_VERBOSE_BENCHMARKS 
    173  
    174         Debug << "traversal type: " << GetType() << endl; 
    175         if (mUseRenderQueue) Debug << "rq sort: " << 1e3f * mRenderQueue.sortTimer.TotalTime() << " ms" << endl; 
    176          
    177         Debug << "wait time: " << 1e3f * waitTimer.TotalTime() << " ms" << endl; 
    178         Debug << "query time: " << 1e3f * queryTimer.TotalTime() << " ms" << endl; 
    179         Debug << "rest time: " << 1e3f * restTimer.TotalTime() << " ms" << endl; 
    180  
    181 #endif 
     170 
     171        //cout << "rq overhead: " << 1e3f * mRenderQueue->rTimer.TotalTime() << " ms" << endl; 
    182172} 
    183173 
     
    243233OcclusionQuery *RenderTraverser::IssueOcclusionQuery(BvhNode *node) 
    244234{ 
    245         queryTimer.Entry(); 
    246  
    247235        OcclusionQuery *query = mQueryHandler.RequestQuery(); 
    248236        query->AddNode(node); 
    249237 
    250238        IssueOcclusionQuery(*query); 
    251  
    252         queryTimer.Exit(); 
    253239 
    254240        return query; 
  • GTP/trunk/App/Demos/Vis/FriendlyCulling/src/RenderTraverser.h

    r2801 r2802  
    216216 
    217217 
    218 /// timers for detailed benchmarks 
    219 static PerfTimer restTimer; 
    220 static PerfTimer waitTimer; 
    221 static PerfTimer queryTimer; 
    222218 
    223219} 
  • GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SceneEntity.cpp

    r2795 r2802  
    1313                                                 Material *mat, 
    1414                                                 Matrix4x4 *trafo): 
    15 mGeometry(geometry), mMaterial(mat), mTransform(trafo) 
     15mGeometry(geometry), mMaterial(mat), mTransform(trafo), mRenderQueueBucket(NULL) 
    1616{ 
    1717} 
  • GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SceneEntity.h

    r2795 r2802  
    1313class Geometry; 
    1414class RenderState; 
    15  
     15struct RenderQueueBucket; 
    1616 
    1717/** Class representing a scene entity. 
     
    2020class SceneEntity 
    2121{ 
     22        friend class RenderQueue; 
     23 
    2224public: 
    2325        /** Creates a scene entity. 
     
    5254 
    5355        inline Material *GetMaterial() const  { return mMaterial; } 
     56        inline Matrix4x4 *GetTransformation() const  { return mTransform; } 
    5457 
    5558protected: 
     
    6164         
    6265        int mLastRendered; 
     66        /// pointer to the renderqueue bucket this entity belongs to 
     67        RenderQueueBucket *mRenderQueueBucket; 
    6368}; 
    6469 
  • GTP/trunk/App/Demos/Vis/FriendlyCulling/src/StopAndWaitTraverser.cpp

    r2800 r2802  
    3333                                OcclusionQuery *query = IssueOcclusionQuery(node); 
    3434 
    35                                 waitTimer.Entry(); 
    36                                 bool visible = query->GetQueryResult() > mVisibilityThreshold; 
    37                                 waitTimer.Exit(); 
    38  
     35                                const bool visible = query->GetQueryResult() > mVisibilityThreshold; 
     36                         
    3937                                if (visible) 
    4038                                { 
     
    4341                                else 
    4442                                { 
    45                                         node->SetVisible(false); 
    4643                                        ++ mStats.mNumQueryCulledNodes; 
    4744                                } 
    48                                  
    49                                 // update node's visited flag (could be interesting for the visualization) 
    50                                 node->SetVisible(visible);               
    5145                        } 
    5246                } 
  • GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Timer/PerfTimer.h

    r2801 r2802  
    2222#define _PERFTIMER_H 
    2323 
    24 // RDTSC timer does not work with modern CPUs 
     24// note: RDTSC timer does not work with modern CPUs 
    2525#define NO_RDTSC_TIMER 
    2626 
  • GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp

    r2801 r2802  
    168168        visCamera->Yaw(.5 * M_PI); 
    169169 
    170         renderQueue = new RenderQueue(&state); 
     170        renderQueue = new RenderQueue(&state, camera); 
    171171 
    172172        glutInitWindowSize(winWidth, winHeight); 
     
    518518        // note: have to flush queue in order to get reliable timings 
    519519        // for optimal performance, remove this 
    520         glFinish(); 
     520        //glFinish(); 
    521521 
    522522        algTimer.Start(); 
     
    575575        // note: have to flush queue in order to get reliable timings 
    576576        // for optimal performance, remove this 
    577         glFinish(); 
     577        //glFinish(); 
    578578        algTime = algTimer.Elapsedms(); 
    579579 
     
    10911091        const float expFactor = 0.3f; 
    10921092 
    1093         // if there was something fishy going on in this frame => don't count 
    1094         if (algTime < 1000)  
    1095                 renderTime = algTime * expFactor + (1.0f - expFactor) * algTime; 
    1096  
    1097         accumulatedTime += renderTime; 
     1093        //if (useRenderQueue) cout << "rq overhead: " << 1e6f * rqTimer.TotalTime() << " ms" << endl; 
     1094 
     1095        // if some strange render time spike happened in this frame => don't count 
     1096        //if (algTime < 1000) renderTime = algTime * expFactor + (1.0f - expFactor) * algTime; 
     1097 
     1098        renderTime = 1e3f * (elapsedTime * expFactor + (1.0f - expFactor) * elapsedTime); 
     1099 
     1100        accumulatedTime += elapsedTime * 1e3f; 
    10981101 
    10991102        if (accumulatedTime > 500) // update every fraction of a second 
Note: See TracChangeset for help on using the changeset viewer.