00001
00032 #include "llviewerprecompiledheaders.h"
00033
00034 #include "pipeline.h"
00035
00036
00037 #include "audioengine.h"
00038 #include "imageids.h"
00039 #include "llerror.h"
00040 #include "llviewercontrol.h"
00041 #include "llfasttimer.h"
00042 #include "llfontgl.h"
00043 #include "llmemory.h"
00044 #include "llmemtype.h"
00045 #include "llnamevalue.h"
00046 #include "llprimitive.h"
00047 #include "llvolume.h"
00048 #include "material_codes.h"
00049 #include "timing.h"
00050 #include "v3color.h"
00051 #include "llui.h"
00052 #include "llglheaders.h"
00053 #include "llglimmediate.h"
00054
00055
00056 #include "llagent.h"
00057 #include "lldrawable.h"
00058 #include "lldrawpoolalpha.h"
00059 #include "lldrawpoolavatar.h"
00060 #include "lldrawpoolground.h"
00061 #include "lldrawpoolbump.h"
00062 #include "lldrawpooltree.h"
00063 #include "lldrawpoolwater.h"
00064 #include "llface.h"
00065 #include "llfeaturemanager.h"
00066 #include "llfloatertelehub.h"
00067 #include "llframestats.h"
00068 #include "llgldbg.h"
00069 #include "llhudmanager.h"
00070 #include "lllightconstants.h"
00071 #include "llresmgr.h"
00072 #include "llselectmgr.h"
00073 #include "llsky.h"
00074 #include "lltracker.h"
00075 #include "lltool.h"
00076 #include "lltoolmgr.h"
00077 #include "llviewercamera.h"
00078 #include "llviewerimagelist.h"
00079 #include "llviewerobject.h"
00080 #include "llviewerobjectlist.h"
00081 #include "llviewerparcelmgr.h"
00082 #include "llviewerregion.h"
00083 #include "llviewerwindow.h"
00084 #include "llvoavatar.h"
00085 #include "llvoground.h"
00086 #include "llvosky.h"
00087 #include "llvotree.h"
00088 #include "llvovolume.h"
00089 #include "llvosurfacepatch.h"
00090 #include "llvowater.h"
00091 #include "llvotree.h"
00092 #include "llvopartgroup.h"
00093 #include "llworld.h"
00094 #include "llcubemap.h"
00095 #include "lldebugmessagebox.h"
00096 #include "llglslshader.h"
00097 #include "llviewerjoystick.h"
00098 #include "llviewerdisplay.h"
00099 #include "llwlparammanager.h"
00100 #include "llwaterparammanager.h"
00101 #include "llspatialpartition.h"
00102 #include "llmutelist.h"
00103
00104 #ifdef _DEBUG
00105
00106
00107 #else
00108
00109 #endif
00110
00111 void render_ui_and_swap_if_needed();
00112
00113 const F32 BACKLIGHT_DAY_MAGNITUDE_AVATAR = 0.2f;
00114 const F32 BACKLIGHT_NIGHT_MAGNITUDE_AVATAR = 0.1f;
00115 const F32 BACKLIGHT_DAY_MAGNITUDE_OBJECT = 0.1f;
00116 const F32 BACKLIGHT_NIGHT_MAGNITUDE_OBJECT = 0.08f;
00117 const S32 MAX_ACTIVE_OBJECT_QUIET_FRAMES = 40;
00118 const S32 MAX_OFFSCREEN_GEOMETRY_CHANGES_PER_FRAME = 10;
00119 const U32 REFLECTION_MAP_RES = 128;
00120
00121
00122 const S32 MAX_OCCLUDER_COUNT = 2;
00123
00124 extern S32 gBoxFrame;
00125 extern BOOL gRenderLightGlows;
00126 extern BOOL gHideSelectedObjects;
00127 extern BOOL gDisplaySwapBuffers;
00128 extern BOOL gDebugGL;
00129
00130
00131
00132 static S32 sDelayedVBOEnable = 0;
00133
00134 BOOL gAvatarBacklight = FALSE;
00135
00136 BOOL gRenderForSelect = FALSE;
00137
00138 BOOL gDebugPipeline = FALSE;
00139 LLPipeline gPipeline;
00140 const LLMatrix4* gGLLastMatrix = NULL;
00141
00142
00143
00144 U32 nhpo2(U32 v)
00145 {
00146 U32 r = 1;
00147 while (r < v) {
00148 r *= 2;
00149 }
00150 return r;
00151 }
00152
00153 glh::matrix4f glh_copy_matrix(GLdouble* src)
00154 {
00155 glh::matrix4f ret;
00156 for (U32 i = 0; i < 16; i++)
00157 {
00158 ret.m[i] = (F32) src[i];
00159 }
00160 return ret;
00161 }
00162
00163 glh::matrix4f glh_get_current_modelview()
00164 {
00165 return glh_copy_matrix(gGLModelView);
00166 }
00167
00168 glh::matrix4f glh_get_current_projection()
00169 {
00170 return glh_copy_matrix(gGLProjection);
00171 }
00172
00173 void glh_copy_matrix(const glh::matrix4f& src, GLdouble* dst)
00174 {
00175 for (U32 i = 0; i < 16; i++)
00176 {
00177 dst[i] = src.m[i];
00178 }
00179 }
00180
00181 void glh_set_current_modelview(const glh::matrix4f& mat)
00182 {
00183 glh_copy_matrix(mat, gGLModelView);
00184 }
00185
00186 void glh_set_current_projection(glh::matrix4f& mat)
00187 {
00188 glh_copy_matrix(mat, gGLProjection);
00189 }
00190
00191 glh::matrix4f gl_ortho(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat znear, GLfloat zfar)
00192 {
00193 glh::matrix4f ret(
00194 2.f/(right-left), 0.f, 0.f, -(right+left)/(right-left),
00195 0.f, 2.f/(top-bottom), 0.f, -(top+bottom)/(top-bottom),
00196 0.f, 0.f, -2.f/(zfar-znear), -(zfar+znear)/(zfar-znear),
00197 0.f, 0.f, 0.f, 1.f);
00198
00199 return ret;
00200 }
00201
00202
00203
00204 S32 LLPipeline::sCompiles = 0;
00205
00206 BOOL LLPipeline::sDynamicLOD = TRUE;
00207 BOOL LLPipeline::sShowHUDAttachments = TRUE;
00208 BOOL LLPipeline::sRenderPhysicalBeacons = TRUE;
00209 BOOL LLPipeline::sRenderScriptedBeacons = FALSE;
00210 BOOL LLPipeline::sRenderScriptedTouchBeacons = TRUE;
00211 BOOL LLPipeline::sRenderParticleBeacons = FALSE;
00212 BOOL LLPipeline::sRenderSoundBeacons = FALSE;
00213 BOOL LLPipeline::sRenderBeacons = FALSE;
00214 BOOL LLPipeline::sRenderHighlight = TRUE;
00215 BOOL LLPipeline::sRenderProcessBeacons = FALSE;
00216 S32 LLPipeline::sUseOcclusion = 0;
00217 BOOL LLPipeline::sFastAlpha = TRUE;
00218 BOOL LLPipeline::sDisableShaders = FALSE;
00219 BOOL LLPipeline::sRenderBump = TRUE;
00220 BOOL LLPipeline::sUseFarClip = TRUE;
00221 BOOL LLPipeline::sSkipUpdate = FALSE;
00222 BOOL LLPipeline::sDynamicReflections = FALSE;
00223 BOOL LLPipeline::sWaterReflections = FALSE;
00224 BOOL LLPipeline::sRenderGlow = FALSE;
00225 BOOL LLPipeline::sReflectionRender = FALSE;
00226 BOOL LLPipeline::sImpostorRender = FALSE;
00227 BOOL LLPipeline::sUnderWaterRender = FALSE;
00228 BOOL LLPipeline::sTextureBindTest = FALSE;
00229 BOOL LLPipeline::sRenderFrameTest = FALSE;
00230
00231 static LLCullResult* sCull = NULL;
00232
00233 static const U32 gl_cube_face[] =
00234 {
00235 GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB,
00236 GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB,
00237 GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB,
00238 GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB,
00239 GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB,
00240 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB,
00241 };
00242
00243 void validate_framebuffer_object();
00244
00245 LLPipeline::LLPipeline() :
00246 mCubeBuffer(NULL),
00247 mInitialized(FALSE),
00248 mVertexShadersEnabled(FALSE),
00249 mVertexShadersLoaded(0),
00250 mLastRebuildPool(NULL),
00251 mAlphaPool(NULL),
00252 mSkyPool(NULL),
00253 mTerrainPool(NULL),
00254 mWaterPool(NULL),
00255 mGroundPool(NULL),
00256 mSimplePool(NULL),
00257 mInvisiblePool(NULL),
00258 mGlowPool(NULL),
00259 mBumpPool(NULL),
00260 mWLSkyPool(NULL),
00261 mLightMask(0),
00262 mLightMovingMask(0)
00263 {
00264
00265 mBlurCubeBuffer[0] = mBlurCubeBuffer[1] = mBlurCubeBuffer[2] = 0;
00266 mBlurCubeTexture[0] = mBlurCubeTexture[1] = mBlurCubeTexture[2] = 0;
00267
00268
00269 mCubeFrameBuffer = 0;
00270 mCubeDepth = 0;
00271 }
00272
00273 void LLPipeline::init()
00274 {
00275 LLMemType mt(LLMemType::MTYPE_PIPELINE);
00276
00277 sDynamicLOD = gSavedSettings.getBOOL("RenderDynamicLOD");
00278 sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
00279
00280 mInitialized = TRUE;
00281
00282 stop_glerror();
00283
00284
00285 getPool(LLDrawPool::POOL_ALPHA);
00286 getPool(LLDrawPool::POOL_SIMPLE);
00287 getPool(LLDrawPool::POOL_INVISIBLE);
00288 getPool(LLDrawPool::POOL_BUMP);
00289 getPool(LLDrawPool::POOL_GLOW);
00290
00291 mTrianglesDrawnStat.reset();
00292 resetFrameStats();
00293
00294 mRenderTypeMask = 0xffffffff;
00295 mRenderDebugFeatureMask = 0xffffffff;
00296 mRenderDebugMask = 0;
00297
00298 mOldRenderDebugMask = mRenderDebugMask;
00299
00300 mBackfaceCull = TRUE;
00301
00302 stop_glerror();
00303
00304
00305
00306 LLShaderMgr::setShaders();
00307
00308 stop_glerror();
00309 }
00310
00311 LLPipeline::~LLPipeline()
00312 {
00313
00314 }
00315
00316 void LLPipeline::cleanup()
00317 {
00318 assertInitialized();
00319
00320 for(pool_set_t::iterator iter = mPools.begin();
00321 iter != mPools.end(); )
00322 {
00323 pool_set_t::iterator curiter = iter++;
00324 LLDrawPool* poolp = *curiter;
00325 if (poolp->isFacePool())
00326 {
00327 LLFacePool* face_pool = (LLFacePool*) poolp;
00328 if (face_pool->mReferences.empty())
00329 {
00330 mPools.erase(curiter);
00331 removeFromQuickLookup( poolp );
00332 delete poolp;
00333 }
00334 }
00335 else
00336 {
00337 mPools.erase(curiter);
00338 removeFromQuickLookup( poolp );
00339 delete poolp;
00340 }
00341 }
00342
00343 if (!mTerrainPools.empty())
00344 {
00345 llwarns << "Terrain Pools not cleaned up" << llendl;
00346 }
00347 if (!mTreePools.empty())
00348 {
00349 llwarns << "Tree Pools not cleaned up" << llendl;
00350 }
00351
00352 delete mAlphaPool;
00353 mAlphaPool = NULL;
00354 delete mSkyPool;
00355 mSkyPool = NULL;
00356 delete mTerrainPool;
00357 mTerrainPool = NULL;
00358 delete mWaterPool;
00359 mWaterPool = NULL;
00360 delete mGroundPool;
00361 mGroundPool = NULL;
00362 delete mSimplePool;
00363 mSimplePool = NULL;
00364 delete mInvisiblePool;
00365 mInvisiblePool = NULL;
00366 delete mGlowPool;
00367 mGlowPool = NULL;
00368 delete mBumpPool;
00369 mBumpPool = NULL;
00370
00371
00372 mWLSkyPool = NULL;
00373
00374 releaseGLBuffers();
00375
00376 mBloomImagep = NULL;
00377 mBloomImage2p = NULL;
00378 mFaceSelectImagep = NULL;
00379
00380 mMovedBridge.clear();
00381
00382 mInitialized = FALSE;
00383 }
00384
00385
00386
00387 void LLPipeline::destroyGL()
00388 {
00389 stop_glerror();
00390 unloadShaders();
00391 mHighlightFaces.clear();
00392
00393 resetDrawOrders();
00394
00395 resetVertexBuffers();
00396
00397 releaseGLBuffers();
00398
00399 if (LLVertexBuffer::sEnableVBOs)
00400 {
00401
00402 sDelayedVBOEnable = 30;
00403 LLVertexBuffer::sEnableVBOs = FALSE;
00404 }
00405 }
00406
00407 void LLPipeline::resizeScreenTexture()
00408 {
00409 if (gPipeline.canUseVertexShaders() && assertInitialized())
00410 {
00411 GLuint resX = gViewerWindow->getWindowDisplayWidth();
00412 GLuint resY = gViewerWindow->getWindowDisplayHeight();
00413
00414 U32 res_mod = gSavedSettings.getU32("RenderResolutionDivisor");
00415 if (res_mod > 1)
00416 {
00417 resX /= res_mod;
00418 resY /= res_mod;
00419 }
00420
00421 mScreen.release();
00422 mScreen.allocate(resX, resY, GL_RGBA, TRUE, GL_TEXTURE_RECTANGLE_ARB);
00423
00424 llinfos << "RESIZED SCREEN TEXTURE: " << resX << "x" << resY << llendl;
00425 }
00426 }
00427
00428
00429 void LLPipeline::releaseGLBuffers()
00430 {
00431 assertInitialized();
00432
00433 if (mCubeBuffer)
00434 {
00435 mCubeBuffer = NULL;
00436 }
00437
00438 if (mCubeFrameBuffer)
00439 {
00440 glDeleteFramebuffersEXT(1, &mCubeFrameBuffer);
00441 glDeleteRenderbuffersEXT(1, &mCubeDepth);
00442 mCubeDepth = mCubeFrameBuffer = 0;
00443 }
00444
00445
00446
00447
00448
00449
00450
00451 if (mBlurCubeBuffer[0])
00452 {
00453 glDeleteFramebuffersEXT(3, mBlurCubeBuffer);
00454 mBlurCubeBuffer[0] = mBlurCubeBuffer[1] = mBlurCubeBuffer[2] = 0;
00455 }
00456
00457 if (mBlurCubeTexture[0])
00458 {
00459 glDeleteTextures(3, mBlurCubeTexture);
00460 mBlurCubeTexture[0] = mBlurCubeTexture[1] = mBlurCubeTexture[2] = 0;
00461 }
00462
00463 mWaterRef.release();
00464 mWaterDis.release();
00465 mScreen.release();
00466
00467 for (U32 i = 0; i < 3; i++)
00468 {
00469 mGlow[i].release();
00470 }
00471
00472 LLVOAvatar::resetImpostors();
00473 }
00474
00475 void LLPipeline::createGLBuffers()
00476 {
00477 assertInitialized();
00478
00479 if (LLPipeline::sDynamicReflections ||
00480 LLPipeline::sWaterReflections)
00481 {
00482 U32 res = (U32) gSavedSettings.getS32("RenderWaterRefResolution");
00483
00484 mWaterRef.allocate(res,res,GL_RGBA,TRUE);
00485 mWaterDis.allocate(res,res,GL_RGBA,TRUE);
00486
00487 if (LLPipeline::sDynamicReflections)
00488 {
00489
00490 if (mCubeFrameBuffer == 0)
00491 {
00492 glGenFramebuffersEXT(1, &mCubeFrameBuffer);
00493 glGenRenderbuffersEXT(1, &mCubeDepth);
00494
00495 U32 res = REFLECTION_MAP_RES;
00496
00497 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, mCubeDepth);
00498
00499 glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,GL_DEPTH_COMPONENT,res,res);
00500
00501 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
00502 }
00503
00504 if (mCubeBuffer.isNull())
00505 {
00506 res = 128;
00507 mCubeBuffer = new LLCubeMap();
00508 mCubeBuffer->initGL();
00509 glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, mCubeBuffer->getGLName());
00510 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00511 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00512 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
00513 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
00514
00515 for (U32 i = 0; i < 6; i++)
00516 {
00517 glTexImage2D(gl_cube_face[i], 0, GL_RGBA, res, res, 0, GL_RGBA, GL_FLOAT, NULL);
00518 }
00519 }
00520
00521 if (mBlurCubeBuffer[0] == 0)
00522 {
00523 glGenFramebuffersEXT(3, mBlurCubeBuffer);
00524 }
00525
00526 if (mBlurCubeTexture[0] == 0)
00527 {
00528 glGenTextures(3, mBlurCubeTexture);
00529 }
00530
00531 res = (U32) gSavedSettings.getS32("RenderReflectionRes");
00532
00533 for (U32 j = 0; j < 3; j++)
00534 {
00535 glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, mBlurCubeTexture[j]);
00536 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00537 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00538 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
00539 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
00540
00541 for (U32 i = 0; i < 6; i++)
00542 {
00543 glTexImage2D(gl_cube_face[i], 0, GL_RGBA, res, res, 0, GL_RGBA, GL_FLOAT, NULL);
00544 }
00545 }
00546 }
00547 }
00548
00549 stop_glerror();
00550
00551 if (LLPipeline::sRenderGlow)
00552 {
00553 const U32 glow_res = llmax(1,
00554 llmin(512, 1 << gSavedSettings.getS32("RenderGlowResolutionPow")));
00555
00556 for (U32 i = 0; i < 3; i++)
00557 {
00558 mGlow[i].allocate(512,glow_res,GL_RGBA,FALSE);
00559 }
00560 }
00561
00562 GLuint resX = gViewerWindow->getWindowDisplayWidth();
00563 GLuint resY = gViewerWindow->getWindowDisplayHeight();
00564
00565 mScreen.allocate(resX, resY, GL_RGBA, TRUE, GL_TEXTURE_RECTANGLE_ARB);
00566 }
00567
00568 void LLPipeline::restoreGL()
00569 {
00570 assertInitialized();
00571
00572 if (mVertexShadersEnabled)
00573 {
00574 LLShaderMgr::setShaders();
00575 }
00576
00577 for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin();
00578 iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
00579 {
00580 LLViewerRegion* region = *iter;
00581 for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
00582 {
00583 LLSpatialPartition* part = region->getSpatialPartition(i);
00584 if (part)
00585 {
00586 part->restoreGL();
00587 }
00588 }
00589 }
00590 }
00591
00592
00593 BOOL LLPipeline::canUseVertexShaders()
00594 {
00595 if (!gGLManager.mHasVertexShader ||
00596 !gGLManager.mHasFragmentShader ||
00597 !LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable") ||
00598 (assertInitialized() && mVertexShadersLoaded != 1) )
00599 {
00600 return FALSE;
00601 }
00602 else
00603 {
00604 return TRUE;
00605 }
00606 }
00607
00608 BOOL LLPipeline::canUseWindLightShaders() const
00609 {
00610 return (!LLPipeline::sDisableShaders &&
00611 gWLSkyProgram.mProgramObject != 0 &&
00612 LLShaderMgr::getVertexShaderLevel(LLShaderMgr::SHADER_WINDLIGHT) > 1);
00613 }
00614
00615 BOOL LLPipeline::canUseWindLightShadersOnObjects() const
00616 {
00617 return (canUseWindLightShaders()
00618 && LLShaderMgr::getVertexShaderLevel(LLShaderMgr::SHADER_OBJECT) > 0);
00619 }
00620
00621 void LLPipeline::unloadShaders()
00622 {
00623 LLShaderMgr::unloadShaders();
00624
00625 mVertexShadersLoaded = 0;
00626 }
00627
00628 void LLPipeline::assertInitializedDoError()
00629 {
00630 llerrs << "LLPipeline used when uninitialized." << llendl;
00631 }
00632
00633
00634
00635 void LLPipeline::enableShadows(const BOOL enable_shadows)
00636 {
00637
00638 }
00639
00640 S32 LLPipeline::getMaxLightingDetail() const
00641 {
00642
00643
00644
00645
00646
00647 {
00648 return 1;
00649 }
00650 }
00651
00652 S32 LLPipeline::setLightingDetail(S32 level)
00653 {
00654 assertInitialized();
00655
00656 if (level < 0)
00657 {
00658 level = gSavedSettings.getS32("RenderLightingDetail");
00659 }
00660 level = llclamp(level, 0, getMaxLightingDetail());
00661 if (level != mLightingDetail)
00662 {
00663 gSavedSettings.setS32("RenderLightingDetail", level);
00664
00665 mLightingDetail = level;
00666
00667 if (mVertexShadersLoaded == 1)
00668 {
00669 LLShaderMgr::setShaders();
00670 }
00671 }
00672 return mLightingDetail;
00673 }
00674
00675 class LLOctreeDirtyTexture : public LLOctreeTraveler<LLDrawable>
00676 {
00677 public:
00678 const std::set<LLViewerImage*>& mTextures;
00679
00680 LLOctreeDirtyTexture(const std::set<LLViewerImage*>& textures) : mTextures(textures) { }
00681
00682 virtual void visit(const LLOctreeNode<LLDrawable>* node)
00683 {
00684 LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0);
00685
00686 if (!group->isState(LLSpatialGroup::GEOM_DIRTY) && !group->getData().empty())
00687 {
00688 for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i)
00689 {
00690 for (LLSpatialGroup::drawmap_elem_t::iterator j = i->second.begin(); j != i->second.end(); ++j)
00691 {
00692 LLDrawInfo* params = *j;
00693 if (mTextures.find(params->mTexture) != mTextures.end())
00694 {
00695 group->setState(LLSpatialGroup::GEOM_DIRTY);
00696 }
00697 }
00698 }
00699 }
00700
00701 for (LLSpatialGroup::bridge_list_t::iterator i = group->mBridgeList.begin(); i != group->mBridgeList.end(); ++i)
00702 {
00703 LLSpatialBridge* bridge = *i;
00704 traverse(bridge->mOctree);
00705 }
00706 }
00707 };
00708
00709
00710 void LLPipeline::dirtyPoolObjectTextures(const std::set<LLViewerImage*>& textures)
00711 {
00712 assertInitialized();
00713
00714
00715
00716
00717 for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter)
00718 {
00719 LLDrawPool *poolp = *iter;
00720 if (poolp->isFacePool())
00721 {
00722 ((LLFacePool*) poolp)->dirtyTextures(textures);
00723 }
00724 }
00725
00726 LLOctreeDirtyTexture dirty(textures);
00727 for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin();
00728 iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
00729 {
00730 LLViewerRegion* region = *iter;
00731 for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
00732 {
00733 LLSpatialPartition* part = region->getSpatialPartition(i);
00734 if (part)
00735 {
00736 dirty.traverse(part->mOctree);
00737 }
00738 }
00739 }
00740 }
00741
00742 LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerImage *tex0)
00743 {
00744 assertInitialized();
00745
00746 LLDrawPool *poolp = NULL;
00747 switch( type )
00748 {
00749 case LLDrawPool::POOL_SIMPLE:
00750 poolp = mSimplePool;
00751 break;
00752
00753 case LLDrawPool::POOL_INVISIBLE:
00754 poolp = mInvisiblePool;
00755 break;
00756
00757 case LLDrawPool::POOL_GLOW:
00758 poolp = mGlowPool;
00759 break;
00760
00761 case LLDrawPool::POOL_TREE:
00762 poolp = get_if_there(mTreePools, (uintptr_t)tex0, (LLDrawPool*)0 );
00763 break;
00764
00765 case LLDrawPool::POOL_TERRAIN:
00766 poolp = get_if_there(mTerrainPools, (uintptr_t)tex0, (LLDrawPool*)0 );
00767 break;
00768
00769 case LLDrawPool::POOL_BUMP:
00770 poolp = mBumpPool;
00771 break;
00772
00773 case LLDrawPool::POOL_ALPHA:
00774 poolp = mAlphaPool;
00775 break;
00776
00777 case LLDrawPool::POOL_AVATAR:
00778 break;
00779
00780 case LLDrawPool::POOL_SKY:
00781 poolp = mSkyPool;
00782 break;
00783
00784 case LLDrawPool::POOL_WATER:
00785 poolp = mWaterPool;
00786 break;
00787
00788 case LLDrawPool::POOL_GROUND:
00789 poolp = mGroundPool;
00790 break;
00791
00792 case LLDrawPool::POOL_WL_SKY:
00793 poolp = mWLSkyPool;
00794 break;
00795
00796 default:
00797 llassert(0);
00798 llerrs << "Invalid Pool Type in LLPipeline::findPool() type=" << type << llendl;
00799 break;
00800 }
00801
00802 return poolp;
00803 }
00804
00805
00806 LLDrawPool *LLPipeline::getPool(const U32 type, LLViewerImage *tex0)
00807 {
00808 LLMemType mt(LLMemType::MTYPE_PIPELINE);
00809 LLDrawPool *poolp = findPool(type, tex0);
00810 if (poolp)
00811 {
00812 return poolp;
00813 }
00814
00815 LLDrawPool *new_poolp = LLDrawPool::createPool(type, tex0);
00816 addPool( new_poolp );
00817
00818 return new_poolp;
00819 }
00820
00821
00822
00823 LLDrawPool* LLPipeline::getPoolFromTE(const LLTextureEntry* te, LLViewerImage* imagep)
00824 {
00825 LLMemType mt(LLMemType::MTYPE_PIPELINE);
00826 U32 type = getPoolTypeFromTE(te, imagep);
00827 return gPipeline.getPool(type, imagep);
00828 }
00829
00830
00831 U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerImage* imagep)
00832 {
00833 LLMemType mt(LLMemType::MTYPE_PIPELINE);
00834
00835 if (!te || !imagep)
00836 {
00837 return 0;
00838 }
00839
00840 bool alpha = te->getColor().mV[3] < 0.999f;
00841 if (imagep)
00842 {
00843 alpha = alpha || (imagep->getComponents() == 4 && ! imagep->mIsMediaTexture) || (imagep->getComponents() == 2);
00844 }
00845
00846 if (alpha)
00847 {
00848 return LLDrawPool::POOL_ALPHA;
00849 }
00850 else if ((te->getBumpmap() || te->getShiny()))
00851 {
00852 return LLDrawPool::POOL_BUMP;
00853 }
00854 else
00855 {
00856 return LLDrawPool::POOL_SIMPLE;
00857 }
00858 }
00859
00860
00861 void LLPipeline::addPool(LLDrawPool *new_poolp)
00862 {
00863 LLMemType mt(LLMemType::MTYPE_PIPELINE);
00864 assertInitialized();
00865 mPools.insert(new_poolp);
00866 addToQuickLookup( new_poolp );
00867 }
00868
00869 void LLPipeline::allocDrawable(LLViewerObject *vobj)
00870 {
00871 LLMemType mt(LLMemType::MTYPE_DRAWABLE);
00872 LLDrawable *drawable = new LLDrawable();
00873 vobj->mDrawable = drawable;
00874
00875 drawable->mVObjp = vobj;
00876
00877
00878
00879 drawable->setRadius(LLVector3(1,1,0.5f).scaleVec(vobj->getScale()).magVec());
00880 if (vobj->isOrphaned())
00881 {
00882 drawable->setState(LLDrawable::FORCE_INVISIBLE);
00883 }
00884 drawable->updateXform(TRUE);
00885 }
00886
00887
00888 void LLPipeline::unlinkDrawable(LLDrawable *drawable)
00889 {
00890 LLFastTimer t(LLFastTimer::FTM_PIPELINE);
00891
00892 assertInitialized();
00893
00894 LLPointer<LLDrawable> drawablep = drawable;
00895
00896
00897 if (drawablep->isState(LLDrawable::ON_MOVE_LIST))
00898 {
00899 LLDrawable::drawable_vector_t::iterator iter = std::find(mMovedList.begin(), mMovedList.end(), drawablep);
00900 if (iter != mMovedList.end())
00901 {
00902 mMovedList.erase(iter);
00903 }
00904 }
00905
00906 if (drawablep->getSpatialGroup())
00907 {
00908 if (!drawablep->getSpatialGroup()->mSpatialPartition->remove(drawablep, drawablep->getSpatialGroup()))
00909 {
00910 #ifdef LL_RELEASE_FOR_DOWNLOAD
00911 llwarns << "Couldn't remove object from spatial group!" << llendl;
00912 #else
00913 llerrs << "Couldn't remove object from spatial group!" << llendl;
00914 #endif
00915 }
00916 }
00917
00918 mLights.erase(drawablep);
00919 }
00920
00921 U32 LLPipeline::addObject(LLViewerObject *vobj)
00922 {
00923 LLMemType mt(LLMemType::MTYPE_DRAWABLE);
00924 if (gNoRender)
00925 {
00926 return 0;
00927 }
00928
00929 LLDrawable* drawablep = vobj->mDrawable;
00930
00931 if (!drawablep)
00932 {
00933 drawablep = vobj->createDrawable(this);
00934 }
00935
00936 llassert(drawablep);
00937
00938 if (vobj->getParent())
00939 {
00940 vobj->setDrawableParent(((LLViewerObject*)vobj->getParent())->mDrawable);
00941 }
00942 else
00943 {
00944 vobj->setDrawableParent(NULL);
00945 }
00946
00947 markRebuild(drawablep, LLDrawable::REBUILD_ALL, TRUE);
00948
00949 return 1;
00950 }
00951
00952
00953 void LLPipeline::resetFrameStats()
00954 {
00955 assertInitialized();
00956
00957 mTrianglesDrawnStat.addValue(mTrianglesDrawn/1000.f);
00958
00959 if (mBatchCount > 0)
00960 {
00961 mMeanBatchSize = gPipeline.mTrianglesDrawn/gPipeline.mBatchCount;
00962 }
00963 mTrianglesDrawn = 0;
00964 sCompiles = 0;
00965 mVerticesRelit = 0;
00966 mLightingChanges = 0;
00967 mGeometryChanges = 0;
00968 mNumVisibleFaces = 0;
00969
00970 if (mOldRenderDebugMask != mRenderDebugMask)
00971 {
00972 gObjectList.clearDebugText();
00973 mOldRenderDebugMask = mRenderDebugMask;
00974 }
00975
00976 }
00977
00978
00979 void LLPipeline::updateMoveDampedAsync(LLDrawable* drawablep)
00980 {
00981 if (gSavedSettings.getBOOL("FreezeTime"))
00982 {
00983 return;
00984 }
00985 if (!drawablep)
00986 {
00987 llerrs << "updateMove called with NULL drawablep" << llendl;
00988 return;
00989 }
00990 if (drawablep->isState(LLDrawable::EARLY_MOVE))
00991 {
00992 return;
00993 }
00994
00995 assertInitialized();
00996
00997
00998 drawablep->clearState(LLDrawable::MOVE_UNDAMPED);
00999 drawablep->updateMove();
01000 drawablep->setState(LLDrawable::EARLY_MOVE);
01001
01002 if (!drawablep->isState(LLDrawable::ON_MOVE_LIST))
01003 {
01004 mMovedList.push_back(drawablep);
01005 drawablep->setState(LLDrawable::ON_MOVE_LIST);
01006 }
01007 }
01008
01009 void LLPipeline::updateMoveNormalAsync(LLDrawable* drawablep)
01010 {
01011 if (gSavedSettings.getBOOL("FreezeTime"))
01012 {
01013 return;
01014 }
01015 if (!drawablep)
01016 {
01017 llerrs << "updateMove called with NULL drawablep" << llendl;
01018 }
01019 if (drawablep->isState(LLDrawable::EARLY_MOVE))
01020 {
01021 return;
01022 }
01023
01024 assertInitialized();
01025
01026
01027 drawablep->setState(LLDrawable::MOVE_UNDAMPED);
01028 drawablep->updateMove();
01029 drawablep->setState(LLDrawable::EARLY_MOVE);
01030
01031 if (!drawablep->isState(LLDrawable::ON_MOVE_LIST))
01032 {
01033 mMovedList.push_back(drawablep);
01034 drawablep->setState(LLDrawable::ON_MOVE_LIST);
01035 }
01036 }
01037
01038 void LLPipeline::updateMovedList(LLDrawable::drawable_vector_t& moved_list)
01039 {
01040 for (LLDrawable::drawable_vector_t::iterator iter = moved_list.begin();
01041 iter != moved_list.end(); )
01042 {
01043 LLDrawable::drawable_vector_t::iterator curiter = iter++;
01044 LLDrawable *drawablep = *curiter;
01045 BOOL done = TRUE;
01046 if (!drawablep->isDead() && (!drawablep->isState(LLDrawable::EARLY_MOVE)))
01047 {
01048 done = drawablep->updateMove();
01049 }
01050 drawablep->clearState(LLDrawable::EARLY_MOVE | LLDrawable::MOVE_UNDAMPED);
01051 if (done)
01052 {
01053 drawablep->clearState(LLDrawable::ON_MOVE_LIST);
01054 iter = moved_list.erase(curiter);
01055 }
01056 }
01057 }
01058
01059 void LLPipeline::updateMove()
01060 {
01061 LLFastTimer t(LLFastTimer::FTM_UPDATE_MOVE);
01062 LLMemType mt(LLMemType::MTYPE_PIPELINE);
01063
01064 if (gSavedSettings.getBOOL("FreezeTime"))
01065 {
01066 return;
01067 }
01068
01069 assertInitialized();
01070
01071 for (LLDrawable::drawable_set_t::iterator iter = mRetexturedList.begin();
01072 iter != mRetexturedList.end(); ++iter)
01073 {
01074 LLDrawable* drawablep = *iter;
01075 if (drawablep && !drawablep->isDead())
01076 {
01077 drawablep->updateTexture();
01078 }
01079 }
01080 mRetexturedList.clear();
01081
01082 updateMovedList(mMovedList);
01083
01084 for (LLDrawable::drawable_set_t::iterator iter = mActiveQ.begin();
01085 iter != mActiveQ.end(); )
01086 {
01087 LLDrawable::drawable_set_t::iterator curiter = iter++;
01088 LLDrawable* drawablep = *curiter;
01089 if (drawablep && !drawablep->isDead())
01090 {
01091 if (drawablep->isRoot() &&
01092 drawablep->mQuietCount++ > MAX_ACTIVE_OBJECT_QUIET_FRAMES &&
01093 (!drawablep->getParent() || !drawablep->getParent()->isActive()))
01094 {
01095 drawablep->makeStatic();
01096 iter = mActiveQ.upper_bound(drawablep);
01097 }
01098 }
01099 else
01100 {
01101 mActiveQ.erase(curiter);
01102 }
01103 }
01104
01105
01106 {
01107 LLFastTimer ot(LLFastTimer::FTM_OCTREE_BALANCE);
01108
01109 for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin();
01110 iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
01111 {
01112 LLViewerRegion* region = *iter;
01113 for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
01114 {
01115 LLSpatialPartition* part = region->getSpatialPartition(i);
01116 if (part)
01117 {
01118 part->mOctree->balance();
01119 }
01120 }
01121 }
01122 }
01123 }
01124
01126
01128
01129
01130 F32 LLPipeline::calcPixelArea(LLVector3 center, LLVector3 size, LLCamera &camera)
01131 {
01132 LLVector3 lookAt = center - camera.getOrigin();
01133 F32 dist = lookAt.magVec();
01134
01135
01136 if (dist < 16.f)
01137 {
01138 dist /= 16.f;
01139 dist *= dist;
01140 dist *= 16.f;
01141 }
01142
01143
01144 F32 app_angle = atanf(size.magVec()/dist);
01145 F32 radius = app_angle*LLDrawable::sCurPixelAngle;
01146 return radius*radius * 3.14159f;
01147 }
01148
01149 void LLPipeline::grabReferences(LLCullResult& result)
01150 {
01151 sCull = &result;
01152 }
01153
01154 void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_clip)
01155 {
01156 LLFastTimer t(LLFastTimer::FTM_CULL);
01157 LLMemType mt(LLMemType::MTYPE_PIPELINE);
01158
01159 grabReferences(result);
01160
01161 sCull->clear();
01162
01163 BOOL to_texture = LLPipeline::sUseOcclusion > 1 &&
01164 !hasRenderType(LLPipeline::RENDER_TYPE_HUD) &&
01165 !sReflectionRender &&
01166 gPipeline.canUseVertexShaders() &&
01167 sRenderGlow;
01168
01169 if (to_texture)
01170 {
01171 mScreen.bindTarget();
01172 }
01173
01174 glPushMatrix();
01175 gGLLastMatrix = NULL;
01176 glLoadMatrixd(gGLLastModelView);
01177
01178 LLVertexBuffer::unbind();
01179 LLGLDisable blend(GL_BLEND);
01180 LLGLDisable test(GL_ALPHA_TEST);
01181 LLViewerImage::unbindTexture(0, GL_TEXTURE_2D);
01182
01183 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
01184 LLGLDepthTest depth(GL_TRUE, GL_FALSE);
01185
01186 for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin();
01187 iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
01188 {
01189 LLViewerRegion* region = *iter;
01190 if (water_clip != 0)
01191 {
01192 LLPlane plane(LLVector3(0,0, (F32) -water_clip), (F32) water_clip*region->getWaterHeight());
01193 camera.setUserClipPlane(plane);
01194 }
01195 else
01196 {
01197 camera.disableUserClipPlane();
01198 }
01199
01200 for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
01201 {
01202 LLSpatialPartition* part = region->getSpatialPartition(i);
01203 if (part)
01204 {
01205 if (hasRenderType(part->mDrawableType))
01206 {
01207 part->cull(camera);
01208 }
01209 }
01210 }
01211 }
01212
01213 camera.disableUserClipPlane();
01214
01215 if (gSky.mVOSkyp.notNull() && gSky.mVOSkyp->mDrawable.notNull())
01216 {
01217
01218 if (hasRenderType(LLPipeline::RENDER_TYPE_SKY))
01219 {
01220 gSky.mVOSkyp->mDrawable->setVisible(camera);
01221 sCull->pushDrawable(gSky.mVOSkyp->mDrawable);
01222 gSky.updateCull();
01223 stop_glerror();
01224 }
01225 }
01226 else
01227 {
01228 llinfos << "No sky drawable!" << llendl;
01229 }
01230
01231 if (hasRenderType(LLPipeline::RENDER_TYPE_GROUND) &&
01232 !gPipeline.canUseWindLightShaders() &&
01233 gSky.mVOGroundp.notNull() &&
01234 gSky.mVOGroundp->mDrawable.notNull() &&
01235 !LLPipeline::sWaterReflections)
01236 {
01237 gSky.mVOGroundp->mDrawable->setVisible(camera);
01238 sCull->pushDrawable(gSky.mVOGroundp->mDrawable);
01239 }
01240
01241 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
01242 glPopMatrix();
01243
01244 if (to_texture)
01245 {
01246 mScreen.flush();
01247 LLRenderTarget::unbindTarget();
01248 }
01249 else if (LLPipeline::sUseOcclusion > 1)
01250 {
01251 glFlush();
01252 }
01253 }
01254
01255 void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera)
01256 {
01257 if (group->getData().empty())
01258 {
01259 return;
01260 }
01261
01262 group->setVisible();
01263
01264 if (!sSkipUpdate)
01265 {
01266 group->updateDistance(camera);
01267 }
01268
01269 const F32 MINIMUM_PIXEL_AREA = 16.f;
01270
01271 if (group->mPixelArea < MINIMUM_PIXEL_AREA)
01272 {
01273 return;
01274 }
01275
01276 assertInitialized();
01277
01278 if (!group->mSpatialPartition->mRenderByGroup)
01279 {
01280 sCull->pushDrawableGroup(group);
01281 }
01282 else
01283 {
01284 sCull->pushVisibleGroup(group);
01285 }
01286
01287 mNumVisibleNodes++;
01288 }
01289
01290 void LLPipeline::markOccluder(LLSpatialGroup* group)
01291 {
01292 if (sUseOcclusion > 1 && group && !group->isState(LLSpatialGroup::ACTIVE_OCCLUSION))
01293 {
01294 LLSpatialGroup* parent = group->getParent();
01295
01296 if (!parent || !parent->isState(LLSpatialGroup::OCCLUDED))
01297 {
01298 sCull->pushOcclusionGroup(group);
01299 group->setState(LLSpatialGroup::ACTIVE_OCCLUSION);
01300
01301 if (parent &&
01302 !parent->isState(LLSpatialGroup::ACTIVE_OCCLUSION) &&
01303 parent->getElementCount() == 0 &&
01304 parent->needsUpdate())
01305 {
01306 sCull->pushOcclusionGroup(group);
01307 parent->setState(LLSpatialGroup::ACTIVE_OCCLUSION);
01308 }
01309 }
01310 }
01311 }
01312
01313 void LLPipeline::doOcclusion(LLCamera& camera)
01314 {
01315 LLVertexBuffer::unbind();
01316 if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION))
01317 {
01318 glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_FALSE);
01319 }
01320 else
01321 {
01322 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
01323 }
01324 LLGLDisable blend(GL_BLEND);
01325 LLGLDisable test(GL_ALPHA_TEST);
01326 LLViewerImage::unbindTexture(0, GL_TEXTURE_2D);
01327 LLGLDepthTest depth(GL_TRUE, GL_FALSE);
01328
01329 if (LLPipeline::sUseOcclusion > 1)
01330 {
01331 for (LLCullResult::sg_list_t::iterator iter = sCull->beginOcclusionGroups(); iter != sCull->endOcclusionGroups(); ++iter)
01332 {
01333 LLSpatialGroup* group = *iter;
01334 group->doOcclusion(&camera);
01335 group->clearState(LLSpatialGroup::ACTIVE_OCCLUSION);
01336 }
01337 }
01338
01339 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
01340 glFlush();
01341 }
01342
01343 BOOL LLPipeline::updateDrawableGeom(LLDrawable* drawablep, BOOL priority)
01344 {
01345 BOOL update_complete = drawablep->updateGeometry(priority);
01346 if (update_complete && assertInitialized())
01347 {
01348 drawablep->setState(LLDrawable::BUILT);
01349 mGeometryChanges++;
01350 }
01351 return update_complete;
01352 }
01353
01354 void LLPipeline::updateGeom(F32 max_dtime)
01355 {
01356 LLTimer update_timer;
01357 LLMemType mt(LLMemType::MTYPE_PIPELINE);
01358 LLPointer<LLDrawable> drawablep;
01359
01360 LLFastTimer t(LLFastTimer::FTM_GEO_UPDATE);
01361
01362 assertInitialized();
01363
01364 if (sDelayedVBOEnable > 0)
01365 {
01366 if (--sDelayedVBOEnable <= 0)
01367 {
01368 resetVertexBuffers();
01369 LLVertexBuffer::sEnableVBOs = TRUE;
01370 }
01371 }
01372
01373
01374
01375 LLVOVolume::preUpdateGeom();
01376
01377
01378 for (LLDrawable::drawable_list_t::iterator iter = mBuildQ1.begin();
01379 iter != mBuildQ1.end();)
01380 {
01381 LLDrawable::drawable_list_t::iterator curiter = iter++;
01382 LLDrawable* drawablep = *curiter;
01383 if (drawablep && !drawablep->isDead())
01384 {
01385 if (drawablep->isState(LLDrawable::IN_REBUILD_Q2))
01386 {
01387 drawablep->clearState(LLDrawable::IN_REBUILD_Q2);
01388 LLDrawable::drawable_list_t::iterator find = std::find(mBuildQ2.begin(), mBuildQ2.end(), drawablep);
01389 if (find != mBuildQ2.end())
01390 {
01391 mBuildQ2.erase(find);
01392 }
01393 }
01394
01395 if (updateDrawableGeom(drawablep, TRUE))
01396 {
01397 drawablep->clearState(LLDrawable::IN_REBUILD_Q1);
01398 mBuildQ1.erase(curiter);
01399 }
01400 }
01401 else
01402 {
01403 mBuildQ1.erase(curiter);
01404 }
01405 }
01406
01407
01408 S32 min_count = 16;
01409 S32 size = (S32) mBuildQ2.size();
01410 if (size > 1024)
01411 {
01412 min_count = llclamp((S32) (size * (F32) size/4096), 16, size);
01413 }
01414
01415 S32 count = 0;
01416
01417 max_dtime = llmax(update_timer.getElapsedTimeF32()+0.001f, max_dtime);
01418 LLSpatialGroup* last_group = NULL;
01419 LLSpatialBridge* last_bridge = NULL;
01420
01421 for (LLDrawable::drawable_list_t::iterator iter = mBuildQ2.begin();
01422 iter != mBuildQ2.end(); )
01423 {
01424 LLDrawable::drawable_list_t::iterator curiter = iter++;
01425 LLDrawable* drawablep = *curiter;
01426
01427 LLSpatialBridge* bridge = drawablep->isRoot() ? drawablep->getSpatialBridge() :
01428 drawablep->getParent()->getSpatialBridge();
01429
01430 if (drawablep->getSpatialGroup() != last_group &&
01431 (!last_bridge || bridge != last_bridge) &&
01432 (update_timer.getElapsedTimeF32() >= max_dtime) && count > min_count)
01433 {
01434 break;
01435 }
01436
01437
01438
01439 last_group = drawablep->getSpatialGroup();
01440 last_bridge = bridge;
01441
01442 BOOL update_complete = TRUE;
01443 if (!drawablep->isDead())
01444 {
01445 update_complete = updateDrawableGeom(drawablep, FALSE);
01446 count++;
01447 }
01448 if (update_complete)
01449 {
01450 drawablep->clearState(LLDrawable::IN_REBUILD_Q2);
01451 mBuildQ2.erase(curiter);
01452 }
01453 }
01454
01455 updateMovedList(mMovedBridge);
01456 }
01457
01458 void LLPipeline::markVisible(LLDrawable *drawablep, LLCamera& camera)
01459 {
01460 LLMemType mt(LLMemType::MTYPE_PIPELINE);
01461 if(!drawablep || drawablep->isDead())
01462 {
01463 return;
01464 }
01465
01466 if (drawablep->isSpatialBridge())
01467 {
01468 sCull->pushBridge((LLSpatialBridge*) drawablep);
01469 }
01470 else
01471 {
01472 sCull->pushDrawable(drawablep);
01473 }
01474
01475 drawablep->setVisible(camera);
01476 }
01477
01478 void LLPipeline::markMoved(LLDrawable *drawablep, BOOL damped_motion)
01479 {
01480 LLMemType mt(LLMemType::MTYPE_PIPELINE);
01481
01482 if (!drawablep)
01483 {
01484 llerrs << "Sending null drawable to moved list!" << llendl;
01485 return;
01486 }
01487
01488 if (drawablep->isDead())
01489 {
01490 llwarns << "Marking NULL or dead drawable moved!" << llendl;
01491 return;
01492 }
01493
01494 if (drawablep->getParent())
01495 {
01496
01497 markMoved(drawablep->getParent(), damped_motion);
01498 }
01499
01500 assertInitialized();
01501
01502 if (!drawablep->isState(LLDrawable::ON_MOVE_LIST))
01503 {
01504 if (drawablep->isSpatialBridge())
01505 {
01506 mMovedBridge.push_back(drawablep);
01507 }
01508 else
01509 {
01510 mMovedList.push_back(drawablep);
01511 }
01512 drawablep->setState(LLDrawable::ON_MOVE_LIST);
01513 }
01514 if (damped_motion == FALSE)
01515 {
01516 drawablep->setState(LLDrawable::MOVE_UNDAMPED);
01517 }
01518 else if (drawablep->isState(LLDrawable::MOVE_UNDAMPED))
01519 {
01520 drawablep->clearState(LLDrawable::MOVE_UNDAMPED);
01521 }
01522 }
01523
01524 void LLPipeline::markShift(LLDrawable *drawablep)
01525 {
01526 LLMemType mt(LLMemType::MTYPE_PIPELINE);
01527
01528 if (!drawablep || drawablep->isDead())
01529 {
01530 return;
01531 }
01532
01533 assertInitialized();
01534
01535 if (!drawablep->isState(LLDrawable::ON_SHIFT_LIST))
01536 {
01537 drawablep->getVObj()->setChanged(LLXform::SHIFTED | LLXform::SILHOUETTE);
01538 if (drawablep->getParent())
01539 {
01540 markShift(drawablep->getParent());
01541 }
01542 mShiftList.push_back(drawablep);
01543 drawablep->setState(LLDrawable::ON_SHIFT_LIST);
01544 }
01545 }
01546
01547 void LLPipeline::shiftObjects(const LLVector3 &offset)
01548 {
01549 LLMemType mt(LLMemType::MTYPE_PIPELINE);
01550
01551 assertInitialized();
01552
01553
01554 render_ui_and_swap_if_needed();
01555 glClear(GL_DEPTH_BUFFER_BIT);
01556 gDisplaySwapBuffers = FALSE;
01557
01558 for (LLDrawable::drawable_vector_t::iterator iter = mShiftList.begin();
01559 iter != mShiftList.end(); iter++)
01560 {
01561 LLDrawable *drawablep = *iter;
01562 if (drawablep->isDead())
01563 {
01564 continue;
01565 }
01566 drawablep->shiftPos(offset);
01567 drawablep->clearState(LLDrawable::ON_SHIFT_LIST);
01568 }
01569 mShiftList.resize(0);
01570
01571 for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin();
01572 iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
01573 {
01574 LLViewerRegion* region = *iter;
01575 for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
01576 {
01577 LLSpatialPartition* part = region->getSpatialPartition(i);
01578 if (part)
01579 {
01580 part->shift(offset);
01581 }
01582 }
01583 }
01584 }
01585
01586 void LLPipeline::markTextured(LLDrawable *drawablep)
01587 {
01588 LLMemType mt(LLMemType::MTYPE_PIPELINE);
01589
01590 if (drawablep && !drawablep->isDead() && assertInitialized())
01591 {
01592 mRetexturedList.insert(drawablep);
01593 }
01594 }
01595
01596 void LLPipeline::markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags flag, BOOL priority)
01597 {
01598 LLMemType mt(LLMemType::MTYPE_PIPELINE);
01599
01600 if (drawablep && !drawablep->isDead() && assertInitialized())
01601 {
01602 if (!drawablep->isState(LLDrawable::BUILT))
01603 {
01604 priority = TRUE;
01605 }
01606 if (priority)
01607 {
01608 if (!drawablep->isState(LLDrawable::IN_REBUILD_Q1))
01609 {
01610 mBuildQ1.push_back(drawablep);
01611 drawablep->setState(LLDrawable::IN_REBUILD_Q1);
01612 }
01613 }
01614 else if (!drawablep->isState(LLDrawable::IN_REBUILD_Q2))
01615 {
01616 mBuildQ2.push_back(drawablep);
01617 drawablep->setState(LLDrawable::IN_REBUILD_Q2);
01618 }
01619 if (flag & (LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION))
01620 {
01621 drawablep->getVObj()->setChanged(LLXform::SILHOUETTE);
01622 }
01623 drawablep->setState(flag);
01624 }
01625 }
01626
01627 void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
01628 {
01629 const U32 face_mask = (1 << LLPipeline::RENDER_TYPE_AVATAR) |
01630 (1 << LLPipeline::RENDER_TYPE_GROUND) |
01631 (1 << LLPipeline::RENDER_TYPE_TERRAIN) |
01632 (1 << LLPipeline::RENDER_TYPE_TREE) |
01633 (1 << LLPipeline::RENDER_TYPE_SKY) |
01634 (1 << LLPipeline::RENDER_TYPE_WATER);
01635
01636 if (mRenderTypeMask & face_mask)
01637 {
01638
01639 LLFastTimer t(LLFastTimer::FTM_RESET_DRAWORDER);
01640 gPipeline.resetDrawOrders();
01641 }
01642
01643 LLFastTimer ftm(LLFastTimer::FTM_STATESORT);
01644 LLMemType mt(LLMemType::MTYPE_PIPELINE);
01645
01646
01647
01648 grabReferences(result);
01649
01650 {
01651 for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter)
01652 {
01653 LLSpatialGroup* group = *iter;
01654 group->checkOcclusion();
01655 if (sUseOcclusion && group->isState(LLSpatialGroup::OCCLUDED))
01656 {
01657 markOccluder(group);
01658 }
01659 else
01660 {
01661 group->setVisible();
01662 for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i)
01663 {
01664 markVisible(*i, camera);
01665 }
01666 }
01667 }
01668
01669 for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
01670 {
01671 LLSpatialGroup* group = *iter;
01672 group->checkOcclusion();
01673 if (sUseOcclusion && group->isState(LLSpatialGroup::OCCLUDED))
01674 {
01675 markOccluder(group);
01676 }
01677 else
01678 {
01679 group->setVisible();
01680 stateSort(group, camera);
01681 }
01682 }
01683 }
01684
01685 {
01686 for (LLCullResult::bridge_list_t::iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i)
01687 {
01688 LLCullResult::bridge_list_t::iterator cur_iter = i;
01689 LLSpatialBridge* bridge = *cur_iter;
01690 LLSpatialGroup* group = bridge->getSpatialGroup();
01691 if (!bridge->isDead() && group && !group->isState(LLSpatialGroup::OCCLUDED))
01692 {
01693 stateSort(bridge, camera);
01694 }
01695 }
01696 }
01697
01698 {
01699 LLFastTimer ftm(LLFastTimer::FTM_STATESORT_DRAWABLE);
01700 for (LLCullResult::drawable_list_t::iterator iter = sCull->beginVisibleList();
01701 iter != sCull->endVisibleList(); ++iter)
01702 {
01703 LLDrawable *drawablep = *iter;
01704 if (!drawablep->isDead())
01705 {
01706 stateSort(drawablep, camera);
01707 }
01708 }
01709 }
01710
01711 {
01712 LLFastTimer ftm(LLFastTimer::FTM_CLIENT_COPY);
01713 LLVertexBuffer::clientCopy();
01714 }
01715
01716 postSort(camera);
01717 }
01718
01719 void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera)
01720 {
01721 LLMemType mt(LLMemType::MTYPE_PIPELINE);
01722 if (!sSkipUpdate && group->changeLOD())
01723 {
01724 for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i)
01725 {
01726 LLDrawable* drawablep = *i;
01727 stateSort(drawablep, camera);
01728 }
01729 }
01730 }
01731
01732 void LLPipeline::stateSort(LLSpatialBridge* bridge, LLCamera& camera)
01733 {
01734 LLMemType mt(LLMemType::MTYPE_PIPELINE);
01735 if (!sSkipUpdate && bridge->getSpatialGroup()->changeLOD())
01736 {
01737 bridge->updateDistance(camera);
01738 }
01739 }
01740
01741 void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera)
01742 {
01743 LLMemType mt(LLMemType::MTYPE_PIPELINE);
01744
01745 if (!drawablep
01746 || drawablep->isDead()
01747 || !hasRenderType(drawablep->getRenderType()))
01748 {
01749 return;
01750 }
01751
01752 if (gHideSelectedObjects)
01753 {
01754 if (drawablep->getVObj().notNull() &&
01755 drawablep->getVObj()->isSelected())
01756 {
01757 return;
01758 }
01759 }
01760
01761 if (drawablep->isAvatar())
01762 {
01763 if ((drawablep->getSpatialGroup() == NULL) ||
01764 (drawablep->getSpatialGroup()->mDistance > LLVOAvatar::sRenderDistance))
01765 {
01766 return;
01767 }
01768 }
01769
01770 assertInitialized();
01771
01772 if (hasRenderType(drawablep->mRenderType))
01773 {
01774 if (!drawablep->isState(LLDrawable::INVISIBLE|LLDrawable::FORCE_INVISIBLE))
01775 {
01776 drawablep->setVisible(camera, NULL, FALSE);
01777 }
01778 else if (drawablep->isState(LLDrawable::CLEAR_INVISIBLE))
01779 {
01780
01781 drawablep->clearState(LLDrawable::FORCE_INVISIBLE|LLDrawable::CLEAR_INVISIBLE);
01782 }
01783 }
01784
01785 LLSpatialGroup* group = drawablep->getSpatialGroup();
01786 if (!group || group->changeLOD())
01787 {
01788 if (!drawablep->isActive() && drawablep->isVisible())
01789 {
01790 if (!sSkipUpdate)
01791 {
01792 drawablep->updateDistance(camera);
01793 }
01794 }
01795 else if (drawablep->isAvatar() && drawablep->isVisible())
01796 {
01797 LLVOAvatar* vobj = (LLVOAvatar*) drawablep->getVObj().get();
01798 vobj->updateVisibility();
01799 }
01800 }
01801
01802 for (LLDrawable::face_list_t::iterator iter = drawablep->mFaces.begin();
01803 iter != drawablep->mFaces.end(); iter++)
01804 {
01805 LLFace* facep = *iter;
01806
01807 if (facep->hasGeometry())
01808 {
01809 if (facep->getPool())
01810 {
01811 facep->getPool()->enqueue(facep);
01812 }
01813 else
01814 {
01815 break;
01816 }
01817 }
01818 }
01819
01820 mNumVisibleFaces += drawablep->getNumFaces();
01821 }
01822
01823
01824 void forAllDrawables(LLCullResult::sg_list_t::iterator begin,
01825 LLCullResult::sg_list_t::iterator end,
01826 void (*func)(LLDrawable*))
01827 {
01828 for (LLCullResult::sg_list_t::iterator i = begin; i != end; ++i)
01829 {
01830 for (LLSpatialGroup::element_iter j = (*i)->getData().begin(); j != (*i)->getData().end(); ++j)
01831 {
01832 func(*j);
01833 }
01834 }
01835 }
01836
01837 void LLPipeline::forAllVisibleDrawables(void (*func)(LLDrawable*))
01838 {
01839 forAllDrawables(sCull->beginDrawableGroups(), sCull->endDrawableGroups(), func);
01840 forAllDrawables(sCull->beginVisibleGroups(), sCull->endVisibleGroups(), func);
01841 }
01842
01843
01844 void renderScriptedBeacons(LLDrawable* drawablep)
01845 {
01846 LLViewerObject *vobj = drawablep->getVObj();
01847 if (vobj
01848 && !vobj->isAvatar()
01849 && !vobj->getParent()
01850 && vobj->flagScripted())
01851 {
01852 if (gPipeline.sRenderBeacons)
01853 {
01854 gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(1.f, 0.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), gSavedSettings.getS32("DebugBeaconLineWidth"));
01855 }
01856
01857 if (gPipeline.sRenderHighlight)
01858 {
01859 S32 face_id;
01860 S32 count = drawablep->getNumFaces();
01861 for (face_id = 0; face_id < count; face_id++)
01862 {
01863 gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) );
01864 }
01865 }
01866 }
01867 }
01868
01869 void renderScriptedTouchBeacons(LLDrawable* drawablep)
01870 {
01871 LLViewerObject *vobj = drawablep->getVObj();
01872 if (vobj
01873 && !vobj->isAvatar()
01874 && !vobj->getParent()
01875 && vobj->flagScripted()
01876 && vobj->flagHandleTouch())
01877 {
01878 if (gPipeline.sRenderBeacons)
01879 {
01880 gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(1.f, 0.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), gSavedSettings.getS32("DebugBeaconLineWidth"));
01881 }
01882
01883 if (gPipeline.sRenderHighlight)
01884 {
01885 S32 face_id;
01886 S32 count = drawablep->getNumFaces();
01887 for (face_id = 0; face_id < count; face_id++)
01888 {
01889 gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) );
01890 }
01891 }
01892 }
01893 }
01894
01895 void renderPhysicalBeacons(LLDrawable* drawablep)
01896 {
01897 LLViewerObject *vobj = drawablep->getVObj();
01898 if (vobj
01899 && !vobj->isAvatar()
01900
01901 && vobj->usePhysics())
01902 {
01903 if (gPipeline.sRenderBeacons)
01904 {
01905 gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(0.f, 1.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), gSavedSettings.getS32("DebugBeaconLineWidth"));
01906 }
01907
01908 if (gPipeline.sRenderHighlight)
01909 {
01910 S32 face_id;
01911 S32 count = drawablep->getNumFaces();
01912 for (face_id = 0; face_id < count; face_id++)
01913 {
01914 gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) );
01915 }
01916 }
01917 }
01918 }
01919
01920 void renderParticleBeacons(LLDrawable* drawablep)
01921 {
01922
01923 LLViewerObject *vobj = drawablep->getVObj();
01924 if (vobj
01925 && vobj->isParticleSource())
01926 {
01927 if (gPipeline.sRenderBeacons)
01928 {
01929 LLColor4 light_blue(0.5f, 0.5f, 1.f, 0.5f);
01930 gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", light_blue, LLColor4(1.f, 1.f, 1.f, 0.5f), gSavedSettings.getS32("DebugBeaconLineWidth"));
01931 }
01932
01933 if (gPipeline.sRenderHighlight)
01934 {
01935 S32 face_id;
01936 S32 count = drawablep->getNumFaces();
01937 for (face_id = 0; face_id < count; face_id++)
01938 {
01939 gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) );
01940 }
01941 }
01942 }
01943 }
01944
01945 void renderSoundHighlights(LLDrawable* drawablep)
01946 {
01947
01948 LLViewerObject *vobj = drawablep->getVObj();
01949 if (vobj && vobj->isAudioSource())
01950 {
01951 if (gPipeline.sRenderHighlight)
01952 {
01953 S32 face_id;
01954 S32 count = drawablep->getNumFaces();
01955 for (face_id = 0; face_id < count; face_id++)
01956 {
01957 gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) );
01958 }
01959 }
01960 }
01961 }
01962
01963 void LLPipeline::postSort(LLCamera& camera)
01964 {
01965 LLMemType mt(LLMemType::MTYPE_PIPELINE);
01966 LLFastTimer ftm(LLFastTimer::FTM_STATESORT_POSTSORT);
01967
01968 assertInitialized();
01969
01970
01971 for (LLCullResult::sg_list_t::iterator i = sCull->beginDrawableGroups(); i != sCull->endDrawableGroups(); ++i)
01972 {
01973 LLSpatialGroup* group = *i;
01974 if (!sUseOcclusion ||
01975 !group->isState(LLSpatialGroup::OCCLUDED))
01976 {
01977 group->rebuildGeom();
01978 }
01979 }
01980
01981
01982 for (LLCullResult::sg_list_t::iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i)
01983 {
01984 LLSpatialGroup* group = *i;
01985 if (sUseOcclusion &&
01986 group->isState(LLSpatialGroup::OCCLUDED))
01987 {
01988 continue;
01989 }
01990
01991 group->rebuildGeom();
01992
01993 for (LLSpatialGroup::draw_map_t::iterator j = group->mDrawMap.begin(); j != group->mDrawMap.end(); ++j)
01994 {
01995 LLSpatialGroup::drawmap_elem_t& src_vec = j->second;
01996
01997 for (LLSpatialGroup::drawmap_elem_t::iterator k = src_vec.begin(); k != src_vec.end(); ++k)
01998 {
01999 sCull->pushDrawInfo(j->first, *k);
02000 }
02001 }
02002
02003 LLSpatialGroup::draw_map_t::iterator alpha = group->mDrawMap.find(LLRenderPass::PASS_ALPHA);
02004
02005 if (alpha != group->mDrawMap.end())
02006 {
02007 LLSpatialBridge* bridge = group->mSpatialPartition->asBridge();
02008 if (!sSkipUpdate)
02009 {
02010 if (bridge)
02011 {
02012 LLCamera trans_camera = bridge->transformCamera(camera);
02013 group->updateDistance(trans_camera);
02014 }
02015 else
02016 {
02017 group->updateDistance(camera);
02018 }
02019 }
02020
02021 if (hasRenderType(LLDrawPool::POOL_ALPHA))
02022 {
02023 sCull->pushAlphaGroup(group);
02024 }
02025 }
02026 }
02027
02028 {
02029
02030 for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; ++i)
02031 {
02032
02033 {
02034 if (i == LLRenderPass::PASS_BUMP)
02035 {
02036 std::sort(sCull->beginRenderMap(i), sCull->endRenderMap(i), LLDrawInfo::CompareBump());
02037 }
02038 else
02039 {
02040 std::sort(sCull->beginRenderMap(i), sCull->endRenderMap(i), LLDrawInfo::CompareTexturePtrMatrix());
02041 }
02042 }
02043 }
02044
02045 std::sort(sCull->beginAlphaGroups(), sCull->endAlphaGroups(), LLSpatialGroup::CompareDepthGreater());
02046 }
02047
02048
02049 if (sRenderProcessBeacons)
02050 {
02051 if (sRenderScriptedTouchBeacons)
02052 {
02053
02054 forAllVisibleDrawables(renderScriptedTouchBeacons);
02055 }
02056 else
02057 if (sRenderScriptedBeacons)
02058 {
02059
02060 forAllVisibleDrawables(renderScriptedBeacons);
02061 }
02062
02063 if (sRenderPhysicalBeacons)
02064 {
02065
02066 forAllVisibleDrawables(renderPhysicalBeacons);
02067 }
02068
02069 if (sRenderParticleBeacons)
02070 {
02071 forAllVisibleDrawables(renderParticleBeacons);
02072 }
02073
02074
02075 if (sRenderSoundBeacons && gAudiop)
02076 {
02077
02078 LLAudioEngine::source_map::iterator iter;
02079 for (iter = gAudiop->mAllSources.begin(); iter != gAudiop->mAllSources.end(); ++iter)
02080 {
02081 LLAudioSource *sourcep = iter->second;
02082
02083 LLVector3d pos_global = sourcep->getPositionGlobal();
02084 LLVector3 pos = gAgent.getPosAgentFromGlobal(pos_global);
02085 if (gPipeline.sRenderBeacons)
02086 {
02087
02088 gObjectList.addDebugBeacon(pos, "", LLColor4(1.f, 1.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), gSavedSettings.getS32("DebugBeaconLineWidth"));
02089 }
02090 }
02091
02092 forAllVisibleDrawables(renderSoundHighlights);
02093 }
02094 }
02095
02096
02097 if (LLFloaterTelehub::renderBeacons())
02098 {
02099 LLFloaterTelehub::addBeacons();
02100 }
02101
02102 mSelectedFaces.clear();
02103
02104
02105 if (LLSelectMgr::getInstance()->getTEMode())
02106 {
02107 struct f : public LLSelectedTEFunctor
02108 {
02109 virtual bool apply(LLViewerObject* object, S32 te)
02110 {
02111 if (object->mDrawable)
02112 {
02113 gPipeline.mSelectedFaces.push_back(object->mDrawable->getFace(te));
02114 }
02115 return true;
02116 }
02117 } func;
02118 LLSelectMgr::getInstance()->getSelection()->applyToTEs(&func);
02119 }
02120 }
02121
02122
02123 void render_hud_elements()
02124 {
02125 LLFastTimer t(LLFastTimer::FTM_RENDER_UI);
02126 gPipeline.disableLights();
02127
02128 LLGLDisable fog(GL_FOG);
02129 LLGLSUIDefault gls_ui;
02130
02131 LLGLEnable stencil(GL_STENCIL_TEST);
02132 glStencilFunc(GL_ALWAYS, 255, 0xFFFFFFFF);
02133 glStencilMask(0xFFFFFFFF);
02134 glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
02135
02136 gGL.color4f(1,1,1,1);
02137 if (!LLPipeline::sReflectionRender && gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
02138 {
02139 gViewerWindow->renderSelections(FALSE, FALSE, FALSE);
02140
02141
02142 LLTracker::render3D();
02143
02144
02145 LLWorld::getInstance()->renderPropertyLines();
02146 LLViewerParcelMgr::getInstance()->render();
02147 LLViewerParcelMgr::getInstance()->renderParcelCollision();
02148
02149
02150
02151
02152
02153 }
02154 else if (gForceRenderLandFence)
02155 {
02156
02157 LLViewerParcelMgr::getInstance()->render();
02158 }
02159 else if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD))
02160 {
02161 LLHUDText::renderAllHUD();
02162 }
02163 gGL.flush();
02164 }
02165
02166 void LLPipeline::renderHighlights()
02167 {
02168 LLMemType mt(LLMemType::MTYPE_PIPELINE);
02169
02170 assertInitialized();
02171
02172
02173
02174 LLColor4 color(1.f, 1.f, 1.f, 0.5f);
02175 LLGLEnable color_mat(GL_COLOR_MATERIAL);
02176 disableLights();
02177
02178 if ((LLShaderMgr::sVertexShaderLevel[LLShaderMgr::SHADER_INTERFACE] > 0))
02179 {
02180 gHighlightProgram.bind();
02181 gHighlightProgram.vertexAttrib4f(LLShaderMgr::MATERIAL_COLOR,1,1,1,0.5f);
02182 }
02183
02184 if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED))
02185 {
02186
02187 if (!mFaceSelectImagep)
02188 {
02189 mFaceSelectImagep = gImageList.getImage(IMG_FACE_SELECT);
02190 }
02191 mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA);
02192
02193 U32 count = mSelectedFaces.size();
02194 for (U32 i = 0; i < count; i++)
02195 {
02196 LLFace *facep = mSelectedFaces[i];
02197 if (!facep || facep->getDrawable()->isDead())
02198 {
02199 llerrs << "Bad face on selection" << llendl;
02200 return;
02201 }
02202
02203 facep->renderSelected(mFaceSelectImagep, color);
02204 }
02205 }
02206
02207 if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED))
02208 {
02209
02210 color.setVec(1.f, 0.f, 0.f, 0.5f);
02211 if ((LLShaderMgr::sVertexShaderLevel[LLShaderMgr::SHADER_INTERFACE] > 0))
02212 {
02213 gHighlightProgram.vertexAttrib4f(LLShaderMgr::MATERIAL_COLOR,1,0,0,0.5f);
02214 }
02215 int count = mHighlightFaces.size();
02216 for (S32 i = 0; i < count; i++)
02217 {
02218 LLFace* facep = mHighlightFaces[i];
02219 facep->renderSelected(LLViewerImage::sNullImagep, color);
02220 }
02221 }
02222
02223
02224
02225 mHighlightFaces.clear();
02226
02227 if (LLShaderMgr::sVertexShaderLevel[LLShaderMgr::SHADER_INTERFACE] > 0)
02228 {
02229 gHighlightProgram.unbind();
02230 }
02231 }
02232
02233 void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)
02234 {
02235 LLMemType mt(LLMemType::MTYPE_PIPELINE);
02236 LLFastTimer t(LLFastTimer::FTM_RENDER_GEOMETRY);
02237
02238 assertInitialized();
02239
02240 F64 saved_modelview[16];
02241 F64 saved_projection[16];
02242
02243
02244 if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD))
02245 {
02246 for (U32 i = 0; i < 16; i++)
02247 {
02248 saved_modelview[i] = gGLModelView[i];
02249 saved_projection[i] = gGLProjection[i];
02250 }
02251 }
02252
02254
02255
02256
02257
02258
02259 stop_glerror();
02260 gFrameStats.start(LLFrameStats::RENDER_SYNC);
02261
02262 glEnableClientState(GL_VERTEX_ARRAY);
02263
02264 LLVertexBuffer::unbind();
02265
02266
02267 LLGLState::checkStates();
02268 LLGLState::checkTextureChannels();
02269 LLGLState::checkClientArrays();
02270 if (mRenderDebugMask & RENDER_DEBUG_VERIFY)
02271 {
02272 if (!verify())
02273 {
02274 llerrs << "Pipeline verification failed!" << llendl;
02275 }
02276 }
02277
02278
02279
02280
02281
02282
02283
02284
02285 if(forceVBOUpdate)
02286 gSky.mVOSkyp->updateDummyVertexBuffer() ;
02287
02288 gFrameStats.start(LLFrameStats::RENDER_GEOM);
02289
02290
02291 glMatrixMode(GL_TEXTURE);
02292 glLoadIdentity();
02293 glMatrixMode(GL_MODELVIEW);
02294
02295 LLGLSPipeline gls_pipeline;
02296 LLGLEnable multisample(GL_MULTISAMPLE_ARB);
02297
02298 LLGLState gls_color_material(GL_COLOR_MATERIAL, mLightingDetail < 2);
02299
02300
02301 LLGLEnable cull_face(mBackfaceCull ? GL_CULL_FACE : 0);
02302
02303 BOOL use_fog = hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FOG);
02304 LLGLEnable fog_enable(use_fog &&
02305 !gPipeline.canUseWindLightShadersOnObjects() ? GL_FOG : 0);
02306 gSky.updateFog(camera.getFar());
02307 if (!use_fog)
02308 {
02309 sUnderWaterRender = FALSE;
02310 }
02311
02312 LLViewerImage::sDefaultImagep->bind(0);
02313 LLViewerImage::sDefaultImagep->setClamp(FALSE, FALSE);
02314
02316
02317
02318
02319
02320 stop_glerror();
02321 BOOL occlude = sUseOcclusion > 1;
02322
02323 U32 cur_type = 0;
02324
02325 if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PICKING))
02326 {
02327 gObjectList.renderObjectsForSelect(camera);
02328 }
02329 else if (gSavedSettings.getBOOL("RenderDeferred"))
02330 {
02331 renderGeomDeferred();
02332 }
02333 else
02334 {
02335 for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter)
02336 {
02337 LLDrawPool *poolp = *iter;
02338 if (hasRenderType(poolp->getType()))
02339 {
02340 poolp->prerender();
02341 }
02342 }
02343
02344
02345 LLFastTimer t(LLFastTimer::FTM_POOLS);
02346 calcNearbyLights(camera);
02347 setupHWLights(NULL);
02348
02349 pool_set_t::iterator iter1 = mPools.begin();
02350 while ( iter1 != mPools.end() )
02351 {
02352 LLDrawPool *poolp = *iter1;
02353
02354 cur_type = poolp->getType();
02355
02356 if (occlude && cur_type > LLDrawPool::POOL_AVATAR)
02357 {
02358 occlude = FALSE;
02359 gGLLastMatrix = NULL;
02360 glLoadMatrixd(gGLModelView);
02361 doOcclusion(camera);
02362 }
02363
02364 pool_set_t::iterator iter2 = iter1;
02365 if (hasRenderType(poolp->getType()) && poolp->getNumPasses() > 0)
02366 {
02367 LLFastTimer t(LLFastTimer::FTM_POOLRENDER);
02368
02369 gGLLastMatrix = NULL;
02370 glLoadMatrixd(gGLModelView);
02371
02372 for( S32 i = 0; i < poolp->getNumPasses(); i++ )
02373 {
02374 poolp->beginRenderPass(i);
02375 for (iter2 = iter1; iter2 != mPools.end(); iter2++)
02376 {
02377 LLDrawPool *p = *iter2;
02378 if (p->getType() != cur_type)
02379 {
02380 break;
02381 }
02382
02383 p->render(i);
02384 }
02385 poolp->endRenderPass(i);
02386 LLVertexBuffer::unbind();
02387 if (gDebugGL || gDebugPipeline)
02388 {
02389 GLint depth;
02390 glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &depth);
02391 if (depth > 3)
02392 {
02393 llerrs << "GL matrix stack corrupted!" << llendl;
02394 }
02395 LLGLState::checkStates();
02396 LLGLState::checkTextureChannels();
02397 LLGLState::checkClientArrays();
02398 }
02399 }
02400 }
02401 else
02402 {
02403
02404 for (iter2 = iter1; iter2 != mPools.end(); iter2++)
02405 {
02406 LLDrawPool *p = *iter2;
02407 if (p->getType() != cur_type)
02408 {
02409 break;
02410 }
02411 }
02412 }
02413 iter1 = iter2;
02414 stop_glerror();
02415 }
02416 }
02417
02418 LLVertexBuffer::unbind();
02419 LLGLState::checkStates();
02420 LLGLState::checkTextureChannels();
02421 LLGLState::checkClientArrays();
02422
02423 gGLLastMatrix = NULL;
02424 glLoadMatrixd(gGLModelView);
02425
02426 if (occlude)
02427 {
02428 occlude = FALSE;
02429 gGLLastMatrix = NULL;
02430 glLoadMatrixd(gGLModelView);
02431 doOcclusion(camera);
02432 }
02433
02434 stop_glerror();
02435
02436 LLGLState::checkStates();
02437 LLGLState::checkTextureChannels();
02438 LLGLState::checkClientArrays();
02439
02440 if (!sReflectionRender)
02441 {
02442 renderHighlights();
02443 }
02444
02445
02446
02447 mHighlightFaces.clear();
02448
02449 renderDebug();
02450
02451 LLVertexBuffer::unbind();
02452
02453 if (!LLPipeline::sReflectionRender && gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
02454 {
02455
02456 gObjectList.renderObjectBeacons();
02457 LLHUDObject::renderAll();
02458 gObjectList.resetObjectBeacons();
02459 }
02460
02461
02462 if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD))
02463 {
02464 for (U32 i = 0; i < 16; i++)
02465 {
02466 gGLModelView[i] = saved_modelview[i];
02467 gGLProjection[i] = saved_projection[i];
02468 }
02469 }
02470
02471 LLVertexBuffer::unbind();
02472
02473 LLGLState::checkStates();
02474 LLGLState::checkTextureChannels();
02475 LLGLState::checkClientArrays();
02476 }
02477
02478 void LLPipeline::renderGeomDeferred()
02479 {
02480 gDeferredDiffuseProgram.bind();
02481 gPipeline.renderObjects(LLRenderPass::PASS_SIMPLE, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_NORMAL, TRUE);
02482 gDeferredDiffuseProgram.unbind();
02483 }
02484
02485 void LLPipeline::addTrianglesDrawn(S32 count)
02486 {
02487 assertInitialized();
02488 mTrianglesDrawn += count;
02489 mBatchCount++;
02490 mMaxBatchSize = llmax(mMaxBatchSize, count);
02491 mMinBatchSize = llmin(mMinBatchSize, count);
02492
02493 if (LLPipeline::sRenderFrameTest)
02494 {
02495 gViewerWindow->getWindow()->swapBuffers();
02496 ms_sleep(16);
02497 }
02498 }
02499
02500 void LLPipeline::renderDebug()
02501 {
02502 LLMemType mt(LLMemType::MTYPE_PIPELINE);
02503
02504 assertInitialized();
02505
02506 gGL.color4f(1,1,1,1);
02507
02508 gGLLastMatrix = NULL;
02509 glLoadMatrixd(gGLModelView);
02510 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
02511
02512
02513 for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin();
02514 iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
02515 {
02516 LLViewerRegion* region = *iter;
02517 for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
02518 {
02519 LLSpatialPartition* part = region->getSpatialPartition(i);
02520 if (part)
02521 {
02522 if (hasRenderType(part->mDrawableType))
02523 {
02524 part->renderDebug();
02525 }
02526 }
02527 }
02528 }
02529
02530 for (LLCullResult::bridge_list_t::iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i)
02531 {
02532 LLSpatialBridge* bridge = *i;
02533 if (!bridge->isDead() && !bridge->isState(LLSpatialGroup::OCCLUDED) && hasRenderType(bridge->mDrawableType))
02534 {
02535 glPushMatrix();
02536 glMultMatrixf((F32*)bridge->mDrawable->getRenderMatrix().mMatrix);
02537 bridge->renderDebug();
02538 glPopMatrix();
02539 }
02540 }
02541
02542 if (mRenderDebugMask & RENDER_DEBUG_COMPOSITION)
02543 {
02544
02545 F32 x, y;
02546
02547 LLGLSNoTexture gls_no_texture;
02548
02549 if (gAgent.getRegion())
02550 {
02551 gGL.begin(LLVertexBuffer::POINTS);
02552
02553 for (x = 0; x <= 260; x++)
02554 {
02555 for (y = 0; y <= 260; y++)
02556 {
02557 if ((x > 255) || (y > 255))
02558 {
02559 gGL.color4f(1.f, 0.f, 0.f, 1.f);
02560 }
02561 else
02562 {
02563 gGL.color4f(0.f, 0.f, 1.f, 1.f);
02564 }
02565 F32 z = gAgent.getRegion()->getCompositionXY((S32)x, (S32)y);
02566 z *= 5.f;
02567 z += 50.f;
02568 gGL.vertex3f(x, y, z);
02569 }
02570 }
02571 gGL.end();
02572 }
02573 }
02574 gGL.flush();
02575 }
02576
02577 void LLPipeline::renderForSelect(std::set<LLViewerObject*>& objects)
02578 {
02579 assertInitialized();
02580
02581 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
02582 gPipeline.resetDrawOrders();
02583
02584 for (std::set<LLViewerObject*>::iterator iter = objects.begin(); iter != objects.end(); ++iter)
02585 {
02586 stateSort((*iter)->mDrawable, *LLViewerCamera::getInstance());
02587 }
02588
02589 LLMemType mt(LLMemType::MTYPE_PIPELINE);
02590
02591
02592
02593 glMatrixMode(GL_MODELVIEW);
02594
02595 LLGLSDefault gls_default;
02596 LLGLSObjectSelect gls_object_select;
02597 LLGLDepthTest gls_depth(GL_TRUE,GL_TRUE);
02598 disableLights();
02599
02600 LLVertexBuffer::unbind();
02601
02602
02603 LLGLState::checkStates();
02604 LLGLState::checkTextureChannels();
02605 LLGLState::checkClientArrays();
02606 U32 last_type = 0;
02607
02608 for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter)
02609 {
02610 LLDrawPool *poolp = *iter;
02611 if (poolp->isFacePool() && hasRenderType(poolp->getType()))
02612 {
02613 LLFacePool* face_pool = (LLFacePool*) poolp;
02614 face_pool->renderForSelect();
02615 LLVertexBuffer::unbind();
02616 gGLLastMatrix = NULL;
02617 glLoadMatrixd(gGLModelView);
02618
02619 if (poolp->getType() != last_type)
02620 {
02621 last_type = poolp->getType();
02622 LLGLState::checkStates();
02623 LLGLState::checkTextureChannels();
02624 LLGLState::checkClientArrays();
02625 }
02626 }
02627 }
02628
02629 LLGLEnable alpha_test(GL_ALPHA_TEST);
02630 if (gPickTransparent)
02631 {
02632 glAlphaFunc(GL_GEQUAL, 0.0f);
02633 }
02634 else
02635 {
02636 glAlphaFunc(GL_GREATER, 0.2f);
02637 }
02638
02639 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
02640 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE);
02641 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE);
02642
02643 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PRIMARY_COLOR);
02644 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
02645
02646 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
02647 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
02648
02649 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_PRIMARY_COLOR_ARB);
02650 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, GL_SRC_ALPHA);
02651
02652 U32 prim_mask = LLVertexBuffer::MAP_VERTEX |
02653 LLVertexBuffer::MAP_TEXCOORD;
02654
02655 for (std::set<LLViewerObject*>::iterator i = objects.begin(); i != objects.end(); ++i)
02656 {
02657 LLViewerObject* vobj = *i;
02658 LLDrawable* drawable = vobj->mDrawable;
02659 if (vobj->isDead() ||
02660 vobj->isHUDAttachment() ||
02661 (gHideSelectedObjects && vobj->isSelected()) ||
02662 drawable->isDead() ||
02663 !hasRenderType(drawable->getRenderType()))
02664 {
02665 continue;
02666 }
02667
02668 for (S32 j = 0; j < drawable->getNumFaces(); ++j)
02669 {
02670 LLFace* facep = drawable->getFace(j);
02671 if (!facep->getPool())
02672 {
02673 facep->renderForSelect(prim_mask);
02674 }
02675 }
02676 }
02677
02678
02679 LLVOAvatar* avatarp = gAgent.getAvatarObject();
02680 if (avatarp && sShowHUDAttachments)
02681 {
02682 glh::matrix4f save_proj(glh_get_current_projection());
02683 glh::matrix4f save_model(glh_get_current_modelview());
02684
02685 U32 viewport[4];
02686
02687 for (U32 i = 0; i < 4; i++)
02688 {
02689 viewport[i] = gGLViewport[i];
02690 }
02691
02692 setup_hud_matrices(TRUE);
02693 for (LLVOAvatar::attachment_map_t::iterator iter = avatarp->mAttachmentPoints.begin();
02694 iter != avatarp->mAttachmentPoints.end(); )
02695 {
02696 LLVOAvatar::attachment_map_t::iterator curiter = iter++;
02697 LLViewerJointAttachment* attachmentp = curiter->second;
02698 if (attachmentp->getIsHUDAttachment())
02699 {
02700 LLViewerObject* objectp = attachmentp->getObject();
02701 if (objectp)
02702 {
02703 LLDrawable* drawable = objectp->mDrawable;
02704 if (drawable->isDead())
02705 {
02706 continue;
02707 }
02708
02709 for (S32 j = 0; j < drawable->getNumFaces(); ++j)
02710 {
02711 LLFace* facep = drawable->getFace(j);
02712 if (!facep->getPool())
02713 {
02714 facep->renderForSelect(prim_mask);
02715 }
02716 }
02717
02718
02719 for (U32 k = 0; k < drawable->getChildCount(); ++k)
02720 {
02721 LLDrawable* child = drawable->getChild(k);
02722 for (S32 l = 0; l < child->getNumFaces(); ++l)
02723 {
02724 LLFace* facep = child->getFace(l);
02725 if (!facep->getPool())
02726 {
02727 facep->renderForSelect(prim_mask);
02728 }
02729 }
02730 }
02731 }
02732 }
02733 }
02734
02735 glMatrixMode(GL_PROJECTION);
02736 glLoadMatrixf(save_proj.m);
02737 glh_set_current_projection(save_proj);
02738
02739 glMatrixMode(GL_MODELVIEW);
02740 glLoadMatrixf(save_model.m);
02741 glh_set_current_modelview(save_model);
02742
02743
02744 for (U32 i = 0; i < 4; i++)
02745 {
02746 gGLViewport[i] = viewport[i];
02747 }
02748 glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
02749 }
02750
02751 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
02752
02753 LLVertexBuffer::unbind();
02754
02755 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
02756 }
02757
02758 void LLPipeline::renderFaceForUVSelect(LLFace* facep)
02759 {
02760 if (facep) facep->renderSelectedUV();
02761 }
02762
02763 void LLPipeline::rebuildPools()
02764 {
02765 LLMemType mt(LLMemType::MTYPE_PIPELINE);
02766
02767 assertInitialized();
02768
02769 S32 max_count = mPools.size();
02770 pool_set_t::iterator iter1 = mPools.upper_bound(mLastRebuildPool);
02771 while(max_count > 0 && mPools.size() > 0)
02772 {
02773 if (iter1 == mPools.end())
02774 {
02775 iter1 = mPools.begin();
02776 }
02777 LLDrawPool* poolp = *iter1;
02778
02779 if (poolp->isDead())
02780 {
02781 mPools.erase(iter1++);
02782 removeFromQuickLookup( poolp );
02783 if (poolp == mLastRebuildPool)
02784 {
02785 mLastRebuildPool = NULL;
02786 }
02787 delete poolp;
02788 }
02789 else
02790 {
02791 mLastRebuildPool = poolp;
02792 iter1++;
02793 }
02794 max_count--;
02795 }
02796
02797 if (gAgent.getAvatarObject())
02798 {
02799 gAgent.getAvatarObject()->rebuildHUD();
02800 }
02801 }
02802
02803 void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )
02804 {
02805 LLMemType mt(LLMemType::MTYPE_PIPELINE);
02806
02807 assertInitialized();
02808
02809 switch( new_poolp->getType() )
02810 {
02811 case LLDrawPool::POOL_SIMPLE:
02812 if (mSimplePool)
02813 {
02814 llassert(0);
02815 llwarns << "Ignoring duplicate simple pool." << llendl;
02816 }
02817 else
02818 {
02819 mSimplePool = (LLRenderPass*) new_poolp;
02820 }
02821 break;
02822
02823 case LLDrawPool::POOL_INVISIBLE:
02824 if (mInvisiblePool)
02825 {
02826 llassert(0);
02827 llwarns << "Ignoring duplicate simple pool." << llendl;
02828 }
02829 else
02830 {
02831 mInvisiblePool = (LLRenderPass*) new_poolp;
02832 }
02833 break;
02834
02835 case LLDrawPool::POOL_GLOW:
02836 if (mGlowPool)
02837 {
02838 llassert(0);
02839 llwarns << "Ignoring duplicate glow pool." << llendl;
02840 }
02841 else
02842 {
02843 mGlowPool = (LLRenderPass*) new_poolp;
02844 }
02845 break;
02846
02847 case LLDrawPool::POOL_TREE:
02848 mTreePools[ uintptr_t(new_poolp->getTexture()) ] = new_poolp ;
02849 break;
02850
02851 case LLDrawPool::POOL_TERRAIN:
02852 mTerrainPools[ uintptr_t(new_poolp->getTexture()) ] = new_poolp ;
02853 break;
02854
02855 case LLDrawPool::POOL_BUMP:
02856 if (mBumpPool)
02857 {
02858 llassert(0);
02859 llwarns << "Ignoring duplicate bump pool." << llendl;
02860 }
02861 else
02862 {
02863 mBumpPool = new_poolp;
02864 }
02865 break;
02866
02867 case LLDrawPool::POOL_ALPHA:
02868 if( mAlphaPool )
02869 {
02870 llassert(0);
02871 llwarns << "LLPipeline::addPool(): Ignoring duplicate Alpha pool" << llendl;
02872 }
02873 else
02874 {
02875 mAlphaPool = new_poolp;
02876 }
02877 break;
02878
02879 case LLDrawPool::POOL_AVATAR:
02880 break;
02881
02882 case LLDrawPool::POOL_SKY:
02883 if( mSkyPool )
02884 {
02885 llassert(0);
02886 llwarns << "LLPipeline::addPool(): Ignoring duplicate Sky pool" << llendl;
02887 }
02888 else
02889 {
02890 mSkyPool = new_poolp;
02891 }
02892 break;
02893
02894 case LLDrawPool::POOL_WATER:
02895 if( mWaterPool )
02896 {
02897 llassert(0);
02898 llwarns << "LLPipeline::addPool(): Ignoring duplicate Water pool" << llendl;
02899 }
02900 else
02901 {
02902 mWaterPool = new_poolp;
02903 }
02904 break;
02905
02906 case LLDrawPool::POOL_GROUND:
02907 if( mGroundPool )
02908 {
02909 llassert(0);
02910 llwarns << "LLPipeline::addPool(): Ignoring duplicate Ground Pool" << llendl;
02911 }
02912 else
02913 {
02914 mGroundPool = new_poolp;
02915 }
02916 break;
02917
02918 case LLDrawPool::POOL_WL_SKY:
02919 if( mWLSkyPool )
02920 {
02921 llassert(0);
02922 llwarns << "LLPipeline::addPool(): Ignoring duplicate WLSky Pool" << llendl;
02923 }
02924 else
02925 {
02926 mWLSkyPool = new_poolp;
02927 }
02928 break;
02929
02930 default:
02931 llassert(0);
02932 llwarns << "Invalid Pool Type in LLPipeline::addPool()" << llendl;
02933 break;
02934 }
02935 }
02936
02937 void LLPipeline::removePool( LLDrawPool* poolp )
02938 {
02939 assertInitialized();
02940 removeFromQuickLookup(poolp);
02941 mPools.erase(poolp);
02942 delete poolp;
02943 }
02944
02945 void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp )
02946 {
02947 assertInitialized();
02948 LLMemType mt(LLMemType::MTYPE_PIPELINE);
02949 switch( poolp->getType() )
02950 {
02951 case LLDrawPool::POOL_SIMPLE:
02952 llassert(mSimplePool == poolp);
02953 mSimplePool = NULL;
02954 break;
02955
02956 case LLDrawPool::POOL_INVISIBLE:
02957 llassert(mInvisiblePool == poolp);
02958 mInvisiblePool = NULL;
02959 break;
02960
02961 case LLDrawPool::POOL_WL_SKY:
02962 llassert(mWLSkyPool == poolp);
02963 mWLSkyPool = NULL;
02964 break;
02965
02966 case LLDrawPool::POOL_GLOW:
02967 llassert(mGlowPool == poolp);
02968 mGlowPool = NULL;
02969 break;
02970
02971 case LLDrawPool::POOL_TREE:
02972 #ifdef _DEBUG
02973 {
02974 BOOL found = mTreePools.erase( (uintptr_t)poolp->getTexture() );
02975 llassert( found );
02976 }
02977 #else
02978 mTreePools.erase( (uintptr_t)poolp->getTexture() );
02979 #endif
02980 break;
02981
02982 case LLDrawPool::POOL_TERRAIN:
02983 #ifdef _DEBUG
02984 {
02985 BOOL found = mTerrainPools.erase( (uintptr_t)poolp->getTexture() );
02986 llassert( found );
02987 }
02988 #else
02989 mTerrainPools.erase( (uintptr_t)poolp->getTexture() );
02990 #endif
02991 break;
02992
02993 case LLDrawPool::POOL_BUMP:
02994 llassert( poolp == mBumpPool );
02995 mBumpPool = NULL;
02996 break;
02997
02998 case LLDrawPool::POOL_ALPHA:
02999 llassert( poolp == mAlphaPool );
03000 mAlphaPool = NULL;
03001 break;
03002
03003 case LLDrawPool::POOL_AVATAR:
03004 break;
03005
03006 case LLDrawPool::POOL_SKY:
03007 llassert( poolp == mSkyPool );
03008 mSkyPool = NULL;
03009 break;
03010
03011 case LLDrawPool::POOL_WATER:
03012 llassert( poolp == mWaterPool );
03013 mWaterPool = NULL;
03014 break;
03015
03016 case LLDrawPool::POOL_GROUND:
03017 llassert( poolp == mGroundPool );
03018 mGroundPool = NULL;
03019 break;
03020
03021 default:
03022 llassert(0);
03023 llwarns << "Invalid Pool Type in LLPipeline::removeFromQuickLookup() type=" << poolp->getType() << llendl;
03024 break;
03025 }
03026 }
03027
03028 void LLPipeline::resetDrawOrders()
03029 {
03030 assertInitialized();
03031
03032 for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter)
03033 {
03034 LLDrawPool *poolp = *iter;
03035 poolp->resetDrawOrders();
03036 }
03037 }
03038
03039
03040
03041
03042
03043 void LLPipeline::setupAvatarLights(BOOL for_edit)
03044 {
03045 assertInitialized();
03046
03047 if (for_edit)
03048 {
03049 LLColor4 diffuse(0.8f, 0.8f, 0.8f, 0.f);
03050 LLVector4 light_pos_cam(-8.f, 0.25f, 10.f, 0.f);
03051 LLMatrix4 camera_mat = LLViewerCamera::getInstance()->getModelview();
03052 LLMatrix4 camera_rot(camera_mat.getMat3());
03053 camera_rot.invert();
03054 LLVector4 light_pos = light_pos_cam * camera_rot;
03055
03056 light_pos.normVec();
03057
03058 mHWLightColors[1] = diffuse;
03059 glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse.mV);
03060 glLightfv(GL_LIGHT1, GL_AMBIENT, LLColor4::black.mV);
03061 glLightfv(GL_LIGHT1, GL_SPECULAR, LLColor4::black.mV);
03062 glLightfv(GL_LIGHT1, GL_POSITION, light_pos.mV);
03063 glLightf (GL_LIGHT1, GL_CONSTANT_ATTENUATION, 1.0f);
03064 glLightf (GL_LIGHT1, GL_LINEAR_ATTENUATION, 0.0f);
03065 glLightf (GL_LIGHT1, GL_QUADRATIC_ATTENUATION, 0.0f);
03066 glLightf (GL_LIGHT1, GL_SPOT_EXPONENT, 0.0f);
03067 glLightf (GL_LIGHT1, GL_SPOT_CUTOFF, 180.0f);
03068 }
03069 else if (gAvatarBacklight)
03070 {
03071 LLVector3 opposite_pos = -1.f * mSunDir;
03072 LLVector3 orthog_light_pos = mSunDir % LLVector3::z_axis;
03073 LLVector4 backlight_pos = LLVector4(lerp(opposite_pos, orthog_light_pos, 0.3f), 0.0f);
03074 backlight_pos.normVec();
03075
03076 LLColor4 light_diffuse = mSunDiffuse;
03077 LLColor4 backlight_diffuse(1.f - light_diffuse.mV[VRED], 1.f - light_diffuse.mV[VGREEN], 1.f - light_diffuse.mV[VBLUE], 1.f);
03078 F32 max_component = 0.001f;
03079 for (S32 i = 0; i < 3; i++)
03080 {
03081 if (backlight_diffuse.mV[i] > max_component)
03082 {
03083 max_component = backlight_diffuse.mV[i];
03084 }
03085 }
03086 F32 backlight_mag;
03087 if (gSky.getSunDirection().mV[2] >= NIGHTTIME_ELEVATION_COS)
03088 {
03089 backlight_mag = BACKLIGHT_DAY_MAGNITUDE_OBJECT;
03090 }
03091 else
03092 {
03093 backlight_mag = BACKLIGHT_NIGHT_MAGNITUDE_OBJECT;
03094 }
03095 backlight_diffuse *= backlight_mag / max_component;
03096
03097 mHWLightColors[1] = backlight_diffuse;
03098 glLightfv(GL_LIGHT1, GL_POSITION, backlight_pos.mV);
03099 glLightfv(GL_LIGHT1, GL_DIFFUSE, backlight_diffuse.mV);
03100 glLightfv(GL_LIGHT1, GL_AMBIENT, LLColor4::black.mV);
03101 glLightfv(GL_LIGHT1, GL_SPECULAR, LLColor4::black.mV);
03102 glLightf (GL_LIGHT1, GL_CONSTANT_ATTENUATION, 1.0f);
03103 glLightf (GL_LIGHT1, GL_LINEAR_ATTENUATION, 0.0f);
03104 glLightf (GL_LIGHT1, GL_QUADRATIC_ATTENUATION, 0.0f);
03105 glLightf (GL_LIGHT1, GL_SPOT_EXPONENT, 0.0f);
03106 glLightf (GL_LIGHT1, GL_SPOT_CUTOFF, 180.0f);
03107 }
03108 else
03109 {
03110 mHWLightColors[1] = LLColor4::black;
03111 glLightfv(GL_LIGHT1, GL_DIFFUSE, LLColor4::black.mV);
03112 glLightfv(GL_LIGHT1, GL_AMBIENT, LLColor4::black.mV);
03113 glLightfv(GL_LIGHT1, GL_SPECULAR, LLColor4::black.mV);
03114 }
03115 }
03116
03117 static F32 calc_light_dist(LLVOVolume* light, const LLVector3& cam_pos, F32 max_dist)
03118 {
03119 F32 inten = light->getLightIntensity();
03120 if (inten < .001f)
03121 {
03122 return max_dist;
03123 }
03124 F32 radius = light->getLightRadius();
03125 BOOL selected = light->isSelected();
03126 LLVector3 dpos = light->getRenderPosition() - cam_pos;
03127 F32 dist2 = dpos.magVecSquared();
03128 if (!selected && dist2 > (max_dist + radius)*(max_dist + radius))
03129 {
03130 return max_dist;
03131 }
03132 F32 dist = fsqrtf(dist2);
03133 dist *= 1.f / inten;
03134 dist -= radius;
03135 if (selected)
03136 {
03137 dist -= 10000.f;
03138 }
03139 if (light->mDrawable.notNull() && light->mDrawable->isState(LLDrawable::ACTIVE))
03140 {
03141
03142 dist -= light->getLightRadius()*0.25f;
03143 }
03144 return dist;
03145 }
03146
03147 void LLPipeline::calcNearbyLights(LLCamera& camera)
03148 {
03149 assertInitialized();
03150
03151 if (mLightingDetail >= 1)
03152 {
03153
03154
03155 const S32 MAX_LOCAL_LIGHTS = 6;
03156
03157 LLVector3 cam_pos = LLViewerJoystick::getInstance()->getOverrideCamera() ?
03158 camera.getOrigin() :
03159 gAgent.getPositionAgent();
03160
03161 F32 max_dist = LIGHT_MAX_RADIUS * 4.f;
03162
03163
03164 if (!LLPipeline::sSkipUpdate)
03165 {
03166 light_set_t cur_nearby_lights;
03167 for (light_set_t::iterator iter = mNearbyLights.begin();
03168 iter != mNearbyLights.end(); iter++)
03169 {
03170 const Light* light = &(*iter);
03171 LLDrawable* drawable = light->drawable;
03172 LLVOVolume* volight = drawable->getVOVolume();
03173 if (!volight || !drawable->isState(LLDrawable::LIGHT))
03174 {
03175 drawable->clearState(LLDrawable::NEARBY_LIGHT);
03176 continue;
03177 }
03178 if (light->fade <= -LIGHT_FADE_TIME)
03179 {
03180 drawable->clearState(LLDrawable::NEARBY_LIGHT);
03181 }
03182 else
03183 {
03184 F32 dist = calc_light_dist(volight, cam_pos, max_dist);
03185 cur_nearby_lights.insert(Light(drawable, dist, light->fade));
03186 }
03187 }
03188 mNearbyLights = cur_nearby_lights;
03189 }
03190
03191
03192 light_set_t new_nearby_lights;
03193 for (LLDrawable::drawable_set_t::iterator iter = mLights.begin();
03194 iter != mLights.end(); ++iter)
03195 {
03196 LLDrawable* drawable = *iter;
03197 LLVOVolume* light = drawable->getVOVolume();
03198 if (!light || drawable->isState(LLDrawable::NEARBY_LIGHT))
03199 {
03200 continue;
03201 }
03202 if (light->isHUDAttachment())
03203 {
03204 continue;
03205 }
03206 F32 dist = calc_light_dist(light, cam_pos, max_dist);
03207 if (dist >= max_dist)
03208 {
03209 continue;
03210 }
03211 new_nearby_lights.insert(Light(drawable, dist, 0.f));
03212 if (new_nearby_lights.size() > (U32)MAX_LOCAL_LIGHTS)
03213 {
03214 new_nearby_lights.erase(--new_nearby_lights.end());
03215 const Light& last = *new_nearby_lights.rbegin();
03216 max_dist = last.dist;
03217 }
03218 }
03219
03220
03221 for (light_set_t::iterator iter = new_nearby_lights.begin();
03222 iter != new_nearby_lights.end(); iter++)
03223 {
03224 const Light* light = &(*iter);
03225 if (mNearbyLights.size() < (U32)MAX_LOCAL_LIGHTS)
03226 {
03227 mNearbyLights.insert(*light);
03228 ((LLDrawable*) light->drawable)->setState(LLDrawable::NEARBY_LIGHT);
03229 }
03230 else
03231 {
03232
03233
03234
03235 Light* farthest_light = ((Light*) (&(*(mNearbyLights.rbegin()))));
03236 if (light->dist < farthest_light->dist)
03237 {
03238 if (farthest_light->fade >= 0.f)
03239 {
03240 farthest_light->fade = -gFrameIntervalSeconds;
03241 }
03242 }
03243 else
03244 {
03245 break;
03246 }
03247 }
03248 }
03249
03250 }
03251 }
03252
03253 void LLPipeline::setupHWLights(LLDrawPool* pool)
03254 {
03255 assertInitialized();
03256
03257
03258 LLColor4 ambient = gSky.getTotalAmbientColor();
03259 glLightModelfv(GL_LIGHT_MODEL_AMBIENT,ambient.mV);
03260
03261
03262 {
03263 if (gSky.getSunDirection().mV[2] >= NIGHTTIME_ELEVATION_COS)
03264 {
03265 mSunDir.setVec(gSky.getSunDirection());
03266 mSunDiffuse.setVec(gSky.getSunDiffuseColor());
03267 }
03268 else
03269 {
03270 mSunDir.setVec(gSky.getMoonDirection());
03271 mSunDiffuse.setVec(gSky.getMoonDiffuseColor());
03272 }
03273
03274 F32 max_color = llmax(mSunDiffuse.mV[0], mSunDiffuse.mV[1], mSunDiffuse.mV[2]);
03275 if (max_color > 1.f)
03276 {
03277 mSunDiffuse *= 1.f/max_color;
03278 }
03279 mSunDiffuse.clamp();
03280
03281 LLVector4 light_pos(mSunDir, 0.0f);
03282 LLColor4 light_diffuse = mSunDiffuse;
03283 mHWLightColors[0] = light_diffuse;
03284 glLightfv(GL_LIGHT0, GL_POSITION, light_pos.mV);
03285 glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse.mV);
03286 glLightfv(GL_LIGHT0, GL_AMBIENT, LLColor4::black.mV);
03287 glLightfv(GL_LIGHT0, GL_SPECULAR, LLColor4::black.mV);
03288 glLightf (GL_LIGHT0, GL_CONSTANT_ATTENUATION, 1.0f);
03289 glLightf (GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.0f);
03290 glLightf (GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.0f);
03291 glLightf (GL_LIGHT0, GL_SPOT_EXPONENT, 0.0f);
03292 glLightf (GL_LIGHT0, GL_SPOT_CUTOFF, 180.0f);
03293 }
03294
03295
03296
03297
03298 S32 cur_light = 2;
03299
03300
03301
03302 mLightMovingMask = 0;
03303
03304 if (mLightingDetail >= 1)
03305 {
03306 for (light_set_t::iterator iter = mNearbyLights.begin();
03307 iter != mNearbyLights.end(); ++iter)
03308 {
03309 LLDrawable* drawable = iter->drawable;
03310 LLVOVolume* light = drawable->getVOVolume();
03311 if (!light)
03312 {
03313 continue;
03314 }
03315 if (drawable->isState(LLDrawable::ACTIVE))
03316 {
03317 mLightMovingMask |= (1<<cur_light);
03318 }
03319
03320 LLColor4 light_color = light->getLightColor();
03321 light_color.mV[3] = 0.0f;
03322
03323 F32 fade = iter->fade;
03324 if (fade < LIGHT_FADE_TIME)
03325 {
03326
03327 if (fade >= 0.f)
03328 {
03329 fade = fade / LIGHT_FADE_TIME;
03330 ((Light*) (&(*iter)))->fade += gFrameIntervalSeconds;
03331 }
03332 else
03333 {
03334 fade = 1.f + fade / LIGHT_FADE_TIME;
03335 ((Light*) (&(*iter)))->fade -= gFrameIntervalSeconds;
03336 }
03337 fade = llclamp(fade,0.f,1.f);
03338 light_color *= fade;
03339 }
03340
03341 LLVector3 light_pos(light->getRenderPosition());
03342 LLVector4 light_pos_gl(light_pos, 1.0f);
03343
03344 F32 light_radius = llmax(light->getLightRadius(), 0.001f);
03345 F32 atten, quad;
03346
03347 #if 0 //1.9.1
03348 if (pool->getVertexShaderLevel() > 0)
03349 {
03350 atten = light_radius;
03351 quad = llmax(light->getLightFalloff(), 0.0001f);
03352 }
03353 else
03354 #endif
03355 {
03356 F32 x = (3.f * (1.f + light->getLightFalloff()));
03357 atten = x / (light_radius);
03358 quad = 0.0f;
03359 }
03360 mHWLightColors[cur_light] = light_color;
03361 S32 gllight = GL_LIGHT0+cur_light;
03362 glLightfv(gllight, GL_POSITION, light_pos_gl.mV);
03363 glLightfv(gllight, GL_DIFFUSE, light_color.mV);
03364 glLightfv(gllight, GL_AMBIENT, LLColor4::black.mV);
03365 glLightfv(gllight, GL_SPECULAR, LLColor4::black.mV);
03366 glLightf (gllight, GL_CONSTANT_ATTENUATION, 0.0f);
03367 glLightf (gllight, GL_LINEAR_ATTENUATION, atten);
03368 glLightf (gllight, GL_QUADRATIC_ATTENUATION, quad);
03369 glLightf (gllight, GL_SPOT_EXPONENT, 0.0f);
03370 glLightf (gllight, GL_SPOT_CUTOFF, 180.0f);
03371 cur_light++;
03372 if (cur_light >= 8)
03373 {
03374 break;
03375 }
03376 }
03377 }
03378 for ( ; cur_light < 8 ; cur_light++)
03379 {
03380 mHWLightColors[cur_light] = LLColor4::black;
03381 S32 gllight = GL_LIGHT0+cur_light;
03382 glLightfv(gllight, GL_DIFFUSE, LLColor4::black.mV);
03383 glLightfv(gllight, GL_AMBIENT, LLColor4::black.mV);
03384 glLightfv(gllight, GL_SPECULAR, LLColor4::black.mV);
03385 }
03386
03387 if (gAgent.getAvatarObject() &&
03388 gAgent.getAvatarObject()->mSpecialRenderMode == 3)
03389 {
03390 LLColor4 light_color = LLColor4::white;
03391 light_color.mV[3] = 0.0f;
03392
03393 LLVector3 light_pos(LLViewerCamera::getInstance()->getOrigin());
03394 LLVector4 light_pos_gl(light_pos, 1.0f);
03395
03396 F32 light_radius = 16.f;
03397 F32 atten, quad;
03398
03399 {
03400 F32 x = 3.f;
03401 atten = x / (light_radius);
03402 quad = 0.0f;
03403 }
03404
03405 S32 gllight = GL_LIGHT2;
03406 glLightfv(gllight, GL_POSITION, light_pos_gl.mV);
03407 glLightfv(gllight, GL_DIFFUSE, light_color.mV);
03408 glLightfv(gllight, GL_AMBIENT, LLColor4::black.mV);
03409 glLightfv(gllight, GL_SPECULAR, LLColor4::black.mV);
03410 glLightf (gllight, GL_CONSTANT_ATTENUATION, 0.0f);
03411 glLightf (gllight, GL_LINEAR_ATTENUATION, atten);
03412 glLightf (gllight, GL_QUADRATIC_ATTENUATION, quad);
03413 glLightf (gllight, GL_SPOT_EXPONENT, 0.0f);
03414 glLightf (gllight, GL_SPOT_CUTOFF, 180.0f);
03415 }
03416
03417
03418 glDisable(GL_LIGHTING);
03419 for (S32 gllight=GL_LIGHT0; gllight<=GL_LIGHT7; gllight++)
03420 {
03421 glDisable(gllight);
03422 }
03423 mLightMask = 0;
03424 }
03425
03426 void LLPipeline::enableLights(U32 mask)
03427 {
03428 assertInitialized();
03429 if (mLightingDetail == 0)
03430 {
03431 mask &= 0xf003;
03432 }
03433 if (mLightMask != mask)
03434 {
03435 if (!mLightMask)
03436 {
03437 glEnable(GL_LIGHTING);
03438 }
03439 if (mask)
03440 {
03441 for (S32 i=0; i<8; i++)
03442 {
03443 if (mask & (1<<i))
03444 {
03445 glEnable(GL_LIGHT0 + i);
03446 glLightfv(GL_LIGHT0 + i, GL_DIFFUSE, mHWLightColors[i].mV);
03447 }
03448 else
03449 {
03450 glDisable(GL_LIGHT0 + i);
03451 glLightfv(GL_LIGHT0 + i, GL_DIFFUSE, LLColor4::black.mV);
03452 }
03453 }
03454 }
03455 else
03456 {
03457 glDisable(GL_LIGHTING);
03458 }
03459 mLightMask = mask;
03460 LLColor4 ambient = gSky.getTotalAmbientColor();
03461 glLightModelfv(GL_LIGHT_MODEL_AMBIENT,ambient.mV);
03462 }
03463 }
03464
03465 void LLPipeline::enableLightsStatic()
03466 {
03467 assertInitialized();
03468 U32 mask = 0x01;
03469 if (mLightingDetail >= 2)
03470 {
03471 mask |= mLightMovingMask;
03472 glColor4f(0.f, 0.f, 0.f, 1.0f);
03473 }
03474 else
03475 {
03476 mask |= 0xff & (~2);
03477 }
03478 enableLights(mask);
03479 }
03480
03481 void LLPipeline::enableLightsDynamic()
03482 {
03483 assertInitialized();
03484 U32 mask = 0xff & (~2);
03485 enableLights(mask);
03486 if (mLightingDetail >= 2)
03487 {
03488 glColor4f(0.f, 0.f, 0.f, 1.f);
03489 }
03490
03491 LLVOAvatar* avatarp = gAgent.getAvatarObject();
03492
03493 if (avatarp && getLightingDetail() <= 0)
03494 {
03495 if (avatarp->mSpecialRenderMode == 0)
03496 {
03497 gPipeline.enableLightsAvatar();
03498 }
03499 else if (avatarp->mSpecialRenderMode >= 1)
03500 {
03501 gPipeline.enableLightsAvatarEdit(LLColor4(0.7f, 0.6f, 0.3f, 1.f));
03502 }
03503 }
03504 }
03505
03506 void LLPipeline::enableLightsAvatar()
03507 {
03508 U32 mask = 0xff;
03509 setupAvatarLights(FALSE);
03510 enableLights(mask);
03511 }
03512
03513 void LLPipeline::enableLightsAvatarEdit(const LLColor4& color)
03514 {
03515 U32 mask = 0x2002;
03516 setupAvatarLights(TRUE);
03517 enableLights(mask);
03518
03519 glLightModelfv(GL_LIGHT_MODEL_AMBIENT,color.mV);
03520 }
03521
03522 void LLPipeline::enableLightsFullbright(const LLColor4& color)
03523 {
03524 assertInitialized();
03525 U32 mask = 0x1000;
03526 enableLights(mask);
03527
03528 glLightModelfv(GL_LIGHT_MODEL_AMBIENT,color.mV);
03529 if (mLightingDetail >= 2)
03530 {
03531 glColor4f(0.f, 0.f, 0.f, 1.f);
03532 }
03533 }
03534
03535 void LLPipeline::disableLights()
03536 {
03537 enableLights(0);
03538 glColor4f(1.f, 1.f, 1.f, 1.f);
03539 }
03540
03541
03542
03543 class LLMenuItemGL;
03544 class LLInvFVBridge;
03545 struct cat_folder_pair;
03546 class LLVOBranch;
03547 class LLVOLeaf;
03548
03549 void LLPipeline::findReferences(LLDrawable *drawablep)
03550 {
03551 assertInitialized();
03552 if (mLights.find(drawablep) != mLights.end())
03553 {
03554 llinfos << "In mLights" << llendl;
03555 }
03556 if (std::find(mMovedList.begin(), mMovedList.end(), drawablep) != mMovedList.end())
03557 {
03558 llinfos << "In mMovedList" << llendl;
03559 }
03560 if (std::find(mShiftList.begin(), mShiftList.end(), drawablep) != mShiftList.end())
03561 {
03562 llinfos << "In mShiftList" << llendl;
03563 }
03564 if (mRetexturedList.find(drawablep) != mRetexturedList.end())
03565 {
03566 llinfos << "In mRetexturedList" << llendl;
03567 }
03568
03569 if (mActiveQ.find(drawablep) != mActiveQ.end())
03570 {
03571 llinfos << "In mActiveQ" << llendl;
03572 }
03573 if (std::find(mBuildQ1.begin(), mBuildQ1.end(), drawablep) != mBuildQ1.end())
03574 {
03575 llinfos << "In mBuildQ1" << llendl;
03576 }
03577 if (std::find(mBuildQ2.begin(), mBuildQ2.end(), drawablep) != mBuildQ2.end())
03578 {
03579 llinfos << "In mBuildQ2" << llendl;
03580 }
03581
03582 S32 count;
03583
03584 count = gObjectList.findReferences(drawablep);
03585 if (count)
03586 {
03587 llinfos << "In other drawables: " << count << " references" << llendl;
03588 }
03589 }
03590
03591 BOOL LLPipeline::verify()
03592 {
03593 BOOL ok = assertInitialized();
03594 if (ok)
03595 {
03596 for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter)
03597 {
03598 LLDrawPool *poolp = *iter;
03599 if (!poolp->verify())
03600 {
03601 ok = FALSE;
03602 }
03603 }
03604 }
03605
03606 if (!ok)
03607 {
03608 llwarns << "Pipeline verify failed!" << llendl;
03609 }
03610 return ok;
03611 }
03612
03614
03615
03616
03617
03618
03620
03640
03641
03642 #define IR(x) ((U32&)x)
03643
03644 bool LLRayAABB(const LLVector3 ¢er, const LLVector3 &size, const LLVector3& origin, const LLVector3& dir, LLVector3 &coord, F32 epsilon)
03645 {
03646 BOOL Inside = TRUE;
03647 LLVector3 MinB = center - size;
03648 LLVector3 MaxB = center + size;
03649 LLVector3 MaxT;
03650 MaxT.mV[VX]=MaxT.mV[VY]=MaxT.mV[VZ]=-1.0f;
03651
03652
03653 for(U32 i=0;i<3;i++)
03654 {
03655 if(origin.mV[i] < MinB.mV[i])
03656 {
03657 coord.mV[i] = MinB.mV[i];
03658 Inside = FALSE;
03659
03660
03661 if(IR(dir.mV[i])) MaxT.mV[i] = (MinB.mV[i] - origin.mV[i]) / dir.mV[i];
03662 }
03663 else if(origin.mV[i] > MaxB.mV[i])
03664 {
03665 coord.mV[i] = MaxB.mV[i];
03666 Inside = FALSE;
03667
03668
03669 if(IR(dir.mV[i])) MaxT.mV[i] = (MaxB.mV[i] - origin.mV[i]) / dir.mV[i];
03670 }
03671 }
03672
03673
03674 if(Inside)
03675 {
03676 coord = origin;
03677 return true;
03678 }
03679
03680
03681 U32 WhichPlane = 0;
03682 if(MaxT.mV[1] > MaxT.mV[WhichPlane]) WhichPlane = 1;
03683 if(MaxT.mV[2] > MaxT.mV[WhichPlane]) WhichPlane = 2;
03684
03685
03686 if(IR(MaxT.mV[WhichPlane])&0x80000000) return false;
03687
03688 for(U32 i=0;i<3;i++)
03689 {
03690 if(i!=WhichPlane)
03691 {
03692 coord.mV[i] = origin.mV[i] + MaxT.mV[WhichPlane] * dir.mV[i];
03693 if (epsilon > 0)
03694 {
03695 if(coord.mV[i] < MinB.mV[i] - epsilon || coord.mV[i] > MaxB.mV[i] + epsilon) return false;
03696 }
03697 else
03698 {
03699 if(coord.mV[i] < MinB.mV[i] || coord.mV[i] > MaxB.mV[i]) return false;
03700 }
03701 }
03702 }
03703 return true;
03704 }
03705
03707
03708
03709
03710
03711
03712 void LLPipeline::setLight(LLDrawable *drawablep, BOOL is_light)
03713 {
03714 if (drawablep && assertInitialized())
03715 {
03716 if (is_light)
03717 {
03718 mLights.insert(drawablep);
03719 drawablep->setState(LLDrawable::LIGHT);
03720 }
03721 else
03722 {
03723 drawablep->clearState(LLDrawable::LIGHT);
03724 mLights.erase(drawablep);
03725 }
03726 }
03727 }
03728
03729 void LLPipeline::setActive(LLDrawable *drawablep, BOOL active)
03730 {
03731 assertInitialized();
03732 if (active)
03733 {
03734 mActiveQ.insert(drawablep);
03735 }
03736 else
03737 {
03738 mActiveQ.erase(drawablep);
03739 }
03740 }
03741
03742
03743 void LLPipeline::toggleRenderType(U32 type)
03744 {
03745 U32 bit = (1<<type);
03746 gPipeline.mRenderTypeMask ^= bit;
03747 }
03748
03749
03750 void LLPipeline::toggleRenderTypeControl(void* data)
03751 {
03752 U32 type = (U32)(intptr_t)data;
03753 U32 bit = (1<<type);
03754 if (gPipeline.hasRenderType(type))
03755 {
03756 llinfos << "Toggling render type mask " << std::hex << bit << " off" << std::dec << llendl;
03757 }
03758 else
03759 {
03760 llinfos << "Toggling render type mask " << std::hex << bit << " on" << std::dec << llendl;
03761 }
03762 gPipeline.toggleRenderType(type);
03763 }
03764
03765
03766 BOOL LLPipeline::hasRenderTypeControl(void* data)
03767 {
03768 U32 type = (U32)(intptr_t)data;
03769 return gPipeline.hasRenderType(type);
03770 }
03771
03772
03773
03774 BOOL LLPipeline::toggleRenderTypeControlNegated(void* data)
03775 {
03776 S32 type = (S32)(intptr_t)data;
03777 return !gPipeline.hasRenderType(type);
03778 }
03779
03780
03781 void LLPipeline::toggleRenderDebug(void* data)
03782 {
03783 U32 bit = (U32)(intptr_t)data;
03784 if (gPipeline.hasRenderDebugMask(bit))
03785 {
03786 llinfos << "Toggling render debug mask " << std::hex << bit << " off" << std::dec << llendl;
03787 }
03788 else
03789 {
03790 llinfos << "Toggling render debug mask " << std::hex << bit << " on" << std::dec << llendl;
03791 }
03792 gPipeline.mRenderDebugMask ^= bit;
03793 }
03794
03795
03796
03797 BOOL LLPipeline::toggleRenderDebugControl(void* data)
03798 {
03799 U32 bit = (U32)(intptr_t)data;
03800 return gPipeline.hasRenderDebugMask(bit);
03801 }
03802
03803
03804 void LLPipeline::toggleRenderDebugFeature(void* data)
03805 {
03806 U32 bit = (U32)(intptr_t)data;
03807 gPipeline.mRenderDebugFeatureMask ^= bit;
03808 }
03809
03810
03811
03812 BOOL LLPipeline::toggleRenderDebugFeatureControl(void* data)
03813 {
03814 U32 bit = (U32)(intptr_t)data;
03815 return gPipeline.hasRenderDebugFeatureMask(bit);
03816 }
03817
03818
03819 void LLPipeline::setRenderScriptedBeacons(BOOL val)
03820 {
03821 sRenderScriptedBeacons = val;
03822 }
03823
03824
03825 void LLPipeline::toggleRenderScriptedBeacons(void*)
03826 {
03827 sRenderScriptedBeacons = !sRenderScriptedBeacons;
03828 }
03829
03830
03831 BOOL LLPipeline::getRenderScriptedBeacons(void*)
03832 {
03833 return sRenderScriptedBeacons;
03834 }
03835
03836
03837 void LLPipeline::setRenderScriptedTouchBeacons(BOOL val)
03838 {
03839 sRenderScriptedTouchBeacons = val;
03840 }
03841
03842
03843 void LLPipeline::toggleRenderScriptedTouchBeacons(void*)
03844 {
03845 sRenderScriptedTouchBeacons = !sRenderScriptedTouchBeacons;
03846 }
03847
03848
03849 BOOL LLPipeline::getRenderScriptedTouchBeacons(void*)
03850 {
03851 return sRenderScriptedTouchBeacons;
03852 }
03853
03854
03855 void LLPipeline::setRenderPhysicalBeacons(BOOL val)
03856 {
03857 sRenderPhysicalBeacons = val;
03858 }
03859
03860
03861 void LLPipeline::toggleRenderPhysicalBeacons(void*)
03862 {
03863 sRenderPhysicalBeacons = !sRenderPhysicalBeacons;
03864 }
03865
03866
03867 BOOL LLPipeline::getRenderPhysicalBeacons(void*)
03868 {
03869 return sRenderPhysicalBeacons;
03870 }
03871
03872
03873 void LLPipeline::setRenderParticleBeacons(BOOL val)
03874 {
03875 sRenderParticleBeacons = val;
03876 }
03877
03878
03879 void LLPipeline::toggleRenderParticleBeacons(void*)
03880 {
03881 sRenderParticleBeacons = !sRenderParticleBeacons;
03882 }
03883
03884
03885 BOOL LLPipeline::getRenderParticleBeacons(void*)
03886 {
03887 return sRenderParticleBeacons;
03888 }
03889
03890
03891 void LLPipeline::setRenderSoundBeacons(BOOL val)
03892 {
03893 sRenderSoundBeacons = val;
03894 }
03895
03896
03897 void LLPipeline::toggleRenderSoundBeacons(void*)
03898 {
03899 sRenderSoundBeacons = !sRenderSoundBeacons;
03900 }
03901
03902
03903 BOOL LLPipeline::getRenderSoundBeacons(void*)
03904 {
03905 return sRenderSoundBeacons;
03906 }
03907
03908
03909 void LLPipeline::setRenderBeacons(BOOL val)
03910 {
03911 sRenderBeacons = val;
03912 }
03913
03914
03915 void LLPipeline::toggleRenderBeacons(void*)
03916 {
03917 sRenderBeacons = !sRenderBeacons;
03918 }
03919
03920
03921 BOOL LLPipeline::getRenderBeacons(void*)
03922 {
03923 return sRenderBeacons;
03924 }
03925
03926
03927 void LLPipeline::setRenderHighlights(BOOL val)
03928 {
03929 sRenderHighlight = val;
03930 }
03931
03932
03933 void LLPipeline::toggleRenderHighlights(void*)
03934 {
03935 sRenderHighlight = !sRenderHighlight;
03936 }
03937
03938
03939 BOOL LLPipeline::getRenderHighlights(void*)
03940 {
03941 return sRenderHighlight;
03942 }
03943
03944
03945 BOOL LLPipeline::getProcessBeacons(void* data)
03946 {
03947 return sRenderProcessBeacons;
03948 }
03949
03950 LLViewerObject* LLPipeline::pickObject(const LLVector3 &start, const LLVector3 &end, LLVector3 &collision)
03951 {
03952 LLDrawable* drawable = NULL;
03953
03954 for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin();
03955 iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
03956 {
03957 LLViewerRegion* region = *iter;
03958 LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_VOLUME);
03959 if (part)
03960 {
03961 LLDrawable* hit = part->pickDrawable(start, end, collision);
03962 if (hit)
03963 {
03964 drawable = hit;
03965 }
03966 }
03967 }
03968 return drawable ? drawable->getVObj().get() : NULL;
03969 }
03970
03971 LLSpatialPartition* LLPipeline::getSpatialPartition(LLViewerObject* vobj)
03972 {
03973 if (vobj)
03974 {
03975 LLViewerRegion* region = vobj->getRegion();
03976 if (region)
03977 {
03978 return region->getSpatialPartition(vobj->getPartitionType());
03979 }
03980 }
03981 return NULL;
03982 }
03983
03984
03985 void LLPipeline::resetVertexBuffers(LLDrawable* drawable)
03986 {
03987 if (!drawable || drawable->isDead())
03988 {
03989 return;
03990 }
03991
03992 if (!drawable)
03993 {
03994 return;
03995 }
03996
03997 for (S32 i = 0; i < drawable->getNumFaces(); i++)
03998 {
03999 LLFace* facep = drawable->getFace(i);
04000 facep->mVertexBuffer = NULL;
04001 facep->mLastVertexBuffer = NULL;
04002 }
04003 }
04004
04005 void LLPipeline::resetVertexBuffers()
04006 {
04007 sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
04008
04009 for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin();
04010 iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
04011 {
04012 LLViewerRegion* region = *iter;
04013 for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
04014 {
04015 LLSpatialPartition* part = region->getSpatialPartition(i);
04016 if (part)
04017 {
04018 part->resetVertexBuffers();
04019 }
04020 }
04021 }
04022
04023 resetDrawOrders();
04024
04025 gSky.resetVertexBuffers();
04026
04027 if (LLVertexBuffer::sGLCount > 0)
04028 {
04029 LLVertexBuffer::cleanupClass();
04030 }
04031
04032
04033 LLGLNamePool::cleanupPools();
04034
04035 if (LLVertexBuffer::sGLCount > 0)
04036 {
04037 llwarns << "VBO wipe failed." << llendl;
04038 }
04039
04040 if (!LLVertexBuffer::sStreamIBOPool.mNameList.empty() ||
04041 !LLVertexBuffer::sStreamVBOPool.mNameList.empty() ||
04042 !LLVertexBuffer::sDynamicIBOPool.mNameList.empty() ||
04043 !LLVertexBuffer::sDynamicVBOPool.mNameList.empty())
04044 {
04045 llwarns << "VBO name pool cleanup failed." << llendl;
04046 }
04047
04048 LLVertexBuffer::unbind();
04049
04050 LLPipeline::sTextureBindTest = gSavedSettings.getBOOL("RenderDebugTextureBind");
04051 }
04052
04053 void LLPipeline::renderObjects(U32 type, U32 mask, BOOL texture)
04054 {
04055 assertInitialized();
04056 gGLLastMatrix = NULL;
04057 glLoadMatrixd(gGLLastModelView);
04058 mSimplePool->renderGroups(type, mask, texture);
04059 gGLLastMatrix = NULL;
04060 glLoadMatrixd(gGLLastModelView);
04061 }
04062
04063 void LLPipeline::setUseVBO(BOOL use_vbo)
04064 {
04065 if (use_vbo != LLVertexBuffer::sEnableVBOs)
04066 {
04067 if (use_vbo)
04068 {
04069 llinfos << "Enabling VBO." << llendl;
04070 }
04071 else
04072 {
04073 llinfos << "Disabling VBO." << llendl;
04074 }
04075
04076 resetVertexBuffers();
04077 LLVertexBuffer::initClass(use_vbo);
04078 }
04079 }
04080
04081 void apply_cube_face_rotation(U32 face)
04082 {
04083 switch (face)
04084 {
04085 case 0:
04086 glRotatef(90.f, 0, 1, 0);
04087 glRotatef(180.f, 1, 0, 0);
04088 break;
04089 case 2:
04090 glRotatef(-90.f, 1, 0, 0);
04091 break;
04092 case 4:
04093 glRotatef(180.f, 0, 1, 0);
04094 glRotatef(180.f, 0, 0, 1);
04095 break;
04096 case 1:
04097 glRotatef(-90.f, 0, 1, 0);
04098 glRotatef(180.f, 1, 0, 0);
04099 break;
04100 case 3:
04101 glRotatef(90, 1, 0, 0);
04102 break;
04103 case 5:
04104 glRotatef(180, 0, 0, 1);
04105 break;
04106 }
04107 }
04108 void LLPipeline::generateReflectionMap(LLCubeMap* cube_map, LLCamera& cube_cam)
04109 {
04110 LLGLState::checkStates();
04111 LLGLState::checkTextureChannels();
04112 LLGLState::checkClientArrays();
04113
04114 assertInitialized();
04115
04116
04117 U32 type_mask = gPipeline.getRenderTypeMask();
04118 S32 use_occlusion = LLPipeline::sUseOcclusion;
04119 LLPipeline::sUseOcclusion = 0;
04120 LLPipeline::sSkipUpdate = TRUE;
04121 U32 res = REFLECTION_MAP_RES;
04122
04123 LLPipeline::sReflectionRender = TRUE;
04124
04125 cube_map->bind();
04126 GLint width;
04127 glGetTexLevelParameteriv(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, 0, GL_TEXTURE_WIDTH, &width);
04128 if (width != res)
04129 {
04130 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
04131 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
04132 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
04133 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
04134
04135 for (U32 i = 0; i < 6; i++)
04136 {
04137 glTexImage2D(gl_cube_face[i], 0, GL_RGBA, res, res, 0, GL_RGBA, GL_FLOAT, NULL);
04138 }
04139 }
04140 glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, 0);
04141 cube_map->disable();
04142
04143 BOOL toggle_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI);
04144 if (toggle_ui)
04145 {
04146 gPipeline.toggleRenderDebugFeature((void*) LLPipeline::RENDER_DEBUG_FEATURE_UI);
04147 }
04148
04149 U32 cube_mask = (1 << LLPipeline::RENDER_TYPE_SIMPLE) |
04150 (1 << LLPipeline::RENDER_TYPE_WATER) |
04151
04152 (1 << LLPipeline::RENDER_TYPE_ALPHA) |
04153 (1 << LLPipeline::RENDER_TYPE_TREE) |
04154
04155 (1 << LLPipeline::RENDER_TYPE_CLOUDS) |
04156
04157
04158 (1 << LLPipeline::RENDER_TYPE_GLOW) |
04159 (1 << LLPipeline::RENDER_TYPE_GRASS) |
04160 (1 << LLPipeline::RENDER_TYPE_VOLUME) |
04161 (1 << LLPipeline::RENDER_TYPE_TERRAIN) |
04162 (1 << LLPipeline::RENDER_TYPE_SKY) |
04163 (1 << LLPipeline::RENDER_TYPE_WL_SKY) |
04164 (1 << LLPipeline::RENDER_TYPE_GROUND);
04165
04166 LLDrawPoolWater::sSkipScreenCopy = TRUE;
04167 LLPipeline::sSkipUpdate = TRUE;
04168 cube_mask = cube_mask & type_mask;
04169 gPipeline.setRenderTypeMask(cube_mask);
04170
04171 glMatrixMode(GL_PROJECTION);
04172 glPushMatrix();
04173 glMatrixMode(GL_MODELVIEW);
04174 glPushMatrix();
04175
04176 glViewport(0,0,res,res);
04177
04178 glClearColor(0,0,0,0);
04179
04180 LLVector3 origin = cube_cam.getOrigin();
04181
04182 gPipeline.calcNearbyLights(cube_cam);
04183
04184 stop_glerror();
04185 LLViewerImage::unbindTexture(0, GL_TEXTURE_2D);
04186 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mCubeFrameBuffer);
04187 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
04188 GL_RENDERBUFFER_EXT, mCubeDepth);
04189 stop_glerror();
04190
04191 for (S32 i = 0; i < 6; i++)
04192 {
04193 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mCubeFrameBuffer);
04194 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
04195 gl_cube_face[i], cube_map->getGLName(), 0);
04196 validate_framebuffer_object();
04197 glMatrixMode(GL_PROJECTION);
04198 glLoadIdentity();
04199 gluPerspective(90.f, 1.f, 0.1f, 1024.f);
04200 glMatrixMode(GL_MODELVIEW);
04201 glLoadIdentity();
04202
04203 apply_cube_face_rotation(i);
04204
04205 glTranslatef(-origin.mV[0], -origin.mV[1], -origin.mV[2]);
04206 cube_cam.setOrigin(origin);
04207 LLViewerCamera::updateFrustumPlanes(cube_cam);
04208 cube_cam.setOrigin(LLViewerCamera::getInstance()->getOrigin());
04209 static LLCullResult result;
04210 gPipeline.updateCull(cube_cam, result);
04211 gPipeline.stateSort(cube_cam, result);
04212
04213 glClearColor(0,0,0,0);
04214 glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
04215 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
04216 glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_FALSE);
04217 stop_glerror();
04218 gPipeline.renderGeom(cube_cam);
04219 }
04220
04221 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
04222
04223 cube_cam.setOrigin(origin);
04224 gShinyOrigin.setVec(cube_cam.getOrigin(), cube_cam.getFar()*2.f);
04225 glMatrixMode(GL_PROJECTION);
04226 glPopMatrix();
04227 glMatrixMode(GL_MODELVIEW);
04228 glPopMatrix();
04229
04230 gViewerWindow->setupViewport();
04231
04232 gPipeline.setRenderTypeMask(type_mask);
04233 LLPipeline::sUseOcclusion = use_occlusion;
04234 LLPipeline::sSkipUpdate = FALSE;
04235
04236 if (toggle_ui)
04237 {
04238 gPipeline.toggleRenderDebugFeature((void*)LLPipeline::RENDER_DEBUG_FEATURE_UI);
04239 }
04240 LLDrawPoolWater::sSkipScreenCopy = FALSE;
04241 LLPipeline::sSkipUpdate = FALSE;
04242 LLPipeline::sReflectionRender = FALSE;
04243
04244 LLGLState::checkStates();
04245 LLGLState::checkTextureChannels();
04246 LLGLState::checkClientArrays();
04247 }
04248
04249
04250 void render_cube_map()
04251 {
04252 U16 idx[36];
04253
04254 idx[0] = 1; idx[1] = 0; idx[2] = 2;
04255 idx[3] = 3; idx[4] = 2; idx[5] = 0;
04256
04257 idx[6] = 4; idx[7] = 5; idx[8] = 1;
04258 idx[9] = 0; idx[10] = 1; idx[11] = 5;
04259
04260 idx[12] = 5; idx[13] = 4; idx[14] = 6;
04261 idx[15] = 7; idx[16] = 6; idx[17] = 4;
04262
04263 idx[18] = 6; idx[19] = 7; idx[20] = 3;
04264 idx[21] = 2; idx[22] = 3; idx[23] = 7;
04265
04266 idx[24] = 0; idx[25] = 5; idx[26] = 3;
04267 idx[27] = 6; idx[28] = 3; idx[29] = 5;
04268
04269 idx[30] = 4; idx[31] = 1; idx[32] = 7;
04270 idx[33] = 2; idx[34] = 7; idx[35] = 1;
04271
04272 LLVector3 vert[8];
04273 LLVector3 r = LLVector3(1,1,1);
04274
04275 vert[0] = r.scaledVec(LLVector3(-1,1,1));
04276 vert[1] = r.scaledVec(LLVector3(1,1,1));
04277 vert[2] = r.scaledVec(LLVector3(1,-1,1));
04278 vert[3] = r.scaledVec(LLVector3(-1,-1,1));
04279
04280 vert[4] = r.scaledVec(LLVector3(1,1,-1));
04281 vert[5] = r.scaledVec(LLVector3(-1,1,-1));
04282 vert[6] = r.scaledVec(LLVector3(-1,-1,-1));
04283 vert[7] = r.scaledVec(LLVector3(1,-1,-1));
04284
04285 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
04286 glTexCoordPointer(3, GL_FLOAT, 0, vert);
04287 glVertexPointer(3, GL_FLOAT, 0, vert);
04288
04289 glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, (GLushort*) idx);
04290
04291 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
04292 }
04293
04294 void validate_framebuffer_object()
04295 {
04296 GLenum status;
04297 status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
04298 switch(status)
04299 {
04300 case GL_FRAMEBUFFER_COMPLETE_EXT:
04301
04302 break;
04303 case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
04304
04305 llerrs << "Framebuffer Incomplete Dimensions." << llendl;
04306 break;
04307 case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
04308
04309 llerrs << "Framebuffer Incomplete Attachment." << llendl;
04310 break;
04311 case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
04312
04313 llerrs << "Framebuffer unsupported." << llendl;
04314 break;
04315 default:
04316 llerrs << "Unknown framebuffer status." << llendl;
04317 break;
04318 }
04319 }
04320
04321 void LLPipeline::blurReflectionMap(LLCubeMap* cube_in, LLCubeMap* cube_out)
04322 {
04323 LLGLState::checkStates();
04324 LLGLState::checkTextureChannels();
04325 LLGLState::checkClientArrays();
04326
04327 assertInitialized();
04328
04329 U32 res = (U32) gSavedSettings.getS32("RenderReflectionRes");
04330 enableLightsFullbright(LLColor4::white);
04331 LLGLDepthTest depth(GL_FALSE);
04332 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
04333 glMatrixMode(GL_PROJECTION);
04334 glPushMatrix();
04335 glLoadIdentity();
04336 gluPerspective(90.f+45.f/res, 1.f, 0.1f, 1024.f);
04337 glMatrixMode(GL_MODELVIEW);
04338 glPushMatrix();
04339
04340 cube_out->enableTexture(0);
04341 cube_out->bind();
04342 GLint width;
04343 glGetTexLevelParameteriv(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, 0, GL_TEXTURE_WIDTH, &width);
04344 if (width != res)
04345 {
04346 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
04347 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
04348 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
04349 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
04350
04351 for (U32 i = 0; i < 6; i++)
04352 {
04353 glTexImage2D(gl_cube_face[i], 0, GL_RGBA, res, res, 0, GL_RGBA, GL_FLOAT, NULL);
04354 }
04355 }
04356 glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, 0);
04357
04358 glViewport(0, 0, res, res);
04359 LLGLEnable blend(GL_BLEND);
04360
04361 S32 kernel = 2;
04362 F32 step = 90.f/res;
04363 F32 alpha = 1.f / ((kernel*2)+1);
04364
04365 gGL.color4f(alpha,alpha,alpha,alpha*1.25f);
04366
04367 LLVector3 axis[] =
04368 {
04369 LLVector3(1,0,0),
04370 LLVector3(0,1,0),
04371 LLVector3(0,0,1)
04372 };
04373
04374 stop_glerror();
04375 glViewport(0,0,res, res);
04376 gGL.blendFunc(GL_ONE, GL_ONE);
04377 cube_in->enableTexture(0);
04378
04379 for (U32 j = 0; j < 3; j++)
04380 {
04381 stop_glerror();
04382
04383 if (j == 0)
04384 {
04385 cube_in->bind();
04386 }
04387 else
04388 {
04389 glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, mBlurCubeTexture[j-1]);
04390 }
04391
04392 stop_glerror();
04393
04394 LLViewerImage::unbindTexture(0, GL_TEXTURE_2D);
04395 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mBlurCubeBuffer[j]);
04396 stop_glerror();
04397
04398 for (U32 i = 0; i < 6; i++)
04399 {
04400 stop_glerror();
04401 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
04402 GL_COLOR_ATTACHMENT0_EXT,
04403 gl_cube_face[i],
04404 j < 2 ? mBlurCubeTexture[j] : cube_out->getGLName(), 0);
04405 validate_framebuffer_object();
04406 glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
04407 glClear(GL_COLOR_BUFFER_BIT);
04408 glLoadIdentity();
04409 apply_cube_face_rotation(i);
04410 for (S32 x = -kernel; x <= kernel; ++x)
04411 {
04412 glPushMatrix();
04413 glRotatef(x*step, axis[j].mV[0], axis[j].mV[1], axis[j].mV[2]);
04414 render_cube_map();
04415 glPopMatrix();
04416 }
04417 stop_glerror();
04418 }
04419 }
04420
04421 stop_glerror();
04422
04423 glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, 0);
04424
04425 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
04426 glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_FALSE);
04427 glMatrixMode(GL_PROJECTION);
04428 glPopMatrix();
04429 glMatrixMode(GL_MODELVIEW);
04430 glPopMatrix();
04431
04432 cube_in->disableTexture();
04433 gViewerWindow->setupViewport();
04434 gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
04435
04436 LLGLState::checkStates();
04437 LLGLState::checkTextureChannels();
04438 LLGLState::checkClientArrays();
04439 }
04440
04441 void LLPipeline::bindScreenToTexture()
04442 {
04443
04444 }
04445
04446 void LLPipeline::renderBloom(BOOL for_snapshot)
04447 {
04448 if (!(gPipeline.canUseVertexShaders() &&
04449 sRenderGlow))
04450 {
04451 return;
04452 }
04453
04454 LLGLState::checkStates();
04455 LLGLState::checkTextureChannels();
04456
04457 assertInitialized();
04458
04459 if (gUseWireframe)
04460 {
04461 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
04462 }
04463
04464 U32 res_mod = gSavedSettings.getU32("RenderResolutionDivisor");
04465
04466 LLVector2 tc1(0,0);
04467 LLVector2 tc2((F32) gViewerWindow->getWindowDisplayWidth(),
04468 (F32) gViewerWindow->getWindowDisplayHeight());
04469
04470 if (res_mod > 1)
04471 {
04472 tc2 /= (F32) res_mod;
04473 }
04474
04475 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
04476
04477 LLFastTimer ftm(LLFastTimer::FTM_RENDER_BLOOM);
04478 gGL.color4f(1,1,1,1);
04479 LLGLDepthTest depth(GL_FALSE);
04480 LLGLDisable blend(GL_BLEND);
04481 LLGLDisable cull(GL_CULL_FACE);
04482
04483 enableLightsFullbright(LLColor4(1,1,1,1));
04484
04485 glMatrixMode(GL_PROJECTION);
04486 glPushMatrix();
04487 glLoadIdentity();
04488 glMatrixMode(GL_MODELVIEW);
04489 glPushMatrix();
04490 glLoadIdentity();
04491
04492 LLGLDisable test(GL_ALPHA_TEST);
04493
04494 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
04495 glClearColor(0,0,0,0);
04496
04497 if (for_snapshot)
04498 {
04499 mGlow[1].bindTexture();
04500 {
04501
04502
04503
04504
04505 LLGLEnable blend(GL_BLEND);
04506 gGL.blendFunc(GL_ONE, GL_ONE);
04507 tc2.setVec(1,1);
04508 gGL.begin(LLVertexBuffer::TRIANGLE_STRIP);
04509 gGL.color4f(1,1,1,1);
04510 gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
04511 gGL.vertex2f(-1,-1);
04512
04513 gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
04514 gGL.vertex2f(-1,1);
04515
04516 gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
04517 gGL.vertex2f(1,-1);
04518
04519 gGL.texCoord2f(tc2.mV[0], tc2.mV[1]);
04520 gGL.vertex2f(1,1);
04521 gGL.end();
04522
04523 gGL.flush();
04524 gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
04525 }
04526
04527 gGL.flush();
04528 glMatrixMode(GL_PROJECTION);
04529 glPopMatrix();
04530 glMatrixMode(GL_MODELVIEW);
04531 glPopMatrix();
04532
04533 return;
04534 }
04535
04536 {
04537 {
04538 LLFastTimer ftm(LLFastTimer::FTM_RENDER_BLOOM_FBO);
04539 mGlow[2].bindTarget();
04540 mGlow[2].clear();
04541 }
04542
04543 gGlowExtractProgram.bind();
04544 F32 minLum = llclamp(gSavedSettings.getF32("RenderGlowMinLuminance"), 0.0f, 1.0f);
04545 F32 maxAlpha = gSavedSettings.getF32("RenderGlowMaxExtractAlpha");
04546 F32 warmthAmount = gSavedSettings.getF32("RenderGlowWarmthAmount");
04547 LLVector3 lumWeights = gSavedSettings.getVector3("RenderGlowLumWeights");
04548 LLVector3 warmthWeights = gSavedSettings.getVector3("RenderGlowWarmthWeights");
04549 gGlowExtractProgram.uniform1f("minLuminance", minLum);
04550 gGlowExtractProgram.uniform1f("maxExtractAlpha", maxAlpha);
04551 gGlowExtractProgram.uniform3f("lumWeights", lumWeights.mV[0], lumWeights.mV[1], lumWeights.mV[2]);
04552 gGlowExtractProgram.uniform3f("warmthWeights", warmthWeights.mV[0], warmthWeights.mV[1], warmthWeights.mV[2]);
04553 gGlowExtractProgram.uniform1f("warmthAmount", warmthAmount);
04554 LLGLEnable blend_on(GL_BLEND);
04555 LLGLEnable test(GL_ALPHA_TEST);
04556 glAlphaFunc(GL_GREATER, 0.f);
04557 gGL.blendFunc(GL_SRC_ALPHA, GL_ONE);
04558 LLViewerImage::unbindTexture(0, GL_TEXTURE_2D);
04559
04560 glDisable(GL_TEXTURE_2D);
04561 glEnable(GL_TEXTURE_RECTANGLE_ARB);
04562 mScreen.bindTexture();
04563
04564 gGL.color4f(1,1,1,1);
04565 gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
04566 gGL.begin(LLVertexBuffer::TRIANGLE_STRIP);
04567 gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
04568 gGL.vertex2f(-1,-1);
04569
04570 gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
04571 gGL.vertex2f(-1,1);
04572
04573 gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
04574 gGL.vertex2f(1,-1);
04575
04576 gGL.texCoord2f(tc2.mV[0], tc2.mV[1]);
04577 gGL.vertex2f(1,1);
04578 gGL.end();
04579
04580 glEnable(GL_TEXTURE_2D);
04581 glDisable(GL_TEXTURE_RECTANGLE_ARB);
04582
04583 mGlow[2].flush();
04584 }
04585
04586 tc1.setVec(0,0);
04587 tc2.setVec(1,1);
04588
04589
04590
04591
04592 U32 glowResPow = gSavedSettings.getS32("RenderGlowResolutionPow");
04593 const U32 glow_res = llmax(1,
04594 llmin(1024, 1 << glowResPow));
04595
04596 S32 kernel = gSavedSettings.getS32("RenderGlowIterations")*2;
04597 F32 delta = gSavedSettings.getF32("RenderGlowWidth") / glow_res;
04598
04599
04600 if (glowResPow < 9)
04601 {
04602 delta *= 0.5f;
04603 }
04604 F32 strength = gSavedSettings.getF32("RenderGlowStrength");
04605
04606 gGlowProgram.bind();
04607 gGlowProgram.uniform1f("glowStrength", strength);
04608
04609 for (S32 i = 0; i < kernel; i++)
04610 {
04611 LLViewerImage::unbindTexture(0, GL_TEXTURE_2D);
04612 {
04613 LLFastTimer ftm(LLFastTimer::FTM_RENDER_BLOOM_FBO);
04614 mGlow[i%2].bindTarget();
04615 mGlow[i%2].clear();
04616 }
04617
04618 if (i == 0)
04619 {
04620 mGlow[2].bindTexture();
04621 }
04622 else
04623 {
04624 mGlow[(i-1)%2].bindTexture();
04625 }
04626
04627 if (i%2 == 0)
04628 {
04629 gGlowProgram.uniform2f("glowDelta", delta, 0);
04630 }
04631 else
04632 {
04633 gGlowProgram.uniform2f("glowDelta", 0, delta);
04634 }
04635
04636 gGL.begin(LLVertexBuffer::TRIANGLE_STRIP);
04637 gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
04638 gGL.vertex2f(-1,-1);
04639
04640 gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
04641 gGL.vertex2f(-1,1);
04642
04643 gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
04644 gGL.vertex2f(1,-1);
04645
04646 gGL.texCoord2f(tc2.mV[0], tc2.mV[1]);
04647 gGL.vertex2f(1,1);
04648 gGL.end();
04649
04650 mGlow[i%2].flush();
04651 }
04652
04653 gGlowProgram.unbind();
04654
04655 if (LLRenderTarget::sUseFBO)
04656 {
04657 LLFastTimer ftm(LLFastTimer::FTM_RENDER_BLOOM_FBO);
04658 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
04659 }
04660
04661 gViewerWindow->setupViewport();
04662
04663
04664
04665
04666
04667
04668
04669
04670
04671
04672
04673
04674
04675
04676
04677
04678
04679
04680
04681
04682
04683
04684
04685
04686
04687
04688
04689
04690
04691
04692
04693
04694
04695
04696
04697
04698
04699
04700
04701
04702
04703
04704
04705
04706
04707
04708
04709
04710
04711
04712
04713
04714
04715
04716
04717
04718
04719
04720
04721
04722
04723
04724
04725
04726
04727 gGL.flush();
04728
04729 {
04730 LLVertexBuffer::unbind();
04731
04732 F32 uv0[] =
04733 {
04734 tc1.mV[0], tc1.mV[1],
04735 tc1.mV[0], tc2.mV[1],
04736 tc2.mV[0], tc1.mV[1],
04737 tc2.mV[0], tc2.mV[1]
04738 };
04739
04740 tc2.setVec((F32) gViewerWindow->getWindowDisplayWidth(),
04741 (F32) gViewerWindow->getWindowDisplayHeight());
04742
04743 if (res_mod > 1)
04744 {
04745 tc2 /= (F32) res_mod;
04746 }
04747
04748 F32 uv1[] =
04749 {
04750 tc1.mV[0], tc1.mV[1],
04751 tc1.mV[0], tc2.mV[1],
04752 tc2.mV[0], tc1.mV[1],
04753 tc2.mV[0], tc2.mV[1]
04754 };
04755
04756 F32 v[] =
04757 {
04758 -1,-1,
04759 -1,1,
04760 1,-1,
04761 1,1
04762 };
04763
04764 LLGLDisable blend(GL_BLEND);
04765
04766
04767 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
04768 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE);
04769 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
04770 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
04771
04772 mGlow[1].bindTexture();
04773 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
04774 glTexCoordPointer(2, GL_FLOAT, 0, uv0);
04775 glActiveTextureARB(GL_TEXTURE1_ARB);
04776 glEnable(GL_TEXTURE_RECTANGLE_ARB);
04777
04778
04779 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
04780 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_ADD);
04781 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB);
04782 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
04783 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE);
04784 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
04785
04786 glClientActiveTextureARB(GL_TEXTURE1_ARB);
04787 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
04788 glTexCoordPointer(2, GL_FLOAT, 0, uv1);
04789
04790 glVertexPointer(2, GL_FLOAT, 0, v);
04791
04792 mScreen.bindTexture();
04793
04794 LLGLEnable multisample(GL_MULTISAMPLE_ARB);
04795 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
04796
04797 glDisable(GL_TEXTURE_RECTANGLE_ARB);
04798 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
04799 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
04800 glClientActiveTextureARB(GL_TEXTURE0_ARB);
04801 glActiveTextureARB(GL_TEXTURE0_ARB);
04802 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
04803 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
04804 }
04805
04806 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
04807 glMatrixMode(GL_PROJECTION);
04808 glPopMatrix();
04809 glMatrixMode(GL_MODELVIEW);
04810 glPopMatrix();
04811
04812 LLVertexBuffer::unbind();
04813
04814 LLGLState::checkStates();
04815 LLGLState::checkTextureChannels();
04816
04817 }
04818
04819 void LLPipeline::processImagery(LLCamera& camera)
04820 {
04821 for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin();
04822 iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
04823 {
04824 LLViewerRegion* region = *iter;
04825 LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_VOLUME);
04826 if (part)
04827 {
04828 part->processImagery(&camera);
04829 }
04830 }
04831 }
04832
04833
04834 inline float sgn(float a)
04835 {
04836 if (a > 0.0F) return (1.0F);
04837 if (a < 0.0F) return (-1.0F);
04838 return (0.0F);
04839 }
04840
04841 void LLPipeline::generateWaterReflection(LLCamera& camera_in)
04842 {
04843 if (LLPipeline::sWaterReflections && assertInitialized() && LLDrawPoolWater::sNeedsReflectionUpdate)
04844 {
04845 LLVertexBuffer::unbind();
04846
04847 LLGLState::checkStates();
04848 LLGLState::checkTextureChannels();
04849 LLGLState::checkClientArrays();
04850
04851 LLCamera camera = camera_in;
04852 camera.setFar(camera.getFar()*0.87654321f);
04853 LLPipeline::sReflectionRender = TRUE;
04854 S32 occlusion = LLPipeline::sUseOcclusion;
04855 LLPipeline::sUseOcclusion = llmin(occlusion, 1);
04856 U32 type_mask = gPipeline.mRenderTypeMask;
04857
04858 glh::matrix4f projection = glh_get_current_projection();
04859 glh::matrix4f mat;
04860
04861 stop_glerror();
04862 LLPlane plane;
04863
04864 F32 height = gAgent.getRegion()->getWaterHeight();
04865 F32 to_clip = fabsf(camera.getOrigin().mV[2]-height);
04866 F32 pad = -to_clip*0.05f;
04867
04868
04869 LLVector3 pnorm;
04870 F32 pd;
04871
04872 S32 water_clip = 0;
04873 if (!LLViewerCamera::getInstance()->cameraUnderWater())
04874 {
04875 pnorm.setVec(0,0,1);
04876 pd = -height;
04877 plane.setVec(pnorm, pd);
04878 water_clip = -1;
04879 }
04880 else
04881 {
04882 pnorm = LLVector3(0,0,-1);
04883 pd = height;
04884 plane.setVec(pnorm, pd);
04885 water_clip = 1;
04886 }
04887
04888
04889
04890 if (!LLViewerCamera::getInstance()->cameraUnderWater())
04891 {
04892 LLViewerImage::unbindTexture(0, GL_TEXTURE_2D);
04893 glClearColor(0,0,0,0);
04894 glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
04895 mWaterRef.bindTarget();
04896 mWaterRef.getViewport(gGLViewport);
04897 mWaterRef.clear();
04898 glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_FALSE);
04899
04900 stop_glerror();
04901
04902 LLVector3 origin = camera.getOrigin();
04903
04904 glPushMatrix();
04905
04906 mat.set_scale(glh::vec3f(1,1,-1));
04907 mat.set_translate(glh::vec3f(0,0,height*2.f));
04908
04909 glh::matrix4f current = glh_get_current_modelview();
04910
04911 mat = current * mat;
04912
04913 glh_set_current_modelview(mat);
04914 glLoadMatrixf(mat.m);
04915
04916 LLViewerCamera::updateFrustumPlanes(camera, FALSE, TRUE);
04917
04918 glCullFace(GL_FRONT);
04919
04920
04921 {
04922 U32 tmp = mRenderTypeMask;
04923 mRenderTypeMask &= ((1 << LLPipeline::RENDER_TYPE_SKY) |
04924 (1 << LLPipeline::RENDER_TYPE_CLOUDS) |
04925 (1 << LLPipeline::RENDER_TYPE_WL_SKY));
04926
04927 static LLCullResult result;
04928 updateCull(camera, result);
04929 stateSort(camera, result);
04930 renderGeom(camera, TRUE);
04931
04932 mRenderTypeMask = tmp;
04933 }
04934
04935 if (LLDrawPoolWater::sNeedsDistortionUpdate)
04936 {
04937 mRenderTypeMask &= ~((1<<LLPipeline::RENDER_TYPE_WATER) |
04938 (1<<LLPipeline::RENDER_TYPE_GROUND) |
04939 (1<<LLPipeline::RENDER_TYPE_SKY) |
04940 (1<<LLPipeline::RENDER_TYPE_CLOUDS));
04941
04942 if (gSavedSettings.getBOOL("RenderWaterReflections"))
04943 {
04944
04945 S32 detail = gSavedSettings.getS32("RenderReflectionDetail");
04946 if (detail < 3)
04947 {
04948 mRenderTypeMask &= ~(1 << LLPipeline::RENDER_TYPE_PARTICLES);
04949 if (detail < 2)
04950 {
04951 mRenderTypeMask &= ~(1 << LLPipeline::RENDER_TYPE_AVATAR);
04952 if (detail < 1)
04953 {
04954 mRenderTypeMask &= ~(1 << LLPipeline::RENDER_TYPE_VOLUME);
04955 }
04956 }
04957 }
04958
04959 LLSpatialPartition::sFreezeState = TRUE;
04960 LLPipeline::sSkipUpdate = TRUE;
04961 LLGLUserClipPlane clip_plane(plane, mat, projection);
04962 static LLCullResult result;
04963 updateCull(camera, result, 1);
04964 stateSort(camera, result);
04965 renderGeom(camera);
04966 LLSpatialPartition::sFreezeState = FALSE;
04967 LLPipeline::sSkipUpdate = FALSE;
04968 }
04969 }
04970 glCullFace(GL_BACK);
04971 glPopMatrix();
04972 mWaterRef.flush();
04973
04974 glh_set_current_modelview(current);
04975 }
04976
04977
04978 static BOOL last_update = TRUE;
04979 if (last_update)
04980 {
04981 camera.setFar(camera_in.getFar());
04982 mRenderTypeMask = type_mask & (~(1<<LLPipeline::RENDER_TYPE_WATER) |
04983 (1<<LLPipeline::RENDER_TYPE_GROUND));
04984 stop_glerror();
04985
04986 LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater() ? FALSE : TRUE;
04987
04988 if (LLPipeline::sUnderWaterRender)
04989 {
04990 mRenderTypeMask &= ~((1<<LLPipeline::RENDER_TYPE_GROUND) |
04991 (1<<LLPipeline::RENDER_TYPE_SKY) |
04992 (1<<LLPipeline::RENDER_TYPE_CLOUDS) |
04993 (1<<LLPipeline::RENDER_TYPE_WL_SKY));
04994 }
04995 LLViewerCamera::updateFrustumPlanes(camera);
04996
04997 LLViewerImage::unbindTexture(0, GL_TEXTURE_2D);
04998 LLColor4& col = LLDrawPoolWater::sWaterFogColor;
04999 glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f);
05000 glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
05001 mWaterDis.bindTarget();
05002 mWaterDis.getViewport(gGLViewport);
05003 mWaterDis.clear();
05004 glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_FALSE);
05005
05006 if (!LLPipeline::sUnderWaterRender || LLDrawPoolWater::sNeedsReflectionUpdate)
05007 {
05008
05009 mat = glh_get_current_modelview();
05010 LLGLUserClipPlane clip_plane(LLPlane(-pnorm, -(pd+pad)), mat, projection);
05011 static LLCullResult result;
05012 updateCull(camera, result, water_clip);
05013 stateSort(camera, result);
05014 renderGeom(camera);
05015 }
05016
05017 LLPipeline::sUnderWaterRender = FALSE;
05018 mWaterDis.flush();
05019 }
05020 last_update = LLDrawPoolWater::sNeedsReflectionUpdate && LLDrawPoolWater::sNeedsDistortionUpdate;
05021
05022 LLRenderTarget::unbindTarget();
05023 LLPipeline::sReflectionRender = FALSE;
05024
05025 if (!LLRenderTarget::sUseFBO)
05026 {
05027 glClear(GL_DEPTH_BUFFER_BIT);
05028 }
05029 glClearColor(0.f, 0.f, 0.f, 0.f);
05030
05031 gViewerWindow->setupViewport();
05032 mRenderTypeMask = type_mask;
05033 LLDrawPoolWater::sNeedsReflectionUpdate = FALSE;
05034 LLDrawPoolWater::sNeedsDistortionUpdate = FALSE;
05035 LLViewerCamera::getInstance()->setUserClipPlane(LLPlane(-pnorm, -pd));
05036 LLPipeline::sUseOcclusion = occlusion;
05037
05038 LLGLState::checkStates();
05039 LLGLState::checkTextureChannels();
05040 LLGLState::checkClientArrays();
05041 }
05042 }
05043
05044 LLCubeMap* LLPipeline::findReflectionMap(const LLVector3& location)
05045 {
05046 LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosAgent(location);
05047 if (region)
05048 {
05049 LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_VOLUME);
05050 if (part)
05051 {
05052 LLSpatialGroup::OctreeNode* node = part->mOctree->getNodeAt(LLVector3d(location), 32.0);
05053 if (node)
05054 {
05055 LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0);
05056 return group->mReflectionMap;
05057 }
05058 }
05059 }
05060
05061 return NULL;
05062 }
05063
05064 void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, BOOL texture)
05065 {
05066 for (LLCullResult::sg_list_t::iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i)
05067 {
05068 LLSpatialGroup* group = *i;
05069 if (!group->isDead() &&
05070 (!sUseOcclusion || !group->isState(LLSpatialGroup::OCCLUDED)) &&
05071 gPipeline.hasRenderType(group->mSpatialPartition->mDrawableType) &&
05072 group->mDrawMap.find(type) != group->mDrawMap.end())
05073 {
05074 pass->renderGroup(group,type,mask,texture);
05075 }
05076 }
05077 }
05078
05079 void LLPipeline::generateImpostor(LLVOAvatar* avatar)
05080 {
05081 static LLCullResult result;
05082 result.clear();
05083 grabReferences(result);
05084
05085 if (!avatar || !avatar->mDrawable)
05086 {
05087 return;
05088 }
05089
05090 assertInitialized();
05091
05092 U32 mask;
05093 BOOL muted = LLMuteList::getInstance()->isMuted(avatar->getID());
05094
05095 if (muted)
05096 {
05097 mask = 1 << LLPipeline::RENDER_TYPE_AVATAR;
05098 }
05099 else
05100 {
05101 mask = (1<<LLPipeline::RENDER_TYPE_VOLUME) |
05102 (1<<LLPipeline::RENDER_TYPE_AVATAR) |
05103 (1<<LLPipeline::RENDER_TYPE_BUMP) |
05104 (1<<LLPipeline::RENDER_TYPE_GRASS) |
05105 (1<<LLPipeline::RENDER_TYPE_SIMPLE) |
05106 (1<<LLPipeline::RENDER_TYPE_ALPHA) |
05107 (1<<LLPipeline::RENDER_TYPE_INVISIBLE);
05108 }
05109
05110 mask = mask & gPipeline.getRenderTypeMask();
05111 U32 saved_mask = gPipeline.mRenderTypeMask;
05112 gPipeline.mRenderTypeMask = mask;
05113
05114 S32 occlusion = sUseOcclusion;
05115 sUseOcclusion = 0;
05116 sReflectionRender = TRUE;
05117 sImpostorRender = TRUE;
05118
05119 markVisible(avatar->mDrawable, *LLViewerCamera::getInstance());
05120 LLVOAvatar::sUseImpostors = FALSE;
05121
05122 LLVOAvatar::attachment_map_t::iterator iter;
05123 for (iter = avatar->mAttachmentPoints.begin();
05124 iter != avatar->mAttachmentPoints.end();
05125 ++iter)
05126 {
05127 LLViewerObject* object = iter->second->getObject();
05128 if (object)
05129 {
05130 markVisible(object->mDrawable->getSpatialBridge(), *LLViewerCamera::getInstance());
05131 }
05132 }
05133
05134 stateSort(*LLViewerCamera::getInstance(), result);
05135
05136 const LLVector3* ext = avatar->mDrawable->getSpatialExtents();
05137 LLVector3 pos(avatar->getRenderPosition()+avatar->getImpostorOffset());
05138
05139 LLCamera camera = *LLViewerCamera::getInstance();
05140
05141 camera.lookAt(LLViewerCamera::getInstance()->getOrigin(), pos, LLViewerCamera::getInstance()->getUpAxis());
05142
05143 LLVector2 tdim;
05144
05145 LLVector3 half_height = (ext[1]-ext[0])*0.5f;
05146
05147 LLVector3 left = camera.getLeftAxis();
05148 left *= left;
05149 left.normVec();
05150
05151 LLVector3 up = camera.getUpAxis();
05152 up *= up;
05153 up.normVec();
05154
05155 tdim.mV[0] = fabsf(half_height * left);
05156 tdim.mV[1] = fabsf(half_height * up);
05157
05158 glMatrixMode(GL_PROJECTION);
05159 glPushMatrix();
05160
05161 F32 distance = (pos-camera.getOrigin()).magVec();
05162 F32 fov = atanf(tdim.mV[1]/distance)*2.f*RAD_TO_DEG;
05163 F32 aspect = tdim.mV[0]/tdim.mV[1];
05164 glh::matrix4f persp = gl_perspective(fov, aspect, 1.f, 256.f);
05165 glh_set_current_projection(persp);
05166 glLoadMatrixf(persp.m);
05167
05168 glMatrixMode(GL_MODELVIEW);
05169 glPushMatrix();
05170 glh::matrix4f mat;
05171 camera.getOpenGLTransform(mat.m);
05172
05173 mat = glh::matrix4f((GLfloat*) OGL_TO_CFR_ROTATION) * mat;
05174
05175 glLoadMatrixf(mat.m);
05176 glh_set_current_modelview(mat);
05177
05178 glClearColor(0.0f,0.0f,0.0f,0.0f);
05179 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
05180 glStencilMask(0xFFFFFFFF);
05181 glClearStencil(0);
05182
05183
05184 F32 pa = gViewerWindow->getWindowDisplayHeight() / (RAD_TO_DEG * LLViewerCamera::getInstance()->getView());
05185
05186
05187 U32 resY = llmin(nhpo2((U32) (fov*pa)), (U32) 512);
05188 U32 resX = llmin(nhpo2((U32) (atanf(tdim.mV[0]/distance)*2.f*RAD_TO_DEG*pa)), (U32) 512);
05189
05190 if (!avatar->mImpostor.isComplete() || resX != avatar->mImpostor.getWidth() ||
05191 resY != avatar->mImpostor.getHeight())
05192 {
05193 avatar->mImpostor.allocate(resX,resY,GL_RGBA,TRUE);
05194 avatar->mImpostor.bindTexture();
05195 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
05196 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
05197 LLImageGL::unbindTexture(0, GL_TEXTURE_2D);
05198 }
05199
05200 {
05201 LLGLEnable scissor(GL_SCISSOR_TEST);
05202 glScissor(0, 0, resX, resY);
05203 avatar->mImpostor.bindTarget();
05204 avatar->mImpostor.getViewport(gGLViewport);
05205 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
05206 }
05207
05208 LLGLEnable stencil(GL_STENCIL_TEST);
05209
05210 glStencilFunc(GL_ALWAYS, 1, 0xFFFFFFFF);
05211 glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
05212
05213 renderGeom(camera);
05214
05215 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
05216 glStencilFunc(GL_EQUAL, 1, 0xFFFFFF);
05217
05218 {
05219 LLVector3 left = camera.getLeftAxis()*tdim.mV[0]*2.f;
05220 LLVector3 up = camera.getUpAxis()*tdim.mV[1]*2.f;
05221
05222 LLGLEnable blend(muted ? 0 : GL_BLEND);
05223
05224 if (muted)
05225 {
05226 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
05227 }
05228 else
05229 {
05230 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
05231 }
05232
05233 gGL.blendFunc(GL_ONE, GL_ONE);
05234 LLImageGL::unbindTexture(0, GL_TEXTURE_2D);
05235
05236 LLGLDepthTest depth(GL_FALSE, GL_FALSE);
05237
05238 gGL.color4f(1,1,1,1);
05239 gGL.color4ub(64,64,64,1);
05240 gGL.begin(LLVertexBuffer::QUADS);
05241 gGL.vertex3fv((pos+left-up).mV);
05242 gGL.vertex3fv((pos-left-up).mV);
05243 gGL.vertex3fv((pos-left+up).mV);
05244 gGL.vertex3fv((pos+left+up).mV);
05245 gGL.end();
05246 gGL.flush();
05247
05248
05249 gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
05250 }
05251
05252
05253 avatar->mImpostor.flush();
05254
05255 avatar->setImpostorDim(tdim);
05256
05257 LLVOAvatar::sUseImpostors = TRUE;
05258 sUseOcclusion = occlusion;
05259 sReflectionRender = FALSE;
05260 sImpostorRender = FALSE;
05261 gPipeline.mRenderTypeMask = saved_mask;
05262
05263 glMatrixMode(GL_PROJECTION);
05264 glPopMatrix();
05265 glMatrixMode(GL_MODELVIEW);
05266 glPopMatrix();
05267
05268 avatar->mNeedsImpostorUpdate = FALSE;
05269 avatar->cacheImpostorValues();
05270 }
05271
05272 BOOL LLPipeline::hasRenderBatches(const U32 type) const
05273 {
05274 return sCull->getRenderMapSize(type) > 0;
05275 }
05276
05277 LLCullResult::drawinfo_list_t::iterator LLPipeline::beginRenderMap(U32 type)
05278 {
05279 return sCull->beginRenderMap(type);
05280 }
05281
05282 LLCullResult::drawinfo_list_t::iterator LLPipeline::endRenderMap(U32 type)
05283 {
05284 return sCull->endRenderMap(type);
05285 }
05286
05287 LLCullResult::sg_list_t::iterator LLPipeline::beginAlphaGroups()
05288 {
05289 return sCull->beginAlphaGroups();
05290 }
05291
05292 LLCullResult::sg_list_t::iterator LLPipeline::endAlphaGroups()
05293 {
05294 return sCull->endAlphaGroups();
05295 }
05296