Merge branch 'master' of github.com:Shyotl/SingularityViewer

# Conflicts:
#	indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl
This commit is contained in:
Shyotl
2018-08-06 20:42:32 -05:00
87 changed files with 1582 additions and 1599 deletions

View File

@@ -29,6 +29,7 @@
#include "linden_common.h"
#include "llapr.h"
#include "llscopedvolatileaprpool.h"
#include <limits>
bool ll_apr_warn_status(apr_status_t status)
{
@@ -150,7 +151,7 @@ apr_status_t LLAPRFile::open(const std::string& filename, apr_int32_t flags, BOO
return open(filename, flags, use_global_pool ? LLAPRFile::long_lived : LLAPRFile::short_lived);
}
// File I/O
S32 LLAPRFile::read(void *buf, S32 nbytes)
S32 LLAPRFile::read(void *buf, U64 nbytes)
{
if(!mFile)
{
@@ -167,12 +168,12 @@ S32 LLAPRFile::read(void *buf, S32 nbytes)
}
else
{
llassert_always(sz <= 0x7fffffff);
llassert_always(sz <= std::numeric_limits<apr_size_t>::max());
return (S32)sz;
}
}
S32 LLAPRFile::write(const void *buf, S32 nbytes)
S32 LLAPRFile::write(const void *buf, U64 nbytes)
{
if(!mFile)
{
@@ -189,7 +190,7 @@ S32 LLAPRFile::write(const void *buf, S32 nbytes)
}
else
{
llassert_always(sz <= 0x7fffffff);
llassert_always(sz <= std::numeric_limits<apr_size_t>::max());
return (S32)sz;
}
}

View File

@@ -92,8 +92,8 @@ public:
apr_status_t eof() { return apr_file_eof(mFile);}
// Returns bytes read/written, 0 if read/write fails:
S32 read(void* buf, S32 nbytes);
S32 write(const void* buf, S32 nbytes);
S32 read(void* buf, U64 nbytes);
S32 write(const void* buf, U64 nbytes);
apr_file_t* getFileHandle() {return mFile;}

View File

@@ -281,7 +281,7 @@ U8* LLImageBase::allocateDataSize(S32 width, S32 height, S32 ncomponents, S32 si
// LLImageRaw
//---------------------------------------------------------------------------
AIThreadSafeSimpleDC<S32> LLImageRaw::sGlobalRawMemory;
AIThreadSafeSimpleDC<S64> LLImageRaw::sGlobalRawMemory;
S32 LLImageRaw::sRawImageCount = 0;
S32 LLImageRaw::sRawImageCachedCount = 0;
@@ -358,7 +358,7 @@ LLImageRaw::~LLImageRaw()
U8* LLImageRaw::allocateData(S32 size)
{
U8* res = LLImageBase::allocateData(size);
*AIAccess<S32>(sGlobalRawMemory) += getDataSize();
*AIAccess<S64>(sGlobalRawMemory) += getDataSize();
return res;
}
@@ -367,7 +367,7 @@ U8* LLImageRaw::reallocateData(S32 size)
{
S32 old_data_size = getDataSize();
U8* res = LLImageBase::reallocateData(size);
*AIAccess<S32>(sGlobalRawMemory) += getDataSize() - old_data_size;
*AIAccess<S64>(sGlobalRawMemory) += getDataSize() - old_data_size;
return res;
}
@@ -375,7 +375,7 @@ U8* LLImageRaw::reallocateData(S32 size)
void LLImageRaw::deleteData()
{
{
*AIAccess<S32>(sGlobalRawMemory) -= getDataSize();
*AIAccess<S64>(sGlobalRawMemory) -= getDataSize();
}
LLImageBase::deleteData();
}
@@ -392,7 +392,7 @@ void LLImageRaw::setDataAndSize(U8 *data, S32 width, S32 height, S8 components)
LLImageBase::setSize(width, height, components) ;
LLImageBase::setDataAndSize(data, width * height * components) ;
*AIAccess<S32>(sGlobalRawMemory) += getDataSize();
*AIAccess<S64>(sGlobalRawMemory) += getDataSize();
}
BOOL LLImageRaw::resize(U16 width, U16 height, S8 components)

View File

@@ -257,7 +257,7 @@ protected:
void setDataAndSize(U8 *data, S32 width, S32 height, S8 components) ;
public:
static AIThreadSafeSimpleDC<S32> sGlobalRawMemory;
static AIThreadSafeSimpleDC<S64> sGlobalRawMemory;
static S32 sRawImageCount;
static S32 sRawImageCachedCount;

View File

@@ -962,3 +962,4 @@ P(wholeModelFeeResponder);
P(wholeModelUploadResponder);
P2(XMLRPCResponder, connect_40s);
P2(crashLoggerResponder, transfer_300s);
P(getUpdateInfoResponder);

View File

@@ -414,7 +414,7 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes,
}
// Attach existing objects
if (!LLShaderMgr::instance()->attachShaderFeatures(this))
if (!LLShaderMgr::instance()->attachClassSharedShaders(*this, mShaderClass) || !LLShaderMgr::instance()->attachShaderFeatures(this))
{
if(mProgramObject)
glDeleteObjectARB(mProgramObject);

View File

@@ -50,9 +50,9 @@ U32 wpo2(U32 i);
U32 LLImageGL::sUniqueCount = 0;
U32 LLImageGL::sBindCount = 0;
S32Bytes LLImageGL::sGlobalTextureMemory(0);
S32Bytes LLImageGL::sBoundTextureMemory(0);
S32Bytes LLImageGL::sCurBoundTextureMemory(0);
S64Bytes LLImageGL::sGlobalTextureMemory(0);
S64Bytes LLImageGL::sBoundTextureMemory(0);
S64Bytes LLImageGL::sCurBoundTextureMemory(0);
S32 LLImageGL::sCount = 0;
BOOL LLImageGL::sGlobalUseAnisotropic = FALSE;
@@ -78,9 +78,9 @@ S32 LLImageGL::sCurTexPickSize = -1 ;
LLPointer<LLImageGL> LLImageGL::sHighlightTexturep = NULL;
S32 LLImageGL::sMaxCategories = 1 ;
std::vector<S32Bytes> LLImageGL::sTextureMemByCategory;
std::vector<S32Bytes> LLImageGL::sTextureMemByCategoryBound ;
std::vector<S32Bytes> LLImageGL::sTextureCurMemByCategoryBound ;
std::vector<S64Bytes> LLImageGL::sTextureMemByCategory;
std::vector<S64Bytes> LLImageGL::sTextureMemByCategoryBound ;
std::vector<S64Bytes> LLImageGL::sTextureCurMemByCategoryBound ;
//------------------------
// ****************************************************************************************************
//End for texture auditing use only
@@ -293,7 +293,7 @@ void LLImageGL::updateStats(F32 current_time)
LL_RECORD_BLOCK_TIME(FTM_IMAGE_UPDATE_STATS);
sLastFrameTime = current_time;
sBoundTextureMemory = sCurBoundTextureMemory;
sCurBoundTextureMemory = S32Bytes(0);
sCurBoundTextureMemory = S64Bytes(0);
if(gAuditTexture)
{
@@ -305,7 +305,7 @@ void LLImageGL::updateStats(F32 current_time)
for(U32 i = 0 ; i < sTextureCurMemByCategoryBound.size() ; i++)
{
sTextureMemByCategoryBound[i] = sTextureCurMemByCategoryBound[i] ;
sTextureCurMemByCategoryBound[i] = (S32Bytes)0 ;
sTextureCurMemByCategoryBound[i] = (S64Bytes)0 ;
}
}
}

View File

@@ -233,9 +233,9 @@ public:
static F32 sLastFrameTime;
// Global memory statistics
static S32Bytes sGlobalTextureMemory; // Tracks main memory texmem
static S32Bytes sBoundTextureMemory; // Tracks bound texmem for last completed frame
static S32Bytes sCurBoundTextureMemory; // Tracks bound texmem for current frame
static S64Bytes sGlobalTextureMemory; // Tracks main memory texmem
static S64Bytes sBoundTextureMemory; // Tracks bound texmem for last completed frame
static S64Bytes sCurBoundTextureMemory; // Tracks bound texmem for current frame
static U32 sBindCount; // Tracks number of texture binds for current frame
static U32 sUniqueCount; // Tracks number of unique texture binds for current frame
static BOOL sGlobalUseAnisotropic;
@@ -288,9 +288,9 @@ public:
//for debug use: show texture category distribution
//----------------------------------------
static std::vector<S32Bytes> sTextureMemByCategory;
static std::vector<S32Bytes> sTextureMemByCategoryBound ;
static std::vector<S32Bytes> sTextureCurMemByCategoryBound ;
static std::vector<S64Bytes> sTextureMemByCategory;
static std::vector<S64Bytes> sTextureMemByCategoryBound ;
static std::vector<S64Bytes> sTextureCurMemByCategoryBound ;
//----------------------------------------
// ****************************************************************************************************
//End of definitions for texture auditing use only

View File

@@ -611,95 +611,90 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
if (minor_version <= 19)
{
text[count++] = strdup("#version 110\n");
text[count++] = strdup("#define ATTRIBUTE attribute\n");
text[count++] = strdup("#define VARYING varying\n");
text[count++] = strdup("#define VARYING_FLAT varying\n");
// Need to enable extensions here instead of in the shader files,
// before any non-preprocessor directives (per spec)
text[count++] = strdup("#extension GL_ARB_texture_rectangle : enable\n");
text[count++] = strdup("#extension GL_ARB_shader_texture_lod : enable\n");
}
else if (minor_version <= 29)
{
//set version to 1.20
text[count++] = strdup("#version 120\n");
text[count++] = strdup("#define FXAA_GLSL_120 1\n");
text[count++] = strdup("#define FXAA_FAST_PIXEL_OFFSET 0\n");
text[count++] = strdup("#define ATTRIBUTE attribute\n");
text[count++] = strdup("#define VARYING varying\n");
text[count++] = strdup("#define VARYING_FLAT varying\n");
// Need to enable extensions here instead of in the shader files,
// before any non-preprocessor directives (per spec)
text[count++] = strdup("#extension GL_ARB_texture_rectangle : enable\n");
text[count++] = strdup("#extension GL_ARB_shader_texture_lod : enable\n");
if (type == GL_FRAGMENT_SHADER_ARB)
{
// Need to enable extensions here instead of in the shader files,
// before any non-preprocessor directives (per spec)
text[count++] = strdup("#extension GL_ARB_shader_texture_lod : enable\n");
text[count++] = strdup("#define FXAA_GLSL_120 1\n");
text[count++] = strdup("#define FXAA_FAST_PIXEL_OFFSET 0\n");
}
}
text[count++] = strdup("#define ATTRIBUTE attribute\n");
text[count++] = strdup("#define VARYING varying\n");
text[count++] = strdup("#define VARYING_FLAT varying\n");
}
else
{
if (major_version < 4)
{
//set version to 1.30
text[count++] = strdup("#version 130\n");
// Need to enable extensions here instead of in the shader files,
// before any non-preprocessor directives (per spec)
text[count++] = strdup("#extension GL_ARB_texture_rectangle : enable\n");
text[count++] = strdup("#extension GL_ARB_shader_texture_lod : enable\n");
if (major_version > 1 || minor_version >= 40)
{
//set version to 1.40
text[count++] = strdup("#version 140\n");
}
else
{
//set version to 1.30
text[count++] = strdup("#version 130\n");
}
if (minor_version == 50 && gGLManager.mHasGpuShader5)
{
// Need to enable extensions here instead of in the shader files,
// before any non-preprocessor directives (per spec)
text[count++] = strdup("#extension GL_ARB_gpu_shader5 : enable\n");
}
//some implementations of GLSL 1.30 require integer precision be explicitly declared
text[count++] = strdup("precision mediump int;\n");
text[count++] = strdup("precision highp float;\n");
text[count++] = strdup("#define FXAA_GLSL_130 1\n");
if (type == GL_FRAGMENT_SHADER_ARB)
{
text[count++] = strdup("#define FXAA_GLSL_130 1\n");
}
}
else
{ //set version to 400
text[count++] = strdup("#version 400\n");
// Need to enable extensions here instead of in the shader files,
// before any non-preprocessor directives (per spec)
text[count++] = strdup("#extension GL_ARB_texture_rectangle : enable\n");
text[count++] = strdup("#extension GL_ARB_shader_texture_lod : enable\n");
text[count++] = strdup("#define FXAA_GLSL_400 1\n");
if (type == GL_FRAGMENT_SHADER_ARB)
{
text[count++] = strdup("#define FXAA_GLSL_400 1\n");
}
}
text[count++] = strdup("#define DEFINE_GL_FRAGCOLOR 1\n");
text[count++] = strdup("#define ATTRIBUTE in\n");
if (type == GL_VERTEX_SHADER_ARB)
{ //"varying" state is "out" in a vertex program, "in" in a fragment program
// ("varying" is deprecated after version 1.20)
text[count++] = strdup("#define ATTRIBUTE in\n");
text[count++] = strdup("#define VARYING out\n");
text[count++] = strdup("#define VARYING_FLAT flat out\n");
}
else
{
text[count++] = strdup("#define DEFINE_GL_FRAGCOLOR 1\n");
text[count++] = strdup("#define VARYING in\n");
text[count++] = strdup("#define VARYING_FLAT flat in\n");
}
//backwards compatibility with legacy texture lookup syntax
text[count++] = strdup("#define texture2D texture\n");
text[count++] = strdup("#define textureCube texture\n");
text[count++] = strdup("#define texture2DLod textureLod\n");
text[count++] = strdup("#define shadow2D(a,b) vec2(texture(a,b))\n");
if (major_version > 1 || minor_version >= 40)
{ //GLSL 1.40 replaces texture2DRect et al with texture
text[count++] = strdup("#define texture2DRect texture\n");
text[count++] = strdup("#define shadow2DRect(a,b) vec2(texture(a,b))\n");
//backwards compatibility with legacy texture lookup syntax
text[count++] = strdup("#define texture2D texture\n");
text[count++] = strdup("#define textureCube texture\n");
text[count++] = strdup("#define texture2DLod textureLod\n");
text[count++] = strdup("#define shadow2D(a,b) vec2(texture(a,b))\n");
}
}
if(defines)
{
for (std::map<std::string,std::string>::iterator iter = defines->begin(); iter != defines->end(); ++iter)
{
std::string define = "#define " + iter->first + " " + iter->second + "\n";
text[count++] = (GLcharARB *) strdup(define.c_str());
}
{
std::string define = "#define " + iter->first + " " + iter->second + "\n";
text[count++] = (GLcharARB *) strdup(define.c_str());
}
}
if (texture_index_channels > 0 && type == GL_FRAGMENT_SHADER_ARB)
@@ -796,7 +791,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
LL_ERRS() << "Indexed texture rendering requires GLSL 1.30 or later." << LL_ENDL;
}
}
else
else if( type == GL_FRAGMENT_SHADER_ARB )
{
text[count++] = strdup("#define HAS_DIFFUSE_LOOKUP 0\n");
}

View File

@@ -240,6 +240,7 @@ DISPLAY_GAMMA,
// Implemented in the application to actually update out of date uniforms for a particular shader
virtual void updateShaderUniforms(LLGLSLShader * shader) = 0; // Pure Virtual
virtual bool attachClassSharedShaders(LLGLSLShader& shader, S32 shader_class) = 0; // Pure Virtual
public:
struct CachedObjectInfo

View File

