Microsoft windows builds

From Second Life Wiki
Jump to navigation Jump to search

Index: /branches/shadow-draft/doc/asset_urls.txt

=======================================================

--- /branches/shadow-draft/doc/asset_urls.txt (revision 573) +++ /branches/shadow-draft/doc/asset_urls.txt (revision 575) @@ -2,7 +2,7 @@

# https://wiki.secondlife.com/wiki/Get_source_and_compile

-SLASSET_MD5=http://secondlife.com/developers/opensource/downloads/2008/05/md5sums-shadow-draft-r87567.txt -SLASSET_ART=http://secondlife.com/developers/opensource/downloads/2008/05/slviewer-artwork-shadow-draft-r87567.zip -SLASSET_LIBS_DARWIN=http://secondlife.com/developers/opensource/downloads/2008/05/slviewer-darwin-libs-shadow-draft-r87567.tar.gz -SLASSET_LIBS_WIN32=http://secondlife.com/developers/opensource/downloads/2008/05/slviewer-win32-libs-shadow-draft-r87567.zip -SLASSET_LIBS_LINUXI386=http://secondlife.com/developers/opensource/downloads/2008/05/slviewer-linux-libs-shadow-draft-r87567.tar.gz +SLASSET_MD5=http://secondlife.com/developers/opensource/downloads/2008/05/md5sums-shadow-draft-r87814.txt +SLASSET_ART=http://secondlife.com/developers/opensource/downloads/2008/05/slviewer-artwork-shadow-draft-r87814.zip +SLASSET_LIBS_DARWIN=http://secondlife.com/developers/opensource/downloads/2008/05/slviewer-darwin-libs-shadow-draft-r87814.tar.gz +SLASSET_LIBS_WIN32=http://secondlife.com/developers/opensource/downloads/2008/05/slviewer-win32-libs-shadow-draft-r87814.zip +SLASSET_LIBS_LINUXI386=http://secondlife.com/developers/opensource/downloads/2008/05/slviewer-linux-libs-shadow-draft-r87814.tar.gz Index: /branches/shadow-draft/indra/llcommon/llfasttimer.h

=======================================================

--- /branches/shadow-draft/indra/llcommon/llfasttimer.h (revision 280) +++ /branches/shadow-draft/indra/llcommon/llfasttimer.h (revision 575) @@ -185,9 +185,11 @@

public:

+ static LLFastTimer::EFastTimerType sCurType; +

	LLFastTimer(EFastTimerType type)
	{
#if FAST_TIMER_ON
		mType = type;

- + sCurType = type;

		// These don't get counted, because they use CPU clockticks
		//gTimerBins[gCurTimerBin]++;

Index: /branches/shadow-draft/indra/llcommon/llfasttimer.cpp

=======================================================

--- /branches/shadow-draft/indra/llcommon/llfasttimer.cpp (revision 173) +++ /branches/shadow-draft/indra/llcommon/llfasttimer.cpp (revision 575) @@ -49,4 +49,6 @@

// statics

+ +LLFastTimer::EFastTimerType LLFastTimer::sCurType = LLFastTimer::FTM_OTHER;

int LLFastTimer::sCurDepth = 0;
U64 LLFastTimer::sStart[LLFastTimer::FTM_MAX_DEPTH];

Index: /branches/shadow-draft/indra/newview/lldrawpoolavatar.h

=======================================================

--- /branches/shadow-draft/indra/newview/lldrawpoolavatar.h (revision 280) +++ /branches/shadow-draft/indra/newview/lldrawpoolavatar.h (revision 575) @@ -74,4 +74,19 @@

	/*virtual*/ void renderForSelect();

+ /*virtual*/ S32 getNumDeferredPasses(); + /*virtual*/ void beginDeferredPass(S32 pass); + /*virtual*/ void endDeferredPass(S32 pass); + /*virtual*/ void renderDeferred(S32 pass); + + /*virtual*/ S32 getNumPostDeferredPasses(); + /*virtual*/ void beginPostDeferredPass(S32 pass); + /*virtual*/ void endPostDeferredPass(S32 pass); + /*virtual*/ void renderPostDeferred(S32 pass); + + /*virtual*/ S32 getNumShadowPasses(); + /*virtual*/ void beginShadowPass(S32 pass); + /*virtual*/ void endShadowPass(S32 pass); + /*virtual*/ void renderShadow(S32 pass); +

	void beginRigid();
	void beginFootShadow();

@@ -81,4 +96,12 @@

	void endFootShadow();
	void endSkinned();

+ + void beginDeferredImpostor(); + void beginDeferredRigid(); + void beginDeferredSkinned(); + + void endDeferredImpostor(); + void endDeferredRigid(); + void endDeferredSkinned();

	/*virtual*/ LLViewerImage *getDebugTexture();

@@ -86,4 +109,6 @@

	void renderAvatars(LLVOAvatar *single_avatar, S32 pass = -1); // renders only one avatar if single_avatar is not null.

+ + static BOOL sSkipOpaque;

};

Index: /branches/shadow-draft/indra/newview/lldrawpoolterrain.h

=======================================================

--- /branches/shadow-draft/indra/newview/lldrawpoolterrain.h (revision 280) +++ /branches/shadow-draft/indra/newview/lldrawpoolterrain.h (revision 575) @@ -48,5 +48,5 @@

	};

- virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; } + virtual U32 getVertexDataMask();

	static S32 getDetailMode();

@@ -56,4 +56,13 @@

	/*virtual*/ LLDrawPool *instancePool();

+ /*virtual*/ S32 getNumDeferredPasses() { return 1; } + /*virtual*/ void beginDeferredPass(S32 pass); + /*virtual*/ void endDeferredPass(S32 pass); + /*virtual*/ void renderDeferred(S32 pass); + + /*virtual*/ S32 getNumShadowPasses() { return 1; } + /*virtual*/ void beginShadowPass(S32 pass); + /*virtual*/ void endShadowPass(S32 pass); + /*virtual*/ void renderShadow(S32 pass);

	/*virtual*/ void render(S32 pass = 0);

Index: /branches/shadow-draft/indra/newview/llviewerjointmesh.cpp

=======================================================

--- /branches/shadow-draft/indra/newview/llviewerjointmesh.cpp (revision 573) +++ /branches/shadow-draft/indra/newview/llviewerjointmesh.cpp (revision 575) @@ -459,9 +459,6 @@

			{
				F32* vector = gJointMatUnaligned[joint_num].mMatrix[axis];

- //glProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_ARB, LL_CHARACTER_MAX_JOINTS_PER_MESH * axis + joint_num+5, (GLfloat*)vector);

				U32 offset = LL_CHARACTER_MAX_JOINTS_PER_MESH*axis+joint_num;
				memcpy(mat+offset*4, vector, sizeof(GLfloat)*4);

- //glProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_ARB, LL_CHARACTER_MAX_JOINTS_PER_MESH * axis + joint_num+6, (GLfloat*)vector); - //cgGLSetParameterArray4f(gPipeline.mAvatarMatrix, offset, 1, vector);

			}
		}

Index: /branches/shadow-draft/indra/newview/llviewercontrol.cpp

=======================================================

--- /branches/shadow-draft/indra/newview/llviewercontrol.cpp (revision 573) +++ /branches/shadow-draft/indra/newview/llviewercontrol.cpp (revision 575) @@ -355,5 +355,5 @@

static bool handleRenderUseImpostorsChanged(const LLSD& newvalue)
{

- LLVOAvatar::sUseImpostors = FALSE; //newvalue.asBoolean(); + LLVOAvatar::sUseImpostors = newvalue.asBoolean();

	return true;
}

Index: /branches/shadow-draft/indra/newview/lldrawpoolsimple.h

=======================================================

--- /branches/shadow-draft/indra/newview/lldrawpoolsimple.h (revision 280) +++ /branches/shadow-draft/indra/newview/lldrawpoolsimple.h (revision 575) @@ -49,8 +49,39 @@

	LLDrawPoolSimple();
	

+ /*virtual*/ S32 getNumDeferredPasses() { return 1; } + /*virtual*/ void beginDeferredPass(S32 pass); + /*virtual*/ void endDeferredPass(S32 pass); + /*virtual*/ void renderDeferred(S32 pass); +

	/*virtual*/ void beginRenderPass(S32 pass);
	/*virtual*/ void endRenderPass(S32 pass);
	/// We need two passes so we can handle emissive materials separately.
	/*virtual*/ S32	 getNumPasses() { return 1; }

+ /*virtual*/ void render(S32 pass = 0); + /*virtual*/ void prerender(); + +}; + +class LLDrawPoolFullbright : public LLRenderPass +{ +public: + enum + { + VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX | + LLVertexBuffer::MAP_TEXCOORD | + LLVertexBuffer::MAP_COLOR + }; + virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; } + + LLDrawPoolFullbright(); + + /*virtual*/ S32 getNumPostDeferredPasses() { return 1; } + /*virtual*/ void beginPostDeferredPass(S32 pass) { beginRenderPass(pass); } + /*virtual*/ void endPostDeferredPass(S32 pass) { endRenderPass(pass); } + /*virtual*/ void renderPostDeferred(S32 pass) { render(pass); } + + /*virtual*/ void beginRenderPass(S32 pass); + /*virtual*/ void endRenderPass(S32 pass); + /*virtual*/ S32 getNumPasses();

	/*virtual*/ void render(S32 pass = 0);
	/*virtual*/ void prerender();

@@ -73,4 +104,9 @@

	virtual void prerender() { }

+ /*virtual*/ S32 getNumPostDeferredPasses() { return 1; } + /*virtual*/ void beginPostDeferredPass(S32 pass) { beginRenderPass(pass); } + /*virtual*/ void endPostDeferredPass(S32 pass) { endRenderPass(pass); } + /*virtual*/ void renderPostDeferred(S32 pass) { render(pass); } +

	void render(S32 pass = 0);
	void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture = TRUE);

Index: /branches/shadow-draft/indra/newview/lldrawpoolterrain.cpp

=======================================================

--- /branches/shadow-draft/indra/newview/lldrawpoolterrain.cpp (revision 573) +++ /branches/shadow-draft/indra/newview/lldrawpoolterrain.cpp (revision 575) @@ -100,4 +100,16 @@


+U32 LLDrawPoolTerrain::getVertexDataMask() +{ + if (LLPipeline::sShadowRender) + { + return LLVertexBuffer::MAP_VERTEX; + } + else + { + return VERTEX_DATA_MASK; + } +} +

void LLDrawPoolTerrain::prerender()
{

@@ -217,4 +229,58 @@

}

+void LLDrawPoolTerrain::beginDeferredPass(S32 pass) +{ + LLFastTimer t(LLFastTimer::FTM_RENDER_TERRAIN); + LLFacePool::beginRenderPass(pass); + + sShader = &gDeferredTerrainProgram; + + sShader->bind(); +} + +void LLDrawPoolTerrain::endDeferredPass(S32 pass) +{ + LLFastTimer t(LLFastTimer::FTM_RENDER_TERRAIN); + LLFacePool::endRenderPass(pass); + sShader->unbind(); +} + +void LLDrawPoolTerrain::renderDeferred(S32 pass) +{ + LLFastTimer t(LLFastTimer::FTM_RENDER_TERRAIN); + if (mDrawFace.empty()) + { + return; + } + renderFullShader(); +} + +void LLDrawPoolTerrain::beginShadowPass(S32 pass) +{ + LLFastTimer t(LLFastTimer::FTM_RENDER_TERRAIN); + LLFacePool::beginRenderPass(pass); + LLViewerImage::unbindTexture(0); + gDeferredShadowProgram.bind(); +} + +void LLDrawPoolTerrain::endShadowPass(S32 pass) +{ + LLFastTimer t(LLFastTimer::FTM_RENDER_TERRAIN); + LLFacePool::endRenderPass(pass); + gDeferredShadowProgram.unbind(); +} + +void LLDrawPoolTerrain::renderShadow(S32 pass) +{ + LLFastTimer t(LLFastTimer::FTM_RENDER_TERRAIN); + if (mDrawFace.empty()) + { + return; + } + //LLGLEnable offset(GL_POLYGON_OFFSET); + glCullFace(GL_FRONT); + drawLoop(); + glCullFace(GL_BACK); +}

void LLDrawPoolTerrain::renderFullShader()

Index: /branches/shadow-draft/indra/newview/llvoavatar.cpp

=======================================================

--- /branches/shadow-draft/indra/newview/llvoavatar.cpp (revision 573) +++ /branches/shadow-draft/indra/newview/llvoavatar.cpp (revision 575) @@ -3997,5 +3997,5 @@

				mEyeLashLOD.updateGeometry();
				mHeadLOD.updateGeometry();

- mHairLOD.updateGeometry(); + mHairLOD.updateGeometry();

			}
			mNeedsSkin = FALSE;

@@ -4094,16 +4094,20 @@

	{
		BOOL first_pass = TRUE;

- if (!mIsSelf || gAgent.needsRenderHead()) - { - num_indices += mHeadLOD.render(mAdjustedPixelArea); - first_pass = FALSE; - } - num_indices += mUpperBodyLOD.render(mAdjustedPixelArea, first_pass); - num_indices += mLowerBodyLOD.render(mAdjustedPixelArea, FALSE); - + if (!LLDrawPoolAvatar::sSkipOpaque) + { + if (!mIsSelf || gAgent.needsRenderHead()) + { + num_indices += mHeadLOD.render(mAdjustedPixelArea); + first_pass = FALSE; + } + num_indices += mUpperBodyLOD.render(mAdjustedPixelArea, first_pass); + num_indices += mLowerBodyLOD.render(mAdjustedPixelArea, FALSE); + } + + if (!LLPipeline::sRenderDeferred || LLPipeline::sImpostorRender)

		{
			LLGLEnable blend(GL_BLEND);
			LLGLEnable test(GL_ALPHA_TEST);

- num_indices += renderTransparent(); + num_indices += renderTransparent(first_pass);

		}
	}

@@ -4118,8 +4122,7 @@

}

-U32 LLVOAvatar::renderTransparent() +U32 LLVOAvatar::renderTransparent(BOOL first_pass)

{
	U32 num_indices = 0;

- BOOL first_pass = FALSE;

	if( isWearingWearableType( WT_SKIRT ) )
	{

@@ -9724,5 +9727,5 @@

BOOL LLVOAvatar::needsImpostorUpdate() const
{

- return mNeedsImpostorUpdate ; + return mNeedsImpostorUpdate;

}

Index: /branches/shadow-draft/indra/newview/lldrawpool.h

=======================================================

--- /branches/shadow-draft/indra/newview/lldrawpool.h (revision 515) +++ /branches/shadow-draft/indra/newview/lldrawpool.h (revision 575) @@ -53,4 +53,5 @@

		// Correspond to LLPipeline render type
		POOL_SIMPLE = 1,

+ POOL_FULLBRIGHT,

		POOL_TERRAIN,	
		POOL_TREE,

@@ -78,5 +79,21 @@

	virtual void beginRenderPass( S32 pass );
	virtual void endRenderPass( S32 pass );

- virtual S32 getNumPasses() { return 1; } + virtual S32 getNumPasses(); + + virtual void beginDeferredPass(S32 pass); + virtual void endDeferredPass(S32 pass); + virtual S32 getNumDeferredPasses(); + virtual void renderDeferred(S32 pass = 0); + + virtual void beginPostDeferredPass(S32 pass); + virtual void endPostDeferredPass(S32 pass); + virtual S32 getNumPostDeferredPasses(); + virtual void renderPostDeferred(S32 pass = 0); + + virtual void beginShadowPass(S32 pass); + virtual void endShadowPass(S32 pass); + virtual S32 getNumShadowPasses(); + virtual void renderShadow(S32 pass = 0); +

	virtual void render(S32 pass = 0) = 0;
	virtual void prerender() = 0;

Index: /branches/shadow-draft/indra/newview/llspatialpartition.h

=======================================================

--- /branches/shadow-draft/indra/newview/llspatialpartition.h (revision 280) +++ /branches/shadow-draft/indra/newview/llspatialpartition.h (revision 575) @@ -54,4 +54,7 @@

S32 AABBSphereIntersect(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &rad);

+// get index buffer for binary encoded axis vertex buffer given a box at center being viewed by given camera +U8* get_box_fan_indices(LLCamera* camera, const LLVector3& center); +

class LLDrawInfo : public LLRefCount 
{

Index: /branches/shadow-draft/indra/newview/llviewerjoint.cpp

=======================================================

--- /branches/shadow-draft/indra/newview/llviewerjoint.cpp (revision 573) +++ /branches/shadow-draft/indra/newview/llviewerjoint.cpp (revision 575) @@ -260,4 +260,8 @@

			triangle_count += drawShape( pixelArea, first_pass );
		}

+ else if (LLPipeline::sShadowRender) + { + triangle_count += drawShape(pixelArea, first_pass); + }

		else if ( isTransparent() && !LLPipeline::sReflectionRender)
		{

@@ -278,5 +282,5 @@

				}
				// third past respects z buffer and writes color

- gGL.setColorMask(true, false); + gGL.setColorMask(true, LLPipeline::sRenderDeferred);

				{
					LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);

Index: /branches/shadow-draft/indra/newview/llvovolume.cpp

=======================================================

--- /branches/shadow-draft/indra/newview/llvovolume.cpp (revision 515) +++ /branches/shadow-draft/indra/newview/llvovolume.cpp (revision 575) @@ -2425,4 +2425,5 @@

				BOOL is_alpha = facep->getPoolType() == LLDrawPool::POOL_ALPHA ? TRUE : FALSE;

+

				if (!is_alpha 
					&& gPipeline.canUseWindLightShadersOnObjects()

@@ -2434,4 +2435,8 @@

						registerFace(group, facep, LLRenderPass::PASS_INVISI_SHINY);
						registerFace(group, facep, LLRenderPass::PASS_INVISIBLE);

+ } + else if (LLPipeline::sRenderDeferred) + { + registerFace(group, facep, LLRenderPass::PASS_SIMPLE);

					}
					else if (fullbright)

Index: /branches/shadow-draft/indra/newview/pipeline.h

=======================================================

--- /branches/shadow-draft/indra/newview/pipeline.h (revision 536) +++ /branches/shadow-draft/indra/newview/pipeline.h (revision 575) @@ -57,4 +57,5 @@

class LLCullResult;
class LLVOAvatar;

+class LLGLSLShader;

typedef enum e_avatar_skinning_method

@@ -75,4 +76,5 @@

glh::matrix4f gl_ortho(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat znear, GLfloat zfar);
glh::matrix4f gl_perspective(GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar);

+glh::matrix4f gl_lookat(LLVector3 eye, LLVector3 center, LLVector3 up);

class LLPipeline

@@ -88,4 +90,5 @@

	void releaseGLBuffers();
	void createGLBuffers();

+ void allocateScreenBuffer(U32 resX, U32 resY);

	void resetVertexBuffers(LLDrawable* drawable);

@@ -182,8 +185,14 @@

	void renderGeom(LLCamera& camera, BOOL forceVBOUpdate = FALSE);

- void renderGeomDeferred(); - + void renderGeomDeferred(LLCamera& camera); + void renderGeomPostDeferred(LLCamera& camera); + void renderGeomShadow(LLCamera& camera); + void bindDeferredShader(LLGLSLShader& shader); + void unbindDeferredShader(LLGLSLShader& shader); + void renderDeferredLighting(); +

	void processImagery(LLCamera& camera);
	void generateWaterReflection(LLCamera& camera);

+ void generateSunShadow(LLCamera& camera);

	void renderHighlights();
	void renderDebug();

@@ -286,4 +295,5 @@

		RENDER_TYPE_TERRAIN		= LLDrawPool::POOL_TERRAIN,
		RENDER_TYPE_SIMPLE		= LLDrawPool::POOL_SIMPLE,

+ RENDER_TYPE_FULLBRIGHT = LLDrawPool::POOL_FULLBRIGHT,

		RENDER_TYPE_BUMP		= LLDrawPool::POOL_BUMP,
		RENDER_TYPE_AVATAR		= LLDrawPool::POOL_AVATAR,

@@ -371,4 +381,5 @@

	static BOOL				sUseFBO;
	static BOOL				sUseFarClip;

+ static BOOL sShadowRender;

	static BOOL				sSkipUpdate; //skip lod updates
	static BOOL				sDynamicReflections;

@@ -381,8 +392,17 @@

	static BOOL				sTextureBindTest;
	static BOOL				sRenderFrameTest;

- + static BOOL sRenderDeferred; + static S32 sVisibleLightCount; +

	//screen texture
	LLRenderTarget			mScreen;

- + LLRenderTarget mDeferredScreen; + LLRenderTarget mDeferredLight; + + //sun shadow map + LLRenderTarget mSunShadow; + glh::matrix4f mSunShadowMatrix[3]; + LLVector3 mSunClipPlanes; +

	LLVector2				mScreenScale;

@@ -406,4 +426,7 @@

	GLuint					mBlurCubeBuffer[3];
	GLuint					mBlurCubeTexture[3];

+ + //noise map + GLuint mNoiseMap;

	//frambuffer object for rendering dynamic cube maps

@@ -517,4 +540,5 @@

	LLDrawPool*					mGroundPool;
	LLRenderPass*				mSimplePool;

+ LLRenderPass* mFullbrightPool;

	LLDrawPool*					mInvisiblePool;
	LLDrawPool*					mGlowPool;

Index: /branches/shadow-draft/indra/newview/llviewermenu.cpp

=======================================================

--- /branches/shadow-draft/indra/newview/llviewermenu.cpp (revision 543) +++ /branches/shadow-draft/indra/newview/llviewermenu.cpp (revision 575) @@ -1207,4 +1207,5 @@

	menu->append(new LLMenuItemCheckGL("Show Time", menu_toggle_control, NULL, menu_check_control, (void*)"DebugShowTime"));
	menu->append(new LLMenuItemCheckGL("Show Render Info", menu_toggle_control, NULL, menu_check_control, (void*)"DebugShowRenderInfo"));

+ menu->append(new LLMenuItemCheckGL("Show Matrices", menu_toggle_control, NULL, menu_check_control, (void*)"DebugShowRenderMatrices"));

	menu->append(new LLMenuItemCheckGL("Show Color Under Cursor", menu_toggle_control, NULL, menu_check_control, (void*)"DebugShowColor"));
	

Index: /branches/shadow-draft/indra/newview/llviewerwindow.cpp

=======================================================

--- /branches/shadow-draft/indra/newview/llviewerwindow.cpp (revision 573) +++ /branches/shadow-draft/indra/newview/llviewerwindow.cpp (revision 575) @@ -584,7 +584,44 @@

			ypos += y_inc;

+ addText(xpos,ypos, llformat("%d Lights visible", LLPipeline::sVisibleLightCount)); + + ypos += y_inc; +

			LLVertexBuffer::sBindCount = LLImageGL::sBindCount = 
				LLVertexBuffer::sSetCount = LLImageGL::sUniqueCount = 

- gPipeline.mNumVisibleNodes = 0; + gPipeline.mNumVisibleNodes = LLPipeline::sVisibleLightCount = 0; + } + if (gSavedSettings.getBOOL("DebugShowRenderMatrices")) + { + addText(xpos, ypos, llformat("%.4f .%4f  %.4f  %.4f", gGLProjection[12], gGLProjection[13], gGLProjection[14], gGLProjection[15])); + ypos += y_inc; + + addText(xpos, ypos, llformat("%.4f .%4f  %.4f  %.4f", gGLProjection[8], gGLProjection[9], gGLProjection[10], gGLProjection[11])); + ypos += y_inc; + + addText(xpos, ypos, llformat("%.4f .%4f  %.4f  %.4f", gGLProjection[4], gGLProjection[5], gGLProjection[6], gGLProjection[7])); + ypos += y_inc; + + addText(xpos, ypos, llformat("%.4f .%4f  %.4f  %.4f", gGLProjection[0], gGLProjection[1], gGLProjection[2], gGLProjection[3])); + ypos += y_inc; + + addText(xpos, ypos, "Projection Matrix"); + ypos += y_inc; + + + addText(xpos, ypos, llformat("%.4f .%4f  %.4f  %.4f", gGLModelView[12], gGLModelView[13], gGLModelView[14], gGLModelView[15])); + ypos += y_inc; + + addText(xpos, ypos, llformat("%.4f .%4f  %.4f  %.4f", gGLModelView[8], gGLModelView[9], gGLModelView[10], gGLModelView[11])); + ypos += y_inc; + + addText(xpos, ypos, llformat("%.4f .%4f  %.4f  %.4f", gGLModelView[4], gGLModelView[5], gGLModelView[6], gGLModelView[7])); + ypos += y_inc; + + addText(xpos, ypos, llformat("%.4f .%4f  %.4f  %.4f", gGLModelView[0], gGLModelView[1], gGLModelView[2], gGLModelView[3])); + ypos += y_inc; + + addText(xpos, ypos, "View Matrix"); + ypos += y_inc;

		}
		if (gSavedSettings.getBOOL("DebugShowColor"))

Index: /branches/shadow-draft/indra/newview/llviewercamera.cpp

=======================================================

--- /branches/shadow-draft/indra/newview/llviewercamera.cpp (revision 431) +++ /branches/shadow-draft/indra/newview/llviewercamera.cpp (revision 575) @@ -86,4 +86,19 @@

}

