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.
This commit is contained in:
Shyotl
2011-03-08 18:36:59 -06:00
parent 60f3104eb6
commit 1b039a1be6
32 changed files with 708 additions and 375 deletions

View File

@@ -56,6 +56,7 @@ U32 LLVertexBuffer::sSetCount = 0;
S32 LLVertexBuffer::sCount = 0; S32 LLVertexBuffer::sCount = 0;
S32 LLVertexBuffer::sGLCount = 0; S32 LLVertexBuffer::sGLCount = 0;
S32 LLVertexBuffer::sMappedCount = 0; S32 LLVertexBuffer::sMappedCount = 0;
BOOL LLVertexBuffer::sDisableVBOMapping = FALSE ;
BOOL LLVertexBuffer::sEnableVBOs = TRUE; BOOL LLVertexBuffer::sEnableVBOs = TRUE;
U32 LLVertexBuffer::sGLRenderBuffer = 0; U32 LLVertexBuffer::sGLRenderBuffer = 0;
U32 LLVertexBuffer::sGLRenderIndices = 0; U32 LLVertexBuffer::sGLRenderIndices = 0;
@@ -287,9 +288,10 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
} }
//static //static
void LLVertexBuffer::initClass(bool use_vbo) void LLVertexBuffer::initClass(bool use_vbo, bool no_vbo_mapping)
{ {
sEnableVBOs = use_vbo; sEnableVBOs = use_vbo;
sDisableVBOMapping = sEnableVBOs && no_vbo_mapping ;
LLGLNamePool::registerPool(&sDynamicVBOPool); LLGLNamePool::registerPool(&sDynamicVBOPool);
LLGLNamePool::registerPool(&sDynamicIBOPool); LLGLNamePool::registerPool(&sDynamicIBOPool);
LLGLNamePool::registerPool(&sStreamVBOPool); LLGLNamePool::registerPool(&sStreamVBOPool);
@@ -346,7 +348,9 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :
mGLBuffer(0), mGLBuffer(0),
mGLIndices(0), mGLIndices(0),
mMappedData(NULL), mMappedData(NULL),
mMappedIndexData(NULL), mLocked(FALSE), mMappedIndexData(NULL),
mVertexLocked(FALSE),
mIndexLocked(FALSE),
mFinal(FALSE), mFinal(FALSE),
mFilthy(FALSE), mFilthy(FALSE),
mEmpty(TRUE), mEmpty(TRUE),
@@ -544,6 +548,8 @@ void LLVertexBuffer::destroyGLBuffer()
{ {
if (useVBOs()) if (useVBOs())
{ {
freeClientBuffer() ;
if (mMappedData || mMappedIndexData) if (mMappedData || mMappedIndexData)
{ {
llerrs << "Vertex buffer destroyed while mapped!" << llendl; llerrs << "Vertex buffer destroyed while mapped!" << llendl;
@@ -571,6 +577,8 @@ void LLVertexBuffer::destroyGLIndices()
{ {
if (useVBOs()) if (useVBOs())
{ {
freeClientBuffer() ;
if (mMappedData || mMappedIndexData) if (mMappedData || mMappedIndexData)
{ {
llerrs << "Vertex buffer destroyed while mapped." << llendl; llerrs << "Vertex buffer destroyed while mapped." << llendl;
@@ -768,6 +776,7 @@ void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices)
if (mResized && useVBOs()) if (mResized && useVBOs())
{ {
freeClientBuffer() ;
setBuffer(0); 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 // Map for data access
volatile U8* LLVertexBuffer::mapBuffer(S32 access) volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 access)
{ {
LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
if (mFinal) if (mFinal)
{ {
llerrs << "LLVertexBuffer::mapBuffer() called on a finalized buffer." << llendl; llerrs << "LLVertexBuffer::mapVeretxBuffer() called on a finalized buffer." << llendl;
} }
if (!useVBOs() && !mMappedData && !mMappedIndexData) 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; setBuffer(0, type);
stop_glerror(); mVertexLocked = TRUE;
mMappedData = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); stop_glerror();
stop_glerror();
mMappedIndexData = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); if(sDisableVBOMapping)
stop_glerror(); {
allocateClientVertexBuffer() ;
}
else
{
mMappedData = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
}
stop_glerror();
}
if (!mMappedData) if (!mMappedData)
{ {
//-------------------- if(!sDisableVBOMapping)
//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; //--------------------
//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;
} }
else
llerrs << "glMapBuffer returned NULL (no vertex data)" << llendl;
}
if (!mMappedIndexData)
{
GLint buff;
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
if ((GLuint)buff != mGLIndices)
{ {
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++; sMappedCount++;
} }
return mMappedData; return mMappedData;
} }
void LLVertexBuffer::unmapBuffer() volatile U8* LLVertexBuffer::mapIndexBuffer(S32 access)
{ {
LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); 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(); stop_glerror();
glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
stop_glerror(); 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); glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
stop_glerror(); stop_glerror();
/*if (!sMapped) mMappedIndexData = NULL ;
}
mIndexLocked = FALSE ;
sMappedCount--;
}
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)
{ {
llerrs << "Redundantly unmapped VBO!" << llendl; freeClientBuffer() ;
} }
sMapped = FALSE;*/ }
sMappedCount--; else
{
if (mUsage == GL_STATIC_DRAW_ARB) mEmpty = FALSE;
{ //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;
}
mMappedIndexData = NULL;
mMappedData = NULL;
mLocked = FALSE;
} }
} }
} }
@@ -893,15 +1026,16 @@ template <class T,S32 type> struct VertexBufferStrider
strider_t& strider, strider_t& strider,
S32 index) S32 index)
{ {
if (vbo.mapBuffer() == NULL)
{
llwarns << "mapBuffer failed!" << llendl;
return FALSE;
}
if (type == LLVertexBuffer::TYPE_INDEX) if (type == LLVertexBuffer::TYPE_INDEX)
{ {
S32 stride = sizeof(T); S32 stride = sizeof(T);
if (vbo.mapIndexBuffer() == NULL)
{
llwarns << "mapIndexBuffer failed!" << llendl;
return FALSE;
}
strider = (T*)(vbo.getMappedIndices() + index*stride); strider = (T*)(vbo.getMappedIndices() + index*stride);
strider.setStride(0); strider.setStride(0);
return TRUE; return TRUE;
@@ -909,6 +1043,13 @@ template <class T,S32 type> struct VertexBufferStrider
else if (vbo.hasDataType(type)) else if (vbo.hasDataType(type))
{ {
S32 stride = vbo.getStride(); 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 = (T*)(vbo.getMappedData() + vbo.getOffset(type) + index*stride);
strider.setStride(stride); strider.setStride(stride);
return TRUE; return TRUE;
@@ -989,7 +1130,7 @@ void LLVertexBuffer::setStride(S32 type, S32 new_stride)
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// Set for rendering // Set for rendering
void LLVertexBuffer::setBuffer(U32 data_mask) void LLVertexBuffer::setBuffer(U32 data_mask, S32 type)
{ {
LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
//set up pointers if the data mask is different ... //set up pointers if the data mask is different ...
@@ -1023,6 +1164,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
sIBOActive = TRUE; sIBOActive = TRUE;
} }
BOOL error = FALSE;
if (gDebugGL) if (gDebugGL)
{ {
GLint buff; GLint buff;
@@ -1085,7 +1227,11 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
} }
} }
unmapBuffer(); if (error)
{
llerrs << "LLVertexBuffer::mapBuffer failed" << llendl;
}
unmapBuffer(type);
} }
else else
{ {

View File

@@ -88,7 +88,7 @@ public:
static BOOL sUseStreamDraw; static BOOL sUseStreamDraw;
static BOOL sOmitBlank; static BOOL sOmitBlank;
static void initClass(bool use_vbo); static void initClass(bool use_vbo, bool no_vbo_mapping);
static void cleanupClass(); static void cleanupClass();
static void setupClientArrays(U32 data_mask); static void setupClientArrays(U32 data_mask);
static void clientCopy(F64 max_time = 0.005); //copy data from client to GL static void clientCopy(F64 max_time = 0.005); //copy data from client to GL
@@ -147,15 +147,20 @@ protected:
void updateNumVerts(S32 nverts); void updateNumVerts(S32 nverts);
void updateNumIndices(S32 nindices); void updateNumIndices(S32 nindices);
virtual BOOL useVBOs() const; virtual BOOL useVBOs() const;
void unmapBuffer(); void unmapBuffer(S32 type);
void freeClientBuffer() ;
void allocateClientVertexBuffer() ;
void allocateClientIndexBuffer() ;
public: public:
LLVertexBuffer(U32 typemask, S32 usage); LLVertexBuffer(U32 typemask, S32 usage);
// map for data access // 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 // 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 // allocate buffer
void allocateBuffer(S32 nverts, S32 nindices, bool create); void allocateBuffer(S32 nverts, S32 nindices, bool create);
virtual void resizeBuffer(S32 newnverts, S32 newnindices); virtual void resizeBuffer(S32 newnverts, S32 newnindices);
@@ -178,7 +183,7 @@ public:
bool getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index=0); bool getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index=0);
BOOL isEmpty() const { return mEmpty; } BOOL isEmpty() const { return mEmpty; }
BOOL isLocked() const { return mLocked; } BOOL isLocked() const { return mVertexLocked || mIndexLocked; }
S32 getNumVerts() const { return mNumVerts; } S32 getNumVerts() const { return mNumVerts; }
S32 getNumIndices() const { return mNumIndices; } S32 getNumIndices() const { return mNumIndices; }
S32 getRequestedVerts() const { return mRequestedNumVerts; } S32 getRequestedVerts() const { return mRequestedNumVerts; }
@@ -217,13 +222,14 @@ protected:
U32 mGLIndices; // GL IBO handle U32 mGLIndices; // GL IBO handle
volatile U8* mMappedData; // pointer to currently mapped data (NULL if unmapped) volatile U8* mMappedData; // pointer to currently mapped data (NULL if unmapped)
volatile U8* mMappedIndexData; // pointer to currently mapped indices (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 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 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. BOOL mEmpty; // if TRUE, client buffer is empty (or NULL). Old values have been discarded.
S32 mOffsets[TYPE_MAX];
BOOL mResized; // if TRUE, client buffer has been resized and GL buffer has not 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) BOOL mDynamicSize; // if TRUE, buffer has been resized at least once (and should be padded)
S32 mOffsets[TYPE_MAX];
class DirtyRegion class DirtyRegion
{ {
@@ -248,13 +254,14 @@ public:
static std::vector<U32> sDeleteList; static std::vector<U32> sDeleteList;
typedef std::list<LLVertexBuffer*> buffer_list_t; typedef std::list<LLVertexBuffer*> buffer_list_t;
static BOOL sDisableVBOMapping; //disable glMapBufferARB
static BOOL sEnableVBOs; static BOOL sEnableVBOs;
static BOOL sVBOActive;
static BOOL sIBOActive;
static S32 sTypeOffsets[TYPE_MAX]; static S32 sTypeOffsets[TYPE_MAX];
static U32 sGLMode[LLRender::NUM_MODES]; static U32 sGLMode[LLRender::NUM_MODES];
static U32 sGLRenderBuffer; static U32 sGLRenderBuffer;
static U32 sGLRenderIndices; static U32 sGLRenderIndices;
static BOOL sVBOActive;
static BOOL sIBOActive;
static U32 sLastMask; static U32 sLastMask;
static U32 sAllocatedBytes; static U32 sAllocatedBytes;
static U32 sBindCount; static U32 sBindCount;

View File

@@ -9843,6 +9843,17 @@
<key>Value</key> <key>Value</key>
<integer>1</integer> <integer>1</integer>
</map> </map>
<key>RenderVBOMappingDisable</key>
<map>
<key>Comment</key>
<string>Disable VBO glMapBufferARB</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>RenderVolumeLODFactor</key> <key>RenderVolumeLODFactor</key>
<map> <map>
<key>Comment</key> <key>Comment</key>
@@ -12800,6 +12811,17 @@
<key>Value</key> <key>Value</key>
<integer>1</integer> <integer>1</integer>
</map> </map>
<key>SkipReflectOcclusionUpdates</key>
<map>
<key>Comment</key>
<string>Enable optimization that prevents occlusion updates for refelction pass</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>UseOutfitFolders</key> <key>UseOutfitFolders</key>
<map> <map>
<key>Comment</key> <key>Comment</key>

View File

@@ -71,14 +71,14 @@ void main()
color.rgb = scaleSoftClip(color.rgb); color.rgb = scaleSoftClip(color.rgb);
if (samp_pos.z != 0.0) /*if (samp_pos.z != 0.0)
{ {
float dist_factor = alpha_soften; float dist_factor = alpha_soften;
float a = gl_Color.a; float a = gl_Color.a;
a *= a; a *= a;
dist_factor *= 1.0/(1.0-a); dist_factor *= 1.0/(1.0-a);
color.a *= min((pos.z-samp_pos.z)*dist_factor, 1.0); color.a *= min((pos.z-samp_pos.z)*dist_factor, 1.0);
} }*/
//gl_FragColor = gl_Color; //gl_FragColor = gl_Color;
gl_FragColor = color; gl_FragColor = color;

View File

@@ -37,8 +37,8 @@ void main()
calcAtmospherics(pos.xyz); calcAtmospherics(pos.xyz);
//vec4 color = calcLighting(pos.xyz, norm, gl_Color, vec4(0.)); //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 // Add windlight lights
col.rgb = atmosAmbient(vec3(0.)); col.rgb = atmosAmbient(vec3(0.));

View File

@@ -12,7 +12,14 @@ varying vec4 vary_position;
void main() 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[1] = vec4(0,0,0,0);
gl_FragData[2] = vec4(normalize(vary_normal), 0.0); gl_FragData[2] = vec4(normalize(vary_normal), 0.0);
gl_FragData[3] = vary_position; gl_FragData[3] = vary_position;

View File

@@ -13,7 +13,8 @@ varying vec4 vary_position;
void main() 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[1] = texture2D(specularMap, gl_TexCoord[0].xy);
gl_FragData[2] = vec4(texture2D(normalMap, gl_TexCoord[0].xy).xyz, vary_position.z); gl_FragData[2] = vec4(texture2D(normalMap, gl_TexCoord[0].xy).xyz, vary_position.z);
gl_FragData[3] = vary_position; gl_FragData[3] = vary_position;

View File

@@ -78,6 +78,12 @@ void main()
//attenuate point light contribution by SSAO component //attenuate point light contribution by SSAO component
out_col *= texture2DRect(lightMap, frag.xy).g; out_col *= texture2DRect(lightMap, frag.xy).g;
if (dot(out_col, out_col) <= 0.0)
{
discard;
}
gl_FragColor.rgb = out_col; gl_FragColor.rgb = out_col;
gl_FragColor.a = 0.0; gl_FragColor.a = 0.0;
} }

View File

@@ -69,6 +69,11 @@ void main()
//attenuate point light contribution by SSAO component //attenuate point light contribution by SSAO component
col *= texture2DRect(lightMap, frag.xy).g; col *= texture2DRect(lightMap, frag.xy).g;
if (dot(col, col) <= 0.0)
{
discard;
}
gl_FragColor.rgb = col; gl_FragColor.rgb = col;
gl_FragColor.a = 0.0; gl_FragColor.a = 0.0;

View File

@@ -13,7 +13,7 @@ varying vec4 vary_position;
void main() void main()
{ {
vec4 col = texture2D(diffuseMap, gl_TexCoord[0].xy); 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[1] = vec4(0,0,0,0);
gl_FragData[2] = vec4(normalize(vary_normal), 0.0); gl_FragData[2] = vec4(normalize(vary_normal), 0.0);
gl_FragData[3] = vary_position; gl_FragData[3] = vary_position;

View File

@@ -5,6 +5,7 @@
* $License$ * $License$
*/ */
#extension GL_ARB_texture_rectangle : enable
vec3 scaleSoftClip(vec3 inColor); vec3 scaleSoftClip(vec3 inColor);
vec3 atmosTransport(vec3 inColor); vec3 atmosTransport(vec3 inColor);
@@ -32,6 +33,7 @@ uniform vec3 normScale;
uniform float fresnelScale; uniform float fresnelScale;
uniform float fresnelOffset; uniform float fresnelOffset;
uniform float blurMultiplier; uniform float blurMultiplier;
uniform mat4 norm_mat; //region space to screen space
//bigWave is (refCoord.w, view.w); //bigWave is (refCoord.w, view.w);
@@ -88,7 +90,7 @@ void main()
refcol *= df1 * 0.333; refcol *= df1 * 0.333;
vec3 wavef = (wave1 + wave2 * 0.4 + wave3 * 0.6) * 0.5; 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); wavef = normalize(wavef);
float df2 = dot(viewVec, wavef) * fresnelScale+fresnelOffset; float df2 = dot(viewVec, wavef) * fresnelScale+fresnelOffset;
@@ -101,10 +103,10 @@ void main()
refcol = mix(baseCol*df2, refcol, dweight); refcol = mix(baseCol*df2, refcol, dweight);
//get specular component //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 //harden specular
spec = pow(spec, 128.0); // spec = pow(spec, 128.0);
//figure out distortion vector (ripply) //figure out distortion vector (ripply)
vec2 distort2 = distort+wavef.xy*refScale/max(dmod*df1, 1.0); vec2 distort2 = distort+wavef.xy*refScale/max(dmod*df1, 1.0);
@@ -118,13 +120,13 @@ void main()
float shadow = 1.0; float shadow = 1.0;
vec4 pos = vary_position; 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; vec4 spos = pos;
if (pos.z < -shadow_clip.z) /* if (pos.z < -shadow_clip.z)
{ {
vec4 lpos = (shadow_matrix[3]*spos); vec4 lpos = (shadow_matrix[3]*spos);
shadow = shadow2DProj(shadowMap3, lpos).x; shadow = shadow2DProj(shadowMap3, lpos).x;
@@ -144,14 +146,19 @@ void main()
vec4 lpos = (shadow_matrix[0]*spos); vec4 lpos = (shadow_matrix[0]*spos);
shadow = shadow2DProj(shadowMap0, lpos).x; shadow = shadow2DProj(shadowMap0, lpos).x;
} }
} }*/
spec *= shadow; // spec *= shadow;
color.rgb += spec * specular; // color.rgb += spec * specular;
color.rgb = atmosTransport(color.rgb); color.rgb = atmosTransport(color.rgb);
color.rgb = scaleSoftClip(color.rgb); // color.rgb = scaleSoftClip(color.rgb);
color.a = spec * sunAngle2; // 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
} }

View File

@@ -90,22 +90,23 @@ void LLDrawPoolAlpha::beginDeferredPass(S32 pass)
void LLDrawPoolAlpha::endDeferredPass(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); LLFastTimer t(LLFastTimer::FTM_RENDER_GRASS);
gDeferredTreeProgram.bind(); gDeferredTreeProgram.bind();
LLGLEnable test(GL_ALPHA_TEST); LLGLEnable test(GL_ALPHA_TEST);
//render alpha masked objects //render alpha masked objects
LLRenderPass::renderTexture(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask()); LLRenderPass::renderTexture(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask());
gDeferredTreeProgram.unbind();
} }
gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
} }
void LLDrawPoolAlpha::renderDeferred(S32 pass)
{
}
S32 LLDrawPoolAlpha::getNumPostDeferredPasses() S32 LLDrawPoolAlpha::getNumPostDeferredPasses()
{ {

View File

@@ -263,7 +263,7 @@ void LLDrawPoolGrass::endDeferredPass(S32 pass)
void LLDrawPoolGrass::renderDeferred(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); LLFastTimer t(LLFastTimer::FTM_RENDER_GRASS);

View File

@@ -141,7 +141,7 @@ void LLDrawPoolTree::endRenderPass(S32 pass)
void LLDrawPoolTree::beginDeferredPass(S32 pass) void LLDrawPoolTree::beginDeferredPass(S32 pass)
{ {
LLFastTimer t(LLFastTimer::FTM_RENDER_TREES); LLFastTimer t(LLFastTimer::FTM_RENDER_TREES);
gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.f);
shader = &gDeferredTreeProgram; shader = &gDeferredTreeProgram;
shader->bind(); shader->bind();

View File

@@ -137,6 +137,19 @@ void LLDrawPoolWater::endPostDeferredPass(S32 pass)
deferred_render = FALSE; 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) void LLDrawPoolWater::render(S32 pass)
{ {
LLFastTimer ftm(LLFastTimer::FTM_RENDER_WATER); LLFastTimer ftm(LLFastTimer::FTM_RENDER_WATER);
@@ -338,7 +351,10 @@ void LLDrawPoolWater::renderReflection(LLFace* face)
void LLDrawPoolWater::shade() void LLDrawPoolWater::shade()
{ {
gGL.setColorMask(true, true); if (!deferred_render)
{
gGL.setColorMask(true, true);
}
LLVOSky *voskyp = gSky.mVOSkyp; LLVOSky *voskyp = gSky.mVOSkyp;
@@ -354,7 +370,7 @@ void LLDrawPoolWater::shade()
LLVector3 light_dir; LLVector3 light_dir;
LLColor3 light_color; 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 = gSky.getSunDirection();
light_dir.normVec(); light_dir.normVec();
@@ -388,11 +404,11 @@ void LLDrawPoolWater::shade()
F32 eyedepth = LLViewerCamera::getInstance()->getOrigin().mV[2] - gAgent.getRegion()->getWaterHeight(); F32 eyedepth = LLViewerCamera::getInstance()->getOrigin().mV[2] - gAgent.getRegion()->getWaterHeight();
if (deferred_render) if (eyedepth > 0.f && deferred_render)
{ {
shader = &gDeferredWaterProgram; shader = &gDeferredWaterProgram;
} }
else if (eyedepth < 0.f && LLPipeline::sWaterReflections) else if (eyedepth < 0.f /*&& LLPipeline::sWaterReflections*/)
{ {
shader = &gUnderWaterProgram; shader = &gUnderWaterProgram;
} }
@@ -401,6 +417,15 @@ void LLDrawPoolWater::shade()
shader = &gWaterProgram; shader = &gWaterProgram;
} }
if (deferred_render)
{
gPipeline.bindDeferredShader(*shader);
}
else
{
shader->bind();
}
sTime = (F32)LLFrameTimer::getElapsedSeconds()*0.5f; sTime = (F32)LLFrameTimer::getElapsedSeconds()*0.5f;
S32 reftex = shader->enableTexture(LLViewerShaderMgr::WATER_REFTEX); S32 reftex = shader->enableTexture(LLViewerShaderMgr::WATER_REFTEX);
@@ -436,15 +461,6 @@ void LLDrawPoolWater::shade()
S32 screentex = shader->enableTexture(LLViewerShaderMgr::WATER_SCREENTEX); S32 screentex = shader->enableTexture(LLViewerShaderMgr::WATER_SCREENTEX);
if (deferred_render)
{
gPipeline.bindDeferredShader(*shader);
}
else
{
shader->bind();
}
if (screentex > -1) if (screentex > -1)
{ {
shader->uniform4fv(LLViewerShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV); shader->uniform4fv(LLViewerShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV);
@@ -545,7 +561,7 @@ void LLDrawPoolWater::shade()
sNeedsDistortionUpdate = TRUE; sNeedsDistortionUpdate = TRUE;
face->renderIndexed(); face->renderIndexed();
} }
else if (gGLManager.mHasDepthClamp) else if (gGLManager.mHasDepthClamp || deferred_render)
{ {
face->renderIndexed(); face->renderIndexed();
} }
@@ -575,7 +591,10 @@ void LLDrawPoolWater::shade()
gGL.getTexUnit(0)->activate(); gGL.getTexUnit(0)->activate();
gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
gGL.setColorMask(true, false); if (!deferred_render)
{
gGL.setColorMask(true, false);
}
} }

View File

@@ -71,10 +71,12 @@ public:
/*virtual*/ LLDrawPool *instancePool(); /*virtual*/ LLDrawPool *instancePool();
static void restoreGL(); static void restoreGL();
/*virtual*/ S32 getNumPostDeferredPasses() { return getNumPasses(); } /*virtual*/ S32 getNumPostDeferredPasses() { return 0; } //getNumPasses(); }
/*virtual*/ void beginPostDeferredPass(S32 pass); /*virtual*/ void beginPostDeferredPass(S32 pass);
/*virtual*/ void endPostDeferredPass(S32 pass); /*virtual*/ void endPostDeferredPass(S32 pass);
/*virtual*/ void renderPostDeferred(S32 pass) { render(pass); } /*virtual*/ void renderPostDeferred(S32 pass) { render(pass); }
/*virtual*/ S32 getNumDeferredPasses() { return 1; }
/*virtual*/ void renderDeferred(S32 pass = 0);
/*virtual*/ S32 getNumPasses(); /*virtual*/ S32 getNumPasses();
/*virtual*/ void render(S32 pass = 0); /*virtual*/ void render(S32 pass = 0);

View File

@@ -293,9 +293,10 @@ void LLDrawPoolWLSky::render(S32 pass)
LLImageGL * tex = gSky.mVOSkyp->mFace[LLVOSky::FACE_MOON]->getTexture(); LLImageGL * tex = gSky.mVOSkyp->mFace[LLVOSky::FACE_MOON]->getTexture();
gGL.getTexUnit(0)->bind(tex); gGL.getTexUnit(0)->bind(tex);
renderHeavenlyBodies();
renderStars(); renderStars();
renderHeavenlyBodies();
glPopMatrix(); glPopMatrix();

View File

@@ -67,6 +67,9 @@ F32 elevation_from_vector(const LLVector3 &v);
LLSky gSky; LLSky gSky;
// ---------------- LLSky ---------------- // ---------------- LLSky ----------------
const F32 LLSky::NIGHTTIME_ELEVATION = -8.0f; // degrees
const F32 LLSky::NIGHTTIME_ELEVATION_COS = (F32)sin(NIGHTTIME_ELEVATION*DEG_TO_RAD);
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// Construction/Destruction // Construction/Destruction
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////

View File

@@ -42,9 +42,6 @@
#include "llvosky.h" #include "llvosky.h"
#include "llvoground.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 LLViewerCamera;
class LLVOWLSky; class LLVOWLSky;
@@ -111,6 +108,9 @@ public:
// Legacy stuff // Legacy stuff
LLVector3 mSunDefaultPosition; LLVector3 mSunDefaultPosition;
static const F32 NIGHTTIME_ELEVATION; // degrees
static const F32 NIGHTTIME_ELEVATION_COS;
protected: protected:
BOOL mOverrideSimSunPosition; BOOL mOverrideSimSunPosition;

View File

@@ -534,7 +534,7 @@ void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group)
return; return;
} }
if (/*!LLPipeline::sSkipUpdate && */group->changeLOD()) if (!LLPipeline::sSkipUpdate && group->changeLOD())
{ {
group->mLastUpdateDistance = group->mDistance; group->mLastUpdateDistance = group->mDistance;
group->mLastUpdateViewAngle = group->mViewAngle; group->mLastUpdateViewAngle = group->mViewAngle;
@@ -1397,7 +1397,6 @@ void LLSpatialGroup::checkOcclusion()
} }
else if (isOcclusionState(QUERY_PENDING)) else if (isOcclusionState(QUERY_PENDING))
{ //otherwise, if a query is pending, read it back { //otherwise, if a query is pending, read it back
LLFastTimer t(LLFastTimer::FTM_OCCLUSION_READBACK);
GLuint res = 1; GLuint res = 1;
if (!isOcclusionState(DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID]) if (!isOcclusionState(DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID])
{ {
@@ -1437,10 +1436,9 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera)
{ {
if (mSpatialPartition->isOcclusionEnabled() && LLPipeline::sUseOcclusion > 1) if (mSpatialPartition->isOcclusionEnabled() && LLPipeline::sUseOcclusion > 1)
{ {
static const LLCachedControl<BOOL> render_water_void_culling("RenderWaterVoidCulling", TRUE); //static const LLCachedControl<BOOL> 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. // 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 && if ((mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER && !gGLManager.mHasDepthClamp) ||
!(render_water_void_culling && gGLManager.mHasDepthClamp)) ||
earlyFail(camera, this)) earlyFail(camera, this))
{ {
setOcclusionState(LLSpatialGroup::DISCARD_QUERY); 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 // 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 // behind the far clip plane, and in the case of edge water to avoid
// it being culled while still visible. // it being culled while still visible.
bool const use_depth_clamp = bool const use_depth_clamp = gGLManager.mHasDepthClamp &&
gGLManager.mHasDepthClamp && (mSpatialPartition->mDrawableType == LLDrawPool::POOL_WATER ||
(mSpatialPartition->mDrawableType == LLPipeline::RENDER_TYPE_WATER || mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER);
mSpatialPartition->mDrawableType == LLPipeline::RENDER_TYPE_VOIDWATER);
if (use_depth_clamp) if (use_depth_clamp)
{ {
glEnable(GL_DEPTH_CLAMP); glEnable(GL_DEPTH_CLAMP);

View File

@@ -356,6 +356,15 @@ static bool handleRenderUseVBOChanged(const LLSD& newvalue)
return true; return true;
} }
static bool handleRenderUseVBOMappingChanged(const LLSD& newvalue)
{
if (gPipeline.isInit())
{
gPipeline.setDisableVBOMapping(newvalue.asBoolean());
}
return true;
}
static bool handleWLSkyDetailChanged(const LLSD&) static bool handleWLSkyDetailChanged(const LLSD&)
{ {
if (gSky.mVOWLSkyp.notNull()) if (gSky.mVOWLSkyp.notNull())
@@ -602,6 +611,7 @@ void settings_setup_listeners()
gSavedSettings.getControl("MuteAmbient")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1)); gSavedSettings.getControl("MuteAmbient")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1));
gSavedSettings.getControl("MuteUI")->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("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("WLSkyDetail")->getSignal()->connect(boost::bind(&handleWLSkyDetailChanged, _1));
gSavedSettings.getControl("RenderLightingDetail")->getSignal()->connect(boost::bind(&handleRenderLightingDetailChanged, _1)); gSavedSettings.getControl("RenderLightingDetail")->getSignal()->connect(boost::bind(&handleRenderLightingDetailChanged, _1));
gSavedSettings.getControl("NumpadControl")->getSignal()->connect(boost::bind(&handleNumpadControlChanged, _1)); gSavedSettings.getControl("NumpadControl")->getSignal()->connect(boost::bind(&handleNumpadControlChanged, _1));

View File

@@ -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 const F32 max_geom_update_time = 0.005f*10.f*gFrameIntervalSeconds; // 50 ms/second update time
gPipeline.createObjects(max_geom_update_time); gPipeline.createObjects(max_geom_update_time);
gPipeline.updateGeom(max_geom_update_time); gPipeline.updateGeom(max_geom_update_time);
gPipeline.updateGL();
stop_glerror(); stop_glerror();
gFrameStats.start(LLFrameStats::UPDATE_CULL); gFrameStats.start(LLFrameStats::UPDATE_CULL);
@@ -667,6 +668,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
LLGLState::checkClientArrays(); LLGLState::checkClientArrays();
static LLCullResult result; static LLCullResult result;
LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
gPipeline.updateCull(*LLViewerCamera::getInstance(), result, water_clip); gPipeline.updateCull(*LLViewerCamera::getInstance(), result, water_clip);
stop_glerror(); stop_glerror();
@@ -784,6 +786,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
// //
LLAppViewer::instance()->pingMainloopTimeout("Display:StateSort"); LLAppViewer::instance()->pingMainloopTimeout("Display:StateSort");
{ {
LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
gFrameStats.start(LLFrameStats::STATE_SORT); gFrameStats.start(LLFrameStats::STATE_SORT);
gPipeline.sAllowRebuildPriorityGroup = TRUE ; gPipeline.sAllowRebuildPriorityGroup = TRUE ;
gPipeline.stateSort(*LLViewerCamera::getInstance(), result); 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()) if (!(LLAppViewer::instance()->logoutRequestSent() && LLAppViewer::instance()->hasSavedFinalSnapshot())
&& !gRestoreGL) && !gRestoreGL)
{ {
LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
gGL.setColorMask(true, false); gGL.setColorMask(true, false);
if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender) if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender)
{ {
@@ -1366,6 +1369,12 @@ void render_disconnected_background()
gGL.color4f(1,1,1,1); gGL.color4f(1,1,1,1);
if (!gDisconnectedImagep && gDisconnected) if (!gDisconnectedImagep && gDisconnected)
{ {
//Default black image.
gDisconnectedImagep = new LLImageGL( FALSE );
LLPointer<LLImageRaw> raw = new LLImageRaw(1,1,3);
raw->clear();
gDisconnectedImagep->createGLTexture(0, raw, 0, TRUE, LLViewerImageBoostLevel::OTHER);
llinfos << "Loading last bitmap..." << llendl; llinfos << "Loading last bitmap..." << llendl;
std::string temp_str; std::string temp_str;
@@ -1378,8 +1387,6 @@ void render_disconnected_background()
return; return;
} }
gDisconnectedImagep = new LLImageGL( FALSE );
LLPointer<LLImageRaw> raw = new LLImageRaw;
if (!image_bmp->decode(raw, 0.0f)) if (!image_bmp->decode(raw, 0.0f))
{ {
llinfos << "Bitmap decode failed" << llendl; llinfos << "Bitmap decode failed" << llendl;

View File

@@ -456,7 +456,6 @@ void LLViewerObject::initVOClasses()
llinfos << "Viewer Object size: " << sizeof(LLViewerObject) << llendl; llinfos << "Viewer Object size: " << sizeof(LLViewerObject) << llendl;
LLVOGrass::initClass(); LLVOGrass::initClass();
LLVOWater::initClass(); LLVOWater::initClass();
LLVOSky::initClass();
LLVOVolume::initClass(); LLVOVolume::initClass();
} }

View File

@@ -127,7 +127,8 @@ LLGLSLShader gDeferredFullbrightProgram(LLViewerShaderMgr::SHADER_DEFERRED); /
GLint gAvatarMatrixParam; GLint gAvatarMatrixParam;
LLViewerShaderMgr::LLViewerShaderMgr() : LLViewerShaderMgr::LLViewerShaderMgr() :
mVertexShaderLevel(SHADER_COUNT, 0) mVertexShaderLevel(SHADER_COUNT, 0),
mMaxAvatarShaderLevel(0)
{} {}
LLViewerShaderMgr::~LLViewerShaderMgr() LLViewerShaderMgr::~LLViewerShaderMgr()
@@ -253,11 +254,16 @@ S32 LLViewerShaderMgr::getVertexShaderLevel(S32 type)
void LLViewerShaderMgr::setShaders() 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; return;
} }
reentrance = true;
initAttribsAndUniforms(); initAttribsAndUniforms();
gPipeline.releaseGLBuffers(); gPipeline.releaseGLBuffers();
@@ -269,8 +275,8 @@ void LLViewerShaderMgr::setShaders()
} }
else else
{ {
LLPipeline::sRenderGlow = LLPipeline::sRenderGlow = FALSE;
LLPipeline::sWaterReflections = FALSE; LLPipeline::sWaterReflections = FALSE;
} }
//hack to reset buffers that change behavior with shaders //hack to reset buffers that change behavior with shaders
@@ -302,6 +308,21 @@ void LLViewerShaderMgr::setShaders()
S32 wl_class = 2; S32 wl_class = 2;
S32 water_class = 2; S32 water_class = 2;
S32 deferred_class = 0; 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") if (!(LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders")
&& gSavedSettings.getBOOL("WindLightUseAtmosShaders"))) && gSavedSettings.getBOOL("WindLightUseAtmosShaders")))
{ {
@@ -310,11 +331,6 @@ void LLViewerShaderMgr::setShaders()
wl_class = 1; wl_class = 1;
} }
if (LLPipeline::sRenderDeferred)
{
deferred_class = 1;
}
if(!gSavedSettings.getBOOL("EnableRippleWater")) if(!gSavedSettings.getBOOL("EnableRippleWater"))
{ {
water_class = 0; water_class = 0;
@@ -428,6 +444,7 @@ void LLViewerShaderMgr::setShaders()
gViewerWindow->setCursor(UI_CURSOR_ARROW); gViewerWindow->setCursor(UI_CURSOR_ARROW);
} }
gPipeline.createGLBuffers(); gPipeline.createGLBuffers();
reentrance = false;
} }
void LLViewerShaderMgr::unloadShaders() void LLViewerShaderMgr::unloadShaders()