@@ -97,7 +97,6 @@ U32 LLVertexBuffer::sCurVAOName = 1;
U32 LLVertexBuffer::sAllocatedIndexBytes = 0;
U32 LLVertexBuffer::sIndexCount = 0;
LLPrivateMemoryPool* LLVertexBuffer::sPrivatePoolp = NULL;
U32 LLVertexBuffer::sBindCount = 0;
U32 LLVertexBuffer::sSetCount = 0;
S32 LLVertexBuffer::sCount = 0;
@@ -117,6 +116,7 @@ bool LLVertexBuffer::sMapped = false;
bool LLVertexBuffer::sUseStreamDraw = true;
bool LLVertexBuffer::sUseVAO = false;
bool LLVertexBuffer::sPreferStreamDraw = false;
LLVertexBuffer* LLVertexBuffer::sUtilityBuffer = nullptr;
U32 LLVBOPool::genBuffer()
@@ -135,7 +135,7 @@ void LLVBOPool::deleteBuffer(U32 name)
LLVertexBuffer::unbind();
glBindBufferARB(mType, name);
glBufferDataARB(mType, 0, NULL, mUsage);
glBufferDataARB(mType, 0, nullptr, mUsage);
glBindBufferARB(mType, 0);
glDeleteBuffersARB(1, &name);
@@ -154,7 +154,7 @@ volatile U8* LLVBOPool::allocate(U32& name, U32 size, bool for_seed)
{
llassert(vbo_block_size(size) == size);
volatile U8* ret = NULL;
volatile U8* ret = nullptr;
U32 i = vbo_block_index(size);
@@ -186,12 +186,12 @@ volatile U8* LLVBOPool::allocate(U32& name, U32 size, bool for_seed)
if (LLVertexBuffer::sDisableVBOMapping || mUsage != GL_DYNAMIC_DRAW_ARB)
{
glBufferDataARB(mType, size, 0, mUsage);
glBufferDataARB(mType, size, nullptr, mUsage);
ret = (U8*) ll_aligned_malloc<64>(size);
}
else
{ //always use a true hint of static draw when allocating non-client-backed buffers
glBufferDataARB(mType, size, 0, GL_STATIC_DRAW_ARB);
glBufferDataARB(mType, size, nullptr, GL_STATIC_DRAW_ARB);
}
glBindBufferARB(mType, 0);
@@ -449,7 +449,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
else
{
GLenum array[] =
static const GLenum array[] =
{
GL_VERTEX_ARRAY,
GL_NORMAL_ARRAY,
@@ -457,7 +457,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
GL_COLOR_ARRAY,
};
GLenum mask[] =
static const GLenum mask[] =
{
MAP_VERTEX,
MAP_NORMAL,
@@ -564,77 +564,96 @@ void LLVertexBuffer::drawArrays(U32 mode, const std::vector<LLVector3>& pos, con
gGL.syncMatrices();
U32 count = pos.size();
llassert(norm.size() >= pos.size());
llassert(count > 0);
if( count == 0 )
if (count == 0)
{
LL_WARNS() << "Called drawArrays with 0 vertices" << LL_ENDL;
return;
}
if( norm.size() < pos.size() )
if (norm.size() < pos.size())
{
LL_WARNS() << "Called drawArrays with #" << norm.size() << " normals and #" << pos.size() << " vertices" << LL_ENDL;
return;
}
unbind();
setupClientArrays(MAP_VERTEX | MAP_NORMAL);
LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
if (shader)
if (!sUtilityBuffer)
{
glVertexAttribPointerARB(TYPE_VERTEX, 3, GL_FLOAT, GL_FALSE, 0, pos[0].mV);
glVertexAttribPointerARB(TYPE_NORMAL, 3, GL_FLOAT, GL_FALSE, 0, norm[0].mV);
sUtilityBuffer = new LLVertexBuffer(MAP_VERTEX | MAP_NORMAL | MAP_TEXCOORD0, GL_STREAM_DRAW);
sUtilityBuffer->allocateBuffer(count, count, true);
}
else
if (sUtilityBuffer->getNumVerts() < (S32)count)
{
glVertexPointer(3, GL_FLOAT, 0, pos[0].mV);
glNormalPointer(GL_FLOAT, 0, norm[0].mV);
sUtilityBuffer->resizeBuffer(count, count);
}
glDrawArrays(sGLMode[mode], 0, count);
LLStrider<LLVector3> vertex_strider;
LLStrider<LLVector3> normal_strider;
sUtilityBuffer->getVertexStrider(vertex_strider);
sUtilityBuffer->getNormalStrider(normal_strider);
for (U32 i = 0; i < count; ++i)
{
*(vertex_strider++) = pos[i];
*(normal_strider++) = norm[i];
}
sUtilityBuffer->setBuffer(MAP_VERTEX | MAP_NORMAL);
sUtilityBuffer->drawArrays(mode, 0, pos.size());
}
//static
void LLVertexBuffer::drawElements(U32 mode, const LLVector4a* pos, const LLVector2* tc, S32 num_indices, const U16* indicesp)
void LLVertexBuffer::drawElements(U32 mode, const S32 num_vertices, const LLVector4a* pos, const LLVector2* tc, S32 num_indices, const U16* indicesp)
{
llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
if (num_vertices <= 0)
{
LL_WARNS() << "Called drawElements with 0 vertices" << LL_ENDL;
return;
}
if (num_indices <= 0)
{
LL_WARNS() << "Called drawElements with 0 indices" << LL_ENDL;
return;
}
gGL.syncMatrices();
if (!sUtilityBuffer)
{
sUtilityBuffer = new LLVertexBuffer(MAP_VERTEX | MAP_NORMAL | MAP_TEXCOORD0, GL_STREAM_DRAW);
sUtilityBuffer->allocateBuffer(num_vertices, num_indices, true);
}
if (sUtilityBuffer->getNumVerts() < num_vertices || sUtilityBuffer->getNumIndices() < num_indices)
{
sUtilityBuffer->resizeBuffer(llmax(sUtilityBuffer->getNumVerts(), num_vertices), llmax(sUtilityBuffer->getNumIndices(), num_indices));
}
U32 mask = LLVertexBuffer::MAP_VERTEX;
LLStrider<U16> index_strider;
LLStrider<LLVector4a> vertex_strider;
sUtilityBuffer->getIndexStrider(index_strider);
sUtilityBuffer->getVertexStrider(vertex_strider);
const S32 index_size = ((num_indices * sizeof(U16)) + 0xF) & ~0xF;
const S32 vertex_size = ((num_vertices * 4 * sizeof(F32)) + 0xF) & ~0xF;
LLVector4a::memcpyNonAliased16((F32*)index_strider.get(), (F32*)indicesp, index_size);
LLVector4a::memcpyNonAliased16((F32*)vertex_strider.get(), (F32*)pos, vertex_size);
if (tc)
{
mask = mask | LLVertexBuffer::MAP_TEXCOORD0;
LLStrider<LLVector2> tc_strider;
sUtilityBuffer->getTexCoord0Strider(tc_strider);
const S32 tc_size = ((num_vertices * 2 * sizeof(F32)) + 0xF) & ~0xF;
LLVector4a::memcpyNonAliased16((F32*)tc_strider.get(), (F32*)tc, tc_size);
}
unbind();
setupClientArrays(mask);
if (LLGLSLShader::sNoFixedFunction)
{
glVertexAttribPointerARB(TYPE_VERTEX, 3, GL_FLOAT, GL_FALSE, 16, pos);
if (tc)
{
glVertexAttribPointerARB(TYPE_TEXCOORD0, 2, GL_FLOAT, GL_FALSE, 0, tc);
}
}
else
{
glVertexPointer(3, GL_FLOAT, 16, pos);
if (tc)
{
glTexCoordPointer(2, GL_FLOAT, 0, tc);
}
}
glDrawElements(sGLMode[mode], num_indices, GL_UNSIGNED_SHORT, indicesp);
sUtilityBuffer->setBuffer(mask);
sUtilityBuffer->draw(mode, num_indices, 0);
}
void LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_offset) const
@@ -822,7 +841,7 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
}
{
LL_RECORD_BLOCK_TIME(FTM_GL_DRAW_ARRAYS);
//LL_RECORD_BLOCK_TIME(FTM_GL_DRAW_ARRAYS);
stop_glerror();
glDrawArrays(sGLMode[mode], first, count);
}
@@ -834,12 +853,7 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
void LLVertexBuffer::initClass(bool use_vbo, bool no_vbo_mapping)
{
sEnableVBOs = use_vbo && gGLManager.mHasVertexBufferObject;
sDisableVBOMapping = sEnableVBOs;// && no_vbo_mapping; //Temporary workaround for vbo mapping being straight up broken
if (!sPrivatePoolp)
{
sPrivatePoolp = LLPrivateMemoryPoolManager::getInstance()->newPool(LLPrivateMemoryPool::STATIC);
}
sDisableVBOMapping = sEnableVBOs;// && no_vbo_mapping;
}
//static
@@ -882,11 +896,8 @@ void LLVertexBuffer::cleanupClass()
sStreamVBOPool.cleanup();
sDynamicVBOPool.cleanup();
if(sPrivatePoolp)
{
LLPrivateMemoryPoolManager::getInstance()->deletePool(sPrivatePoolp);
sPrivatePoolp = NULL;
}
delete sUtilityBuffer;
sUtilityBuffer = nullptr;
}
//----------------------------------------------------------------------------
@@ -944,8 +955,8 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :
mGLBuffer(0),
mGLIndices(0),
mGLArray(0),
mMappedData(NULL),
mMappedIndexData(NULL),
mMappedData(nullptr),
mMappedIndexData(nullptr),
mMappedDataUsingVBOs(false),
mMappedIndexDataUsingVBOs(false),
mVertexLocked(false),
@@ -953,7 +964,7 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :
mFinal(false),
mEmpty(true),
mMappable(false),
mFence(NULL)
mFence(nullptr)
{
mMappable = (mUsage == GL_DYNAMIC_DRAW_ARB && !sDisableVBOMapping);
@@ -1031,7 +1042,7 @@ LLVertexBuffer::~LLVertexBuffer()
delete mFence;
}
mFence = NULL;
mFence = nullptr;
sVertexCount -= mNumVerts;
sIndexCount -= mNumIndices;
@@ -1109,7 +1120,7 @@ void LLVertexBuffer::releaseBuffer()
}
mGLBuffer = 0;
mMappedData = NULL;
mMappedData = nullptr;
sGLCount--;
}
@@ -1126,7 +1137,7 @@ void LLVertexBuffer::releaseIndices()
}
mGLIndices = 0;
mMappedIndexData = NULL;
mMappedIndexData = nullptr;
sGLCount--;
}
@@ -1155,7 +1166,7 @@ void LLVertexBuffer::createGLBuffer(U32 size)
{
static int gl_buffer_idx = 0;
mGLBuffer = ++gl_buffer_idx;
mMappedData = (U8*)ALLOCATE_MEM(sPrivatePoolp, size);
mMappedData = (U8*)ll_aligned_malloc_16(size);
mSize = size;
}
}
@@ -1187,7 +1198,7 @@ void LLVertexBuffer::createGLIndices(U32 size)
}
else
{
mMappedIndexData = (U8*)ALLOCATE_MEM(sPrivatePoolp, size);
mMappedIndexData = (U8*)ll_aligned_malloc_16(size);
static int gl_buffer_idx = 0;
mGLIndices = ++gl_buffer_idx;
mIndicesSize = size;
@@ -1204,8 +1215,8 @@ void LLVertexBuffer::destroyGLBuffer()
}
else
{
FREE_MEM(sPrivatePoolp, (void*) mMappedData);
mMappedData = NULL;
ll_aligned_free_16((void*) mMappedData);
mMappedData = nullptr;
mEmpty = true;
}
}
@@ -1224,8 +1235,8 @@ void LLVertexBuffer::destroyGLIndices()
}
else
{
FREE_MEM(sPrivatePoolp, (void*) mMappedIndexData);
mMappedIndexData = NULL;
ll_aligned_free_16((void*) mMappedIndexData);
mMappedIndexData = nullptr;
mEmpty = true;
}
}
@@ -1529,7 +1540,7 @@ volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, boo
}
else
{
volatile U8* src = NULL;
volatile U8* src = nullptr;
waitFence();
if (gGLManager.mHasMapBufferRange)
{
@@ -1716,7 +1727,7 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range
}
else
{
volatile U8* src = NULL;
volatile U8* src = nullptr;
waitFence();
if (gGLManager.mHasMapBufferRange)
{
@@ -1849,7 +1860,7 @@ void LLVertexBuffer::unmapBuffer()
else
{
stop_glerror();
glBufferDataARB(GL_ARRAY_BUFFER_ARB, getSize(), NULL, mUsage);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, getSize(), nullptr, mUsage); // <alchemy/>
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, getSize(), (U8*) mMappedData);
stop_glerror();
}
@@ -1887,7 +1898,7 @@ void LLVertexBuffer::unmapBuffer()
glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
stop_glerror();
mMappedData = NULL;
mMappedData = nullptr;
}
mVertexLocked = false;
@@ -1916,7 +1927,7 @@ void LLVertexBuffer::unmapBuffer()
else
{
stop_glerror();
glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, getIndicesSize(), NULL, mUsage);
glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, getIndicesSize(), nullptr, mUsage); // <alchemy/>
glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, getIndicesSize(), (U8*) mMappedIndexData);
stop_glerror();
}
@@ -1955,7 +1966,7 @@ void LLVertexBuffer::unmapBuffer()
glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
stop_glerror();
mMappedIndexData = NULL;
mMappedIndexData = nullptr;
}
mIndexLocked = false;
@@ -1970,7 +1981,8 @@ void LLVertexBuffer::unmapBuffer()
//----------------------------------------------------------------------------
template <class T,S32 type> struct VertexBufferStrider
template <class T, S32 type>
struct VertexBufferStrider
{
typedef LLStrider<T> strider_t;
static bool get(LLVertexBuffer& vbo,
@@ -1983,7 +1995,7 @@ template <class T,S32 type> struct VertexBufferStrider
volatile U8* ptr = vbo.mapVertexBuffer(type, index, count, map_range);
if (ptr == NULL)
if (ptr == nullptr)
{
LL_WARNS() << "mapVertexBuffer failed!" << LL_ENDL;
return false;
@@ -2011,7 +2023,7 @@ struct VertexBufferStrider<T, LLVertexBuffer::TYPE_INDEX>
{
volatile U8* ptr = vbo.mapIndexBuffer(index, count, map_range);
if (ptr == NULL)
if (ptr == nullptr)
{
LL_WARNS() << "mapIndexBuffer failed!" << LL_ENDL;
return false;
@@ -2176,16 +2188,6 @@ void LLVertexBuffer::flush()
}
}
// bind for transform feedback (quick 'n dirty)
void LLVertexBuffer::bindForFeedback(U32 channel, U32 type, U32 index, U32 count)
{
#ifdef GL_TRANSFORM_FEEDBACK_BUFFER
U32 offset = mOffsets[type] + sTypeSize[type]*index;
U32 size= (sTypeSize[type]*count);
glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, channel, mGLBuffer, offset, size);
#endif
}
// Set for rendering
void LLVertexBuffer::setBuffer(U32 data_mask)
{

View File

@@ -93,7 +93,6 @@ public:
//============================================================================
// base class
class LLPrivateMemoryPool;
class LLVertexBuffer : public LLRefCount
{
public:
@@ -142,7 +141,7 @@ public:
static void cleanupClass();
static void setupClientArrays(U32 data_mask);
static void drawArrays(U32 mode, const std::vector<LLVector3>& pos, const std::vector<LLVector3>& norm);
static void drawElements(U32 mode, const LLVector4a* pos, const LLVector2* tc, S32 num_indices, const U16* indicesp);
static void drawElements(U32 mode, const S32 num_vertices, const LLVector4a* pos, const LLVector2* tc, S32 num_indices, const U16* indicesp);
static void unbind(); //unbind any bound vertex buffer
@@ -227,8 +226,6 @@ public:
volatile U8* mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range);
volatile U8* mapIndexBuffer(S32 index, S32 count, bool map_range);
void bindForFeedback(U32 channel, U32 type, U32 index, U32 count);
// set for rendering
virtual void setBuffer(U32 data_mask); // calls setupVertexBuffer() if data_mask is not 0
void flush(); //flush pending data to GL memory
@@ -327,9 +324,6 @@ protected:
static S32 determineUsage(S32 usage);
private:
static LLPrivateMemoryPool* sPrivatePoolp;
public:
static S32 sCount;
static S32 sGLCount;
@@ -353,6 +347,9 @@ public:
static U32 sIndexCount;
static U32 sBindCount;
static U32 sSetCount;
private:
static LLVertexBuffer* sUtilityBuffer;
};

View File

@@ -48,6 +48,7 @@
#include "lluictrlfactory.h"
#include "llnotifications.h"
#include "llfunctorregistry.h"
#include "lldraghandle.h"
const S32 MAX_ALLOWED_MSG_WIDTH = 400;
const F32 DEFAULT_BUTTON_DELAY = 0.5f;
@@ -233,6 +234,12 @@ LLAlertDialog::LLAlertDialog( LLNotificationPtr notification, bool modal)
msg_box->setColor( LLUI::sColorsGroup->getColor( "AlertTextColor" ) );
}
LLDragHandle* handle = getDragHandle();
if (handle)
{
getDragHandle()->setTextColor(LLUI::sColorsGroup->getColor(mCaution ? "AlertCautionTextColor" : "AlertTextColor"));
}
LLRect rect;
rect.setLeftTopAndSize( msg_x, msg_y, text_rect.getWidth(), text_rect.getHeight() );
msg_box->setRect( rect );
@@ -257,6 +264,10 @@ LLAlertDialog::LLAlertDialog( LLNotificationPtr notification, bool modal)
button_data.mText);
btn->setClickedCallback(boost::bind(&LLAlertDialog::onButtonPressed, this, _1, button_data.mUrl));
if (mCaution)
{
btn->setColor(LLUI::sColorsGroup->getColor("ButtonCautionImageColor"));
}
addChild(btn);
@@ -370,6 +381,11 @@ bool LLAlertDialog::setCheckBox( const std::string& check_title, const std::stri
max_msg_width, LINE_HEIGHT);
mCheck = new LLCheckboxCtrl(std::string("check"), check_rect, check_title, font, boost::bind(&LLAlertDialog::onClickIgnore, this, _1));
mCheck->setEnabledColor(LLUI::sColorsGroup->getColor( mCaution ? "AlertCautionTextColor" : "AlertTextColor"));
if (mCaution)
{
mCheck->setButtonColor(LLUI::sColorsGroup->getColor("ButtonCautionImageColor"));
}
addChild(mCheck);
return true;

View File

@@ -100,8 +100,10 @@ public:
// LLCheckBoxCtrl interface
virtual BOOL toggle() { return mButton->toggleState(); } // returns new state
void setEnabledColor( const LLColor4 &color ) { mTextEnabledColor = color; }
void setDisabledColor( const LLColor4 &color ) { mTextDisabledColor = color; }
void setEnabledColor(const LLColor4 &color) { mTextEnabledColor = color; setEnabled(getEnabled()); }
void setDisabledColor( const LLColor4 &color ) { mTextDisabledColor = color; setEnabled(getEnabled()); }
void setButtonColor(const LLColor4 &color) { if (mButton) mButton->setColor(color); }
void setLabel( const LLStringExplicit& label );
std::string getLabel() const;

View File

@@ -301,6 +301,13 @@ BOOL LLDragHandle::handleMouseUp(S32 x, S32 y, MASK mask)
return TRUE;
}
void LLDragHandle::setTextColor(const LLColor4& color)
{
if (mTitleBox)
{
mTitleBox->setColor(color);
}
}
BOOL LLDragHandle::handleHover(S32 x, S32 y, MASK mask)
{

View File

@@ -63,6 +63,8 @@ public:
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
virtual void setTextColor(const LLColor4& color);
protected:
LLTextBox* getTitleBox() const { return mTitleBox; }
void setTitleBox(LLTextBox*);

View File

@@ -891,7 +891,7 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPt
assert(!wasFound);
if (passesFilter)
{
LL_INFOS() << "Inserting " << pNotification->getName() << LL_ENDL;
//LL_INFOS() << "Inserting " << pNotification->getName() << LL_ENDL;
// not in our list, add it and say so
mItems.insert(pNotification);
abortProcessing = mChanged(payload);

View File

@@ -125,6 +125,7 @@ LLScrollListCtrl::LLScrollListCtrl(const std::string& name, const LLRect& rect,
mNeedsScroll(false),
mCanSelect(true),
mColumnsDirty(false),
mSortEnabled(true),
mMaxItemCount(INT_MAX),
mMaxContentWidth(0),
mBorderThickness( 2 ),
@@ -501,12 +502,14 @@ BOOL LLScrollListCtrl::addItem( LLScrollListItem* item, EAddPosition pos, BOOL r
case ADD_SORTED:
{
// sort by column 0, in ascending order
std::vector<sort_column_t> single_sort_column;
single_sort_column.push_back(std::make_pair(0, TRUE));
mItemList.push_back(item);
std::stable_sort(mItemList.begin(), mItemList.end(), SortScrollListItem(single_sort_column,mSortCallback));
// std::stable_sort is expensive. Only do this if the user sort criteria is not column 0, otherwise
// setNeedsSort does what we want.
if (mSortColumns.empty() || mSortColumns[0].first != 0)
{
// sort by column 0, in ascending order
std::stable_sort(mItemList.begin(), mItemList.end(), SortScrollListItem({ {0,true} }, mSortCallback));
}
// ADD_SORTED just sorts by first column...
// this might not match user sort criteria, so flag list as being in unsorted state
@@ -2301,6 +2304,16 @@ BOOL LLScrollListCtrl::setSort(S32 column_idx, BOOL ascending)
}
}
void LLScrollListCtrl::setSortEnabled(bool sort)
{
bool update = sort && !mSortEnabled;
mSortEnabled = sort;
if (update)
{
updateSort();
}
}
S32 LLScrollListCtrl::getLinesPerPage()
{
//if mPageLines is NOT provided display all item
@@ -2942,7 +2955,7 @@ std::string LLScrollListCtrl::getSortColumnName()
BOOL LLScrollListCtrl::hasSortOrder() const
{
return !mSortColumns.empty();
return mSortEnabled && !mSortColumns.empty();
}
void LLScrollListCtrl::clearSortOrder()

View File

@@ -322,6 +322,7 @@ public:
BOOL getSortAscending() { return mSortColumns.empty() ? TRUE : mSortColumns.back().second; }
BOOL hasSortOrder() const;
void clearSortOrder();
void setSortEnabled(bool sort);
template<typename T> S32 selectMultiple(const std::vector<T>& vec)
{
@@ -368,6 +369,7 @@ public:
return mSortCallback->connect(cb);
}
S32 getLinesPerPage();
protected:
// "Full" interface: use this when you're creating a list that has one or more of the following:
@@ -404,7 +406,6 @@ private:
void deselectItem(LLScrollListItem* itemp);
void commitIfChanged();
BOOL setSort(S32 column, BOOL ascending);
S32 getLinesPerPage();
S32 mLineHeight; // the max height of a single line
S32 mScrollLines; // how many lines we've scrolled down
@@ -423,6 +424,7 @@ private:
bool mDisplayColumnHeaders;
bool mColumnsDirty;
bool mColumnWidthsDirty;
bool mSortEnabled;
mutable item_list mItemList;

View File

@@ -65,6 +65,7 @@ public:
// currently unused
};
public:
virtual void postInitialized() {}
virtual void show() = 0;
virtual void hide() = 0;
virtual void close() = 0;

View File

@@ -185,6 +185,11 @@ void LLWindowCallbacks::handleResumeWatchdog(LLWindow *window)
}
bool LLWindowCallbacks::handleDPIScaleChange(LLWindow *window, float xDPIScale, float yDPIScale, U32 width, U32 height)
{
return false;
}
std::string LLWindowCallbacks::translateString(const char* tag)
{
return std::string();

View File

@@ -79,7 +79,8 @@ public:
DND_LINK // Drop accepted would result in a "link" operation
};
virtual DragNDropResult handleDragNDrop(LLWindow *window, LLCoordGL pos, MASK mask, DragNDropAction action, std::string data);
virtual bool handleDPIScaleChange(LLWindow *window, float xDPIScale, float yDPIScale, U32 width = 0, U32 height = 0);
virtual void handlePingWatchdog(LLWindow *window, const char * msg);
virtual void handlePauseWatchdog(LLWindow *window);
virtual void handleResumeWatchdog(LLWindow *window);

View File

@@ -53,6 +53,7 @@
#include <shellapi.h>
#include <fstream>
#include <Imm.h>
#include <ShellScalingAPI.h>
// Require DirectInput version 8
#define DIRECTINPUT_VERSION 0x0800
@@ -74,6 +75,27 @@ const F32 ICON_FLASH_TIME = 0.5f;
extern BOOL gDebugWindowProc;
#ifndef WM_DPICHANGED
#define WM_DPICHANGED 0x02E0
#endif
#ifndef DPI_ENUMS_DECLARED
typedef enum PROCESS_DPI_AWARENESS {
PROCESS_DPI_UNAWARE = 0,
PROCESS_SYSTEM_DPI_AWARE = 1,
PROCESS_PER_MONITOR_DPI_AWARE = 2
} PROCESS_DPI_AWARENESS;
typedef enum MONITOR_DPI_TYPE {
MDT_EFFECTIVE_DPI = 0,
MDT_ANGULAR_DPI = 1,
MDT_RAW_DPI = 2,
MDT_DEFAULT = MDT_EFFECTIVE_DPI
} MONITOR_DPI_TYPE;
#endif
LPWSTR gIconResource = IDI_APPLICATION;
LLW32MsgCallback gAsyncMsgCallback = NULL;
@@ -395,6 +417,8 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks,
mKeyVirtualKey = 0;
mhDC = NULL;
mhRC = NULL;
mUser32Lib = nullptr;
mSHCoreLib = nullptr;
LL_INFOS() << "Desired FSAA Samples = " << mFSAASamples << LL_ENDL;
@@ -659,6 +683,8 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks,
// Initialize (boot strap) the Language text input management,
// based on the system's (or user's) default settings.
allowLanguageTextInput(NULL, FALSE);
initDPIAwareness();
}
@@ -674,6 +700,16 @@ LLWindowWin32::~LLWindowWin32()
delete [] mWindowClassName;
mWindowClassName = NULL;
FreeLibrary(mUser32Lib);
FreeLibrary(mSHCoreLib);
}
void LLWindowWin32::postInitialized()
{
float xDPIScale, yDPIScale;
getDPIScales(xDPIScale, yDPIScale);
mCallbacks->handleDPIScaleChange(this, xDPIScale, yDPIScale);
}
void LLWindowWin32::show()
@@ -1774,7 +1810,50 @@ void LLWindowWin32::initCursors()
}
}
void LLWindowWin32::initDPIAwareness()
{
mUser32Lib = LoadLibrary(L"user32.dll");
mSHCoreLib = LoadLibrary(L"Shcore.dll");
if (mUser32Lib && mSHCoreLib)
{
MonitorFromWindowFn = reinterpret_cast<decltype(MonitorFromWindowFn)>(GetProcAddress(mUser32Lib, "MonitorFromWindow"));
GetDpiForMonitorFn = reinterpret_cast<decltype(GetDpiForMonitorFn)>(GetProcAddress(mSHCoreLib, "GetDpiForMonitor"));
if (MonitorFromWindowFn && GetDpiForMonitorFn)
{
HRESULT(WINAPI* SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS);
SetProcessDpiAwareness = reinterpret_cast<decltype(SetProcessDpiAwareness)>(GetProcAddress(mSHCoreLib, "SetProcessDpiAwareness"));
if (SetProcessDpiAwareness && SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE) == S_OK)
return;
BOOL(WINAPI* SetProcessDPIAware)(void);
SetProcessDPIAware = reinterpret_cast<decltype(SetProcessDPIAware)>(GetProcAddress(mUser32Lib, "SetProcessDPIAware"));
if (SetProcessDPIAware && SetProcessDPIAware())
return;
}
}
FreeLibrary(mUser32Lib);
FreeLibrary(mSHCoreLib);
mUser32Lib = nullptr;
mSHCoreLib = nullptr;
}
void LLWindowWin32::getDPIScales(float &xDPIScale, float& yDPIScale)
{
xDPIScale = yDPIScale = 1.f;
if (mUser32Lib)
{
uint32_t xDPI, yDPI;
auto window = MonitorFromWindowFn(mWindowHandle, MONITOR_DEFAULTTONEAREST);
if (GetDpiForMonitorFn(window, MDT_EFFECTIVE_DPI, &xDPI, &yDPI) == S_OK)
{
xDPIScale = (float)xDPI / (float)USER_DEFAULT_SCREEN_DPI;
yDPIScale = (float)yDPI / (float)USER_DEFAULT_SCREEN_DPI;
}
}
}
void LLWindowWin32::updateCursor()
{
@@ -2657,6 +2736,26 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
};
return 0;
case WM_DPICHANGED:
{
window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_DPICHANGED");
if (gDebugWindowProc)
{
LL_INFOS("Window") << "WM_DPICHANGED " << LOWORD(w_param) << " " << HIWORD(w_param) << LL_ENDL;
}
LPRECT rect = (LPRECT)l_param;
S32 width = ((LPRECT)l_param)->right - ((LPRECT)l_param)->left;
S32 height = ((LPRECT)l_param)->bottom - ((LPRECT)l_param)->top;
LL_INFOS() << "rect: " << width << "x" << height << LL_ENDL;
if(window_imp->mCallbacks->handleDPIScaleChange(window_imp,
(F32)LOWORD(w_param) / (F32)USER_DEFAULT_SCREEN_DPI,
(F32)HIWORD(w_param) / (F32)USER_DEFAULT_SCREEN_DPI,
width,
height))
SetWindowPos(h_wnd, HWND_TOP, rect->left, rect->top, rect->right - rect->left, rect->bottom - rect->top, SWP_NOZORDER | SWP_NOACTIVATE);
}
return 0;
break;
}

