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

Revision 2826, 4.2 KB checked in by mattausch, 16 years ago (diff)

changed font

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