Merge branch 'master' of github.com:Shyotl/SingularityViewer
# Conflicts: # indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -962,3 +962,4 @@ P(wholeModelFeeResponder);
|
||||
P(wholeModelUploadResponder);
|
||||
P2(XMLRPCResponder, connect_40s);
|
||||
P2(crashLoggerResponder, transfer_300s);
|
||||
P(getUpdateInfoResponder);
|
||||
@@ -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);
|
||||
|
||||
@@ -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 ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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*);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -65,6 +65,7 @@ public:
|
||||
// currently unused
|
||||
};
|
||||
public:
|
||||
virtual void postInitialized() {}
|
||||
virtual void show() = 0;
|
||||
virtual void hide() = 0;
|
||||
virtual void close() = 0;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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() &&
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 ;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
163
indra/newview/shupdatechecker.cpp
Normal file
163
indra/newview/shupdatechecker.cpp
Normal 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
|
||||
}
|
||||
6
indra/newview/shupdatechecker.h
Normal file
6
indra/newview/shupdatechecker.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#ifndef SH_SHUPDATECHECKER_H
|
||||
#define SH_SHUPDATECHECKER_H
|
||||
|
||||
void check_for_updates();
|
||||
|
||||
#endif //SH_SHUPDATECHECKER_H
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user