+glh::matrix4f gl_lookat(LLVector3 eye, LLVector3 center, LLVector3 up) +{ + LLVector3 f = center-eye; + f.normVec(); + up.normVec(); + LLVector3 s = f % up; + LLVector3 u = s % f; + + return glh::matrix4f(s[0], s[1], s[2], 0, + u[0], u[1], u[2], 0, + -f[0], -f[1], -f[2], 0, + 0, 0, 0, 1); + +} +

LLViewerCamera::LLViewerCamera() : LLCamera()
{

@@ -192,5 +207,5 @@

//static

-void LLViewerCamera::updateFrustumPlanes(LLCamera& camera, BOOL ortho, BOOL zflip) +void LLViewerCamera::updateFrustumPlanes(LLCamera& camera, BOOL ortho, BOOL zflip, BOOL no_hacks)

{
	GLint* viewport = (GLint*) gGLViewport;

@@ -201,5 +216,25 @@

	LLVector3 frust[8];

- if (zflip) + if (no_hacks) + { + gluUnProject(viewport[0],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ); + frust[0].setVec((F32)objX,(F32)objY,(F32)objZ); + gluUnProject(viewport[0]+viewport[2],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ); + frust[1].setVec((F32)objX,(F32)objY,(F32)objZ); + gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ); + frust[2].setVec((F32)objX,(F32)objY,(F32)objZ); + gluUnProject(viewport[0],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ); + frust[3].setVec((F32)objX,(F32)objY,(F32)objZ); + + gluUnProject(viewport[0],viewport[1],1,model,proj,viewport,&objX,&objY,&objZ); + frust[4].setVec((F32)objX,(F32)objY,(F32)objZ); + gluUnProject(viewport[0]+viewport[2],viewport[1],1,model,proj,viewport,&objX,&objY,&objZ); + frust[5].setVec((F32)objX,(F32)objY,(F32)objZ); + gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],1,model,proj,viewport,&objX,&objY,&objZ); + frust[6].setVec((F32)objX,(F32)objY,(F32)objZ); + gluUnProject(viewport[0],viewport[1]+viewport[3],1,model,proj,viewport,&objX,&objY,&objZ); + frust[7].setVec((F32)objX,(F32)objY,(F32)objZ); + } + else if (zflip)

	{
		gluUnProject(viewport[0],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ);

@@ -241,5 +276,5 @@

		if (ortho)
		{

- LLVector3 far_shift = LLVector3(camera.getFar()*2.0f,0,0); + LLVector3 far_shift = camera.getAtAxis()*camera.getFar()*2.f;

			for (U32 i = 0; i < 4; i++)
			{

@@ -381,5 +416,5 @@

	updateFrustumPlanes(*this);

- if (gSavedSettings.getBOOL("CameraOffset")) + /*if (gSavedSettings.getBOOL("CameraOffset"))

	{
		glMatrixMode(GL_PROJECTION);

@@ -387,5 +422,5 @@

		glRotatef(20.0,1,0,0);
		glMatrixMode(GL_MODELVIEW);

- } + }*/

}

Index: /branches/shadow-draft/indra/newview/lldrawpoolwater.cpp

=======================================================

--- /branches/shadow-draft/indra/newview/lldrawpoolwater.cpp (revision 573) +++ /branches/shadow-draft/indra/newview/lldrawpoolwater.cpp (revision 575) @@ -59,4 +59,6 @@

static float sTime;

+BOOL deferred_render = FALSE; +

BOOL LLDrawPoolWater::sSkipScreenCopy = FALSE;
BOOL LLDrawPoolWater::sNeedsReflectionUpdate = TRUE;

@@ -119,4 +121,16 @@

	return 0;

+} + +void LLDrawPoolWater::beginPostDeferredPass(S32 pass) +{ + beginRenderPass(pass); + deferred_render = TRUE; +} + +void LLDrawPoolWater::endPostDeferredPass(S32 pass) +{ + endRenderPass(pass); + deferred_render = FALSE;

}

@@ -375,5 +389,9 @@

	F32 eyedepth = LLViewerCamera::getInstance()->getOrigin().mV[2] - gAgent.getRegion()->getWaterHeight();
	

- if (eyedepth < 0.f && LLPipeline::sWaterReflections) + if (deferred_render) + { + shader = &gDeferredWaterProgram; + } + else if (eyedepth < 0.f && LLPipeline::sWaterReflections)

	{
		shader = &gUnderWaterProgram;

@@ -412,8 +430,4 @@

	S32 screentex = shader->enableTexture(LLShaderMgr::WATER_SCREENTEX);	

- stop_glerror(); - - shader->bind(); -

	if (screentex > -1)
	{

@@ -421,7 +435,17 @@

		shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY, 
			param_mgr->getFogDensity());

- } - - gPipeline.mWaterDis.bindTexture(); + gPipeline.mWaterDis.bindTexture(); + } + + stop_glerror(); + + if (deferred_render) + { + gPipeline.bindDeferredShader(*shader); + } + else + { + shader->bind(); + }

	if (mVertexShaderLevel == 1)

@@ -534,5 +558,13 @@

	shader->disableTexture(LLShaderMgr::WATER_REFTEX);
	shader->disableTexture(LLShaderMgr::WATER_SCREENDEPTH);

- shader->unbind(); + + if (deferred_render) + { + gPipeline.unbindDeferredShader(*shader); + } + else + { + shader->unbind(); + }

	gGL.getTexUnit(0)->activate();

Index: /branches/shadow-draft/indra/newview/llviewercamera.h

=======================================================

--- /branches/shadow-draft/indra/newview/llviewercamera.h (revision 431) +++ /branches/shadow-draft/indra/newview/llviewercamera.h (revision 575) @@ -63,5 +63,5 @@

								const LLVector3 &point_of_interest);

- static void updateFrustumPlanes(LLCamera& camera, BOOL ortho = FALSE, BOOL zflip = FALSE); + static void updateFrustumPlanes(LLCamera& camera, BOOL ortho = FALSE, BOOL zflip = FALSE, BOOL no_hacks = FALSE);

	void setPerspective(BOOL for_selection, S32 x, S32 y_from_bot, S32 width, S32 height, BOOL limit_select_distance, F32 z_near = 0, F32 z_far = 0);

Index: /branches/shadow-draft/indra/newview/lldrawpoolwater.h

=======================================================

--- /branches/shadow-draft/indra/newview/lldrawpoolwater.h (revision 387) +++ /branches/shadow-draft/indra/newview/lldrawpoolwater.h (revision 575) @@ -70,4 +70,9 @@

	/*virtual*/ LLDrawPool *instancePool();
	static void restoreGL();

+ + /*virtual*/ S32 getNumPostDeferredPasses() { return getNumPasses(); } + /*virtual*/ void beginPostDeferredPass(S32 pass); + /*virtual*/ void endPostDeferredPass(S32 pass); + /*virtual*/ void renderPostDeferred(S32 pass) { render(pass); }

	/*virtual*/ S32 getNumPasses();

Index: /branches/shadow-draft/indra/newview/pipeline.cpp

=======================================================

--- /branches/shadow-draft/indra/newview/pipeline.cpp (revision 573) +++ /branches/shadow-draft/indra/newview/pipeline.cpp (revision 575) @@ -219,4 +219,5 @@

BOOL	LLPipeline::sRenderBump = TRUE;
BOOL	LLPipeline::sUseFarClip = TRUE;

+BOOL LLPipeline::sShadowRender = FALSE;

BOOL	LLPipeline::sSkipUpdate = FALSE;
BOOL	LLPipeline::sDynamicReflections = FALSE;

@@ -228,4 +229,6 @@

BOOL	LLPipeline::sTextureBindTest = FALSE;
BOOL	LLPipeline::sRenderFrameTest = FALSE;

+BOOL LLPipeline::sRenderDeferred = FALSE; +S32 LLPipeline::sVisibleLightCount = 0;

static LLCullResult* sCull = NULL;

@@ -242,4 +245,11 @@

void validate_framebuffer_object();

+ +void addDeferredAttachments(LLRenderTarget& target) +{ + target.addColorAttachment(GL_RGBA); //specular + target.addColorAttachment(GL_RGB16F_ARB); //normal + target.addColorAttachment(GL_RGBA32F_ARB); //position +}

LLPipeline::LLPipeline() :

@@ -255,4 +265,5 @@

	mGroundPool(NULL),
	mSimplePool(NULL),

+ mFullbrightPool(NULL),

	mInvisiblePool(NULL),
	mGlowPool(NULL),

@@ -268,4 +279,5 @@

	//mDepthbuffer[0] = mDepthbuffer[1] = 0;
	mCubeFrameBuffer = 0;

+ mNoiseMap = 0;

	mCubeDepth = 0;
}

@@ -285,4 +297,5 @@

	getPool(LLDrawPool::POOL_ALPHA);
	getPool(LLDrawPool::POOL_SIMPLE);

+ getPool(LLDrawPool::POOL_FULLBRIGHT);

	getPool(LLDrawPool::POOL_INVISIBLE);
	getPool(LLDrawPool::POOL_BUMP);

@@ -362,4 +375,6 @@

	delete mSimplePool;
	mSimplePool = NULL;

+ delete mFullbrightPool; + mFullbrightPool = NULL;

	delete mInvisiblePool;
	mInvisiblePool = NULL;

@@ -419,6 +434,6 @@

		}
	

- mScreen.release(); - mScreen.allocate(resX, resY, GL_RGBA, TRUE, GL_TEXTURE_RECTANGLE_ARB); + + allocateScreenBuffer(resX,resY);

		llinfos << "RESIZED SCREEN TEXTURE: " << resX << "x" << resY << llendl;

@@ -426,4 +441,15 @@

}

+void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) +{ + mScreen.allocate(resX, resY, GL_RGBA, TRUE, GL_TEXTURE_RECTANGLE_ARB); + if (LLPipeline::sRenderDeferred) + { + //allocate deferred rendering color buffers + mDeferredScreen.allocate(resX, resY, GL_RGBA, TRUE, GL_TEXTURE_RECTANGLE_ARB); + addDeferredAttachments(mDeferredScreen); + mDeferredLight.allocate(resX, resY, GL_RGBA, FALSE, GL_TEXTURE_RECTANGLE_ARB); + } +}

void LLPipeline::releaseGLBuffers()

@@ -431,4 +457,10 @@

	assertInitialized();
	

+ if (mNoiseMap) + { + glDeleteTextures(1, &mNoiseMap); + mNoiseMap = 0; + } +

	if (mCubeBuffer)
	{

@@ -464,4 +496,6 @@

	mWaterDis.release();
	mScreen.release();

+ mDeferredScreen.release(); + mSunShadow.release();

	for (U32 i = 0; i < 3; i++)

@@ -559,5 +593,30 @@

	GLuint resY = gViewerWindow->getWindowDisplayHeight();
	

- mScreen.allocate(resX, resY, GL_RGBA, TRUE, GL_TEXTURE_RECTANGLE_ARB); + allocateScreenBuffer(resX,resY); + + if (sRenderDeferred) + { + mSunShadow.allocate(1024,1024, GL_RGB32F_ARB, TRUE); + + if (!mNoiseMap) + { + const U32 noiseRes = 128; + LLVector3 noise[noiseRes*noiseRes]; + + for (U32 i = 0; i < noiseRes*noiseRes; ++i) + { + noise[i] = LLVector3(ll_frand()-0.5f, + ll_frand()-0.5f, + ll_frand()-0.5f); + noise[i].normVec(); + } + + glGenTextures(1, &mNoiseMap); + glBindTexture(GL_TEXTURE_2D, mNoiseMap); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F_ARB, noiseRes, noiseRes, 0, GL_RGB, GL_FLOAT, noise); + } + }

}

@@ -747,4 +806,8 @@

		break;

+ case LLDrawPool::POOL_FULLBRIGHT: + poolp = mFullbrightPool; + break; +

	case LLDrawPool::POOL_INVISIBLE:
		poolp = mInvisiblePool;

@@ -1165,5 +1228,12 @@

	if (to_texture)
	{

- mScreen.bindTarget(); + if (LLPipeline::sRenderDeferred) + { + mDeferredScreen.bindTarget(); + } + else + { + mScreen.bindTarget(); + }

	}

@@ -1177,5 +1247,9 @@

	LLViewerImage::unbindTexture(0, GL_TEXTURE_2D);

- gGL.setColorMask(false, false); + if (sUseOcclusion > 1) + { + gGL.setColorMask(false, false); + } +

	LLGLDepthTest depth(GL_TRUE, GL_FALSE);

@@ -1235,10 +1309,24 @@

	}
	

- gGL.setColorMask(true, false); +

	glPopMatrix();

+ if (sUseOcclusion > 1) + { + gGL.setColorMask(true, false); + } +

	if (to_texture)
	{
		mScreen.flush();

+ + if (LLPipeline::sRenderDeferred) + { + mDeferredScreen.flush(); + } + else + { + mScreen.flush(); + }

		LLRenderTarget::unbindTarget();
	}

@@ -1310,4 +1398,5 @@

{
	LLVertexBuffer::unbind();

+

	if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION))
	{

@@ -2315,7 +2404,13 @@

	//	
	stop_glerror();

- BOOL occlude = sUseOcclusion > 1; - - U32 cur_type = 0; + + for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) + { + LLDrawPool *poolp = *iter; + if (hasRenderType(poolp->getType())) + { + poolp->prerender(); + } + }

	if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PICKING))

@@ -2323,21 +2418,13 @@

		gObjectList.renderObjectsForSelect(camera);
	}

- else if (gSavedSettings.getBOOL("RenderDeferred")) - { - renderGeomDeferred(); + else if (sRenderDeferred) + { + renderGeomDeferred(camera);

	}
	else
	{

- for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) - { - LLDrawPool *poolp = *iter; - if (hasRenderType(poolp->getType())) - { - poolp->prerender(); - } - } - -

		LLFastTimer t(LLFastTimer::FTM_POOLS);

+ BOOL occlude = sUseOcclusion > 1; + U32 cur_type = 0;

		calcNearbyLights(camera);
		setupHWLights(NULL);

@@ -2368,4 +2455,5 @@

				for( S32 i = 0; i < poolp->getNumPasses(); i++ )
				{

+ LLVertexBuffer::unbind();

					poolp->beginRenderPass(i);
					for (iter2 = iter1; iter2 != mPools.end(); iter2++)

@@ -2410,4 +2498,16 @@

			stop_glerror();
		}

+ LLVertexBuffer::unbind(); + + gGLLastMatrix = NULL; + glLoadMatrixd(gGLModelView); + + if (occlude) + { + occlude = FALSE; + gGLLastMatrix = NULL; + glLoadMatrixd(gGLModelView); + doOcclusion(camera); + }

	}

@@ -2417,6 +2517,218 @@

	LLGLState::checkClientArrays();

+ + + stop_glerror(); + + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); + LLGLState::checkClientArrays(); + + if (!sReflectionRender) + { + renderHighlights(); + } + + // Contains a list of the faces of objects that are physical or + // have touch-handlers. + mHighlightFaces.clear(); + + renderDebug(); + + LLVertexBuffer::unbind(); + + if (!LLPipeline::sReflectionRender && !LLPipeline::sRenderDeferred && gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) + { + // Render debugging beacons. + gObjectList.renderObjectBeacons(); + LLHUDObject::renderAll(); + gObjectList.resetObjectBeacons(); + } + + //HACK: preserve/restore matrices around HUD render + if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) + { + for (U32 i = 0; i < 16; i++) + { + gGLModelView[i] = saved_modelview[i]; + gGLProjection[i] = saved_projection[i]; + } + } + + LLVertexBuffer::unbind(); + + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); + LLGLState::checkClientArrays(); +} + +void LLPipeline::renderGeomDeferred(LLCamera& camera) +{ + LLFastTimer t(LLFastTimer::FTM_POOLS); + U32 cur_type = 0; + + gGL.setColorMask(true, true); + + pool_set_t::iterator iter1 = mPools.begin(); + + while ( iter1 != mPools.end() ) + { + LLDrawPool *poolp = *iter1; + + cur_type = poolp->getType(); + + pool_set_t::iterator iter2 = iter1; + if (hasRenderType(poolp->getType()) && poolp->getNumDeferredPasses() > 0) + { + LLFastTimer t(LLFastTimer::FTM_POOLRENDER); + + gGLLastMatrix = NULL; + glLoadMatrixd(gGLModelView); + + for( S32 i = 0; i < poolp->getNumDeferredPasses(); i++ ) + { + LLVertexBuffer::unbind(); + poolp->beginDeferredPass(i); + for (iter2 = iter1; iter2 != mPools.end(); iter2++) + { + LLDrawPool *p = *iter2; + if (p->getType() != cur_type) + { + break; + } + + p->renderDeferred(i); + } + poolp->endDeferredPass(i); + LLVertexBuffer::unbind(); + + GLint depth; + glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &depth); + if (depth > 3) + { + llerrs << "GL matrix stack corrupted!" << llendl; + } + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); + LLGLState::checkClientArrays(); + } + } + else + { + // Skip all pools of this type + for (iter2 = iter1; iter2 != mPools.end(); iter2++) + { + LLDrawPool *p = *iter2; + if (p->getType() != cur_type) + { + break; + } + } + } + iter1 = iter2; + stop_glerror(); + } +

	gGLLastMatrix = NULL;
	glLoadMatrixd(gGLModelView);