View File

@@ -43,6 +43,7 @@ typedef void (*LLW32MsgCallback)(const MSG &msg);
class LLWindowWin32 : public LLWindow
{
public:
/*virtual*/ void postInitialized();
/*virtual*/ void show();
/*virtual*/ void hide();
/*virtual*/ void close();
@@ -129,6 +130,8 @@ protected:
void initCursors();
void initInputDevices();
void initDPIAwareness();
void getDPIScales(float& xDPIScale, float& yDPIScale);
HCURSOR loadColorCursor(LPCTSTR name);
BOOL isValid();
void moveWindow(const LLCoordScreen& position,const LLCoordScreen& size);
@@ -219,6 +222,11 @@ protected:
U32 mRawWParam;
U32 mRawLParam;
HMODULE mUser32Lib;
HMODULE mSHCoreLib;
HMONITOR(WINAPI *MonitorFromWindowFn)(HWND, DWORD);
HRESULT(WINAPI *GetDpiForMonitorFn)(HMONITOR, INT, UINT *, UINT *);
friend class LLWindowManager;
};

View File

@@ -596,6 +596,7 @@ set(viewer_SOURCE_FILES
scriptcounter.cpp
sgmemstat.cpp
shcommandhandler.cpp
shupdatechecker.cpp
shfloatermediaticker.cpp
wlfPanel_AdvSettings.cpp
)
@@ -1138,6 +1139,7 @@ set(viewer_HEADER_FILES
sgmemstat.h
shcommandhandler.h
shfloatermediaticker.h
shupdatechecker.h
wlfPanel_AdvSettings.h
)

View File

@@ -873,6 +873,61 @@
<key>Value</key>
<boolean>1</boolean>
</map>
<key>SinguLastKnownReleaseBuild</key>
<map>
<key>Comment</key>
<string>Latest known available verson.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>S32</string>
<key>Value</key>
<boolean>0</boolean>
</map>
<key>SinguLastKnownAlphaBuild</key>
<map>
<key>Comment</key>
<string>Latest known available verson.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>S32</string>
<key>Value</key>
<boolean>0</boolean>
</map>
<key>WarnRecommendedUpdate</key>
<map>
<key>Comment</key>
<string>Enables recommended update notification dialog</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>WarnUrgentUpdate</key>
<map>
<key>Comment</key>
<string>Enables critical update notification dialog</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>WarnUrgentUpdateModal</key>
<map>
<key>Comment</key>
<string>Enables critical update modal dialog</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>UseWebProfiles</key>
<map>
<key>Comment</key>
@@ -1004,7 +1059,7 @@
<key>Type</key>
<string>String</string>
<key>Value</key>
<string>http://singularity-viewer.github.io</string>
<string></string>
</map>
<key>SingularitySplashPagePath</key>
<map>

View File

@@ -45,28 +45,8 @@ uniform float ssao_factor;
uniform vec2 kern_scale;
uniform vec2 noise_scale;
vec3 decode_normal (vec2 enc)
{
vec2 fenc = enc*4-2;
float f = dot(fenc,fenc);
float g = sqrt(1-f/4);
vec3 n;
n.xy = fenc*g;
n.z = 1-f/2;
return n;
}
vec4 getPosition(vec2 pos_screen)
{
float depth = texture2D(depthMapDownsampled, pos_screen.xy).r;
vec2 sc = pos_screen.xy*2.0;
sc -= vec2(1.0,1.0);
vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
vec4 pos = inv_proj * ndc;
pos /= pos.w;
pos.w = 1.0;
return pos;
}
vec3 decode_normal(vec2 enc);
vec4 getPosition(vec2 pos_screen);
vec2 getKern(int i)
{

View File

@@ -99,59 +99,10 @@ uniform vec3 light_direction[8];
uniform vec3 light_attenuation[8];
uniform vec3 light_diffuse[8];
vec3 srgb_to_linear(vec3 cs)
{
vec3 low_range = cs / vec3(12.92);
vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
bvec3 lte = lessThanEqual(cs,vec3(0.04045));
#ifdef OLD_SELECT
vec3 result;
result.r = lte.r ? low_range.r : high_range.r;
result.g = lte.g ? low_range.g : high_range.g;
result.b = lte.b ? low_range.b : high_range.b;
return result;
#else
return mix(high_range, low_range, lte);
#endif
}
vec3 linear_to_srgb(vec3 cl)
{
cl = clamp(cl, vec3(0), vec3(1));
vec3 low_range = cl * 12.92;
vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
bvec3 lt = lessThan(cl,vec3(0.0031308));
#ifdef OLD_SELECT
vec3 result;
result.r = lt.r ? low_range.r : high_range.r;
result.g = lt.g ? low_range.g : high_range.g;
result.b = lt.b ? low_range.b : high_range.b;
return result;
#else
return mix(high_range, low_range, lt);
#endif
}
vec2 encode_normal(vec3 n)
{
float f = sqrt(8 * n.z + 8);
return n.xy / f + 0.5;
}
vec3 decode_normal (vec2 enc)
{
vec2 fenc = enc*4-2;
float f = dot(fenc,fenc);
float g = sqrt(1-f/4);
vec3 n;
n.xy = fenc*g;
n.z = 1-f/2;
return n;
}
vec2 encode_normal(vec3 n);
vec3 decode_normal(vec2 enc);
vec3 srgb_to_linear(vec3 cs);
vec3 linear_to_srgb(vec3 cl);
vec3 calcDirectionalLight(vec3 n, vec3 l)
{

View File

@@ -36,11 +36,7 @@ uniform float minimum_alpha;
VARYING vec3 vary_normal;
VARYING vec2 vary_texcoord0;
vec2 encode_normal(vec3 n)
{
float f = sqrt(8 * n.z + 8);
return n.xy / f + 0.5;
}
vec2 encode_normal(vec3 n);
void main()
{

View File

@@ -44,6 +44,9 @@ VARYING vec2 vary_fragcoord;
uniform mat4 inv_proj;
vec3 decode_normal(vec2 enc);
vec4 getPosition(vec2 pos_screen);
vec2 getKern(int i)
{
vec2 kern[4];
@@ -55,35 +58,6 @@ vec2 getKern(int i)
return kern[i];
}
vec4 getPosition(vec2 pos_screen)
{
float depth = texture2D(depthMap, pos_screen.xy).r;
vec2 sc = pos_screen.xy*2.0;
sc -= vec2(1.0,1.0);
vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
vec4 pos = inv_proj * ndc;
pos /= pos.w;
pos.w = 1.0;
return pos;
}
vec2 encode_normal(vec3 n)
{
float f = sqrt(8 * n.z + 8);
return n.xy / f + 0.5;
}
vec3 decode_normal (vec2 enc)
{
vec2 fenc = enc*4-2;
float f = dot(fenc,fenc);
float g = sqrt(1-f/4);
vec3 n;
n.xy = fenc*g;
n.z = 1-f/2;
return n;
}
void main()
{
vec2 tc = vary_fragcoord.xy;

View File

@@ -39,11 +39,7 @@ VARYING vec3 vary_mat2;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
vec2 encode_normal(vec3 n)
{
float f = sqrt(8 * n.z + 8);
return n.xy / f + 0.5;
}
vec2 encode_normal(vec3 n);
void main()
{

View File

@@ -0,0 +1,104 @@
/**
* @file utilityFuncF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2007, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
uniform mat4 inv_proj;
uniform vec2 screen_res;
uniform sampler2D depthMap;
vec2 encode_normal(vec3 n)
{
float f = sqrt(8 * n.z + 8);
return n.xy / f + 0.5;
}
vec3 decode_normal(vec2 enc)
{
vec2 fenc = enc*4-2;
float f = dot(fenc,fenc);
float g = sqrt(1-f/4);
vec3 n;
n.xy = fenc*g;
n.z = 1-f/2;
return n;
}
vec4 getPosition(vec2 pos_screen)
{
float depth = texture2D(depthMap, pos_screen.xy).r;
vec2 sc = pos_screen.xy*2.0;
sc -= vec2(1.0,1.0);
vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
vec4 pos = inv_proj * ndc;
pos /= pos.w;
pos.w = 1.0;
return pos;
}
vec3 srgb_to_linear(vec3 cs)
{
vec3 low_range = cs / vec3(12.92);
vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
bvec3 lte = lessThanEqual(cs,vec3(0.04045));
vec3 result;
#ifdef OLD_SELECT
vec3 result;
result.r = lte.r ? low_range.r : high_range.r;
result.g = lte.g ? low_range.g : high_range.g;
result.b = lte.b ? low_range.b : high_range.b;
return result;
#else
return mix(high_range, low_range, lte);
#endif
}
vec4 srgb_to_linear(vec4 cs)
{
return vec4(srgb_to_linear(cs.rgb), cs.a);
}
vec3 linear_to_srgb(vec3 cl)
{
cl = clamp(cl, vec3(0), vec3(1));
vec3 low_range = cl * 12.92;
vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
bvec3 lt = lessThan(cl,vec3(0.0031308));
#ifdef OLD_SELECT
vec3 result;
result.r = lt.r ? low_range.r : high_range.r;
result.g = lt.g ? low_range.g : high_range.g;
result.b = lt.b ? low_range.b : high_range.b;
return result;
#else
return mix(high_range, low_range, lt);
#endif
}
vec4 linear_to_srgb(vec4 cl)
{
return vec4(linear_to_srgb(cl.rgb), cl.a);
}

View File

@@ -37,11 +37,7 @@ VARYING vec3 vary_normal;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
vec2 encode_normal(vec3 n)
{
float f = sqrt(8 * n.z + 8);
return n.xy / f + 0.5;
}
vec2 encode_normal(vec3 n);
void main()
{

View File

@@ -36,11 +36,7 @@ uniform float minimum_alpha;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
vec2 encode_normal(vec3 n)
{
float f = sqrt(8 * n.z + 8);
return n.xy / f + 0.5;
}
vec2 encode_normal(vec3 n);
void main()
{

View File

@@ -37,11 +37,7 @@ uniform sampler2D diffuseMap;
VARYING vec3 vary_normal;
VARYING vec2 vary_texcoord0;
vec2 encode_normal(vec3 n)
{
float f = sqrt(8 * n.z + 8);
return n.xy / f + 0.5;
}
vec2 encode_normal(vec3 n);
void main()
{

View File

@@ -35,11 +35,7 @@ VARYING vec3 vary_normal;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
vec2 encode_normal(vec3 n)
{
float f = sqrt(8 * n.z + 8);
return n.xy / f + 0.5;
}
vec2 encode_normal(vec3 n);
void main()
{

View File

@@ -33,12 +33,7 @@ VARYING vec3 vary_normal;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
vec2 encode_normal(vec3 n)
{
float f = sqrt(8 * n.z + 8);
return n.xy / f + 0.5;
}
vec2 encode_normal(vec3 n);
void main()
{

View File

@@ -39,16 +39,10 @@ VARYING vec2 vary_texcoord0;
void main()
{
float shadow = 1.0;
vec4 color = diffuseLookup(vary_texcoord0.xy)*vertex_color;
if(color.a < .01)
float alpha = diffuseLookup(vary_texcoord0.xy).a*vertex_color.a;
if(alpha < .01)
discard;
color.rgb = pow(color.rgb, vec3(2.2));
color.rgb = fullbrightAtmosTransport(color.rgb);
color.rgb = fullbrightScaleSoftClip(color.rgb);
frag_color = color;
frag_color = vec4(0,0,0,alpha);
}

View File

@@ -46,17 +46,12 @@ VARYING vec2 vary_texcoord0;
void main()
{
//transform vertex
vec4 vert = vec4(position.xyz, 1.0);
vec4 pos = (modelview_matrix * vert);
passTextureIndex();
gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
calcAtmospherics(pos.xyz);
vertex_color = emissive;

View File

@@ -39,43 +39,8 @@ VARYING vec3 vary_position;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
vec3 srgb_to_linear(vec3 cs)
{
vec3 low_range = cs / vec3(12.92);
vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
bvec3 lte = lessThanEqual(cs,vec3(0.04045));
#ifdef OLD_SELECT
vec3 result;
result.r = lte.r ? low_range.r : high_range.r;
result.g = lte.g ? low_range.g : high_range.g;
result.b = lte.b ? low_range.b : high_range.b;
return result;
#else
return mix(high_range, low_range, lte);
#endif
}
vec3 linear_to_srgb(vec3 cl)
{
cl = clamp(cl, vec3(0), vec3(1));
vec3 low_range = cl * 12.92;
vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
bvec3 lt = lessThan(cl,vec3(0.0031308));
#ifdef OLD_SELECT
vec3 result;
result.r = lt.r ? low_range.r : high_range.r;
result.g = lt.g ? low_range.g : high_range.g;
result.b = lt.b ? low_range.b : high_range.b;
return result;
#else
return mix(high_range, low_range, lt);
#endif
}
vec3 srgb_to_linear(vec3 cs);
vec3 linear_to_srgb(vec3 cl);
vec3 fullbrightAtmosTransportDeferred(vec3 light)
{

View File

@@ -38,41 +38,7 @@ uniform sampler2D specularMap;
VARYING vec2 vary_texcoord0;
vec3 decode_normal (vec2 enc)
{
vec2 fenc = enc*4-2;
float f = dot(fenc,fenc);
float g = sqrt(1-f/4);
vec3 n;
n.xy = fenc*g;
n.z = 1-f/2;
return n;
}
vec2 encode_normal(vec3 n)
{
float f = sqrt(8 * n.z + 8);
return n.xy / f + 0.5;
}
vec3 linear_to_srgb(vec3 cl)
{
cl = clamp(cl, vec3(0), vec3(1));
vec3 low_range = cl * 12.92;
vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
bvec3 lt = lessThan(cl,vec3(0.0031308));
#ifdef OLD_SELECT
vec3 result;
result.r = lt.r ? low_range.r : high_range.r;
result.g = lt.g ? low_range.g : high_range.g;
result.b = lt.b ? low_range.b : high_range.b;
return result;
#else
return mix(high_range, low_range, lt);
#endif
}
vec3 linear_to_srgb(vec3 cs);
void main()
{

View File

@@ -30,42 +30,10 @@
uniform float emissive_brightness;
vec3 srgb_to_linear(vec3 cs)
{
vec3 low_range = cs / vec3(12.92);
vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
bvec3 lte = lessThanEqual(cs,vec3(0.04045));
#ifdef OLD_SELECT
vec3 result;
result.r = lte.r ? low_range.r : high_range.r;
result.g = lte.g ? low_range.g : high_range.g;
result.b = lte.b ? low_range.b : high_range.b;
return result;
#else
return mix(high_range, low_range, lte);
#endif
}
vec3 linear_to_srgb(vec3 cl)
{
cl = clamp(cl, vec3(0), vec3(1));
vec3 low_range = cl * 12.92;
vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
bvec3 lt = lessThan(cl,vec3(0.0031308));
#ifdef OLD_SELECT
vec3 result;
result.r = lt.r ? low_range.r : high_range.r;
result.g = lt.g ? low_range.g : high_range.g;
result.b = lt.b ? low_range.b : high_range.b;
return result;
#else
return mix(high_range, low_range, lt);
#endif
}
vec2 encode_normal(vec3 n);
vec3 decode_normal(vec2 enc);
vec3 srgb_to_linear(vec3 cs);
vec3 linear_to_srgb(vec3 cl);
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
@@ -271,17 +239,6 @@ vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 npos, vec3 diffuse, vec4 spe
}
vec4 getPosition_d(vec2 pos_screen, float depth)
{
vec2 sc = pos_screen.xy*2.0;
sc -= vec2(1.0,1.0);
vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
vec4 pos = inv_proj * ndc;
pos /= pos.w;
pos.w = 1.0;
return pos;
}
#ifndef WATER_FOG
vec3 getPositionEye()
{
@@ -504,23 +461,6 @@ VARYING vec3 vary_normal;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
vec2 encode_normal(vec3 n)
{
float f = sqrt(8 * n.z + 8);
return n.xy / f + 0.5;
}
vec3 decode_normal (vec2 enc)
{
vec2 fenc = enc*4-2;
float f = dot(fenc,fenc);
float g = sqrt(1-f/4);
vec3 n;
n.xy = fenc*g;
n.z = 1-f/2;
return n;
}
void main()
{
vec4 diffcol = texture2D(diffuseMap, vary_texcoord0.xy);

View File

@@ -55,34 +55,8 @@ uniform float far_z;
uniform mat4 inv_proj;
uniform vec2 noise_scale;
vec2 encode_normal(vec3 n)
{
float f = sqrt(8 * n.z + 8);
return n.xy / f + 0.5;
}
vec3 decode_normal (vec2 enc)
{
vec2 fenc = enc*4-2;
float f = dot(fenc,fenc);
float g = sqrt(1-f/4);
vec3 n;
n.xy = fenc*g;
n.z = 1-f/2;
return n;
}
vec4 getPosition(vec2 pos_screen)
{
float depth = texture2D(depthMap, pos_screen.xy).r;
vec2 sc = pos_screen.xy*2.0;
sc -= vec2(1.0,1.0);
vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
vec4 pos = inv_proj * ndc;
pos /= pos.w;
pos.w = 1.0;
return pos;
}
vec3 decode_normal(vec2 enc);
vec4 getPosition(vec2 pos_screen);
void main()
{

View File

@@ -31,7 +31,6 @@ out vec4 frag_color;
//class 1 -- no shadows
uniform sampler2D diffuseRect;
uniform sampler2D specularRect;
uniform sampler2D depthMap;
@@ -66,61 +65,30 @@ VARYING vec4 vary_fragcoord;
uniform mat4 inv_proj;
uniform vec2 noise_scale;
vec2 encode_normal(vec3 n)
{
float f = sqrt(8 * n.z + 8);
return n.xy / f + 0.5;
}
vec3 decode_normal (vec2 enc)
{
vec2 fenc = enc*4-2;
float f = dot(fenc,fenc);
float g = sqrt(1-f/4);
vec3 n;
n.xy = fenc*g;
n.z = 1-f/2;
return n;
}
vec3 srgb_to_linear(vec3 cs)
{
vec3 low_range = cs / vec3(12.92);
vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
bvec3 lte = lessThanEqual(cs,vec3(0.04045));
#ifdef OLD_SELECT
vec3 result;
result.r = lte.r ? low_range.r : high_range.r;
result.g = lte.g ? low_range.g : high_range.g;
result.b = lte.b ? low_range.b : high_range.b;
return result;
#else
return mix(high_range, low_range, lte);
#endif
}
vec3 decode_normal(vec2 enc);
vec4 getPosition(vec2 pos_screen);
vec4 srgb_to_linear(vec4 cs);
vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
ret.rgb = srgb_to_linear(ret.rgb);
vec2 dist = tc-vec2(0.5);
float det = max(1.0-lod/(proj_lod*0.5), 0.0);
float d = dot(dist,dist);
ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0)+det, 1.0);
ret = srgb_to_linear(ret);
vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
float det = min(lod/(proj_lod*0.5), 1.0);
float d = min(dist.x, dist.y);
d *= min(1, d * (proj_lod - lod));
float edge = 0.25*det;
ret *= clamp(d/edge, 0.0, 1.0);
return ret;
}
vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
ret.rgb = srgb_to_linear(ret.rgb);
ret = srgb_to_linear(ret);
vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
float det = min(lod/(proj_lod*0.5), 1.0);
@@ -137,7 +105,7 @@ vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
ret.rgb = srgb_to_linear(ret.rgb);
ret = srgb_to_linear(ret);
vec2 dist = tc-vec2(0.5);
@@ -148,19 +116,6 @@ vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
return ret;
}
vec4 getPosition(vec2 pos_screen)
{
float depth = texture2D(depthMap, pos_screen.xy).r;
vec2 sc = pos_screen.xy*2.0;
sc -= vec2(1.0,1.0);
vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
vec4 pos = inv_proj * ndc;
pos /= pos.w;
pos.w = 1.0;
return pos;
}
void main()
{
vec4 frag = vary_fragcoord;
@@ -175,8 +130,9 @@ void main()
{
discard;
}
vec3 norm = texture2D(normalMap, frag.xy).xyz;
float envIntensity = norm.z;
norm = decode_normal(norm.xy);
@@ -205,12 +161,12 @@ void main()
lv = proj_origin-pos.xyz;
lv = normalize(lv);
float da = dot(norm, lv);
vec3 col = vec3(0,0,0);
vec3 diff_tex = texture2D(diffuseRect, frag.xy).rgb;
vec3 dlit = vec3(0, 0, 0);
float noise = texture2D(noiseMap, frag.xy*noise_scale).b;
if (proj_tc.z > 0.0 &&
proj_tc.x < 1.0 &&
@@ -223,32 +179,34 @@ void main()
if (da > 0.0)
{
lit = da * dist_atten * noise;
float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
float lod = diff * proj_lod;
vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
dlit = color.rgb * plcol.rgb * plcol.a;
lit = da * dist_atten * noise;
col = dlit*lit*diff_tex;
amb_da += (da*0.5)*proj_ambiance;
}
//float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod);
amb_da += (da*da*0.5+0.5)*proj_ambiance;
amb_da *= dist_atten * noise;
amb_da = min(amb_da, 1.0-lit);
col += amb_da*color.rgb*diff_tex*amb_plcol.rgb*amb_plcol.a;
col += amb_da*color*diff_tex*amb_plcol.rgb*amb_plcol.a;
}
vec4 spec = texture2D(specularRect, frag.xy);
if (spec.a > 0.0)
{
dlit *= min(da*6.0, 1.0) * dist_atten;
@@ -291,21 +249,21 @@ void main()
if (stc.z > 0.0)
{
stc /= stc.w;
float fatten = clamp(envIntensity*envIntensity+envIntensity*0.25, 0.25, 1.0);
stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);
if (stc.x < 1.0 &&
stc.y < 1.0 &&
stc.x > 0.0 &&
stc.y > 0.0)
{
col += color.rgb*texture2DLodSpecular(projectionMap, stc.xy, proj_lod).rgb*spec.rgb;
col += color.rgb * texture2DLodSpecular(projectionMap, stc.xy, (1 - spec.a) * (proj_lod * 0.6)).rgb * envIntensity;
}
}
}
}
//not sure why, but this line prevents MATBUG-194
col = max(col, vec3(0.0));
frag_color.rgb = col;
frag_color.a = 0.0;
}

View File

@@ -53,34 +53,8 @@ uniform mat4 inv_proj;
uniform vec4 viewport;
uniform vec2 noise_scale;
vec2 encode_normal(vec3 n)
{
float f = sqrt(8 * n.z + 8);
return n.xy / f + 0.5;
}
vec3 decode_normal (vec2 enc)
{
vec2 fenc = enc*4-2;
float f = dot(fenc,fenc);
float g = sqrt(1-f/4);
vec3 n;
n.xy = fenc*g;
n.z = 1-f/2;
return n;
}
vec4 getPosition(vec2 pos_screen)
{
float depth = texture2D(depthMap, pos_screen.xy).r;
vec2 sc = pos_screen.xy*2.0;
sc -= vec2(1.0,1.0);
vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
vec4 pos = inv_proj * ndc;
pos /= pos.w;
pos.w = 1.0;
return pos;
}
vec3 decode_normal(vec2 enc);
vec4 getPosition(vec2 pos_screen);
void main()
{

View File

@@ -37,25 +37,7 @@ VARYING vec2 vary_fragcoord;
//uniform float display_gamma;
vec3 linear_to_srgb(vec3 cl)
{
cl = clamp(cl, vec3(0), vec3(1));
vec3 low_range = cl * 12.92;
vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
bvec3 lt = lessThan(cl,vec3(0.0031308));
#ifdef OLD_SELECT
vec3 result;
result.r = lt.r ? low_range.r : high_range.r;
result.g = lt.g ? low_range.g : high_range.g;
result.b = lt.b ? low_range.b : high_range.b;
return result;
#else
return mix(high_range, low_range, lt);
#endif
}
vec3 linear_to_srgb(vec3 cl);
void main()
{

View File

@@ -47,18 +47,7 @@ VARYING vec2 vary_fragcoord;
uniform mat4 inv_proj;
uniform vec2 screen_res;
vec4 getPosition(vec2 pos_screen)
{
float depth = texture2DRect(depthMap, pos_screen.xy).a;
vec2 sc = pos_screen.xy*2.0;
sc /= screen_res;
sc -= vec2(1.0,1.0);
vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
vec4 pos = inv_proj * ndc;
pos /= pos.w;
pos.w = 1.0;
return pos;
}
vec4 getPosition(vec2 pos_screen);
void main()
{

View File

@@ -74,53 +74,9 @@ vec3 vary_AtmosAttenuation;
uniform mat4 inv_proj;
vec3 srgb_to_linear(vec3 cs)
{
vec3 low_range = cs / vec3(12.92);
vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
bvec3 lte = lessThanEqual(cs,vec3(0.04045));
#ifdef OLD_SELECT
vec3 result;
result.r = lte.r ? low_range.r : high_range.r;
result.g = lte.g ? low_range.g : high_range.g;
result.b = lte.b ? low_range.b : high_range.b;
return result;
#else
return mix(high_range, low_range, lte);
#endif
}
vec3 linear_to_srgb(vec3 cl)
{
vec3 low_range = cl * 12.92;
vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
bvec3 lt = lessThan(cl,vec3(0.0031308));
#ifdef OLD_SELECT
vec3 result;
result.r = lt.r ? low_range.r : high_range.r;
result.g = lt.g ? low_range.g : high_range.g;
result.b = lt.b ? low_range.b : high_range.b;
return result;
#else
return mix(high_range, low_range, lt);
#endif
}
vec3 decode_normal (vec2 enc)
{
vec2 fenc = enc*4-2;
float f = dot(fenc,fenc);
float g = sqrt(1-f/4);
vec3 n;
n.xy = fenc*g;
n.z = 1-f/2;
return n;
}
vec3 decode_normal(vec2 enc);
vec3 srgb_to_linear(vec3 cs);
vec3 linear_to_srgb(vec3 cl);
vec4 getPosition_d(vec2 pos_screen, float depth)
{
@@ -133,12 +89,6 @@ vec4 getPosition_d(vec2 pos_screen, float depth)
return pos;
}
vec4 getPosition(vec2 pos_screen)
{ //get position in screen space (world units) given window coordinate and depth map
float depth = texture2D(depthMap, pos_screen.xy).a;
return getPosition_d(pos_screen, depth);
}
vec3 getPositionEye()
{
return vary_PositionEye;

View File

@@ -23,7 +23,6 @@
* $/LicenseInfo$
*/
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
@@ -56,9 +55,10 @@ uniform float far_clip;
uniform vec3 proj_origin; //origin of projection to be used for angular attenuation
uniform float sun_wash;
uniform float size;
uniform vec3 color;
uniform float falloff;
uniform float size;
VARYING vec3 trans_center;
VARYING vec4 vary_fragcoord;
@@ -66,67 +66,30 @@ VARYING vec4 vary_fragcoord;
uniform mat4 inv_proj;
uniform vec2 noise_scale;
vec2 encode_normal(vec3 n)
{
float f = sqrt(8 * n.z + 8);
return n.xy / f + 0.5;
}
vec3 decode_normal (vec2 enc)
{
vec2 fenc = enc*4-2;
float f = dot(fenc,fenc);
float g = sqrt(1-f/4);
vec3 n;
n.xy = fenc*g;
n.z = 1-f/2;
return n;
}
vec3 srgb_to_linear(vec3 cs)
{
vec3 low_range = cs / vec3(12.92);
vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
bvec3 lte = lessThanEqual(cs,vec3(0.04045));
#ifdef OLD_SELECT
vec3 result;
result.r = lte.r ? low_range.r : high_range.r;
result.g = lte.g ? low_range.g : high_range.g;
result.b = lte.b ? low_range.b : high_range.b;
return result;
#else
return mix(high_range, low_range, lte);
#endif
}
vec4 correctWithGamma(vec4 col)
{
return vec4(srgb_to_linear(col.rgb), col.a);
}
vec3 decode_normal(vec2 enc);
vec4 getPosition(vec2 pos_screen);
vec4 srgb_to_linear(vec4 cs);
vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
ret = correctWithGamma(ret);
vec2 dist = tc-vec2(0.5);
float det = max(1.0-lod/(proj_lod*0.5), 0.0);
float d = dot(dist,dist);
ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0)+det, 1.0);
ret = srgb_to_linear(ret);
vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
float det = min(lod/(proj_lod*0.5), 1.0);
float d = min(dist.x, dist.y);
d *= min(1, d * (proj_lod - lod));
float edge = 0.25*det;
ret *= clamp(d/edge, 0.0, 1.0);
return ret;
}
vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
ret = correctWithGamma(ret);
ret = srgb_to_linear(ret);
vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
float det = min(lod/(proj_lod*0.5), 1.0);
@@ -143,7 +106,7 @@ vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
ret = correctWithGamma(ret);
ret = srgb_to_linear(ret);
vec2 dist = tc-vec2(0.5);
@@ -154,19 +117,6 @@ vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
return ret;
}
vec4 getPosition(vec2 pos_screen)
{
float depth = texture2D(depthMap, pos_screen.xy).r;
vec2 sc = pos_screen.xy*2.0;
sc -= vec2(1.0,1.0);
vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
vec4 pos = inv_proj * ndc;
pos /= pos.w;
pos.w = 1.0;
return pos;
}
void main()
{
vec4 frag = vary_fragcoord;
@@ -181,10 +131,11 @@ void main()
{
discard;
}
vec3 norm = texture2D(normalMap, frag.xy).xyz;
float envIntensity = norm.z;
norm = decode_normal(norm.xy);
norm = normalize(norm);
@@ -211,26 +162,21 @@ void main()
lv = proj_origin-pos.xyz;
lv = normalize(lv);
float da = dot(norm, lv);
vec3 col = vec3(0,0,0);
vec3 diff_tex = texture2D(diffuseRect, frag.xy).rgb;
vec4 spec = texture2D(specularRect, frag.xy);
vec3 col = vec3(0,0,0);
vec3 diff_tex = texture2D(diffuseRect, frag.xy).rgb;
vec3 dlit = vec3(0, 0, 0);
float noise = texture2D(noiseMap, frag.xy*noise_scale).b;
vec3 dlit = vec3(0, 0, 0);
if (proj_tc.z > 0.0 &&
proj_tc.x < 1.0 &&
proj_tc.y < 1.0 &&
proj_tc.x > 0.0 &&
proj_tc.y > 0.0)
{
float amb_da = proj_ambiance;
float lit = 0.0;
float amb_da = proj_ambiance;
if (da > 0.0)
{
@@ -238,28 +184,34 @@ void main()
float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
float lod = diff * proj_lod;
vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
dlit = color.rgb * plcol.rgb * plcol.a;
col = dlit*lit*diff_tex;
//amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance;
amb_da += (da*0.5)*proj_ambiance;
}
//float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod);
amb_da += (da*da*0.5+0.5)*proj_ambiance;
amb_da *= dist_atten * noise;
amb_da = min(amb_da, 1.0-lit);
col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a*diff_tex.rgb;
col += amb_da*color*diff_tex*amb_plcol.rgb*amb_plcol.a;
}
vec4 spec = texture2D(specularRect, frag.xy);
if (spec.a > 0.0)
{
dlit *= min(da*6.0, 1.0) * dist_atten;
vec3 npos = -normalize(pos);
//vec3 ref = dot(pos+lv, norm);
@@ -272,17 +224,15 @@ void main()
float gtdenom = 2 * nh;
float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
if (nh > 0.0)
{
float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
col += dlit*scol*spec.rgb;
//col += spec.rgb;
}
}
if (envIntensity > 0.0)
{
vec3 ref = reflect(normalize(pos), norm);
@@ -294,29 +244,27 @@ void main()
if (ds < 0.0)
{
vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));
if (stc.z > 0.0)
{
stc.xy /= stc.w;
stc /= stc.w;
float fatten = clamp(envIntensity*envIntensity+envIntensity*0.5, 0.25, 1.0);
//stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);
stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);
if (stc.x < 1.0 &&
stc.y < 1.0 &&
stc.x > 0.0 &&
stc.y > 0.0)
{
col += color.rgb*texture2DLodSpecular(projectionMap, stc.xy, proj_lod-envIntensity*proj_lod).rgb*spec.rgb;
col += color.rgb * texture2DLodSpecular(projectionMap, stc.xy, (1 - spec.a) * (proj_lod * 0.6)).rgb * envIntensity;
}
}
}
}
//not sure why, but this line prevents MATBUG-194
col = max(col, vec3(0.0));
frag_color.rgb = col;
frag_color.a = 0.0;
}

