This commit is contained in:
Shyotl
2012-01-26 16:09:47 -06:00
parent f9d802f832
commit afed6dad84
15 changed files with 321 additions and 212 deletions

View File

@@ -73,10 +73,23 @@ BOOL shouldChange(const LLVector4& v1, const LLVector4& v2)
} }
LLShaderFeatures::LLShaderFeatures() LLShaderFeatures::LLShaderFeatures()
: calculatesLighting(false), isShiny(false), isFullbright(false), hasWaterFog(false), : atmosphericHelpers(false)
hasTransport(false), hasSkinning(false), hasObjectSkinning(false), hasAtmospherics(false), isSpecular(false), , calculatesLighting(false)
hasGamma(false), hasLighting(false), isAlphaLighting(false), calculatesAtmospherics(false), mIndexedTextureChannels(0), disableTextureIndex(false), , calculatesAtmospherics(false)
hasAlphaMask(false) , hasLighting(false)
, isAlphaLighting(false)
, isShiny(false)
, isFullbright(false)
, isSpecular(false)
, hasWaterFog(false)
, hasTransport(false)
, hasSkinning(false)
, hasObjectSkinning(false)
, hasAtmospherics(false)
, hasGamma(false)
, mIndexedTextureChannels(0)
, disableTextureIndex(false)
, hasAlphaMask(false)
{ {
} }

View File

