The unbearable lightness of being norspec

master
Graham Linden 2013-09-18 18:24:16 -07:00
commit 95e34d86b9
66 changed files with 3276 additions and 680 deletions

View File

@ -1612,9 +1612,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>38ea083fe1204ee106b4d44d9811af19</string>
<string>facee34b8bd57ad602157e65a5af1a49</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-openssl/rev/249044/arch/Darwin/installer/openssl-1.0.0g-darwin-20120207.tar.bz2</string>
<string>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/openssl-0.9.8q-darwin-20110211.tar.bz2</string>
</map>
<key>name</key>
<string>darwin</string>
@ -1624,9 +1624,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>7dc5191a3d95074a6ed3bd53f57420e5</string>
<string>3d40be8566fa4b9df9a38e2a0f9ea467</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-openssl/rev/249044/arch/Linux/installer/openssl-1.0.0g-linux-20120207.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-openssl/rev/226882/arch/Linux/installer/openssl-1.0.0d-linux-20110418.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
@ -1636,9 +1636,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>ed6cbaf9860a03bc99ac301277f1452a</string>
<string>774c7f0a0312bee3054757a623e227bc</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-openssl/rev/249044/arch/CYGWIN/installer/openssl-1.0.0g-windows-20120207.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-openssl/rev/220986/arch/CYGWIN/installer/openssl-0.9.8q-windows-20110211.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@ -2638,7 +2638,6 @@
<array>
<string>/build</string>
<string>"/cfg=Release|Win32"</string>
<string>"/CL_ADD=/m:1"</string>
</array>
</map>
<key>configure</key>

View File

@ -409,6 +409,26 @@ inline void LLVector4a::normalize3fast()
mQ = _mm_mul_ps( mQ, approxRsqrt );
}
inline void LLVector4a::normalize3fast_checked(LLVector4a* d)
{
if (!isFinite3())
{
*this = d ? *d : LLVector4a(0,1,0,1);
return;
}
LLVector4a lenSqrd; lenSqrd.setAllDot3( *this, *this );
if (lenSqrd.getF32ptr()[0] <= FLT_EPSILON)
{
*this = d ? *d : LLVector4a(0,1,0,1);
return;
}
const LLQuad approxRsqrt = _mm_rsqrt_ps(lenSqrd.mQ);
mQ = _mm_mul_ps( mQ, approxRsqrt );
}
// Return true if this vector is normalized with respect to x,y,z up to tolerance
inline LLBool32 LLVector4a::isNormalized3( F32 tolerance ) const
{

View File

@ -94,8 +94,6 @@ const S32 SCULPT_MIN_AREA_DETAIL = 1;
extern BOOL gDebugGL;
bool less_than_max_mag(const LLVector4a& vec);
BOOL check_same_clock_dir( const LLVector3& pt1, const LLVector3& pt2, const LLVector3& pt3, const LLVector3& norm)
{
LLVector3 test = (pt2-pt1)%(pt3-pt2);
@ -138,6 +136,82 @@ BOOL LLLineSegmentBoxIntersect(const F32* start, const F32* end, const F32* cent
return true;
}
// Finds tangent vec based on three vertices with texture coordinates.
// Fills in dummy values if the triangle has degenerate texture coordinates.
void calc_tangent_from_triangle(
LLVector4a& normal,
LLVector4a& tangent_out,
const LLVector4a& v1,
const LLVector2& w1,
const LLVector4a& v2,
const LLVector2& w2,
const LLVector4a& v3,
const LLVector2& w3)
{
const F32* v1ptr = v1.getF32ptr();
const F32* v2ptr = v2.getF32ptr();
const F32* v3ptr = v3.getF32ptr();
float x1 = v2ptr[0] - v1ptr[0];
float x2 = v3ptr[0] - v1ptr[0];
float y1 = v2ptr[1] - v1ptr[1];
float y2 = v3ptr[1] - v1ptr[1];
float z1 = v2ptr[2] - v1ptr[2];
float z2 = v3ptr[2] - v1ptr[2];
float s1 = w2.mV[0] - w1.mV[0];
float s2 = w3.mV[0] - w1.mV[0];
float t1 = w2.mV[1] - w1.mV[1];
float t2 = w3.mV[1] - w1.mV[1];
F32 rd = s1*t2-s2*t1;
float r = ((rd*rd) > FLT_EPSILON) ? 1.0F / rd : 1024.f; //some made up large ratio for division by zero
llassert(llfinite(r));
llassert(!llisnan(r));
LLVector4a sdir(
(t2 * x1 - t1 * x2) * r,
(t2 * y1 - t1 * y2) * r,
(t2 * z1 - t1 * z2) * r);
LLVector4a tdir(
(s1 * x2 - s2 * x1) * r,
(s1 * y2 - s2 * y1) * r,
(s1 * z2 - s2 * z1) * r);
LLVector4a n = normal;
LLVector4a t = sdir;
LLVector4a ncrosst;
ncrosst.setCross3(n,t);
// Gram-Schmidt orthogonalize
n.mul(n.dot3(t).getF32());
LLVector4a tsubn;
tsubn.setSub(t,n);
if (tsubn.dot3(tsubn).getF32() > F_APPROXIMATELY_ZERO)
{
tsubn.normalize3fast_checked();
// Calculate handedness
F32 handedness = ncrosst.dot3(tdir).getF32() < 0.f ? -1.f : 1.f;
tsubn.getF32ptr()[3] = handedness;
tangent_out = tsubn;
}
else
{
// degenerate, make up a value
//
tangent_out.set(0,0,1,1);
}
}
// intersect test between triangle vert0, vert1, vert2 and a ray from orig in direction dir.
@ -991,7 +1065,6 @@ BOOL LLProfile::generate(const LLProfileParams& params, BOOL path_open,F32 detai
{
mOpen = FALSE;
mProfile.push_back(mProfile[0]);
llassert(mProfile[0].isFinite3());
mTotal++;
}
}
@ -1019,7 +1092,7 @@ BOOL LLProfile::generate(const LLProfileParams& params, BOOL path_open,F32 detai
addFace(mTotal-2, 2,0.5,LL_FACE_PROFILE_END, TRUE);
}
}
return TRUE;
}
@ -1357,7 +1430,7 @@ void LLPath::genNGon(const LLPathParams& params, S32 sides, F32 startOff, F32 en
qang.setQuat (ang,path_axis);
LLMatrix3 tmp(twist*qang);
pt->mRot.loadu(tmp);
t+=step;
}
@ -1383,7 +1456,7 @@ void LLPath::genNGon(const LLPathParams& params, S32 sides, F32 startOff, F32 en
qang.setQuat (ang,path_axis);
LLMatrix3 tmp(twist*qang);
pt->mRot.loadu(tmp);
mTotal = mPath.size();
}
@ -1987,7 +2060,7 @@ LLVolume::LLVolume(const LLVolumeParams &params, const F32 detail, const BOOL ge
mHullIndices = NULL;
mNumHullPoints = 0;
mNumHullIndices = 0;
// set defaults
if (mParams.getPathParams().getCurveType() == LL_PCODE_PATH_FLEXIBLE)
{
@ -2733,7 +2806,7 @@ inline LLVector4a sculpt_rgb_to_vector(U8 r, U8 g, U8 b)
value.set(r,g,b);
value.mul(1.f/255.f);
value.sub(sub);
return value;
}
@ -2836,7 +2909,7 @@ void LLVolume::sculptGeneratePlaceholder()
F32 v = (F32)t/(sizeT-1);
const F32 RADIUS = (F32) 0.3;
F32* p = pt.getF32ptr();
p[0] = (F32)(sin(F_PI * v) * cos(2.0 * F_PI * u) * RADIUS);
@ -4541,7 +4614,7 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src)
if (src.mNormals)
{
LLVector4a::memcpyNonAliased16((F32*) mNormals, (F32*) src.mNormals, vert_size);
LLVector4a::memcpyNonAliased16((F32*) mNormals, (F32*) src.mNormals, vert_size);
}
if(src.mTexCoords)
@ -4751,13 +4824,27 @@ void LLVolumeFace::optimize(F32 angle_cutoff)
}
}
if (angle_cutoff > 1.f && !mNormals)
{
ll_aligned_free_16(new_face.mNormals);
new_face.mNormals = NULL;
}
if (!mTexCoords)
{
ll_aligned_free_16(new_face.mTexCoords);
new_face.mTexCoords = NULL;
}
// Only swap data if we've actually optimized the mesh
//
if (new_face.mNumVertices <= mNumVertices)
{
llassert(new_face.mNumIndices == mNumIndices);
llassert(new_face.mNumIndices == mNumIndices);
swapData(new_face);
}
}
class LLVCacheTriangleData;
@ -4827,29 +4914,29 @@ F64 find_vertex_score(LLVCacheVertexData& data)
if (data.mActiveTriangles >= 0)
{
score = 0.0;
S32 cache_idx = data.mCacheTag;
if (cache_idx < 0)
{
//not in cache
S32 cache_idx = data.mCacheTag;
if (cache_idx < 0)
{
//not in cache
}
else
{
if (cache_idx < 3)
{ //vertex was in the last triangle
score = FindVertexScore_LastTriScore;
}
else
{
if (cache_idx < 3)
{ //vertex was in the last triangle
score = FindVertexScore_LastTriScore;
}
else
{ //more points for being higher in the cache
{ //more points for being higher in the cache
score = 1.0-((cache_idx-3)*FindVertexScore_Scaler);
score = pow(score, FindVertexScore_CacheDecayPower);
}
}
}
//bonus points for having low valence
//bonus points for having low valence
F64 valence_boost = pow((F64)data.mActiveTriangles, -FindVertexScore_ValenceBoostPower);
score += FindVertexScore_ValenceBoostScale * valence_boost;
score += FindVertexScore_ValenceBoostScale * valence_boost;
}
return score;
@ -5429,9 +5516,6 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)
mCenter->mul(0.5f);
}
llassert(less_than_max_mag(mExtents[0]));
llassert(less_than_max_mag(mExtents[1]));
if (!partial_build)
{
resizeIndices(grid_size*grid_size*6);
@ -5572,9 +5656,9 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
++src;
++pos;
}
}
else
{
}
else
{
min_uv.set((*p)[0]+0.5f,
0.5f - (*p)[1]);
@ -5589,9 +5673,9 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
llassert(src->isFinite3());
update_min_max(min,max,*src);
update_min_max(min_uv, max_uv, *tc);
*pos = *src;
*pos = *src;
llassert(pos->isFinite3());
++p;
@ -5619,7 +5703,7 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
*tc++ = cuv;
num_vertices++;
}
LL_CHECK_MEMORY
if (partial_build)
@ -5760,7 +5844,7 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
const F32* p2V = p2.getF32ptr();
const F32* paV = pa.getF32ptr();
const F32* pbV = pb.getF32ptr();
// Use area of triangle to determine backfacing
F32 area_1a2, area_1ba, area_21b, area_2ab;
area_1a2 = (p1V[0]*paV[1] - paV[0]*p1V[1]) +
@ -5941,7 +6025,7 @@ void LLVolumeFace::resizeVertices(S32 num_verts)
ll_aligned_free(mPositions);
//DO NOT free mNormals and mTexCoords as they are part of mPositions buffer
ll_aligned_free_16(mTangents);
mTangents = NULL;
if (num_verts)
@ -5993,15 +6077,15 @@ void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, con
mNormals = mPositions+new_verts;
mTexCoords = (LLVector2*) (mNormals+new_verts);
//positions
//positions
LLVector4a::memcpyNonAliased16((F32*) mPositions, (F32*) old_buf, old_vsize);
//normals
//normals
LLVector4a::memcpyNonAliased16((F32*) mNormals, (F32*) (old_buf+mNumVertices), old_vsize);
//tex coords
//tex coords
LLVector4a::memcpyNonAliased16((F32*) mTexCoords, (F32*) (old_buf+mNumVertices*2), old_tc_size);
//just clear tangents
ll_aligned_free_16(mTangents);
mTangents = NULL;
@ -6265,7 +6349,6 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
i = mBeginS + s + max_s*t;
}
llassert(less_than_max_mag(mesh[i]));
mesh[i].store4a((F32*)(pos+cur_vertex));
tc[cur_vertex].set(ss,tt);
@ -6273,7 +6356,6 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
if (test && s > 0)
{
llassert(less_than_max_mag(mesh[i]));
mesh[i].store4a((F32*)(pos+cur_vertex));
tc[cur_vertex].set(ss,tt);
cur_vertex++;
@ -6294,16 +6376,13 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
i = mBeginS + s + max_s*t;
ss = profile[mBeginS + s][2] - begin_stex;
llassert(less_than_max_mag(mesh[i]));
mesh[i].store4a((F32*)(pos+cur_vertex));
tc[cur_vertex].set(ss,tt);
cur_vertex++;
}
}
}
LL_CHECK_MEMORY
mCenter->clear();
@ -6459,7 +6538,7 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
LLQuad& vector1 = *((LLQuad*) &v1);
LLQuad& vector2 = *((LLQuad*) &v2);
LLQuad& amQ = *((LLQuad*) &a);
LLQuad& bmQ = *((LLQuad*) &b);
@ -6482,7 +6561,7 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
llassert(v1.isFinite3());
v1.store4a((F32*) output);
output++;
idx += 3;
@ -6500,20 +6579,20 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
LLVector4a* n0p = norm+idx[0];
LLVector4a* n1p = norm+idx[1];
LLVector4a* n2p = norm+idx[2];
idx += 3;
LLVector4a n0,n1,n2;
n0.load4a((F32*) n0p);
n1.load4a((F32*) n1p);
n2.load4a((F32*) n2p);
n0.add(c);
n1.add(c);
n2.add(c);
llassert(c.isFinite3());
//even out quad contributions
switch (i%2+1)
{
@ -6758,7 +6837,7 @@ void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVe
tangent[a].set(0,0,1,1);
}
}
ll_aligned_free_16(tan1);
}

View File

@ -73,7 +73,6 @@ std::ofstream gFailLog;
#define APIENTRY
#endif
void APIENTRY gl_debug_callback(GLenum source,
GLenum type,
GLuint id,
@ -84,24 +83,24 @@ void APIENTRY gl_debug_callback(GLenum source,
{
if (gGLDebugLoggingEnabled)
{
if (severity == GL_DEBUG_SEVERITY_HIGH_ARB)
{
llwarns << "----- GL ERROR --------" << llendl;
}
else
{
llwarns << "----- GL WARNING -------" << llendl;
}
llwarns << "Type: " << std::hex << type << llendl;
llwarns << "ID: " << std::hex << id << llendl;
llwarns << "Severity: " << std::hex << severity << llendl;
llwarns << "Message: " << message << llendl;
llwarns << "-----------------------" << llendl;
if (severity == GL_DEBUG_SEVERITY_HIGH_ARB)
{
llerrs << "Halting on GL Error" << llendl;
}
if (severity == GL_DEBUG_SEVERITY_HIGH_ARB)
{
llwarns << "----- GL ERROR --------" << llendl;
}
else
{
llwarns << "----- GL WARNING -------" << llendl;
}
llwarns << "Type: " << std::hex << type << llendl;
llwarns << "ID: " << std::hex << id << llendl;
llwarns << "Severity: " << std::hex << severity << llendl;
llwarns << "Message: " << message << llendl;
llwarns << "-----------------------" << llendl;
if (severity == GL_DEBUG_SEVERITY_HIGH_ARB)
{
llerrs << "Halting on GL Error" << llendl;
}
}
}
#endif
@ -653,7 +652,8 @@ bool LLGLManager::initGL()
}
#if LL_DARWIN
else if ((mGLRenderer.find("9400M") != std::string::npos)
|| (mGLRenderer.find("9600M") != std::string::npos))
|| (mGLRenderer.find("9600M") != std::string::npos)
|| (mGLRenderer.find("9800M") != std::string::npos))
{
mIsMobileGF = TRUE;
}
@ -751,7 +751,7 @@ bool LLGLManager::initGL()
#if LL_WINDOWS
if (mHasDebugOutput && gDebugGL)
{ //setup debug output callback
glDebugMessageControlARB(GL_DONT_CARE, GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB, GL_DEBUG_SEVERITY_LOW_ARB, 0, NULL, GL_TRUE);
//glDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW_ARB, 0, NULL, GL_TRUE);
glDebugMessageCallbackARB((GLDEBUGPROCARB) gl_debug_callback, NULL);
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
}

View File