View File

@@ -37,12 +37,12 @@ uniform sampler2D depthMap;
uniform sampler2D diffuseRect;
uniform vec2 kern_scale;
uniform vec2 ssao_scale;
void main()
{
frag_color[0] = 1.0;
frag_color[1] = texture2D(diffuseRect,vary_fragcoord.xy * kern_scale).r; // Scales to handle lower-res ssao.
frag_color[1] = texture2D(diffuseRect,vary_fragcoord.xy * ssao_scale).r; // Scales to handle lower-res ssao.
frag_color[2] = 1.0;
frag_color[3] = 1.0;
}

View File

@@ -39,11 +39,7 @@ VARYING vec3 vary_normal;
VARYING vec4 vary_texcoord0;
VARYING vec4 vary_texcoord1;
vec2 encode_normal(vec3 n)
{
float f = sqrt(8 * n.z + 8);
return n.xy / f + 0.5;
}
vec2 encode_normal(vec3 n);
void main()
{

View File

@@ -37,11 +37,7 @@ VARYING vec2 vary_texcoord0;
uniform float minimum_alpha;
vec2 encode_normal(vec3 n)
{
float f = sqrt(8 * n.z + 8);
return n.xy / f + 0.5;
}
vec2 encode_normal(vec3 n);
void main()
{

View File

@@ -56,48 +56,8 @@ VARYING vec4 refCoord;
VARYING vec4 littleWave;
VARYING vec4 view;
vec3 srgb_to_linear(vec3 cs)
{
vec3 low_range = cs / vec3(12.92);
vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
bvec3 lte = lessThanEqual(cs,vec3(0.04045));
#ifdef OLD_SELECT
vec3 result;
result.r = lte.r ? low_range.r : high_range.r;
result.g = lte.g ? low_range.g : high_range.g;
result.b = lte.b ? low_range.b : high_range.b;
return result;
#else
return mix(high_range, low_range, lte);
#endif
}
vec3 linear_to_srgb(vec3 cl)
{
cl = clamp(cl, vec3(0), vec3(1));
vec3 low_range = cl * 12.92;
vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
bvec3 lt = lessThan(cl,vec3(0.0031308));
#ifdef OLD_SELECT
vec3 result;
result.r = lt.r ? low_range.r : high_range.r;
result.g = lt.g ? low_range.g : high_range.g;
result.b = lt.b ? low_range.b : high_range.b;
return result;
#else
return mix(high_range, low_range, lt);
#endif
}
vec2 encode_normal(vec3 n)
{
float f = sqrt(8 * n.z + 8);
return n.xy / f + 0.5;
}
vec2 encode_normal(vec3 n);
vec3 encode_diffuse(vec3 color);
vec4 applyWaterFog(vec4 color, vec3 viewVec)
{

View File

@@ -62,29 +62,7 @@ VARYING vec4 littleWave;
VARYING vec4 view;
VARYING vec4 vary_position;
vec3 srgb_to_linear(vec3 cs)
{
vec3 low_range = cs / vec3(12.92);
vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
bvec3 lte = lessThanEqual(cs,vec3(0.04045));
#ifdef OLD_SELECT
vec3 result;
result.r = lte.r ? low_range.r : high_range.r;
result.g = lte.g ? low_range.g : high_range.g;
result.b = lte.b ? low_range.b : high_range.b;
return result;
#else
return mix(high_range, low_range, lte);
#endif
}
vec2 encode_normal(vec3 n)
{
float f = sqrt(8 * n.z + 8);
return n.xy / f + 0.5;
}
vec2 encode_normal(vec3 n);
void main()
{

View File

@@ -22,7 +22,6 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
@@ -35,7 +34,6 @@ uniform sampler2D specularRect;
uniform sampler2D depthMap;
uniform sampler2D normalMap;
uniform samplerCube environmentMap;
uniform sampler2D lightMap;
uniform sampler2D noiseMap;
uniform sampler2D projectionMap;
uniform sampler2D lightFunc;
@@ -54,6 +52,9 @@ uniform float far_clip;
uniform vec3 proj_origin; //origin of projection to be used for angular attenuation
uniform float sun_wash;
// Shadows
uniform sampler2D lightMap;
uniform int proj_shadow_idx;
uniform float shadow_fade;
@@ -67,54 +68,21 @@ VARYING vec4 vary_fragcoord;
uniform mat4 inv_proj;
uniform vec2 noise_scale;
vec2 encode_normal(vec3 n)
{
float f = sqrt(8 * n.z + 8);
return n.xy / f + 0.5;
}
vec3 decode_normal (vec2 enc)
{
vec2 fenc = enc*4-2;
float f = dot(fenc,fenc);
float g = sqrt(1-f/4);
vec3 n;
n.xy = fenc*g;
n.z = 1-f/2;
return n;
}
vec3 srgb_to_linear(vec3 cs)
{
vec3 low_range = cs / vec3(12.92);
vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
bvec3 lte = lessThanEqual(cs,vec3(0.04045));
#ifdef OLD_SELECT
vec3 result;
result.r = lte.r ? low_range.r : high_range.r;
result.g = lte.g ? low_range.g : high_range.g;
result.b = lte.b ? low_range.b : high_range.b;
return result;
#else
return mix(high_range, low_range, lte);
#endif
}
vec3 decode_normal(vec2 enc);
vec4 getPosition(vec2 pos_screen);
vec4 srgb_to_linear(vec4 cs);
vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
ret.rgb = srgb_to_linear(ret.rgb);
vec2 dist = tc-vec2(0.5);
float det = max(1.0-lod/(proj_lod*0.5), 0.0);
float d = dot(dist,dist);
ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0)+det, 1.0);
ret = srgb_to_linear(ret);
vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
float det = min(lod/(proj_lod*0.5), 1.0);
float d = min(dist.x, dist.y);
d *= min(1, d * (proj_lod - lod));
float edge = 0.25*det;
ret *= clamp(d/edge, 0.0, 1.0);
return ret;
}
@@ -122,7 +90,7 @@ vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
ret.rgb = srgb_to_linear(ret.rgb);
ret = srgb_to_linear(ret);
vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
@@ -140,7 +108,7 @@ vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
ret.rgb = srgb_to_linear(ret.rgb);
ret = srgb_to_linear(ret);
vec2 dist = tc-vec2(0.5);
@@ -151,19 +119,6 @@ vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
return ret;
}
vec4 getPosition(vec2 pos_screen)
{
float depth = texture2D(depthMap, pos_screen.xy).r;
vec2 sc = pos_screen.xy*2.0;
sc -= vec2(1.0,1.0);
vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
vec4 pos = inv_proj * ndc;
pos /= pos.w;
pos.w = 1.0;
return pos;
}
void main()
{
vec4 frag = vary_fragcoord;
@@ -178,9 +133,9 @@ void main()
{
discard;
}
float shadow = 1.0;
if (proj_shadow_idx >= 0)
{
vec4 shd = texture2D(lightMap, frag.xy);
@@ -189,9 +144,9 @@ void main()
sh[1] = shd.a;
shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0);
}
vec3 norm = texture2D(normalMap, frag.xy).xyz;
float envIntensity = norm.z;
norm = decode_normal(norm.xy);
@@ -222,7 +177,7 @@ void main()
float da = dot(norm, lv);
vec3 col = vec3(0,0,0);
vec3 diff_tex = texture2D(diffuseRect, frag.xy).rgb;
vec3 dlit = vec3(0, 0, 0);
@@ -235,33 +190,32 @@ void main()
{
float lit = 0.0;
float amb_da = proj_ambiance;
if (da > 0.0)
{
lit = da * dist_atten * noise;
float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
float lod = diff * proj_lod;
vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
dlit = color.rgb * plcol.rgb * plcol.a;
lit = da * dist_atten * noise;
col = dlit*lit*diff_tex*shadow;
amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance;
}
//float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod);
amb_da += (da*da*0.5+0.5)*proj_ambiance;
amb_da *= dist_atten * noise;
amb_da = min(amb_da, 1.0-lit);
col += amb_da*color.rgb*diff_tex*amb_plcol.rgb*amb_plcol.a;
col += amb_da*color*diff_tex*amb_plcol.rgb*amb_plcol.a;
}
@@ -270,7 +224,7 @@ void main()
if (spec.a > 0.0)
{
dlit *= min(da*6.0, 1.0) * dist_atten;
vec3 npos = -normalize(pos);
//vec3 ref = dot(pos+lv, norm);
@@ -283,7 +237,7 @@ void main()
float gtdenom = 2 * nh;
float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
if (nh > 0.0)
{
float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
@@ -303,27 +257,23 @@ void main()
if (ds < 0.0)
{
vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));
stc /= stc.w;
if (stc.z > 0.0)
{
float fatten = clamp(envIntensity*envIntensity+envIntensity*0.25, 0.25, 1.0);
stc /= stc.w;
stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);
if (stc.x < 1.0 &&
stc.y < 1.0 &&
stc.x > 0.0 &&
stc.y > 0.0)
{
col += color.rgb*texture2DLodSpecular(projectionMap, stc.xy, proj_lod).rgb*shadow*spec.rgb;
col += color.rgb * texture2DLodSpecular(projectionMap, stc.xy, (1 - spec.a) * (proj_lod * 0.6)).rgb * shadow * envIntensity;
}
}
}
}
//not sure why, but this line prevents MATBUG-194
col = max(col, vec3(0.0));

View File

