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

Revision 2805, 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)
66                return false;
67
68        const bool hasTexture = (mat->GetTexture() != NULL);
69
70        if (hasTexture != mBuckets[idx]->mHasTexture)
71                return false;
72
73        if (hasTexture)
74        {
75                if (mat->GetTexture()->GetWidth() != mBuckets[idx]->mTexWidth)
76                        return false;
77
78                if (mat->GetTexture()->GetHeight() != mBuckets[idx]->mTexHeight)
79                        return false;
80        }
81
82        return true;
83}
84
85
86void RenderQueue::Enqueue(SceneEntity *entity)
87{
88        RenderQueueBucket *bucket;
89        ++ mSize;
90
91        if (entity->mRenderQueueBucket)
92        {
93                bucket = entity->mRenderQueueBucket;
94        }
95        else
96        {
97                bool bucketFound = false;
98
99                size_t i = 0;
100
101                for (; i < mBuckets.size(); ++ i)
102                {
103                        if (bucketFound = FitsInBucket(entity, i))
104                                break;
105                }
106
107                // create new bucket
108                if (!bucketFound)
109                {
110                        RenderQueueBucket *bucket = new RenderQueueBucket();
111
112                        Material *mat = entity->GetMaterial();
113
114                        bucket->mAlphaTestEnabled = mat->IsAlphaTestEnabled();
115
116                        const bool hasTexture = (mat->GetTexture() != NULL);
117
118                        bucket->mHasTexture = hasTexture;
119
120                        bucket->mTexWidth = hasTexture ? mat->GetTexture()->GetWidth() : 0;
121                        bucket->mTexHeight = hasTexture ? mat->GetTexture()->GetHeight() : 0;
122
123                        mBuckets.push_back(bucket);
124
125                        // assume that the incoming nodes are ordered by distance => set min dist
126                        // on first incoming node
127                        float dist = SqrMagnitude(entity->GetBoundingBox().Center() - mCamera->GetPosition());
128                        mBuckets[i]->mMinDistance = dist;
129
130                        //cout << "num buckets: " << (int)mBuckets.size() << endl;
131                }
132
133                bucket = mBuckets[i];
134                entity->mRenderQueueBucket = bucket;
135        }
136
137        bucket->mEntities.push_back(entity);
138}
139
140
141void RenderQueue::Clear()
142{
143        for (size_t i = 0; i < mBuckets.size(); ++ i)
144                mBuckets[i]->mEntities.clear();
145
146        mSize = 0;
147}
148
149
150void RenderQueue::SetRenderState(RenderState *state)
151{
152        mState = state;
153}
154
155
156void RenderQueue::Render()
157{
158        Sort();
159       
160        // render all buckets
161        for (size_t i = 0; i < mBuckets.size(); ++ i)
162        {
163                SceneEntityContainer::const_iterator sit, sit_end = mBuckets[i]->mEntities.end();
164                for (sit = mBuckets[i]->mEntities.begin(); sit != sit_end; ++ sit)
165                {
166                        SceneEntity *ent = *sit;
167                        ent->Render(mState);
168                }
169        }
170
171        //Print();
172}
173
174
175void RenderQueue::Print()
176{
177        for (size_t i = 0; i < mBuckets.size(); ++ i)
178        {
179                Debug << "\n******\nbucket " << (int)i << endl;
180
181                SceneEntityContainer::const_iterator sit, sit_end = mBuckets[i]->mEntities.end();
182
183                for (sit = mBuckets[i]->mEntities.begin(); sit != sit_end; ++ sit)
184                {
185                        SceneEntity *ent = *sit;
186       
187                        Material *mat = ent->GetMaterial();
188                        int tsize = mat->GetTexture() ? mat->GetTexture()->GetByteSize() : 0;
189                        float dist = SqrMagnitude(ent->GetBoundingBox().Center() - mCamera->GetPosition());
190                        Debug << "e: " << ent << " a: " << mat->IsAlphaTestEnabled() << " s: " << tsize << " d: " << dist << " " << endl;
191                }
192        }
193}
194
195
196void RenderQueue::Apply()
197{
198        Render();
199        Clear();
200}
201
202
203void RenderQueue::Sort()
204{
205        // sort buckets itself
206        sort(mBuckets.begin(), mBuckets.end(), CompDist2);
207}
208
209
210}
Note: See TracBrowser for help on using the repository browser.