+ + gGL.setColorMask(true, false); +} + +void LLPipeline::renderGeomPostDeferred(LLCamera& camera) +{ + LLFastTimer t(LLFastTimer::FTM_POOLS); + U32 cur_type = 0; + + calcNearbyLights(camera); + setupHWLights(NULL); + + pool_set_t::iterator iter1 = mPools.begin(); + BOOL occlude = LLPipeline::sUseOcclusion > 1; + + while ( iter1 != mPools.end() ) + { + LLDrawPool *poolp = *iter1; + + cur_type = poolp->getType(); + + if (occlude && cur_type > LLDrawPool::POOL_AVATAR) + { + occlude = FALSE; + gGLLastMatrix = NULL; + glLoadMatrixd(gGLModelView); + doOcclusion(camera); + gGL.setColorMask(true, true); + } + + pool_set_t::iterator iter2 = iter1; + if (hasRenderType(poolp->getType()) && poolp->getNumPostDeferredPasses() > 0) + { + LLFastTimer t(LLFastTimer::FTM_POOLRENDER); + + gGLLastMatrix = NULL; + glLoadMatrixd(gGLModelView); + + for( S32 i = 0; i < poolp->getNumPostDeferredPasses(); i++ ) + { + LLVertexBuffer::unbind(); + poolp->beginPostDeferredPass(i); + for (iter2 = iter1; iter2 != mPools.end(); iter2++) + { + LLDrawPool *p = *iter2; + if (p->getType() != cur_type) + { + break; + } + + p->renderPostDeferred(i); + } + poolp->endPostDeferredPass(i); + LLVertexBuffer::unbind(); + + GLint depth; + glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &depth); + if (depth > 3) + { + llerrs << "GL matrix stack corrupted!" << llendl; + } + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); + LLGLState::checkClientArrays(); + } + } + else + { + // Skip all pools of this type + for (iter2 = iter1; iter2 != mPools.end(); iter2++) + { + LLDrawPool *p = *iter2; + if (p->getType() != cur_type) + { + break; + } + } + } + iter1 = iter2; + stop_glerror(); + } + + gGLLastMatrix = NULL; + glLoadMatrixd(gGLModelView); + + renderHighlights(); + mHighlightFaces.clear(); + + renderDebug(); + + LLVertexBuffer::unbind(); + + if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) + { + // Render debugging beacons. + gObjectList.renderObjectBeacons(); + LLHUDObject::renderAll(); + gObjectList.resetObjectBeacons(); + }

	if (occlude)

@@ -2427,55 +2739,78 @@

		doOcclusion(camera);
	}

- - stop_glerror(); - - LLGLState::checkStates(); - LLGLState::checkTextureChannels(); - LLGLState::checkClientArrays(); - - if (!sReflectionRender) - { - renderHighlights(); - } - - // Contains a list of the faces of objects that are physical or - // have touch-handlers. - mHighlightFaces.clear(); - - renderDebug(); - - LLVertexBuffer::unbind(); - - if (!LLPipeline::sReflectionRender && gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) - { - // Render debugging beacons. - gObjectList.renderObjectBeacons(); - LLHUDObject::renderAll(); - gObjectList.resetObjectBeacons(); - } - - //HACK: preserve/restore matrices around HUD render - if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) - { - for (U32 i = 0; i < 16; i++) - { - gGLModelView[i] = saved_modelview[i]; - gGLProjection[i] = saved_projection[i]; - } - } - - LLVertexBuffer::unbind(); - - LLGLState::checkStates(); - LLGLState::checkTextureChannels(); - LLGLState::checkClientArrays(); -} - -void LLPipeline::renderGeomDeferred() -{ - gDeferredDiffuseProgram.bind(); - gPipeline.renderObjects(LLRenderPass::PASS_SIMPLE, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_NORMAL, TRUE); - gDeferredDiffuseProgram.unbind(); -} +} + +void LLPipeline::renderGeomShadow(LLCamera& camera) +{ + LLFastTimer t(LLFastTimer::FTM_POOLS); + U32 cur_type = 0; + + pool_set_t::iterator iter1 = mPools.begin(); + + while ( iter1 != mPools.end() ) + { + LLDrawPool *poolp = *iter1; + + cur_type = poolp->getType(); + + pool_set_t::iterator iter2 = iter1; + if (hasRenderType(poolp->getType()) && poolp->getNumShadowPasses() > 0) + { + LLFastTimer t(LLFastTimer::FTM_POOLRENDER); + + gGLLastMatrix = NULL; + glLoadMatrixd(gGLModelView); + + for( S32 i = 0; i < poolp->getNumShadowPasses(); i++ ) + { + LLVertexBuffer::unbind(); + poolp->beginShadowPass(i); + for (iter2 = iter1; iter2 != mPools.end(); iter2++) + { + LLDrawPool *p = *iter2; + if (p->getType() != cur_type) + { + break; + } + + p->renderShadow(i); + } + poolp->endShadowPass(i); + LLVertexBuffer::unbind(); +#ifndef LL_RELEASE_FOR_DOWNLOAD +# if LL_DEBUG_GL + GLint depth; + glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &depth); + if (depth > 3) + { + llerrs << "GL matrix stack corrupted!" << llendl; + } + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); + LLGLState::checkClientArrays(); +# endif +#endif + } + } + else + { + // Skip all pools of this type + for (iter2 = iter1; iter2 != mPools.end(); iter2++) + { + LLDrawPool *p = *iter2; + if (p->getType() != cur_type) + { + break; + } + } + } + iter1 = iter2; + stop_glerror(); + } + + gGLLastMatrix = NULL; + glLoadMatrixd(gGLModelView); +} +

void LLPipeline::addTrianglesDrawn(S32 count)

@@ -2807,4 +3142,16 @@

		break;

+ case LLDrawPool::POOL_FULLBRIGHT: + if (mFullbrightPool) + { + llassert(0); + llwarns << "Ignoring duplicate simple pool." << llendl; + } + else + { + mFullbrightPool = (LLRenderPass*) new_poolp; + } + break; +

	case LLDrawPool::POOL_INVISIBLE:
		if (mInvisiblePool)

@@ -2938,4 +3285,9 @@

		llassert(mSimplePool == poolp);
		mSimplePool = NULL;

+ break; + + case LLDrawPool::POOL_FULLBRIGHT: + llassert(mFullbrightPool == poolp); + mFullbrightPool = NULL;

		break;

@@ -4131,4 +4483,5 @@

	U32 cube_mask = (1 << LLPipeline::RENDER_TYPE_SIMPLE) |

+ (1 << LLPipeline::RENDER_TYPE_FULLBRIGHT) |

					(1 << LLPipeline::RENDER_TYPE_WATER) |
					//(1 << LLPipeline::RENDER_TYPE_BUMP) |

@@ -4641,68 +4994,4 @@

	gViewerWindow->setupViewport();

- /*mGlow[1].bindTexture(); - { - LLGLEnable stencil(GL_STENCIL_TEST); - glStencilFunc(GL_NOTEQUAL, 255, 0xFFFFFFFF); - glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); - LLGLDisable blend(GL_BLEND); - - gGL.begin(LLVertexBuffer::TRIANGLE_STRIP); - gGL.color4f(1,1,1,1); - gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); - gGL.vertex2f(-1,-1); - - gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); - gGL.vertex2f(-1,1); - - gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); - gGL.vertex2f(1,-1); - - gGL.texCoord2f(tc2.mV[0], tc2.mV[1]); - gGL.vertex2f(1,1); - gGL.end(); - - gGL.flush(); - } - - if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_GLOW)) - { - tc2.setVec((F32) gViewerWindow->getWindowDisplayWidth(), - (F32) gViewerWindow->getWindowDisplayHeight()); - - if (res_mod > 1) - { - tc2 /= (F32) res_mod; - } - - LLGLEnable blend(GL_BLEND); - gGL.blendFunc(GL_ONE, GL_ONE); - - glDisable(GL_TEXTURE_2D); - glEnable(GL_TEXTURE_RECTANGLE_ARB); - mScreen.bindTexture(); - - gGL.begin(LLVertexBuffer::TRIANGLE_STRIP); - gGL.color4f(1,1,1,1); - gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); - gGL.vertex2f(-1,-1); - - gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); - gGL.vertex2f(-1,1); - - gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); - gGL.vertex2f(1,-1); - - gGL.texCoord2f(tc2.mV[0], tc2.mV[1]); - gGL.vertex2f(1,1); - gGL.end(); - - gGL.flush(); - - glEnable(GL_TEXTURE_2D); - glDisable(GL_TEXTURE_RECTANGLE_ARB); - - gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - }*/

	gGL.flush();
	

@@ -4789,4 +5078,353 @@

}

+void LLPipeline::bindDeferredShader(LLGLSLShader& shader) +{ + shader.bind(); + S32 channel = 0; + channel = shader.enableTexture(LLShaderMgr::DIFFUSE_MAP, GL_TEXTURE_RECTANGLE_ARB); + if (channel > -1) + { + mDeferredScreen.bindTexture(0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + } + + channel = shader.enableTexture(LLShaderMgr::SPECULAR_MAP, GL_TEXTURE_RECTANGLE_ARB); + if (channel > -1) + { + mDeferredScreen.bindTexture(1); + } + + channel = shader.enableTexture(LLShaderMgr::DEFERRED_NORMAL, GL_TEXTURE_RECTANGLE_ARB); + if (channel > -1) + { + mDeferredScreen.bindTexture(2); + } + + channel = shader.enableTexture(LLShaderMgr::DEFERRED_POSITION, GL_TEXTURE_RECTANGLE_ARB); + if (channel > -1) + { + mDeferredScreen.bindTexture(3); + } + + channel = shader.enableTexture(LLShaderMgr::DEFERRED_DEPTH, GL_TEXTURE_RECTANGLE_ARB); + if (channel > -1) + { + mDeferredScreen.bindDepth(); + } + + channel = shader.enableTexture(LLShaderMgr::DEFERRED_NOISE); + if (channel > -1) + { + glBindTexture(GL_TEXTURE_2D, mNoiseMap); + } + + channel = shader.enableTexture(LLShaderMgr::DEFERRED_LIGHT, GL_TEXTURE_RECTANGLE_ARB); + if (channel > -1) + { + mDeferredLight.bindTexture(); + } + + channel = shader.enableTexture(LLShaderMgr::DEFERRED_SHADOW); + if (channel > -1) + { + mSunShadow.bindTexture(); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL); + + F32 mat[48]; + for (U32 i = 0; i < 16; i++) + { + mat[i] = mSunShadowMatrix[0].m[i]; + mat[i+16] = mSunShadowMatrix[1].m[i]; + mat[i+32] = mSunShadowMatrix[2].m[i]; + } + + shader.uniformMatrix4fv("shadow_matrix", 3, FALSE, mat); + } + + channel = shader.enableTexture(LLShaderMgr::ENVIRONMENT_MAP, GL_TEXTURE_CUBE_MAP_ARB); + if (channel > -1) + { + LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL; + if (cube_map) + { + cube_map->enable(channel); + cube_map->bind(); + F64* m = gGLModelView; + + + F32 mat[] = { m[0], m[1], m[2], + m[4], m[5], m[6], + m[8], m[9], m[10] }; + + shader.uniform3fv("env_mat", 3, mat); + } + } + + shader.uniform3fv("shadow_clip", 1, mSunClipPlanes.mV); + shader.uniform1f("sun_wash", gSavedSettings.getF32("RenderDeferredSunWash")); + glActiveTextureARB(GL_TEXTURE0_ARB); +} + +void LLPipeline::renderDeferredLighting() +{ + if (!sCull) + { + return; + } + + if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) + { + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD); + } + + mDeferredLight.bindTarget(); + + gGL.setColorMask(true, true); + mDeferredLight.clear(); + + //draw a cube around every light + LLVertexBuffer::unbind(); + + glClear(GL_COLOR_BUFFER_BIT); + glBlendFunc(GL_ONE, GL_ONE); + LLGLEnable cull(GL_CULL_FACE); + LLGLEnable blend(GL_BLEND); + + glh::matrix4f mat = glh_copy_matrix(gGLModelView); + + F32 vert[] = + { + -1,1, + -1,-1, + 1,1, + 1,-1 + }; + + bindDeferredShader(gDeferredSunProgram); + + F32 aoBackground = gSavedSettings.getF32("RenderSSAOBackground"); + F32 aoForeground = gSavedSettings.getF32("RenderSSAOForeground"); + F32 aoScale = gSavedSettings.getF32("RenderSSAOScale"); + + 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()); + + gDeferredSunProgram.uniform1f("aoScale", aoScale); + gDeferredSunProgram.uniform1f("aoBackground", aoBackground); + gDeferredSunProgram.uniform1f("aoForeground", aoForeground); + + setupHWLights(NULL); //to set mSunDir; + + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + + LLVector4 dir(mSunDir, 0.f); + + glh::vec4f tc(dir.mV); + mat.mult_matrix_vec(tc); + glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], 0); + glColor3f(1,1,1); + + glVertexPointer(2, GL_FLOAT, 0, vert); + { + LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + } + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + + unbindDeferredShader(gDeferredSunProgram); + + mDeferredLight.flush(); + + mScreen.bindTarget(); + mScreen.clear(); + gGL.setColorMask(true, false); + + bindDeferredShader(gDeferredSoftenProgram); + { + LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS); + LLGLDisable blend(GL_BLEND); + + //full screen blit + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + + glVertexPointer(2, GL_FLOAT, 0, vert); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + } + + unbindDeferredShader(gDeferredSoftenProgram); + + bindDeferredShader(gDeferredLightProgram); + + F32 v[24]; + glVertexPointer(3, GL_FLOAT, 0, v); + { + 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; + } + + LLVector3 center = drawablep->getPositionAgent(); + F32* c = center.mV; + F32 s = volume->getLightRadius()*1.5f; + + if (LLViewerCamera::getInstance()->AABBInFrustumNoFarClip(center, LLVector3(s,s,s)) == 0) + { + continue; + } + + sVisibleLightCount++; + glh::vec3f tc(c); + mat.mult_matrix_vec(tc); + glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s); + + LLColor3 col = volume->getLightColor(); + col *= volume->getLightIntensity(); + + glColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f); + + //vertex positions are encoded so the 3 bits of their vertex index + //correspond to their axis facing, with bit position 3,2,1 matching + //axis facing x,y,z, bit set meaning positive facing, bit clear + //meaning negative facing + v[0] = c[0]-s; v[1] = c[1]-s; v[2] = c[2]-s; // 0 - 0000 + v[3] = c[0]-s; v[4] = c[1]-s; v[5] = c[2]+s; // 1 - 0001 + v[6] = c[0]-s; v[7] = c[1]+s; v[8] = c[2]-s; // 2 - 0010 + v[9] = c[0]-s; v[10] = c[1]+s; v[11] = c[2]+s; // 3 - 0011 + + v[12] = c[0]+s; v[13] = c[1]-s; v[14] = c[2]-s; // 4 - 0100 + v[15] = c[0]+s; v[16] = c[1]-s; v[17] = c[2]+s; // 5 - 0101 + v[18] = c[0]+s; v[19] = c[1]+s; v[20] = c[2]-s; // 6 - 0110 + v[21] = c[0]+s; v[22] = c[1]+s; v[23] = c[2]+s; // 7 - 0111 + + if (LLViewerCamera::getInstance()->getOrigin().mV[0] > c[0] + s + 0.2f || + LLViewerCamera::getInstance()->getOrigin().mV[0] < c[0] - s - 0.2f || + LLViewerCamera::getInstance()->getOrigin().mV[1] > c[1] + s + 0.2f || + LLViewerCamera::getInstance()->getOrigin().mV[1] < c[1] - s - 0.2f || + LLViewerCamera::getInstance()->getOrigin().mV[2] > c[2] + s + 0.2f || + LLViewerCamera::getInstance()->getOrigin().mV[2] < c[2] - s - 0.2f) + { //draw box if camera is outside box + glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, + GL_UNSIGNED_BYTE, get_box_fan_indices(LLViewerCamera::getInstance(), center)); + } + else + { + LLGLDepthTest depth(GL_FALSE); + //full screen blit + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + + glVertexPointer(2, GL_FLOAT, 0, vert); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + glVertexPointer(3, GL_FLOAT, 0, v); + + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + } + } + } + + unbindDeferredShader(gDeferredLightProgram); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + { //render non-deferred geometry + LLGLDisable blend(GL_BLEND); + U32 render_mask = mRenderTypeMask; + sRenderDeferred = FALSE; + mRenderTypeMask = (1 << LLPipeline::RENDER_TYPE_SKY) | + (1 << LLPipeline::RENDER_TYPE_CLOUDS) | + (1 << LLPipeline::RENDER_TYPE_WL_SKY) | + (1 << LLPipeline::RENDER_TYPE_ALPHA) | + (1 << LLPipeline::RENDER_TYPE_AVATAR) | + (1 << LLPipeline::RENDER_TYPE_WATER) | + (1 << LLPipeline::RENDER_TYPE_FULLBRIGHT) | + (1 << LLPipeline::RENDER_TYPE_VOLUME) | + (1 << LLPipeline::RENDER_TYPE_GLOW); + + renderGeomPostDeferred(*LLViewerCamera::getInstance()); + sRenderDeferred = TRUE; + mRenderTypeMask = render_mask; + } + + mScreen.flush(); + +} + +void LLPipeline::unbindDeferredShader(LLGLSLShader &shader) +{ + shader.disableTexture(LLShaderMgr::DEFERRED_POSITION, GL_TEXTURE_RECTANGLE_ARB); + shader.disableTexture(LLShaderMgr::DEFERRED_NORMAL, GL_TEXTURE_RECTANGLE_ARB); + shader.disableTexture(LLShaderMgr::DIFFUSE_MAP, GL_TEXTURE_RECTANGLE_ARB); + shader.disableTexture(LLShaderMgr::SPECULAR_MAP, GL_TEXTURE_RECTANGLE_ARB); + shader.disableTexture(LLShaderMgr::DEFERRED_DEPTH, GL_TEXTURE_RECTANGLE_ARB); + shader.disableTexture(LLShaderMgr::DEFERRED_SHADOW); + shader.disableTexture(LLShaderMgr::DEFERRED_LIGHT); + shader.disableTexture(LLShaderMgr::DEFERRED_NOISE); + + S32 channel = shader.disableTexture(LLShaderMgr::ENVIRONMENT_MAP, GL_TEXTURE_CUBE_MAP_ARB); + if (channel > -1) + { + LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL; + if (cube_map) + { + cube_map->disable(); + } + } + LLImageGL::unbindTexture(0); + glActiveTextureARB(GL_TEXTURE0_ARB); + glEnable(GL_TEXTURE_2D); + shader.unbind(); +} +

void LLPipeline::processImagery(LLCamera& camera)
{

@@ -4826,4 +5464,6 @@

		S32 occlusion = LLPipeline::sUseOcclusion;
		LLPipeline::sUseOcclusion = llmin(occlusion, 1);

+ BOOL deferred = LLPipeline::sRenderDeferred; +

		U32 type_mask = gPipeline.mRenderTypeMask;

@@ -4900,6 +5540,7 @@

				updateCull(camera, result);
				stateSort(camera, result);

+ LLPipeline::sRenderDeferred = FALSE;

				renderGeom(camera, TRUE);

- + LLPipeline::sRenderDeferred = deferred;

				mRenderTypeMask = tmp;
			}

@@ -4935,5 +5576,7 @@

					updateCull(camera, result, 1);
					stateSort(camera, result);

+ LLPipeline::sRenderDeferred = FALSE;

					renderGeom(camera);

+ LLPipeline::sRenderDeferred = deferred;

					LLSpatialPartition::sFreezeState = FALSE;
					LLPipeline::sSkipUpdate = FALSE;

@@ -4984,5 +5627,7 @@

				updateCull(camera, result, water_clip);
				stateSort(camera, result);

+ LLPipeline::sRenderDeferred = FALSE;

				renderGeom(camera);

+ LLPipeline::sRenderDeferred = deferred;

			}

@@ -4993,4 +5638,5 @@

		LLRenderTarget::unbindTarget();

+

		LLPipeline::sReflectionRender = FALSE;

@@ -5011,5 +5657,420 @@

		LLGLState::checkTextureChannels();
		LLGLState::checkClientArrays();

