From 1b039a1be6b412d4dec972d612a4a9b92de1c890 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Tue, 8 Mar 2011 18:36:59 -0600 Subject: [PATCH] Deferred has sky and water textures now. Underwater is still borked. Deferred fastalpha behaves a bit better. Pulled over patch for https://jira.secondlife.com/browse/STORM-336 and https://jira.secondlife.com/browse/STORM-1011 from linden repo Sky rendered using new LL method. Assuming this fixes issues on AMD cards(works on cat 11.2) Added a few things missed related to spatial-parition updating. Added 'SkipReflectOcclusionUpdates' setting that prevents occlusion updates for reflection pass. Less taxing on CPU. --- indra/llrender/llvertexbuffer.cpp | 286 ++++++++++---- indra/llrender/llvertexbuffer.h | 29 +- indra/newview/app_settings/settings.xml | 22 ++ .../shaders/class1/deferred/alphaF.glsl | 4 +- .../shaders/class1/deferred/alphaV.glsl | 4 +- .../shaders/class1/deferred/avatarF.glsl | 9 +- .../shaders/class1/deferred/impostorF.glsl | 3 +- .../class1/deferred/multiPointLightF.glsl | 6 + .../shaders/class1/deferred/pointLightF.glsl | 5 + .../shaders/class1/deferred/treeF.glsl | 2 +- .../shaders/class1/deferred/waterF.glsl | 33 +- indra/newview/lldrawpoolalpha.cpp | 13 +- indra/newview/lldrawpoolsimple.cpp | 2 +- indra/newview/lldrawpooltree.cpp | 4 +- indra/newview/lldrawpoolwater.cpp | 49 ++- indra/newview/lldrawpoolwater.h | 4 +- indra/newview/lldrawpoolwlsky.cpp | 3 +- indra/newview/llsky.cpp | 3 + indra/newview/llsky.h | 6 +- indra/newview/llspatialpartition.cpp | 15 +- indra/newview/llviewercontrol.cpp | 10 + indra/newview/llviewerdisplay.cpp | 13 +- indra/newview/llviewerobject.cpp | 1 - indra/newview/llviewershadermgr.cpp | 35 +- indra/newview/llviewerwindow.cpp | 2 +- indra/newview/llvosky.cpp | 54 +-- indra/newview/llvosky.h | 51 +-- indra/newview/llvowlsky.cpp | 42 +- indra/newview/llwaterparammanager.cpp | 2 +- indra/newview/llwlparammanager.cpp | 2 +- indra/newview/pipeline.cpp | 368 +++++++++++------- indra/newview/pipeline.h | 1 + 32 files changed, 708 insertions(+), 375 deletions(-) diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 756603a32..1d5d03581 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -56,6 +56,7 @@ U32 LLVertexBuffer::sSetCount = 0; S32 LLVertexBuffer::sCount = 0; S32 LLVertexBuffer::sGLCount = 0; S32 LLVertexBuffer::sMappedCount = 0; +BOOL LLVertexBuffer::sDisableVBOMapping = FALSE ; BOOL LLVertexBuffer::sEnableVBOs = TRUE; U32 LLVertexBuffer::sGLRenderBuffer = 0; U32 LLVertexBuffer::sGLRenderIndices = 0; @@ -287,9 +288,10 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const } //static -void LLVertexBuffer::initClass(bool use_vbo) +void LLVertexBuffer::initClass(bool use_vbo, bool no_vbo_mapping) { sEnableVBOs = use_vbo; + sDisableVBOMapping = sEnableVBOs && no_vbo_mapping ; LLGLNamePool::registerPool(&sDynamicVBOPool); LLGLNamePool::registerPool(&sDynamicIBOPool); LLGLNamePool::registerPool(&sStreamVBOPool); @@ -346,7 +348,9 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) : mGLBuffer(0), mGLIndices(0), mMappedData(NULL), - mMappedIndexData(NULL), mLocked(FALSE), + mMappedIndexData(NULL), + mVertexLocked(FALSE), + mIndexLocked(FALSE), mFinal(FALSE), mFilthy(FALSE), mEmpty(TRUE), @@ -544,6 +548,8 @@ void LLVertexBuffer::destroyGLBuffer() { if (useVBOs()) { + freeClientBuffer() ; + if (mMappedData || mMappedIndexData) { llerrs << "Vertex buffer destroyed while mapped!" << llendl; @@ -571,6 +577,8 @@ void LLVertexBuffer::destroyGLIndices() { if (useVBOs()) { + freeClientBuffer() ; + if (mMappedData || mMappedIndexData) { llerrs << "Vertex buffer destroyed while mapped." << llendl; @@ -768,6 +776,7 @@ void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices) if (mResized && useVBOs()) { + freeClientBuffer() ; setBuffer(0); } } @@ -782,104 +791,228 @@ BOOL LLVertexBuffer::useVBOs() const } //---------------------------------------------------------------------------- +void LLVertexBuffer::freeClientBuffer() +{ + if(useVBOs() && sDisableVBOMapping && (mMappedData || mMappedIndexData)) + { + delete[] mMappedData ; + delete[] mMappedIndexData ; + mMappedData = NULL ; + mMappedIndexData = NULL ; + } +} + +void LLVertexBuffer::allocateClientVertexBuffer() +{ + if(!mMappedData) + { + U32 size = getSize() ; + mMappedData = new U8[size]; + memset((void*)mMappedData, 0, size); + } +} + +void LLVertexBuffer::allocateClientIndexBuffer() +{ + if(!mMappedIndexData) + { + U32 size = getIndicesSize(); + mMappedIndexData = new U8[size]; + memset((void*)mMappedIndexData, 0, size); + } +} // Map for data access -volatile U8* LLVertexBuffer::mapBuffer(S32 access) +volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 access) { LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); if (mFinal) { - llerrs << "LLVertexBuffer::mapBuffer() called on a finalized buffer." << llendl; + llerrs << "LLVertexBuffer::mapVeretxBuffer() called on a finalized buffer." << llendl; } if (!useVBOs() && !mMappedData && !mMappedIndexData) { - llerrs << "LLVertexBuffer::mapBuffer() called on unallocated buffer." << llendl; + llerrs << "LLVertexBuffer::mapVertexBuffer() called on unallocated buffer." << llendl; } - if (!mLocked && useVBOs()) + if (!mVertexLocked && useVBOs()) { - setBuffer(0); - mLocked = TRUE; - stop_glerror(); - mMappedData = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); - stop_glerror(); - mMappedIndexData = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); - stop_glerror(); + { + setBuffer(0, type); + mVertexLocked = TRUE; + stop_glerror(); + if(sDisableVBOMapping) + { + allocateClientVertexBuffer() ; + } + else + { + mMappedData = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); + } + stop_glerror(); + } + if (!mMappedData) { - //-------------------- - //print out more debug info before crash - llinfos << "vertex buffer size: (num verts : num indices) = " << getNumVerts() << " : " << getNumIndices() << llendl ; - GLint size ; - glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &size) ; - llinfos << "GL_ARRAY_BUFFER_ARB size is " << size << llendl ; - //-------------------- - - GLint buff; - glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff); - if ((GLuint)buff != mGLBuffer) + if(!sDisableVBOMapping) { - llerrs << "Invalid GL vertex buffer bound: " << buff << llendl; + //-------------------- + //print out more debug info before crash + llinfos << "vertex buffer size: (num verts : num indices) = " << getNumVerts() << " : " << getNumIndices() << llendl ; + GLint size ; + glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &size) ; + llinfos << "GL_ARRAY_BUFFER_ARB size is " << size << llendl ; + //-------------------- + + GLint buff; + glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff); + if ((GLuint)buff != mGLBuffer) + { + llerrs << "Invalid GL vertex buffer bound: " << buff << llendl; + } + + + llerrs << "glMapBuffer returned NULL (no vertex data)" << llendl; } - - - llerrs << "glMapBuffer returned NULL (no vertex data)" << llendl; - } - - if (!mMappedIndexData) - { - GLint buff; - glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff); - if ((GLuint)buff != mGLIndices) + else { - llerrs << "Invalid GL index buffer bound: " << buff << llendl; + llerrs << "memory allocation for vertex data failed." << llendl ; } - - llerrs << "glMapBuffer returned NULL (no index data)" << llendl; } - sMappedCount++; } return mMappedData; } -void LLVertexBuffer::unmapBuffer() +volatile U8* LLVertexBuffer::mapIndexBuffer(S32 access) { LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); - if (mMappedData || mMappedIndexData) + if (mFinal) { - if (useVBOs() && mLocked) + llerrs << "LLVertexBuffer::mapIndexBuffer() called on a finalized buffer." << llendl; + } + if (!useVBOs() && !mMappedData && !mMappedIndexData) + { + llerrs << "LLVertexBuffer::mapIndexBuffer() called on unallocated buffer." << llendl; + } + + if (!mIndexLocked && useVBOs()) + { + { + + setBuffer(0, TYPE_INDEX); + mIndexLocked = TRUE; + stop_glerror(); + + if(sDisableVBOMapping) + { + allocateClientIndexBuffer() ; + } + else + { + mMappedIndexData = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); + } + stop_glerror(); + } + + if (!mMappedIndexData) + { + + if(!sDisableVBOMapping) + { + GLint buff; + glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff); + if ((GLuint)buff != mGLIndices) + { + llerrs << "Invalid GL index buffer bound: " << buff << llendl; + } + + llerrs << "glMapBuffer returned NULL (no index data)" << llendl; + } + else + { + llerrs << "memory allocation for Index data failed. " << llendl ; + } + } + + sMappedCount++; + } + + return mMappedIndexData ; +} + +void LLVertexBuffer::unmapBuffer(S32 type) +{ + LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); + if (!useVBOs()) + { + return ; //nothing to unmap + } + + bool updated_all = false ; + if (mMappedData && mVertexLocked && type != TYPE_INDEX) + { + updated_all = (mIndexLocked && type < 0) ; //both vertex and index buffers done updating + + if(sDisableVBOMapping) + { + stop_glerror(); + glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, getSize(), (void*)mMappedData); + stop_glerror(); + } + else { stop_glerror(); glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); stop_glerror(); + + mMappedData = NULL; + } + + mVertexLocked = FALSE ; + sMappedCount--; + } + + if(mMappedIndexData && mIndexLocked && (type < 0 || type == TYPE_INDEX)) + { + if(sDisableVBOMapping) + { + stop_glerror(); + glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, getIndicesSize(), (void*)mMappedIndexData); + stop_glerror(); + } + else + { + stop_glerror(); glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB); stop_glerror(); - /*if (!sMapped) - { - llerrs << "Redundantly unmapped VBO!" << llendl; - } - sMapped = FALSE;*/ - sMappedCount--; + mMappedIndexData = NULL ; + } - if (mUsage == GL_STATIC_DRAW_ARB) - { //static draw buffers can only be mapped a single time - //throw out client data (we won't be using it again) - mEmpty = TRUE; - mFinal = TRUE; - } - else - { - mEmpty = FALSE; - } + mIndexLocked = FALSE ; + sMappedCount--; + } - mMappedIndexData = NULL; - mMappedData = NULL; - - mLocked = FALSE; + if(updated_all) + { + if(mUsage == GL_STATIC_DRAW_ARB) + { + //static draw buffers can only be mapped a single time + //throw out client data (we won't be using it again) + mEmpty = TRUE; + mFinal = TRUE; + + if(sDisableVBOMapping) + { + freeClientBuffer() ; + } + } + else + { + mEmpty = FALSE; } } } @@ -893,15 +1026,16 @@ template struct VertexBufferStrider strider_t& strider, S32 index) { - if (vbo.mapBuffer() == NULL) - { - llwarns << "mapBuffer failed!" << llendl; - return FALSE; - } - if (type == LLVertexBuffer::TYPE_INDEX) { S32 stride = sizeof(T); + + if (vbo.mapIndexBuffer() == NULL) + { + llwarns << "mapIndexBuffer failed!" << llendl; + return FALSE; + } + strider = (T*)(vbo.getMappedIndices() + index*stride); strider.setStride(0); return TRUE; @@ -909,6 +1043,13 @@ template struct VertexBufferStrider else if (vbo.hasDataType(type)) { S32 stride = vbo.getStride(); + + if (vbo.mapVertexBuffer(type) == NULL) + { + llwarns << "mapVertexBuffer failed!" << llendl; + return FALSE; + } + strider = (T*)(vbo.getMappedData() + vbo.getOffset(type) + index*stride); strider.setStride(stride); return TRUE; @@ -989,7 +1130,7 @@ void LLVertexBuffer::setStride(S32 type, S32 new_stride) //---------------------------------------------------------------------------- // Set for rendering -void LLVertexBuffer::setBuffer(U32 data_mask) +void LLVertexBuffer::setBuffer(U32 data_mask, S32 type) { LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); //set up pointers if the data mask is different ... @@ -1023,6 +1164,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask) sIBOActive = TRUE; } + BOOL error = FALSE; if (gDebugGL) { GLint buff; @@ -1085,7 +1227,11 @@ void LLVertexBuffer::setBuffer(U32 data_mask) } } - unmapBuffer(); + if (error) + { + llerrs << "LLVertexBuffer::mapBuffer failed" << llendl; + } + unmapBuffer(type); } else { diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index 4cd8087c3..c7984e615 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -88,7 +88,7 @@ public: static BOOL sUseStreamDraw; static BOOL sOmitBlank; - static void initClass(bool use_vbo); + static void initClass(bool use_vbo, bool no_vbo_mapping); static void cleanupClass(); static void setupClientArrays(U32 data_mask); static void clientCopy(F64 max_time = 0.005); //copy data from client to GL @@ -147,15 +147,20 @@ protected: void updateNumVerts(S32 nverts); void updateNumIndices(S32 nindices); virtual BOOL useVBOs() const; - void unmapBuffer(); + void unmapBuffer(S32 type); + void freeClientBuffer() ; + void allocateClientVertexBuffer() ; + void allocateClientIndexBuffer() ; public: LLVertexBuffer(U32 typemask, S32 usage); // map for data access - volatile U8* mapBuffer(S32 access = -1); + volatile U8* mapVertexBuffer(S32 type = -1, S32 access = -1); + volatile U8* mapIndexBuffer(S32 access = -1); + // set for rendering - virtual void setBuffer(U32 data_mask); // calls setupVertexBuffer() if data_mask is not 0 + virtual void setBuffer(U32 data_mask, S32 type = -1); // calls setupVertexBuffer() if data_mask is not 0 // allocate buffer void allocateBuffer(S32 nverts, S32 nindices, bool create); virtual void resizeBuffer(S32 newnverts, S32 newnindices); @@ -178,7 +183,7 @@ public: bool getClothWeightStrider(LLStrider& strider, S32 index=0); BOOL isEmpty() const { return mEmpty; } - BOOL isLocked() const { return mLocked; } + BOOL isLocked() const { return mVertexLocked || mIndexLocked; } S32 getNumVerts() const { return mNumVerts; } S32 getNumIndices() const { return mNumIndices; } S32 getRequestedVerts() const { return mRequestedNumVerts; } @@ -217,13 +222,14 @@ protected: U32 mGLIndices; // GL IBO handle volatile U8* mMappedData; // pointer to currently mapped data (NULL if unmapped) volatile U8* mMappedIndexData; // pointer to currently mapped indices (NULL if unmapped) - BOOL mLocked; // if TRUE, buffer is being or has been written to in client memory + BOOL mVertexLocked; // if TRUE, vertex buffer is being or has been written to in client memory + BOOL mIndexLocked; // if TRUE, index buffer is being or has been written to in client memory BOOL mFinal; // if TRUE, buffer can not be mapped again BOOL mFilthy; // if TRUE, entire buffer must be copied (used to prevent redundant dirty flags) - BOOL mEmpty; // if TRUE, client buffer is empty (or NULL). Old values have been discarded. - S32 mOffsets[TYPE_MAX]; + BOOL mEmpty; // if TRUE, client buffer is empty (or NULL). Old values have been discarded. BOOL mResized; // if TRUE, client buffer has been resized and GL buffer has not BOOL mDynamicSize; // if TRUE, buffer has been resized at least once (and should be padded) + S32 mOffsets[TYPE_MAX]; class DirtyRegion { @@ -248,13 +254,14 @@ public: static std::vector sDeleteList; typedef std::list buffer_list_t; + static BOOL sDisableVBOMapping; //disable glMapBufferARB static BOOL sEnableVBOs; + static BOOL sVBOActive; + static BOOL sIBOActive; static S32 sTypeOffsets[TYPE_MAX]; static U32 sGLMode[LLRender::NUM_MODES]; static U32 sGLRenderBuffer; - static U32 sGLRenderIndices; - static BOOL sVBOActive; - static BOOL sIBOActive; + static U32 sGLRenderIndices; static U32 sLastMask; static U32 sAllocatedBytes; static U32 sBindCount; diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 2f3cb3ec3..5538c66a0 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -9843,6 +9843,17 @@ Value 1 + RenderVBOMappingDisable + + Comment + Disable VBO glMapBufferARB + Persist + 1 + Type + Boolean + Value + 1 + RenderVolumeLODFactor Comment @@ -12800,6 +12811,17 @@ Value 1 + SkipReflectOcclusionUpdates + + Comment + Enable optimization that prevents occlusion updates for refelction pass + Persist + 1 + Type + Boolean + Value + 1 + UseOutfitFolders Comment diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl index a91e9fa15..7c8d238d2 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl @@ -71,14 +71,14 @@ void main() color.rgb = scaleSoftClip(color.rgb); - if (samp_pos.z != 0.0) + /*if (samp_pos.z != 0.0) { float dist_factor = alpha_soften; float a = gl_Color.a; a *= a; dist_factor *= 1.0/(1.0-a); color.a *= min((pos.z-samp_pos.z)*dist_factor, 1.0); - } + }*/ //gl_FragColor = gl_Color; gl_FragColor = color; diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl index b496bd674..9f130ee42 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl @@ -37,8 +37,8 @@ void main() calcAtmospherics(pos.xyz); //vec4 color = calcLighting(pos.xyz, norm, gl_Color, vec4(0.)); - vec4 col; - col.a = gl_Color.a; + + vec4 col = vec4(0.0, 0.0, 0.0, gl_Color.a); // Add windlight lights col.rgb = atmosAmbient(vec3(0.)); diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl index 58aa5a9cb..b5daef03e 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl @@ -12,7 +12,14 @@ varying vec4 vary_position; void main() { - gl_FragData[0] = gl_Color * texture2D(diffuseMap, gl_TexCoord[0].xy); + vec4 diff = gl_Color*texture2D(diffuseMap, gl_TexCoord[0].xy); + + if (diff.a < 0.2) + { + discard; + } + + gl_FragData[0] = vec4(diff.rgb, 0.0); gl_FragData[1] = vec4(0,0,0,0); gl_FragData[2] = vec4(normalize(vary_normal), 0.0); gl_FragData[3] = vary_position; diff --git a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl index 20a3f3df5..4e3e635f1 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl @@ -13,7 +13,8 @@ varying vec4 vary_position; void main() { - gl_FragData[0] = texture2D(diffuseMap, gl_TexCoord[0].xy); + vec4 col = texture2D(diffuseMap, gl_TexCoord[0].xy); + gl_FragData[0] = vec4(col.rgb, col.a <= 0.5 ? 0.0 : 0.005); gl_FragData[1] = texture2D(specularMap, gl_TexCoord[0].xy); gl_FragData[2] = vec4(texture2D(normalMap, gl_TexCoord[0].xy).xyz, vary_position.z); gl_FragData[3] = vary_position; diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl index 3689d1284..c8248b294 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl @@ -77,6 +77,12 @@ void main() //attenuate point light contribution by SSAO component out_col *= texture2DRect(lightMap, frag.xy).g; + + + if (dot(out_col, out_col) <= 0.0) + { + discard; + } gl_FragColor.rgb = out_col; gl_FragColor.a = 0.0; diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl index 52bad1f34..68f376d69 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl @@ -69,6 +69,11 @@ void main() //attenuate point light contribution by SSAO component col *= texture2DRect(lightMap, frag.xy).g; + if (dot(col, col) <= 0.0) + { + discard; + } + gl_FragColor.rgb = col; gl_FragColor.a = 0.0; diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl index bc2c9816d..ea70eabf5 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl @@ -13,7 +13,7 @@ varying vec4 vary_position; void main() { vec4 col = texture2D(diffuseMap, gl_TexCoord[0].xy); - gl_FragData[0] = gl_Color*col; + gl_FragData[0] = vec4(gl_Color.rgb*col.rgb, col.a <= 0.5 ? 0.0 : 0.005); gl_FragData[1] = vec4(0,0,0,0); gl_FragData[2] = vec4(normalize(vary_normal), 0.0); gl_FragData[3] = vary_position; diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl index 0a1f019e3..99cc2f851 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl @@ -5,6 +5,7 @@ * $License$ */ +#extension GL_ARB_texture_rectangle : enable vec3 scaleSoftClip(vec3 inColor); vec3 atmosTransport(vec3 inColor); @@ -32,6 +33,7 @@ uniform vec3 normScale; uniform float fresnelScale; uniform float fresnelOffset; uniform float blurMultiplier; +uniform mat4 norm_mat; //region space to screen space //bigWave is (refCoord.w, view.w); @@ -88,7 +90,7 @@ void main() refcol *= df1 * 0.333; vec3 wavef = (wave1 + wave2 * 0.4 + wave3 * 0.6) * 0.5; - wavef.z *= max(-viewVec.z, 0.1); +// wavef.z *= max(-viewVec.z, 0.1); wavef = normalize(wavef); float df2 = dot(viewVec, wavef) * fresnelScale+fresnelOffset; @@ -101,10 +103,10 @@ void main() refcol = mix(baseCol*df2, refcol, dweight); //get specular component - float spec = clamp(dot(lightDir, (reflect(viewVec,wavef))),0.0,1.0); +// float spec = clamp(dot(lightDir, (reflect(viewVec,wavef))),0.0,1.0); //harden specular - spec = pow(spec, 128.0); +// spec = pow(spec, 128.0); //figure out distortion vector (ripply) vec2 distort2 = distort+wavef.xy*refScale/max(dmod*df1, 1.0); @@ -118,13 +120,13 @@ void main() float shadow = 1.0; vec4 pos = vary_position; - vec3 nz = texture2D(noiseMap, gl_FragCoord.xy/128.0).xyz; + //vec3 nz = texture2D(noiseMap, gl_FragCoord.xy/128.0).xyz; - if (pos.z > -shadow_clip.w) - { +// if (pos.z > -shadow_clip.w) +// { vec4 spos = pos; - if (pos.z < -shadow_clip.z) +/* if (pos.z < -shadow_clip.z) { vec4 lpos = (shadow_matrix[3]*spos); shadow = shadow2DProj(shadowMap3, lpos).x; @@ -144,14 +146,19 @@ void main() vec4 lpos = (shadow_matrix[0]*spos); shadow = shadow2DProj(shadowMap0, lpos).x; } - } + }*/ - spec *= shadow; - color.rgb += spec * specular; +// spec *= shadow; +// color.rgb += spec * specular; color.rgb = atmosTransport(color.rgb); - color.rgb = scaleSoftClip(color.rgb); - color.a = spec * sunAngle2; +// color.rgb = scaleSoftClip(color.rgb); +// color.a = spec * sunAngle2; - gl_FragColor = color; +// gl_FragColor = color; + vec3 screenspacewavef = (norm_mat*vec4(wavef, 1.0)).xyz; + + gl_FragData[0] = vec4(color.rgb, 0.5); // diffuse + gl_FragData[1] = vec4(0.5,0.5,0.5, 0.95); // speccolor*spec, spec + gl_FragData[2] = vec4(screenspacewavef, 0.0); // normalxyz, displace } diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index e9127ad49..f64672cac 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -90,22 +90,23 @@ void LLDrawPoolAlpha::beginDeferredPass(S32 pass) void LLDrawPoolAlpha::endDeferredPass(S32 pass) { - gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.4f); + +} + +void LLDrawPoolAlpha::renderDeferred(S32 pass) +{ + gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.f); { LLFastTimer t(LLFastTimer::FTM_RENDER_GRASS); gDeferredTreeProgram.bind(); LLGLEnable test(GL_ALPHA_TEST); //render alpha masked objects LLRenderPass::renderTexture(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask()); + gDeferredTreeProgram.unbind(); } gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); } -void LLDrawPoolAlpha::renderDeferred(S32 pass) -{ - -} - S32 LLDrawPoolAlpha::getNumPostDeferredPasses() { diff --git a/indra/newview/lldrawpoolsimple.cpp b/indra/newview/lldrawpoolsimple.cpp index 14931024e..7ca763a18 100644 --- a/indra/newview/lldrawpoolsimple.cpp +++ b/indra/newview/lldrawpoolsimple.cpp @@ -263,7 +263,7 @@ void LLDrawPoolGrass::endDeferredPass(S32 pass) void LLDrawPoolGrass::renderDeferred(S32 pass) { - gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); + gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.f); { LLFastTimer t(LLFastTimer::FTM_RENDER_GRASS); diff --git a/indra/newview/lldrawpooltree.cpp b/indra/newview/lldrawpooltree.cpp index d3241fdf2..f08e22569 100644 --- a/indra/newview/lldrawpooltree.cpp +++ b/indra/newview/lldrawpooltree.cpp @@ -141,8 +141,8 @@ void LLDrawPoolTree::endRenderPass(S32 pass) void LLDrawPoolTree::beginDeferredPass(S32 pass) { LLFastTimer t(LLFastTimer::FTM_RENDER_TREES); - gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); - + gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.f); + shader = &gDeferredTreeProgram; shader->bind(); } diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp index 6fa1d5894..89c5bb88b 100644 --- a/indra/newview/lldrawpoolwater.cpp +++ b/indra/newview/lldrawpoolwater.cpp @@ -137,6 +137,19 @@ void LLDrawPoolWater::endPostDeferredPass(S32 pass) deferred_render = FALSE; } +//=============================== +//DEFERRED IMPLEMENTATION +//=============================== +void LLDrawPoolWater::renderDeferred(S32 pass) +{ + LLFastTimer t(LLFastTimer::FTM_RENDER_WATER); + deferred_render = TRUE; + shade(); + deferred_render = FALSE; +} + +//========================================= + void LLDrawPoolWater::render(S32 pass) { LLFastTimer ftm(LLFastTimer::FTM_RENDER_WATER); @@ -338,7 +351,10 @@ void LLDrawPoolWater::renderReflection(LLFace* face) void LLDrawPoolWater::shade() { - gGL.setColorMask(true, true); + if (!deferred_render) + { + gGL.setColorMask(true, true); + } LLVOSky *voskyp = gSky.mVOSkyp; @@ -354,7 +370,7 @@ void LLDrawPoolWater::shade() LLVector3 light_dir; LLColor3 light_color; - if (gSky.getSunDirection().mV[2] > NIGHTTIME_ELEVATION_COS) + if (gSky.getSunDirection().mV[2] > LLSky::NIGHTTIME_ELEVATION_COS) { light_dir = gSky.getSunDirection(); light_dir.normVec(); @@ -388,11 +404,11 @@ void LLDrawPoolWater::shade() F32 eyedepth = LLViewerCamera::getInstance()->getOrigin().mV[2] - gAgent.getRegion()->getWaterHeight(); - if (deferred_render) + if (eyedepth > 0.f && deferred_render) { shader = &gDeferredWaterProgram; } - else if (eyedepth < 0.f && LLPipeline::sWaterReflections) + else if (eyedepth < 0.f /*&& LLPipeline::sWaterReflections*/) { shader = &gUnderWaterProgram; } @@ -401,6 +417,15 @@ void LLDrawPoolWater::shade() shader = &gWaterProgram; } + if (deferred_render) + { + gPipeline.bindDeferredShader(*shader); + } + else + { + shader->bind(); + } + sTime = (F32)LLFrameTimer::getElapsedSeconds()*0.5f; S32 reftex = shader->enableTexture(LLViewerShaderMgr::WATER_REFTEX); @@ -436,15 +461,6 @@ void LLDrawPoolWater::shade() S32 screentex = shader->enableTexture(LLViewerShaderMgr::WATER_SCREENTEX); - if (deferred_render) - { - gPipeline.bindDeferredShader(*shader); - } - else - { - shader->bind(); - } - if (screentex > -1) { shader->uniform4fv(LLViewerShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV); @@ -545,7 +561,7 @@ void LLDrawPoolWater::shade() sNeedsDistortionUpdate = TRUE; face->renderIndexed(); } - else if (gGLManager.mHasDepthClamp) + else if (gGLManager.mHasDepthClamp || deferred_render) { face->renderIndexed(); } @@ -575,7 +591,10 @@ void LLDrawPoolWater::shade() gGL.getTexUnit(0)->activate(); gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); - gGL.setColorMask(true, false); + if (!deferred_render) + { + gGL.setColorMask(true, false); + } } diff --git a/indra/newview/lldrawpoolwater.h b/indra/newview/lldrawpoolwater.h index 635104114..90db2ed29 100644 --- a/indra/newview/lldrawpoolwater.h +++ b/indra/newview/lldrawpoolwater.h @@ -71,10 +71,12 @@ public: /*virtual*/ LLDrawPool *instancePool(); static void restoreGL(); - /*virtual*/ S32 getNumPostDeferredPasses() { return getNumPasses(); } + /*virtual*/ S32 getNumPostDeferredPasses() { return 0; } //getNumPasses(); } /*virtual*/ void beginPostDeferredPass(S32 pass); /*virtual*/ void endPostDeferredPass(S32 pass); /*virtual*/ void renderPostDeferred(S32 pass) { render(pass); } + /*virtual*/ S32 getNumDeferredPasses() { return 1; } + /*virtual*/ void renderDeferred(S32 pass = 0); /*virtual*/ S32 getNumPasses(); /*virtual*/ void render(S32 pass = 0); diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp index ec8c66509..3f5754007 100644 --- a/indra/newview/lldrawpoolwlsky.cpp +++ b/indra/newview/lldrawpoolwlsky.cpp @@ -293,9 +293,10 @@ void LLDrawPoolWLSky::render(S32 pass) LLImageGL * tex = gSky.mVOSkyp->mFace[LLVOSky::FACE_MOON]->getTexture(); gGL.getTexUnit(0)->bind(tex); + renderHeavenlyBodies(); + renderStars(); - renderHeavenlyBodies(); glPopMatrix(); diff --git a/indra/newview/llsky.cpp b/indra/newview/llsky.cpp index ac7e865de..b6f4dedbd 100644 --- a/indra/newview/llsky.cpp +++ b/indra/newview/llsky.cpp @@ -67,6 +67,9 @@ F32 elevation_from_vector(const LLVector3 &v); LLSky gSky; // ---------------- LLSky ---------------- +const F32 LLSky::NIGHTTIME_ELEVATION = -8.0f; // degrees +const F32 LLSky::NIGHTTIME_ELEVATION_COS = (F32)sin(NIGHTTIME_ELEVATION*DEG_TO_RAD); + ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llsky.h b/indra/newview/llsky.h index abd4205e6..d7796dea8 100644 --- a/indra/newview/llsky.h +++ b/indra/newview/llsky.h @@ -42,9 +42,6 @@ #include "llvosky.h" #include "llvoground.h" -const F32 NIGHTTIME_ELEVATION = -8.0f; // degrees -const F32 NIGHTTIME_ELEVATION_COS = (F32)sin(NIGHTTIME_ELEVATION*DEG_TO_RAD); - class LLViewerCamera; class LLVOWLSky; @@ -111,6 +108,9 @@ public: // Legacy stuff LLVector3 mSunDefaultPosition; + static const F32 NIGHTTIME_ELEVATION; // degrees + static const F32 NIGHTTIME_ELEVATION_COS; + protected: BOOL mOverrideSimSunPosition; diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index d4e63945e..63784107b 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -534,7 +534,7 @@ void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group) return; } - if (/*!LLPipeline::sSkipUpdate && */group->changeLOD()) + if (!LLPipeline::sSkipUpdate && group->changeLOD()) { group->mLastUpdateDistance = group->mDistance; group->mLastUpdateViewAngle = group->mViewAngle; @@ -1397,7 +1397,6 @@ void LLSpatialGroup::checkOcclusion() } else if (isOcclusionState(QUERY_PENDING)) { //otherwise, if a query is pending, read it back - LLFastTimer t(LLFastTimer::FTM_OCCLUSION_READBACK); GLuint res = 1; if (!isOcclusionState(DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID]) { @@ -1437,10 +1436,9 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera) { if (mSpatialPartition->isOcclusionEnabled() && LLPipeline::sUseOcclusion > 1) { - static const LLCachedControl render_water_void_culling("RenderWaterVoidCulling", TRUE); + //static const LLCachedControl render_water_void_culling("RenderWaterVoidCulling", TRUE); // Don't cull hole/edge water, unless RenderWaterVoidCulling is set and we have the GL_ARB_depth_clamp extension. - if ((mSpatialPartition->mDrawableType == LLPipeline::RENDER_TYPE_VOIDWATER && - !(render_water_void_culling && gGLManager.mHasDepthClamp)) || + if ((mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER && !gGLManager.mHasDepthClamp) || earlyFail(camera, this)) { setOcclusionState(LLSpatialGroup::DISCARD_QUERY); @@ -1466,10 +1464,9 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera) // Depth clamp all water to avoid it being culled as a result of being // behind the far clip plane, and in the case of edge water to avoid // it being culled while still visible. - bool const use_depth_clamp = - gGLManager.mHasDepthClamp && - (mSpatialPartition->mDrawableType == LLPipeline::RENDER_TYPE_WATER || - mSpatialPartition->mDrawableType == LLPipeline::RENDER_TYPE_VOIDWATER); + bool const use_depth_clamp = gGLManager.mHasDepthClamp && + (mSpatialPartition->mDrawableType == LLDrawPool::POOL_WATER || + mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER); if (use_depth_clamp) { glEnable(GL_DEPTH_CLAMP); diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index b201fb877..089f52af8 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -356,6 +356,15 @@ static bool handleRenderUseVBOChanged(const LLSD& newvalue) return true; } +static bool handleRenderUseVBOMappingChanged(const LLSD& newvalue) +{ + if (gPipeline.isInit()) + { + gPipeline.setDisableVBOMapping(newvalue.asBoolean()); + } + return true; +} + static bool handleWLSkyDetailChanged(const LLSD&) { if (gSky.mVOWLSkyp.notNull()) @@ -602,6 +611,7 @@ void settings_setup_listeners() gSavedSettings.getControl("MuteAmbient")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1)); gSavedSettings.getControl("MuteUI")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1)); gSavedSettings.getControl("RenderVBOEnable")->getSignal()->connect(boost::bind(&handleRenderUseVBOChanged, _1)); + gSavedSettings.getControl("RenderVBOMappingDisable")->getSignal()->connect(boost::bind(&handleRenderUseVBOMappingChanged, _1)); gSavedSettings.getControl("WLSkyDetail")->getSignal()->connect(boost::bind(&handleWLSkyDetailChanged, _1)); gSavedSettings.getControl("RenderLightingDetail")->getSignal()->connect(boost::bind(&handleRenderLightingDetailChanged, _1)); gSavedSettings.getControl("NumpadControl")->getSignal()->connect(boost::bind(&handleNumpadControlChanged, _1)); diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 7c412906f..7bb055193 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -615,6 +615,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) const F32 max_geom_update_time = 0.005f*10.f*gFrameIntervalSeconds; // 50 ms/second update time gPipeline.createObjects(max_geom_update_time); gPipeline.updateGeom(max_geom_update_time); + gPipeline.updateGL(); stop_glerror(); gFrameStats.start(LLFrameStats::UPDATE_CULL); @@ -667,6 +668,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) LLGLState::checkClientArrays(); static LLCullResult result; + LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; gPipeline.updateCull(*LLViewerCamera::getInstance(), result, water_clip); stop_glerror(); @@ -784,6 +786,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) // LLAppViewer::instance()->pingMainloopTimeout("Display:StateSort"); { + LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; gFrameStats.start(LLFrameStats::STATE_SORT); gPipeline.sAllowRebuildPriorityGroup = TRUE ; gPipeline.stateSort(*LLViewerCamera::getInstance(), result); @@ -887,7 +890,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) if (!(LLAppViewer::instance()->logoutRequestSent() && LLAppViewer::instance()->hasSavedFinalSnapshot()) && !gRestoreGL) { - + LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; gGL.setColorMask(true, false); if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender) { @@ -1366,6 +1369,12 @@ void render_disconnected_background() gGL.color4f(1,1,1,1); if (!gDisconnectedImagep && gDisconnected) { + //Default black image. + gDisconnectedImagep = new LLImageGL( FALSE ); + LLPointer raw = new LLImageRaw(1,1,3); + raw->clear(); + gDisconnectedImagep->createGLTexture(0, raw, 0, TRUE, LLViewerImageBoostLevel::OTHER); + llinfos << "Loading last bitmap..." << llendl; std::string temp_str; @@ -1378,8 +1387,6 @@ void render_disconnected_background() return; } - gDisconnectedImagep = new LLImageGL( FALSE ); - LLPointer raw = new LLImageRaw; if (!image_bmp->decode(raw, 0.0f)) { llinfos << "Bitmap decode failed" << llendl; diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 71e3ddcfd..f3639d3b0 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -456,7 +456,6 @@ void LLViewerObject::initVOClasses() llinfos << "Viewer Object size: " << sizeof(LLViewerObject) << llendl; LLVOGrass::initClass(); LLVOWater::initClass(); - LLVOSky::initClass(); LLVOVolume::initClass(); } diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 98fe69549..8ef475a24 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -127,7 +127,8 @@ LLGLSLShader gDeferredFullbrightProgram(LLViewerShaderMgr::SHADER_DEFERRED); / GLint gAvatarMatrixParam; LLViewerShaderMgr::LLViewerShaderMgr() : - mVertexShaderLevel(SHADER_COUNT, 0) + mVertexShaderLevel(SHADER_COUNT, 0), + mMaxAvatarShaderLevel(0) {} LLViewerShaderMgr::~LLViewerShaderMgr() @@ -253,10 +254,15 @@ S32 LLViewerShaderMgr::getVertexShaderLevel(S32 type) void LLViewerShaderMgr::setShaders() { - if (!gPipeline.mInitialized || !sInitialized) + //setShaders might be called redundantly by gSavedSettings, so return on reentrance + static bool reentrance = false; + + if (!gPipeline.mInitialized || !sInitialized || reentrance) { return; } + + reentrance = true; initAttribsAndUniforms(); gPipeline.releaseGLBuffers(); @@ -269,8 +275,8 @@ void LLViewerShaderMgr::setShaders() } else { - LLPipeline::sRenderGlow = - LLPipeline::sWaterReflections = FALSE; + LLPipeline::sRenderGlow = FALSE; + LLPipeline::sWaterReflections = FALSE; } //hack to reset buffers that change behavior with shaders @@ -302,6 +308,21 @@ void LLViewerShaderMgr::setShaders() S32 wl_class = 2; S32 water_class = 2; S32 deferred_class = 0; + + if (LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") && + gSavedSettings.getBOOL("RenderDeferred")) + { + deferred_class = 1; + + //make sure framebuffer objects are enabled + gSavedSettings.setBOOL("RenderUseFBO", TRUE); + + //make sure hardware skinning is enabled + gSavedSettings.setBOOL("RenderAvatarVP", TRUE); + + //make sure atmospheric shaders are enabled + gSavedSettings.setBOOL("WindLightUseAtmosShaders", TRUE); + } if (!(LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders") && gSavedSettings.getBOOL("WindLightUseAtmosShaders"))) { @@ -310,11 +331,6 @@ void LLViewerShaderMgr::setShaders() wl_class = 1; } - if (LLPipeline::sRenderDeferred) - { - deferred_class = 1; - } - if(!gSavedSettings.getBOOL("EnableRippleWater")) { water_class = 0; @@ -428,6 +444,7 @@ void LLViewerShaderMgr::setShaders() gViewerWindow->setCursor(UI_CURSOR_ARROW); } gPipeline.createGLBuffers(); + reentrance = false; } void LLViewerShaderMgr::unloadShaders() diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 48a1e3f8a..5ee61a1b8 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1544,7 +1544,7 @@ LLViewerWindow::LLViewerWindow( { gSavedSettings.setBOOL("RenderVBOEnable", FALSE); } - LLVertexBuffer::initClass(gSavedSettings.getBOOL("RenderVBOEnable")); + LLVertexBuffer::initClass(gSavedSettings.getBOOL("RenderVBOEnable"), gSavedSettings.getBOOL("RenderVBOMappingDisable")); if (LLFeatureManager::getInstance()->isSafe() || (gSavedSettings.getS32("LastFeatureVersion") != LLFeatureManager::getInstance()->getVersion()) diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp index ff6bba3b3..0443aaaca 100644 --- a/indra/newview/llvosky.cpp +++ b/indra/newview/llvosky.cpp @@ -78,16 +78,9 @@ static const LLVector2 TEX01 = LLVector2(0.f, 1.f); static const LLVector2 TEX10 = LLVector2(1.f, 0.f); static const LLVector2 TEX11 = LLVector2(1.f, 1.f); -// Exported global semi-constants. +// Exported globals LLUUID gSunTextureID = IMG_SUN; LLUUID gMoonTextureID = IMG_MOON; -// Exported global constants. -LLColor3 const gAirScaSeaLevel = calc_air_sca_sea_level(); -F32 const AIR_SCA_INTENS = color_intens(gAirScaSeaLevel); -F32 const AIR_SCA_AVG = AIR_SCA_INTENS / 3.f; - -//static -LLColor3 LLHaze::sAirScaSeaLevel; class LLFastLn { @@ -191,6 +184,23 @@ inline void color_gamma_correct(LLColor3 &col) } } +static LLColor3 calc_air_sca_sea_level() +{ + static LLColor3 WAVE_LEN(675, 520, 445); + static LLColor3 refr_ind = refr_ind_calc(WAVE_LEN); + static LLColor3 n21 = refr_ind * refr_ind - LLColor3(1, 1, 1); + static LLColor3 n4 = n21 * n21; + static LLColor3 wl2 = WAVE_LEN * WAVE_LEN * 1e-6f; + static LLColor3 wl4 = wl2 * wl2; + static LLColor3 mult_const = fsigma * 2.0f/ 3.0f * 1e24f * (F_PI * F_PI) * n4; + static F32 dens_div_N = F32( ATM_SEA_LEVEL_NDENS / Ndens2); + return dens_div_N * color_div ( mult_const, wl4 ); +} + +// static constants. +LLColor3 const LLHaze::sAirScaSeaLevel = calc_air_sca_sea_level(); +F32 const LLHaze::sAirScaIntense = color_intens(LLHaze::sAirScaSeaLevel); +F32 const LLHaze::sAirScaAvg = LLHaze::sAirScaIntense / 3.f; /*************************************** @@ -389,22 +399,21 @@ LLVOSky::LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) mBloomTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); mHeavenlyBodyUpdated = FALSE ; + + mDrawRefl = 0; + mHazeConcentration = 0.f; + mInterpVal = 0.f; } LLVOSky::~LLVOSky() { - // Don't delete images - it'll get deleted by gImageList on shutdown + // Don't delete images - it'll get deleted by gTextureList on shutdown // This needs to be done for each texture mCubeMap = NULL; } -void LLVOSky::initClass() -{ - LLHaze::initClass(); -} - void LLVOSky::init() { @@ -969,7 +978,7 @@ void LLVOSky::calcAtmospherics(void) // and vary_sunlight will work properly with moon light F32 lighty = unclamped_lightnorm[1]; - if(lighty < NIGHTTIME_ELEVATION_COS) + if(lighty < LLSky::NIGHTTIME_ELEVATION_COS) { lighty = -lighty; } @@ -1080,10 +1089,10 @@ BOOL LLVOSky::updateSky() ++next_frame; next_frame = next_frame % cycle_frame_no; - sInterpVal = (!mInitialized) ? 1 : (F32)next_frame / cycle_frame_no; + mInterpVal = (!mInitialized) ? 1 : (F32)next_frame / cycle_frame_no; // sInterpVal = (F32)next_frame / cycle_frame_no; - LLSkyTex::setInterpVal( sInterpVal ); - LLHeavenBody::setInterpVal( sInterpVal ); + LLSkyTex::setInterpVal( mInterpVal ); + LLHeavenBody::setInterpVal( mInterpVal ); calcAtmospherics(); if (mForceUpdate || total_no_tiles == frame) @@ -2151,17 +2160,8 @@ void LLVOSky::updateFog(const F32 distance) stop_glerror(); } -// static -void LLHaze::initClass() -{ - sAirScaSeaLevel = LLHaze::calcAirScaSeaLevel(); -} - - // Functions used a lot. - - F32 color_norm_pow(LLColor3& col, F32 e, BOOL postmultiply) { F32 mv = color_max(col); diff --git a/indra/newview/llvosky.h b/indra/newview/llvosky.h index 137082481..19dd1443d 100644 --- a/indra/newview/llvosky.h +++ b/indra/newview/llvosky.h @@ -147,8 +147,8 @@ protected: static S32 getResolution() { return sResolution; } static S32 getCurrent() { return sCurrent; } - static S32 stepCurrent() { sCurrent++; sCurrent&=1; return sCurrent; } - static S32 getNext() { return ((sCurrent+1) % 2); } + static S32 stepCurrent() { sCurrent++; sCurrent &= 1; return sCurrent; } + static S32 getNext() { return ((sCurrent+1) & 1); } static S32 getWhich(const BOOL curr) { return curr ? sCurrent : getNext(); } void initEmpty(const S32 tex); @@ -298,24 +298,6 @@ LL_FORCE_INLINE LLColor3 refr_ind_calc(const LLColor3 &wave_length) } -LL_FORCE_INLINE LLColor3 calc_air_sca_sea_level() -{ - const static LLColor3 WAVE_LEN(675, 520, 445); - const static LLColor3 refr_ind = refr_ind_calc(WAVE_LEN); - const static LLColor3 n21 = refr_ind * refr_ind - LLColor3(1, 1, 1); - const static LLColor3 n4 = n21 * n21; - const static LLColor3 wl2 = WAVE_LEN * WAVE_LEN * 1e-6f; - const static LLColor3 wl4 = wl2 * wl2; - const static LLColor3 mult_const = fsigma * 2.0f/ 3.0f * 1e24f * (F_PI * F_PI) * n4; - const static F32 dens_div_N = F32( ATM_SEA_LEVEL_NDENS / Ndens2); - return dens_div_N * color_div ( mult_const, wl4 ); -} - -// Non-POD constants. -extern LLColor3 const gAirScaSeaLevel; -extern F32 const AIR_SCA_INTENS; -extern F32 const AIR_SCA_AVG; - class LLHaze { public: @@ -323,18 +305,15 @@ public: LLHaze(const F32 g, const LLColor3& sca, const F32 fo = 2.f) : mG(g), mSigSca(0.25f/F_PI * sca), mFalloff(fo), mAbsCoef(0.f) { - mAbsCoef = color_intens(mSigSca) / AIR_SCA_INTENS; + mAbsCoef = color_intens(mSigSca) / sAirScaIntense; } LLHaze(const F32 g, const F32 sca, const F32 fo = 2.f) : mG(g), mSigSca(0.25f/F_PI * LLColor3(sca, sca, sca)), mFalloff(fo) { - mAbsCoef = 0.01f * sca / AIR_SCA_AVG; + mAbsCoef = 0.01f * sca / sAirScaAvg; } - static void initClass(); - - F32 getG() const { return mG; } void setG(const F32 g) @@ -350,12 +329,12 @@ public: void setSigSca(const LLColor3& s) { mSigSca = s; - mAbsCoef = 0.01f * color_intens(mSigSca) / AIR_SCA_INTENS; + mAbsCoef = 0.01f * color_intens(mSigSca) / sAirScaIntense; } void setSigSca(const F32 s0, const F32 s1, const F32 s2) { - mSigSca = AIR_SCA_AVG * LLColor3 (s0, s1, s2); + mSigSca = sAirScaAvg * LLColor3 (s0, s1, s2); mAbsCoef = 0.01f * (s0 + s1 + s2) / 3; } @@ -399,10 +378,11 @@ public: static inline LLColor3 calcAirSca(const F32 h); static inline void calcAirSca(const F32 h, LLColor3 &result); - static LLColor3 calcAirScaSeaLevel() { return gAirScaSeaLevel; } - static const LLColor3 &getAirScaSeaLevel() { return sAirScaSeaLevel; } -public: - static LLColor3 sAirScaSeaLevel; + +private: + static LLColor3 const sAirScaSeaLevel; + static F32 const sAirScaIntense; + static F32 const sAirScaAvg; protected: F32 mG; @@ -480,7 +460,6 @@ public: LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp); // Initialize/delete data that's only inited once per class. - static void initClass(); void init(); void initCubeMap(); void initEmpty(); @@ -614,7 +593,7 @@ protected: LLColor3 mLastTotalAmbient; F32 mAmbientScale; LLColor3 mNightColorShift; - F32 sInterpVal; + F32 mInterpVal; LLColor4 mFogColor; LLColor4 mGLFogCol; @@ -661,14 +640,12 @@ F32 color_norm_pow(LLColor3& col, F32 e, BOOL postmultiply = FALSE); inline LLColor3 LLHaze::calcAirSca(const F32 h) { - static const LLColor3 air_sca_sea_level = calcAirScaSeaLevel(); - return calcFalloff(h) * air_sca_sea_level; + return calcFalloff(h) * sAirScaSeaLevel; } inline void LLHaze::calcAirSca(const F32 h, LLColor3 &result) { - static const LLColor3 air_sca_sea_level = calcAirScaSeaLevel(); - result = air_sca_sea_level; + result = sAirScaSeaLevel; result *= calcFalloff(h); } diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp index abd25e659..8d63b069c 100644 --- a/indra/newview/llvowlsky.cpp +++ b/indra/newview/llvowlsky.cpp @@ -49,12 +49,12 @@ const U32 LLVOWLSky::MAX_SKY_DETAIL = 180; inline U32 LLVOWLSky::getNumStacks(void) { - return gSavedSettings.getU32("WLSkyDetail"); + return llmin(MAX_SKY_DETAIL, llmax(MIN_SKY_DETAIL, gSavedSettings.getU32("WLSkyDetail"))); } inline U32 LLVOWLSky::getNumSlices(void) { - return 2 * gSavedSettings.getU32("WLSkyDetail"); + return 2 * llmin(MAX_SKY_DETAIL, llmax(MIN_SKY_DETAIL, gSavedSettings.getU32("WLSkyDetail"))); } inline U32 LLVOWLSky::getFanNumVerts(void) @@ -489,7 +489,7 @@ void LLVOWLSky::drawStars(void) if (mStarsVerts.notNull()) { mStarsVerts->setBuffer(LLDrawPoolWLSky::STAR_VERTEX_DATA_MASK); - mStarsVerts->draw(LLRender::POINTS, getStarsNumIndices(), 0); + mStarsVerts->drawArrays(LLRender::QUADS, 0, getStarsNumVerts()*4); } } @@ -769,17 +769,17 @@ BOOL LLVOWLSky::updateStarGeometry(LLDrawable *drawable) { LLStrider verticesp; LLStrider colorsp; - LLStrider indicesp; + LLStrider texcoordsp; if (mStarsVerts.isNull()) { mStarsVerts = new LLVertexBuffer(LLDrawPoolWLSky::STAR_VERTEX_DATA_MASK, GL_DYNAMIC_DRAW); - mStarsVerts->allocateBuffer(getStarsNumVerts(), getStarsNumIndices(), TRUE); + mStarsVerts->allocateBuffer(getStarsNumVerts()*4, 0, TRUE); } BOOL success = mStarsVerts->getVertexStrider(verticesp) - && mStarsVerts->getIndexStrider(indicesp) - && mStarsVerts->getColorStrider(colorsp); + && mStarsVerts->getColorStrider(colorsp) + && mStarsVerts->getTexCoord0Strider(texcoordsp); if(!success) { @@ -789,11 +789,37 @@ BOOL LLVOWLSky::updateStarGeometry(LLDrawable *drawable) // *TODO: fix LLStrider with a real prefix increment operator so it can be // used as a model of OutputIterator. -Brad // std::copy(mStarVertices.begin(), mStarVertices.end(), verticesp); + + if (mStarVertices.size() < getStarsNumVerts()) + { + llerrs << "Star reference geometry insufficient." << llendl; + } + for (U32 vtx = 0; vtx < getStarsNumVerts(); ++vtx) { + LLVector3 at = mStarVertices[vtx]; + at.normVec(); + LLVector3 left = at%LLVector3(0,0,1); + LLVector3 up = at%left; + + F32 sc = 0.5f+ll_frand()*1.25f; + left *= sc; + up *= sc; + *(verticesp++) = mStarVertices[vtx]; + *(verticesp++) = mStarVertices[vtx]+left; + *(verticesp++) = mStarVertices[vtx]+left+up; + *(verticesp++) = mStarVertices[vtx]+up; + + *(texcoordsp++) = LLVector2(0,0); + *(texcoordsp++) = LLVector2(0,1); + *(texcoordsp++) = LLVector2(1,1); + *(texcoordsp++) = LLVector2(1,0); + + *(colorsp++) = LLColor4U(mStarColors[vtx]); + *(colorsp++) = LLColor4U(mStarColors[vtx]); + *(colorsp++) = LLColor4U(mStarColors[vtx]); *(colorsp++) = LLColor4U(mStarColors[vtx]); - *(indicesp++) = vtx; } mStarsVerts->setBuffer(0); diff --git a/indra/newview/llwaterparammanager.cpp b/indra/newview/llwaterparammanager.cpp index 50e407739..848c8137f 100644 --- a/indra/newview/llwaterparammanager.cpp +++ b/indra/newview/llwaterparammanager.cpp @@ -301,7 +301,7 @@ void LLWaterParamManager::update(LLViewerCamera * cam) mWaterPlane = LLVector4(enorm.v[0], enorm.v[1], enorm.v[2], -ep.dot(enorm)); LLVector3 sunMoonDir; - if (gSky.getSunDirection().mV[2] > NIGHTTIME_ELEVATION_COS) + if (gSky.getSunDirection().mV[2] > LLSky::NIGHTTIME_ELEVATION_COS) { sunMoonDir = gSky.getSunDirection(); } diff --git a/indra/newview/llwlparammanager.cpp b/indra/newview/llwlparammanager.cpp index c4d146664..dfe921667 100644 --- a/indra/newview/llwlparammanager.cpp +++ b/indra/newview/llwlparammanager.cpp @@ -315,7 +315,7 @@ void LLWLParamManager::propagateParameters(void) { mLightDir = sunDir; } - else if(sunDir.mV[1] < 0 && sunDir.mV[1] > NIGHTTIME_ELEVATION_COS) + else if(sunDir.mV[1] < 0 && sunDir.mV[1] > LLSky::NIGHTTIME_ELEVATION_COS) { // clamp v1 to 0 so sun never points up and causes weirdness on some machines LLVector3 vec(sunDir.mV[0], sunDir.mV[1], sunDir.mV[2]); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 59000e600..21ab8e598 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -2114,7 +2114,7 @@ void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera) void LLPipeline::stateSort(LLSpatialBridge* bridge, LLCamera& camera) { LLMemType mt(LLMemType::MTYPE_PIPELINE); - if (!sSkipUpdate && bridge->getSpatialGroup()->changeLOD()) + if (!sShadowRender && !sSkipUpdate && bridge->getSpatialGroup()->changeLOD()) { bool force_update = false; bridge->updateDistance(camera, force_update); @@ -2181,7 +2181,7 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera) LLSpatialGroup* group = drawablep->getSpatialGroup(); if (!group || group->changeLOD()) { - if (drawablep->isVisible()) + if (drawablep->isVisible() && !sSkipUpdate) { if (!drawablep->isActive()) { @@ -2434,7 +2434,7 @@ void LLPipeline::postSort(LLCamera& camera) for (LLSpatialGroup::draw_map_t::iterator j = group->mDrawMap.begin(); j != group->mDrawMap.end(); ++j) { LLSpatialGroup::drawmap_elem_t& src_vec = j->second; - if (!hasRenderType(j->first)) //No worky yet. + if (!hasRenderType(j->first)) { continue; } @@ -2579,7 +2579,7 @@ void LLPipeline::postSort(LLCamera& camera) } } - LLSpatialGroup::sNoDelete = FALSE; + //LLSpatialGroup::sNoDelete = FALSE; } @@ -3983,7 +3983,7 @@ void LLPipeline::setupAvatarLights(BOOL for_edit) } } F32 backlight_mag; - if (gSky.getSunDirection().mV[2] >= NIGHTTIME_ELEVATION_COS) + if (gSky.getSunDirection().mV[2] >= LLSky::NIGHTTIME_ELEVATION_COS) { backlight_mag = BACKLIGHT_DAY_MAGNITUDE_OBJECT; } @@ -4172,7 +4172,7 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) // Light 0 = Sun or Moon (All objects) { - if (gSky.getSunDirection().mV[2] >= NIGHTTIME_ELEVATION_COS) + if (gSky.getSunDirection().mV[2] >= LLSky::NIGHTTIME_ELEVATION_COS) { mSunDir.setVec(gSky.getSunDirection()); mSunDiffuse.setVec(gSky.getSunDiffuseColor()); @@ -4438,10 +4438,10 @@ void LLPipeline::enableLightsFullbright(const LLColor4& color) enableLights(mask); glLightModelfv(GL_LIGHT_MODEL_AMBIENT,color.mV); - if (mLightingDetail >= 2) + /*if (mLightingDetail >= 2) { glColor4f(0.f, 0.f, 0.f, 1.f); // no local lighting by default - } + }*/ } void LLPipeline::disableLights() @@ -5149,7 +5149,25 @@ void LLPipeline::setUseVBO(BOOL use_vbo) } resetVertexBuffers(); - LLVertexBuffer::initClass(use_vbo); + LLVertexBuffer::initClass(use_vbo, gSavedSettings.getBOOL("RenderVBOMappingDisable")); + } +} + +void LLPipeline::setDisableVBOMapping(BOOL no_vbo_mapping) +{ + if (LLVertexBuffer::sEnableVBOs && no_vbo_mapping != LLVertexBuffer::sDisableVBOMapping) + { + if (no_vbo_mapping) + { + llinfos << "Disabling VBO glMapBufferARB." << llendl; + } + else + { + llinfos << "Enabling VBO glMapBufferARB." << llendl; + } + + resetVertexBuffers(); + LLVertexBuffer::initClass(true, no_vbo_mapping); } } @@ -5668,6 +5686,11 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index) shader.uniform2f("screen_res", mDeferredScreen.getWidth(), mDeferredScreen.getHeight()); shader.uniform1f("near_clip", LLViewerCamera::getInstance()->getNear()*2.f); shader.uniform1f("alpha_soften", render_deferred_alpha_soft); + if (shader.getUniformLocation("norm_mat") >= 0) + { + glh::matrix4f norm_mat = glh_get_current_modelview().inverse().transpose(); + shader.uniformMatrix4fv("norm_mat", 1, FALSE, norm_mat.m); + } } void LLPipeline::renderDeferredLighting() @@ -5677,6 +5700,7 @@ void LLPipeline::renderDeferredLighting() return; } + LLViewerCamera* camera = LLViewerCamera::getInstance(); LLGLEnable multisample(GL_MULTISAMPLE_ARB); if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) @@ -5691,15 +5715,13 @@ void LLPipeline::renderDeferredLighting() gGL.setColorMask(true, true); - mDeferredLight[0].bindTarget(); - //mDeferredLight[0].copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(), // 0, 0, mDeferredLight[0].getWidth(), mDeferredLight[0].getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); //draw a cube around every light LLVertexBuffer::unbind(); - glBlendFunc(GL_ONE, GL_ONE); + //glBlendFunc(GL_ONE, GL_ONE); LLGLEnable cull(GL_CULL_FACE); LLGLEnable blend(GL_BLEND); @@ -5711,126 +5733,130 @@ void LLPipeline::renderDeferredLighting() -1,-3, 3,1, }; + glVertexPointer(2, GL_FLOAT, 0, vert); + glColor3f(1,1,1); - bindDeferredShader(gDeferredSunProgram); - - 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]; - } + setupHWLights(NULL); //to set mSunDir; + LLVector4 dir(mSunDir, 0.f); + glh::vec4f tc(dir.mV); + mat.mult_matrix_vec(tc); + glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], 0); } - gDeferredSunProgram.uniform3fv("offset", slice, offset); - gDeferredSunProgram.uniform2f("screenRes", mDeferredLight[0].getWidth(), mDeferredLight[0].getHeight()); - - setupHWLights(NULL); //to set mSunDir; - glPushMatrix(); glLoadIdentity(); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); - LLVector4 dir(mSunDir, 0.f); - - glh::vec4f tc(dir.mV); - mat.mult_matrix_vec(tc); - glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], 0); - glColor3f(1,1,1); - - glVertexPointer(2, GL_FLOAT, 0, vert); - { - LLGLDisable blend(GL_BLEND); - LLGLDepthTest depth(GL_FALSE); - stop_glerror(); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); - stop_glerror(); - } - - unbindDeferredShader(gDeferredSunProgram); - - mDeferredLight[0].flush(); - - //blur lightmap - mDeferredLight[1].bindTarget(); - - //mDeferredLight[1].copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(), - // 0, 0, mDeferredLight[0].getWidth(), mDeferredLight[0].getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); - - bindDeferredShader(gDeferredBlurLightProgram); - - LLVector3 gauss[32]; // xweight, yweight, offset - - LLVector3 go = gSavedSettings.getVector3("RenderShadowGaussian"); - U32 kern_length = llclamp(gSavedSettings.getU32("RenderShadowBlurSamples"), (U32) 1, (U32) 16)*2 - 1; - F32 blur_size = gSavedSettings.getF32("RenderShadowBlurSize"); - - // sample symmetrically with the middle sample falling exactly on 0.0 - F32 x = -(kern_length/2.0f) + 0.5f; - - for (U32 i = 0; i < kern_length; i++) - { - gauss[i].mV[0] = llgaussian(x, go.mV[0]); - gauss[i].mV[1] = llgaussian(x, go.mV[1]); - gauss[i].mV[2] = x; - x += 1.f; - } - /* swap the x=0 position to the start of gauss[] so we can - treat it specially as an optimization. */ - LLVector3 swap; - swap = gauss[kern_length/2]; - gauss[kern_length/2] = gauss[0]; - gauss[0] = swap; - llassert(gauss[0].mV[2] == 0.0f); - - gDeferredBlurLightProgram.uniform2f("delta", 1.f, 0.f); - gDeferredBlurLightProgram.uniform3fv("kern[0]", kern_length, gauss[0].mV); - gDeferredBlurLightProgram.uniform3fv("kern", kern_length, gauss[0].mV); - gDeferredBlurLightProgram.uniform1i("kern_length", kern_length); - gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f)); - - { - LLGLDisable blend(GL_BLEND); - LLGLDepthTest depth(GL_FALSE); - stop_glerror(); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); - stop_glerror(); - } - - mDeferredLight[1].flush(); - unbindDeferredShader(gDeferredBlurLightProgram); - - bindDeferredShader(gDeferredBlurLightProgram, 1); mDeferredLight[0].bindTarget(); - gDeferredBlurLightProgram.uniform2f("delta", 0.f, 1.f); - gDeferredBlurLightProgram.uniform3fv("kern[0]", kern_length, gauss[0].mV); - gDeferredBlurLightProgram.uniform3fv("kern", kern_length, gauss[0].mV); - gDeferredBlurLightProgram.uniform1i("kern_length", kern_length); - gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f)); - + //Sun shadows. { - LLGLDisable blend(GL_BLEND); - LLGLDepthTest depth(GL_FALSE); - stop_glerror(); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - stop_glerror(); + bindDeferredShader(gDeferredSunProgram); + + 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("offset", slice, offset); + gDeferredSunProgram.uniform2f("screenRes", mDeferredLight[0].getWidth(), mDeferredLight[0].getHeight()); + + { + LLGLDisable blend(GL_BLEND); + LLGLDepthTest depth(GL_FALSE); + stop_glerror(); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); + stop_glerror(); + } + + unbindDeferredShader(gDeferredSunProgram); } + mDeferredLight[0].flush(); - unbindDeferredShader(gDeferredBlurLightProgram); + + //SSAO + { + //blur lightmap + mDeferredLight[1].bindTarget(); + + //mDeferredLight[1].copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(), + // 0, 0, mDeferredLight[0].getWidth(), mDeferredLight[0].getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); + + bindDeferredShader(gDeferredBlurLightProgram); + + LLVector3 go = gSavedSettings.getVector3("RenderShadowGaussian"); + U32 kern_length = llclamp(gSavedSettings.getU32("RenderShadowBlurSamples"), (U32) 1, (U32) 16)*2 - 1; + F32 blur_size = gSavedSettings.getF32("RenderShadowBlurSize"); + + // sample symmetrically with the middle sample falling exactly on 0.0 + F32 x = -(kern_length/2.0f) + 0.5f; + + LLVector3 gauss[32]; // xweight, yweight, offset + + for (U32 i = 0; i < kern_length; i++) + { + gauss[i].mV[0] = llgaussian(x, go.mV[0]); + gauss[i].mV[1] = llgaussian(x, go.mV[1]); + gauss[i].mV[2] = x; + x += 1.f; + } + /* swap the x=0 position to the start of gauss[] so we can + treat it specially as an optimization. */ + LLVector3 swap; + swap = gauss[kern_length/2]; + gauss[kern_length/2] = gauss[0]; + gauss[0] = swap; + llassert(gauss[0].mV[2] == 0.0f); + + gDeferredBlurLightProgram.uniform2f("delta", 1.f, 0.f); + gDeferredBlurLightProgram.uniform3fv("kern[0]", kern_length, gauss[0].mV); + gDeferredBlurLightProgram.uniform3fv("kern", kern_length, gauss[0].mV); + gDeferredBlurLightProgram.uniform1i("kern_length", kern_length); + gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f)); + + { + LLGLDisable blend(GL_BLEND); + LLGLDepthTest depth(GL_FALSE); + stop_glerror(); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); + stop_glerror(); + } + + mDeferredLight[1].flush(); + unbindDeferredShader(gDeferredBlurLightProgram); + + bindDeferredShader(gDeferredBlurLightProgram, 1); + mDeferredLight[0].bindTarget(); + + gDeferredBlurLightProgram.uniform2f("delta", 0.f, 1.f); + + { + LLGLDisable blend(GL_BLEND); + LLGLDepthTest depth(GL_FALSE); + stop_glerror(); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + stop_glerror(); + } + mDeferredLight[0].flush(); + unbindDeferredShader(gDeferredBlurLightProgram); + } stop_glerror(); glPopMatrix(); @@ -5845,6 +5871,8 @@ void LLPipeline::renderDeferredLighting() // 0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); mScreen.bindTarget(); + // clear color buffer here - zeroing alpha (glow) is important or it will accumulate against sky + glClearColor(0,0,0,0); mScreen.clear(GL_COLOR_BUFFER_BIT); bindDeferredShader(gDeferredSoftenProgram); @@ -5871,7 +5899,23 @@ void LLPipeline::renderDeferredLighting() unbindDeferredShader(gDeferredSoftenProgram); - bindDeferredShader(gDeferredLightProgram); + + { //render sky + 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_WL_CLOUDS, + LLPipeline::RENDER_TYPE_WL_SKY, + LLPipeline::END_RENDER_TYPES); + + + renderGeomPostDeferred(*LLViewerCamera::getInstance()); + gPipeline.popRenderTypeMask(); + } std::list fullscreen_lights; std::list light_colors; @@ -5879,6 +5923,7 @@ void LLPipeline::renderDeferredLighting() F32 v[24]; glVertexPointer(3, GL_FLOAT, 0, v); { + bindDeferredShader(gDeferredLightProgram); LLGLDepthTest depth(GL_TRUE, GL_FALSE); for (LLDrawable::drawable_set_t::iterator iter = mLights.begin(); iter != mLights.end(); ++iter) { @@ -5890,22 +5935,42 @@ void LLPipeline::renderDeferredLighting() continue; } + if (volume->isAttachment()) + { + if (!sRenderAttachedLights) + { + continue; + } + } + + LLVector3 center = drawablep->getPositionAgent(); F32* c = center.mV; F32 s = volume->getLightRadius()*1.5f; - if (LLViewerCamera::getInstance()->AABBInFrustumNoFarClip(center, LLVector3(s,s,s)) == 0) + LLColor3 col = volume->getLightColor(); + col *= volume->getLightIntensity(); + + if (col.magVecSquared() < 0.001f) + { + continue; + } + + if (s <= 0.001f) + { + continue; + } + + if (camera->AABBInFrustumNoFarClip(center, LLVector3(s,s,s)) == 0) { continue; } sVisibleLightCount++; + glh::vec3f tc(c); mat.mult_matrix_vec(tc); - - LLColor3 col = volume->getLightColor(); - col *= volume->getLightIntensity(); - + //vertex positions are encoded so the 3 bits of their vertex index //correspond to their axis facing, with bit position 3,2,1 matching //axis facing x,y,z, bit set meaning positive facing, bit clear @@ -5920,17 +5985,17 @@ void LLPipeline::renderDeferredLighting() v[18] = c[0]+s; v[19] = c[1]+s; v[20] = c[2]-s; // 6 - 0110 v[21] = c[0]+s; v[22] = c[1]+s; v[23] = c[2]+s; // 7 - 0111 - if (LLViewerCamera::getInstance()->getOrigin().mV[0] > c[0] + s + 0.2f || - LLViewerCamera::getInstance()->getOrigin().mV[0] < c[0] - s - 0.2f || - LLViewerCamera::getInstance()->getOrigin().mV[1] > c[1] + s + 0.2f || - LLViewerCamera::getInstance()->getOrigin().mV[1] < c[1] - s - 0.2f || - LLViewerCamera::getInstance()->getOrigin().mV[2] > c[2] + s + 0.2f || - LLViewerCamera::getInstance()->getOrigin().mV[2] < c[2] - s - 0.2f) + 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 glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s); glColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f); glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, - GL_UNSIGNED_BYTE, get_box_fan_indices(LLViewerCamera::getInstance(), center)); + GL_UNSIGNED_BYTE, get_box_fan_indices(camera, center)); } else { @@ -5938,9 +6003,10 @@ void LLPipeline::renderDeferredLighting() light_colors.push_back(LLVector4(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f)); } } + unbindDeferredShader(gDeferredLightProgram); } - unbindDeferredShader(gDeferredLightProgram); + if (!fullscreen_lights.empty()) { @@ -5956,8 +6022,9 @@ void LLPipeline::renderDeferredLighting() U32 count = 0; - LLVector4 light[16]; - LLVector4 col[16]; + const U32 max_count = 16; + LLVector4 light[max_count]; + LLVector4 col[max_count]; glVertexPointer(2, GL_FLOAT, 0, vert); @@ -5967,9 +6034,9 @@ void LLPipeline::renderDeferredLighting() fullscreen_lights.pop_front(); col[count] = light_colors.front(); light_colors.pop_front(); - count++; - if (count == 16 || fullscreen_lights.empty()) + + if (count == max_count || fullscreen_lights.empty()) { gDeferredMultiLightProgram.uniform1i("light_count", count); gDeferredMultiLightProgram.uniform4fv("light[0]", count, (GLfloat*) light); @@ -5977,12 +6044,9 @@ void LLPipeline::renderDeferredLighting() gDeferredMultiLightProgram.uniform4fv("light_col[0]", count, (GLfloat*) col); gDeferredMultiLightProgram.uniform4fv("light_col", count, (GLfloat*) col); count = 0; - glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); - + glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); } } - - glPopMatrix(); glMatrixMode(GL_MODELVIEW); @@ -5990,7 +6054,7 @@ void LLPipeline::renderDeferredLighting() unbindDeferredShader(gDeferredMultiLightProgram); } - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); { //render non-deferred geometry LLGLDisable blend(GL_BLEND); @@ -6212,7 +6276,8 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) } } } - + static LLCachedControl skip_distortion_updates("SkipReflectOcclusionUpdates",false); + LLPipeline::sSkipUpdate = skip_distortion_updates; LLGLUserClipPlane clip_plane(plane, mat, projection); LLGLDisable cull(GL_CULL_FACE); updateCull(camera, ref_result, 1); @@ -6221,6 +6286,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) gPipeline.grabReferences(ref_result); LLGLUserClipPlane clip_plane(plane, mat, projection); renderGeom(camera); + LLPipeline::sSkipUpdate = FALSE; } } gPipeline.popRenderTypeMask(); @@ -6381,7 +6447,6 @@ glh::matrix4f scale_translate_to_fit(const LLVector3 min, const LLVector3 max) void LLPipeline::generateSunShadow(LLCamera& camera) { - if (!sRenderDeferred) { return; @@ -6896,6 +6961,10 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); } + LLGLEnable stencil(GL_STENCIL_TEST); + glStencilMask(0xFFFFFFFF); + glStencilFunc(GL_ALWAYS, 1, 0xFFFFFFFF); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); { LLGLEnable scissor(GL_SCISSOR_TEST); glScissor(0, 0, resX, resY); @@ -6903,15 +6972,11 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) avatar->mImpostor.clear(); } - LLGLEnable stencil(GL_STENCIL_TEST); - - glStencilFunc(GL_ALWAYS, 1, 0xFFFFFFFF); - glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - if (LLPipeline::sRenderDeferred) { stop_glerror(); renderGeomDeferred(camera); + renderGeomPostDeferred(camera); } else { @@ -6921,11 +6986,18 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); glStencilFunc(GL_EQUAL, 1, 0xFFFFFF); - if (!sRenderDeferred || muted) + //if (!sRenderDeferred || muted) { LLVector3 left = camera.getLeftAxis()*tdim.mV[0]*2.f; LLVector3 up = camera.getUpAxis()*tdim.mV[1]*2.f; + //Safe?? + if (LLPipeline::sRenderDeferred) + { + GLuint buff = GL_COLOR_ATTACHMENT0_EXT; + glDrawBuffersARB(1, &buff); + } + LLGLEnable blend(muted ? 0 : GL_BLEND); if (muted) diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index d0148d2a8..36f4c33ec 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -96,6 +96,7 @@ public: void resetVertexBuffers(LLDrawable* drawable); void setUseVBO(BOOL use_vbo); + void setDisableVBOMapping(BOOL no_vbo_mapping); void generateImpostor(LLVOAvatar* avatar); void bindScreenToTexture(); void renderBloom(BOOL for_snapshot, F32 zoom_factor = 1.f, int subfield = 0);