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

Revision 3060, 6.0 KB checked in by mattausch, 16 years ago (diff)

updated render queue: as we assume incoming nodes to be sorted front to back,
no sorting is required anymore

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#include "Shape.h"
8#include "RenderState.h"
9
10using namespace std;
11
12
13namespace CHCDemoEngine
14{
15
16
17/*inline static bool CompDist(RenderQueueBucket *b1, RenderQueueBucket *b2)
18{
19        return (b1->mMinDistance < b2->mMinDistance);
20}*/
21RenderQueue::RenderQueue():
22mState(NULL),
23mCamera(NULL),
24mNumEntries(0)
25{
26}
27
28
29RenderQueue::RenderQueue(RenderState *state, Camera *cam):
30mState(state),
31mCamera(cam),
32mNumEntries(0)
33{
34}
35
36
37RenderQueue::~RenderQueue()
38{
39        for (size_t i = 0; i < mBuckets.size(); ++ i)
40        {
41                DEL_PTR(mBuckets[i]);
42        }
43}
44
45
46bool RenderQueue::FitsInBucket(Shape *shape, size_t idx) const
47{
48        Technique *tech = shape->GetMaterial()->GetTechnique(mState->GetRenderTechnique());
49
50        // test if entity belongs to this bucket
51        if (tech->IsAlphaTestEnabled() != mBuckets[idx]->mAlphaTestEnabled) { return false; }
52        if (tech->IsCullFaceEnabled() != mBuckets[idx]->mCullFaceEnabled) { return false; }
53        if (tech->IsColorWriteEnabled() != mBuckets[idx]->mColorWriteEnabled) { return false; }
54        if (tech->IsLightingEnabled() != mBuckets[idx]->mLightingEnabled) { return false; }
55        if (tech->IsDepthWriteEnabled() != mBuckets[idx]->mDepthWriteEnabled) { return false; }
56
57        //if (tech->IsColorWriteEnabled()) cout << "x";
58
59        const bool hasTexture = (tech->GetTexture() != NULL);
60
61        if (hasTexture != mBuckets[idx]->mHasTexture) { return false; }
62
63        if (hasTexture)
64        {
65                if (tech->GetTexture()->GetWidth() != mBuckets[idx]->mTexWidth) { return false; }
66                if (tech->GetTexture()->GetHeight() != mBuckets[idx]->mTexHeight) {return false; }
67                if (tech->GetTexture()->GetFormat() != mBuckets[idx]->mTexFormat) { return false; }
68        }
69
70        //if (!tech->GetFragmentProgram() && mBuckets[idx]->mHasFragmentProgram) { return false; }
71        //if (!tech->GetVertexProgram() && mBuckets[idx]->mHasVertexProgram) { return false; }
72        if (tech->GetFragmentProgram() != mBuckets[idx]->mFragmentProgram) { return false; }
73        if (tech->GetVertexProgram() != mBuckets[idx]->mVertexProgram) { return false; }
74
75        return true;
76}
77
78
79void RenderQueue::Enqueue(SceneEntity *entity)
80{
81        ShapeContainer::iterator sit, sit_end;
82
83        entity->GetCurrentLODLevel(sit, sit_end);
84
85        for (; sit != sit_end; ++ sit)
86        {
87                Enqueue(*sit);
88        }
89}
90
91
92void RenderQueue::Enqueue(Shape *shape)
93{
94        Technique *tech = shape->GetMaterial()->GetTechnique(mState->GetRenderTechnique());
95        RenderQueueBucket *bucket = tech->mRenderQueueBucket;
96
97        ++ mNumEntries;
98       
99        if (!bucket)
100        {
101                bool bucketFound = false;
102
103                size_t i = 0;
104
105                for (; i < mBuckets.size(); ++ i)
106                {
107                        if (bucketFound = FitsInBucket(shape, i))
108                                break;
109                }
110
111                // create new bucket
112                if (!bucketFound)
113                {
114                        RenderQueueBucket *bucket = new RenderQueueBucket();
115                        //bucket->mMinDistance = -1;
116
117                        bucket->mAlphaTestEnabled = tech->IsAlphaTestEnabled();
118                        bucket->mCullFaceEnabled = tech->IsCullFaceEnabled();
119
120                        bucket->mColorWriteEnabled = tech->IsColorWriteEnabled();
121                        bucket->mLightingEnabled = tech->IsLightingEnabled();
122                        bucket->mDepthWriteEnabled = tech->IsDepthWriteEnabled();
123
124
125                        Texture *tex = tech->GetTexture();
126
127                        if (tex != NULL)
128                        {
129                                bucket->mHasTexture = true;
130
131                                bucket->mTexWidth = tex->GetWidth();
132                                bucket->mTexHeight = tex->GetHeight();
133
134                                bucket->mTexFormat = tex->GetFormat();
135                        }
136                        else
137                        {
138                                bucket->mHasTexture = false;
139
140                                bucket->mTexWidth = 0;
141                                bucket->mTexHeight = 0;
142                                bucket->mTexFormat = 0;
143                        }
144
145                        //      bucket->mHasVertexProgram = (tech->GetVertexProgram() != NULL);
146                        //      bucket->mHasFragmentProgram = (tech->GetFragmentProgram() != NULL);
147                        bucket->mVertexProgram = tech->GetVertexProgram();
148                        bucket->mFragmentProgram = tech->GetFragmentProgram();
149
150                        mBuckets.push_back(bucket);
151                        //cout << "increased #buckets to " << (int)mBuckets.size() << endl;
152                }
153
154                bucket = mBuckets[i];
155                tech->mRenderQueueBucket = bucket;
156        }
157
158        if (bucket->IsEmpty())
159        {
160                // add to currently active buckets that will be rendered
161                // assume that the incoming nodes are ordered by distance
162                // => active buckets are sorted by distance
163                mActiveBuckets.push_back(bucket);
164       
165                // => set min dist on first incoming node
166                //const Vector3 v = shape->GetCenter() - mCamera->GetPosition();
167                //const float dist = SqrMagnitude(v);
168                //bucket->mMinDistance = dist;
169
170                }
171
172        bucket->mShapes.push_back(shape);
173}
174
175
176void RenderQueue::Clear()
177{
178        for (size_t i = 0; i < mActiveBuckets.size(); ++ i)
179        {
180                //mBuckets[i]->mMinDistance = -1;
181                mActiveBuckets[i]->mShapes.clear();
182        }
183
184        mNumEntries = 0;
185
186        mActiveBuckets.clear();
187}
188
189
190void RenderQueue::SetRenderState(RenderState *state)
191{
192        mState = state;
193}
194
195
196void RenderQueue::Render()
197{
198        // sort the buckets
199        //Sort();
200
201        // render all buckets
202        for (size_t i = 0; i < mBuckets.size(); ++ i)
203        {
204                ShapeContainer::const_iterator sit, sit_end = mBuckets[i]->mShapes.end();
205
206                for (sit = mBuckets[i]->mShapes.begin(); sit != sit_end; ++ sit)
207                {
208                        Shape *shape = *sit;
209                        shape->Render(mState);
210                }
211        }
212        //Print();
213}
214
215
216void RenderQueue::Print()
217{
218        for (size_t i = 0; i < mBuckets.size(); ++ i)
219        {
220                Debug << "\n******\nbucket " << (int)i << endl;
221
222                ShapeContainer::const_iterator sit, sit_end = mBuckets[i]->mShapes.end();
223
224                for (sit = mBuckets[i]->mShapes.begin(); sit != sit_end; ++ sit)
225                {
226                        Shape *shape = *sit;
227                       
228                        Technique *tech = shape->GetMaterial()->GetTechnique(mState->GetRenderTechnique());
229                        int tsize = tech->GetTexture() ? tech->GetTexture()->GetByteSize() : 0;
230                       
231                        float dist = SqrMagnitude(shape->GetBoundingBox().Center() - mCamera->GetPosition());
232                       
233                        Debug << "e: " << shape << " a: " << tech->IsAlphaTestEnabled() << " s: " << tsize << " d: " << dist << " " << endl;
234                }
235        }
236}
237
238
239/*void RenderQueue::Sort()
240{
241        // sort buckets itself by distance
242        sort(mBuckets.begin(), mBuckets.end(), CompDist);
243}*/
244
245
246void RenderQueue::Apply()
247{
248        Render();
249        Clear();
250}
251
252
253}
Note: See TracBrowser for help on using the repository browser.