- } + LLPipeline::sRenderDeferred = deferred; + } +} + +glh::matrix4f look(const LLVector3 pos, const LLVector3 dir, const LLVector3 up) +{ + glh::matrix4f ret; + + LLVector3 dirN; + LLVector3 upN; + LLVector3 lftN; + + lftN = dir % up; + lftN.normVec(); + + upN = lftN % dir; + upN.normVec(); + + dirN = dir; + dirN.normVec(); + + + ret.m[ 0] = lftN[0]; + ret.m[ 1] = upN[0]; + ret.m[ 2] = -dirN[0]; + ret.m[ 3] = 0.f; + + ret.m[ 4] = lftN[1]; + ret.m[ 5] = upN[1]; + ret.m[ 6] = -dirN[1]; + ret.m[ 7] = 0.f; + + ret.m[ 8] = lftN[2]; + ret.m[ 9] = upN[2]; + ret.m[10] = -dirN[2]; + ret.m[11] = 0.f; + + ret.m[12] = -(lftN*pos); + ret.m[13] = -(upN*pos); + ret.m[14] = dirN*pos; + ret.m[15] = 1.f; + + return ret; +} + +glh::matrix4f scale_translate_to_fit(const LLVector3 min, const LLVector3 max) +{ + glh::matrix4f ret; + ret.m[ 0] = 2/(max[0]-min[0]); + ret.m[ 4] = 0; + ret.m[ 8] = 0; + ret.m[12] = -(max[0]+min[0])/(max[0]-min[0]); + + ret.m[ 1] = 0; + ret.m[ 5] = 2/(max[1]-min[1]); + ret.m[ 9] = 0; + ret.m[13] = -(max[1]+min[1])/(max[1]-min[1]); + + ret.m[ 2] = 0; + ret.m[ 6] = 0; + ret.m[10] = 2/(max[2]-min[2]); + ret.m[14] = -(max[2]+min[2])/(max[2]-min[2]); + + ret.m[ 3] = 0; + ret.m[ 7] = 0; + ret.m[11] = 0; + ret.m[15] = 1; + + return ret; +} + +void LLPipeline::generateSunShadow(LLCamera& camera) +{ + if (!sRenderDeferred) + { + return; + } + + mSunShadow.bindTarget(); + mSunShadow.getViewport(gGLViewport); + + //get sun view matrix + + F32 range = 128.f; + + glh::matrix4f saved_proj = glh_get_current_projection(); + glh::matrix4f saved_view = glh_get_current_modelview(); + glh::matrix4f inv_view = saved_view.inverse(); + + glh::matrix4f view[3]; + glh::matrix4f proj[3]; + LLVector3 up; + + mSunClipPlanes = gSavedSettings.getVector3("RenderShadowClipPlanes"); + if (!gLastHitPosGlobal.isExactlyZero()) + { + F32 focus_dist = (F32) (gLastHitPosGlobal + gLastHitObjectOffset - gAgent.getPosGlobalFromAgent(LLViewerCamera::getInstance()->getOrigin())).magVec(); + mSunClipPlanes.mV[0] = llclamp(focus_dist*focus_dist, 2.f, mSunClipPlanes.mV[0]); + } + + F32 dist[] = { 0.1f, mSunClipPlanes.mV[0], mSunClipPlanes.mV[1], mSunClipPlanes.mV[2] }; + + for (S32 j = 2; j >= 0; j--) + { + glh_set_current_modelview(saved_view); + glh_set_current_projection(saved_proj); + + LLVector3 center = camera.getOrigin() + camera.getAtAxis() * range; + + LLVector3 eye = camera.getOrigin(); //center + LLVector3(0, 0, range); + + LLCamera shadow_cam; + + if (j > 2) + { //uniform shadow mapping + glh::vec3f p[16]; + glh::vec3f wp[16]; + + LLVector3 lightDir = -mSunDir; //(0, 0, -1.f); + glh::vec3f light_dir(lightDir.mV); + + LLVector3 at = lightDir%camera.getLeftAxis(); + LLVector3 left = lightDir%at; + up = left%lightDir; + up.normVec(); + + shadow_cam = camera; + shadow_cam.setFar(camera.getFar()); + F32 shadow_dist = camera.getFar()*2.f; + + LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); + + view[j] = look(eye, lightDir, up); + + LLVector3* frust = shadow_cam.mAgentFrustum; + + LLVector3 pn = shadow_cam.getAtAxis(); + + for (U32 i = 0; i < 4; i++) + { + LLVector3 delta = frust[i+4]-eye; + delta.normVec(); + F32 dp = delta*pn; + wp[i] = glh::vec3f(( eye + (delta*dist[j])/dp ).mV); + wp[i+4] = glh::vec3f(( eye + (delta*dist[j+1])/dp ).mV); + } + + for (U32 i = 0; i < 8; i++) + { + wp[i+8] = wp[i] - light_dir*shadow_dist; + view[j].mult_matrix_vec(wp[i], p[i]); + view[j].mult_matrix_vec(wp[i+8], p[i+8]); + } + + LLVector3 min = LLVector3(p[0].v); + LLVector3 max = LLVector3(p[0].v); + + for (U32 i = 1; i < 16; i++) + { + update_min_max(min, max, LLVector3(p[i].v)); + } + + proj[j] = gl_ortho(min.mV[0], max.mV[0], min.mV[1], max.mV[1], min.mV[2], max.mV[2]); + } + else + { // perspective shadow map + glh::vec3f p[16]; + glh::vec3f wp[16]; + + LLVector3 lightDir = -mSunDir; //(0, 0, -1.f); + glh::vec3f light_dir(lightDir.mV); + + LLVector3 at; + F32 dl = camera.getLeftAxis() * lightDir; + F32 du = camera.getUpAxis() * lightDir; + + if (dl*dl < du*du) + { + at = lightDir%camera.getLeftAxis(); + } + else + { + at = lightDir%camera.getUpAxis(); + } + + if (at * camera.getAtAxis() < 0) + { + at = -at; + } + + LLVector3 left = lightDir%at; + up = left%lightDir; + up.normVec(); + view[j] = look(eye, lightDir, up); + + shadow_cam = camera; + shadow_cam.setFar(16.f); + F32 shadow_dist = camera.getFar(); + + LLViewerCamera::updateFrustumPlanes(shadow_cam); + + LLVector3* frust = shadow_cam.mAgentFrustum; + + LLVector3 pn = shadow_cam.getAtAxis(); + + for (U32 i = 0; i < 4; i++) + { + LLVector3 delta = frust[i+4]-eye; + delta.normVec(); + F32 dp = delta*pn; + wp[i] = glh::vec3f(( eye + (delta*dist[j])/dp ).mV); + wp[i+4] = glh::vec3f(( eye + (delta*dist[j+1])/dp ).mV); + } + + for (U32 i = 0; i < 8; i++) + { + wp[i+8] = wp[i] - light_dir*shadow_dist; + view[j].mult_matrix_vec(wp[i], p[i]); + view[j].mult_matrix_vec(wp[i+8], p[i+8]); + } + + LLVector3 min = LLVector3(p[0].v); + LLVector3 max = LLVector3(p[0].v); + + for (U32 i = 1; i < 16; i++) + { + update_min_max(min, max, LLVector3(p[i].v)); + } + + F32 nearDist = gSavedSettings.getF32("RenderShadowNearDist"); + //nearDist *= dist[j]; + /*F32 dp = pn * lightDir; + dp *= dp; + nearDist += dist[j] * dp;*/ + + //use the formulas of the paper to get n (and f) + F32 dotProd = lightDir*camera.getAtAxis(); + if (fabsf(dotProd) > 1.f) + { + llerrs << "WTF?" << llendl; + } + + F32 sinGamma = sqrtf(1.f-dotProd*dotProd); + + F32 factor = 1.f/sinGamma; + F32 z_n = factor*nearDist; + F32 d = fabsf(max[1]-min[1]); //perspective transform depth //light space y extents + F32 z_f = z_n + d*sinGamma; + F32 n = (z_n+sqrtf(z_f*z_n))/sinGamma; + F32 f = n+d; + + if (n > f) + { + llerrs << "WTF" << llendl; + } + + LLVector3 pos = eye - up*(n-nearDist); + + view[j] = look(pos,lightDir,up); + + //one possibility for a simple perspective transformation matrix + //with the two parameters n(near) and f(far) in y direction + glh::matrix4f lispMtx; + // a = (f+n)/(f-n); b = -2*f*n/(f-n); + lispMtx.m[ 5] = (f+n)/(f-n); // [ 1 0 0 0] + lispMtx.m[13] = -2*f*n/(f-n); // [ 0 a 0 b] + lispMtx.m[ 7] = 1; // [ 0 0 1 0] + lispMtx.m[15] = 0; // [ 0 1 0 0] + + //temporal arrangement for the transformation of the points to post-perspective space + proj[j] = lispMtx*view[j]; + + for (U32 i = 0; i < 16; ++i) + { + proj[j].mult_matrix_vec(wp[i]); + } + + min = LLVector3(wp[0].v); + max = min; + for (U32 i = 1; i < 16; ++i) + { + update_min_max(min, max, LLVector3(wp[i].v)); + } + + proj[j] = scale_translate_to_fit(min, max); + + proj[j] = proj[j] * lispMtx; + + glh::matrix4f rh2lh; + rh2lh.set_scale(glh::vec3f(1.f, 1.f, -1.f)); + proj[j] = rh2lh * proj[j]; + } + + + //translate and scale to from [-1, 1] to [0, 1] + glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f, + 0.f, 0.5f, 0.f, 0.5f, + 0.f, 0.f, 0.5f, 0.5f, + 0.f, 0.f, 0.f, 1.f); + + mSunShadowMatrix[j] = trans*proj[j]*view[j]*inv_view; + + shadow_cam.setFar(128.f); + shadow_cam.setOriginAndLookAt(eye, up, center); + + glh_set_current_modelview(view[j]); + glh_set_current_projection(proj[j]); + + LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); + + //generate sun shadow map + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadMatrixf(proj[j].m); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadMatrixf(view[j].m); + + gGLLastMatrix = NULL; + + U32 type_mask = mRenderTypeMask; + mRenderTypeMask = type_mask & ((1<<LLPipeline::RENDER_TYPE_SIMPLE) | + (1<<LLPipeline::RENDER_TYPE_ALPHA) | + (1<<LLPipeline::RENDER_TYPE_FULLBRIGHT) | + (1<<LLPipeline::RENDER_TYPE_BUMP) | + (1<<LLPipeline::RENDER_TYPE_VOLUME) | + (1<<LLPipeline::RENDER_TYPE_AVATAR) | + (1<<LLPipeline::RENDER_TYPE_TREE) | + (1<<LLPipeline::RENDER_TYPE_TERRAIN)); + + LLViewerImage::unbindTexture(0, GL_TEXTURE_2D); + + switch (j) + { + case 0: + gGL.setColorMask(true, false, false, false); + break; + case 1: + gGL.setColorMask(false, true, false, false); + break; + case 2: + gGL.setColorMask(false, false, true, false); + break; + } + + { + LLGLDepthTest depth(GL_TRUE); + glClearColor(1,1,1,1); + mSunShadow.clear(); + glClearColor(0,0,0,0); + } + + //clip out geometry on the same side of water as the camera + static LLCullResult result; + S32 occlude = LLPipeline::sUseOcclusion; + BOOL deferred = LLPipeline::sRenderDeferred; + LLPipeline::sUseOcclusion = 0; + LLPipeline::sShadowRender = TRUE; + //hack to prevent LOD updates from using sun camera origin + shadow_cam.setOrigin(camera.getOrigin()); + updateCull(shadow_cam, result); + stateSort(shadow_cam, result); + LLPipeline::sRenderDeferred = FALSE; + + U32 types[] = { LLRenderPass::PASS_SIMPLE, LLRenderPass::PASS_FULLBRIGHT, LLRenderPass::PASS_SHINY }; + LLGLEnable cull(GL_CULL_FACE); + + glColor4f(1,1,1,1); + LLImageGL::unbindTexture(0); + gDeferredShadowProgram.bind(); + + for (U32 i = 0; i < sizeof(types)/sizeof(U32); ++i) + { + renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE); + } + + { + LLGLEnable test(GL_ALPHA_TEST); + gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.6f); + renderObjects(LLRenderPass::PASS_ALPHA, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD | LLVertexBuffer::MAP_COLOR, TRUE); + glColor4f(1,1,1,1); + gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); + } + + gDeferredShadowProgram.unbind(); + + renderGeomShadow(shadow_cam); + LLPipeline::sRenderDeferred = deferred; + LLPipeline::sUseOcclusion = occlude; + LLPipeline::sShadowRender = FALSE; + mRenderTypeMask = type_mask; + + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + gGLLastMatrix = NULL; + } + + mSunShadow.flush(); + + if (!gSavedSettings.getBOOL("CameraOffset")) + { + glh_set_current_modelview(saved_view); + glh_set_current_projection(saved_proj); + } + else + { + glh_set_current_modelview(view[1]); + glh_set_current_projection(proj[1]); + glLoadMatrixf(view[1].m); + glMatrixMode(GL_PROJECTION); + glLoadMatrixf(proj[1].m); + glMatrixMode(GL_MODELVIEW); + } + gGL.setColorMask(true, false);

}

@@ -5076,4 +6137,5 @@

				(1<<LLPipeline::RENDER_TYPE_GRASS) |
				(1<<LLPipeline::RENDER_TYPE_SIMPLE) |

+ (1<<LLPipeline::RENDER_TYPE_FULLBRIGHT) |

				(1<<LLPipeline::RENDER_TYPE_ALPHA) | 
				(1<<LLPipeline::RENDER_TYPE_INVISIBLE);

@@ -5086,5 +6148,5 @@

	S32 occlusion = sUseOcclusion;
	sUseOcclusion = 0;

- sReflectionRender = TRUE; + sReflectionRender = sRenderDeferred ? FALSE : TRUE;

	sImpostorRender = TRUE;

@@ -5164,4 +6226,8 @@

	{
		avatar->mImpostor.allocate(resX,resY,GL_RGBA,TRUE);

+ if (LLPipeline::sRenderDeferred) + { + addDeferredAttachments(avatar->mImpostor); + }

		avatar->mImpostor.bindTexture();
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

@@ -5174,6 +6240,5 @@

		glScissor(0, 0, resX, resY);
		avatar->mImpostor.bindTarget();

- avatar->mImpostor.getViewport(gGLViewport); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + avatar->mImpostor.clear();

	}
	

@@ -5188,4 +6253,5 @@

	glStencilFunc(GL_EQUAL, 1, 0xFFFFFF);

+ if (!sRenderDeferred || muted)

	{
		LLVector3 left = camera.getLeftAxis()*tdim.mV[0]*2.f;

@@ -5218,5 +6284,4 @@

		gGL.flush();

-

		gGL.setSceneBlendType(LLRender::BT_ALPHA);
	}

Index: /branches/shadow-draft/indra/newview/llappviewer.cpp

=======================================================

--- /branches/shadow-draft/indra/newview/llappviewer.cpp (revision 573) +++ /branches/shadow-draft/indra/newview/llappviewer.cpp (revision 575) @@ -3175,4 +3175,5 @@

	    gFrameStats.start(LLFrameStats::IDLE_NETWORK);

+ stop_glerror();

		idleNetwork();
	    stop_glerror();

Index: /branches/shadow-draft/indra/newview/llvosky.cpp

=======================================================

--- /branches/shadow-draft/indra/newview/llvosky.cpp (revision 543) +++ /branches/shadow-draft/indra/newview/llvosky.cpp (revision 575) @@ -2024,5 +2024,5 @@

	LLColor4 target_fog(0.f, 0.2f, 0.5f, 0.f);

- const F32 water_height = gAgent.getRegion()->getWaterHeight(); + const F32 water_height = gAgent.getRegion() ? gAgent.getRegion()->getWaterHeight() : 0.f;

	// LLWorld::getInstance()->getWaterHeight();
	F32 camera_height = gAgent.getCameraPositionAgent().mV[2];

Index: /branches/shadow-draft/indra/newview/llviewerdisplay.cpp

=======================================================

--- /branches/shadow-draft/indra/newview/llviewerdisplay.cpp (revision 573) +++ /branches/shadow-draft/indra/newview/llviewerdisplay.cpp (revision 575) @@ -556,7 +556,8 @@

			if (!for_snapshot)
			{

+ gPipeline.generateSunShadow(*LLViewerCamera::getInstance());

				render_ui_and_swap_if_needed();
				gDisplaySwapBuffers = TRUE;

- +

				glh::matrix4f proj = glh_get_current_projection();
				glh::matrix4f mod = glh_get_current_modelview();

@@ -680,8 +681,19 @@

		//}

+ LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater() ? TRUE : FALSE; + LLPipeline::sRenderDeferred = gSavedSettings.getBOOL("RenderDeferred") && LLRenderTarget::sUseFBO && + !LLPipeline::sUnderWaterRender; +

		if (to_texture)
		{
			gGL.setColorMask(true, true);

- gPipeline.mScreen.bindTarget(); + if (LLPipeline::sRenderDeferred) + { + gPipeline.mDeferredScreen.bindTarget(); + } + else + { + gPipeline.mScreen.bindTarget(); + }

			glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
			gGL.setColorMask(true, false);

@@ -692,5 +704,4 @@

		{
			gGL.setColorMask(true, false);

- LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater() ? TRUE : FALSE;

			gPipeline.renderGeom(*LLViewerCamera::getInstance(), TRUE);
			LLPipeline::sUnderWaterRender = FALSE;

@@ -708,5 +719,12 @@

		if (to_texture)
		{

- gPipeline.mScreen.flush(); + if (LLPipeline::sRenderDeferred) + { + gPipeline.mDeferredScreen.flush(); + } + else + { + gPipeline.mScreen.flush(); + }

		}

@@ -716,7 +734,12 @@

		/// grasp of their full display stack just yet.
		// gPostProcess->apply(gViewerWindow->getWindowDisplayWidth(), gViewerWindow->getWindowDisplayHeight());

+ + if (LLPipeline::sRenderDeferred) + { + gPipeline.renderDeferredLighting(); + }

	}
	gFrameStats.start(LLFrameStats::RENDER_UI);

- +

	if (gHandleKeysAsync)
	{

@@ -756,5 +779,8 @@

		U32 mask = gPipeline.getRenderTypeMask();
		gPipeline.setRenderTypeMask(0);

- gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD); + if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) + { + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD); + }

		BOOL has_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI);

@@ -776,4 +802,5 @@

		gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_VOLUME);
		gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_ALPHA);

+ gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_FULLBRIGHT);

		gPipeline.stateSort(hud_cam, result);

Index: /branches/shadow-draft/indra/newview/llglslshader.cpp

=======================================================

--- /branches/shadow-draft/indra/newview/llglslshader.cpp (revision 573) +++ /branches/shadow-draft/indra/newview/llglslshader.cpp (revision 575) @@ -117,5 +117,17 @@

// Deferred rendering shaders

+LLGLSLShader gDeferredImpostorProgram; +LLGLSLShader gDeferredWaterProgram;

LLGLSLShader			gDeferredDiffuseProgram;

+LLGLSLShader gDeferredTerrainProgram; +LLGLSLShader gDeferredTreeProgram; +LLGLSLShader gDeferredAvatarProgram; +LLGLSLShader gDeferredAvatarAlphaProgram; +LLGLSLShader gDeferredLightProgram; +LLGLSLShader gDeferredSunProgram; +LLGLSLShader gDeferredSoftenProgram; +LLGLSLShader gDeferredShadowProgram; +LLGLSLShader gDeferredAvatarShadowProgram; +LLGLSLShader gDeferredAlphaProgram;

//current avatar shader parameter pointer

@@ -137,4 +149,5 @@

vector<string> LLShaderMgr::sAvatarAttribs;
vector<string> LLShaderMgr::sAvatarUniforms;

+

//vector< GLhandleARB > LLShaderMgr::sBaseObjects;

@@ -158,4 +171,9 @@

	&gObjectShinyWaterProgram,
	&gUnderWaterProgram,

+ &gDeferredSunProgram, + &gDeferredLightProgram, + &gDeferredAlphaProgram, + &gDeferredWaterProgram, + &gDeferredAvatarAlphaProgram,

};
const size_t LLShaderMgr::sNumShaders = sizeof(sShaderList) / sizeof(sShaderList[0]);

@@ -235,4 +253,10 @@

		sReservedUniforms.push_back("gamma");
		sReservedUniforms.push_back("scene_light_strength");

+ sReservedUniforms.push_back("depthMap"); + sReservedUniforms.push_back("shadowMap"); + sReservedUniforms.push_back("normalMap"); + sReservedUniforms.push_back("positionMap"); + sReservedUniforms.push_back("noiseMap"); + sReservedUniforms.push_back("lightMap");

		sWLUniforms.push_back("camPosLocal");

@@ -271,4 +295,5 @@

		sWaterUniforms.push_back("refScale");
		sWaterUniforms.push_back("waterHeight");

+

	}	
}

@@ -739,4 +764,5 @@

		LLPipeline::sWaterReflections = gGLManager.mHasCubeMap;
		LLPipeline::sRenderGlow = gSavedSettings.getBOOL("RenderGlow"); 

+ LLPipeline::sRenderDeferred = gSavedSettings.getBOOL("RenderDeferred") && LLRenderTarget::sUseFBO;

	}
	else

@@ -799,11 +825,6 @@

		}

- if (gSavedSettings.getBOOL("RenderDeferred")) - { - light_class = 1; - env_class = 0; - obj_class = 0; - water_class = 1; - effect_class = 1; + if (LLPipeline::sRenderDeferred) + {

			deferred_class = 1;
		}

@@ -844,10 +865,10 @@

			loadShadersEffects();
			loadShadersInterface();

- loadShadersDeferred(); - +

			// Load max avatar shaders to set the max level
			sVertexShaderLevel[SHADER_AVATAR] = 3;
			sMaxAvatarShaderLevel = 3;
			loadShadersAvatar();

+

#if 0 && LL_DARWIN // force avatar shaders off for mac

@@ -892,4 +913,6 @@

				loadShadersAvatar(); // unloads
			}

+ + loadShadersDeferred();

#endif
		}

@@ -955,5 +978,17 @@

	gPostNightVisionProgram.unload();

+ gDeferredAvatarProgram.unload(); + gDeferredAvatarAlphaProgram.unload();

	gDeferredDiffuseProgram.unload();

+ gDeferredTreeProgram.unload(); + gDeferredImpostorProgram.unload(); + gDeferredTerrainProgram.unload(); + gDeferredLightProgram.unload(); + gDeferredSunProgram.unload(); + gDeferredSoftenProgram.unload(); + gDeferredShadowProgram.unload(); + gDeferredAvatarShadowProgram.unload(); + gDeferredAlphaProgram.unload(); + gDeferredWaterProgram.unload();

	sVertexShaderLevel[SHADER_LIGHTING] = 0;

@@ -1261,7 +1296,21 @@

	if (sVertexShaderLevel[SHADER_DEFERRED] == 0)
	{

+ gDeferredTreeProgram.unload();

		gDeferredDiffuseProgram.unload();

+ gDeferredImpostorProgram.unload(); + gDeferredTerrainProgram.unload(); + gDeferredLightProgram.unload(); + gDeferredSunProgram.unload(); + gDeferredSoftenProgram.unload(); + gDeferredShadowProgram.unload(); + gDeferredAvatarShadowProgram.unload(); + gDeferredAvatarProgram.unload(); + gDeferredAvatarAlphaProgram.unload(); + gDeferredAlphaProgram.unload(); + gDeferredWaterProgram.unload();

		return FALSE;
	}

+ + sVertexShaderLevel[SHADER_AVATAR] = 1;

	BOOL success = TRUE;