View File

@@ -1544,7 +1544,7 @@ LLViewerWindow::LLViewerWindow(
{ {
gSavedSettings.setBOOL("RenderVBOEnable", FALSE); gSavedSettings.setBOOL("RenderVBOEnable", FALSE);
} }
LLVertexBuffer::initClass(gSavedSettings.getBOOL("RenderVBOEnable")); LLVertexBuffer::initClass(gSavedSettings.getBOOL("RenderVBOEnable"), gSavedSettings.getBOOL("RenderVBOMappingDisable"));
if (LLFeatureManager::getInstance()->isSafe() if (LLFeatureManager::getInstance()->isSafe()
|| (gSavedSettings.getS32("LastFeatureVersion") != LLFeatureManager::getInstance()->getVersion()) || (gSavedSettings.getS32("LastFeatureVersion") != LLFeatureManager::getInstance()->getVersion())

View File

@@ -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 TEX10 = LLVector2(1.f, 0.f);
static const LLVector2 TEX11 = LLVector2(1.f, 1.f); static const LLVector2 TEX11 = LLVector2(1.f, 1.f);
// Exported global semi-constants. // Exported globals
LLUUID gSunTextureID = IMG_SUN; LLUUID gSunTextureID = IMG_SUN;
LLUUID gMoonTextureID = IMG_MOON; 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 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); mBloomTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
mHeavenlyBodyUpdated = FALSE ; mHeavenlyBodyUpdated = FALSE ;
mDrawRefl = 0;
mHazeConcentration = 0.f;
mInterpVal = 0.f;
} }
LLVOSky::~LLVOSky() 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 // This needs to be done for each texture
mCubeMap = NULL; mCubeMap = NULL;
} }
void LLVOSky::initClass()
{
LLHaze::initClass();
}
void LLVOSky::init() void LLVOSky::init()
{ {
@@ -969,7 +978,7 @@ void LLVOSky::calcAtmospherics(void)
// and vary_sunlight will work properly with moon light // and vary_sunlight will work properly with moon light
F32 lighty = unclamped_lightnorm[1]; F32 lighty = unclamped_lightnorm[1];
if(lighty < NIGHTTIME_ELEVATION_COS) if(lighty < LLSky::NIGHTTIME_ELEVATION_COS)
{ {
lighty = -lighty; lighty = -lighty;
} }
@@ -1080,10 +1089,10 @@ BOOL LLVOSky::updateSky()
++next_frame; ++next_frame;
next_frame = next_frame % cycle_frame_no; 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; // sInterpVal = (F32)next_frame / cycle_frame_no;
LLSkyTex::setInterpVal( sInterpVal ); LLSkyTex::setInterpVal( mInterpVal );
LLHeavenBody::setInterpVal( sInterpVal ); LLHeavenBody::setInterpVal( mInterpVal );
calcAtmospherics(); calcAtmospherics();
if (mForceUpdate || total_no_tiles == frame) if (mForceUpdate || total_no_tiles == frame)
@@ -2151,17 +2160,8 @@ void LLVOSky::updateFog(const F32 distance)
stop_glerror(); stop_glerror();
} }
// static
void LLHaze::initClass()
{
sAirScaSeaLevel = LLHaze::calcAirScaSeaLevel();
}
// Functions used a lot. // Functions used a lot.
F32 color_norm_pow(LLColor3& col, F32 e, BOOL postmultiply) F32 color_norm_pow(LLColor3& col, F32 e, BOOL postmultiply)
{ {
F32 mv = color_max(col); F32 mv = color_max(col);

View File

@@ -147,8 +147,8 @@ protected:
static S32 getResolution() { return sResolution; } static S32 getResolution() { return sResolution; }
static S32 getCurrent() { return sCurrent; } static S32 getCurrent() { return sCurrent; }
static S32 stepCurrent() { sCurrent++; sCurrent&=1; return sCurrent; } static S32 stepCurrent() { sCurrent++; sCurrent &= 1; return sCurrent; }
static S32 getNext() { return ((sCurrent+1) % 2); } static S32 getNext() { return ((sCurrent+1) & 1); }
static S32 getWhich(const BOOL curr) { return curr ? sCurrent : getNext(); } static S32 getWhich(const BOOL curr) { return curr ? sCurrent : getNext(); }
void initEmpty(const S32 tex); 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 class LLHaze
{ {
public: public:
@@ -323,18 +305,15 @@ public:
LLHaze(const F32 g, const LLColor3& sca, const F32 fo = 2.f) : 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) 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), 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) 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; } F32 getG() const { return mG; }
void setG(const F32 g) void setG(const F32 g)
@@ -350,12 +329,12 @@ public:
void setSigSca(const LLColor3& s) void setSigSca(const LLColor3& s)
{ {
mSigSca = 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) 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; mAbsCoef = 0.01f * (s0 + s1 + s2) / 3;
} }
@@ -399,10 +378,11 @@ public:
static inline LLColor3 calcAirSca(const F32 h); static inline LLColor3 calcAirSca(const F32 h);
static inline void calcAirSca(const F32 h, LLColor3 &result); static inline void calcAirSca(const F32 h, LLColor3 &result);
static LLColor3 calcAirScaSeaLevel() { return gAirScaSeaLevel; }
static const LLColor3 &getAirScaSeaLevel() { return sAirScaSeaLevel; } private:
public: static LLColor3 const sAirScaSeaLevel;
static LLColor3 sAirScaSeaLevel; static F32 const sAirScaIntense;
static F32 const sAirScaAvg;
protected: protected:
F32 mG; F32 mG;
@@ -480,7 +460,6 @@ public:
LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp); LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp);
// Initialize/delete data that's only inited once per class. // Initialize/delete data that's only inited once per class.
static void initClass();
void init(); void init();
void initCubeMap(); void initCubeMap();
void initEmpty(); void initEmpty();
@@ -614,7 +593,7 @@ protected:
LLColor3 mLastTotalAmbient; LLColor3 mLastTotalAmbient;
F32 mAmbientScale; F32 mAmbientScale;
LLColor3 mNightColorShift; LLColor3 mNightColorShift;
F32 sInterpVal; F32 mInterpVal;
LLColor4 mFogColor; LLColor4 mFogColor;
LLColor4 mGLFogCol; LLColor4 mGLFogCol;
@@ -661,14 +640,12 @@ F32 color_norm_pow(LLColor3& col, F32 e, BOOL postmultiply = FALSE);
inline LLColor3 LLHaze::calcAirSca(const F32 h) inline LLColor3 LLHaze::calcAirSca(const F32 h)
{ {
static const LLColor3 air_sca_sea_level = calcAirScaSeaLevel(); return calcFalloff(h) * sAirScaSeaLevel;
return calcFalloff(h) * air_sca_sea_level;
} }
inline void LLHaze::calcAirSca(const F32 h, LLColor3 &result) inline void LLHaze::calcAirSca(const F32 h, LLColor3 &result)
{ {
static const LLColor3 air_sca_sea_level = calcAirScaSeaLevel(); result = sAirScaSeaLevel;
result = air_sca_sea_level;
result *= calcFalloff(h); result *= calcFalloff(h);
} }