@@ -39,10 +39,11 @@
class LLShaderFeatures class LLShaderFeatures
{ {
public: public:
bool atmosphericHelpers;
bool calculatesLighting; bool calculatesLighting;
bool calculatesAtmospherics; bool calculatesAtmospherics;
bool hasLighting; // implies no transport (it's possible to have neither though) bool hasLighting; // implies no transport (it's possible to have neither though)
bool isAlphaLighting; // indicates lighting shaders need not be linked in (lighting performed directly in alpha shader to match deferred lighting functions bool isAlphaLighting; // indicates lighting shaders need not be linked in (lighting performed directly in alpha shader to match deferred lighting functions)
bool isShiny; bool isShiny;
bool isFullbright; // implies no lighting bool isFullbright; // implies no lighting
bool isSpecular; bool isSpecular;

View File

@@ -96,13 +96,16 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
} }
} }
if (features->calculatesLighting) if (features->calculatesLighting || features->atmosphericHelpers)
{ {
if (!shader->attachObject("windlight/atmosphericsHelpersV.glsl")) if (!shader->attachObject("windlight/atmosphericsHelpersV.glsl"))
{ {
return FALSE; return FALSE;
} }
}
if (features->calculatesLighting)
{
if (features->isSpecular) if (features->isSpecular)
{ {
if (!shader->attachObject("lighting/lightFuncSpecularV.glsl")) if (!shader->attachObject("lighting/lightFuncSpecularV.glsl"))
@@ -116,7 +119,6 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
{ {
return FALSE; return FALSE;
} }
} }
if (!shader->attachObject("lighting/lightSpecularV.glsl")) if (!shader->attachObject("lighting/lightSpecularV.glsl"))

View File

@@ -55,10 +55,10 @@ U32 nhpo2(U32 v)
//============================================================================ //============================================================================
//static //static
LLVBOPool LLVertexBuffer::sStreamVBOPool; LLVBOPool LLVertexBuffer::sStreamVBOPool(GL_STREAM_DRAW_ARB, GL_ARRAY_BUFFER_ARB);
LLVBOPool LLVertexBuffer::sDynamicVBOPool; LLVBOPool LLVertexBuffer::sDynamicVBOPool(GL_DYNAMIC_DRAW_ARB, GL_ARRAY_BUFFER_ARB);
LLVBOPool LLVertexBuffer::sStreamIBOPool; LLVBOPool LLVertexBuffer::sStreamIBOPool(GL_STREAM_DRAW_ARB, GL_ELEMENT_ARRAY_BUFFER_ARB);
LLVBOPool LLVertexBuffer::sDynamicIBOPool; LLVBOPool LLVertexBuffer::sDynamicIBOPool(GL_DYNAMIC_DRAW_ARB, GL_ELEMENT_ARRAY_BUFFER_ARB);
U32 LLVBOPool::sBytesPooled = 0; U32 LLVBOPool::sBytesPooled = 0;
LLPrivateMemoryPool* LLVertexBuffer::sPrivatePoolp = NULL ; LLPrivateMemoryPool* LLVertexBuffer::sPrivatePoolp = NULL ;
@@ -67,19 +67,19 @@ 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::sDisableVBOMapping = false;
BOOL LLVertexBuffer::sEnableVBOs = TRUE; bool LLVertexBuffer::sEnableVBOs = true;
U32 LLVertexBuffer::sGLRenderBuffer = 0; U32 LLVertexBuffer::sGLRenderBuffer = 0;
U32 LLVertexBuffer::sGLRenderArray = 0; U32 LLVertexBuffer::sGLRenderArray = 0;
U32 LLVertexBuffer::sGLRenderIndices = 0; U32 LLVertexBuffer::sGLRenderIndices = 0;
U32 LLVertexBuffer::sLastMask = 0; U32 LLVertexBuffer::sLastMask = 0;
BOOL LLVertexBuffer::sVBOActive = FALSE; bool LLVertexBuffer::sVBOActive = false;
BOOL LLVertexBuffer::sIBOActive = FALSE; bool LLVertexBuffer::sIBOActive = false;
U32 LLVertexBuffer::sAllocatedBytes = 0; U32 LLVertexBuffer::sAllocatedBytes = 0;
BOOL LLVertexBuffer::sMapped = FALSE; bool LLVertexBuffer::sMapped = false;
BOOL LLVertexBuffer::sUseStreamDraw = TRUE; bool LLVertexBuffer::sUseStreamDraw = true;
BOOL LLVertexBuffer::sUseVAO = FALSE; bool LLVertexBuffer::sUseVAO = false;
BOOL LLVertexBuffer::sPreferStreamDraw = FALSE; bool LLVertexBuffer::sPreferStreamDraw = false;
const U32 FENCE_WAIT_TIME_NANOSECONDS = 10000; //1 ms const U32 FENCE_WAIT_TIME_NANOSECONDS = 10000; //1 ms
@@ -206,7 +206,7 @@ void LLVBOPool::release(U32 name, volatile U8* buffer, U32 size)
rec.mGLName = name; rec.mGLName = name;
rec.mClientData = buffer; rec.mClientData = buffer;
if (!LLVertexBuffer::sDisableVBOMapping && mUsage == GL_DYNAMIC_DRAW_ARB) if (buffer == NULL)
{ {
glDeleteBuffersARB(1, &rec.mGLName); glDeleteBuffersARB(1, &rec.mGLName);
} }
@@ -283,7 +283,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
{ {
if (sLastMask != data_mask) if (sLastMask != data_mask)
{ {
BOOL error = FALSE; bool error = false;
if (LLGLSLShader::sNoFixedFunction) if (LLGLSLShader::sNoFixedFunction)
{ {
@@ -344,7 +344,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
{ {
if (gDebugSession) if (gDebugSession)
{ {
error = TRUE; error = true;
gFailLog << "Bad client state! " << array[i] << " disabled." << std::endl; gFailLog << "Bad client state! " << array[i] << " disabled." << std::endl;
} }
else else
@@ -364,7 +364,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
{ //needs to be disabled, make sure it was (DEBUG TEMPORARY) { //needs to be disabled, make sure it was (DEBUG TEMPORARY)
if (gDebugSession) if (gDebugSession)
{ {
error = TRUE; error = true;
gFailLog << "Bad client state! " << array[i] << " enabled." << std::endl; gFailLog << "Bad client state! " << array[i] << " enabled." << std::endl;
} }
else else
@@ -548,7 +548,7 @@ void LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_of
void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const
{ {
validateRange(start, end, count, indices_offset); validateRange(start, end, count, indices_offset);
mMappable = FALSE; mMappable = false;
gGL.syncMatrices(); gGL.syncMatrices();
llassert(mNumVerts >= 0); llassert(mNumVerts >= 0);
@@ -603,7 +603,7 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi
void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
{ {
llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL); llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
mMappable = FALSE; mMappable = false;
gGL.syncMatrices(); gGL.syncMatrices();
llassert(mNumIndices >= 0); llassert(mNumIndices >= 0);
@@ -649,7 +649,7 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
{ {
llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL); llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
mMappable = FALSE; mMappable = false;
gGL.syncMatrices(); gGL.syncMatrices();
llassert(mNumVerts >= 0); llassert(mNumVerts >= 0);
@@ -692,20 +692,10 @@ void LLVertexBuffer::initClass(bool use_vbo, bool no_vbo_mapping)
sEnableVBOs = use_vbo && gGLManager.mHasVertexBufferObject ; sEnableVBOs = use_vbo && gGLManager.mHasVertexBufferObject ;
sDisableVBOMapping = sEnableVBOs && no_vbo_mapping ; sDisableVBOMapping = sEnableVBOs && no_vbo_mapping ;
if(!sPrivatePoolp) if (!sPrivatePoolp)
{ {
sPrivatePoolp = LLPrivateMemoryPoolManager::getInstance()->newPool(LLPrivateMemoryPool::STATIC) ; sPrivatePoolp = LLPrivateMemoryPoolManager::getInstance()->newPool(LLPrivateMemoryPool::STATIC);
} }
sStreamVBOPool.mType = GL_ARRAY_BUFFER_ARB;
sStreamVBOPool.mUsage= GL_STREAM_DRAW_ARB;
sStreamIBOPool.mType = GL_ELEMENT_ARRAY_BUFFER_ARB;
sStreamIBOPool.mUsage= GL_STREAM_DRAW_ARB;
sDynamicVBOPool.mType = GL_ARRAY_BUFFER_ARB;
sDynamicVBOPool.mUsage= GL_DYNAMIC_DRAW_ARB;
sDynamicIBOPool.mType = GL_ELEMENT_ARRAY_BUFFER_ARB;
sDynamicIBOPool.mUsage= GL_DYNAMIC_DRAW_ARB;
} }
//static //static
@@ -718,18 +708,18 @@ void LLVertexBuffer::unbind()
#endif #endif
sGLRenderArray = 0; sGLRenderArray = 0;
sGLRenderIndices = 0; sGLRenderIndices = 0;
sIBOActive = FALSE; sIBOActive = false;
} }
if (sVBOActive) if (sVBOActive)
{ {
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
sVBOActive = FALSE; sVBOActive = false;
} }
if (sIBOActive) if (sIBOActive)
{ {
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
sIBOActive = FALSE; sIBOActive = false;
} }
sGLRenderBuffer = 0; sGLRenderBuffer = 0;
@@ -758,64 +748,79 @@ void LLVertexBuffer::cleanupClass()
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
S32 LLVertexBuffer::determineUsage(S32 usage)
{
S32 ret_usage = usage;
if (!sEnableVBOs)
{
ret_usage = 0;
}
if (usage == GL_STREAM_DRAW_ARB && !sUseStreamDraw)
{
ret_usage = 0;
}
if (usage == GL_DYNAMIC_DRAW_ARB && sPreferStreamDraw)
{
ret_usage = GL_STREAM_DRAW_ARB;
}
if (usage == 0 && LLRender::sGLCoreProfile)
{ //MUST use VBOs for all rendering
ret_usage = GL_STREAM_DRAW_ARB;
}
if (usage && usage != GL_STREAM_DRAW_ARB)
{ //only stream_draw and dynamic_draw are supported when using VBOs, dynamic draw is the default
if (sDisableVBOMapping)
{ //always use stream draw if VBO mapping is disabled
ret_usage = GL_STREAM_DRAW_ARB;
}
else
{
ret_usage = GL_DYNAMIC_DRAW_ARB;
}
}
return ret_usage;
}
LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) : LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :
LLRefCount(), LLRefCount(),
mNumVerts(0), mNumVerts(0),
mNumIndices(0), mNumIndices(0),
mUsage(usage), mAlignedOffset(0),
mAlignedIndexOffset(0),
mSize(0),
mIndicesSize(0),
mTypeMask(typemask),
mUsage(LLVertexBuffer::determineUsage(usage)),
mGLBuffer(0), mGLBuffer(0),
mGLArray(0),
mGLIndices(0), mGLIndices(0),
mGLArray(0),
mMappedData(NULL), mMappedData(NULL),
mMappedIndexData(NULL), mMappedIndexData(NULL),
mVertexLocked(FALSE), mMappedDataUsingVBOs(false),
mIndexLocked(FALSE), mMappedIndexDataUsingVBOs(false),
mFinal(FALSE), mVertexLocked(false),
mEmpty(TRUE), mIndexLocked(false),
mFinal(false),
mEmpty(true),
mMappable(false),
mFence(NULL) mFence(NULL)
{ {
LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
mFence = NULL;
if (!sEnableVBOs)
{
mUsage = 0 ;
}
if (mUsage == GL_STREAM_DRAW_ARB && !sUseStreamDraw)
{
mUsage = 0;
}
if (mUsage == GL_DYNAMIC_DRAW_ARB && sPreferStreamDraw)
{
mUsage = GL_STREAM_DRAW_ARB;
}
if (mUsage == 0 && LLRender::sGLCoreProfile)
{ //MUST use VBOs for all rendering
mUsage = GL_STREAM_DRAW_ARB;
}
if (mUsage && mUsage != GL_STREAM_DRAW_ARB)
{ //only stream_draw and dynamic_draw are supported when using VBOs, dynamic draw is the default
if (sDisableVBOMapping)
{ //always use stream draw if VBO mapping is disabled
mUsage = GL_STREAM_DRAW_ARB;
}
else
{
mUsage = GL_DYNAMIC_DRAW_ARB;
}
}
if (mUsage == GL_DYNAMIC_DRAW_ARB && !sDisableVBOMapping) if (mUsage == GL_DYNAMIC_DRAW_ARB && !sDisableVBOMapping)
{ {
mMappable = TRUE; mMappable = true;
} }
else else
{ {
mMappable = FALSE; mMappable = false;
} }
//zero out offsets //zero out offsets
@@ -824,12 +829,6 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :
mOffsets[i] = 0; mOffsets[i] = 0;
} }
mTypeMask = typemask;
mSize = 0;
mIndicesSize = 0;
mAlignedOffset = 0;
mAlignedIndexOffset = 0;
sCount++; sCount++;
} }
@@ -1010,9 +1009,11 @@ void LLVertexBuffer::createGLBuffer(U32 size)
return; return;
} }
mEmpty = TRUE; mEmpty = true;
if (useVBOs()) mMappedDataUsingVBOs = useVBOs();
if (mMappedDataUsingVBOs)
{ {
genBuffer(size); genBuffer(size);
} }
@@ -1039,12 +1040,14 @@ void LLVertexBuffer::createGLIndices(U32 size)
return; return;
} }
mEmpty = TRUE; mEmpty = true;
//pad by 16 bytes for aligned copies //pad by 16 bytes for aligned copies
size += 16; size += 16;
if (useVBOs()) mMappedIndexDataUsingVBOs = useVBOs();
if (mMappedIndexDataUsingVBOs)
{ {
//pad by another 16 bytes for VBO pointer adjustment //pad by another 16 bytes for VBO pointer adjustment
size += 16; size += 16;
@@ -1064,15 +1067,15 @@ void LLVertexBuffer::destroyGLBuffer()
LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
if (mGLBuffer) if (mGLBuffer)
{ {
if (useVBOs()) if (mMappedDataUsingVBOs)
{ {
releaseBuffer(); releaseBuffer();
} }
else else
{ {
FREE_MEM(sPrivatePoolp, (void*) mMappedData) ; FREE_MEM(sPrivatePoolp, (void*) mMappedData);
mMappedData = NULL; mMappedData = NULL;
mEmpty = TRUE; mEmpty = true;
} }
} }
@@ -1085,15 +1088,15 @@ void LLVertexBuffer::destroyGLIndices()
LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
if (mGLIndices) if (mGLIndices)
{ {
if (useVBOs()) if (mMappedIndexDataUsingVBOs)
{ {
releaseIndices(); releaseIndices();
} }
else else
{ {
FREE_MEM(sPrivatePoolp, (void*) mMappedIndexData) ; FREE_MEM(sPrivatePoolp, (void*) mMappedIndexData);
mMappedIndexData = NULL; mMappedIndexData = NULL;
mEmpty = TRUE; mEmpty = true;
} }
} }
@@ -1113,9 +1116,9 @@ void LLVertexBuffer::updateNumVerts(S32 nverts)
nverts = 65535; nverts = 65535;
} }
S32 needed_size = calcOffsets(mTypeMask, mOffsets, nverts); U32 needed_size = calcOffsets(mTypeMask, mOffsets, nverts);
if (needed_size > mSize || needed_size <= mSize/2) if (needed_size > (U32)mSize || needed_size <= (U32)mSize/2)
{ {
createGLBuffer(needed_size); createGLBuffer(needed_size);
} }
@@ -1129,9 +1132,9 @@ void LLVertexBuffer::updateNumIndices(S32 nindices)
llassert(nindices >= 0); llassert(nindices >= 0);
S32 needed_size = sizeof(U16) * nindices; U32 needed_size = sizeof(U16) * nindices;
if (needed_size > mIndicesSize || needed_size <= mIndicesSize/2) if (needed_size > (U32)mIndicesSize || needed_size <= (U32)mIndicesSize/2)
{ {
createGLIndices(needed_size); createGLIndices(needed_size);
} }
@@ -1278,16 +1281,10 @@ void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices)
} }
} }
BOOL LLVertexBuffer::useVBOs() const bool LLVertexBuffer::useVBOs() const
{ {
//it's generally ineffective to use VBO for things that are streaming on apple //it's generally ineffective to use VBO for things that are streaming on apple
return (mUsage != 0);
if (!mUsage)
{
return FALSE;
}
return TRUE;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@@ -1365,7 +1362,7 @@ volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, boo
if (!mVertexLocked) if (!mVertexLocked)
{ {
mVertexLocked = TRUE; mVertexLocked = true;
sMappedCount++; sMappedCount++;
stop_glerror(); stop_glerror();
@@ -1445,7 +1442,7 @@ volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, boo
log_glerror(); log_glerror();
//check the availability of memory //check the availability of memory
LLMemory::logMemoryInfo(TRUE) ; LLMemory::logMemoryInfo(true) ;
if(mMappable) if(mMappable)
{ {
@@ -1492,6 +1489,7 @@ volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, boo
static LLFastTimer::DeclareTimer FTM_VBO_MAP_INDEX_RANGE("IBO Map Range"); static LLFastTimer::DeclareTimer FTM_VBO_MAP_INDEX_RANGE("IBO Map Range");
static LLFastTimer::DeclareTimer FTM_VBO_MAP_INDEX("IBO Map"); static LLFastTimer::DeclareTimer FTM_VBO_MAP_INDEX("IBO Map");
volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
{ {
LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
@@ -1543,7 +1541,7 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range
{ {
//LLMemType mt_v(LLMemType::MTYPE_VERTEX_MAP_BUFFER_INDICES); //LLMemType mt_v(LLMemType::MTYPE_VERTEX_MAP_BUFFER_INDICES);
mIndexLocked = TRUE; mIndexLocked = true;
sMappedCount++; sMappedCount++;
stop_glerror(); stop_glerror();
@@ -1622,7 +1620,7 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range
if (!mMappedIndexData) if (!mMappedIndexData)
{ {
log_glerror(); log_glerror();
LLMemory::logMemoryInfo(TRUE) ; LLMemory::logMemoryInfo(true) ;
if(mMappable) if(mMappable)
{ {
@@ -1738,12 +1736,13 @@ void LLVertexBuffer::unmapBuffer()
mMappedData = NULL; mMappedData = NULL;
} }
mVertexLocked = FALSE ; mVertexLocked = false;
sMappedCount--; sMappedCount--;
} }
if (mMappedIndexData && mIndexLocked) if (mMappedIndexData && mIndexLocked)
{ {
LLFastTimer t(FTM_IBO_UNMAP);
bindGLIndices(); bindGLIndices();
if(!mMappable) if(!mMappable)
{ {
@@ -1804,13 +1803,13 @@ void LLVertexBuffer::unmapBuffer()
mMappedIndexData = NULL ; mMappedIndexData = NULL ;
} }
mIndexLocked = FALSE ; mIndexLocked = false ;
sMappedCount--; sMappedCount--;
} }
if(updated_all) if(updated_all)
{ {
mEmpty = FALSE; mEmpty = false;
} }
} }
@@ -1830,12 +1829,12 @@ template <class T,S32 type> struct VertexBufferStrider
if (ptr == NULL) if (ptr == NULL)
{ {
llwarns << "mapIndexBuffer failed!" << llendl; llwarns << "mapIndexBuffer failed!" << llendl;
return FALSE; return false;
} }
strider = (T*)ptr; strider = (T*)ptr;
strider.setStride(0); strider.setStride(0);
return TRUE; return true;
} }
else if (vbo.hasDataType(type)) else if (vbo.hasDataType(type))
{ {
@@ -1846,21 +1845,18 @@ template <class T,S32 type> struct VertexBufferStrider
if (ptr == NULL) if (ptr == NULL)
{ {
llwarns << "mapVertexBuffer failed!" << llendl; llwarns << "mapVertexBuffer failed!" << llendl;
return FALSE; return false;
} }
strider = (T*)ptr; strider = (T*)ptr;
strider.setStride(stride); strider.setStride(stride);
//strider.setTypeSize(LLVertexBuffer::sTypeSize[type]); return true;
return TRUE;
} }
else else
{ {
llerrs << "VertexBufferStrider could not find valid vertex data." << llendl; llerrs << "VertexBufferStrider could not find valid vertex data." << llendl;
} }
return FALSE; return false;
} }
}; };
@@ -1959,7 +1955,7 @@ bool LLVertexBuffer::bindGLBuffer(bool force_bind)
glBindBufferARB(GL_ARRAY_BUFFER_ARB, mGLBuffer); glBindBufferARB(GL_ARRAY_BUFFER_ARB, mGLBuffer);
sGLRenderBuffer = mGLBuffer; sGLRenderBuffer = mGLBuffer;
sBindCount++; sBindCount++;
sVBOActive = TRUE; sVBOActive = true;
if (mGLArray) if (mGLArray)
{ {
@@ -1991,7 +1987,7 @@ bool LLVertexBuffer::bindGLIndices(bool force_bind)
sGLRenderIndices = mGLIndices; sGLRenderIndices = mGLIndices;
stop_glerror(); stop_glerror();
sBindCount++; sBindCount++;
sIBOActive = TRUE; sIBOActive = true;
ret = true; ret = true;
} }
@@ -2013,7 +2009,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
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 ...
BOOL setup = (sLastMask != data_mask); bool setup = (sLastMask != data_mask);
if (gDebugGL && data_mask != 0) if (gDebugGL && data_mask != 0)
{ //make sure data requirements are fulfilled { //make sure data requirements are fulfilled
@@ -2047,21 +2043,17 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
if (mGLArray) if (mGLArray)
{ {
bindGLArray(); bindGLArray();
setup = FALSE; //do NOT perform pointer setup if using VAO setup = false; //do NOT perform pointer setup if using VAO
} }
else else
{ {
if (bindGLBuffer()) const bool bindBuffer = bindGLBuffer();
{ const bool bindIndices = bindGLIndices();
setup = TRUE;
} setup = setup || bindBuffer || bindIndices;
if (bindGLIndices())
{
setup = TRUE;
}
} }
BOOL error = FALSE; bool error = false;
if (gDebugGL && !mGLArray) if (gDebugGL && !mGLArray)
{ {
GLint buff; GLint buff;
@@ -2070,7 +2062,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
{ {
if (gDebugSession) if (gDebugSession)
{ {
error = TRUE; error = true;
gFailLog << "Invalid GL vertex buffer bound: " << buff << std::endl; gFailLog << "Invalid GL vertex buffer bound: " << buff << std::endl;
} }
else else
@@ -2086,7 +2078,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
{ {
if (gDebugSession) if (gDebugSession)
{ {
error = TRUE; error = true;
gFailLog << "Invalid GL index buffer bound: " << buff << std::endl; gFailLog << "Invalid GL index buffer bound: " << buff << std::endl;
} }
else else
@@ -2108,7 +2100,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
#endif #endif
sGLRenderArray = 0; sGLRenderArray = 0;
sGLRenderIndices = 0; sGLRenderIndices = 0;
sIBOActive = FALSE; sIBOActive = false;
} }
if (mGLBuffer) if (mGLBuffer)
@@ -2117,13 +2109,13 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
{ {
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
sBindCount++; sBindCount++;
sVBOActive = FALSE; sVBOActive = false;
setup = TRUE; // ... or a VBO is deactivated setup = true; // ... or a VBO is deactivated
} }
if (sGLRenderBuffer != mGLBuffer) if (sGLRenderBuffer != mGLBuffer)
{ {
sGLRenderBuffer = mGLBuffer; sGLRenderBuffer = mGLBuffer;
setup = TRUE; // ... or a client memory pointer changed setup = true; // ... or a client memory pointer changed
} }
} }
if (mGLIndices) if (mGLIndices)
@@ -2132,7 +2124,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
{ {
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
sBindCount++; sBindCount++;
sIBOActive = FALSE; sIBOActive = false;
} }
sGLRenderIndices = mGLIndices; sGLRenderIndices = mGLIndices;
@@ -2220,19 +2212,19 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
{ {
S32 loc = TYPE_WEIGHT; S32 loc = TYPE_WEIGHT;
void* ptr = (void*)(base + mOffsets[TYPE_WEIGHT]); void* ptr = (void*)(base + mOffsets[TYPE_WEIGHT]);
glVertexAttribPointerARB(loc, 1, GL_FLOAT, FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT], ptr); glVertexAttribPointerARB(loc, 1, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT], ptr);
} }
if (data_mask & MAP_WEIGHT4) if (data_mask & MAP_WEIGHT4)
{ {
S32 loc = TYPE_WEIGHT4; S32 loc = TYPE_WEIGHT4;
void* ptr = (void*)(base+mOffsets[TYPE_WEIGHT4]); void* ptr = (void*)(base+mOffsets[TYPE_WEIGHT4]);
glVertexAttribPointerARB(loc, 4, GL_FLOAT, FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT4], ptr); glVertexAttribPointerARB(loc, 4, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT4], ptr);
} }
if (data_mask & MAP_CLOTHWEIGHT) if (data_mask & MAP_CLOTHWEIGHT)
{ {
S32 loc = TYPE_CLOTHWEIGHT; S32 loc = TYPE_CLOTHWEIGHT;
void* ptr = (void*)(base + mOffsets[TYPE_CLOTHWEIGHT]); void* ptr = (void*)(base + mOffsets[TYPE_CLOTHWEIGHT]);
glVertexAttribPointerARB(loc, 4, GL_FLOAT, TRUE, LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], ptr); glVertexAttribPointerARB(loc, 4, GL_FLOAT, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], ptr);
} }
if (data_mask & MAP_TEXTURE_INDEX) if (data_mask & MAP_TEXTURE_INDEX)
{ {

View File

@@ -57,7 +57,12 @@ class LLVBOPool
public: public:
static U32 sBytesPooled; static U32 sBytesPooled;
U32 mUsage; LLVBOPool(U32 vboUsage, U32 vboType)
: mUsage(vboUsage)
, mType(vboType)
{}
const U32 mUsage;
U32 mType; U32 mType;
//size MUST be a power of 2 //size MUST be a power of 2
@@ -104,6 +109,7 @@ public:
}; };
LLVertexBuffer(const LLVertexBuffer& rhs) LLVertexBuffer(const LLVertexBuffer& rhs)
: mUsage(rhs.mUsage)
{ {
*this = rhs; *this = rhs;
} }
@@ -119,9 +125,9 @@ public:
static LLVBOPool sStreamIBOPool; static LLVBOPool sStreamIBOPool;
static LLVBOPool sDynamicIBOPool; static LLVBOPool sDynamicIBOPool;
static BOOL sUseStreamDraw; static bool sUseStreamDraw;
static BOOL sUseVAO; static bool sUseVAO;
static BOOL sPreferStreamDraw; static bool sPreferStreamDraw;
static void initClass(bool use_vbo, bool no_vbo_mapping); static void initClass(bool use_vbo, bool no_vbo_mapping);
static void cleanupClass(); static void cleanupClass();
@@ -202,7 +208,7 @@ protected:
void destroyGLIndices(); void destroyGLIndices();
void updateNumVerts(S32 nverts); void updateNumVerts(S32 nverts);
void updateNumIndices(S32 nindices); void updateNumIndices(S32 nindices);
virtual BOOL useVBOs() const; bool useVBOs() const;
void unmapBuffer(); void unmapBuffer();
public: public:
@@ -240,8 +246,8 @@ public:
bool getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index=0, S32 count = -1, bool map_range = false); bool getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index=0, S32 count = -1, bool map_range = false);
BOOL isEmpty() const { return mEmpty; } bool isEmpty() const { return mEmpty; }
BOOL isLocked() const { return mVertexLocked || mIndexLocked; } 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; }
@@ -255,7 +261,7 @@ public:
volatile U8* getMappedIndices() const { return mMappedIndexData; } volatile U8* getMappedIndices() const { return mMappedIndexData; }
S32 getOffset(S32 type) const { return mOffsets[type]; } S32 getOffset(S32 type) const { return mOffsets[type]; }
S32 getUsage() const { return mUsage; } S32 getUsage() const { return mUsage; }
BOOL isWriteable() const { return (mMappable || mUsage == GL_STREAM_DRAW_ARB) ? TRUE : FALSE; } bool isWriteable() const { return (mMappable || mUsage == GL_STREAM_DRAW_ARB) ? true : false; }
void draw(U32 mode, U32 count, U32 indices_offset) const; void draw(U32 mode, U32 count, U32 indices_offset) const;
void drawArrays(U32 mode, U32 offset, U32 count) const; void drawArrays(U32 mode, U32 offset, U32 count) const;
@@ -282,11 +288,15 @@ protected:
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 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 U32 mMappedDataUsingVBOs : 1;
BOOL mFinal; // if TRUE, buffer can not be mapped again U32 mMappedIndexDataUsingVBOs : 1;
BOOL mEmpty; // if TRUE, client buffer is empty (or NULL). Old values have been discarded. U32 mVertexLocked : 1; // if true, vertex buffer is being or has been written to in client memory
mutable BOOL mMappable; // if TRUE, use memory mapping to upload data (otherwise doublebuffer and use glBufferSubData) U32 mIndexLocked : 1; // if true, index buffer is being or has been written to in client memory
U32 mFinal : 1; // if true, buffer can not be mapped again
U32 mEmpty : 1; // if true, client buffer is empty (or NULL). Old values have been discarded.
mutable bool mMappable; // if true, use memory mapping to upload data (otherwise doublebuffer and use glBufferSubData)
S32 mOffsets[TYPE_MAX]; S32 mOffsets[TYPE_MAX];
std::vector<MappedRegion> mMappedVertexRegions; std::vector<MappedRegion> mMappedVertexRegions;
@@ -297,6 +307,7 @@ protected:
void placeFence() const; void placeFence() const;
void waitFence() const; void waitFence() const;
static S32 determineUsage(S32 usage);
private: private:
static LLPrivateMemoryPool* sPrivatePoolp ; static LLPrivateMemoryPool* sPrivatePoolp ;
@@ -305,18 +316,18 @@ public:
static S32 sCount; static S32 sCount;
static S32 sGLCount; static S32 sGLCount;
static S32 sMappedCount; static S32 sMappedCount;
static BOOL sMapped; static bool sMapped;
typedef std::list<LLVertexBuffer*> buffer_list_t; typedef std::list<LLVertexBuffer*> buffer_list_t;
static BOOL sDisableVBOMapping; //disable glMapBufferARB static bool sDisableVBOMapping; //disable glMapBufferARB
static BOOL sEnableVBOs; static bool sEnableVBOs;
static S32 sTypeSize[TYPE_MAX]; static S32 sTypeSize[TYPE_MAX];
static U32 sGLMode[LLRender::NUM_MODES]; static U32 sGLMode[LLRender::NUM_MODES];
static U32 sGLRenderBuffer; static U32 sGLRenderBuffer;
static U32 sGLRenderArray; static U32 sGLRenderArray;
static U32 sGLRenderIndices; static U32 sGLRenderIndices;
static BOOL sVBOActive; static bool sVBOActive;
static BOOL sIBOActive; static bool sIBOActive;
static U32 sLastMask; static U32 sLastMask;
static U32 sAllocatedBytes; static U32 sAllocatedBytes;
static U32 sBindCount; static U32 sBindCount;