@ -375,6 +375,11 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes,
// Create program
mProgramObject = glCreateProgramObjectARB();
#if LL_DARWIN
// work-around missing mix(vec3,vec3,bvec3)
mDefines["OLD_SELECT"] = "1";
#endif
//compile new source
vector< pair<string,GLenum> >::iterator fileIter = mShaderFiles.begin();
for ( ; fileIter != mShaderFiles.end(); fileIter++ )
@ -1190,7 +1195,7 @@ GLint LLGLSLShader::getAttribLocation(U32 attrib)
void LLGLSLShader::uniform1i(const LLStaticHashedString& uniform, GLint v)
{
GLint location = getUniformLocation(uniform);
if (location >= 0)
{
std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
@ -1223,7 +1228,7 @@ void LLGLSLShader::uniform2i(const LLStaticHashedString& uniform, GLint i, GLint
void LLGLSLShader::uniform1f(const LLStaticHashedString& uniform, GLfloat v)
{
GLint location = getUniformLocation(uniform);
if (location >= 0)
{
std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
@ -1239,7 +1244,7 @@ void LLGLSLShader::uniform1f(const LLStaticHashedString& uniform, GLfloat v)
void LLGLSLShader::uniform2f(const LLStaticHashedString& uniform, GLfloat x, GLfloat y)
{
GLint location = getUniformLocation(uniform);
if (location >= 0)
{
std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
@ -1256,7 +1261,7 @@ void LLGLSLShader::uniform2f(const LLStaticHashedString& uniform, GLfloat x, GLf
void LLGLSLShader::uniform3f(const LLStaticHashedString& uniform, GLfloat x, GLfloat y, GLfloat z)
{
GLint location = getUniformLocation(uniform);
if (location >= 0)
{
std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
@ -1288,7 +1293,7 @@ void LLGLSLShader::uniform1fv(const LLStaticHashedString& uniform, U32 count, co
void LLGLSLShader::uniform2fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v)
{
GLint location = getUniformLocation(uniform);
if (location >= 0)
{
std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
@ -1304,7 +1309,7 @@ void LLGLSLShader::uniform2fv(const LLStaticHashedString& uniform, U32 count, co
void LLGLSLShader::uniform3fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v)
{
GLint location = getUniformLocation(uniform);
if (location >= 0)
{
std::map<GLint, LLVector4>::iterator iter = mValue.find(location);

View File

@ -1872,33 +1872,33 @@ void LLRender::flush()
//store mCount in a local variable to avoid re-entrance (drawArrays may call flush)
U32 count = mCount;
if (mMode == LLRender::QUADS && !sGLCoreProfile)
{
if (mCount%4 != 0)
if (mMode == LLRender::QUADS && !sGLCoreProfile)
{
if (mCount%4 != 0)
{
count -= (mCount % 4);
llwarns << "Incomplete quad requested." << llendl;
}
}
}
if (mMode == LLRender::TRIANGLES)
{
if (mCount%3 != 0)
if (mMode == LLRender::TRIANGLES)
{
if (mCount%3 != 0)
{
count -= (mCount % 3);
llwarns << "Incomplete triangle requested." << llendl;
}
}
}
if (mMode == LLRender::LINES)
{
if (mCount%2 != 0)
if (mMode == LLRender::LINES)
{
if (mCount%2 != 0)
{
count -= (mCount % 2);
llwarns << "Incomplete line requested." << llendl;
}
}
mCount = 0;
if (mBuffer->useVBOs() && !mBuffer->isLocked())

View File

@ -79,7 +79,7 @@ LLRenderTarget::~LLRenderTarget()
release();
}
void LLRenderTarget::resize(U32 resx, U32 resy, U32 color_fmt)
void LLRenderTarget::resize(U32 resx, U32 resy)
{
//for accounting, get the number of pixels added/subtracted
S32 pix_diff = (resx*resy)-(mResX*mResY);
@ -87,10 +87,12 @@ void LLRenderTarget::resize(U32 resx, U32 resy, U32 color_fmt)
mResX = resx;
mResY = resy;
llassert(mInternalFormat.size() == mTex.size());
for (U32 i = 0; i < mTex.size(); ++i)
{ //resize color attachments
gGL.getTexUnit(0)->bindManual(mUsage, mTex[i]);
LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, color_fmt, mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL, false);
LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, mInternalFormat[i], mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL, false);
sBytesAllocated += pix_diff*4;
}

View File

@ -79,7 +79,7 @@ public:
// CAUTION: if the GL runs out of memory attempting to resize, this render target will be undefined
// DO NOT use for screen space buffers or for scratch space for an image that might be uploaded
// DO use for render targets that resize often and aren't likely to ruin someone's day if they break
void resize(U32 resx, U32 resy, U32 color_fmt);
void resize(U32 resx, U32 resy);
//add color buffer attachment
//limit of 4 color attachments per render target

View File

@ -1137,7 +1137,8 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("lightMap");
mReservedUniforms.push_back("bloomMap");
mReservedUniforms.push_back("projectionMap");
mReservedUniforms.push_back("norm_mat");
mReservedUniforms.push_back("global_gamma");
mReservedUniforms.push_back("texture_gamma");
@ -1183,7 +1184,7 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("alpha_ramp");
mReservedUniforms.push_back("origin");
mReservedUniforms.push_back("display_gamma");
llassert(mReservedUniforms.size() == END_RESERVED_UNIFORMS);
std::set<std::string> dupe_check;

View File

@ -167,7 +167,8 @@ public:
DEFERRED_LIGHT,
DEFERRED_BLOOM,
DEFERRED_PROJECTION,
DEFERRED_NORM_MATRIX,
GLOBAL_GAMMA,
TEXTURE_GAMMA,
@ -213,9 +214,8 @@ public:
TERRAIN_ALPHARAMP,
SHINY_ORIGIN,
DISPLAY_GAMMA,
END_RESERVED_UNIFORMS
} eGLSLReservedUniforms;
// singleton pattern implementation

View File

@ -954,15 +954,15 @@ S32 LLVertexBuffer::determineUsage(S32 usage)
{ //only stream_draw and dynamic_draw are supported when using VBOs, dynamic draw is the default
if (ret_usage != GL_DYNAMIC_COPY_ARB)
{
if (sDisableVBOMapping)
{ //always use stream draw if VBO mapping is disabled
ret_usage = GL_STREAM_DRAW_ARB;
}
else
{
ret_usage = GL_DYNAMIC_DRAW_ARB;
}
if (sDisableVBOMapping)
{ //always use stream draw if VBO mapping is disabled
ret_usage = GL_STREAM_DRAW_ARB;
}
else
{
ret_usage = GL_DYNAMIC_DRAW_ARB;
}
}
}
return ret_usage;
@ -1119,7 +1119,7 @@ void LLVertexBuffer::genBuffer(U32 size)
{
mMappedData = sDynamicCopyVBOPool.allocate(mGLBuffer, mSize);
}
sGLCount++;
}
@ -1333,7 +1333,7 @@ void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)
//actually allocate space for the vertex buffer if using VBO mapping
flush();
if (gGLManager.mHasVertexArrayObject && useVBOs() && (sUseVAO))
if (gGLManager.mHasVertexArrayObject && useVBOs() && (LLRender::sGLCoreProfile || sUseVAO))
{
#if GL_ARB_vertex_array_object
mGLArray = getVAOName();
@ -1489,18 +1489,21 @@ bool LLVertexBuffer::useVBOs() const
//----------------------------------------------------------------------------
bool expand_region(LLVertexBuffer::MappedRegion& region, S32 start, S32 end)
bool expand_region(LLVertexBuffer::MappedRegion& region, S32 index, S32 count)
{
S32 end = index+count;
S32 region_end = region.mIndex+region.mCount;
if (end < region.mIndex ||
start > region.mEnd)
index > region_end)
{ //gap exists, do not merge
return false;
}
region.mEnd = llmax(end, region.mEnd);
region.mIndex = llmin(start, region.mIndex);
region.mCount = region.mEnd-region.mIndex;
S32 new_end = llmax(end, region_end);
S32 new_index = llmin(index, region.mIndex);
region.mIndex = new_index;
region.mCount = new_end-new_index;
return true;
}
@ -1510,6 +1513,7 @@ static LLFastTimer::DeclareTimer FTM_VBO_MAP_BUFFER("VBO Map");
// Map for data access
volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range)
{
bindGLBuffer(true);
if (mFinal)
{
llerrs << "LLVertexBuffer::mapVeretxBuffer() called on a finalized buffer." << llendl;
@ -1530,23 +1534,23 @@ volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, boo
bool mapped = false;
//see if range is already mapped
S32 start_index = mOffsets[type]+index*sTypeSize[type];
S32 end_index = start_index+count*sTypeSize[type];
for (std::vector<MappedRegion>::iterator iter = mMappedVertexRegions.begin(), end = mMappedVertexRegions.end(); iter != end; ++iter)
for (U32 i = 0; i < mMappedVertexRegions.size(); ++i)
{
MappedRegion& region = *iter;
if (expand_region(region, index, end_index))
MappedRegion& region = mMappedVertexRegions[i];
if (region.mType == type)
{
mapped = true;
break;
if (expand_region(region, index, count))
{
mapped = true;
break;
}
}
}
if (!mapped)
{
//not already mapped, map new region
MappedRegion region(mMappable && map_range ? -1 : start_index, end_index-start_index);
MappedRegion region(type, mMappable && map_range ? -1 : index, count);
mMappedVertexRegions.push_back(region);
}
}
@ -1570,7 +1574,6 @@ volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, boo
{
volatile U8* src = NULL;
waitFence();
bindGLBuffer();
if (gGLManager.mHasMapBufferRange)
{
if (map_range)
@ -1691,6 +1694,7 @@ static LLFastTimer::DeclareTimer FTM_VBO_MAP_INDEX("IBO Map");
volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
{
bindGLIndices(true);
if (mFinal)
{
llerrs << "LLVertexBuffer::mapIndexBuffer() called on a finalized buffer." << llendl;
@ -1709,14 +1713,12 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range
count = mNumIndices-index;
}
S32 end = index+count;
bool mapped = false;
//see if range is already mapped
for (U32 i = 0; i < mMappedIndexRegions.size(); ++i)
{
MappedRegion& region = mMappedIndexRegions[i];
if (expand_region(region, index, end))
if (expand_region(region, index, count))
{
mapped = true;
break;
@ -1726,7 +1728,7 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range
if (!mapped)
{
//not already mapped, map new region
MappedRegion region(mMappable && map_range ? -1 : index, count);
MappedRegion region(TYPE_INDEX, mMappable && map_range ? -1 : index, count);
mMappedIndexRegions.push_back(region);
}
}
@ -1742,23 +1744,23 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range
sMappedCount++;
stop_glerror();
if (gDebugGL && useVBOs())
{
GLint elem = 0;
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &elem);
if (elem != mGLIndices)
{
llerrs << "Wrong index buffer bound!" << llendl;
}
}
if(!mMappable)
{
map_range = false;
}
else
{
bindGLIndices();
if (gDebugGL && useVBOs())
{
GLint elem = 0;
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &elem);
if (elem != mGLIndices)
{
llerrs << "Wrong index buffer bound!" << llendl;
}
}
volatile U8* src = NULL;
waitFence();
if (gGLManager.mHasMapBufferRange)
@ -1871,10 +1873,8 @@ void LLVertexBuffer::unmapBuffer()
if (mMappedData && mVertexLocked)
{
llassert(mUsage != GL_DYNAMIC_COPY_ARB);
LLFastTimer t(FTM_VBO_UNMAP);
bindGLBuffer();
bindGLBuffer(true);
updated_all = mIndexLocked; //both vertex and index buffers done updating
if(!mMappable)
@ -1885,8 +1885,8 @@ void LLVertexBuffer::unmapBuffer()
for (U32 i = 0; i < mMappedVertexRegions.size(); ++i)
{
const MappedRegion& region = mMappedVertexRegions[i];
S32 offset = region.mIndex;
S32 length = region.mCount;
S32 offset = region.mIndex >= 0 ? mOffsets[region.mType]+sTypeSize[region.mType]*region.mIndex : 0;
S32 length = sTypeSize[region.mType]*region.mCount;
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, offset, length, (U8*) mMappedData+offset);
stop_glerror();
}
@ -1910,8 +1910,8 @@ void LLVertexBuffer::unmapBuffer()
for (U32 i = 0; i < mMappedVertexRegions.size(); ++i)
{
const MappedRegion& region = mMappedVertexRegions[i];
S32 offset = region.mIndex;
S32 length = region.mCount;
S32 offset = region.mIndex >= 0 ? mOffsets[region.mType]+sTypeSize[region.mType]*region.mIndex : 0;
S32 length = sTypeSize[region.mType]*region.mCount;
if (gGLManager.mHasMapBufferRange)
{
LLFastTimer t(FTM_VBO_FLUSH_RANGE);
@ -2131,6 +2131,7 @@ bool LLVertexBuffer::bindGLArray()
if (mGLArray && sGLRenderArray != mGLArray)
{
{
LLFastTimer t(FTM_BIND_GL_ARRAY);
#if GL_ARB_vertex_array_object
glBindVertexArray(mGLArray);
#endif
@ -2165,7 +2166,7 @@ bool LLVertexBuffer::bindGLBuffer(bool force_bind)
sVBOActive = true;
llassert(!mGLArray || sGLRenderArray == mGLArray);
ret = true;
}
@ -2245,7 +2246,38 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
if ((data_mask & required_mask) != required_mask)
{
llwarns << "Shader consumption mismatches data provision." << llendl;
U32 unsatisfied_mask = (required_mask & ~data_mask);
U32 i = 0;
while (i < TYPE_MAX)
{
U32 unsatisfied_flag = unsatisfied_mask & (1 << i);
switch (unsatisfied_flag)
{
case MAP_VERTEX: llinfos << "Missing vert pos" << llendl; break;
case MAP_NORMAL: llinfos << "Missing normals" << llendl; break;
case MAP_TEXCOORD0: llinfos << "Missing TC 0" << llendl; break;
case MAP_TEXCOORD1: llinfos << "Missing TC 1" << llendl; break;
case MAP_TEXCOORD2: llinfos << "Missing TC 2" << llendl; break;
case MAP_TEXCOORD3: llinfos << "Missing TC 3" << llendl; break;
case MAP_COLOR: llinfos << "Missing vert color" << llendl; break;
case MAP_EMISSIVE: llinfos << "Missing emissive" << llendl; break;
case MAP_TANGENT: llinfos << "Missing tangent" << llendl; break;
case MAP_WEIGHT: llinfos << "Missing weight" << llendl; break;
case MAP_WEIGHT4: llinfos << "Missing weightx4" << llendl; break;
case MAP_CLOTHWEIGHT: llinfos << "Missing clothweight" << llendl; break;
case MAP_TEXTURE_INDEX: llinfos << "Missing tex index" << llendl; break;
default: llinfos << "Missing who effin knows: " << unsatisfied_flag << llendl;
}
}
if (unsatisfied_mask & (1 << TYPE_INDEX))
{
llinfos << "Missing indices" << llendl;
}
llerrs << "Shader consumption mismatches data provision." << llendl;
}
}
}
@ -2512,8 +2544,8 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
llglassertok();
}
LLVertexBuffer::MappedRegion::MappedRegion(S32 index, S32 count)
: mIndex(index), mCount(count)
LLVertexBuffer::MappedRegion::MappedRegion(S32 type, S32 index, S32 count)
: mType(type), mIndex(index), mCount(count)
{
mEnd = mIndex+mCount;
}

View File

@ -104,11 +104,12 @@ public:
class MappedRegion
{
public:
S32 mType;
S32 mIndex;
S32 mCount;
S32 mEnd;
MappedRegion(S32 index, S32 count);
MappedRegion(S32 type, S32 index, S32 count);
};
LLVertexBuffer(const LLVertexBuffer& rhs)

View File

@ -1 +1 @@
3.6.6
3.6.7

View File

@ -8842,6 +8842,18 @@
</array>
</map>
<key>RenderSpecularPrecision</key>
<map>
<key>Comment</key>
<string>Force 32-bit floating point LUT</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
<real>0</real>
</map>
<key>RenderSpecularResX</key>
<map>
<key>Comment</key>
@ -9132,6 +9144,17 @@
<key>Value</key>
<real>1.0</real>
</map>
<key>RenderDeferredDisplayGamma</key>
<map>
<key>Comment</key>
<string>Gamma ramp exponent for final correction before display gamma.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>2.2</real>
</map>
<key>RenderGLCoreProfile</key>
<map>
<key>Comment</key>
@ -9892,6 +9915,17 @@
<key>Value</key>
<integer>1</integer>
</map>
<key>RenderWaterMaterials</key>
<map>
<key>Comment</key>
<string>Water planar reflections include materials rendering.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>S32</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>RenderWaterMipNormal</key>
<map>
<key>Comment</key>

View File

@ -35,6 +35,26 @@ out vec4 frag_color;
#define frag_color gl_FragColor
#endif
uniform float display_gamma;
uniform vec4 gamma;
uniform vec4 lightnorm;
uniform vec4 sunlight_color;
uniform vec4 ambient;
uniform vec4 blue_horizon;
uniform vec4 blue_density;
uniform float haze_horizon;
uniform float haze_density;
uniform float cloud_shadow;
uniform float density_multiplier;
uniform float distance_multiplier;
uniform float max_y;
uniform vec4 glow;
uniform float scene_light_strength;
uniform mat3 env_mat;
uniform mat3 ssao_effect_mat;
uniform vec3 sun_dir;
#if HAS_SHADOW
uniform sampler2DShadow shadowMap0;
uniform sampler2DShadow shadowMap1;
@ -53,15 +73,8 @@ uniform float shadow_bias;
uniform sampler2D diffuseMap;
#endif
vec3 atmosLighting(vec3 light);
vec3 scaleSoftClip(vec3 light);
VARYING vec3 vary_ambient;
VARYING vec3 vary_directional;
VARYING vec3 vary_fragcoord;
VARYING vec3 vary_position;
VARYING vec3 vary_pointlight_col;
VARYING vec3 vary_pointlight_col_linear;
VARYING vec2 vary_texcoord0;
VARYING vec3 vary_norm;
@ -69,12 +82,73 @@ VARYING vec3 vary_norm;
VARYING vec4 vertex_color;
#endif
vec3 vary_PositionEye;
vec3 vary_SunlitColor;
vec3 vary_AmblitColor;
vec3 vary_AdditiveColor;
vec3 vary_AtmosAttenuation;
uniform mat4 inv_proj;
uniform vec2 screen_res;
uniform vec4 light_position[8];
uniform vec3 light_direction[8];
uniform vec3 light_attenuation[8];
uniform vec3 light_diffuse[8];
uniform vec2 screen_res;
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 calcDirectionalLight(vec3 n, vec3 l)
{
@ -83,7 +157,7 @@ vec3 calcDirectionalLight(vec3 n, vec3 l)
return vec3(a,a,a);
}
float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 diffuse, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)
{
//get light vector
vec3 lv = lp.xyz-v;
@ -91,19 +165,20 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa
//get distance
float d = length(lv);
float da = 0.0;
float da = 1.0;
//if (d > 0.0 && la > 0.0 && fa > 0.0)
vec3 col = vec3(0);
if (d > 0.0 && la > 0.0 && fa > 0.0)
{
//normalize light vector
lv /= d;
lv = normalize(lv);
//distance attenuation
float dist = d*la;
da = clamp(1.0-(dist+fa-1.0)/fa, 0.0, 1.0);
da *= da;
da *= 2.0;
float dist = d/la;
float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
dist_atten *= dist_atten;
dist_atten *= 2.0;
// spotlight coefficient.
float spot = max(dot(-ln, lv), is_pointlight);
@ -111,9 +186,15 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa
//angular attenuation
da *= max(dot(n, lv), 0.0);
float lit = max(da * dist_atten,0.0);
col = light_col * lit * diffuse;
// no spec for alpha shader...
}
return da;
return max(col, vec3(0.0,0.0,0.0));
}
#if HAS_SHADOW
@ -136,40 +217,254 @@ float pcfShadow(sampler2DShadow shadowMap, vec4 stc)
}
#endif
#ifdef WATER_FOG
uniform vec4 waterPlane;
uniform vec4 waterFogColor;
uniform float waterFogDensity;
uniform float waterFogKS;
vec4 applyWaterFogDeferred(vec3 pos, vec4 color)
{
//normalize view vector
vec3 view = normalize(pos);
float es = -(dot(view, waterPlane.xyz));
//find intersection point with water plane and eye vector
//get eye depth
float e0 = max(-waterPlane.w, 0.0);
vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w/es : vec3(0.0, 0.0, 0.0);
//get object depth
float depth = length(pos - int_v);
//get "thickness" of water
float l = max(depth, 0.1);
float kd = waterFogDensity;
float ks = waterFogKS;
vec4 kc = waterFogColor;
float F = 0.98;
float t1 = -kd * pow(F, ks * e0);
float t2 = kd + ks * es;
float t3 = pow(F, t2*l) - 1.0;
float L = min(t1/t2*t3, 1.0);
float D = pow(0.98, l*kd);
color.rgb = color.rgb * D + kc.rgb * L;
color.a = kc.a + color.a;
return color;
}
#endif
vec3 getSunlitColor()
{
return vary_SunlitColor;
}
vec3 getAmblitColor()
{
return vary_AmblitColor;
}
vec3 getAdditiveColor()
{
return vary_AdditiveColor;
}
vec3 getAtmosAttenuation()
{
return vary_AtmosAttenuation;
}
void setPositionEye(vec3 v)
{
vary_PositionEye = v;
}
void setSunlitColor(vec3 v)
{
vary_SunlitColor = v;
}
void setAmblitColor(vec3 v)
{
vary_AmblitColor = v;
}
void setAdditiveColor(vec3 v)
{
vary_AdditiveColor = v;
}
void setAtmosAttenuation(vec3 v)
{
vary_AtmosAttenuation = v;
}
void calcAtmospherics(vec3 inPositionEye, float ambFactor) {
vec3 P = inPositionEye;
setPositionEye(P);
vec3 tmpLightnorm = lightnorm.xyz;
vec3 Pn = normalize(P);
float Plen = length(P);
vec4 temp1 = vec4(0);
vec3 temp2 = vec3(0);
vec4 blue_weight;
vec4 haze_weight;
vec4 sunlight = sunlight_color;
vec4 light_atten;
//sunlight attenuation effect (hue and brightness) due to atmosphere
//this is used later for sunlight modulation at various altitudes
light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y);
//I had thought blue_density and haze_density should have equal weighting,
//but attenuation due to haze_density tends to seem too strong
temp1 = blue_density + vec4(haze_density);
blue_weight = blue_density / temp1;
haze_weight = vec4(haze_density) / temp1;
//(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain)
temp2.y = max(0.0, tmpLightnorm.y);
temp2.y = 1. / temp2.y;
sunlight *= exp( - light_atten * temp2.y);
// main atmospheric scattering line integral
temp2.z = Plen * density_multiplier;
// Transparency (-> temp1)
// ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier in a variable because the ati
// compiler gets confused.
temp1 = exp(-temp1 * temp2.z * distance_multiplier);
//final atmosphere attenuation factor
setAtmosAttenuation(temp1.rgb);
//compute haze glow
//(can use temp2.x as temp because we haven't used it yet)
temp2.x = dot(Pn, tmpLightnorm.xyz);
temp2.x = 1. - temp2.x;
//temp2.x is 0 at the sun and increases away from sun
temp2.x = max(temp2.x, .03); //was glow.y
//set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
temp2.x *= glow.x;
//higher glow.x gives dimmer glow (because next step is 1 / "angle")
temp2.x = pow(temp2.x, glow.z);
//glow.z should be negative, so we're doing a sort of (1 / "angle") function
//add "minimum anti-solar illumination"
temp2.x += .25;
//increase ambient when there are more clouds
vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow * 0.5;
/* decrease value and saturation (that in HSV, not HSL) for occluded areas
* // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html
* // The following line of code performs the equivalent of:
* float ambAlpha = tmpAmbient.a;
* float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis
* vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue);
* tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat, ambAlpha);
*/
tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a);
//haze color
setAdditiveColor(
vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow) + tmpAmbient)
+ (haze_horizon * haze_weight) * (sunlight*(1.-cloud_shadow) * temp2.x
+ tmpAmbient)));
//brightness of surface both sunlight and ambient
setSunlitColor(vec3(sunlight * .5));
setAmblitColor(vec3(tmpAmbient * .25));
setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1));
}
vec3 atmosLighting(vec3 light)
{
light *= getAtmosAttenuation().r;
light += getAdditiveColor();
return (2.0 * light);
}
vec3 atmosTransport(vec3 light) {
light *= getAtmosAttenuation().r;
light += getAdditiveColor() * 2.0;
return light;
}
vec3 atmosGetDiffuseSunlightColor()
{
return getSunlitColor();
}
vec3 scaleDownLight(vec3 light)
{
return (light / vec3(scene_light_strength, scene_light_strength, scene_light_strength));
}
vec3 scaleUpLight(vec3 light)
{
return (light * vec3(scene_light_strength, scene_light_strength, scene_light_strength));
}
vec3 atmosAmbient(vec3 light)
{
return getAmblitColor() + (light * vec3(0.5f, 0.5f, 0.5f));
}
vec3 atmosAffectDirectionalLight(float lightIntensity)
{
return getSunlitColor() * vec3(lightIntensity, lightIntensity, lightIntensity);
}
vec3 scaleSoftClip(vec3 light)
{
//soft clip effect:
vec3 zeroes = vec3(0.0f, 0.0f, 0.0f);
vec3 ones = vec3(1.0f, 1.0f, 1.0f);
light = ones - clamp(light, zeroes, ones);
light = ones - pow(light, gamma.xxx);
return light;
}
vec3 fullbrightAtmosTransport(vec3 light) {
float brightness = dot(light.rgb, vec3(0.33333));
return mix(atmosTransport(light.rgb), light.rgb + getAdditiveColor().rgb, brightness * brightness);
}
vec3 fullbrightScaleSoftClip(vec3 light)
{
//soft clip effect:
return light;
}
void main()
{
#ifdef USE_INDEXED_TEX
vec4 diff = diffuseLookup(vary_texcoord0.xy);
#else
vec4 diff = texture2D(diffuseMap,vary_texcoord0.xy);
#endif
#ifdef USE_VERTEX_COLOR
float vertex_color_alpha = vertex_color.a;
#else
float vertex_color_alpha = 1.0;
#endif
float alpha = vertex_color_alpha*diff.a;
vec4 gamma_diff = diff;
diff.rgb = pow(diff.rgb, vec3(2.2f, 2.2f, 2.2f));
vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5;
frag *= screen_res;
vec4 pos = vec4(vary_position, 1.0);
float shadow = 1.0;
#if HAS_SHADOW
float shadow = 0.0;
vec4 spos = pos;
if (spos.z > -shadow_clip.w)
{
shadow = 0.0;
vec4 lpos;
vec4 near_split = shadow_clip*-0.75;
@ -230,30 +525,81 @@ void main()
}
#endif
vec3 normal = vary_norm;
vec3 l = light_position[0].xyz;
vec3 dlight = calcDirectionalLight(normal, l);
dlight = dlight * vary_directional.rgb * vary_pointlight_col;
#if HAS_SHADOW
vec4 col = vec4(vary_ambient + dlight * shadow, vertex_color_alpha);
#ifdef USE_INDEXED_TEX
vec4 diff = diffuseLookup(vary_texcoord0.xy);
#else
vec4 col = vec4(vary_ambient + dlight, vertex_color_alpha);
vec4 diff = texture2D(diffuseMap,vary_texcoord0.xy);
#endif
vec4 color = gamma_diff * col;
#ifdef FOR_IMPOSTOR
vec4 color;
color.rgb = diff.rgb;
#ifdef USE_VERTEX_COLOR
float final_alpha = diff.a * vertex_color.a;
diff.rgb *= vertex_color.rgb;
#else
float final_alpha = diff.a;
#endif
// Insure we don't pollute depth with invis pixels in impostor rendering
//
if (final_alpha < 0.01)
{
discard;
}
#else
#ifdef USE_VERTEX_COLOR
float final_alpha = diff.a * vertex_color.a;
diff.rgb *= vertex_color.rgb;
#else
float final_alpha = diff.a;
#endif
vec4 gamma_diff = diff;
diff.rgb = srgb_to_linear(diff.rgb);
vec3 norm = vary_norm;
calcAtmospherics(pos.xyz, 1.0);
vec2 abnormal = encode_normal(norm.xyz);
norm.xyz = decode_normal(abnormal.xy);
float da = dot(norm.xyz, sun_dir.xyz);
float final_da = da;
final_da = min(final_da, shadow);
final_da = max(final_da, 0.0f);
final_da = min(final_da, 1.0f);
final_da = pow(final_da, 1.0/1.3);
vec4 color = vec4(0,0,0,0);
color.rgb = atmosAmbient(color.rgb);
color.a = final_alpha;
float ambient = abs(da);
ambient *= 0.5;
ambient *= ambient;
ambient = (1.0-ambient);
color.rgb *= ambient;
color.rgb += atmosAffectDirectionalLight(final_da);
color.rgb *= gamma_diff.rgb;
//color.rgb = mix(diff.rgb, color.rgb, final_alpha);
color.rgb = atmosLighting(color.rgb);
color.rgb = scaleSoftClip(color.rgb);
//convert to linear space
color.rgb = pow(color.rgb, vec3(2.2));
col = vec4(0,0,0,0);
vec4 light = vec4(0,0,0,0);
color.rgb = srgb_to_linear(color.rgb);
#define LIGHT_LOOP(i) col.rgb += light_diffuse[i].rgb * calcPointLightOrSpotLight(pos.xyz, normal, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z);
#define LIGHT_LOOP(i) light.rgb += calcPointLightOrSpotLight(light_diffuse[i].rgb, diff.rgb, pos.xyz, norm, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z);
LIGHT_LOOP(1)
LIGHT_LOOP(2)
@ -263,10 +609,19 @@ void main()
LIGHT_LOOP(6)
LIGHT_LOOP(7)
color.rgb += diff.rgb * vary_pointlight_col_linear * col.rgb;
// keep it linear
//
color.rgb += light.rgb;
//convert to gamma space
color.rgb = pow(color.rgb, vec3(1.0/2.2));
// straight to display gamma, we're post-deferred
//
color.rgb = linear_to_srgb(color.rgb);
#ifdef WATER_FOG
color = applyWaterFogDeferred(pos.xyz, color);
#endif
#endif
frag_color = color;
}

View File

@ -55,33 +55,18 @@ mat4 getSkinnedTransform();
#endif
#endif
vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
void calcAtmospherics(vec3 inPositionEye);
vec3 atmosAmbient(vec3 light);
vec3 atmosAffectDirectionalLight(float lightIntensity);
vec3 scaleDownLight(vec3 light);
vec3 scaleUpLight(vec3 light);
VARYING vec3 vary_ambient;
VARYING vec3 vary_directional;
VARYING vec3 vary_fragcoord;
VARYING vec3 vary_position;
VARYING vec3 vary_pointlight_col;
VARYING vec3 vary_pointlight_col_linear;
#ifdef USE_VERTEX_COLOR
VARYING vec4 vertex_color;
#endif
VARYING vec2 vary_texcoord0;
VARYING vec3 vary_norm;
uniform float near_clip;
uniform vec3 sun_dir;
void main()
{
vec4 pos;
@ -134,42 +119,8 @@ void main()
vary_norm = norm;
vary_position = pos.xyz;
calcAtmospherics(pos.xyz);
#ifndef USE_VERTEX_COLOR
vec4 diffuse_color = vec4(1,1,1,1);
#endif
//vec4 color = calcLighting(pos.xyz, norm, diffuse_color, vec4(0.));
vec4 col = vec4(0.0, 0.0, 0.0, diffuse_color.a);
vec3 diff = diffuse_color.rgb;
vary_pointlight_col = diff;
vary_pointlight_col_linear = pow(diff, vec3(2.2));
col.rgb = vec3(0,0,0);
// Add windlight lights
col.rgb = atmosAmbient(col.rgb);
float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
ambient *= 0.5;
ambient *= ambient;
ambient = (1.0-ambient);
col.rgb *= ambient;
vary_ambient = col.rgb*diff.rgb;
vary_directional.rgb = atmosAffectDirectionalLight(1.0f);
col.rgb = col.rgb*diff.rgb;
#ifdef USE_VERTEX_COLOR
vertex_color = col;
vertex_color = diffuse_color;
#endif
#ifdef HAS_SKIN

View File

@ -50,7 +50,7 @@ void main()
{
discard;
}
frag_data[0] = vec4(col.rgb, 0.0);
frag_data[1] = vec4(0,0,0,0);
vec3 nvn = normalize(vary_normal);

View File

@ -35,29 +35,143 @@ out vec4 frag_color;
uniform sampler2D diffuseMap;
#endif
VARYING vec3 vary_position;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
vec3 fullbrightAtmosTransport(vec3 light);
vec3 fullbrightScaleSoftClip(vec3 light);
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 fullbrightAtmosTransportDeferred(vec3 light)
{
return light;
}
vec3 fullbrightScaleSoftClipDeferred(vec3 light)
{
//soft clip effect:
return light;
}
#ifdef HAS_ALPHA_MASK
uniform float minimum_alpha;
#endif
#ifdef WATER_FOG
uniform vec4 waterPlane;
uniform vec4 waterFogColor;
uniform float waterFogDensity;
uniform float waterFogKS;
vec4 applyWaterFogDeferred(vec3 pos, vec4 color)
{
//normalize view vector
vec3 view = normalize(pos);
float es = -(dot(view, waterPlane.xyz));
//find intersection point with water plane and eye vector
//get eye depth
float e0 = max(-waterPlane.w, 0.0);
vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w/es : vec3(0.0, 0.0, 0.0);
//get object depth
float depth = length(pos - int_v);
//get "thickness" of water
float l = max(depth, 0.1);
float kd = waterFogDensity;
float ks = waterFogKS;
vec4 kc = waterFogColor;
float F = 0.98;
float t1 = -kd * pow(F, ks * e0);
float t2 = kd + ks * es;
float t3 = pow(F, t2*l) - 1.0;
float L = min(t1/t2*t3, 1.0);
float D = pow(0.98, l*kd);
color.rgb = color.rgb * D + kc.rgb * L;
color.a = kc.a + color.a;
return color;
}
#endif
void main()
{
#if HAS_DIFFUSE_LOOKUP
vec4 color = diffuseLookup(vary_texcoord0.xy)*vertex_color;
vec4 color = diffuseLookup(vary_texcoord0.xy);
#else
vec4 color = texture2D(diffuseMap, vary_texcoord0.xy)*vertex_color;
vec4 color = texture2D(diffuseMap, vary_texcoord0.xy);
#endif
color.rgb = pow(color.rgb,vec3(2.2f,2.2f,2.2f));
float final_alpha = color.a * vertex_color.a;
#ifdef HAS_ALPHA_MASK
if (color.a < minimum_alpha)
{
discard;
}
#endif
color.rgb *= vertex_color.rgb;
color.rgb = srgb_to_linear(color.rgb);
color.rgb = fullbrightAtmosTransportDeferred(color.rgb);
color.rgb = fullbrightScaleSoftClipDeferred(color.rgb);
color.rgb = fullbrightAtmosTransport(color.rgb);
color.rgb = linear_to_srgb(color.rgb);
color.rgb = fullbrightScaleSoftClip(color.rgb);
#ifdef WATER_FOG
vec3 pos = vary_position;
vec4 fogged = applyWaterFogDeferred(pos, vec4(color.rgb, final_alpha));
color.rgb = fogged.rgb;
color.a = fogged.a;
#else
color.a = final_alpha;
#endif
color.rgb = pow(color.rgb, vec3(1.0/2.2));
frag_color = color;
frag_color.rgb = color.rgb;
frag_color.a = color.a;
}

View File

@ -40,6 +40,9 @@ vec3 atmosAffectDirectionalLight(float lightIntensity);
vec3 scaleDownLight(vec3 light);
vec3 scaleUpLight(vec3 light);
#ifdef WATER_FOG
VARYING vec3 vary_position;
#endif
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
@ -53,7 +56,11 @@ void main()
passTextureIndex();
gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
#ifdef WATER_FOG
vary_position = pos.xyz;
#endif
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
calcAtmospherics(pos.xyz);

View File

@ -38,6 +38,42 @@ 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
}
void main()
{
vec4 col = texture2D(diffuseMap, vary_texcoord0.xy);
@ -47,7 +83,12 @@ void main()
discard;
}
frag_data[0] = vec4(col.rgb, col.a * 0.005);
frag_data[1] = texture2D(specularMap, vary_texcoord0.xy);
frag_data[2] = vec4(texture2D(normalMap, vary_texcoord0.xy).xyz, 0.0);
vec4 norm = texture2D(normalMap, vary_texcoord0.xy);
vec4 spec = texture2D(specularMap, vary_texcoord0.xy);
col.rgb = linear_to_srgb(col.rgb);
frag_data[0] = vec4(col.rgb, 0.0);
frag_data[1] = spec;
frag_data[2] = vec4(norm.xy,0,0);
}

View File

@ -29,6 +29,44 @@
#define DIFFUSE_ALPHA_MODE_EMISSIVE 3
uniform float emissive_brightness;
uniform float display_gamma;
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
}
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
@ -114,6 +152,52 @@ uniform vec3 light_direction[8];
uniform vec3 light_attenuation[8];
uniform vec3 light_diffuse[8];
#ifdef WATER_FOG
uniform vec4 waterPlane;
uniform vec4 waterFogColor;
uniform float waterFogDensity;
uniform float waterFogKS;
vec4 applyWaterFogDeferred(vec3 pos, vec4 color)
{
//normalize view vector
vec3 view = normalize(pos);
float es = -(dot(view, waterPlane.xyz));
//find intersection point with water plane and eye vector
//get eye depth
float e0 = max(-waterPlane.w, 0.0);
vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w/es : vec3(0.0, 0.0, 0.0);
//get object depth
float depth = length(pos - int_v);
//get "thickness" of water
float l = max(depth, 0.1);
float kd = waterFogDensity;
float ks = waterFogKS;
vec4 kc = waterFogColor;
float F = 0.98;
float t1 = -kd * pow(F, ks * e0);
float t2 = kd + ks * es;
float t3 = pow(F, t2*l) - 1.0;
float L = min(t1/t2*t3, 1.0);
float D = pow(0.98, l*kd);
color.rgb = color.rgb * D + kc.rgb * L;
color.a = kc.a + color.a;
return color;
}
#endif
vec3 calcDirectionalLight(vec3 n, vec3 l)
{
float a = max(dot(n,l),0.0);
@ -133,14 +217,14 @@ vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 npos, vec3 diffuse, vec4 spe
vec3 col = vec3(0,0,0);
//if (d > 0.0 && la > 0.0 && fa > 0.0)
if (d > 0.0 && la > 0.0 && fa > 0.0)
{
//normalize light vector
lv /= d;
lv = normalize(lv);
//distance attenuation
float dist = d*la;
float dist_atten = clamp(1.0-(dist-1.0+fa)/fa, 0.0, 1.0);
float dist = d/la;
float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
dist_atten *= dist_atten;
dist_atten *= 2.0;
@ -199,10 +283,13 @@ vec4 getPosition_d(vec2 pos_screen, float depth)
return pos;
}
#ifndef WATER_FOG
vec3 getPositionEye()
{
return vary_PositionEye;
}
#endif
vec3 getSunlitColor()
{
return vary_SunlitColor;
@ -458,8 +545,8 @@ void main()
#endif
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
vec3 old_diffcol = diffcol.rgb;
diffcol.rgb = pow(diffcol.rgb, vec3(2.2));
vec3 gamma_diff = diffcol.rgb;
diffcol.rgb = srgb_to_linear(diffcol.rgb);
#endif
#if HAS_SPECULAR_MAP
@ -485,6 +572,9 @@ void main()
norm.xyz = tnorm;
norm.xyz = normalize(norm.xyz);
vec2 abnormal = encode_normal(norm.xyz);
norm.xyz = decode_normal(abnormal.xy);
vec4 final_color = diffcol;
#if (DIFFUSE_ALPHA_MODE != DIFFUSE_ALPHA_MODE_EMISSIVE)
@ -588,22 +678,26 @@ void main()
vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
float da =dot(norm.xyz, sun_dir.xyz);
float final_da = da;
final_da = min(final_da, shadow);
final_da = max(final_da, diffuse.a);
//final_da = max(final_da, diffuse.a);
final_da = max(final_da, 0.0f);
final_da = min(final_da, 1.0f);
final_da = pow(final_da, 1.0/1.3);
col.rgb = atmosAmbient(col);
float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
float ambient = min(abs(da), 1.0);
ambient *= 0.5;
ambient *= ambient;
ambient = (1.0-ambient);
col.rgb *= ambient;
col.rgb = col.rgb + atmosAffectDirectionalLight(pow(final_da, 1.0/1.3));
col.rgb *= old_diffcol.rgb;
col.rgb = col.rgb + atmosAffectDirectionalLight(final_da);
col.rgb *= gamma_diff.rgb;
float glare = 0.0;
@ -626,7 +720,8 @@ void main()
col += spec_contrib;
}
col = mix(col.rgb, old_diffcol.rgb, diffuse.a);
col = mix(col.rgb, diffcol.rgb, diffuse.a);
if (envIntensity > 0.0)
{
@ -644,16 +739,20 @@ void main()
glare += cur_glare;
}
col = mix(atmosLighting(col), fullbrightAtmosTransport(col), diffuse.a);
col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a);
//col = mix(atmosLighting(col), fullbrightAtmosTransport(col), diffuse.a);
//col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a);
col = atmosLighting(col);
col = scaleSoftClip(col);
//convert to linear space before adding local lights
col = pow(col, vec3(2.2));
col = srgb_to_linear(col);
vec3 npos = normalize(-pos.xyz);
vec3 light = vec3(0,0,0);
#define LIGHT_LOOP(i) col.rgb = col.rgb + calcPointLightOrSpotLight(light_diffuse[i].rgb, npos, diffuse.rgb, final_specular, pos.xyz, norm.xyz, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z, glare);
#define LIGHT_LOOP(i) light.rgb += calcPointLightOrSpotLight(light_diffuse[i].rgb, npos, diffuse.rgb, final_specular, pos.xyz, norm.xyz, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z, glare);
LIGHT_LOOP(1)
LIGHT_LOOP(2)
@ -663,13 +762,22 @@ void main()
LIGHT_LOOP(6)
LIGHT_LOOP(7)
col.rgb += light.rgb;
glare = min(glare, 1.0);
float al = max(diffcol.a,glare)*vertex_color.a;
//convert to gamma space for display on screen
col.rgb = pow(col.rgb, vec3(1.0/2.2));
col.rgb = linear_to_srgb(col.rgb);
#ifdef WATER_FOG
vec4 temp = applyWaterFogDeferred(pos, vec4(col.rgb, al));
col.rgb = temp.rgb;
al = temp.a;
#endif
frag_color.rgb = col.rgb;
glare = min(glare, 1.0);
frag_color.a = max(diffcol.a,glare)*vertex_color.a;
frag_color.a = al;
#else
frag_data[0] = final_color;
@ -677,3 +785,4 @@ void main()
frag_data[2] = final_normal; // XY = Normal. Z = Env. intensity.
#endif
}

View File

@ -142,3 +142,4 @@ vary_normal = n;
#endif
#endif
}