View File

@@ -49,12 +49,12 @@ const U32 LLVOWLSky::MAX_SKY_DETAIL = 180;
inline U32 LLVOWLSky::getNumStacks(void) 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) 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) inline U32 LLVOWLSky::getFanNumVerts(void)
@@ -489,7 +489,7 @@ void LLVOWLSky::drawStars(void)
if (mStarsVerts.notNull()) if (mStarsVerts.notNull())
{ {
mStarsVerts->setBuffer(LLDrawPoolWLSky::STAR_VERTEX_DATA_MASK); 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<LLVector3> verticesp; LLStrider<LLVector3> verticesp;
LLStrider<LLColor4U> colorsp; LLStrider<LLColor4U> colorsp;
LLStrider<U16> indicesp; LLStrider<LLVector2> texcoordsp;
if (mStarsVerts.isNull()) if (mStarsVerts.isNull())
{ {
mStarsVerts = new LLVertexBuffer(LLDrawPoolWLSky::STAR_VERTEX_DATA_MASK, GL_DYNAMIC_DRAW); 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) BOOL success = mStarsVerts->getVertexStrider(verticesp)
&& mStarsVerts->getIndexStrider(indicesp) && mStarsVerts->getColorStrider(colorsp)
&& mStarsVerts->getColorStrider(colorsp); && mStarsVerts->getTexCoord0Strider(texcoordsp);
if(!success) if(!success)
{ {
@@ -789,11 +789,37 @@ BOOL LLVOWLSky::updateStarGeometry(LLDrawable *drawable)
// *TODO: fix LLStrider with a real prefix increment operator so it can be // *TODO: fix LLStrider with a real prefix increment operator so it can be
// used as a model of OutputIterator. -Brad // used as a model of OutputIterator. -Brad
// std::copy(mStarVertices.begin(), mStarVertices.end(), verticesp); // std::copy(mStarVertices.begin(), mStarVertices.end(), verticesp);
if (mStarVertices.size() < getStarsNumVerts())
{
llerrs << "Star reference geometry insufficient." << llendl;
}
for (U32 vtx = 0; vtx < getStarsNumVerts(); ++vtx) 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];
*(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]); *(colorsp++) = LLColor4U(mStarColors[vtx]);
*(indicesp++) = vtx;
} }
mStarsVerts->setBuffer(0); mStarsVerts->setBuffer(0);

View File

@@ -301,7 +301,7 @@ void LLWaterParamManager::update(LLViewerCamera * cam)
mWaterPlane = LLVector4(enorm.v[0], enorm.v[1], enorm.v[2], -ep.dot(enorm)); mWaterPlane = LLVector4(enorm.v[0], enorm.v[1], enorm.v[2], -ep.dot(enorm));
LLVector3 sunMoonDir; LLVector3 sunMoonDir;
if (gSky.getSunDirection().mV[2] > NIGHTTIME_ELEVATION_COS) if (gSky.getSunDirection().mV[2] > LLSky::NIGHTTIME_ELEVATION_COS)
{ {
sunMoonDir = gSky.getSunDirection(); sunMoonDir = gSky.getSunDirection();
} }

View File

@@ -315,7 +315,7 @@ void LLWLParamManager::propagateParameters(void)
{ {
mLightDir = sunDir; 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 // 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]); LLVector3 vec(sunDir.mV[0], sunDir.mV[1], sunDir.mV[2]);

View File

@@ -2114,7 +2114,7 @@ void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera)
void LLPipeline::stateSort(LLSpatialBridge* bridge, LLCamera& camera) void LLPipeline::stateSort(LLSpatialBridge* bridge, LLCamera& camera)
{ {
LLMemType mt(LLMemType::MTYPE_PIPELINE); LLMemType mt(LLMemType::MTYPE_PIPELINE);
if (!sSkipUpdate && bridge->getSpatialGroup()->changeLOD()) if (!sShadowRender && !sSkipUpdate && bridge->getSpatialGroup()->changeLOD())
{ {
bool force_update = false; bool force_update = false;
bridge->updateDistance(camera, force_update); bridge->updateDistance(camera, force_update);
@@ -2181,7 +2181,7 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera)
LLSpatialGroup* group = drawablep->getSpatialGroup(); LLSpatialGroup* group = drawablep->getSpatialGroup();
if (!group || group->changeLOD()) if (!group || group->changeLOD())
{ {
if (drawablep->isVisible()) if (drawablep->isVisible() && !sSkipUpdate)
{ {
if (!drawablep->isActive()) 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) for (LLSpatialGroup::draw_map_t::iterator j = group->mDrawMap.begin(); j != group->mDrawMap.end(); ++j)
{ {
LLSpatialGroup::drawmap_elem_t& src_vec = j->second; LLSpatialGroup::drawmap_elem_t& src_vec = j->second;
if (!hasRenderType(j->first)) //No worky yet. if (!hasRenderType(j->first))
{ {
continue; 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; 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; backlight_mag = BACKLIGHT_DAY_MAGNITUDE_OBJECT;
} }
@@ -4172,7 +4172,7 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
// Light 0 = Sun or Moon (All objects) // 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()); mSunDir.setVec(gSky.getSunDirection());
mSunDiffuse.setVec(gSky.getSunDiffuseColor()); mSunDiffuse.setVec(gSky.getSunDiffuseColor());
@@ -4438,10 +4438,10 @@ void LLPipeline::enableLightsFullbright(const LLColor4& color)
enableLights(mask); enableLights(mask);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT,color.mV); 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 glColor4f(0.f, 0.f, 0.f, 1.f); // no local lighting by default
} }*/
} }
void LLPipeline::disableLights() void LLPipeline::disableLights()
@@ -5149,7 +5149,25 @@ void LLPipeline::setUseVBO(BOOL use_vbo)
} }
resetVertexBuffers(); 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.uniform2f("screen_res", mDeferredScreen.getWidth(), mDeferredScreen.getHeight());
shader.uniform1f("near_clip", LLViewerCamera::getInstance()->getNear()*2.f); shader.uniform1f("near_clip", LLViewerCamera::getInstance()->getNear()*2.f);
shader.uniform1f("alpha_soften", render_deferred_alpha_soft); 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() void LLPipeline::renderDeferredLighting()
@@ -5677,6 +5700,7 @@ void LLPipeline::renderDeferredLighting()
return; return;
} }
LLViewerCamera* camera = LLViewerCamera::getInstance();
LLGLEnable multisample(GL_MULTISAMPLE_ARB); LLGLEnable multisample(GL_MULTISAMPLE_ARB);
if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD))
@@ -5691,15 +5715,13 @@ void LLPipeline::renderDeferredLighting()
gGL.setColorMask(true, true); gGL.setColorMask(true, true);
mDeferredLight[0].bindTarget();
//mDeferredLight[0].copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(), //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); // 0, 0, mDeferredLight[0].getWidth(), mDeferredLight[0].getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
//draw a cube around every light //draw a cube around every light
LLVertexBuffer::unbind(); LLVertexBuffer::unbind();
glBlendFunc(GL_ONE, GL_ONE); //glBlendFunc(GL_ONE, GL_ONE);
LLGLEnable cull(GL_CULL_FACE); LLGLEnable cull(GL_CULL_FACE);
LLGLEnable blend(GL_BLEND); LLGLEnable blend(GL_BLEND);
@@ -5711,126 +5733,130 @@ void LLPipeline::renderDeferredLighting()
-1,-3, -1,-3,
3,1, 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++) setupHWLights(NULL); //to set mSunDir;
{ LLVector4 dir(mSunDir, 0.f);
glh::vec3f v; glh::vec4f tc(dir.mV);
v.set_value(sinf(6.284f/8*j), cosf(6.284f/8*j), -(F32) i); mat.mult_matrix_vec(tc);
v.normalize(); glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], 0);
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());
setupHWLights(NULL); //to set mSunDir;
glPushMatrix(); glPushMatrix();
glLoadIdentity(); glLoadIdentity();
glMatrixMode(GL_PROJECTION); glMatrixMode(GL_PROJECTION);
glPushMatrix(); glPushMatrix();
glLoadIdentity(); 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(); mDeferredLight[0].bindTarget();
gDeferredBlurLightProgram.uniform2f("delta", 0.f, 1.f); //Sun shadows.
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); bindDeferredShader(gDeferredSunProgram);
LLGLDepthTest depth(GL_FALSE);
stop_glerror(); glh::matrix4f inv_trans = glh_get_current_modelview().inverse().transpose();
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
stop_glerror(); 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(); 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(); stop_glerror();
glPopMatrix(); glPopMatrix();
@@ -5845,6 +5871,8 @@ void LLPipeline::renderDeferredLighting()
// 0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); // 0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
mScreen.bindTarget(); 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); mScreen.clear(GL_COLOR_BUFFER_BIT);
bindDeferredShader(gDeferredSoftenProgram); bindDeferredShader(gDeferredSoftenProgram);
@@ -5871,7 +5899,23 @@ void LLPipeline::renderDeferredLighting()
unbindDeferredShader(gDeferredSoftenProgram); 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<LLVector4> fullscreen_lights; std::list<LLVector4> fullscreen_lights;
std::list<LLVector4> light_colors; std::list<LLVector4> light_colors;
@@ -5879,6 +5923,7 @@ void LLPipeline::renderDeferredLighting()
F32 v[24]; F32 v[24];
glVertexPointer(3, GL_FLOAT, 0, v); glVertexPointer(3, GL_FLOAT, 0, v);
{ {
bindDeferredShader(gDeferredLightProgram);
LLGLDepthTest depth(GL_TRUE, GL_FALSE); LLGLDepthTest depth(GL_TRUE, GL_FALSE);
for (LLDrawable::drawable_set_t::iterator iter = mLights.begin(); iter != mLights.end(); ++iter) for (LLDrawable::drawable_set_t::iterator iter = mLights.begin(); iter != mLights.end(); ++iter)
{ {
@@ -5890,22 +5935,42 @@ void LLPipeline::renderDeferredLighting()
continue; continue;
} }
if (volume->isAttachment())
{
if (!sRenderAttachedLights)
{
continue;
}
}
LLVector3 center = drawablep->getPositionAgent(); LLVector3 center = drawablep->getPositionAgent();
F32* c = center.mV; F32* c = center.mV;
F32 s = volume->getLightRadius()*1.5f; 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; continue;
} }
sVisibleLightCount++; sVisibleLightCount++;
glh::vec3f tc(c); glh::vec3f tc(c);
mat.mult_matrix_vec(tc); mat.mult_matrix_vec(tc);
LLColor3 col = volume->getLightColor();
col *= volume->getLightIntensity();
//vertex positions are encoded so the 3 bits of their vertex index //vertex positions are encoded so the 3 bits of their vertex index
//correspond to their axis facing, with bit position 3,2,1 matching //correspond to their axis facing, with bit position 3,2,1 matching
//axis facing x,y,z, bit set meaning positive facing, bit clear //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[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 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 || if (camera->getOrigin().mV[0] > c[0] + s + 0.2f ||
LLViewerCamera::getInstance()->getOrigin().mV[0] < c[0] - s - 0.2f || camera->getOrigin().mV[0] < c[0] - s - 0.2f ||
LLViewerCamera::getInstance()->getOrigin().mV[1] > c[1] + s + 0.2f || camera->getOrigin().mV[1] > c[1] + s + 0.2f ||
LLViewerCamera::getInstance()->getOrigin().mV[1] < c[1] - s - 0.2f || camera->getOrigin().mV[1] < c[1] - s - 0.2f ||
LLViewerCamera::getInstance()->getOrigin().mV[2] > c[2] + s + 0.2f || camera->getOrigin().mV[2] > c[2] + s + 0.2f ||
LLViewerCamera::getInstance()->getOrigin().mV[2] < c[2] - s - 0.2f) camera->getOrigin().mV[2] < c[2] - s - 0.2f)
{ //draw box if camera is outside box { //draw box if camera is outside box
glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s); 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); glColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f);
glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, 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 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)); 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()) if (!fullscreen_lights.empty())
{ {
@@ -5956,8 +6022,9 @@ void LLPipeline::renderDeferredLighting()
U32 count = 0; U32 count = 0;
LLVector4 light[16]; const U32 max_count = 16;
LLVector4 col[16]; LLVector4 light[max_count];
LLVector4 col[max_count];
glVertexPointer(2, GL_FLOAT, 0, vert); glVertexPointer(2, GL_FLOAT, 0, vert);
@@ -5967,9 +6034,9 @@ void LLPipeline::renderDeferredLighting()
fullscreen_lights.pop_front(); fullscreen_lights.pop_front();
col[count] = light_colors.front(); col[count] = light_colors.front();
light_colors.pop_front(); light_colors.pop_front();
count++; count++;
if (count == 16 || fullscreen_lights.empty())
if (count == max_count || fullscreen_lights.empty())
{ {
gDeferredMultiLightProgram.uniform1i("light_count", count); gDeferredMultiLightProgram.uniform1i("light_count", count);
gDeferredMultiLightProgram.uniform4fv("light[0]", count, (GLfloat*) light); gDeferredMultiLightProgram.uniform4fv("light[0]", count, (GLfloat*) light);
@@ -5978,19 +6045,16 @@ void LLPipeline::renderDeferredLighting()
gDeferredMultiLightProgram.uniform4fv("light_col", count, (GLfloat*) col); gDeferredMultiLightProgram.uniform4fv("light_col", count, (GLfloat*) col);
count = 0; count = 0;
glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
} }
} }
glPopMatrix(); glPopMatrix();
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
glPopMatrix(); glPopMatrix();
unbindDeferredShader(gDeferredMultiLightProgram); unbindDeferredShader(gDeferredMultiLightProgram);
} }
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
{ //render non-deferred geometry { //render non-deferred geometry
LLGLDisable blend(GL_BLEND); LLGLDisable blend(GL_BLEND);
@@ -6212,7 +6276,8 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
} }
} }
} }
static LLCachedControl<bool> skip_distortion_updates("SkipReflectOcclusionUpdates",false);
LLPipeline::sSkipUpdate = skip_distortion_updates;
LLGLUserClipPlane clip_plane(plane, mat, projection); LLGLUserClipPlane clip_plane(plane, mat, projection);
LLGLDisable cull(GL_CULL_FACE); LLGLDisable cull(GL_CULL_FACE);
updateCull(camera, ref_result, 1); updateCull(camera, ref_result, 1);
@@ -6221,6 +6286,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
gPipeline.grabReferences(ref_result); gPipeline.grabReferences(ref_result);
LLGLUserClipPlane clip_plane(plane, mat, projection); LLGLUserClipPlane clip_plane(plane, mat, projection);
renderGeom(camera); renderGeom(camera);
LLPipeline::sSkipUpdate = FALSE;
} }
} }
gPipeline.popRenderTypeMask(); gPipeline.popRenderTypeMask();
@@ -6381,7 +6447,6 @@ glh::matrix4f scale_translate_to_fit(const LLVector3 min, const LLVector3 max)
void LLPipeline::generateSunShadow(LLCamera& camera) void LLPipeline::generateSunShadow(LLCamera& camera)
{ {
if (!sRenderDeferred) if (!sRenderDeferred)
{ {
return; return;
@@ -6896,6 +6961,10 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); 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); LLGLEnable scissor(GL_SCISSOR_TEST);
glScissor(0, 0, resX, resY); glScissor(0, 0, resX, resY);
@@ -6903,15 +6972,11 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
avatar->mImpostor.clear(); avatar->mImpostor.clear();
} }
LLGLEnable stencil(GL_STENCIL_TEST);
glStencilFunc(GL_ALWAYS, 1, 0xFFFFFFFF);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
if (LLPipeline::sRenderDeferred) if (LLPipeline::sRenderDeferred)
{ {
stop_glerror(); stop_glerror();
renderGeomDeferred(camera); renderGeomDeferred(camera);
renderGeomPostDeferred(camera);
} }
else else
{ {
@@ -6921,11 +6986,18 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
glStencilFunc(GL_EQUAL, 1, 0xFFFFFF); glStencilFunc(GL_EQUAL, 1, 0xFFFFFF);
if (!sRenderDeferred || muted) //if (!sRenderDeferred || muted)
{ {
LLVector3 left = camera.getLeftAxis()*tdim.mV[0]*2.f; LLVector3 left = camera.getLeftAxis()*tdim.mV[0]*2.f;
LLVector3 up = camera.getUpAxis()*tdim.mV[1]*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); LLGLEnable blend(muted ? 0 : GL_BLEND);
if (muted) if (muted)

View File

@@ -96,6 +96,7 @@ public:
void resetVertexBuffers(LLDrawable* drawable); void resetVertexBuffers(LLDrawable* drawable);
void setUseVBO(BOOL use_vbo); void setUseVBO(BOOL use_vbo);
void setDisableVBOMapping(BOOL no_vbo_mapping);
void generateImpostor(LLVOAvatar* avatar); void generateImpostor(LLVOAvatar* avatar);
void bindScreenToTexture(); void bindScreenToTexture();
void renderBloom(BOOL for_snapshot, F32 zoom_factor = 1.f, int subfield = 0); void renderBloom(BOOL for_snapshot, F32 zoom_factor = 1.f, int subfield = 0);