The unbearable lightness of being norspec
commit
95e34d86b9
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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 ¶ms, 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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
3.6.6
|
||||
3.6.7
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -142,3 +142,4 @@ vary_normal = n;
|
|||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -31,8 +31,6 @@ out vec4 frag_color;
|
|||
|
||||
uniform sampler2D depthMap;
|
||||
|
||||
uniform float delta;
|
||||
|
||||
VARYING vec2 tc0;
|
||||
VARYING vec2 tc1;
|
||||
VARYING vec2 tc2;
|
||||
|
|
|
|||
|
|
@ -33,8 +33,6 @@ out vec4 frag_color;
|
|||
|
||||
uniform sampler2DRect depthMap;
|
||||
|
||||
uniform float delta;
|
||||
|
||||
VARYING vec2 tc0;
|
||||
VARYING vec2 tc1;
|
||||
VARYING vec2 tc2;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -155,3 +155,4 @@ void LLDrawPoolSky::renderSkyCubeFace(U8 side)
|
|||
void LLDrawPoolSky::endRenderPass( S32 pass )
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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++;
|
||||
|
||||
|
|
|
|||
|
|
@ -1035,7 +1035,7 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms_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
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue