[2767] | 1 | #include "RenderQueue.h"
|
---|
| 2 | #include "SceneEntity.h"
|
---|
| 3 | #include "Geometry.h"
|
---|
| 4 | #include "Texture.h"
|
---|
| 5 | #include "Material.h"
|
---|
[2802] | 6 | #include "Camera.h"
|
---|
[2840] | 7 | #include "Shape.h"
|
---|
[2767] | 8 |
|
---|
[2802] | 9 |
|
---|
[2768] | 10 | using namespace std;
|
---|
[2767] | 11 |
|
---|
[2768] | 12 |
|
---|
[2776] | 13 | namespace CHCDemoEngine
|
---|
[2767] | 14 | {
|
---|
| 15 |
|
---|
| 16 |
|
---|
[2844] | 17 | inline static bool CompDist(RenderQueueBucket *b1, RenderQueueBucket *b2)
|
---|
[2802] | 18 | {
|
---|
| 19 | return (b1->mMinDistance < b2->mMinDistance);
|
---|
[2767] | 20 | }
|
---|
| 21 |
|
---|
| 22 |
|
---|
[2842] | 23 |
|
---|
[2802] | 24 | RenderQueue::RenderQueue():
|
---|
| 25 | mState(NULL),
|
---|
| 26 | mMinSizeForSorting(3),
|
---|
| 27 | mCamera(NULL),
|
---|
[2844] | 28 | mNumEntries(0)
|
---|
[2802] | 29 | {
|
---|
[2801] | 30 | }
|
---|
| 31 |
|
---|
| 32 |
|
---|
[2802] | 33 | RenderQueue::RenderQueue(RenderState *state, Camera *cam):
|
---|
| 34 | mState(state),
|
---|
| 35 | mMinSizeForSorting(3),
|
---|
| 36 | mCamera(cam),
|
---|
[2844] | 37 | mNumEntries(0)
|
---|
[2795] | 38 | {
|
---|
| 39 | }
|
---|
| 40 |
|
---|
| 41 |
|
---|
[2802] | 42 | RenderQueue::~RenderQueue()
|
---|
[2767] | 43 | {
|
---|
[2802] | 44 | for (size_t i = 0; i < mBuckets.size(); ++ i)
|
---|
| 45 | {
|
---|
| 46 | DEL_PTR(mBuckets[i]);
|
---|
| 47 | }
|
---|
[2767] | 48 | }
|
---|
| 49 |
|
---|
| 50 |
|
---|
[2841] | 51 | bool RenderQueue::FitsInBucket(Shape *shape, size_t idx) const
|
---|
[2767] | 52 | {
|
---|
[2841] | 53 | Material *mat = shape->GetMaterial();
|
---|
| 54 |
|
---|
[2826] | 55 | // test if entity belongs to this bucket
|
---|
| 56 | // note: rather slows down the application for some reason!!
|
---|
[2841] | 57 | if (mat->IsAlphaTestEnabled() != mBuckets[idx]->mAlphaTestEnabled)
|
---|
[2826] | 58 | return false;
|
---|
[2802] | 59 |
|
---|
[2845] | 60 | if (mat->IsCullFaceEnabled() != mBuckets[idx]->mCullFaceEnabled)
|
---|
[2844] | 61 | return false;
|
---|
| 62 |
|
---|
[2805] | 63 | const bool hasTexture = (mat->GetTexture() != NULL);
|
---|
| 64 |
|
---|
| 65 | if (hasTexture != mBuckets[idx]->mHasTexture)
|
---|
[2802] | 66 | return false;
|
---|
| 67 |
|
---|
[2805] | 68 | if (hasTexture)
|
---|
| 69 | {
|
---|
| 70 | if (mat->GetTexture()->GetWidth() != mBuckets[idx]->mTexWidth)
|
---|
| 71 | return false;
|
---|
| 72 |
|
---|
| 73 | if (mat->GetTexture()->GetHeight() != mBuckets[idx]->mTexHeight)
|
---|
| 74 | return false;
|
---|
| 75 | }
|
---|
| 76 |
|
---|
[2802] | 77 | return true;
|
---|
[2767] | 78 | }
|
---|
| 79 |
|
---|
| 80 |
|
---|
[2773] | 81 | void RenderQueue::Enqueue(SceneEntity *entity)
|
---|
[2767] | 82 | {
|
---|
[2844] | 83 | ShapeContainer::iterator sit, sit_end;
|
---|
[2841] | 84 |
|
---|
[2844] | 85 | entity->GetCurrentLODLevel(sit, sit_end);
|
---|
[2841] | 86 |
|
---|
[2844] | 87 | for (; sit != sit_end; ++ sit)
|
---|
[2841] | 88 | {
|
---|
| 89 | Enqueue(*sit);
|
---|
| 90 | }
|
---|
| 91 | }
|
---|
| 92 |
|
---|
| 93 |
|
---|
| 94 | void RenderQueue::Enqueue(Shape *shape)
|
---|
| 95 | {
|
---|
[2802] | 96 | RenderQueueBucket *bucket;
|
---|
[2844] | 97 | ++ mNumEntries;
|
---|
[2841] | 98 |
|
---|
[2842] | 99 | if (shape->mRenderQueueBucket)
|
---|
[2802] | 100 | {
|
---|
[2842] | 101 | bucket = shape->mRenderQueueBucket;
|
---|
[2802] | 102 | }
|
---|
| 103 | else
|
---|
| 104 | {
|
---|
| 105 | bool bucketFound = false;
|
---|
| 106 |
|
---|
| 107 | size_t i = 0;
|
---|
| 108 |
|
---|
| 109 | for (; i < mBuckets.size(); ++ i)
|
---|
| 110 | {
|
---|
[2842] | 111 | if (bucketFound = FitsInBucket(shape, i))
|
---|
[2802] | 112 | break;
|
---|
| 113 | }
|
---|
| 114 |
|
---|
| 115 | // create new bucket
|
---|
| 116 | if (!bucketFound)
|
---|
| 117 | {
|
---|
| 118 | RenderQueueBucket *bucket = new RenderQueueBucket();
|
---|
[2844] | 119 | bucket->mMinDistance = -1;
|
---|
[2802] | 120 |
|
---|
[2842] | 121 | Material *mat = shape->GetMaterial();
|
---|
[2802] | 122 |
|
---|
| 123 | bucket->mAlphaTestEnabled = mat->IsAlphaTestEnabled();
|
---|
[2844] | 124 | bucket->mCullFaceEnabled = mat->IsCullFaceEnabled();
|
---|
[2802] | 125 |
|
---|
[2805] | 126 | const bool hasTexture = (mat->GetTexture() != NULL);
|
---|
| 127 |
|
---|
| 128 | bucket->mHasTexture = hasTexture;
|
---|
| 129 |
|
---|
| 130 | bucket->mTexWidth = hasTexture ? mat->GetTexture()->GetWidth() : 0;
|
---|
| 131 | bucket->mTexHeight = hasTexture ? mat->GetTexture()->GetHeight() : 0;
|
---|
| 132 |
|
---|
[2802] | 133 | mBuckets.push_back(bucket);
|
---|
| 134 |
|
---|
| 135 | //cout << "num buckets: " << (int)mBuckets.size() << endl;
|
---|
| 136 | }
|
---|
| 137 |
|
---|
| 138 | bucket = mBuckets[i];
|
---|
[2842] | 139 | shape->mRenderQueueBucket = bucket;
|
---|
[2802] | 140 | }
|
---|
[2840] | 141 |
|
---|
[2845] | 142 | if (bucket->mMinDistance < .0f)
|
---|
[2844] | 143 | {
|
---|
| 144 | // assume that the incoming nodes are ordered by distance
|
---|
| 145 | // => set min dist on first incoming node
|
---|
[2847] | 146 | const Vector3 v = shape->GetCenter() - mCamera->GetPosition();
|
---|
[2844] | 147 |
|
---|
| 148 | const float dist = SqrMagnitude(v);
|
---|
| 149 | bucket->mMinDistance = dist;
|
---|
| 150 | }
|
---|
| 151 |
|
---|
[2842] | 152 | bucket->mShapes.push_back(shape);
|
---|
[2767] | 153 | }
|
---|
| 154 |
|
---|
[2802] | 155 |
|
---|
[2767] | 156 | void RenderQueue::Clear()
|
---|
| 157 | {
|
---|
[2802] | 158 | for (size_t i = 0; i < mBuckets.size(); ++ i)
|
---|
[2844] | 159 | {
|
---|
| 160 | mBuckets[i]->mMinDistance = -1;
|
---|
[2840] | 161 | mBuckets[i]->mShapes.clear();
|
---|
[2844] | 162 | }
|
---|
[2767] | 163 |
|
---|
[2844] | 164 | mNumEntries = 0;
|
---|
[2767] | 165 | }
|
---|
| 166 |
|
---|
| 167 |
|
---|
| 168 | void RenderQueue::SetRenderState(RenderState *state)
|
---|
| 169 | {
|
---|
| 170 | mState = state;
|
---|
| 171 | }
|
---|
| 172 |
|
---|
| 173 |
|
---|
| 174 | void RenderQueue::Render()
|
---|
| 175 | {
|
---|
[2842] | 176 | // sort the buckets
|
---|
[2802] | 177 | Sort();
|
---|
[2842] | 178 |
|
---|
[2802] | 179 | // render all buckets
|
---|
| 180 | for (size_t i = 0; i < mBuckets.size(); ++ i)
|
---|
[2767] | 181 | {
|
---|
[2840] | 182 | ShapeContainer::const_iterator sit, sit_end = mBuckets[i]->mShapes.end();
|
---|
| 183 |
|
---|
| 184 | for (sit = mBuckets[i]->mShapes.begin(); sit != sit_end; ++ sit)
|
---|
[2802] | 185 | {
|
---|
[2840] | 186 | Shape *shape = *sit;
|
---|
| 187 | shape->Render(mState);
|
---|
[2802] | 188 | }
|
---|
[2767] | 189 | }
|
---|
[2795] | 190 | //Print();
|
---|
[2767] | 191 | }
|
---|
[2795] | 192 |
|
---|
| 193 |
|
---|
| 194 | void RenderQueue::Print()
|
---|
| 195 | {
|
---|
[2802] | 196 | for (size_t i = 0; i < mBuckets.size(); ++ i)
|
---|
| 197 | {
|
---|
[2804] | 198 | Debug << "\n******\nbucket " << (int)i << endl;
|
---|
[2795] | 199 |
|
---|
[2840] | 200 | ShapeContainer::const_iterator sit, sit_end = mBuckets[i]->mShapes.end();
|
---|
[2800] | 201 |
|
---|
[2840] | 202 | for (sit = mBuckets[i]->mShapes.begin(); sit != sit_end; ++ sit)
|
---|
[2802] | 203 | {
|
---|
[2840] | 204 | Shape *shape = *sit;
|
---|
| 205 |
|
---|
| 206 | Material *mat = shape->GetMaterial();
|
---|
[2802] | 207 | int tsize = mat->GetTexture() ? mat->GetTexture()->GetByteSize() : 0;
|
---|
[2841] | 208 |
|
---|
[2840] | 209 | float dist = SqrMagnitude(shape->GetBoundingBox().Center() - mCamera->GetPosition());
|
---|
[2841] | 210 |
|
---|
[2840] | 211 | Debug << "e: " << shape << " a: " << mat->IsAlphaTestEnabled() << " s: " << tsize << " d: " << dist << " " << endl;
|
---|
[2802] | 212 | }
|
---|
[2795] | 213 | }
|
---|
| 214 | }
|
---|
[2767] | 215 |
|
---|
[2795] | 216 |
|
---|
[2842] | 217 | void RenderQueue::Sort()
|
---|
[2795] | 218 | {
|
---|
[2842] | 219 | // sort buckets itself
|
---|
[2844] | 220 | sort(mBuckets.begin(), mBuckets.end(), CompDist);
|
---|
[2795] | 221 | }
|
---|
| 222 |
|
---|
| 223 |
|
---|
[2842] | 224 | void RenderQueue::Apply()
|
---|
[2767] | 225 | {
|
---|
[2842] | 226 | Render();
|
---|
| 227 | Clear();
|
---|
[2767] | 228 | }
|
---|
| 229 |
|
---|
| 230 |
|
---|
| 231 | } |
---|