View File

@ -36,6 +36,7 @@ uniform sampler2DRect diffuseRect;
uniform sampler2DRect specularRect;
uniform sampler2DRect normalMap;
uniform samplerCube environmentMap;
uniform sampler2D noiseMap;
uniform sampler2D lightFunc;
@ -98,6 +99,8 @@ void main()
norm = normalize(norm);
vec4 spec = texture2DRect(specularRect, frag.xy);
vec3 diff = texture2DRect(diffuseRect, frag.xy).rgb;
float noise = texture2D(noiseMap, frag.xy/128.0).b;
vec3 out_col = vec3(0,0,0);
vec3 npos = normalize(-pos);
@ -105,47 +108,56 @@ void main()
for (int i = 0; i < LIGHT_COUNT; ++i)
{
vec3 lv = light[i].xyz-pos;
float d = length(lv);
float dist = d * light[i].w;
float dist = length(lv);
dist /= light[i].w;
if (dist <= 1.0)
{
float da = dot(norm, lv);
float da = dot(norm, lv);
if (da > 0.0)
{
lv /= d;
da = dot(norm, lv);
{
lv = normalize(lv);
da = dot(norm, lv);
float fa = light_col[i].a+1.0;
float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
dist_atten *= dist_atten;
dist_atten *= 2.0;
float fa = light_col[i].a+1.0;
float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
dist_atten *= dist_atten;
dist_atten *= 2.0;
float lit = da * dist_atten;
vec3 col = light_col[i].rgb*lit*diff;
if (spec.a > 0.0)
{
lit = min(da*6.0, 1.0) * dist_atten;
//vec3 ref = dot(pos+lv, norm);
vec3 h = normalize(lv+npos);
float nh = dot(norm, h);
float nv = dot(norm, npos);
float vh = dot(npos, h);
float sa = nh;
float fres = pow(1 - dot(h, npos), 5)*0.4+0.5;
dist_atten *= noise;
float gtdenom = 2 * nh;
float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
col += max(lit*scol*light_col[i].rgb*spec.rgb, vec3(0.0));
}
float lit = da * dist_atten;
vec3 col = light_col[i].rgb*lit*diff;
out_col += col;
//vec3 col = vec3(dist2, light_col[i].a, lit);
if (spec.a > 0.0)
{
lit = min(da*6.0, 1.0) * dist_atten;
//vec3 ref = dot(pos+lv, norm);
vec3 h = normalize(lv+npos);
float nh = dot(norm, h);
float nv = dot(norm, npos);
float vh = dot(npos, h);
float sa = nh;
float fres = pow(1 - dot(h, npos), 5)*0.4+0.5;
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 += lit*scol*light_col[i].rgb*spec.rgb;
//col += spec.rgb;
}
}
out_col += col;
}
}
}
frag_color.rgb = out_col;
frag_color.a = 0.0;

