source: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/RenderQueue.cpp @ 2848

Revision 2848, 4.4 KB checked in by mattausch, 16 years ago (diff)
RevLine 
[2767]1#include "RenderQueue.h"
2#include "SceneEntity.h"
3#include "Geometry.h"
4#include "Texture.h"
5#include "Material.h"
[2802]6#include "Camera.h"
[2840]7#include "Shape.h"
[2767]8
[2802]9
[2768]10using namespace std;
[2767]11
[2768]12
[2776]13namespace CHCDemoEngine
[2767]14{
15
16
[2844]17inline static bool CompDist(RenderQueueBucket *b1, RenderQueueBucket *b2)
[2802]18{
19        return (b1->mMinDistance < b2->mMinDistance);
[2767]20}
21
22
[2842]23
[2802]24RenderQueue::RenderQueue():
25mState(NULL),
26mMinSizeForSorting(3),
27mCamera(NULL),
[2844]28mNumEntries(0)
[2802]29{
[2801]30}
31
32
[2802]33RenderQueue::RenderQueue(RenderState *state, Camera *cam):
34mState(state),
35mMinSizeForSorting(3),
36mCamera(cam),
[2844]37mNumEntries(0)
[2795]38{
39}
40
41
[2802]42RenderQueue::~RenderQueue()
[2767]43{
[2802]44        for (size_t i = 0; i < mBuckets.size(); ++ i)
45        {
46                DEL_PTR(mBuckets[i]);
47        }
[2767]48}
49
50
[2841]51bool RenderQueue::FitsInBucket(Shape *shape, size_t idx) const
[2767]52{
[2841]53        Material *mat = shape->GetMaterial();
54
[2826]55        // test if entity belongs to this bucket
56        // note: rather slows down the application for some reason!!
[2841]57        if (mat->IsAlphaTestEnabled() != mBuckets[idx]->mAlphaTestEnabled)
[2826]58                return false;
[2802]59
[2845]60        if (mat->IsCullFaceEnabled() != mBuckets[idx]->mCullFaceEnabled)
[2844]61                return false;
62
[2805]63        const bool hasTexture = (mat->GetTexture() != NULL);
64
65        if (hasTexture != mBuckets[idx]->mHasTexture)
[2802]66                return false;
67
[2805]68        if (hasTexture)
69        {
70                if (mat->GetTexture()->GetWidth() != mBuckets[idx]->mTexWidth)
71                        return false;
72
73                if (mat->GetTexture()->GetHeight() != mBuckets[idx]->mTexHeight)
74                        return false;
75        }
76
[2802]77        return true;
[2767]78}
79
80
[2773]81void RenderQueue::Enqueue(SceneEntity *entity)
[2767]82{
[2844]83        ShapeContainer::iterator sit, sit_end;
[2841]84
[2844]85        entity->GetCurrentLODLevel(sit, sit_end);
[2841]86
[2844]87        for (; sit != sit_end; ++ sit)
[2841]88        {
89                Enqueue(*sit);
90        }
91}
92
93
94void RenderQueue::Enqueue(Shape *shape)
95{
[2802]96        RenderQueueBucket *bucket;
[2844]97        ++ mNumEntries;
[2841]98       
[2842]99        if (shape->mRenderQueueBucket)
[2802]100        {
[2842]101                bucket = shape->mRenderQueueBucket;
[2802]102        }
103        else
104        {
105                bool bucketFound = false;
106
107                size_t i = 0;
108
109                for (; i < mBuckets.size(); ++ i)
110                {
[2842]111                        if (bucketFound = FitsInBucket(shape, i))
[2802]112                                break;
113                }
114
115                // create new bucket
116                if (!bucketFound)
117                {
118                        RenderQueueBucket *bucket = new RenderQueueBucket();
[2844]119                        bucket->mMinDistance = -1;
[2802]120
[2842]121                        Material *mat = shape->GetMaterial();
[2802]122
123                        bucket->mAlphaTestEnabled = mat->IsAlphaTestEnabled();
[2844]124                        bucket->mCullFaceEnabled = mat->IsCullFaceEnabled();
[2802]125
[2805]126                        const bool hasTexture = (mat->GetTexture() != NULL);
127
128                        bucket->mHasTexture = hasTexture;
129
130                        bucket->mTexWidth = hasTexture ? mat->GetTexture()->GetWidth() : 0;
131                        bucket->mTexHeight = hasTexture ? mat->GetTexture()->GetHeight() : 0;
132
[2802]133                        mBuckets.push_back(bucket);
134
135                        //cout << "num buckets: " << (int)mBuckets.size() << endl;
136                }
137
138                bucket = mBuckets[i];
[2842]139                shape->mRenderQueueBucket = bucket;
[2802]140        }
[2840]141
[2845]142        if (bucket->mMinDistance < .0f)
[2844]143        {
144                // assume that the incoming nodes are ordered by distance
145                // => set min dist on first incoming node
[2847]146                const Vector3 v = shape->GetCenter() - mCamera->GetPosition();
[2844]147               
148                const float dist = SqrMagnitude(v);
149                bucket->mMinDistance = dist;
150        }
151
[2842]152        bucket->mShapes.push_back(shape);
[2767]153}
154
[2802]155
[2767]156void RenderQueue::Clear()
157{
[2802]158        for (size_t i = 0; i < mBuckets.size(); ++ i)
[2844]159        {
160                mBuckets[i]->mMinDistance = -1;
[2840]161                mBuckets[i]->mShapes.clear();
[2844]162        }
[2767]163
[2844]164        mNumEntries = 0;
[2767]165}
166
167
168void RenderQueue::SetRenderState(RenderState *state)
169{
170        mState = state;
171}
172
173
174void RenderQueue::Render()
175{
[2842]176        // sort the buckets
[2802]177        Sort();
[2842]178
[2802]179        // render all buckets
180        for (size_t i = 0; i < mBuckets.size(); ++ i)
[2767]181        {
[2840]182                ShapeContainer::const_iterator sit, sit_end = mBuckets[i]->mShapes.end();
183
184                for (sit = mBuckets[i]->mShapes.begin(); sit != sit_end; ++ sit)
[2802]185                {
[2840]186                        Shape *shape = *sit;
187                        shape->Render(mState);
[2802]188                }
[2767]189        }
[2795]190        //Print();
[2767]191}
[2795]192
193
194void RenderQueue::Print()
195{
[2802]196        for (size_t i = 0; i < mBuckets.size(); ++ i)
197        {
[2804]198                Debug << "\n******\nbucket " << (int)i << endl;
[2795]199
[2840]200                ShapeContainer::const_iterator sit, sit_end = mBuckets[i]->mShapes.end();
[2800]201
[2840]202                for (sit = mBuckets[i]->mShapes.begin(); sit != sit_end; ++ sit)
[2802]203                {
[2840]204                        Shape *shape = *sit;
205                       
206                        Material *mat = shape->GetMaterial();
[2802]207                        int tsize = mat->GetTexture() ? mat->GetTexture()->GetByteSize() : 0;
[2841]208                       
[2840]209                        float dist = SqrMagnitude(shape->GetBoundingBox().Center() - mCamera->GetPosition());
[2841]210                       
[2840]211                        Debug << "e: " << shape << " a: " << mat->IsAlphaTestEnabled() << " s: " << tsize << " d: " << dist << " " << endl;
[2802]212                }
[2795]213        }
214}
[2767]215
[2795]216
[2842]217void RenderQueue::Sort()
[2795]218{
[2842]219        // sort buckets itself
[2844]220        sort(mBuckets.begin(), mBuckets.end(), CompDist);
[2795]221}
222
223
[2842]224void RenderQueue::Apply()
[2767]225{
[2842]226        Render();
227        Clear();
[2767]228}
229
230
231}
Note: See TracBrowser for help on using the repository browser.