View File

@@ -37,8 +37,6 @@ float calcDirectionalLight(vec3 n, vec3 l);
vec3 atmosAmbient(vec3 light); vec3 atmosAmbient(vec3 light);
vec3 atmosAffectDirectionalLight(float lightIntensity); vec3 atmosAffectDirectionalLight(float lightIntensity);
vec3 scaleDownLight(vec3 light);
vec3 scaleUpLight(vec3 light);
VARYING vec3 vary_position; VARYING vec3 vary_position;
VARYING vec3 vary_ambient; VARYING vec3 vary_ambient;
@@ -57,23 +55,29 @@ uniform vec3 light_direction[8];
uniform vec3 light_attenuation[8]; uniform vec3 light_attenuation[8];
uniform vec3 light_diffuse[8]; uniform vec3 light_diffuse[8];
float calcDirectionalLight(vec3 n, vec3 l)
{
float a = max(dot(n,l),0.0);
return a;
}
float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight) float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
{ {
//get light vector //get light vector
vec3 lv = lp.xyz-v; vec3 lv = lp.xyz-v;
//get distance //get distance
float d = length(lv); float d = dot(lv,lv);
float da = 0.0; float da = 0.0;
if (d > 0.0 && la > 0.0 && fa > 0.0) if (d > 0.0 && la > 0.0 && fa > 0.0)
{ {
//normalize light vector //normalize light vector
lv *= 1.0/d; lv = normalize(lv);
//distance attenuation //distance attenuation
float dist2 = d*d/(la*la); float dist2 = d/la;
da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
// spotlight coefficient. // spotlight coefficient.
@@ -81,7 +85,7 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa
da *= spot*spot; // GL_SPOT_EXPONENT=2 da *= spot*spot; // GL_SPOT_EXPONENT=2
//angular attenuation //angular attenuation
da *= calcDirectionalLight(n, lv); da *= max(dot(n, lv), 0.0);
} }
return da; return da;

View File

@@ -64,23 +64,29 @@ uniform vec3 light_direction[8];
uniform vec3 light_attenuation[8]; uniform vec3 light_attenuation[8];
uniform vec3 light_diffuse[8]; uniform vec3 light_diffuse[8];
float calcDirectionalLight(vec3 n, vec3 l)
{
float a = max(dot(n,l),0.0);
return a;
}
float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight) float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
{ {
//get light vector //get light vector
vec3 lv = lp.xyz-v; vec3 lv = lp.xyz-v;
//get distance //get distance
float d = length(lv); float d = dot(lv,lv);
float da = 0.0; float da = 0.0;
if (d > 0.0 && la > 0.0 && fa > 0.0) if (d > 0.0 && la > 0.0 && fa > 0.0)
{ {
//normalize light vector //normalize light vector
lv *= 1.0/d; lv = normalize(lv);
//distance attenuation //distance attenuation
float dist2 = d*d/(la*la); float dist2 = d/la;
da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
// spotlight coefficient. // spotlight coefficient.
@@ -88,7 +94,7 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa
da *= spot*spot; // GL_SPOT_EXPONENT=2 da *= spot*spot; // GL_SPOT_EXPONENT=2
//angular attenuation //angular attenuation
da *= calcDirectionalLight(n, lv); da *= max(dot(n, lv), 0.0);
} }
return da; return da;

View File

@@ -59,23 +59,29 @@ uniform vec3 light_direction[8];
uniform vec3 light_attenuation[8]; uniform vec3 light_attenuation[8];
uniform vec3 light_diffuse[8]; uniform vec3 light_diffuse[8];
float calcDirectionalLight(vec3 n, vec3 l)
{
float a = max(dot(n,l),0.0);
return a;
}
float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight) float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
{ {
//get light vector //get light vector
vec3 lv = lp.xyz-v; vec3 lv = lp.xyz-v;
//get distance //get distance
float d = length(lv); float d = dot(lv,lv);
float da = 0.0; float da = 0.0;
if (d > 0.0 && la > 0.0 && fa > 0.0) if (d > 0.0 && la > 0.0 && fa > 0.0)
{ {
//normalize light vector //normalize light vector
lv *= 1.0/d; lv = normalize(lv);
//distance attenuation //distance attenuation
float dist2 = d*d/(la*la); float dist2 = d/la;
da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
// spotlight coefficient. // spotlight coefficient.
@@ -83,7 +89,7 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa
da *= spot*spot; // GL_SPOT_EXPONENT=2 da *= spot*spot; // GL_SPOT_EXPONENT=2
//angular attenuation //angular attenuation
da *= calcDirectionalLight(n, lv); da *= max(dot(n, lv), 0.0);
} }
return da; return da;

View File

@@ -57,7 +57,7 @@ float getDepth(vec2 pos_screen)
float calc_cof(float depth) float calc_cof(float depth)
{ {
float sc = abs(depth-focal_distance)/-depth*blur_constant; float sc = (depth-focal_distance)/-depth*blur_constant;
sc /= magnification; sc /= magnification;
@@ -79,9 +79,10 @@ void main()
vec4 diff = texture2DRect(diffuseRect, vary_fragcoord.xy); vec4 diff = texture2DRect(diffuseRect, vary_fragcoord.xy);
float sc = calc_cof(depth); float sc = calc_cof(depth);
sc = min(abs(sc), max_cof); sc = min(sc, max_cof);
sc = max(sc, -max_cof);
vec4 bloom = texture2D(bloomMap, vary_fragcoord.xy/screen_res); vec4 bloom = texture2D(bloomMap, vary_fragcoord.xy/screen_res);
gl_FragColor.rgb = diff.rgb + bloom.rgb; gl_FragColor.rgb = diff.rgb + bloom.rgb;
gl_FragColor.a = sc/max_cof; gl_FragColor.a = sc/max_cof*0.5+0.5;
} }

View File

@@ -48,7 +48,7 @@ void main()
vec4 diff = texture2DRect(lightMap, vary_fragcoord.xy); vec4 diff = texture2DRect(lightMap, vary_fragcoord.xy);
float a = min(diff.a * max_cof*res_scale*res_scale, 1.0); float a = min(abs(diff.a*2.0-1.0) * max_cof*res_scale*res_scale, 1.0);
if (a > 0.25 && a < 0.75) if (a > 0.25 && a < 0.75)
{ //help out the transition a bit { //help out the transition a bit

View File

@@ -42,7 +42,7 @@ void dofSample(inout vec4 diff, inout float w, float min_sc, vec2 tc)
{ {
vec4 s = texture2DRect(diffuseRect, tc); vec4 s = texture2DRect(diffuseRect, tc);
float sc = s.a*max_cof; float sc = abs(s.a*2.0-1.0)*max_cof;
if (sc > min_sc) //sampled pixel is more "out of focus" than current sample radius if (sc > min_sc) //sampled pixel is more "out of focus" than current sample radius
{ {
@@ -57,6 +57,20 @@ void dofSample(inout vec4 diff, inout float w, float min_sc, vec2 tc)
} }
} }
void dofSampleNear(inout vec4 diff, inout float w, float min_sc, vec2 tc)
{
vec4 s = texture2DRect(diffuseRect, tc);
float wg = 0.25;
// de-weight dull areas to make highlights 'pop'
wg += s.r+s.g+s.b;
diff += wg*s;
w += wg;
}
void main() void main()
{ {
vec2 tc = vary_fragcoord.xy; vec2 tc = vary_fragcoord.xy;
@@ -66,12 +80,30 @@ void main()
{ {
float w = 1.0; float w = 1.0;
float sc = diff.a*max_cof; float sc = (diff.a*2.0-1.0)*max_cof;
float PI = 3.14159265358979323846264; float PI = 3.14159265358979323846264;
// sample quite uniformly spaced points within a circle, for a circular 'bokeh' // sample quite uniformly spaced points within a circle, for a circular 'bokeh'
if (sc > 0.5)
{ {
while (sc > 0.5)
{
int its = int(max(1.0,(sc*3.7)));
for (int i=0; i<its; ++i)
{
float ang = sc+i*2*PI/its; // sc is added for rotary perturbance
float samp_x = sc*sin(ang);
float samp_y = sc*cos(ang);
// you could test sample coords against an interesting non-circular aperture shape here, if desired.
dofSampleNear(diff, w, sc, vary_fragcoord.xy + vec2(samp_x,samp_y));
}
sc -= 1.0;
}
}
else if (sc < -0.5)
{
sc = abs(sc);
while (sc > 0.5) while (sc > 0.5)
{ {
int its = int(max(1.0,(sc*3.7))); int its = int(max(1.0,(sc*3.7)));

View File

@@ -39,6 +39,8 @@ float calcDirectionalLight(vec3 n, vec3 l);
mat4 getObjectSkinnedTransform(); mat4 getObjectSkinnedTransform();
vec3 atmosAmbient(vec3 light); vec3 atmosAmbient(vec3 light);
vec3 atmosAffectDirectionalLight(float lightIntensity); vec3 atmosAffectDirectionalLight(float lightIntensity);
vec3 scaleDownLight(vec3 light);
vec3 scaleUpLight(vec3 light);
VARYING vec3 vary_ambient; VARYING vec3 vary_ambient;
VARYING vec3 vary_directional; VARYING vec3 vary_directional;
@@ -59,23 +61,29 @@ uniform vec3 light_direction[8];
uniform vec3 light_attenuation[8]; uniform vec3 light_attenuation[8];
uniform vec3 light_diffuse[8]; uniform vec3 light_diffuse[8];
float calcDirectionalLight(vec3 n, vec3 l)
{
float a = max(dot(n,l),0.0);
return a;
}
float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight) float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
{ {
//get light vector //get light vector
vec3 lv = lp.xyz-v; vec3 lv = lp.xyz-v;
//get distance //get distance
float d = length(lv); float d = dot(lv,lv);
float da = 0.0; float da = 0.0;
if (d > 0.0 && la > 0.0 && fa > 0.0) if (d > 0.0 && la > 0.0 && fa > 0.0)
{ {
//normalize light vector //normalize light vector
lv *= 1.0/d; lv = normalize(lv);
//distance attenuation //distance attenuation
float dist2 = d*d/(la*la); float dist2 = d/la;
da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
// spotlight coefficient. // spotlight coefficient.
@@ -83,7 +91,7 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa
da *= spot*spot; // GL_SPOT_EXPONENT=2 da *= spot*spot; // GL_SPOT_EXPONENT=2
//angular attenuation //angular attenuation
da *= calcDirectionalLight(n, lv); da *= max(dot(n, lv), 0.0);
} }
return da; return da;

View File

@@ -63,23 +63,29 @@ uniform vec3 light_direction[8];
uniform vec3 light_attenuation[8]; uniform vec3 light_attenuation[8];
uniform vec3 light_diffuse[8]; uniform vec3 light_diffuse[8];
float calcDirectionalLight(vec3 n, vec3 l)
{
float a = max(dot(n,l),0.0);
return a;
}
float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight) float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
{ {
//get light vector //get light vector
vec3 lv = lp.xyz-v; vec3 lv = lp.xyz-v;
//get distance //get distance
float d = length(lv); float d = dot(lv,lv);
float da = 0.0; float da = 0.0;
if (d > 0.0 && la > 0.0 && fa > 0.0) if (d > 0.0 && la > 0.0 && fa > 0.0)
{ {
//normalize light vector //normalize light vector
lv *= 1.0/d; lv = normalize(lv);
//distance attenuation //distance attenuation
float dist2 = d*d/(la*la); float dist2 = d/la;
da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
// spotlight coefficient. // spotlight coefficient.
@@ -87,7 +93,7 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa
da *= spot*spot; // GL_SPOT_EXPONENT=2 da *= spot*spot; // GL_SPOT_EXPONENT=2
//angular attenuation //angular attenuation
da *= calcDirectionalLight(n, lv); da *= max(dot(n, lv), 0.0);
} }
return da; return da;

View File

@@ -60,23 +60,29 @@ uniform vec3 light_direction[8];
uniform vec3 light_attenuation[8]; uniform vec3 light_attenuation[8];
uniform vec3 light_diffuse[8]; uniform vec3 light_diffuse[8];
float calcDirectionalLight(vec3 n, vec3 l)
{
float a = max(dot(n,l),0.0);
return a;
}
float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight) float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
{ {
//get light vector //get light vector
vec3 lv = lp.xyz-v; vec3 lv = lp.xyz-v;
//get distance //get distance
float d = length(lv); float d = dot(lv,lv);
float da = 0.0; float da = 0.0;
if (d > 0.0 && la > 0.0 && fa > 0.0) if (d > 0.0 && la > 0.0 && fa > 0.0)
{ {
//normalize light vector //normalize light vector
lv *= 1.0/d; lv = normalize(lv);
//distance attenuation //distance attenuation
float dist2 = d*d/(la*la); float dist2 = d/la;
da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
// spotlight coefficient. // spotlight coefficient.
@@ -84,7 +90,7 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa
da *= spot*spot; // GL_SPOT_EXPONENT=2 da *= spot*spot; // GL_SPOT_EXPONENT=2
//angular attenuation //angular attenuation
da *= calcDirectionalLight(n, lv); da *= max(dot(n, lv), 0.0);
} }
return da; return da;

View File

@@ -318,9 +318,13 @@ void LLViewerShaderMgr::setShaders()
LLGLSLShader::sIndexedTextureChannels = llmin(LLGLSLShader::sIndexedTextureChannels, 16); LLGLSLShader::sIndexedTextureChannels = llmin(LLGLSLShader::sIndexedTextureChannels, 16);
reentrance = true; reentrance = true;
if (gGLManager.mGLVersion < 2.f)
{ //NEVER use shaders on a pre 2.0 context if (LLRender::sGLCoreProfile)
gSavedSettings.setBOOL("VertexShaderEnable", FALSE); {
if (!gSavedSettings.getBOOL("VertexShaderEnable"))
{ //vertex shaders MUST be enabled to use core profile
gSavedSettings.setBOOL("VertexShaderEnable", TRUE);
}
} }
//setup preprocessor definitions //setup preprocessor definitions
@@ -983,19 +987,25 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (success) if (success)
{ {
gDeferredSkinnedAlphaProgram.mName = "Deferred Skinned Alpha Shader"; gDeferredSkinnedAlphaProgram.mName = "Deferred Skinned Alpha Shader";
gDeferredSkinnedAlphaProgram.mFeatures.atmosphericHelpers = true;
gDeferredSkinnedAlphaProgram.mFeatures.hasObjectSkinning = true; gDeferredSkinnedAlphaProgram.mFeatures.hasObjectSkinning = true;
gDeferredSkinnedAlphaProgram.mFeatures.calculatesAtmospherics = true; gDeferredSkinnedAlphaProgram.mFeatures.calculatesAtmospherics = true;
gDeferredSkinnedAlphaProgram.mFeatures.hasGamma = true; gDeferredSkinnedAlphaProgram.mFeatures.hasGamma = true;
gDeferredSkinnedAlphaProgram.mFeatures.hasAtmospherics = true; gDeferredSkinnedAlphaProgram.mFeatures.hasAtmospherics = true;
gDeferredSkinnedAlphaProgram.mFeatures.calculatesLighting = true; gDeferredSkinnedAlphaProgram.mFeatures.calculatesLighting = false;
gDeferredSkinnedAlphaProgram.mFeatures.hasLighting = true; gDeferredSkinnedAlphaProgram.mFeatures.hasLighting = false;
gDeferredSkinnedAlphaProgram.mFeatures.isAlphaLighting = true; gDeferredSkinnedAlphaProgram.mFeatures.isAlphaLighting = true;
gDeferredSkinnedAlphaProgram.mFeatures.disableTextureIndex = true; gDeferredSkinnedAlphaProgram.mFeatures.disableTextureIndex = true;
gDeferredSkinnedAlphaProgram.mShaderFiles.clear(); gDeferredSkinnedAlphaProgram.mShaderFiles.clear();
gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaNonIndexedF.glsl", GL_FRAGMENT_SHADER_ARB)); gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaNonIndexedF.glsl", GL_FRAGMENT_SHADER_ARB));
gDeferredSkinnedAlphaProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; gDeferredSkinnedAlphaProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
success = gDeferredSkinnedAlphaProgram.createShader(NULL, NULL); success = gDeferredSkinnedAlphaProgram.createShader(NULL, NULL);
// Hack to include uniforms for lighting without linking in lighting file
gDeferredSkinnedAlphaProgram.mFeatures.calculatesLighting = true;
gDeferredSkinnedAlphaProgram.mFeatures.hasLighting = true;
} }
if (success) if (success)
@@ -1112,11 +1122,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (success) if (success)
{ {
gDeferredAlphaProgram.mName = "Deferred Alpha Shader"; gDeferredAlphaProgram.mName = "Deferred Alpha Shader";
gDeferredAlphaProgram.mFeatures.calculatesLighting = true; gDeferredAlphaProgram.mFeatures.atmosphericHelpers = true;
gDeferredAlphaProgram.mFeatures.calculatesLighting = false;
gDeferredAlphaProgram.mFeatures.calculatesAtmospherics = true; gDeferredAlphaProgram.mFeatures.calculatesAtmospherics = true;
gDeferredAlphaProgram.mFeatures.hasGamma = true; gDeferredAlphaProgram.mFeatures.hasGamma = true;
gDeferredAlphaProgram.mFeatures.hasAtmospherics = true; gDeferredAlphaProgram.mFeatures.hasAtmospherics = true;
gDeferredAlphaProgram.mFeatures.hasLighting = true; gDeferredAlphaProgram.mFeatures.hasLighting = false;
gDeferredAlphaProgram.mFeatures.isAlphaLighting = true; gDeferredAlphaProgram.mFeatures.isAlphaLighting = true;
gDeferredAlphaProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels gDeferredAlphaProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels
if (mVertexShaderLevel[SHADER_DEFERRED] < 1) if (mVertexShaderLevel[SHADER_DEFERRED] < 1)
@@ -1132,7 +1143,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));
gDeferredAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB)); gDeferredAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));
gDeferredAlphaProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; gDeferredAlphaProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
success = gDeferredAlphaProgram.createShader(NULL, NULL); success = gDeferredAlphaProgram.createShader(NULL, NULL);
// Hack
gDeferredAlphaProgram.mFeatures.calculatesLighting = true;
gDeferredAlphaProgram.mFeatures.hasLighting = true;
} }
if (success) if (success)
@@ -1261,19 +1277,24 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (success) if (success)
{ {
gDeferredAvatarAlphaProgram.mName = "Avatar Alpha Shader"; gDeferredAvatarAlphaProgram.mName = "Avatar Alpha Shader";
gDeferredAvatarAlphaProgram.mFeatures.atmosphericHelpers = true;
gDeferredAvatarAlphaProgram.mFeatures.hasSkinning = true; gDeferredAvatarAlphaProgram.mFeatures.hasSkinning = true;
gDeferredAvatarAlphaProgram.mFeatures.calculatesLighting = true; gDeferredAvatarAlphaProgram.mFeatures.calculatesLighting = false;
gDeferredAvatarAlphaProgram.mFeatures.calculatesAtmospherics = true; gDeferredAvatarAlphaProgram.mFeatures.calculatesAtmospherics = true;
gDeferredAvatarAlphaProgram.mFeatures.hasGamma = true; gDeferredAvatarAlphaProgram.mFeatures.hasGamma = true;
gDeferredAvatarAlphaProgram.mFeatures.hasAtmospherics = true; gDeferredAvatarAlphaProgram.mFeatures.hasAtmospherics = true;
gDeferredAvatarAlphaProgram.mFeatures.hasLighting = true; gDeferredAvatarAlphaProgram.mFeatures.hasLighting = false;
gDeferredAvatarAlphaProgram.mFeatures.isAlphaLighting = true; gDeferredAvatarAlphaProgram.mFeatures.isAlphaLighting = true;
gDeferredAvatarAlphaProgram.mFeatures.disableTextureIndex = true; gDeferredAvatarAlphaProgram.mFeatures.disableTextureIndex = true;
gDeferredAvatarAlphaProgram.mShaderFiles.clear(); gDeferredAvatarAlphaProgram.mShaderFiles.clear();
gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaV.glsl", GL_VERTEX_SHADER_ARB));
gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaNonIndexedNoColorF.glsl", GL_FRAGMENT_SHADER_ARB)); gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaNonIndexedNoColorF.glsl", GL_FRAGMENT_SHADER_ARB));
gDeferredAvatarAlphaProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; gDeferredAvatarAlphaProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
success = gDeferredAvatarAlphaProgram.createShader(NULL, &mAvatarUniforms); success = gDeferredAvatarAlphaProgram.createShader(NULL, &mAvatarUniforms);
gDeferredAvatarAlphaProgram.mFeatures.calculatesLighting = true;
gDeferredAvatarAlphaProgram.mFeatures.hasLighting = true;
} }
if (success) if (success)