diff options
Diffstat (limited to '')
-rw-r--r-- | linden/indra/newview/pipeline.cpp | 3435 |
1 files changed, 1488 insertions, 1947 deletions
diff --git a/linden/indra/newview/pipeline.cpp b/linden/indra/newview/pipeline.cpp index a7b4d47..1a5b4f1 100644 --- a/linden/indra/newview/pipeline.cpp +++ b/linden/indra/newview/pipeline.cpp | |||
@@ -32,12 +32,12 @@ | |||
32 | // library includes | 32 | // library includes |
33 | #include "audioengine.h" // For MAX_BUFFERS for debugging. | 33 | #include "audioengine.h" // For MAX_BUFFERS for debugging. |
34 | #include "imageids.h" | 34 | #include "imageids.h" |
35 | #include "llagpmempool.h" | ||
36 | #include "llerror.h" | 35 | #include "llerror.h" |
37 | #include "llviewercontrol.h" | 36 | #include "llviewercontrol.h" |
38 | #include "llfasttimer.h" | 37 | #include "llfasttimer.h" |
39 | #include "llfontgl.h" | 38 | #include "llfontgl.h" |
40 | #include "llmemory.h" | 39 | #include "llmemory.h" |
40 | #include "llmemtype.h" | ||
41 | #include "llnamevalue.h" | 41 | #include "llnamevalue.h" |
42 | #include "llprimitive.h" | 42 | #include "llprimitive.h" |
43 | #include "llvolume.h" | 43 | #include "llvolume.h" |
@@ -45,17 +45,17 @@ | |||
45 | #include "timing.h" | 45 | #include "timing.h" |
46 | #include "v3color.h" | 46 | #include "v3color.h" |
47 | #include "llui.h" | 47 | #include "llui.h" |
48 | #include "llglheaders.h" | ||
48 | 49 | ||
49 | // newview includes | 50 | // newview includes |
50 | #include "llagent.h" | 51 | #include "llagent.h" |
51 | #include "llagparray.h" | ||
52 | #include "lldrawable.h" | 52 | #include "lldrawable.h" |
53 | #include "lldrawpoolalpha.h" | 53 | #include "lldrawpoolalpha.h" |
54 | #include "lldrawpoolavatar.h" | 54 | #include "lldrawpoolavatar.h" |
55 | #include "lldrawpoolground.h" | 55 | #include "lldrawpoolground.h" |
56 | #include "lldrawpoolsimple.h" | 56 | #include "lldrawpoolsimple.h" |
57 | #include "lldrawpoolbump.h" | ||
57 | #include "lldrawpooltree.h" | 58 | #include "lldrawpooltree.h" |
58 | #include "lldrawpoolhud.h" | ||
59 | #include "lldrawpoolwater.h" | 59 | #include "lldrawpoolwater.h" |
60 | #include "llface.h" | 60 | #include "llface.h" |
61 | #include "llfeaturemanager.h" | 61 | #include "llfeaturemanager.h" |
@@ -82,10 +82,13 @@ | |||
82 | #include "llvosky.h" | 82 | #include "llvosky.h" |
83 | #include "llvotree.h" | 83 | #include "llvotree.h" |
84 | #include "llvovolume.h" | 84 | #include "llvovolume.h" |
85 | #include "llvosurfacepatch.h" | ||
86 | #include "llvowater.h" | ||
87 | #include "llvotree.h" | ||
88 | #include "llvopartgroup.h" | ||
85 | #include "llworld.h" | 89 | #include "llworld.h" |
86 | #include "viewer.h" | 90 | #include "viewer.h" |
87 | #include "llagpmempoolarb.h" | 91 | #include "llcubemap.h" |
88 | #include "llagparray.inl" | ||
89 | 92 | ||
90 | #ifdef _DEBUG | 93 | #ifdef _DEBUG |
91 | // Debug indices is disabled for now for debug performance - djs 4/24/02 | 94 | // Debug indices is disabled for now for debug performance - djs 4/24/02 |
@@ -94,6 +97,8 @@ | |||
94 | //#define DEBUG_INDICES | 97 | //#define DEBUG_INDICES |
95 | #endif | 98 | #endif |
96 | 99 | ||
100 | #define AGGRESSIVE_OCCLUSION 0 | ||
101 | |||
97 | const F32 BACKLIGHT_DAY_MAGNITUDE_AVATAR = 0.2f; | 102 | const F32 BACKLIGHT_DAY_MAGNITUDE_AVATAR = 0.2f; |
98 | const F32 BACKLIGHT_NIGHT_MAGNITUDE_AVATAR = 0.1f; | 103 | const F32 BACKLIGHT_NIGHT_MAGNITUDE_AVATAR = 0.1f; |
99 | const F32 BACKLIGHT_DAY_MAGNITUDE_OBJECT = 0.1f; | 104 | const F32 BACKLIGHT_DAY_MAGNITUDE_OBJECT = 0.1f; |
@@ -117,18 +122,12 @@ extern S32 gBoxFrame; | |||
117 | extern BOOL gRenderLightGlows; | 122 | extern BOOL gRenderLightGlows; |
118 | extern BOOL gHideSelectedObjects; | 123 | extern BOOL gHideSelectedObjects; |
119 | 124 | ||
120 | |||
121 | BOOL gAvatarBacklight = FALSE; | 125 | BOOL gAvatarBacklight = FALSE; |
122 | 126 | ||
123 | F32 gMinObjectDistance = MIN_NEAR_PLANE; | ||
124 | S32 gTrivialAccepts = 0; | 127 | S32 gTrivialAccepts = 0; |
125 | 128 | ||
126 | BOOL gRenderForSelect = FALSE; | 129 | BOOL gRenderForSelect = FALSE; |
127 | 130 | ||
128 | BOOL gUsePickAlpha = TRUE; | ||
129 | F32 gPickAlphaThreshold = 0.f; | ||
130 | F32 gPickAlphaTargetThreshold = 0.f; | ||
131 | |||
132 | //glsl parameter tables | 131 | //glsl parameter tables |
133 | const char* LLPipeline::sReservedAttribs[] = | 132 | const char* LLPipeline::sReservedAttribs[] = |
134 | { | 133 | { |
@@ -177,6 +176,13 @@ const char* LLPipeline::sTerrainUniforms[] = | |||
177 | 176 | ||
178 | U32 LLPipeline::sTerrainUniformCount = sizeof(LLPipeline::sTerrainUniforms)/sizeof(char*); | 177 | U32 LLPipeline::sTerrainUniformCount = sizeof(LLPipeline::sTerrainUniforms)/sizeof(char*); |
179 | 178 | ||
179 | const char* LLPipeline::sShinyUniforms[] = | ||
180 | { | ||
181 | "origin" | ||
182 | }; | ||
183 | |||
184 | U32 LLPipeline::sShinyUniformCount = sizeof(LLPipeline::sShinyUniforms)/sizeof(char*); | ||
185 | |||
180 | const char* LLPipeline::sWaterUniforms[] = | 186 | const char* LLPipeline::sWaterUniforms[] = |
181 | { | 187 | { |
182 | "screenTex", | 188 | "screenTex", |
@@ -193,8 +199,6 @@ const char* LLPipeline::sWaterUniforms[] = | |||
193 | 199 | ||
194 | U32 LLPipeline::sWaterUniformCount = sizeof(LLPipeline::sWaterUniforms)/sizeof(char*); | 200 | U32 LLPipeline::sWaterUniformCount = sizeof(LLPipeline::sWaterUniforms)/sizeof(char*); |
195 | 201 | ||
196 | // the SSE variable is dependent on software blending being enabled. | ||
197 | |||
198 | //---------------------------------------- | 202 | //---------------------------------------- |
199 | 203 | ||
200 | void stamp(F32 x, F32 y, F32 xs, F32 ys) | 204 | void stamp(F32 x, F32 y, F32 xs, F32 ys) |
@@ -216,40 +220,35 @@ void stamp(F32 x, F32 y, F32 xs, F32 ys) | |||
216 | //---------------------------------------- | 220 | //---------------------------------------- |
217 | 221 | ||
218 | S32 LLPipeline::sCompiles = 0; | 222 | S32 LLPipeline::sCompiles = 0; |
219 | S32 LLPipeline::sAGPMaxPoolSize = 1 << 25; // 32MB | 223 | |
224 | BOOL LLPipeline::sShowHUDAttachments = TRUE; | ||
220 | BOOL LLPipeline::sRenderPhysicalBeacons = FALSE; | 225 | BOOL LLPipeline::sRenderPhysicalBeacons = FALSE; |
221 | BOOL LLPipeline::sRenderScriptedBeacons = FALSE; | 226 | BOOL LLPipeline::sRenderScriptedBeacons = FALSE; |
222 | BOOL LLPipeline::sRenderParticleBeacons = FALSE; | 227 | BOOL LLPipeline::sRenderParticleBeacons = FALSE; |
223 | BOOL LLPipeline::sRenderSoundBeacons = FALSE; | 228 | BOOL LLPipeline::sRenderSoundBeacons = FALSE; |
229 | BOOL LLPipeline::sUseOcclusion = FALSE; | ||
230 | BOOL LLPipeline::sSkipUpdate = FALSE; | ||
231 | BOOL LLPipeline::sDynamicReflections = FALSE; | ||
224 | 232 | ||
225 | LLPipeline::LLPipeline() : | 233 | LLPipeline::LLPipeline() : |
234 | mCubeBuffer(NULL), | ||
235 | mCubeList(0), | ||
226 | mVertexShadersEnabled(FALSE), | 236 | mVertexShadersEnabled(FALSE), |
227 | mVertexShadersLoaded(0), | 237 | mVertexShadersLoaded(0), |
228 | mLastRebuildPool(NULL), | 238 | mLastRebuildPool(NULL), |
229 | mAlphaPool(NULL), | 239 | mAlphaPool(NULL), |
240 | mAlphaPoolPostWater(NULL), | ||
230 | mSkyPool(NULL), | 241 | mSkyPool(NULL), |
231 | mStarsPool(NULL), | 242 | mStarsPool(NULL), |
232 | mCloudsPool(NULL), | ||
233 | mTerrainPool(NULL), | 243 | mTerrainPool(NULL), |
234 | mWaterPool(NULL), | 244 | mWaterPool(NULL), |
235 | mGroundPool(NULL), | 245 | mGroundPool(NULL), |
236 | mHUDPool(NULL), | 246 | mSimplePool(NULL), |
237 | mAGPMemPool(NULL), | 247 | mBumpPool(NULL), |
238 | mGlobalFence(0), | ||
239 | mBufferIndex(0), | ||
240 | mBufferCount(kMaxBufferCount), | ||
241 | mUseOcclusionCulling(FALSE), | ||
242 | mLightMask(0), | 248 | mLightMask(0), |
243 | mLightMovingMask(0) | 249 | mLightMovingMask(0) |
244 | { | 250 | { |
245 | for(S32 i = 0; i < kMaxBufferCount; i++) | 251 | |
246 | { | ||
247 | mBufferMemory[i] = NULL; | ||
248 | } | ||
249 | for (S32 i = 0; i < kMaxBufferCount; i++) | ||
250 | { | ||
251 | mBufferFence[i] = 0; | ||
252 | } | ||
253 | } | 252 | } |
254 | 253 | ||
255 | void LLPipeline::init() | 254 | void LLPipeline::init() |
@@ -258,8 +257,25 @@ void LLPipeline::init() | |||
258 | 257 | ||
259 | stop_glerror(); | 258 | stop_glerror(); |
260 | 259 | ||
261 | mAGPBound = FALSE; | 260 | //create object partitions |
262 | mObjectPartition = new LLSpatialPartition; | 261 | //MUST MATCH declaration of eObjectPartitions |
262 | mObjectPartition.push_back(new LLVolumePartition()); //PARTITION_VOLUME | ||
263 | mObjectPartition.push_back(new LLBridgePartition()); //PARTITION_BRIDGE | ||
264 | mObjectPartition.push_back(new LLHUDPartition()); //PARTITION_HUD | ||
265 | mObjectPartition.push_back(new LLTerrainPartition()); //PARTITION_TERRAIN | ||
266 | mObjectPartition.push_back(new LLWaterPartition()); //PARTITION_WATER | ||
267 | mObjectPartition.push_back(new LLTreePartition()); //PARTITION_TREE | ||
268 | mObjectPartition.push_back(new LLParticlePartition()); //PARTITION_PARTICLE | ||
269 | mObjectPartition.push_back(new LLCloudPartition()); //PARTITION_CLOUD | ||
270 | mObjectPartition.push_back(new LLGrassPartition()); //PARTITION_GRASS | ||
271 | mObjectPartition.push_back(NULL); //PARTITION_NONE | ||
272 | |||
273 | //create render pass pools | ||
274 | getPool(LLDrawPool::POOL_ALPHA); | ||
275 | getPool(LLDrawPool::POOL_ALPHA_POST_WATER); | ||
276 | getPool(LLDrawPool::POOL_SIMPLE); | ||
277 | getPool(LLDrawPool::POOL_BUMP); | ||
278 | |||
263 | mTrianglesDrawnStat.reset(); | 279 | mTrianglesDrawnStat.reset(); |
264 | resetFrameStats(); | 280 | resetFrameStats(); |
265 | 281 | ||
@@ -268,43 +284,15 @@ void LLPipeline::init() | |||
268 | mRenderFeatureMask = 0; // All features start off | 284 | mRenderFeatureMask = 0; // All features start off |
269 | mRenderDebugMask = 0; // All debug starts off | 285 | mRenderDebugMask = 0; // All debug starts off |
270 | 286 | ||
287 | mOldRenderDebugMask = mRenderDebugMask; | ||
288 | |||
271 | mBackfaceCull = TRUE; | 289 | mBackfaceCull = TRUE; |
272 | 290 | ||
273 | // Disable AGP initially. | ||
274 | mRenderFeatureMask &= ~RENDER_FEATURE_AGP; | ||
275 | |||
276 | stop_glerror(); | 291 | stop_glerror(); |
277 | 292 | ||
278 | // Enable features | 293 | // Enable features |
279 | |||
280 | mUseVBO = gSavedSettings.getBOOL("RenderUseVBO"); | ||
281 | |||
282 | // Allocate the shared buffers for software skinning | ||
283 | for(S32 i=0; i < mBufferCount; i++) | ||
284 | { | ||
285 | mBufferMemory[i] = new LLAGPArray<U8>; | ||
286 | mBufferMemory[i]->reserve_block(AVATAR_VERTEX_BYTES*AVATAR_BUFFER_ELEMENTS); | ||
287 | } | ||
288 | |||
289 | if (gFeatureManagerp->isFeatureAvailable("RenderAGP")) | ||
290 | { | ||
291 | setUseAGP(gSavedSettings.getBOOL("RenderUseAGP") && gGLManager.mHasAnyAGP); | ||
292 | } | ||
293 | else | ||
294 | { | ||
295 | setUseAGP(FALSE); | ||
296 | } | ||
297 | |||
298 | stop_glerror(); | 294 | stop_glerror(); |
299 | 295 | ||
300 | for(S32 i=0; i < mBufferCount; i++) | ||
301 | { | ||
302 | if (!mBufferMemory[i]->isAGP() && usingAGP()) | ||
303 | { | ||
304 | llwarns << "pipeline buffer memory is non-AGP when AGP available!" << llendl; | ||
305 | } | ||
306 | } | ||
307 | |||
308 | setShaders(); | 296 | setShaders(); |
309 | } | 297 | } |
310 | 298 | ||
@@ -327,7 +315,17 @@ void LLPipeline::cleanup() | |||
327 | { | 315 | { |
328 | pool_set_t::iterator curiter = iter++; | 316 | pool_set_t::iterator curiter = iter++; |
329 | LLDrawPool* poolp = *curiter; | 317 | LLDrawPool* poolp = *curiter; |
330 | if (poolp->mReferences.empty()) | 318 | if (poolp->isFacePool()) |
319 | { | ||
320 | LLFacePool* face_pool = (LLFacePool*) poolp; | ||
321 | if (face_pool->mReferences.empty()) | ||
322 | { | ||
323 | mPools.erase(curiter); | ||
324 | removeFromQuickLookup( poolp ); | ||
325 | delete poolp; | ||
326 | } | ||
327 | } | ||
328 | else | ||
331 | { | 329 | { |
332 | mPools.erase(curiter); | 330 | mPools.erase(curiter); |
333 | removeFromQuickLookup( poolp ); | 331 | removeFromQuickLookup( poolp ); |
@@ -335,10 +333,6 @@ void LLPipeline::cleanup() | |||
335 | } | 333 | } |
336 | } | 334 | } |
337 | 335 | ||
338 | if (!mSimplePools.empty()) | ||
339 | { | ||
340 | llwarns << "Simple Pools not cleaned up" << llendl; | ||
341 | } | ||
342 | if (!mTerrainPools.empty()) | 336 | if (!mTerrainPools.empty()) |
343 | { | 337 | { |
344 | llwarns << "Terrain Pools not cleaned up" << llendl; | 338 | llwarns << "Terrain Pools not cleaned up" << llendl; |
@@ -347,208 +341,105 @@ void LLPipeline::cleanup() | |||
347 | { | 341 | { |
348 | llwarns << "Tree Pools not cleaned up" << llendl; | 342 | llwarns << "Tree Pools not cleaned up" << llendl; |
349 | } | 343 | } |
350 | if (!mTreeNewPools.empty()) | 344 | |
351 | { | ||
352 | llwarns << "TreeNew Pools not cleaned up" << llendl; | ||
353 | } | ||
354 | if (!mBumpPools.empty()) | ||
355 | { | ||
356 | llwarns << "Bump Pools not cleaned up" << llendl; | ||
357 | } | ||
358 | delete mAlphaPool; | 345 | delete mAlphaPool; |
359 | mAlphaPool = NULL; | 346 | mAlphaPool = NULL; |
347 | delete mAlphaPoolPostWater; | ||
348 | mAlphaPoolPostWater = NULL; | ||
360 | delete mSkyPool; | 349 | delete mSkyPool; |
361 | mSkyPool = NULL; | 350 | mSkyPool = NULL; |
362 | delete mStarsPool; | 351 | delete mStarsPool; |
363 | mStarsPool = NULL; | 352 | mStarsPool = NULL; |
364 | delete mCloudsPool; | ||
365 | mCloudsPool = NULL; | ||
366 | delete mTerrainPool; | 353 | delete mTerrainPool; |
367 | mTerrainPool = NULL; | 354 | mTerrainPool = NULL; |
368 | delete mWaterPool; | 355 | delete mWaterPool; |
369 | mWaterPool = NULL; | 356 | mWaterPool = NULL; |
370 | delete mGroundPool; | 357 | delete mGroundPool; |
371 | mGroundPool = NULL; | 358 | mGroundPool = NULL; |
372 | delete mHUDPool; | 359 | delete mSimplePool; |
373 | mHUDPool = NULL; | 360 | mSimplePool = NULL; |
361 | delete mBumpPool; | ||
362 | mBumpPool = NULL; | ||
374 | 363 | ||
375 | mBloomImagep = NULL; | 364 | if (mCubeBuffer) |
376 | mBloomImage2p = NULL; | ||
377 | mFaceSelectImagep = NULL; | ||
378 | mAlphaSizzleImagep = NULL; | ||
379 | |||
380 | for(S32 i=0; i < mBufferCount; i++) | ||
381 | { | 365 | { |
382 | delete mBufferMemory[i]; | 366 | delete mCubeBuffer; |
383 | mBufferMemory[i] = NULL; | 367 | mCubeBuffer = NULL; |
384 | } | 368 | } |
385 | 369 | ||
386 | delete mObjectPartition; | 370 | if (mCubeList) |
387 | mObjectPartition = NULL; | ||
388 | |||
389 | if (mAGPMemPool && mGlobalFence) | ||
390 | { | 371 | { |
391 | mAGPMemPool->deleteFence(mGlobalFence); | 372 | glDeleteLists(mCubeList, 1); |
392 | mGlobalFence = 0; | 373 | mCubeList = 0; |
393 | } | 374 | } |
394 | delete mAGPMemPool; | ||
395 | mAGPMemPool = NULL; | ||
396 | } | ||
397 | |||
398 | //============================================================================ | ||
399 | 375 | ||
400 | BOOL LLPipeline::initAGP() | 376 | mBloomImagep = NULL; |
401 | { | 377 | mBloomImage2p = NULL; |
402 | LLMemType mt(LLMemType::MTYPE_PIPELINE); | 378 | mFaceSelectImagep = NULL; |
403 | 379 | mAlphaSizzleImagep = NULL; | |
404 | mAGPMemPool = LLAGPMemPool::createPool(sAGPMaxPoolSize, mUseVBO); | ||
405 | 380 | ||
406 | if (!mAGPMemPool) | 381 | for (S32 i = 0; i < NUM_PARTITIONS-1; i++) |
407 | { | ||
408 | llinfos << "Warning! Couldn't allocate AGP memory!" << llendl; | ||
409 | llinfos << "Disabling AGP!" << llendl; | ||
410 | mAGPMemPool = NULL; | ||
411 | mRenderFeatureMask &= ~RENDER_FEATURE_AGP; // Need to disable the using AGP flag | ||
412 | return FALSE; | ||
413 | } | ||
414 | else if (!mAGPMemPool->getSize()) | ||
415 | { | ||
416 | llinfos << "Warning! Unable to allocate AGP memory! Disabling AGP" << llendl; | ||
417 | delete mAGPMemPool; | ||
418 | mAGPMemPool = NULL; | ||
419 | mRenderFeatureMask &= ~RENDER_FEATURE_AGP; // Need to disable the using AGP flag | ||
420 | return FALSE; | ||
421 | } | ||
422 | else | ||
423 | { | 382 | { |
424 | llinfos << "Allocated " << mAGPMemPool->getSize() << " bytes of AGP memory" << llendl; | 383 | delete mObjectPartition[i]; |
425 | mAGPMemPool->bind(); | ||
426 | |||
427 | if (mAGPMemPool->getSize() < MIN_AGP_SIZE) | ||
428 | { | ||
429 | llwarns << "Not enough AGP memory!" << llendl; | ||
430 | delete mAGPMemPool; | ||
431 | mAGPMemPool = NULL; | ||
432 | mRenderFeatureMask &= ~RENDER_FEATURE_AGP; // Need to disable the using AGP flag | ||
433 | return FALSE; | ||
434 | } | ||
435 | |||
436 | |||
437 | if (mAGPMemPool) | ||
438 | { | ||
439 | // Create the fence that we use for global synchronization. | ||
440 | mGlobalFence = mAGPMemPool->createFence(); | ||
441 | } | ||
442 | return TRUE; | ||
443 | } | 384 | } |
385 | mObjectPartition.clear(); | ||
444 | 386 | ||
387 | mVisibleList.clear(); | ||
388 | mVisibleGroups.clear(); | ||
389 | mDrawableGroups.clear(); | ||
390 | mActiveGroups.clear(); | ||
391 | mVisibleBridge.clear(); | ||
392 | mMovedBridge.clear(); | ||
393 | mOccludedBridge.clear(); | ||
394 | mAlphaGroups.clear(); | ||
395 | clearRenderMap(); | ||
445 | } | 396 | } |
446 | 397 | ||
447 | void LLPipeline::cleanupAGP() | 398 | //============================================================================ |
448 | { | ||
449 | int i; | ||
450 | for(i=0; i < mBufferCount; i++) | ||
451 | { | ||
452 | mBufferMemory[i]->deleteFence(mBufferFence[i]); | ||
453 | mBufferMemory[i]->setUseAGP(FALSE); | ||
454 | } | ||
455 | |||
456 | flushAGPMemory(); | ||
457 | if (mAGPMemPool && mGlobalFence) | ||
458 | { | ||
459 | mAGPMemPool->deleteFence(mGlobalFence); | ||
460 | mGlobalFence = 0; | ||
461 | } | ||
462 | delete mAGPMemPool; | ||
463 | mAGPMemPool = NULL; | ||
464 | } | ||
465 | 399 | ||
466 | BOOL LLPipeline::usingAGP() const | 400 | void LLPipeline::destroyGL() |
467 | { | 401 | { |
468 | return (mRenderFeatureMask & RENDER_FEATURE_AGP) ? TRUE : FALSE; | 402 | stop_glerror(); |
469 | } | 403 | unloadShaders(); |
404 | mHighlightFaces.clear(); | ||
405 | mVisibleList.clear(); | ||
406 | mVisibleGroups.clear(); | ||
407 | mDrawableGroups.clear(); | ||
408 | mActiveGroups.clear(); | ||
409 | mVisibleBridge.clear(); | ||
410 | mOccludedBridge.clear(); | ||
411 | mAlphaGroups.clear(); | ||
412 | clearRenderMap(); | ||
413 | resetVertexBuffers(); | ||
470 | 414 | ||
471 | void LLPipeline::setUseAGP(const BOOL use_agp) | 415 | if (mCubeBuffer) |
472 | { | ||
473 | LLMemType mt(LLMemType::MTYPE_PIPELINE); | ||
474 | |||
475 | if (use_agp == usingAGP()) | ||
476 | { | 416 | { |
477 | return; | 417 | delete mCubeBuffer; |
418 | mCubeBuffer = NULL; | ||
478 | } | 419 | } |
479 | else if (use_agp) | ||
480 | { | ||
481 | mRenderFeatureMask |= RENDER_FEATURE_AGP; | ||
482 | initAGP(); | ||
483 | 420 | ||
484 | // Forces us to allocate an AGP memory block immediately. | 421 | if (mCubeList) |
485 | int i; | ||
486 | for(i=0; i < mBufferCount; i++) | ||
487 | { | ||
488 | mBufferMemory[i]->setUseAGP(use_agp); | ||
489 | mBufferMemory[i]->realloc(mBufferMemory[i]->getMax()); | ||
490 | mBufferFence[i] = mBufferMemory[i]->createFence(); | ||
491 | } | ||
492 | |||
493 | // Must be done AFTER you initialize AGP | ||
494 | for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) | ||
495 | { | ||
496 | LLDrawPool *poolp = *iter; | ||
497 | poolp->setUseAGP(use_agp); | ||
498 | } | ||
499 | } | ||
500 | else | ||
501 | { | 422 | { |
502 | unbindAGP(); | 423 | glDeleteLists(mCubeList, 1); |
503 | mRenderFeatureMask &= ~RENDER_FEATURE_AGP; | 424 | mCubeList = 0; |
504 | |||
505 | // Must be done BEFORE you blow away AGP | ||
506 | for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) | ||
507 | { | ||
508 | LLDrawPool *poolp = *iter; | ||
509 | poolp->setUseAGP(use_agp); | ||
510 | } | ||
511 | |||
512 | int i; | ||
513 | for(i=0; i < mBufferCount; i++) | ||
514 | { | ||
515 | if (mBufferMemory[i]) | ||
516 | { | ||
517 | mBufferMemory[i]->setUseAGP(use_agp); | ||
518 | mBufferMemory[i]->deleteFence(mBufferFence[i]); | ||
519 | mBufferFence[i] = 0; | ||
520 | } | ||
521 | else | ||
522 | { | ||
523 | llerrs << "setUseAGP without buffer memory" << llendl; | ||
524 | } | ||
525 | } | ||
526 | |||
527 | cleanupAGP(); | ||
528 | } | 425 | } |
529 | |||
530 | } | ||
531 | |||
532 | //============================================================================ | ||
533 | |||
534 | void LLPipeline::destroyGL() | ||
535 | { | ||
536 | setUseAGP(FALSE); | ||
537 | stop_glerror(); | ||
538 | unloadShaders(); | ||
539 | mHighlightFaces.reset(); | ||
540 | } | 426 | } |
541 | 427 | ||
542 | void LLPipeline::restoreGL() | 428 | void LLPipeline::restoreGL() |
543 | { | 429 | { |
430 | resetVertexBuffers(); | ||
431 | |||
544 | if (mVertexShadersEnabled) | 432 | if (mVertexShadersEnabled) |
545 | { | 433 | { |
546 | setShaders(); | 434 | setShaders(); |
547 | } | 435 | } |
548 | 436 | ||
549 | if (mObjectPartition) | 437 | for (U32 i = 0; i < mObjectPartition.size()-1; i++) |
550 | { | 438 | { |
551 | mObjectPartition->restoreGL(); | 439 | if (mObjectPartition[i]) |
440 | { | ||
441 | mObjectPartition[i]->restoreGL(); | ||
442 | } | ||
552 | } | 443 | } |
553 | } | 444 | } |
554 | 445 | ||
@@ -616,8 +507,8 @@ GLhandleARB LLPipeline::loadShader(const LLString& filename, S32 cls, GLenum typ | |||
616 | fname << gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "shaders/class"); | 507 | fname << gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "shaders/class"); |
617 | fname << gpu_class << "/" << filename; | 508 | fname << gpu_class << "/" << filename; |
618 | 509 | ||
619 | llinfos << "Looking in " << fname.str().c_str() << llendl; | 510 | // llinfos << "Looking in " << fname.str().c_str() << llendl; |
620 | file = fopen(fname.str().c_str(), "r"); | 511 | file = fopen(fname.str().c_str(), "r"); /* Flawfinder: ignore */ |
621 | if (file) | 512 | if (file) |
622 | { | 513 | { |
623 | break; // done | 514 | break; // done |
@@ -791,6 +682,11 @@ BOOL LLPipeline::validateProgramObject(GLhandleARB obj) | |||
791 | 682 | ||
792 | void LLPipeline::setShaders() | 683 | void LLPipeline::setShaders() |
793 | { | 684 | { |
685 | sDynamicReflections = gSavedSettings.getBOOL("RenderDynamicReflections"); | ||
686 | |||
687 | //hack to reset buffers that change behavior with shaders | ||
688 | resetVertexBuffers(); | ||
689 | |||
794 | if (gViewerWindow) | 690 | if (gViewerWindow) |
795 | { | 691 | { |
796 | gViewerWindow->setCursor(UI_CURSOR_WAIT); | 692 | gViewerWindow->setCursor(UI_CURSOR_WAIT); |
@@ -809,6 +705,8 @@ void LLPipeline::setShaders() | |||
809 | { | 705 | { |
810 | S32 light_class = 2; | 706 | S32 light_class = 2; |
811 | S32 env_class = 2; | 707 | S32 env_class = 2; |
708 | S32 obj_class = 0; | ||
709 | |||
812 | if (getLightingDetail() == 0) | 710 | if (getLightingDetail() == 0) |
813 | { | 711 | { |
814 | light_class = 1; | 712 | light_class = 1; |
@@ -818,7 +716,11 @@ void LLPipeline::setShaders() | |||
818 | mMaxVertexShaderLevel[SHADER_LIGHTING] = light_class; | 716 | mMaxVertexShaderLevel[SHADER_LIGHTING] = light_class; |
819 | mVertexShaderLevel[SHADER_ENVIRONMENT] = env_class; | 717 | mVertexShaderLevel[SHADER_ENVIRONMENT] = env_class; |
820 | mMaxVertexShaderLevel[SHADER_ENVIRONMENT] = env_class; | 718 | mMaxVertexShaderLevel[SHADER_ENVIRONMENT] = env_class; |
719 | mVertexShaderLevel[SHADER_OBJECT] = obj_class; | ||
720 | mMaxVertexShaderLevel[SHADER_OBJECT] = obj_class; | ||
721 | |||
821 | BOOL loaded = loadShadersLighting(); | 722 | BOOL loaded = loadShadersLighting(); |
723 | |||
822 | if (loaded) | 724 | if (loaded) |
823 | { | 725 | { |
824 | mVertexShadersEnabled = TRUE; | 726 | mVertexShadersEnabled = TRUE; |
@@ -826,7 +728,7 @@ void LLPipeline::setShaders() | |||
826 | 728 | ||
827 | // Load all shaders to set max levels | 729 | // Load all shaders to set max levels |
828 | loadShadersEnvironment(); | 730 | loadShadersEnvironment(); |
829 | 731 | loadShadersObject(); | |
830 | // Load max avatar shaders to set the max level | 732 | // Load max avatar shaders to set the max level |
831 | mVertexShaderLevel[SHADER_AVATAR] = 3; | 733 | mVertexShaderLevel[SHADER_AVATAR] = 3; |
832 | mMaxVertexShaderLevel[SHADER_AVATAR] = 3; | 734 | mMaxVertexShaderLevel[SHADER_AVATAR] = 3; |
@@ -898,6 +800,7 @@ BOOL LLPipeline::canUseVertexShaders() | |||
898 | void LLPipeline::unloadShaders() | 800 | void LLPipeline::unloadShaders() |
899 | { | 801 | { |
900 | mObjectSimpleProgram.unload(); | 802 | mObjectSimpleProgram.unload(); |
803 | mObjectShinyProgram.unload(); | ||
901 | mObjectBumpProgram.unload(); | 804 | mObjectBumpProgram.unload(); |
902 | mObjectAlphaProgram.unload(); | 805 | mObjectAlphaProgram.unload(); |
903 | mWaterProgram.unload(); | 806 | mWaterProgram.unload(); |
@@ -939,7 +842,8 @@ BOOL LLPipeline::loadShaders() | |||
939 | light_class = 2; // Use medium lighting shader | 842 | light_class = 2; // Use medium lighting shader |
940 | } | 843 | } |
941 | mVertexShaderLevel[SHADER_LIGHTING] = light_class; | 844 | mVertexShaderLevel[SHADER_LIGHTING] = light_class; |
942 | mVertexShaderLevel[SHADER_OBJECT] = llmin(mMaxVertexShaderLevel[SHADER_OBJECT], gSavedSettings.getS32("VertexShaderLevelObject")); | 845 | //mVertexShaderLevel[SHADER_OBJECT] = llmin(mMaxVertexShaderLevel[SHADER_OBJECT], gSavedSettings.getS32("VertexShaderLevelObject")); |
846 | mVertexShaderLevel[SHADER_OBJECT] = 0; | ||
943 | mVertexShaderLevel[SHADER_AVATAR] = llmin(mMaxVertexShaderLevel[SHADER_AVATAR], gSavedSettings.getS32("VertexShaderLevelAvatar")); | 847 | mVertexShaderLevel[SHADER_AVATAR] = llmin(mMaxVertexShaderLevel[SHADER_AVATAR], gSavedSettings.getS32("VertexShaderLevelAvatar")); |
944 | mVertexShaderLevel[SHADER_ENVIRONMENT] = llmin(mMaxVertexShaderLevel[SHADER_ENVIRONMENT], gSavedSettings.getS32("VertexShaderLevelEnvironment")); | 848 | mVertexShaderLevel[SHADER_ENVIRONMENT] = llmin(mMaxVertexShaderLevel[SHADER_ENVIRONMENT], gSavedSettings.getS32("VertexShaderLevelEnvironment")); |
945 | mVertexShaderLevel[SHADER_INTERFACE] = mMaxVertexShaderLevel[SHADER_INTERFACE]; | 849 | mVertexShaderLevel[SHADER_INTERFACE] = mMaxVertexShaderLevel[SHADER_INTERFACE]; |
@@ -1120,12 +1024,14 @@ BOOL LLPipeline::loadShadersObject() | |||
1120 | 1024 | ||
1121 | if (mVertexShaderLevel[SHADER_OBJECT] == 0) | 1025 | if (mVertexShaderLevel[SHADER_OBJECT] == 0) |
1122 | { | 1026 | { |
1027 | mObjectShinyProgram.unload(); | ||
1123 | mObjectSimpleProgram.unload(); | 1028 | mObjectSimpleProgram.unload(); |
1124 | mObjectBumpProgram.unload(); | 1029 | mObjectBumpProgram.unload(); |
1125 | mObjectAlphaProgram.unload(); | 1030 | mObjectAlphaProgram.unload(); |
1126 | return FALSE; | 1031 | return FALSE; |
1127 | } | 1032 | } |
1128 | 1033 | ||
1034 | #if 0 | ||
1129 | if (success) | 1035 | if (success) |
1130 | { | 1036 | { |
1131 | //load object (volume/tree) vertex shader | 1037 | //load object (volume/tree) vertex shader |
@@ -1186,6 +1092,28 @@ BOOL LLPipeline::loadShadersObject() | |||
1186 | llwarns << "Failed to load " << alphavertex << llendl; | 1092 | llwarns << "Failed to load " << alphavertex << llendl; |
1187 | } | 1093 | } |
1188 | } | 1094 | } |
1095 | #endif | ||
1096 | |||
1097 | if (success) | ||
1098 | { | ||
1099 | //load shiny vertex shader | ||
1100 | std::string shinyvertex = "objects/shinyV.glsl"; | ||
1101 | std::string shinyfragment = "objects/shinyF.glsl"; | ||
1102 | mObjectShinyProgram.mProgramObject = glCreateProgramObjectARB(); | ||
1103 | mObjectShinyProgram.attachObjects(baseObjects, baseCount); | ||
1104 | mObjectShinyProgram.attachObject(loadShader(shinyvertex, SHADER_OBJECT, GL_VERTEX_SHADER_ARB)); | ||
1105 | mObjectShinyProgram.attachObject(loadShader(shinyfragment, SHADER_OBJECT, GL_FRAGMENT_SHADER_ARB)); | ||
1106 | |||
1107 | success = mObjectShinyProgram.mapAttributes(); | ||
1108 | if (success) | ||
1109 | { | ||
1110 | success = mObjectShinyProgram.mapUniforms(LLPipeline::sShinyUniforms, LLPipeline::sShinyUniformCount); | ||
1111 | } | ||
1112 | if( !success ) | ||
1113 | { | ||
1114 | llwarns << "Failed to load " << shinyvertex << llendl; | ||
1115 | } | ||
1116 | } | ||
1189 | 1117 | ||
1190 | if( !success ) | 1118 | if( !success ) |
1191 | { | 1119 | { |
@@ -1342,11 +1270,11 @@ void LLPipeline::enableShadows(const BOOL enable_shadows) | |||
1342 | 1270 | ||
1343 | S32 LLPipeline::getMaxLightingDetail() const | 1271 | S32 LLPipeline::getMaxLightingDetail() const |
1344 | { | 1272 | { |
1345 | if (mVertexShaderLevel[SHADER_OBJECT] >= LLDrawPoolSimple::SHADER_LEVEL_LOCAL_LIGHTS) | 1273 | /*if (mVertexShaderLevel[SHADER_OBJECT] >= LLDrawPoolSimple::SHADER_LEVEL_LOCAL_LIGHTS) |
1346 | { | 1274 | { |
1347 | return 3; | 1275 | return 3; |
1348 | } | 1276 | } |
1349 | else | 1277 | else*/ |
1350 | { | 1278 | { |
1351 | return 1; | 1279 | return 1; |
1352 | } | 1280 | } |
@@ -1376,79 +1304,62 @@ S32 LLPipeline::setLightingDetail(S32 level) | |||
1376 | return mLightingDetail; | 1304 | return mLightingDetail; |
1377 | } | 1305 | } |
1378 | 1306 | ||
1379 | LLAGPMemBlock *LLPipeline::allocAGPFromPool(const S32 bytes, const U32 target) | 1307 | class LLOctreeDirtyTexture : public LLOctreeTraveler<LLDrawable> |
1380 | { | 1308 | { |
1381 | LLMemType mt(LLMemType::MTYPE_PIPELINE); | 1309 | public: |
1382 | 1310 | const std::set<LLViewerImage*>& mTextures; | |
1383 | if (!mAGPMemPool) | 1311 | |
1384 | { | 1312 | LLOctreeDirtyTexture(const std::set<LLViewerImage*>& textures) : mTextures(textures) { } |
1385 | llwarns << "Attempting to allocate AGP memory when AGP disabled!" << llendl; | 1313 | |
1386 | return NULL; | 1314 | virtual void visit(const LLOctreeState<LLDrawable>* state) |
1387 | } | ||
1388 | else | ||
1389 | { | 1315 | { |
1390 | if (mUseVBO) | 1316 | LLSpatialGroup* group = (LLSpatialGroup*) state->getNode()->getListener(0); |
1317 | |||
1318 | if (!group->isState(LLSpatialGroup::GEOM_DIRTY) && !group->getData().empty()) | ||
1391 | { | 1319 | { |
1392 | return ((LLAGPMemPoolARB*) mAGPMemPool)->allocBlock(bytes, target); | 1320 | for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i) |
1321 | { | ||
1322 | for (std::vector<LLDrawInfo*>::iterator j = i->second.begin(); j != i->second.end(); ++j) | ||
1323 | { | ||
1324 | LLDrawInfo* params = *j; | ||
1325 | if (mTextures.find(params->mTexture) != mTextures.end()) | ||
1326 | { | ||
1327 | group->setState(LLSpatialGroup::GEOM_DIRTY); | ||
1328 | } | ||
1329 | } | ||
1330 | } | ||
1393 | } | 1331 | } |
1394 | else | 1332 | |
1333 | for (LLSpatialGroup::bridge_list_t::iterator i = group->mBridgeList.begin(); i != group->mBridgeList.end(); ++i) | ||
1395 | { | 1334 | { |
1396 | return mAGPMemPool->allocBlock(bytes); | 1335 | LLSpatialBridge* bridge = *i; |
1336 | traverse(bridge->mOctree); | ||
1397 | } | 1337 | } |
1398 | } | 1338 | } |
1399 | } | 1339 | }; |
1400 | |||
1401 | |||
1402 | void LLPipeline::unbindAGP() | ||
1403 | { | ||
1404 | if (mAGPMemPool && mAGPBound) | ||
1405 | { | ||
1406 | mAGPMemPool->disable(); | ||
1407 | mAGPBound = FALSE; | ||
1408 | } | ||
1409 | } | ||
1410 | |||
1411 | void LLPipeline::bindAGP() | ||
1412 | { | ||
1413 | LLMemType mt(LLMemType::MTYPE_PIPELINE); | ||
1414 | |||
1415 | if (mAGPMemPool && !mAGPBound && usingAGP()) | ||
1416 | { | ||
1417 | mAGPMemPool->enable(); | ||
1418 | mAGPBound = TRUE; | ||
1419 | } | ||
1420 | } | ||
1421 | |||
1422 | U8* LLPipeline::bufferGetScratchMemory(void) | ||
1423 | { | ||
1424 | LLMemType mt(LLMemType::MTYPE_PIPELINE); | ||
1425 | return(mBufferMemory[mBufferIndex]->getScratchMemory()); | ||
1426 | } | ||
1427 | |||
1428 | void LLPipeline::bufferWaitFence(void) | ||
1429 | { | ||
1430 | mBufferMemory[mBufferIndex]->waitFence(mBufferFence[mBufferIndex]); | ||
1431 | } | ||
1432 | |||
1433 | void LLPipeline::bufferSendFence(void) | ||
1434 | { | ||
1435 | mBufferMemory[mBufferIndex]->sendFence(mBufferFence[mBufferIndex]); | ||
1436 | } | ||
1437 | 1340 | ||
1438 | void LLPipeline::bufferRotate(void) | 1341 | // Called when a texture changes # of channels (causes faces to move to alpha pool) |
1342 | void LLPipeline::dirtyPoolObjectTextures(const std::set<LLViewerImage*>& textures) | ||
1439 | { | 1343 | { |
1440 | mBufferIndex++; | 1344 | // *TODO: This is inefficient and causes frame spikes; need a better way to do this |
1441 | if(mBufferIndex >= mBufferCount) | 1345 | // Most of the time is spent in dirty.traverse. |
1442 | mBufferIndex = 0; | ||
1443 | } | ||
1444 | 1346 | ||
1445 | // Called when a texture changes # of channels (rare, may cause faces to move to alpha pool) | ||
1446 | void LLPipeline::dirtyPoolObjectTextures(const LLViewerImage *texturep) | ||
1447 | { | ||
1448 | for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) | 1347 | for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) |
1449 | { | 1348 | { |
1450 | LLDrawPool *poolp = *iter; | 1349 | LLDrawPool *poolp = *iter; |
1451 | poolp->dirtyTexture(texturep); | 1350 | if (poolp->isFacePool()) |
1351 | { | ||
1352 | ((LLFacePool*) poolp)->dirtyTextures(textures); | ||
1353 | } | ||
1354 | } | ||
1355 | |||
1356 | LLOctreeDirtyTexture dirty(textures); | ||
1357 | for (U32 i = 0; i < mObjectPartition.size(); i++) | ||
1358 | { | ||
1359 | if (mObjectPartition[i]) | ||
1360 | { | ||
1361 | dirty.traverse(mObjectPartition[i]->mOctree); | ||
1362 | } | ||
1452 | } | 1363 | } |
1453 | } | 1364 | } |
1454 | 1365 | ||
@@ -1458,33 +1369,29 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerImage *tex0) | |||
1458 | switch( type ) | 1369 | switch( type ) |
1459 | { | 1370 | { |
1460 | case LLDrawPool::POOL_SIMPLE: | 1371 | case LLDrawPool::POOL_SIMPLE: |
1461 | poolp = get_if_there(mSimplePools, (uintptr_t)tex0, (LLDrawPool*)0 ); | 1372 | poolp = mSimplePool; |
1462 | break; | 1373 | break; |
1463 | 1374 | ||
1464 | case LLDrawPool::POOL_TREE: | 1375 | case LLDrawPool::POOL_TREE: |
1465 | poolp = get_if_there(mTreePools, (uintptr_t)tex0, (LLDrawPool*)0 ); | 1376 | poolp = get_if_there(mTreePools, (uintptr_t)tex0, (LLDrawPool*)0 ); |
1466 | break; | 1377 | break; |
1467 | 1378 | ||
1468 | case LLDrawPool::POOL_TREE_NEW: | ||
1469 | poolp = get_if_there(mTreeNewPools, (uintptr_t)tex0, (LLDrawPool*)0 ); | ||
1470 | break; | ||
1471 | |||
1472 | case LLDrawPool::POOL_TERRAIN: | 1379 | case LLDrawPool::POOL_TERRAIN: |
1473 | poolp = get_if_there(mTerrainPools, (uintptr_t)tex0, (LLDrawPool*)0 ); | 1380 | poolp = get_if_there(mTerrainPools, (uintptr_t)tex0, (LLDrawPool*)0 ); |
1474 | break; | 1381 | break; |
1475 | 1382 | ||
1476 | case LLDrawPool::POOL_BUMP: | 1383 | case LLDrawPool::POOL_BUMP: |
1477 | poolp = get_if_there(mBumpPools, (uintptr_t)tex0, (LLDrawPool*)0 ); | 1384 | poolp = mBumpPool; |
1478 | break; | ||
1479 | |||
1480 | case LLDrawPool::POOL_MEDIA: | ||
1481 | poolp = get_if_there(mMediaPools, (uintptr_t)tex0, (LLDrawPool*)0 ); | ||
1482 | break; | 1385 | break; |
1483 | 1386 | ||
1484 | case LLDrawPool::POOL_ALPHA: | 1387 | case LLDrawPool::POOL_ALPHA: |
1485 | poolp = mAlphaPool; | 1388 | poolp = mAlphaPool; |
1486 | break; | 1389 | break; |
1487 | 1390 | ||
1391 | case LLDrawPool::POOL_ALPHA_POST_WATER: | ||
1392 | poolp = mAlphaPoolPostWater; | ||
1393 | break; | ||
1394 | |||
1488 | case LLDrawPool::POOL_AVATAR: | 1395 | case LLDrawPool::POOL_AVATAR: |
1489 | break; // Do nothing | 1396 | break; // Do nothing |
1490 | 1397 | ||
@@ -1496,10 +1403,6 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerImage *tex0) | |||
1496 | poolp = mStarsPool; | 1403 | poolp = mStarsPool; |
1497 | break; | 1404 | break; |
1498 | 1405 | ||
1499 | case LLDrawPool::POOL_CLOUDS: | ||
1500 | poolp = mCloudsPool; | ||
1501 | break; | ||
1502 | |||
1503 | case LLDrawPool::POOL_WATER: | 1406 | case LLDrawPool::POOL_WATER: |
1504 | poolp = mWaterPool; | 1407 | poolp = mWaterPool; |
1505 | break; | 1408 | break; |
@@ -1508,10 +1411,6 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerImage *tex0) | |||
1508 | poolp = mGroundPool; | 1411 | poolp = mGroundPool; |
1509 | break; | 1412 | break; |
1510 | 1413 | ||
1511 | case LLDrawPool::POOL_HUD: | ||
1512 | poolp = mHUDPool; | ||
1513 | break; | ||
1514 | |||
1515 | default: | 1414 | default: |
1516 | llassert(0); | 1415 | llassert(0); |
1517 | llerrs << "Invalid Pool Type in LLPipeline::findPool() type=" << type << llendl; | 1416 | llerrs << "Invalid Pool Type in LLPipeline::findPool() type=" << type << llendl; |
@@ -1542,29 +1441,37 @@ LLDrawPool *LLPipeline::getPool(const U32 type, LLViewerImage *tex0) | |||
1542 | LLDrawPool* LLPipeline::getPoolFromTE(const LLTextureEntry* te, LLViewerImage* imagep) | 1441 | LLDrawPool* LLPipeline::getPoolFromTE(const LLTextureEntry* te, LLViewerImage* imagep) |
1543 | { | 1442 | { |
1544 | LLMemType mt(LLMemType::MTYPE_PIPELINE); | 1443 | LLMemType mt(LLMemType::MTYPE_PIPELINE); |
1444 | U32 type = getPoolTypeFromTE(te, imagep); | ||
1445 | return gPipeline.getPool(type, imagep); | ||
1446 | } | ||
1447 | |||
1448 | //static | ||
1449 | U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerImage* imagep) | ||
1450 | { | ||
1451 | LLMemType mt(LLMemType::MTYPE_PIPELINE); | ||
1452 | |||
1453 | if (!te || !imagep) | ||
1454 | { | ||
1455 | return 0; | ||
1456 | } | ||
1457 | |||
1545 | bool alpha = te->getColor().mV[3] < 0.999f; | 1458 | bool alpha = te->getColor().mV[3] < 0.999f; |
1546 | if (imagep) | 1459 | if (imagep) |
1547 | { | 1460 | { |
1548 | alpha = alpha || (imagep->getComponents() == 4) || (imagep->getComponents() == 2); | 1461 | alpha = alpha || (imagep->getComponents() == 4) || (imagep->getComponents() == 2); |
1549 | } | 1462 | } |
1550 | #if 0 // Not currently used | 1463 | |
1551 | if (te->getMediaFlags() == LLTextureEntry::MF_WEB_PAGE) | ||
1552 | { | ||
1553 | return gPipeline.getPool(LLDrawPool::POOL_MEDIA, imagep); | ||
1554 | } | ||
1555 | else | ||
1556 | #endif | ||
1557 | if (alpha) | 1464 | if (alpha) |
1558 | { | 1465 | { |
1559 | return gPipeline.getPool(LLDrawPool::POOL_ALPHA); | 1466 | return LLDrawPool::POOL_ALPHA; |
1560 | } | 1467 | } |
1561 | else if ((te->getBumpmap() || te->getShiny())) | 1468 | else if ((te->getBumpmap() || te->getShiny())) |
1562 | { | 1469 | { |
1563 | return gPipeline.getPool(LLDrawPool::POOL_BUMP, imagep); | 1470 | return LLDrawPool::POOL_BUMP; |
1564 | } | 1471 | } |
1565 | else | 1472 | else |
1566 | { | 1473 | { |
1567 | return gPipeline.getPool(LLDrawPool::POOL_SIMPLE, imagep); | 1474 | return LLDrawPool::POOL_SIMPLE; |
1568 | } | 1475 | } |
1569 | } | 1476 | } |
1570 | 1477 | ||
@@ -1595,14 +1502,20 @@ void LLPipeline::allocDrawable(LLViewerObject *vobj) | |||
1595 | } | 1502 | } |
1596 | 1503 | ||
1597 | 1504 | ||
1598 | void LLPipeline::unlinkDrawable(LLDrawable *drawablep) | 1505 | void LLPipeline::unlinkDrawable(LLDrawable *drawable) |
1599 | { | 1506 | { |
1600 | LLFastTimer t(LLFastTimer::FTM_PIPELINE); | 1507 | LLFastTimer t(LLFastTimer::FTM_PIPELINE); |
1508 | |||
1509 | LLPointer<LLDrawable> drawablep = drawable; // make sure this doesn't get deleted before we are done | ||
1601 | 1510 | ||
1602 | // Based on flags, remove the drawable from the queues that it's on. | 1511 | // Based on flags, remove the drawable from the queues that it's on. |
1603 | if (drawablep->isState(LLDrawable::ON_MOVE_LIST)) | 1512 | if (drawablep->isState(LLDrawable::ON_MOVE_LIST)) |
1604 | { | 1513 | { |
1605 | mMovedList.erase(drawablep); | 1514 | LLDrawable::drawable_vector_t::iterator iter = std::find(mMovedList.begin(), mMovedList.end(), drawablep); |
1515 | if (iter != mMovedList.end()) | ||
1516 | { | ||
1517 | mMovedList.erase(iter); | ||
1518 | } | ||
1606 | } | 1519 | } |
1607 | 1520 | ||
1608 | if (drawablep->getSpatialGroup()) | 1521 | if (drawablep->getSpatialGroup()) |
@@ -1632,9 +1545,6 @@ U32 LLPipeline::addObject(LLViewerObject *vobj) | |||
1632 | 1545 | ||
1633 | llassert(drawablep); | 1546 | llassert(drawablep); |
1634 | 1547 | ||
1635 | //mCompleteSet.put(drawable); | ||
1636 | //gResyncObjects = TRUE; | ||
1637 | |||
1638 | if (vobj->getParent()) | 1548 | if (vobj->getParent()) |
1639 | { | 1549 | { |
1640 | vobj->setDrawableParent(((LLViewerObject*)vobj->getParent())->mDrawable); // LLPipeline::addObject 1 | 1550 | vobj->setDrawableParent(((LLViewerObject*)vobj->getParent())->mDrawable); // LLPipeline::addObject 1 |
@@ -1644,28 +1554,6 @@ U32 LLPipeline::addObject(LLViewerObject *vobj) | |||
1644 | vobj->setDrawableParent(NULL); // LLPipeline::addObject 2 | 1554 | vobj->setDrawableParent(NULL); // LLPipeline::addObject 2 |
1645 | } | 1555 | } |
1646 | 1556 | ||
1647 | |||
1648 | if ((!drawablep->getVOVolume()) && | ||
1649 | (vobj->getPCode() != LLViewerObject::LL_VO_SKY) && | ||
1650 | (vobj->getPCode() != LLViewerObject::LL_VO_STARS) && | ||
1651 | (vobj->getPCode() != LLViewerObject::LL_VO_GROUND)) | ||
1652 | { | ||
1653 | drawablep->getSpatialPartition()->put(drawablep); | ||
1654 | if (!drawablep->getSpatialGroup()) | ||
1655 | { | ||
1656 | #ifdef LL_RELEASE_FOR_DOWNLOAD | ||
1657 | llwarns << "Failure adding drawable to object partition!" << llendl; | ||
1658 | #else | ||
1659 | llerrs << "Failure adding drawable to object partition!" << llendl; | ||
1660 | #endif | ||
1661 | } | ||
1662 | } | ||
1663 | else | ||
1664 | { | ||
1665 | markMoved(drawablep); | ||
1666 | } | ||
1667 | |||
1668 | markMaterialed(drawablep); | ||
1669 | markRebuild(drawablep, LLDrawable::REBUILD_ALL, TRUE); | 1557 | markRebuild(drawablep, LLDrawable::REBUILD_ALL, TRUE); |
1670 | 1558 | ||
1671 | return 1; | 1559 | return 1; |
@@ -1674,11 +1562,27 @@ U32 LLPipeline::addObject(LLViewerObject *vobj) | |||
1674 | 1562 | ||
1675 | void LLPipeline::resetFrameStats() | 1563 | void LLPipeline::resetFrameStats() |
1676 | { | 1564 | { |
1565 | mCompilesStat.addValue(sCompiles); | ||
1566 | mLightingChangesStat.addValue(mLightingChanges); | ||
1567 | mGeometryChangesStat.addValue(mGeometryChanges); | ||
1568 | mTrianglesDrawnStat.addValue(mTrianglesDrawn/1000.f); | ||
1569 | mVerticesRelitStat.addValue(mVerticesRelit); | ||
1570 | mNumVisibleFacesStat.addValue(mNumVisibleFaces); | ||
1571 | mNumVisibleDrawablesStat.addValue((S32)mVisibleList.size()); | ||
1572 | |||
1573 | mTrianglesDrawn = 0; | ||
1677 | sCompiles = 0; | 1574 | sCompiles = 0; |
1678 | mVerticesRelit = 0; | 1575 | mVerticesRelit = 0; |
1679 | mLightingChanges = 0; | 1576 | mLightingChanges = 0; |
1680 | mGeometryChanges = 0; | 1577 | mGeometryChanges = 0; |
1681 | mNumVisibleFaces = 0; | 1578 | mNumVisibleFaces = 0; |
1579 | |||
1580 | if (mOldRenderDebugMask != mRenderDebugMask) | ||
1581 | { | ||
1582 | gObjectList.clearDebugText(); | ||
1583 | mOldRenderDebugMask = mRenderDebugMask; | ||
1584 | } | ||
1585 | |||
1682 | } | 1586 | } |
1683 | 1587 | ||
1684 | //external functions for asynchronous updating | 1588 | //external functions for asynchronous updating |
@@ -1703,7 +1607,7 @@ void LLPipeline::updateMoveDampedAsync(LLDrawable* drawablep) | |||
1703 | // Put on move list so that EARLY_MOVE gets cleared | 1607 | // Put on move list so that EARLY_MOVE gets cleared |
1704 | if (!drawablep->isState(LLDrawable::ON_MOVE_LIST)) | 1608 | if (!drawablep->isState(LLDrawable::ON_MOVE_LIST)) |
1705 | { | 1609 | { |
1706 | mMovedList.insert(drawablep); | 1610 | mMovedList.push_back(drawablep); |
1707 | drawablep->setState(LLDrawable::ON_MOVE_LIST); | 1611 | drawablep->setState(LLDrawable::ON_MOVE_LIST); |
1708 | } | 1612 | } |
1709 | } | 1613 | } |
@@ -1729,15 +1633,35 @@ void LLPipeline::updateMoveNormalAsync(LLDrawable* drawablep) | |||
1729 | // Put on move list so that EARLY_MOVE gets cleared | 1633 | // Put on move list so that EARLY_MOVE gets cleared |
1730 | if (!drawablep->isState(LLDrawable::ON_MOVE_LIST)) | 1634 | if (!drawablep->isState(LLDrawable::ON_MOVE_LIST)) |
1731 | { | 1635 | { |
1732 | mMovedList.insert(drawablep); | 1636 | mMovedList.push_back(drawablep); |
1733 | drawablep->setState(LLDrawable::ON_MOVE_LIST); | 1637 | drawablep->setState(LLDrawable::ON_MOVE_LIST); |
1734 | } | 1638 | } |
1735 | } | 1639 | } |
1736 | 1640 | ||
1641 | void LLPipeline::updateMovedList(LLDrawable::drawable_vector_t& moved_list) | ||
1642 | { | ||
1643 | for (LLDrawable::drawable_vector_t::iterator iter = moved_list.begin(); | ||
1644 | iter != moved_list.end(); ) | ||
1645 | { | ||
1646 | LLDrawable::drawable_vector_t::iterator curiter = iter++; | ||
1647 | LLDrawable *drawablep = *curiter; | ||
1648 | BOOL done = TRUE; | ||
1649 | if (!drawablep->isDead() && (!drawablep->isState(LLDrawable::EARLY_MOVE))) | ||
1650 | { | ||
1651 | done = drawablep->updateMove(); | ||
1652 | } | ||
1653 | drawablep->clearState(LLDrawable::EARLY_MOVE | LLDrawable::MOVE_UNDAMPED); | ||
1654 | if (done) | ||
1655 | { | ||
1656 | drawablep->clearState(LLDrawable::ON_MOVE_LIST); | ||
1657 | iter = moved_list.erase(curiter); | ||
1658 | } | ||
1659 | } | ||
1660 | } | ||
1661 | |||
1737 | void LLPipeline::updateMove() | 1662 | void LLPipeline::updateMove() |
1738 | { | 1663 | { |
1739 | mObjectPartition->mOctree->validate(); | 1664 | //LLFastTimer t(LLFastTimer::FTM_UPDATE_MOVE); |
1740 | LLFastTimer t(LLFastTimer::FTM_UPDATE_MOVE); | ||
1741 | LLMemType mt(LLMemType::MTYPE_PIPELINE); | 1665 | LLMemType mt(LLMemType::MTYPE_PIPELINE); |
1742 | 1666 | ||
1743 | if (gSavedSettings.getBOOL("FreezeTime")) | 1667 | if (gSavedSettings.getBOOL("FreezeTime")) |
@@ -1747,23 +1671,18 @@ void LLPipeline::updateMove() | |||
1747 | 1671 | ||
1748 | mMoveChangesStat.addValue((F32)mMovedList.size()); | 1672 | mMoveChangesStat.addValue((F32)mMovedList.size()); |
1749 | 1673 | ||
1750 | for (LLDrawable::drawable_set_t::iterator iter = mMovedList.begin(); | 1674 | for (LLDrawable::drawable_set_t::iterator iter = mRetexturedList.begin(); |
1751 | iter != mMovedList.end(); ) | 1675 | iter != mRetexturedList.end(); ++iter) |
1752 | { | 1676 | { |
1753 | LLDrawable::drawable_set_t::iterator curiter = iter++; | 1677 | LLDrawable* drawablep = *iter; |
1754 | LLDrawable *drawablep = *curiter; | 1678 | if (drawablep && !drawablep->isDead()) |
1755 | BOOL done = TRUE; | ||
1756 | if (!drawablep->isDead() && (!drawablep->isState(LLDrawable::EARLY_MOVE))) | ||
1757 | { | ||
1758 | done = drawablep->updateMove(); | ||
1759 | } | ||
1760 | drawablep->clearState(LLDrawable::EARLY_MOVE | LLDrawable::MOVE_UNDAMPED); | ||
1761 | if (done) | ||
1762 | { | 1679 | { |
1763 | mMovedList.erase(curiter); | 1680 | drawablep->updateTexture(); |
1764 | drawablep->clearState(LLDrawable::ON_MOVE_LIST); | ||
1765 | } | 1681 | } |
1766 | } | 1682 | } |
1683 | mRetexturedList.clear(); | ||
1684 | |||
1685 | updateMovedList(mMovedList); | ||
1767 | 1686 | ||
1768 | for (LLDrawable::drawable_set_t::iterator iter = mActiveQ.begin(); | 1687 | for (LLDrawable::drawable_set_t::iterator iter = mActiveQ.begin(); |
1769 | iter != mActiveQ.end(); ) | 1688 | iter != mActiveQ.end(); ) |
@@ -1772,7 +1691,8 @@ void LLPipeline::updateMove() | |||
1772 | LLDrawable* drawablep = *curiter; | 1691 | LLDrawable* drawablep = *curiter; |
1773 | if (drawablep && !drawablep->isDead()) | 1692 | if (drawablep && !drawablep->isDead()) |
1774 | { | 1693 | { |
1775 | if (drawablep->mQuietCount++ > MAX_ACTIVE_OBJECT_QUIET_FRAMES && | 1694 | if (drawablep->isRoot() && |
1695 | drawablep->mQuietCount++ > MAX_ACTIVE_OBJECT_QUIET_FRAMES && | ||
1776 | (!drawablep->getParent() || !drawablep->getParent()->isActive())) | 1696 | (!drawablep->getParent() || !drawablep->getParent()->isActive())) |
1777 | { | 1697 | { |
1778 | drawablep->makeStatic(); // removes drawable and its children from mActiveQ | 1698 | drawablep->makeStatic(); // removes drawable and its children from mActiveQ |
@@ -1785,172 +1705,164 @@ void LLPipeline::updateMove() | |||
1785 | } | 1705 | } |
1786 | } | 1706 | } |
1787 | 1707 | ||
1788 | for (LLDrawable::drawable_set_t::iterator iter = mRetexturedList.begin(); | 1708 | //balance octrees |
1789 | iter != mRetexturedList.end(); ++iter) | ||
1790 | { | 1709 | { |
1791 | LLDrawable* drawablep = *iter; | 1710 | LLFastTimer ot(LLFastTimer::FTM_OCTREE_BALANCE); |
1792 | if (drawablep && !drawablep->isDead()) | 1711 | for (U32 i = 0; i < mObjectPartition.size()-1; i++) |
1793 | { | ||
1794 | drawablep->updateTexture(); | ||
1795 | } | ||
1796 | } | ||
1797 | mRetexturedList.clear(); | ||
1798 | |||
1799 | for (LLDrawable::drawable_set_t::iterator iter = mRematerialedList.begin(); | ||
1800 | iter != mRematerialedList.end(); ++iter) | ||
1801 | { | ||
1802 | LLDrawable* drawablep = *iter; | ||
1803 | if (drawablep && !drawablep->isDead()) | ||
1804 | { | 1712 | { |
1805 | drawablep->updateMaterial(); | 1713 | if (mObjectPartition[i]) |
1714 | { | ||
1715 | mObjectPartition[i]->mOctree->balance(); | ||
1716 | } | ||
1806 | } | 1717 | } |
1807 | } | 1718 | } |
1808 | mRematerialedList.clear(); | ||
1809 | |||
1810 | if (mObjectPartition->mOctree) | ||
1811 | { | ||
1812 | //balance octree | ||
1813 | LLFastTimer ot(LLFastTimer::FTM_OCTREE_BALANCE); | ||
1814 | mObjectPartition->mOctree->validate(); | ||
1815 | mObjectPartition->mOctree->balance(); | ||
1816 | mObjectPartition->mOctree->validate(); | ||
1817 | } | ||
1818 | } | 1719 | } |
1819 | 1720 | ||
1820 | ///////////////////////////////////////////////////////////////////////////// | 1721 | ///////////////////////////////////////////////////////////////////////////// |
1821 | // Culling and occlusion testing | 1722 | // Culling and occlusion testing |
1822 | ///////////////////////////////////////////////////////////////////////////// | 1723 | ///////////////////////////////////////////////////////////////////////////// |
1823 | 1724 | ||
1824 | void LLPipeline::updateCull() | 1725 | //static |
1726 | F32 LLPipeline::calcPixelArea(LLVector3 center, LLVector3 size, LLCamera &camera) | ||
1825 | { | 1727 | { |
1826 | LLFastTimer t(LLFastTimer::FTM_CULL); | 1728 | LLVector3 lookAt = center - camera.getOrigin(); |
1827 | LLMemType mt(LLMemType::MTYPE_PIPELINE); | 1729 | F32 dist = lookAt.magVec(); |
1828 | |||
1829 | LLDrawable::incrementVisible(); | ||
1830 | mVisibleList.resize(0); | ||
1831 | mVisibleList.reserve(ESTIMATED_VISIBLE_OBJECT_COUNT); | ||
1832 | |||
1833 | gTrivialAccepts = 0; | ||
1834 | 1730 | ||
1835 | if (mObjectPartition) | 1731 | //ramp down distance for nearby objects |
1732 | if (dist < 16.f) | ||
1836 | { | 1733 | { |
1837 | if (gSavedSettings.getBOOL("UseOcclusion") && gGLManager.mHasOcclusionQuery) | 1734 | dist /= 16.f; |
1838 | { | 1735 | dist *= dist; |
1839 | mObjectPartition->processOcclusion(gCamera); | 1736 | dist *= 16.f; |
1840 | stop_glerror(); | ||
1841 | } | ||
1842 | mObjectPartition->cull(*gCamera); | ||
1843 | } | 1737 | } |
1844 | |||
1845 | // Hack for avatars - warning - this is really FRAGILE! - djs 05/06/02 | ||
1846 | LLVOAvatar::updateAllAvatarVisiblity(); | ||
1847 | |||
1848 | // If there are any other hacks here, make sure to add them to the | ||
1849 | // standard pick code. | ||
1850 | 1738 | ||
1851 | gMinObjectDistance = llclamp(gMinObjectDistance, MIN_NEAR_PLANE, MAX_NEAR_PLANE); | 1739 | //get area of circle around node |
1740 | F32 app_angle = atanf(size.magVec()/dist); | ||
1741 | F32 radius = app_angle*LLDrawable::sCurPixelAngle; | ||
1742 | return radius*radius * 3.14159f; | ||
1743 | } | ||
1852 | 1744 | ||
1853 | F32 water_height = gAgent.getRegion()->getWaterHeight(); | 1745 | void LLPipeline::updateCull(LLCamera& camera) |
1854 | F32 camera_height = gAgent.getCameraPositionAgent().mV[2]; | 1746 | { |
1855 | if (fabs(camera_height - water_height) < 2.f) | 1747 | LLFastTimer t(LLFastTimer::FTM_CULL); |
1856 | { | 1748 | LLMemType mt(LLMemType::MTYPE_PIPELINE); |
1857 | gMinObjectDistance = MIN_NEAR_PLANE; | ||
1858 | } | ||
1859 | 1749 | ||
1860 | gCamera->setNear(gMinObjectDistance); | 1750 | mVisibleList.clear(); |
1751 | mVisibleGroups.clear(); | ||
1752 | mDrawableGroups.clear(); | ||
1753 | mActiveGroups.clear(); | ||
1754 | gTrivialAccepts = 0; | ||
1755 | mVisibleBridge.clear(); | ||
1861 | 1756 | ||
1862 | // Disable near clip stuff for now... | 1757 | processOcclusion(camera); |
1863 | 1758 | ||
1864 | // now push it back out to max value | 1759 | for (U32 i = 0; i < mObjectPartition.size(); i++) |
1865 | gMinObjectDistance = MIN_NEAR_PLANE; | 1760 | { |
1761 | if (mObjectPartition[i] && hasRenderType(mObjectPartition[i]->mDrawableType)) | ||
1762 | { | ||
1763 | mObjectPartition[i]->cull(camera); | ||
1764 | } | ||
1765 | } | ||
1866 | 1766 | ||
1867 | if (gSky.mVOSkyp.notNull() && gSky.mVOSkyp->mDrawable.notNull()) | 1767 | if (gSky.mVOSkyp.notNull() && gSky.mVOSkyp->mDrawable.notNull()) |
1868 | { | 1768 | { |
1869 | // Hack for sky - always visible. | 1769 | // Hack for sky - always visible. |
1870 | gSky.mVOSkyp->mDrawable->setVisible(*gCamera); | 1770 | if (hasRenderType(LLPipeline::RENDER_TYPE_SKY)) |
1871 | mVisibleList.push_back(gSky.mVOSkyp->mDrawable); | 1771 | { |
1872 | gSky.updateCull(); | 1772 | gSky.mVOSkyp->mDrawable->setVisible(camera); |
1873 | stop_glerror(); | 1773 | mVisibleList.push_back(gSky.mVOSkyp->mDrawable); |
1774 | gSky.updateCull(); | ||
1775 | stop_glerror(); | ||
1776 | } | ||
1874 | } | 1777 | } |
1875 | else | 1778 | else |
1876 | { | 1779 | { |
1877 | llinfos << "No sky drawable!" << llendl; | 1780 | llinfos << "No sky drawable!" << llendl; |
1878 | } | 1781 | } |
1879 | 1782 | ||
1880 | if (gSky.mVOGroundp.notNull() && gSky.mVOGroundp->mDrawable.notNull()) | 1783 | if (hasRenderType(LLPipeline::RENDER_TYPE_GROUND) && gSky.mVOGroundp.notNull() && gSky.mVOGroundp->mDrawable.notNull()) |
1881 | { | 1784 | { |
1882 | gSky.mVOGroundp->mDrawable->setVisible(*gCamera); | 1785 | gSky.mVOGroundp->mDrawable->setVisible(camera); |
1883 | mVisibleList.push_back(gSky.mVOGroundp->mDrawable); | 1786 | mVisibleList.push_back(gSky.mVOGroundp->mDrawable); |
1884 | } | 1787 | } |
1788 | } | ||
1885 | 1789 | ||
1886 | // add all HUD attachments | 1790 | void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera, BOOL active) |
1887 | LLVOAvatar* my_avatarp = gAgent.getAvatarObject(); | 1791 | { |
1888 | if (my_avatarp && my_avatarp->hasHUDAttachment()) | 1792 | if (group->getData().empty()) |
1793 | { | ||
1794 | return; | ||
1795 | } | ||
1796 | |||
1797 | if (!sSkipUpdate) | ||
1889 | { | 1798 | { |
1890 | for (LLViewerJointAttachment* attachmentp = my_avatarp->mAttachmentPoints.getFirstData(); | 1799 | group->updateDistance(camera); |
1891 | attachmentp; | ||
1892 | attachmentp = my_avatarp->mAttachmentPoints.getNextData()) | ||
1893 | { | ||
1894 | if (attachmentp->getIsHUDAttachment() && attachmentp->getObject(0)) | ||
1895 | { | ||
1896 | LLViewerObject* objectp = attachmentp->getObject(0); | ||
1897 | markVisible(objectp->mDrawable); | ||
1898 | objectp->mDrawable->updateDistance(*gCamera); | ||
1899 | for (S32 i = 0; i < (S32)objectp->mChildList.size(); i++) | ||
1900 | { | ||
1901 | LLViewerObject* childp = objectp->mChildList[i]; | ||
1902 | if (childp->mDrawable.notNull()) | ||
1903 | { | ||
1904 | markVisible(childp->mDrawable); | ||
1905 | childp->mDrawable->updateDistance(*gCamera); | ||
1906 | } | ||
1907 | } | ||
1908 | } | ||
1909 | } | ||
1910 | } | 1800 | } |
1911 | } | 1801 | |
1802 | const F32 MINIMUM_PIXEL_AREA = 16.f; | ||
1912 | 1803 | ||
1913 | void LLPipeline::markNotCulled(LLDrawable* drawablep, LLCamera& camera) | 1804 | if (group->mPixelArea < MINIMUM_PIXEL_AREA) |
1914 | { | ||
1915 | if (drawablep->isVisible()) | ||
1916 | { | 1805 | { |
1917 | return; | 1806 | return; |
1918 | } | 1807 | } |
1919 | 1808 | ||
1920 | // Tricky render mode to hide selected objects, but we definitely | 1809 | group->mLastRenderTime = gFrameTimeSeconds; |
1921 | // don't want to do any unnecessary pointer dereferences. JC | 1810 | if (!group->mSpatialPartition->mRenderByGroup) |
1922 | if (gHideSelectedObjects) | 1811 | { //render by drawable |
1923 | { | 1812 | mDrawableGroups.push_back(group); |
1924 | if (drawablep->getVObj() && drawablep->getVObj()->isSelected()) | 1813 | for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i) |
1925 | { | 1814 | { |
1926 | return; | 1815 | markVisible(*i, camera); |
1927 | } | 1816 | } |
1928 | } | 1817 | } |
1929 | 1818 | else | |
1930 | if (drawablep && (hasRenderType(drawablep->mRenderType))) | 1819 | { //render by group |
1931 | { | 1820 | if (active) |
1932 | if (!drawablep->isState(LLDrawable::INVISIBLE|LLDrawable::FORCE_INVISIBLE)) | ||
1933 | { | 1821 | { |
1934 | mVisibleList.push_back(drawablep); | 1822 | mActiveGroups.push_back(group); |
1935 | drawablep->setVisible(camera, NULL, FALSE); | ||
1936 | } | 1823 | } |
1937 | else if (drawablep->isState(LLDrawable::CLEAR_INVISIBLE)) | 1824 | else |
1938 | { | 1825 | { |
1939 | // clear invisible flag here to avoid single frame glitch | 1826 | mVisibleGroups.push_back(group); |
1940 | drawablep->clearState(LLDrawable::FORCE_INVISIBLE|LLDrawable::CLEAR_INVISIBLE); | 1827 | for (LLSpatialGroup::bridge_list_t::iterator i = group->mBridgeList.begin(); i != group->mBridgeList.end(); ++i) |
1828 | { | ||
1829 | LLSpatialBridge* bridge = *i; | ||
1830 | markVisible(bridge, camera); | ||
1831 | } | ||
1941 | } | 1832 | } |
1942 | } | 1833 | } |
1943 | } | 1834 | } |
1944 | 1835 | ||
1945 | void LLPipeline::doOcclusion() | 1836 | void LLPipeline::doOcclusion(LLCamera& camera) |
1946 | { | 1837 | { |
1947 | if (gSavedSettings.getBOOL("UseOcclusion") && gGLManager.mHasOcclusionQuery) | 1838 | if (sUseOcclusion) |
1948 | { | 1839 | { |
1949 | mObjectPartition->doOcclusion(gCamera); | 1840 | for (U32 i = 0; i < mObjectPartition.size(); i++) |
1841 | { | ||
1842 | if (mObjectPartition[i] && hasRenderType(mObjectPartition[i]->mDrawableType)) | ||
1843 | { | ||
1844 | mObjectPartition[i]->doOcclusion(&camera); | ||
1845 | } | ||
1846 | } | ||
1847 | |||
1848 | #if AGGRESSIVE_OCCLUSION | ||
1849 | for (LLSpatialBridge::bridge_vector_t::iterator i = mVisibleBridge.begin(); i != mVisibleBridge.end(); ++i) | ||
1850 | { | ||
1851 | LLSpatialBridge* bridge = *i; | ||
1852 | if (!bridge->isDead() && hasRenderType(bridge->mDrawableType)) | ||
1853 | { | ||
1854 | glPushMatrix(); | ||
1855 | glMultMatrixf((F32*)bridge->mDrawable->getRenderMatrix().mMatrix); | ||
1856 | LLCamera trans = bridge->transformCamera(camera); | ||
1857 | bridge->doOcclusion(&trans); | ||
1858 | glPopMatrix(); | ||
1859 | mOccludedBridge.push_back(bridge); | ||
1860 | } | ||
1861 | } | ||
1862 | #endif | ||
1950 | } | 1863 | } |
1951 | } | 1864 | } |
1952 | 1865 | ||
1953 | |||
1954 | BOOL LLPipeline::updateDrawableGeom(LLDrawable* drawablep, BOOL priority) | 1866 | BOOL LLPipeline::updateDrawableGeom(LLDrawable* drawablep, BOOL priority) |
1955 | { | 1867 | { |
1956 | BOOL update_complete = drawablep->updateGeometry(priority); | 1868 | BOOL update_complete = drawablep->updateGeometry(priority); |
@@ -1975,19 +1887,31 @@ void LLPipeline::updateGeom(F32 max_dtime) | |||
1975 | LLVOVolume::preUpdateGeom(); | 1887 | LLVOVolume::preUpdateGeom(); |
1976 | 1888 | ||
1977 | // Iterate through all drawables on the priority build queue, | 1889 | // Iterate through all drawables on the priority build queue, |
1978 | for (LLDrawable::drawable_set_t::iterator iter = mBuildQ1.begin(); | 1890 | for (LLDrawable::drawable_list_t::iterator iter = mBuildQ1.begin(); |
1979 | iter != mBuildQ1.end();) | 1891 | iter != mBuildQ1.end();) |
1980 | { | 1892 | { |
1981 | LLDrawable::drawable_set_t::iterator curiter = iter++; | 1893 | LLDrawable::drawable_list_t::iterator curiter = iter++; |
1982 | LLDrawable* drawablep = *curiter; | 1894 | LLDrawable* drawablep = *curiter; |
1983 | BOOL update_complete = TRUE; | ||
1984 | if (drawablep && !drawablep->isDead()) | 1895 | if (drawablep && !drawablep->isDead()) |
1985 | { | 1896 | { |
1986 | update_complete = updateDrawableGeom(drawablep, TRUE); | 1897 | if (drawablep->isState(LLDrawable::IN_REBUILD_Q2)) |
1898 | { | ||
1899 | drawablep->clearState(LLDrawable::IN_REBUILD_Q2); | ||
1900 | LLDrawable::drawable_list_t::iterator find = std::find(mBuildQ2.begin(), mBuildQ2.end(), drawablep); | ||
1901 | if (find != mBuildQ2.end()) | ||
1902 | { | ||
1903 | mBuildQ2.erase(find); | ||
1904 | } | ||
1905 | } | ||
1906 | |||
1907 | if (updateDrawableGeom(drawablep, TRUE)) | ||
1908 | { | ||
1909 | drawablep->clearState(LLDrawable::IN_REBUILD_Q1); | ||
1910 | mBuildQ1.erase(curiter); | ||
1911 | } | ||
1987 | } | 1912 | } |
1988 | if (update_complete) | 1913 | else |
1989 | { | 1914 | { |
1990 | drawablep->clearState(LLDrawable::IN_REBUILD_Q1); | ||
1991 | mBuildQ1.erase(curiter); | 1915 | mBuildQ1.erase(curiter); |
1992 | } | 1916 | } |
1993 | } | 1917 | } |
@@ -1998,20 +1922,34 @@ void LLPipeline::updateGeom(F32 max_dtime) | |||
1998 | { | 1922 | { |
1999 | min_count = mBuildQ2.size(); | 1923 | min_count = mBuildQ2.size(); |
2000 | } | 1924 | } |
2001 | else | 1925 | |
2002 | { | ||
2003 | mBuildQ2.sort(LLDrawable::CompareDistanceGreaterVisibleFirst()); | ||
2004 | } | ||
2005 | |||
2006 | S32 count = 0; | 1926 | S32 count = 0; |
2007 | 1927 | ||
2008 | max_dtime = llmax(update_timer.getElapsedTimeF32()+0.001f, max_dtime); | 1928 | max_dtime = llmax(update_timer.getElapsedTimeF32()+0.001f, max_dtime); |
2009 | 1929 | LLSpatialGroup* last_group = NULL; | |
1930 | LLSpatialBridge* last_bridge = NULL; | ||
1931 | |||
2010 | for (LLDrawable::drawable_list_t::iterator iter = mBuildQ2.begin(); | 1932 | for (LLDrawable::drawable_list_t::iterator iter = mBuildQ2.begin(); |
2011 | iter != mBuildQ2.end(); ) | 1933 | iter != mBuildQ2.end(); ) |
2012 | { | 1934 | { |
2013 | LLDrawable::drawable_list_t::iterator curiter = iter++; | 1935 | LLDrawable::drawable_list_t::iterator curiter = iter++; |
2014 | LLDrawable* drawablep = *curiter; | 1936 | LLDrawable* drawablep = *curiter; |
1937 | |||
1938 | LLSpatialBridge* bridge = drawablep->isRoot() ? drawablep->getSpatialBridge() : | ||
1939 | drawablep->getParent()->getSpatialBridge(); | ||
1940 | |||
1941 | if (drawablep->getSpatialGroup() != last_group && | ||
1942 | (!last_bridge || bridge != last_bridge) && | ||
1943 | (update_timer.getElapsedTimeF32() >= max_dtime) && count > min_count) | ||
1944 | { | ||
1945 | break; | ||
1946 | } | ||
1947 | |||
1948 | //make sure updates don't stop in the middle of a spatial group | ||
1949 | //to avoid thrashing (objects are enqueued by group) | ||
1950 | last_group = drawablep->getSpatialGroup(); | ||
1951 | last_bridge = bridge; | ||
1952 | |||
2015 | BOOL update_complete = TRUE; | 1953 | BOOL update_complete = TRUE; |
2016 | if (drawablep && !drawablep->isDead()) | 1954 | if (drawablep && !drawablep->isDead()) |
2017 | { | 1955 | { |
@@ -2023,14 +1961,12 @@ void LLPipeline::updateGeom(F32 max_dtime) | |||
2023 | drawablep->clearState(LLDrawable::IN_REBUILD_Q2); | 1961 | drawablep->clearState(LLDrawable::IN_REBUILD_Q2); |
2024 | mBuildQ2.erase(curiter); | 1962 | mBuildQ2.erase(curiter); |
2025 | } | 1963 | } |
2026 | if ((update_timer.getElapsedTimeF32() >= max_dtime) && count > min_count) | 1964 | } |
2027 | { | 1965 | |
2028 | break; | 1966 | updateMovedList(mMovedBridge); |
2029 | } | ||
2030 | } | ||
2031 | } | 1967 | } |
2032 | 1968 | ||
2033 | void LLPipeline::markVisible(LLDrawable *drawablep) | 1969 | void LLPipeline::markVisible(LLDrawable *drawablep, LLCamera& camera) |
2034 | { | 1970 | { |
2035 | LLMemType mt(LLMemType::MTYPE_PIPELINE); | 1971 | LLMemType mt(LLMemType::MTYPE_PIPELINE); |
2036 | if(!drawablep || drawablep->isDead()) | 1972 | if(!drawablep || drawablep->isDead()) |
@@ -2038,11 +1974,36 @@ void LLPipeline::markVisible(LLDrawable *drawablep) | |||
2038 | llwarns << "LLPipeline::markVisible called with NULL drawablep" << llendl; | 1974 | llwarns << "LLPipeline::markVisible called with NULL drawablep" << llendl; |
2039 | return; | 1975 | return; |
2040 | } | 1976 | } |
2041 | if (!drawablep->isVisible()) | 1977 | |
1978 | |||
1979 | #if LL_DEBUG | ||
1980 | if (drawablep->isSpatialBridge()) | ||
1981 | { | ||
1982 | if (std::find(mVisibleBridge.begin(), mVisibleBridge.end(), (LLSpatialBridge*) drawablep) != | ||
1983 | mVisibleBridge.end()) | ||
1984 | { | ||
1985 | llerrs << "Spatial bridge marked visible redundantly." << llendl; | ||
1986 | } | ||
1987 | } | ||
1988 | else | ||
1989 | { | ||
1990 | if (std::find(mVisibleList.begin(), mVisibleList.end(), drawablep) != | ||
1991 | mVisibleList.end()) | ||
1992 | { | ||
1993 | llerrs << "Drawable marked visible redundantly." << llendl; | ||
1994 | } | ||
1995 | } | ||
1996 | #endif | ||
1997 | |||
1998 | if (drawablep->isSpatialBridge()) | ||
1999 | { | ||
2000 | mVisibleBridge.push_back((LLSpatialBridge*) drawablep); | ||
2001 | } | ||
2002 | else | ||
2042 | { | 2003 | { |
2043 | drawablep->setVisible(*gCamera); | ||
2044 | mVisibleList.push_back(drawablep); | 2004 | mVisibleList.push_back(drawablep); |
2045 | } | 2005 | } |
2006 | drawablep->setVisible(camera); | ||
2046 | } | 2007 | } |
2047 | 2008 | ||
2048 | void LLPipeline::markMoved(LLDrawable *drawablep, BOOL damped_motion) | 2009 | void LLPipeline::markMoved(LLDrawable *drawablep, BOOL damped_motion) |
@@ -2066,10 +2027,17 @@ void LLPipeline::markMoved(LLDrawable *drawablep, BOOL damped_motion) | |||
2066 | markMoved(drawablep->getParent(), damped_motion); | 2027 | markMoved(drawablep->getParent(), damped_motion); |
2067 | } | 2028 | } |
2068 | 2029 | ||
2069 | 2030 | ||
2070 | if (!drawablep->isState(LLDrawable::ON_MOVE_LIST)) | 2031 | if (!drawablep->isState(LLDrawable::ON_MOVE_LIST)) |
2071 | { | 2032 | { |
2072 | mMovedList.insert(drawablep); | 2033 | if (drawablep->isSpatialBridge()) |
2034 | { | ||
2035 | mMovedBridge.push_back(drawablep); | ||
2036 | } | ||
2037 | else | ||
2038 | { | ||
2039 | mMovedList.push_back(drawablep); | ||
2040 | } | ||
2073 | drawablep->setState(LLDrawable::ON_MOVE_LIST); | 2041 | drawablep->setState(LLDrawable::ON_MOVE_LIST); |
2074 | } | 2042 | } |
2075 | if (damped_motion == FALSE) | 2043 | if (damped_motion == FALSE) |
@@ -2118,30 +2086,28 @@ void LLPipeline::shiftObjects(const LLVector3 &offset) | |||
2118 | } | 2086 | } |
2119 | mShiftList.resize(0); | 2087 | mShiftList.resize(0); |
2120 | 2088 | ||
2121 | mObjectPartition->shift(offset); | 2089 | for (U32 i = 0; i < mObjectPartition.size()-1; i++) |
2122 | } | ||
2123 | |||
2124 | void LLPipeline::markTextured(LLDrawable *drawablep) | ||
2125 | { | ||
2126 | LLMemType mt(LLMemType::MTYPE_PIPELINE); | ||
2127 | if (!drawablep->isDead()) | ||
2128 | { | 2090 | { |
2129 | mRetexturedList.insert(drawablep); | 2091 | if (mObjectPartition[i]) |
2092 | { | ||
2093 | mObjectPartition[i]->shift(offset); | ||
2094 | } | ||
2130 | } | 2095 | } |
2131 | } | 2096 | } |
2132 | 2097 | ||
2133 | void LLPipeline::markMaterialed(LLDrawable *drawablep) | 2098 | void LLPipeline::markTextured(LLDrawable *drawablep) |
2134 | { | 2099 | { |
2135 | LLMemType mt(LLMemType::MTYPE_PIPELINE); | 2100 | LLMemType mt(LLMemType::MTYPE_PIPELINE); |
2136 | if (!drawablep->isDead()) | 2101 | if (drawablep && !drawablep->isDead()) |
2137 | { | 2102 | { |
2138 | mRematerialedList.insert(drawablep); | 2103 | mRetexturedList.insert(drawablep); |
2139 | } | 2104 | } |
2140 | } | 2105 | } |
2141 | 2106 | ||
2142 | void LLPipeline::markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags flag, BOOL priority) | 2107 | void LLPipeline::markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags flag, BOOL priority) |
2143 | { | 2108 | { |
2144 | LLMemType mt(LLMemType::MTYPE_PIPELINE); | 2109 | LLMemType mt(LLMemType::MTYPE_PIPELINE); |
2110 | |||
2145 | if (drawablep && !drawablep->isDead()) | 2111 | if (drawablep && !drawablep->isDead()) |
2146 | { | 2112 | { |
2147 | if (!drawablep->isState(LLDrawable::BUILT)) | 2113 | if (!drawablep->isState(LLDrawable::BUILT)) |
@@ -2150,15 +2116,18 @@ void LLPipeline::markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags f | |||
2150 | } | 2116 | } |
2151 | if (priority) | 2117 | if (priority) |
2152 | { | 2118 | { |
2153 | mBuildQ1.insert(drawablep); | 2119 | if (!drawablep->isState(LLDrawable::IN_REBUILD_Q1)) |
2154 | drawablep->setState(LLDrawable::IN_REBUILD_Q1); // flag is not needed, just for debugging | 2120 | { |
2121 | mBuildQ1.push_back(drawablep); | ||
2122 | drawablep->setState(LLDrawable::IN_REBUILD_Q1); // mark drawable as being in priority queue | ||
2123 | } | ||
2155 | } | 2124 | } |
2156 | else if (!drawablep->isState(LLDrawable::IN_REBUILD_Q2)) | 2125 | else if (!drawablep->isState(LLDrawable::IN_REBUILD_Q2)) |
2157 | { | 2126 | { |
2158 | mBuildQ2.push_back(drawablep); | 2127 | mBuildQ2.push_back(drawablep); |
2159 | drawablep->setState(LLDrawable::IN_REBUILD_Q2); // need flag here because it is just a list | 2128 | drawablep->setState(LLDrawable::IN_REBUILD_Q2); // need flag here because it is just a list |
2160 | } | 2129 | } |
2161 | if (flag & LLDrawable::REBUILD_VOLUME) | 2130 | if (flag & (LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION)) |
2162 | { | 2131 | { |
2163 | drawablep->getVObj()->setChanged(LLXform::SILHOUETTE); | 2132 | drawablep->getVObj()->setChanged(LLXform::SILHOUETTE); |
2164 | } | 2133 | } |
@@ -2185,111 +2154,400 @@ void LLPipeline::markRelight(LLDrawable *drawablep, const BOOL priority) | |||
2185 | } | 2154 | } |
2186 | } | 2155 | } |
2187 | 2156 | ||
2188 | void LLPipeline::stateSort() | 2157 | void LLPipeline::stateSort(LLCamera& camera) |
2189 | { | 2158 | { |
2190 | LLFastTimer ftm(LLFastTimer::FTM_STATESORT); | 2159 | LLFastTimer ftm(LLFastTimer::FTM_STATESORT); |
2191 | LLMemType mt(LLMemType::MTYPE_PIPELINE); | 2160 | LLMemType mt(LLMemType::MTYPE_PIPELINE); |
2192 | 2161 | ||
2162 | for (LLSpatialGroup::sg_vector_t::iterator iter = mVisibleGroups.begin(); iter != mVisibleGroups.end(); ++iter) | ||
2163 | { | ||
2164 | stateSort(*iter, camera); | ||
2165 | } | ||
2166 | |||
2167 | for (LLSpatialBridge::bridge_vector_t::iterator i = mVisibleBridge.begin(); i != mVisibleBridge.end(); ++i) | ||
2168 | { | ||
2169 | LLSpatialBridge* bridge = *i; | ||
2170 | if (!bridge->isDead()) | ||
2171 | { | ||
2172 | stateSort(bridge, camera); | ||
2173 | } | ||
2174 | } | ||
2175 | |||
2193 | for (LLDrawable::drawable_vector_t::iterator iter = mVisibleList.begin(); | 2176 | for (LLDrawable::drawable_vector_t::iterator iter = mVisibleList.begin(); |
2194 | iter != mVisibleList.end(); iter++) | 2177 | iter != mVisibleList.end(); iter++) |
2195 | { | 2178 | { |
2196 | LLDrawable *drawablep = *iter; | 2179 | LLDrawable *drawablep = *iter; |
2197 | if (drawablep->isDead()) | 2180 | if (!drawablep->isDead()) |
2198 | { | 2181 | { |
2199 | continue; | 2182 | stateSort(drawablep, camera); |
2200 | } | 2183 | } |
2184 | } | ||
2185 | |||
2186 | for (LLSpatialGroup::sg_vector_t::iterator iter = mActiveGroups.begin(); iter != mActiveGroups.end(); ++iter) | ||
2187 | { | ||
2188 | stateSort(*iter, camera); | ||
2189 | } | ||
2190 | |||
2191 | postSort(camera); | ||
2192 | } | ||
2201 | 2193 | ||
2202 | if (!drawablep->isActive()) | 2194 | void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera) |
2195 | { | ||
2196 | LLMemType mt(LLMemType::MTYPE_PIPELINE); | ||
2197 | if (!sSkipUpdate && group->changeLOD()) | ||
2198 | { | ||
2199 | for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i) | ||
2203 | { | 2200 | { |
2204 | drawablep->updateDistance(*gCamera); | 2201 | LLDrawable* drawablep = *i; |
2202 | stateSort(drawablep, camera); | ||
2205 | } | 2203 | } |
2204 | } | ||
2205 | |||
2206 | #if !LL_DARWIN | ||
2207 | if (gFrameTimeSeconds - group->mLastUpdateTime > 4.f) | ||
2208 | { | ||
2209 | group->makeStatic(); | ||
2210 | } | ||
2211 | #endif | ||
2212 | } | ||
2206 | 2213 | ||
2207 | /* | 2214 | void LLPipeline::stateSort(LLSpatialBridge* bridge, LLCamera& camera) |
2208 | if (!drawablep->isState(LLDrawable::BUILT)) | 2215 | { |
2216 | LLMemType mt(LLMemType::MTYPE_PIPELINE); | ||
2217 | if (!sSkipUpdate) | ||
2218 | { | ||
2219 | bridge->updateDistance(camera); | ||
2220 | } | ||
2221 | } | ||
2222 | |||
2223 | void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera) | ||
2224 | { | ||
2225 | LLMemType mt(LLMemType::MTYPE_PIPELINE); | ||
2226 | LLFastTimer ftm(LLFastTimer::FTM_STATESORT_DRAWABLE); | ||
2227 | |||
2228 | if (drawablep->isDead() || !hasRenderType(drawablep->getRenderType())) | ||
2229 | { | ||
2230 | return; | ||
2231 | } | ||
2232 | |||
2233 | if (gHideSelectedObjects) | ||
2234 | { | ||
2235 | if (drawablep->getVObj() && | ||
2236 | drawablep->getVObj()->isSelected()) | ||
2209 | { | 2237 | { |
2210 | // This geometry hasn't been rebuilt but it's visible, make sure it gets put on the rebuild list. | 2238 | return; |
2211 | llerrs << "Visible object " << drawablep << ":" << drawablep->getVObj()->getPCodeString(); | 2239 | } |
2212 | llcont << " visible but not built, put on rebuild" << llendl; | 2240 | } |
2213 | markRebuild(drawablep); | 2241 | |
2214 | continue; | 2242 | if (drawablep && (hasRenderType(drawablep->mRenderType))) |
2243 | { | ||
2244 | if (!drawablep->isState(LLDrawable::INVISIBLE|LLDrawable::FORCE_INVISIBLE)) | ||
2245 | { | ||
2246 | drawablep->setVisible(camera, NULL, FALSE); | ||
2215 | } | 2247 | } |
2216 | */ | 2248 | else if (drawablep->isState(LLDrawable::CLEAR_INVISIBLE)) |
2249 | { | ||
2250 | // clear invisible flag here to avoid single frame glitch | ||
2251 | drawablep->clearState(LLDrawable::FORCE_INVISIBLE|LLDrawable::CLEAR_INVISIBLE); | ||
2252 | } | ||
2253 | } | ||
2217 | 2254 | ||
2218 | for (LLDrawable::face_list_t::iterator iter = drawablep->mFaces.begin(); | 2255 | if (!drawablep->isActive() && drawablep->isVisible()) |
2219 | iter != drawablep->mFaces.end(); iter++) | 2256 | { |
2257 | if (!sSkipUpdate) | ||
2220 | { | 2258 | { |
2221 | LLFace* facep = *iter; | 2259 | drawablep->updateDistance(camera); |
2222 | if (facep->hasGeometry()) | 2260 | } |
2261 | } | ||
2262 | else if (drawablep->isAvatar() && drawablep->isVisible()) | ||
2263 | { | ||
2264 | LLVOAvatar* vobj = (LLVOAvatar*) drawablep->getVObj(); | ||
2265 | vobj->updateVisibility(FALSE); | ||
2266 | } | ||
2267 | |||
2268 | for (LLDrawable::face_list_t::iterator iter = drawablep->mFaces.begin(); | ||
2269 | iter != drawablep->mFaces.end(); iter++) | ||
2270 | { | ||
2271 | LLFace* facep = *iter; | ||
2272 | |||
2273 | if (facep->hasGeometry()) | ||
2274 | { | ||
2275 | if (facep->getPool()) | ||
2223 | { | 2276 | { |
2224 | facep->getPool()->enqueue(facep); | 2277 | facep->getPool()->enqueue(facep); |
2225 | } | 2278 | } |
2279 | else | ||
2280 | { | ||
2281 | break; | ||
2282 | } | ||
2226 | } | 2283 | } |
2227 | 2284 | } | |
2228 | if (sRenderPhysicalBeacons) | 2285 | |
2229 | { | 2286 | |
2230 | // Only show the beacon on the root object. | 2287 | mNumVisibleFaces += drawablep->getNumFaces(); |
2231 | LLViewerObject *vobj = drawablep->getVObj(); | 2288 | } |
2232 | if (vobj | 2289 | |
2233 | && !vobj->isAvatar() | 2290 | |
2234 | && !vobj->getParent() | 2291 | void LLPipeline::forAllDrawables(LLSpatialGroup::sg_vector_t& groups, void (*func)(LLDrawable*)) |
2235 | && vobj->usePhysics()) | 2292 | { |
2293 | for (LLSpatialGroup::sg_vector_t::iterator i = groups.begin(); i != groups.end(); ++i) | ||
2294 | { | ||
2295 | for (LLSpatialGroup::element_iter j = (*i)->getData().begin(); j != (*i)->getData().end(); ++j) | ||
2296 | { | ||
2297 | func(*j); | ||
2298 | } | ||
2299 | } | ||
2300 | } | ||
2301 | |||
2302 | void LLPipeline::forAllVisibleDrawables(void (*func)(LLDrawable*)) | ||
2303 | { | ||
2304 | forAllDrawables(mDrawableGroups, func); | ||
2305 | forAllDrawables(mVisibleGroups, func); | ||
2306 | forAllDrawables(mActiveGroups, func); | ||
2307 | } | ||
2308 | |||
2309 | //function for creating scripted beacons | ||
2310 | void renderScriptedBeacons(LLDrawable* drawablep) | ||
2311 | { | ||
2312 | LLViewerObject *vobj = drawablep->getVObj(); | ||
2313 | if (vobj | ||
2314 | && !vobj->isAvatar() | ||
2315 | && !vobj->getParent() | ||
2316 | && vobj->flagScripted()) | ||
2317 | { | ||
2318 | gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(1.f, 0.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f)); | ||
2319 | } | ||
2320 | } | ||
2321 | |||
2322 | void renderPhysicalBeacons(LLDrawable* drawablep) | ||
2323 | { | ||
2324 | LLViewerObject *vobj = drawablep->getVObj(); | ||
2325 | if (vobj | ||
2326 | && !vobj->isAvatar() | ||
2327 | && !vobj->getParent() | ||
2328 | && vobj->usePhysics()) | ||
2329 | { | ||
2330 | gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(0.f, 1.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f)); | ||
2331 | } | ||
2332 | } | ||
2333 | |||
2334 | void renderParticleBeacons(LLDrawable* drawablep) | ||
2335 | { | ||
2336 | // Look for attachments, objects, etc. | ||
2337 | LLViewerObject *vobj = drawablep->getVObj(); | ||
2338 | if (vobj | ||
2339 | && vobj->isParticleSource()) | ||
2340 | { | ||
2341 | LLColor4 light_blue(0.5f, 0.5f, 1.f, 0.5f); | ||
2342 | gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", light_blue, LLColor4(1.f, 1.f, 1.f, 0.5f)); | ||
2343 | } | ||
2344 | } | ||
2345 | |||
2346 | void LLPipeline::highlightPhysical(LLDrawable* drawablep) | ||
2347 | { | ||
2348 | LLMemType mt(LLMemType::MTYPE_PIPELINE); | ||
2349 | LLViewerObject *vobj; | ||
2350 | vobj = drawablep->getVObj(); | ||
2351 | if (vobj && !vobj->isAvatar()) | ||
2352 | { | ||
2353 | if (!vobj->isAvatar() && | ||
2354 | (vobj->usePhysics() || vobj->flagHandleTouch())) | ||
2355 | { | ||
2356 | S32 face_id; | ||
2357 | for (face_id = 0; face_id < drawablep->getNumFaces(); face_id++) | ||
2236 | { | 2358 | { |
2237 | gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(0.f, 1.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f)); | 2359 | gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) ); |
2238 | } | 2360 | } |
2239 | } | 2361 | } |
2362 | } | ||
2363 | } | ||
2364 | |||
2365 | void LLPipeline::postSort(LLCamera& camera) | ||
2366 | { | ||
2367 | LLMemType mt(LLMemType::MTYPE_PIPELINE); | ||
2368 | LLFastTimer ftm(LLFastTimer::FTM_STATESORT_POSTSORT); | ||
2369 | //reset render data sets | ||
2370 | clearRenderMap(); | ||
2371 | mAlphaGroups.clear(); | ||
2372 | mAlphaGroupsPostWater.clear(); | ||
2373 | |||
2374 | if (!gSavedSettings.getBOOL("RenderRippleWater") && hasRenderType(LLDrawPool::POOL_ALPHA)) | ||
2375 | { //turn off clip plane for non-ripple water | ||
2376 | toggleRenderType(LLDrawPool::POOL_ALPHA); | ||
2377 | } | ||
2240 | 2378 | ||
2241 | if (sRenderScriptedBeacons) | 2379 | F32 water_height = gAgent.getRegion()->getWaterHeight(); |
2380 | BOOL above_water = gCamera->getOrigin().mV[2] > water_height ? TRUE : FALSE; | ||
2381 | |||
2382 | //prepare occlusion geometry | ||
2383 | if (sUseOcclusion) | ||
2384 | { | ||
2385 | for (U32 i = 0; i < mObjectPartition.size(); i++) | ||
2242 | { | 2386 | { |
2243 | // Only show the beacon on the root object. | 2387 | if (mObjectPartition[i] && hasRenderType(mObjectPartition[i]->mDrawableType)) |
2244 | LLViewerObject *vobj = drawablep->getVObj(); | ||
2245 | if (vobj | ||
2246 | && !vobj->isAvatar() | ||
2247 | && !vobj->getParent() | ||
2248 | && vobj->flagScripted()) | ||
2249 | { | 2388 | { |
2250 | gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(1.f, 0.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f)); | 2389 | mObjectPartition[i]->buildOcclusion(); |
2390 | } | ||
2391 | } | ||
2392 | |||
2393 | #if AGGRESSIVE_OCCLUSION | ||
2394 | for (LLSpatialBridge::bridge_vector_t::iterator i = mVisibleBridge.begin(); i != mVisibleBridge.end(); ++i) | ||
2395 | { | ||
2396 | LLSpatialBridge* bridge = *i; | ||
2397 | if (!bridge->isDead() && hasRenderType(bridge->mDrawableType)) | ||
2398 | { | ||
2399 | bridge->buildOcclusion(); | ||
2251 | } | 2400 | } |
2252 | } | 2401 | } |
2402 | #endif | ||
2403 | } | ||
2404 | |||
2405 | |||
2406 | if (!sSkipUpdate) | ||
2407 | { | ||
2408 | //rebuild drawable geometry | ||
2409 | for (LLSpatialGroup::sg_vector_t::iterator i = mDrawableGroups.begin(); i != mDrawableGroups.end(); ++i) | ||
2410 | { | ||
2411 | LLSpatialGroup* group = *i; | ||
2412 | group->rebuildGeom(); | ||
2413 | } | ||
2414 | } | ||
2253 | 2415 | ||
2254 | if (sRenderParticleBeacons) | 2416 | //build render map |
2417 | for (LLSpatialGroup::sg_vector_t::iterator i = mVisibleGroups.begin(); i != mVisibleGroups.end(); ++i) | ||
2418 | { | ||
2419 | LLSpatialGroup* group = *i; | ||
2420 | if (!sSkipUpdate) | ||
2421 | { | ||
2422 | group->rebuildGeom(); | ||
2423 | } | ||
2424 | for (LLSpatialGroup::draw_map_t::iterator j = group->mDrawMap.begin(); j != group->mDrawMap.end(); ++j) | ||
2255 | { | 2425 | { |
2256 | // Look for attachments, objects, etc. | 2426 | std::vector<LLDrawInfo*>& src_vec = j->second; |
2257 | LLViewerObject *vobj = drawablep->getVObj(); | 2427 | std::vector<LLDrawInfo*>& dest_vec = mRenderMap[j->first]; |
2258 | if (vobj | 2428 | |
2259 | && vobj->isParticleSource()) | 2429 | for (std::vector<LLDrawInfo*>::iterator k = src_vec.begin(); k != src_vec.end(); ++k) |
2260 | { | 2430 | { |
2261 | LLColor4 light_blue(0.5f, 0.5f, 1.f, 0.5f); | 2431 | dest_vec.push_back(*k); |
2262 | gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", light_blue, LLColor4(1.f, 1.f, 1.f, 0.5f)); | ||
2263 | } | 2432 | } |
2264 | } | 2433 | } |
2434 | |||
2435 | LLSpatialGroup::draw_map_t::iterator alpha = group->mDrawMap.find(LLRenderPass::PASS_ALPHA); | ||
2436 | |||
2437 | if (alpha != group->mDrawMap.end()) | ||
2438 | { //store alpha groups for sorting | ||
2439 | if (!sSkipUpdate) | ||
2440 | { | ||
2441 | group->updateDistance(camera); | ||
2442 | } | ||
2443 | |||
2444 | if (hasRenderType(LLDrawPool::POOL_ALPHA)) | ||
2445 | { | ||
2446 | BOOL above = group->mObjectBounds[0].mV[2] + group->mObjectBounds[1].mV[2] > water_height ? TRUE : FALSE; | ||
2447 | BOOL below = group->mObjectBounds[0].mV[2] - group->mObjectBounds[1].mV[2] < water_height ? TRUE : FALSE; | ||
2448 | |||
2449 | if (below == above_water || above == below) | ||
2450 | { | ||
2451 | mAlphaGroups.push_back(group); | ||
2452 | } | ||
2265 | 2453 | ||
2266 | // Draw physical objects in red. | 2454 | if (above == above_water || below == above) |
2267 | if (gHUDManager->getShowPhysical()) | 2455 | { |
2456 | mAlphaGroupsPostWater.push_back(group); | ||
2457 | } | ||
2458 | } | ||
2459 | else | ||
2460 | { | ||
2461 | mAlphaGroupsPostWater.push_back(group); | ||
2462 | } | ||
2463 | } | ||
2464 | } | ||
2465 | |||
2466 | //store active alpha groups | ||
2467 | for (LLSpatialGroup::sg_vector_t::iterator i = mActiveGroups.begin(); i != mActiveGroups.end(); ++i) | ||
2468 | { | ||
2469 | LLSpatialGroup* group = *i; | ||
2470 | if (!sSkipUpdate) | ||
2471 | { | ||
2472 | group->rebuildGeom(); | ||
2473 | } | ||
2474 | LLSpatialGroup::draw_map_t::iterator alpha = group->mDrawMap.find(LLRenderPass::PASS_ALPHA); | ||
2475 | |||
2476 | if (alpha != group->mDrawMap.end()) | ||
2268 | { | 2477 | { |
2269 | LLViewerObject *vobj; | 2478 | LLSpatialBridge* bridge = group->mSpatialPartition->asBridge(); |
2270 | vobj = drawablep->getVObj(); | 2479 | LLCamera trans_camera = bridge->transformCamera(camera); |
2271 | if (vobj && !vobj->isAvatar()) | 2480 | if (!sSkipUpdate) |
2272 | { | 2481 | { |
2273 | if (!vobj->isAvatar() && | 2482 | group->updateDistance(trans_camera); |
2274 | (vobj->usePhysics() || vobj->flagHandleTouch())) | 2483 | } |
2484 | |||
2485 | if (hasRenderType(LLDrawPool::POOL_ALPHA)) | ||
2486 | { | ||
2487 | LLSpatialGroup* bridge_group = bridge->getSpatialGroup(); | ||
2488 | BOOL above = bridge_group->mObjectBounds[0].mV[2] + bridge_group->mObjectBounds[1].mV[2] > water_height ? TRUE : FALSE; | ||
2489 | BOOL below = bridge_group->mObjectBounds[0].mV[2] - bridge_group->mObjectBounds[1].mV[2] < water_height ? TRUE : FALSE; | ||
2490 | |||
2491 | |||
2492 | if (below == above_water || above == below) | ||
2275 | { | 2493 | { |
2276 | if (!drawablep->isVisible()) | 2494 | mAlphaGroups.push_back(group); |
2277 | { | 2495 | } |
2278 | // Skip objects that aren't visible. | 2496 | |
2279 | continue; | 2497 | if (above == above_water || below == above) |
2280 | } | 2498 | { |
2281 | S32 face_id; | 2499 | mAlphaGroupsPostWater.push_back(group); |
2282 | for (face_id = 0; face_id < drawablep->getNumFaces(); face_id++) | ||
2283 | { | ||
2284 | mHighlightFaces.put(drawablep->getFace(face_id) ); | ||
2285 | } | ||
2286 | } | 2500 | } |
2287 | } | 2501 | } |
2502 | else | ||
2503 | { | ||
2504 | mAlphaGroupsPostWater.push_back(group); | ||
2505 | } | ||
2288 | } | 2506 | } |
2507 | } | ||
2289 | 2508 | ||
2290 | mNumVisibleFaces += drawablep->getNumFaces(); | 2509 | //sort by texture or bump map |
2510 | for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; ++i) | ||
2511 | { | ||
2512 | if (!mRenderMap[i].empty()) | ||
2513 | { | ||
2514 | if (i == LLRenderPass::PASS_BUMP) | ||
2515 | { | ||
2516 | std::sort(mRenderMap[i].begin(), mRenderMap[i].end(), LLDrawInfo::CompareBump()); | ||
2517 | } | ||
2518 | else | ||
2519 | { | ||
2520 | std::sort(mRenderMap[i].begin(), mRenderMap[i].end(), LLDrawInfo::CompareTexturePtr()); | ||
2521 | } | ||
2522 | } | ||
2291 | } | 2523 | } |
2292 | 2524 | ||
2525 | std::sort(mAlphaGroups.begin(), mAlphaGroups.end(), LLSpatialGroup::CompareDepthGreater()); | ||
2526 | std::sort(mAlphaGroupsPostWater.begin(), mAlphaGroupsPostWater.end(), LLSpatialGroup::CompareDepthGreater()); | ||
2527 | |||
2528 | if (sRenderScriptedBeacons) | ||
2529 | { | ||
2530 | // Only show the beacon on the root object. | ||
2531 | forAllVisibleDrawables(renderScriptedBeacons); | ||
2532 | } | ||
2533 | |||
2534 | if (sRenderPhysicalBeacons) | ||
2535 | { | ||
2536 | // Only show the beacon on the root object. | ||
2537 | forAllVisibleDrawables(renderPhysicalBeacons); | ||
2538 | } | ||
2539 | |||
2540 | if (sRenderParticleBeacons) | ||
2541 | { | ||
2542 | forAllVisibleDrawables(renderParticleBeacons); | ||
2543 | } | ||
2544 | |||
2545 | // Draw physical objects in red. | ||
2546 | if (gHUDManager->getShowPhysical()) | ||
2547 | { | ||
2548 | forAllVisibleDrawables(highlightPhysical); | ||
2549 | } | ||
2550 | |||
2293 | // If god mode, also show audio cues | 2551 | // If god mode, also show audio cues |
2294 | if (sRenderSoundBeacons && gAudiop) | 2552 | if (sRenderSoundBeacons && gAudiop) |
2295 | { | 2553 | { |
@@ -2312,66 +2570,19 @@ void LLPipeline::stateSort() | |||
2312 | LLFloaterTelehub::addBeacons(); | 2570 | LLFloaterTelehub::addBeacons(); |
2313 | } | 2571 | } |
2314 | 2572 | ||
2315 | mSelectedFaces.reset(); | 2573 | mSelectedFaces.clear(); |
2316 | 2574 | ||
2317 | // Draw face highlights for selected faces. | 2575 | // Draw face highlights for selected faces. |
2318 | if (gSelectMgr->getTEMode()) | 2576 | if (gSelectMgr->getTEMode()) |
2319 | { | 2577 | { |
2320 | LLViewerObject *vobjp; | 2578 | LLViewerObject *vobjp; |
2321 | S32 te; | 2579 | S32 te; |
2322 | gSelectMgr->getFirstTE(&vobjp,&te); | 2580 | gSelectMgr->getSelection()->getFirstTE(&vobjp,&te); |
2323 | 2581 | ||
2324 | while (vobjp) | 2582 | while (vobjp) |
2325 | { | 2583 | { |
2326 | LLDrawable *drawablep = vobjp->mDrawable; | 2584 | mSelectedFaces.push_back(vobjp->mDrawable->getFace(te)); |
2327 | if (!drawablep || drawablep->isDead() || (!vobjp->isHUDAttachment() && !drawablep->isVisible())) | 2585 | gSelectMgr->getSelection()->getNextTE(&vobjp,&te); |
2328 | { | ||
2329 | llwarns << "Dead drawable on selected face list!" << llendl; | ||
2330 | } | ||
2331 | else | ||
2332 | { | ||
2333 | LLVOVolume *volp = drawablep->getVOVolume(); | ||
2334 | if (volp) | ||
2335 | { | ||
2336 | if (volp->getAllTEsSame()) | ||
2337 | { | ||
2338 | SelectedFaceInfo* faceinfo = mSelectedFaces.reserve_block(1); | ||
2339 | faceinfo->mFacep = drawablep->getFace(vobjp->getFaceIndexOffset()); | ||
2340 | faceinfo->mTE = te; | ||
2341 | } | ||
2342 | else | ||
2343 | { | ||
2344 | // This is somewhat inefficient, but works correctly. | ||
2345 | S32 face_id; | ||
2346 | for (face_id = 0; face_id < vobjp->getVolume()->getNumFaces(); face_id++) | ||
2347 | { | ||
2348 | LLFace *facep = drawablep->getFace(face_id + vobjp->getFaceIndexOffset()); | ||
2349 | if (te == facep->getTEOffset()) | ||
2350 | { | ||
2351 | SelectedFaceInfo* faceinfo = mSelectedFaces.reserve_block(1); | ||
2352 | faceinfo->mFacep = facep; | ||
2353 | faceinfo->mTE = -1; | ||
2354 | } | ||
2355 | } | ||
2356 | } | ||
2357 | } | ||
2358 | else | ||
2359 | { | ||
2360 | // This is somewhat inefficient, but works correctly. | ||
2361 | S32 face_id; | ||
2362 | for (face_id = 0; face_id < drawablep->getNumFaces(); face_id++) | ||
2363 | { | ||
2364 | LLFace *facep = drawablep->getFace(face_id + vobjp->getFaceIndexOffset()); | ||
2365 | if (te == facep->getTEOffset()) | ||
2366 | { | ||
2367 | SelectedFaceInfo* faceinfo = mSelectedFaces.reserve_block(1); | ||
2368 | faceinfo->mFacep = facep; | ||
2369 | faceinfo->mTE = -1; | ||
2370 | } | ||
2371 | } | ||
2372 | } | ||
2373 | } | ||
2374 | gSelectMgr->getNextTE(&vobjp,&te); | ||
2375 | } | 2586 | } |
2376 | } | 2587 | } |
2377 | } | 2588 | } |
@@ -2383,13 +2594,13 @@ static void render_hud_elements() | |||
2383 | gPipeline.disableLights(); | 2594 | gPipeline.disableLights(); |
2384 | 2595 | ||
2385 | gPipeline.renderDebug(); | 2596 | gPipeline.renderDebug(); |
2386 | 2597 | ||
2387 | LLGLDisable fog(GL_FOG); | 2598 | LLGLDisable fog(GL_FOG); |
2388 | LLGLSUIDefault gls_ui; | 2599 | LLGLSUIDefault gls_ui; |
2389 | 2600 | ||
2390 | if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) | 2601 | if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) |
2391 | { | 2602 | { |
2392 | gViewerWindow->renderSelections(FALSE, FALSE, FALSE); // For HUD bersion in render_ui_3d() | 2603 | gViewerWindow->renderSelections(FALSE, FALSE, FALSE); // For HUD version in render_ui_3d() |
2393 | 2604 | ||
2394 | // Draw the tracking overlays | 2605 | // Draw the tracking overlays |
2395 | LLTracker::render3D(); | 2606 | LLTracker::render3D(); |
@@ -2404,7 +2615,7 @@ static void render_hud_elements() | |||
2404 | gParcelMgr->render(); | 2615 | gParcelMgr->render(); |
2405 | gParcelMgr->renderParcelCollision(); | 2616 | gParcelMgr->renderParcelCollision(); |
2406 | } | 2617 | } |
2407 | 2618 | ||
2408 | // Render debugging beacons. | 2619 | // Render debugging beacons. |
2409 | gObjectList.renderObjectBeacons(); | 2620 | gObjectList.renderObjectBeacons(); |
2410 | LLHUDObject::renderAll(); | 2621 | LLHUDObject::renderAll(); |
@@ -2415,11 +2626,15 @@ static void render_hud_elements() | |||
2415 | // This is only set when not rendering the UI, for parcel snapshots | 2626 | // This is only set when not rendering the UI, for parcel snapshots |
2416 | gParcelMgr->render(); | 2627 | gParcelMgr->render(); |
2417 | } | 2628 | } |
2418 | 2629 | else if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) | |
2630 | { | ||
2631 | LLHUDText::renderAllHUD(); | ||
2632 | } | ||
2419 | } | 2633 | } |
2420 | 2634 | ||
2421 | void LLPipeline::renderHighlights() | 2635 | void LLPipeline::renderHighlights() |
2422 | { | 2636 | { |
2637 | LLMemType mt(LLMemType::MTYPE_PIPELINE); | ||
2423 | // Draw 3D UI elements here (before we clear the Z buffer in POOL_HUD) | 2638 | // Draw 3D UI elements here (before we clear the Z buffer in POOL_HUD) |
2424 | // Render highlighted faces. | 2639 | // Render highlighted faces. |
2425 | LLColor4 color(1.f, 1.f, 1.f, 0.5f); | 2640 | LLColor4 color(1.f, 1.f, 1.f, 0.5f); |
@@ -2441,48 +2656,15 @@ void LLPipeline::renderHighlights() | |||
2441 | } | 2656 | } |
2442 | mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA); | 2657 | mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA); |
2443 | 2658 | ||
2444 | for (S32 i = 0; i < mSelectedFaces.count(); i++) | 2659 | for (U32 i = 0; i < mSelectedFaces.size(); i++) |
2445 | { | 2660 | { |
2446 | LLFace *facep = mSelectedFaces[i].mFacep; | 2661 | LLFace *facep = mSelectedFaces[i]; |
2447 | if (!facep || facep->getDrawable()->isDead()) | 2662 | if (!facep || facep->getDrawable()->isDead()) |
2448 | { | 2663 | { |
2449 | llerrs << "Bad face on selection" << llendl; | 2664 | llerrs << "Bad face on selection" << llendl; |
2450 | } | 2665 | } |
2451 | 2666 | ||
2452 | LLDrawPool* poolp = facep->getPool(); | 2667 | facep->renderSelected(mFaceSelectImagep, color); |
2453 | |||
2454 | if (!poolp->canUseAGP()) | ||
2455 | { | ||
2456 | unbindAGP(); | ||
2457 | } | ||
2458 | else if (usingAGP()) | ||
2459 | { | ||
2460 | bindAGP(); | ||
2461 | } | ||
2462 | |||
2463 | if (mSelectedFaces[i].mTE == -1) | ||
2464 | { | ||
2465 | // Yes, I KNOW this is stupid... | ||
2466 | poolp->renderFaceSelected(facep, mFaceSelectImagep, color); | ||
2467 | } | ||
2468 | else | ||
2469 | { | ||
2470 | LLVOVolume *volp = (LLVOVolume *)facep->getViewerObject(); | ||
2471 | // Do the special coalesced face mode. | ||
2472 | S32 j; | ||
2473 | S32 offset = 0; | ||
2474 | S32 count = volp->getVolume()->getVolumeFace(0).mIndices.size(); | ||
2475 | for (j = 0; j <= mSelectedFaces[i].mTE; j++) | ||
2476 | { | ||
2477 | count = volp->getVolume()->getVolumeFace(j).mIndices.size(); | ||
2478 | if (j < mSelectedFaces[i].mTE) | ||
2479 | { | ||
2480 | offset += count; | ||
2481 | } | ||
2482 | } | ||
2483 | |||
2484 | poolp->renderFaceSelected(facep, mFaceSelectImagep, color, offset, count); | ||
2485 | } | ||
2486 | } | 2668 | } |
2487 | } | 2669 | } |
2488 | 2670 | ||
@@ -2490,26 +2672,16 @@ void LLPipeline::renderHighlights() | |||
2490 | { | 2672 | { |
2491 | // Paint 'em red! | 2673 | // Paint 'em red! |
2492 | color.setVec(1.f, 0.f, 0.f, 0.5f); | 2674 | color.setVec(1.f, 0.f, 0.f, 0.5f); |
2493 | for (S32 i = 0; i < mHighlightFaces.count(); i++) | 2675 | for (U32 i = 0; i < mHighlightFaces.size(); i++) |
2494 | { | 2676 | { |
2495 | LLFace* facep = mHighlightFaces[i]; | 2677 | LLFace* facep = mHighlightFaces[i]; |
2496 | LLDrawPool* poolp = facep->getPool(); | 2678 | facep->renderSelected(LLViewerImage::sNullImagep, color); |
2497 | if (!poolp->canUseAGP()) | ||
2498 | { | ||
2499 | unbindAGP(); | ||
2500 | } | ||
2501 | else if (usingAGP()) | ||
2502 | { | ||
2503 | bindAGP(); | ||
2504 | } | ||
2505 | |||
2506 | poolp->renderFaceSelected(facep, LLViewerImage::sNullImagep, color); | ||
2507 | } | 2679 | } |
2508 | } | 2680 | } |
2509 | 2681 | ||
2510 | // Contains a list of the faces of objects that are physical or | 2682 | // Contains a list of the faces of objects that are physical or |
2511 | // have touch-handlers. | 2683 | // have touch-handlers. |
2512 | mHighlightFaces.reset(); | 2684 | mHighlightFaces.clear(); |
2513 | 2685 | ||
2514 | if (mVertexShaderLevel[SHADER_INTERFACE] > 0) | 2686 | if (mVertexShaderLevel[SHADER_INTERFACE] > 0) |
2515 | { | 2687 | { |
@@ -2517,11 +2689,11 @@ void LLPipeline::renderHighlights() | |||
2517 | } | 2689 | } |
2518 | } | 2690 | } |
2519 | 2691 | ||
2520 | void LLPipeline::renderGeom() | 2692 | void LLPipeline::renderGeom(LLCamera& camera) |
2521 | { | 2693 | { |
2522 | LLMemType mt(LLMemType::MTYPE_PIPELINE); | 2694 | LLMemType mt(LLMemType::MTYPE_PIPELINE); |
2523 | LLFastTimer t(LLFastTimer::FTM_RENDER_GEOMETRY); | 2695 | LLFastTimer t(LLFastTimer::FTM_RENDER_GEOMETRY); |
2524 | 2696 | ||
2525 | if (!mAlphaSizzleImagep) | 2697 | if (!mAlphaSizzleImagep) |
2526 | { | 2698 | { |
2527 | mAlphaSizzleImagep = gImageList.getImage(LLUUID(gViewerArt.getString("alpha_sizzle.tga")), MIPMAP_TRUE, TRUE); | 2699 | mAlphaSizzleImagep = gImageList.getImage(LLUUID(gViewerArt.getString("alpha_sizzle.tga")), MIPMAP_TRUE, TRUE); |
@@ -2533,6 +2705,8 @@ void LLPipeline::renderGeom() | |||
2533 | // | 2705 | // |
2534 | // | 2706 | // |
2535 | 2707 | ||
2708 | glEnableClientState(GL_VERTEX_ARRAY); | ||
2709 | |||
2536 | stop_glerror(); | 2710 | stop_glerror(); |
2537 | gFrameStats.start(LLFrameStats::RENDER_SYNC); | 2711 | gFrameStats.start(LLFrameStats::RENDER_SYNC); |
2538 | 2712 | ||
@@ -2540,6 +2714,7 @@ void LLPipeline::renderGeom() | |||
2540 | #ifndef LL_RELEASE_FOR_DOWNLOAD | 2714 | #ifndef LL_RELEASE_FOR_DOWNLOAD |
2541 | LLGLState::checkStates(); | 2715 | LLGLState::checkStates(); |
2542 | LLGLState::checkTextureChannels(); | 2716 | LLGLState::checkTextureChannels(); |
2717 | LLGLState::checkClientArrays(); | ||
2543 | #endif | 2718 | #endif |
2544 | if (mRenderDebugMask & RENDER_DEBUG_VERIFY) | 2719 | if (mRenderDebugMask & RENDER_DEBUG_VERIFY) |
2545 | { | 2720 | { |
@@ -2549,27 +2724,23 @@ void LLPipeline::renderGeom() | |||
2549 | } | 2724 | } |
2550 | } | 2725 | } |
2551 | 2726 | ||
2552 | if (mAGPMemPool) | ||
2553 | { | 2727 | { |
2554 | mAGPMemPool->waitFence(mGlobalFence); | 2728 | //LLFastTimer ftm(LLFastTimer::FTM_TEMP6); |
2729 | LLVertexBuffer::startRender(); | ||
2555 | } | 2730 | } |
2556 | 2731 | ||
2557 | unbindAGP(); | ||
2558 | for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) | 2732 | for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) |
2559 | { | 2733 | { |
2560 | LLDrawPool *poolp = *iter; | 2734 | LLDrawPool *poolp = *iter; |
2561 | if (hasRenderType(poolp->getType())) | 2735 | if (hasRenderType(poolp->getType())) |
2562 | { | 2736 | { |
2563 | poolp->prerender(); | 2737 | poolp->prerender(); |
2564 | poolp->syncAGP(); | ||
2565 | } | 2738 | } |
2566 | } | 2739 | } |
2567 | 2740 | ||
2568 | gFrameStats.start(LLFrameStats::RENDER_GEOM); | 2741 | gFrameStats.start(LLFrameStats::RENDER_GEOM); |
2569 | 2742 | ||
2570 | // Initialize lots of GL state to "safe" values | 2743 | // Initialize lots of GL state to "safe" values |
2571 | mTrianglesDrawn = 0; | ||
2572 | |||
2573 | glMatrixMode(GL_TEXTURE); | 2744 | glMatrixMode(GL_TEXTURE); |
2574 | glLoadIdentity(); | 2745 | glLoadIdentity(); |
2575 | glMatrixMode(GL_MODELVIEW); | 2746 | glMatrixMode(GL_MODELVIEW); |
@@ -2577,13 +2748,13 @@ void LLPipeline::renderGeom() | |||
2577 | LLGLSPipeline gls_pipeline; | 2748 | LLGLSPipeline gls_pipeline; |
2578 | 2749 | ||
2579 | LLGLState gls_color_material(GL_COLOR_MATERIAL, mLightingDetail < 2); | 2750 | LLGLState gls_color_material(GL_COLOR_MATERIAL, mLightingDetail < 2); |
2580 | LLGLState normalize(GL_NORMALIZE, TRUE); | 2751 | // LLGLState normalize(GL_NORMALIZE, TRUE); |
2581 | 2752 | ||
2582 | // Toggle backface culling for debugging | 2753 | // Toggle backface culling for debugging |
2583 | LLGLEnable cull_face(mBackfaceCull ? GL_CULL_FACE : 0); | 2754 | LLGLEnable cull_face(mBackfaceCull ? GL_CULL_FACE : 0); |
2584 | // Set fog | 2755 | // Set fog |
2585 | LLGLEnable fog_enable(hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FOG) ? GL_FOG : 0); | 2756 | LLGLEnable fog_enable(hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FOG) ? GL_FOG : 0); |
2586 | 2757 | gSky.updateFog(camera.getFar()); | |
2587 | 2758 | ||
2588 | LLViewerImage::sDefaultImagep->bind(0); | 2759 | LLViewerImage::sDefaultImagep->bind(0); |
2589 | LLViewerImage::sDefaultImagep->setClamp(FALSE, FALSE); | 2760 | LLViewerImage::sDefaultImagep->setClamp(FALSE, FALSE); |
@@ -2592,19 +2763,20 @@ void LLPipeline::renderGeom() | |||
2592 | // | 2763 | // |
2593 | // Actually render all of the geometry | 2764 | // Actually render all of the geometry |
2594 | // | 2765 | // |
2595 | // | 2766 | // |
2596 | |||
2597 | stop_glerror(); | 2767 | stop_glerror(); |
2598 | BOOL non_agp = FALSE; | ||
2599 | BOOL did_hud_elements = FALSE; | 2768 | BOOL did_hud_elements = FALSE; |
2600 | 2769 | BOOL occlude = sUseOcclusion; | |
2770 | |||
2601 | U32 cur_type = 0; | 2771 | U32 cur_type = 0; |
2602 | 2772 | ||
2603 | S32 skipped_vertices = 0; | 2773 | if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PICKING)) |
2774 | { | ||
2775 | gObjectList.renderObjectsForSelect(camera); | ||
2776 | } | ||
2777 | else | ||
2604 | { | 2778 | { |
2605 | LLFastTimer t(LLFastTimer::FTM_POOLS); | 2779 | LLFastTimer t(LLFastTimer::FTM_POOLS); |
2606 | BOOL occlude = TRUE; | ||
2607 | |||
2608 | calcNearbyLights(); | 2780 | calcNearbyLights(); |
2609 | 2781 | ||
2610 | pool_set_t::iterator iter1 = mPools.begin(); | 2782 | pool_set_t::iterator iter1 = mPools.begin(); |
@@ -2614,80 +2786,27 @@ void LLPipeline::renderGeom() | |||
2614 | 2786 | ||
2615 | cur_type = poolp->getType(); | 2787 | cur_type = poolp->getType(); |
2616 | 2788 | ||
2617 | if (cur_type >= LLDrawPool::POOL_TREE && occlude) | 2789 | if (occlude && cur_type > LLDrawPool::POOL_AVATAR) |
2618 | { //all the occluders have been drawn, do occlusion queries | 2790 | { |
2619 | if (mVertexShadersEnabled) | ||
2620 | { | ||
2621 | glUseProgramObjectARB(0); | ||
2622 | } | ||
2623 | doOcclusion(); | ||
2624 | occlude = FALSE; | 2791 | occlude = FALSE; |
2792 | doOcclusion(camera); | ||
2625 | } | 2793 | } |
2626 | 2794 | ||
2627 | if (cur_type >= LLDrawPool::POOL_HUD && !did_hud_elements) | 2795 | if (cur_type > LLDrawPool::POOL_ALPHA_POST_WATER && !did_hud_elements) |
2628 | { | 2796 | { |
2629 | renderHighlights(); | 2797 | renderHighlights(); |
2630 | // Draw 3D UI elements here (before we clear the Z buffer in POOL_HUD) | 2798 | // Draw 3D UI elements here (before we clear the Z buffer in POOL_HUD) |
2631 | if (mVertexShadersEnabled) | ||
2632 | { | ||
2633 | glUseProgramObjectARB(0); | ||
2634 | } | ||
2635 | render_hud_elements(); | 2799 | render_hud_elements(); |
2636 | did_hud_elements = TRUE; | 2800 | did_hud_elements = TRUE; |
2637 | } | 2801 | } |
2638 | 2802 | ||
2639 | pool_set_t::iterator iter2 = iter1; | 2803 | pool_set_t::iterator iter2 = iter1; |
2640 | if (hasRenderType(poolp->getType())) | 2804 | if (hasRenderType(poolp->getType()) && poolp->getNumPasses() > 0) |
2641 | { | 2805 | { |
2642 | LLFastTimer t(LLFastTimer::FTM_POOLRENDER); | 2806 | LLFastTimer t(LLFastTimer::FTM_POOLRENDER); |
2643 | 2807 | ||
2644 | setupHWLights(poolp); | 2808 | setupHWLights(poolp); |
2645 | 2809 | ||
2646 | if (mVertexShadersEnabled && poolp->getVertexShaderLevel() == 0) | ||
2647 | { | ||
2648 | glUseProgramObjectARB(0); | ||
2649 | } | ||
2650 | else if (mVertexShadersEnabled) | ||
2651 | { | ||
2652 | mMaterialIndex = mSpecularIndex = 0; | ||
2653 | switch(cur_type) | ||
2654 | { | ||
2655 | case LLDrawPool::POOL_SKY: | ||
2656 | case LLDrawPool::POOL_STARS: | ||
2657 | case LLDrawPool::POOL_CLOUDS: | ||
2658 | glUseProgramObjectARB(0); | ||
2659 | break; | ||
2660 | case LLDrawPool::POOL_TERRAIN: | ||
2661 | mTerrainProgram.bind(); | ||
2662 | break; | ||
2663 | case LLDrawPool::POOL_GROUND: | ||
2664 | mGroundProgram.bind(); | ||
2665 | break; | ||
2666 | case LLDrawPool::POOL_TREE: | ||
2667 | case LLDrawPool::POOL_TREE_NEW: | ||
2668 | case LLDrawPool::POOL_SIMPLE: | ||
2669 | case LLDrawPool::POOL_MEDIA: | ||
2670 | mObjectSimpleProgram.bind(); | ||
2671 | break; | ||
2672 | case LLDrawPool::POOL_BUMP: | ||
2673 | mObjectBumpProgram.bind(); | ||
2674 | break; | ||
2675 | case LLDrawPool::POOL_AVATAR: | ||
2676 | glUseProgramObjectARB(0); | ||
2677 | break; | ||
2678 | case LLDrawPool::POOL_WATER: | ||
2679 | glUseProgramObjectARB(0); | ||
2680 | break; | ||
2681 | case LLDrawPool::POOL_ALPHA: | ||
2682 | mObjectAlphaProgram.bind(); | ||
2683 | break; | ||
2684 | case LLDrawPool::POOL_HUD: | ||
2685 | default: | ||
2686 | glUseProgramObjectARB(0); | ||
2687 | break; | ||
2688 | } | ||
2689 | } | ||
2690 | |||
2691 | for( S32 i = 0; i < poolp->getNumPasses(); i++ ) | 2810 | for( S32 i = 0; i < poolp->getNumPasses(); i++ ) |
2692 | { | 2811 | { |
2693 | poolp->beginRenderPass(i); | 2812 | poolp->beginRenderPass(i); |
@@ -2698,33 +2817,19 @@ void LLPipeline::renderGeom() | |||
2698 | { | 2817 | { |
2699 | break; | 2818 | break; |
2700 | } | 2819 | } |
2701 | if (p->getType() != LLDrawPool::POOL_AVATAR | 2820 | |
2702 | && p->getType() != LLDrawPool::POOL_ALPHA | ||
2703 | && p->getType() != LLDrawPool::POOL_HUD | ||
2704 | && (!p->getIndexCount() || !p->getVertexCount())) | ||
2705 | { | ||
2706 | continue; | ||
2707 | } | ||
2708 | |||
2709 | if (p->canUseAGP() && usingAGP()) | ||
2710 | { | ||
2711 | bindAGP(); | ||
2712 | } | ||
2713 | else | ||
2714 | { | ||
2715 | //llinfos << "Rendering pool type " << p->getType() << " without AGP!" << llendl; | ||
2716 | unbindAGP(); | ||
2717 | non_agp = TRUE; | ||
2718 | } | ||
2719 | |||
2720 | p->resetTrianglesDrawn(); | 2821 | p->resetTrianglesDrawn(); |
2721 | p->render(i); | 2822 | p->render(i); |
2722 | mTrianglesDrawn += p->getTrianglesDrawn(); | 2823 | mTrianglesDrawn += p->getTrianglesDrawn(); |
2723 | skipped_vertices += p->mSkippedVertices; | ||
2724 | p->mSkippedVertices = 0; | ||
2725 | } | 2824 | } |
2726 | poolp->endRenderPass(i); | 2825 | poolp->endRenderPass(i); |
2727 | #ifndef LL_RELEASE_FOR_DOWNLOAD | 2826 | #ifndef LL_RELEASE_FOR_DOWNLOAD |
2827 | GLint depth; | ||
2828 | glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &depth); | ||
2829 | if (depth > 3) | ||
2830 | { | ||
2831 | llerrs << "GL matrix stack corrupted!" << llendl; | ||
2832 | } | ||
2728 | LLGLState::checkStates(); | 2833 | LLGLState::checkStates(); |
2729 | LLGLState::checkTextureChannels(); | 2834 | LLGLState::checkTextureChannels(); |
2730 | LLGLState::checkClientArrays(); | 2835 | LLGLState::checkClientArrays(); |
@@ -2746,21 +2851,18 @@ void LLPipeline::renderGeom() | |||
2746 | iter1 = iter2; | 2851 | iter1 = iter2; |
2747 | stop_glerror(); | 2852 | stop_glerror(); |
2748 | } | 2853 | } |
2749 | |||
2750 | if (occlude) | ||
2751 | { | ||
2752 | if (mVertexShadersEnabled) | ||
2753 | { | ||
2754 | glUseProgramObjectARB(0); | ||
2755 | } | ||
2756 | doOcclusion(); | ||
2757 | } | ||
2758 | } | 2854 | } |
2759 | stop_glerror(); | 2855 | |
2760 | 2856 | #ifndef LL_RELEASE_FOR_DOWNLOAD | |
2761 | if (mVertexShadersEnabled) | 2857 | LLGLState::checkStates(); |
2858 | LLGLState::checkTextureChannels(); | ||
2859 | LLGLState::checkClientArrays(); | ||
2860 | #endif | ||
2861 | |||
2862 | if (occlude) | ||
2762 | { | 2863 | { |
2763 | glUseProgramObjectARB(0); | 2864 | doOcclusion(camera); |
2865 | occlude = FALSE; | ||
2764 | } | 2866 | } |
2765 | 2867 | ||
2766 | if (!did_hud_elements) | 2868 | if (!did_hud_elements) |
@@ -2768,32 +2870,49 @@ void LLPipeline::renderGeom() | |||
2768 | renderHighlights(); | 2870 | renderHighlights(); |
2769 | render_hud_elements(); | 2871 | render_hud_elements(); |
2770 | } | 2872 | } |
2873 | |||
2874 | stop_glerror(); | ||
2771 | 2875 | ||
2772 | static S32 agp_mix_count = 0; | ||
2773 | if (non_agp && usingAGP()) | ||
2774 | { | ||
2775 | if (0 == agp_mix_count % 16) | ||
2776 | { | ||
2777 | lldebugs << "Mixing AGP and non-AGP pools, slow!" << llendl; | ||
2778 | } | ||
2779 | agp_mix_count++; | ||
2780 | } | ||
2781 | else | ||
2782 | { | 2876 | { |
2783 | agp_mix_count = 0; | 2877 | LLVertexBuffer::stopRender(); |
2784 | } | 2878 | } |
2785 | 2879 | ||
2880 | #ifndef LL_RELEASE_FOR_DOWNLOAD | ||
2881 | LLGLState::checkStates(); | ||
2882 | LLGLState::checkTextureChannels(); | ||
2883 | LLGLState::checkClientArrays(); | ||
2884 | #endif | ||
2885 | |||
2786 | // Contains a list of the faces of objects that are physical or | 2886 | // Contains a list of the faces of objects that are physical or |
2787 | // have touch-handlers. | 2887 | // have touch-handlers. |
2788 | mHighlightFaces.reset(); | 2888 | mHighlightFaces.clear(); |
2889 | } | ||
2789 | 2890 | ||
2790 | // This wait is in case we try to do multiple renders of a frame, | 2891 | void LLPipeline::processOcclusion(LLCamera& camera) |
2791 | // I don't know what happens when we send a fence multiple times without | 2892 | { |
2792 | // checking it. | 2893 | //process occlusion (readback) |
2793 | if (mAGPMemPool) | 2894 | if (sUseOcclusion) |
2794 | { | 2895 | { |
2795 | mAGPMemPool->waitFence(mGlobalFence); | 2896 | for (U32 i = 0; i < mObjectPartition.size(); i++) |
2796 | mAGPMemPool->sendFence(mGlobalFence); | 2897 | { |
2898 | if (mObjectPartition[i] && hasRenderType(mObjectPartition[i]->mDrawableType)) | ||
2899 | { | ||
2900 | mObjectPartition[i]->processOcclusion(&camera); | ||
2901 | } | ||
2902 | } | ||
2903 | |||
2904 | #if AGGRESSIVE_OCCLUSION | ||
2905 | for (LLSpatialBridge::bridge_vector_t::iterator i = mOccludedBridge.begin(); i != mOccludedBridge.end(); ++i) | ||
2906 | { | ||
2907 | LLSpatialBridge* bridge = *i; | ||
2908 | if (!bridge->isDead() && hasRenderType(bridge->mDrawableType)) | ||
2909 | { | ||
2910 | LLCamera trans = bridge->transformCamera(camera); | ||
2911 | bridge->processOcclusion(&trans); | ||
2912 | } | ||
2913 | } | ||
2914 | #endif | ||
2915 | mOccludedBridge.clear(); | ||
2797 | } | 2916 | } |
2798 | } | 2917 | } |
2799 | 2918 | ||
@@ -2802,13 +2921,30 @@ void LLPipeline::renderDebug() | |||
2802 | LLMemType mt(LLMemType::MTYPE_PIPELINE); | 2921 | LLMemType mt(LLMemType::MTYPE_PIPELINE); |
2803 | 2922 | ||
2804 | // Disable all client state | 2923 | // Disable all client state |
2805 | glDisableClientState(GL_VERTEX_ARRAY); | 2924 | glDisableClientState(GL_TEXTURE_COORD_ARRAY); |
2806 | glDisableClientState(GL_TEXTURE_COORD_ARRAY); | ||
2807 | glDisableClientState(GL_NORMAL_ARRAY); | 2925 | glDisableClientState(GL_NORMAL_ARRAY); |
2808 | glDisableClientState(GL_VERTEX_ARRAY); | 2926 | glDisableClientState(GL_COLOR_ARRAY); |
2809 | 2927 | ||
2810 | // Debug stuff. | 2928 | // Debug stuff. |
2811 | mObjectPartition->renderDebug(); | 2929 | for (U32 i = 0; i < mObjectPartition.size(); i++) |
2930 | { | ||
2931 | if (mObjectPartition[i] && hasRenderType(mObjectPartition[i]->mDrawableType)) | ||
2932 | { | ||
2933 | mObjectPartition[i]->renderDebug(); | ||
2934 | } | ||
2935 | } | ||
2936 | |||
2937 | for (LLSpatialBridge::bridge_vector_t::iterator i = mVisibleBridge.begin(); i != mVisibleBridge.end(); ++i) | ||
2938 | { | ||
2939 | LLSpatialBridge* bridge = *i; | ||
2940 | if (!bridge->isDead() && hasRenderType(bridge->mDrawableType)) | ||
2941 | { | ||
2942 | glPushMatrix(); | ||
2943 | glMultMatrixf((F32*)bridge->mDrawable->getRenderMatrix().mMatrix); | ||
2944 | bridge->renderDebug(); | ||
2945 | glPopMatrix(); | ||
2946 | } | ||
2947 | } | ||
2812 | 2948 | ||
2813 | if (mRenderDebugMask & LLPipeline::RENDER_DEBUG_LIGHT_TRACE) | 2949 | if (mRenderDebugMask & LLPipeline::RENDER_DEBUG_LIGHT_TRACE) |
2814 | { | 2950 | { |
@@ -2855,81 +2991,6 @@ void LLPipeline::renderDebug() | |||
2855 | } | 2991 | } |
2856 | } | 2992 | } |
2857 | 2993 | ||
2858 | mCompilesStat.addValue(sCompiles); | ||
2859 | mLightingChangesStat.addValue(mLightingChanges); | ||
2860 | mGeometryChangesStat.addValue(mGeometryChanges); | ||
2861 | mTrianglesDrawnStat.addValue(mTrianglesDrawn/1000.f); | ||
2862 | mVerticesRelitStat.addValue(mVerticesRelit); | ||
2863 | mNumVisibleFacesStat.addValue(mNumVisibleFaces); | ||
2864 | mNumVisibleDrawablesStat.addValue((S32)mVisibleList.size()); | ||
2865 | |||
2866 | if (gRenderLightGlows) | ||
2867 | { | ||
2868 | displaySSBB(); | ||
2869 | } | ||
2870 | |||
2871 | /*if (mRenderDebugMask & RENDER_DEBUG_BBOXES) | ||
2872 | { | ||
2873 | LLGLSPipelineAlpha gls_pipeline_alpha; | ||
2874 | LLGLSNoTexture no_texture; | ||
2875 | |||
2876 | for (LLDrawable::drawable_vector_t::iterator iter = mVisibleList.begin(); iter != mVisibleList.end(); iter++) | ||
2877 | { | ||
2878 | LLDrawable *drawablep = *iter; | ||
2879 | if (drawablep->isDead()) | ||
2880 | { | ||
2881 | continue; | ||
2882 | } | ||
2883 | LLVector3 min, max; | ||
2884 | |||
2885 | if (drawablep->getVObj() && drawablep->getVObj()->getPCode() == LLViewerObject::LL_VO_SURFACE_PATCH) | ||
2886 | { | ||
2887 | // Render drawable bbox | ||
2888 | drawablep->getBounds(min, max); | ||
2889 | glColor4f(0.f, 1.f, 0.f, 0.25f); | ||
2890 | render_bbox(min, max); | ||
2891 | |||
2892 | // Render object bbox | ||
2893 | LLVector3 scale = drawablep->getVObj()->getScale(); | ||
2894 | LLVector3 pos = drawablep->getVObj()->getPositionAgent(); | ||
2895 | min = pos - scale * 0.5f; | ||
2896 | max = pos + scale * 0.5f; | ||
2897 | glColor4f(1.f, 0.f, 0.f, 0.25f); | ||
2898 | render_bbox(min, max); | ||
2899 | } | ||
2900 | } | ||
2901 | }*/ | ||
2902 | |||
2903 | /* | ||
2904 | // Debugging code for parcel sound. | ||
2905 | F32 x, y; | ||
2906 | |||
2907 | LLGLSNoTexture gls_no_texture; | ||
2908 | |||
2909 | glBegin(GL_POINTS); | ||
2910 | if (gAgent.getRegion()) | ||
2911 | { | ||
2912 | // Draw the composition layer for the region that I'm in. | ||
2913 | for (x = 0; x <= 260; x++) | ||
2914 | { | ||
2915 | for (y = 0; y <= 260; y++) | ||
2916 | { | ||
2917 | if (gParcelMgr->isSoundLocal(gAgent.getRegion()->getOriginGlobal() + LLVector3d(x, y, 0.f))) | ||
2918 | { | ||
2919 | glColor4f(1.f, 0.f, 0.f, 1.f); | ||
2920 | } | ||
2921 | else | ||
2922 | { | ||
2923 | glColor4f(0.f, 0.f, 1.f, 1.f); | ||
2924 | } | ||
2925 | |||
2926 | glVertex3f(x, y, gAgent.getRegion()->getLandHeightRegion(LLVector3(x, y, 0.f))); | ||
2927 | } | ||
2928 | } | ||
2929 | } | ||
2930 | glEnd(); | ||
2931 | */ | ||
2932 | |||
2933 | if (mRenderDebugMask & RENDER_DEBUG_COMPOSITION) | 2994 | if (mRenderDebugMask & RENDER_DEBUG_COMPOSITION) |
2934 | { | 2995 | { |
2935 | // Debug composition layers | 2996 | // Debug composition layers |
@@ -2962,358 +3023,163 @@ void LLPipeline::renderDebug() | |||
2962 | } | 3023 | } |
2963 | glEnd(); | 3024 | glEnd(); |
2964 | } | 3025 | } |
2965 | |||
2966 | if (mRenderDebugMask & RENDER_DEBUG_AGP_MEM) | ||
2967 | { | ||
2968 | displayAGP(); | ||
2969 | } | ||
2970 | |||
2971 | if (mRenderDebugMask & RENDER_DEBUG_POOLS) | ||
2972 | { | ||
2973 | displayPools(); | ||
2974 | } | ||
2975 | |||
2976 | // if (mRenderDebugMask & RENDER_DEBUG_QUEUES) | ||
2977 | // { | ||
2978 | // displayQueues(); | ||
2979 | // } | ||
2980 | |||
2981 | if (mRenderDebugMask & RENDER_DEBUG_MAP) | ||
2982 | { | ||
2983 | displayMap(); | ||
2984 | } | ||
2985 | } | 3026 | } |
2986 | 3027 | ||
2987 | 3028 | void LLPipeline::renderForSelect(std::set<LLViewerObject*>& objects) | |
2988 | |||
2989 | |||
2990 | BOOL compute_min_max(LLMatrix4& box, LLVector2& min, LLVector2& max) | ||
2991 | { | 3029 | { |
2992 | min.setVec(1000,1000); | 3030 | LLMemType mt(LLMemType::MTYPE_PIPELINE); |
2993 | max.setVec(-1000,-1000); | 3031 | |
2994 | 3032 | LLVertexBuffer::startRender(); | |
2995 | if (box.mMatrix[3][3] <= 0.0f) return FALSE; | 3033 | |
3034 | glMatrixMode(GL_MODELVIEW); | ||
2996 | 3035 | ||
2997 | const F32 vec[8][3] = { | 3036 | LLGLSDefault gls_default; |
2998 | { -0.5f,-0.5f,-0.5f }, | 3037 | LLGLSObjectSelect gls_object_select; |
2999 | { -0.5f,-0.5f,+0.5f }, | 3038 | LLGLDepthTest gls_depth(GL_TRUE,GL_TRUE); |
3000 | { -0.5f,+0.5f,-0.5f }, | 3039 | disableLights(); |
3001 | { -0.5f,+0.5f,+0.5f }, | 3040 | |
3002 | { +0.5f,-0.5f,-0.5f }, | 3041 | glEnableClientState ( GL_VERTEX_ARRAY ); |
3003 | { +0.5f,-0.5f,+0.5f }, | ||
3004 | { +0.5f,+0.5f,-0.5f }, | ||
3005 | { +0.5f,+0.5f,+0.5f } }; | ||
3006 | |||
3007 | LLVector4 v; | ||
3008 | 3042 | ||
3009 | for (S32 i=0;i<8;i++) | 3043 | //for each drawpool |
3044 | #ifndef LL_RELEASE_FOR_DOWNLOAD | ||
3045 | LLGLState::checkStates(); | ||
3046 | LLGLState::checkTextureChannels(); | ||
3047 | LLGLState::checkClientArrays(); | ||
3048 | U32 last_type = 0; | ||
3049 | #endif | ||
3050 | for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) | ||
3010 | { | 3051 | { |
3011 | v.setVec(vec[i][0],vec[i][1],vec[i][2],1); | 3052 | LLDrawPool *poolp = *iter; |
3012 | v = v * box; | 3053 | if (poolp->isFacePool() && hasRenderType(poolp->getType())) |
3013 | F32 iw = 1.0f / v.mV[3]; | 3054 | { |
3014 | v.mV[0] *= iw; | 3055 | LLFacePool* face_pool = (LLFacePool*) poolp; |
3015 | v.mV[1] *= iw; | 3056 | face_pool->renderForSelect(); |
3016 | 3057 | ||
3017 | min.mV[0] = llmin(min.mV[0],v.mV[0]); | 3058 | #ifndef LL_RELEASE_FOR_DOWNLOAD |
3018 | max.mV[0] = llmax(max.mV[0],v.mV[0]); | 3059 | if (poolp->getType() != last_type) |
3019 | 3060 | { | |
3020 | min.mV[1] = llmin(min.mV[1],v.mV[1]); | 3061 | last_type = poolp->getType(); |
3021 | max.mV[1] = llmax(max.mV[1],v.mV[1]); | 3062 | LLGLState::checkStates(); |
3063 | LLGLState::checkTextureChannels(); | ||
3064 | LLGLState::checkClientArrays(); | ||
3065 | } | ||
3066 | #endif | ||
3067 | } | ||
3022 | } | 3068 | } |
3023 | 3069 | ||
3024 | /* | 3070 | LLGLEnable tex(GL_TEXTURE_2D); |
3025 | min.mV[0] = max.mV[0] = box.mMatrix[3][0]; | 3071 | glEnableClientState(GL_TEXTURE_COORD_ARRAY); |
3026 | min.mV[1] = max.mV[1] = box.mMatrix[3][1]; | 3072 | LLGLEnable alpha_test(GL_ALPHA_TEST); |
3027 | F32 iw = 1.0f / box.mMatrix[3][3]; | 3073 | if (gPickTransparent) |
3028 | |||
3029 | F32 f0 = (fabs(box.mMatrix[0][0])+fabs(box.mMatrix[1][0])+fabs(box.mMatrix[2][0])) * 0.5f; | ||
3030 | F32 f1 = (fabs(box.mMatrix[0][1])+fabs(box.mMatrix[1][1])+fabs(box.mMatrix[2][1])) * 0.5f; | ||
3031 | F32 f2 = (fabs(box.mMatrix[0][2])+fabs(box.mMatrix[1][2])+fabs(box.mMatrix[2][2])) * 0.5f; | ||
3032 | |||
3033 | min.mV[0] -= f0; | ||
3034 | min.mV[1] -= f1; | ||
3035 | |||
3036 | max.mV[0] += f0; | ||
3037 | max.mV[1] += f1; | ||
3038 | |||
3039 | min.mV[0] *= iw; | ||
3040 | min.mV[1] *= iw; | ||
3041 | |||
3042 | max.mV[0] *= iw; | ||
3043 | max.mV[1] *= iw; | ||
3044 | */ | ||
3045 | return TRUE; | ||
3046 | } | ||
3047 | |||
3048 | void LLPipeline::displaySSBB() | ||
3049 | { | ||
3050 | LLMatrix4 proj; | ||
3051 | LLMatrix4 cfr(OGL_TO_CFR_ROTATION); | ||
3052 | LLMatrix4 camera; | ||
3053 | LLMatrix4 comb; | ||
3054 | |||
3055 | gCamera->getMatrixToLocal(camera); | ||
3056 | |||
3057 | if (!mBloomImagep) | ||
3058 | { | 3074 | { |
3059 | mBloomImagep = gImageList.getImage(IMG_BLOOM1); | 3075 | glAlphaFunc(GL_GEQUAL, 0.0f); |
3076 | } | ||
3077 | else | ||
3078 | { | ||
3079 | glAlphaFunc(GL_GREATER, 0.2f); | ||
3060 | } | 3080 | } |
3061 | 3081 | ||
3062 | // don't write to depth buffer with light glows so that chat bubbles can pop through | 3082 | glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); |
3063 | LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); | 3083 | glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE); |
3064 | LLViewerImage::bindTexture(mBloomImagep); | 3084 | glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE); |
3065 | |||
3066 | glGetFloatv(GL_PROJECTION_MATRIX,(float*)proj.mMatrix); | ||
3067 | |||
3068 | glMatrixMode(GL_PROJECTION); | ||
3069 | glPushMatrix(); | ||
3070 | glLoadIdentity(); | ||
3071 | |||
3072 | glMatrixMode(GL_MODELVIEW); | ||
3073 | glPushMatrix(); | ||
3074 | glLoadIdentity(); | ||
3075 | 3085 | ||
3076 | LLGLSPipelineAlpha gls_pipeline_alpha; | 3086 | glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PRIMARY_COLOR); |
3087 | glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR); | ||
3077 | 3088 | ||
3078 | //glScalef(0.25,0.25,0.25); | 3089 | glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE); |
3090 | glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA); | ||
3079 | 3091 | ||
3080 | S32 sizex = gViewerWindow->getWindowWidth() / 2; | 3092 | glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_PRIMARY_COLOR_ARB); |
3081 | S32 sizey = gViewerWindow->getWindowHeight() / 2; | 3093 | glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, GL_SRC_ALPHA); |
3082 | 3094 | ||
3083 | F32 aspect = (float)sizey / (float)sizex; | 3095 | U32 prim_mask = LLVertexBuffer::MAP_VERTEX | |
3096 | LLVertexBuffer::MAP_TEXCOORD; | ||
3084 | 3097 | ||
3085 | for (LLDrawable::drawable_set_t::iterator iter = mLights.begin(); | 3098 | for (std::set<LLViewerObject*>::iterator i = objects.begin(); i != objects.end(); ++i) |
3086 | iter != mLights.end(); iter++) | ||
3087 | { | 3099 | { |
3088 | LLDrawable *lightp = *iter; | 3100 | LLViewerObject* vobj = *i; |
3089 | if (lightp->isDead()) | 3101 | LLDrawable* drawable = vobj->mDrawable; |
3102 | if (vobj->isDead() || | ||
3103 | vobj->isHUDAttachment() || | ||
3104 | (gHideSelectedObjects && vobj->isSelected()) || | ||
3105 | drawable->isDead() || | ||
3106 | !hasRenderType(drawable->getRenderType())) | ||
3090 | { | 3107 | { |
3091 | continue; | 3108 | continue; |
3092 | } | 3109 | } |
3093 | |||
3094 | LLMatrix4 mat = lightp->mXform.getWorldMatrix(); | ||
3095 | 3110 | ||
3096 | mat *= camera; | 3111 | for (S32 j = 0; j < drawable->getNumFaces(); ++j) |
3097 | mat *= cfr; | ||
3098 | mat *= proj; | ||
3099 | |||
3100 | U8 color[64]; | ||
3101 | |||
3102 | LLVector2 min,max; | ||
3103 | if (mat.mMatrix[3][3] < 160 && compute_min_max(mat,min,max)) | ||
3104 | { | 3112 | { |
3105 | F32 cx = (max.mV[0] + min.mV[0]) * 0.5f; | 3113 | LLFace* facep = drawable->getFace(j); |
3106 | F32 cy = (max.mV[1] + min.mV[1]) * 0.5f; | 3114 | if (!facep->getPool()) |
3107 | F32 sx = (max.mV[0] - min.mV[0]) * 2.0f; | ||
3108 | F32 sy = (max.mV[1] - min.mV[1]) * 2.0f; | ||
3109 | S32 x = (S32)(cx * (F32)sizex) + sizex; | ||
3110 | S32 y = (S32)(cy * (F32)sizey) + sizey; | ||
3111 | |||
3112 | if (cx > -1 && cx < 1 && cy > -1 && cy < 1) | ||
3113 | { | 3115 | { |
3114 | glReadPixels(x-2,y-2,4,4,GL_RGBA,GL_UNSIGNED_BYTE,&color[0]); | 3116 | facep->renderForSelect(prim_mask); |
3115 | |||
3116 | S32 total = 0; | ||
3117 | for (S32 i=0;i<64;i++) | ||
3118 | { | ||
3119 | total += color[i]; | ||
3120 | } | ||
3121 | total /= 64; | ||
3122 | |||
3123 | sx = (sy = (sx + sy) * 0.5f * ((float)total/255.0f)) * aspect; | ||
3124 | |||
3125 | |||
3126 | if (total > 60) | ||
3127 | { | ||
3128 | color[3+32] = total >> 1; | ||
3129 | glBegin(GL_QUADS); | ||
3130 | glColor4ubv(&color[32]); | ||
3131 | glTexCoord2f(0,0); | ||
3132 | glVertex3f(cx-sx,cy-sy,0); | ||
3133 | glTexCoord2f(1,0); | ||
3134 | glVertex3f(cx+sx,cy-sy,0); | ||
3135 | glTexCoord2f(1,1); | ||
3136 | glVertex3f(cx+sx,cy+sy,0); | ||
3137 | glTexCoord2f(0,1); | ||
3138 | glVertex3f(cx-sx,cy+sy,0); | ||
3139 | glEnd(); | ||
3140 | } | ||
3141 | } | 3117 | } |
3142 | } | 3118 | } |
3143 | |||
3144 | } | 3119 | } |
3145 | 3120 | ||
3146 | // sun | 3121 | // pick HUD objects |
3122 | LLVOAvatar* avatarp = gAgent.getAvatarObject(); | ||
3123 | if (avatarp && sShowHUDAttachments) | ||
3147 | { | 3124 | { |
3148 | LLVector4 sdir(gSky.getSunDirection() * 10000.0f + gAgent.getPositionAgent()); | 3125 | glMatrixMode(GL_PROJECTION); |
3149 | sdir.mV[3] = 1.0f; | 3126 | glPushMatrix(); |
3150 | sdir = sdir * camera; | 3127 | glMatrixMode(GL_MODELVIEW); |
3151 | sdir = sdir * cfr; | 3128 | glPushMatrix(); |
3152 | sdir = sdir * proj; // todo: preconcat | ||
3153 | 3129 | ||
3154 | sdir.mV[0] /= sdir.mV[3]; | 3130 | setup_hud_matrices(TRUE); |
3155 | sdir.mV[1] /= sdir.mV[3]; | 3131 | LLViewerJointAttachment* attachmentp; |
3156 | 3132 | for (attachmentp = avatarp->mAttachmentPoints.getFirstData(); | |
3157 | U8 color[64]; | 3133 | attachmentp; |
3158 | 3134 | attachmentp = avatarp->mAttachmentPoints.getNextData()) | |
3159 | if (sdir.mV[3] > 0) | ||
3160 | { | 3135 | { |
3161 | F32 cx = sdir.mV[0]; | 3136 | if (attachmentp->getIsHUDAttachment()) |
3162 | F32 cy = sdir.mV[1]; | ||
3163 | F32 sx, sy; | ||
3164 | S32 x = (S32)(cx * (F32)sizex) + sizex; | ||
3165 | S32 y = (S32)(cy * (F32)sizey) + sizey; | ||
3166 | |||
3167 | if (cx > -1 && cx < 1 && cy > -1 && cy < 1) | ||
3168 | { | 3137 | { |
3169 | glReadPixels(x-2,y-2,4,4,GL_RGBA,GL_UNSIGNED_BYTE,&color[0]); | 3138 | LLViewerObject* objectp = attachmentp->getObject(); |
3170 | 3139 | if (objectp) | |
3171 | S32 total = 0; | ||
3172 | for (S32 i=0;i<64;i++) | ||
3173 | { | 3140 | { |
3174 | total += color[i]; | 3141 | LLDrawable* drawable = objectp->mDrawable; |
3175 | } | 3142 | if (drawable->isDead()) |
3176 | total >>= 7; | 3143 | { |
3177 | 3144 | continue; | |
3178 | sx = (sy = ((float)total/255.0f)) * aspect; | 3145 | } |
3179 | |||
3180 | const F32 fix = -0.1f; | ||
3181 | 3146 | ||
3182 | color[32] = (U8)(color[32] * 0.5f + 255 * 0.5f); | 3147 | for (S32 j = 0; j < drawable->getNumFaces(); ++j) |
3183 | color[33] = (U8)(color[33] * 0.5f + 255 * 0.5f); | 3148 | { |
3184 | color[34] = (U8)(color[34] * 0.5f + 255 * 0.5f); | 3149 | LLFace* facep = drawable->getFace(j); |
3150 | if (!facep->getPool()) | ||
3151 | { | ||
3152 | facep->renderForSelect(prim_mask); | ||
3153 | } | ||
3154 | } | ||
3185 | 3155 | ||
3186 | if (total > 80) | 3156 | //render child faces |
3187 | { | 3157 | for (U32 k = 0; k < drawable->getChildCount(); ++k) |
3188 | color[32+3] = (U8)total; | 3158 | { |
3189 | glBegin(GL_QUADS); | 3159 | LLDrawable* child = drawable->getChild(k); |
3190 | glColor4ubv(&color[32]); | 3160 | for (S32 l = 0; l < child->getNumFaces(); ++l) |
3191 | glTexCoord2f(0,0); | 3161 | { |
3192 | glVertex3f(cx-sx,cy-sy+fix,0); | 3162 | LLFace* facep = child->getFace(l); |
3193 | glTexCoord2f(1,0); | 3163 | if (!facep->getPool()) |
3194 | glVertex3f(cx+sx,cy-sy+fix,0); | 3164 | { |
3195 | glTexCoord2f(1,1); | 3165 | facep->renderForSelect(prim_mask); |
3196 | glVertex3f(cx+sx,cy+sy+fix,0); | 3166 | } |
3197 | glTexCoord2f(0,1); | 3167 | } |
3198 | glVertex3f(cx-sx,cy+sy+fix,0); | 3168 | } |
3199 | glEnd(); | 3169 | } |
3200 | } | ||
3201 | } | 3170 | } |
3202 | } | 3171 | } |
3203 | } | ||
3204 | 3172 | ||
3205 | glMatrixMode(GL_PROJECTION); | 3173 | glMatrixMode(GL_PROJECTION); |
3206 | glPopMatrix(); | 3174 | glPopMatrix(); |
3207 | glMatrixMode(GL_MODELVIEW); | 3175 | glMatrixMode(GL_MODELVIEW); |
3208 | glPopMatrix(); | 3176 | glPopMatrix(); |
3209 | } | ||
3210 | |||
3211 | void LLPipeline::displayMap() | ||
3212 | { | ||
3213 | LLGLSPipelineAlpha gls_pipeline_alpha; | ||
3214 | LLGLSNoTexture no_texture; | ||
3215 | LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); | ||
3216 | |||
3217 | glMatrixMode(GL_MODELVIEW); | ||
3218 | glPushMatrix(); | ||
3219 | glLoadIdentity(); | ||
3220 | |||
3221 | glMatrixMode(GL_PROJECTION); | ||
3222 | glPushMatrix(); | ||
3223 | glLoadIdentity(); | ||
3224 | |||
3225 | glTranslatef(-1,-1,0); | ||
3226 | glScalef(2,2,0); | ||
3227 | |||
3228 | glColor4f(0,0,0,0.5); | ||
3229 | glBegin(GL_QUADS); | ||
3230 | glVertex3f(0,0,0); | ||
3231 | glVertex3f(1,0,0); | ||
3232 | glVertex3f(1,1,0); | ||
3233 | glVertex3f(0,1,0); | ||
3234 | glEnd(); | ||
3235 | |||
3236 | static F32 totalW = 1.5f; | ||
3237 | static F32 offset = 0.5f; | ||
3238 | static F32 scale = 1.0f; | ||
3239 | |||
3240 | S32 mousex = gViewerWindow->getCurrentMouseX(); | ||
3241 | S32 mousey = gViewerWindow->getCurrentMouseY(); | ||
3242 | S32 w = gViewerWindow->getWindowWidth(); | ||
3243 | S32 h = gViewerWindow->getWindowHeight(); | ||
3244 | |||
3245 | if (mousex < 20 && offset > 0) offset -= (20 - mousex) * 0.02f; | ||
3246 | if (mousex > (w - 20)) offset += (20 - (w - mousex)) * 0.02f; | ||
3247 | if (offset > (totalW-1)) offset = (totalW-1); | ||
3248 | |||
3249 | if (mousey < 20 && scale > 0.1) scale -= (20 - mousey) * 0.001f; | ||
3250 | if (mousey > (h - 20) && scale < 1.0f) scale += (20 - (h - mousey)) * 0.001f; | ||
3251 | |||
3252 | glScalef(scale*scale,scale,1); | ||
3253 | glTranslatef(-offset,0,0); | ||
3254 | //totalW = mStaticTree->render2D(0,0.8f/scale); | ||
3255 | //mDynamicTree->render2D(0,0.4f/scale); | ||
3256 | |||
3257 | glMatrixMode(GL_PROJECTION); | ||
3258 | glPopMatrix(); | ||
3259 | glMatrixMode(GL_MODELVIEW); | ||
3260 | glPopMatrix(); | ||
3261 | } | ||
3262 | |||
3263 | void LLPipeline::renderForSelect() | ||
3264 | { | ||
3265 | LLMemType mt(LLMemType::MTYPE_PIPELINE); | ||
3266 | //for each drawpool | ||
3267 | |||
3268 | glMatrixMode(GL_MODELVIEW); | ||
3269 | |||
3270 | LLGLSDefault gls_default; | ||
3271 | LLGLSObjectSelect gls_object_select; | ||
3272 | LLGLDepthTest gls_depth(GL_TRUE); | ||
3273 | disableLights(); | ||
3274 | |||
3275 | glEnableClientState ( GL_VERTEX_ARRAY ); | ||
3276 | glDisableClientState( GL_NORMAL_ARRAY ); | ||
3277 | glDisableClientState( GL_TEXTURE_COORD_ARRAY ); | ||
3278 | |||
3279 | #ifndef LL_RELEASE_FOR_DOWNLOAD | ||
3280 | LLGLState::checkStates(); | ||
3281 | LLGLState::checkTextureChannels(); | ||
3282 | LLGLState::checkClientArrays(); | ||
3283 | U32 last_type = 0; | ||
3284 | #endif | ||
3285 | for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) | ||
3286 | { | ||
3287 | LLDrawPool *poolp = *iter; | ||
3288 | if (poolp->canUseAGP() && usingAGP()) | ||
3289 | { | ||
3290 | bindAGP(); | ||
3291 | } | ||
3292 | else | ||
3293 | { | ||
3294 | //llinfos << "Rendering pool type " << p->getType() << " without AGP!" << llendl; | ||
3295 | unbindAGP(); | ||
3296 | } | ||
3297 | poolp->renderForSelect(); | ||
3298 | #ifndef LL_RELEASE_FOR_DOWNLOAD | ||
3299 | if (poolp->getType() != last_type) | ||
3300 | { | ||
3301 | last_type = poolp->getType(); | ||
3302 | LLGLState::checkStates(); | ||
3303 | LLGLState::checkTextureChannels(); | ||
3304 | LLGLState::checkClientArrays(); | ||
3305 | } | ||
3306 | #endif | ||
3307 | } | 3177 | } |
3308 | 3178 | ||
3309 | // Disable all of the client state | 3179 | glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); |
3310 | glDisableClientState( GL_VERTEX_ARRAY ); | 3180 | glDisableClientState( GL_TEXTURE_COORD_ARRAY ); |
3311 | 3181 | ||
3312 | if (mAGPMemPool) | 3182 | LLVertexBuffer::stopRender(); |
3313 | { | ||
3314 | mAGPMemPool->waitFence(mGlobalFence); | ||
3315 | mAGPMemPool->sendFence(mGlobalFence); | ||
3316 | } | ||
3317 | } | 3183 | } |
3318 | 3184 | ||
3319 | void LLPipeline::renderFaceForUVSelect(LLFace* facep) | 3185 | void LLPipeline::renderFaceForUVSelect(LLFace* facep) |
@@ -3325,7 +3191,6 @@ void LLPipeline::rebuildPools() | |||
3325 | { | 3191 | { |
3326 | LLMemType mt(LLMemType::MTYPE_PIPELINE); | 3192 | LLMemType mt(LLMemType::MTYPE_PIPELINE); |
3327 | S32 max_count = mPools.size(); | 3193 | S32 max_count = mPools.size(); |
3328 | S32 num_rebuilds = 0; | ||
3329 | pool_set_t::iterator iter1 = mPools.upper_bound(mLastRebuildPool); | 3194 | pool_set_t::iterator iter1 = mPools.upper_bound(mLastRebuildPool); |
3330 | while(max_count > 0 && mPools.size() > 0) // && num_rebuilds < MAX_REBUILDS) | 3195 | while(max_count > 0 && mPools.size() > 0) // && num_rebuilds < MAX_REBUILDS) |
3331 | { | 3196 | { |
@@ -3334,8 +3199,8 @@ void LLPipeline::rebuildPools() | |||
3334 | iter1 = mPools.begin(); | 3199 | iter1 = mPools.begin(); |
3335 | } | 3200 | } |
3336 | LLDrawPool* poolp = *iter1; | 3201 | LLDrawPool* poolp = *iter1; |
3337 | num_rebuilds += poolp->rebuild(); | 3202 | |
3338 | if (poolp->mReferences.empty()) | 3203 | if (poolp->isDead()) |
3339 | { | 3204 | { |
3340 | mPools.erase(iter1++); | 3205 | mPools.erase(iter1++); |
3341 | removeFromQuickLookup( poolp ); | 3206 | removeFromQuickLookup( poolp ); |
@@ -3365,27 +3230,35 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp ) | |||
3365 | switch( new_poolp->getType() ) | 3230 | switch( new_poolp->getType() ) |
3366 | { | 3231 | { |
3367 | case LLDrawPool::POOL_SIMPLE: | 3232 | case LLDrawPool::POOL_SIMPLE: |
3368 | mSimplePools[ uintptr_t(new_poolp->getTexture()) ] = new_poolp ; | 3233 | if (mSimplePool) |
3234 | { | ||
3235 | llassert(0); | ||
3236 | llwarns << "Ignoring duplicate simple pool." << llendl; | ||
3237 | } | ||
3238 | else | ||
3239 | { | ||
3240 | mSimplePool = (LLRenderPass*) new_poolp; | ||
3241 | } | ||
3369 | break; | 3242 | break; |
3370 | 3243 | ||
3371 | case LLDrawPool::POOL_TREE: | 3244 | case LLDrawPool::POOL_TREE: |
3372 | mTreePools[ uintptr_t(new_poolp->getTexture()) ] = new_poolp ; | 3245 | mTreePools[ uintptr_t(new_poolp->getTexture()) ] = new_poolp ; |
3373 | break; | 3246 | break; |
3374 | |||
3375 | case LLDrawPool::POOL_TREE_NEW: | ||
3376 | mTreeNewPools[ uintptr_t(new_poolp->getTexture()) ] = new_poolp ; | ||
3377 | break; | ||
3378 | 3247 | ||
3379 | case LLDrawPool::POOL_TERRAIN: | 3248 | case LLDrawPool::POOL_TERRAIN: |
3380 | mTerrainPools[ uintptr_t(new_poolp->getTexture()) ] = new_poolp ; | 3249 | mTerrainPools[ uintptr_t(new_poolp->getTexture()) ] = new_poolp ; |
3381 | break; | 3250 | break; |
3382 | 3251 | ||
3383 | case LLDrawPool::POOL_BUMP: | 3252 | case LLDrawPool::POOL_BUMP: |
3384 | mBumpPools[ uintptr_t(new_poolp->getTexture()) ] = new_poolp ; | 3253 | if (mBumpPool) |
3385 | break; | 3254 | { |
3386 | 3255 | llassert(0); | |
3387 | case LLDrawPool::POOL_MEDIA: | 3256 | llwarns << "Ignoring duplicate bump pool." << llendl; |
3388 | mMediaPools[ uintptr_t(new_poolp->getTexture()) ] = new_poolp ; | 3257 | } |
3258 | else | ||
3259 | { | ||
3260 | mBumpPool = new_poolp; | ||
3261 | } | ||
3389 | break; | 3262 | break; |
3390 | 3263 | ||
3391 | case LLDrawPool::POOL_ALPHA: | 3264 | case LLDrawPool::POOL_ALPHA: |
@@ -3400,6 +3273,18 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp ) | |||
3400 | } | 3273 | } |
3401 | break; | 3274 | break; |
3402 | 3275 | ||
3276 | case LLDrawPool::POOL_ALPHA_POST_WATER: | ||
3277 | if( mAlphaPoolPostWater ) | ||
3278 | { | ||
3279 | llassert(0); | ||
3280 | llwarns << "LLPipeline::addPool(): Ignoring duplicate Alpha pool" << llendl; | ||
3281 | } | ||
3282 | else | ||
3283 | { | ||
3284 | mAlphaPoolPostWater = new_poolp; | ||
3285 | } | ||
3286 | break; | ||
3287 | |||
3403 | case LLDrawPool::POOL_AVATAR: | 3288 | case LLDrawPool::POOL_AVATAR: |
3404 | break; // Do nothing | 3289 | break; // Do nothing |
3405 | 3290 | ||
@@ -3426,19 +3311,7 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp ) | |||
3426 | mStarsPool = new_poolp; | 3311 | mStarsPool = new_poolp; |
3427 | } | 3312 | } |
3428 | break; | 3313 | break; |
3429 | 3314 | ||
3430 | case LLDrawPool::POOL_CLOUDS: | ||
3431 | if( mCloudsPool ) | ||
3432 | { | ||
3433 | llassert(0); | ||
3434 | llwarns << "LLPipeline::addPool(): Ignoring duplicate Clouds pool" << llendl; | ||
3435 | } | ||
3436 | else | ||
3437 | { | ||
3438 | mCloudsPool = new_poolp; | ||
3439 | } | ||
3440 | break; | ||
3441 | |||
3442 | case LLDrawPool::POOL_WATER: | 3315 | case LLDrawPool::POOL_WATER: |
3443 | if( mWaterPool ) | 3316 | if( mWaterPool ) |
3444 | { | 3317 | { |
@@ -3463,14 +3336,6 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp ) | |||
3463 | } | 3336 | } |
3464 | break; | 3337 | break; |
3465 | 3338 | ||
3466 | case LLDrawPool::POOL_HUD: | ||
3467 | if( mHUDPool ) | ||
3468 | { | ||
3469 | llerrs << "LLPipeline::addPool(): Duplicate HUD Pool!" << llendl; | ||
3470 | } | ||
3471 | mHUDPool = new_poolp; | ||
3472 | break; | ||
3473 | |||
3474 | default: | 3339 | default: |
3475 | llassert(0); | 3340 | llassert(0); |
3476 | llwarns << "Invalid Pool Type in LLPipeline::addPool()" << llendl; | 3341 | llwarns << "Invalid Pool Type in LLPipeline::addPool()" << llendl; |
@@ -3491,14 +3356,8 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp ) | |||
3491 | switch( poolp->getType() ) | 3356 | switch( poolp->getType() ) |
3492 | { | 3357 | { |
3493 | case LLDrawPool::POOL_SIMPLE: | 3358 | case LLDrawPool::POOL_SIMPLE: |
3494 | #ifdef _DEBUG | 3359 | llassert(mSimplePool == poolp); |
3495 | { | 3360 | mSimplePool = NULL; |
3496 | BOOL found = mSimplePools.erase( (uintptr_t)poolp->getTexture() ); | ||
3497 | llassert( found ); | ||
3498 | } | ||
3499 | #else | ||
3500 | mSimplePools.erase( (uintptr_t)poolp->getTexture() ); | ||
3501 | #endif | ||
3502 | break; | 3361 | break; |
3503 | 3362 | ||
3504 | case LLDrawPool::POOL_TREE: | 3363 | case LLDrawPool::POOL_TREE: |
@@ -3512,17 +3371,6 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp ) | |||
3512 | #endif | 3371 | #endif |
3513 | break; | 3372 | break; |
3514 | 3373 | ||
3515 | case LLDrawPool::POOL_TREE_NEW: | ||
3516 | #ifdef _DEBUG | ||
3517 | { | ||
3518 | BOOL found = mTreeNewPools.erase( (uintptr_t)poolp->getTexture() ); | ||
3519 | llassert( found ); | ||
3520 | } | ||
3521 | #else | ||
3522 | mTreeNewPools.erase( (uintptr_t)poolp->getTexture() ); | ||
3523 | #endif | ||
3524 | break; | ||
3525 | |||
3526 | case LLDrawPool::POOL_TERRAIN: | 3374 | case LLDrawPool::POOL_TERRAIN: |
3527 | #ifdef _DEBUG | 3375 | #ifdef _DEBUG |
3528 | { | 3376 | { |
@@ -3535,32 +3383,20 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp ) | |||
3535 | break; | 3383 | break; |
3536 | 3384 | ||
3537 | case LLDrawPool::POOL_BUMP: | 3385 | case LLDrawPool::POOL_BUMP: |
3538 | #ifdef _DEBUG | 3386 | llassert( poolp == mBumpPool ); |
3539 | { | 3387 | mBumpPool = NULL; |
3540 | BOOL found = mBumpPools.erase( (uintptr_t)poolp->getTexture() ); | ||
3541 | llassert( found ); | ||
3542 | } | ||
3543 | #else | ||
3544 | mBumpPools.erase( (uintptr_t)poolp->getTexture() ); | ||
3545 | #endif | ||
3546 | break; | ||
3547 | |||
3548 | case LLDrawPool::POOL_MEDIA: | ||
3549 | #ifdef _DEBUG | ||
3550 | { | ||
3551 | BOOL found = mMediaPools.erase( (uintptr_t)poolp->getTexture() ); | ||
3552 | llassert( found ); | ||
3553 | } | ||
3554 | #else | ||
3555 | mMediaPools.erase( (uintptr_t)poolp->getTexture() ); | ||
3556 | #endif | ||
3557 | break; | 3388 | break; |
3558 | 3389 | ||
3559 | case LLDrawPool::POOL_ALPHA: | 3390 | case LLDrawPool::POOL_ALPHA: |
3560 | llassert( poolp == mAlphaPool ); | 3391 | llassert( poolp == mAlphaPool ); |
3561 | mAlphaPool = NULL; | 3392 | mAlphaPool = NULL; |
3562 | break; | 3393 | break; |
3563 | 3394 | ||
3395 | case LLDrawPool::POOL_ALPHA_POST_WATER: | ||
3396 | llassert( poolp == mAlphaPoolPostWater ); | ||
3397 | mAlphaPoolPostWater = NULL; | ||
3398 | break; | ||
3399 | |||
3564 | case LLDrawPool::POOL_AVATAR: | 3400 | case LLDrawPool::POOL_AVATAR: |
3565 | break; // Do nothing | 3401 | break; // Do nothing |
3566 | 3402 | ||
@@ -3574,11 +3410,6 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp ) | |||
3574 | mStarsPool = NULL; | 3410 | mStarsPool = NULL; |
3575 | break; | 3411 | break; |
3576 | 3412 | ||
3577 | case LLDrawPool::POOL_CLOUDS: | ||
3578 | llassert( poolp == mCloudsPool ); | ||
3579 | mCloudsPool = NULL; | ||
3580 | break; | ||
3581 | |||
3582 | case LLDrawPool::POOL_WATER: | 3413 | case LLDrawPool::POOL_WATER: |
3583 | llassert( poolp == mWaterPool ); | 3414 | llassert( poolp == mWaterPool ); |
3584 | mWaterPool = NULL; | 3415 | mWaterPool = NULL; |
@@ -3589,11 +3420,6 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp ) | |||
3589 | mGroundPool = NULL; | 3420 | mGroundPool = NULL; |
3590 | break; | 3421 | break; |
3591 | 3422 | ||
3592 | case LLDrawPool::POOL_HUD: | ||
3593 | llassert( poolp == mHUDPool ); | ||
3594 | mHUDPool = NULL; | ||
3595 | break; | ||
3596 | |||
3597 | default: | 3423 | default: |
3598 | llassert(0); | 3424 | llassert(0); |
3599 | llwarns << "Invalid Pool Type in LLPipeline::removeFromQuickLookup() type=" << poolp->getType() << llendl; | 3425 | llwarns << "Invalid Pool Type in LLPipeline::removeFromQuickLookup() type=" << poolp->getType() << llendl; |
@@ -3601,17 +3427,6 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp ) | |||
3601 | } | 3427 | } |
3602 | } | 3428 | } |
3603 | 3429 | ||
3604 | void LLPipeline::flushAGPMemory() | ||
3605 | { | ||
3606 | LLMemType mt(LLMemType::MTYPE_PIPELINE); | ||
3607 | |||
3608 | for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) | ||
3609 | { | ||
3610 | LLDrawPool *poolp = *iter; | ||
3611 | poolp->flushAGP(); | ||
3612 | } | ||
3613 | } | ||
3614 | |||
3615 | void LLPipeline::resetDrawOrders() | 3430 | void LLPipeline::resetDrawOrders() |
3616 | { | 3431 | { |
3617 | // Iterate through all of the draw pools and rebuild them. | 3432 | // Iterate through all of the draw pools and rebuild them. |
@@ -3622,346 +3437,6 @@ void LLPipeline::resetDrawOrders() | |||
3622 | } | 3437 | } |
3623 | } | 3438 | } |
3624 | 3439 | ||
3625 | //------------------------------- | ||
3626 | |||
3627 | |||
3628 | LLViewerObject *LLPipeline::nearestObjectAt(F32 yaw, F32 pitch) | ||
3629 | { | ||
3630 | // Stub to find nearest Object at given yaw and pitch | ||
3631 | |||
3632 | /* | ||
3633 | LLEdge *vd = NULL; | ||
3634 | |||
3635 | if (vd) | ||
3636 | { | ||
3637 | return (LLViewerObject*)vd->mDrawablep->getVObj(); | ||
3638 | } | ||
3639 | */ | ||
3640 | |||
3641 | return NULL; | ||
3642 | } | ||
3643 | |||
3644 | void LLPipeline::printPools() | ||
3645 | { | ||
3646 | /* | ||
3647 | // Iterate through all of the draw pools and rebuild them. | ||
3648 | for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) | ||
3649 | { | ||
3650 | LLDrawPool *poolp = *iter; | ||
3651 | if (pool->mTexturep[0]) | ||
3652 | { | ||
3653 | llinfos << "Op pool " << pool->mTexturep[0]->mID << llendflush; | ||
3654 | } | ||
3655 | else | ||
3656 | { | ||
3657 | llinfos << "Opaque pool NULL" << llendflush; | ||
3658 | } | ||
3659 | llinfos << " Vertices: \t" << pool->getVertexCount() << llendl; | ||
3660 | } | ||
3661 | |||
3662 | |||
3663 | for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) | ||
3664 | { | ||
3665 | LLDrawPool *poolp = *iter; | ||
3666 | llinfos << "Al pool " << pool; | ||
3667 | llcont << " Vertices: \t" << pool->getVertexCount() << llendl; | ||
3668 | } | ||
3669 | |||
3670 | pool = mHighlightPools.getFirst(); | ||
3671 | llinfos << "Si pool " << pool; | ||
3672 | llcont << " Vertices: \t" << pool->getVertexCount() << llendl; | ||
3673 | */ | ||
3674 | } | ||
3675 | |||
3676 | |||
3677 | void LLPipeline::displayPools() | ||
3678 | { | ||
3679 | // Needs to be fixed to handle chained pools - djs | ||
3680 | LLUI::setLineWidth(1.0); | ||
3681 | glMatrixMode(GL_PROJECTION); | ||
3682 | glPushMatrix(); | ||
3683 | glLoadIdentity(); | ||
3684 | glMatrixMode(GL_MODELVIEW); | ||
3685 | glPushMatrix(); | ||
3686 | glLoadIdentity(); | ||
3687 | |||
3688 | LLGLSPipelineAlpha gls_pipeline_alpha; | ||
3689 | LLGLSNoTexture no_texture; | ||
3690 | LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); | ||
3691 | |||
3692 | glScalef(2,2,1); | ||
3693 | glTranslatef(-0.5f,-0.5f,0); | ||
3694 | |||
3695 | F32 x = 0.0f, y = 0.05f; | ||
3696 | F32 xs = 0.01f, ys = 0.01f; | ||
3697 | F32 xs2 = xs*0.1f, ys2 = ys * 0.1f; | ||
3698 | |||
3699 | for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) | ||
3700 | { | ||
3701 | LLGLSTexture gls_texture; | ||
3702 | LLDrawPool *poolp = *iter; | ||
3703 | if (poolp->getDebugTexture()) | ||
3704 | { | ||
3705 | poolp->getDebugTexture()->bind(); | ||
3706 | glColor4f(1,1,1,1); | ||
3707 | stamp(x,y,xs*4,ys*4); | ||
3708 | } | ||
3709 | |||
3710 | LLGLSNoTexture no_texture; | ||
3711 | |||
3712 | F32 a = 1.f - (F32)poolp->mRebuildTime / (F32)poolp->mRebuildFreq; | ||
3713 | glColor4f(a,a,a,1); | ||
3714 | stamp(x,y,xs,ys); | ||
3715 | |||
3716 | x = (xs + xs2) * 4.0f; | ||
3717 | |||
3718 | F32 h = ys * 0.5f; | ||
3719 | |||
3720 | S32 total = 0; | ||
3721 | |||
3722 | for (std::vector<LLFace*>::iterator iter = poolp->mReferences.begin(); | ||
3723 | iter != poolp->mReferences.end(); iter++) | ||
3724 | { | ||
3725 | LLFace *face = *iter; | ||
3726 | F32 w = xs; | ||
3727 | |||
3728 | if (!face || !face->getDrawable()) | ||
3729 | { | ||
3730 | w = 16 / 3000.0f; | ||
3731 | |||
3732 | stamp(x,y,w,h); | ||
3733 | |||
3734 | if (x+w > 0.95f) | ||
3735 | { | ||
3736 | x = (xs + xs2) * 4.0f; | ||
3737 | y += h + ys2; | ||
3738 | } | ||
3739 | else | ||
3740 | { | ||
3741 | if (w) x += w + xs2; | ||
3742 | } | ||
3743 | |||
3744 | continue; | ||
3745 | } | ||
3746 | |||
3747 | if (face->getDrawable()->isVisible()) | ||
3748 | { | ||
3749 | if (face->isState(LLFace::BACKLIST)) | ||
3750 | { | ||
3751 | glColor4f(1,0,1,1); | ||
3752 | } | ||
3753 | else if (total > poolp->getMaxVertices()) | ||
3754 | { | ||
3755 | glColor4f(1,0,0,1); | ||
3756 | } | ||
3757 | else | ||
3758 | { | ||
3759 | glColor4f(0,1,0,1); | ||
3760 | total += face->getGeomCount(); | ||
3761 | } | ||
3762 | } | ||
3763 | else | ||
3764 | { | ||
3765 | if (face->isState(LLFace::BACKLIST)) | ||
3766 | { | ||
3767 | glColor4f(0,0,1,1); | ||
3768 | } | ||
3769 | else | ||
3770 | { | ||
3771 | glColor4f(1,1,0,1); | ||
3772 | } | ||
3773 | } | ||
3774 | |||
3775 | w = face->getGeomCount() / 3000.0f; | ||
3776 | |||
3777 | stamp(x,y,w,h); | ||
3778 | |||
3779 | if (x+w > 0.95f) | ||
3780 | { | ||
3781 | x = (xs + xs2) * 4.0f; | ||
3782 | y += h + ys2; | ||
3783 | } | ||
3784 | else | ||
3785 | { | ||
3786 | if (w) x += w + xs2; | ||
3787 | } | ||
3788 | } | ||
3789 | |||
3790 | y += ys + ys2; | ||
3791 | x = 0; | ||
3792 | } | ||
3793 | |||
3794 | glPopMatrix(); | ||
3795 | glMatrixMode(GL_PROJECTION); | ||
3796 | glPopMatrix(); | ||
3797 | glMatrixMode(GL_MODELVIEW); | ||
3798 | } | ||
3799 | |||
3800 | static F32 xs = 0.01f, ys = 0.01f; | ||
3801 | static F32 xs2 = xs*0.1f, ys2 = ys * 0.1f; | ||
3802 | static F32 winx, winy; | ||
3803 | |||
3804 | void displayDrawable(F32 &x, F32 &y, LLDrawable *drawable, F32 alpha = 0.5f) | ||
3805 | { | ||
3806 | F32 w = 0; | ||
3807 | F32 h = ys * 0.5f; | ||
3808 | |||
3809 | if (drawable && !drawable->isDead()) | ||
3810 | { | ||
3811 | for (S32 f=0;f < drawable->getNumFaces(); f++) | ||
3812 | { | ||
3813 | w += drawable->getFace(f)->getGeomCount() / 30000.0f; | ||
3814 | } | ||
3815 | w+=xs; | ||
3816 | glColor4f(1,1,0, alpha); | ||
3817 | } | ||
3818 | else | ||
3819 | { | ||
3820 | w = 0.01f; | ||
3821 | glColor4f(0,0,0,alpha); | ||
3822 | } | ||
3823 | |||
3824 | // const LLFontGL* font = gResMgr->getRes( LLFONT_SANSSERIF_SMALL ); | ||
3825 | |||
3826 | // U8 pcode = drawable->getVObj()->getPCode(); | ||
3827 | |||
3828 | //char *string = (char*)LLPrimitive::pCodeToString(pcode); | ||
3829 | //if (pcode == 0x3e) string = "terrain"; | ||
3830 | //else if (pcode == 0x2e) string = "cloud"; | ||
3831 | //string[3] = 0; | ||
3832 | |||
3833 | stamp(x * winx,y * winy,w * winx,h * winy); | ||
3834 | |||
3835 | /* | ||
3836 | glColor4f(0,0,0,1); | ||
3837 | font->render(string,x*winx+1,y*winy+1); | ||
3838 | LLGLSNoTexture no_texture; | ||
3839 | */ | ||
3840 | |||
3841 | if (x+w > 0.95f) | ||
3842 | { | ||
3843 | x = (xs + xs2) * 4.0f; | ||
3844 | y += h + ys2; | ||
3845 | } | ||
3846 | else | ||
3847 | { | ||
3848 | if (w) x += w + xs2; | ||
3849 | } | ||
3850 | |||
3851 | } | ||
3852 | |||
3853 | #if 0 // No longer up date | ||
3854 | |||
3855 | void displayQueue(F32 &x, F32 &y, LLDynamicArray<LLDrawable*>& processed, LLDynamicQueuePtr<LLPointer<LLDrawable> >& remaining) | ||
3856 | { | ||
3857 | S32 i; | ||
3858 | for (i=0;i<processed.count();i++) | ||
3859 | { | ||
3860 | displayDrawable(x,y,processed[i],1); | ||
3861 | } | ||
3862 | |||
3863 | x += xs * 2; | ||
3864 | |||
3865 | S32 count = remaining.count(); | ||
3866 | for (i=0;i<count;i++) | ||
3867 | { | ||
3868 | LLDrawable* drawablep = remaining[(i + remaining.getFirst()) % remaining.getMax()]; | ||
3869 | if (drawablep && !drawablep->isDead()) | ||
3870 | { | ||
3871 | displayDrawable(x,y,drawable,0.5); | ||
3872 | } | ||
3873 | } | ||
3874 | |||
3875 | y += ys * 4; | ||
3876 | x = (xs + xs2) * 4.0f; | ||
3877 | |||
3878 | } | ||
3879 | |||
3880 | void LLPipeline::displayQueues() | ||
3881 | { | ||
3882 | LLUI::setLineWidth(1.0); | ||
3883 | glMatrixMode(GL_PROJECTION); | ||
3884 | glPushMatrix(); | ||
3885 | glLoadIdentity(); | ||
3886 | glMatrixMode(GL_MODELVIEW); | ||
3887 | glPushMatrix(); | ||
3888 | glLoadIdentity(); | ||
3889 | |||
3890 | LLGLSPipelineAlpha gls_pipeline_alpha; | ||
3891 | LLGLSNoTexture no_texture; | ||
3892 | LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); | ||
3893 | |||
3894 | glScalef(2,2,1); | ||
3895 | glTranslatef(-0.5f,-0.5f,0); | ||
3896 | |||
3897 | winx = (F32)gViewerWindow->getWindowWidth(); | ||
3898 | winy = (F32)gViewerWindow->getWindowHeight(); | ||
3899 | |||
3900 | glScalef(1.0f/winx,1.0f/winy,1); | ||
3901 | |||
3902 | F32 x = (xs + xs2) * 4.0f; | ||
3903 | F32 y = 0.1f; | ||
3904 | |||
3905 | const LLFontGL* font = gResMgr->getRes( LLFONT_SANSSERIF ); | ||
3906 | |||
3907 | font->renderUTF8("Build1", 0,0,(S32)(y*winy),LLColor4(1,1,1,1)); | ||
3908 | displayQueue(x,y, gBuildProcessed, mBuildQ1); | ||
3909 | |||
3910 | glPopMatrix(); | ||
3911 | glMatrixMode(GL_PROJECTION); | ||
3912 | glPopMatrix(); | ||
3913 | glMatrixMode(GL_MODELVIEW); | ||
3914 | |||
3915 | } | ||
3916 | |||
3917 | #endif | ||
3918 | |||
3919 | // static | ||
3920 | void render_bbox(const LLVector3 &min, const LLVector3 &max) | ||
3921 | { | ||
3922 | S32 i; | ||
3923 | LLVector3 verticesp[16]; | ||
3924 | |||
3925 | verticesp[0].setVec(min.mV[0],min.mV[1],max.mV[2]); | ||
3926 | verticesp[1].setVec(min.mV[0],min.mV[1],min.mV[2]); | ||
3927 | verticesp[2].setVec(min.mV[0],max.mV[1],min.mV[2]); | ||
3928 | verticesp[3].setVec(min.mV[0],max.mV[1],max.mV[2]); | ||
3929 | verticesp[4].setVec(max.mV[0],max.mV[1],max.mV[2]); | ||
3930 | verticesp[5].setVec(max.mV[0],max.mV[1],min.mV[2]); | ||
3931 | verticesp[6].setVec(max.mV[0],min.mV[1],min.mV[2]); | ||
3932 | verticesp[7].setVec(max.mV[0],min.mV[1],max.mV[2]); | ||
3933 | verticesp[8 ] = verticesp[0]; | ||
3934 | verticesp[9 ] = verticesp[1]; | ||
3935 | verticesp[10] = verticesp[6]; | ||
3936 | verticesp[11] = verticesp[7]; | ||
3937 | verticesp[12] = verticesp[4]; | ||
3938 | verticesp[13] = verticesp[5]; | ||
3939 | verticesp[14] = verticesp[2]; | ||
3940 | verticesp[15] = verticesp[3]; | ||
3941 | |||
3942 | LLGLSNoTexture gls_no_texture; | ||
3943 | { | ||
3944 | LLUI::setLineWidth(1.f); | ||
3945 | glBegin(GL_LINE_LOOP); | ||
3946 | for (i = 0; i < 16; i++) | ||
3947 | { | ||
3948 | glVertex3fv(verticesp[i].mV); | ||
3949 | } | ||
3950 | glEnd(); | ||
3951 | } | ||
3952 | { | ||
3953 | LLGLDepthTest gls_depth(GL_TRUE); | ||
3954 | LLUI::setLineWidth(3.0f); | ||
3955 | glBegin(GL_LINE_LOOP); | ||
3956 | for (i = 0; i < 16; i++) | ||
3957 | { | ||
3958 | glVertex3fv(verticesp[i].mV); | ||
3959 | } | ||
3960 | glEnd(); | ||
3961 | } | ||
3962 | LLUI::setLineWidth(1.0f); | ||
3963 | } | ||
3964 | |||
3965 | //============================================================================ | 3440 | //============================================================================ |
3966 | // Once-per-frame setup of hardware lights, | 3441 | // Once-per-frame setup of hardware lights, |
3967 | // including sun/moon, avatar backlight, and up to 6 local lights | 3442 | // including sun/moon, avatar backlight, and up to 6 local lights |
@@ -4173,8 +3648,6 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) | |||
4173 | { | 3648 | { |
4174 | const LLColor4 black(0,0,0,1); | 3649 | const LLColor4 black(0,0,0,1); |
4175 | 3650 | ||
4176 | setLightingDetail(-1); // update | ||
4177 | |||
4178 | // Ambient | 3651 | // Ambient |
4179 | LLColor4 ambient = gSky.getTotalAmbientColor(); | 3652 | LLColor4 ambient = gSky.getTotalAmbientColor(); |
4180 | glLightModelfv(GL_LIGHT_MODEL_AMBIENT,ambient.mV); | 3653 | glLightModelfv(GL_LIGHT_MODEL_AMBIENT,ambient.mV); |
@@ -4430,16 +3903,6 @@ class LLVOBranch; | |||
4430 | class LLVOLeaf; | 3903 | class LLVOLeaf; |
4431 | class Foo; | 3904 | class Foo; |
4432 | 3905 | ||
4433 | template<> char* LLAGPArray<U8>::sTypeName = "U8 [AGP]"; | ||
4434 | template<> char* LLAGPArray<U32>::sTypeName = "U32 [AGP]"; | ||
4435 | template<> char* LLAGPArray<F32>::sTypeName = "F32 [AGP]"; | ||
4436 | template<> char* LLAGPArray<LLColor4>::sTypeName = "LLColor4 [AGP]"; | ||
4437 | template<> char* LLAGPArray<LLColor4U>::sTypeName = "LLColor4U [AGP]"; | ||
4438 | template<> char* LLAGPArray<LLVector4>::sTypeName = "LLVector4 [AGP]"; | ||
4439 | template<> char* LLAGPArray<LLVector3>::sTypeName = "LLVector3 [AGP]"; | ||
4440 | template<> char* LLAGPArray<LLVector2>::sTypeName = "LLVector2 [AGP]"; | ||
4441 | template<> char* LLAGPArray<LLFace*>::sTypeName = "LLFace* [AGP]"; | ||
4442 | |||
4443 | void scale_stamp(const F32 x, const F32 y, const F32 xs, const F32 ys) | 3906 | void scale_stamp(const F32 x, const F32 y, const F32 xs, const F32 ys) |
4444 | { | 3907 | { |
4445 | stamp(0.25f + 0.5f*x, | 3908 | stamp(0.25f + 0.5f*x, |
@@ -4481,221 +3944,6 @@ void drawBars(const F32 begin, const F32 end, const F32 height = 1.f) | |||
4481 | } | 3944 | } |
4482 | } | 3945 | } |
4483 | 3946 | ||
4484 | void LLPipeline::displayAGP() | ||
4485 | { | ||
4486 | LLUI::setLineWidth(1.0); | ||
4487 | glMatrixMode(GL_PROJECTION); | ||
4488 | glPushMatrix(); | ||
4489 | glLoadIdentity(); | ||
4490 | glMatrixMode(GL_MODELVIEW); | ||
4491 | glPushMatrix(); | ||
4492 | glLoadIdentity(); | ||
4493 | |||
4494 | LLGLSPipelineAlpha gls_alpha; | ||
4495 | LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); | ||
4496 | |||
4497 | LLImageGL::unbindTexture(0, GL_TEXTURE_2D); | ||
4498 | glScalef(2,2,1); | ||
4499 | glTranslatef(-0.5f,-0.5f,0); | ||
4500 | |||
4501 | glColor4f(0,0,0,0.5f); | ||
4502 | scale_stamp(0,0,1,1); | ||
4503 | |||
4504 | F32 x = 0.0f, y = 0.05f; | ||
4505 | F32 xs = 0.015f, ys = 0.015f; | ||
4506 | F32 xs2 = xs*0.1f, ys2 = ys * 0.1f; | ||
4507 | F32 w = xs+xs2, h = ys + ys2; | ||
4508 | S32 i=0; | ||
4509 | |||
4510 | F32 agp_size = 1.f; | ||
4511 | if (mAGPMemPool) | ||
4512 | { | ||
4513 | agp_size = (F32)mAGPMemPool->getSize(); | ||
4514 | } | ||
4515 | |||
4516 | x = (xs + xs2) * 4.0f; | ||
4517 | |||
4518 | static float c = 0.0f; | ||
4519 | c += 0.0001f; | ||
4520 | |||
4521 | LLAGPMemBlock *blockp = mBufferMemory[mBufferIndex]->getAGPMemBlock(); | ||
4522 | |||
4523 | pool_set_t::iterator iter = mPools.begin(); | ||
4524 | LLDrawPool *poolp = *iter; | ||
4525 | |||
4526 | // Dump the shared AGP buffer | ||
4527 | if (blockp) | ||
4528 | { | ||
4529 | F32 begin = blockp->getOffset()/agp_size; | ||
4530 | F32 end = begin + (blockp->getSize()/agp_size); | ||
4531 | F32 used = begin + (poolp->mMemory.count()/agp_size); | ||
4532 | |||
4533 | LLViewerImage::bindTexture(NULL); | ||
4534 | glColor4f(0.5f, 0.5f, 0.5f, 0.5f); | ||
4535 | drawBars(begin,end); | ||
4536 | |||
4537 | LLViewerImage::bindTexture(NULL); | ||
4538 | glColor4f(0.5f, 0.5f, 0.5f, 0.5f); | ||
4539 | drawBars(begin,end); | ||
4540 | |||
4541 | LLViewerImage::bindTexture(NULL); | ||
4542 | glColor4f(0.5f, 0.5f, 0.5f, 0.5f); | ||
4543 | drawBars(begin,used, 0.5f); | ||
4544 | |||
4545 | glColor4f(0.5f, 0.5f, 0.5f, 0.5f); | ||
4546 | drawBars(begin,end, 0.25f); | ||
4547 | } | ||
4548 | |||
4549 | S32 used_bytes = 0; | ||
4550 | S32 total_bytes = 0; | ||
4551 | while (iter != mPools.end()) | ||
4552 | { | ||
4553 | poolp = *iter++; | ||
4554 | |||
4555 | BOOL synced = FALSE; | ||
4556 | i++; | ||
4557 | total_bytes += poolp->mMemory.getMax(); | ||
4558 | used_bytes += poolp->mMemory.count(); | ||
4559 | LLViewerImage *texturep = poolp->getDebugTexture(); | ||
4560 | |||
4561 | |||
4562 | if (poolp->mMemory.mSynced) | ||
4563 | { | ||
4564 | poolp->mMemory.mSynced = FALSE; | ||
4565 | synced = TRUE; | ||
4566 | } | ||
4567 | |||
4568 | LLAGPMemBlock *blockp = poolp->mMemory.getAGPMemBlock(); | ||
4569 | if (blockp) | ||
4570 | { | ||
4571 | F32 begin = blockp->getOffset()/agp_size; | ||
4572 | F32 end = begin + (blockp->getSize()/agp_size); | ||
4573 | F32 used = begin + (poolp->mMemory.count()/agp_size); | ||
4574 | |||
4575 | LLViewerImage::bindTexture(NULL); | ||
4576 | glColor4f(1.f, 0.5f, 0.5f, 0.5f); | ||
4577 | drawBars(begin,end); | ||
4578 | |||
4579 | LLViewerImage::bindTexture(texturep); | ||
4580 | glColor4f(1.f, 0.75f, 0.75f, 0.5f); | ||
4581 | drawBars(begin,end); | ||
4582 | |||
4583 | LLViewerImage::bindTexture(NULL); | ||
4584 | glColor4f(1.f, 0.75f, 0.75f, 1.f); | ||
4585 | drawBars(begin,used, 0.5f); | ||
4586 | |||
4587 | glColor3fv(poolp->getDebugColor().mV); | ||
4588 | drawBars(begin,end, 0.25f); | ||
4589 | |||
4590 | if (synced) | ||
4591 | { | ||
4592 | LLViewerImage::bindTexture(NULL); | ||
4593 | glColor4f(1.f, 1.f, 1.f, 0.4f); | ||
4594 | drawBars(begin,end); | ||
4595 | } | ||
4596 | } | ||
4597 | |||
4598 | synced = FALSE; | ||
4599 | if (poolp->mWeights.mSynced) | ||
4600 | { | ||
4601 | poolp->mWeights.mSynced = FALSE; | ||
4602 | synced = TRUE; | ||
4603 | } | ||
4604 | blockp = poolp->mWeights.getAGPMemBlock(); | ||
4605 | if (blockp) | ||
4606 | { | ||
4607 | F32 begin = blockp->getOffset()/agp_size; | ||
4608 | F32 end = begin + (blockp->getSize()/agp_size); | ||
4609 | F32 used = begin + (poolp->mWeights.count()*sizeof(float)/agp_size); | ||
4610 | |||
4611 | LLViewerImage::bindTexture(NULL); | ||
4612 | glColor4f(0.0f, 0.f, 0.75f, 0.5f); | ||
4613 | drawBars(begin,end); | ||
4614 | |||
4615 | LLViewerImage::bindTexture(texturep); | ||
4616 | glColor4f(0.0, 0.f, 0.75f, 0.5f); | ||
4617 | drawBars(begin,end); | ||
4618 | |||
4619 | LLViewerImage::bindTexture(NULL); | ||
4620 | glColor4f(0.0, 0.f, 0.75f, 1.f); | ||
4621 | drawBars(begin,used, 0.5f); | ||
4622 | |||
4623 | LLViewerImage::bindTexture(NULL); | ||
4624 | glColor3fv(poolp->getDebugColor().mV); | ||
4625 | drawBars(begin,end, 0.25f); | ||
4626 | |||
4627 | if (synced) | ||
4628 | { | ||
4629 | LLViewerImage::bindTexture(NULL); | ||
4630 | glColor4f(1.f, 1.f, 1.f, 0.4f); | ||
4631 | drawBars(begin,end); | ||
4632 | } | ||
4633 | } | ||
4634 | |||
4635 | synced = FALSE; | ||
4636 | if (poolp->mClothingWeights.mSynced) | ||
4637 | { | ||
4638 | poolp->mClothingWeights.mSynced = FALSE; | ||
4639 | synced = TRUE; | ||
4640 | } | ||
4641 | blockp = poolp->mClothingWeights.getAGPMemBlock(); | ||
4642 | if (blockp) | ||
4643 | { | ||
4644 | F32 begin = blockp->getOffset()/agp_size; | ||
4645 | F32 end = begin + (blockp->getSize()/agp_size); | ||
4646 | F32 used = begin + (poolp->mClothingWeights.count()*sizeof(LLVector4)/agp_size); | ||
4647 | |||
4648 | LLViewerImage::bindTexture(NULL); | ||
4649 | glColor4f(0.75f, 0.f, 0.75f, 0.5f); | ||
4650 | drawBars(begin,end); | ||
4651 | |||
4652 | LLViewerImage::bindTexture(texturep); | ||
4653 | glColor4f(0.75f, 0.f, 0.75f, 0.5f); | ||
4654 | drawBars(begin,end); | ||
4655 | |||
4656 | LLViewerImage::bindTexture(NULL); | ||
4657 | glColor4f(0.75f, 0.f, 0.75f, 0.5f); | ||
4658 | drawBars(begin,used, 0.5f); | ||
4659 | |||
4660 | LLViewerImage::bindTexture(NULL); | ||
4661 | glColor3fv(poolp->getDebugColor().mV); | ||
4662 | drawBars(begin,end, 0.25f); | ||
4663 | |||
4664 | if (synced) | ||
4665 | { | ||
4666 | LLViewerImage::bindTexture(NULL); | ||
4667 | glColor4f(1.f, 1.f, 1.f, 0.5f); | ||
4668 | drawBars(begin,end); | ||
4669 | } | ||
4670 | } | ||
4671 | |||
4672 | // | ||
4673 | // Stamps on bottom of screen | ||
4674 | // | ||
4675 | LLViewerImage::bindTexture(texturep); | ||
4676 | glColor4f(1.f, 1.f, 1.f, 1.f); | ||
4677 | stamp(x,y,xs,ys); | ||
4678 | |||
4679 | LLViewerImage::bindTexture(NULL); | ||
4680 | glColor3fv(poolp->getDebugColor().mV); | ||
4681 | stamp(x,y,xs, ys*0.25f); | ||
4682 | if (x+w > 0.95f) | ||
4683 | { | ||
4684 | x = (xs + xs2) * 4.0f; | ||
4685 | y += h; | ||
4686 | } | ||
4687 | else | ||
4688 | { | ||
4689 | x += w + xs2; | ||
4690 | } | ||
4691 | } | ||
4692 | |||
4693 | glPopMatrix(); | ||
4694 | glMatrixMode(GL_PROJECTION); | ||
4695 | glPopMatrix(); | ||
4696 | glMatrixMode(GL_MODELVIEW); | ||
4697 | } | ||
4698 | |||
4699 | void LLPipeline::findReferences(LLDrawable *drawablep) | 3947 | void LLPipeline::findReferences(LLDrawable *drawablep) |
4700 | { | 3948 | { |
4701 | if (std::find(mVisibleList.begin(), mVisibleList.end(), drawablep) != mVisibleList.end()) | 3949 | if (std::find(mVisibleList.begin(), mVisibleList.end(), drawablep) != mVisibleList.end()) |
@@ -4706,7 +3954,7 @@ void LLPipeline::findReferences(LLDrawable *drawablep) | |||
4706 | { | 3954 | { |
4707 | llinfos << "In mLights" << llendl; | 3955 | llinfos << "In mLights" << llendl; |
4708 | } | 3956 | } |
4709 | if (mMovedList.find(drawablep) != mMovedList.end()) | 3957 | if (std::find(mMovedList.begin(), mMovedList.end(), drawablep) != mMovedList.end()) |
4710 | { | 3958 | { |
4711 | llinfos << "In mMovedList" << llendl; | 3959 | llinfos << "In mMovedList" << llendl; |
4712 | } | 3960 | } |
@@ -4718,18 +3966,14 @@ void LLPipeline::findReferences(LLDrawable *drawablep) | |||
4718 | { | 3966 | { |
4719 | llinfos << "In mRetexturedList" << llendl; | 3967 | llinfos << "In mRetexturedList" << llendl; |
4720 | } | 3968 | } |
4721 | if (mRematerialedList.find(drawablep) != mRematerialedList.end()) | 3969 | |
4722 | { | ||
4723 | llinfos << "In mRematerialedList" << llendl; | ||
4724 | } | ||
4725 | |||
4726 | if (mActiveQ.find(drawablep) != mActiveQ.end()) | 3970 | if (mActiveQ.find(drawablep) != mActiveQ.end()) |
4727 | { | 3971 | { |
4728 | llinfos << "In mActiveQ" << llendl; | 3972 | llinfos << "In mActiveQ" << llendl; |
4729 | } | 3973 | } |
4730 | if (mBuildQ1.find(drawablep) != mBuildQ1.end()) | 3974 | if (std::find(mBuildQ1.begin(), mBuildQ1.end(), drawablep) != mBuildQ1.end()) |
4731 | { | 3975 | { |
4732 | llinfos << "In mBuildQ2" << llendl; | 3976 | llinfos << "In mBuildQ1" << llendl; |
4733 | } | 3977 | } |
4734 | if (std::find(mBuildQ2.begin(), mBuildQ2.end(), drawablep) != mBuildQ2.end()) | 3978 | if (std::find(mBuildQ2.begin(), mBuildQ2.end(), drawablep) != mBuildQ2.end()) |
4735 | { | 3979 | { |
@@ -4737,19 +3981,7 @@ void LLPipeline::findReferences(LLDrawable *drawablep) | |||
4737 | } | 3981 | } |
4738 | 3982 | ||
4739 | S32 count; | 3983 | S32 count; |
4740 | /* | 3984 | |
4741 | count = mStaticTree->count(drawablep); | ||
4742 | if (count) | ||
4743 | { | ||
4744 | llinfos << "In mStaticTree: " << count << " references" << llendl; | ||
4745 | } | ||
4746 | |||
4747 | count = mDynamicTree->count(drawablep); | ||
4748 | if (count) | ||
4749 | { | ||
4750 | llinfos << "In mStaticTree: " << count << " references" << llendl; | ||
4751 | } | ||
4752 | */ | ||
4753 | count = gObjectList.findReferences(drawablep); | 3985 | count = gObjectList.findReferences(drawablep); |
4754 | if (count) | 3986 | if (count) |
4755 | { | 3987 | { |
@@ -4776,53 +4008,6 @@ BOOL LLPipeline::verify() | |||
4776 | return ok; | 4008 | return ok; |
4777 | } | 4009 | } |
4778 | 4010 | ||
4779 | S32 LLPipeline::getAGPMemUsage() | ||
4780 | { | ||
4781 | if (mAGPMemPool) | ||
4782 | { | ||
4783 | return mAGPMemPool->getSize(); | ||
4784 | } | ||
4785 | else | ||
4786 | { | ||
4787 | return 0; | ||
4788 | } | ||
4789 | } | ||
4790 | |||
4791 | S32 LLPipeline::getMemUsage(const BOOL print) | ||
4792 | { | ||
4793 | S32 mem_usage = 0; | ||
4794 | |||
4795 | if (mAGPMemPool) | ||
4796 | { | ||
4797 | S32 agp_usage = 0; | ||
4798 | agp_usage = mAGPMemPool->getSize(); | ||
4799 | if (print) | ||
4800 | { | ||
4801 | llinfos << "AGP Mem: " << agp_usage << llendl; | ||
4802 | llinfos << "AGP Mem used: " << mAGPMemPool->getTotalAllocated() << llendl; | ||
4803 | } | ||
4804 | mem_usage += agp_usage; | ||
4805 | } | ||
4806 | |||
4807 | |||
4808 | S32 pool_usage = 0; | ||
4809 | for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) | ||
4810 | { | ||
4811 | LLDrawPool *poolp = *iter; | ||
4812 | pool_usage += poolp->getMemUsage(print); | ||
4813 | } | ||
4814 | |||
4815 | if (print) | ||
4816 | { | ||
4817 | llinfos << "Pool Mem: " << pool_usage << llendl; | ||
4818 | } | ||
4819 | |||
4820 | mem_usage += pool_usage; | ||
4821 | |||
4822 | return mem_usage; | ||
4823 | |||
4824 | } | ||
4825 | |||
4826 | ////////////////////////////// | 4011 | ////////////////////////////// |
4827 | // | 4012 | // |
4828 | // Collision detection | 4013 | // Collision detection |
@@ -4933,8 +4118,8 @@ void LLPipeline::setLight(LLDrawable *drawablep, BOOL is_light) | |||
4933 | } | 4118 | } |
4934 | else | 4119 | else |
4935 | { | 4120 | { |
4936 | mLights.erase(drawablep); | ||
4937 | drawablep->clearState(LLDrawable::LIGHT); | 4121 | drawablep->clearState(LLDrawable::LIGHT); |
4122 | mLights.erase(drawablep); | ||
4938 | } | 4123 | } |
4939 | markRelight(drawablep); | 4124 | markRelight(drawablep); |
4940 | } | 4125 | } |
@@ -4953,9 +4138,16 @@ void LLPipeline::setActive(LLDrawable *drawablep, BOOL active) | |||
4953 | } | 4138 | } |
4954 | 4139 | ||
4955 | //static | 4140 | //static |
4956 | void LLPipeline::toggleRenderType(void* data) | 4141 | void LLPipeline::toggleRenderType(U32 type) |
4957 | { | 4142 | { |
4958 | S32 type = (S32)(intptr_t)data; | 4143 | U32 bit = (1<<type); |
4144 | gPipeline.mRenderTypeMask ^= bit; | ||
4145 | } | ||
4146 | |||
4147 | //static | ||
4148 | void LLPipeline::toggleRenderTypeControl(void* data) | ||
4149 | { | ||
4150 | U32 type = (U32)(intptr_t)data; | ||
4959 | U32 bit = (1<<type); | 4151 | U32 bit = (1<<type); |
4960 | if (gPipeline.hasRenderType(type)) | 4152 | if (gPipeline.hasRenderType(type)) |
4961 | { | 4153 | { |
@@ -4965,13 +4157,13 @@ void LLPipeline::toggleRenderType(void* data) | |||
4965 | { | 4157 | { |
4966 | llinfos << "Toggling render type mask " << std::hex << bit << " on" << std::dec << llendl; | 4158 | llinfos << "Toggling render type mask " << std::hex << bit << " on" << std::dec << llendl; |
4967 | } | 4159 | } |
4968 | gPipeline.mRenderTypeMask ^= bit; | 4160 | gPipeline.toggleRenderType(type); |
4969 | } | 4161 | } |
4970 | 4162 | ||
4971 | //static | 4163 | //static |
4972 | BOOL LLPipeline::toggleRenderTypeControl(void* data) | 4164 | BOOL LLPipeline::hasRenderTypeControl(void* data) |
4973 | { | 4165 | { |
4974 | S32 type = (S32)(intptr_t)data; | 4166 | U32 type = (U32)(intptr_t)data; |
4975 | return gPipeline.hasRenderType(type); | 4167 | return gPipeline.hasRenderType(type); |
4976 | } | 4168 | } |
4977 | 4169 | ||
@@ -5010,14 +4202,6 @@ BOOL LLPipeline::toggleRenderDebugControl(void* data) | |||
5010 | void LLPipeline::toggleRenderDebugFeature(void* data) | 4202 | void LLPipeline::toggleRenderDebugFeature(void* data) |
5011 | { | 4203 | { |
5012 | U32 bit = (U32)(intptr_t)data; | 4204 | U32 bit = (U32)(intptr_t)data; |
5013 | if (gPipeline.hasRenderDebugFeatureMask(bit)) | ||
5014 | { | ||
5015 | llinfos << "Toggling render debug feature mask " << std::hex << bit << " off" << std::dec << llendl; | ||
5016 | } | ||
5017 | else | ||
5018 | { | ||
5019 | llinfos << "Toggling render debug feature mask " << std::hex << bit << " on" << std::dec << llendl; | ||
5020 | } | ||
5021 | gPipeline.mRenderDebugFeatureMask ^= bit; | 4205 | gPipeline.mRenderDebugFeatureMask ^= bit; |
5022 | } | 4206 | } |
5023 | 4207 | ||
@@ -5185,7 +4369,7 @@ void LLGLSLShader::mapUniform(GLint index, const char** uniform_names, S32 count | |||
5185 | GLenum type; | 4369 | GLenum type; |
5186 | GLsizei length; | 4370 | GLsizei length; |
5187 | GLint size; | 4371 | GLint size; |
5188 | char name[1024]; | 4372 | char name[1024]; /* Flawfinder: ignore */ |
5189 | name[0] = 0; | 4373 | name[0] = 0; |
5190 | 4374 | ||
5191 | glGetActiveUniformARB(mProgramObject, index, 1024, &length, &size, &type, name); | 4375 | glGetActiveUniformARB(mProgramObject, index, 1024, &length, &size, &type, name); |
@@ -5193,7 +4377,7 @@ void LLGLSLShader::mapUniform(GLint index, const char** uniform_names, S32 count | |||
5193 | //find the index of this uniform | 4377 | //find the index of this uniform |
5194 | for (S32 i = 0; i < (S32) LLPipeline::sReservedUniformCount; i++) | 4378 | for (S32 i = 0; i < (S32) LLPipeline::sReservedUniformCount; i++) |
5195 | { | 4379 | { |
5196 | if (mUniform[i] == -1 && !strncmp(LLPipeline::sReservedUniforms[i],name, strlen(LLPipeline::sReservedUniforms[i]))) | 4380 | if (mUniform[i] == -1 && !strncmp(LLPipeline::sReservedUniforms[i],name, strlen(LLPipeline::sReservedUniforms[i]))) /* Flawfinder: ignore */ |
5197 | { | 4381 | { |
5198 | //found it | 4382 | //found it |
5199 | S32 location = glGetUniformLocationARB(mProgramObject, name); | 4383 | S32 location = glGetUniformLocationARB(mProgramObject, name); |
@@ -5207,7 +4391,7 @@ void LLGLSLShader::mapUniform(GLint index, const char** uniform_names, S32 count | |||
5207 | for (S32 i = 0; i < count; i++) | 4391 | for (S32 i = 0; i < count; i++) |
5208 | { | 4392 | { |
5209 | if (mUniform[i+LLPipeline::sReservedUniformCount] == -1 && | 4393 | if (mUniform[i+LLPipeline::sReservedUniformCount] == -1 && |
5210 | !strncmp(uniform_names[i],name, strlen(uniform_names[i]))) | 4394 | !strncmp(uniform_names[i],name, strlen(uniform_names[i]))) /* Flawfinder: ignore */ |
5211 | { | 4395 | { |
5212 | //found it | 4396 | //found it |
5213 | S32 location = glGetUniformLocationARB(mProgramObject, name); | 4397 | S32 location = glGetUniformLocationARB(mProgramObject, name); |
@@ -5330,8 +4514,365 @@ void LLGLSLShader::vertexAttrib4fv(U32 index, GLfloat* v) | |||
5330 | 4514 | ||
5331 | LLViewerObject* LLPipeline::pickObject(const LLVector3 &start, const LLVector3 &end, LLVector3 &collision) | 4515 | LLViewerObject* LLPipeline::pickObject(const LLVector3 &start, const LLVector3 &end, LLVector3 &collision) |
5332 | { | 4516 | { |
5333 | LLDrawable* drawable = mObjectPartition->pickDrawable(start, end, collision); | 4517 | LLDrawable* drawable = mObjectPartition[PARTITION_VOLUME]->pickDrawable(start, end, collision); |
5334 | return drawable ? drawable->getVObj() : NULL; | 4518 | return drawable ? drawable->getVObj() : NULL; |
5335 | } | 4519 | } |
5336 | 4520 | ||
4521 | LLSpatialPartition* LLPipeline::getSpatialPartition(LLViewerObject* vobj) | ||
4522 | { | ||
4523 | if (vobj) | ||
4524 | { | ||
4525 | return getSpatialPartition(vobj->getPartitionType()); | ||
4526 | } | ||
4527 | return NULL; | ||
4528 | } | ||
4529 | |||
4530 | LLSpatialPartition* LLPipeline::getSpatialPartition(U32 type) | ||
4531 | { | ||
4532 | if (type < mObjectPartition.size()) | ||
4533 | { | ||
4534 | return mObjectPartition[type]; | ||
4535 | } | ||
4536 | return NULL; | ||
4537 | } | ||
4538 | |||
4539 | void LLPipeline::clearRenderMap() | ||
4540 | { | ||
4541 | for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; i++) | ||
4542 | { | ||
4543 | mRenderMap[i].clear(); | ||
4544 | } | ||
4545 | } | ||
4546 | |||
4547 | |||
4548 | void LLPipeline::resetVertexBuffers(LLDrawable* drawable) | ||
4549 | { | ||
4550 | for (S32 i = 0; i < drawable->getNumFaces(); i++) | ||
4551 | { | ||
4552 | LLFace* facep = drawable->getFace(i); | ||
4553 | facep->mVertexBuffer = NULL; | ||
4554 | facep->mLastVertexBuffer = NULL; | ||
4555 | } | ||
4556 | } | ||
4557 | |||
4558 | void LLPipeline::resetVertexBuffers() | ||
4559 | { | ||
4560 | for (U32 i = 0; i < mObjectPartition.size(); ++i) | ||
4561 | { | ||
4562 | if (mObjectPartition[i]) | ||
4563 | { | ||
4564 | mObjectPartition[i]->resetVertexBuffers(); | ||
4565 | } | ||
4566 | } | ||
4567 | |||
4568 | resetDrawOrders(); | ||
4569 | |||
4570 | if (gSky.mVOSkyp.notNull()) | ||
4571 | { | ||
4572 | resetVertexBuffers(gSky.mVOSkyp->mDrawable); | ||
4573 | resetVertexBuffers(gSky.mVOGroundp->mDrawable); | ||
4574 | resetVertexBuffers(gSky.mVOStarsp->mDrawable); | ||
4575 | markRebuild(gSky.mVOSkyp->mDrawable, LLDrawable::REBUILD_ALL, TRUE); | ||
4576 | markRebuild(gSky.mVOGroundp->mDrawable, LLDrawable::REBUILD_ALL, TRUE); | ||
4577 | markRebuild(gSky.mVOStarsp->mDrawable, LLDrawable::REBUILD_ALL, TRUE); | ||
4578 | } | ||
4579 | |||
4580 | if (LLVertexBuffer::sGLCount > 0) | ||
4581 | { | ||
4582 | LLVertexBuffer::cleanupClass(); | ||
4583 | } | ||
4584 | } | ||
4585 | |||
4586 | void LLPipeline::renderObjects(U32 type, U32 mask, BOOL texture) | ||
4587 | { | ||
4588 | mSimplePool->renderStatic(type, mask, texture); | ||
4589 | mSimplePool->renderActive(type, mask, texture); | ||
4590 | } | ||
4591 | |||
4592 | void LLPipeline::setUseVBO(BOOL use_vbo) | ||
4593 | { | ||
4594 | if (use_vbo != LLVertexBuffer::sEnableVBOs) | ||
4595 | { | ||
4596 | if (use_vbo) | ||
4597 | { | ||
4598 | llinfos << "Enabling VBO." << llendl; | ||
4599 | } | ||
4600 | else | ||
4601 | { | ||
4602 | llinfos << "Disabling VBO." << llendl; | ||
4603 | } | ||
4604 | |||
4605 | resetVertexBuffers(); | ||
4606 | LLVertexBuffer::initClass(use_vbo); | ||
4607 | } | ||
4608 | } | ||
4609 | |||
4610 | void apply_cube_face_rotation(U32 face) | ||
4611 | { | ||
4612 | switch (face) | ||
4613 | { | ||
4614 | case 0: | ||
4615 | glRotatef(90.f, 0, 1, 0); | ||
4616 | glRotatef(180.f, 1, 0, 0); | ||
4617 | break; | ||
4618 | case 2: | ||
4619 | glRotatef(-90.f, 1, 0, 0); | ||
4620 | break; | ||
4621 | case 4: | ||
4622 | glRotatef(180.f, 0, 1, 0); | ||
4623 | glRotatef(180.f, 0, 0, 1); | ||
4624 | break; | ||
4625 | case 1: | ||
4626 | glRotatef(-90.f, 0, 1, 0); | ||
4627 | glRotatef(180.f, 1, 0, 0); | ||
4628 | break; | ||
4629 | case 3: | ||
4630 | glRotatef(90, 1, 0, 0); | ||
4631 | break; | ||
4632 | case 5: | ||
4633 | glRotatef(180, 0, 0, 1); | ||
4634 | break; | ||
4635 | } | ||
4636 | } | ||
4637 | void LLPipeline::generateReflectionMap(LLCubeMap* cube_map, LLCamera& cube_cam, GLsizei res) | ||
4638 | { | ||
4639 | //render dynamic cube map | ||
4640 | U32 type_mask = gPipeline.getRenderTypeMask(); | ||
4641 | BOOL use_occlusion = LLPipeline::sUseOcclusion; | ||
4642 | LLPipeline::sUseOcclusion = FALSE; | ||
4643 | LLPipeline::sSkipUpdate = TRUE; | ||
4644 | static GLuint blur_tex = 0; | ||
4645 | if (!blur_tex) | ||
4646 | { | ||
4647 | glGenTextures(1, &blur_tex); | ||
4648 | } | ||
4649 | |||
4650 | BOOL toggle_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI); | ||
4651 | if (toggle_ui) | ||
4652 | { | ||
4653 | gPipeline.toggleRenderDebugFeature((void*) LLPipeline::RENDER_DEBUG_FEATURE_UI); | ||
4654 | } | ||
4655 | |||
4656 | U32 cube_mask = (1 << LLPipeline::RENDER_TYPE_SIMPLE) | | ||
4657 | (1 << LLPipeline::RENDER_TYPE_WATER) | | ||
4658 | (1 << LLPipeline::RENDER_TYPE_BUMP) | | ||
4659 | (1 << LLPipeline::RENDER_TYPE_ALPHA) | | ||
4660 | (1 << LLPipeline::RENDER_TYPE_TREE) | | ||
4661 | (1 << LLDrawPool::POOL_ALPHA_POST_WATER) | | ||
4662 | //(1 << LLPipeline::RENDER_TYPE_PARTICLES) | | ||
4663 | (1 << LLPipeline::RENDER_TYPE_CLOUDS) | | ||
4664 | //(1 << LLPipeline::RENDER_TYPE_STARS) | | ||
4665 | //(1 << LLPipeline::RENDER_TYPE_AVATAR) | | ||
4666 | (1 << LLPipeline::RENDER_TYPE_GRASS) | | ||
4667 | (1 << LLPipeline::RENDER_TYPE_VOLUME) | | ||
4668 | (1 << LLPipeline::RENDER_TYPE_TERRAIN) | | ||
4669 | (1 << LLPipeline::RENDER_TYPE_SKY) | | ||
4670 | (1 << LLPipeline::RENDER_TYPE_GROUND); | ||
4671 | |||
4672 | LLDrawPoolWater::sSkipScreenCopy = TRUE; | ||
4673 | cube_mask = cube_mask & type_mask; | ||
4674 | gPipeline.setRenderTypeMask(cube_mask); | ||
4675 | |||
4676 | glMatrixMode(GL_PROJECTION); | ||
4677 | glPushMatrix(); | ||
4678 | glMatrixMode(GL_MODELVIEW); | ||
4679 | glPushMatrix(); | ||
4680 | |||
4681 | glViewport(0,0,res,res); | ||
4682 | |||
4683 | glClearColor(0,0,0,0); | ||
4684 | |||
4685 | U32 cube_face[] = | ||
4686 | { | ||
4687 | GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, | ||
4688 | GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB, | ||
4689 | GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB, | ||
4690 | GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB, | ||
4691 | GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, | ||
4692 | GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB, | ||
4693 | }; | ||
4694 | |||
4695 | LLVector3 origin = cube_cam.getOrigin(); | ||
4696 | |||
4697 | gPipeline.calcNearbyLights(); | ||
4698 | |||
4699 | for (S32 i = 0; i < 6; i++) | ||
4700 | { | ||
4701 | |||
4702 | glMatrixMode(GL_PROJECTION); | ||
4703 | glLoadIdentity(); | ||
4704 | gluPerspective(90.f, 1.f, 0.1f, 1024.f); | ||
4705 | glMatrixMode(GL_MODELVIEW); | ||
4706 | glLoadIdentity(); | ||
4707 | |||
4708 | apply_cube_face_rotation(i); | ||
4709 | |||
4710 | |||
4711 | glTranslatef(-origin.mV[0], -origin.mV[1], -origin.mV[2]); | ||
4712 | cube_cam.setOrigin(origin); | ||
4713 | LLViewerCamera::updateFrustumPlanes(cube_cam); | ||
4714 | cube_cam.setOrigin(gCamera->getOrigin()); | ||
4715 | gPipeline.updateCull(cube_cam); | ||
4716 | gPipeline.stateSort(cube_cam); | ||
4717 | |||
4718 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | ||
4719 | gPipeline.renderGeom(cube_cam); | ||
4720 | |||
4721 | cube_map->enable(0); | ||
4722 | cube_map->bind(); | ||
4723 | glCopyTexImage2D(cube_face[i], 0, GL_RGB, 0, 0, res, res, 0); | ||
4724 | cube_map->disable(); | ||
4725 | } | ||
4726 | |||
4727 | cube_cam.setOrigin(origin); | ||
4728 | gPipeline.resetDrawOrders(); | ||
4729 | gPipeline.mShinyOrigin.setVec(cube_cam.getOrigin(), cube_cam.getFar()*2.f); | ||
4730 | glMatrixMode(GL_PROJECTION); | ||
4731 | glPopMatrix(); | ||
4732 | glMatrixMode(GL_MODELVIEW); | ||
4733 | glPopMatrix(); | ||
4734 | |||
4735 | gPipeline.setRenderTypeMask(type_mask); | ||
4736 | LLPipeline::sUseOcclusion = use_occlusion; | ||
4737 | LLPipeline::sSkipUpdate = FALSE; | ||
4738 | |||
4739 | if (toggle_ui) | ||
4740 | { | ||
4741 | gPipeline.toggleRenderDebugFeature((void*)LLPipeline::RENDER_DEBUG_FEATURE_UI); | ||
4742 | } | ||
4743 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | ||
4744 | LLDrawPoolWater::sSkipScreenCopy = FALSE; | ||
4745 | } | ||
4746 | |||
4747 | //send cube map vertices and texture coordinates | ||
4748 | void render_cube_map() | ||
4749 | { | ||
4750 | |||
4751 | U32 idx[36]; | ||
4752 | |||
4753 | idx[0] = 1; idx[1] = 0; idx[2] = 2; //front | ||
4754 | idx[3] = 3; idx[4] = 2; idx[5] = 0; | ||
4755 | |||
4756 | idx[6] = 4; idx[7] = 5; idx[8] = 1; //top | ||
4757 | idx[9] = 0; idx[10] = 1; idx[11] = 5; | ||
4758 | |||
4759 | idx[12] = 5; idx[13] = 4; idx[14] = 6; //back | ||
4760 | idx[15] = 7; idx[16] = 6; idx[17] = 4; | ||
4761 | |||
4762 | idx[18] = 6; idx[19] = 7; idx[20] = 3; //bottom | ||
4763 | idx[21] = 2; idx[22] = 3; idx[23] = 7; | ||
4764 | |||
4765 | idx[24] = 0; idx[25] = 5; idx[26] = 3; //left | ||
4766 | idx[27] = 6; idx[28] = 3; idx[29] = 5; | ||
4767 | |||
4768 | idx[30] = 4; idx[31] = 1; idx[32] = 7; //right | ||
4769 | idx[33] = 2; idx[34] = 7; idx[35] = 1; | ||
4770 | |||
4771 | LLVector3 vert[8]; | ||
4772 | LLVector3 r = LLVector3(1,1,1); | ||
4773 | |||
4774 | vert[0] = r.scaledVec(LLVector3(-1,1,1)); // 0 - left top front | ||
4775 | vert[1] = r.scaledVec(LLVector3(1,1,1)); // 1 - right top front | ||
4776 | vert[2] = r.scaledVec(LLVector3(1,-1,1)); // 2 - right bottom front | ||
4777 | vert[3] = r.scaledVec(LLVector3(-1,-1,1)); // 3 - left bottom front | ||
4778 | |||
4779 | vert[4] = r.scaledVec(LLVector3(1,1,-1)); // 4 - left top back | ||
4780 | vert[5] = r.scaledVec(LLVector3(-1,1,-1)); // 5 - right top back | ||
4781 | vert[6] = r.scaledVec(LLVector3(-1,-1,-1)); // 6 - right bottom back | ||
4782 | vert[7] = r.scaledVec(LLVector3(1,-1,-1)); // 7 -left bottom back | ||
4783 | |||
4784 | glBegin(GL_TRIANGLES); | ||
4785 | for (U32 i = 0; i < 36; i++) | ||
4786 | { | ||
4787 | glTexCoord3fv(vert[idx[i]].mV); | ||
4788 | glVertex3fv(vert[idx[i]].mV); | ||
4789 | } | ||
4790 | glEnd(); | ||
4791 | } | ||
4792 | |||
4793 | void LLPipeline::blurReflectionMap(LLCubeMap* cube_in, LLCubeMap* cube_out, U32 res) | ||
4794 | { | ||
4795 | LLGLEnable cube(GL_TEXTURE_CUBE_MAP_ARB); | ||
4796 | LLGLDepthTest depth(GL_FALSE); | ||
4797 | |||
4798 | glMatrixMode(GL_PROJECTION); | ||
4799 | glPushMatrix(); | ||
4800 | glLoadIdentity(); | ||
4801 | gluPerspective(90.f+45.f/res, 1.f, 0.1f, 1024.f); | ||
4802 | glMatrixMode(GL_MODELVIEW); | ||
4803 | glPushMatrix(); | ||
4804 | |||
4805 | glViewport(0, 0, res, res); | ||
4806 | LLGLEnable blend(GL_BLEND); | ||
4807 | |||
4808 | S32 kernel = 2; | ||
4809 | F32 step = 90.f/res; | ||
4810 | F32 alpha = 1.f/((kernel*2+1)); | ||
4811 | |||
4812 | glColor4f(1,1,1,alpha); | ||
4813 | |||
4814 | S32 x = 0; | ||
4815 | |||
4816 | U32 cube_face[] = | ||
4817 | { | ||
4818 | GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, | ||
4819 | GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB, | ||
4820 | GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB, | ||
4821 | GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB, | ||
4822 | GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, | ||
4823 | GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB, | ||
4824 | }; | ||
4825 | |||
4826 | LLVector3 axis[] = | ||
4827 | { | ||
4828 | LLVector3(1,0,0), | ||
4829 | LLVector3(0,1,0), | ||
4830 | LLVector3(0,0,1) | ||
4831 | }; | ||
4832 | |||
4833 | |||
4834 | glBlendFunc(GL_SRC_ALPHA_SATURATE, GL_ONE); | ||
4835 | //3-axis blur | ||
4836 | for (U32 j = 0; j < 3; j++) | ||
4837 | { | ||
4838 | glViewport(0,0,res, res*6); | ||
4839 | glClear(GL_COLOR_BUFFER_BIT); | ||
4840 | if (j == 0) | ||
4841 | { | ||
4842 | cube_in->bind(); | ||
4843 | } | ||
4844 | |||
4845 | for (U32 i = 0; i < 6; i++) | ||
4846 | { | ||
4847 | glViewport(0,i*res, res, res); | ||
4848 | glLoadIdentity(); | ||
4849 | apply_cube_face_rotation(i); | ||
4850 | for (x = -kernel; x <= kernel; ++x) | ||
4851 | { | ||
4852 | glPushMatrix(); | ||
4853 | glRotatef(x*step, axis[j].mV[0], axis[j].mV[1], axis[j].mV[2]); | ||
4854 | render_cube_map(); | ||
4855 | glPopMatrix(); | ||
4856 | } | ||
4857 | } | ||
4858 | |||
4859 | //readback | ||
4860 | if (j == 0) | ||
4861 | { | ||
4862 | cube_out->bind(); | ||
4863 | } | ||
4864 | for (U32 i = 0; i < 6; i++) | ||
4865 | { | ||
4866 | glCopyTexImage2D(cube_face[i], 0, GL_RGB, 0, i*res, res, res, 0); | ||
4867 | } | ||
4868 | } | ||
5337 | 4869 | ||
4870 | glMatrixMode(GL_PROJECTION); | ||
4871 | glPopMatrix(); | ||
4872 | glMatrixMode(GL_MODELVIEW); | ||
4873 | glPopMatrix(); | ||
4874 | |||
4875 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | ||
4876 | } | ||
4877 | |||
4878 | |||