diff options
81 files changed, 3395 insertions, 1118 deletions
| @@ -465,3 +465,4 @@ fe4f7c5e9fd27e09d03deb1cc9ab3e5093f6309e 3.6.3-release  83357f31d8dbf048a8bfdc323f363bf4d588aca1 CHOP-951-a  91ed595b716f14f07409595b734fda891a59379e 3.6.4-release  bf6d453046011a11de2643fac610cc5258650f82 3.6.5-release +b62e417982d9d4f3ec49d0de3b3c2e37c6d394c1 3.6.6-release diff --git a/autobuild.xml b/autobuild.xml index e047d4d686..b1478a46b2 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -2638,7 +2638,6 @@                  <array>                    <string>/build</string>                    <string>"/cfg=Release|Win32"</string> -                  <string>"/CL_ADD=/m:1"</string>                  </array>                </map>                <key>configure</key> diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp index a0802c6adf..b7815b0e35 100755 --- a/indra/llcommon/llapr.cpp +++ b/indra/llcommon/llapr.cpp @@ -226,7 +226,7 @@ void LLVolatileAPRPool::clearVolatileAPRPool()  		llassert_always(mNumActiveRef > 0) ;  	} -	llassert(mNumTotalRef < (FULL_VOLATILE_APR_POOL << 2)) ; +	llassert(mNumTotalRef <= (FULL_VOLATILE_APR_POOL << 2)) ;  }  BOOL LLVolatileAPRPool::isFull() diff --git a/indra/llmath/llvector4a.inl b/indra/llmath/llvector4a.inl index 7c52ffef21..558fe09323 100755 --- a/indra/llmath/llvector4a.inl +++ b/indra/llmath/llvector4a.inl @@ -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  { diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 14cebfe5aa..a030d889af 100755 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -136,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. @@ -5908,10 +5984,10 @@ void LLVolumeFace::cacheOptimize()  		wght = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);  	} -	LLVector4a* binorm = NULL; +	LLVector4a* tangent = NULL;  	if (mTangents)  	{ -		binorm = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts); +		tangent = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);  	}  	//allocate mapping of old indices to new indices @@ -5936,7 +6012,7 @@ void LLVolumeFace::cacheOptimize()  			}  			if (mTangents)  			{ -				binorm[cur_idx] = mTangents[idx]; +				tangent[cur_idx] = mTangents[idx];  			}  			cur_idx++; @@ -5958,7 +6034,7 @@ void LLVolumeFace::cacheOptimize()  	mNormals = norm;  	mTexCoords = tc;  	mWeights = wght; -	mTangents = binorm; +	mTangents = tangent;  	//std::string result = llformat("ACMR pre/post: %.3f/%.3f  --  %d triangles %d breaks", pre_acmr, post_acmr, mNumIndices/3, breaks);  	//llinfos << result << llendl; @@ -6306,6 +6382,43 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)  	cuv = (min_uv + max_uv)*0.5f; + +	LLVector4a tangent; +	calc_tangent_from_triangle( +			*norm, +			tangent, +			*mCenter, cuv, +			pos[0], tc[0], +			pos[1], tc[1]); + +	if (tangent.getLength3() < 0.01) +	{ +		tangent.set(1,0,0,1); +	} +	else +	{ +		LLVector4a default_tangent; +		default_tangent.set(1,0,0,1); +		tangent.normalize3fast_checked(&default_tangent); +	} + +	LLVector4a normal; +	LLVector4a d0, d1; + +	d0.setSub(*mCenter, pos[0]); +	d1.setSub(*mCenter, pos[1]); +	 +	if (mTypeMask & TOP_MASK) +	{ +		normal.setCross3(d0, d1); +	} +	else +	{ +		normal.setCross3(d1, d0); +	} + +	normal.normalize3fast_checked(); +  	VertexData vd;  	vd.setPosition(*mCenter);  	vd.mTexCoord = cuv; @@ -6318,6 +6431,14 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)  		num_vertices++;  	} +	allocateTangents(num_vertices);		 + +	for (S32 i = 0; i < num_vertices; i++) +	{ +		mTangents[i].load4a(tangent.getF32ptr()); +		norm[i].load4a(normal.getF32ptr()); +	}	 +  	if (partial_build)  	{  		return TRUE; @@ -6553,36 +6674,6 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)  	} -	LLVector4a d0,d1; - -	d0.setSub(mPositions[mIndices[1]], mPositions[mIndices[0]]); -	d1.setSub(mPositions[mIndices[2]], mPositions[mIndices[0]]); - -	LLVector4a normal; -	normal.setCross3(d0,d1); - -	if (normal.dot3(normal).getF32() > F_APPROXIMATELY_ZERO) -	{ -		normal.normalize3fast(); -	} -	else -	{ //degenerate, make up a value -		normal.set(0,0,1); -	} - -	llassert(llfinite(normal.getF32ptr()[0])); -	llassert(llfinite(normal.getF32ptr()[1])); -	llassert(llfinite(normal.getF32ptr()[2])); - -	llassert(!llisnan(normal.getF32ptr()[0])); -	llassert(!llisnan(normal.getF32ptr()[1])); -	llassert(!llisnan(normal.getF32ptr()[2])); -	 -	for (S32 i = 0; i < num_vertices; i++) -	{ -		norm[i].load4a(normal.getF32ptr()); -	} -  	return TRUE;  } @@ -6611,11 +6702,13 @@ void LLVolumeFace::createTangents()  		CalculateTangentArray(mNumVertices, mPositions, mNormals, mTexCoords, mNumIndices/3, mIndices, mTangents);  		//normalize tangents +		LLVector4a default_norm; +		default_norm.set(0,1,0,1);  		for (U32 i = 0; i < mNumVertices; i++)   		{ -			//binorm[i].normalize3fast(); +			//tangent[i].normalize3fast();  			//bump map/planar projection code requires normals to be normalized -			mNormals[i].normalize3fast(); +			mNormals[i].normalize3fast_checked();  		}  	}  } @@ -6800,7 +6893,7 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat  		//transform appended face normal and store  		norm_mat.rotate(src_norm[i], dst_norm[i]); -		dst_norm[i].normalize3fast(); +		dst_norm[i].normalize3fast_checked();  		//copy appended face texture coordinate  		dst_tc[i] = src_tc[i]; @@ -7209,11 +7302,61 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)  	return TRUE;  } +// Finds binormal based on three vertices with texture coordinates. +// Fills in dummy values if the triangle has degenerate texture coordinates. +void calc_binormal_from_triangle(LLVector4a& binormal, + +	const LLVector4a& pos0, +	const LLVector2& tex0, +	const LLVector4a& pos1, +	const LLVector2& tex1, +	const LLVector4a& pos2, +	const LLVector2& tex2) +{ +	LLVector4a rx0( pos0[VX], tex0.mV[VX], tex0.mV[VY] ); +	LLVector4a rx1( pos1[VX], tex1.mV[VX], tex1.mV[VY] ); +	LLVector4a rx2( pos2[VX], tex2.mV[VX], tex2.mV[VY] ); +	 +	LLVector4a ry0( pos0[VY], tex0.mV[VX], tex0.mV[VY] ); +	LLVector4a ry1( pos1[VY], tex1.mV[VX], tex1.mV[VY] ); +	LLVector4a ry2( pos2[VY], tex2.mV[VX], tex2.mV[VY] ); + +	LLVector4a rz0( pos0[VZ], tex0.mV[VX], tex0.mV[VY] ); +	LLVector4a rz1( pos1[VZ], tex1.mV[VX], tex1.mV[VY] ); +	LLVector4a rz2( pos2[VZ], tex2.mV[VX], tex2.mV[VY] ); +	 +	LLVector4a lhs, rhs; + +	LLVector4a r0;  +	lhs.setSub(rx0, rx1); rhs.setSub(rx0, rx2); +	r0.setCross3(lhs, rhs); +		 +	LLVector4a r1; +	lhs.setSub(ry0, ry1); rhs.setSub(ry0, ry2); +	r1.setCross3(lhs, rhs); + +	LLVector4a r2; +	lhs.setSub(rz0, rz1); rhs.setSub(rz0, rz2); +	r2.setCross3(lhs, rhs); + +	if( r0[VX] && r1[VX] && r2[VX] ) +	{ +		binormal.set( +				-r0[VZ] / r0[VX], +				-r1[VZ] / r1[VX], +				-r2[VZ] / r2[VX]); +		// binormal.normVec(); +	} +	else +	{ +		binormal.set( 0, 1 , 0 ); +	} +} +  //adapted from Lengyel, Eric. “Computing Tangent Space Basis Vectors for an Arbitrary Mesh”. Terathon Software 3D Graphics Library, 2001. http://www.terathon.com/code/tangent.html  void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal,          const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent)  { -    //LLVector4a *tan1 = new LLVector4a[vertexCount * 2];  	LLVector4a* tan1 = (LLVector4a*) ll_aligned_malloc_16(vertexCount*2*sizeof(LLVector4a));      LLVector4a* tan2 = tan1 + vertexCount; diff --git a/indra/llprimitive/lltextureentry.cpp b/indra/llprimitive/lltextureentry.cpp index 597f078490..0db75a0e82 100755 --- a/indra/llprimitive/lltextureentry.cpp +++ b/indra/llprimitive/lltextureentry.cpp @@ -545,7 +545,7 @@ S32 LLTextureEntry::setMaterialID(const LLMaterialID& pMaterialID)  		{  			mMaterialUpdatePending = true;  			mMaterialID = pMaterialID; -			return TEM_CHANGE_NONE; +			return TEM_CHANGE_TEXTURE;  		}  		mMaterialUpdatePending = false; diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index c3005f1722..a157cd94c4 100755 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -647,7 +647,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;  		} @@ -1155,7 +1156,7 @@ void LLGLManager::initExtensions()  	glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, (GLint*) &mGLMaxVertexRange);  	glGetIntegerv(GL_MAX_ELEMENTS_INDICES, (GLint*) &mGLMaxIndexRange);  	glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint*) &mGLMaxTextureSize); - +	  #if (LL_WINDOWS || LL_LINUX || LL_SOLARIS) && !LL_MESA_HEADLESS  	LL_DEBUGS("RenderInit") << "GL Probe: Getting symbols" << LL_ENDL;  	if (mHasVertexBufferObject) diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index ac16e30796..40aff36dac 100755 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -374,6 +374,11 @@ BOOL LLGLSLShader::createShader(vector<string> * 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(); diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index c60eb8d9d9..f2f1b62be0 100755 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -1849,35 +1849,36 @@ void LLRender::flush()  			sUIVerts += mCount;  		} -		if (gDebugGL) +		//store mCount in a local variable to avoid re-entrance (drawArrays may call flush) +		U32 count = mCount; + +		if (mMode == LLRender::QUADS && !sGLCoreProfile)  		{ -			if (mMode == LLRender::QUADS && !sGLCoreProfile) +			if (mCount%4 != 0)  			{ -				if (mCount%4 != 0) -				{ -					llerrs << "Incomplete quad rendered." << llendl; -				} +				count -= (mCount % 4); +				llwarns << "Incomplete quad requested." << llendl;  			} -			 -			if (mMode == LLRender::TRIANGLES) +		} + +		if (mMode == LLRender::TRIANGLES) +		{ +			if (mCount%3 != 0)  			{ -				if (mCount%3 != 0) -				{ -					llerrs << "Incomplete triangle rendered." << llendl; -				} +				count -= (mCount % 3); +				llwarns << "Incomplete triangle requested." << llendl;  			} -			 -			if (mMode == LLRender::LINES) +		} + +		if (mMode == LLRender::LINES) +		{ +			if (mCount%2 != 0)  			{ -				if (mCount%2 != 0) -				{ -					llerrs << "Incomplete line rendered." << llendl; -				} +				count -= (mCount % 2); +				llwarns << "Incomplete line requested." << llendl;  			}  		} - -		//store mCount in a local variable to avoid re-entrance (drawArrays may call flush) -		U32 count = mCount; +		  		mCount = 0;  		if (mBuffer->useVBOs() && !mBuffer->isLocked()) diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp index 5ea8387c04..c0602d79bd 100755 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -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;  	} @@ -260,7 +262,7 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)  	}  #endif -     +  	return true;  } @@ -362,36 +364,56 @@ void LLRenderTarget::release()  		sBytesAllocated -= mResX*mResY*4;  	} -	else if (mUseDepth && mFBO) -	{ //detach shared depth buffer +	else if (mFBO) +	{  		glBindFramebuffer(GL_FRAMEBUFFER, mFBO); -		if (mStencil) -		{ //attached as a renderbuffer -			glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0); -			glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0); -			mStencil = false; + +		if (mUseDepth) +		{ //detach shared depth buffer +			if (mStencil) +			{ //attached as a renderbuffer +				glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0); +				glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0); +				mStencil = false; +			} +			else +			{ //attached as a texture +				glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), 0, 0); +			} +			mUseDepth = false;  		} -		else -		{ //attached as a texture -			glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), 0, 0); +	} + +	// Detach any extra color buffers (e.g. SRGB spec buffers) +	// +	if (mFBO && (mTex.size() > 1)) +	{		 +		S32 z; +		for (z = mTex.size() - 1; z >= 1; z--) +		{ +			sBytesAllocated -= mResX*mResY*4; +			glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+z, LLTexUnit::getInternalType(mUsage), 0, 0); +			stop_glerror(); +			LLImageGL::deleteTextures(mUsage, mInternalFormat[z], 0, 1, &mTex[z], true);  		} -		mUseDepth = false;  	}  	if (mFBO)  	{  		glDeleteFramebuffers(1, (GLuint *) &mFBO); +		stop_glerror();  		mFBO = 0;  	}  	if (mTex.size() > 0)  	{ -		sBytesAllocated -= mResX*mResY*4*mTex.size(); -		LLImageGL::deleteTextures(mUsage, mInternalFormat[0], 0, mTex.size(), &mTex[0], true); -		mTex.clear(); -		mInternalFormat.clear(); +		sBytesAllocated -= mResX*mResY*4; +		LLImageGL::deleteTextures(mUsage, mInternalFormat[0], 0, 1, &mTex[0], true);  	} -	 + +	mTex.clear(); +	mInternalFormat.clear(); +  	mResX = mResY = 0;  	sBoundTarget = NULL; @@ -575,8 +597,10 @@ void LLRenderTarget::copyContentsToFramebuffer(LLRenderTarget& source, S32 srcX0  {  	if (!source.mFBO)  	{ -		llerrs << "Cannot copy framebuffer contents for non FBO render targets." << llendl; +		llwarns << "Cannot copy framebuffer contents for non FBO render targets." << llendl; +		return;  	} +  	{  		GLboolean write_depth = mask & GL_DEPTH_BUFFER_BIT ? TRUE : FALSE; diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h index 66a9874a6b..336441661c 100755 --- a/indra/llrender/llrendertarget.h +++ b/indra/llrender/llrendertarget.h @@ -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 diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index fea4ee2819..63404abeff 100755 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -1137,11 +1137,13 @@ void LLShaderMgr::initAttribsAndUniforms()  	mReservedUniforms.push_back("projectionMap");  	mReservedUniforms.push_back("global_gamma"); -	mReservedUniforms.push_back("texture_gamma"); -	 +	mReservedUniforms.push_back("texture_gamma");	 +  	mReservedUniforms.push_back("specular_color");  	mReservedUniforms.push_back("env_intensity"); +	mReservedUniforms.push_back("display_gamma"); +  	llassert(mReservedUniforms.size() == END_RESERVED_UNIFORMS);  	std::set<std::string> dupe_check; diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index c049e935b8..3c282bf24f 100755 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -167,11 +167,13 @@ public:  		DEFERRED_PROJECTION,  		GLOBAL_GAMMA, -		TEXTURE_GAMMA, -		 +		TEXTURE_GAMMA,		 +  		SPECULAR_COLOR,  		ENVIRONMENT_INTENSITY, +		DISPLAY_GAMMA, +  		END_RESERVED_UNIFORMS  	} eGLSLReservedUniforms; diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 01541026b1..6a7cec3bad 100755 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -753,10 +753,10 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi  	U16* idx = ((U16*) getIndicesPointer())+indices_offset;  	stop_glerror(); -	LLGLSLShader::startProfile(); -	glDrawRangeElements(sGLMode[mode], start, end, count, GL_UNSIGNED_SHORT,  +		LLGLSLShader::startProfile(); +		glDrawRangeElements(sGLMode[mode], start, end, count, GL_UNSIGNED_SHORT,   		idx); -	LLGLSLShader::stopProfile(count, mode); +		LLGLSLShader::stopProfile(count, mode);  	stop_glerror(); @@ -2236,10 +2236,41 @@ void LLVertexBuffer::setBuffer(U32 data_mask)  					required_mask |= required;  				}  			} - +          			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;  			}  		}  	} diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index 4f2c1d15f6..5b3413147c 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -3.6.6 +3.6.7 diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 72fe21cf14..388589a398 100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -3579,13 +3579,13 @@      </map>      <key>FilterItemsMaxTimePerFrameUnvisible</key>      <map> -        <key>Comment</key> +      <key>Comment</key>          <string>Max time devoted to items filtering per frame for non visible inventory listings (in milliseconds)</string> -        <key>Persist</key> -        <integer>1</integer> -        <key>Type</key> -        <string>S32</string> -        <key>Value</key> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>S32</string> +      <key>Value</key>          <integer>1</integer>      </map>      <key>FindLandArea</key> @@ -8831,6 +8831,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> @@ -9121,6 +9133,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> @@ -9848,6 +9871,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> diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl index 0899caa2af..cd7a76db28 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl @@ -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,14 +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 vec2 vary_texcoord0;  VARYING vec3 vary_norm; @@ -68,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)  { @@ -82,7 +157,7 @@ vec3 calcDirectionalLight(vec3 n, vec3 l)  	return vec3(a,a,a);  } -vec3 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; @@ -90,7 +165,9 @@ vec3 calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float  	//get distance  	float d = length(lv); -	float da = 0.0; +	float da = 1.0; + +	vec3 col = vec3(0);  	if (d > 0.0 && la > 0.0 && fa > 0.0)  	{ @@ -99,20 +176,25 @@ vec3 calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float  		//distance attenuation  		float dist = d/la; -		da = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0); -		da *= da; -		da *= 1.4; -	 +		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);  		da *= spot*spot; // GL_SPOT_EXPONENT=2  		//angular attenuation -		da *= max(dot(n, lv), 0.0);		 +		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 vec3(da,da,da);	 +	return max(col, vec3(0.0,0.0,0.0));  }  #if HAS_SHADOW @@ -135,6 +217,237 @@ 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()   { @@ -143,13 +456,15 @@ void main()  	vec4 pos = vec4(vary_position, 1.0); +	float shadow = 1.0; -#if HAS_SHADOW -	float shadow = 0.0; +#if HAS_SHADOW	  	vec4 spos = pos;  	if (spos.z > -shadow_clip.w)  	{	 +		shadow = 0.0; +  		vec4 lpos;  		vec4 near_split = shadow_clip*-0.75; @@ -215,40 +530,77 @@ void main()  #else  	vec4 diff = texture2D(diffuseMap,vary_texcoord0.xy);  #endif -	vec4 gamma_diff = diff; -	diff.rgb = pow(diff.rgb, vec3(2.2f, 2.2f, 2.2f)); +#ifdef FOR_IMPOSTOR +	vec4 color; +	color.rgb = diff.rgb;  #ifdef USE_VERTEX_COLOR -	float vertex_color_alpha = vertex_color.a;	 +	float final_alpha = diff.a * vertex_color.a; +	diff.rgb *= vertex_color.rgb;  #else -	float vertex_color_alpha = 1.0; +	float final_alpha = diff.a;  #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); +	// 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 -	vec4 col = vec4(vary_ambient + dlight, vertex_color_alpha); +	float final_alpha = diff.a;  #endif -	vec4 color = gamma_diff * col; -	 -	color.rgb = atmosLighting(color.rgb); +	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); -	color.rgb = pow(color.rgb, vec3(2.2)); -	col = vec4(0,0,0,0); +	vec4 light = vec4(0,0,0,0); -	 -   #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); +	color.rgb = srgb_to_linear(color.rgb); +   #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)  	LIGHT_LOOP(3) @@ -257,9 +609,19 @@ void main()  	LIGHT_LOOP(6)  	LIGHT_LOOP(7) -	color.rgb += diff.rgb * pow(vary_pointlight_col, vec3(2.2)) * col.rgb; +	// keep it linear +	// +	color.rgb += light.rgb; -	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;  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl index 9d3ba564cd..60d414f2ff 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl @@ -55,67 +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;  #ifdef USE_VERTEX_COLOR  VARYING vec4 vertex_color;  #endif  VARYING vec2 vary_texcoord0; -  VARYING vec3 vary_norm;  uniform float near_clip; -uniform vec4 light_position[8]; -uniform vec3 light_direction[8]; -uniform vec3 light_attenuation[8];  -uniform vec3 light_diffuse[8]; - -uniform vec3 sun_dir; - -vec3 calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight) -{ -	//get light vector -	vec3 lv = lp.xyz-v; -	 -	//get distance -	float d = dot(lv,lv); -	 -	float da = 0.0; - -	if (d > 0.0 && la > 0.0 && fa > 0.0) -	{ -		//normalize light vector -		lv = normalize(lv); -	 -		//distance attenuation -		float dist2 = d/la; -		da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); - -		// spotlight coefficient. -		float spot = max(dot(-ln, lv), is_pointlight); -		da *= spot*spot; // GL_SPOT_EXPONENT=2 - -		//angular attenuation -		da *= max(dot(n, lv), 0.0);		 -	} - -	return vec3(da,da,da);	 -} -  void main()  {  	vec4 pos; @@ -168,43 +119,10 @@ 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; - -	 -	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  	vary_fragcoord.xyz = frag_pos.xyz + vec3(0,0,near_clip);  #else @@ -219,4 +137,3 @@ void main()  #endif  } - diff --git a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl index 968a5f6b3d..a4f54dff70 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl @@ -59,22 +59,6 @@ vec4 getPosition(vec2 pos_screen)  	return pos;  } -#ifdef SINGLE_FP_ONLY -vec2 encode_normal(vec3 n) -{ -	vec2 sn; -	sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); -	return sn; -} - -vec3 decode_normal (vec2 enc) -{ -	vec3 n; -	n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); -	n.z = sqrt(1.0f - dot(n.xy,n.xy)); -	return n; -} -#else  vec2 encode_normal(vec3 n)  {  	float f = sqrt(8 * n.z + 8); @@ -91,7 +75,6 @@ vec3 decode_normal (vec2 enc)      n.z = 1-f/2;      return n;  } -#endif  void main()   { diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl index 59d109b886..8525e13333 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl @@ -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); diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl index dc1dead656..f22b16965c 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl @@ -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)); -	 -	color.rgb = fullbrightAtmosTransport(color.rgb); +	float final_alpha = color.a * vertex_color.a; -	color.rgb = fullbrightScaleSoftClip(color.rgb); +#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 = linear_to_srgb(color.rgb); -	color.rgb = pow(color.rgb, vec3(1.0/2.2)); +#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 -	frag_color = color; +	frag_color.rgb = color.rgb; +	frag_color.a   = color.a;  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl index 3f09a15375..8e899e3e0f 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl @@ -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); diff --git a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl index bc0719cb82..f8fdde43f9 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl @@ -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);  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl index 618ea747f5..8202b4978f 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl @@ -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); @@ -142,7 +226,7 @@ vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 npos, vec3 diffuse, vec4 spe  		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 *= 1.4; +		dist_atten *= 2.0;  		// spotlight coefficient.  		float spot = max(dot(-ln, lv), is_pointlight); @@ -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; @@ -428,22 +515,6 @@ VARYING vec3 vary_normal;  VARYING vec4 vertex_color;  VARYING vec2 vary_texcoord0; -#ifdef SINGLE_FP_ONLY -vec2 encode_normal(vec3 n) -{ -	vec2 sn; -	sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); -	return sn; -} - -vec3 decode_normal (vec2 enc) -{ -	vec3 n; -	n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); -	n.z = sqrt(1.0f - dot(n.xy,n.xy)); -	return n; -} -#else  vec2 encode_normal(vec3 n)  {  	float f = sqrt(8 * n.z + 8); @@ -460,7 +531,6 @@ vec3 decode_normal (vec2 enc)      n.z = 1-f/2;      return n;  } -#endif  void main()   { @@ -475,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 @@ -502,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) @@ -597,7 +670,7 @@ void main()  	vec4 diffuse = final_color;  	float envIntensity = final_normal.z; -    vec3 col = vec3(0.0f,0.0f,0.0f); +	vec3 col = vec3(0.0f,0.0f,0.0f);  	float bloom = 0.0;  	calcAtmospherics(pos.xyz, 1.0); @@ -605,23 +678,27 @@ 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; @@ -643,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)  	{ @@ -661,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); -	//convert to linear space before adding local lights -	col = pow(col, vec3(2.2)); +	col = atmosLighting(col); +	col = scaleSoftClip(col); +	//convert to linear space before adding local lights +	col = srgb_to_linear(col);  	vec3 npos = normalize(-pos.xyz); - #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); +	vec3 light = vec3(0,0,0); + + #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) @@ -680,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; @@ -694,3 +785,4 @@ void main()  	frag_data[2] = final_normal; // XY = Normal.  Z = Env. intensity.  #endif  } + diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl index b25032866b..393d1e69da 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl @@ -142,3 +142,4 @@ vary_normal  = n;  #endif  #endif  } + diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl index 868526d457..3ba6de8b76 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl @@ -45,9 +45,8 @@ uniform float sun_wash;  uniform int light_count; -#define MAX_LIGHT_COUNT		16 -uniform vec4 light[MAX_LIGHT_COUNT]; -uniform vec4 light_col[MAX_LIGHT_COUNT]; +uniform vec4 light[LIGHT_COUNT]; +uniform vec4 light_col[LIGHT_COUNT];  VARYING vec4 vary_fragcoord;  uniform vec2 screen_res; @@ -56,22 +55,6 @@ uniform float far_z;  uniform mat4 inv_proj; -#ifdef SINGLE_FP_ONLY -vec2 encode_normal(vec3 n) -{ -	vec2 sn; -	sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); -	return sn; -} - -vec3 decode_normal (vec2 enc) -{ -	vec3 n; -	n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); -	n.z = sqrt(1.0f - dot(n.xy,n.xy)); -	return n; -} -#else  vec2 encode_normal(vec3 n)  {  	float f = sqrt(8 * n.z + 8); @@ -88,7 +71,6 @@ vec3 decode_normal (vec2 enc)      n.z = 1-f/2;      return n;  } -#endif  vec4 getPosition(vec2 pos_screen)  { @@ -117,78 +99,66 @@ 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);  	// As of OSX 10.6.7 ATI Apple's crash when using a variable size loop -	for (int i = 0; i < MAX_LIGHT_COUNT; ++i) +	for (int i = 0; i < LIGHT_COUNT; ++i)  	{ -		bool light_contrib = (i < light_count); -		  		vec3 lv = light[i].xyz-pos;  		float dist = length(lv);  		dist /= light[i].w; -		if (dist > 1.0) +		if (dist <= 1.0)  		{ -			light_contrib = false; -		} -		 -		float da = dot(norm, lv); -		if (da < 0.0) -		{ -			light_contrib = false; -		} -		 -		if (light_contrib) -		{ -			lv = normalize(lv); -			da = dot(norm, lv); +			float da = dot(norm, lv); +			if (da > 0.0) +			{ +				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; -			dist_atten *= noise; +				dist_atten *= noise; -			float lit = da * dist_atten; +				float lit = da * dist_atten; -			vec3 col = light_col[i].rgb*lit*diff; +				vec3 col = light_col[i].rgb*lit*diff; -			//vec3 col = vec3(dist2, light_col[i].a, lit); +				//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) +				if (spec.a > 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; +					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; +				out_col += col; +			}  		}  	} -	if (dot(out_col, out_col) <= 0.0) -	{ -		discard; -	} -	 +  	frag_color.rgb = out_col;  	frag_color.a = 0.0;  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl index 0443b592e2..0e6ab80d4d 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl @@ -68,22 +68,6 @@ uniform vec2 screen_res;  uniform mat4 inv_proj; -#ifdef SINGLE_FP_ONLY -vec2 encode_normal(vec3 n) -{ -	vec2 sn; -	sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); -	return sn; -} - -vec3 decode_normal (vec2 enc) -{ -	vec3 n; -	n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); -	n.z = sqrt(1.0f - dot(n.xy,n.xy)); -	return n; -} -#else  vec2 encode_normal(vec3 n)  {  	float f = sqrt(8 * n.z + 8); @@ -100,17 +84,48 @@ vec3 decode_normal (vec2 enc)      n.z = 1-f/2;      return n;  } +vec3 srgb_to_linear(vec3 cs) +{ +	vec3 low_range = cs / vec3(12.92); +	vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4)); +	bvec3 lte = lessThanEqual(cs,vec3(0.04045)); + +#ifdef OLD_SELECT +	vec3 result; +	result.r = lte.r ? low_range.r : high_range.r; +	result.g = lte.g ? low_range.g : high_range.g; +	result.b = lte.b ? low_range.b : high_range.b; +    return result; +#else +	return mix(high_range, low_range, lte);  #endif -vec4 correctWithGamma(vec4 col) +} + +vec3 linear_to_srgb(vec3 cl)  { -	return vec4(pow(col.rgb, vec3(2.2)), col.a); +	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); @@ -126,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)); @@ -144,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); @@ -296,14 +311,11 @@ 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.5, 0.25, 1.0); +				float fatten = clamp(envIntensity*envIntensity+envIntensity*0.25, 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 && @@ -311,7 +323,7 @@ void main()  					stc.x > 0.0 &&  					stc.y > 0.0)  				{ -					col += color.rgb*texture2DLodSpecular(projectionMap, stc.xy, proj_lod-envIntensity*proj_lod).rgb*spec.rgb;										 +					col += color.rgb*texture2DLodSpecular(projectionMap, stc.xy, proj_lod).rgb*spec.rgb;										  				}  			}  		} diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl index caf20ce707..106d48bd71 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl @@ -54,22 +54,6 @@ uniform vec2 screen_res;  uniform mat4 inv_proj;  uniform vec4 viewport; -#ifdef SINGLE_FP_ONLY -vec2 encode_normal(vec3 n) -{ -	vec2 sn; -	sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); -	return sn; -} - -vec3 decode_normal (vec2 enc) -{ -	vec3 n; -	n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); -	n.z = sqrt(1.0f - dot(n.xy,n.xy)); -	return n; -} -#else  vec2 encode_normal(vec3 n)  {  	float f = sqrt(8 * n.z + 8); @@ -86,7 +70,6 @@ vec3 decode_normal (vec2 enc)      n.z = 1-f/2;      return n;  } -#endif  vec4 getPosition(vec2 pos_screen)  { diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl index 6f2cfae6d2..4e2f98aa29 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl @@ -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;  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl index 58875ff4ea..760d52a9ce 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl @@ -79,22 +79,43 @@ vec3 vary_AtmosAttenuation;  uniform mat4 inv_proj;  uniform vec2 screen_res; -#ifdef SINGLE_FP_ONLY -vec2 encode_normal(vec3 n) +vec3 srgb_to_linear(vec3 cs)  { -	vec2 sn; -	sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); -	return sn; +	vec3 low_range = cs / vec3(12.92); +	vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4)); +	bvec3 lte = lessThanEqual(cs,vec3(0.04045)); + +#ifdef OLD_SELECT +	vec3 result; +	result.r = lte.r ? low_range.r : high_range.r; +	result.g = lte.g ? low_range.g : high_range.g; +	result.b = lte.b ? low_range.b : high_range.b; +    return result; +#else +	return mix(high_range, low_range, lte); +#endif +  } -vec3 decode_normal (vec2 enc) +vec3 linear_to_srgb(vec3 cl)  { -	vec3 n; -	n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); -	n.z = sqrt(1.0f - dot(n.xy,n.xy)); -	return n; -} +	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; @@ -105,7 +126,6 @@ vec3 decode_normal (vec2 enc)      n.z = 1-f/2;      return n;  } -#endif  vec4 getPosition_d(vec2 pos_screen, float depth)  { @@ -171,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; @@ -325,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; @@ -347,7 +417,7 @@ void main()  		col.rgb *= ambient; -		col += atmosAffectDirectionalLight(max(min(da, 1.0), 0.0)); +		col += atmosAffectDirectionalLight(final_da);	  		col *= diffuse.rgb; @@ -387,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;  } + diff --git a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl index 28432dac9a..2020e8691b 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl @@ -22,7 +22,7 @@   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ - +   #extension GL_ARB_texture_rectangle : enable  #extension GL_ARB_shader_texture_lod : enable @@ -68,22 +68,6 @@ uniform vec2 screen_res;  uniform mat4 inv_proj; -#ifdef SINGLE_FP_ONLY -vec2 encode_normal(vec3 n) -{ -	vec2 sn; -	sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); -	return sn; -} - -vec3 decode_normal (vec2 enc) -{ -	vec3 n; -	n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); -	n.z = sqrt(1.0f - dot(n.xy,n.xy)); -	return n; -} -#else  vec2 encode_normal(vec3 n)  {  	float f = sqrt(8 * n.z + 8); @@ -100,11 +84,47 @@ vec3 decode_normal (vec2 enc)      n.z = 1-f/2;      return n;  } + +vec3 srgb_to_linear(vec3 cs) +{ +	vec3 low_range = cs / vec3(12.92); +	vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4)); +	bvec3 lte = lessThanEqual(cs,vec3(0.04045)); + +#ifdef OLD_SELECT +	vec3 result; +	result.r = lte.r ? low_range.r : high_range.r; +	result.g = lte.g ? low_range.g : high_range.g; +	result.b = lte.b ? low_range.b : high_range.b; +    return result; +#else +	return mix(high_range, low_range, lte); +#endif + +} + +vec3 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) diff --git a/indra/newview/app_settings/shaders/class1/deferred/srgb.glsl b/indra/newview/app_settings/shaders/class1/deferred/srgb.glsl new file mode 100644 index 0000000000..587f3d5a94 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/srgb.glsl @@ -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); + +} + diff --git a/indra/newview/app_settings/shaders/class1/deferred/srgb_mac.glsl b/indra/newview/app_settings/shaders/class1/deferred/srgb_mac.glsl new file mode 100644 index 0000000000..6cc1e6e798 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/srgb_mac.glsl @@ -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; +} + diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl index 6653f57ee1..c0a5865bef 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl @@ -49,22 +49,6 @@ VARYING vec2 vary_fragcoord;  uniform mat4 inv_proj;  uniform vec2 screen_res; -#ifdef SINGLE_FP_ONLY -vec2 encode_normal(vec3 n) -{ -	vec2 sn; -	sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); -	return sn; -} - -vec3 decode_normal (vec2 enc) -{ -	vec3 n; -	n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); -	n.z = sqrt(1.0f - dot(n.xy,n.xy)); -	return n; -} -#else  vec2 encode_normal(vec3 n)  {  	float f = sqrt(8 * n.z + 8); @@ -81,7 +65,6 @@ vec3 decode_normal (vec2 enc)      n.z = 1-f/2;      return n;  } -#endif  vec4 getPosition(vec2 pos_screen)  { diff --git a/indra/newview/app_settings/shaders/class1/deferred/underWaterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/underWaterF.glsl new file mode 100644 index 0000000000..78f841c733 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/underWaterF.glsl @@ -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 +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl index daa2fb390a..72c46e240d 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl @@ -67,6 +67,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); @@ -121,7 +158,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; @@ -131,13 +168,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); @@ -148,24 +186,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 = (norm_mat*vec4(wavef, 1.0)).xyz; +	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  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl index ece34dcc4e..9734acf005 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl @@ -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; diff --git a/indra/newview/app_settings/shaders/class1/interface/downsampleDepthF.glsl b/indra/newview/app_settings/shaders/class1/interface/downsampleDepthF.glsl index 6523a06d22..f8efd7cb4a 100644 --- a/indra/newview/app_settings/shaders/class1/interface/downsampleDepthF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/downsampleDepthF.glsl @@ -31,8 +31,6 @@ out vec4 frag_color;  uniform sampler2D depthMap; -uniform float delta; -  VARYING vec2 tc0;  VARYING vec2 tc1;  VARYING vec2 tc2; diff --git a/indra/newview/app_settings/shaders/class1/interface/downsampleDepthRectF.glsl b/indra/newview/app_settings/shaders/class1/interface/downsampleDepthRectF.glsl index 0e5dc08183..942c5888e7 100644 --- a/indra/newview/app_settings/shaders/class1/interface/downsampleDepthRectF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/downsampleDepthRectF.glsl @@ -33,8 +33,6 @@ out vec4 frag_color;  uniform sampler2DRect depthMap; -uniform float delta; -  VARYING vec2 tc0;  VARYING vec2 tc1;  VARYING vec2 tc2; diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl index eaaa7b208d..cad5b9ff04 100755 --- a/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl @@ -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); diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl deleted file mode 100755 index 13c6ffc607..0000000000 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl +++ /dev/null @@ -1,224 +0,0 @@ -/**  - * @file alphaV.glsl - * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2007, Linden Research, Inc. - *  - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - *  - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU - * Lesser General Public License for more details. - *  - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA - * $/LicenseInfo$ - */ - -uniform mat3 normal_matrix; -uniform mat4 texture_matrix0; -uniform mat4 projection_matrix; -uniform mat4 modelview_matrix; -uniform mat4 modelview_projection_matrix; - -ATTRIBUTE vec3 position; - -#ifdef USE_INDEXED_TEX -void passTextureIndex(); -#endif - -ATTRIBUTE vec3 normal; - -#ifdef USE_VERTEX_COLOR -ATTRIBUTE vec4 diffuse_color; -#endif - -ATTRIBUTE vec2 texcoord0; - -#ifdef HAS_SKIN -mat4 getObjectSkinnedTransform(); -#else -#ifdef IS_AVATAR_SKIN -mat4 getSkinnedTransform(); -#endif -#endif - -vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); -void calcAtmospherics(vec3 inPositionEye); - -vec3 calcDirectionalLight(vec3 n, vec3 l); - -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; - -#ifdef USE_VERTEX_COLOR -VARYING vec4 vertex_color; -#endif - -VARYING vec2 vary_texcoord0; -VARYING vec3 vary_norm; - -uniform float near_clip; -uniform float shadow_offset; -uniform float shadow_bias; - -uniform vec4 light_position[8]; -uniform vec3 light_direction[8]; -uniform vec3 light_attenuation[8];  -uniform vec3 light_diffuse[8]; - -uniform vec3 sun_dir; - -vec3 calcDirectionalLight(vec3 n, vec3 l) -{ -        float a = max(dot(n,l),0.0); -        return vec3(a,a,a); -} - -vec3 calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight) -{ -	//get light vector -	vec3 lv = lp.xyz-v; -	 -	//get distance -	float d = dot(lv,lv); -	 -	float da = 0.0; - -	if (d > 0.0 && la > 0.0 && fa > 0.0) -	{ -		//normalize light vector -		lv = normalize(lv); -	 -		//distance attenuation -		float dist2 = d/la; -		da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); - -		// spotlight coefficient. -		float spot = max(dot(-ln, lv), is_pointlight); -		da *= spot*spot; // GL_SPOT_EXPONENT=2 - -		//angular attenuation -		da *= max(dot(n, lv), 0.0);		 -	} - -	return vec3(da,da,da);	 -} - -void main() -{ -	vec4 pos; -	vec3 norm; -	 -	//transform vertex -#ifdef HAS_SKIN -	mat4 trans = getObjectSkinnedTransform(); -	trans = modelview_matrix * trans; -	 -	pos = trans * vec4(position.xyz, 1.0); -	 -	norm = position.xyz + normal.xyz; -	norm = normalize((trans * vec4(norm, 1.0)).xyz - pos.xyz); -	vec4 frag_pos = projection_matrix * pos; -	gl_Position = frag_pos; -#else - -#ifdef IS_AVATAR_SKIN -	mat4 trans = getSkinnedTransform(); -	vec4 pos_in = vec4(position.xyz, 1.0); -	pos.x = dot(trans[0], pos_in); -	pos.y = dot(trans[1], pos_in); -	pos.z = dot(trans[2], pos_in); -	pos.w = 1.0; -	 -	norm.x = dot(trans[0].xyz, normal); -	norm.y = dot(trans[1].xyz, normal); -	norm.z = dot(trans[2].xyz, normal); -	norm = normalize(norm); -	 -	vec4 frag_pos = projection_matrix * pos; -	gl_Position = frag_pos; -#else -	norm = normalize(normal_matrix * normal); -	vec4 vert = vec4(position.xyz, 1.0); -	pos = (modelview_matrix * vert); -	gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0); -#endif -	 -#endif - -#ifdef USE_INDEXED_TEX -	passTextureIndex(); -	vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; -#else -	vary_texcoord0 = texcoord0; -#endif -	 -	vary_norm = norm; -	float dp_directional_light = max(0.0, dot(norm, light_position[0].xyz)); -	vary_position = pos.xyz + light_position[0].xyz * (1.0-dp_directional_light)*shadow_offset; -	 -	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 dff = pow(diffuse_color.rgb, vec3(2.2f,2.2f,2.2f)); - -	vary_pointlight_col = dff; - -	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_directional.rgb = atmosAffectDirectionalLight(1.0f); -	vary_ambient = col.rgb*dff; -	 -	col.rgb = col.rgb*dff; -	 -#ifdef USE_VERTEX_COLOR -	vertex_color = col; -#endif -	 -#ifdef HAS_SKIN -	vary_fragcoord.xyz = frag_pos.xyz + vec3(0,0,near_clip); -#else - -#ifdef IS_AVATAR_SKIN -	vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip); -#else -	pos = modelview_projection_matrix * vert; -	vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip); -#endif - -#endif - -} diff --git a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl index 37179c7e14..c20e00163c 100755 --- a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl @@ -69,22 +69,43 @@ uniform vec2 screen_res;  uniform mat4 inv_proj; -#ifdef SINGLE_FP_ONLY -vec2 encode_normal(vec3 n) +vec3 srgb_to_linear(vec3 cs)  { -	vec2 sn; -	sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); -	return sn; +	vec3 low_range = cs / vec3(12.92); +	vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4)); +	bvec3 lte = lessThanEqual(cs,vec3(0.04045)); + +#ifdef OLD_SELECT +	vec3 result; +	result.r = lte.r ? low_range.r : high_range.r; +	result.g = lte.g ? low_range.g : high_range.g; +	result.b = lte.b ? low_range.b : high_range.b; +    return result; +#else +	return mix(high_range, low_range, lte); +#endif +  } -vec3 decode_normal (vec2 enc) +vec3 linear_to_srgb(vec3 cl)  { -	vec3 n; -	n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); -	n.z = sqrt(1.0f - dot(n.xy,n.xy)); -	return n; -} +	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); @@ -101,14 +122,12 @@ vec3 decode_normal (vec2 enc)      n.z = 1-f/2;      return n;  } -#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)  {  	vec4 ret = texture2DLod(projectionMap, tc, lod); @@ -315,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 && @@ -330,12 +347,16 @@ 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;										  				}  			}  		}  	} + +	//not sure why, but this line prevents MATBUG-194 +	col = max(col, vec3(0.0)); +  	frag_color.rgb = col;	  	frag_color.a = 0.0;  } diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl index 67bac1f7c2..cc34285d65 100755 --- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl @@ -78,22 +78,43 @@ vec3 vary_AtmosAttenuation;  uniform mat4 inv_proj;  uniform vec2 screen_res; -#ifdef SINGLE_FP_ONLY -vec2 encode_normal(vec3 n) +vec3 srgb_to_linear(vec3 cs)  { -	vec2 sn; -	sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); -	return sn; +	vec3 low_range = cs / vec3(12.92); +	vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4)); +	bvec3 lte = lessThanEqual(cs,vec3(0.04045)); + +#ifdef OLD_SELECT +	vec3 result; +	result.r = lte.r ? low_range.r : high_range.r; +	result.g = lte.g ? low_range.g : high_range.g; +	result.b = lte.b ? low_range.b : high_range.b; +    return result; +#else +	return mix(high_range, low_range, lte); +#endif +  } -vec3 decode_normal (vec2 enc) +vec3 linear_to_srgb(vec3 cl)  { -	vec3 n; -	n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); -	n.z = sqrt(1.0f - dot(n.xy,n.xy)); -	return n; -} +	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); @@ -110,7 +131,6 @@ vec3 decode_normal (vec2 enc)      n.z = 1-f/2;      return n;  } -#endif  vec4 getPosition_d(vec2 pos_screen, float depth)  { @@ -263,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; @@ -343,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; @@ -402,19 +468,25 @@ void main()  				envIntensity);    		} -						 +	  		if (norm.w < 0.5)  		{  			col = mix(atmosLighting(col), fullbrightAtmosTransport(col), diffuse.a);  			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.a = bloom;  } diff --git a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl index 9bdee15541..7689b72d20 100755 --- a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl @@ -69,22 +69,6 @@ uniform vec2 screen_res;  uniform mat4 inv_proj; -#ifdef SINGLE_FP_ONLY -vec2 encode_normal(vec3 n) -{ -	vec2 sn; -	sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); -	return sn; -} - -vec3 decode_normal (vec2 enc) -{ -	vec3 n; -	n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); -	n.z = sqrt(1.0f - dot(n.xy,n.xy)); -	return n; -} -#else  vec2 encode_normal(vec3 n)  {  	float f = sqrt(8 * n.z + 8); @@ -101,11 +85,47 @@ vec3 decode_normal (vec2 enc)      n.z = 1-f/2;      return n;  } + +vec3 srgb_to_linear(vec3 cs) +{ +	vec3 low_range = cs / vec3(12.92); +	vec3 high_range = pow((cs+vec3(0.055))/vec3(1.055), vec3(2.4)); +	bvec3 lte = lessThanEqual(cs,vec3(0.04045)); + +#ifdef OLD_SELECT +	vec3 result; +	result.r = lte.r ? low_range.r : high_range.r; +	result.g = lte.g ? low_range.g : high_range.g; +	result.b = lte.b ? low_range.b : high_range.b; +    return result; +#else +	return mix(high_range, low_range, lte); +#endif + +} + +vec3 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) @@ -334,6 +354,9 @@ void main()  		}  	} +	//not sure why, but this line prevents MATBUG-194 +	col = max(col, vec3(0.0)); +  	frag_color.rgb = col;	  	frag_color.a = 0.0;  } diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl index 7b09dd29dd..95c09d3238 100755 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl @@ -65,22 +65,6 @@ uniform float shadow_offset;  uniform float spot_shadow_bias;  uniform float spot_shadow_offset; -#ifdef SINGLE_FP_ONLY -vec2 encode_normal(vec3 n) -{ -	vec2 sn; -	sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); -	return sn; -} - -vec3 decode_normal (vec2 enc) -{ -	vec3 n; -	n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); -	n.z = sqrt(1.0f - dot(n.xy,n.xy)); -	return n; -} -#else  vec2 encode_normal(vec3 n)  {  	float f = sqrt(8 * n.z + 8); @@ -97,7 +81,6 @@ vec3 decode_normal (vec2 enc)      n.z = 1-f/2;      return n;  } -#endif  vec4 getPosition(vec2 pos_screen)  { diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl index 01e34ed792..b5ff6404ea 100755 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl @@ -66,22 +66,6 @@ uniform float shadow_offset;  uniform float spot_shadow_bias;  uniform float spot_shadow_offset; -#ifdef SINGLE_FP_ONLY -vec2 encode_normal(vec3 n) -{ -	vec2 sn; -	sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f); -	return sn; -} - -vec3 decode_normal (vec2 enc) -{ -	vec3 n; -	n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f); -	n.z = sqrt(1.0f - dot(n.xy,n.xy)); -	return n; -} -#else  vec2 encode_normal(vec3 n)  {  	float f = sqrt(8 * n.z + 8); @@ -98,7 +82,6 @@ vec3 decode_normal (vec2 enc)      n.z = 1-f/2;      return n;  } -#endif  vec4 getPosition(vec2 pos_screen)  { diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index 1c0d45c11b..0bdd425504 100755 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -309,8 +309,8 @@ RenderVolumeLODFactor		1	2.0  VertexShaderEnable			1	1  WindLightUseAtmosShaders	1	1  WLSkyDetail					1	128 -RenderDeferred				1	0 -RenderDeferredSSAO			1	0 +RenderDeferred				1	1 +RenderDeferredSSAO			1	1  RenderShadowDetail			1	2  RenderFSAASamples			1	2 diff --git a/indra/newview/gpu_table.txt b/indra/newview/gpu_table.txt index 291d89d77a..0513c60ba8 100755 --- a/indra/newview/gpu_table.txt +++ b/indra/newview/gpu_table.txt @@ -316,13 +316,13 @@ Intel Brookdale							.*Intel.*Brookdale.*								0	0	1	1.3  Intel Cantiga							.*Intel.*Cantiga.*									0	0	1	2  Intel Eaglelake							.*Intel.*Eaglelake.*								1	1	1	2  Intel Graphics Media HD					.*Intel.*Graphics Media.*HD.*						1	1	1	2.1 -Intel HD Graphics 2500					.*Intel.*HD Graphics 25.*							2	1	0	4 -Intel HD Graphics 2000					.*Intel.*HD Graphics 2.*							2	1	0	3.1 -Intel HD Graphics 3000					.*Intel.*HD Graphics 3.*							3	1	1	3.1 -Intel HD Graphics 4200					.*Intel.*HD Graphics 42.*							3	1	0	4 -Intel HD Graphics 4400					.*Intel.*HD Graphics 44.*							3	1	0	4 -Intel HD Graphics 4600					.*Intel.*HD Graphics 46.*							3	1	0	4 -Intel HD Graphics 4000					.*Intel.*HD Graphics 4.*							3	1	1	4 +Intel HD Graphics 2500					.*Intel.*HD Graphics 25.*							2	1	0	4.2 +Intel HD Graphics 2000					.*Intel.*HD Graphics 2.*							2	1	0	4.2 +Intel HD Graphics 3000					.*Intel.*HD Graphics 3.*							3	1	1	4.2 +Intel HD Graphics 4200					.*Intel.*HD Graphics 42.*							3	1	0	4.2 +Intel HD Graphics 4400					.*Intel.*HD Graphics 44.*							3	1	0	4.2 +Intel HD Graphics 4600					.*Intel.*HD Graphics 46.*							3	1	0	4.2 +Intel HD Graphics 4000					.*Intel.*HD Graphics 4.*							3	1	1	4.2  Intel Intel Iris Pro Graphics 5200		.*Intel.*Iris Pro Graphics 52.*						4	1	0	4  Intel Intel Iris Graphics 5100			.*Intel.*Iris Graphics 51.*							4	1	0	4  Intel HD Graphics 5000					.*Intel.*HD Graphics 5.*							4	1	0	4 @@ -656,3 +656,4 @@ Humper									Humper.*											0	1	1	2.1  PowerVR SGX545							.*PowerVR SGX.*										1	1	1	3  ATI GeForce Lulz						.*ATI.*GeForce.*									0	0	0	0 + diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 8c9fd4152a..9682f38227 100755 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -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(); @@ -527,6 +533,8 @@ void LLDrawable::makeStatic(BOOL warning_enabled)  		}  		updatePartition();  	} + +	llassert(isAvatar() || isRoot() || mParent->isStatic());  }  // Returns "distance" between target destination and resulting xfrom diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index c832e1401d..e4ebfea665 100755 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -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; @@ -348,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;  				} @@ -396,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); @@ -500,7 +570,8 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)  					}  				} -				params.mVertexBuffer->setBuffer(mask); +				params.mVertexBuffer->setBuffer(mask & ~(params.mFullbright ? (LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2) : 0)); +                  				params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);  				gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode); @@ -515,7 +586,6 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)  					emissive_shader->bind(); -					// glow doesn't use vertex colors from the mesh data  					params.mVertexBuffer->setBuffer((mask & ~LLVertexBuffer::MAP_COLOR) | LLVertexBuffer::MAP_EMISSIVE);  					// do the actual drawing, again @@ -545,3 +615,4 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)  		gPipeline.enableLightsDynamic();  	}  } + diff --git a/indra/newview/lldrawpoolalpha.h b/indra/newview/lldrawpoolalpha.h index 43122218ed..d064a3a324 100755 --- a/indra/newview/lldrawpoolalpha.h +++ b/indra/newview/lldrawpoolalpha.h @@ -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; diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index a0024a231c..66bbc6819b 100755 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -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; @@ -309,6 +310,11 @@ void LLDrawPoolAvatar::beginDeferredRiggedMaterialAlpha(S32 pass)  	sVertexProgram = &gDeferredMaterialProgram[pass]; +	if (LLPipeline::sUnderWaterRender) +	{ +		sVertexProgram = &(gDeferredMaterialWaterProgram[pass]); +	} +  	gPipeline.bindDeferredShader(*sVertexProgram);  	sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);  	normal_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::BUMP_MAP); @@ -501,7 +507,7 @@ S32 LLDrawPoolAvatar::getNumDeferredPasses()  {  	if (LLPipeline::sImpostorRender)  	{ -		return 3; +		return 19;  	}  	else  	{ @@ -687,12 +693,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);  } @@ -702,8 +706,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() @@ -891,6 +896,8 @@ void LLDrawPoolAvatar::beginRiggedGlow()  		sVertexProgram->bind();  		sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, LLPipeline::sRenderDeferred ? 2.2f : 1.1f); +		F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma"); +		sVertexProgram->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));  	}  } @@ -943,6 +950,9 @@ void LLDrawPoolAvatar::beginRiggedFullbright()  		else   		{  			sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f); + +			F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma"); +			sVertexProgram->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));  		}  	}  } @@ -1044,6 +1054,8 @@ void LLDrawPoolAvatar::beginRiggedFullbrightShiny()  		else   		{  			sVertexProgram->uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f); +			F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma"); +			sVertexProgram->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));  		}  	}  } @@ -1103,6 +1115,12 @@ void LLDrawPoolAvatar::beginDeferredRiggedMaterial(S32 pass)  		return;  	}  	sVertexProgram = &gDeferredMaterialProgram[pass+LLMaterial::SHADER_COUNT]; + +	if (LLPipeline::sUnderWaterRender) +	{ +		sVertexProgram = &(gDeferredMaterialWaterProgram[pass+LLMaterial::SHADER_COUNT]); +	} +  	sVertexProgram->bind();  	normal_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::BUMP_MAP);  	specular_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::SPECULAR_MAP); @@ -1445,63 +1463,63 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)  }  void LLDrawPoolAvatar::getRiggedGeometry(LLFace* face, LLPointer<LLVertexBuffer>& buffer, U32 data_mask, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face) -{ -	face->setGeomIndex(0); -	face->setIndicesIndex(0); +	{ +		face->setGeomIndex(0); +		face->setIndicesIndex(0); -	//rigged faces do not batch textures -	face->setTextureIndex(255); +		//rigged faces do not batch textures +		face->setTextureIndex(255); -	if (buffer.isNull() || buffer->getTypeMask() != data_mask || !buffer->isWriteable()) -	{ //make a new buffer -		if (sShaderLevel > 0) -		{ -			buffer = new LLVertexBuffer(data_mask, GL_DYNAMIC_DRAW_ARB); +		if (buffer.isNull() || buffer->getTypeMask() != data_mask || !buffer->isWriteable()) +		{ //make a new buffer +			if (sShaderLevel > 0) +			{ +				buffer = new LLVertexBuffer(data_mask, GL_DYNAMIC_DRAW_ARB); +			} +			else +			{ +				buffer = new LLVertexBuffer(data_mask, GL_STREAM_DRAW_ARB); +			} +			buffer->allocateBuffer(vol_face.mNumVertices, vol_face.mNumIndices, true);  		}  		else -		{ -			buffer = new LLVertexBuffer(data_mask, GL_STREAM_DRAW_ARB); +		{ //resize existing buffer +			buffer->resizeBuffer(vol_face.mNumVertices, vol_face.mNumIndices);  		} -		buffer->allocateBuffer(vol_face.mNumVertices, vol_face.mNumIndices, true); -	} -	else -	{ //resize existing buffer -		buffer->resizeBuffer(vol_face.mNumVertices, vol_face.mNumIndices); -	} -	face->setSize(vol_face.mNumVertices, vol_face.mNumIndices); -	face->setVertexBuffer(buffer); +		face->setSize(vol_face.mNumVertices, vol_face.mNumIndices); +		face->setVertexBuffer(buffer); -	U16 offset = 0; +		U16 offset = 0; -	LLMatrix4 mat_vert = skin->mBindShapeMatrix; -	glh::matrix4f m((F32*) mat_vert.mMatrix); -	m = m.inverse().transpose(); +		LLMatrix4 mat_vert = skin->mBindShapeMatrix; +		glh::matrix4f m((F32*) mat_vert.mMatrix); +		m = m.inverse().transpose(); -	F32 mat3[] =  -	{ m.m[0], m.m[1], m.m[2], -		m.m[4], m.m[5], m.m[6], -		m.m[8], m.m[9], m.m[10] }; +		F32 mat3[] =  +		{ m.m[0], m.m[1], m.m[2], +		  m.m[4], m.m[5], m.m[6], +		  m.m[8], m.m[9], m.m[10] }; -	LLMatrix3 mat_normal(mat3);				 +		LLMatrix3 mat_normal(mat3);				 -	//let getGeometryVolume know if alpha should override shiny -	U32 type = gPipeline.getPoolTypeFromTE(face->getTextureEntry(), face->getTexture()); +		//let getGeometryVolume know if alpha should override shiny +		U32 type = gPipeline.getPoolTypeFromTE(face->getTextureEntry(), face->getTexture()); -	if (type == LLDrawPool::POOL_ALPHA) -	{ -		face->setPoolType(LLDrawPool::POOL_ALPHA); -	} -	else -	{ -		face->setPoolType(LLDrawPool::POOL_AVATAR); -	} +		if (type == LLDrawPool::POOL_ALPHA) +		{ +			face->setPoolType(LLDrawPool::POOL_ALPHA); +		} +		else +		{ +			face->setPoolType(LLDrawPool::POOL_AVATAR); +		}  	//llinfos << "Rebuilt face " << face->getTEOffset() << " of " << face->getDrawable() << " at " << gFrameTimeSeconds << llendl; -	face->getGeometryVolume(*volume, face->getTEOffset(), mat_vert, mat_normal, offset, true); +		face->getGeometryVolume(*volume, face->getTEOffset(), mat_vert, mat_normal, offset, true); -	buffer->flush(); -} +		buffer->flush(); +	}  void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* face, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face)  { diff --git a/indra/newview/lldrawpoolmaterials.cpp b/indra/newview/lldrawpoolmaterials.cpp index 08a36bddf1..d1b5080650 100644 --- a/indra/newview/lldrawpoolmaterials.cpp +++ b/indra/newview/lldrawpoolmaterials.cpp @@ -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);  	}  } + diff --git a/indra/newview/lldrawpoolsimple.cpp b/indra/newview/lldrawpoolsimple.cpp index 2cf9d833c6..8926f64c64 100755 --- a/indra/newview/lldrawpoolsimple.cpp +++ b/indra/newview/lldrawpoolsimple.cpp @@ -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);  } diff --git a/indra/newview/lldrawpoolsky.cpp b/indra/newview/lldrawpoolsky.cpp index 7f7d9f65c6..ef8bdc3304 100755 --- a/indra/newview/lldrawpoolsky.cpp +++ b/indra/newview/lldrawpoolsky.cpp @@ -155,3 +155,4 @@ void LLDrawPoolSky::renderSkyCubeFace(U8 side)  void LLDrawPoolSky::endRenderPass( S32 pass )  {  } + diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp index 5ddc15df42..6774926f62 100755 --- a/indra/newview/lldrawpoolwater.cpp +++ b/indra/newview/lldrawpoolwater.cpp @@ -522,13 +522,20 @@ void LLDrawPoolWater::shade()  	F32 eyedepth = LLViewerCamera::getInstance()->getOrigin().mV[2] - gAgent.getRegion()->getWaterHeight(); -	if (deferred_render) +	if (eyedepth < 0.f && LLPipeline::sWaterReflections)  	{ -		shader = &gDeferredWaterProgram; +		if (deferred_render) +		{ +			shader = &gDeferredUnderWaterProgram; +		} +		else +		{ +			shader = &gUnderWaterProgram; +		}		  	} -	else if (eyedepth < 0.f && LLPipeline::sWaterReflections) +	else if (deferred_render)  	{ -		shader = &gUnderWaterProgram; +		shader = &gDeferredWaterProgram;  	}  	else  	{ diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp index b5faff7968..53339222eb 100755 --- a/indra/newview/lldrawpoolwlsky.cpp +++ b/indra/newview/lldrawpoolwlsky.cpp @@ -420,3 +420,4 @@ void LLDrawPoolWLSky::restoreGL()  		sCloudNoiseTexture = LLViewerTextureManager::getLocalTexture(sCloudNoiseRawImage.get(), TRUE);  	}  } + diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 9b2b778677..53e5b55b89 100755 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -821,21 +821,21 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,  		{  			v[i].setSelectWithMask(mask[i], min, max);  		} - +		  		LLVector4a tv[8]; - +		  		//transform bounding box into drawable space  		for (U32 i = 0; i < 8; ++i)  		{  			mat_vert.affineTransform(v[i], tv[i]);  		} -	 +  		//find bounding box  		LLVector4a& newMin = mExtents[0];  		LLVector4a& newMax = mExtents[1]; - +		  		newMin = newMax = tv[0]; - +		  		for (U32 i = 1; i < 8; ++i)  		{  			newMin.setMin(newMin, tv[i]); @@ -851,11 +851,11 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,  		}  		LLVector4a t; -		t.setAdd(newMin,newMax); +		t.setAdd(newMin, newMax);  		t.mul(0.5f);  		mCenterLocal.set(t.getF32ptr()); - +		  		t.setSub(newMax,newMin);  		mBoundingSphereRadius = t.getLength3().getF32()*0.5f; diff --git a/indra/newview/llface.h b/indra/newview/llface.h index 763634a3ab..66b5f13740 100755 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -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(); diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp index 14923eec3c..7b25291da7 100755 --- a/indra/newview/llfloatertools.cpp +++ b/indra/newview/llfloatertools.cpp @@ -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); diff --git a/indra/newview/llfloatertools.h b/indra/newview/llfloatertools.h index ecb0092a6f..189bae46c2 100755 --- a/indra/newview/llfloatertools.h +++ b/indra/newview/llfloatertools.h @@ -109,6 +109,8 @@ public:  	static void setGridMode(S32 mode); +	LLPanelFace* getPanelFace() { return mPanelFace; } +  private:  	void refresh();  	void refreshMedia(); diff --git a/indra/newview/llmaterialmgr.cpp b/indra/newview/llmaterialmgr.cpp index 16871adc4d..658fea944d 100644 --- a/indra/newview/llmaterialmgr.cpp +++ b/indra/newview/llmaterialmgr.cpp @@ -51,12 +51,9 @@  #define MATERIALS_CAP_OBJECT_ID_FIELD             "ID"  #define MATERIALS_CAP_MATERIAL_ID_FIELD           "MaterialID" -#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 @@ -544,11 +541,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);  	}  } @@ -565,14 +560,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;  		} @@ -595,8 +590,9 @@ void LLMaterialMgr::processGetQueue()  		LLSD materialsData = LLSD::emptyArray();  		material_queue_t& materials = itRegionQueue->second; -		material_queue_t::iterator loopMaterial = materials.begin(); -		while ( (materials.end() != loopMaterial) && (materialsData.size() <= MATERIALS_GET_MAX_ENTRIES) ) +		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++;  			materialsData.append((*itMaterial).asLLSD()); @@ -628,6 +624,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 +643,7 @@ void LLMaterialMgr::processGetAllQueue()  			clearGetQueues(region_id);		// Invalidates region_id  			continue;  		} -		else if (!regionp->capabilitiesReceived()) +		else if (!regionp->capabilitiesReceived() || regionp->materialsCapThrottled())  		{  			continue;  		} @@ -663,6 +660,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 +668,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(); @@ -680,49 +678,54 @@ void LLMaterialMgr::processPutQueue()  		const LLUUID& object_id = itQueue->first;  		const LLViewerObject* objectp = gObjectList.findObject(object_id); -		if ( (!objectp) || (!objectp->getRegion()) ) +		if ( !objectp )  		{ -			LL_WARNS("Materials") << "Object or object region is NULL" << LL_ENDL; - +			LL_WARNS("Materials") << "Object is NULL" << LL_ENDL;  			mPutQueue.erase(itQueue); -			continue;  		} - -		const LLViewerRegion* regionp = objectp->getRegion(); -		if (!regionp->capabilitiesReceived()) -		{ -			continue; -		} - -		LLSD& facesData = requests[regionp]; - -		facematerial_map_t& face_map = itQueue->second; -		facematerial_map_t::iterator itFace = face_map.begin(); -		while ( (face_map.end() != itFace) && (facesData.size() < MATERIALS_GET_MAX_ENTRIES) ) +		else  		{ -			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()) +			LLViewerRegion* regionp = objectp->getRegion(); +			if ( !regionp )  			{ -				faceData[MATERIALS_CAP_MATERIAL_FIELD] = itFace->second.asLLSD(); +				LL_WARNS("Materials") << "Object region is NULL" << LL_ENDL; +				mPutQueue.erase(itQueue); +			} +			else if ( regionp->capabilitiesReceived() && !regionp->materialsCapThrottled()) +			{ +				LLSD& facesData = requests[regionp]; + +				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); +				}  			} -			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;  		} @@ -745,6 +748,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  		{ @@ -773,7 +777,6 @@ void LLMaterialMgr::clearGetQueues(const LLUUID& region_id)  	mGetAllPending.erase(region_id);  	mGetAllCallbacks.erase(region_id);  } -  void LLMaterialMgr::onRegionRemoved(LLViewerRegion* regionp)  {  	clearGetQueues(regionp->getRegionID()); diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 911af9df04..3869219da6 100755 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -66,7 +66,7 @@  #include "llvovolume.h"  #include "lluictrlfactory.h"  #include "llpluginclassmedia.h" -#include "llviewertexturelist.h" +#include "llviewertexturelist.h"// Update sel manager as to which channel we're editing so it can reflect the correct overlay UI  //  // Constant definitions for comboboxes @@ -89,6 +89,19 @@ const S32 SHINY_TEXTURE = 4;		// use supplied specular map  //  std::string USE_TEXTURE; +LLRender::eTexIndex LLPanelFace::getTextureChannelToEdit() +{ +	LLComboBox* combobox_matmedia = getChild<LLComboBox>("combobox matmedia"); +	LLComboBox* combobox_mattype	= getChild<LLComboBox>("combobox mattype"); + +	LLRender::eTexIndex channel_to_edit = (combobox_matmedia && combobox_matmedia->getCurrentIndex() == MATMEDIA_MATERIAL) ? +													  (combobox_mattype ? (LLRender::eTexIndex)combobox_mattype->getCurrentIndex() : LLRender::DIFFUSE_MAP) : LLRender::DIFFUSE_MAP; + +	channel_to_edit = (channel_to_edit == LLRender::NORMAL_MAP)		? (getCurrentNormalMap().isNull()		? LLRender::DIFFUSE_MAP : channel_to_edit) : channel_to_edit; +	channel_to_edit = (channel_to_edit == LLRender::SPECULAR_MAP)	? (getCurrentSpecularMap().isNull()		? LLRender::DIFFUSE_MAP : channel_to_edit) : channel_to_edit; +	return channel_to_edit; +} +  // Things the UI provides...  //  LLUUID	LLPanelFace::getCurrentNormalMap()			{ return getChild<LLTextureCtrl>("bumpytexture control")->getImageAssetID();	} @@ -1194,7 +1207,8 @@ void LLPanelFace::updateUI()  			getChildView("checkbox fullbright")->setEnabled(editable);  			getChild<LLUICtrl>("checkbox fullbright")->setTentative(!identical_fullbright);  		} -		 + +  		// Repeats per meter  		{  			F32 repeats_diff = 1.f; @@ -1218,6 +1232,9 @@ void LLPanelFace::updateUI()  				F32  repeats = 1.0f;  				U32 material_type = (combobox_matmedia->getCurrentIndex() == MATMEDIA_MATERIAL) ? combobox_mattype->getCurrentIndex() : MATTYPE_DIFFUSE; + +				LLSelectMgr::getInstance()->setTextureChannel(LLRender::eTexIndex(material_type)); +  				switch (material_type)  				{  					default: @@ -1328,18 +1345,6 @@ void LLPanelFace::updateUI()  					getChild<LLColorSwatchCtrl>("shinycolorswatch")->set(material->getSpecularLightColor(),TRUE);  				} -				// Update sel manager as to which channel we're editing so it can reflect the correct overlay UI -				// NORSPEC-103 -				LLRender::eTexIndex channel_to_edit = (combobox_matmedia->getCurrentIndex() == MATMEDIA_MATERIAL) ? (LLRender::eTexIndex)combobox_mattype->getCurrentIndex() : LLRender::DIFFUSE_MAP; - -				if ( ((channel_to_edit == LLRender::NORMAL_MAP) && material->getNormalID().isNull()) -					||((channel_to_edit == LLRender::SPECULAR_MAP) && material->getSpecularID().isNull())) -				{ -					channel_to_edit = LLRender::DIFFUSE_MAP; -				} - -				LLSelectMgr::getInstance()->setTextureChannel(channel_to_edit); -  				// Bumpy (normal)  				texture_ctrl = getChild<LLTextureCtrl>("bumpytexture control");  				texture_ctrl->setImageAssetID(material->getNormalID()); @@ -1365,10 +1370,6 @@ void LLPanelFace::updateUI()  					updateBumpyControls(!material->getNormalID().isNull(), true);  				}  			} -			else -			{ -				LLSelectMgr::getInstance()->setTextureChannel(LLRender::DIFFUSE_MAP); -			}  		}  		// Set variable values for numeric expressions diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h index 42c1f6bd48..46b3375f64 100755 --- a/indra/newview/llpanelface.h +++ b/indra/newview/llpanelface.h @@ -100,6 +100,19 @@ public:  	void			setMediaURL(const std::string& url);  	void			setMediaType(const std::string& mime_type); +	LLMaterialPtr createDefaultMaterial(LLMaterialPtr current_material) +	{ +		LLMaterialPtr new_material(!current_material.isNull() ? new LLMaterial(current_material->asLLSD()) : new LLMaterial()); +		llassert_always(new_material); + +		// Preserve old diffuse alpha mode or assert correct default blend mode as appropriate for the alpha channel content of the diffuse texture +		// +		new_material->setDiffuseAlphaMode(current_material.isNull() ? (isAlpha() ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE) : current_material->getDiffuseAlphaMode()); +		return new_material; +	} + +	LLRender::eTexIndex getTextureChannelToEdit(); +  protected:  	void			getState(); @@ -178,6 +191,8 @@ protected:  	static F32     valueGlow(LLViewerObject* object, S32 face); +	 +  private:  	bool		isAlpha() { return mIsAlpha; } @@ -234,17 +249,32 @@ private:  			{  				if (_edit)  				{ -					LLMaterialPtr new_material(!current_material.isNull() ? new LLMaterial(current_material->asLLSD()) : new LLMaterial()); +					LLMaterialPtr new_material = _panel->createDefaultMaterial(current_material);  					llassert_always(new_material);  					// 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(); +					} -					// Default to matching expected state of UI +					// 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(current_material.isNull() ? default_alpha_mode : current_material->getDiffuseAlphaMode()); +					new_material->setDiffuseAlphaMode(default_alpha_mode);  					// Do "It"!  					// @@ -254,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) diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp index 02d363d795..a1d60b5b16 100755 --- a/indra/newview/llpanelvolume.cpp +++ b/indra/newview/llpanelvolume.cpp @@ -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);  	}  } diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 0cbdbe16a3..7b397d46f3 100755 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -91,7 +91,7 @@  #include "llvovolume.h"  #include "pipeline.h"  #include "llviewershadermgr.h" - +#include "llpanelface.h"  #include "llglheaders.h"  LLViewerObject* getSelectedParentObject(LLViewerObject *object) ; @@ -2534,7 +2534,7 @@ void LLSelectMgr::adjustTexturesByScale(BOOL send_to_sim, BOOL stretch)  					if (tep && !tep->getMaterialParams().isNull())  					{  						LLMaterialPtr orig = tep->getMaterialParams(); -						LLMaterialPtr p = new LLMaterial(orig->asLLSD()); +						LLMaterialPtr p = gFloaterTools->getPanelFace()->createDefaultMaterial(orig);  						p->setNormalRepeat(normal_scale_s, normal_scale_t);  						p->setSpecularRepeat(specular_scale_s, specular_scale_t); @@ -2560,8 +2560,8 @@ void LLSelectMgr::adjustTexturesByScale(BOOL send_to_sim, BOOL stretch)  					if (tep && !tep->getMaterialParams().isNull())  					{  						LLMaterialPtr orig = tep->getMaterialParams(); +						LLMaterialPtr p = gFloaterTools->getPanelFace()->createDefaultMaterial(orig); -						LLMaterialPtr p = new LLMaterial(orig->asLLSD());  						p->setNormalRepeat(normal_scale_s, normal_scale_t);  						p->setSpecularRepeat(specular_scale_s, specular_scale_t); diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 4676f7b251..2b1ed5858a 100755 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -133,7 +133,8 @@ public:  	PermissionMask 	getFilterPermMask();  	void updateFilterPermMask();  	void commitIfImmediateSet(); -	 +	void commitCancel(); +  	void onFilterEdit(const std::string& search_string );  	void setCanApply(bool can_preview, bool can_apply); @@ -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();  }  /* diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index e085834326..ef7d0cd81b 100755 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -58,6 +58,7 @@  #include "llviewerwindow.h"  #include "llvoavatarself.h"  #include "llworld.h" +#include "llpanelface.h"  // syntactic sugar  #define callMemberFunction(object,ptrToMember)  ((object).*(ptrToMember)) @@ -1163,7 +1164,51 @@ void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj,  	// update viewer side image in anticipation of update from simulator  	LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(asset_id);  	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT ); -	hit_obj->setTEImage(hit_face, image); + +	LLTextureEntry* tep = hit_obj ? (hit_obj->getTE(hit_face)) : NULL; + +	LLPanelFace* panel_face = gFloaterTools->getPanelFace(); + +	if (gFloaterTools->getVisible() && panel_face) +	{ +		switch (LLSelectMgr::getInstance()->getTextureChannel()) +		{ + +		case 0: +		default: +			{ +				hit_obj->setTEImage(hit_face, image); +			} +			break; + +		case 1: +			{ +				LLMaterialPtr old_mat = tep->getMaterialParams(); +				LLMaterialPtr new_mat = panel_face->createDefaultMaterial(old_mat); +				new_mat->setNormalID(asset_id); +				tep->setMaterialParams(new_mat); +				hit_obj->setTENormalMap(hit_face, asset_id); +				LLMaterialMgr::getInstance()->put(hit_obj->getID(), hit_face, *new_mat); +			} +			break; + +		case 2: +			{ +				LLMaterialPtr old_mat = tep->getMaterialParams(); +				LLMaterialPtr new_mat = panel_face->createDefaultMaterial(old_mat); +				new_mat->setSpecularID(asset_id); +				tep->setMaterialParams(new_mat); +				hit_obj->setTESpecularMap(hit_face, asset_id); +				LLMaterialMgr::getInstance()->put(hit_obj->getID(), hit_face, *new_mat); +			} +			break; +		} +	} +	else +	{ +		hit_obj->setTEImage(hit_face, image); +	} +	  	dialog_refresh_all();  	// send the update to the simulator diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index f90b35a7bd..bbebeea3e0 100755 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -890,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); @@ -939,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());  			} @@ -976,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) @@ -1002,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();  		} @@ -1623,3 +1623,4 @@ void display_cleanup()  {  	gDisconnectedImagep = NULL;  } + diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 6f7b2f40e6..0070240803 100755 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -4410,12 +4410,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);  	}  } @@ -4519,6 +4517,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); diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index ea0d55cda5..16f1f403d3 100755 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -339,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 diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 8422708add..e6fc82f761 100755 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1219,7 +1219,7 @@ void LLViewerRegion::getInfo(LLSD& info)  	info["Region"]["Handle"]["y"] = (LLSD::Integer)y;  } -void LLViewerRegion::getSimulatorFeatures(LLSD& sim_features) +void LLViewerRegion::getSimulatorFeatures(LLSD& sim_features) const  {  	sim_features = mSimulatorFeatures; @@ -1944,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; +} + + diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index 56cd0c9ea1..109baccf9a 100755 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -43,6 +43,7 @@  #include "llcapabilityprovider.h"  #include "m4math.h"					// LLMatrix4  #include "llhttpclient.h" +#include "llframetimer.h"  // Surface id's  #define LAND  1 @@ -293,7 +294,7 @@ public:  	bool meshRezEnabled() const;  	bool meshUploadEnabled() const; -	void getSimulatorFeatures(LLSD& info);	 +	void getSimulatorFeatures(LLSD& info) const;	  	void setSimulatorFeatures(const LLSD& info); @@ -342,7 +343,12 @@ public:  	void getNeighboringRegionsStatus( std::vector<S32>& regions );  	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  	{ @@ -434,6 +440,9 @@ private:  	BOOL mReleaseNotesRequested;  	LLSD mSimulatorFeatures; + +	// the materials capability throttle +	LLFrameTimer mMaterialsCapThrottleTimer;  };  inline BOOL LLViewerRegion::getRegionProtocol(U64 protocol) const diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index e24237522a..995eb599b8 100755 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -42,22 +42,6 @@  #include "llvosky.h"  #include "llrender.h" -#if LL_DARWIN -#include "OpenGL/OpenGL.h" - -// include spec exp clamp to fix older mac rendering artifacts -// -#define SINGLE_FP_PERMUTATION(shader)					\ -	if (gGLManager.mIsMobileGF)							\ -	{																\ -		shader.addPermutation("SINGLE_FP_ONLY","1");		\ -	} - - -#else -#define SINGLE_FP_PERMUTATION(shader) -#endif -  #ifdef LL_RELEASE_FOR_DOWNLOAD  #define UNIFORM_ERRS LL_WARNS_ONCE("Shader")  #else @@ -99,6 +83,7 @@ LLGLSLShader	gAlphaMaskProgram;  //object shaders  LLGLSLShader		gObjectSimpleProgram; +LLGLSLShader		gObjectSimpleImpostorProgram;  LLGLSLShader		gObjectPreviewProgram;  LLGLSLShader		gObjectSimpleWaterProgram;  LLGLSLShader		gObjectSimpleAlphaMaskProgram; @@ -184,6 +169,7 @@ LLGLSLShader			gPostNightVisionProgram;  // Deferred rendering shaders  LLGLSLShader			gDeferredImpostorProgram;  LLGLSLShader			gDeferredWaterProgram; +LLGLSLShader			gDeferredUnderWaterProgram;  LLGLSLShader			gDeferredDiffuseProgram;  LLGLSLShader			gDeferredDiffuseAlphaMaskProgram;  LLGLSLShader			gDeferredNonIndexedDiffuseProgram; @@ -199,20 +185,26 @@ LLGLSLShader			gDeferredTreeShadowProgram;  LLGLSLShader			gDeferredAvatarProgram;  LLGLSLShader			gDeferredAvatarAlphaProgram;  LLGLSLShader			gDeferredLightProgram; -LLGLSLShader			gDeferredMultiLightProgram; +LLGLSLShader			gDeferredMultiLightProgram[16];  LLGLSLShader			gDeferredSpotLightProgram;  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; @@ -230,6 +222,7 @@ LLGLSLShader			gNormalMapGenProgram;  // Deferred materials shaders  LLGLSLShader			gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2]; +LLGLSLShader			gDeferredMaterialWaterProgram[LLMaterial::SHADER_COUNT*2];  LLViewerShaderMgr::LLViewerShaderMgr() :  	mVertexShaderLevel(SHADER_COUNT, 0), @@ -245,6 +238,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); @@ -295,6 +289,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]); @@ -303,15 +298,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); @@ -721,6 +731,7 @@ void LLViewerShaderMgr::unloadShaders()  	gObjectFullbrightNoColorProgram.unload();  	gObjectFullbrightNoColorWaterProgram.unload();  	gObjectSimpleProgram.unload(); +	gObjectSimpleImpostorProgram.unload();  	gObjectPreviewProgram.unload();  	gImpostorProgram.unload();  	gObjectSimpleAlphaMaskProgram.unload(); @@ -1128,12 +1139,16 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredImpostorProgram.unload();  		gDeferredTerrainProgram.unload();  		gDeferredLightProgram.unload(); -		gDeferredMultiLightProgram.unload(); +		for (U32 i = 0; i < LL_DEFERRED_MULTI_LIGHT_COUNT; ++i) +		{ +			gDeferredMultiLightProgram[i].unload(); +		}  		gDeferredSpotLightProgram.unload();  		gDeferredMultiSpotLightProgram.unload();  		gDeferredSunProgram.unload();  		gDeferredBlurLightProgram.unload();  		gDeferredSoftenProgram.unload(); +		gDeferredSoftenWaterProgram.unload();  		gDeferredShadowProgram.unload();  		gDeferredShadowCubeProgram.unload();  		gDeferredShadowAlphaMaskProgram.unload(); @@ -1142,7 +1157,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();		 @@ -1151,6 +1170,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredPostGammaCorrectProgram.unload();  		gFXAAProgram.unload();  		gDeferredWaterProgram.unload(); +		gDeferredUnderWaterProgram.unload();  		gDeferredWLSkyProgram.unload();  		gDeferredWLCloudProgram.unload();  		gDeferredStarProgram.unload(); @@ -1162,6 +1182,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		for (U32 i = 0; i < LLMaterial::SHADER_COUNT*2; ++i)  		{  			gDeferredMaterialProgram[i].unload(); +			gDeferredMaterialWaterProgram[i].unload();  		}  		return TRUE;  	} @@ -1170,7 +1191,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	if (success)  	{ -		gDeferredDiffuseProgram.mName = "Deferred Diffuse Shader"; +		gDeferredDiffuseProgram.mName = "Deferred Diffuse Shader";		  		gDeferredDiffuseProgram.mShaderFiles.clear();  		gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseIndexedF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -1246,11 +1267,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; @@ -1260,8 +1277,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); @@ -1289,6 +1306,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) @@ -1308,8 +1334,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  			bool has_skin = i & 0x10;  			gDeferredMaterialProgram[i].addPermutation("HAS_SKIN",has_skin ? "1" : "0"); -			SINGLE_FP_PERMUTATION(gDeferredMaterialProgram[i]); -  			if (has_skin)  			{  				gDeferredMaterialProgram[i].mFeatures.hasObjectSkinning = true; @@ -1317,6 +1341,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; @@ -1328,6 +1380,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) @@ -1368,22 +1428,21 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; -		SINGLE_FP_PERMUTATION(gDeferredLightProgram); -  		success = gDeferredLightProgram.createShader(NULL, NULL);  	} -	if (success) +	for (U32 i = 0; i < LL_DEFERRED_MULTI_LIGHT_COUNT; i++)  	{ -		gDeferredMultiLightProgram.mName = "Deferred MultiLight Shader"; -		gDeferredMultiLightProgram.mShaderFiles.clear(); -		gDeferredMultiLightProgram.mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER_ARB)); -		gDeferredMultiLightProgram.mShaderFiles.push_back(make_pair("deferred/multiPointLightF.glsl", GL_FRAGMENT_SHADER_ARB)); -		gDeferredMultiLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; - -		SINGLE_FP_PERMUTATION(gDeferredMultiLightProgram); - -		success = gDeferredMultiLightProgram.createShader(NULL, NULL); +		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)); +			gDeferredMultiLightProgram[i].mShaderFiles.push_back(make_pair("deferred/multiPointLightF.glsl", GL_FRAGMENT_SHADER_ARB)); +			gDeferredMultiLightProgram[i].mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; +			gDeferredMultiLightProgram[i].addPermutation("LIGHT_COUNT", llformat("%d", i+1)); +			success = gDeferredMultiLightProgram[i].createShader(NULL, NULL); +		}  	}  	if (success) @@ -1394,8 +1453,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/spotLightF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredSpotLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; -		SINGLE_FP_PERMUTATION(gDeferredSpotLightProgram); -  		success = gDeferredSpotLightProgram.createShader(NULL, NULL);  	} @@ -1407,8 +1464,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiSpotLightF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredMultiSpotLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; -		SINGLE_FP_PERMUTATION(gDeferredMultiSpotLightProgram); -  		success = gDeferredMultiSpotLightProgram.createShader(NULL, NULL);  	} @@ -1436,8 +1491,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredSunProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB));  		gDeferredSunProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; -		SINGLE_FP_PERMUTATION(gDeferredSunProgram); -  		success = gDeferredSunProgram.createShader(NULL, NULL);  	} @@ -1449,19 +1502,14 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair("deferred/blurLightF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredBlurLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; -		SINGLE_FP_PERMUTATION(gDeferredBlurLightProgram); -  		success = gDeferredBlurLightProgram.createShader(NULL, NULL);  	}  	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 @@ -1478,12 +1526,10 @@ 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]; -		SINGLE_FP_PERMUTATION(gDeferredAlphaProgram); -  		success = gDeferredAlphaProgram.createShader(NULL, NULL);  		// Hack @@ -1493,6 +1539,72 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	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";  		gDeferredAvatarEyesProgram.mFeatures.calculatesAtmospherics = true;  		gDeferredAvatarEyesProgram.mFeatures.hasGamma = true; @@ -1521,6 +1633,54 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	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";  		gDeferredFullbrightShinyProgram.mFeatures.calculatesAtmospherics = true;  		gDeferredFullbrightShinyProgram.mFeatures.hasGamma = true; @@ -1593,6 +1753,20 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	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, &mWaterUniforms); +	} + +	if (success) +	{  		gDeferredSoftenProgram.mName = "Deferred Soften Shader";  		gDeferredSoftenProgram.mShaderFiles.clear();  		gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightV.glsl", GL_VERTEX_SHADER_ARB)); @@ -1600,8 +1774,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredSoftenProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; -		SINGLE_FP_PERMUTATION(gDeferredSoftenProgram); -  		if (gSavedSettings.getBOOL("RenderDeferredSSAO"))  		{ //if using SSAO, take screen space light map into account as if shadows are enabled  			gDeferredSoftenProgram.mShaderLevel = llmax(gDeferredSoftenProgram.mShaderLevel, 2); @@ -1612,6 +1784,25 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	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, &mWLUniforms); +	} + +	if (success) +	{  		gDeferredShadowProgram.mName = "Deferred Shadow Shader";  		gDeferredShadowProgram.mShaderFiles.clear();  		gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowV.glsl", GL_VERTEX_SHADER_ARB)); @@ -1692,12 +1883,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; @@ -1836,6 +2023,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectFullbrightNoColorProgram.unload();  		gObjectFullbrightNoColorWaterProgram.unload();  		gObjectSimpleProgram.unload(); +		gObjectSimpleImpostorProgram.unload();  		gObjectPreviewProgram.unload();  		gImpostorProgram.unload();  		gObjectSimpleAlphaMaskProgram.unload(); @@ -2258,6 +2446,27 @@ BOOL LLViewerShaderMgr::loadShadersObject()  	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";  		gObjectSimpleWaterProgram.mFeatures.calculatesLighting = true;  		gObjectSimpleWaterProgram.mFeatures.calculatesAtmospherics = true; @@ -3191,3 +3400,4 @@ LLViewerShaderMgr::shader_iter LLViewerShaderMgr::endShaders() const  {  	return mShaderList.end();  } + diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index 438853cd6f..e4684c19d5 100755 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -30,6 +30,8 @@  #include "llshadermgr.h"  #include "llmaterial.h" +#define LL_DEFERRED_MULTI_LIGHT_COUNT 16 +  class LLViewerShaderMgr: public LLShaderMgr  {  public: @@ -240,6 +242,7 @@ extern LLGLSLShader			gOneTextureNoColorProgram;  //object shaders  extern LLGLSLShader			gObjectSimpleProgram; +extern LLGLSLShader			gObjectSimpleImpostorProgram;  extern LLGLSLShader			gObjectPreviewProgram;  extern LLGLSLShader			gObjectSimpleAlphaMaskProgram;  extern LLGLSLShader			gObjectSimpleWaterProgram; @@ -328,6 +331,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; @@ -341,13 +345,14 @@ extern LLGLSLShader			gDeferredTerrainProgram;  extern LLGLSLShader			gDeferredTreeProgram;  extern LLGLSLShader			gDeferredTreeShadowProgram;  extern LLGLSLShader			gDeferredLightProgram; -extern LLGLSLShader			gDeferredMultiLightProgram; +extern LLGLSLShader			gDeferredMultiLightProgram[LL_DEFERRED_MULTI_LIGHT_COUNT];  extern LLGLSLShader			gDeferredSpotLightProgram;  extern LLGLSLShader			gDeferredMultiSpotLightProgram;  extern LLGLSLShader			gDeferredSunProgram;  extern LLGLSLShader			gDeferredBlurLightProgram;  extern LLGLSLShader			gDeferredAvatarProgram;  extern LLGLSLShader			gDeferredSoftenProgram; +extern LLGLSLShader			gDeferredSoftenWaterProgram;  extern LLGLSLShader			gDeferredShadowProgram;  extern LLGLSLShader			gDeferredShadowCubeProgram;  extern LLGLSLShader			gDeferredShadowAlphaMaskProgram; @@ -360,7 +365,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; @@ -374,5 +384,6 @@ extern LLGLSLShader			gNormalMapGenProgram;  // Deferred materials shaders  extern LLGLSLShader			gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2]; - +extern LLGLSLShader			gDeferredMaterialWaterProgram[LLMaterial::SHADER_COUNT*2];  #endif + diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 2de31cae98..d64db19733 100755 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -562,11 +562,11 @@ void LLViewerTextureList::addImageToList(LLViewerFetchedTexture *image)  	llassert(image);  	if (image->isInImageList())  	{ -		llerrs << "LLViewerTextureList::addImageToList - Image already in list" << llendl; +		llinfos << "LLViewerTextureList::addImageToList - Image already in list" << llendl;  	}  	if((mImageList.insert(image)).second != true)   	{ -		llerrs << "Error happens when insert image to mImageList!" << llendl ; +		llinfos << "Error happens when insert image to mImageList!" << llendl ;  	}  	image->setInImageList(TRUE) ; @@ -585,14 +585,14 @@ void LLViewerTextureList::removeImageFromList(LLViewerFetchedTexture *image)  		{  			llinfos << "Image is not in mUUIDMap!" << llendl ;  		} -		llerrs << "LLViewerTextureList::removeImageFromList - Image not in list" << llendl; +		llinfos << "LLViewerTextureList::removeImageFromList - Image not in list" << llendl;  	}  	S32 count = mImageList.erase(image) ; +	llassert(count == 1);  	if(count != 1)   	{ -		llinfos << image->getID() << llendl ; -		llerrs << "Error happens when remove image from mImageList: " << count << llendl ; +		llinfos << image->getID() << " removed with non-one count of " << count << llendl;  	}  	image->setInImageList(FALSE) ; @@ -602,15 +602,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++; @@ -1281,7 +1281,7 @@ S32 LLViewerTextureList::getMaxVideoRamSetting(bool get_recommended, float mem_m  		max_texmem = llmin(max_texmem, (S32)(system_ram/2));  	else  		max_texmem = llmin(max_texmem, (S32)(system_ram)); -     +		      // limit the texture memory to a multiple of the default if we've found some cards to behave poorly otherwise  	max_texmem = llmin(max_texmem, (S32) (mem_multiplier * (F32) max_texmem)); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index e6385dceea..6b3611b796 100755 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1114,7 +1114,7 @@ void LLVOVolume::sculpt()  		S32 max_discard = mSculptTexture->getMaxDiscardLevel();  		if (discard_level > max_discard)  		{ -			discard_level = max_discard;    // clamp to the best we can do			 +			discard_level = max_discard;    // clamp to the best we can do  		}  		if(discard_level > MAX_DISCARD_LEVEL)  		{ @@ -1458,7 +1458,7 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global)  			continue;  		}  		res &= face->genVolumeBBoxes(*volume, i, -										mRelativeXform,  +										mRelativeXform, /*mRelativeXformInvTrans,*/  										(mVolumeImpl && mVolumeImpl->isVolumeGlobal()) || force_global);  		if (rebuild) @@ -2596,6 +2596,7 @@ void LLVOVolume::setLightTextureID(LLUUID id)  		if (hasLightTexture())  		{  			setParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE, FALSE, true); +			parameterChanged(LLNetworkData::PARAMS_LIGHT_IMAGE, true);  			mLightTexture = NULL;  		}  	}		 @@ -2613,7 +2614,8 @@ void LLVOVolume::setSpotLightParams(LLVector3 params)  void LLVOVolume::setIsLight(BOOL is_light)  { -	if (is_light != getIsLight()) +	BOOL was_light = getIsLight(); +	if (is_light != was_light)  	{  		if (is_light)  		{ @@ -2798,7 +2800,7 @@ void LLVOVolume::updateSpotLightPriority()  bool LLVOVolume::isLightSpotlight() const  {  	LLLightImageParams* params = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); -	if (params) +	if (params && getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE))  	{  		return params->isLightSpotlight();  	} @@ -3728,8 +3730,30 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&  			{  				LLFace* face = mDrawable->getFace(face_hit);				 +				bool ignore_alpha = false; + +				const LLTextureEntry* te = face->getTextureEntry(); +				if (te) +				{ +					LLMaterial* mat = te->getMaterialParams(); +					if (mat) +					{ +						U8 mode = mat->getDiffuseAlphaMode(); + +						if (mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE || +							mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE) +						{ +							ignore_alpha = true; +						} +					} +				} +  				if (face && -					(pick_transparent || !face->getTexture() || !face->getTexture()->hasGLTexture() || face->getTexture()->getMask(face->surfaceToTexture(tc, p, n)))) +					(ignore_alpha || +					pick_transparent ||  +					!face->getTexture() ||  +					!face->getTexture()->hasGLTexture() ||  +					face->getTexture()->getMask(face->surfaceToTexture(tc, p, n))))  				{  					local_end = p;  					if (face_hitp != NULL) @@ -4841,7 +4865,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  			{  				if (!drawablep->isState(LLDrawable::RIGGED))  				{ -					drawablep->setState(LLDrawable::RIGGED); +				drawablep->setState(LLDrawable::RIGGED);  					//first time this is drawable is being marked as rigged,  					// do another LoD update to use avatar bounding box @@ -5367,19 +5391,24 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  								mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE;  			} -			bool use_legacy_bump = te->getBumpmap() && (!mat || mat->getNormalID().isNull()); +			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  						{ diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index f49395da34..b4e59909db 100755 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -111,6 +111,8 @@  #include "llpathinglib.h"  #include "llfloaterpathfindingconsole.h"  #include "llfloaterpathfindingcharacters.h" +#include "llfloatertools.h" +#include "llpanelface.h"  #include "llpathfindingpathtool.h"  #ifdef _DEBUG @@ -120,6 +122,10 @@  //#define DEBUG_INDICES  #endif +// Expensive and currently broken +// +#define MATERIALS_IN_REFLECTIONS 0 +  bool gShiftFrame = false;  //cached settings @@ -374,6 +380,7 @@ BOOL	LLPipeline::sWaterReflections = FALSE;  BOOL	LLPipeline::sRenderGlow = FALSE;  BOOL	LLPipeline::sReflectionRender = FALSE;  BOOL	LLPipeline::sImpostorRender = FALSE; +BOOL	LLPipeline::sImpostorRenderAlphaDepthPass = FALSE;  BOOL	LLPipeline::sUnderWaterRender = FALSE;  BOOL	LLPipeline::sTextureBindTest = FALSE;  BOOL	LLPipeline::sRenderFrameTest = FALSE; @@ -789,14 +796,22 @@ void LLPipeline::resizeScreenTexture()  		GLuint resX = gViewerWindow->getWorldViewWidthRaw();  		GLuint resY = gViewerWindow->getWorldViewHeightRaw(); -		if (!allocateScreenBuffer(resX,resY)) -		{ //FAILSAFE: screen buffer allocation failed, disable deferred rendering if it's enabled -			//NOTE: if the session closes successfully after this call, deferred rendering will be  -			// disabled on future sessions -			if (LLPipeline::sRenderDeferred) +		if ((resX != mScreen.getWidth()) || (resY != mScreen.getHeight())) +		{ +			releaseScreenBuffers(); +			if (!allocateScreenBuffer(resX,resY))  			{ -				gSavedSettings.setBOOL("RenderDeferred", FALSE); -				LLPipeline::refreshCachedSettings(); +#if PROBABLE_FALSE_DISABLES_OF_ALM_HERE +				//FAILSAFE: screen buffer allocation failed, disable deferred rendering if it's enabled +				//NOTE: if the session closes successfully after this call, deferred rendering will be  +				// disabled on future sessions +				if (LLPipeline::sRenderDeferred) +				{ +					gSavedSettings.setBOOL("RenderDeferred", FALSE); +					LLPipeline::refreshCachedSettings(); + +				} +#endif  			}  		}  	} @@ -1186,7 +1201,8 @@ void LLPipeline::releaseGLBuffers()  	mWaterRef.release();  	mWaterDis.release(); -	 +	mHighlight.release(); +  	for (U32 i = 0; i < 3; i++)  	{  		mGlow[i].release(); @@ -1216,12 +1232,12 @@ void LLPipeline::releaseScreenBuffers()  	mDeferredScreen.release();  	mDeferredDepth.release();  	mDeferredLight.release(); -	 -	mHighlight.release(); +	mOcclusionDepth.release();  	for (U32 i = 0; i < 6; i++)  	{  		mShadow[i].release(); +		mShadowOcclusion[i].release();  	}  } @@ -1233,14 +1249,31 @@ void LLPipeline::createGLBuffers()  	updateRenderDeferred(); +	bool materials_in_water = false; + +#if MATERIALS_IN_REFLECTIONS +	materials_in_water = gSavedSettings.getS32("RenderWaterMaterials"); +#endif +  	if (LLPipeline::sWaterReflections)  	{ //water reflection texture  		U32 res = (U32) llmax(gSavedSettings.getS32("RenderWaterRefResolution"), 512); +		// Set up SRGB targets if we're doing deferred-path reflection rendering +		// +		if (LLPipeline::sRenderDeferred && materials_in_water) +		{ +			mWaterRef.allocate(res,res,GL_SRGB8_ALPHA8,TRUE,FALSE); +			//always use FBO for mWaterDis so it can be used for avatar texture bakes +			mWaterDis.allocate(res,res,GL_SRGB8_ALPHA8,TRUE,FALSE,LLTexUnit::TT_TEXTURE, true); +		} +		else +		{  		mWaterRef.allocate(res,res,GL_RGBA,TRUE,FALSE);  		//always use FBO for mWaterDis so it can be used for avatar texture bakes  		mWaterDis.allocate(res,res,GL_RGBA,TRUE,FALSE,LLTexUnit::TT_TEXTURE, true);  	} +	}  	mHighlight.allocate(256,256,GL_RGBA, FALSE, FALSE); @@ -1402,9 +1435,15 @@ void LLPipeline::createLUTBuffers()  				}  			} -			LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, GL_R16F, 1, &mLightFunc); +			U32 pix_format = GL_R16F; +#if LL_DARWIN +			// Need to work around limited precision with 10.6.8 and older drivers +			// +			pix_format = GL_R32F; +#endif +			LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, pix_format, 1, &mLightFunc);  			gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc); -			LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_R16F, lightResX, lightResY, GL_RED, GL_FLOAT, ls, false); +			LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, pix_format, lightResX, lightResY, GL_RED, GL_FLOAT, ls, false);  			//LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_UNSIGNED_BYTE, lightResX, lightResY, GL_RED, GL_UNSIGNED_BYTE, ls, false);  			gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);  			gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR); @@ -2443,7 +2482,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl  	if (to_texture)  	{ -		if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender) +		if (LLPipeline::sRenderDeferred)  		{  			mOcclusionDepth.bindTarget();  		} @@ -2588,7 +2627,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl  	if (to_texture)  	{ -		if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender) +		if (LLPipeline::sRenderDeferred)  		{  			mOcclusionDepth.flush();  		} @@ -3959,7 +3998,7 @@ void LLPipeline::postSort(LLCamera& camera)  	{  		mSelectedFaces.clear(); -		LLPipeline::setRenderHighlightTextureChannel(LLSelectMgr::getInstance()->getTextureChannel()); +		LLPipeline::setRenderHighlightTextureChannel(gFloaterTools->getPanelFace()->getTextureChannelToEdit());  		// Draw face highlights for selected faces.  		if (LLSelectMgr::getInstance()->getTEMode()) @@ -5383,7 +5422,7 @@ void LLPipeline::renderDebug()  			if (i > 3)  			{ //render shadow frusta as volumes  				if (mShadowFrustPoints[i-4].empty()) -				{ +			{  					continue;  				} @@ -8527,7 +8566,7 @@ void LLPipeline::renderDeferredLighting()  		if (RenderDeferredAtmospheric)  		{ //apply sunlight contribution   			LLFastTimer ftm(FTM_ATMOSPHERICS); -			bindDeferredShader(gDeferredSoftenProgram);	 +			bindDeferredShader(LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram);	  			{  				LLGLDepthTest depth(GL_FALSE);  				LLGLDisable blend(GL_BLEND); @@ -8549,7 +8588,7 @@ void LLPipeline::renderDeferredLighting()  				gGL.popMatrix();  			} -			unbindDeferredShader(gDeferredSoftenProgram); +			unbindDeferredShader(LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram);  		}  		{ //render non-deferred geometry (fullbright, alpha, etc) @@ -8742,10 +8781,6 @@ void LLPipeline::renderDeferredLighting()  			vert[2].set(3,1,0);  			{ -				bindDeferredShader(gDeferredMultiLightProgram); -			 -				mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); -  				LLGLDepthTest depth(GL_FALSE);  				//full screen blit @@ -8757,7 +8792,7 @@ void LLPipeline::renderDeferredLighting()  				U32 count = 0; -				const U32 max_count = 8; +				const U32 max_count = LL_DEFERRED_MULTI_LIGHT_COUNT;  				LLVector4 light[max_count];  				LLVector4 col[max_count]; @@ -8780,18 +8815,20 @@ void LLPipeline::renderDeferredLighting()  					count++;  					if (count == max_count || fullscreen_lights.empty())  					{ -						gDeferredMultiLightProgram.uniform1i(LLShaderMgr::MULTI_LIGHT_COUNT, count); -						gDeferredMultiLightProgram.uniform4fv(LLShaderMgr::MULTI_LIGHT, count, (GLfloat*) light); -						gDeferredMultiLightProgram.uniform4fv(LLShaderMgr::MULTI_LIGHT_COL, count, (GLfloat*) col); -						gDeferredMultiLightProgram.uniform1f(LLShaderMgr::MULTI_LIGHT_FAR_Z, far_z); +						U32 idx = count-1; +						bindDeferredShader(gDeferredMultiLightProgram[idx]); +						gDeferredMultiLightProgram[idx].uniform1i(LLShaderMgr::MULTI_LIGHT_COUNT, count); +						gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT, count, (GLfloat*) light); +						gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT_COL, count, (GLfloat*) col); +						gDeferredMultiLightProgram[idx].uniform1f(LLShaderMgr::MULTI_LIGHT_FAR_Z, far_z);  						far_z = 0.f;  						count = 0;  +      mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);  						mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); +						unbindDeferredShader(gDeferredMultiLightProgram[idx]);  					}  				} -				unbindDeferredShader(gDeferredMultiLightProgram); -  				bindDeferredShader(gDeferredMultiSpotLightProgram);  				gDeferredMultiSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION); @@ -8872,9 +8909,9 @@ void LLPipeline::renderDeferredLighting()  		gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mScreen.getWidth(), mScreen.getHeight()); -		F32 gamma = 1.0/2.2; +		F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma"); -		gDeferredPostGammaCorrectProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, gamma); +		gDeferredPostGammaCorrectProgram.uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));  		gGL.begin(LLRender::TRIANGLE_STRIP);  		gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); @@ -8953,6 +8990,537 @@ void LLPipeline::renderDeferredLighting()  } +void LLPipeline::renderDeferredLightingToRT(LLRenderTarget* target) +{ +	if (!sCull) +	{ +		return; +	} + +	{ +		LLFastTimer ftm(FTM_RENDER_DEFERRED); + +		LLViewerCamera* camera = LLViewerCamera::getInstance(); + +		{ +			LLGLDepthTest depth(GL_TRUE); +			mDeferredDepth.copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(), +							0, 0, mDeferredDepth.getWidth(), mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);	 +		} + +		LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0); + +		if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) +		{ +			gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD); +		} + +		//ati doesn't seem to love actually using the stencil buffer on FBO's +		LLGLDisable stencil(GL_STENCIL_TEST); +		//glStencilFunc(GL_EQUAL, 1, 0xFFFFFFFF); +		//glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + +		gGL.setColorMask(true, true); +		 +		//draw a cube around every light +		LLVertexBuffer::unbind(); + +		LLGLEnable cull(GL_CULL_FACE); +		LLGLEnable blend(GL_BLEND); + +		glh::matrix4f mat = glh_copy_matrix(gGLModelView); + +		LLStrider<LLVector3> vert;  +		mDeferredVB->getVertexStrider(vert); +		 +		vert[0].set(-1,1,0); +		vert[1].set(-1,-3,0); +		vert[2].set(3,1,0); +		 +		{ +			setupHWLights(NULL); //to set mSunDir; +			LLVector4 dir(mSunDir, 0.f); +			glh::vec4f tc(dir.mV); +			mat.mult_matrix_vec(tc); +			mTransformedSunDir.set(tc.v); +		} + +		gGL.pushMatrix(); +		gGL.loadIdentity(); +		gGL.matrixMode(LLRender::MM_PROJECTION); +		gGL.pushMatrix(); +		gGL.loadIdentity(); + +		if (RenderDeferredSSAO || RenderShadowDetail > 0) +		{ +			mDeferredLight.bindTarget(); +			{ //paint shadow/SSAO light map (direct lighting lightmap) +				LLFastTimer ftm(FTM_SUN_SHADOW); +				bindDeferredShader(gDeferredSunProgram); +				mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); +				glClearColor(1,1,1,1); +				mDeferredLight.clear(GL_COLOR_BUFFER_BIT); +				glClearColor(0,0,0,0); + +				glh::matrix4f inv_trans = glh_get_current_modelview().inverse().transpose(); + +				const U32 slice = 32; +				F32 offset[slice*3]; +				for (U32 i = 0; i < 4; i++) +				{ +					for (U32 j = 0; j < 8; j++) +					{ +						glh::vec3f v; +						v.set_value(sinf(6.284f/8*j), cosf(6.284f/8*j), -(F32) i); +						v.normalize(); +						inv_trans.mult_matrix_vec(v); +						v.normalize(); +						offset[(i*8+j)*3+0] = v.v[0]; +						offset[(i*8+j)*3+1] = v.v[2]; +						offset[(i*8+j)*3+2] = v.v[1]; +					} +				} + +				gDeferredSunProgram.uniform3fv("offset", slice, offset); +				gDeferredSunProgram.uniform2f("screenRes", mDeferredLight.getWidth(), mDeferredLight.getHeight()); +				 +				{ +					LLGLDisable blend(GL_BLEND); +					LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); +					stop_glerror(); +					mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); +					stop_glerror(); +				} +				 +				unbindDeferredShader(gDeferredSunProgram); +			} +			mDeferredLight.flush(); +		} +				 +		stop_glerror(); +		gGL.popMatrix(); +		stop_glerror(); +		gGL.matrixMode(LLRender::MM_MODELVIEW); +		stop_glerror(); +		gGL.popMatrix(); +		stop_glerror(); + +		target->bindTarget(); + +		//clear color buffer here - zeroing alpha (glow) is important or it will accumulate against sky +		glClearColor(0,0,0,0); +		target->clear(GL_COLOR_BUFFER_BIT); +		 +		if (RenderDeferredAtmospheric) +		{ //apply sunlight contribution  +			LLFastTimer ftm(FTM_ATMOSPHERICS); +			bindDeferredShader(gDeferredSoftenProgram);	 +			{ +				LLGLDepthTest depth(GL_FALSE); +				LLGLDisable blend(GL_BLEND); +				LLGLDisable test(GL_ALPHA_TEST); + +				//full screen blit +				gGL.pushMatrix(); +				gGL.loadIdentity(); +				gGL.matrixMode(LLRender::MM_PROJECTION); +				gGL.pushMatrix(); +				gGL.loadIdentity(); + +				mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); +				 +				mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); + +				gGL.popMatrix(); +				gGL.matrixMode(LLRender::MM_MODELVIEW); +				gGL.popMatrix(); +			} + +			unbindDeferredShader(gDeferredSoftenProgram); +		} + +		{ //render non-deferred geometry (fullbright, alpha, etc) +			LLGLDisable blend(GL_BLEND); +			LLGLDisable stencil(GL_STENCIL_TEST); +			gGL.setSceneBlendType(LLRender::BT_ALPHA); + +			gPipeline.pushRenderTypeMask(); +			 +			gPipeline.andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, +										LLPipeline::RENDER_TYPE_CLOUDS, +										LLPipeline::RENDER_TYPE_WL_SKY, +										LLPipeline::END_RENDER_TYPES); +								 +			 +			renderGeomPostDeferred(*LLViewerCamera::getInstance(), false); +			gPipeline.popRenderTypeMask(); +		} + +		BOOL render_local = RenderLocalLights; +				 +		if (render_local) +		{ +			gGL.setSceneBlendType(LLRender::BT_ADD); +			std::list<LLVector4> fullscreen_lights; +			LLDrawable::drawable_list_t spot_lights; +			LLDrawable::drawable_list_t fullscreen_spot_lights; + +			for (U32 i = 0; i < 2; i++) +			{ +				mTargetShadowSpotLight[i] = NULL; +			} + +			std::list<LLVector4> light_colors; + +			LLVertexBuffer::unbind(); + +			{ +				bindDeferredShader(gDeferredLightProgram); +				 +				if (mCubeVB.isNull()) +				{ +					mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB); +				} + +				mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX); +				 +				LLGLDepthTest depth(GL_TRUE, GL_FALSE); +				for (LLDrawable::drawable_set_t::iterator iter = mLights.begin(); iter != mLights.end(); ++iter) +				{ +					LLDrawable* drawablep = *iter; +					 +					LLVOVolume* volume = drawablep->getVOVolume(); +					if (!volume) +					{ +						continue; +					} + +					if (volume->isAttachment()) +					{ +						if (!sRenderAttachedLights) +						{ +							continue; +						} +					} + + +					LLVector4a center; +					center.load3(drawablep->getPositionAgent().mV); +					const F32* c = center.getF32ptr(); +					F32 s = volume->getLightRadius()*1.5f; + +					LLColor3 col = volume->getLightColor(); +					 +					if (col.magVecSquared() < 0.001f) +					{ +						continue; +					} + +					if (s <= 0.001f) +					{ +						continue; +					} + +					LLVector4a sa; +					sa.splat(s); +					if (camera->AABBInFrustumNoFarClip(center, sa) == 0) +					{ +						continue; +					} + +					sVisibleLightCount++; +										 +					if (camera->getOrigin().mV[0] > c[0] + s + 0.2f || +						camera->getOrigin().mV[0] < c[0] - s - 0.2f || +						camera->getOrigin().mV[1] > c[1] + s + 0.2f || +						camera->getOrigin().mV[1] < c[1] - s - 0.2f || +						camera->getOrigin().mV[2] > c[2] + s + 0.2f || +						camera->getOrigin().mV[2] < c[2] - s - 0.2f) +					{ //draw box if camera is outside box +						if (render_local) +						{ +							if (volume->isLightSpotlight()) +							{ +								drawablep->getVOVolume()->updateSpotLightPriority(); +								spot_lights.push_back(drawablep); +								continue; +							} +							 +							/*col.mV[0] = powf(col.mV[0], 2.2f); +							col.mV[1] = powf(col.mV[1], 2.2f); +							col.mV[2] = powf(col.mV[2], 2.2f);*/ +							 +							LLFastTimer ftm(FTM_LOCAL_LIGHTS); +							gDeferredLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c); +							gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s); +							gDeferredLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV); +							gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f); +							gGL.syncMatrices(); +							 +							mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center)); +							stop_glerror(); +						} +					} +					else +					{	 +						if (volume->isLightSpotlight()) +						{ +							drawablep->getVOVolume()->updateSpotLightPriority(); +							fullscreen_spot_lights.push_back(drawablep); +							continue; +						} + +						glh::vec3f tc(c); +						mat.mult_matrix_vec(tc); +					 +						fullscreen_lights.push_back(LLVector4(tc.v[0], tc.v[1], tc.v[2], s)); +						light_colors.push_back(LLVector4(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f)); +					} +				} +				unbindDeferredShader(gDeferredLightProgram); +			} + +			if (!spot_lights.empty()) +			{ +				LLGLDepthTest depth(GL_TRUE, GL_FALSE); +				bindDeferredShader(gDeferredSpotLightProgram); + +				mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + +				gDeferredSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION); + +				for (LLDrawable::drawable_list_t::iterator iter = spot_lights.begin(); iter != spot_lights.end(); ++iter) +				{ +					LLFastTimer ftm(FTM_PROJECTORS); +					LLDrawable* drawablep = *iter; + +					LLVOVolume* volume = drawablep->getVOVolume(); + +					LLVector4a center; +					center.load3(drawablep->getPositionAgent().mV); +					const F32* c = center.getF32ptr(); +					F32 s = volume->getLightRadius()*1.5f; + +					sVisibleLightCount++; + +					setupSpotLight(gDeferredSpotLightProgram, drawablep); +					 +					LLColor3 col = volume->getLightColor(); +					/*col.mV[0] = powf(col.mV[0], 2.2f); +					col.mV[1] = powf(col.mV[1], 2.2f); +					col.mV[2] = powf(col.mV[2], 2.2f);*/ +					 +					gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c); +					gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s); +					gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV); +					gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f); +					gGL.syncMatrices(); +										 +					mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center)); +				} +				gDeferredSpotLightProgram.disableTexture(LLShaderMgr::DEFERRED_PROJECTION); +				unbindDeferredShader(gDeferredSpotLightProgram); +			} + +			//reset mDeferredVB to fullscreen triangle +			mDeferredVB->getVertexStrider(vert); +			vert[0].set(-1,1,0); +			vert[1].set(-1,-3,0); +			vert[2].set(3,1,0); + +			{ +				LLGLDepthTest depth(GL_FALSE); + +				//full screen blit +				gGL.pushMatrix(); +				gGL.loadIdentity(); +				gGL.matrixMode(LLRender::MM_PROJECTION); +				gGL.pushMatrix(); +				gGL.loadIdentity(); + +				U32 count = 0; + +				const U32 max_count = LL_DEFERRED_MULTI_LIGHT_COUNT; +				LLVector4 light[max_count]; +				LLVector4 col[max_count]; + +				F32 far_z = 0.f; + +				while (!fullscreen_lights.empty()) +				{ +					LLFastTimer ftm(FTM_FULLSCREEN_LIGHTS); +					light[count] = fullscreen_lights.front(); +					fullscreen_lights.pop_front(); +					col[count] = light_colors.front(); +					light_colors.pop_front(); +					 +					/*col[count].mV[0] = powf(col[count].mV[0], 2.2f); +					col[count].mV[1] = powf(col[count].mV[1], 2.2f); +					col[count].mV[2] = powf(col[count].mV[2], 2.2f);*/ +					 +					far_z = llmin(light[count].mV[2]-light[count].mV[3], far_z); +					//col[count] = pow4fsrgb(col[count], 2.2f); +					count++; +					if (count == max_count || fullscreen_lights.empty()) +					{ +						U32 idx = count-1; +						bindDeferredShader(gDeferredMultiLightProgram[idx]); +						gDeferredMultiLightProgram[idx].uniform1i(LLShaderMgr::MULTI_LIGHT_COUNT, count); +						gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT, count, (GLfloat*) light); +						gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT_COL, count, (GLfloat*) col); +						gDeferredMultiLightProgram[idx].uniform1f(LLShaderMgr::MULTI_LIGHT_FAR_Z, far_z); +						far_z = 0.f; +						count = 0;  +						mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); +						mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); +					} +				} +				 +				unbindDeferredShader(gDeferredMultiLightProgram[0]); + +				bindDeferredShader(gDeferredMultiSpotLightProgram); + +				gDeferredMultiSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION); + +				mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + +				for (LLDrawable::drawable_list_t::iterator iter = fullscreen_spot_lights.begin(); iter != fullscreen_spot_lights.end(); ++iter) +				{ +					LLFastTimer ftm(FTM_PROJECTORS); +					LLDrawable* drawablep = *iter; +					 +					LLVOVolume* volume = drawablep->getVOVolume(); + +					LLVector3 center = drawablep->getPositionAgent(); +					F32* c = center.mV; +					F32 s = volume->getLightRadius()*1.5f; + +					sVisibleLightCount++; + +					glh::vec3f tc(c); +					mat.mult_matrix_vec(tc); +					 +					setupSpotLight(gDeferredMultiSpotLightProgram, drawablep); + +					LLColor3 col = volume->getLightColor(); +					 +					/*col.mV[0] = powf(col.mV[0], 2.2f); +					col.mV[1] = powf(col.mV[1], 2.2f); +					col.mV[2] = powf(col.mV[2], 2.2f);*/ +					 +					gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, tc.v); +					gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s); +					gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV); +					gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f); +					mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); +				} + +				gDeferredMultiSpotLightProgram.disableTexture(LLShaderMgr::DEFERRED_PROJECTION); +				unbindDeferredShader(gDeferredMultiSpotLightProgram); + +				gGL.popMatrix(); +				gGL.matrixMode(LLRender::MM_MODELVIEW); +				gGL.popMatrix(); +			} +		} + +		gGL.setColorMask(true, true); +	} + +	/*target->flush(); + +	//gamma correct lighting +	gGL.matrixMode(LLRender::MM_PROJECTION); +	gGL.pushMatrix(); +	gGL.loadIdentity(); +	gGL.matrixMode(LLRender::MM_MODELVIEW); +	gGL.pushMatrix(); +	gGL.loadIdentity(); + +	{ +		LLGLDepthTest depth(GL_FALSE, GL_FALSE); + +		LLVector2 tc1(0,0); +		LLVector2 tc2((F32) target->getWidth()*2, +				  (F32) target->getHeight()*2); + +		target->bindTarget(); +		// Apply gamma correction to the frame here. +		gDeferredPostGammaCorrectProgram.bind(); +		//mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); +		S32 channel = 0; +		channel = gDeferredPostGammaCorrectProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, target->getUsage()); +		if (channel > -1) +		{ +			target->bindTexture(0,channel); +			gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); +		} +		 +		gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, target->getWidth(), target->getHeight()); +		 +		F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma"); + +		gDeferredPostGammaCorrectProgram.uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f)); +		 +		gGL.begin(LLRender::TRIANGLE_STRIP); +		gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); +		gGL.vertex2f(-1,-1); +		 +		gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); +		gGL.vertex2f(-1,3); +		 +		gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); +		gGL.vertex2f(3,-1); +		 +		gGL.end(); +		 +		gGL.getTexUnit(channel)->unbind(target->getUsage()); +		gDeferredPostGammaCorrectProgram.unbind(); +		target->flush(); +	} + +	gGL.matrixMode(LLRender::MM_PROJECTION); +	gGL.popMatrix(); +	gGL.matrixMode(LLRender::MM_MODELVIEW); +	gGL.popMatrix();	 + +	target->bindTarget();*/ + +	{ //render non-deferred geometry (alpha, fullbright, glow) +		LLGLDisable blend(GL_BLEND); +		LLGLDisable stencil(GL_STENCIL_TEST); + +		pushRenderTypeMask(); +		andRenderTypeMask(LLPipeline::RENDER_TYPE_ALPHA, +						 LLPipeline::RENDER_TYPE_FULLBRIGHT, +						 LLPipeline::RENDER_TYPE_VOLUME, +						 LLPipeline::RENDER_TYPE_GLOW, +						 LLPipeline::RENDER_TYPE_BUMP, +						 LLPipeline::RENDER_TYPE_PASS_SIMPLE, +						 LLPipeline::RENDER_TYPE_PASS_ALPHA, +						 LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK, +						 LLPipeline::RENDER_TYPE_PASS_BUMP, +						 LLPipeline::RENDER_TYPE_PASS_POST_BUMP, +						 LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT, +						 LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK, +						 LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY, +						 LLPipeline::RENDER_TYPE_PASS_GLOW, +						 LLPipeline::RENDER_TYPE_PASS_GRASS, +						 LLPipeline::RENDER_TYPE_PASS_SHINY, +						 LLPipeline::RENDER_TYPE_PASS_INVISIBLE, +						 LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY, +						 LLPipeline::RENDER_TYPE_AVATAR, +						 LLPipeline::RENDER_TYPE_ALPHA_MASK, +						 LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK, +						 END_RENDER_TYPES); +		 +		renderGeomPostDeferred(*LLViewerCamera::getInstance()); +		popRenderTypeMask(); +	} + +	//target->flush();				 +} +  void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)  {  	//construct frustum @@ -9199,6 +9767,12 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)  			water_clip = 1;  		} +		bool materials_in_water = false; + +#if MATERIALS_IN_REFLECTIONS +		materials_in_water = gSavedSettings.getS32("RenderWaterMaterials"); +#endif +  		if (!LLViewerCamera::getInstance()->cameraUnderWater())  		{	//generate planar reflection map @@ -9207,7 +9781,9 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)  			LLPipeline::sUseOcclusion = 0;  			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);  			glClearColor(0,0,0,0); +  			mWaterRef.bindTarget(); +  			LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER0;  			gGL.setColorMask(true, true);  			mWaterRef.clear(); @@ -9256,11 +9832,27 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)  					updateCull(camera, result);  					stateSort(camera, result); +					if (LLPipeline::sRenderDeferred && materials_in_water) +					{ +						mWaterRef.flush(); + +						gPipeline.grabReferences(result); +						gPipeline.mDeferredScreen.bindTarget(); +						gGL.setColorMask(true, true);						 +						glClearColor(0,0,0,0); +						gPipeline.mDeferredScreen.clear(); + +						renderGeomDeferred(camera);						 +					} +					else +					{  					renderGeom(camera, TRUE); +					}					  					gPipeline.popRenderTypeMask();  				} +				gGL.setColorMask(true, false);  				gPipeline.pushRenderTypeMask();  				clearRenderTypeMask(LLPipeline::RENDER_TYPE_WATER, @@ -9298,9 +9890,23 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)  					{  						gPipeline.grabReferences(ref_result);  						LLGLUserClipPlane clip_plane(plane, mat, projection); + +						if (LLPipeline::sRenderDeferred && materials_in_water) +						{							 +							renderGeomDeferred(camera); +						} +						else +						{  						renderGeom(camera);  					}  				}	 +				}	 + +				if (LLPipeline::sRenderDeferred && materials_in_water) +				{ +					gPipeline.mDeferredScreen.flush(); +					renderDeferredLightingToRT(&mWaterRef); +				}  				gPipeline.popRenderTypeMask();  			}	 @@ -9336,10 +9942,12 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)  			LLViewerCamera::updateFrustumPlanes(camera);  			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); +			  			LLColor4& col = LLDrawPoolWater::sWaterFogColor;  			glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f);  			mWaterDis.bindTarget();  			LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER1; +			  			mWaterDis.getViewport(gGLViewport);  			if (!LLPipeline::sUnderWaterRender || LLDrawPoolWater::sNeedsReflectionUpdate) @@ -9355,14 +9963,36 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)  				gGL.setColorMask(true, true);  				mWaterDis.clear(); +				 +  				gGL.setColorMask(true, false); +				 +				if (LLPipeline::sRenderDeferred && materials_in_water) +				{										 +					mWaterDis.flush(); +					gPipeline.mDeferredScreen.bindTarget(); +					gGL.setColorMask(true, true); +					glClearColor(0,0,0,0); +					gPipeline.mDeferredScreen.clear(); +					gPipeline.grabReferences(result); +					renderGeomDeferred(camera);					 +				} +				else +				{  				renderGeom(camera); +				} +				if (LLPipeline::sRenderDeferred && materials_in_water) +				{ +					gPipeline.mDeferredScreen.flush(); +					renderDeferredLightingToRT(&mWaterDis); +				}  			} -			LLPipeline::sUnderWaterRender = FALSE;  			mWaterDis.flush(); +			LLPipeline::sUnderWaterRender = FALSE; +			  		}  		last_update = LLDrawPoolWater::sNeedsReflectionUpdate && LLDrawPoolWater::sNeedsDistortionUpdate; @@ -9769,14 +10399,14 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector  			const LLPlane& cp = camera.getAgentPlane(j);  			F32 dist = cp.dist(pp[i]);  			if (dist > 0.05f) //point is above some plane, not contained -			{ +					{  				found = false;  				break; -			} -		} +						} +					} -		if (found) -		{ +					if (found) +					{  			fp.push_back(pp[i]);  		}  	} @@ -10688,29 +11318,37 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)  	}  	else  	{ -		andRenderTypeMask(LLPipeline::RENDER_TYPE_VOLUME, -						LLPipeline::RENDER_TYPE_AVATAR, +		andRenderTypeMask(LLPipeline::RENDER_TYPE_ALPHA, +			LLPipeline::RENDER_TYPE_FULLBRIGHT, +			LLPipeline::RENDER_TYPE_VOLUME, +			LLPipeline::RENDER_TYPE_GLOW,  						LLPipeline::RENDER_TYPE_BUMP, -						LLPipeline::RENDER_TYPE_GRASS, -						LLPipeline::RENDER_TYPE_SIMPLE, -						LLPipeline::RENDER_TYPE_FULLBRIGHT, -						LLPipeline::RENDER_TYPE_ALPHA,  -						LLPipeline::RENDER_TYPE_INVISIBLE,  						LLPipeline::RENDER_TYPE_PASS_SIMPLE,  						LLPipeline::RENDER_TYPE_PASS_ALPHA,  						LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK, +			LLPipeline::RENDER_TYPE_PASS_BUMP, +			LLPipeline::RENDER_TYPE_PASS_POST_BUMP,  						LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT,  						LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK,  						LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY, +			LLPipeline::RENDER_TYPE_PASS_GLOW, +			LLPipeline::RENDER_TYPE_PASS_GRASS,  						LLPipeline::RENDER_TYPE_PASS_SHINY,  						LLPipeline::RENDER_TYPE_PASS_INVISIBLE,  						LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY, +			LLPipeline::RENDER_TYPE_AVATAR, +			LLPipeline::RENDER_TYPE_ALPHA_MASK, +			LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK, +			LLPipeline::RENDER_TYPE_INVISIBLE, +			LLPipeline::RENDER_TYPE_SIMPLE,  						END_RENDER_TYPES);  	}  	S32 occlusion = sUseOcclusion;  	sUseOcclusion = 0; +  	sReflectionRender = sRenderDeferred ? FALSE : TRUE; +  	sShadowRender = TRUE;  	sImpostorRender = TRUE; @@ -10805,22 +11443,26 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)  		if (!avatar->mImpostor.isComplete())  		{  			LLFastTimer t(FTM_IMPOSTOR_ALLOCATE); -			avatar->mImpostor.allocate(resX,resY,GL_RGBA,TRUE,FALSE); +			  			if (LLPipeline::sRenderDeferred)  			{ +				avatar->mImpostor.allocate(resX,resY,GL_SRGB8_ALPHA8,TRUE,FALSE);  				addDeferredAttachments(avatar->mImpostor);  			} +			else +			{ +				avatar->mImpostor.allocate(resX,resY,GL_RGBA,TRUE,FALSE); +			}  			gGL.getTexUnit(0)->bind(&avatar->mImpostor);  			gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);  			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);  		} -		else if(resX != avatar->mImpostor.getWidth() || -			resY != avatar->mImpostor.getHeight()) +		else if(resX != avatar->mImpostor.getWidth() || resY != avatar->mImpostor.getHeight())  		{  			LLFastTimer t(FTM_IMPOSTOR_RESIZE); -			avatar->mImpostor.resize(resX,resY,GL_RGBA); +			avatar->mImpostor.resize(resX,resY);  		}  		avatar->mImpostor.bindTarget(); @@ -10830,7 +11472,23 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)  	{  		avatar->mImpostor.clear();  		renderGeomDeferred(camera); + +		renderGeomPostDeferred(camera);		 + +		// Shameless hack time: render it all again, +		// this time writing the depth +		// values we need to generate the alpha mask below +		// while preserving the alpha-sorted color rendering +		// from the previous pass +		// +		sImpostorRenderAlphaDepthPass = true; +		// depth-only here... +		// +		gGL.setColorMask(false,false);  		renderGeomPostDeferred(camera); + +		sImpostorRenderAlphaDepthPass = false; +  	}  	else  	{ @@ -10838,10 +11496,26 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)  		glScissor(0, 0, resX, resY);  		avatar->mImpostor.clear();  		renderGeom(camera); + +		// Shameless hack time: render it all again, +		// this time writing the depth +		// values we need to generate the alpha mask below +		// while preserving the alpha-sorted color rendering +		// from the previous pass +		// +		sImpostorRenderAlphaDepthPass = true; + +		// depth-only here... +		// +		gGL.setColorMask(false,false); +		renderGeom(camera); + +		sImpostorRenderAlphaDepthPass = false;  	}  	{ //create alpha mask based on depth buffer (grey out if muted)  		LLFastTimer t(FTM_IMPOSTOR_BACKGROUND); +  		if (LLPipeline::sRenderDeferred)  		{  			GLuint buff = GL_COLOR_ATTACHMENT0; @@ -11226,6 +11900,3 @@ void LLPipeline::restoreHiddenObject( const LLUUID& id )  	}  } - - - diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index f0bebbe20d..fbbcf8f06d 100755 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -295,7 +295,8 @@ public:  	void unbindDeferredShader(LLGLSLShader& shader);  	void renderDeferredLighting(); -	 +	void renderDeferredLightingToRT(LLRenderTarget* target); +  	void generateWaterReflection(LLCamera& camera);  	void generateSunShadow(LLCamera& camera);  	void generateHighlight(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; diff --git a/indra/newview/skins/default/xui/en/panel_tools_texture.xml b/indra/newview/skins/default/xui/en/panel_tools_texture.xml index 5ac2ec2b20..426c0c4915 100644 --- a/indra/newview/skins/default/xui/en/panel_tools_texture.xml +++ b/indra/newview/skins/default/xui/en/panel_tools_texture.xml @@ -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 diff --git a/indra/newview/tests/gpus_results.txt b/indra/newview/tests/gpus_results.txt index 1cd3654446..0d126191f3 100755 --- a/indra/newview/tests/gpus_results.txt +++ b/indra/newview/tests/gpus_results.txt @@ -1394,13 +1394,13 @@ Intel G41  Intel G45                                                                                                supported      1     1     2.1    Intel G45  Intel Graphics Media HD                                                                                  supported      1     1     2.1    Intel Graphics Media HD  Intel HD Graphics                                                                                        supported      2     1     4      Intel HD Graphics -Intel HD Graphics 2000                                                                                   supported      2     0     3.1    Intel HD Graphics 2000 -Intel HD Graphics 3000                                                                                   supported      3     1     3.1    Intel HD Graphics 3000 -Intel HD Graphics 4000                                                                                   supported      3     1     4      Intel HD Graphics 4000 +Intel HD Graphics 2000                                                                                   supported      2     0     4.2    Intel HD Graphics 2000 +Intel HD Graphics 3000                                                                                   supported      3     1     4.2    Intel HD Graphics 3000 +Intel HD Graphics 4000                                                                                   supported      3     1     4.2    Intel HD Graphics 4000  Intel Inc. Intel GMA 950 OpenGL Engine                                                                   supported      0     1     1.4    Intel 950  Intel Inc. Intel GMA X3100 OpenGL Engine                                                                 supported      1     1     2.1    Intel X3100 -Intel Inc. Intel HD Graphics 3000 OpenGL Engine                                                          supported      3     1     3.1    Intel HD Graphics 3000 -Intel Inc. Intel HD Graphics 4000 OpenGL Engine                                                          supported      3     1     4      Intel HD Graphics 4000 +Intel Inc. Intel HD Graphics 3000 OpenGL Engine                                                          supported      3     1     4.2    Intel HD Graphics 3000 +Intel Inc. Intel HD Graphics 4000 OpenGL Engine                                                          supported      3     1     4.2    Intel HD Graphics 4000  Intel Inc. Intel HD Graphics 5000 OpenGL Engine                                                          supported      4     0     4      Intel HD Graphics 5000  Intel Inc. Intel HD Graphics OpenGL Engine                                                               supported      2     1     4      Intel HD Graphics  Intel Intel 845G                                                                                         unsupported    0     1     1.4    Intel 845G @@ -1432,12 +1432,12 @@ Intel Intel(R) G45/G43/G41 Express Chipset  Intel Intel(R) Graphics Media Accelerator HD                                                             supported      1     1     2.1    Intel Graphics Media HD  Intel Intel(R) HD Graphics                                                                               supported      2     1     4      Intel HD Graphics  Intel Intel(R) HD Graphics 100                                                                           supported      2     1     4      Intel HD Graphics -Intel Intel(R) HD Graphics 2000                                                                          supported      2     0     3.1    Intel HD Graphics 2000 -Intel Intel(R) HD Graphics 2500                                                                          supported      2     0     4      Intel HD Graphics 2500 -Intel Intel(R) HD Graphics 3000                                                                          supported      3     1     3.1    Intel HD Graphics 3000 -Intel Intel(R) HD Graphics 4000                                                                          supported      3     1     4      Intel HD Graphics 4000 -Intel Intel(R) HD Graphics 4400                                                                          supported      3     0     4      Intel HD Graphics 4400 -Intel Intel(R) HD Graphics 4600                                                                          supported      3     0     4      Intel HD Graphics 4600 +Intel Intel(R) HD Graphics 2000                                                                          supported      2     0     4.2    Intel HD Graphics 2000 +Intel Intel(R) HD Graphics 2500                                                                          supported      2     0     4.2    Intel HD Graphics 2500 +Intel Intel(R) HD Graphics 3000                                                                          supported      3     1     4.2    Intel HD Graphics 3000 +Intel Intel(R) HD Graphics 4000                                                                          supported      3     1     4.2    Intel HD Graphics 4000 +Intel Intel(R) HD Graphics 4400                                                                          supported      3     0     4.2    Intel HD Graphics 4400 +Intel Intel(R) HD Graphics 4600                                                                          supported      3     0     4.2    Intel HD Graphics 4600  Intel Intel(R) HD Graphics 5000                                                                          supported      4     0     4      Intel HD Graphics 5000  Intel Intel(R) HD Graphics BR-1004-01Y1                                                                  supported      2     1     4      Intel HD Graphics  Intel Intel(R) HD Graphics Family                                                                        supported      2     1     4      Intel HD Graphics @@ -2913,8 +2913,8 @@ Parallels and ATI Technologies Inc. Parallels using ATI Radeon HD 6770M OpenGL E  Parallels and ATI Technologies Inc. Parallels using ATI Radeon HD 6970M OpenGL Engine                    supported      5     1     4.2    ATI Radeon HD 6900  Parallels and ATI Technologies Inc. Parallels using ATI Radeon X1600 OpenGL Engine                       supported      2     1     2.1    ATI Radeon X1600  Parallels and Intel Inc. Parallels using Intel GMA X3100 OpenGL Engine                                   supported      1     1     2.1    Intel X3100 -Parallels and Intel Inc. Parallels using Intel HD Graphics 3000 OpenGL Engine                            supported      3     1     3.1    Intel HD Graphics 3000 -Parallels and Intel Inc. Parallels using Intel HD Graphics 4000 OpenGL Engine                            supported      3     1     4      Intel HD Graphics 4000 +Parallels and Intel Inc. Parallels using Intel HD Graphics 3000 OpenGL Engine                            supported      3     1     4.2    Intel HD Graphics 3000 +Parallels and Intel Inc. Parallels using Intel HD Graphics 4000 OpenGL Engine                            supported      3     1     4.2    Intel HD Graphics 4000  Parallels and NVIDIA Corporation Parallels using NVIDIA GeForce 320M OpenGL Engine                       supported      2     0     3.3    NVIDIA 320M  Parallels and NVIDIA Corporation Parallels using NVIDIA GeForce 8800 GS OpenGL Engine                    supported      3     1     3.3    NVIDIA GeForce 8800  Parallels and NVIDIA Corporation Parallels using NVIDIA GeForce 9400 OpenGL Engine                       supported      3     1     3.3    NVIDIA GeForce 9400 | 