View File

@ -84,16 +84,48 @@ vec3 decode_normal (vec2 enc)
n.z = 1-f/2;
return n;
}
vec4 correctWithGamma(vec4 col)
vec3 srgb_to_linear(vec3 cs)
{
return vec4(pow(col.rgb, vec3(2.2)), col.a);
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
}
vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
ret = correctWithGamma(ret);
ret.rgb = srgb_to_linear(ret.rgb);
vec2 dist = tc-vec2(0.5);
@ -109,7 +141,7 @@ 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.rgb = srgb_to_linear(ret.rgb);
vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
@ -127,7 +159,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.rgb = srgb_to_linear(ret.rgb);
vec2 dist = tc-vec2(0.5);

View File

@ -93,52 +93,64 @@ void main()
vec3 pos = getPosition(frag.xy).xyz;
vec3 lv = trans_center.xyz-pos;
float d = length(lv);
float dist = d*size;
vec3 col = vec3(0.0);
if (dist <= 1.0)
float dist = length(lv);
dist /= size;
if (dist > 1.0)
{
vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
norm = decode_normal(norm.xy); // unpack norm
norm = normalize(norm);
lv = normalize(lv);
float da = max(dot(norm, lv), 0.0);
discard;
}
vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
norm = decode_normal(norm.xy); // unpack norm
float da = dot(norm, lv);
if (da < 0.0)
{
discard;
}
norm = normalize(norm);
lv = normalize(lv);
da = dot(norm, lv);
//float noise = texture2D(noiseMap, frag.xy/128.0).b;
col = texture2DRect(diffuseRect, frag.xy).rgb;
float fa = falloff+1.0;
float dist_atten = clamp(1.0-(dist-1.0+fa)/fa, 0.0, 1.0);
dist_atten *= dist_atten;
dist_atten *= 2.0;
vec3 col = texture2DRect(diffuseRect, frag.xy).rgb;
float fa = falloff+1.0;
float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
dist_atten *= dist_atten;
dist_atten *= 2.0;
float lit = da * dist_atten;
col = color.rgb*lit*col;
col = color.rgb*lit*col;
vec4 spec = texture2DRect(specularRect, frag.xy);
if (spec.a > 0.0)
vec4 spec = texture2DRect(specularRect, frag.xy);
if (spec.a > 0.0)
{
lit = min(da*6.0, 1.0) * dist_atten;
vec3 npos = -normalize(pos);
vec3 h = normalize(lv+npos);
float nh = dot(norm, h);
float nv = dot(norm, npos);
float vh = dot(npos, h);
float sa = nh;
float fres = pow(1 - dot(h, npos), 5) * 0.4+0.5;
float gtdenom = 2 * nh;
float gt = max(0,(min(gtdenom * nv / vh, gtdenom * da / vh)));
if (nh > 0.0)
{
lit = min(da*6.0, 1.0) * dist_atten;
vec3 npos = -normalize(pos);
vec3 h = normalize(lv+npos);
float nh = dot(norm, h);
float nv = dot(norm, npos);
float vh = dot(npos, h);
float sa = nh;
float fres = pow(1 - dot(h, npos), 5) * 0.4+0.5;
float gtdenom = 2 * nh;
float gt = max(0,(min(gtdenom * nv / vh, gtdenom * da / vh)));
float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
col += max(lit*scol*color.rgb*spec.rgb, vec3(0.0));
col += lit*scol*color.rgb*spec.rgb;
}
}
if (dot(col, col) <= 0.0)
{
discard;
}
frag_color.rgb = col;
frag_color.a = 0.0;
}

View File

@ -36,11 +36,32 @@ uniform sampler2DRect diffuseRect;
uniform vec2 screen_res;
VARYING vec2 vary_fragcoord;
uniform float texture_gamma;
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
}
void main()
{
vec4 diff = texture2DRect(diffuseRect, vary_fragcoord);
frag_color = pow(diff, vec4(texture_gamma, texture_gamma, texture_gamma, 1.0f));
diff.rgb = linear_to_srgb(diff.rgb);
frag_color = diff;
}

View File

@ -79,6 +79,43 @@ vec3 vary_AtmosAttenuation;
uniform mat4 inv_proj;
uniform vec2 screen_res;
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;
@ -154,6 +191,53 @@ void setAtmosAttenuation(vec3 v)
vary_AtmosAttenuation = v;
}
#ifdef WATER_FOG
uniform vec4 waterPlane;
uniform vec4 waterFogColor;
uniform float waterFogDensity;
uniform float waterFogKS;
vec4 applyWaterFogDeferred(vec3 pos, vec4 color)
{
//normalize view vector
vec3 view = normalize(pos);
float es = -(dot(view, waterPlane.xyz));
//find intersection point with water plane and eye vector
//get eye depth
float e0 = max(-waterPlane.w, 0.0);
vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w/es : vec3(0.0, 0.0, 0.0);
//get object depth
float depth = length(pos - int_v);
//get "thickness" of water
float l = max(depth, 0.1);
float kd = waterFogDensity;
float ks = waterFogKS;
vec4 kc = waterFogColor;
float F = 0.98;
float t1 = -kd * pow(F, ks * e0);
float t2 = kd + ks * es;
float t3 = pow(F, t2*l) - 1.0;
float L = min(t1/t2*t3, 1.0);
float D = pow(0.98, l*kd);
color.rgb = color.rgb * D + kc.rgb * L;
color.a = kc.a + color.a;
return color;
}
#endif
void calcAtmospherics(vec3 inPositionEye, float ambFactor) {
vec3 P = inPositionEye;
@ -308,13 +392,16 @@ void main()
float envIntensity = norm.z;
norm.xyz = decode_normal(norm.xy); // unpack norm
float da = max(dot(norm.xyz, sun_dir.xyz), 0.0);
da = pow(da, 1.0/1.3);
float da = dot(norm.xyz, sun_dir.xyz);
float final_da = max(0.0,da);
final_da = min(final_da, 1.0f);
final_da = pow(final_da, 1.0/1.3);
vec4 diffuse = texture2DRect(diffuseRect, tc);
//convert to gamma space
diffuse.rgb = pow(diffuse.rgb, vec3(1.0/2.2));
diffuse.rgb = linear_to_srgb(diffuse.rgb);
vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);
vec3 col;
@ -330,7 +417,7 @@ void main()
col.rgb *= ambient;
col += atmosAffectDirectionalLight(max(min(da, 1.0), 0.0));
col += atmosAffectDirectionalLight(final_da);
col *= diffuse.rgb;
@ -370,13 +457,19 @@ void main()
col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a);
}
col = pow(col, vec3(2.2));
#ifdef WATER_FOG
vec4 fogged = applyWaterFogDeferred(pos,vec4(col, bloom));
col = fogged.rgb;
bloom = fogged.a;
#endif
col = srgb_to_linear(col);
//col = vec3(1,0,1);
//col.g = envIntensity;
}
frag_color.rgb = col;
frag_color.rgb = col.rgb;
frag_color.a = bloom;
}

View File

@ -85,9 +85,46 @@ vec3 decode_normal (vec2 enc)
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 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 correctWithGamma(vec4 col)
{
return vec4(pow(col.rgb, vec3(2.2)), col.a);
return vec4(srgb_to_linear(col.rgb), col.a);
}
vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)

View File

@ -0,0 +1,46 @@
/**
* @file srgb.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$
*/
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));
return mix(high_range, low_range, lte);
}
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));
return mix(high_range, low_range, lt);
}

View File

@ -0,0 +1,54 @@
/**
* @file srgb.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$
*/
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;
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;
}
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));
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;
}

View File

@ -0,0 +1,157 @@
/**
* @file underWaterF.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$
*/
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_data[3];
#else
#define frag_data gl_FragData
#endif
uniform sampler2D diffuseMap;
uniform sampler2D bumpMap;
uniform sampler2D screenTex;
uniform sampler2D refTex;
uniform sampler2D screenDepth;
uniform vec4 fogCol;
uniform vec3 lightDir;
uniform vec3 specular;
uniform float lightExp;
uniform vec2 fbScale;
uniform float refScale;
uniform float znear;
uniform float zfar;
uniform float kd;
uniform vec4 waterPlane;
uniform vec3 eyeVec;
uniform vec4 waterFogColor;
uniform float waterFogDensity;
uniform float waterFogKS;
uniform vec2 screenRes;
//bigWave is (refCoord.w, view.w);
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;
}
vec4 applyWaterFog(vec4 color, vec3 viewVec)
{
//normalize view vector
vec3 view = normalize(viewVec);
float es = -view.z;
//find intersection point with water plane and eye vector
//get eye depth
float e0 = max(-waterPlane.w, 0.0);
//get object depth
float depth = length(viewVec);
//get "thickness" of water
float l = max(depth, 0.1);
float kd = waterFogDensity;
float ks = waterFogKS;
vec4 kc = waterFogColor;
float F = 0.98;
float t1 = -kd * pow(F, ks * e0);
float t2 = kd + ks * es;
float t3 = pow(F, t2*l) - 1.0;
float L = min(t1/t2*t3, 1.0);
float D = pow(0.98, l*kd);
//return vec4(1.0, 0.0, 1.0, 1.0);
return color * D + kc * L;
//depth /= 10.0;
//return vec4(depth,depth,depth,0.0);
}
void main()
{
vec4 color;
//get detail normals
vec3 wave1 = texture2D(bumpMap, vec2(refCoord.w, view.w)).xyz*2.0-1.0;
vec3 wave2 = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0;
vec3 wave3 = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0;
vec3 wavef = normalize(wave1+wave2+wave3);
//figure out distortion vector (ripply)
vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5;
distort = distort+wavef.xy*refScale;
vec4 fb = texture2D(screenTex, distort);
frag_data[0] = vec4(linear_to_srgb(fb.rgb), 1.0); // diffuse
frag_data[1] = vec4(0.5,0.5,0.5, 0.95); // speccolor*spec, spec
frag_data[2] = vec4(encode_normal(wavef), 0.0, 0.0); // normalxyz, displace
}

View File

@ -53,11 +53,12 @@ uniform vec3 specular;
uniform float lightExp;
uniform float refScale;
uniform float kd;
uniform vec2 screenRes;
uniform vec3 normScale;
uniform float fresnelScale;
uniform float fresnelOffset;
uniform float blurMultiplier;
uniform mat3 normal_matrix;
uniform mat4 norm_mat; //region space to screen space
//bigWave is (refCoord.w, view.w);
VARYING vec4 refCoord;
@ -65,6 +66,43 @@ 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
}
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);
@ -119,7 +157,7 @@ void main()
refcol *= df1 * 0.333;
vec3 wavef = (wave1 + wave2 * 0.4 + wave3 * 0.6) * 0.5;
//wavef.z *= max(-viewVec.z, 0.1);
wavef.z *= max(-viewVec.z, 0.1);
wavef = normalize(wavef);
float df2 = dot(viewVec, wavef) * fresnelScale+fresnelOffset;
@ -129,13 +167,14 @@ void main()
vec2 refvec4 = distort+refdistort4/dmod;
float dweight = min(dist2*blurMultiplier, 1.0);
vec4 baseCol = texture2D(refTex, refvec4);
refcol = mix(baseCol*df2, refcol, dweight);
//get specular component
//float spec = clamp(dot(lightDir, (reflect(viewVec,wavef))),0.0,1.0);
float spec = clamp(dot(lightDir, (reflect(viewVec,wavef))),0.0,1.0);
//harden specular
//spec = pow(spec, 128.0);
spec = pow(spec, 128.0);
//figure out distortion vector (ripply)
vec2 distort2 = distort+wavef.xy*refScale/max(dmod*df1, 1.0);
@ -146,24 +185,17 @@ void main()
// Note we actually want to use just df1, but multiplying by 0.999999 gets around an nvidia compiler bug
color.rgb = mix(fb.rgb, refcol.rgb, df1 * 0.99999);
float shadow = 1.0;
vec4 pos = vary_position;
//vec3 nz = texture2D(noiseMap, gl_FragCoord.xy/128.0).xyz;
vec4 spos = pos;
//spec *= shadow;
//color.rgb += spec * specular;
color.rgb += spec * specular;
color.rgb = atmosTransport(color.rgb);
color.rgb = scaleSoftClip(color.rgb);
//color.a = spec * sunAngle2;
color.a = spec * sunAngle2;
//wavef.z *= 0.1f;
//wavef = normalize(wavef);
vec3 screenspacewavef = normal_matrix*wavef;
vec3 screenspacewavef = normalize((norm_mat*vec4(wavef, 1.0)).xyz);
frag_data[0] = vec4(color.rgb, 0.5); // diffuse
frag_data[1] = vec4(0.5,0.5,0.5, 0.95); // speccolor*spec, spec
frag_data[2] = vec4(encode_normal(screenspacewavef), 0.0, 0.0); // normalxyz, displace
frag_data[0] = vec4(color.rgb, color); // diffuse
frag_data[1] = vec4(0); // speccolor, spec
frag_data[2] = vec4(encode_normal(screenspacewavef.xyz*0.5+0.5), 0.05, 0);// normalxy, 0, 0
}

View File

@ -85,7 +85,7 @@ void main()
pos.w = 1.0;
pos = modelview_matrix*pos;
calcAtmospherics(view.xyz);
calcAtmospherics(pos.xyz);
//pass wave parameters to pixel shader
vec2 bigWave = (v.xy) * vec2(0.04,0.04) + d1 * time * 0.055;

View File

@ -31,8 +31,6 @@ out vec4 frag_color;
uniform sampler2D depthMap;
uniform float delta;
VARYING vec2 tc0;
VARYING vec2 tc1;
VARYING vec2 tc2;

View File

@ -33,8 +33,6 @@ out vec4 frag_color;
uniform sampler2DRect depthMap;
uniform float delta;
VARYING vec2 tc0;
VARYING vec2 tc1;
VARYING vec2 tc2;

View File

@ -41,13 +41,13 @@ void default_lighting()
{
vec4 color = diffuseLookup(vary_texcoord0.xy);
color *= vertex_color;
if (color.a < minimum_alpha)
{
discard;
}
color.rgb *= vertex_color.rgb;
color.rgb = atmosLighting(color.rgb);
color.rgb = scaleSoftClip(color.rgb);

View File

@ -69,6 +69,43 @@ uniform vec2 screen_res;
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);
@ -88,10 +125,9 @@ vec3 decode_normal (vec2 enc)
vec4 correctWithGamma(vec4 col)
{
return vec4(pow(col.rgb, vec3(2.2)), col.a);
return vec4(srgb_to_linear(col.rgb), col.a);
}
vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
{
vec4 ret = texture2DLod(projectionMap, tc, lod);
@ -298,14 +334,12 @@ void main()
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)
{
stc.xy /= stc.w;
float fatten = clamp(envIntensity*envIntensity+envIntensity*0.25, 0.25, 1.0);
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 &&
@ -313,7 +347,7 @@ void main()
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, proj_lod).rgb*shadow*spec.rgb;
}
}
}

View File