@@ -77,59 +77,9 @@ vec3 vary_AtmosAttenuation;
uniform mat4 inv_proj;
vec3 srgb_to_linear(vec3 cs)
{
vec3 low_range = cs / vec3(12.92);
vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
bvec3 lte = lessThanEqual(cs,vec3(0.04045));
#ifdef OLD_SELECT
vec3 result;
result.r = lte.r ? low_range.r : high_range.r;
result.g = lte.g ? low_range.g : high_range.g;
result.b = lte.b ? low_range.b : high_range.b;
return result;
#else
return mix(high_range, low_range, lte);
#endif
}
vec3 linear_to_srgb(vec3 cl)
{
cl = clamp(cl, vec3(0), vec3(1));
vec3 low_range = cl * 12.92;
vec3 high_range = 1.055 * pow(cl, vec3(0.41666)) - 0.055;
bvec3 lt = lessThan(cl,vec3(0.0031308));
#ifdef OLD_SELECT
vec3 result;
result.r = lt.r ? low_range.r : high_range.r;
result.g = lt.g ? low_range.g : high_range.g;
result.b = lt.b ? low_range.b : high_range.b;
return result;
#else
return mix(high_range, low_range, lt);
#endif
}
vec2 encode_normal(vec3 n)
{
float f = sqrt(8 * n.z + 8);
return n.xy / f + 0.5;
}
vec3 decode_normal (vec2 enc)
{
vec2 fenc = enc*4-2;
float f = dot(fenc,fenc);
float g = sqrt(1-f/4);
vec3 n;
n.xy = fenc*g;
n.z = 1-f/2;
return n;
}
vec3 decode_normal(vec2 enc);
vec3 srgb_to_linear(vec3 cs);
vec3 linear_to_srgb(vec3 cl);
vec4 getPosition_d(vec2 pos_screen, float depth)
{
@@ -142,12 +92,6 @@ vec4 getPosition_d(vec2 pos_screen, float depth)
return pos;
}
vec4 getPosition(vec2 pos_screen)
{ //get position in screen space (world units) given window coordinate and depth map
float depth = texture2D(depthMap, pos_screen.xy).r;
return getPosition_d(pos_screen, depth);
}
vec3 getPositionEye()
{
return vary_PositionEye;

View File

@@ -22,7 +22,6 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
@@ -35,7 +34,6 @@ uniform sampler2D specularRect;
uniform sampler2D depthMap;
uniform sampler2D normalMap;
uniform samplerCube environmentMap;
uniform sampler2D lightMap;
uniform sampler2D noiseMap;
uniform sampler2D projectionMap;
uniform sampler2D lightFunc;
@@ -54,12 +52,15 @@ uniform float far_clip;
uniform vec3 proj_origin; //origin of projection to be used for angular attenuation
uniform float sun_wash;
// Shadow
uniform sampler2D lightMap;
uniform int proj_shadow_idx;
uniform float shadow_fade;
uniform float size;
uniform vec3 color;
uniform float falloff;
uniform float size;
VARYING vec3 trans_center;
VARYING vec4 vary_fragcoord;
@@ -67,58 +68,21 @@ VARYING vec4 vary_fragcoord;
uniform mat4 inv_proj;
uniform vec2 noise_scale;
vec2 encode_normal(vec3 n)
{
float f = sqrt(8 * n.z + 8);
return n.xy / f + 0.5;
}
vec3 decode_normal (vec2 enc)
{
vec2 fenc = enc*4-2;
float f = dot(fenc,fenc);
float g = sqrt(1-f/4);
vec3 n;
n.xy = fenc*g;
n.z = 1-f/2;
return n;
}
vec3 srgb_to_linear(vec3 cs)
{
vec3 low_range = cs / vec3(12.92);
vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4));
bvec3 lte = lessThanEqual(cs,vec3(0.04045));
#ifdef OLD_SELECT
vec3 result;
result.r = lte.r ? low_range.r : high_range.r;
result.g = lte.g ? low_range.g : high_range.g;
result.b = lte.b ? low_range.b : high_range.b;
return result;
#else
return mix(high_range, low_range, lte);
#endif
}
vec4 correctWithGamma(vec4 col)
{
return vec4(srgb_to_linear(col.rgb), col.a);
}
vec3 decode_normal(vec2 enc);
vec4 getPosition(vec2 pos_screen);
vec4 srgb_to_linear(vec4 cs);
vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
ret = correctWithGamma(ret);
vec2 dist = tc-vec2(0.5);
float det = max(1.0-lod/(proj_lod*0.5), 0.0);
float d = dot(dist,dist);
ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0)+det, 1.0);
ret = srgb_to_linear(ret);
vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
float det = min(lod/(proj_lod*0.5), 1.0);
float d = min(dist.x, dist.y);
d *= min(1, d * (proj_lod - lod));
float edge = 0.25*det;
ret *= clamp(d/edge, 0.0, 1.0);
return ret;
}
@@ -126,8 +90,8 @@ vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
ret = correctWithGamma(ret);
ret = srgb_to_linear(ret);
vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
float det = min(lod/(proj_lod*0.5), 1.0);
@@ -144,7 +108,7 @@ vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
ret = correctWithGamma(ret);
ret = srgb_to_linear(ret);
vec2 dist = tc-vec2(0.5);
@@ -155,19 +119,6 @@ vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
return ret;
}
vec4 getPosition(vec2 pos_screen)
{
float depth = texture2D(depthMap, pos_screen.xy).r;
vec2 sc = pos_screen.xy*2.0;
sc -= vec2(1.0,1.0);
vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
vec4 pos = inv_proj * ndc;
pos /= pos.w;
pos.w = 1.0;
return pos;
}
void main()
{
vec4 frag = vary_fragcoord;
@@ -182,7 +133,7 @@ void main()
{
discard;
}
float shadow = 1.0;
if (proj_shadow_idx >= 0)
@@ -193,9 +144,11 @@ void main()
sh[1] = shd.a;
shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0);
}
vec3 norm = texture2D(normalMap, frag.xy).xyz;
float envIntensity = norm.z;
norm = decode_normal(norm.xy);
norm = normalize(norm);
@@ -222,24 +175,21 @@ void main()
lv = proj_origin-pos.xyz;
lv = normalize(lv);
float da = dot(norm, lv);
vec3 col = vec3(0,0,0);
vec3 diff_tex = texture2D(diffuseRect, frag.xy).rgb;
vec4 spec = texture2D(specularRect, frag.xy);
float noise = texture2D(noiseMap, frag.xy*noise_scale).b;
vec3 col = vec3(0,0,0);
vec3 diff_tex = texture2D(diffuseRect, frag.xy).rgb;
vec3 dlit = vec3(0, 0, 0);
float noise = texture2D(noiseMap, frag.xy*noise_scale).b;
if (proj_tc.z > 0.0 &&
proj_tc.x < 1.0 &&
proj_tc.y < 1.0 &&
proj_tc.x > 0.0 &&
proj_tc.y > 0.0)
{
float amb_da = proj_ambiance;
float lit = 0.0;
float amb_da = proj_ambiance;
if (da > 0.0)
{
@@ -247,31 +197,34 @@ void main()
float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
float lod = diff * proj_lod;
vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
dlit = color.rgb * plcol.rgb * plcol.a;
col = dlit*lit*diff_tex*shadow;
amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance;
}
//float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod);
amb_da += (da*da*0.5+0.5)*proj_ambiance;
amb_da *= dist_atten * noise;
amb_da = min(amb_da, 1.0-lit);
col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
col += amb_da*color*diff_tex*amb_plcol.rgb*amb_plcol.a;
}
vec4 spec = texture2D(specularRect, frag.xy);
if (spec.a > 0.0)
{
dlit *= min(da*6.0, 1.0) * dist_atten;
vec3 npos = -normalize(pos);
//vec3 ref = dot(pos+lv, norm);
@@ -284,7 +237,7 @@ void main()
float gtdenom = 2 * nh;
float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
if (nh > 0.0)
{
float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
@@ -292,10 +245,6 @@ void main()
//col += spec.rgb;
}
}
if (envIntensity > 0.0)
{
@@ -308,29 +257,24 @@ void main()
if (ds < 0.0)
{
vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));
if (stc.z > 0.0)
{
stc.xy /= stc.w;
stc /= stc.w;
float fatten = clamp(envIntensity*envIntensity+envIntensity*0.5, 0.25, 1.0);
//stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);
stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);
if (stc.x < 1.0 &&
stc.y < 1.0 &&
stc.x > 0.0 &&
stc.y > 0.0)
{
col += color.rgb*texture2DLodSpecular(projectionMap, stc.xy, proj_lod-envIntensity*proj_lod).rgb*shadow*spec.rgb;
col += color.rgb * texture2DLodSpecular(projectionMap, stc.xy, (1 - spec.a) * (proj_lod * 0.6)).rgb * shadow * envIntensity;
}
}
}
}
//not sure why, but this line prevents MATBUG-194
col = max(col, vec3(0.0));

View File

@@ -65,34 +65,8 @@ uniform float shadow_offset;
uniform float spot_shadow_bias;
uniform float spot_shadow_offset;
vec2 encode_normal(vec3 n)
{
float f = sqrt(8 * n.z + 8);
return n.xy / f + 0.5;
}
vec3 decode_normal (vec2 enc)
{
vec2 fenc = enc*4-2;
float f = dot(fenc,fenc);
float g = sqrt(1-f/4);
vec3 n;
n.xy = fenc*g;
n.z = 1-f/2;
return n;
}
vec4 getPosition(vec2 pos_screen)
{
float depth = texture2D(depthMap, pos_screen.xy).r;
vec2 sc = pos_screen.xy*2.0;
sc -= vec2(1.0,1.0);
vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
vec4 pos = inv_proj * ndc;
pos /= pos.w;
pos.w = 1.0;
return pos;
}
vec3 decode_normal(vec2 enc);
vec4 getPosition(vec2 pos_screen);
float calcShadow( sampler2DShadow shadowMap, vec4 stc, vec2 res, vec2 pos_screen )
{

View File

@@ -65,34 +65,25 @@ uniform float shadow_offset;
uniform float spot_shadow_bias;
uniform float spot_shadow_offset;
vec3 decode_normal(vec2 enc);
vec4 getPosition(vec2 pos_screen);
vec2 encode_normal(vec3 n)
{
float f = sqrt(8 * n.z + 8);
return n.xy / f + 0.5;
}
vec3 decode_normal (vec2 enc)
float calcShadow( sampler2DShadow shadowMap, vec4 stc, vec2 res, vec2 pos_screen )
{
vec2 fenc = enc*4-2;
float f = dot(fenc,fenc);
float g = sqrt(1-f/4);
vec3 n;
n.xy = fenc*g;
n.z = 1-f/2;
return n;
}
//stc.x += (((texture2D(noiseMap, pos_screen/128.0).x)-.5)/shadow_res.x); //Random dither.
vec4 getPosition(vec2 pos_screen)
{
float depth = texture2D(depthMap, pos_screen.xy).r;
vec2 sc = pos_screen.xy*2.0;
sc -= vec2(1.0,1.0);
vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
vec4 pos = inv_proj * ndc;
pos /= pos.w;
pos.w = 1.0;
return pos;
vec2 off = vec2(1,1.5)/res;
stc.x = floor(stc.x*res.x + fract(pos_screen.y*(1.0/kern_scale.y)*0.5))*off.x;
float shadow = shadow2D(shadowMap, stc.xyz).x; // cs
shadow += shadow2D(shadowMap, stc.xyz+vec3(off.x*2.0, off.y, 0.0)).x;
shadow += shadow2D(shadowMap, stc.xyz+vec3(off.x, -off.y, 0.0)).x;
shadow += shadow2D(shadowMap, stc.xyz+vec3(-off.x*2.0, off.y, 0.0)).x;
shadow += shadow2D(shadowMap, stc.xyz+vec3(-off.x, -off.y, 0.0)).x;
return shadow;
}
float calcShadow( sampler2DShadow shadowMap, vec4 stc, vec2 res, vec2 pos_screen )

View File

@@ -554,20 +554,21 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
gGL.blendFunc(LLRender::BF_ZERO, LLRender::BF_ONE, // don't touch color
LLRender::BF_ONE, LLRender::BF_ONE); // add to alpha (glow)
emissive_shader->bind();
//emissive_shader->bind();
// glow doesn't use vertex colors from the mesh data
// Singu Note: Pull attribs from shader, since we always have one here.
params.mVertexBuffer->setBuffer(emissive_shader->mAttributeMask);
// Singu Note: To avoid ridiculous shader bind cost, simply re-use prior shader, but let llvertexbuffer replace the color attrib ptr with the emissive one.
params.mVertexBuffer->setBuffer(current_shader->mAttributeMask | LLVertexBuffer::MAP_EMISSIVE);
// do the actual drawing, again
params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
//current_shader->bind();
// restore our alpha blend mode
gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor);
current_shader->bind();
}
if (tex_setup)

View File

@@ -1457,6 +1457,9 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*
}
}
extern int sMaxCacheHit;
extern int sCurCacheHit;
void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
{
if ((avatar->isSelf() && !gAgent.needsRenderAvatar()) || !gMeshRepo.meshRezEnabled())
@@ -1516,44 +1519,57 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
if (buff)
{
if (sShaderLevel > 0)
{ //upload matrix palette to shader
// upload matrix palette to shader
LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT];
U32 count = LLSkinningUtil::getMeshJointCount(skin);
LLSkinningUtil::initSkinningMatrixPalette(mat, count, skin, avatar);
stop_glerror();
F32 mp[LL_MAX_JOINTS_PER_MESH_OBJECT*12];
for (U32 i = 0; i < count; ++i)
{
auto& mesh_cache = avatar->getRiggedMatrixCache();
auto& mesh_id = skin->mMeshID;
auto rigged_matrix_data_iter = find_if(mesh_cache.begin(), mesh_cache.end(), [&mesh_id](decltype(mesh_cache[0]) & entry) { return entry.first == mesh_id; });
if (rigged_matrix_data_iter != avatar->getRiggedMatrixCache().cend())
{
F32* m = (F32*) mat[i].getF32ptr();
LLDrawPoolAvatar::sVertexProgram->uniformMatrix3x4fv(LLViewerShaderMgr::AVATAR_MATRIX,
rigged_matrix_data_iter->second.first,
FALSE,
(GLfloat*)rigged_matrix_data_iter->second.second.data());
LLDrawPoolAvatar::sVertexProgram->uniform1f(LLShaderMgr::AVATAR_MAX_WEIGHT, F32(rigged_matrix_data_iter->second.first - 1));
U32 idx = i*12;
mp[idx+0] = m[0];
mp[idx+1] = m[1];
mp[idx+2] = m[2];
mp[idx+3] = m[12];
mp[idx+4] = m[4];
mp[idx+5] = m[5];
mp[idx+6] = m[6];
mp[idx+7] = m[13];
mp[idx+8] = m[8];
mp[idx+9] = m[9];
mp[idx+10] = m[10];
mp[idx+11] = m[14];
stop_glerror();
}
else
{
// upload matrix palette to shader
LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT];
U32 count = LLSkinningUtil::getMeshJointCount(skin);
LLSkinningUtil::initSkinningMatrixPalette(mat, count, skin, avatar);
LLDrawPoolAvatar::sVertexProgram->uniformMatrix3x4fv(LLViewerShaderMgr::AVATAR_MATRIX,
count,
FALSE,
(GLfloat*) mp);
std::array<F32, LL_MAX_JOINTS_PER_MESH_OBJECT * 12> mp;
LLDrawPoolAvatar::sVertexProgram->uniform1f(LLShaderMgr::AVATAR_MAX_WEIGHT, F32(count-1));
for (U32 i = 0; i < count; ++i)
{
F32* m = (F32*)mat[i].getF32ptr();
U32 idx = i * 12;
mp[idx + 0] = m[0];
mp[idx + 1] = m[1];
mp[idx + 2] = m[2];
mp[idx + 3] = m[12];
mp[idx + 4] = m[4];
mp[idx + 5] = m[5];
mp[idx + 6] = m[6];
mp[idx + 7] = m[13];
mp[idx + 8] = m[8];
mp[idx + 9] = m[9];
mp[idx + 10] = m[10];
mp[idx + 11] = m[14];
}
mesh_cache.emplace_back(std::make_pair( skin->mMeshID, std::make_pair(count, mp) ) );
LLDrawPoolAvatar::sVertexProgram->uniformMatrix3x4fv(LLViewerShaderMgr::AVATAR_MATRIX,
count,
FALSE,
(GLfloat*)mp.data());
LLDrawPoolAvatar::sVertexProgram->uniform1f(LLShaderMgr::AVATAR_MAX_WEIGHT, F32(count - 1));
}
stop_glerror();
}

View File

@@ -607,7 +607,7 @@ void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color)
gGL.diffuseColor4fv(color.mV);
LLVertexBuffer::drawElements(LLRender::TRIANGLES, vol_face.mPositions, vol_face.mTexCoords, vol_face.mNumIndices, vol_face.mIndices);
LLVertexBuffer::drawElements(LLRender::TRIANGLES, vol_face.mNumVertices, vol_face.mPositions, vol_face.mTexCoords, vol_face.mNumIndices, vol_face.mIndices);
if(prev_shader)
{
@@ -1439,152 +1439,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
}
static LLCachedControl<bool> use_transform_feedback("RenderUseTransformFeedback", false);
#ifdef GL_TRANSFORM_FEEDBACK_BUFFER
if (use_transform_feedback &&
gTransformPositionProgram.mProgramObject && //transform shaders are loaded
mVertexBuffer->useVBOs() && //target buffer is in VRAM
!rebuild_weights && //TODO: add support for weights
!volume.isUnique()) //source volume is NOT flexi
{ //use transform feedback to pack vertex buffer
LL_RECORD_BLOCK_TIME(FTM_FACE_GEOM_FEEDBACK);
LLGLEnable discard(GL_RASTERIZER_DISCARD);
LLVertexBuffer* buff = (LLVertexBuffer*) vf.mVertexBuffer.get();
if (vf.mVertexBuffer.isNull() || buff->getNumVerts() != vf.mNumVertices)
{
mVObjp->getVolume()->genTangents(f);
LLFace::cacheFaceInVRAM(vf);
buff = (LLVertexBuffer*) vf.mVertexBuffer.get();
}
LLGLSLShader* cur_shader = LLGLSLShader::sCurBoundShaderPtr;
gGL.pushMatrix();
gGL.loadMatrix(mat_vert_in);
if (rebuild_pos)
{
LL_RECORD_BLOCK_TIME(FTM_FACE_GEOM_FEEDBACK_POSITION);
gTransformPositionProgram.bind();
mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_VERTEX, mGeomIndex, mGeomCount);
U8 index = mTextureIndex < 255 ? mTextureIndex : 0;
S32 val = 0;
U8* vp = (U8*) &val;
vp[0] = index;
vp[1] = 0;
vp[2] = 0;
vp[3] = 0;
gTransformPositionProgram.uniform1i(sTextureIndexIn, val);
glBeginTransformFeedback(GL_POINTS);
buff->setBuffer(LLVertexBuffer::MAP_VERTEX);
push_for_transform(buff, vf.mNumVertices, mGeomCount);
glEndTransformFeedback();
}
if (rebuild_color)
{
LL_RECORD_BLOCK_TIME(FTM_FACE_GEOM_FEEDBACK_COLOR);
gTransformColorProgram.bind();
mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_COLOR, mGeomIndex, mGeomCount);
S32 val = *((S32*) color.mV);
gTransformColorProgram.uniform1i(sColorIn, val);
glBeginTransformFeedback(GL_POINTS);
buff->setBuffer(LLVertexBuffer::MAP_VERTEX);
push_for_transform(buff, vf.mNumVertices, mGeomCount);
glEndTransformFeedback();
}
if (rebuild_emissive)
{
LL_RECORD_BLOCK_TIME(FTM_FACE_GEOM_FEEDBACK_EMISSIVE);
gTransformColorProgram.bind();
mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_EMISSIVE, mGeomIndex, mGeomCount);
U8 glow = (U8) llclamp((S32) (getTextureEntry()->getGlow()*255), 0, 255);
S32 glow32 = glow |
(glow << 8) |
(glow << 16) |
(glow << 24);
gTransformColorProgram.uniform1i(sColorIn, glow32);
glBeginTransformFeedback(GL_POINTS);
buff->setBuffer(LLVertexBuffer::MAP_VERTEX);
push_for_transform(buff, vf.mNumVertices, mGeomCount);
glEndTransformFeedback();
}
if (rebuild_normal)
{
LL_RECORD_BLOCK_TIME(FTM_FACE_GEOM_FEEDBACK_NORMAL);
gTransformNormalProgram.bind();
mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_NORMAL, mGeomIndex, mGeomCount);
glBeginTransformFeedback(GL_POINTS);
buff->setBuffer(LLVertexBuffer::MAP_NORMAL);
push_for_transform(buff, vf.mNumVertices, mGeomCount);
glEndTransformFeedback();
}
if (rebuild_tangent)
{
LL_RECORD_BLOCK_TIME(FTM_FACE_GEOM_TANGENT);
gTransformTangentProgram.bind();
mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_TANGENT, mGeomIndex, mGeomCount);
glBeginTransformFeedback(GL_POINTS);
buff->setBuffer(LLVertexBuffer::MAP_TANGENT);
push_for_transform(buff, vf.mNumVertices, mGeomCount);
glEndTransformFeedback();
}
if (rebuild_tcoord)
{
LL_RECORD_BLOCK_TIME(FTM_FACE_GEOM_FEEDBACK_TEXTURE);
gTransformTexCoordProgram.bind();
mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_TEXCOORD0, mGeomIndex, mGeomCount);
glBeginTransformFeedback(GL_POINTS);
buff->setBuffer(LLVertexBuffer::MAP_TEXCOORD0);
push_for_transform(buff, vf.mNumVertices, mGeomCount);
glEndTransformFeedback();
bool do_bump = bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1);
if (do_bump)
{
mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_TEXCOORD1, mGeomIndex, mGeomCount);
glBeginTransformFeedback(GL_POINTS);
buff->setBuffer(LLVertexBuffer::MAP_TEXCOORD0);
push_for_transform(buff, vf.mNumVertices, mGeomCount);
glEndTransformFeedback();
}
}
glBindBufferARB(GL_TRANSFORM_FEEDBACK_BUFFER, 0);
gGL.popMatrix();
if (cur_shader)
{
cur_shader->bind();
}
}
else
#endif
{
//if it's not fullbright and has no normals, bake sunlight based on face normal
//bool bake_sunlight = !getTextureEntry()->getFullbright() &&

View File

@@ -312,7 +312,7 @@ void LLFloaterChat::addChatHistory(const LLChat& chat, bool log_to_file)
// add objects as transient speakers that can be muted
if (chat.mSourceType == CHAT_SOURCE_OBJECT)
{
LLLocalSpeakerMgr::getInstance()->setSpeaker(chat.mFromID, chat.mFromName, LLSpeaker::STATUS_NOT_IN_CHANNEL, LLSpeaker::SPEAKER_OBJECT);
LLLocalSpeakerMgr::getInstance()->setSpeaker({ chat.mFromID, LLSpeaker::SPEAKER_OBJECT, LLSpeaker::STATUS_NOT_IN_CHANNEL, boost::none, boost::none, chat.mFromName });
}
// start tab flashing on incoming text from other users (ignoring system text, etc)

View File

@@ -54,6 +54,7 @@
#include "llfloaterchat.h" // for add_chat_history()
#include "lloverlaybar.h" // for gOverlayBar
#include "lluictrlfactory.h"
#include "llcheckboxctrl.h"
#include "hippogridmanager.h"
@@ -183,6 +184,8 @@ LLNotifyBox::LLNotifyBox(LLNotificationPtr notification)
bool layout_script_dialog(notification->getName() == "ScriptDialog" || notification->getName() == "ScriptDialogGroup");
LLRect rect = mIsTip ? getNotifyTipRect(message)
: getNotifyRect(is_textbox ? 10 : mNumOptions, layout_script_dialog, mIsCaution);
if ((form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_DEFAULT_RESPONSE || form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_LAST_RESPONSE))
rect.mBottom -= BTN_HEIGHT;
setRect(rect);
setFollows(mIsTip ? (FOLLOWS_BOTTOM|FOLLOWS_RIGHT) : (FOLLOWS_TOP|FOLLOWS_RIGHT));
setBackgroundVisible(FALSE);
@@ -359,6 +362,45 @@ LLNotifyBox::LLNotifyBox(LLNotificationPtr notification)
addButton("OK", "OK", false, true, layout_script_dialog);
mAddedDefaultBtn = true;
}
std::string check_title;
if (form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_DEFAULT_RESPONSE)
{
check_title = LLNotificationTemplates::instance().getGlobalString("skipnexttime");
}
else if (form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_LAST_RESPONSE)
{
check_title = LLNotificationTemplates::instance().getGlobalString("alwayschoose");
}
if (!check_title.empty())
{
const LLFontGL* font = LLResMgr::getInstance()->getRes(LLFONT_SANSSERIF);
S32 line_height = llfloor(font->getLineHeight() + 0.99f);
// Extend dialog for "check next time"
S32 max_msg_width = getRect().getWidth() - HPAD * 9;
S32 check_width = S32(font->getWidth(check_title) + 0.99f) + 16;
max_msg_width = llmax(max_msg_width, check_width);
S32 msg_x = (getRect().getWidth() - max_msg_width) / 2;
LLRect check_rect;
check_rect.setOriginAndSize(msg_x, BOTTOM_PAD + BTN_HEIGHT + VPAD*2 + (BTN_HEIGHT + VPAD) * (mNumButtons / 3),
max_msg_width, line_height);
LLCheckboxCtrl* check = new LLCheckboxCtrl(std::string("check"), check_rect, check_title, font,
// Lambda abuse.
[this](LLUICtrl* ctrl, const LLSD& param)
{
this->mNotification->setIgnored(ctrl->getValue());
});
check->setEnabledColor(LLUI::sColorsGroup->getColor(mIsCaution ? "AlertCautionTextColor" : "AlertTextColor"));
if (mIsCaution)
{
check->setButtonColor(LLUI::sColorsGroup->getColor("ButtonCautionImageColor"));
}
addChild(check);
}
if (++sNotifyBoxCount <= 0)
LL_WARNS() << "A notification was mishandled. sNotifyBoxCount = " << sNotifyBoxCount << LL_ENDL;

