Microsoft windows builds
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;