@ -78,6 +78,43 @@ vec3 vary_AtmosAttenuation;
uniform mat4 inv_proj;
uniform vec2 screen_res;
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);
@ -246,6 +283,52 @@ void calcAtmospherics(vec3 inPositionEye, float ambFactor) {
setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1));
}
#ifdef WATER_FOG
uniform vec4 waterPlane;
uniform vec4 waterFogColor;
uniform float waterFogDensity;
uniform float waterFogKS;
vec4 applyWaterFogDeferred(vec3 pos, vec4 color)
{
//normalize view vector
vec3 view = normalize(pos);
float es = -(dot(view, waterPlane.xyz));
//find intersection point with water plane and eye vector
//get eye depth
float e0 = max(-waterPlane.w, 0.0);
vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w/es : vec3(0.0, 0.0, 0.0);
//get object depth
float depth = length(pos - int_v);
//get "thickness" of water
float l = max(depth, 0.1);
float kd = waterFogDensity;
float ks = waterFogKS;
vec4 kc = waterFogColor;
float F = 0.98;
float t1 = -kd * pow(F, ks * e0);
float t2 = kd + ks * es;
float t3 = pow(F, t2*l) - 1.0;
float L = min(t1/t2*t3, 1.0);
float D = pow(0.98, l*kd);
color.rgb = color.rgb * D + kc.rgb * L;
color.a = kc.a + color.a;
return color;
}
#endif
vec3 atmosLighting(vec3 light)
{
light *= getAtmosAttenuation().r;
@ -326,7 +409,7 @@ void main()
vec4 diffuse = texture2DRect(diffuseRect, tc);
//convert to gamma space
diffuse.rgb = pow(diffuse.rgb, vec3(1.0/2.2));
diffuse.rgb = linear_to_srgb(diffuse.rgb);
vec3 col;
float bloom = 0.0;
@ -392,7 +475,13 @@ void main()
col = mix(scaleSoftClip(col), fullbrightScaleSoftClip(col), diffuse.a);
}
col = pow(col, vec3(2.2));
#ifdef WATER_FOG
vec4 fogged = applyWaterFogDeferred(pos,vec4(col, bloom));
col = fogged.rgb;
bloom = fogged.a;
#endif
col = srgb_to_linear(col);
//col = vec3(1,0,1);
//col.g = envIntensity;

View File

@ -86,9 +86,46 @@ vec3 decode_normal (vec2 enc)
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 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 correctWithGamma(vec4 col)
{
return vec4(pow(col.rgb, vec3(2.2)), col.a);
return vec4(srgb_to_linear(col.rgb), col.a);
}
vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
@ -316,7 +353,7 @@ void main()
}
}
}
//not sure why, but this line prevents MATBUG-194
col = max(col, vec3(0.0));

View File

@ -132,10 +132,16 @@ void LLDrawable::destroy()
sNumZombieDrawables--;
}
// Attempt to catch violations of this in debug,
// knowing that some false alarms may result
//
llassert(!LLSpatialGroup::sNoDelete);
/* cannot be guaranteed and causes crashes on false alarms
if (LLSpatialGroup::sNoDelete)
{
llerrs << "Illegal deletion of LLDrawable!" << llendl;
}
}*/
std::for_each(mFaces.begin(), mFaces.end(), DeletePointer());
mFaces.clear();
@ -254,7 +260,7 @@ S32 LLDrawable::findReferences(LLDrawable *drawablep)
return count;
}
static LLFastTimer::DeclareTimer FTM_ALLOCATE_FACE("Allocate Face");
static LLFastTimer::DeclareTimer FTM_ALLOCATE_FACE("Allocate Face", true);
LLFace* LLDrawable::addFace(LLFacePool *poolp, LLViewerTexture *texturep)
{
@ -527,6 +533,8 @@ void LLDrawable::makeStatic(BOOL warning_enabled)
}
updatePartition();
}
llassert(isAvatar() || isRoot() || mParent->isStatic());
}
// Returns "distance" between target destination and resulting xfrom

View File

@ -93,15 +93,35 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)
if (pass == 0)
{
if (LLPipeline::sImpostorRender)
{
simple_shader = &gDeferredAlphaImpostorProgram;
fullbright_shader = &gDeferredFullbrightProgram;
}
else if (LLPipeline::sUnderWaterRender)
{
simple_shader = &gDeferredAlphaWaterProgram;
fullbright_shader = &gDeferredFullbrightWaterProgram;
}
else
{
simple_shader = &gDeferredAlphaProgram;
fullbright_shader = &gObjectFullbrightProgram;
fullbright_shader = &gDeferredFullbrightProgram;
}
F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
fullbright_shader->bind();
fullbright_shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
fullbright_shader->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
fullbright_shader->unbind();
//prime simple shader (loads shadow relevant uniforms)
gPipeline.bindDeferredShader(*simple_shader);
simple_shader->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
}
else
else if (!LLPipeline::sImpostorRender)
{
//update depth buffer sampler
gPipeline.mScreen.flush();
@ -113,6 +133,23 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)
gObjectFullbrightAlphaMaskProgram.setMinimumAlpha(0.33f);
}
if (LLPipeline::sRenderDeferred)
{
emissive_shader = &gDeferredEmissiveProgram;
}
else
{
if (LLPipeline::sUnderWaterRender)
{
emissive_shader = &gObjectEmissiveWaterProgram;
}
else
{
emissive_shader = &gObjectEmissiveProgram;
}
}
deferred_render = TRUE;
if (mVertexShaderLevel > 0)
{
@ -124,7 +161,7 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)
void LLDrawPoolAlpha::endPostDeferredPass(S32 pass)
{
if (pass == 1)
if (pass == 1 && !LLPipeline::sImpostorRender)
{
gPipeline.mDeferredDepth.flush();
gPipeline.mScreen.bindTarget();
@ -144,7 +181,13 @@ void LLDrawPoolAlpha::beginRenderPass(S32 pass)
{
LLFastTimer t(FTM_RENDER_ALPHA);
if (LLPipeline::sUnderWaterRender)
if (LLPipeline::sImpostorRender)
{
simple_shader = &gObjectSimpleImpostorProgram;
fullbright_shader = &gObjectFullbrightProgram;
emissive_shader = &gObjectEmissiveProgram;
}
else if (LLPipeline::sUnderWaterRender)
{
simple_shader = &gObjectSimpleWaterProgram;
fullbright_shader = &gObjectFullbrightWaterProgram;
@ -192,8 +235,13 @@ void LLDrawPoolAlpha::render(S32 pass)
gGL.setColorMask(true, true);
}
LLGLDepthTest depth(GL_TRUE, LLDrawPoolWater::sSkipScreenCopy ||
(deferred_render && pass == 1) ? GL_TRUE : GL_FALSE);
bool write_depth = LLDrawPoolWater::sSkipScreenCopy
|| (deferred_render && pass == 1)
// we want depth written so that rendered alpha will
// contribute to the alpha mask used for impostors
|| LLPipeline::sImpostorRenderAlphaDepthPass;
LLGLDepthTest depth(GL_TRUE, write_depth ? GL_TRUE : GL_FALSE);
if (deferred_render && pass == 1)
{
@ -239,11 +287,11 @@ void LLDrawPoolAlpha::render(S32 pass)
if (mVertexShaderLevel > 0)
{
renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2);
renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2, pass);
}
else
{
renderAlpha(getVertexDataMask());
renderAlpha(getVertexDataMask(), pass);
}
gGL.setColorMask(true, false);
@ -315,7 +363,7 @@ void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask)
}
}
void LLDrawPoolAlpha::renderAlpha(U32 mask)
void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
{
BOOL initialized_lighting = FALSE;
BOOL light_enabled = TRUE;
@ -331,15 +379,10 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
if (group->mSpatialPartition->mRenderByGroup &&
!group->isDead())
{
static LLFastTimer::DeclareTimer FTM_RENDER_ALPHA_GROUP_LOOP("Alpha Group");
LLFastTimer t(FTM_RENDER_ALPHA_GROUP_LOOP);
bool draw_glow_for_this_partition = mVertexShaderLevel > 0; // no shaders = no glow.
bool disable_cull = group->mSpatialPartition->mPartitionType == LLViewerRegion::PARTITION_PARTICLE ||
group->mSpatialPartition->mPartitionType == LLViewerRegion::PARTITION_HUD_PARTICLE;
LLGLDisable cull(disable_cull ? GL_CULL_FACE : 0);
bool draw_glow_for_this_partition = mVertexShaderLevel > 0 && // no shaders = no glow.
// All particle systems seem to come off the wire with texture entries which claim that they glow. This is probably a bug in the data. Suppress.
group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_PARTICLE &&
group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_HUD_PARTICLE;
LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA];
@ -353,11 +396,28 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
continue;
}
// Fix for bug - NORSPEC-271
// If the face is more than 90% transparent, then don't update the Depth buffer for Dof
// We don't want the nearly invisible objects to cause of DoF effects
if(pass == 1 && !LLPipeline::sImpostorRender)
{
LLFace* face = params.mFace;
if(face)
{
const LLTextureEntry* tep = face->getTextureEntry();
if(tep)
{
if(tep->getColor().mV[3] < 0.1f)
continue;
}
}
}
LLRenderPass::applyModelMatrix(params);
LLMaterial* mat = NULL;
if (deferred_render && !LLPipeline::sUnderWaterRender)
if (deferred_render)
{
mat = params.mMaterial;
}
@ -401,6 +461,11 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
llassert(mask < LLMaterial::SHADER_COUNT);
target_shader = &(gDeferredMaterialProgram[mask]);
if (LLPipeline::sUnderWaterRender)
{
target_shader = &(gDeferredMaterialWaterProgram[mask]);
}
if (current_shader != target_shader)
{
gPipeline.bindDeferredShader(*target_shader);
@ -510,8 +575,8 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
LLFastTimer t(FTM_RENDER_ALPHA_PUSH);
gGL.blendFunc((LLRender::eBlendFactor) params.mBlendFuncSrc, (LLRender::eBlendFactor) params.mBlendFuncDst, mAlphaSFactor, mAlphaDFactor);
params.mVertexBuffer->setBuffer(mask);
params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
}
// If this alpha mesh has glow, then draw it a second time to add the destination-alpha (=glow). Interleaving these state-changing calls could be expensive, but glow must be drawn Z-sorted with alpha.
@ -531,6 +596,11 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
// do the actual drawing, again
params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
// restore our alpha blend mode
gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor);
current_shader->bind();
}
if (tex_setup)

View File

@ -63,7 +63,7 @@ public:
/*virtual*/ void prerender();
void renderGroupAlpha(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture = TRUE);
void renderAlpha(U32 mask);
void renderAlpha(U32 mask, S32 pass);
void renderAlphaHighlight(U32 mask);
static BOOL sShowDebugAlpha;

View File

@ -49,6 +49,7 @@
#include "llappviewer.h"
#include "llrendersphere.h"
#include "llviewerpartsim.h"
#include "llviewercontrol.h" // for gSavedSettings
static U32 sDataMask = LLDrawPoolAvatar::VERTEX_DATA_MASK;
static U32 sBufferUsage = GL_STREAM_DRAW_ARB;
@ -688,12 +689,10 @@ void LLDrawPoolAvatar::beginDeferredImpostor()
}
sVertexProgram = &gDeferredImpostorProgram;
specular_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::SPECULAR_MAP);
normal_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::DEFERRED_NORMAL);
sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
sVertexProgram->bind();
gPipeline.bindDeferredShader(*sVertexProgram);
sVertexProgram->setMinimumAlpha(0.01f);
}
@ -703,8 +702,9 @@ void LLDrawPoolAvatar::endDeferredImpostor()
sVertexProgram->disableTexture(LLViewerShaderMgr::DEFERRED_NORMAL);
sVertexProgram->disableTexture(LLViewerShaderMgr::SPECULAR_MAP);
sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
sVertexProgram->unbind();
gGL.getTexUnit(0)->activate();
gPipeline.unbindDeferredShader(*sVertexProgram);
sVertexProgram = NULL;
sDiffuseChannel = 0;
}
void LLDrawPoolAvatar::beginDeferredRigid()

View File

@ -72,6 +72,12 @@ void LLDrawPoolMaterials::beginDeferredPass(S32 pass)
};
mShader = &(gDeferredMaterialProgram[shader_idx[pass]]);
if (LLPipeline::sUnderWaterRender)
{
mShader = &(gDeferredMaterialWaterProgram[shader_idx[pass]]);
}
mShader->bind();
diffuse_channel = mShader->enableTexture(LLShaderMgr::DIFFUSE_MAP);
@ -215,3 +221,4 @@ void LLDrawPoolMaterials::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture,
gGL.matrixMode(LLRender::MM_MODELVIEW);
}
}

View File

@ -37,6 +37,7 @@
#include "llviewershadermgr.h"
#include "llrender.h"
#define GE_FORCE_WORKAROUND LL_DARWIN
static LLGLSLShader* simple_shader = NULL;
static LLGLSLShader* fullbright_shader = NULL;
@ -111,7 +112,14 @@ void LLDrawPoolGlow::render(S32 pass)
LLGLSLShader* shader = LLPipeline::sUnderWaterRender ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram;
shader->bind();
shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.f);
if (LLPipeline::sRenderDeferred)
{
shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
}
else
{
shader->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.f);
}
LLGLDepthTest depth(GL_TRUE, GL_FALSE);
gGL.setColorMask(false, true);
@ -148,7 +156,11 @@ void LLDrawPoolSimple::beginRenderPass(S32 pass)
{
LLFastTimer t(FTM_RENDER_SIMPLE);
if (LLPipeline::sUnderWaterRender)
if (LLPipeline::sImpostorRender)
{
simple_shader = &gObjectSimpleImpostorProgram;
}
else if (LLPipeline::sUnderWaterRender)
{
simple_shader = &gObjectSimpleWaterProgram;
}
@ -536,7 +548,15 @@ void LLDrawPoolFullbright::prerender()
void LLDrawPoolFullbright::beginPostDeferredPass(S32 pass)
{
gDeferredFullbrightProgram.bind();
if (LLPipeline::sUnderWaterRender)
{
gDeferredFullbrightWaterProgram.bind();
}
else
{
gDeferredFullbrightProgram.bind();
}
}
void LLDrawPoolFullbright::renderPostDeferred(S32 pass)
@ -550,7 +570,14 @@ void LLDrawPoolFullbright::renderPostDeferred(S32 pass)
void LLDrawPoolFullbright::endPostDeferredPass(S32 pass)
{
gDeferredFullbrightProgram.unbind();
if (LLPipeline::sUnderWaterRender)
{
gDeferredFullbrightWaterProgram.unbind();
}
else
{
gDeferredFullbrightProgram.unbind();
}
LLRenderPass::endRenderPass(pass);
}
@ -625,15 +652,35 @@ S32 LLDrawPoolFullbright::getNumPasses()
void LLDrawPoolFullbrightAlphaMask::beginPostDeferredPass(S32 pass)
{
gObjectFullbrightAlphaMaskProgram.bind();
if (LLPipeline::sRenderingHUDs || !LLPipeline::sRenderDeferred)
{
gObjectFullbrightAlphaMaskProgram.bind();
gObjectFullbrightAlphaMaskProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 1.0f);
}
else
{
{
// Work-around until we can figure out why the right shader causes
// the GeForce driver to go tango uniform on OS X 10.6.8 only
//
#if GE_FORCE_WORKAROUND
gObjectFullbrightAlphaMaskProgram.bind();
gObjectFullbrightAlphaMaskProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
#else
if (LLPipeline::sUnderWaterRender)
{
gDeferredFullbrightAlphaMaskWaterProgram.bind();
gDeferredFullbrightAlphaMaskWaterProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
}
else
{
gDeferredFullbrightAlphaMaskProgram.bind();
gDeferredFullbrightAlphaMaskProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
}
#endif
}
}
void LLDrawPoolFullbrightAlphaMask::renderPostDeferred(S32 pass)
@ -646,7 +693,30 @@ void LLDrawPoolFullbrightAlphaMask::renderPostDeferred(S32 pass)
void LLDrawPoolFullbrightAlphaMask::endPostDeferredPass(S32 pass)
{
gObjectFullbrightAlphaMaskProgram.unbind();
if (LLPipeline::sRenderingHUDs || !LLPipeline::sRenderDeferred)
{
gObjectFullbrightAlphaMaskProgram.unbind();
}
else
{
// Work-around until we can figure out why the right shader causes
// the GeForce driver to go tango uniform on OS X 10.6.8 only
//
#if GE_FORCE_WORKAROUND
gObjectFullbrightAlphaMaskProgram.unbind();
#else
if (LLPipeline::sUnderWaterRender)
{
gDeferredFullbrightAlphaMaskWaterProgram.unbind();
}
else
{
gDeferredFullbrightAlphaMaskProgram.unbind();
}
#endif
}
LLRenderPass::endRenderPass(pass);
}

View File

@ -155,3 +155,4 @@ void LLDrawPoolSky::renderSkyCubeFace(U8 side)
void LLDrawPoolSky::endRenderPass( S32 pass )
{
}

View File

@ -522,14 +522,21 @@ void LLDrawPoolWater::shade()
F32 eyedepth = LLViewerCamera::getInstance()->getOrigin().mV[2] - gAgent.getRegion()->getWaterHeight();
if (eyedepth < 0.f && LLPipeline::sWaterReflections)
{
if (deferred_render)
{
shader = &gDeferredWaterProgram;
shader = &gDeferredUnderWaterProgram;
}
else if (eyedepth < 0.f && LLPipeline::sWaterReflections)
else
{
shader = &gUnderWaterProgram;
}
}
else if (deferred_render)
{
shader = &gDeferredWaterProgram;
}
else
{
shader = &gWaterProgram;
@ -597,9 +604,15 @@ void LLDrawPoolWater::shade()
shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV);
}
F32 screenRes[] =
{
1.f/gGLViewport[2],
1.f/gGLViewport[3]
};
shader->uniform2fv(LLShaderMgr::DEFERRED_SCREEN_RES, 1, screenRes);
stop_glerror();
S32 diffTex = shader->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
S32 diffTex = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP);
stop_glerror();
light_dir.normVec();

View File