View File

@@ -58,10 +58,15 @@ LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source,
mSpeakerClearListener = new SpeakerClearListener(*this);
//mSpeakerModeratorListener = new SpeakerModeratorUpdateListener(*this);
mSpeakerMuteListener = new SpeakerMuteListener(*this);
mSpeakerBatchBeginListener = new SpeakerBatchBeginListener(*this);
mSpeakerBatchEndListener = new SpeakerBatchEndListener(*this);
mSpeakerSortingUpdateListener = new SpeakerSortingUpdateListener(*this);
mSpeakerMgr->addListener(mSpeakerAddListener, "add");
mSpeakerMgr->addListener(mSpeakerRemoveListener, "remove");
mSpeakerMgr->addListener(mSpeakerClearListener, "clear");
mSpeakerMgr->addListener(mSpeakerBatchBeginListener, "batch_begin");
mSpeakerMgr->addListener(mSpeakerBatchEndListener, "batch_end");
mSpeakerMgr->addListener(mSpeakerSortingUpdateListener, "update_sorting");
//mSpeakerMgr->addListener(mSpeakerModeratorListener, "update_moderator");
}
@@ -226,6 +231,11 @@ void LLParticipantList::handleSpeakerSelect()
void LLParticipantList::refreshSpeakers()
{
if (mUpdateTimer.getElapsedTimeF32() < .5f)
{
return;
}
mUpdateTimer.reset();
// store off current selection and scroll state to preserve across list rebuilds
const S32 scroll_pos = mAvatarList->getScrollInterface()->getScrollPos();
@@ -236,27 +246,42 @@ void LLParticipantList::refreshSpeakers()
// panel and hasn't been motionless for more than a few seconds. see DEV-6655 -MG
LLRect screen_rect;
localRectToScreen(getLocalRect(), &screen_rect);
mSpeakerMgr->update(!(screen_rect.pointInRect(gViewerWindow->getCurrentMouseX(), gViewerWindow->getCurrentMouseY()) && gMouseIdleTimer.getElapsedTimeF32() < 5.f));
bool resort_ok = !(screen_rect.pointInRect(gViewerWindow->getCurrentMouseX(), gViewerWindow->getCurrentMouseY()) && gMouseIdleTimer.getElapsedTimeF32() < 5.f);
mSpeakerMgr->update(resort_ok);
bool re_sort = false;
int start_pos = llmax(0, scroll_pos - 20);
int end_pos = scroll_pos + mAvatarList->getLinesPerPage() + 20;
std::vector<LLScrollListItem*> items = mAvatarList->getAllData();
if (start_pos >= items.size())
{
return;
}
int count = 0;
for (std::vector<LLScrollListItem*>::iterator item_it = items.begin(); item_it != items.end(); ++item_it)
{
LLScrollListItem* itemp = (*item_it);
LLPointer<LLSpeaker> speakerp = mSpeakerMgr->findSpeaker(itemp->getUUID());
if (speakerp.isNull()) continue;
if (LLScrollListCell* icon_cell = itemp->getColumn(0))
++count;
// Color changes. Only perform for rows that are near or in the viewable area.
if (count > start_pos && count <= end_pos)
{
if (speakerp->mStatus == LLSpeaker::STATUS_MUTED)
if (LLScrollListCell* icon_cell = itemp->getColumn(0))
{
icon_cell->setValue("mute_icon.tga");
static const LLCachedControl<LLColor4> sAscentMutedColor("AscentMutedColor");
icon_cell->setColor(speakerp->mModeratorMutedVoice ? /*LLColor4::grey*/sAscentMutedColor : LLColor4(1.f, 71.f / 255.f, 71.f / 255.f, 1.f));
}
else
{
switch(llmin(2, llfloor((speakerp->mSpeechVolume / LLVoiceClient::OVERDRIVEN_POWER_LEVEL) * 3.f)))
if (speakerp->mStatus == LLSpeaker::STATUS_MUTED)
{
icon_cell->setValue("mute_icon.tga");
static const LLCachedControl<LLColor4> sAscentMutedColor("AscentMutedColor");
icon_cell->setColor(speakerp->mModeratorMutedVoice ? /*LLColor4::grey*/sAscentMutedColor : LLColor4(1.f, 71.f / 255.f, 71.f / 255.f, 1.f));
}
else
{
switch (llmin(2, llfloor((speakerp->mSpeechVolume / LLVoiceClient::OVERDRIVEN_POWER_LEVEL) * 3.f)))
{
case 0:
icon_cell->setValue("icn_active-speakers-dot-lvl0.tga");
break;
@@ -266,62 +291,66 @@ void LLParticipantList::refreshSpeakers()
case 2:
icon_cell->setValue("icn_active-speakers-dot-lvl2.tga");
break;
}
// non voice speakers have hidden icons, render as transparent
icon_cell->setColor(speakerp->mStatus > LLSpeaker::STATUS_VOICE_ACTIVE ? LLColor4::transparent : speakerp->mDotColor);
}
// non voice speakers have hidden icons, render as transparent
icon_cell->setColor(speakerp->mStatus > LLSpeaker::STATUS_VOICE_ACTIVE ? LLColor4::transparent : speakerp->mDotColor);
}
}
// update name column
if (LLScrollListCell* name_cell = itemp->getColumn(1))
{
if (speakerp->mStatus == LLSpeaker::STATUS_NOT_IN_CHANNEL)
// update name column
if (LLScrollListCell* name_cell = itemp->getColumn(1))
{
// draw inactive speakers in different color
static const LLCachedControl<LLColor4> sSpeakersInactive(gColors, "SpeakersInactive");
name_cell->setColor(sSpeakersInactive);
}
else
{
// <edit>
bool found = mShowTextChatters || speakerp->mID == gAgentID;
const LLWorld::region_list_t& regions = LLWorld::getInstance()->getRegionList();
for (LLWorld::region_list_t::const_iterator iter = regions.begin(); !found && iter != regions.end(); ++iter)
if (speakerp->mStatus == LLSpeaker::STATUS_NOT_IN_CHANNEL)
{
// Are they in this sim?
if (const LLViewerRegion* regionp = *iter)
if (std::find(regionp->mMapAvatarIDs.begin(), regionp->mMapAvatarIDs.end(), speakerp->mID) != regionp->mMapAvatarIDs.end())
found = true;
}
if (!found)
{
static const LLCachedControl<LLColor4> sSpeakersGhost(gColors, "SpeakersGhost");
name_cell->setColor(sSpeakersGhost);
// draw inactive speakers in different color
static const LLCachedControl<LLColor4> sSpeakersInactive(gColors, "SpeakersInactive");
name_cell->setColor(sSpeakersInactive);
}
else
// </edit>
{
static const LLCachedControl<LLColor4> sDefaultListText(gColors, "DefaultListText");
name_cell->setColor(sDefaultListText);
// <edit>
bool found = mShowTextChatters || speakerp->mID == gAgentID;
const LLWorld::region_list_t& regions = LLWorld::getInstance()->getRegionList();
for (LLWorld::region_list_t::const_iterator iter = regions.begin(); !found && iter != regions.end(); ++iter)
{
// Are they in this sim?
if (const LLViewerRegion* regionp = *iter)
if (std::find(regionp->mMapAvatarIDs.begin(), regionp->mMapAvatarIDs.end(), speakerp->mID) != regionp->mMapAvatarIDs.end())
found = true;
}
if (!found)
{
static const LLCachedControl<LLColor4> sSpeakersGhost(gColors, "SpeakersGhost");
name_cell->setColor(sSpeakersGhost);
}
else
// </edit>
{
static const LLCachedControl<LLColor4> sDefaultListText(gColors, "DefaultListText");
name_cell->setColor(sDefaultListText);
}
}
}
}
// update name column. Need to update all rows to make name sorting behave correctly.
if (LLScrollListCell* name_cell = itemp->getColumn(1))
{
std::string speaker_name = speakerp->mDisplayName.empty() ? LLCacheName::getDefaultName() : speakerp->mDisplayName;
if (speakerp->mIsModerator)
speaker_name += " " + getString("moderator_label");
name_cell->setValue(speaker_name);
if (name_cell->getValue().asString() != speaker_name)
{
re_sort = true;
name_cell->setValue(speaker_name);
}
static_cast<LLScrollListText*>(name_cell)->setFontStyle(speakerp->mIsModerator ? LLFontGL::BOLD : LLFontGL::NORMAL);
}
// update speaking order column
if (LLScrollListCell* speaking_status_cell = itemp->getColumn(2))
{
// since we are forced to sort by text, encode sort order as string
// print speaking ordinal in a text-sorting friendly manner
speaking_status_cell->setValue(llformat("%010d", speakerp->mSortIndex));
}
}
// we potentially modified the sort order by touching the list items
mAvatarList->setNeedsSort();
if (re_sort)
{
mAvatarList->setNeedsSortColumn(1);
}
// keep scroll value stable
mAvatarList->getScrollInterface()->setScrollPos(scroll_pos);
@@ -378,6 +407,44 @@ bool LLParticipantList::onSpeakerMuteEvent(LLPointer<LLOldEvents::LLEvent> event
return true;
}
void LLParticipantList::onSpeakerBatchBeginEvent()
{
mAvatarList->setSortEnabled(false);
}
void LLParticipantList::onSpeakerBatchEndEvent()
{
mAvatarList->setSortEnabled(true);
}
void LLParticipantList::onSpeakerSortingUpdateEvent()
{
bool re_sort = false;
for (auto&& item : mAvatarList->getAllData())
{
// update speaking order column
if (LLScrollListCell* speaking_status_cell = item->getColumn(2))
{
LLPointer<LLSpeaker> speakerp = mSpeakerMgr->findSpeaker(item->getUUID());
if (speakerp)
{
re_sort = true;
std::string sort_index = llformat("%010d", speakerp->mSortIndex);
// since we are forced to sort by text, encode sort order as string
// print speaking ordinal in a text-sorting friendly manner
if (speaking_status_cell->getValue().asString() != sort_index)
{
speaking_status_cell->setValue(sort_index);
}
}
}
}
if (re_sort)
{
mAvatarList->setNeedsSortColumn(2);
}
}
void LLParticipantList::addAvatarIDExceptAgent(const LLUUID& avatar_id)
{
//if (mExcludeAgent && gAgent.getID() == avatar_id) return;
@@ -468,6 +535,23 @@ bool LLParticipantList::SpeakerMuteListener::handleEvent(LLPointer<LLOldEvents::
return mParent.onSpeakerMuteEvent(event, userdata);
}
bool LLParticipantList::SpeakerBatchBeginListener::handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
{
mParent.onSpeakerBatchBeginEvent();
return true;
}
bool LLParticipantList::SpeakerBatchEndListener::handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
{
mParent.onSpeakerBatchEndEvent();
return true;
}
bool LLParticipantList::SpeakerSortingUpdateListener::handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
{
mParent.onSpeakerSortingUpdateEvent();
return true;
}
// Singu Note: The following functions are actually of the LLParticipantListMenu class, but we haven't married lists with menus yet.
void LLParticipantList::toggleAllowTextChat(const LLSD& userdata)
{

View File

@@ -76,6 +76,9 @@ protected:
bool onClearListEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
//bool onModeratorUpdateEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
bool onSpeakerMuteEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
void onSpeakerBatchBeginEvent();
void onSpeakerBatchEndEvent();
void onSpeakerSortingUpdateEvent();
/**
* List of listeners implementing LLOldEvents::LLSimpleListener.
@@ -126,6 +129,27 @@ protected:
/*virtual*/ bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
};
class SpeakerBatchBeginListener : public BaseSpeakerListener
{
public:
SpeakerBatchBeginListener(LLParticipantList& parent) : BaseSpeakerListener(parent) {}
/*virtual*/ bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
};
class SpeakerBatchEndListener : public BaseSpeakerListener
{
public:
SpeakerBatchEndListener(LLParticipantList& parent) : BaseSpeakerListener(parent) {}
/*virtual*/ bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
};
class SpeakerSortingUpdateListener : public BaseSpeakerListener
{
public:
SpeakerSortingUpdateListener(LLParticipantList& parent) : BaseSpeakerListener(parent) {}
/*virtual*/ bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
};
/**
* Menu used in the participant list.
class LLParticipantListMenu : public LLListContextMenu
@@ -196,12 +220,16 @@ private:
LLSpeakerMgr* mSpeakerMgr;
LLScrollListCtrl* mAvatarList;
bool mShowTextChatters;
LLFrameTimer mUpdateTimer;
LLPointer<SpeakerAddListener> mSpeakerAddListener;
LLPointer<SpeakerRemoveListener> mSpeakerRemoveListener;
LLPointer<SpeakerClearListener> mSpeakerClearListener;
//LLPointer<SpeakerModeratorUpdateListener> mSpeakerModeratorListener;
LLPointer<SpeakerMuteListener> mSpeakerMuteListener;
LLPointer<SpeakerBatchBeginListener> mSpeakerBatchBeginListener;
LLPointer<SpeakerBatchEndListener> mSpeakerBatchEndListener;
LLPointer<SpeakerSortingUpdateListener> mSpeakerSortingUpdateListener;
validate_speaker_callback_t mValidateSpeakerCallback;
};

View File

@@ -6140,7 +6140,7 @@ void pushWireframe(LLDrawable* drawable)
for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)
{
const LLVolumeFace& face = volume->getVolumeFace(i);
LLVertexBuffer::drawElements(LLRender::TRIANGLES, face.mPositions, NULL, face.mNumIndices, face.mIndices);
LLVertexBuffer::drawElements(LLRender::TRIANGLES, face.mNumVertices, face.mPositions, NULL, face.mNumIndices, face.mIndices);
}
}

View File

@@ -1456,7 +1456,7 @@ void pushVerts(LLVolume* volume)
for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)
{
const LLVolumeFace& face = volume->getVolumeFace(i);
LLVertexBuffer::drawElements(LLRender::TRIANGLES, face.mPositions, NULL, face.mNumIndices, face.mIndices);
LLVertexBuffer::drawElements(LLRender::TRIANGLES, face.mNumVertices, face.mPositions, NULL, face.mNumIndices, face.mIndices);
}
}
@@ -2325,11 +2325,11 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume)
llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShader != 0);
LLVertexBuffer::drawElements(LLRender::TRIANGLES, phys_volume->mHullPoints, NULL, phys_volume->mNumHullIndices, phys_volume->mHullIndices);
LLVertexBuffer::drawElements(LLRender::TRIANGLES, phys_volume->mNumHullPoints phys_volume->mHullPoints, NULL, phys_volume->mNumHullIndices, phys_volume->mHullIndices);
gGL.diffuseColor4fv(color.mV);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
LLVertexBuffer::drawElements(LLRender::TRIANGLES, phys_volume->mHullPoints, NULL, phys_volume->mNumHullIndices, phys_volume->mHullIndices);
LLVertexBuffer::drawElements(LLRender::TRIANGLES, phys_volume->mNumHullPoints phys_volume->mHullPoints, NULL, phys_volume->mNumHullIndices, phys_volume->mHullIndices);
}
else
@@ -2406,11 +2406,11 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume)
{
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
gGL.diffuseColor4fv(line_color.mV);
LLVertexBuffer::drawElements(LLRender::TRIANGLES, phys_volume->mHullPoints, NULL, phys_volume->mNumHullIndices, phys_volume->mHullIndices);
LLVertexBuffer::drawElements(LLRender::TRIANGLES, phys_volume->mNumHullPoints, phys_volume->mHullPoints, NULL, phys_volume->mNumHullIndices, phys_volume->mHullIndices);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
gGL.diffuseColor4fv(color.mV);
LLVertexBuffer::drawElements(LLRender::TRIANGLES, phys_volume->mHullPoints, NULL, phys_volume->mNumHullIndices, phys_volume->mHullIndices);
LLVertexBuffer::drawElements(LLRender::TRIANGLES, phys_volume->mNumHullPoints, phys_volume->mHullPoints, NULL, phys_volume->mNumHullIndices, phys_volume->mHullIndices);
}
else
{
@@ -2824,7 +2824,7 @@ void renderRaycast(LLDrawable* drawablep)
{
//render face positions
gGL.diffuseColor4f(0,1,1,0.5f);
LLVertexBuffer::drawElements(LLRender::TRIANGLES, face.mPositions, NULL, face.mNumIndices, face.mIndices);
LLVertexBuffer::drawElements(LLRender::TRIANGLES, face.mNumVertices, face.mPositions, NULL, face.mNumIndices, face.mIndices);
}
if (!volume->isUnique())

View File

@@ -45,31 +45,54 @@
const LLColor4 INACTIVE_COLOR(0.3f, 0.3f, 0.3f, 0.5f);
const LLColor4 ACTIVE_COLOR(0.5f, 0.5f, 0.5f, 1.f);
LLSpeaker::LLSpeaker(const LLUUID& id, const std::string& name, const ESpeakerType type) :
mStatus(LLSpeaker::STATUS_TEXT_ONLY),
LLSpeaker::LLSpeaker(const speaker_entry_t& entry) :
mID(entry.id),
mStatus(entry.status),
mType(entry.type),
mIsModerator(entry.moderator != boost::none && *entry.moderator),
mModeratorMutedText(entry.moderator_muted_text != boost::none && *entry.moderator_muted_text),
mModeratorMutedVoice(FALSE),
mLastSpokeTime(0.f),
mSpeechVolume(0.f),
mHasSpoken(FALSE),
mHasLeftCurrentCall(FALSE),
mDotColor(LLColor4::white),
mID(id),
mTyping(FALSE),
mSortIndex(0),
mType(type),
mIsModerator(FALSE),
mModeratorMutedVoice(FALSE),
mModeratorMutedText(FALSE)
mDisplayName(entry.name),
mNeedsResort(true)
{
if (name.empty() && type == SPEAKER_AGENT)
if (mType == SPEAKER_AGENT)
{
lookupName();
}
else
{
mDisplayName = name;
}
}
void LLSpeaker::update(const speaker_entry_t& entry)
{
// keep highest priority status (lowest value) instead of overriding current value
setStatus(llmin(mStatus, entry.status));
if (entry.moderator != boost::none)
{
mIsModerator = *entry.moderator;
}
if (entry.moderator_muted_text != boost::none)
{
mModeratorMutedText = *entry.moderator_muted_text;
};
// RN: due to a weird behavior where IMs from attached objects come from the wearer's agent_id
// we need to override speakers that we think are objects when we find out they are really
// residents
if (entry.type == LLSpeaker::SPEAKER_AGENT)
{
mType = LLSpeaker::SPEAKER_AGENT;
lookupName();
}
if (mDisplayName.empty())
setName(entry.name);
}
void LLSpeaker::lookupName()
{
@@ -77,7 +100,7 @@ void LLSpeaker::lookupName()
{
// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Added: RLVa-1.0.0g
if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES) && gAgentID != mID)
mDisplayName = RlvStrings::getAnonym(mDisplayName);
setName(RlvStrings::getAnonym(mDisplayName));
else
// [/RLVa:KB]
LLAvatarNameCache::get(mID, boost::bind(&LLSpeaker::onNameCache, this, _2));
@@ -88,9 +111,9 @@ void LLSpeaker::onNameCache(const LLAvatarName& full_name)
{
static const LLCachedControl<S32> name_system("SpeakerNameSystem");
if (!name_system)
mDisplayName = gCacheName->cleanFullName(full_name.getLegacyName());
setName(gCacheName->cleanFullName(full_name.getLegacyName()));
else
mDisplayName = full_name.getNSName(name_system);
setName(full_name.getNSName(name_system));
}
bool LLSpeaker::isInVoiceChannel()
@@ -200,7 +223,7 @@ BOOL LLSpeakerActionTimer::tick()
void LLSpeakerActionTimer::unset()
{
mActionCallback = NULL;
mActionCallback = nullptr;
}
LLSpeakersDelayActionsStorage::LLSpeakersDelayActionsStorage(LLSpeakerActionTimer::action_callback_t action_cb, F32 action_delay)
@@ -338,47 +361,42 @@ LLSpeakerMgr::~LLSpeakerMgr()
delete mSpeakerDelayRemover;
}
LLPointer<LLSpeaker> LLSpeakerMgr::setSpeaker(const LLUUID& id, const std::string& name, LLSpeaker::ESpeakerStatus status, LLSpeaker::ESpeakerType type)
void LLSpeakerMgr::setSpeakers(const std::vector<speaker_entry_t>& speakers)
{
if (!speakers.empty())
{
fireEvent(new LLOldEvents::LLEvent(this), "batch_begin");
for (auto entry : speakers)
{
setSpeaker(entry);
}
fireEvent(new LLOldEvents::LLEvent(this), "batch_end");
}
}
LLPointer<LLSpeaker> LLSpeakerMgr::setSpeaker(const speaker_entry_t& entry)
{
LLUUID session_id = getSessionID();
const LLUUID& id = entry.id;
if (id.isNull() || (id == session_id))
{
return NULL;
}
LLPointer<LLSpeaker> speakerp;
if (mSpeakers.find(id) == mSpeakers.end())
auto it = mSpeakers.find(id);
if (it == mSpeakers.end() || it->second.isNull())
{
speakerp = new LLSpeaker(id, name, type);
speakerp->mStatus = status;
mSpeakers.insert(std::make_pair(speakerp->mID, speakerp));
mSpeakersSorted.push_back(speakerp);
LL_DEBUGS("Speakers") << "Added speaker " << id << LL_ENDL;
fireEvent(new LLSpeakerListChangeEvent(this, speakerp->mID), "add");
mSpeakersSorted.emplace_back(new LLSpeaker(entry));
mSpeakers.emplace(id, mSpeakersSorted.back());
fireEvent(new LLSpeakerListChangeEvent(this, id), "add");
}
else
{
speakerp = findSpeaker(id);
if (speakerp.notNull())
{
// keep highest priority status (lowest value) instead of overriding current value
speakerp->mStatus = llmin(speakerp->mStatus, status);
// RN: due to a weird behavior where IMs from attached objects come from the wearer's agent_id
// we need to override speakers that we think are objects when we find out they are really
// residents
if (type == LLSpeaker::SPEAKER_AGENT)
{
speakerp->mType = LLSpeaker::SPEAKER_AGENT;
speakerp->lookupName();
}
}
else
{
LL_WARNS("Speakers") << "Speaker " << id << " not found" << LL_ENDL;
}
it->second->update(entry);
}
mSpeakerDelayRemover->unsetActionTimer(speakerp->mID);
mSpeakerDelayRemover->unsetActionTimer(entry.id);
return speakerp;
}
@@ -426,7 +444,8 @@ void LLSpeakerMgr::update(BOOL resort_ok)
// update status of all current speakers
BOOL voice_channel_active = (!mVoiceChannel && LLVoiceClient::getInstance()->inProximalChannel()) || (mVoiceChannel && mVoiceChannel->isActive());
for (speaker_map_t::iterator speaker_it = mSpeakers.begin(); speaker_it != mSpeakers.end(); speaker_it++)
bool re_sort = false;
for (speaker_map_t::iterator speaker_it = mSpeakers.begin(); speaker_it != mSpeakers.end(); ++speaker_it)
{
LLUUID speaker_id = speaker_it->first;
LLSpeaker* speakerp = speaker_it->second;
@@ -434,7 +453,7 @@ void LLSpeakerMgr::update(BOOL resort_ok)
if (voice_channel_active && LLVoiceClient::getInstance()->getVoiceEnabled(speaker_id))
{
speakerp->mSpeechVolume = LLVoiceClient::getInstance()->getCurrentPower(speaker_id);
BOOL moderator_muted_voice = LLVoiceClient::getInstance()->getIsModeratorMuted(speaker_id);
bool moderator_muted_voice = LLVoiceClient::getInstance()->getIsModeratorMuted(speaker_id);
if (moderator_muted_voice != speakerp->mModeratorMutedVoice)
{
speakerp->mModeratorMutedVoice = moderator_muted_voice;
@@ -444,18 +463,18 @@ void LLSpeakerMgr::update(BOOL resort_ok)
if (LLVoiceClient::getInstance()->getOnMuteList(speaker_id) || speakerp->mModeratorMutedVoice)
{
speakerp->mStatus = LLSpeaker::STATUS_MUTED;
speakerp->setStatus(LLSpeaker::STATUS_MUTED);
}
else if (LLVoiceClient::getInstance()->getIsSpeaking(speaker_id))
{
// reset inactivity expiration
if (speakerp->mStatus != LLSpeaker::STATUS_SPEAKING)
{
speakerp->mLastSpokeTime = mSpeechTimer.getElapsedTimeF32();
speakerp->setSpokenTime(mSpeechTimer.getElapsedTimeF32());
speakerp->mHasSpoken = TRUE;
fireEvent(new LLSpeakerUpdateSpeakerEvent(speakerp), "update_speaker");
}
speakerp->mStatus = LLSpeaker::STATUS_SPEAKING;
speakerp->setStatus(LLSpeaker::STATUS_SPEAKING);
// interpolate between active color and full speaking color based on power of speech output
speakerp->mDotColor = speaking_color;
if (speakerp->mSpeechVolume > LLVoiceClient::OVERDRIVEN_POWER_LEVEL)
@@ -471,12 +490,12 @@ void LLSpeakerMgr::update(BOOL resort_ok)
if (speakerp->mHasSpoken)
{
// have spoken once, not currently speaking
speakerp->mStatus = LLSpeaker::STATUS_HAS_SPOKEN;
speakerp->setStatus(LLSpeaker::STATUS_HAS_SPOKEN);
}
else
{
// default state for being in voice channel
speakerp->mStatus = LLSpeaker::STATUS_VOICE_ACTIVE;
speakerp->setStatus(LLSpeaker::STATUS_VOICE_ACTIVE);
}
}
}
@@ -490,39 +509,53 @@ void LLSpeakerMgr::update(BOOL resort_ok)
}
else
{
speakerp->mStatus = LLSpeaker::STATUS_TEXT_ONLY;
speakerp->setStatus(LLSpeaker::STATUS_TEXT_ONLY);
speakerp->mSpeechVolume = 0.f;
speakerp->mDotColor = ACTIVE_COLOR;
}
}
if (speakerp->mNeedsResort)
{
re_sort = true;
speakerp->mNeedsResort = false;
}
}
if(resort_ok) // only allow list changes when user is not interacting with it
if (resort_ok && re_sort) // only allow list changes when user is not interacting with it
{
// sort by status then time last spoken
std::sort(mSpeakersSorted.begin(), mSpeakersSorted.end(), LLSortRecentSpeakers());
}
// for recent speakers who are not currently speaking, show "recent" color dot for most recent
// fading to "active" color
// for recent speakers who are not currently speaking, show "recent" color dot for most recent
// fading to "active" color
S32 recent_speaker_count = 0;
S32 sort_index = 0;
speaker_list_t::iterator sorted_speaker_it;
for(sorted_speaker_it = mSpeakersSorted.begin();
sorted_speaker_it != mSpeakersSorted.end(); ++sorted_speaker_it)
{
LLPointer<LLSpeaker> speakerp = *sorted_speaker_it;
// color code recent speakers who are not currently speaking
if (speakerp->mStatus == LLSpeaker::STATUS_HAS_SPOKEN)
bool index_changed = false;
S32 recent_speaker_count = 0;
S32 sort_index = 0;
for (speaker_list_t::iterator sorted_speaker_it = mSpeakersSorted.begin();
sorted_speaker_it != mSpeakersSorted.end();
++sorted_speaker_it)
{
speakerp->mDotColor = lerp(speaking_color, ACTIVE_COLOR, clamp_rescale((F32)recent_speaker_count, -2.f, 3.f, 0.f, 1.f));
recent_speaker_count++;
}
LLPointer<LLSpeaker> speakerp = *sorted_speaker_it;
// stuff sort ordinal into speaker so the ui can sort by this value
speakerp->mSortIndex = sort_index++;
// color code recent speakers who are not currently speaking
if (speakerp->mStatus == LLSpeaker::STATUS_HAS_SPOKEN)
{
speakerp->mDotColor = lerp(speaking_color, ACTIVE_COLOR, clamp_rescale((F32)recent_speaker_count, -2.f, 3.f, 0.f, 1.f));
recent_speaker_count++;
}
// stuff sort ordinal into speaker so the ui can sort by this value
if (speakerp->mSortIndex != sort_index++)
{
speakerp->mSortIndex = sort_index-1;
index_changed = true;
}
}
if (index_changed)
{
fireEvent(new LLOldEvents::LLEvent(this), "update_sorting");
}
}
}
@@ -534,13 +567,19 @@ void LLSpeakerMgr::updateSpeakerList()
std::set<LLUUID> participants;
LLVoiceClient::getInstance()->getParticipantList(participants);
// If we are, add all voice client participants to our list of known speakers
std::vector<speaker_entry_t> speakers;
speakers.reserve(participants.size());
for (std::set<LLUUID>::iterator participant_it = participants.begin(); participant_it != participants.end(); ++participant_it)
{
setSpeaker(*participant_it,
LLVoiceClient::getInstance()->getDisplayName(*participant_it),
LLSpeaker::STATUS_VOICE_ACTIVE,
(LLVoiceClient::getInstance()->isParticipantAvatar(*participant_it)?LLSpeaker::SPEAKER_AGENT:LLSpeaker::SPEAKER_EXTERNAL));
speakers.emplace_back(
*participant_it,
(LLVoiceClient::getInstance()->isParticipantAvatar(*participant_it) ? LLSpeaker::SPEAKER_AGENT : LLSpeaker::SPEAKER_EXTERNAL),
LLSpeaker::STATUS_VOICE_ACTIVE,
boost::none,
boost::none,
LLVoiceClient::getInstance()->getDisplayName(*participant_it));
}
setSpeakers(speakers);
}
else
{
@@ -569,10 +608,11 @@ void LLSpeakerMgr::updateSpeakerList()
}
else if (gdatap && gdatap->isMemberDataComplete() && !gdatap->mMembers.empty())
{
std::vector<speaker_entry_t> speakers;
speakers.reserve(gdatap->mMembers.size());
// Add group members when we get the complete list (note: can take a while before we get that list)
LLGroupMgrGroupData::member_list_t::iterator member_it = gdatap->mMembers.begin();
const S32 load_group_max_members = gSavedSettings.getS32("ChatLoadGroupMaxMembers");
S32 updated = 0;
while (member_it != gdatap->mMembers.end())
{
LLGroupMemberData* member = member_it->second;
@@ -581,16 +621,15 @@ void LLSpeakerMgr::updateSpeakerList()
const std::string& localized_online();
if ((member->getOnlineStatus() == localized_online()) && (mSpeakers.find(id) == mSpeakers.end()))
{
LLPointer<LLSpeaker> speakerp = setSpeaker(id, "", LLSpeaker::STATUS_VOICE_ACTIVE, LLSpeaker::SPEAKER_AGENT);
speakerp->mIsModerator = ((member->getAgentPowers() & GP_SESSION_MODERATOR) == GP_SESSION_MODERATOR);
updated++;
speakers.emplace_back(
id,
LLSpeaker::SPEAKER_AGENT,
LLSpeaker::STATUS_VOICE_ACTIVE,
(member->getAgentPowers() & GP_SESSION_MODERATOR) == GP_SESSION_MODERATOR);
}
++member_it;
// Limit the number of "manually updated" participants to a reasonable number to avoid severe fps drop
// *TODO : solve the perf issue of having several hundreds of widgets in the conversation list
if (updated >= load_group_max_members)
break;
}
setSpeakers(speakers);
mSpeakerListUpdated = true;
}
}
@@ -617,12 +656,12 @@ void LLSpeakerMgr::updateSpeakerList()
}
}
// Always add the current agent (it has to be there...). Will do nothing if already there.
setSpeaker(gAgentID, "", LLSpeaker::STATUS_VOICE_ACTIVE, LLSpeaker::SPEAKER_AGENT);
setSpeaker({ gAgentID, LLSpeaker::SPEAKER_AGENT, LLSpeaker::STATUS_VOICE_ACTIVE });
}
void LLSpeakerMgr::setSpeakerNotInChannel(LLSpeaker* speakerp)
{
speakerp->mStatus = LLSpeaker::STATUS_NOT_IN_CHANNEL;
speakerp->setStatus(LLSpeaker::STATUS_NOT_IN_CHANNEL);
speakerp->mDotColor = INACTIVE_COLOR;
mSpeakerDelayRemover->setActionTimer(speakerp->mID);
}
@@ -702,7 +741,7 @@ void LLSpeakerMgr::speakerChatted(const LLUUID& speaker_id)
LLPointer<LLSpeaker> speakerp = findSpeaker(speaker_id);
if (speakerp.notNull())
{
speakerp->mLastSpokeTime = mSpeechTimer.getElapsedTimeF32();
speakerp->setSpokenTime(mSpeechTimer.getElapsedTimeF32());
speakerp->mHasSpoken = TRUE;
fireEvent(new LLSpeakerUpdateSpeakerEvent(speakerp), "update_speaker");
}
@@ -737,6 +776,7 @@ void LLIMSpeakerMgr::setSpeakers(const LLSD& speakers)
{
if ( !speakers.isMap() ) return;
std::vector<speaker_entry_t> speakerentries;
if ( speakers.has("agent_info") && speakers["agent_info"].isMap() )
{
LLSD::map_const_iterator speaker_it;
@@ -744,26 +784,20 @@ void LLIMSpeakerMgr::setSpeakers(const LLSD& speakers)
speaker_it != speakers["agent_info"].endMap();
++speaker_it)
{
LLUUID agent_id(speaker_it->first);
LLPointer<LLSpeaker> speakerp = setSpeaker(
agent_id,
LLStringUtil::null,
LLSpeaker::STATUS_TEXT_ONLY);
if ( speaker_it->second.isMap() )
boost::optional<bool> moderator;
boost::optional<bool> moderator_muted;
if (speaker_it->second.isMap())
{
BOOL is_moderator = speakerp->mIsModerator;
speakerp->mIsModerator = speaker_it->second["is_moderator"];
speakerp->mModeratorMutedText =
speaker_it->second["mutes"]["text"];
// Fire event only if moderator changed
if ( is_moderator != speakerp->mIsModerator )
{
LL_DEBUGS("Speakers") << "Speaker " << agent_id << (is_moderator ? "is now" : "no longer is") << " a moderator" << LL_ENDL;
fireEvent(new LLSpeakerUpdateModeratorEvent(speakerp), "update_moderator");
}
moderator = speaker_it->second["is_moderator"];
moderator_muted = speaker_it->second["mutes"]["text"];
}
speakerentries.emplace_back(
LLUUID(speaker_it->first),
LLSpeaker::SPEAKER_AGENT,
LLSpeaker::STATUS_TEXT_ONLY,
moderator,
moderator_muted
);
}
}
else if ( speakers.has("agents" ) && speakers["agents"].isArray() )
@@ -775,22 +809,20 @@ void LLIMSpeakerMgr::setSpeakers(const LLSD& speakers)
speaker_it != speakers["agents"].endArray();
++speaker_it)
{
const LLUUID agent_id = (*speaker_it).asUUID();
LLPointer<LLSpeaker> speakerp = setSpeaker(
agent_id,
LLStringUtil::null,
LLSpeaker::STATUS_TEXT_ONLY);
speakerentries.emplace_back((*speaker_it).asUUID());
}
}
LLSpeakerMgr::setSpeakers(speakerentries);
}
void LLIMSpeakerMgr::updateSpeakers(const LLSD& update)
{
if ( !update.isMap() ) return;
std::vector<speaker_entry_t> speakerentries;
if ( update.has("agent_updates") && update["agent_updates"].isMap() )
{
LLSD::map_const_iterator update_it;
for(
update_it = update["agent_updates"].beginMap();
@@ -800,8 +832,11 @@ void LLIMSpeakerMgr::updateSpeakers(const LLSD& update)
LLUUID agent_id(update_it->first);
LLPointer<LLSpeaker> speakerp = findSpeaker(agent_id);
LLSD agent_data = update_it->second;
bool new_speaker = false;
boost::optional<bool> moderator;
boost::optional<bool> moderator_muted_text;
LLSD agent_data = update_it->second;
if (agent_data.isMap() && agent_data.has("transition"))
{
if (agent_data["transition"].asString() == "LEAVE" && speakerp.notNull())
@@ -811,15 +846,17 @@ void LLIMSpeakerMgr::updateSpeakers(const LLSD& update)
else if (agent_data["transition"].asString() == "ENTER")
{
// add or update speaker
speakerp = setSpeaker(agent_id);
new_speaker = true;
}
else
{
LL_WARNS() << "bad membership list update from 'agent_updates' for agent " << agent_id << ", transition " << ll_print_sd(agent_data["transition"]) << LL_ENDL;
}
}
if (speakerp.isNull()) continue;
if (speakerp.isNull() && !new_speaker)
{
continue;
}
// should have a valid speaker from this point on
if (agent_data.isMap() && agent_data.has("info"))
@@ -828,21 +865,20 @@ void LLIMSpeakerMgr::updateSpeakers(const LLSD& update)
if (agent_info.has("is_moderator"))
{
BOOL is_moderator = speakerp->mIsModerator;
speakerp->mIsModerator = agent_info["is_moderator"];
// Fire event only if moderator changed
if ( is_moderator != speakerp->mIsModerator )
{
LL_DEBUGS("Speakers") << "Speaker " << agent_id << (is_moderator ? "is now" : "no longer is") << " a moderator" << LL_ENDL;
fireEvent(new LLSpeakerUpdateModeratorEvent(speakerp), "update_moderator");
}
moderator = agent_info["is_moderator"];
}
if (agent_info.has("mutes"))
{
speakerp->mModeratorMutedText = agent_info["mutes"]["text"];
moderator_muted_text = agent_info["mutes"]["text"];
}
}
speakerentries.emplace_back(
agent_id,
LLSpeaker::SPEAKER_AGENT,
LLSpeaker::STATUS_TEXT_ONLY,
moderator,
moderator_muted_text
);
}
}
else if ( update.has("updates") && update["updates"].isMap() )
@@ -864,7 +900,7 @@ void LLIMSpeakerMgr::updateSpeakers(const LLSD& update)
else if ( agent_transition == "ENTER")
{
// add or update speaker
speakerp = setSpeaker(agent_id);
speakerentries.emplace_back(agent_id);
}
else
{
@@ -872,6 +908,7 @@ void LLIMSpeakerMgr::updateSpeakers(const LLSD& update)
}
}
}
LLSpeakerMgr::setSpeakers(speakerentries);
}
void LLIMSpeakerMgr::toggleAllowTextChat(const LLUUID& speaker_id)
@@ -1039,17 +1076,20 @@ void LLLocalSpeakerMgr::updateSpeakerList()
// pick up non-voice speakers in chat range
uuid_vec_t avatar_ids;
LLWorld::getInstance()->getAvatars(&avatar_ids, nullptr, gAgent.getPositionGlobal(), CHAT_NORMAL_RADIUS);
std::vector<speaker_entry_t> speakers;
speakers.reserve(avatar_ids.size());
for (const auto& id : avatar_ids)
{
setSpeaker(id);
speakers.emplace_back(id);
}
setSpeakers(speakers);
// check if text only speakers have moved out of chat range
for (speaker_map_t::iterator speaker_it = mSpeakers.begin(); speaker_it != mSpeakers.end(); ++speaker_it)
{
LLUUID speaker_id = speaker_it->first;
LLSpeaker* speakerp = speaker_it->second;
if (speakerp && speakerp->mStatus == LLSpeaker::STATUS_TEXT_ONLY)
LLPointer<LLSpeaker> speakerp = speaker_it->second;
if (speakerp.notNull() && speakerp->mStatus == LLSpeaker::STATUS_TEXT_ONLY)
{
LLVOAvatar* avatarp = gObjectList.findAvatar(speaker_id);
if (!avatarp || dist_vec_squared(avatarp->getPositionAgent(), gAgent.getPositionAgent()) > CHAT_NORMAL_RADIUS * CHAT_NORMAL_RADIUS)

View File

@@ -56,29 +56,78 @@ public:
STATUS_MUTED
} ESpeakerStatus;
struct speaker_entry_t
{
speaker_entry_t(const LLUUID& id,
LLSpeaker::ESpeakerType type = ESpeakerType::SPEAKER_AGENT,
LLSpeaker::ESpeakerStatus status = ESpeakerStatus::STATUS_TEXT_ONLY,
const boost::optional<bool> moderator = boost::none,
const boost::optional<bool> moderator_muted_text = boost::none,
std::string name = std::string()) :
id(id),
type(type),
status(status),
moderator(moderator),
moderator_muted_text(moderator_muted_text),
name(name)
{}
const LLUUID id;
const LLSpeaker::ESpeakerType type;
const LLSpeaker::ESpeakerStatus status;
const boost::optional<bool> moderator;
const boost::optional<bool> moderator_muted_text;
const std::string name;
};
LLSpeaker(const LLUUID& id, const std::string& name = LLStringUtil::null, const ESpeakerType type = SPEAKER_AGENT);
LLSpeaker(const speaker_entry_t& entry);
~LLSpeaker() {};
void update(const speaker_entry_t& entry);
void lookupName();
void onNameCache(const LLAvatarName& full_name);
bool isInVoiceChannel();
void setStatus(ESpeakerStatus status)
{
if (status != mStatus)
{
mStatus = status;
mNeedsResort = true;
}
}
void setName(const std::string& name)
{
if (name != mDisplayName)
{
mDisplayName = name;
mNeedsResort = true;
}
}
void setSpokenTime(F32 time)
{
if (mLastSpokeTime != time)
{
mLastSpokeTime = time;
mNeedsResort = true;
}
}
LLUUID mID;
ESpeakerStatus mStatus; // current activity status in speech group
ESpeakerType mType : 2;
bool mIsModerator : 1;
bool mModeratorMutedVoice : 1;
bool mModeratorMutedText : 1;
bool mHasSpoken : 1; // has this speaker said anything this session?
bool mHasLeftCurrentCall : 1; // has this speaker left the current voice call?
bool mTyping : 1;
F32 mLastSpokeTime; // timestamp when this speaker last spoke
F32 mSpeechVolume; // current speech amplitude (timea average rms amplitude?)
std::string mDisplayName; // cache user name for this speaker
BOOL mHasSpoken; // has this speaker said anything this session?
BOOL mHasLeftCurrentCall; // has this speaker left the current voice call?
LLColor4 mDotColor;
LLUUID mID;
BOOL mTyping;
bool mNeedsResort;
S32 mSortIndex;
ESpeakerType mType;
BOOL mIsModerator;
BOOL mModeratorMutedVoice;
BOOL mModeratorMutedText;
};
class LLSpeakerUpdateSpeakerEvent : public LLOldEvents::LLEvent
@@ -137,7 +186,7 @@ private:
class LLSpeakerActionTimer : public LLEventTimer
{
public:
typedef boost::function<bool(const LLUUID&)> action_callback_t;
typedef std::function<bool(const LLUUID&)> action_callback_t;
typedef std::map<LLUUID, LLSpeakerActionTimer*> action_timers_map_t;
typedef action_timers_map_t::value_type action_value_t;
typedef action_timers_map_t::const_iterator action_timer_const_iter_t;
@@ -223,6 +272,8 @@ class LLSpeakerMgr : public LLOldEvents::LLObservable
LOG_CLASS(LLSpeakerMgr);
public:
typedef LLSpeaker::speaker_entry_t speaker_entry_t;
LLSpeakerMgr(LLVoiceChannel* channelp);
virtual ~LLSpeakerMgr();
@@ -230,10 +281,9 @@ public:
void update(BOOL resort_ok);
void setSpeakerTyping(const LLUUID& speaker_id, BOOL typing);
void speakerChatted(const LLUUID& speaker_id);
LLPointer<LLSpeaker> setSpeaker(const LLUUID& id,
const std::string& name = LLStringUtil::null,
LLSpeaker::ESpeakerStatus status = LLSpeaker::STATUS_TEXT_ONLY,
LLSpeaker::ESpeakerType = LLSpeaker::SPEAKER_AGENT);
void setSpeakers(const std::vector<speaker_entry_t>& speakers);
LLPointer<LLSpeaker> setSpeaker(const speaker_entry_t& speakers);
BOOL isVoiceActive();

View File

@@ -225,6 +225,7 @@
#include "llfloaterblacklist.h"
#include "scriptcounter.h"
#include "shfloatermediaticker.h"
#include "shupdatechecker.h"
#include "llpacketring.h"
// </edit>
@@ -849,6 +850,7 @@ bool idle_startup()
// Go to the next startup state
LLStartUp::setStartupState( STATE_BROWSER_INIT );
check_for_updates();
return FALSE;
}

View File

@@ -1305,14 +1305,12 @@ void LLTextureCache::writeEntriesAndClose(const std::vector<Entry>& entries)
if (!mReadOnly)
{
LLAPRFile* aprfile = openHeaderEntriesFile(false, (S32)sizeof(EntriesInfo));
for (S32 idx=0; idx<num_entries; idx++)
U64 write_size = U64(sizeof(Entry)) * num_entries;
U64 bytes_written = aprfile->write((void*)(entries.data()), write_size);
if (bytes_written != write_size)
{
S32 bytes_written = aprfile->write((void*)(&entries[idx]), (S32)sizeof(Entry));
if(bytes_written != sizeof(Entry))
{
clearCorruptedCache(); //clear the cache.
return;
}
clearCorruptedCache(); //clear the cache.
return;
}
closeHeaderEntriesFile();
}

View File

@@ -583,11 +583,11 @@ void LLGLTexMemBar::draw()
std::string text = "";
S32 global_raw_memory;
S64 global_raw_memory;
{
global_raw_memory = *AIAccess<S32>(LLImageRaw::sGlobalRawMemory);
global_raw_memory = *AIAccess<S64>(LLImageRaw::sGlobalRawMemory);
}
text = llformat("GL Tot: %d/%d MB Bound: %d/%d MB FBO: %d MB Raw Tot: %d MB Bias: %.2f Cache: %.1f/%.1f MB Net Tot Tex: %.1f MB Tot Obj: %.1f MB Tot Htp: %d",
text = llformat("GL Tot: %d/%d MB Bound: %d/%d MB FBO: %d MB Raw Tot: %lld MB Bias: %.2f Cache: %.1f/%.1f MB Net Tot Tex: %.1f MB Tot Obj: %.1f MB Tot Htp: %d",
total_mem.value(),
max_total_mem.value(),
bound_mem.value(),

View File

@@ -81,6 +81,7 @@
#include "llviewerregion.h"
#include "lldrawpoolwater.h"
#include "lldrawpoolbump.h"
#include "lldrawpoolavatar.h"
#include "llwlparammanager.h"
#include "llwaterparammanager.h"
#include "llpostprocess.h"
@@ -255,11 +256,24 @@ static LLTrace::BlockTimerStatHandle FTM_IMAGE_UPDATE_CLASS("Class");
static LLTrace::BlockTimerStatHandle FTM_IMAGE_UPDATE_BUMP("Bump");
static LLTrace::BlockTimerStatHandle FTM_IMAGE_UPDATE_LIST("List");
static LLTrace::BlockTimerStatHandle FTM_IMAGE_UPDATE_DELETE("Delete");
int sMaxCacheHit = 0;
int sCurCacheHit = 0;
// Paint the display!
void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot, bool tiling)
{
LL_RECORD_BLOCK_TIME(FTM_RENDER);
for (auto avatar : LLCharacter::sInstances)
{
LLVOAvatar* avatarp = dynamic_cast<LLVOAvatar*>(avatar);
if (!avatarp) continue;
if (avatarp->isDead()) continue;
avatarp->clearRiggedMatrixCache();
}
sCurCacheHit = 0;
if (gWindowResized)
{ //skip render on frames where window has been resized
gGL.flush();

View File

@@ -952,6 +952,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
BOOL success = TRUE;
success = loadShaderFile("deferred/components/utilityFuncF.glsl", mVertexShaderLevel[SHADER_DEFERRED], GL_FRAGMENT_SHADER_ARB);
if (success)
{
gDeferredDiffuseProgram.mName = "Deferred Diffuse Shader";
@@ -2533,6 +2535,17 @@ void LLViewerShaderMgr::updateShaderUniforms(LLGLSLShader * shader)
LLWaterParamManager::getInstance()->updateShaderUniforms(shader);
}
/* virtual */ bool LLViewerShaderMgr::attachClassSharedShaders(LLGLSLShader& shader, S32 shader_class)
{
switch (shader_class)
{
case LLViewerShaderMgr::SHADER_DEFERRED:
LL_INFOS() << "deferred/components/utilityFuncF.glsl" << LL_ENDL;
return shader.attachObject("deferred/components/utilityFuncF.glsl");
}
return true;
}
/*static*/ void LLShaderMgr::unloadShaderClass(int shader_class)
{
std::vector<LLGLSLShader *> &shader_list = getGlobalShaderList();

View File

@@ -146,6 +146,8 @@ public:
/* virtual */ void updateShaderUniforms(LLGLSLShader * shader); // Virtual
/* virtual */ bool attachClassSharedShaders(LLGLSLShader& shader, S32 shader_class); // Virtual
private:
std::vector<std::string> mShinyUniforms;

View File

@@ -444,9 +444,9 @@ void reset_statistics()
void output_statistics(void*)
{
S32 global_raw_memory;
S64 global_raw_memory;
{
global_raw_memory = *AIAccess<S32>(LLImageRaw::sGlobalRawMemory);
global_raw_memory = *AIAccess<S64>(LLImageRaw::sGlobalRawMemory);
}
LL_INFOS() << "Number of orphans: " << gObjectList.getOrphanCount() << LL_ENDL;
LL_INFOS() << "Number of dead objects: " << gObjectList.mNumDeadObjects << LL_ENDL;

View File

@@ -65,7 +65,7 @@
// extern
const S32Megabytes gMinVideoRam(32);
const S32Megabytes gMaxVideoRam(1024);
const S32Megabytes gMaxVideoRam(2048);
// statics
@@ -88,11 +88,11 @@ S32 LLViewerTexture::sAuxCount = 0;
LLFrameTimer LLViewerTexture::sEvaluationTimer;
F32 LLViewerTexture::sDesiredDiscardBias = 0.f;
F32 LLViewerTexture::sDesiredDiscardScale = 1.1f;
S32Bytes LLViewerTexture::sBoundTextureMemory;
S32Bytes LLViewerTexture::sTotalTextureMemory;
S64Bytes LLViewerTexture::sBoundTextureMemory;
S64Bytes LLViewerTexture::sTotalTextureMemory;
S32Megabytes LLViewerTexture::sMaxBoundTextureMemory;
S32Megabytes LLViewerTexture::sMaxTotalTextureMem;
S32Bytes LLViewerTexture::sMaxDesiredTextureMem;
S64Bytes LLViewerTexture::sMaxDesiredTextureMem;
S8 LLViewerTexture::sCameraMovingDiscardBias = 0;
F32 LLViewerTexture::sCameraMovingBias = 0.0f ;
S32 LLViewerTexture::sMaxSculptRez = 128 ; //max sculpt image size

View File

@@ -218,11 +218,11 @@ public:
static LLFrameTimer sEvaluationTimer;
static F32 sDesiredDiscardBias;
static F32 sDesiredDiscardScale;
static S32Bytes sBoundTextureMemory;
static S32Bytes sTotalTextureMemory;
static S64Bytes sBoundTextureMemory;
static S64Bytes sTotalTextureMemory;
static S32Megabytes sMaxBoundTextureMemory;
static S32Megabytes sMaxTotalTextureMem;
static S32Bytes sMaxDesiredTextureMem ;
static S64Bytes sMaxDesiredTextureMem ;
static S8 sCameraMovingDiscardBias;
static F32 sCameraMovingBias;
static S32 sMaxSculptRez ;

View File

@@ -746,9 +746,9 @@ void LLViewerTextureList::updateImages(F32 max_time)
}
cleared = FALSE;
S32 global_raw_memory;
S64 global_raw_memory;
{
global_raw_memory = *AIAccess<S32>(LLImageRaw::sGlobalRawMemory);
global_raw_memory = *AIAccess<S64>(LLImageRaw::sGlobalRawMemory);
}
LLViewerStats::getInstance()->mNumImagesStat.addValue(sNumImages);
LLViewerStats::getInstance()->mNumRawImagesStat.addValue(LLImageRaw::sRawImageCount);

View File

@@ -1569,6 +1569,22 @@ BOOL LLViewerWindow::handleDeviceChange(LLWindow *window)
return FALSE;
}
bool LLViewerWindow::handleDPIScaleChange(LLWindow *window, float xDPIScale, float yDPIScale, U32 width, U32 height)
{
LL_INFOS() << "handleDPIScaleChange" << LL_ENDL;
if (mDPIScaleX != xDPIScale || mDPIScaleY != yDPIScale)
{
LL_INFOS() << "handleDPIScaleChange APPLY" << LL_ENDL;
mDPIScaleX = xDPIScale;
mDPIScaleY = yDPIScale;
if (!mWindow->getFullscreen()) {
reshape(width ? width : getWindowWidthRaw(), height ? height : getWindowHeightRaw());
return true;
}
}
return false;
}
void LLViewerWindow::handlePingWatchdog(LLWindow *window, const char * msg)
{
LLAppViewer::instance()->pingMainloopTimeout(msg);
@@ -1637,7 +1653,9 @@ LLViewerWindow::LLViewerWindow(
//mStatesDirty(false), //Singu Note: No longer needed. State update is now in restoreGL.
mIsFullscreenChecked(false),
mCurrResolutionIndex(0),
mProgressView(NULL)
mProgressView(NULL),
mDPIScaleX(1.f),
mDPIScaleY(1.f)
{
LLNotificationChannel::buildChannel("VW_alerts", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alert"));
LLNotificationChannel::buildChannel("VW_alertmodal", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alertmodal"));
@@ -1706,10 +1724,9 @@ LLViewerWindow::LLViewerWindow(
// Get the real window rect the window was created with (since there are various OS-dependent reasons why
// the size of a window or fullscreen context may have been adjusted slightly...)
F32 ui_scale_factor = gSavedSettings.getF32("UIScaleFactor");
mDisplayScale.setVec(llmax(1.f / mWindow->getPixelAspectRatio(), 1.f), llmax(mWindow->getPixelAspectRatio(), 1.f));
mDisplayScale *= ui_scale_factor;
mDisplayScale.scaleVec(getUIScale());
LLUI::setScaleFactor(mDisplayScale);
{
@@ -1799,6 +1816,8 @@ LLViewerWindow::LLViewerWindow(
mDebugText = new LLDebugText(this);
mWindow->postInitialized();
}
void LLViewerWindow::initGLDefaults()
@@ -5730,17 +5749,17 @@ F32 LLViewerWindow::getDisplayAspectRatio() const
void LLViewerWindow::calcDisplayScale()
{
F32 ui_scale_factor = gSavedSettings.getF32("UIScaleFactor");
LLVector2 ui_scale_factor = getUIScale();
LLVector2 display_scale;
display_scale.setVec(llmax(1.f / mWindow->getPixelAspectRatio(), 1.f), llmax(mWindow->getPixelAspectRatio(), 1.f));
if(mWindow->getFullscreen())
{
F32 height_normalization = gSavedSettings.getBOOL("UIAutoScale") ? ((F32)mWindowRectRaw.getHeight() / display_scale.mV[VY]) / 768.f : 1.f;
display_scale *= (ui_scale_factor * height_normalization);
display_scale.scaleVec(ui_scale_factor * height_normalization);
}
else
{
display_scale *= ui_scale_factor;
display_scale.scaleVec(ui_scale_factor);
}
// limit minimum display scale
@@ -5765,6 +5784,20 @@ void LLViewerWindow::calcDisplayScale()
}
}
LLVector2 LLViewerWindow::getUIScale() const
{
LL_INFOS() << "getUIScale" << LL_ENDL;
static LLCachedControl<F32> ui_scale_factor("UIScaleFactor");
if (mWindow->getFullscreen())
{
return LLVector2(ui_scale_factor, ui_scale_factor);
}
else
{
return LLVector2(mDPIScaleX * ui_scale_factor, mDPIScaleY * ui_scale_factor);
}
}
S32 LLViewerWindow::getChatConsoleBottomPad()
{
static const LLCachedControl<S32> user_offset("ConsoleBottomOffset");

View File

@@ -181,6 +181,7 @@ public:
/*virtual*/ void handleDataCopy(LLWindow *window, S32 data_type, void *data);
/*virtual*/ BOOL handleTimerEvent(LLWindow *window);
/*virtual*/ BOOL handleDeviceChange(LLWindow *window);
/*virtual*/ bool handleDPIScaleChange(LLWindow *window, float xDPIScale, float yDPIScale, U32 width = 0, U32 height = 0);
/*virtual*/ void handlePingWatchdog(LLWindow *window, const char * msg);
/*virtual*/ void handlePauseWatchdog(LLWindow *window);
@@ -393,6 +394,8 @@ public:
const LLVector2& getDisplayScale() const { return mDisplayScale; }
void calcDisplayScale();
LLVector2 getUIScale() const;
private:
bool shouldShowToolTipFor(LLMouseHandler *mh);
static bool onAlert(const LLSD& notify);
@@ -464,6 +467,9 @@ protected:
bool mIsFullscreenChecked; // Did the user check the fullscreen checkbox in the display settings
U32 mCurrResolutionIndex;
float mDPIScaleX;
float mDPIScaleY;
protected:
static std::string sSnapshotBaseName;
static std::string sSnapshotDir;

View File

@@ -1096,6 +1096,21 @@ protected: // Shared with LLVOAvatarSelf
/** Support classes
** **
*******************************************************************************/
public:
typedef std::array<F32, LL_MAX_JOINTS_PER_MESH_OBJECT * 12> rigged_matrix_array_t;
typedef std::vector<std::pair<LLUUID, std::pair<U32, rigged_matrix_array_t> > > rigged_transformation_cache_t;
rigged_transformation_cache_t& getRiggedMatrixCache()
{
return mRiggedMatrixDataCache;
}
void clearRiggedMatrixCache()
{
mRiggedMatrixDataCache.clear();
}
private:
rigged_transformation_cache_t mRiggedMatrixDataCache;
// <edit>
//Avatar idle timer

View File

@@ -1250,9 +1250,9 @@ void LLWorldMapView::drawFrustum()
F32 half_width_pixels = half_width_meters * meters_to_pixels;
// Compute the frustum coordinates. Take the UI scale into account.
static LLCachedControl<F32> ui_scale_factor("UIScaleFactor");
F32 ctr_x = (getLocalRect().getWidth() * 0.5f + sPanX) * ui_scale_factor;
F32 ctr_y = (getLocalRect().getHeight() * 0.5f + sPanY) * ui_scale_factor;
LLVector2 ui_scale_factor = gViewerWindow->getUIScale();
F32 ctr_x = (getLocalRect().getWidth() * 0.5f + sPanX) * ui_scale_factor.mV[VX];
F32 ctr_y = (getLocalRect().getHeight() * 0.5f + sPanY) * ui_scale_factor.mV[VY];
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);

View File

@@ -0,0 +1,163 @@
#include "llviewerprecompiledheaders.h"
#include "llviewerwindow.h"
#include "llwindow.h"
#include "llpanelgeneral.h"
#include "llappviewer.h"
#include "llbutton.h"
#include "llviewercontrol.h"
#include "llnotificationsutil.h"
#include "llstartup.h"
#include "llviewerwindow.h" // to link into child list
#include "llnotify.h"
#include "lluictrlfactory.h"
#include "llhttpclient.h"
#include "llversioninfo.h"
#include "llbufferstream.h"
#include "llweb.h"
#include <jsoncpp/reader.h>
extern AIHTTPTimeoutPolicy getUpdateInfoResponder_timeout;
///////////////////////////////////////////////////////////////////////////////
// GetUpdateInfoResponder
class GetUpdateInfoResponder : public LLHTTPClient::ResponderWithCompleted
{
LOG_CLASS(GetUpdateInfoResponder);
public:
GetUpdateInfoResponder(std::string type)
: mType(type)
{}
void onNotifyButtonPress(const LLSD& notification, const LLSD& response, std::string name, std::string url)
{
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
if (option == 0) // URL
{
std::string escaped_url = LLWeb::escapeURL(url);
if (gViewerWindow)
{
gViewerWindow->getWindow()->spawnWebBrowser(escaped_url, true);
}
}
if (option == 1) // Later
{}
}
/*virtual*/ void completedRaw(LLChannelDescriptors const& channels, buffer_ptr_t const& buffer)
{
LLBufferStream istr(channels, buffer.get());
std::stringstream strstrm;
strstrm << istr.rdbuf();
const std::string body = strstrm.str();
if (mStatus != HTTP_OK)
{
LL_WARNS() << "Failed to get update info (" << mStatus << ")" << LL_ENDL;
return;
}
Json::Value root;
Json::Reader reader;
if (!reader.parse(body, root))
{
LL_WARNS() << "Failed to parse update info: " << reader.getFormattedErrorMessages() << LL_ENDL;
return;
}
std::string viewer_version = llformat("%s (%i)", LLVersionInfo::getShortVersion().c_str(), LLVersionInfo::getBuild());
const Json::Value data = root[mType];
#if LL_WINDOWS
std::string recommended_version = data["recommended"]["windows"].asString();
std::string minimum_version = data["minimum"]["windows"].asString();
#elif LL_LINUX
std::string recommended_version = data["recommended"]["linux"].asString();
std::string minimum_version = data["minimum"]["linux"].asString();
#elif LL_DARWIN
std::string recommended_version = data["recommended"]["apple"].asString();
std::string minimum_version = data["minimum"]["apple"].asString();
#endif
S32 minimum_build, recommended_build;
sscanf(recommended_version.c_str(), "%*i.%*i.%*i (%i)", &recommended_build);
sscanf(minimum_version.c_str(), "%*i.%*i.%*i (%i)", &minimum_build);
LL_INFOS() << LLVersionInfo::getBuild() << LL_ENDL;
LLSD args;
args["CURRENT_VER"] = viewer_version;
args["RECOMMENDED_VER"] = recommended_version;
args["MINIMUM_VER"] = minimum_version;
args["URL"] = data["url"].asString();
args["TYPE"] = mType == "release" ? "Viewer" : "Alpha";
static LLCachedControl<S32> sLastKnownReleaseBuild("SinguLastKnownReleaseBuild", 0);
static LLCachedControl<S32> sLastKnownAlphaBuild("SinguLastKnownAlphaBuild", 0);
LLCachedControl<S32>& lastver = mType == "release" ? sLastKnownReleaseBuild : sLastKnownAlphaBuild;
if (LLVersionInfo::getBuild() < minimum_build || LLVersionInfo::getBuild() < recommended_build)
{
if (lastver.get() < recommended_build)
{
lastver = recommended_build;
LLUI::sIgnoresGroup->setWarning("UrgentUpdateModal", true);
LLUI::sIgnoresGroup->setWarning("UrgentUpdate", true);
LLUI::sIgnoresGroup->setWarning("RecommendedUpdate", true);
}
std::string notificaiton;
if (LLVersionInfo::getBuild() < minimum_build)
{
if (LLUI::sIgnoresGroup->getWarning("UrgentUpdateModal"))
{
notificaiton = "UrgentUpdateModal";
}
else
{
notificaiton = "UrgentUpdate";
}
}
else if (LLVersionInfo::getBuild() < recommended_build)
{
notificaiton = "RecommendedUpdate";
}
if (!notificaiton.empty())
{
LLNotificationsUtil::add(notificaiton, args, LLSD(), boost::bind(&GetUpdateInfoResponder::onNotifyButtonPress, this, _1, _2, notificaiton, data["url"].asString()));
}
}
}
protected:
/*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return getUpdateInfoResponder_timeout; }
/*virtual*/ char const* getName(void) const { return "GetUpdateInfoResponder"; }
private:
std::string mType;
};
void check_for_updates()
{
#if LL_WINDOWS | LL_LINUX | LL_DARWIN
// Hard-code the update url for now.
std::string url = "http://singularity-viewer.github.io/pages/api/get_update_info.json";//gSavedSettings.getString("SHUpdateCheckURL");
if (!url.empty())
{
std::string type;
auto& channel = LLVersionInfo::getChannel();
if (channel == std::string("Singularity"))
{
type = "release";
}
else if (channel == std::string("Singularity Test") || channel == std::string("Singularity Alpha"))
{
type = "alpha";
}
else
{
return;
}
LLHTTPClient::get(url, new GetUpdateInfoResponder(type));
}
#endif
}

View File

@@ -0,0 +1,6 @@
#ifndef SH_SHUPDATECHECKER_H
#define SH_SHUPDATECHECKER_H
void check_for_updates();
#endif //SH_SHUPDATECHECKER_H

View File

@@ -57,20 +57,6 @@
</form>
</template>
<template name="okcancelbuttonscanceldefault">
<form>
<button
index="0"
name="OK"
text="$yestext"/>
<button
default="true"
index="1"
name="Cancel"
text="$notext"/>
</form>
</template>
<template name="okcancelignore">
<form>
<button
@@ -86,6 +72,20 @@
</form>
</template>
<template name="okcancelignorecanceldefault">
<form>
<button
index="0"
name="OK"
text="$yestext"/>
<button
default="true"
index="1"
name="Cancel"
text="$notext"/>
<ignore text="$ignoretext"/>
</form>
</template>
<template name="okhelpbuttons">
<form>
<button
@@ -10595,4 +10595,62 @@ Do you wish to export anyway?
Object successfully exported to: [FILENAME]
</notification>
<notification
icon="notifytip.tga"
label="Update Available"
name="RecommendedUpdate"
type="notify">
A newer version, [RECOMMENDED_VER], is available for Singularity[TYPE].
Click [Visit Page] to open
[URL]
for information and download links for this new version.
<tag>confirm</tag>
<usetemplate
name="okcancelignorecanceldefault"
notext="Later"
yestext="Visit Page"
ignoretext="Ignore recommended update notification"/>
</notification>
<notification
icon="alert.tga"
label="Critical Update!"
name="UrgentUpdate"
priority="high"
type="notify">
Your version of Singularity[TYPE] is critically out of date!
It is STRONGLY recommended to download a newer version of this viewer due to grid compatability and/or security concerns.
Click [Visit Page] to open
[URL]
for information and download links for newer versions.
<tag>confirm</tag>
<usetemplate
name="okcancelignorecanceldefault"
notext="Later"
yestext="Visit Page"
ignoretext="Ignore critical update notification"/>
</notification>
<notification
icon="alert.tga"
label="Critical Update"
name="UrgentUpdateModal"
priority="high"
type="alertmodal">
Your version of Singularity[TYPE] is critically out of date!
It is STRONGLY recommended to download a newer version of this viewer due to grid compatability and/or security concerns.
Click [Visit Page] to open
[URL]
for information and download links for newer versions.
<tag>confirm</tag>
<usetemplate
name="okcancelignorecanceldefault"
notext="Later"
yestext="Visit Page"
ignoretext="Ignore critical update alert"/>
</notification>
</notifications>