@@ -1275,4 +1324,141 @@

		gDeferredDiffuseProgram.mShaderLevel = sVertexShaderLevel[SHADER_DEFERRED];
		success = gDeferredDiffuseProgram.createShader(NULL, NULL);

+ } + + if (success) + { + gDeferredTreeProgram.mName = "Deffered Tree Shader"; + gDeferredTreeProgram.mShaderFiles.clear(); + gDeferredTreeProgram.mShaderFiles.push_back(make_pair("deferred/treeV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredTreeProgram.mShaderFiles.push_back(make_pair("deferred/treeF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredTreeProgram.mShaderLevel = sVertexShaderLevel[SHADER_DEFERRED]; + success = gDeferredTreeProgram.createShader(NULL, NULL); + } + + if (success) + { + gDeferredImpostorProgram.mName = "Deffered Impostor Shader"; + gDeferredImpostorProgram.mShaderFiles.clear(); + gDeferredImpostorProgram.mShaderFiles.push_back(make_pair("deferred/impostorV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredImpostorProgram.mShaderFiles.push_back(make_pair("deferred/impostorF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredImpostorProgram.mShaderLevel = sVertexShaderLevel[SHADER_DEFERRED]; + success = gDeferredImpostorProgram.createShader(NULL, NULL); + } + + if (success) + { + gDeferredLightProgram.mName = "Deffered Light Shader"; + gDeferredLightProgram.mShaderFiles.clear(); + gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredLightProgram.mShaderLevel = sVertexShaderLevel[SHADER_DEFERRED]; + success = gDeferredLightProgram.createShader(NULL, NULL); + } + + if (success) + { + gDeferredSunProgram.mName = "Deffered Sun Shader"; + gDeferredSunProgram.mShaderFiles.clear(); + gDeferredSunProgram.mShaderFiles.push_back(make_pair("deferred/sunLightV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredSunProgram.mShaderFiles.push_back(make_pair("deferred/sunLightF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredSunProgram.mShaderLevel = sVertexShaderLevel[SHADER_DEFERRED]; + success = gDeferredSunProgram.createShader(NULL, NULL); + } + + if (success) + { + gDeferredAlphaProgram.mName = "Deffered Alpha Shader"; + gDeferredAlphaProgram.mFeatures.calculatesLighting = true; + gDeferredAlphaProgram.mFeatures.calculatesAtmospherics = true; + gDeferredAlphaProgram.mFeatures.hasGamma = true; + gDeferredAlphaProgram.mFeatures.hasAtmospherics = true; + gDeferredAlphaProgram.mFeatures.hasLighting = true; + gDeferredAlphaProgram.mShaderFiles.clear(); + 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.mShaderLevel = sVertexShaderLevel[SHADER_DEFERRED]; + success = gDeferredAlphaProgram.createShader(NULL, NULL); + } + + if (success) + { + // load water shader + gDeferredWaterProgram.mName = "Deferred Water Shader"; + gDeferredWaterProgram.mFeatures.calculatesAtmospherics = true; + gDeferredWaterProgram.mFeatures.hasGamma = true; + gDeferredWaterProgram.mFeatures.hasTransport = true; + gDeferredWaterProgram.mShaderFiles.clear(); + gDeferredWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredWaterProgram.mShaderLevel = sVertexShaderLevel[SHADER_DEFERRED]; + success = gDeferredWaterProgram.createShader(NULL, &sWaterUniforms); + } + + if (success) + { + gDeferredSoftenProgram.mName = "Deffered Soften Shader"; + gDeferredSoftenProgram.mShaderFiles.clear(); + gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredSoftenProgram.mShaderLevel = sVertexShaderLevel[SHADER_DEFERRED]; + success = gDeferredSoftenProgram.createShader(NULL, NULL); + } + + if (success) + { + gDeferredShadowProgram.mName = "Deffered Shadow Shader"; + gDeferredShadowProgram.mShaderFiles.clear(); + gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredShadowProgram.mShaderLevel = sVertexShaderLevel[SHADER_DEFERRED]; + success = gDeferredShadowProgram.createShader(NULL, NULL); + } + + if (success) + { + gDeferredAvatarShadowProgram.mName = "Deffered Avatar Shadow Shader"; + gDeferredAvatarShadowProgram.mFeatures.hasSkinning = true; + gDeferredAvatarShadowProgram.mShaderFiles.clear(); + gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredAvatarShadowProgram.mShaderLevel = sVertexShaderLevel[SHADER_DEFERRED]; + success = gDeferredAvatarShadowProgram.createShader(&sAvatarAttribs, &sAvatarUniforms); + } + + if (success) + { + gTerrainProgram.mName = "Deferred Terrain Shader"; + gDeferredTerrainProgram.mShaderFiles.clear(); + gDeferredTerrainProgram.mShaderFiles.push_back(make_pair("deferred/terrainV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredTerrainProgram.mShaderFiles.push_back(make_pair("deferred/terrainF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredTerrainProgram.mShaderLevel = sVertexShaderLevel[SHADER_DEFERRED]; + success = gDeferredTerrainProgram.createShader(NULL, &sTerrainUniforms); + } + + if (success) + { + gDeferredAvatarProgram.mName = "Avatar Shader"; + gDeferredAvatarProgram.mFeatures.hasSkinning = true; + gDeferredAvatarProgram.mShaderFiles.clear(); + gDeferredAvatarProgram.mShaderFiles.push_back(make_pair("deferred/avatarV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredAvatarProgram.mShaderFiles.push_back(make_pair("deferred/avatarF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredAvatarProgram.mShaderLevel = sVertexShaderLevel[SHADER_DEFERRED]; + success = gDeferredAvatarProgram.createShader(&sAvatarAttribs, &sAvatarUniforms); + } + + if (success) + { + gDeferredAvatarAlphaProgram.mName = "Avatar Alpha Shader"; + gDeferredAvatarAlphaProgram.mFeatures.hasSkinning = true; + gDeferredAvatarAlphaProgram.mFeatures.calculatesLighting = true; + gDeferredAvatarAlphaProgram.mFeatures.calculatesAtmospherics = true; + gDeferredAvatarAlphaProgram.mFeatures.hasGamma = true; + gDeferredAvatarAlphaProgram.mFeatures.hasAtmospherics = true; + gDeferredAvatarAlphaProgram.mFeatures.hasLighting = true; + gDeferredAvatarAlphaProgram.mShaderFiles.clear(); + gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredAvatarAlphaProgram.mShaderLevel = sVertexShaderLevel[SHADER_DEFERRED]; + success = gDeferredAvatarAlphaProgram.createShader(&sAvatarAttribs, &sAvatarUniforms);

	}

Index: /branches/shadow-draft/indra/newview/lldrawpoolsky.h

=======================================================

--- /branches/shadow-draft/indra/newview/lldrawpoolsky.h (revision 280) +++ /branches/shadow-draft/indra/newview/lldrawpoolsky.h (revision 575) @@ -59,4 +59,9 @@

	/*virtual*/ LLDrawPool *instancePool();

+ /*virtual*/ S32 getNumPostDeferredPasses() { return getNumPasses(); } + /*virtual*/ void beginPostDeferredPass(S32 pass) { beginRenderPass(pass); } + /*virtual*/ void endPostDeferredPass(S32 pass) { endRenderPass(pass); } + /*virtual*/ void renderPostDeferred(S32 pass) { render(pass); } +

	/*virtual*/ void prerender();
	/*virtual*/ void render(S32 pass = 0);

Index: /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl

=======================================================

--- /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl (revision 575) +++ /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl (revision 575) @@ -0,0 +1,20 @@ +/** + * @file impostorF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2D diffuseMap; +uniform sampler2D normalMap; +uniform sampler2D specularMap; + +varying vec4 vary_position; + +void main() +{ + gl_FragData[0] = texture2D(diffuseMap, gl_TexCoord[0].xy); + gl_FragData[1] = texture2D(specularMap, gl_TexCoord[0].xy); + gl_FragData[2].xyz = texture2D(normalMap, gl_TexCoord[0].xy).xyz; + gl_FragData[3] = vary_position; +} Index: /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/sunLightV.glsl

=======================================================

--- /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/sunLightV.glsl (revision 575) +++ /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/sunLightV.glsl (revision 575) @@ -0,0 +1,21 @@ +/** + * @file sunLightF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +varying vec4 vary_light; + +void main() +{ + //transform vertex + gl_Position = ftransform(); + + vec4 tex = gl_MultiTexCoord0; + tex.w = 1.0; + + vary_light = gl_MultiTexCoord0; + + gl_FrontColor = gl_Color; +} Index: /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl

=======================================================

--- /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl (revision 575) +++ /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl (revision 575) @@ -0,0 +1,20 @@ +/** + * @file avatarF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2D diffuseMap; + +varying vec3 vary_normal; +varying vec4 vary_position; + +void main() +{ + gl_FragData[0] = gl_Color * texture2D(diffuseMap, gl_TexCoord[0].xy); + gl_FragData[1] = vec4(0,0,0,0); + gl_FragData[2].xyz = normalize(vary_normal); + gl_FragData[3] = vary_position; +} + Index: /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl

=======================================================

--- /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl (revision 575) +++ /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl (revision 575) @@ -0,0 +1,22 @@ +/** + * @file treeV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +varying vec3 vary_normal; +varying vec4 vary_position; + +void main() +{ + //transform vertex + gl_Position = ftransform(); + gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; + + vary_position = gl_ModelViewMatrix * gl_Vertex; + + vary_normal = normalize(gl_NormalMatrix * gl_Normal); + + gl_FrontColor = gl_Color; +} Index: /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl

=======================================================

--- /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl (revision 575) +++ /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl (revision 575) @@ -0,0 +1,63 @@ +/** + * @file pointLightF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2DRect diffuseMap; +uniform sampler2DRect specularMap; +uniform sampler2DRect positionMap; +uniform sampler2DRect normalMap; +uniform samplerCube environmentMap; +uniform sampler2DRect lightMap; + +uniform vec3 env_mat[3]; +uniform float sun_wash; + +varying vec4 vary_light; + +void main() +{ + vec3 pos = texture2DRect(positionMap, gl_FragCoord.xy).xyz; + vec3 lv = vary_light.xyz-pos; + float dist2 = dot(lv,lv); + if (dist2 > vary_light.w) + { + discard; + } + + vec3 norm = texture2DRect(normalMap, gl_FragCoord.xy).xyz; + vec4 spec = texture2DRect(specularMap, gl_FragCoord.xy); + + if (dot(norm, lv) < 0.0 && spec.a == 0.0) + { + discard; + } + + + lv = normalize(lv); + float da = dot(norm, lv); + + vec3 col = texture2DRect(diffuseMap, gl_FragCoord.xy).rgb; + float fa = gl_Color.a+1.0; + float dist_atten = clamp(1.0-(dist2-vary_light.w*(1.0-fa))/(vary_light.w*fa), 0.0, 1.0); + float lit = da * dist_atten; + + col = gl_Color.rgb*lit*col; + + if (spec.a > 0.0) + { + vec3 ref = reflect(normalize(pos), norm); + da = dot(ref,lv); + da = max(da, 0.0); + da = pow(da, 128.0 * spec.a*spec.a/dist_atten)*min(dist_atten*4.0, 1.0); + col += da*gl_Color.rgb*spec.rgb; + } + + vec3 light = texture2DRect(lightMap, gl_FragCoord.xy); + light *= sun_wash; + + gl_FragColor = vec4(col*(1.0-light), 1.0); + //gl_FragColor.rgb = vec3(spec.a); +} Index: /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl

=======================================================

--- /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl (revision 575) +++ /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl (revision 575) @@ -0,0 +1,165 @@ +/** + * @file waterF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +vec3 scaleSoftClip(vec3 inColor); +vec3 atmosTransport(vec3 inColor); + +uniform sampler2D bumpMap; +uniform sampler2D screenTex; +uniform sampler2D refTex; +uniform sampler2D shadowMap; +uniform sampler2D noiseMap; + +uniform mat4 shadow_matrix[3]; +uniform vec3 shadow_clip; + +uniform float sunAngle; +uniform float sunAngle2; +uniform vec3 lightDir; +uniform vec3 specular; +uniform float lightExp; +uniform float refScale; +uniform float kd; +uniform vec2 screenRes; +uniform vec3 normScale; +uniform float fresnelScale; +uniform float fresnelOffset; +uniform float blurMultiplier; + + +//bigWave is (refCoord.w, view.w); +varying vec4 refCoord; +varying vec4 littleWave; +varying vec4 view; +varying vec4 vary_position; +varying vec3 vary_normal; + +void main() +{ + vec4 color; + float dist = length(view.xy); + + //normalize view vector + vec3 viewVec = normalize(view.xyz); + + //get wave 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; + //get base fresnel components + + vec3 df = vec3( + dot(viewVec, wave1), + dot(viewVec, (wave2 + wave3) * 0.5), + dot(viewVec, wave3) + ) * fresnelScale + fresnelOffset; + df *= df; + + vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5; + + float dist2 = dist; + dist = max(dist, 5.0); + + float dmod = sqrt(dist); + + vec2 dmod_scale = vec2(dmod*dmod, dmod); + + //get reflected color + vec2 refdistort1 = wave1.xy*normScale.x; + vec2 refvec1 = distort+refdistort1/dmod_scale; + vec4 refcol1 = texture2D(refTex, refvec1); + + vec2 refdistort2 = wave2.xy*normScale.y; + vec2 refvec2 = distort+refdistort2/dmod_scale; + vec4 refcol2 = texture2D(refTex, refvec2); + + vec2 refdistort3 = wave3.xy*normScale.z; + vec2 refvec3 = distort+refdistort3/dmod_scale; + vec4 refcol3 = texture2D(refTex, refvec3); + + vec4 refcol = refcol1 + refcol2 + refcol3; + float df1 = df.x + df.y + df.z; + refcol *= df1 * 0.333; + + vec3 wavef = (wave1 + wave2 * 0.4 + wave3 * 0.6) * 0.5; + wavef.z *= max(-viewVec.z, 0.1); + wavef = normalize(wavef); + + float df2 = dot(viewVec, wavef) * fresnelScale+fresnelOffset; + + vec2 refdistort4 = wavef.xy*0.125; + refdistort4.y -= abs(refdistort4.y); + 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); + + //harden specular + spec = pow(spec, 128.0); + + //figure out distortion vector (ripply) + vec2 distort2 = distort+wavef.xy*refScale/max(dmod*df1, 1.0); + + vec4 fb = texture2D(screenTex, distort2); + + //mix with reflection + // Note we actually want to use just df1, but multiplying by 0.999999 gets around and nvidia compiler bug + color.rgb = mix(fb.rgb, refcol.rgb, df1 * 0.99999); + + float shadow = 1.0; + vec4 pos = vary_position; + vec3 norm = normalize(vary_normal); + + int i = 0; + if (pos.z < -shadow_clip.x) + { + i++; + } + if (pos.z < -shadow_clip.y) + { + i++; + } + + vec4 lpos; + if (pos.z > -shadow_clip.z) + { + dist = sqrt(-pos.z)*0.1; + vec4 spos = pos; + spos.xyz += norm*dist; + + lpos = (shadow_matrix[i]*spos); + vec3 depth = texture2DProj(shadowMap, lpos).xyz; + float d[3]; + d[0] = depth.x; d[1] = depth.y; d[2] = depth.z; + + float sdist = lpos.z/lpos.w - d[i]; + if (sdist > 0) + { + vec3 nz = norm * max(length(pos)/8.0, 1.0) + + texture2D(noiseMap, gl_FragCoord.xy/128.0).xyz; + lpos = (shadow_matrix[i]* + (spos + vec4(nz*0.5, 0.0))); + depth = texture2DProj(shadowMap, lpos).xyz; + d[0] = depth.x; d[1] = depth.y; d[2] = depth.z; + float shadow2 = d[i] < lpos.z/lpos.w ? 0.0 : 1.0; + + shadow = shadow2*0.5; + } + } + + spec *= shadow; + color.rgb += spec * specular; + + color.rgb = atmosTransport(color.rgb); + color.rgb = scaleSoftClip(color.rgb); + color.a = spec * sunAngle2; + + gl_FragColor = color; +} Index: /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl

=======================================================

--- /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl (revision 575) +++ /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl (revision 575) @@ -0,0 +1,16 @@ +/** + * @file avatarShadowF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2D diffuseMap; + + +void main() +{ + gl_FragColor.rgb = vec3(gl_FragCoord.z); + gl_FragColor.a = gl_Color.a * texture2D(diffuseMap, gl_TexCoord[0].xy); +} + Index: /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaF.glsl

=======================================================

--- /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaF.glsl (revision 575) +++ /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaF.glsl (revision 575) @@ -0,0 +1,73 @@ +/** + * @file avatarAlphaF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2D diffuseMap; +uniform sampler2D shadowMap; +uniform sampler2D noiseMap; + +uniform mat4 shadow_matrix[3]; +uniform vec3 shadow_clip; + +vec3 atmosLighting(vec3 light); +vec3 scaleSoftClip(vec3 light); + +varying vec3 vary_ambient; +varying vec3 vary_directional; +varying vec4 vary_position; +varying vec3 vary_normal; + +void main() +{ + float shadow = 1.0; + vec4 pos = vary_position; + vec3 norm = normalize(vary_normal); + float dist = sqrt(-pos.z)*0.1; + + int i = 0; + if (pos.z < -shadow_clip.x) + { + i++; + } + if (pos.z < -shadow_clip.y) + { + i++; + } + + if (pos.z > -shadow_clip.z) + { + vec4 spos = pos; + spos.xyz += norm*dist; + + vec4 lpos = (shadow_matrix[i]*spos); + vec3 depth = texture2DProj(shadowMap, lpos).xyz; + float d[3]; + d[0] = depth.x; d[1] = depth.y; d[2] = depth.z; + + float sdist = lpos.z/lpos.w - d[i]; + if (sdist > 0) + { + vec3 nz = norm * max(length(pos)/8.0, 1.0) + + texture2D(noiseMap, gl_FragCoord.xy/128.0).xyz; + lpos = (shadow_matrix[i]* + (spos + vec4(nz*0.01, 0.0))); + depth = texture2DProj(shadowMap, lpos).xyz; + d[0] = depth.x; d[1] = depth.y; d[2] = depth.z; + float shadow2 = d[i] < lpos.z/lpos.w ? 0.0 : 1.0; + + shadow = shadow2*0.5; + } + } + + vec4 col = vec4(vary_ambient + vary_directional*shadow, gl_Color.a); + vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy) * col; + + color.rgb = atmosLighting(color.rgb); + + color.rgb = scaleSoftClip(color.rgb); + + gl_FragColor = color; +} Index: /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl

=======================================================

--- /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl (revision 575) +++ /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl (revision 575) @@ -0,0 +1,41 @@ +/** + * @file terrainV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +varying vec3 vary_normal; +varying vec4 vary_position; + +vec4 texgen_object(vec4 vpos, vec4 tc, mat4 mat, vec4 tp0, vec4 tp1) +{ + vec4 tcoord; + + tcoord.x = dot(vpos, tp0); + tcoord.y = dot(vpos, tp1); + tcoord.z = tc.z; + tcoord.w = tc.w; + + tcoord = mat * tcoord; + + return tcoord; +} + +void main() +{ + //transform vertex + gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; + + vary_position = gl_ModelViewMatrix * gl_Vertex; + vary_normal = normalize(gl_NormalMatrix * gl_Normal); + + // Transform and pass tex coords + gl_TexCoord[0].xy = texgen_object(gl_Vertex, gl_MultiTexCoord0, gl_TextureMatrix[0], gl_ObjectPlaneS[0], gl_ObjectPlaneT[0]).xy; + + vec4 t = gl_MultiTexCoord1; + + gl_TexCoord[0].zw = t.xy; + gl_TexCoord[1].xy = t.xy-vec2(2.0, 0.0); + gl_TexCoord[1].zw = t.xy-vec2(1.0, 0.0); +} Index: /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl

=======================================================

--- /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl (revision 575) +++ /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl (revision 575) @@ -0,0 +1,15 @@ +/** + * @file shadowF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2D diffuseMap; + + +void main() +{ + gl_FragColor.rgb = vec3(gl_FragCoord.z); + gl_FragColor.a = texture2D(diffuseMap, gl_TexCoord[0].xy).a * gl_Color.a; +} Index: /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl

=======================================================

--- /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl (revision 387) +++ /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl (revision 575) @@ -9,8 +9,12 @@

varying vec3 vary_normal;

+varying vec4 vary_position;

void main() 
{

- gl_FragColor = gl_Color * texture2D(diffuseMap, gl_TexCoord[0].xy); - gl_FragColor.rgb = vary_normal*0.5+0.5; + vec3 col = texture2D(diffuseMap, gl_TexCoord[0].xy).rgb; + gl_FragData[0] = vec4(gl_Color.rgb*col, 1.0); + gl_FragData[1] = vec4(col*(gl_Color.a*1.5), gl_Color.a); + gl_FragData[2].xyz = normalize(vary_normal); + gl_FragData[3] = vary_position;

}

Index: /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl

=======================================================

--- /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl (revision 575) +++ /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl (revision 575) @@ -0,0 +1,75 @@ +/** + * @file alphaF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2D diffuseMap; +uniform sampler2D shadowMap; +uniform sampler2D noiseMap; + +uniform mat4 shadow_matrix[3]; +uniform vec3 shadow_clip; + +vec3 atmosLighting(vec3 light); +vec3 scaleSoftClip(vec3 light); + +varying vec3 vary_ambient; +varying vec3 vary_directional; +varying vec4 vary_position; +varying vec3 vary_normal; + +void main() +{ + float shadow = 1.0; + vec4 pos = vary_position; + vec3 norm = normalize(vary_normal); + float dist = sqrt(-pos.z)*0.1; + + int i = 0; + if (pos.z < -shadow_clip.x) + { + i++; + } + if (pos.z < -shadow_clip.y) + { + i++; + } + + if (pos.z > -shadow_clip.z) + { + vec4 spos = pos; + spos.xyz += norm*dist; + + vec4 lpos = (shadow_matrix[i]*spos); + vec3 depth = texture2DProj(shadowMap, lpos).xyz; + float d[3]; + d[0] = depth.x; d[1] = depth.y; d[2] = depth.z; + + float sdist = lpos.z/lpos.w - d[i]; + if (sdist > 0) + { + vec3 nz = norm * max(length(pos)/8.0, 1.0) + + texture2D(noiseMap, gl_FragCoord.xy/128.0).xyz; + lpos = (shadow_matrix[i]* + (spos + vec4(nz*0.01, 0.0))); + depth = texture2DProj(shadowMap, lpos).xyz; + d[0] = depth.x; d[1] = depth.y; d[2] = depth.z; + float shadow2 = d[i] < lpos.z/lpos.w ? 0.0 : 1.0; + + shadow = shadow2*0.5; + } + } + + vec4 col = vec4(vary_ambient + vary_directional*shadow, gl_Color.a); + vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy) * col; + + color.rgb = atmosLighting(color.rgb); + + color.rgb = scaleSoftClip(color.rgb); + + //gl_FragColor = gl_Color; + gl_FragColor = color; +} + Index: /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl

=======================================================

--- /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl (revision 575) +++ /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl (revision 575) @@ -0,0 +1,106 @@ +/** + * @file softenLightF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2DRect diffuseMap; +uniform sampler2DRect specularMap; +uniform sampler2DRect positionMap; +uniform sampler2DRect normalMap; +uniform sampler2DRect depthMap; +uniform sampler2DRect lightMap; +uniform samplerCube environmentMap; + +uniform vec3 env_mat[3]; + +uniform vec4 gamma; + +vec3 scaleSoftClip(vec3 light) +{ + //soft clip effect: + light = 1. - clamp(light, vec3(0.), vec3(1.)); + light = 1. - pow(light, gamma.xxx); + + return light; +} + +vec2 kern[] = +{ + 16*vec2(0.7, 0.7), + 15*vec2(-0.7, -0.7), + 14*vec2(-0.7, 0.7), + 13*vec2(0.7, -0.7), + 12*vec2(1.0, 0.0), + 11*vec2(-1.0, 0.0), + 10*vec2(0.0, 1.0), + 9*vec2(0.0, -1.0), + + 8*vec2(0.7, 0.7), + 7*vec2(-0.7, -0.7), + 6*vec2(-0.7, 0.7), + 5*vec2(0.7, -0.7), + 4*vec2(1.0, 0.0), + 3*vec2(-1.0, 0.0), + 2*vec2(0.0, 1.0), + 1*vec2(0.0, -1.0) +}; + +void main() +{ + vec3 pos = texture2DRect(positionMap, gl_FragCoord.xy).xyz; + vec3 norm = texture2DRect(normalMap, gl_FragCoord.xy).xyz; + + float dist = clamp(16.0/sqrt(-pos.z), 1.0/8.0, 1.0)*0.5; + vec2 nd = dist/(norm.xy*norm.xy*4.0+1.0); + + vec4 diffuse = vec4(texture2DRect(diffuseMap, gl_FragCoord.xy).rgb, 1.0); + vec4 spec = texture2DRect(specularMap, gl_FragCoord.xy); + + vec4 col = texture2DRect(lightMap, gl_FragCoord.xy); + vec4 centcol = col; + + int count = 1; + + for (int i = 0; i < 16; i++) { + vec2 coord = gl_FragCoord.xy+kern[i]*nd; + //vec3 cpos = texture2DRect(positionMap, coord).xyz; + vec3 cnorm = texture2DRect(normalMap, coord).xyz; + + if (dot(cnorm, norm) > 0.9) { + count++; + col += texture2DRect(lightMap, coord); + + vec4 delta = centcol-col/count; + if (count==5 && + dot(delta, delta) < 0.001) { + // first four coarsest surrounding samples were + // fairly identical to centre; don't bother + // taking any more (quite expensive) samples. + break; + } + } + } + + col = diffuse*col/count; + + spec *= col.a*0.5+0.5; + if (spec.a > 0.2) + { + vec3 ref = reflect(pos.xyz, norm); + vec3 rc; + rc.x = dot(ref, env_mat[0]); + rc.y = dot(ref, env_mat[1]); + rc.z = dot(ref, env_mat[2]); + + vec3 refcol = textureCube(environmentMap, rc).rgb; + col.rgb += refcol * spec.rgb; + } + + gl_FragColor.rgb = col; + //gl_FragColor.rgb = pos/8.0*0.5+0.5; + //gl_FragColor.rgb = vec3(diffuse.a); + gl_FragColor.a = 1.0; + gl_FragDepth = texture2DRect(depthMap, gl_FragCoord.xy).x; +} Index: /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/impostorV.glsl

=======================================================

--- /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/impostorV.glsl (revision 575) +++ /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/impostorV.glsl (revision 575) @@ -0,0 +1,19 @@ +/** + * @file impostorV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +varying vec4 vary_position; + +void main() +{ + //transform vertex + gl_Position = ftransform(); + gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; + + vary_position = gl_ModelViewMatrix * gl_Vertex; + + gl_FrontColor = gl_Color; +} Index: /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl

=======================================================

--- /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl (revision 575) +++ /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl (revision 575) @@ -0,0 +1,294 @@ +/** + * @file sunLightF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +//uniform sampler2DRect diffuseMap; +uniform sampler2DRect specularMap; +uniform sampler2DRect positionMap; +uniform sampler2DRect normalMap; +uniform sampler2DRect depthMap; +uniform sampler2D shadowMap; +uniform sampler2D noiseMap; + +// Inputs +uniform vec4 morphFactor; +uniform vec3 camPosLocal; +//uniform vec4 camPosWorld; +uniform vec4 gamma; +uniform vec4 lightnorm; +uniform vec4 sunlight_color; +uniform vec4 ambient; +uniform vec4 blue_horizon; +uniform vec4 blue_density; +uniform vec4 haze_horizon; +uniform vec4 haze_density; +uniform vec4 cloud_shadow; +uniform vec4 density_multiplier; +uniform vec4 distance_multiplier; +uniform vec4 max_y; +uniform vec4 glow; +uniform float scene_light_strength; +uniform vec3 env_mat[3]; +uniform mat4 shadow_matrix[3]; +uniform vec3 shadow_clip; +varying vec4 vary_light; + +vec3 vary_PositionEye; + +vec3 vary_SunlitColor; +vec3 vary_AmblitColor; +vec3 vary_AdditiveColor; +vec3 vary_AtmosAttenuation; + +vec3 getPositionEye() +{ + return vary_PositionEye; +} +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) { + + vec3 P = inPositionEye; + setPositionEye(P); + + //(TERRAIN) limit altitude + if (P.y > max_y.x) P *= (max_y.x / P.y); + if (P.y < -max_y.x) P *= (-max_y.x / P.y); + + 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 * 1.0 + vec4(haze_density.r) * 0.25) * (density_multiplier.x * max_y.x); + //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.r); + blue_weight = blue_density / temp1; + haze_weight = vec4(haze_density.r) / 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.x; + + // Transparency (-> temp1) + // ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier.x in a variable because the ati + // compiler gets confused. + temp1 = exp(-temp1 * temp2.z * distance_multiplier.x); + + //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.x * 0.5; + + //haze color + setAdditiveColor( + vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow.x) + tmpAmbient) + + (haze_horizon.r * haze_weight) * (sunlight*(1.-cloud_shadow.x) * 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 / scene_light_strength ); +} + +vec3 scaleUpLight(vec3 light) +{ + return (light * scene_light_strength); +} + +vec3 atmosAmbient(vec3 light) +{ + return getAmblitColor() + light / 2.0; +} + +vec3 atmosAffectDirectionalLight(float lightIntensity) +{ + return getSunlitColor() * lightIntensity; +} + +vec3 scaleSoftClip(vec3 light) +{ + //soft clip effect: + light = 1. - clamp(light, vec3(0.), vec3(1.)); + light = 1. - pow(light, gamma.xxx); + + return light; +} + +vec2 kern[] = +{ + vec2(-1.0, -1.0), + vec2(1.0, -1.0), + vec2(1.0, 1.0), + vec2(-1.0, 1.0), + vec2(0.0, -2.0), + vec2(2.0, 0.0), + vec2(0.0, 2.0), + vec2(-2.0, 0.0) +}; + +void main() +{ + vec3 norm = texture2DRect(normalMap, gl_FragCoord.xy).xyz; + //vec3 diffuse = texture2DRect(diffuseMap, gl_FragCoord.xy).rgb; + vec3 nz = texture2D(noiseMap, gl_FragCoord.xy/128.0).xyz; + + vec4 spec = texture2DRect(specularMap, gl_FragCoord.xy); + + float da = max(dot(norm, vary_light.xyz), 0.0); + vec4 pos = texture2DRect(positionMap, gl_FragCoord.xy).xyzw; + nz += norm * max(length(pos)/8.0, 1.0); + calcAtmospherics(pos.xyz); + + float dist = sqrt(-pos.z)*0.05; + + vec3 col = atmosAmbient(vec3(0)); + int i = 0; + if (pos.z < -shadow_clip.x) + { + i++; + } + if (pos.z < -shadow_clip.y) + { + i++; + } + + float shadow = 1.0; + + if (pos.z > -shadow_clip.z) + { + vec4 spos = pos; + spos.xyz += norm*dist; + + vec4 lpos = (shadow_matrix[i]*spos); + vec3 depth = texture2DProj(shadowMap, lpos).xyz; + float d[3]; + d[0] = depth.x; d[1] = depth.y; d[2] = depth.z; + + float sdist = lpos.z/lpos.w - d[i]; + if (sdist > 0) + { + lpos = (shadow_matrix[i]* + (spos + vec4(nz*0.01, 0.0))); + depth = texture2DProj(shadowMap, lpos).xyz; + d[0] = depth.x; d[1] = depth.y; d[2] = depth.z; + float shadow2 = d[i] < lpos.z/lpos.w ? 0.0 : 1.0; + + shadow = shadow2*0.5; + } + } + + col.rgb += atmosAffectDirectionalLight(da) * shadow; + + //col *= diffuse; + + col = atmosLighting(col); + + gl_FragColor.rgb = scaleSoftClip(col); + //gl_FragColor.g = i/3.0; + gl_FragColor.a = shadow; + //lpos.xy /= lpos.w; + //gl_FragColor.rgb = vec3(lpos.x, lpos.y, d[i]); + //gl_FragColor.rgb = vec3((d[i]-lpos.z)/256.0); + //gl_FragColor = texture2D(shadowMap, gl_FragCoord.xy/512.0).x; + gl_FragDepth = texture2DRect(depthMap, gl_FragCoord.xy).x; +} Index: /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl

=======================================================

--- /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl (revision 575) +++ /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl (revision 575) @@ -0,0 +1,42 @@ +/** + * @file avatarV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +mat4 getSkinnedTransform(); + +attribute vec4 weight; + +varying vec3 vary_normal; +varying vec4 vary_position; + +void main() +{ + gl_TexCoord[0] = gl_MultiTexCoord0; + + vec4 pos; + vec3 norm; + + mat4 trans = getSkinnedTransform(); + pos.x = dot(trans[0], gl_Vertex); + pos.y = dot(trans[1], gl_Vertex); + pos.z = dot(trans[2], gl_Vertex); + pos.w = 1.0; + + norm.x = dot(trans[0].xyz, gl_Normal); + norm.y = dot(trans[1].xyz, gl_Normal); + norm.z = dot(trans[2].xyz, gl_Normal); + norm = normalize(norm); + + vary_position = pos; + vary_normal = norm; + + gl_Position = gl_ProjectionMatrix * pos; + //gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; + + gl_FrontColor = gl_Color; +} + + Index: /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl

=======================================================

--- /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl (revision 575) +++ /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl (revision 575) @@ -0,0 +1,20 @@ +/** + * @file treeF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2D diffuseMap; + +varying vec3 vary_normal; +varying vec4 vary_position; + +void main() +{ + vec4 col = texture2D(diffuseMap, gl_TexCoord[0].xy); + gl_FragData[0] = gl_Color*col; + gl_FragData[1] = vec4(0,0,0,0); + gl_FragData[2].xyz = normalize(vary_normal); + gl_FragData[3] = vary_position; +} Index: /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl

=======================================================

--- /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl (revision 575) +++ /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl (revision 575) @@ -0,0 +1,21 @@ +/** + * @file pointLightF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +varying vec4 vary_light; + +void main() +{ + //transform vertex + gl_Position = ftransform(); + + vec4 tex = gl_MultiTexCoord0; + tex.w = 1.0; + + vary_light = gl_MultiTexCoord0; + + gl_FrontColor = gl_Color; +} Index: /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl

=======================================================

--- /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl (revision 575) +++ /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl (revision 575) @@ -0,0 +1,78 @@ +/** + * @file waterV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +void calcAtmospherics(vec3 inPositionEye); + +uniform vec2 d1; +uniform vec2 d2; +uniform float time; +uniform vec3 eyeVec; +uniform float waterHeight; + +varying vec4 refCoord; +varying vec4 littleWave; +varying vec4 view; + +varying vec4 vary_position; +varying vec3 vary_normal; + +float wave(vec2 v, float t, float f, vec2 d, float s) +{ + return (dot(d, v)*f + t*s)*f; +} + +void main() +{ + //transform vertex + vec4 position = gl_Vertex; + mat4 modelViewProj = gl_ModelViewProjectionMatrix; + + vec4 oPosition; + + //get view vector + vec3 oEyeVec; + oEyeVec.xyz = position.xyz-eyeVec; + + float d = length(oEyeVec.xy); + float ld = min(d, 2560.0); + + position.xy = eyeVec.xy + oEyeVec.xy/d*ld; + view.xyz = oEyeVec; + + d = clamp(ld/1536.0-0.5, 0.0, 1.0); + d *= d; + + oPosition = position; + oPosition.z = mix(oPosition.z, max(eyeVec.z*0.75, 0.0), d); + vary_position = gl_ModelViewMatrix * oPosition; + vary_normal = normalize(gl_NormalMatrix * vec3(0, 0, 1)); + oPosition = modelViewProj * oPosition; + + refCoord.xyz = oPosition.xyz + vec3(0,0,0.2); + + //get wave position parameter (create sweeping horizontal waves) + vec3 v = position.xyz; + v.x += (cos(v.x*0.08/*+time*0.01*/)+sin(v.y*0.02))*6.0; + + //push position for further horizon effect. + position.xyz = oEyeVec.xyz*(waterHeight/oEyeVec.z); + position.w = 1.0; + position = position*gl_ModelViewMatrix; + + calcAtmospherics((gl_ModelViewMatrix * gl_Vertex).xyz); + + + //pass wave parameters to pixel shader + vec2 bigWave = (v.xy) * vec2(0.04,0.04) + d1 * time * 0.055; + //get two normal map (detail map) texture coordinates + littleWave.xy = (v.xy) * vec2(0.45, 0.9) + d2 * time * 0.13; + littleWave.zw = (v.xy) * vec2(0.1, 0.2) + d1 * time * 0.1; + view.w = bigWave.y; + refCoord.w = bigWave.x; + + gl_Position = oPosition; +} Index: /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl

=======================================================

--- /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl (revision 575) +++ /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl (revision 575) @@ -0,0 +1,35 @@ +/** + * @file avatarShadowV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +mat4 getSkinnedTransform(); + +attribute vec4 weight; + +void main() +{ + gl_TexCoord[0] = gl_MultiTexCoord0; + + vec4 pos; + vec3 norm; + + mat4 trans = getSkinnedTransform(); + pos.x = dot(trans[0], gl_Vertex); + pos.y = dot(trans[1], gl_Vertex); + pos.z = dot(trans[2], gl_Vertex); + pos.w = 1.0; + + norm.x = dot(trans[0].xyz, gl_Normal); + norm.y = dot(trans[1].xyz, gl_Normal); + norm.z = dot(trans[2].xyz, gl_Normal); + norm = normalize(norm); + + gl_Position = gl_ProjectionMatrix * pos; + + gl_FrontColor = gl_Color; +} + + Index: /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl

=======================================================

--- /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl (revision 575) +++ /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl (revision 575) @@ -0,0 +1,78 @@ +/** + * @file avatarAlphaV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); +mat4 getSkinnedTransform(); +void calcAtmospherics(vec3 inPositionEye); + +float calcDirectionalLight(vec3 n, vec3 l); +float calcPointLight(vec3 v, vec3 n, vec4 lp, float la); + +vec3 atmosAmbient(vec3 light); +vec3 atmosAffectDirectionalLight(float lightIntensity); +vec3 scaleDownLight(vec3 light); +vec3 scaleUpLight(vec3 light); + +varying vec4 vary_position; +varying vec3 vary_ambient; +varying vec3 vary_directional; +varying vec3 vary_normal; + +void main() +{ + gl_TexCoord[0] = gl_MultiTexCoord0; + + vec4 pos; + vec3 norm; + + mat4 trans = getSkinnedTransform(); + pos.x = dot(trans[0], gl_Vertex); + pos.y = dot(trans[1], gl_Vertex); + pos.z = dot(trans[2], gl_Vertex); + pos.w = 1.0; + + norm.x = dot(trans[0].xyz, gl_Normal); + norm.y = dot(trans[1].xyz, gl_Normal); + norm.z = dot(trans[2].xyz, gl_Normal); + norm = normalize(norm); + + gl_Position = gl_ProjectionMatrix * pos; + vary_position = pos; + vary_normal = norm; + + calcAtmospherics(pos.xyz); + + //vec4 color = calcLighting(pos.xyz, norm, gl_Color, vec4(0.)); + vec4 col; + col.a = gl_Color.a; + + // Add windlight lights + col.rgb = atmosAmbient(vec4(0.)); + col.rgb = scaleUpLight(col.rgb); + + // Collect normal lights (need to be divided by two, as we later multiply by 2) + col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].linearAttenuation); + col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].linearAttenuation); + col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].linearAttenuation); + col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].linearAttenuation); + col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].linearAttenuation); + col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].linearAttenuation); + col.rgb += gl_LightSource[1].diffuse.rgb*calcDirectionalLight(norm, gl_LightSource[1].position.xyz); + col.rgb = scaleDownLight(col.rgb); + + vary_ambient = col.rgb*gl_Color.rgb; + vary_directional = gl_Color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, gl_LightSource[0].position.xyz), (1.0-gl_Color.a)*(1.0-gl_Color.a))); + + col.rgb = min(col.rgb*gl_Color.rgb, 1.0); + + gl_FrontColor = col; + + gl_FogFragCoord = pos.z; + +} + + Index: /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl

=======================================================

--- /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl (revision 575) +++ /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl (revision 575) @@ -0,0 +1,36 @@ +/** + * @file terrainF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2D detail_0; +uniform sampler2D detail_1; +uniform sampler2D detail_2; +uniform sampler2D detail_3; +uniform sampler2D alpha_ramp; + +varying vec3 vary_normal; +varying vec4 vary_position; + +void main() +{ + /// Note: This should duplicate the blending functionality currently used for the terrain rendering. + + vec4 color0 = texture2D(detail_0, gl_TexCoord[0].xy); + vec4 color1 = texture2D(detail_1, gl_TexCoord[0].xy); + vec4 color2 = texture2D(detail_2, gl_TexCoord[0].xy); + vec4 color3 = texture2D(detail_3, gl_TexCoord[0].xy); + + float alpha1 = texture2D(alpha_ramp, gl_TexCoord[0].zw).a; + float alpha2 = texture2D(alpha_ramp,gl_TexCoord[1].xy).a; + float alphaFinal = texture2D(alpha_ramp, gl_TexCoord[1].zw).a; + vec4 outColor = mix( mix(color3, color2, alpha2), mix(color1, color0, alpha1), alphaFinal ); + + gl_FragData[0] = vec4(outColor.rgb, 1.0); + gl_FragData[1] = vec4(outColor.rgb*0.2, 0.2); + gl_FragData[2].xyz = normalize(vary_normal); + gl_FragData[3] = vary_position; +} + Index: /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl

=======================================================

--- /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl (revision 575) +++ /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl (revision 575) @@ -0,0 +1,14 @@ +/** + * @file shadowV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +void main() +{ + //transform vertex + gl_Position = ftransform(); + gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; + gl_FrontColor = gl_Color; +} Index: /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl

=======================================================

--- /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl (revision 387) +++ /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl (revision 575) @@ -7,5 +7,5 @@

varying vec3 vary_normal;

-varying vec3 vary_position; +varying vec4 vary_position;

void main()

@@ -15,5 +15,5 @@

	gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
	

- vary_position = (gl_ModelViewMatrix * gl_Vertex).xyz; + vary_position = gl_ModelViewMatrix * gl_Vertex;

	vary_normal = normalize(gl_NormalMatrix * gl_Normal);

Index: /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl

=======================================================

--- /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl (revision 575) +++ /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl (revision 575) @@ -0,0 +1,65 @@ +/** + * @file alphaV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); +void calcAtmospherics(vec3 inPositionEye); + +float calcDirectionalLight(vec3 n, vec3 l); +float calcPointLight(vec3 v, vec3 n, vec4 lp, float la); + +vec3 atmosAmbient(vec3 light); +vec3 atmosAffectDirectionalLight(float lightIntensity); +vec3 scaleDownLight(vec3 light); +vec3 scaleUpLight(vec3 light); + +varying vec4 vary_position; +varying vec3 vary_ambient; +varying vec3 vary_directional; +varying vec3 vary_normal; + +void main() +{ + //transform vertex + gl_Position = ftransform(); + + gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; + + vec4 pos = (gl_ModelViewMatrix * gl_Vertex); + vary_position = pos; + + vec3 norm = normalize(gl_NormalMatrix * gl_Normal); + vary_normal = norm; + + calcAtmospherics(pos.xyz); + + //vec4 color = calcLighting(pos.xyz, norm, gl_Color, vec4(0.)); + vec4 col; + col.a = gl_Color.a; + + // Add windlight lights + col.rgb = atmosAmbient(vec4(0.)); + col.rgb = scaleUpLight(col.rgb); + + // Collect normal lights (need to be divided by two, as we later multiply by 2) + col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].linearAttenuation); + col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].linearAttenuation); + col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].linearAttenuation); + col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].linearAttenuation); + col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].linearAttenuation); + col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].linearAttenuation); + col.rgb += gl_LightSource[1].diffuse.rgb*calcDirectionalLight(norm, gl_LightSource[1].position.xyz); + col.rgb = scaleDownLight(col.rgb); + + vary_ambient = col.rgb*gl_Color.rgb; + vary_directional = gl_Color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, gl_LightSource[0].position.xyz), (1.0-gl_Color.a)*(1.0-gl_Color.a))); + + col.rgb = min(col.rgb*gl_Color.rgb, 1.0); + + gl_FrontColor = col; + + gl_FogFragCoord = pos.z; +} Index: /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl

=======================================================

--- /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl (revision 575) +++ /branches/shadow-draft/indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl (revision 575) @@ -0,0 +1,12 @@ +/** + * @file softenLightF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +void main() +{ + //transform vertex + gl_Position = ftransform(); +} Index: /branches/shadow-draft/indra/newview/app_settings/shaders/class1/environment/waterF.glsl

=======================================================

--- /branches/shadow-draft/indra/newview/app_settings/shaders/class1/environment/waterF.glsl (revision 487) +++ /branches/shadow-draft/indra/newview/app_settings/shaders/class1/environment/waterF.glsl (revision 575) @@ -8,4 +8,5 @@

vec3 scaleSoftClip(vec3 inColor);
vec3 atmosTransport(vec3 inColor);

+vec3 applyWaterFog(vec4 inColor);

uniform sampler2D diffuseMap;

Index: /branches/shadow-draft/indra/newview/app_settings/settings.xml

=======================================================

--- /branches/shadow-draft/indra/newview/app_settings/settings.xml (revision 543) +++ /branches/shadow-draft/indra/newview/app_settings/settings.xml (revision 575) @@ -1715,4 +1715,15 @@

            <integer>0</integer>
        </map>

+ <key>DebugShowRenderMatrices</key> + <map> + <key>Comment</key> + <string>Display values of current view and projection matrices.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map>

    <key>DebugShowTime</key>
        <map>

@@ -5291,5 +5302,73 @@

            <integer>1</integer>
        </map>

- <key>RenderBumpmapMinDistanceSquared</key> + + + <key>RenderShadowNearDist</key> + <map> + <key>Comment</key> + <string>Near clip plane of shadow camera (affects precision of depth shadows).</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>10</real> + </map> + + <key>RenderShadowClipPlanes</key> + <map> + <key>Comment</key> + <string>Near clip plane split distances for shadow map frusta.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Vector3</string> + <key>Value</key> + <array> + <real>8.0</real> + <real>24.0</real> + <real>128.0</real> + </array> + </map> + + + <key>RenderSSAOScale</key> + <map> + <key>Comment</key> + <string>Currently unused</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>100</real> + </map> + + <key>RenderSSAOBackground</key> + <map> + <key>Comment</key> + <string>Currently unused</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>100</real> + </map> + + <key>RenderSSAOForeground</key> + <map> + <key>Comment</key> + <string>Currently unused</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>100</real> + </map> + + + <key>RenderBumpmapMinDistanceSquared</key>

        <map>
        <key>Comment</key>

@@ -9857,6 +9936,17 @@

			<string>Boolean</string>
		<key>Value</key>

- <integer>0</integer> + <integer>1</integer>

		</map>

+ <key>RenderDeferredSunWash</key> + <map> + <key>Comment</key> + <string>Amount local lights are washed out by sun.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>0.5</real> + </map>

    <key>RenderFSAASamples</key>
		<map>

Index: /branches/shadow-draft/indra/newview/lldrawpoolsimple.cpp

=======================================================

--- /branches/shadow-draft/indra/newview/lldrawpoolsimple.cpp (revision 573) +++ /branches/shadow-draft/indra/newview/lldrawpoolsimple.cpp (revision 575) @@ -158,20 +158,108 @@

	}			

- { //render fullbright - if (mVertexShaderLevel > 0) - { - fullbright_shader->bind(); - fullbright_shader->uniform1f(LLShaderMgr::FULLBRIGHT, 1.f); - } - else - { - gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); - } - LLFastTimer t(LLFastTimer::FTM_RENDER_FULLBRIGHT); - U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD | LLVertexBuffer::MAP_COLOR; - renderTexture(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask); - } -

	gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
}

+//=============================== +//DEFERRED IMPLEMENTATION +//=============================== + +void LLDrawPoolSimple::beginDeferredPass(S32 pass) +{ + LLFastTimer t(LLFastTimer::FTM_RENDER_SIMPLE); + gDeferredDiffuseProgram.bind(); +} + +void LLDrawPoolSimple::endDeferredPass(S32 pass) +{ + LLFastTimer t(LLFastTimer::FTM_RENDER_SIMPLE); + LLRenderPass::endRenderPass(pass); + + gDeferredDiffuseProgram.unbind(); +} + +void LLDrawPoolSimple::renderDeferred(S32 pass) +{ + LLGLDisable blend(GL_BLEND); + LLGLState alpha_test(GL_ALPHA_TEST, gPipeline.canUseWindLightShadersOnObjects()); + + gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); + + { //render simple + LLFastTimer t(LLFastTimer::FTM_RENDER_SIMPLE); + renderTexture(LLRenderPass::PASS_SIMPLE, getVertexDataMask()); + } + + { + LLFastTimer t(LLFastTimer::FTM_RENDER_GRASS); + gDeferredTreeProgram.bind(); + LLGLEnable test(GL_ALPHA_TEST); + //render grass + LLRenderPass::renderTexture(LLRenderPass::PASS_GRASS, getVertexDataMask()); + } + + gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); +} + +// Fullbright drawpool +LLDrawPoolFullbright::LLDrawPoolFullbright() : + LLRenderPass(POOL_FULLBRIGHT) +{ +} + +void LLDrawPoolFullbright::prerender() +{ + mVertexShaderLevel = LLShaderMgr::getVertexShaderLevel(LLShaderMgr::SHADER_OBJECT); +} + +void LLDrawPoolFullbright::beginRenderPass(S32 pass) +{ + LLFastTimer t(LLFastTimer::FTM_RENDER_FULLBRIGHT); + + if (LLPipeline::sUnderWaterRender) + { + fullbright_shader = &gObjectFullbrightWaterProgram; + } + else + { + fullbright_shader = &gObjectFullbrightProgram; + } +} + +void LLDrawPoolFullbright::endRenderPass(S32 pass) +{ + LLFastTimer t(LLFastTimer::FTM_RENDER_FULLBRIGHT); + LLRenderPass::endRenderPass(pass); + + if (mVertexShaderLevel > 0) + { + fullbright_shader->unbind(); + } +} + +void LLDrawPoolFullbright::render(S32 pass) +{ //render fullbright + LLFastTimer t(LLFastTimer::FTM_RENDER_FULLBRIGHT); + if (mVertexShaderLevel > 0) + { + fullbright_shader->bind(); + fullbright_shader->uniform1f(LLShaderMgr::FULLBRIGHT, 1.f); + } + else + { + gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); + } + + gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); + + U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD | LLVertexBuffer::MAP_COLOR; + renderTexture(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask); + + gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); +} + +S32 LLDrawPoolFullbright::getNumPasses() +{ + return 1; +} + Index: /branches/shadow-draft/indra/newview/lldrawpooltree.cpp

=======================================================

--- /branches/shadow-draft/indra/newview/lldrawpooltree.cpp (revision 573) +++ /branches/shadow-draft/indra/newview/lldrawpooltree.cpp (revision 575) @@ -114,4 +114,52 @@

	}
}

+ +//============================================ +// deferred implementation +//============================================ +void LLDrawPoolTree::beginDeferredPass(S32 pass) +{ + LLFastTimer t(LLFastTimer::FTM_RENDER_TREES); + gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); + + shader = &gDeferredTreeProgram; + shader->bind(); +} + +void LLDrawPoolTree::renderDeferred(S32 pass) +{ + render(pass); +} + +void LLDrawPoolTree::endDeferredPass(S32 pass) +{ + LLFastTimer t(LLFastTimer::FTM_RENDER_TREES); + gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); + + shader->unbind(); +} + +//============================================ +// shadow implementation +//============================================ +void LLDrawPoolTree::beginShadowPass(S32 pass) +{ + LLFastTimer t(LLFastTimer::FTM_RENDER_TREES); + gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); + gDeferredShadowProgram.bind(); +} + +void LLDrawPoolTree::renderShadow(S32 pass) +{ + render(pass); +} + +void LLDrawPoolTree::endShadowPass(S32 pass) +{ + LLFastTimer t(LLFastTimer::FTM_RENDER_TREES); + gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); + gDeferredShadowProgram.unbind(); +} +

void LLDrawPoolTree::renderForSelect()

Index: /branches/shadow-draft/indra/newview/lldrawpoolalpha.h

=======================================================

--- /branches/shadow-draft/indra/newview/lldrawpoolalpha.h (revision 543) +++ /branches/shadow-draft/indra/newview/lldrawpoolalpha.h (revision 575) @@ -55,4 +55,9 @@

	/*virtual*/ ~LLDrawPoolAlpha();

+ /*virtual*/ S32 getNumPostDeferredPasses(); + /*virtual*/ void beginPostDeferredPass(S32 pass); + /*virtual*/ void endPostDeferredPass(S32 pass); + /*virtual*/ void renderPostDeferred(S32 pass); +

	/*virtual*/ void beginRenderPass(S32 pass = 0);
	/*virtual*/ void endRenderPass( S32 pass );

Index: /branches/shadow-draft/indra/newview/llglslshader.h

=======================================================

--- /branches/shadow-draft/indra/newview/llglslshader.h (revision 573) +++ /branches/shadow-draft/indra/newview/llglslshader.h (revision 575) @@ -262,4 +262,10 @@

		GAMMA,
		SCENE_LIGHT_STRENGTH,

+ DEFERRED_DEPTH, + DEFERRED_SHADOW, + DEFERRED_NORMAL, + DEFERRED_POSITION, + DEFERRED_NOISE, + DEFERRED_LIGHT,

		END_RESERVED_UNIFORMS
	} eGLSLReservedUniforms;

@@ -413,5 +419,17 @@

// Deferred rendering shaders

+extern LLGLSLShader gDeferredImpostorProgram; +extern LLGLSLShader gDeferredWaterProgram;

extern LLGLSLShader			gDeferredDiffuseProgram;

+extern LLGLSLShader gDeferredTerrainProgram; +extern LLGLSLShader gDeferredTreeProgram; +extern LLGLSLShader gDeferredLightProgram; +extern LLGLSLShader gDeferredSunProgram; +extern LLGLSLShader gDeferredAvatarProgram; +extern LLGLSLShader gDeferredSoftenProgram; +extern LLGLSLShader gDeferredShadowProgram; +extern LLGLSLShader gDeferredAvatarShadowProgram; +extern LLGLSLShader gDeferredAlphaProgram; +extern LLGLSLShader gDeferredAvatarAlphaProgram;

//current avatar shader parameter pointer

Index: /branches/shadow-draft/indra/newview/llvoavatar.h

=======================================================

--- /branches/shadow-draft/indra/newview/llvoavatar.h (revision 521) +++ /branches/shadow-draft/indra/newview/llvoavatar.h (revision 575) @@ -295,5 +295,5 @@

	U32 renderRigid();
	U32 renderSkinned(EAvatarRenderPass pass);

- U32 renderTransparent(); + U32 renderTransparent(BOOL first_pass);

	void renderCollisionVolumes();
	

Index: /branches/shadow-draft/indra/newview/lldrawpoolalpha.cpp

=======================================================

--- /branches/shadow-draft/indra/newview/lldrawpoolalpha.cpp (revision 573) +++ /branches/shadow-draft/indra/newview/lldrawpoolalpha.cpp (revision 575) @@ -76,4 +76,38 @@

}

+S32 LLDrawPoolAlpha::getNumPostDeferredPasses() +{ + return 1; +} + +void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass) +{ + LLFastTimer t(LLFastTimer::FTM_RENDER_ALPHA); + + simple_shader = &gDeferredAlphaProgram; + gPipeline.bindDeferredShader(*simple_shader); + fullbright_shader = &gObjectFullbrightProgram; + + if (mVertexShaderLevel > 0) + { + // Start out with no shaders. + current_shader = target_shader = NULL; + glUseProgramObjectARB(0); + } + gPipeline.enableLightsDynamic(); +} + +void LLDrawPoolAlpha::endPostDeferredPass(S32 pass) +{ + endRenderPass(pass); + simple_shader->bind(); + gPipeline.unbindDeferredShader(*simple_shader); +} + +void LLDrawPoolAlpha::renderPostDeferred(S32 pass) +{ + render(pass); +} +

void LLDrawPoolAlpha::beginRenderPass(S32 pass)
{

Index: /branches/shadow-draft/indra/newview/lldrawpoolavatar.cpp

=======================================================

--- /branches/shadow-draft/indra/newview/lldrawpoolavatar.cpp (revision 573) +++ /branches/shadow-draft/indra/newview/lldrawpoolavatar.cpp (revision 575) @@ -54,4 +54,6 @@

static LLGLSLShader* sVertexProgram = NULL;

+BOOL LLDrawPoolAvatar::sSkipOpaque = FALSE; +

extern BOOL gUseGLPick;

@@ -87,4 +89,6 @@

BOOL gAvatarEmbossBumpMap = FALSE;
static BOOL sRenderingSkinned = FALSE;

+S32 normal_channel = -1; +S32 specular_channel = -1;

LLDrawPoolAvatar::LLDrawPoolAvatar() :

@@ -114,4 +118,5 @@

{
	mVertexShaderLevel = LLShaderMgr::getVertexShaderLevel(LLShaderMgr::SHADER_AVATAR);

+

	sShaderLevel = mVertexShaderLevel;
	

@@ -142,4 +147,178 @@

//-----------------------------------------------------------------------------

+ +S32 LLDrawPoolAvatar::getNumDeferredPasses() +{ + return getNumPasses(); +} + +void LLDrawPoolAvatar::beginDeferredPass(S32 pass) +{ + LLFastTimer t(LLFastTimer::FTM_RENDER_CHARACTERS); + + if (LLPipeline::sImpostorRender) + { + beginDeferredSkinned(); + return; + } + + switch (pass) + { + case 0: + beginDeferredImpostor(); + break; + case 1: + beginDeferredRigid(); + break; + case 2: + beginDeferredSkinned(); + break; + } +} + +void LLDrawPoolAvatar::endDeferredPass(S32 pass) +{ + LLFastTimer t(LLFastTimer::FTM_RENDER_CHARACTERS); + + if (LLPipeline::sImpostorRender) + { + endDeferredSkinned(); + return; + } + + switch (pass) + { + case 0: + endDeferredImpostor(); + break; + case 1: + endDeferredRigid(); + break; + case 2: + endDeferredSkinned(); + break; + } +} + +void LLDrawPoolAvatar::renderDeferred(S32 pass) +{ + render(pass); +} + +S32 LLDrawPoolAvatar::getNumPostDeferredPasses() +{ + return 1; +} + +void LLDrawPoolAvatar::beginPostDeferredPass(S32 pass) +{ + sSkipOpaque = TRUE; + sShaderLevel = mVertexShaderLevel; + sVertexProgram = &gDeferredAvatarAlphaProgram; + + sRenderingSkinned = TRUE; + + gPipeline.bindDeferredShader(*sVertexProgram); + + enable_vertex_weighting(sVertexProgram->mAttribute[LLShaderMgr::AVATAR_WEIGHT]); + + glActiveTextureARB(GL_TEXTURE0_ARB); +} + +void LLDrawPoolAvatar::endPostDeferredPass(S32 pass) +{ + // if we're in software-blending, remember to set the fence _after_ we draw so we wait till this rendering is done + sRenderingSkinned = FALSE; + sSkipOpaque = FALSE; + disable_vertex_weighting(sVertexProgram->mAttribute[LLShaderMgr::AVATAR_WEIGHT]); + + gPipeline.unbindDeferredShader(*sVertexProgram); + + sShaderLevel = mVertexShaderLevel; + + glActiveTextureARB(GL_TEXTURE0_ARB); +} + +void LLDrawPoolAvatar::renderPostDeferred(S32 pass) +{ + render(2); //pass 2 = skinned +} + + +S32 LLDrawPoolAvatar::getNumShadowPasses() +{ + return 1; +} + +void LLDrawPoolAvatar::beginShadowPass(S32 pass) +{ + LLFastTimer t(LLFastTimer::FTM_RENDER_CHARACTERS); + + sVertexProgram = &gDeferredAvatarShadowProgram; + if (sShaderLevel > 0) + { + gAvatarMatrixParam = sVertexProgram->mUniform[LLShaderMgr::AVATAR_MATRIX]; + } + gGL.setAlphaRejectSettings(LLRender::CF_GREATER_EQUAL, 0.2f); + + glColor4f(1,1,1,1); + + if ((sShaderLevel > 0)) // for hardware blending + { + sRenderingSkinned = TRUE; + sVertexProgram->bind(); + enable_vertex_weighting(sVertexProgram->mAttribute[LLShaderMgr::AVATAR_WEIGHT]); + } + +} + +void LLDrawPoolAvatar::endShadowPass(S32 pass) +{ + LLFastTimer t(LLFastTimer::FTM_RENDER_CHARACTERS); + + if (sShaderLevel > 0) + { + sRenderingSkinned = FALSE; + sVertexProgram->unbind(); + disable_vertex_weighting(sVertexProgram->mAttribute[LLShaderMgr::AVATAR_WEIGHT]); + } + + gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); +} + +void LLDrawPoolAvatar::renderShadow(S32 pass) +{ + if (!gRenderAvatar) + { + return; + } + + if (mDrawFace.empty()) + { + return; + } + + const LLFace *facep = mDrawFace[0]; + if (!facep->getDrawable()) + { + return; + } + LLVOAvatar *avatarp = (LLVOAvatar *)facep->getDrawable()->getVObj().get(); + + if (avatarp->isDead() || avatarp->mIsDummy || avatarp->mDrawable.isNull()) + { + return; + } + + BOOL impostor = avatarp->isImpostor(); + if (impostor) + { + return; + } + + avatarp->renderSkinned(AVATAR_RENDER_PASS_SINGLE); + +} +

S32 LLDrawPoolAvatar::getNumPasses()
{

@@ -257,4 +436,45 @@

}

+void LLDrawPoolAvatar::beginDeferredImpostor() +{ + if (!LLPipeline::sReflectionRender) + { + LLVOAvatar::sRenderDistance = llclamp(LLVOAvatar::sRenderDistance, 16.f, 256.f); + LLVOAvatar::sNumVisibleAvatars = 0; + } + + sVertexProgram = &gDeferredImpostorProgram; + + normal_channel = sVertexProgram->enableTexture(LLShaderMgr::DEFERRED_NORMAL); + specular_channel = sVertexProgram->enableTexture(LLShaderMgr::SPECULAR_MAP); + glActiveTextureARB(GL_TEXTURE0_ARB); + + sVertexProgram->bind(); +} + +void LLDrawPoolAvatar::endDeferredImpostor() +{ + sShaderLevel = mVertexShaderLevel; + sVertexProgram->disableTexture(LLShaderMgr::DEFERRED_NORMAL); + sVertexProgram->disableTexture(LLShaderMgr::SPECULAR_MAP); + glActiveTextureARB(GL_TEXTURE0_ARB); + glEnable(GL_TEXTURE_2D); + sVertexProgram->unbind(); +} + +void LLDrawPoolAvatar::beginDeferredRigid() +{ + sVertexProgram = &gDeferredDiffuseProgram; + + sVertexProgram->bind(); +} + +void LLDrawPoolAvatar::endDeferredRigid() +{ + sShaderLevel = mVertexShaderLevel; + sVertexProgram->unbind(); +} + +

void LLDrawPoolAvatar::beginSkinned()
{

@@ -286,5 +506,5 @@

	{
		sRenderingSkinned = TRUE;

- +

		sVertexProgram->bind();
		if (sShaderLevel >= SHADER_LEVEL_CLOTH)

@@ -321,4 +541,5 @@

		sVertexProgram->disableTexture(LLShaderMgr::BUMP_MAP);
		gGL.getTexUnit(0)->activate();

+

		disable_vertex_weighting(sVertexProgram->mAttribute[LLShaderMgr::AVATAR_WEIGHT]);
		if (sShaderLevel >= SHADER_LEVEL_BUMP)

@@ -345,4 +566,30 @@

	gGL.getTexUnit(0)->activate();

+} + +void LLDrawPoolAvatar::beginDeferredSkinned() +{ + sShaderLevel = mVertexShaderLevel; + sVertexProgram = &gDeferredAvatarProgram; + + sRenderingSkinned = TRUE; + + sVertexProgram->bind(); + + enable_vertex_weighting(sVertexProgram->mAttribute[LLShaderMgr::AVATAR_WEIGHT]); + + glActiveTextureARB(GL_TEXTURE0_ARB); +} + +void LLDrawPoolAvatar::endDeferredSkinned() +{ + // if we're in software-blending, remember to set the fence _after_ we draw so we wait till this rendering is done + sRenderingSkinned = FALSE; + disable_vertex_weighting(sVertexProgram->mAttribute[LLShaderMgr::AVATAR_WEIGHT]); + sVertexProgram->unbind(); + + sShaderLevel = mVertexShaderLevel; + + glActiveTextureARB(GL_TEXTURE0_ARB);

}

@@ -444,7 +691,21 @@

		if (impostor)
		{

+ if (LLPipeline::sRenderDeferred && avatarp->mImpostor.isComplete()) + { + if (normal_channel > -1) + { + glActiveTextureARB(GL_TEXTURE0_ARB+normal_channel); + avatarp->mImpostor.bindTexture(2); + } + if (specular_channel > -1) + { + glActiveTextureARB(GL_TEXTURE0_ARB+specular_channel); + avatarp->mImpostor.bindTexture(1); + } + glActiveTextureARB(GL_TEXTURE0_ARB); + }

			avatarp->renderImpostor();
		}

- else if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FOOT_SHADOWS)) + else if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FOOT_SHADOWS) && !LLPipeline::sRenderDeferred)

		{
			avatarp->renderFootShadows();	

@@ -687,8 +948,4 @@

		glVertexPointer(3,GL_FLOAT, mStride, (void*)(base + 0));
		glNormalPointer(GL_FLOAT, mStride, (void*)(base + mOffsets[TYPE_NORMAL]));

- - glClientActiveTextureARB(GL_TEXTURE1_ARB); - glTexCoordPointer(2,GL_FLOAT, mStride, (void*)(base + mOffsets[TYPE_TEXCOORD2])); - glClientActiveTextureARB(GL_TEXTURE0_ARB);

		glTexCoordPointer(2,GL_FLOAT, mStride, (void*)(base + mOffsets[TYPE_TEXCOORD]));
		

Index: /branches/shadow-draft/indra/newview/lldrawpooltree.h

=======================================================

--- /branches/shadow-draft/indra/newview/lldrawpooltree.h (revision 280) +++ /branches/shadow-draft/indra/newview/lldrawpooltree.h (revision 575) @@ -53,4 +53,15 @@

	/*virtual*/ void prerender();

+ + /*virtual*/ S32 getNumDeferredPasses() { return 1; } + /*virtual*/ void beginDeferredPass(S32 pass); + /*virtual*/ void endDeferredPass(S32 pass); + /*virtual*/ void renderDeferred(S32 pass); + + /*virtual*/ S32 getNumShadowPasses() { return 1; } + /*virtual*/ void beginShadowPass(S32 pass); + /*virtual*/ void endShadowPass(S32 pass); + /*virtual*/ void renderShadow(S32 pass); +

	/*virtual*/ void beginRenderPass( S32 pass );
	/*virtual*/ void render(S32 pass = 0);

Index: /branches/shadow-draft/indra/newview/lldrawable.cpp

=======================================================

--- /branches/shadow-draft/indra/newview/lldrawable.cpp (revision 521) +++ /branches/shadow-draft/indra/newview/lldrawable.cpp (revision 575) @@ -1191,5 +1191,6 @@

	LLVector3 size = (mExtents[1]-mExtents[0]) * 0.5f;

- if (LLPipeline::sImpostorRender || + if ((LLPipeline::sShadowRender && camera_in.AABBInFrustum(center, size)) || + LLPipeline::sImpostorRender ||

		(camera_in.AABBInFrustumNoFarClip(center, size) && 
		AABBSphereIntersect(mExtents[0], mExtents[1], camera_in.getOrigin(), camera_in.mFrustumCornerDist)))

Index: /branches/shadow-draft/indra/newview/lldrawpoolwlsky.h

=======================================================

--- /branches/shadow-draft/indra/newview/lldrawpoolwlsky.h (revision 280) +++ /branches/shadow-draft/indra/newview/lldrawpoolwlsky.h (revision 575) @@ -50,4 +50,9 @@

	/*virtual*/ BOOL isDead() { return FALSE; }

+ /*virtual*/ S32 getNumPostDeferredPasses() { return getNumPasses(); } + /*virtual*/ void beginPostDeferredPass(S32 pass) { beginRenderPass(pass); } + /*virtual*/ void endPostDeferredPass(S32 pass) { endRenderPass(pass); } + /*virtual*/ void renderPostDeferred(S32 pass) { render(pass); } +

	/*virtual*/ LLViewerImage *getDebugTexture();
	/*virtual*/ void beginRenderPass( S32 pass );

Index: /branches/shadow-draft/indra/newview/llface.cpp

=======================================================

--- /branches/shadow-draft/indra/newview/llface.cpp (revision 573) +++ /branches/shadow-draft/indra/newview/llface.cpp (revision 575) @@ -178,18 +178,27 @@

void LLFace::destroy()
{

+ if (mDrawPoolp) + { + mDrawPoolp->removeFace(this); + mDrawPoolp = NULL; + } + + if (mTextureMatrix) + { + delete mTextureMatrix; + mTextureMatrix = NULL; + + if (mDrawablep.notNull()) + { + LLSpatialGroup* group = mDrawablep->getSpatialGroup(); + if (group) + { + group->dirtyGeom(); + } + } + } +

	mDrawablep = NULL;
	mVObjp = NULL;

- - if (mDrawPoolp) - { - mDrawPoolp->removeFace(this); - mDrawPoolp = NULL; - } - - if (mTextureMatrix) - { - delete mTextureMatrix; - mTextureMatrix = NULL; - }

}

@@ -943,5 +952,5 @@

		};

- if (getPoolType() != LLDrawPool::POOL_ALPHA && LLPipeline::sRenderBump && tep->getShiny()) + if (getPoolType() != LLDrawPool::POOL_ALPHA && (LLPipeline::sRenderDeferred || LLPipeline::sRenderBump && tep->getShiny()))

		{
			color.mV[3] = U8 (alpha[tep->getShiny()] * 255);

Index: /branches/shadow-draft/indra/newview/lldrawpool.cpp

=======================================================

--- /branches/shadow-draft/indra/newview/lldrawpool.cpp (revision 573) +++ /branches/shadow-draft/indra/newview/lldrawpool.cpp (revision 575) @@ -68,4 +68,7 @@

		poolp = new LLDrawPoolSimple();
		break;

+ case POOL_FULLBRIGHT: + poolp = new LLDrawPoolFullbright(); + break;

	case POOL_INVISIBLE:
		poolp = new LLDrawPoolInvisible();

@@ -133,7 +136,85 @@

}

+//virtual +S32 LLDrawPool::getNumPasses() +{ + return 1; +} + +//virtual +void LLDrawPool::beginDeferredPass(S32 pass) +{ + +} + +//virtual +void LLDrawPool::endDeferredPass(S32 pass) +{ + +} + +//virtual +S32 LLDrawPool::getNumDeferredPasses() +{ + return 0; +} + +//virtual +void LLDrawPool::renderDeferred(S32 pass) +{ + +} + +//virtual +void LLDrawPool::beginPostDeferredPass(S32 pass) +{ + +} + +//virtual +void LLDrawPool::endPostDeferredPass(S32 pass) +{ + +} + +//virtual +S32 LLDrawPool::getNumPostDeferredPasses() +{ + return 0; +} + +//virtual +void LLDrawPool::renderPostDeferred(S32 pass) +{ + +} +

//virtual
void LLDrawPool::endRenderPass( S32 pass )
{

+} + +//virtual +void LLDrawPool::beginShadowPass(S32 pass) +{ + +} + +//virtual +void LLDrawPool::endShadowPass(S32 pass) +{ + +} + +//virtual +S32 LLDrawPool::getNumShadowPasses() +{ + return 0; +} + +//virtual +void LLDrawPool::renderShadow(S32 pass) +{ +

}

Index: /branches/shadow-draft/indra/newview/llspatialpartition.cpp

=======================================================

--- /branches/shadow-draft/indra/newview/llspatialpartition.cpp (revision 573) +++ /branches/shadow-draft/indra/newview/llspatialpartition.cpp (revision 575) @@ -184,5 +184,5 @@

};

-U8* get_occlusion_indices(LLCamera* camera, const LLVector3& center) +U8* get_box_fan_indices(LLCamera* camera, const LLVector3& center)

{
	LLVector3 d = center - camera->getOrigin();

@@ -1320,5 +1320,5 @@

				glVertexPointer(3, GL_FLOAT, 0, mOcclusionVerts);
				glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8,

- GL_UNSIGNED_BYTE, get_occlusion_indices(camera, mBounds[0])); + GL_UNSIGNED_BYTE, get_box_fan_indices(camera, mBounds[0]));

				glEndQueryARB(GL_SAMPLES_PASSED_ARB);
			}