@ -1940,7 +1940,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
LLMatrix4a mat_vert;
mat_vert.loadu(mat_vert_in);
F32* dst = (F32*) vert.get();
F32* end_f32 = dst+mGeomCount*4;
@ -1951,7 +1951,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
LLVector4a res0; //,res1,res2,res3;
LLVector4a texIdx;
S32 index = mTextureIndex < 255 ? mTextureIndex : 0;
@ -2002,14 +2002,14 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
}*/
while (src < end)
{
{
mat_vert.affineTransform(*src++, res0);
tmp.setSelectWithMask(mask, texIdx, res0);
tmp.store4a((F32*) dst);
dst += 4;
}
}
{
//LLFastTimer t(FTM_FACE_POSITION_PAD);
while (dst < end_f32)
@ -2035,7 +2035,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
LLVector4a* end = src+num_vertices;
while (src < end)
{
{
LLVector4a normal;
mat_normal.rotate(*src++, normal);
normal.store4a(normals);

View File

@ -194,8 +194,7 @@ public:
void setSize(S32 numVertices, S32 num_indices = 0, bool align = false);
BOOL genVolumeBBoxes(const LLVolume &volume, S32 f,
const LLMatrix4& mat, BOOL global_volume = FALSE);
BOOL genVolumeBBoxes(const LLVolume &volume, S32 f,const LLMatrix4& mat, BOOL global_volume = FALSE);
void init(LLDrawable* drawablep, LLViewerObject* objp);
void destroy();

View File

@ -1328,7 +1328,7 @@ void LLFloaterTools::getMediaState()
getChildView("media_tex")->setEnabled(bool_has_media && editable);
getChildView("edit_media")->setEnabled(bool_has_media && LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo && editable );
getChildView("delete_media")->setEnabled(bool_has_media && editable );
getChildView("add_media")->setEnabled(( ! bool_has_media ) && editable );
getChildView("add_media")->setEnabled(editable);
// TODO: display a list of all media on the face - use 'identical' flag
}
else // not all face has media but at least one does.
@ -1358,7 +1358,7 @@ void LLFloaterTools::getMediaState()
getChildView("media_tex")->setEnabled(TRUE);
getChildView("edit_media")->setEnabled(LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo);
getChildView("delete_media")->setEnabled(TRUE);
getChildView("add_media")->setEnabled(FALSE );
getChildView("add_media")->setEnabled(editable);
}
media_info->setText(media_title);

View File

@ -52,10 +52,12 @@
#define MATERIALS_CAP_MATERIAL_ID_FIELD "MaterialID"
#define SIM_FEATURE_MAX_MATERIALS_PER_TRANSACTION "MaxMaterialsPerTransaction"
#define MATERIALS_DEFAULT_MAX_ENTRIES 50
#define MATERIALS_GET_MAX_ENTRIES 50
#define MATERIALS_GET_TIMEOUT (60.f * 20)
#define MATERIALS_POST_MAX_ENTRIES 50
#define MATERIALS_POST_TIMEOUT (60.f * 5)
#define MATERIALS_PUT_THROTTLE_SECS 1.f
#define MATERIALS_PUT_MAX_ENTRIES 50
/**
* LLMaterialsResponder helper class
@ -543,11 +545,9 @@ void LLMaterialMgr::onIdle(void*)
instancep->processGetAllQueue();
}
static LLFrameTimer mPutTimer;
if ( (!instancep->mPutQueue.empty()) && (mPutTimer.hasExpired()) )
if (!instancep->mPutQueue.empty())
{
instancep->processPutQueue();
mPutTimer.resetWithExpiry(MATERIALS_PUT_THROTTLE_SECS);
}
}
@ -564,14 +564,14 @@ void LLMaterialMgr::processGetQueue()
continue;
}
const LLViewerRegion* regionp = LLWorld::instance().getRegionFromID(region_id);
LLViewerRegion* regionp = LLWorld::instance().getRegionFromID(region_id);
if (!regionp)
{
LL_WARNS("Materials") << "Unknown region with id " << region_id.asString() << LL_ENDL;
mGetQueue.erase(itRegionQueue);
continue;
}
else if (!regionp->capabilitiesReceived())
else if (!regionp->capabilitiesReceived() || regionp->materialsCapThrottled())
{
continue;
}
@ -594,8 +594,8 @@ void LLMaterialMgr::processGetQueue()
LLSD materialsData = LLSD::emptyArray();
material_queue_t& materials = itRegionQueue->second;
U32 max_entries = getMaxEntries(regionp);
material_queue_t::iterator loopMaterial = materials.begin();
U32 max_entries = regionp->getMaxMaterialsPerTransaction();
material_queue_t::iterator loopMaterial = materials.begin();
while ( (materials.end() != loopMaterial) && (materialsData.size() < max_entries) )
{
material_queue_t::iterator itMaterial = loopMaterial++;
@ -628,6 +628,7 @@ void LLMaterialMgr::processGetQueue()
LL_DEBUGS("Materials") << "POSTing to region '" << regionp->getName() << "' at '"<< capURL << " for " << materialsData.size() << " materials."
<< "\ndata: " << ll_pretty_print_sd(materialsData) << LL_ENDL;
LLHTTPClient::post(capURL, postData, materialsResponder);
regionp->resetMaterialsCapThrottle();
}
}
@ -646,7 +647,7 @@ void LLMaterialMgr::processGetAllQueue()
clearGetQueues(region_id); // Invalidates region_id
continue;
}
else if (!regionp->capabilitiesReceived())
else if (!regionp->capabilitiesReceived() || regionp->materialsCapThrottled())
{
continue;
}
@ -663,6 +664,7 @@ void LLMaterialMgr::processGetAllQueue()
LL_DEBUGS("Materials") << "GET all for region " << region_id << "url " << capURL << LL_ENDL;
LLHTTPClient::ResponderPtr materialsResponder = new LLMaterialsResponder("GET", capURL, boost::bind(&LLMaterialMgr::onGetAllResponse, this, _1, _2, *itRegion));
LLHTTPClient::get(capURL, materialsResponder);
regionp->resetMaterialsCapThrottle();
mGetAllPending.insert(std::pair<LLUUID, F64>(region_id, LLFrameTimer::getTotalSeconds()));
mGetAllQueue.erase(itRegion); // Invalidates region_id
}
@ -670,7 +672,7 @@ void LLMaterialMgr::processGetAllQueue()
void LLMaterialMgr::processPutQueue()
{
typedef std::map<const LLViewerRegion*, LLSD> regionput_request_map;
typedef std::map<LLViewerRegion*, LLSD> regionput_request_map;
regionput_request_map requests;
put_queue_t::iterator loopQueue = mPutQueue.begin();
@ -687,46 +689,47 @@ void LLMaterialMgr::processPutQueue()
}
else
{
const LLViewerRegion* regionp = objectp->getRegion();
LLViewerRegion* regionp = objectp->getRegion();
if ( !regionp )
{
{
LL_WARNS("Materials") << "Object region is NULL" << LL_ENDL;
mPutQueue.erase(itQueue);
}
else if ( regionp->capabilitiesReceived())
}
else if ( regionp->capabilitiesReceived() && !regionp->materialsCapThrottled())
{
LLSD& facesData = requests[regionp];
LLSD& facesData = requests[regionp];
facematerial_map_t& face_map = itQueue->second;
U32 max_entries = getMaxEntries(regionp);
facematerial_map_t::iterator itFace = face_map.begin();
facematerial_map_t& face_map = itQueue->second;
U32 max_entries = regionp->getMaxMaterialsPerTransaction();
facematerial_map_t::iterator itFace = face_map.begin();
while ( (face_map.end() != itFace) && (facesData.size() < max_entries) )
{
LLSD faceData = LLSD::emptyMap();
faceData[MATERIALS_CAP_FACE_FIELD] = static_cast<LLSD::Integer>(itFace->first);
faceData[MATERIALS_CAP_OBJECT_ID_FIELD] = static_cast<LLSD::Integer>(objectp->getLocalID());
if (!itFace->second.isNull())
{
faceData[MATERIALS_CAP_MATERIAL_FIELD] = itFace->second.asLLSD();
}
facesData.append(faceData);
face_map.erase(itFace++);
}
if (face_map.empty())
{
mPutQueue.erase(itQueue);
}
{
LLSD faceData = LLSD::emptyMap();
faceData[MATERIALS_CAP_FACE_FIELD] = static_cast<LLSD::Integer>(itFace->first);
faceData[MATERIALS_CAP_OBJECT_ID_FIELD] = static_cast<LLSD::Integer>(objectp->getLocalID());
if (!itFace->second.isNull())
{
faceData[MATERIALS_CAP_MATERIAL_FIELD] = itFace->second.asLLSD();
}
facesData.append(faceData);
face_map.erase(itFace++);
}
if (face_map.empty())
{
mPutQueue.erase(itQueue);
}
}
}
}
for (regionput_request_map::const_iterator itRequest = requests.begin(); itRequest != requests.end(); ++itRequest)
{
std::string capURL = itRequest->first->getCapability(MATERIALS_CAPABILITY_NAME);
LLViewerRegion* regionp = itRequest->first;
std::string capURL = regionp->getCapability(MATERIALS_CAPABILITY_NAME);
if (capURL.empty())
{
LL_WARNS("Materials") << "Capability '" << MATERIALS_CAPABILITY_NAME
<< "' is not defined on region '" << itRequest->first->getName() << "'" << LL_ENDL;
<< "' is not defined on region '" << regionp->getName() << "'" << LL_ENDL;
continue;
}
@ -749,6 +752,7 @@ void LLMaterialMgr::processPutQueue()
LL_DEBUGS("Materials") << "put for " << itRequest->second.size() << " faces to region " << itRequest->first->getName() << LL_ENDL;
LLHTTPClient::ResponderPtr materialsResponder = new LLMaterialsResponder("PUT", capURL, boost::bind(&LLMaterialMgr::onPutResponse, this, _1, _2));
LLHTTPClient::put(capURL, putData, materialsResponder);
regionp->resetMaterialsCapThrottle();
}
else
{
@ -783,20 +787,3 @@ void LLMaterialMgr::onRegionRemoved(LLViewerRegion* regionp)
// Put doesn't need clearing: objects that can't be found will clean up in processPutQueue()
}
U32 LLMaterialMgr::getMaxEntries(const LLViewerRegion* regionp)
{
LLSD sim_features;
regionp->getSimulatorFeatures(sim_features);
U32 max_entries;
if ( sim_features.has( SIM_FEATURE_MAX_MATERIALS_PER_TRANSACTION )
&& sim_features[ SIM_FEATURE_MAX_MATERIALS_PER_TRANSACTION ].isInteger())
{
max_entries = sim_features[ SIM_FEATURE_MAX_MATERIALS_PER_TRANSACTION ].asInteger();
}
else
{
max_entries = MATERIALS_DEFAULT_MAX_ENTRIES;
}
return max_entries;
}

View File

@ -255,7 +255,26 @@ private:
// Determine correct alpha mode for current diffuse texture
// (i.e. does it have an alpha channel that makes alpha mode useful)
//
U8 default_alpha_mode = (_panel->isAlpha() ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE);
// _panel->isAlpha() "lies" when one face has alpha and the rest do not (NORSPEC-329)
// need to get per-face answer to this question for sane alpha mode retention on updates.
//
bool is_alpha_face = object->isImageAlphaBlended(face);
// need to keep this original answer for valid comparisons in logic below
//
U8 original_default_alpha_mode = is_alpha_face ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
U8 default_alpha_mode = original_default_alpha_mode;
if (!current_material.isNull())
{
default_alpha_mode = current_material->getDiffuseAlphaMode();
}
// Insure we don't inherit the default of blend by accident...
// this will be stomped by a legit request to change the alpha mode by the apply() below
//
new_material->setDiffuseAlphaMode(default_alpha_mode);
// Do "It"!
//
@ -265,7 +284,13 @@ private:
LLUUID new_normal_map_id = new_material->getNormalID();
LLUUID new_spec_map_id = new_material->getSpecularID();
bool is_default_blend_mode = (new_alpha_mode == default_alpha_mode);
if ((new_alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND) && !is_alpha_face)
{
new_alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
new_material->setDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_NONE);
}
bool is_default_blend_mode = (new_alpha_mode == original_default_alpha_mode);
bool is_need_material = !is_default_blend_mode || !new_normal_map_id.isNull() || !new_spec_map_id.isNull();
if (!is_need_material)

View File

@ -710,9 +710,19 @@ void LLPanelVolume::onLightCancelColor(const LLSD& data)
void LLPanelVolume::onLightCancelTexture(const LLSD& data)
{
LLTextureCtrl* LightTextureCtrl = getChild<LLTextureCtrl>("light texture control");
if (LightTextureCtrl)
{
LightTextureCtrl->setImageAssetID(mLightSavedTexture);
LightTextureCtrl->setImageAssetID(LLUUID::null);
}
LLVOVolume *volobjp = (LLVOVolume *) mObject.get();
if(volobjp)
{
// Cancel the light texture as requested
// NORSPEC-292
//
volobjp->setLightTextureID(LLUUID::null);
}
}

View File

@ -133,6 +133,7 @@ public:
PermissionMask getFilterPermMask();
void updateFilterPermMask();
void commitIfImmediateSet();
void commitCancel();
void onFilterEdit(const std::string& search_string );
@ -706,6 +707,14 @@ void LLFloaterTexturePicker::commitIfImmediateSet()
}
}
void LLFloaterTexturePicker::commitCancel()
{
if (!mNoCopyTextureSelected && mOwner && mCanApply)
{
mOwner->onFloaterCommit(LLTextureCtrl::TEXTURE_CANCEL);
}
}
// static
void LLFloaterTexturePicker::onBtnSetToDefault(void* userdata)
{
@ -733,7 +742,7 @@ void LLFloaterTexturePicker::onBtnNone(void* userdata)
{
LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
self->setImageID( LLUUID::null );
self->commitIfImmediateSet();
self->commitCancel();
}
/*

View File

@ -225,13 +225,13 @@ void display_stats()
}
static LLFastTimer::DeclareTimer FTM_PICK("Picking");
static LLFastTimer::DeclareTimer FTM_RENDER("Render");
static LLFastTimer::DeclareTimer FTM_RENDER("Render", true);
static LLFastTimer::DeclareTimer FTM_UPDATE_SKY("Update Sky");
static LLFastTimer::DeclareTimer FTM_UPDATE_TEXTURES("Update Textures");
static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE("Update Images");
static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_CLASS("Class");
static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_BUMP("Image Update Bump");
static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_LIST("List", true);
static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_LIST("List");
static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_DELETE("Delete");
static LLFastTimer::DeclareTimer FTM_RESIZE_WINDOW("Resize Window");
static LLFastTimer::DeclareTimer FTM_HUD_UPDATE("HUD Update");
@ -675,7 +675,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater() ? TRUE : FALSE;
gPipeline.updateCull(*LLViewerCamera::getInstance(), result, water_clip);
LLPipeline::sUnderWaterRender = FALSE;
stop_glerror();
LLGLState::checkStates();
@ -891,7 +890,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
{
gGL.setColorMask(true, true);
if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender)
if (LLPipeline::sRenderDeferred)
{
gPipeline.mDeferredScreen.bindTarget();
glClearColor(1,0,1,1);
@ -940,7 +939,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
gGL.setColorMask(true, false);
if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender)
if (LLPipeline::sRenderDeferred)
{
gPipeline.renderGeomDeferred(*LLViewerCamera::getInstance());
}
@ -977,7 +976,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
if (to_texture)
{
if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender)
if (LLPipeline::sRenderDeferred)
{
gPipeline.mDeferredScreen.flush();
if(LLRenderTarget::sUseFBO)
@ -1003,7 +1002,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
}
}
if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender)
if (LLPipeline::sRenderDeferred)
{
gPipeline.renderDeferredLighting();
}
@ -1624,3 +1623,4 @@ void display_cleanup()
{
gDisconnectedImagep = NULL;
}

View File

@ -1724,7 +1724,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
// keep local flags and overwrite remote-controlled flags
mFlags = (mFlags & FLAGS_LOCAL) | flags;
// ...new objects that should come in selected need to be added to the selected list
// ...new objects that should come in selected need to be added to the selected list
mCreateSelected = ((flags & FLAGS_CREATE_SELECTED) != 0);
}
break;
@ -4412,12 +4412,10 @@ S32 LLViewerObject::setTEMaterialParams(const U8 te, const LLMaterialPtr pMateri
void LLViewerObject::refreshMaterials()
{
setChanged(ALL_CHANGED);
setChanged(TEXTURE);
if (mDrawable.notNull())
{
gPipeline.markTextured(mDrawable);
gPipeline.markRebuild(mDrawable,LLDrawable::REBUILD_ALL);
dirtySpatialGroup(TRUE);
}
}
@ -4521,6 +4519,30 @@ LLViewerTexture *LLViewerObject::getTEImage(const U8 face) const
}
bool LLViewerObject::isImageAlphaBlended(const U8 te) const
{
LLViewerTexture* image = getTEImage(te);
LLGLenum format = image ? image->getPrimaryFormat() : GL_RGB;
switch (format)
{
case GL_RGBA:
case GL_ALPHA:
{
return true;
}
break;
case GL_RGB: break;
default:
{
llwarns << "Unexpected tex format in LLViewerObject::isImageAlphaBlended...returning no alpha." << llendl;
}
break;
}
return false;
}
LLViewerTexture *LLViewerObject::getTENormalMap(const U8 face) const
{
// llassert(mTEImages);

View File

@ -112,6 +112,14 @@ class LLViewerObject : public LLPrimitive, public LLRefCount, public LLGLUpdate
protected:
~LLViewerObject(); // use unref()
// TomY: Provide for a list of extra parameter structures, mapped by structure name
struct ExtraParameter
{
BOOL in_use;
LLNetworkData *data;
};
std::map<U16, ExtraParameter*> mExtraParameterList;
public:
typedef std::list<LLPointer<LLViewerObject> > child_list_t;
typedef std::list<LLPointer<LLViewerObject> > vobj_list_t;
@ -331,6 +339,8 @@ public:
LLViewerTexture *getTENormalMap(const U8 te) const;
LLViewerTexture *getTESpecularMap(const U8 te) const;
bool isImageAlphaBlended(const U8 te) const;
void fitFaceTexture(const U8 face);
void sendTEUpdate() const; // Sends packed representation of all texture entry information
@ -553,8 +563,6 @@ public:
std::vector<LLVector3> mUnselectedChildrenPositions ;
private:
// TomY: Provide for a list of extra parameter structures, mapped by structure name
struct ExtraParameter;
ExtraParameter* createNewParameterEntry(U16 param_type);
ExtraParameter* getExtraParameterEntry(U16 param_type) const;
ExtraParameter* getExtraParameterEntryCreate(U16 param_type);
@ -794,14 +802,6 @@ private:
LLUUID mAttachmentItemID; // ItemID of the associated object is in user inventory.
EObjectUpdateType mLastUpdateType;
BOOL mLastUpdateCached;
// TomY: Provide for a list of extra parameter structures, mapped by structure name
struct ExtraParameter
{
BOOL in_use;
LLNetworkData *data;
};
std::map<U16, ExtraParameter*> mExtraParameterList;
};
///////////////////
@ -847,7 +847,7 @@ public:
LLStrider<LLVector4a>& verticesp,
LLStrider<LLVector3>& normalsp,
LLStrider<LLVector2>& texcoordsp,
LLStrider<LLColor4U>& colorsp,
LLStrider<LLColor4U>& colorsp,
LLStrider<LLColor4U>& emissivep,
LLStrider<U16>& indicesp) = 0;

View File

@ -44,7 +44,6 @@
#include "llagent.h"
#include "llagentcamera.h"
#include "llavatarrenderinfoaccountant.h"
#include "llcallingcard.h"
#include "llcaphttpsender.h"
#include "llcapabilitylistener.h"
@ -301,16 +300,12 @@ public:
if ( regionp->getRegionImpl()->mCapabilities.size() != regionp->getRegionImpl()->mSecondCapabilitiesTracker.size() )
{
llinfos << "BaseCapabilitiesCompleteTracker " << "sim " << regionp->getName()
<< " sent duplicate seed caps that differs in size - most likely content. "
<< (S32) regionp->getRegionImpl()->mCapabilities.size() << " vs " << regionp->getRegionImpl()->mSecondCapabilitiesTracker.size()
<< llendl;
llinfos<<"BaseCapabilitiesCompleteTracker "<<"Sim sent duplicate seed caps that differs in size - most likely content."<<llendl;
//todo#add cap debug versus original check?
/*
CapabilityMap::const_iterator iter = regionp->getRegionImpl()->mCapabilities.begin();
/*CapabilityMap::const_iterator iter = regionp->getRegionImpl()->mCapabilities.begin();
while (iter!=regionp->getRegionImpl()->mCapabilities.end() )
{
llinfos << "BaseCapabilitiesCompleteTracker Original " << iter->first << " is " << iter->second << llendl;
llinfos<<"BaseCapabilitiesCompleteTracker Original "<<iter->first<<" "<< iter->second<<llendl;
++iter;
}
*/
@ -398,9 +393,6 @@ LLViewerRegion::LLViewerRegion(const U64 &handle,
mImpl->mObjectPartition.push_back(new LLBridgePartition()); //PARTITION_BRIDGE
mImpl->mObjectPartition.push_back(new LLHUDParticlePartition());//PARTITION_HUD_PARTICLE
mImpl->mObjectPartition.push_back(NULL); //PARTITION_NONE
mRenderInfoRequestTimer.resetWithExpiry(0.f); // Set timer to be expired
setCapabilitiesReceivedCallback(boost::bind(&LLAvatarRenderInfoAccountant::expireRenderInfoReportTimer, _1));
}
@ -1585,7 +1577,6 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
capabilityNames.append("AgentState");
capabilityNames.append("AttachmentResources");
capabilityNames.append("AvatarPickerSearch");
capabilityNames.append("AvatarRenderInfo");
capabilityNames.append("CharacterProperties");
capabilityNames.append("ChatSessionRequest");
capabilityNames.append("CopyInventoryFromNotecard");
@ -1953,3 +1944,47 @@ bool LLViewerRegion::dynamicPathfindingEnabled() const
mSimulatorFeatures["DynamicPathfindingEnabled"].asBoolean());
}
void LLViewerRegion::resetMaterialsCapThrottle()
{
F32 requests_per_sec = 1.0f; // original default;
if ( mSimulatorFeatures.has("RenderMaterialsCapability")
&& mSimulatorFeatures["RenderMaterialsCapability"].isReal() )
{
requests_per_sec = mSimulatorFeatures["RenderMaterialsCapability"].asReal();
if ( requests_per_sec == 0.0f )
{
requests_per_sec = 1.0f;
LL_WARNS("Materials")
<< "region '" << getName()
<< "' returned zero for RenderMaterialsCapability; using default "
<< requests_per_sec << " per second"
<< LL_ENDL;
}
LL_DEBUGS("Materials") << "region '" << getName()
<< "' RenderMaterialsCapability " << requests_per_sec
<< LL_ENDL;
}
else
{
LL_DEBUGS("Materials")
<< "region '" << getName()
<< "' did not return RenderMaterialsCapability, using default "
<< requests_per_sec << " per second"
<< LL_ENDL;
}
mMaterialsCapThrottleTimer.resetWithExpiry( 1.0f / requests_per_sec );
}
U32 LLViewerRegion::getMaxMaterialsPerTransaction() const
{
U32 max_entries = 50; // original hard coded default
if ( mSimulatorFeatures.has( "MaxMaterialsPerTransaction" )
&& mSimulatorFeatures[ "MaxMaterialsPerTransaction" ].isInteger())
{
max_entries = mSimulatorFeatures[ "MaxMaterialsPerTransaction" ].asInteger();
}
return max_entries;
}

