aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/pipeline.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--linden/indra/newview/pipeline.cpp3435
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
97const F32 BACKLIGHT_DAY_MAGNITUDE_AVATAR = 0.2f; 102const F32 BACKLIGHT_DAY_MAGNITUDE_AVATAR = 0.2f;
98const F32 BACKLIGHT_NIGHT_MAGNITUDE_AVATAR = 0.1f; 103const F32 BACKLIGHT_NIGHT_MAGNITUDE_AVATAR = 0.1f;
99const F32 BACKLIGHT_DAY_MAGNITUDE_OBJECT = 0.1f; 104const F32 BACKLIGHT_DAY_MAGNITUDE_OBJECT = 0.1f;
@@ -117,18 +122,12 @@ extern S32 gBoxFrame;
117extern BOOL gRenderLightGlows; 122extern BOOL gRenderLightGlows;
118extern BOOL gHideSelectedObjects; 123extern BOOL gHideSelectedObjects;
119 124
120
121BOOL gAvatarBacklight = FALSE; 125BOOL gAvatarBacklight = FALSE;
122 126
123F32 gMinObjectDistance = MIN_NEAR_PLANE;
124S32 gTrivialAccepts = 0; 127S32 gTrivialAccepts = 0;
125 128
126BOOL gRenderForSelect = FALSE; 129BOOL gRenderForSelect = FALSE;
127 130
128BOOL gUsePickAlpha = TRUE;
129F32 gPickAlphaThreshold = 0.f;
130F32 gPickAlphaTargetThreshold = 0.f;
131
132//glsl parameter tables 131//glsl parameter tables
133const char* LLPipeline::sReservedAttribs[] = 132const char* LLPipeline::sReservedAttribs[] =
134{ 133{
@@ -177,6 +176,13 @@ const char* LLPipeline::sTerrainUniforms[] =
177 176
178U32 LLPipeline::sTerrainUniformCount = sizeof(LLPipeline::sTerrainUniforms)/sizeof(char*); 177U32 LLPipeline::sTerrainUniformCount = sizeof(LLPipeline::sTerrainUniforms)/sizeof(char*);
179 178
179const char* LLPipeline::sShinyUniforms[] =
180{
181 "origin"
182};
183
184U32 LLPipeline::sShinyUniformCount = sizeof(LLPipeline::sShinyUniforms)/sizeof(char*);
185
180const char* LLPipeline::sWaterUniforms[] = 186const char* LLPipeline::sWaterUniforms[] =
181{ 187{
182 "screenTex", 188 "screenTex",
@@ -193,8 +199,6 @@ const char* LLPipeline::sWaterUniforms[] =
193 199
194U32 LLPipeline::sWaterUniformCount = sizeof(LLPipeline::sWaterUniforms)/sizeof(char*); 200U32 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
200void stamp(F32 x, F32 y, F32 xs, F32 ys) 204void 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
218S32 LLPipeline::sCompiles = 0; 222S32 LLPipeline::sCompiles = 0;
219S32 LLPipeline::sAGPMaxPoolSize = 1 << 25; // 32MB 223
224BOOL LLPipeline::sShowHUDAttachments = TRUE;
220BOOL LLPipeline::sRenderPhysicalBeacons = FALSE; 225BOOL LLPipeline::sRenderPhysicalBeacons = FALSE;
221BOOL LLPipeline::sRenderScriptedBeacons = FALSE; 226BOOL LLPipeline::sRenderScriptedBeacons = FALSE;
222BOOL LLPipeline::sRenderParticleBeacons = FALSE; 227BOOL LLPipeline::sRenderParticleBeacons = FALSE;
223BOOL LLPipeline::sRenderSoundBeacons = FALSE; 228BOOL LLPipeline::sRenderSoundBeacons = FALSE;
229BOOL LLPipeline::sUseOcclusion = FALSE;
230BOOL LLPipeline::sSkipUpdate = FALSE;
231BOOL LLPipeline::sDynamicReflections = FALSE;
224 232
225LLPipeline::LLPipeline() : 233LLPipeline::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
255void LLPipeline::init() 254void 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
400BOOL 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
447void 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
466BOOL LLPipeline::usingAGP() const 400void 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
471void 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
534void LLPipeline::destroyGL()
535{
536 setUseAGP(FALSE);
537 stop_glerror();
538 unloadShaders();
539 mHighlightFaces.reset();
540} 426}
541 427
542void LLPipeline::restoreGL() 428void 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
792void LLPipeline::setShaders() 683void 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()
898void LLPipeline::unloadShaders() 800void 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
1343S32 LLPipeline::getMaxLightingDetail() const 1271S32 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
1379LLAGPMemBlock *LLPipeline::allocAGPFromPool(const S32 bytes, const U32 target) 1307class LLOctreeDirtyTexture : public LLOctreeTraveler<LLDrawable>
1380{ 1308{
1381 LLMemType mt(LLMemType::MTYPE_PIPELINE); 1309public:
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
1402void LLPipeline::unbindAGP()
1403{
1404 if (mAGPMemPool && mAGPBound)
1405 {
1406 mAGPMemPool->disable();
1407 mAGPBound = FALSE;
1408 }
1409}
1410
1411void 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
1422U8* LLPipeline::bufferGetScratchMemory(void)
1423{
1424 LLMemType mt(LLMemType::MTYPE_PIPELINE);
1425 return(mBufferMemory[mBufferIndex]->getScratchMemory());
1426}
1427
1428void LLPipeline::bufferWaitFence(void)
1429{
1430 mBufferMemory[mBufferIndex]->waitFence(mBufferFence[mBufferIndex]);
1431}
1432
1433void LLPipeline::bufferSendFence(void)
1434{
1435 mBufferMemory[mBufferIndex]->sendFence(mBufferFence[mBufferIndex]);
1436}
1437 1340
1438void LLPipeline::bufferRotate(void) 1341// Called when a texture changes # of channels (causes faces to move to alpha pool)
1342void 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)
1446void 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)
1542LLDrawPool* LLPipeline::getPoolFromTE(const LLTextureEntry* te, LLViewerImage* imagep) 1441LLDrawPool* 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
1449U32 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
1598void LLPipeline::unlinkDrawable(LLDrawable *drawablep) 1505void 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
1675void LLPipeline::resetFrameStats() 1563void 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
1641void 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
1737void LLPipeline::updateMove() 1662void 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
1824void LLPipeline::updateCull() 1725//static
1726F32 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(); 1745void 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 1790void 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
1913void 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
1945void LLPipeline::doOcclusion() 1836void 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
1954BOOL LLPipeline::updateDrawableGeom(LLDrawable* drawablep, BOOL priority) 1866BOOL 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
2033void LLPipeline::markVisible(LLDrawable *drawablep) 1969void 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
2048void LLPipeline::markMoved(LLDrawable *drawablep, BOOL damped_motion) 2009void 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
2124void 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
2133void LLPipeline::markMaterialed(LLDrawable *drawablep) 2098void 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
2142void LLPipeline::markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags flag, BOOL priority) 2107void 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
2188void LLPipeline::stateSort() 2157void 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()) 2194void 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 /* 2214void 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
2223void 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() 2291void 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
2302void 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
2310void 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
2322void 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
2334void 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
2346void 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
2365void 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
2421void LLPipeline::renderHighlights() 2635void 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
2520void LLPipeline::renderGeom() 2692void 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, 2891void 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 3028void LLPipeline::renderForSelect(std::set<LLViewerObject*>& objects)
2988
2989
2990BOOL 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
3048void 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
3211void 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
3263void 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
3319void LLPipeline::renderFaceForUVSelect(LLFace* facep) 3185void 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
3604void 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
3615void LLPipeline::resetDrawOrders() 3430void 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
3628LLViewerObject *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
3644void 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
3677void 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
3800static F32 xs = 0.01f, ys = 0.01f;
3801static F32 xs2 = xs*0.1f, ys2 = ys * 0.1f;
3802static F32 winx, winy;
3803
3804void 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
3855void 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
3880void 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
3920void 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;
4430class LLVOLeaf; 3903class LLVOLeaf;
4431class Foo; 3904class Foo;
4432 3905
4433template<> char* LLAGPArray<U8>::sTypeName = "U8 [AGP]";
4434template<> char* LLAGPArray<U32>::sTypeName = "U32 [AGP]";
4435template<> char* LLAGPArray<F32>::sTypeName = "F32 [AGP]";
4436template<> char* LLAGPArray<LLColor4>::sTypeName = "LLColor4 [AGP]";
4437template<> char* LLAGPArray<LLColor4U>::sTypeName = "LLColor4U [AGP]";
4438template<> char* LLAGPArray<LLVector4>::sTypeName = "LLVector4 [AGP]";
4439template<> char* LLAGPArray<LLVector3>::sTypeName = "LLVector3 [AGP]";
4440template<> char* LLAGPArray<LLVector2>::sTypeName = "LLVector2 [AGP]";
4441template<> char* LLAGPArray<LLFace*>::sTypeName = "LLFace* [AGP]";
4442
4443void scale_stamp(const F32 x, const F32 y, const F32 xs, const F32 ys) 3906void 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
4484void 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
4699void LLPipeline::findReferences(LLDrawable *drawablep) 3947void 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
4779S32 LLPipeline::getAGPMemUsage()
4780{
4781 if (mAGPMemPool)
4782 {
4783 return mAGPMemPool->getSize();
4784 }
4785 else
4786 {
4787 return 0;
4788 }
4789}
4790
4791S32 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
4956void LLPipeline::toggleRenderType(void* data) 4141void 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
4148void 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
4972BOOL LLPipeline::toggleRenderTypeControl(void* data) 4164BOOL 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)
5010void LLPipeline::toggleRenderDebugFeature(void* data) 4202void 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
5331LLViewerObject* LLPipeline::pickObject(const LLVector3 &start, const LLVector3 &end, LLVector3 &collision) 4515LLViewerObject* 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
4521LLSpatialPartition* LLPipeline::getSpatialPartition(LLViewerObject* vobj)
4522{
4523 if (vobj)
4524 {
4525 return getSpatialPartition(vobj->getPartitionType());
4526 }
4527 return NULL;
4528}
4529
4530LLSpatialPartition* LLPipeline::getSpatialPartition(U32 type)
4531{
4532 if (type < mObjectPartition.size())
4533 {
4534 return mObjectPartition[type];
4535 }
4536 return NULL;
4537}
4538
4539void LLPipeline::clearRenderMap()
4540{
4541 for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; i++)
4542 {
4543 mRenderMap[i].clear();
4544 }
4545}
4546
4547
4548void 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
4558void 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
4586void LLPipeline::renderObjects(U32 type, U32 mask, BOOL texture)
4587{
4588 mSimplePool->renderStatic(type, mask, texture);
4589 mSimplePool->renderActive(type, mask, texture);
4590}
4591
4592void 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
4610void 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}
4637void 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
4748void 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
4793void 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