summaryrefslogtreecommitdiff
path: root/indra/newview/pipeline.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/pipeline.cpp')
-rwxr-xr-xindra/newview/pipeline.cpp883
1 files changed, 791 insertions, 92 deletions
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index f49395da34..b0c73d0304 100755
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -111,6 +111,8 @@
#include "llpathinglib.h"
#include "llfloaterpathfindingconsole.h"
#include "llfloaterpathfindingcharacters.h"
+#include "llfloatertools.h"
+#include "llpanelface.h"
#include "llpathfindingpathtool.h"
#ifdef _DEBUG
@@ -120,6 +122,10 @@
//#define DEBUG_INDICES
#endif
+// Expensive and currently broken
+//
+#define MATERIALS_IN_REFLECTIONS 0
+
bool gShiftFrame = false;
//cached settings
@@ -255,6 +261,17 @@ LLFastTimer::DeclareTimer FTM_RENDER_DEFERRED("Deferred Shading");
static LLFastTimer::DeclareTimer FTM_STATESORT_DRAWABLE("Sort Drawables");
static LLFastTimer::DeclareTimer FTM_STATESORT_POSTSORT("Post Sort");
+static LLStaticHashedString sTint("tint");
+static LLStaticHashedString sAmbiance("ambiance");
+static LLStaticHashedString sAlphaScale("alpha_scale");
+static LLStaticHashedString sNormMat("norm_mat");
+static LLStaticHashedString sOffset("offset");
+static LLStaticHashedString sScreenRes("screenRes");
+static LLStaticHashedString sDelta("delta");
+static LLStaticHashedString sDistFactor("dist_factor");
+static LLStaticHashedString sKern("kern");
+static LLStaticHashedString sKernScale("kern_scale");
+
//----------------------------------------
std::string gPoolNames[] =
{
@@ -374,6 +391,7 @@ BOOL LLPipeline::sWaterReflections = FALSE;
BOOL LLPipeline::sRenderGlow = FALSE;
BOOL LLPipeline::sReflectionRender = FALSE;
BOOL LLPipeline::sImpostorRender = FALSE;
+BOOL LLPipeline::sImpostorRenderAlphaDepthPass = FALSE;
BOOL LLPipeline::sUnderWaterRender = FALSE;
BOOL LLPipeline::sTextureBindTest = FALSE;
BOOL LLPipeline::sRenderFrameTest = FALSE;
@@ -789,14 +807,22 @@ void LLPipeline::resizeScreenTexture()
GLuint resX = gViewerWindow->getWorldViewWidthRaw();
GLuint resY = gViewerWindow->getWorldViewHeightRaw();
+ if ((resX != mScreen.getWidth()) || (resY != mScreen.getHeight()))
+ {
+ releaseScreenBuffers();
if (!allocateScreenBuffer(resX,resY))
- { //FAILSAFE: screen buffer allocation failed, disable deferred rendering if it's enabled
+ {
+#if PROBABLE_FALSE_DISABLES_OF_ALM_HERE
+ //FAILSAFE: screen buffer allocation failed, disable deferred rendering if it's enabled
//NOTE: if the session closes successfully after this call, deferred rendering will be
// disabled on future sessions
if (LLPipeline::sRenderDeferred)
{
gSavedSettings.setBOOL("RenderDeferred", FALSE);
LLPipeline::refreshCachedSettings();
+
+ }
+#endif
}
}
}
@@ -949,7 +975,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
{
screenFormat = GL_RGBA16F_ARB;
}
-
+
if (!mScreen.allocate(resX, resY, screenFormat, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
if (samples > 0)
{
@@ -1186,6 +1212,7 @@ void LLPipeline::releaseGLBuffers()
mWaterRef.release();
mWaterDis.release();
+ mHighlight.release();
for (U32 i = 0; i < 3; i++)
{
@@ -1216,12 +1243,12 @@ void LLPipeline::releaseScreenBuffers()
mDeferredScreen.release();
mDeferredDepth.release();
mDeferredLight.release();
-
- mHighlight.release();
+ mOcclusionDepth.release();
for (U32 i = 0; i < 6; i++)
{
mShadow[i].release();
+ mShadowOcclusion[i].release();
}
}
@@ -1233,14 +1260,31 @@ void LLPipeline::createGLBuffers()
updateRenderDeferred();
+ bool materials_in_water = false;
+
+#if MATERIALS_IN_REFLECTIONS
+ materials_in_water = gSavedSettings.getS32("RenderWaterMaterials");
+#endif
+
if (LLPipeline::sWaterReflections)
{ //water reflection texture
U32 res = (U32) llmax(gSavedSettings.getS32("RenderWaterRefResolution"), 512);
+ // Set up SRGB targets if we're doing deferred-path reflection rendering
+ //
+ if (LLPipeline::sRenderDeferred && materials_in_water)
+ {
+ mWaterRef.allocate(res,res,GL_SRGB8_ALPHA8,TRUE,FALSE);
+ //always use FBO for mWaterDis so it can be used for avatar texture bakes
+ mWaterDis.allocate(res,res,GL_SRGB8_ALPHA8,TRUE,FALSE,LLTexUnit::TT_TEXTURE, true);
+ }
+ else
+ {
mWaterRef.allocate(res,res,GL_RGBA,TRUE,FALSE);
//always use FBO for mWaterDis so it can be used for avatar texture bakes
mWaterDis.allocate(res,res,GL_RGBA,TRUE,FALSE,LLTexUnit::TT_TEXTURE, true);
}
+ }
mHighlight.allocate(256,256,GL_RGBA, FALSE, FALSE);
@@ -1402,9 +1446,15 @@ void LLPipeline::createLUTBuffers()
}
}
- LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, GL_R16F, 1, &mLightFunc);
+ U32 pix_format = GL_R16F;
+#if LL_DARWIN
+ // Need to work around limited precision with 10.6.8 and older drivers
+ //
+ pix_format = GL_R32F;
+#endif
+ LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, pix_format, 1, &mLightFunc);
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc);
- 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, pix_format, 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);
@@ -2443,7 +2493,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
if (to_texture)
{
- if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender)
+ if (LLPipeline::sRenderDeferred)
{
mOcclusionDepth.bindTarget();
}
@@ -2588,7 +2638,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
if (to_texture)
{
- if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender)
+ if (LLPipeline::sRenderDeferred)
{
mOcclusionDepth.flush();
}
@@ -2691,14 +2741,14 @@ void LLPipeline::downsampleDepthBuffer(LLRenderTarget& source, LLRenderTarget& d
{
shader = &gDownsampleDepthRectProgram;
shader->bind();
- shader->uniform2f("delta", 1.f, 1.f);
+ shader->uniform2f(sDelta, 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(sDelta, 1.f/source.getWidth(), 1.f/source.getHeight());
shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, 1.f, 1.f);
}
@@ -3073,7 +3123,7 @@ void LLPipeline::markVisible(LLDrawable *drawablep, LLCamera& camera)
llassert(vobj); // trying to catch a bad assumption
if (vobj) // this test may not be needed, see above
{
- const LLVOAvatar* av = vobj->asAvatar();
+ LLVOAvatar* av = vobj->asAvatar();
if (av && av->isImpostor())
{
return;
@@ -3959,7 +4009,7 @@ void LLPipeline::postSort(LLCamera& camera)
{
mSelectedFaces.clear();
- LLPipeline::setRenderHighlightTextureChannel(LLSelectMgr::getInstance()->getTextureChannel());
+ LLPipeline::setRenderHighlightTextureChannel(gFloaterTools->getPanelFace()->getTextureChannelToEdit());
// Draw face highlights for selected faces.
if (LLSelectMgr::getInstance()->getTEMode())
@@ -4903,9 +4953,9 @@ void LLPipeline::renderDebug()
if (LLGLSLShader::sNoFixedFunction)
{
gPathfindingProgram.bind();
- gPathfindingProgram.uniform1f("tint", 1.f);
- gPathfindingProgram.uniform1f("ambiance", 1.f);
- gPathfindingProgram.uniform1f("alpha_scale", 1.f);
+ gPathfindingProgram.uniform1f(sTint, 1.f);
+ gPathfindingProgram.uniform1f(sAmbiance, 1.f);
+ gPathfindingProgram.uniform1f(sAlphaScale, 1.f);
}
//Requried character physics capsule render parameters
@@ -4922,7 +4972,7 @@ void LLPipeline::renderDebug()
llPathingLibInstance->renderSimpleShapeCapsuleID( gGL, id, pos, rot );
gGL.setColorMask(true, false);
LLGLEnable blend(GL_BLEND);
- gPathfindingProgram.uniform1f("alpha_scale", 0.90f);
+ gPathfindingProgram.uniform1f(sAlphaScale, 0.90f);
llPathingLibInstance->renderSimpleShapeCapsuleID( gGL, id, pos, rot );
gPathfindingProgram.bind();
}
@@ -4949,9 +4999,9 @@ void LLPipeline::renderDebug()
{
gPathfindingProgram.bind();
- gPathfindingProgram.uniform1f("tint", 1.f);
- gPathfindingProgram.uniform1f("ambiance", ambiance);
- gPathfindingProgram.uniform1f("alpha_scale", 1.f);
+ gPathfindingProgram.uniform1f(sTint, 1.f);
+ gPathfindingProgram.uniform1f(sAmbiance, ambiance);
+ gPathfindingProgram.uniform1f(sAlphaScale, 1.f);
}
if ( !pathfindingConsole->isRenderWorld() )
@@ -4975,7 +5025,7 @@ void LLPipeline::renderDebug()
if ( pathfindingConsole->isRenderWorld() )
{
LLGLEnable blend(GL_BLEND);
- gPathfindingProgram.uniform1f("alpha_scale", 0.66f);
+ gPathfindingProgram.uniform1f(sAlphaScale, 0.66f);
llPathingLibInstance->renderNavMesh();
}
else
@@ -4987,8 +5037,8 @@ void LLPipeline::renderDebug()
if (LLGLSLShader::sNoFixedFunction)
{
gPathfindingNoNormalsProgram.bind();
- gPathfindingNoNormalsProgram.uniform1f("tint", 1.f);
- gPathfindingNoNormalsProgram.uniform1f("alpha_scale", 1.f);
+ gPathfindingNoNormalsProgram.uniform1f(sTint, 1.f);
+ gPathfindingNoNormalsProgram.uniform1f(sAlphaScale, 1.f);
llPathingLibInstance->renderNavMeshEdges();
gPathfindingProgram.bind();
}
@@ -5028,7 +5078,7 @@ void LLPipeline::renderDebug()
gGL.setColorMask(true, false);
//render the bookends
LLGLEnable blend(GL_BLEND);
- gPathfindingProgram.uniform1f("alpha_scale", 0.90f);
+ gPathfindingProgram.uniform1f(sAlphaScale, 0.90f);
llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_START );
llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_END );
gPathfindingProgram.bind();
@@ -5046,7 +5096,7 @@ void LLPipeline::renderDebug()
if (LLGLSLShader::sNoFixedFunction)
{
LLGLEnable blend(GL_BLEND);
- gPathfindingProgram.uniform1f("alpha_scale", 0.90f);
+ gPathfindingProgram.uniform1f(sAlphaScale, 0.90f);
llPathingLibInstance->renderSimpleShapes( gGL, gAgent.getRegion()->getWaterHeight() );
}
else
@@ -5094,7 +5144,7 @@ void LLPipeline::renderDebug()
LLGLEnable blend(GL_BLEND);
{
- gPathfindingProgram.uniform1f("ambiance", ambiance);
+ gPathfindingProgram.uniform1f(sAmbiance, ambiance);
{ //draw solid overlay
LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_LEQUAL);
@@ -5109,8 +5159,8 @@ void LLPipeline::renderDebug()
if (pathfindingConsole->isRenderXRay())
{
- gPathfindingProgram.uniform1f("tint", gSavedSettings.getF32("PathfindingXRayTint"));
- gPathfindingProgram.uniform1f("alpha_scale", gSavedSettings.getF32("PathfindingXRayOpacity"));
+ gPathfindingProgram.uniform1f(sTint, gSavedSettings.getF32("PathfindingXRayTint"));
+ gPathfindingProgram.uniform1f(sAlphaScale, gSavedSettings.getF32("PathfindingXRayOpacity"));
LLGLEnable blend(GL_BLEND);
LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_GREATER);
@@ -5118,13 +5168,13 @@ void LLPipeline::renderDebug()
if (gSavedSettings.getBOOL("PathfindingXRayWireframe"))
{ //draw hidden wireframe as darker and less opaque
- gPathfindingProgram.uniform1f("ambiance", 1.f);
+ gPathfindingProgram.uniform1f(sAmbiance, 1.f);
llPathingLibInstance->renderNavMeshShapesVBO( render_order[i] );
}
else
{
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
- gPathfindingProgram.uniform1f("ambiance", ambiance);
+ gPathfindingProgram.uniform1f(sAmbiance, ambiance);
llPathingLibInstance->renderNavMeshShapesVBO( render_order[i] );
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
}
@@ -5132,9 +5182,9 @@ void LLPipeline::renderDebug()
{ //draw visible wireframe as brighter, thicker and more opaque
glPolygonOffset(offset, offset);
- gPathfindingProgram.uniform1f("ambiance", 1.f);
- gPathfindingProgram.uniform1f("tint", 1.f);
- gPathfindingProgram.uniform1f("alpha_scale", 1.f);
+ gPathfindingProgram.uniform1f(sAmbiance, 1.f);
+ gPathfindingProgram.uniform1f(sTint, 1.f);
+ gPathfindingProgram.uniform1f(sAlphaScale, 1.f);
glLineWidth(gSavedSettings.getF32("PathfindingLineWidth"));
LLGLDisable blendOut(GL_BLEND);
@@ -5166,19 +5216,19 @@ void LLPipeline::renderDebug()
glLineWidth(2.0f);
LLGLEnable cull(GL_CULL_FACE);
- gPathfindingProgram.uniform1f("tint", gSavedSettings.getF32("PathfindingXRayTint"));
- gPathfindingProgram.uniform1f("alpha_scale", gSavedSettings.getF32("PathfindingXRayOpacity"));
+ gPathfindingProgram.uniform1f(sTint, gSavedSettings.getF32("PathfindingXRayTint"));
+ gPathfindingProgram.uniform1f(sAlphaScale, gSavedSettings.getF32("PathfindingXRayOpacity"));
if (gSavedSettings.getBOOL("PathfindingXRayWireframe"))
{ //draw hidden wireframe as darker and less opaque
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
- gPathfindingProgram.uniform1f("ambiance", 1.f);
+ gPathfindingProgram.uniform1f(sAmbiance, 1.f);
llPathingLibInstance->renderNavMesh();
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
}
else
{
- gPathfindingProgram.uniform1f("ambiance", ambiance);
+ gPathfindingProgram.uniform1f(sAmbiance, ambiance);
llPathingLibInstance->renderNavMesh();
}
@@ -5186,8 +5236,8 @@ void LLPipeline::renderDebug()
if (LLGLSLShader::sNoFixedFunction)
{
gPathfindingNoNormalsProgram.bind();
- gPathfindingNoNormalsProgram.uniform1f("tint", gSavedSettings.getF32("PathfindingXRayTint"));
- gPathfindingNoNormalsProgram.uniform1f("alpha_scale", gSavedSettings.getF32("PathfindingXRayOpacity"));
+ gPathfindingNoNormalsProgram.uniform1f(sTint, gSavedSettings.getF32("PathfindingXRayTint"));
+ gPathfindingNoNormalsProgram.uniform1f(sAlphaScale, gSavedSettings.getF32("PathfindingXRayOpacity"));
llPathingLibInstance->renderNavMeshEdges();
gPathfindingProgram.bind();
}
@@ -6297,13 +6347,6 @@ 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);
@@ -7685,7 +7728,11 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
else
{
//focus on alt-zoom target
- focus_point = LLVector3(gAgentCamera.getFocusGlobal()-gAgent.getRegion()->getOriginGlobal());
+ LLViewerRegion* region = gAgent.getRegion();
+ if (region)
+ {
+ focus_point = LLVector3(gAgentCamera.getFocusGlobal()-region->getOriginGlobal());
+ }
}
}
@@ -8308,10 +8355,10 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n
shader.uniform1f(LLShaderMgr::DEFERRED_NORM_CUTOFF, RenderEdgeNormCutoff);
- if (shader.getUniformLocation("norm_mat") >= 0)
+ if (shader.getUniformLocation(LLShaderMgr::DEFERRED_NORM_MATRIX) >= 0)
{
glh::matrix4f norm_mat = glh_get_current_modelview().inverse().transpose();
- shader.uniformMatrix4fv("norm_mat", 1, FALSE, norm_mat.m);
+ shader.uniformMatrix4fv(LLShaderMgr::DEFERRED_NORM_MATRIX, 1, FALSE, norm_mat.m);
}
}
@@ -8433,8 +8480,8 @@ void LLPipeline::renderDeferredLighting()
}
}
- gDeferredSunProgram.uniform3fv("offset", slice, offset);
- gDeferredSunProgram.uniform2f("screenRes", mDeferredLight.getWidth(), mDeferredLight.getHeight());
+ gDeferredSunProgram.uniform3fv(sOffset, slice, offset);
+ gDeferredSunProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mDeferredLight.getWidth(), mDeferredLight.getHeight());
{
LLGLDisable blend(GL_BLEND);
@@ -8478,10 +8525,10 @@ void LLPipeline::renderDeferredLighting()
x += 1.f;
}
- gDeferredBlurLightProgram.uniform2f("delta", 1.f, 0.f);
- gDeferredBlurLightProgram.uniform1f("dist_factor", dist_factor);
- gDeferredBlurLightProgram.uniform3fv("kern", kern_length, gauss[0].mV);
- gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f));
+ gDeferredBlurLightProgram.uniform2f(sDelta, 1.f, 0.f);
+ gDeferredBlurLightProgram.uniform1f(sDistFactor, dist_factor);
+ gDeferredBlurLightProgram.uniform3fv(sKern, kern_length, gauss[0].mV);
+ gDeferredBlurLightProgram.uniform1f(sKernScale, blur_size * (kern_length/2.f - 0.5f));
{
LLGLDisable blend(GL_BLEND);
@@ -8498,7 +8545,7 @@ void LLPipeline::renderDeferredLighting()
mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
mDeferredLight.bindTarget();
- gDeferredBlurLightProgram.uniform2f("delta", 0.f, 1.f);
+ gDeferredBlurLightProgram.uniform2f(sDelta, 0.f, 1.f);
{
LLGLDisable blend(GL_BLEND);
@@ -8527,7 +8574,7 @@ void LLPipeline::renderDeferredLighting()
if (RenderDeferredAtmospheric)
{ //apply sunlight contribution
LLFastTimer ftm(FTM_ATMOSPHERICS);
- bindDeferredShader(gDeferredSoftenProgram);
+ bindDeferredShader(LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram);
{
LLGLDepthTest depth(GL_FALSE);
LLGLDisable blend(GL_BLEND);
@@ -8549,7 +8596,7 @@ void LLPipeline::renderDeferredLighting()
gGL.popMatrix();
}
- unbindDeferredShader(gDeferredSoftenProgram);
+ unbindDeferredShader(LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram);
}
{ //render non-deferred geometry (fullbright, alpha, etc)
@@ -8742,10 +8789,6 @@ void LLPipeline::renderDeferredLighting()
vert[2].set(3,1,0);
{
- bindDeferredShader(gDeferredMultiLightProgram);
-
- mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
-
LLGLDepthTest depth(GL_FALSE);
//full screen blit
@@ -8757,7 +8800,7 @@ void LLPipeline::renderDeferredLighting()
U32 count = 0;
- const U32 max_count = 8;
+ const U32 max_count = LL_DEFERRED_MULTI_LIGHT_COUNT;
LLVector4 light[max_count];
LLVector4 col[max_count];
@@ -8780,18 +8823,20 @@ void LLPipeline::renderDeferredLighting()
count++;
if (count == max_count || fullscreen_lights.empty())
{
- gDeferredMultiLightProgram.uniform1i(LLShaderMgr::MULTI_LIGHT_COUNT, count);
- gDeferredMultiLightProgram.uniform4fv(LLShaderMgr::MULTI_LIGHT, count, (GLfloat*) light);
- gDeferredMultiLightProgram.uniform4fv(LLShaderMgr::MULTI_LIGHT_COL, count, (GLfloat*) col);
- gDeferredMultiLightProgram.uniform1f(LLShaderMgr::MULTI_LIGHT_FAR_Z, far_z);
+ U32 idx = count-1;
+ bindDeferredShader(gDeferredMultiLightProgram[idx]);
+ gDeferredMultiLightProgram[idx].uniform1i(LLShaderMgr::MULTI_LIGHT_COUNT, count);
+ gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT, count, (GLfloat*) light);
+ gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT_COL, count, (GLfloat*) col);
+ gDeferredMultiLightProgram[idx].uniform1f(LLShaderMgr::MULTI_LIGHT_FAR_Z, far_z);
far_z = 0.f;
count = 0;
+ mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ unbindDeferredShader(gDeferredMultiLightProgram[idx]);
}
}
- unbindDeferredShader(gDeferredMultiLightProgram);
-
bindDeferredShader(gDeferredMultiSpotLightProgram);
gDeferredMultiSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION);
@@ -8872,9 +8917,9 @@ void LLPipeline::renderDeferredLighting()
gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mScreen.getWidth(), mScreen.getHeight());
- F32 gamma = 1.0/2.2;
+ F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
- gDeferredPostGammaCorrectProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, gamma);
+ gDeferredPostGammaCorrectProgram.uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
gGL.begin(LLRender::TRIANGLE_STRIP);
gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
@@ -8953,6 +8998,537 @@ void LLPipeline::renderDeferredLighting()
}
+void LLPipeline::renderDeferredLightingToRT(LLRenderTarget* target)
+{
+ if (!sCull)
+ {
+ return;
+ }
+
+ {
+ LLFastTimer ftm(FTM_RENDER_DEFERRED);
+
+ LLViewerCamera* camera = LLViewerCamera::getInstance();
+
+ {
+ LLGLDepthTest depth(GL_TRUE);
+ mDeferredDepth.copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(),
+ 0, 0, mDeferredDepth.getWidth(), mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);
+ }
+
+ LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
+
+ if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD))
+ {
+ gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD);
+ }
+
+ //ati doesn't seem to love actually using the stencil buffer on FBO's
+ LLGLDisable stencil(GL_STENCIL_TEST);
+ //glStencilFunc(GL_EQUAL, 1, 0xFFFFFFFF);
+ //glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
+
+ gGL.setColorMask(true, true);
+
+ //draw a cube around every light
+ LLVertexBuffer::unbind();
+
+ LLGLEnable cull(GL_CULL_FACE);
+ LLGLEnable blend(GL_BLEND);
+
+ glh::matrix4f mat = glh_copy_matrix(gGLModelView);
+
+ LLStrider<LLVector3> vert;
+ mDeferredVB->getVertexStrider(vert);
+
+ vert[0].set(-1,1,0);
+ vert[1].set(-1,-3,0);
+ vert[2].set(3,1,0);
+
+ {
+ setupHWLights(NULL); //to set mSunDir;
+ LLVector4 dir(mSunDir, 0.f);
+ glh::vec4f tc(dir.mV);
+ mat.mult_matrix_vec(tc);
+ mTransformedSunDir.set(tc.v);
+ }
+
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+
+ if (RenderDeferredSSAO || RenderShadowDetail > 0)
+ {
+ mDeferredLight.bindTarget();
+ { //paint shadow/SSAO light map (direct lighting lightmap)
+ LLFastTimer ftm(FTM_SUN_SHADOW);
+ bindDeferredShader(gDeferredSunProgram);
+ mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ glClearColor(1,1,1,1);
+ mDeferredLight.clear(GL_COLOR_BUFFER_BIT);
+ glClearColor(0,0,0,0);
+
+ glh::matrix4f inv_trans = glh_get_current_modelview().inverse().transpose();
+
+ const U32 slice = 32;
+ F32 offset[slice*3];
+ for (U32 i = 0; i < 4; i++)
+ {
+ for (U32 j = 0; j < 8; j++)
+ {
+ glh::vec3f v;
+ v.set_value(sinf(6.284f/8*j), cosf(6.284f/8*j), -(F32) i);
+ v.normalize();
+ inv_trans.mult_matrix_vec(v);
+ v.normalize();
+ offset[(i*8+j)*3+0] = v.v[0];
+ offset[(i*8+j)*3+1] = v.v[2];
+ offset[(i*8+j)*3+2] = v.v[1];
+ }
+ }
+
+ gDeferredSunProgram.uniform3fv(LLShaderMgr::DEFERRED_SHADOW_OFFSET, slice, offset);
+ gDeferredSunProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mDeferredLight.getWidth(), mDeferredLight.getHeight());
+
+ {
+ LLGLDisable blend(GL_BLEND);
+ LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS);
+ stop_glerror();
+ mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ stop_glerror();
+ }
+
+ unbindDeferredShader(gDeferredSunProgram);
+ }
+ mDeferredLight.flush();
+ }
+
+ stop_glerror();
+ gGL.popMatrix();
+ stop_glerror();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ stop_glerror();
+ gGL.popMatrix();
+ stop_glerror();
+
+ target->bindTarget();
+
+ //clear color buffer here - zeroing alpha (glow) is important or it will accumulate against sky
+ glClearColor(0,0,0,0);
+ target->clear(GL_COLOR_BUFFER_BIT);
+
+ if (RenderDeferredAtmospheric)
+ { //apply sunlight contribution
+ LLFastTimer ftm(FTM_ATMOSPHERICS);
+ bindDeferredShader(gDeferredSoftenProgram);
+ {
+ LLGLDepthTest depth(GL_FALSE);
+ LLGLDisable blend(GL_BLEND);
+ LLGLDisable test(GL_ALPHA_TEST);
+
+ //full screen blit
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+
+ mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+
+ mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+
+ gGL.popMatrix();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.popMatrix();
+ }
+
+ unbindDeferredShader(gDeferredSoftenProgram);
+ }
+
+ { //render non-deferred geometry (fullbright, alpha, etc)
+ LLGLDisable blend(GL_BLEND);
+ LLGLDisable stencil(GL_STENCIL_TEST);
+ gGL.setSceneBlendType(LLRender::BT_ALPHA);
+
+ gPipeline.pushRenderTypeMask();
+
+ gPipeline.andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY,
+ LLPipeline::RENDER_TYPE_CLOUDS,
+ LLPipeline::RENDER_TYPE_WL_SKY,
+ LLPipeline::END_RENDER_TYPES);
+
+
+ renderGeomPostDeferred(*LLViewerCamera::getInstance(), false);
+ gPipeline.popRenderTypeMask();
+ }
+
+ BOOL render_local = RenderLocalLights;
+
+ if (render_local)
+ {
+ gGL.setSceneBlendType(LLRender::BT_ADD);
+ std::list<LLVector4> fullscreen_lights;
+ LLDrawable::drawable_list_t spot_lights;
+ LLDrawable::drawable_list_t fullscreen_spot_lights;
+
+ for (U32 i = 0; i < 2; i++)
+ {
+ mTargetShadowSpotLight[i] = NULL;
+ }
+
+ std::list<LLVector4> light_colors;
+
+ LLVertexBuffer::unbind();
+
+ {
+ bindDeferredShader(gDeferredLightProgram);
+
+ if (mCubeVB.isNull())
+ {
+ mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB);
+ }
+
+ mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+
+ LLGLDepthTest depth(GL_TRUE, GL_FALSE);
+ for (LLDrawable::drawable_set_t::iterator iter = mLights.begin(); iter != mLights.end(); ++iter)
+ {
+ LLDrawable* drawablep = *iter;
+
+ LLVOVolume* volume = drawablep->getVOVolume();
+ if (!volume)
+ {
+ continue;
+ }
+
+ if (volume->isAttachment())
+ {
+ if (!sRenderAttachedLights)
+ {
+ continue;
+ }
+ }
+
+
+ LLVector4a center;
+ center.load3(drawablep->getPositionAgent().mV);
+ const F32* c = center.getF32ptr();
+ F32 s = volume->getLightRadius()*1.5f;
+
+ LLColor3 col = volume->getLightColor();
+
+ if (col.magVecSquared() < 0.001f)
+ {
+ continue;
+ }
+
+ if (s <= 0.001f)
+ {
+ continue;
+ }
+
+ LLVector4a sa;
+ sa.splat(s);
+ if (camera->AABBInFrustumNoFarClip(center, sa) == 0)
+ {
+ continue;
+ }
+
+ sVisibleLightCount++;
+
+ if (camera->getOrigin().mV[0] > c[0] + s + 0.2f ||
+ camera->getOrigin().mV[0] < c[0] - s - 0.2f ||
+ camera->getOrigin().mV[1] > c[1] + s + 0.2f ||
+ camera->getOrigin().mV[1] < c[1] - s - 0.2f ||
+ camera->getOrigin().mV[2] > c[2] + s + 0.2f ||
+ camera->getOrigin().mV[2] < c[2] - s - 0.2f)
+ { //draw box if camera is outside box
+ if (render_local)
+ {
+ if (volume->isLightSpotlight())
+ {
+ drawablep->getVOVolume()->updateSpotLightPriority();
+ spot_lights.push_back(drawablep);
+ 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);
+ gDeferredLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
+ gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f);
+ gGL.syncMatrices();
+
+ mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center));
+ stop_glerror();
+ }
+ }
+ else
+ {
+ if (volume->isLightSpotlight())
+ {
+ drawablep->getVOVolume()->updateSpotLightPriority();
+ fullscreen_spot_lights.push_back(drawablep);
+ continue;
+ }
+
+ glh::vec3f tc(c);
+ mat.mult_matrix_vec(tc);
+
+ 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));
+ }
+ }
+ unbindDeferredShader(gDeferredLightProgram);
+ }
+
+ if (!spot_lights.empty())
+ {
+ LLGLDepthTest depth(GL_TRUE, GL_FALSE);
+ bindDeferredShader(gDeferredSpotLightProgram);
+
+ mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+
+ gDeferredSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION);
+
+ for (LLDrawable::drawable_list_t::iterator iter = spot_lights.begin(); iter != spot_lights.end(); ++iter)
+ {
+ LLFastTimer ftm(FTM_PROJECTORS);
+ LLDrawable* drawablep = *iter;
+
+ LLVOVolume* volume = drawablep->getVOVolume();
+
+ LLVector4a center;
+ center.load3(drawablep->getPositionAgent().mV);
+ const F32* c = center.getF32ptr();
+ F32 s = volume->getLightRadius()*1.5f;
+
+ sVisibleLightCount++;
+
+ 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);
+ gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
+ gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f);
+ gGL.syncMatrices();
+
+ mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center));
+ }
+ gDeferredSpotLightProgram.disableTexture(LLShaderMgr::DEFERRED_PROJECTION);
+ unbindDeferredShader(gDeferredSpotLightProgram);
+ }
+
+ //reset mDeferredVB to fullscreen triangle
+ mDeferredVB->getVertexStrider(vert);
+ vert[0].set(-1,1,0);
+ vert[1].set(-1,-3,0);
+ vert[2].set(3,1,0);
+
+ {
+ LLGLDepthTest depth(GL_FALSE);
+
+ //full screen blit
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+
+ U32 count = 0;
+
+ const U32 max_count = LL_DEFERRED_MULTI_LIGHT_COUNT;
+ LLVector4 light[max_count];
+ LLVector4 col[max_count];
+
+ F32 far_z = 0.f;
+
+ while (!fullscreen_lights.empty())
+ {
+ LLFastTimer ftm(FTM_FULLSCREEN_LIGHTS);
+ light[count] = fullscreen_lights.front();
+ fullscreen_lights.pop_front();
+ col[count] = light_colors.front();
+ light_colors.pop_front();
+
+ /*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())
+ {
+ U32 idx = count-1;
+ bindDeferredShader(gDeferredMultiLightProgram[idx]);
+ gDeferredMultiLightProgram[idx].uniform1i(LLShaderMgr::MULTI_LIGHT_COUNT, count);
+ gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT, count, (GLfloat*) light);
+ gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT_COL, count, (GLfloat*) col);
+ gDeferredMultiLightProgram[idx].uniform1f(LLShaderMgr::MULTI_LIGHT_FAR_Z, far_z);
+ far_z = 0.f;
+ count = 0;
+ mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ }
+ }
+
+ unbindDeferredShader(gDeferredMultiLightProgram[0]);
+
+ bindDeferredShader(gDeferredMultiSpotLightProgram);
+
+ gDeferredMultiSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION);
+
+ mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+
+ for (LLDrawable::drawable_list_t::iterator iter = fullscreen_spot_lights.begin(); iter != fullscreen_spot_lights.end(); ++iter)
+ {
+ LLFastTimer ftm(FTM_PROJECTORS);
+ LLDrawable* drawablep = *iter;
+
+ LLVOVolume* volume = drawablep->getVOVolume();
+
+ LLVector3 center = drawablep->getPositionAgent();
+ F32* c = center.mV;
+ F32 s = volume->getLightRadius()*1.5f;
+
+ sVisibleLightCount++;
+
+ glh::vec3f tc(c);
+ mat.mult_matrix_vec(tc);
+
+ setupSpotLight(gDeferredMultiSpotLightProgram, 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);*/
+
+ gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, tc.v);
+ 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);
+ }
+
+ gDeferredMultiSpotLightProgram.disableTexture(LLShaderMgr::DEFERRED_PROJECTION);
+ unbindDeferredShader(gDeferredMultiSpotLightProgram);
+
+ gGL.popMatrix();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.popMatrix();
+ }
+ }
+
+ gGL.setColorMask(true, true);
+ }
+
+ /*target->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) target->getWidth()*2,
+ (F32) target->getHeight()*2);
+
+ target->bindTarget();
+ // Apply gamma correction to the frame here.
+ gDeferredPostGammaCorrectProgram.bind();
+ //mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ S32 channel = 0;
+ channel = gDeferredPostGammaCorrectProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, target->getUsage());
+ if (channel > -1)
+ {
+ target->bindTexture(0,channel);
+ gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
+ }
+
+ gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, target->getWidth(), target->getHeight());
+
+ F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
+
+ gDeferredPostGammaCorrectProgram.uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
+
+ 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(target->getUsage());
+ gDeferredPostGammaCorrectProgram.unbind();
+ target->flush();
+ }
+
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.popMatrix();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.popMatrix();
+
+ target->bindTarget();*/
+
+ { //render non-deferred geometry (alpha, fullbright, glow)
+ LLGLDisable blend(GL_BLEND);
+ LLGLDisable stencil(GL_STENCIL_TEST);
+
+ pushRenderTypeMask();
+ andRenderTypeMask(LLPipeline::RENDER_TYPE_ALPHA,
+ LLPipeline::RENDER_TYPE_FULLBRIGHT,
+ LLPipeline::RENDER_TYPE_VOLUME,
+ LLPipeline::RENDER_TYPE_GLOW,
+ LLPipeline::RENDER_TYPE_BUMP,
+ LLPipeline::RENDER_TYPE_PASS_SIMPLE,
+ LLPipeline::RENDER_TYPE_PASS_ALPHA,
+ LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK,
+ LLPipeline::RENDER_TYPE_PASS_BUMP,
+ LLPipeline::RENDER_TYPE_PASS_POST_BUMP,
+ LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT,
+ LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK,
+ LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY,
+ LLPipeline::RENDER_TYPE_PASS_GLOW,
+ LLPipeline::RENDER_TYPE_PASS_GRASS,
+ LLPipeline::RENDER_TYPE_PASS_SHINY,
+ 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());
+ popRenderTypeMask();
+ }
+
+ //target->flush();
+}
+
void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)
{
//construct frustum
@@ -9199,6 +9775,12 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
water_clip = 1;
}
+ bool materials_in_water = false;
+
+#if MATERIALS_IN_REFLECTIONS
+ materials_in_water = gSavedSettings.getS32("RenderWaterMaterials");
+#endif
+
if (!LLViewerCamera::getInstance()->cameraUnderWater())
{ //generate planar reflection map
@@ -9207,7 +9789,9 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
LLPipeline::sUseOcclusion = 0;
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
glClearColor(0,0,0,0);
+
mWaterRef.bindTarget();
+
LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER0;
gGL.setColorMask(true, true);
mWaterRef.clear();
@@ -9256,11 +9840,27 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
updateCull(camera, result);
stateSort(camera, result);
+ if (LLPipeline::sRenderDeferred && materials_in_water)
+ {
+ mWaterRef.flush();
+
+ gPipeline.grabReferences(result);
+ gPipeline.mDeferredScreen.bindTarget();
+ gGL.setColorMask(true, true);
+ glClearColor(0,0,0,0);
+ gPipeline.mDeferredScreen.clear();
+
+ renderGeomDeferred(camera);
+ }
+ else
+ {
renderGeom(camera, TRUE);
+ }
gPipeline.popRenderTypeMask();
}
+ gGL.setColorMask(true, false);
gPipeline.pushRenderTypeMask();
clearRenderTypeMask(LLPipeline::RENDER_TYPE_WATER,
@@ -9298,9 +9898,23 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
{
gPipeline.grabReferences(ref_result);
LLGLUserClipPlane clip_plane(plane, mat, projection);
+
+ if (LLPipeline::sRenderDeferred && materials_in_water)
+ {
+ renderGeomDeferred(camera);
+ }
+ else
+ {
renderGeom(camera);
}
}
+ }
+
+ if (LLPipeline::sRenderDeferred && materials_in_water)
+ {
+ gPipeline.mDeferredScreen.flush();
+ renderDeferredLightingToRT(&mWaterRef);
+ }
gPipeline.popRenderTypeMask();
}
@@ -9336,10 +9950,12 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
LLViewerCamera::updateFrustumPlanes(camera);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
LLColor4& col = LLDrawPoolWater::sWaterFogColor;
glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f);
mWaterDis.bindTarget();
LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER1;
+
mWaterDis.getViewport(gGLViewport);
if (!LLPipeline::sUnderWaterRender || LLDrawPoolWater::sNeedsReflectionUpdate)
@@ -9355,14 +9971,36 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
gGL.setColorMask(true, true);
mWaterDis.clear();
+
+
gGL.setColorMask(true, false);
+
+ if (LLPipeline::sRenderDeferred && materials_in_water)
+ {
+ mWaterDis.flush();
+ gPipeline.mDeferredScreen.bindTarget();
+ gGL.setColorMask(true, true);
+ glClearColor(0,0,0,0);
+ gPipeline.mDeferredScreen.clear();
+ gPipeline.grabReferences(result);
+ renderGeomDeferred(camera);
+ }
+ else
+ {
renderGeom(camera);
+ }
+ if (LLPipeline::sRenderDeferred && materials_in_water)
+ {
+ gPipeline.mDeferredScreen.flush();
+ renderDeferredLightingToRT(&mWaterDis);
+ }
}
- LLPipeline::sUnderWaterRender = FALSE;
mWaterDis.flush();
+ LLPipeline::sUnderWaterRender = FALSE;
+
}
last_update = LLDrawPoolWater::sNeedsReflectionUpdate && LLDrawPoolWater::sNeedsDistortionUpdate;
@@ -10678,39 +11316,47 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
assertInitialized();
- bool muted = avatar->isVisuallyMuted();
+ bool visually_muted = avatar->isVisuallyMuted();
pushRenderTypeMask();
- if (muted)
+ if (visually_muted)
{
andRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, END_RENDER_TYPES);
}
else
{
- andRenderTypeMask(LLPipeline::RENDER_TYPE_VOLUME,
- LLPipeline::RENDER_TYPE_AVATAR,
+ andRenderTypeMask(LLPipeline::RENDER_TYPE_ALPHA,
+ LLPipeline::RENDER_TYPE_FULLBRIGHT,
+ LLPipeline::RENDER_TYPE_VOLUME,
+ LLPipeline::RENDER_TYPE_GLOW,
LLPipeline::RENDER_TYPE_BUMP,
- LLPipeline::RENDER_TYPE_GRASS,
- LLPipeline::RENDER_TYPE_SIMPLE,
- LLPipeline::RENDER_TYPE_FULLBRIGHT,
- LLPipeline::RENDER_TYPE_ALPHA,
- LLPipeline::RENDER_TYPE_INVISIBLE,
LLPipeline::RENDER_TYPE_PASS_SIMPLE,
LLPipeline::RENDER_TYPE_PASS_ALPHA,
LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK,
+ LLPipeline::RENDER_TYPE_PASS_BUMP,
+ LLPipeline::RENDER_TYPE_PASS_POST_BUMP,
LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT,
LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK,
LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY,
+ LLPipeline::RENDER_TYPE_PASS_GLOW,
+ LLPipeline::RENDER_TYPE_PASS_GRASS,
LLPipeline::RENDER_TYPE_PASS_SHINY,
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,
+ LLPipeline::RENDER_TYPE_INVISIBLE,
+ LLPipeline::RENDER_TYPE_SIMPLE,
END_RENDER_TYPES);
}
S32 occlusion = sUseOcclusion;
sUseOcclusion = 0;
+
sReflectionRender = sRenderDeferred ? FALSE : TRUE;
+
sShadowRender = TRUE;
sImpostorRender = TRUE;
@@ -10805,32 +11451,59 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
if (!avatar->mImpostor.isComplete())
{
LLFastTimer t(FTM_IMPOSTOR_ALLOCATE);
- avatar->mImpostor.allocate(resX,resY,GL_RGBA,TRUE,FALSE);
+
if (LLPipeline::sRenderDeferred)
{
+ avatar->mImpostor.allocate(resX,resY,GL_SRGB8_ALPHA8,TRUE,FALSE);
addDeferredAttachments(avatar->mImpostor);
}
+ else
+ {
+ avatar->mImpostor.allocate(resX,resY,GL_RGBA,TRUE,FALSE);
+ }
gGL.getTexUnit(0)->bind(&avatar->mImpostor);
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
}
- else if(resX != avatar->mImpostor.getWidth() ||
- resY != avatar->mImpostor.getHeight())
+ else if(resX != avatar->mImpostor.getWidth() || resY != avatar->mImpostor.getHeight())
{
LLFastTimer t(FTM_IMPOSTOR_RESIZE);
- avatar->mImpostor.resize(resX,resY,GL_RGBA);
+ avatar->mImpostor.resize(resX,resY);
}
avatar->mImpostor.bindTarget();
}
+ F32 old_alpha = LLDrawPoolAvatar::sMinimumAlpha;
+
+ if (visually_muted)
+ { //disable alpha masking for muted avatars (get whole skin silhouette)
+ LLDrawPoolAvatar::sMinimumAlpha = 0.f;
+ }
+
if (LLPipeline::sRenderDeferred)
{
avatar->mImpostor.clear();
renderGeomDeferred(camera);
+
+ renderGeomPostDeferred(camera);
+
+ // Shameless hack time: render it all again,
+ // this time writing the depth
+ // values we need to generate the alpha mask below
+ // while preserving the alpha-sorted color rendering
+ // from the previous pass
+ //
+ sImpostorRenderAlphaDepthPass = true;
+ // depth-only here...
+ //
+ gGL.setColorMask(false,false);
renderGeomPostDeferred(camera);
+
+ sImpostorRenderAlphaDepthPass = false;
+
}
else
{
@@ -10838,10 +11511,28 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
glScissor(0, 0, resX, resY);
avatar->mImpostor.clear();
renderGeom(camera);
+
+ // Shameless hack time: render it all again,
+ // this time writing the depth
+ // values we need to generate the alpha mask below
+ // while preserving the alpha-sorted color rendering
+ // from the previous pass
+ //
+ sImpostorRenderAlphaDepthPass = true;
+
+ // depth-only here...
+ //
+ gGL.setColorMask(false,false);
+ renderGeom(camera);
+
+ sImpostorRenderAlphaDepthPass = false;
}
-
+
+ LLDrawPoolAvatar::sMinimumAlpha = old_alpha;
+
{ //create alpha mask based on depth buffer (grey out if muted)
LLFastTimer t(FTM_IMPOSTOR_BACKGROUND);
+
if (LLPipeline::sRenderDeferred)
{
GLuint buff = GL_COLOR_ATTACHMENT0;
@@ -10850,7 +11541,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
LLGLDisable blend(GL_BLEND);
- if (muted)
+ if (visually_muted)
{
gGL.setColorMask(true, true);
}
@@ -10875,10 +11566,20 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
if (LLGLSLShader::sNoFixedFunction)
{
- gUIProgram.bind();
+ gDebugProgram.bind();
+ }
+
+
+ if (LLMuteList::getInstance()->isMuted(avatar->getID()))
+ { //grey muted avatar
+ gGL.diffuseColor4ub(64,64,64,255);
+ }
+ else
+ { // Visually muted avatar
+ gGL.diffuseColor4fv( avatar->getMutedAVColor().mV );
}
- gGL.color4ub(64,64,64,255);
+ {
gGL.begin(LLRender::QUADS);
gGL.vertex3f(-1, -1, clip_plane);
gGL.vertex3f(1, -1, clip_plane);
@@ -10886,10 +11587,11 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
gGL.vertex3f(-1, 1, clip_plane);
gGL.end();
gGL.flush();
+ }
if (LLGLSLShader::sNoFixedFunction)
{
- gUIProgram.unbind();
+ gDebugProgram.unbind();
}
gGL.popMatrix();
@@ -11226,6 +11928,3 @@ void LLPipeline::restoreHiddenObject( const LLUUID& id )
}
}
-
-
-