View File

@ -43,6 +43,7 @@
#include "llcapabilityprovider.h"
#include "m4math.h" // LLMatrix4
#include "llhttpclient.h"
#include "llframetimer.h"
// Surface id's
#define LAND 1
@ -343,6 +344,11 @@ public:
const LLViewerRegionImpl * getRegionImpl() const { return mImpl; }
LLViewerRegionImpl * getRegionImplNC() { return mImpl; }
// implements the materials capability throttle
bool materialsCapThrottled() const { return !mMaterialsCapThrottleTimer.hasExpired(); }
void resetMaterialsCapThrottle();
U32 getMaxMaterialsPerTransaction() const;
public:
struct CompareDistance
{
@ -437,7 +443,9 @@ private:
LLSD mSimulatorFeatures;
LLFrameTimer mRenderInfoRequestTimer;
// the materials capability throttle
LLFrameTimer mMaterialsCapThrottleTimer;
LLFrameTimer mRenderInfoRequestTimer;
};
inline BOOL LLViewerRegion::getRegionProtocol(U64 protocol) const

View File

@ -90,6 +90,7 @@ LLGLSLShader gAlphaMaskProgram;
//object shaders
LLGLSLShader gObjectSimpleProgram;
LLGLSLShader gObjectSimpleImpostorProgram;
LLGLSLShader gObjectPreviewProgram;
LLGLSLShader gObjectSimpleWaterProgram;
LLGLSLShader gObjectSimpleAlphaMaskProgram;
@ -175,6 +176,7 @@ LLGLSLShader gPostNightVisionProgram;
// Deferred rendering shaders
LLGLSLShader gDeferredImpostorProgram;
LLGLSLShader gDeferredWaterProgram;
LLGLSLShader gDeferredUnderWaterProgram;
LLGLSLShader gDeferredDiffuseProgram;
LLGLSLShader gDeferredDiffuseAlphaMaskProgram;
LLGLSLShader gDeferredNonIndexedDiffuseProgram;
@ -196,14 +198,20 @@ LLGLSLShader gDeferredMultiSpotLightProgram;
LLGLSLShader gDeferredSunProgram;
LLGLSLShader gDeferredBlurLightProgram;
LLGLSLShader gDeferredSoftenProgram;
LLGLSLShader gDeferredSoftenWaterProgram;
LLGLSLShader gDeferredShadowProgram;
LLGLSLShader gDeferredShadowCubeProgram;
LLGLSLShader gDeferredShadowAlphaMaskProgram;
LLGLSLShader gDeferredAvatarShadowProgram;
LLGLSLShader gDeferredAttachmentShadowProgram;
LLGLSLShader gDeferredAlphaProgram;
LLGLSLShader gDeferredAlphaImpostorProgram;
LLGLSLShader gDeferredAlphaWaterProgram;
LLGLSLShader gDeferredAvatarEyesProgram;
LLGLSLShader gDeferredFullbrightProgram;
LLGLSLShader gDeferredFullbrightAlphaMaskProgram;
LLGLSLShader gDeferredFullbrightWaterProgram;
LLGLSLShader gDeferredFullbrightAlphaMaskWaterProgram;
LLGLSLShader gDeferredEmissiveProgram;
LLGLSLShader gDeferredPostProgram;
LLGLSLShader gDeferredCoFProgram;
@ -221,6 +229,7 @@ LLGLSLShader gNormalMapGenProgram;
// Deferred materials shaders
LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2];
LLGLSLShader gDeferredMaterialWaterProgram[LLMaterial::SHADER_COUNT*2];
LLViewerShaderMgr::LLViewerShaderMgr() :
mVertexShaderLevel(SHADER_COUNT, 0),
@ -236,6 +245,7 @@ LLViewerShaderMgr::LLViewerShaderMgr() :
mShaderList.push_back(&gWaterProgram);
mShaderList.push_back(&gAvatarEyeballProgram);
mShaderList.push_back(&gObjectSimpleProgram);
mShaderList.push_back(&gObjectSimpleImpostorProgram);
mShaderList.push_back(&gObjectPreviewProgram);
mShaderList.push_back(&gImpostorProgram);
mShaderList.push_back(&gObjectFullbrightNoColorProgram);
@ -286,6 +296,7 @@ LLViewerShaderMgr::LLViewerShaderMgr() :
mShaderList.push_back(&gUnderWaterProgram);
mShaderList.push_back(&gDeferredSunProgram);
mShaderList.push_back(&gDeferredSoftenProgram);
mShaderList.push_back(&gDeferredSoftenWaterProgram);
mShaderList.push_back(&gDeferredMaterialProgram[1]);
mShaderList.push_back(&gDeferredMaterialProgram[5]);
mShaderList.push_back(&gDeferredMaterialProgram[9]);
@ -294,15 +305,30 @@ LLViewerShaderMgr::LLViewerShaderMgr() :
mShaderList.push_back(&gDeferredMaterialProgram[5+LLMaterial::SHADER_COUNT]);
mShaderList.push_back(&gDeferredMaterialProgram[9+LLMaterial::SHADER_COUNT]);
mShaderList.push_back(&gDeferredMaterialProgram[13+LLMaterial::SHADER_COUNT]);
mShaderList.push_back(&gDeferredMaterialWaterProgram[1]);
mShaderList.push_back(&gDeferredMaterialWaterProgram[5]);
mShaderList.push_back(&gDeferredMaterialWaterProgram[9]);
mShaderList.push_back(&gDeferredMaterialWaterProgram[13]);
mShaderList.push_back(&gDeferredMaterialWaterProgram[1+LLMaterial::SHADER_COUNT]);
mShaderList.push_back(&gDeferredMaterialWaterProgram[5+LLMaterial::SHADER_COUNT]);
mShaderList.push_back(&gDeferredMaterialWaterProgram[9+LLMaterial::SHADER_COUNT]);
mShaderList.push_back(&gDeferredMaterialWaterProgram[13+LLMaterial::SHADER_COUNT]);
mShaderList.push_back(&gDeferredAlphaProgram);
mShaderList.push_back(&gDeferredAlphaProgram);
mShaderList.push_back(&gDeferredAlphaImpostorProgram);
mShaderList.push_back(&gDeferredAlphaWaterProgram);
mShaderList.push_back(&gDeferredSkinnedAlphaProgram);
mShaderList.push_back(&gDeferredFullbrightProgram);
mShaderList.push_back(&gDeferredFullbrightAlphaMaskProgram);
mShaderList.push_back(&gDeferredFullbrightWaterProgram);
mShaderList.push_back(&gDeferredFullbrightAlphaMaskWaterProgram);
mShaderList.push_back(&gDeferredFullbrightShinyProgram);
mShaderList.push_back(&gDeferredSkinnedFullbrightShinyProgram);
mShaderList.push_back(&gDeferredSkinnedFullbrightProgram);
mShaderList.push_back(&gDeferredEmissiveProgram);
mShaderList.push_back(&gDeferredAvatarEyesProgram);
mShaderList.push_back(&gDeferredWaterProgram);
mShaderList.push_back(&gDeferredUnderWaterProgram);
mShaderList.push_back(&gDeferredAvatarAlphaProgram);
mShaderList.push_back(&gDeferredWLSkyProgram);
mShaderList.push_back(&gDeferredWLCloudProgram);
@ -671,6 +697,7 @@ void LLViewerShaderMgr::unloadShaders()
gObjectFullbrightNoColorProgram.unload();
gObjectFullbrightNoColorWaterProgram.unload();
gObjectSimpleProgram.unload();
gObjectSimpleImpostorProgram.unload();
gObjectPreviewProgram.unload();
gImpostorProgram.unload();
gObjectSimpleAlphaMaskProgram.unload();
@ -1087,6 +1114,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredSunProgram.unload();
gDeferredBlurLightProgram.unload();
gDeferredSoftenProgram.unload();
gDeferredSoftenWaterProgram.unload();
gDeferredShadowProgram.unload();
gDeferredShadowCubeProgram.unload();
gDeferredShadowAlphaMaskProgram.unload();
@ -1095,7 +1123,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredAvatarProgram.unload();
gDeferredAvatarAlphaProgram.unload();
gDeferredAlphaProgram.unload();
gDeferredAlphaWaterProgram.unload();
gDeferredFullbrightProgram.unload();
gDeferredFullbrightAlphaMaskProgram.unload();
gDeferredFullbrightWaterProgram.unload();
gDeferredFullbrightAlphaMaskWaterProgram.unload();
gDeferredEmissiveProgram.unload();
gDeferredAvatarEyesProgram.unload();
gDeferredPostProgram.unload();
@ -1104,6 +1136,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredPostGammaCorrectProgram.unload();
gFXAAProgram.unload();
gDeferredWaterProgram.unload();
gDeferredUnderWaterProgram.unload();
gDeferredWLSkyProgram.unload();
gDeferredWLCloudProgram.unload();
gDeferredStarProgram.unload();
@ -1115,6 +1148,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
for (U32 i = 0; i < LLMaterial::SHADER_COUNT*2; ++i)
{
gDeferredMaterialProgram[i].unload();
gDeferredMaterialWaterProgram[i].unload();
}
return TRUE;
}
@ -1199,11 +1233,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (success)
{
gDeferredSkinnedAlphaProgram.mName = "Deferred Skinned Alpha Shader";
gDeferredSkinnedAlphaProgram.mFeatures.atmosphericHelpers = true;
gDeferredSkinnedAlphaProgram.mFeatures.hasObjectSkinning = true;
gDeferredSkinnedAlphaProgram.mFeatures.calculatesAtmospherics = true;
gDeferredSkinnedAlphaProgram.mFeatures.hasGamma = true;
gDeferredSkinnedAlphaProgram.mFeatures.hasAtmospherics = true;
gDeferredSkinnedAlphaProgram.mFeatures.calculatesLighting = false;
gDeferredSkinnedAlphaProgram.mFeatures.hasLighting = false;
gDeferredSkinnedAlphaProgram.mFeatures.isAlphaLighting = true;
@ -1213,8 +1243,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));
gDeferredSkinnedAlphaProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
gDeferredSkinnedAlphaProgram.addPermutation("USE_DIFFUSE_TEX", "1");
gDeferredSkinnedAlphaProgram.addPermutation("USE_VERTEX_COLOR", "1");
gDeferredSkinnedAlphaProgram.addPermutation("HAS_SKIN", "1");
gDeferredSkinnedAlphaProgram.addPermutation("USE_VERTEX_COLOR", "1");
gDeferredSkinnedAlphaProgram.addPermutation("HAS_SHADOW", mVertexShaderLevel[SHADER_DEFERRED] > 1 ? "1" : "0");
success = gDeferredSkinnedAlphaProgram.createShader(NULL, NULL);
@ -1242,6 +1272,15 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredMaterialProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
gDeferredMaterialProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
gDeferredMaterialWaterProgram[1].mFeatures.hasLighting = false;
gDeferredMaterialWaterProgram[5].mFeatures.hasLighting = false;
gDeferredMaterialWaterProgram[9].mFeatures.hasLighting = false;
gDeferredMaterialWaterProgram[13].mFeatures.hasLighting = false;
gDeferredMaterialWaterProgram[1+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
gDeferredMaterialWaterProgram[5+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
gDeferredMaterialWaterProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
gDeferredMaterialWaterProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = false;
for (U32 i = 0; i < LLMaterial::SHADER_COUNT*2; ++i)
{
if (success)
@ -1268,6 +1307,34 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
success = gDeferredMaterialProgram[i].createShader(NULL, NULL);
}
if (success)
{
gDeferredMaterialWaterProgram[i].mName = llformat("Deferred Underwater Material Shader %d", i);
U32 alpha_mode = i & 0x3;
gDeferredMaterialWaterProgram[i].mShaderFiles.clear();
gDeferredMaterialWaterProgram[i].mShaderFiles.push_back(make_pair("deferred/materialV.glsl", GL_VERTEX_SHADER_ARB));
gDeferredMaterialWaterProgram[i].mShaderFiles.push_back(make_pair("deferred/materialF.glsl", GL_FRAGMENT_SHADER_ARB));
gDeferredMaterialWaterProgram[i].mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
gDeferredMaterialWaterProgram[i].mShaderGroup = LLGLSLShader::SG_WATER;
gDeferredMaterialWaterProgram[i].addPermutation("HAS_NORMAL_MAP", i & 0x8? "1" : "0");
gDeferredMaterialWaterProgram[i].addPermutation("HAS_SPECULAR_MAP", i & 0x4 ? "1" : "0");
gDeferredMaterialWaterProgram[i].addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode));
gDeferredMaterialWaterProgram[i].addPermutation("HAS_SUN_SHADOW", mVertexShaderLevel[SHADER_DEFERRED] > 1 ? "1" : "0");
bool has_skin = i & 0x10;
gDeferredMaterialWaterProgram[i].addPermutation("HAS_SKIN",has_skin ? "1" : "0");
gDeferredMaterialWaterProgram[i].addPermutation("WATER_FOG","1");
if (has_skin)
{
gDeferredMaterialWaterProgram[i].mFeatures.hasObjectSkinning = true;
}
success = gDeferredMaterialWaterProgram[i].createShader(NULL, NULL);//&mWLUniforms);
}
}
gDeferredMaterialProgram[1].mFeatures.hasLighting = true;
@ -1279,6 +1346,14 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredMaterialProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
gDeferredMaterialProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
gDeferredMaterialWaterProgram[1].mFeatures.hasLighting = true;
gDeferredMaterialWaterProgram[5].mFeatures.hasLighting = true;
gDeferredMaterialWaterProgram[9].mFeatures.hasLighting = true;
gDeferredMaterialWaterProgram[13].mFeatures.hasLighting = true;
gDeferredMaterialWaterProgram[1+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
gDeferredMaterialWaterProgram[5+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
gDeferredMaterialWaterProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
gDeferredMaterialWaterProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
if (success)
@ -1324,8 +1399,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
for (U32 i = 0; i < LL_DEFERRED_MULTI_LIGHT_COUNT; i++)
{
if (success)
{
if (success)
{
gDeferredMultiLightProgram[i].mName = llformat("Deferred MultiLight Shader %d", i);
gDeferredMultiLightProgram[i].mShaderFiles.clear();
gDeferredMultiLightProgram[i].mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER_ARB));
@ -1399,11 +1474,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (success)
{
gDeferredAlphaProgram.mName = "Deferred Alpha Shader";
gDeferredAlphaProgram.mFeatures.atmosphericHelpers = true;
gDeferredAlphaProgram.mFeatures.calculatesLighting = false;
gDeferredAlphaProgram.mFeatures.calculatesAtmospherics = true;
gDeferredAlphaProgram.mFeatures.hasGamma = true;
gDeferredAlphaProgram.mFeatures.hasAtmospherics = true;
gDeferredAlphaProgram.mFeatures.hasLighting = false;
gDeferredAlphaProgram.mFeatures.isAlphaLighting = true;
gDeferredAlphaProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels
@ -1420,8 +1492,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));
gDeferredAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));
gDeferredAlphaProgram.addPermutation("USE_INDEXED_TEX", "1");
gDeferredAlphaProgram.addPermutation("USE_VERTEX_COLOR", "1");
gDeferredAlphaProgram.addPermutation("HAS_SHADOW", mVertexShaderLevel[SHADER_DEFERRED] > 1 ? "1" : "0");
gDeferredAlphaProgram.addPermutation("USE_VERTEX_COLOR", "1");
gDeferredAlphaProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
success = gDeferredAlphaProgram.createShader(NULL, NULL);
@ -1431,6 +1503,72 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredAlphaProgram.mFeatures.hasLighting = true;
}
if (success)
{
gDeferredAlphaImpostorProgram.mName = "Deferred Alpha Shader";
gDeferredAlphaImpostorProgram.mFeatures.calculatesLighting = false;
gDeferredAlphaImpostorProgram.mFeatures.hasLighting = false;
gDeferredAlphaImpostorProgram.mFeatures.isAlphaLighting = true;
gDeferredAlphaImpostorProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels
if (mVertexShaderLevel[SHADER_DEFERRED] < 1)
{
gDeferredAlphaImpostorProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
}
else
{ //shave off some texture units for shadow maps
gDeferredAlphaImpostorProgram.mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels - 6, 1);
}
gDeferredAlphaImpostorProgram.mShaderFiles.clear();
gDeferredAlphaImpostorProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));
gDeferredAlphaImpostorProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));
gDeferredAlphaImpostorProgram.addPermutation("USE_INDEXED_TEX", "1");
gDeferredAlphaImpostorProgram.addPermutation("HAS_SHADOW", mVertexShaderLevel[SHADER_DEFERRED] > 1 ? "1" : "0");
gDeferredAlphaImpostorProgram.addPermutation("USE_VERTEX_COLOR", "1");
gDeferredAlphaImpostorProgram.addPermutation("FOR_IMPOSTOR", "1");
gDeferredAlphaImpostorProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
success = gDeferredAlphaImpostorProgram.createShader(NULL, NULL);
// Hack
gDeferredAlphaImpostorProgram.mFeatures.calculatesLighting = true;
gDeferredAlphaImpostorProgram.mFeatures.hasLighting = true;
}
if (success)
{
gDeferredAlphaWaterProgram.mName = "Deferred Alpha Underwater Shader";
gDeferredAlphaWaterProgram.mFeatures.calculatesLighting = false;
gDeferredAlphaWaterProgram.mFeatures.hasLighting = false;
gDeferredAlphaWaterProgram.mFeatures.isAlphaLighting = true;
gDeferredAlphaWaterProgram.mFeatures.disableTextureIndex = true; //hack to disable auto-setup of texture channels
if (mVertexShaderLevel[SHADER_DEFERRED] < 1)
{
gDeferredAlphaWaterProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
}
else
{ //shave off some texture units for shadow maps
gDeferredAlphaWaterProgram.mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels - 6, 1);
}
gDeferredAlphaWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
gDeferredAlphaWaterProgram.mShaderFiles.clear();
gDeferredAlphaWaterProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));
gDeferredAlphaWaterProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));
gDeferredAlphaWaterProgram.addPermutation("USE_INDEXED_TEX", "1");
gDeferredAlphaWaterProgram.addPermutation("WATER_FOG", "1");
gDeferredAlphaWaterProgram.addPermutation("USE_VERTEX_COLOR", "1");
gDeferredAlphaWaterProgram.addPermutation("HAS_SHADOW", mVertexShaderLevel[SHADER_DEFERRED] > 1 ? "1" : "0");
gDeferredAlphaWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
success = gDeferredAlphaWaterProgram.createShader(NULL, NULL);
// Hack
gDeferredAlphaWaterProgram.mFeatures.calculatesLighting = true;
gDeferredAlphaWaterProgram.mFeatures.hasLighting = true;
}
if (success)
{
gDeferredAvatarEyesProgram.mName = "Deferred Avatar Eyes Shader";
@ -1459,6 +1597,54 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
success = gDeferredFullbrightProgram.createShader(NULL, NULL);
}
if (success)
{
gDeferredFullbrightAlphaMaskProgram.mName = "Deferred Fullbright Alpha Masking Shader";
gDeferredFullbrightAlphaMaskProgram.mFeatures.calculatesAtmospherics = true;
gDeferredFullbrightAlphaMaskProgram.mFeatures.hasGamma = true;
gDeferredFullbrightAlphaMaskProgram.mFeatures.hasTransport = true;
gDeferredFullbrightAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
gDeferredFullbrightAlphaMaskProgram.mShaderFiles.clear();
gDeferredFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));
gDeferredFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
gDeferredFullbrightAlphaMaskProgram.addPermutation("HAS_ALPHA_MASK","1");
gDeferredFullbrightAlphaMaskProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
success = gDeferredFullbrightAlphaMaskProgram.createShader(NULL, NULL);
}
if (success)
{
gDeferredFullbrightWaterProgram.mName = "Deferred Fullbright Underwater Shader";
gDeferredFullbrightWaterProgram.mFeatures.calculatesAtmospherics = true;
gDeferredFullbrightWaterProgram.mFeatures.hasGamma = true;
gDeferredFullbrightWaterProgram.mFeatures.hasTransport = true;
gDeferredFullbrightWaterProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
gDeferredFullbrightWaterProgram.mShaderFiles.clear();
gDeferredFullbrightWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));
gDeferredFullbrightWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
gDeferredFullbrightWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
gDeferredFullbrightWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
gDeferredFullbrightWaterProgram.addPermutation("WATER_FOG","1");
success = gDeferredFullbrightWaterProgram.createShader(NULL, NULL);
}
if (success)
{
gDeferredFullbrightAlphaMaskWaterProgram.mName = "Deferred Fullbright Underwater Alpha Masking Shader";
gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.calculatesAtmospherics = true;
gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.hasGamma = true;
gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.hasTransport = true;
gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
gDeferredFullbrightAlphaMaskWaterProgram.mShaderFiles.clear();
gDeferredFullbrightAlphaMaskWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));
gDeferredFullbrightAlphaMaskWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
gDeferredFullbrightAlphaMaskWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
gDeferredFullbrightAlphaMaskWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
gDeferredFullbrightAlphaMaskWaterProgram.addPermutation("HAS_ALPHA_MASK","1");
gDeferredFullbrightAlphaMaskWaterProgram.addPermutation("WATER_FOG","1");
success = gDeferredFullbrightAlphaMaskWaterProgram.createShader(NULL, NULL);
}
if (success)
{
gDeferredFullbrightShinyProgram.mName = "Deferred FullbrightShiny Shader";
@ -1531,6 +1717,20 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
success = gDeferredWaterProgram.createShader(NULL, NULL);
}
if (success)
{
// load water shader
gDeferredUnderWaterProgram.mName = "Deferred Under Water Shader";
gDeferredUnderWaterProgram.mFeatures.calculatesAtmospherics = true;
gDeferredUnderWaterProgram.mFeatures.hasGamma = true;
gDeferredUnderWaterProgram.mFeatures.hasTransport = true;
gDeferredUnderWaterProgram.mShaderFiles.clear();
gDeferredUnderWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterV.glsl", GL_VERTEX_SHADER_ARB));
gDeferredUnderWaterProgram.mShaderFiles.push_back(make_pair("deferred/underWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
gDeferredUnderWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
success = gDeferredUnderWaterProgram.createShader(NULL, NULL);
}
if (success)
{
gDeferredSoftenProgram.mName = "Deferred Soften Shader";
@ -1548,6 +1748,25 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
success = gDeferredSoftenProgram.createShader(NULL, NULL);
}
if (success)
{
gDeferredSoftenWaterProgram.mName = "Deferred Soften Underwater Shader";
gDeferredSoftenWaterProgram.mShaderFiles.clear();
gDeferredSoftenWaterProgram.mShaderFiles.push_back(make_pair("deferred/softenLightV.glsl", GL_VERTEX_SHADER_ARB));
gDeferredSoftenWaterProgram.mShaderFiles.push_back(make_pair("deferred/softenLightF.glsl", GL_FRAGMENT_SHADER_ARB));
gDeferredSoftenWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
gDeferredSoftenWaterProgram.addPermutation("WATER_FOG", "1");
gDeferredSoftenWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
if (gSavedSettings.getBOOL("RenderDeferredSSAO"))
{ //if using SSAO, take screen space light map into account as if shadows are enabled
gDeferredSoftenWaterProgram.mShaderLevel = llmax(gDeferredSoftenWaterProgram.mShaderLevel, 2);
}
success = gDeferredSoftenWaterProgram.createShader(NULL, NULL);
}
if (success)
{
gDeferredShadowProgram.mName = "Deferred Shadow Shader";
@ -1630,12 +1849,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (success)
{
gDeferredAvatarAlphaProgram.mName = "Avatar Alpha Shader";
gDeferredAvatarAlphaProgram.mFeatures.atmosphericHelpers = true;
gDeferredAvatarAlphaProgram.mFeatures.hasSkinning = true;
gDeferredAvatarAlphaProgram.mFeatures.calculatesLighting = false;
gDeferredAvatarAlphaProgram.mFeatures.calculatesAtmospherics = true;
gDeferredAvatarAlphaProgram.mFeatures.hasGamma = true;
gDeferredAvatarAlphaProgram.mFeatures.hasAtmospherics = true;
gDeferredAvatarAlphaProgram.mFeatures.hasLighting = false;
gDeferredAvatarAlphaProgram.mFeatures.isAlphaLighting = true;
gDeferredAvatarAlphaProgram.mFeatures.disableTextureIndex = true;
@ -1774,6 +1989,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectFullbrightNoColorProgram.unload();
gObjectFullbrightNoColorWaterProgram.unload();
gObjectSimpleProgram.unload();
gObjectSimpleImpostorProgram.unload();
gObjectPreviewProgram.unload();
gImpostorProgram.unload();
gObjectSimpleAlphaMaskProgram.unload();
@ -2194,6 +2410,27 @@ BOOL LLViewerShaderMgr::loadShadersObject()
success = gObjectSimpleProgram.createShader(NULL, NULL);
}
if (success)
{
gObjectSimpleImpostorProgram.mName = "Simple Impostor Shader";
gObjectSimpleImpostorProgram.mFeatures.calculatesLighting = true;
gObjectSimpleImpostorProgram.mFeatures.calculatesAtmospherics = true;
gObjectSimpleImpostorProgram.mFeatures.hasGamma = true;
gObjectSimpleImpostorProgram.mFeatures.hasAtmospherics = true;
gObjectSimpleImpostorProgram.mFeatures.hasLighting = true;
gObjectSimpleImpostorProgram.mFeatures.mIndexedTextureChannels = 0;
// force alpha mask version of lighting so we can weed out
// transparent pixels from impostor temp buffer
//
gObjectSimpleImpostorProgram.mFeatures.hasAlphaMask = true;
gObjectSimpleImpostorProgram.mShaderFiles.clear();
gObjectSimpleImpostorProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));
gObjectSimpleImpostorProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB));
gObjectSimpleImpostorProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];
success = gObjectSimpleImpostorProgram.createShader(NULL, NULL);
}
if (success)
{
gObjectSimpleWaterProgram.mName = "Simple Water Shader";
@ -3128,3 +3365,4 @@ LLViewerShaderMgr::shader_iter LLViewerShaderMgr::endShaders() const
{
return mShaderList.end();
}

View File

@ -77,8 +77,6 @@ public:
SHADER_COUNT
};
// simple model of forward iterator
// http://www.sgi.com/tech/stl/ForwardIterator.html
class shader_iter
@ -130,6 +128,23 @@ public:
/* virtual */ void updateShaderUniforms(LLGLSLShader * shader);
private:
std::vector<std::string> mShinyUniforms;
//water parameters
std::vector<std::string> mWaterUniforms;
std::vector<std::string> mWLUniforms;
//terrain parameters
std::vector<std::string> mTerrainUniforms;
//glow parameters
std::vector<std::string> mGlowUniforms;
std::vector<std::string> mGlowExtractUniforms;
std::vector<std::string> mAvatarUniforms;
// the list of shaders we need to propagate parameters to.
std::vector<LLGLSLShader *> mShaderList;
@ -176,6 +191,7 @@ extern LLGLSLShader gOneTextureNoColorProgram;
//object shaders
extern LLGLSLShader gObjectSimpleProgram;
extern LLGLSLShader gObjectSimpleImpostorProgram;
extern LLGLSLShader gObjectPreviewProgram;
extern LLGLSLShader gObjectSimpleAlphaMaskProgram;
extern LLGLSLShader gObjectSimpleWaterProgram;
@ -264,6 +280,7 @@ extern LLGLSLShader gPostNightVisionProgram;
// Deferred rendering shaders
extern LLGLSLShader gDeferredImpostorProgram;
extern LLGLSLShader gDeferredWaterProgram;
extern LLGLSLShader gDeferredUnderWaterProgram;
extern LLGLSLShader gDeferredDiffuseProgram;
extern LLGLSLShader gDeferredDiffuseAlphaMaskProgram;
extern LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskProgram;
@ -284,6 +301,7 @@ extern LLGLSLShader gDeferredSunProgram;
extern LLGLSLShader gDeferredBlurLightProgram;
extern LLGLSLShader gDeferredAvatarProgram;
extern LLGLSLShader gDeferredSoftenProgram;
extern LLGLSLShader gDeferredSoftenWaterProgram;
extern LLGLSLShader gDeferredShadowProgram;
extern LLGLSLShader gDeferredShadowCubeProgram;
extern LLGLSLShader gDeferredShadowAlphaMaskProgram;
@ -296,7 +314,12 @@ extern LLGLSLShader gDeferredPostGammaCorrectProgram;
extern LLGLSLShader gDeferredAvatarShadowProgram;
extern LLGLSLShader gDeferredAttachmentShadowProgram;
extern LLGLSLShader gDeferredAlphaProgram;
extern LLGLSLShader gDeferredAlphaImpostorProgram;
extern LLGLSLShader gDeferredFullbrightProgram;
extern LLGLSLShader gDeferredFullbrightAlphaMaskProgram;
extern LLGLSLShader gDeferredAlphaWaterProgram;
extern LLGLSLShader gDeferredFullbrightWaterProgram;
extern LLGLSLShader gDeferredFullbrightAlphaMaskWaterProgram;
extern LLGLSLShader gDeferredEmissiveProgram;
extern LLGLSLShader gDeferredAvatarEyesProgram;
extern LLGLSLShader gDeferredAvatarAlphaProgram;
@ -310,5 +333,5 @@ extern LLGLSLShader gNormalMapGenProgram;
// Deferred materials shaders
extern LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2];
extern LLGLSLShader gDeferredMaterialWaterProgram[LLMaterial::SHADER_COUNT*2];
#endif

