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

Revision 3054, 5.8 KB checked in by mattausch, 16 years ago (diff)

worked on render queue

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