@@ -1610,4 +1610,22 @@

	}
};

+ +class LLOctreeCullShadow : public LLOctreeCull +{ +public: + LLOctreeCullShadow(LLCamera* camera) + : LLOctreeCull(camera) { } + + virtual S32 frustumCheck(const LLSpatialGroup* group) + { + return mCamera->AABBInFrustum(group->mBounds[0], group->mBounds[1]); + } + + virtual S32 frustumCheckObjects(const LLSpatialGroup* group) + { + return mCamera->AABBInFrustum(group->mObjectBounds[0], group->mObjectBounds[1]); + } +}; +

class LLOctreeSelect : public LLOctreeCull

@@ -1788,4 +1806,10 @@

		LLOctreeSelect selecter(&camera, results);
		selecter.traverse(mOctree);

+ } + else if (LLPipeline::sShadowRender) + { + LLFastTimer ftm(LLFastTimer::FTM_FRUSTUM_CULL); + LLOctreeCullShadow culler(&camera); + culler.traverse(mOctree);

	}
	else if (mInfiniteFarClip || !LLPipeline::sUseFarClip)

@@ -2158,9 +2182,9 @@

			glColor4f(1.0f, 0.f, 0.f, 0.5f);

- glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, GL_UNSIGNED_BYTE, get_occlusion_indices(camera, group->mBounds[0])); + glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, GL_UNSIGNED_BYTE, get_box_fan_indices(camera, group->mBounds[0]));

			glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
			
			glColor4f(1.0f, 1.f, 1.f, 1.0f);

- glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, GL_UNSIGNED_BYTE, get_occlusion_indices(camera, group->mBounds[0])); + glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, GL_UNSIGNED_BYTE, get_box_fan_indices(camera, group->mBounds[0]));

			glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
		}

Index: /branches/shadow-draft/indra/llwindow/llgl.h

=======================================================

--- /branches/shadow-draft/indra/llwindow/llgl.h (revision 543) +++ /branches/shadow-draft/indra/llwindow/llgl.h (revision 575) @@ -78,5 +78,5 @@

	BOOL mHasCompressedTextures;
	BOOL mHasFramebufferObject;

- +

	// ARB Extensions
	BOOL mHasVertexBufferObject;

@@ -87,4 +87,5 @@

	BOOL mHasOcclusionQuery;
	BOOL mHasPointParameters;

+ BOOL mHasDrawBuffers;

	// Other extensions.

Index: /branches/shadow-draft/indra/llwindow/llgl.cpp

=======================================================

--- /branches/shadow-draft/indra/llwindow/llgl.cpp (revision 573) +++ /branches/shadow-draft/indra/llwindow/llgl.cpp (revision 575) @@ -130,4 +130,7 @@

PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glGetFramebufferAttachmentParameterivEXT = NULL;
PFNGLGENERATEMIPMAPEXTPROC glGenerateMipmapEXT = NULL;

