- Timestamp:
- 06/28/08 16:12:59 (17 years ago)
- Location:
- GTP/trunk/App/Demos/Vis/FriendlyCulling
- Files:
-
- 2 deleted
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
GTP/trunk/App/Demos/Vis/FriendlyCulling/src/AxisAlignedBox3.cpp
r2793 r2802 987 987 } 988 988 989 //int AxisAlignedBox3::GetIndexFarthestVertex(const Vector3 &vecPlaneNormal) 989 990 990 int AxisAlignedBox3::GetIndexNearestVertex(const Vector3 &vecPlaneNormal) 991 991 { … … 1000 1000 1001 1001 1002 //int AxisAlignedBox3::GetIndexNearestVertex(const Vector3 &vecPlaneNormal)1003 1002 int AxisAlignedBox3::GetIndexFarthestVertex(const Vector3 &vecPlaneNormal) 1004 1003 { … … 1010 1009 1011 1010 return 4 * x + 2 * y + z; 1012 1013 /*int index;1014 1015 if (vecPlaneNormal.x <= 0.0f)1016 index = (vecPlaneNormal.y <= 0.0f) ? 0 : 3;1017 else1018 index = (vecPlaneNormal.y <= 0.0f) ? 1 : 2;1019 1020 return (vecPlaneNormal.z <= 0.0f) ? index : 7 - index;*/1021 1011 } 1022 1012 -
GTP/trunk/App/Demos/Vis/FriendlyCulling/src/AxisAlignedBox3.h
r2782 r2802 341 341 Vector3 mmin(MAXFLOAT); 342 342 Vector3 mmax(-MAXFLOAT); 343 343 344 344 AxisAlignedBox3 ret(mmin, mmax); 345 345 346 ret.Include(tform * Vector3(box.mMin.x, box.mMin.y, box.mMin.z)); 346 347 ret.Include(tform * Vector3(box.mMin.x, box.mMin.y, box.mMax.z)); … … 351 352 ret.Include(tform * Vector3(box.mMax.x, box.mMax.y, box.mMin.z)); 352 353 ret.Include(tform * Vector3(box.mMax.x, box.mMax.y, box.mMax.z)); 354 353 355 return ret; 354 356 } -
GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Bvh.cpp
r2800 r2802 154 154 } 155 155 156 //cout << "scene box: " << mBox << endl;156 cout << "scene box: " << mBox << endl; 157 157 } 158 158 -
GTP/trunk/App/Demos/Vis/FriendlyCulling/src/CHCPlusPlusTraverser.cpp
r2800 r2802 15 15 void CHCPlusPlusTraverser::HandleQueryResult(OcclusionQuery *query) 16 16 { 17 waitTimer.Entry();18 19 17 // wait until result available 20 18 const int visible = query->GetQueryResult() > mVisibilityThreshold; 21 22 waitTimer.Exit();23 19 24 20 // multiquery … … 199 195 if (mUseRenderQueue) ApplyRenderQueue(); 200 196 201 restTimer.Entry();202 197 203 198 ////////////// … … 220 215 HandleQueryResult(query); 221 216 } 222 223 restTimer.Exit();224 217 } 225 218 -
GTP/trunk/App/Demos/Vis/FriendlyCulling/src/FrustumCullingTraverser.cpp
r2795 r2802 1 1 #include "FrustumCullingTraverser.h" 2 2 #include "SceneEntity.h" 3 4 using namespace std;5 3 6 4 … … 20 18 mDistanceQueue.pop(); 21 19 22 // interesting for the visualization, so rest and set23 node->SetVisible(false);24 25 20 if (mBvh->IsWithinViewFrustum(node)) 26 21 { 27 // update node's visited flag => needed for rendering28 // so set it also here29 //node->SetLastVisited(mFrameID);30 node->SetVisible(true);31 22 TraverseNode(node); 32 23 } -
GTP/trunk/App/Demos/Vis/FriendlyCulling/src/RenderQueue.cpp
r2801 r2802 4 4 #include "Texture.h" 5 5 #include "Material.h" 6 #include "Camera.h" 7 6 8 7 9 using namespace std; … … 13 15 { 14 16 17 static Camera *sCam = NULL; 15 18 16 inline static bool CompTexture(SceneEntity *ent1, SceneEntity *ent2) 19 20 inline static bool CompDist(SceneEntity *e1, SceneEntity *e2) 17 21 { 18 // group by texture size 19 Texture *t1 = ent1->GetMaterial()->GetTexture(); 20 Texture *t2 = ent2->GetMaterial()->GetTexture(); 21 22 int tsize1 = t1 ? t1->GetByteSize() : 0; 23 int tsize2 = t2 ? t2->GetByteSize() : 0; 24 25 return tsize1 > tsize2; 22 return 23 (SqrMagnitude(e1->GetBoundingBox().Center() - sCam->GetPosition()) < 24 SqrMagnitude(e2->GetBoundingBox().Center() - sCam->GetPosition())); 26 25 } 27 26 28 27 29 #ifdef SORT_ALPHA 30 31 inline static bool CompMat(SceneEntity *ent1, SceneEntity *ent2) 32 { 33 return ent1->GetMaterial()->IsAlphaTestEnabled() < ent2->GetMaterial()->IsAlphaTestEnabled(); 28 inline static bool CompDist2(RenderQueueBucket *b1, RenderQueueBucket *b2) 29 { 30 return (b1->mMinDistance < b2->mMinDistance); 34 31 } 35 32 36 #else37 33 38 inline static bool CompMat(SceneEntity *ent1, SceneEntity *ent2) 39 { 40 return ent1->GetMaterial() < ent2->GetMaterial(); 41 } 42 43 #endif 44 45 46 RenderQueue::RenderQueue(): mState(NULL), mMinSizeForSorting(3) 34 RenderQueue::RenderQueue(): 35 mState(NULL), 36 mMinSizeForSorting(3), 37 mCamera(NULL), 38 mSize(0) 47 39 { 48 40 } 49 41 50 42 51 RenderQueue::RenderQueue(RenderState *state): 52 mState(state), mMinSizeForSorting(3) 43 RenderQueue::RenderQueue(RenderState *state, Camera *cam): 44 mState(state), 45 mMinSizeForSorting(3), 46 mCamera(cam), 47 mSize(0) 53 48 { 49 sCam = cam; 50 } 51 52 53 RenderQueue::~RenderQueue() 54 { 55 for (size_t i = 0; i < mBuckets.size(); ++ i) 56 { 57 DEL_PTR(mBuckets[i]); 58 } 59 } 60 61 62 bool RenderQueue::FitsInBucket(SceneEntity *ent, size_t idx) const 63 { 64 Material *mat = ent->GetMaterial(); 65 66 // test if entity 67 if (mat->IsAlphaTestEnabled() != mBuckets[idx]->mAlphaTestEnabled) 68 return false; 69 70 int tsize = mat->GetTexture() ? mat->GetTexture()->GetByteSize() : 0; 71 if (tsize != mBuckets[idx]->mTextureSize) 72 return false; 73 74 return true; 54 75 } 55 76 … … 57 78 void RenderQueue::Enqueue(SceneEntity *entity) 58 79 { 59 mEntities.push_back(entity); 80 RenderQueueBucket *bucket; 81 ++ mSize; 82 83 if (entity->mRenderQueueBucket) 84 { 85 bucket = entity->mRenderQueueBucket; 86 } 87 else 88 { 89 bool bucketFound = false; 90 91 size_t i = 0; 92 93 for (; i < mBuckets.size(); ++ i) 94 { 95 if (bucketFound = FitsInBucket(entity, i)) 96 break; 97 } 98 99 // create new bucket 100 if (!bucketFound) 101 { 102 RenderQueueBucket *bucket = new RenderQueueBucket(); 103 104 Material *mat = entity->GetMaterial(); 105 106 bucket->mAlphaTestEnabled = mat->IsAlphaTestEnabled(); 107 bucket->mTextureSize = mat->GetTexture() ? mat->GetTexture()->GetByteSize() : 0; 108 109 mBuckets.push_back(bucket); 110 111 // assume that the incoming nodes are ordered by distance => set min dist 112 // on first incoming node 113 float dist = SqrMagnitude(entity->GetBoundingBox().Center() - mCamera->GetPosition()); 114 mBuckets[i]->mMinDistance = dist; 115 116 //cout << "num buckets: " << (int)mBuckets.size() << endl; 117 } 118 119 bucket = mBuckets[i]; 120 entity->mRenderQueueBucket = bucket; 121 } 122 123 bucket->mEntities.push_back(entity); 60 124 } 61 125 62 126 63 127 void RenderQueue::Clear() 64 128 { 65 mEntities.clear(); 129 for (size_t i = 0; i < mBuckets.size(); ++ i) 130 mBuckets[i]->mEntities.clear(); 66 131 132 mSize = 0; 67 133 } 68 134 … … 76 142 void RenderQueue::Render() 77 143 { 78 if (mEntities.size() >= mMinSizeForSorting) 144 Sort(); 145 146 // render all buckets 147 for (size_t i = 0; i < mBuckets.size(); ++ i) 79 148 { 80 sortTimer.Entry(); 81 Sort(); 82 sortTimer.Exit(); 83 } 84 85 SceneEntityContainer::const_iterator sit, sit_end = mEntities.end(); 86 87 for (sit = mEntities.begin(); sit != sit_end; ++ sit) 88 { 89 SceneEntity *ent = *sit; 90 ent->Render(mState); 149 SceneEntityContainer::const_iterator sit, sit_end = mBuckets[i]->mEntities.end(); 150 for (sit = mBuckets[i]->mEntities.begin(); sit != sit_end; ++ sit) 151 { 152 SceneEntity *ent = *sit; 153 ent->Render(mState); 154 } 91 155 } 92 156 … … 97 161 void RenderQueue::Print() 98 162 { 99 SceneEntityContainer::const_iterator sit, sit_end = mEntities.end(); 163 for (size_t i = 0; i < mBuckets.size(); ++ i) 164 { 165 Debug << "\n******\nbucket " << i << endl; 100 166 101 Debug << "\nrq size: " << GetSize() << endl; 102 Debug << "texture size: " << endl; 167 SceneEntityContainer::const_iterator sit, sit_end = mBuckets[i]->mEntities.end(); 103 168 104 // show ordering by texture size 105 for (sit = mEntities.begin(); sit != sit_end; ++ sit) 106 { 107 SceneEntity *ent = *sit; 108 Texture *t = ent->GetMaterial()->GetTexture(); 169 for (sit = mBuckets[i]->mEntities.begin(); sit != sit_end; ++ sit) 170 { 171 SceneEntity *ent = *sit; 109 172 110 int tsize = t ? t->GetByteSize() : 0; 111 Debug << tsize << " "; 112 } 113 114 // show ordering by material 115 Debug << "\nmaterial: " << endl; 116 117 for (sit = mEntities.begin(); sit != sit_end; ++ sit) 118 { 119 #ifdef SORT_ALPHA 120 Debug << (*sit)->GetMaterial()->IsAlphaTestEnabled() << " "; 121 #else 122 Debug << (*sit)->GetMaterial() << " "; 123 #endif 173 Material *mat = ent->GetMaterial(); 174 int tsize = mat->GetTexture() ? mat->GetTexture()->GetByteSize() : 0; 175 float dist = SqrMagnitude(ent->GetBoundingBox().Center() - mCamera->GetPosition()); 176 Debug << "e: " << ent << " a: " << mat->IsAlphaTestEnabled() << " s: " << tsize << " d: " << dist << " " << ent->GetBoundingBox() << " g: " << ent->GetGeometry() << " t: " << ent->GetTransformation() << " m: " << ent->GetMaterial() << endl; 177 } 124 178 } 125 179 } … … 135 189 void RenderQueue::Sort() 136 190 { 137 #ifdef SORT_ALPHA 138 // sort by texture size 139 sort(mEntities.begin(), mEntities.end(), CompTexture); 140 // sort by alpha test enabled 141 stable_sort(mEntities.begin(), mEntities.end(), CompMat); 142 #else 143 // sort by material 144 sort(mEntities.begin(), mEntities.end(), CompMat); 145 // sort by texture size 146 stable_sort(mEntities.begin(), mEntities.end(), CompTexture); 147 #endif 191 // sort buckets itself 192 sort(mBuckets.begin(), mBuckets.end(), CompDist2); 148 193 } 149 194 -
GTP/trunk/App/Demos/Vis/FriendlyCulling/src/RenderQueue.h
r2801 r2802 10 10 11 11 class RenderState; 12 class Camera; 12 13 13 14 14 /** This class implements a render queue that sorts entities according to 15 their materials. 15 /** Defines a bucket for scene entities that have the same properties. 16 */ 17 struct RenderQueueBucket 18 { 19 /** should be full texture format, but we as use the same format for all textures 20 they differ only in size, and we implicitly assume that textures with the same 21 size have exactly the same format 22 */ 23 int mTextureSize; 24 bool mAlphaTestEnabled; 25 26 /// minimal distance to the camera 27 float mMinDistance; 28 29 SceneEntityContainer mEntities; 30 }; 31 32 33 /** This class implements a render queue that sorts renderable geometry in order 34 to minimize state changes while approximately keeping front-to-back order 35 The implementation roughly follows the suggested implemenation on Tom Forsyth's article 36 on render state changes. It requires sorting only on bucket level and therefore has very 37 low overhead 16 38 */ 17 39 class RenderQueue … … 24 46 /** Constructor taking a render queue 25 47 */ 26 RenderQueue(RenderState *state); 27 /** Enqueues an entity 48 RenderQueue(RenderState *state, Camera *cam); 49 50 ~RenderQueue(); 51 /** Enqueues an entity. 28 52 */ 29 53 void Enqueue(SceneEntity *entity); 54 /** Sets the current render state 55 */ 56 void SetRenderState(RenderState *state); 57 /** Sets the current render state 58 */ 59 void SetCamera(Camera *cam); 60 /** Returns the number entities currently in the queue. 61 */ 62 inline int GetSize() const { return (int)mSize; } 63 /** Renders and clears the queue. 64 */ 65 void Apply(); 66 67 68 protected: 69 70 inline bool FitsInBucket(SceneEntity *ent, size_t idx) const; 71 72 /** Sorts the render queue by materials / textures. 73 */ 74 void Sort(); 75 /** Clears the render queue 76 */ 77 void Clear(); 30 78 /** Renders the contents of the render queue. 31 79 */ 32 80 void Render(); 33 /** Sets the current render state34 */35 void SetRenderState(RenderState *state);36 /** Clears the render queue37 */38 void Clear();39 /** Returns the number entities currently in the queue.40 */41 inline int GetSize() const { return (int)mEntities.size(); }42 /** Renders and clears the queue.43 */44 void Apply();45 81 /** Prints the current state of the render queue. 46 82 */ 47 83 void Print(); 48 84 49 protected:50 51 /** Sorts the render queue by materials / textures.52 */53 void Sort();54 55 56 85 /////////// 57 86 58 87 RenderState *mState; 59 SceneEntityContainer mEntities; 88 Camera *mCamera; 89 //SceneEntityContainer mEntities; 60 90 int mMinSizeForSorting; 91 92 /// each bucket contains objects with similar materials that don't cause a hard state change 93 std::vector<RenderQueueBucket *> mBuckets; 94 95 int mSize; 61 96 }; 62 63 /// measures sort time for detailed benchmarks64 static PerfTimer sortTimer;65 97 66 98 -
GTP/trunk/App/Demos/Vis/FriendlyCulling/src/RenderTraverser.cpp
r2801 r2802 168 168 glDisableClientState(GL_VERTEX_ARRAY); 169 169 glDisableClientState(GL_NORMAL_ARRAY); 170 171 172 #ifdef PRINT_VERBOSE_BENCHMARKS 173 174 Debug << "traversal type: " << GetType() << endl; 175 if (mUseRenderQueue) Debug << "rq sort: " << 1e3f * mRenderQueue.sortTimer.TotalTime() << " ms" << endl; 176 177 Debug << "wait time: " << 1e3f * waitTimer.TotalTime() << " ms" << endl; 178 Debug << "query time: " << 1e3f * queryTimer.TotalTime() << " ms" << endl; 179 Debug << "rest time: " << 1e3f * restTimer.TotalTime() << " ms" << endl; 180 181 #endif 170 171 //cout << "rq overhead: " << 1e3f * mRenderQueue->rTimer.TotalTime() << " ms" << endl; 182 172 } 183 173 … … 243 233 OcclusionQuery *RenderTraverser::IssueOcclusionQuery(BvhNode *node) 244 234 { 245 queryTimer.Entry();246 247 235 OcclusionQuery *query = mQueryHandler.RequestQuery(); 248 236 query->AddNode(node); 249 237 250 238 IssueOcclusionQuery(*query); 251 252 queryTimer.Exit();253 239 254 240 return query; -
GTP/trunk/App/Demos/Vis/FriendlyCulling/src/RenderTraverser.h
r2801 r2802 216 216 217 217 218 /// timers for detailed benchmarks219 static PerfTimer restTimer;220 static PerfTimer waitTimer;221 static PerfTimer queryTimer;222 218 223 219 } -
GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SceneEntity.cpp
r2795 r2802 13 13 Material *mat, 14 14 Matrix4x4 *trafo): 15 mGeometry(geometry), mMaterial(mat), mTransform(trafo) 15 mGeometry(geometry), mMaterial(mat), mTransform(trafo), mRenderQueueBucket(NULL) 16 16 { 17 17 } -
GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SceneEntity.h
r2795 r2802 13 13 class Geometry; 14 14 class RenderState; 15 15 struct RenderQueueBucket; 16 16 17 17 /** Class representing a scene entity. … … 20 20 class SceneEntity 21 21 { 22 friend class RenderQueue; 23 22 24 public: 23 25 /** Creates a scene entity. … … 52 54 53 55 inline Material *GetMaterial() const { return mMaterial; } 56 inline Matrix4x4 *GetTransformation() const { return mTransform; } 54 57 55 58 protected: … … 61 64 62 65 int mLastRendered; 66 /// pointer to the renderqueue bucket this entity belongs to 67 RenderQueueBucket *mRenderQueueBucket; 63 68 }; 64 69 -
GTP/trunk/App/Demos/Vis/FriendlyCulling/src/StopAndWaitTraverser.cpp
r2800 r2802 33 33 OcclusionQuery *query = IssueOcclusionQuery(node); 34 34 35 waitTimer.Entry(); 36 bool visible = query->GetQueryResult() > mVisibilityThreshold; 37 waitTimer.Exit(); 38 35 const bool visible = query->GetQueryResult() > mVisibilityThreshold; 36 39 37 if (visible) 40 38 { … … 43 41 else 44 42 { 45 node->SetVisible(false);46 43 ++ mStats.mNumQueryCulledNodes; 47 44 } 48 49 // update node's visited flag (could be interesting for the visualization)50 node->SetVisible(visible);51 45 } 52 46 } -
GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Timer/PerfTimer.h
r2801 r2802 22 22 #define _PERFTIMER_H 23 23 24 // RDTSC timer does not work with modern CPUs24 // note: RDTSC timer does not work with modern CPUs 25 25 #define NO_RDTSC_TIMER 26 26 -
GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp
r2801 r2802 168 168 visCamera->Yaw(.5 * M_PI); 169 169 170 renderQueue = new RenderQueue(&state );170 renderQueue = new RenderQueue(&state, camera); 171 171 172 172 glutInitWindowSize(winWidth, winHeight); … … 518 518 // note: have to flush queue in order to get reliable timings 519 519 // for optimal performance, remove this 520 glFinish();520 //glFinish(); 521 521 522 522 algTimer.Start(); … … 575 575 // note: have to flush queue in order to get reliable timings 576 576 // for optimal performance, remove this 577 glFinish();577 //glFinish(); 578 578 algTime = algTimer.Elapsedms(); 579 579 … … 1091 1091 const float expFactor = 0.3f; 1092 1092 1093 // if there was something fishy going on in this frame => don't count 1094 if (algTime < 1000) 1095 renderTime = algTime * expFactor + (1.0f - expFactor) * algTime; 1096 1097 accumulatedTime += renderTime; 1093 //if (useRenderQueue) cout << "rq overhead: " << 1e6f * rqTimer.TotalTime() << " ms" << endl; 1094 1095 // if some strange render time spike happened in this frame => don't count 1096 //if (algTime < 1000) renderTime = algTime * expFactor + (1.0f - expFactor) * algTime; 1097 1098 renderTime = 1e3f * (elapsedTime * expFactor + (1.0f - expFactor) * elapsedTime); 1099 1100 accumulatedTime += elapsedTime * 1e3f; 1098 1101 1099 1102 if (accumulatedTime > 500) // update every fraction of a second
Note: See TracChangeset
for help on using the changeset viewer.