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

Revision 3238, 5.0 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#include "Shape.h"
8#include "RenderState.h"
9#include "Transform3.h"
10
11
12using namespace std;
13
14
15namespace CHCDemoEngine
16{
17
18RenderQueue::RenderQueue():
19mState(NULL),
20mNumEntries(0)
21{
22}
23
24
25RenderQueue::RenderQueue(RenderState *state):
26mState(state),
27mNumEntries(0)
28{
29}
30
31
32RenderQueue::~RenderQueue()
33{
34        for (size_t i = 0; i < mBuckets.size(); ++ i)
35        {
36                DEL_PTR(mBuckets[i]);
37        }
38}
39
40
41bool RenderQueue::FitsInBucket(Shape *shape, size_t idx) const
42{
43        Technique *tech = shape->GetMaterial()->GetTechnique(mState->GetRenderTechnique());
44
45        // test if entity belongs to this bucket
46        if (tech->IsAlphaTestEnabled() != mBuckets[idx]->mAlphaTestEnabled) { return false; }
47        if (tech->IsCullFaceEnabled() != mBuckets[idx]->mCullFaceEnabled) { return false; }
48        if (tech->IsColorWriteEnabled() != mBuckets[idx]->mColorWriteEnabled) { return false; }
49        if (tech->IsLightingEnabled() != mBuckets[idx]->mLightingEnabled) { return false; }
50        if (tech->IsDepthWriteEnabled() != mBuckets[idx]->mDepthWriteEnabled) { return false; }
51
52        const bool hasTexture = (tech->GetTexture() != NULL);
53
54        if (hasTexture != mBuckets[idx]->mHasTexture) { return false; }
55
56        if (hasTexture)
57        {
58                if (tech->GetTexture()->GetWidth() != mBuckets[idx]->mTexWidth) { return false; }
59                if (tech->GetTexture()->GetHeight() != mBuckets[idx]->mTexHeight) {return false; }
60                if (tech->GetTexture()->GetFormat() != mBuckets[idx]->mTexFormat) { return false; }
61        }
62
63        //if (!tech->GetFragmentProgram() && mBuckets[idx]->mHasFragmentProgram) { return false; }
64        //if (!tech->GetVertexProgram() && mBuckets[idx]->mHasVertexProgram) { return false; }
65        if (tech->GetFragmentProgram() != mBuckets[idx]->mFragmentProgram) { return false; }
66        if (tech->GetVertexProgram() != mBuckets[idx]->mVertexProgram) { return false; }
67
68        return true;
69}
70
71
72void RenderQueue::Enqueue(SceneEntity *entity)
73{
74        ShapeContainer::iterator sit, sit_end;
75
76        entity->GetCurrentLODLevel(sit, sit_end);
77
78        for (; sit != sit_end; ++ sit)
79        {
80                Enqueue(*sit, entity);
81        }
82}
83
84
85void RenderQueue::Enqueue(Shape *shape, SceneEntity *containingEnt)
86{
87        Technique *tech = shape->GetMaterial()->GetTechnique(mState->GetRenderTechnique());
88        RenderQueueBucket *bucket = tech->mRenderQueueBucket;
89
90        ++ mNumEntries;
91       
92        if (!bucket)
93        {
94                bool bucketFound = false;
95
96                size_t i = 0;
97
98                for (; i < mBuckets.size(); ++ i)
99                {
100                        if (bucketFound = FitsInBucket(shape, i))
101                                break;
102                }
103
104                // create new bucket
105                if (!bucketFound)
106                {
107                        RenderQueueBucket *bucket = new RenderQueueBucket();
108                        //bucket->mMinDistance = -1;
109
110                        bucket->mAlphaTestEnabled = tech->IsAlphaTestEnabled();
111                        bucket->mCullFaceEnabled = tech->IsCullFaceEnabled();
112
113                        bucket->mColorWriteEnabled = tech->IsColorWriteEnabled();
114                        bucket->mLightingEnabled = tech->IsLightingEnabled();
115                        bucket->mDepthWriteEnabled = tech->IsDepthWriteEnabled();
116
117
118                        Texture *tex = tech->GetTexture();
119
120                        if (tex != NULL)
121                        {
122                                bucket->mHasTexture = true;
123
124                                bucket->mTexWidth = tex->GetWidth();
125                                bucket->mTexHeight = tex->GetHeight();
126
127                                bucket->mTexFormat = tex->GetFormat();
128                        }
129                        else
130                        {
131                                bucket->mHasTexture = false;
132
133                                bucket->mTexWidth = 0;
134                                bucket->mTexHeight = 0;
135                                bucket->mTexFormat = 0;
136                        }
137
138                        //      bucket->mHasVertexProgram = (tech->GetVertexProgram() != NULL);
139                        //      bucket->mHasFragmentProgram = (tech->GetFragmentProgram() != NULL);
140                        bucket->mVertexProgram = tech->GetVertexProgram();
141                        bucket->mFragmentProgram = tech->GetFragmentProgram();
142
143                        mBuckets.push_back(bucket);
144                        //cout << "increased #buckets to " << (int)mBuckets.size() << endl;
145                }
146
147                bucket = mBuckets[i];
148                tech->mRenderQueueBucket = bucket;
149        }
150
151        if (bucket->IsEmpty())
152        {
153                // add bucket to the list of currently active buckets that will be rendered
154                // assume that the incoming nodes are ordered by distance
155                // => active buckets are sorted by distance
156                mActiveBuckets.push_back(bucket);
157        }
158
159        bucket->mShapes.push_back(ShapePair(shape, containingEnt));
160}
161
162
163void RenderQueue::Clear()
164{
165        for (size_t i = 0; i < mActiveBuckets.size(); ++ i)
166        {
167                mActiveBuckets[i]->mShapes.clear();
168        }
169
170        mNumEntries = 0;
171        mActiveBuckets.clear();
172}
173
174
175void RenderQueue::SetRenderState(RenderState *state)
176{
177        mState = state;
178}
179
180
181void RenderQueue::Render()
182{
183        // render all buckets
184        for (size_t i = 0; i < mActiveBuckets.size(); ++ i)
185        {
186                ShapePairArray::const_iterator sit, sit_end = mActiveBuckets[i]->mShapes.end();
187
188                for (sit = mActiveBuckets[i]->mShapes.begin(); sit != sit_end; ++ sit)
189                {
190                        ShapePair s = *sit;
191
192                        Shape *shape = s.first;
193                        SceneEntity *ent = s.second;
194
195                        if (ent) ent->Prepare(mState);
196                        shape->Render(mState, ent);
197                        if (ent) ent->GetTransform()->Unload(mState);
198                }
199        }
200        //cout << "active: " << (int)mActiveBuckets.size() << endl;
201}
202
203
204void RenderQueue::Apply()
205{
206        Render();
207        Clear();
208}
209
210
211}
Note: See TracBrowser for help on using the repository browser.