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

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