summaryrefslogtreecommitdiff
path: root/indra/newview/pipeline.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/pipeline.cpp')
-rwxr-xr-x[-rw-r--r--]indra/newview/pipeline.cpp731
1 files changed, 645 insertions, 86 deletions
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index f320f34f6e..c25d22bbdf 100644..100755
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -233,6 +233,7 @@ LLFastTimer::DeclareTimer FTM_RENDER_WL_SKY("Windlight Sky");
LLFastTimer::DeclareTimer FTM_RENDER_ALPHA("Alpha Objects");
LLFastTimer::DeclareTimer FTM_RENDER_CHARACTERS("Avatars");
LLFastTimer::DeclareTimer FTM_RENDER_BUMP("Bump");
+LLFastTimer::DeclareTimer FTM_RENDER_MATERIALS("Materials");
LLFastTimer::DeclareTimer FTM_RENDER_FULLBRIGHT("Fullbright");
LLFastTimer::DeclareTimer FTM_RENDER_GLOW("Glow");
LLFastTimer::DeclareTimer FTM_GEO_UPDATE("Geo Update");
@@ -262,10 +263,13 @@ std::string gPoolNames[] =
"POOL_GROUND",
"POOL_FULLBRIGHT",
"POOL_BUMP",
+ "POOL_MATERIALS",
"POOL_TERRAIN,"
"POOL_SKY",
"POOL_WL_SKY",
"POOL_TREE",
+ "POOL_ALPHA_MASK",
+ "POOL_FULLBRIGHT_ALPHA_MASK",
"POOL_GRASS",
"POOL_INVISIBLE",
"POOL_AVATAR",
@@ -275,7 +279,7 @@ std::string gPoolNames[] =
"POOL_ALPHA"
};
-void drawBox(const LLVector3& c, const LLVector3& r);
+void drawBox(const LLVector4a& c, const LLVector4a& r);
void drawBoxOutline(const LLVector3& pos, const LLVector3& size);
U32 nhpo2(U32 v);
LLVertexBuffer* ll_create_cube_vb(U32 type_mask, U32 usage);
@@ -352,6 +356,7 @@ BOOL LLPipeline::sRenderParticleBeacons = FALSE;
BOOL LLPipeline::sRenderSoundBeacons = FALSE;
BOOL LLPipeline::sRenderBeacons = FALSE;
BOOL LLPipeline::sRenderHighlight = TRUE;
+LLRender::eTexIndex LLPipeline::sRenderHighlightTextureChannel = LLRender::DIFFUSE_MAP;
BOOL LLPipeline::sForceOldBakedUpload = FALSE;
S32 LLPipeline::sUseOcclusion = 0;
BOOL LLPipeline::sDelayVBUpdate = TRUE;
@@ -377,6 +382,7 @@ BOOL LLPipeline::sRenderDeferred = FALSE;
BOOL LLPipeline::sMemAllocationThrottled = FALSE;
S32 LLPipeline::sVisibleLightCount = 0;
F32 LLPipeline::sMinRenderSize = 0.f;
+BOOL LLPipeline::sRenderingHUDs;
// EventHost API LLPipeline listener.
static LLPipelineListener sPipelineListener;
@@ -398,8 +404,8 @@ void validate_framebuffer_object();
bool addDeferredAttachments(LLRenderTarget& target)
{
- return target.addColorAttachment(GL_RGBA) && //specular
- target.addColorAttachment(GL_RGBA); //normal+z
+ return target.addColorAttachment(GL_SRGB8_ALPHA8) && //specular
+ target.addColorAttachment(GL_RGB10_A2); //normal+z
}
LLPipeline::LLPipeline() :
@@ -435,10 +441,14 @@ LLPipeline::LLPipeline() :
mWaterPool(NULL),
mGroundPool(NULL),
mSimplePool(NULL),
+ mGrassPool(NULL),
+ mAlphaMaskPool(NULL),
+ mFullbrightAlphaMaskPool(NULL),
mFullbrightPool(NULL),
mInvisiblePool(NULL),
mGlowPool(NULL),
mBumpPool(NULL),
+ mMaterialsPool(NULL),
mWLSkyPool(NULL),
mLightMask(0),
mLightMovingMask(0),
@@ -485,10 +495,13 @@ void LLPipeline::init()
//create render pass pools
getPool(LLDrawPool::POOL_ALPHA);
getPool(LLDrawPool::POOL_SIMPLE);
+ getPool(LLDrawPool::POOL_ALPHA_MASK);
+ getPool(LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK);
getPool(LLDrawPool::POOL_GRASS);
getPool(LLDrawPool::POOL_FULLBRIGHT);
getPool(LLDrawPool::POOL_INVISIBLE);
getPool(LLDrawPool::POOL_BUMP);
+ getPool(LLDrawPool::POOL_MATERIALS);
getPool(LLDrawPool::POOL_GLOW);
LLViewerStats::getInstance()->mTrianglesDrawnStat.reset();
@@ -916,12 +929,26 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
S32 shadow_detail = RenderShadowDetail;
BOOL ssao = RenderDeferredSSAO;
+ const U32 occlusion_divisor = 3;
+
//allocate deferred rendering color buffers
- if (!mDeferredScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
+ if (!mDeferredScreen.allocate(resX, resY, GL_SRGB8_ALPHA8, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
if (!mDeferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
+ if (!mOcclusionDepth.allocate(resX/occlusion_divisor, resY/occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
if (!addDeferredAttachments(mDeferredScreen)) return false;
-
- if (!mScreen.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
+
+ GLuint screenFormat = GL_RGBA16;
+ if (gGLManager.mIsATI)
+ {
+ screenFormat = GL_RGBA12;
+ }
+
+ if (gGLManager.mGLVersion < 4.f && gGLManager.mIsNVIDIA)
+ {
+ screenFormat = GL_RGBA16F_ARB;
+ }
+
+ if (!mScreen.allocate(resX, resY, screenFormat, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
if (samples > 0)
{
if (!mFXAABuffer.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false;
@@ -948,6 +975,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
for (U32 i = 0; i < 4; i++)
{
if (!mShadow[i].allocate(sun_shadow_map_width,U32(resY*scale), 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE)) return false;
+ if (!mShadowOcclusion[i].allocate(mShadow[i].getWidth()/occlusion_divisor, mShadow[i].getHeight()/occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE)) return false;
}
}
else
@@ -955,6 +983,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
for (U32 i = 0; i < 4; i++)
{
mShadow[i].release();
+ mShadowOcclusion[i].release();
}
}
@@ -967,6 +996,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
for (U32 i = 4; i < 6; i++)
{
if (!mShadow[i].allocate(spot_shadow_map_width, height, 0, TRUE, FALSE)) return false;
+ if (!mShadowOcclusion[i].allocate(mShadow[i].getWidth()/occlusion_divisor, mShadow[i].getHeight()/occlusion_divisor, 0, TRUE, FALSE)) return false;
}
}
else
@@ -974,6 +1004,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
for (U32 i = 4; i < 6; i++)
{
mShadow[i].release();
+ mShadowOcclusion[i].release();
}
}
@@ -990,11 +1021,13 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
for (U32 i = 0; i < 6; i++)
{
mShadow[i].release();
+ mShadowOcclusion[i].release();
}
mFXAABuffer.release();
mScreen.release();
mDeferredScreen.release(); //make sure to release any render targets that share a depth buffer with mDeferredScreen first
mDeferredDepth.release();
+ mOcclusionDepth.release();
if (!mScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false;
}
@@ -1012,11 +1045,18 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
}
//static
+void LLPipeline::updateRenderBump()
+{
+ sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
+}
+
+//static
void LLPipeline::updateRenderDeferred()
{
BOOL deferred = ((RenderDeferred &&
LLRenderTarget::sUseFBO &&
- LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
+ LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
+ LLPipeline::sRenderBump &&
VertexShaderEnable &&
RenderAvatarVP &&
WindLightUseAtmosShaders) ? TRUE : FALSE) &&
@@ -1159,7 +1199,7 @@ void LLPipeline::releaseLUTBuffers()
{
if (mLightFunc)
{
- LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, GL_R8, 0, 1, &mLightFunc);
+ LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, GL_R16F, 0, 1, &mLightFunc);
mLightFunc = 0;
}
}
@@ -1213,7 +1253,7 @@ void LLPipeline::createGLBuffers()
for (U32 i = 0; i < 3; i++)
{
- mGlow[i].allocate(512,glow_res,GL_RGBA,FALSE,FALSE);
+ mGlow[i].allocate(512,glow_res, GL_RGBA,FALSE,FALSE);
}
allocateScreenBuffer(resX,resY);
@@ -1264,13 +1304,18 @@ void LLPipeline::createGLBuffers()
gBumpImageList.restoreGL();
}
+F32 lerpf(F32 a, F32 b, F32 w)
+{
+ return a + w * (b - a);
+}
+
void LLPipeline::createLUTBuffers()
{
if (sRenderDeferred)
{
if (!mLightFunc)
{
- U32 lightResX = gSavedSettings.getU32("RenderSpecularResX");
+ /*U32 lightResX = gSavedSettings.getU32("RenderSpecularResX");
U32 lightResY = gSavedSettings.getU32("RenderSpecularResY");
U8* ls = new U8[lightResX*lightResY];
F32 specExp = gSavedSettings.getF32("RenderSpecularExponent");
@@ -1306,13 +1351,62 @@ void LLPipeline::createLUTBuffers()
// Combined with a bit of noise and trilinear filtering, the banding is hardly noticable.
ls[y*lightResX+x] = (U8)(llclamp(spec * (1.f / 6), 0.f, 1.f) * 255);
}
+ }*/
+
+
+ U32 lightResX = gSavedSettings.getU32("RenderSpecularResX");
+ U32 lightResY = gSavedSettings.getU32("RenderSpecularResY");
+ F32* ls = new F32[lightResX*lightResY];
+ //F32 specExp = gSavedSettings.getF32("RenderSpecularExponent"); // Note: only use this when creating new specular lighting functions.
+ // Calculate the (normalized) blinn-phong specular lookup texture. (with a few tweaks)
+ for (U32 y = 0; y < lightResY; ++y)
+ {
+ for (U32 x = 0; x < lightResX; ++x)
+ {
+ ls[y*lightResX+x] = 0;
+ F32 sa = (F32) x/(lightResX-1);
+ F32 spec = (F32) y/(lightResY-1);
+ F32 n = spec * spec * 368;
+
+ // Nothing special here. Just your typical blinn-phong term.
+ spec = powf(sa, n);
+
+ // Apply our normalization function.
+ // Note: This is the full equation that applies the full normalization curve, not an approximation.
+ // This is fine, given we only need to create our LUT once per buffer initialization.
+ spec *= (((n + 2) * (n + 4)) / (8 * F_PI * (powf(2, -n/2) + n)));
+
+ // Since we use R16F, we no longer have a dynamic range issue we need to work around here.
+ // Though some older drivers may not like this, newer drivers shouldn't have this problem.
+ ls[y*lightResX+x] = spec;
+
+
+ //beckmann distribution
+ /*F32 alpha = acosf((F32) x/(lightResX-1));
+ F32 m = 1.f - (F32) y/(lightResY-1);
+
+ F32 cos4_alpha = cosf(alpha);
+ cos4_alpha *= cos4_alpha;
+ cos4_alpha *= cos4_alpha;
+
+ F32 tan_alpha = tanf(alpha);
+ F32 tan2_alpha = tan_alpha*tan_alpha;
+
+ F32 k = expf(-(tan2_alpha)/(m*m)) /
+ (3.14159f*m*m*cos4_alpha);
+
+ ls[y*lightResX+x] = k;*/
+ }
}
- LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, GL_R8, 1, &mLightFunc);
+ LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, GL_R16F, 1, &mLightFunc);
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc);
- LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_R8, lightResX, lightResY, GL_RED, GL_UNSIGNED_BYTE, ls, false);
+ LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_R16F, lightResX, lightResY, GL_RED, GL_FLOAT, ls, false);
+ //LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_UNSIGNED_BYTE, lightResX, lightResY, GL_RED, GL_UNSIGNED_BYTE, ls, false);
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
delete [] ls;
}
@@ -1516,6 +1610,14 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerTexture *tex0)
poolp = mGrassPool;
break;
+ case LLDrawPool::POOL_ALPHA_MASK:
+ poolp = mAlphaMaskPool;
+ break;
+
+ case LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK:
+ poolp = mFullbrightAlphaMaskPool;
+ break;
+
case LLDrawPool::POOL_FULLBRIGHT:
poolp = mFullbrightPool;
break;
@@ -1539,7 +1641,9 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerTexture *tex0)
case LLDrawPool::POOL_BUMP:
poolp = mBumpPool;
break;
-
+ case LLDrawPool::POOL_MATERIALS:
+ poolp = mMaterialsPool;
+ break;
case LLDrawPool::POOL_ALPHA:
poolp = mAlphaPool;
break;
@@ -1603,20 +1707,44 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* ima
return 0;
}
- bool alpha = te->getColor().mV[3] < 0.999f;
+ LLMaterial* mat = te->getMaterialParams().get();
+
+ bool color_alpha = te->getColor().mV[3] < 0.999f;
+ bool alpha = color_alpha;
if (imagep)
{
alpha = alpha || (imagep->getComponents() == 4 && imagep->getType() != LLViewerTexture::MEDIA_TEXTURE) || (imagep->getComponents() == 2);
}
-
+
+ if (alpha && mat)
+ {
+ switch (mat->getDiffuseAlphaMode())
+ {
+ case 1:
+ alpha = true; // Material's alpha mode is set to blend. Toss it into the alpha draw pool.
+ break;
+ case 0: //alpha mode set to none, never go to alpha pool
+ case 3: //alpha mode set to emissive, never go to alpha pool
+ alpha = color_alpha;
+ break;
+ default: //alpha mode set to "mask", go to alpha pool if fullbright
+ alpha = color_alpha; // Material's alpha mode is set to none, mask, or emissive. Toss it into the opaque material draw pool.
+ break;
+ }
+ }
+
if (alpha)
{
return LLDrawPool::POOL_ALPHA;
}
- else if ((te->getBumpmap() || te->getShiny()))
+ else if ((te->getBumpmap() || te->getShiny()) && (!mat || mat->getNormalID().isNull()))
{
return LLDrawPool::POOL_BUMP;
}
+ else if (mat && !alpha)
+ {
+ return LLDrawPool::POOL_MATERIALS;
+ }
else
{
return LLDrawPool::POOL_SIMPLE;
@@ -2312,7 +2440,14 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
if (to_texture)
{
- mScreen.bindTarget();
+ if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender)
+ {
+ mOcclusionDepth.bindTarget();
+ }
+ else
+ {
+ mScreen.bindTarget();
+ }
}
if (sUseOcclusion > 1)
@@ -2450,7 +2585,14 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
if (to_texture)
{
- mScreen.flush();
+ if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender)
+ {
+ mOcclusionDepth.flush();
+ }
+ else
+ {
+ mScreen.flush();
+ }
}
}
@@ -2518,6 +2660,73 @@ void LLPipeline::markOccluder(LLSpatialGroup* group)
}
}
+void LLPipeline::downsampleDepthBuffer(LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space)
+{
+ LLGLSLShader* last_shader = LLGLSLShader::sCurBoundShaderPtr;
+
+ LLGLSLShader* shader = NULL;
+
+ if (scratch_space)
+ {
+ scratch_space->copyContents(source,
+ 0, 0, source.getWidth(), source.getHeight(),
+ 0, 0, scratch_space->getWidth(), scratch_space->getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);
+ }
+
+ dest.bindTarget();
+ dest.clear(GL_DEPTH_BUFFER_BIT);
+
+ LLStrider<LLVector3> vert;
+ mDeferredVB->getVertexStrider(vert);
+ LLStrider<LLVector2> tc0;
+
+ vert[0].set(-1,1,0);
+ vert[1].set(-1,-3,0);
+ vert[2].set(3,1,0);
+
+ if (source.getUsage() == LLTexUnit::TT_RECT_TEXTURE)
+ {
+ shader = &gDownsampleDepthRectProgram;
+ shader->bind();
+ shader->uniform2f("delta", 1.f, 1.f);
+ shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, source.getWidth(), source.getHeight());
+ }
+ else
+ {
+ shader = &gDownsampleDepthProgram;
+ shader->bind();
+ shader->uniform2f("delta", 1.f/source.getWidth(), 1.f/source.getHeight());
+ shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, 1.f, 1.f);
+ }
+
+ gGL.getTexUnit(0)->bind(scratch_space ? scratch_space : &source, TRUE);
+
+ {
+ LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS);
+ mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ }
+
+ dest.flush();
+
+ if (last_shader)
+ {
+ last_shader->bind();
+ }
+ else
+ {
+ shader->unbind();
+ }
+}
+
+void LLPipeline::doOcclusion(LLCamera& camera, LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space)
+{
+ downsampleDepthBuffer(source, dest, scratch_space);
+ dest.bindTarget();
+ doOcclusion(camera);
+ dest.flush();
+}
+
void LLPipeline::doOcclusion(LLCamera& camera)
{
if (LLPipeline::sUseOcclusion > 1 && sCull->hasOcclusionGroups())
@@ -3306,11 +3515,6 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera)
{
drawablep->setVisible(camera, NULL, FALSE);
}
- else if (drawablep->isState(LLDrawable::CLEAR_INVISIBLE))
- {
- // clear invisible flag here to avoid single frame glitch
- drawablep->clearState(LLDrawable::FORCE_INVISIBLE|LLDrawable::CLEAR_INVISIBLE);
- }
}
if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD)
@@ -3584,8 +3788,8 @@ void LLPipeline::postSort(LLCamera& camera)
for (LLCullResult::sg_iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i)
{
LLSpatialGroup* group = *i;
- if (sUseOcclusion &&
- group->isOcclusionState(LLSpatialGroup::OCCLUDED) ||
+ if ((sUseOcclusion &&
+ group->isOcclusionState(LLSpatialGroup::OCCLUDED)) ||
(RenderAutoHideSurfaceAreaLimit > 0.f &&
group->mSurfaceArea > RenderAutoHideSurfaceAreaLimit*llmax(group->mObjectBoxSize, 10.f)))
{
@@ -3751,7 +3955,9 @@ void LLPipeline::postSort(LLCamera& camera)
if (!sShadowRender)
{
mSelectedFaces.clear();
-
+
+ LLPipeline::setRenderHighlightTextureChannel(LLSelectMgr::getInstance()->getTextureChannel());
+
// Draw face highlights for selected faces.
if (LLSelectMgr::getInstance()->getTEMode())
{
@@ -3974,13 +4180,14 @@ void LLPipeline::renderHighlights()
gGL.diffuseColor4f(1,1,1,0.5f);
}
- if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED))
+ if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && !mFaceSelectImagep)
+ {
+ mFaceSelectImagep = LLViewerTextureManager::getFetchedTexture(IMG_FACE_SELECT);
+ }
+
+ if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::DIFFUSE_MAP))
{
// Make sure the selection image gets downloaded and decoded
- if (!mFaceSelectImagep)
- {
- mFaceSelectImagep = LLViewerTextureManager::getFetchedTexture(IMG_FACE_SELECT);
- }
mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA);
U32 count = mSelectedFaces.size();
@@ -3996,7 +4203,7 @@ void LLPipeline::renderHighlights()
facep->renderSelected(mFaceSelectImagep, color);
}
}
-
+
if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED))
{
// Paint 'em red!
@@ -4018,6 +4225,67 @@ void LLPipeline::renderHighlights()
{
gHighlightProgram.unbind();
}
+
+
+ if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::NORMAL_MAP))
+ {
+ color.setVec(1.0f, 0.5f, 0.5f, 0.5f);
+ if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
+ {
+ gHighlightNormalProgram.bind();
+ gGL.diffuseColor4f(1,1,1,0.5f);
+ }
+
+ mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA);
+
+ U32 count = mSelectedFaces.size();
+ for (U32 i = 0; i < count; i++)
+ {
+ LLFace *facep = mSelectedFaces[i];
+ if (!facep || facep->getDrawable()->isDead())
+ {
+ llerrs << "Bad face on selection" << llendl;
+ return;
+ }
+
+ facep->renderSelected(mFaceSelectImagep, color);
+ }
+
+ if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
+ {
+ gHighlightNormalProgram.unbind();
+ }
+ }
+
+ if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::SPECULAR_MAP))
+ {
+ color.setVec(0.0f, 0.3f, 1.0f, 0.8f);
+ if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
+ {
+ gHighlightSpecularProgram.bind();
+ gGL.diffuseColor4f(1,1,1,0.5f);
+ }
+
+ mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA);
+
+ U32 count = mSelectedFaces.size();
+ for (U32 i = 0; i < count; i++)
+ {
+ LLFace *facep = mSelectedFaces[i];
+ if (!facep || facep->getDrawable()->isDead())
+ {
+ llerrs << "Bad face on selection" << llendl;
+ return;
+ }
+
+ facep->renderSelected(mFaceSelectImagep, color);
+ }
+
+ if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
+ {
+ gHighlightSpecularProgram.unbind();
+ }
+ }
}
//debug use
@@ -4371,7 +4639,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)
gGL.setColorMask(true, false);
}
-void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
+void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion)
{
LLFastTimer t(FTM_POST_DEFERRED_POOLS);
U32 cur_type = 0;
@@ -4386,7 +4654,7 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
gGL.setColorMask(true, false);
pool_set_t::iterator iter1 = mPools.begin();
- BOOL occlude = LLPipeline::sUseOcclusion > 1;
+ BOOL occlude = LLPipeline::sUseOcclusion > 1 && do_occlusion;
while ( iter1 != mPools.end() )
{
@@ -4400,7 +4668,7 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
gGLLastMatrix = NULL;
gGL.loadMatrix(gGLModelView);
LLGLSLShader::bindNoShader();
- doOcclusion(camera);
+ doOcclusion(camera, mScreen, mOcclusionDepth, &mDeferredDepth);
gGL.setColorMask(true, false);
}
@@ -4618,6 +4886,7 @@ void LLPipeline::renderPhysicsDisplay()
mPhysicsDisplay.flush();
}
+extern std::set<LLSpatialGroup*> visible_selected_groups;
void LLPipeline::renderDebug()
{
@@ -5007,8 +5276,8 @@ void LLPipeline::renderDebug()
LLSpatialPartition* part = region->getSpatialPartition(i);
if (part)
{
- if ( hud_only && (part->mDrawableType == RENDER_TYPE_HUD || part->mDrawableType == RENDER_TYPE_HUD_PARTICLES) ||
- !hud_only && hasRenderType(part->mDrawableType) )
+ if ( (hud_only && (part->mDrawableType == RENDER_TYPE_HUD || part->mDrawableType == RENDER_TYPE_HUD_PARTICLES)) ||
+ (!hud_only && hasRenderType(part->mDrawableType)) )
{
part->renderDebug();
}
@@ -5028,6 +5297,27 @@ void LLPipeline::renderDebug()
}
}
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION) && LLGLSLShader::sNoFixedFunction)
+ { //render visible selected group occlusion geometry
+ gDebugProgram.bind();
+ LLGLDepthTest depth(GL_TRUE, GL_FALSE);
+ gGL.diffuseColor3f(1,0,1);
+ for (std::set<LLSpatialGroup*>::iterator iter = visible_selected_groups.begin(); iter != visible_selected_groups.end(); ++iter)
+ {
+ LLSpatialGroup* group = *iter;
+
+ LLVector4a fudge;
+ fudge.splat(0.25f); //SG_OCCLUSION_FUDGE
+
+ LLVector4a size;
+ size.setAdd(fudge, group->mBounds[1]);
+
+ drawBox(group->mBounds[0], size);
+ }
+ }
+
+ visible_selected_groups.clear();
+
if (LLGLSLShader::sNoFixedFunction)
{
gUIProgram.bind();
@@ -5323,6 +5613,32 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )
}
break;
+ case LLDrawPool::POOL_ALPHA_MASK:
+ if (mAlphaMaskPool)
+ {
+ llassert(0);
+ llwarns << "Ignoring duplicate alpha mask pool." << llendl;
+ break;
+ }
+ else
+ {
+ mAlphaMaskPool = (LLRenderPass*) new_poolp;
+ }
+ break;
+
+ case LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK:
+ if (mFullbrightAlphaMaskPool)
+ {
+ llassert(0);
+ llwarns << "Ignoring duplicate alpha mask pool." << llendl;
+ break;
+ }
+ else
+ {
+ mFullbrightAlphaMaskPool = (LLRenderPass*) new_poolp;
+ }
+ break;
+
case LLDrawPool::POOL_GRASS:
if (mGrassPool)
{
@@ -5390,7 +5706,17 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )
mBumpPool = new_poolp;
}
break;
-
+ case LLDrawPool::POOL_MATERIALS:
+ if (mMaterialsPool)
+ {
+ llassert(0);
+ llwarns << "Ignorning duplicate materials pool." << llendl;
+ }
+ else
+ {
+ mMaterialsPool = new_poolp;
+ }
+ break;
case LLDrawPool::POOL_ALPHA:
if( mAlphaPool )
{
@@ -5399,7 +5725,7 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )
}
else
{
- mAlphaPool = new_poolp;
+ mAlphaPool = (LLDrawPoolAlpha*) new_poolp;
}
break;
@@ -5479,6 +5805,16 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp )
mSimplePool = NULL;
break;
+ case LLDrawPool::POOL_ALPHA_MASK:
+ llassert(mAlphaMaskPool == poolp);
+ mAlphaMaskPool = NULL;
+ break;
+
+ case LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK:
+ llassert(mFullbrightAlphaMaskPool == poolp);
+ mFullbrightAlphaMaskPool = NULL;
+ break;
+
case LLDrawPool::POOL_GRASS:
llassert(mGrassPool == poolp);
mGrassPool = NULL;
@@ -5530,7 +5866,12 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp )
llassert( poolp == mBumpPool );
mBumpPool = NULL;
break;
-
+
+ case LLDrawPool::POOL_MATERIALS:
+ llassert(poolp == mMaterialsPool);
+ mMaterialsPool = NULL;
+ break;
+
case LLDrawPool::POOL_ALPHA:
llassert( poolp == mAlphaPool );
mAlphaPool = NULL;
@@ -5593,8 +5934,15 @@ void LLPipeline::setupAvatarLights(BOOL for_edit)
LLLightState* light = gGL.getLight(1);
- mHWLightColors[1] = diffuse;
+ if (LLPipeline::sRenderDeferred)
+ {
+ /*diffuse.mV[0] = powf(diffuse.mV[0], 2.2f);
+ diffuse.mV[1] = powf(diffuse.mV[1], 2.2f);
+ diffuse.mV[2] = powf(diffuse.mV[2], 2.2f);*/
+ }
+ mHWLightColors[1] = diffuse;
+
light->setDiffuse(diffuse);
light->setAmbient(LLColor4::black);
light->setSpecular(LLColor4::black);
@@ -5633,6 +5981,13 @@ void LLPipeline::setupAvatarLights(BOOL for_edit)
}
backlight_diffuse *= backlight_mag / max_component;
+ if (LLPipeline::sRenderDeferred)
+ {
+ /*backlight_diffuse.mV[0] = powf(backlight_diffuse.mV[0], 2.2f);
+ backlight_diffuse.mV[1] = powf(backlight_diffuse.mV[1], 2.2f);
+ backlight_diffuse.mV[2] = powf(backlight_diffuse.mV[2], 2.2f);*/
+ }
+
mHWLightColors[1] = backlight_diffuse;
LLLightState* light = gGL.getLight(1);
@@ -5839,6 +6194,14 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
LLVector4 light_pos(mSunDir, 0.0f);
LLColor4 light_diffuse = mSunDiffuse;
+
+ if (LLPipeline::sRenderDeferred)
+ {
+ /*light_diffuse.mV[0] = powf(light_diffuse.mV[0], 2.2f);
+ light_diffuse.mV[1] = powf(light_diffuse.mV[1], 2.2f);
+ light_diffuse.mV[2] = powf(light_diffuse.mV[2], 2.2f);*/
+ }
+
mHWLightColors[0] = light_diffuse;
LLLightState* light = gGL.getLight(0);
@@ -5907,6 +6270,13 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
F32 x = (3.f * (1.f + light->getLightFalloff())); // why this magic? probably trying to match a historic behavior.
float linatten = x / (light_radius); // % of brightness at radius
+ if (LLPipeline::sRenderDeferred)
+ {
+ /*light_color.mV[0] = powf(light_color.mV[0], 2.2f);
+ light_color.mV[1] = powf(light_color.mV[1], 2.2f);
+ light_color.mV[2] = powf(light_color.mV[2], 2.2f);*/
+ }
+
mHWLightColors[cur_light] = light_color;
LLLightState* light_state = gGL.getLight(cur_light);
@@ -5917,7 +6287,7 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
if (sRenderDeferred)
{
F32 size = light_radius*1.5f;
- light_state->setLinearAttenuation(size*size);
+ light_state->setLinearAttenuation(size);
light_state->setQuadraticAttenuation(light->getLightFalloff()*0.5f+1.f);
}
else
@@ -5980,6 +6350,13 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
F32 x = 3.f;
float linatten = x / (light_radius); // % of brightness at radius
+ if (LLPipeline::sRenderDeferred)
+ {
+ /*light_color.mV[0] = powf(light_color.mV[0], 2.2f);
+ light_color.mV[1] = powf(light_color.mV[1], 2.2f);
+ light_color.mV[2] = powf(light_color.mV[2], 2.2f);*/
+ }
+
mHWLightColors[2] = light_color;
LLLightState* light = gGL.getLight(2);
@@ -6620,20 +6997,26 @@ BOOL LLPipeline::getRenderHighlights(void*)
return sRenderHighlight;
}
-LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start, const LLVector3& end,
+// static
+void LLPipeline::setRenderHighlightTextureChannel(LLRender::eTexIndex channel)
+{
+ sRenderHighlightTextureChannel = channel;
+}
+
+LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector4a& start, const LLVector4a& end,
BOOL pick_transparent,
S32* face_hit,
- LLVector3* intersection, // return the intersection point
+ LLVector4a* intersection, // return the intersection point
LLVector2* tex_coord, // return the texture coordinates of the intersection point
- LLVector3* normal, // return the surface normal at the intersection point
- LLVector3* bi_normal // return the surface bi-normal at the intersection point
+ LLVector4a* normal, // return the surface normal at the intersection point
+ LLVector4a* tangent // return the surface tangent at the intersection point
)
{
LLDrawable* drawable = NULL;
- LLVector3 local_end = end;
+ LLVector4a local_end = end;
- LLVector3 position;
+ LLVector4a position;
sPickAvatar = FALSE; //LLToolMgr::getInstance()->inBuildMode() ? FALSE : TRUE;
@@ -6653,7 +7036,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,
LLSpatialPartition* part = region->getSpatialPartition(j);
if (part && hasRenderType(part->mDrawableType))
{
- LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, face_hit, &position, tex_coord, normal, bi_normal);
+ LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, face_hit, &position, tex_coord, normal, tangent);
if (hit)
{
drawable = hit;
@@ -6668,8 +7051,8 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,
{
//save hit info in case we need to restore
//due to attachment override
- LLVector3 local_normal;
- LLVector3 local_binormal;
+ LLVector4a local_normal;
+ LLVector4a local_tangent;
LLVector2 local_texcoord;
S32 local_face_hit = -1;
@@ -6681,14 +7064,22 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,
{
local_texcoord = *tex_coord;
}
- if (bi_normal)
+ if (tangent)
+ {
+ local_tangent = *tangent;
+ }
+ else
{
- local_binormal = *bi_normal;
+ local_tangent.clear();
}
if (normal)
{
local_normal = *normal;
}
+ else
+ {
+ local_normal.clear();
+ }
const F32 ATTACHMENT_OVERRIDE_DIST = 0.1f;
@@ -6702,12 +7093,15 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,
LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_BRIDGE);
if (part && hasRenderType(part->mDrawableType))
{
- LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, face_hit, &position, tex_coord, normal, bi_normal);
+ LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, face_hit, &position, tex_coord, normal, tangent);
if (hit)
{
+ LLVector4a delta;
+ delta.setSub(position, local_end);
+
if (!drawable ||
!drawable->getVObj()->isAttachment() ||
- (position-local_end).magVec() > ATTACHMENT_OVERRIDE_DIST)
+ delta.getLength3().getF32() > ATTACHMENT_OVERRIDE_DIST)
{ //avatar overrides if previously hit drawable is not an attachment or
//attachment is far enough away from detected intersection
drawable = hit;
@@ -6725,9 +7119,9 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,
{
*tex_coord = local_texcoord;
}
- if (bi_normal)
+ if (tangent)
{
- *bi_normal = local_binormal;
+ *tangent = local_tangent;
}
if (normal)
{
@@ -6761,13 +7155,13 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,
return drawable ? drawable->getVObj().get() : NULL;
}
-LLViewerObject* LLPipeline::lineSegmentIntersectInHUD(const LLVector3& start, const LLVector3& end,
+LLViewerObject* LLPipeline::lineSegmentIntersectInHUD(const LLVector4a& start, const LLVector4a& end,
BOOL pick_transparent,
S32* face_hit,
- LLVector3* intersection, // return the intersection point
+ LLVector4a* intersection, // return the intersection point
LLVector2* tex_coord, // return the texture coordinates of the intersection point
- LLVector3* normal, // return the surface normal at the intersection point
- LLVector3* bi_normal // return the surface bi-normal at the intersection point
+ LLVector4a* normal, // return the surface normal at the intersection point
+ LLVector4a* tangent // return the surface tangent at the intersection point
)
{
LLDrawable* drawable = NULL;
@@ -6787,7 +7181,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInHUD(const LLVector3& start, co
LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_HUD);
if (part)
{
- LLDrawable* hit = part->lineSegmentIntersect(start, end, pick_transparent, face_hit, intersection, tex_coord, normal, bi_normal);
+ LLDrawable* hit = part->lineSegmentIntersect(start, end, pick_transparent, face_hit, intersection, tex_coord, normal, tangent);
if (hit)
{
drawable = hit;
@@ -6891,7 +7285,9 @@ void LLPipeline::doResetVertexBuffers()
LLVertexBuffer::unbind();
- sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
+ updateRenderBump();
+ updateRenderDeferred();
+
sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips");
LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("RenderUseStreamVBO");
LLVertexBuffer::sUseVAO = gSavedSettings.getBOOL("RenderUseVAO");
@@ -6917,6 +7313,17 @@ void LLPipeline::renderObjects(U32 type, U32 mask, BOOL texture, BOOL batch_text
gGLLastMatrix = NULL;
}
+void LLPipeline::renderMaskedObjects(U32 type, U32 mask, BOOL texture, BOOL batch_texture)
+{
+ assertInitialized();
+ gGL.loadMatrix(gGLModelView);
+ gGLLastMatrix = NULL;
+ mAlphaMaskPool->pushMaskBatches(type, mask, texture, batch_texture);
+ gGL.loadMatrix(gGLModelView);
+ gGLLastMatrix = NULL;
+}
+
+
void apply_cube_face_rotation(U32 face)
{
switch (face)
@@ -7018,10 +7425,10 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
gGL.loadIdentity();
LLGLDisable test(GL_ALPHA_TEST);
-
+
gGL.setColorMask(true, true);
glClearColor(0,0,0,0);
-
+
{
{
LLFastTimer ftm(FTM_RENDER_BLOOM_FBO);
@@ -7193,13 +7600,18 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
{
if (LLViewerJoystick::getInstance()->getOverrideCamera())
{ //focus on point under cursor
- focus_point = gDebugRaycastIntersection;
+ focus_point.set(gDebugRaycastIntersection.getF32ptr());
}
else if (gAgentCamera.cameraMouselook())
{ //focus on point under mouselook crosshairs
+ LLVector4a result;
+ result.clear();
+
gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE,
NULL,
- &focus_point);
+ &result);
+
+ focus_point.set(result.getF32ptr());
}
else
{
@@ -7359,6 +7771,13 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
mScreen.bindTexture(0, channel);
gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
}
+
+ if (!LLViewerCamera::getInstance()->cameraUnderWater())
+ {
+ shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 2.2);
+ } else {
+ shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 1.0);
+ }
shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
@@ -7400,6 +7819,13 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
{
mScreen.bindTexture(0, channel);
}
+
+ if (!LLViewerCamera::getInstance()->cameraUnderWater())
+ {
+ shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 2.2);
+ } else {
+ shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 1.0);
+ }
gGL.begin(LLRender::TRIANGLE_STRIP);
gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
@@ -7820,6 +8246,22 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n
}
}
+LLColor3 pow3f(LLColor3 v, F32 f)
+{
+ v.mV[0] = powf(v.mV[0], f);
+ v.mV[1] = powf(v.mV[1], f);
+ v.mV[2] = powf(v.mV[2], f);
+ return v;
+}
+
+LLVector4 pow4fsrgb(LLVector4 v, F32 f)
+{
+ v.mV[0] = powf(v.mV[0], f);
+ v.mV[1] = powf(v.mV[1], f);
+ v.mV[2] = powf(v.mV[2], f);
+ return v;
+}
+
static LLFastTimer::DeclareTimer FTM_GI_TRACE("Trace");
static LLFastTimer::DeclareTimer FTM_GI_GATHER("Gather");
static LLFastTimer::DeclareTimer FTM_SUN_SHADOW("Shadow Map");
@@ -7873,11 +8315,7 @@ void LLPipeline::renderDeferredLighting()
LLStrider<LLVector3> vert;
mDeferredVB->getVertexStrider(vert);
- LLStrider<LLVector2> tc0;
- LLStrider<LLVector2> tc1;
- mDeferredVB->getTexCoord0Strider(tc0);
- mDeferredVB->getTexCoord1Strider(tc1);
-
+
vert[0].set(-1,1,0);
vert[1].set(-1,-3,0);
vert[2].set(3,1,0);
@@ -8058,7 +8496,7 @@ void LLPipeline::renderDeferredLighting()
LLPipeline::END_RENDER_TYPES);
- renderGeomPostDeferred(*LLViewerCamera::getInstance());
+ renderGeomPostDeferred(*LLViewerCamera::getInstance(), false);
gPipeline.popRenderTypeMask();
}
@@ -8152,9 +8590,13 @@ void LLPipeline::renderDeferredLighting()
continue;
}
+ /*col.mV[0] = powf(col.mV[0], 2.2f);
+ col.mV[1] = powf(col.mV[1], 2.2f);
+ col.mV[2] = powf(col.mV[2], 2.2f);*/
+
LLFastTimer ftm(FTM_LOCAL_LIGHTS);
gDeferredLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c);
- gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s*s);
+ gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s);
gDeferredLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f);
gGL.syncMatrices();
@@ -8175,7 +8617,7 @@ void LLPipeline::renderDeferredLighting()
glh::vec3f tc(c);
mat.mult_matrix_vec(tc);
- fullscreen_lights.push_back(LLVector4(tc.v[0], tc.v[1], tc.v[2], s*s));
+ fullscreen_lights.push_back(LLVector4(tc.v[0], tc.v[1], tc.v[2], s));
light_colors.push_back(LLVector4(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f));
}
}
@@ -8208,9 +8650,12 @@ void LLPipeline::renderDeferredLighting()
setupSpotLight(gDeferredSpotLightProgram, drawablep);
LLColor3 col = volume->getLightColor();
+ /*col.mV[0] = powf(col.mV[0], 2.2f);
+ col.mV[1] = powf(col.mV[1], 2.2f);
+ col.mV[2] = powf(col.mV[2], 2.2f);*/
gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c);
- gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s*s);
+ gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s);
gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f);
gGL.syncMatrices();
@@ -8256,9 +8701,13 @@ void LLPipeline::renderDeferredLighting()
fullscreen_lights.pop_front();
col[count] = light_colors.front();
light_colors.pop_front();
-
- far_z = llmin(light[count].mV[2]-sqrtf(light[count].mV[3]), far_z);
-
+
+ /*col[count].mV[0] = powf(col[count].mV[0], 2.2f);
+ col[count].mV[1] = powf(col[count].mV[1], 2.2f);
+ col[count].mV[2] = powf(col[count].mV[2], 2.2f);*/
+
+ far_z = llmin(light[count].mV[2]-light[count].mV[3], far_z);
+ //col[count] = pow4fsrgb(col[count], 2.2f);
count++;
if (count == max_count || fullscreen_lights.empty())
{
@@ -8300,8 +8749,12 @@ void LLPipeline::renderDeferredLighting()
LLColor3 col = volume->getLightColor();
+ /*col.mV[0] = powf(col.mV[0], 2.2f);
+ col.mV[1] = powf(col.mV[1], 2.2f);
+ col.mV[2] = powf(col.mV[2], 2.2f);*/
+
gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, tc.v);
- gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s*s);
+ gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s);
gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f);
mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
@@ -8319,6 +8772,65 @@ void LLPipeline::renderDeferredLighting()
gGL.setColorMask(true, true);
}
+ mScreen.flush();
+
+ //gamma correct lighting
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+
+ {
+ LLGLDepthTest depth(GL_FALSE, GL_FALSE);
+
+ LLVector2 tc1(0,0);
+ LLVector2 tc2((F32) mScreen.getWidth()*2,
+ (F32) mScreen.getHeight()*2);
+
+ mScreen.bindTarget();
+ // Apply gamma correction to the frame here.
+ gDeferredPostGammaCorrectProgram.bind();
+ //mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ S32 channel = 0;
+ channel = gDeferredPostGammaCorrectProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage());
+ if (channel > -1)
+ {
+ mScreen.bindTexture(0,channel);
+ gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
+ }
+
+ gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mScreen.getWidth(), mScreen.getHeight());
+
+ F32 gamma = 1.0/2.2;
+
+ gDeferredPostGammaCorrectProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, gamma);
+
+ gGL.begin(LLRender::TRIANGLE_STRIP);
+ gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
+ gGL.vertex2f(-1,-1);
+
+ gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
+ gGL.vertex2f(-1,3);
+
+ gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
+ gGL.vertex2f(3,-1);
+
+ gGL.end();
+
+ gGL.getTexUnit(channel)->unbind(mScreen.getUsage());
+ gDeferredPostGammaCorrectProgram.unbind();
+ mScreen.flush();
+ }
+
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.popMatrix();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.popMatrix();
+
+ mScreen.bindTarget();
+
{ //render non-deferred geometry (alpha, fullbright, glow)
LLGLDisable blend(GL_BLEND);
LLGLDisable stencil(GL_STENCIL_TEST);
@@ -8343,6 +8855,8 @@ void LLPipeline::renderDeferredLighting()
LLPipeline::RENDER_TYPE_PASS_INVISIBLE,
LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY,
LLPipeline::RENDER_TYPE_AVATAR,
+ LLPipeline::RENDER_TYPE_ALPHA_MASK,
+ LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK,
END_RENDER_TYPES);
renderGeomPostDeferred(*LLViewerCamera::getInstance());
@@ -8895,19 +9409,36 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
LLRenderPass::PASS_FULLBRIGHT,
LLRenderPass::PASS_SHINY,
LLRenderPass::PASS_BUMP,
- LLRenderPass::PASS_FULLBRIGHT_SHINY
+ LLRenderPass::PASS_FULLBRIGHT_SHINY ,
+ LLRenderPass::PASS_MATERIAL,
+ LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE,
+ LLRenderPass::PASS_SPECMAP,
+ LLRenderPass::PASS_SPECMAP_EMISSIVE,
+ LLRenderPass::PASS_NORMMAP,
+ LLRenderPass::PASS_NORMMAP_EMISSIVE,
+ LLRenderPass::PASS_NORMSPEC,
+ LLRenderPass::PASS_NORMSPEC_EMISSIVE,
};
LLGLEnable cull(GL_CULL_FACE);
+ //enable depth clamping if available
+ LLGLEnable depth_clamp(gGLManager.mHasDepthClamp ? GL_DEPTH_CLAMP : 0);
+
if (use_shader)
{
gDeferredShadowCubeProgram.bind();
}
+ LLRenderTarget& occlusion_target = mShadowOcclusion[LLViewerCamera::sCurCameraID-1];
+
+ occlusion_target.bindTarget();
updateCull(shadow_cam, result);
+ occlusion_target.flush();
+
stateSort(shadow_cam, result);
+
//generate shadow map
gGL.matrixMode(LLRender::MM_PROJECTION);
gGL.pushMatrix();
@@ -8966,7 +9497,6 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
{
LLFastTimer ftm(FTM_SHADOW_ALPHA);
gDeferredShadowAlphaMaskProgram.bind();
- gDeferredShadowAlphaMaskProgram.setMinimumAlpha(0.598f);
gDeferredShadowAlphaMaskProgram.uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width);
U32 mask = LLVertexBuffer::MAP_VERTEX |
@@ -8974,10 +9504,19 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
LLVertexBuffer::MAP_COLOR |
LLVertexBuffer::MAP_TEXTURE_INDEX;
- renderObjects(LLRenderPass::PASS_ALPHA_MASK, mask, TRUE, TRUE);
- renderObjects(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, mask, TRUE, TRUE);
+ renderMaskedObjects(LLRenderPass::PASS_ALPHA_MASK, mask, TRUE, TRUE);
+ renderMaskedObjects(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, mask, TRUE, TRUE);
+ gDeferredShadowAlphaMaskProgram.setMinimumAlpha(0.598f);
renderObjects(LLRenderPass::PASS_ALPHA, mask, TRUE, TRUE);
+
+ mask = mask & ~LLVertexBuffer::MAP_TEXTURE_INDEX;
+
gDeferredTreeShadowProgram.bind();
+ renderMaskedObjects(LLRenderPass::PASS_NORMSPEC_MASK, mask);
+ renderMaskedObjects(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, mask);
+ renderMaskedObjects(LLRenderPass::PASS_SPECMAP_MASK, mask);
+ renderMaskedObjects(LLRenderPass::PASS_NORMMAP_MASK, mask);
+
gDeferredTreeShadowProgram.setMinimumAlpha(0.598f);
renderObjects(LLRenderPass::PASS_GRASS, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, TRUE);
}
@@ -8987,7 +9526,10 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
gDeferredShadowCubeProgram.bind();
gGLLastMatrix = NULL;
gGL.loadMatrix(gGLModelView);
- doOcclusion(shadow_cam);
+
+ LLRenderTarget& occlusion_source = mShadow[LLViewerCamera::sCurCameraID-1];
+
+ doOcclusion(shadow_cam, occlusion_source, occlusion_target);
if (use_shader)
{
@@ -9308,6 +9850,22 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT,
LLPipeline::RENDER_TYPE_PASS_SHINY,
LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY,
+ LLPipeline::RENDER_TYPE_PASS_MATERIAL,
+ LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA,
+ LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA_MASK,
+ LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA_EMISSIVE,
+ LLPipeline::RENDER_TYPE_PASS_SPECMAP,
+ LLPipeline::RENDER_TYPE_PASS_SPECMAP_BLEND,
+ LLPipeline::RENDER_TYPE_PASS_SPECMAP_MASK,
+ LLPipeline::RENDER_TYPE_PASS_SPECMAP_EMISSIVE,
+ LLPipeline::RENDER_TYPE_PASS_NORMMAP,
+ LLPipeline::RENDER_TYPE_PASS_NORMMAP_BLEND,
+ LLPipeline::RENDER_TYPE_PASS_NORMMAP_MASK,
+ LLPipeline::RENDER_TYPE_PASS_NORMMAP_EMISSIVE,
+ LLPipeline::RENDER_TYPE_PASS_NORMSPEC,
+ LLPipeline::RENDER_TYPE_PASS_NORMSPEC_BLEND,
+ LLPipeline::RENDER_TYPE_PASS_NORMSPEC_MASK,
+ LLPipeline::RENDER_TYPE_PASS_NORMSPEC_EMISSIVE,
END_RENDER_TYPES);
gGL.setColorMask(false, false);
@@ -9827,7 +10385,6 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
{
static LLCullResult result[4];
- //LLGLEnable enable(GL_DEPTH_CLAMP_NV);
renderShadow(view[j], proj[j], shadow_cam, result[j], TRUE, TRUE, target_width);
}
@@ -10134,11 +10691,13 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
LLVector4a left;
left.load3(camera.getLeftAxis().mV);
left.mul(left);
+ llassert(left.dot3(left).getF32() > F_APPROXIMATELY_ZERO);
left.normalize3fast();
LLVector4a up;
up.load3(camera.getUpAxis().mV);
up.mul(up);
+ llassert(up.dot3(up).getF32() > F_APPROXIMATELY_ZERO);
up.normalize3fast();
tdim.mV[0] = fabsf(half_height.dot3(left).getF32());