View File

@ -566,12 +566,12 @@ void LLViewerTextureList::addImageToList(LLViewerFetchedTexture *image)
}
else
{
if((mImageList.insert(image)).second != true)
{
if((mImageList.insert(image)).second != true)
{
llwarns << "Error happens when insert image " << image->getID() << " into mImageList!" << llendl ;
}
image->setInImageList(TRUE) ;
}
image->setInImageList(TRUE) ;
}
}
void LLViewerTextureList::removeImageFromList(LLViewerFetchedTexture *image)
@ -585,30 +585,30 @@ void LLViewerTextureList::removeImageFromList(LLViewerFetchedTexture *image)
{
count = mImageList.erase(image) ;
if(count != 1)
{
llwarns << "Image " << image->getID()
{
llinfos << "Image " << image->getID()
<< " had mInImageList set but mImageList.erase() returned " << count
<< llendl;
}
}
else
{ // Something is wrong, image is expected in list or callers should check first
llwarns << "Calling removeImageFromList() for " << image->getID()
llinfos << "Calling removeImageFromList() for " << image->getID()
<< " but doesn't have mInImageList set"
<< " ref count is " << image->getNumRefs()
<< llendl;
uuid_map_t::iterator iter = mUUIDMap.find(image->getID());
if(iter == mUUIDMap.end())
{
llwarns << "Image " << image->getID() << " is also not in mUUIDMap!" << llendl ;
llinfos << "Image " << image->getID() << " is also not in mUUIDMap!" << llendl ;
}
else if (iter->second != image)
{
llwarns << "Image " << image->getID() << " was in mUUIDMap but with different pointer" << llendl ;
}
llinfos << "Image " << image->getID() << " was in mUUIDMap but with different pointer" << llendl ;
}
else
{
llwarns << "Image " << image->getID() << " was in mUUIDMap with same pointer" << llendl ;
{
llinfos << "Image " << image->getID() << " was in mUUIDMap with same pointer" << llendl ;
}
count = mImageList.erase(image) ;
if(count != 0)
@ -618,7 +618,7 @@ void LLViewerTextureList::removeImageFromList(LLViewerFetchedTexture *image)
<< llendl;
}
}
image->setInImageList(FALSE) ;
}
@ -626,15 +626,15 @@ void LLViewerTextureList::addImage(LLViewerFetchedTexture *new_image)
{
if (!new_image)
{
llwarning("No image to add to image list", 0);
return;
}
llassert(new_image);
LLUUID image_id = new_image->getID();
LLViewerFetchedTexture *image = findImage(image_id);
if (image)
{
llwarns << "Image with ID " << image_id << " already in list" << llendl;
llinfos << "Image with ID " << image_id << " already in list" << llendl;
}
sNumImages++;

View File

@ -1035,7 +1035,7 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &params_in, const S32 detail, bo
}
}
}
static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback");
bool cache_in_vram = use_transform_feedback && gTransformPositionProgram.mProgramObject &&
@ -4426,7 +4426,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
U32 spec_count = 0;
U32 normspec_count = 0;
U32 useage = group->mSpatialPartition->mBufferUsage;
U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcVertexSize(group->mSpatialPartition->mVertexDataMask);
@ -5004,7 +5004,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
}
else
{
pAvatarVO->mAttachmentGeometryBytes += group->mGeometryBytes;
pAvatarVO->mAttachmentGeometryBytes += group->mGeometryBytes;
}
if (pAvatarVO->mAttachmentSurfaceArea < 0.f)
{ // First time through value is -1
@ -5012,10 +5012,10 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
}
else
{
pAvatarVO->mAttachmentSurfaceArea += group->mSurfaceArea;
}
pAvatarVO->mAttachmentSurfaceArea += group->mSurfaceArea;
}
}
}
static LLFastTimer::DeclareTimer FTM_REBUILD_MESH_FLUSH("Flush Mesh");
@ -5033,7 +5033,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
const U32 MAX_BUFFER_COUNT = 4096;
LLVertexBuffer* locked_buffer[MAX_BUFFER_COUNT];
U32 buffer_count = 0;
for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
@ -5044,7 +5044,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
{
LLVOVolume* vobj = drawablep->getVOVolume();
vobj->preRebuild();
if (drawablep->isState(LLDrawable::ANIMATED_CHILD))
{
vobj->updateRelativeXform(true);
@ -5090,17 +5090,17 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
{
LLFastTimer t(FTM_REBUILD_MESH_FLUSH);
for (LLVertexBuffer** iter = locked_buffer, ** end_iter = locked_buffer+buffer_count; iter != end_iter; ++iter)
{
(*iter)->flush();
}
// don't forget alpha
if(group != NULL &&
!group->mVertexBuffer.isNull() &&
group->mVertexBuffer->isLocked())
{
group->mVertexBuffer->flush();
}
{
(*iter)->flush();
}
// don't forget alpha
if(group != NULL &&
!group->mVertexBuffer.isNull() &&
group->mVertexBuffer->isLocked())
{
group->mVertexBuffer->flush();
}
}
//if not all buffers are unmapped
@ -5297,7 +5297,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac
{
texture_list[texture_count++] = tex;
}
if (can_batch_texture(facep))
{ //populate texture_list with any textures that can be batched
//move i to the next unbatchable face
@ -5503,18 +5503,23 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac
}
bool use_legacy_bump = te->getBumpmap() && (te->getBumpmap() < 18) && (!mat || mat->getNormalID().isNull());
bool opaque = te->getColor().mV[3] >= 0.999f;
if (mat && LLPipeline::sRenderDeferred && !hud_group)
{
bool material_pass = false;
if (fullbright)
// do NOT use 'fullbright' for this logic or you risk sending
// things without normals down the materials pipeline and will
// render poorly if not crash NORSPEC-240,314
//
if (te->getFullbright())
{
if (mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
{
if (te->getColor().mV[3] >= 0.999f)
if (opaque)
{
material_pass = true;
registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK);
}
else
{

File diff suppressed because it is too large Load Diff

View File

@ -295,6 +295,7 @@ public:
void unbindDeferredShader(LLGLSLShader& shader);
void renderDeferredLighting();
void renderDeferredLightingToRT(LLRenderTarget* target);
void generateWaterReflection(LLCamera& camera);
void generateSunShadow(LLCamera& camera);
@ -594,6 +595,7 @@ public:
static BOOL sPickAvatar;
static BOOL sReflectionRender;
static BOOL sImpostorRender;
static BOOL sImpostorRenderAlphaDepthPass;
static BOOL sUnderWaterRender;
static BOOL sRenderGlow;
static BOOL sTextureBindTest;

View File

@ -663,7 +663,7 @@
label_width="205"
layout="topleft"
left="10"
min_val="-1"
min_val="0"
name="bumpyOffsetU"
width="265" />
<spinner
@ -674,7 +674,7 @@
label_width="205"
layout="topleft"
left="10"
min_val="-1"
min_val="0"
name="bumpyOffsetV"
width="265" />
<spinner
@ -726,7 +726,7 @@
label_width="205"
layout="topleft"
left="10"
min_val="-1"
min_val="0"
name="shinyOffsetU"
width="265" />
<spinner
@ -737,7 +737,7 @@
label_width="205"
layout="topleft"
left="10"
min_val="-1"
min_val="0"
name="shinyOffsetV"
width="265" />
<check_box