+ +// GL_ARB_draw_buffers +PFNGLDRAWBUFFERSARBPROC glDrawBuffersARB = NULL;

//shader object prototypes

@@ -542,4 +545,9 @@

	mHasFramebufferObject = FALSE;
# endif

+# if GL_ARB_draw_buffers + mHasDrawBuffers = TRUE; +#else + mHasDrawBuffers = FALSE; +# endif

	mHasMipMapGeneration = FALSE;
	mHasPalettedTextures = FALSE;

@@ -567,4 +575,5 @@

	mHasFramebufferObject = ExtensionExists("GL_EXT_framebuffer_object", gGLHExts.mSysExts)
		&& ExtensionExists("GL_EXT_packed_depth_stencil", gGLHExts.mSysExts);

+ mHasDrawBuffers = ExtensionExists("GL_ARB_draw_buffers", gGLHExts.mSysExts);

#if !LL_DARWIN
	mHasPointParameters = !mIsATI && ExtensionExists("GL_ARB_point_parameters", gGLHExts.mSysExts);

@@ -586,4 +595,5 @@

		mHasVertexBufferObject = FALSE;
		mHasFramebufferObject = FALSE;

+ mHasDrawBuffers = FALSE;

		mHasMipMapGeneration = FALSE;
		mHasPalettedTextures = FALSE;

@@ -640,4 +650,6 @@

		if (strchr(blacklist,'p')) mHasPointParameters = FALSE;//S
		if (strchr(blacklist,'q')) mHasFramebufferObject = FALSE;//S

+ if (strchr(blacklist,'r')) mHasDrawBuffers = FALSE;//S +

	}
#endif // LL_LINUX

@@ -757,4 +769,8 @@

		glGetFramebufferAttachmentParameterivEXT = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glGetFramebufferAttachmentParameterivEXT");
		glGenerateMipmapEXT = (PFNGLGENERATEMIPMAPEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glGenerateMipmapEXT");

+ } + if (mHasDrawBuffers) + { + glDrawBuffersARB = (PFNGLDRAWBUFFERSARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDrawBuffersARB");

	}
#if !LL_LINUX

@@ -1588,4 +1604,19 @@

{
	std::sort(mNameList.begin(), mNameList.end(), CompareUsed());

+ /*for (name_list_t::iterator iter = mNameList.begin(); iter != mNameList.end(); ++iter) + { + if (iter->used == FALSE) + { + releaseName(iter->name); + } + else + { + mNameList.erase(mNameList.begin(), iter); + return; + } + } + + //if we hit this point, whole pool has been released + mNameList.clear();*/

}

Index: /branches/shadow-draft/indra/llwindow/llglheaders.h

=======================================================

--- /branches/shadow-draft/indra/llwindow/llglheaders.h (revision 280) +++ /branches/shadow-draft/indra/llwindow/llglheaders.h (revision 575) @@ -261,4 +261,6 @@

extern PFNGLGENERATEMIPMAPEXTPROC glGenerateMipmapEXT;

+//GL_ARB_draw_buffers +extern PFNGLDRAWBUFFERSARBPROC glDrawBuffersARB;

#elif LL_WINDOWS

@@ -449,4 +451,6 @@

extern PFNGLGENERATEMIPMAPEXTPROC glGenerateMipmapEXT;

+//GL_ARB_draw_buffers +extern PFNGLDRAWBUFFERSARBPROC glDrawBuffersARB;

#elif LL_DARWIN

@@ -485,4 +489,6 @@

extern void glGenerateMipmapEXT(GLenum target) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;

+// GL_ARB_draw_buffers +extern void glDrawBuffersARB(GLsizei n, const GLenum* bufs) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;

#ifdef __cplusplus

Index: /branches/shadow-draft/indra/llrender/llvertexbuffer.cpp

=======================================================

--- /branches/shadow-draft/indra/llrender/llvertexbuffer.cpp (revision 573) +++ /branches/shadow-draft/indra/llrender/llvertexbuffer.cpp (revision 575) @@ -123,5 +123,5 @@

					glDisableClientState(array[i]);
				}

- else + else if (gDebugGL)

				{ //needs to be enabled, make sure it was (DEBUG TEMPORARY)
					if (i > 0 && !glIsEnabled(array[i]))

@@ -137,5 +137,5 @@

					glEnableClientState(array[i]);
				}

- else if (glIsEnabled(array[i])) + else if (gDebugGL && glIsEnabled(array[i]))

				{ //needs to be disabled, make sure it was (DEBUG TEMPORARY)
					llerrs << "Bad client state! " << array[i] << " enabled." << llendl;

@@ -762,9 +762,5 @@

		mMappedIndexData = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
		stop_glerror();

- /*if (sMapped) - { - llerrs << "Mapped two VBOs at the same time!" << llendl; - } - sMapped = TRUE;*/ +

		if (!mMappedData)
		{

Index: /branches/shadow-draft/indra/llrender/llrendertarget.cpp

=======================================================

--- /branches/shadow-draft/indra/llrender/llrendertarget.cpp (revision 573) +++ /branches/shadow-draft/indra/llrender/llrendertarget.cpp (revision 575) @@ -67,10 +67,65 @@

	release();

- glGenTextures(1, (GLuint *) &mTex); - glBindTexture(mUsage, mTex); - glTexImage2D(mUsage, 0, color_fmt, mResX, mResY, 0, color_fmt, GL_UNSIGNED_BYTE, NULL); - - glTexParameteri(mUsage, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(mUsage, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + stop_glerror(); + + if ((sUseFBO || use_fbo) && gGLManager.mHasFramebufferObject) + { + + if (depth) + { + stop_glerror(); + allocateDepth(); + stop_glerror(); + } + + glGenFramebuffersEXT(1, (GLuint *) &mFBO); + + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBO); + + if (mDepth) + { + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, mUsage, mDepth, 0); + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, mUsage, mDepth, 0); + stop_glerror(); + } + + stop_glerror(); + + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + stop_glerror(); + } + + addColorAttachment(color_fmt); +} + +void LLRenderTarget::addColorAttachment(U32 color_fmt) +{ + if (color_fmt == 0) + { + return; + } + + U32 offset = mTex.size(); + if (offset >= 4 || + offset > 0 && (mFBO == 0 || !gGLManager.mHasDrawBuffers)) + { + llerrs << "Too many color attachments!" << llendl; + } + + U32 tex; + glGenTextures(1, (GLuint *) &tex); + glBindTexture(mUsage, tex); + glTexImage2D(mUsage, 0, color_fmt, mResX, mResY, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + + if (offset == 0) + { + glTexParameteri(mUsage, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(mUsage, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + } + else + { //don't filter data attachments + glTexParameteri(mUsage, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(mUsage, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + }

	if (mUsage != GL_TEXTURE_RECTANGLE_ARB)

@@ -86,34 +141,28 @@

	}

- stop_glerror(); - - if ((sUseFBO || use_fbo) && gGLManager.mHasFramebufferObject) - { - - if (depth) - { - stop_glerror(); - allocateDepth(); - stop_glerror(); - } - - glGenFramebuffersEXT(1, (GLuint *) &mFBO); - + if (mFBO) + {

		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBO);

- - if (mDepth) - { - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, mUsage, mDepth, 0); - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, mUsage, mDepth, 0); - stop_glerror(); - } - - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, - mUsage, mTex, 0); - stop_glerror(); - - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); - stop_glerror(); - } + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT+offset, + mUsage, tex, 0); + + + GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); + switch (status) + { + case GL_FRAMEBUFFER_COMPLETE_EXT: + break; + case GL_FRAMEBUFFER_UNSUPPORTED_EXT: + llerrs << "WTF?" << llendl; + break; + default: + llerrs << "WTF?" << llendl; + } + + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + } + + mTex.push_back(tex); +

}

@@ -135,8 +184,8 @@

	}

- if (mTex) - { - glDeleteTextures(1, (GLuint *) &mTex); - mTex = 0; + if (mTex.size() > 0) + { + glDeleteTextures(mTex.size(), (GLuint *) &mTex[0]); + mTex.clear();

	}

@@ -153,4 +202,12 @@

	{
		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBO);

+ if (gGLManager.mHasDrawBuffers) + { //setup multiple render targets + GLenum drawbuffers[] = {GL_COLOR_ATTACHMENT0_EXT, + GL_COLOR_ATTACHMENT1_EXT, + GL_COLOR_ATTACHMENT2_EXT, + GL_COLOR_ATTACHMENT3_EXT}; + glDrawBuffersARB(mTex.size(), drawbuffers); + }

	}

@@ -187,7 +244,11 @@

}

-void LLRenderTarget::bindTexture() -{ - glBindTexture(mUsage, mTex); +void LLRenderTarget::bindTexture(U32 attachment) +{ + if (attachment > mTex.size()-1) + { + llerrs << "Invalid attachment index." << llendl; + } + glBindTexture(mUsage, mTex[attachment]);

}

@@ -225,5 +286,5 @@

BOOL LLRenderTarget::isComplete() const
{

- return (mTex || mDepth) ? TRUE : FALSE; + return (!mTex.empty() || mDepth) ? TRUE : FALSE;

}

Index: /branches/shadow-draft/indra/llrender/llrendertarget.h

=======================================================

--- /branches/shadow-draft/indra/llrender/llrendertarget.h (revision 531) +++ /branches/shadow-draft/indra/llrender/llrendertarget.h (revision 575) @@ -74,4 +74,8 @@

	void allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, U32 usage = GL_TEXTURE_2D, BOOL use_fbo = FALSE);

+ //add color buffer attachment + //limit of 4 color attachments per render target + void addColorAttachment(U32 color_fmt); +

	//allocate a depth texture
	void allocateDepth();

@@ -102,5 +106,5 @@

	//bind results of render for sampling

- void bindTexture(); + void bindTexture(U32 attachment = 0);

	//bind results of render for sampling depth buffer

@@ -123,5 +127,5 @@

	U32 mResX;
	U32 mResY;

- U32 mTex; + std::vector<U32> mTex;

	U32 mFBO;
	U32 mDepth;