Occlusion culling overhaul.
parent
8d67ad3d86
commit
ccd04cd66c
|
|
@ -7277,9 +7277,6 @@ void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVe
|
|||
|
||||
const LLVector4a& t = tan1[a];
|
||||
|
||||
llassert(tan1[a].getLength3().getF32() >= 0.f);
|
||||
llassert(tan2[a].getLength3().getF32() >= 0.f);
|
||||
|
||||
LLVector4a ncrosst;
|
||||
ncrosst.setCross3(n,t);
|
||||
|
||||
|
|
|
|||
|
|
@ -149,6 +149,9 @@ void LLGLSLShader::clearStats()
|
|||
mTimeElapsed = 0;
|
||||
mSamplesDrawn = 0;
|
||||
mDrawCalls = 0;
|
||||
mTextureStateFetched = false;
|
||||
mTextureMagFilter.clear();
|
||||
mTextureMinFilter.clear();
|
||||
}
|
||||
|
||||
void LLGLSLShader::dumpStats()
|
||||
|
|
@ -161,6 +164,16 @@ void LLGLSLShader::dumpStats()
|
|||
{
|
||||
llinfos << mShaderFiles[i].first << llendl;
|
||||
}
|
||||
for (U32 i = 0; i < mTexture.size(); ++i)
|
||||
{
|
||||
GLint idx = mTexture[i];
|
||||
|
||||
if (idx >= 0)
|
||||
{
|
||||
GLint uniform_idx = getUniformLocation(i);
|
||||
llinfos << mUniformNameMap[uniform_idx] << " - " << std::hex << mTextureMagFilter[i] << "/" << mTextureMinFilter[i] << std::dec << llendl;
|
||||
}
|
||||
}
|
||||
llinfos << "=============================================" << llendl;
|
||||
|
||||
F32 ms = mTimeElapsed/1000000.f;
|
||||
|
|
@ -211,6 +224,39 @@ void LLGLSLShader::placeProfileQuery()
|
|||
glGenQueriesARB(1, &mTimerQuery);
|
||||
}
|
||||
|
||||
if (!mTextureStateFetched)
|
||||
{
|
||||
mTextureStateFetched = true;
|
||||
mTextureMagFilter.resize(mTexture.size());
|
||||
mTextureMinFilter.resize(mTexture.size());
|
||||
|
||||
U32 cur_active = gGL.getCurrentTexUnitIndex();
|
||||
|
||||
for (U32 i = 0; i < mTexture.size(); ++i)
|
||||
{
|
||||
GLint idx = mTexture[i];
|
||||
|
||||
if (idx >= 0)
|
||||
{
|
||||
gGL.getTexUnit(idx)->activate();
|
||||
|
||||
U32 mag = 0xFFFFFFFF;
|
||||
U32 min = 0xFFFFFFFF;
|
||||
|
||||
U32 type = LLTexUnit::getInternalType(gGL.getTexUnit(idx)->getCurrType());
|
||||
|
||||
glGetTexParameteriv(type, GL_TEXTURE_MAG_FILTER, (GLint*) &mag);
|
||||
glGetTexParameteriv(type, GL_TEXTURE_MIN_FILTER, (GLint*) &min);
|
||||
|
||||
mTextureMagFilter[i] = mag;
|
||||
mTextureMinFilter[i] = min;
|
||||
}
|
||||
}
|
||||
|
||||
gGL.getTexUnit(cur_active)->activate();
|
||||
}
|
||||
|
||||
|
||||
glBeginQueryARB(GL_SAMPLES_PASSED, 1);
|
||||
glBeginQueryARB(GL_TIME_ELAPSED, mTimerQuery);
|
||||
#endif
|
||||
|
|
@ -573,6 +619,7 @@ void LLGLSLShader::mapUniform(GLint index, const vector<string> * uniforms)
|
|||
}
|
||||
|
||||
mUniformMap[name] = location;
|
||||
mUniformNameMap[location] = name;
|
||||
LL_DEBUGS("ShaderLoading") << "Uniform " << name << " is at location " << location << LL_ENDL;
|
||||
|
||||
//find the index of this uniform
|
||||
|
|
@ -635,6 +682,7 @@ BOOL LLGLSLShader::mapUniforms(const vector<string> * uniforms)
|
|||
mActiveTextureChannels = 0;
|
||||
mUniform.clear();
|
||||
mUniformMap.clear();
|
||||
mUniformNameMap.clear();
|
||||
mTexture.clear();
|
||||
mValue.clear();
|
||||
//initialize arrays
|
||||
|
|
@ -1152,6 +1200,23 @@ void LLGLSLShader::uniform1i(const string& uniform, GLint v)
|
|||
}
|
||||
}
|
||||
|
||||
void LLGLSLShader::uniform2i(const string& uniform, GLint i, GLint j)
|
||||
{
|
||||
GLint location = getUniformLocation(uniform);
|
||||
|
||||
if (location >= 0)
|
||||
{
|
||||
std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
|
||||
LLVector4 vec(i,j,0.f,0.f);
|
||||
if (iter == mValue.end() || shouldChange(iter->second,vec))
|
||||
{
|
||||
glUniform2iARB(location, i, j);
|
||||
mValue[location] = vec;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LLGLSLShader::uniform1f(const string& uniform, GLfloat v)
|
||||
{
|
||||
GLint location = getUniformLocation(uniform);
|
||||
|
|
|
|||
|
|
@ -111,6 +111,7 @@ public:
|
|||
void uniform3fv(U32 index, U32 count, const GLfloat* v);
|
||||
void uniform4fv(U32 index, U32 count, const GLfloat* v);
|
||||
void uniform1i(const std::string& uniform, GLint i);
|
||||
void uniform2i(const std::string& uniform, GLint i, GLint j);
|
||||
void uniform1f(const std::string& uniform, GLfloat v);
|
||||
void uniform2f(const std::string& uniform, GLfloat x, GLfloat y);
|
||||
void uniform3f(const std::string& uniform, GLfloat x, GLfloat y, GLfloat z);
|
||||
|
|
@ -170,6 +171,7 @@ public:
|
|||
U32 mAttributeMask; //mask of which reserved attributes are set (lines up with LLVertexBuffer::getTypeMask())
|
||||
std::vector<GLint> mUniform; //lookup table of uniform enum to uniform location
|
||||
std::map<std::string, GLint> mUniformMap; //lookup map of uniform name to uniform location
|
||||
std::map<GLint, std::string> mUniformNameMap; //lookup map of uniform location to uniform name
|
||||
std::map<GLint, LLVector4> mValue; //lookup map of uniform location to last known value
|
||||
std::vector<GLint> mTexture;
|
||||
S32 mTotalUniformSize;
|
||||
|
|
@ -192,6 +194,11 @@ public:
|
|||
static U64 sTotalSamplesDrawn;
|
||||
U32 mDrawCalls;
|
||||
static U32 sTotalDrawCalls;
|
||||
|
||||
bool mTextureStateFetched;
|
||||
std::vector<U32> mTextureMagFilter;
|
||||
std::vector<U32> mTextureMinFilter;
|
||||
|
||||
};
|
||||
|
||||
//UI shader (declared here so llui_libtest will link properly)
|
||||
|
|
|
|||
|
|
@ -53,11 +53,23 @@ void check_framebuffer_status()
|
|||
bool LLRenderTarget::sUseFBO = false;
|
||||
U32 LLRenderTarget::sCurFBO = 0;
|
||||
|
||||
|
||||
extern S32 gGLViewport[4];
|
||||
|
||||
//HEY DAVE HOOK THESE UP
|
||||
U32 LLRenderTarget::sCurResX = 0;
|
||||
U32 LLRenderTarget::sCurResY = 0;
|
||||
|
||||
|
||||
/// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
LLRenderTarget::LLRenderTarget() :
|
||||
mResX(0),
|
||||
mResY(0),
|
||||
mFBO(0),
|
||||
mPreviousFBO(0),
|
||||
mPreviousResX(0),
|
||||
mPreviousResY(0),
|
||||
mDepth(0),
|
||||
mStencil(0),
|
||||
mUseDepth(false),
|
||||
|
|
@ -390,13 +402,12 @@ void LLRenderTarget::bindTarget()
|
|||
{
|
||||
if (mFBO)
|
||||
{
|
||||
mPreviousFBO = sCurFBO;
|
||||
|
||||
stop_glerror();
|
||||
|
||||
mPreviousFBO = sCurFBO;
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
|
||||
sCurFBO = mFBO;
|
||||
|
||||
|
||||
stop_glerror();
|
||||
if (gGLManager.mHasDrawBuffers)
|
||||
{ //setup multiple render targets
|
||||
|
|
@ -418,7 +429,12 @@ void LLRenderTarget::bindTarget()
|
|||
stop_glerror();
|
||||
}
|
||||
|
||||
mPreviousResX = sCurResX;
|
||||
mPreviousResY = sCurResY;
|
||||
glViewport(0, 0, mResX, mResY);
|
||||
sCurResX = mResX;
|
||||
sCurResY = mResY;
|
||||
|
||||
sBoundTarget = this;
|
||||
}
|
||||
|
||||
|
|
@ -489,6 +505,20 @@ void LLRenderTarget::flush(bool fetch_depth)
|
|||
stop_glerror();
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mPreviousFBO);
|
||||
sCurFBO = mPreviousFBO;
|
||||
|
||||
if (mPreviousFBO)
|
||||
{
|
||||
glViewport(0, 0, mPreviousResX, mPreviousResY);
|
||||
sCurResX = mPreviousResX;
|
||||
sCurResY = mPreviousResY;
|
||||
}
|
||||
else
|
||||
{
|
||||
glViewport(gGLViewport[0],gGLViewport[1],gGLViewport[2],gGLViewport[3]);
|
||||
sCurResX = gGLViewport[2];
|
||||
sCurResY = gGLViewport[3];
|
||||
}
|
||||
|
||||
stop_glerror();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,6 +63,9 @@ public:
|
|||
static bool sUseFBO;
|
||||
static U32 sBytesAllocated;
|
||||
static U32 sCurFBO;
|
||||
static U32 sCurResX;
|
||||
static U32 sCurResY;
|
||||
|
||||
|
||||
LLRenderTarget();
|
||||
~LLRenderTarget();
|
||||
|
|
@ -146,6 +149,9 @@ protected:
|
|||
std::vector<U32> mInternalFormat;
|
||||
U32 mFBO;
|
||||
U32 mPreviousFBO;
|
||||
U32 mPreviousResX;
|
||||
U32 mPreviousResY;
|
||||
|
||||
U32 mDepth;
|
||||
bool mStencil;
|
||||
bool mUseDepth;
|
||||
|
|
|
|||
|
|
@ -7732,7 +7732,7 @@
|
|||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>4</integer>
|
||||
<integer>3</integer>
|
||||
</map>
|
||||
|
||||
<key>OctreeAlphaDistanceFactor</key>
|
||||
|
|
@ -8504,7 +8504,6 @@
|
|||
<key>Value</key>
|
||||
<real>1.0</real>
|
||||
</map>
|
||||
|
||||
<key>RenderDeferredTreeShadowBias</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
|
|||
|
|
@ -46,11 +46,6 @@ VARYING vec2 vary_fragcoord;
|
|||
uniform mat4 inv_proj;
|
||||
uniform vec2 screen_res;
|
||||
|
||||
vec3 getKern(int i)
|
||||
{
|
||||
return kern[i];
|
||||
}
|
||||
|
||||
vec4 getPosition(vec2 pos_screen)
|
||||
{
|
||||
float depth = texture2DRect(depthMap, pos_screen.xy).r;
|
||||
|
|
@ -64,38 +59,38 @@ vec4 getPosition(vec2 pos_screen)
|
|||
return pos;
|
||||
}
|
||||
|
||||
#ifdef SINGLE_FP_ONLY
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
vec2 sn;
|
||||
sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f);
|
||||
return sn;
|
||||
}
|
||||
|
||||
vec3 decode_normal (vec2 enc)
|
||||
{
|
||||
vec3 n;
|
||||
n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f);
|
||||
n.z = sqrt(1.0f - dot(n.xy,n.xy));
|
||||
return n;
|
||||
}
|
||||
#else
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
float f = sqrt(8 * n.z + 8);
|
||||
return n.xy / f + 0.5;
|
||||
}
|
||||
|
||||
vec3 decode_normal (vec2 enc)
|
||||
{
|
||||
vec2 fenc = enc*4-2;
|
||||
float f = dot(fenc,fenc);
|
||||
float g = sqrt(1-f/4);
|
||||
vec3 n;
|
||||
n.xy = fenc*g;
|
||||
n.z = 1-f/2;
|
||||
return n;
|
||||
}
|
||||
#ifdef SINGLE_FP_ONLY
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
vec2 sn;
|
||||
sn.xy = (n.xy * vec2(0.5f,0.5f)) + vec2(0.5f,0.5f);
|
||||
return sn;
|
||||
}
|
||||
|
||||
vec3 decode_normal (vec2 enc)
|
||||
{
|
||||
vec3 n;
|
||||
n.xy = (enc.xy * vec2(2.0f,2.0f)) - vec2(1.0f,1.0f);
|
||||
n.z = sqrt(1.0f - dot(n.xy,n.xy));
|
||||
return n;
|
||||
}
|
||||
#else
|
||||
vec2 encode_normal(vec3 n)
|
||||
{
|
||||
float f = sqrt(8 * n.z + 8);
|
||||
return n.xy / f + 0.5;
|
||||
}
|
||||
|
||||
vec3 decode_normal (vec2 enc)
|
||||
{
|
||||
vec2 fenc = enc*4-2;
|
||||
float f = dot(fenc,fenc);
|
||||
float g = sqrt(1-f/4);
|
||||
vec3 n;
|
||||
n.xy = fenc*g;
|
||||
n.z = 1-f/2;
|
||||
return n;
|
||||
}
|
||||
#endif
|
||||
|
||||
void main()
|
||||
|
|
@ -110,7 +105,7 @@ void main()
|
|||
vec2 dlt = kern_scale * delta / (1.0+norm.xy*norm.xy);
|
||||
dlt /= max(-pos.z*dist_factor, 1.0);
|
||||
|
||||
vec2 defined_weight = getKern(0).xy; // special case the first (centre) sample's weight in the blur; we have to sample it anyway so we get it for 'free'
|
||||
vec2 defined_weight = kern[0].xy; // special case the first (centre) sample's weight in the blur; we have to sample it anyway so we get it for 'free'
|
||||
vec4 col = defined_weight.xyxx * ccol;
|
||||
|
||||
// relax tolerance according to distance to avoid speckling artifacts, as angles and distances are a lot more abrupt within a small screen area at larger distances
|
||||
|
|
@ -120,28 +115,33 @@ void main()
|
|||
float tc_mod = 0.5*(tc.x + tc.y); // mod(tc.x+tc.y,2)
|
||||
tc_mod -= floor(tc_mod);
|
||||
tc_mod *= 2.0;
|
||||
tc += ( (tc_mod - 0.5) * getKern(1).z * dlt * 0.5 );
|
||||
tc += ( (tc_mod - 0.5) * kern[1].z * dlt * 0.5 );
|
||||
|
||||
for (int i = 1; i < 4; i++)
|
||||
{
|
||||
vec2 samptc = tc + getKern(i).z*dlt;
|
||||
vec3 samppos = getPosition(samptc).xyz;
|
||||
vec2 samptc = tc + kern[i].z*dlt;
|
||||
vec3 samppos = getPosition(samptc).xyz;
|
||||
|
||||
float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane
|
||||
|
||||
if (d*d <= pointplanedist_tolerance_pow2)
|
||||
{
|
||||
col += texture2DRect(lightMap, samptc)*getKern(i).xyxx;
|
||||
defined_weight += getKern(i).xy;
|
||||
col += texture2DRect(lightMap, samptc)*kern[i].xyxx;
|
||||
defined_weight += kern[i].xy;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 1; i < 4; i++)
|
||||
{
|
||||
vec2 samptc = tc - getKern(i).z*dlt;
|
||||
vec3 samppos = getPosition(samptc).xyz;
|
||||
vec2 samptc = tc - kern[i].z*dlt;
|
||||
vec3 samppos = getPosition(samptc).xyz;
|
||||
|
||||
float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane
|
||||
|
||||
if (d*d <= pointplanedist_tolerance_pow2)
|
||||
{
|
||||
col += texture2DRect(lightMap, samptc)*getKern(i).xyxx;
|
||||
defined_weight += getKern(i).xy;
|
||||
col += texture2DRect(lightMap, samptc)*kern[i].xyxx;
|
||||
defined_weight += kern[i].xy;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,67 @@
|
|||
/**
|
||||
* @file debugF.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2011, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifdef DEFINE_GL_FRAGCOLOR
|
||||
out vec4 frag_color;
|
||||
#else
|
||||
#define frag_color gl_FragColor
|
||||
#endif
|
||||
|
||||
uniform sampler2D depthMap;
|
||||
|
||||
uniform float delta;
|
||||
|
||||
VARYING vec2 tc0;
|
||||
VARYING vec2 tc1;
|
||||
VARYING vec2 tc2;
|
||||
VARYING vec2 tc3;
|
||||
VARYING vec2 tc4;
|
||||
VARYING vec2 tc5;
|
||||
VARYING vec2 tc6;
|
||||
VARYING vec2 tc7;
|
||||
VARYING vec2 tc8;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 depth1 =
|
||||
vec4(texture2D(depthMap, tc0).r,
|
||||
texture2D(depthMap, tc1).r,
|
||||
texture2D(depthMap, tc2).r,
|
||||
texture2D(depthMap, tc3).r);
|
||||
|
||||
vec4 depth2 =
|
||||
vec4(texture2D(depthMap, tc4).r,
|
||||
texture2D(depthMap, tc5).r,
|
||||
texture2D(depthMap, tc6).r,
|
||||
texture2D(depthMap, tc7).r);
|
||||
|
||||
depth1 = min(depth1, depth2);
|
||||
float depth = min(depth1.x, depth1.y);
|
||||
depth = min(depth, depth1.z);
|
||||
depth = min(depth, depth1.w);
|
||||
depth = min(depth, texture2D(depthMap, tc8).r);
|
||||
|
||||
gl_FragDepth = depth;
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
/**
|
||||
* @file debugF.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2011, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifdef DEFINE_GL_FRAGCOLOR
|
||||
out vec4 frag_color;
|
||||
#else
|
||||
#define frag_color gl_FragColor
|
||||
#endif
|
||||
|
||||
uniform sampler2DRect depthMap;
|
||||
|
||||
uniform float delta;
|
||||
|
||||
VARYING vec2 tc0;
|
||||
VARYING vec2 tc1;
|
||||
VARYING vec2 tc2;
|
||||
VARYING vec2 tc3;
|
||||
VARYING vec2 tc4;
|
||||
VARYING vec2 tc5;
|
||||
VARYING vec2 tc6;
|
||||
VARYING vec2 tc7;
|
||||
VARYING vec2 tc8;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 depth1 =
|
||||
vec4(texture2DRect(depthMap, tc0).r,
|
||||
texture2DRect(depthMap, tc1).r,
|
||||
texture2DRect(depthMap, tc2).r,
|
||||
texture2DRect(depthMap, tc3).r);
|
||||
|
||||
vec4 depth2 =
|
||||
vec4(texture2DRect(depthMap, tc4).r,
|
||||
texture2DRect(depthMap, tc5).r,
|
||||
texture2DRect(depthMap, tc6).r,
|
||||
texture2DRect(depthMap, tc7).r);
|
||||
|
||||
depth1 = min(depth1, depth2);
|
||||
float depth = min(depth1.x, depth1.y);
|
||||
depth = min(depth, depth1.z);
|
||||
depth = min(depth, depth1.w);
|
||||
depth = min(depth, texture2DRect(depthMap, tc8).r);
|
||||
|
||||
gl_FragDepth = depth;
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
/**
|
||||
* @file debugV.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2011, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
uniform mat4 modelview_projection_matrix;
|
||||
|
||||
ATTRIBUTE vec3 position;
|
||||
|
||||
uniform vec2 screen_res;
|
||||
|
||||
uniform vec2 delta;
|
||||
|
||||
VARYING vec2 tc0;
|
||||
VARYING vec2 tc1;
|
||||
VARYING vec2 tc2;
|
||||
VARYING vec2 tc3;
|
||||
VARYING vec2 tc4;
|
||||
VARYING vec2 tc5;
|
||||
VARYING vec2 tc6;
|
||||
VARYING vec2 tc7;
|
||||
VARYING vec2 tc8;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(position, 1.0);
|
||||
|
||||
vec2 tc = (position.xy*0.5+0.5)*screen_res;
|
||||
tc0 = tc+vec2(-delta.x,-delta.y);
|
||||
tc1 = tc+vec2(0,-delta.y);
|
||||
tc2 = tc+vec2(delta.x,-delta.y);
|
||||
tc3 = tc+vec2(-delta.x,0);
|
||||
tc4 = tc+vec2(0,0);
|
||||
tc5 = tc+vec2(delta.x,0);
|
||||
tc6 = tc+vec2(-delta.x,delta.y);
|
||||
tc7 = tc+vec2(0,delta.y);
|
||||
tc8 = tc+vec2(delta.x,delta.y);
|
||||
}
|
||||
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
|
||||
/**
|
||||
* @file llmeshrepository.cpp
|
||||
* @brief Mesh repository implementation.
|
||||
|
|
|
|||
|
|
@ -1498,6 +1498,8 @@ BOOL LLSpatialGroup::rebound()
|
|||
if (mOctreeNode->getChildCount() == 1 && mOctreeNode->getElementCount() == 0)
|
||||
{
|
||||
LLSpatialGroup* group = (LLSpatialGroup*) mOctreeNode->getChild(0)->getListener(0);
|
||||
|
||||
//rebound single child
|
||||
group->rebound();
|
||||
|
||||
//copy single child's bounding box
|
||||
|
|
@ -1506,10 +1508,11 @@ BOOL LLSpatialGroup::rebound()
|
|||
mExtents[0] = group->mExtents[0];
|
||||
mExtents[1] = group->mExtents[1];
|
||||
|
||||
//treat this node as a "chute" to a deeper level of the tree
|
||||
group->setState(SKIP_FRUSTUM_CHECK);
|
||||
}
|
||||
else if (mOctreeNode->isLeaf())
|
||||
{ //copy object bounding box if this is a leaf
|
||||
{ //copy object bounding box if this is a leaf
|
||||
boundObjects(TRUE, mExtents[0], mExtents[1]);
|
||||
mBounds[0] = mObjectBounds[0];
|
||||
mBounds[1] = mObjectBounds[1];
|
||||
|
|
@ -1518,14 +1521,17 @@ BOOL LLSpatialGroup::rebound()
|
|||
{
|
||||
LLVector4a& newMin = mExtents[0];
|
||||
LLVector4a& newMax = mExtents[1];
|
||||
|
||||
//get bounding box of first child
|
||||
LLSpatialGroup* group = (LLSpatialGroup*) mOctreeNode->getChild(0)->getListener(0);
|
||||
group->clearState(SKIP_FRUSTUM_CHECK);
|
||||
group->rebound();
|
||||
|
||||
//initialize to first child
|
||||
newMin = group->mExtents[0];
|
||||
newMax = group->mExtents[1];
|
||||
|
||||
//first, rebound children
|
||||
//rebound remaining children, expanding bounding box to encompass children
|
||||
for (U32 i = 1; i < mOctreeNode->getChildCount(); i++)
|
||||
{
|
||||
group = (LLSpatialGroup*) mOctreeNode->getChild(i)->getListener(0);
|
||||
|
|
@ -2506,7 +2512,7 @@ void pushBufferVerts(LLVertexBuffer* buffer, U32 mask)
|
|||
}
|
||||
}
|
||||
|
||||
void pushBufferVerts(LLSpatialGroup* group, U32 mask)
|
||||
void pushBufferVerts(LLSpatialGroup* group, U32 mask, bool push_alpha = true)
|
||||
{
|
||||
if (group->mSpatialPartition->mRenderByGroup)
|
||||
{
|
||||
|
|
@ -2515,7 +2521,10 @@ void pushBufferVerts(LLSpatialGroup* group, U32 mask)
|
|||
LLDrawInfo* params = *(group->mDrawMap.begin()->second.begin());
|
||||
LLRenderPass::applyModelMatrix(*params);
|
||||
|
||||
pushBufferVerts(group->mVertexBuffer, mask);
|
||||
if (push_alpha)
|
||||
{
|
||||
pushBufferVerts(group->mVertexBuffer, mask);
|
||||
}
|
||||
|
||||
for (LLSpatialGroup::buffer_map_t::iterator i = group->mBufferMap.begin(); i != group->mBufferMap.end(); ++i)
|
||||
{
|
||||
|
|
@ -2529,10 +2538,10 @@ void pushBufferVerts(LLSpatialGroup* group, U32 mask)
|
|||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
/*else
|
||||
{
|
||||
drawBox(group->mBounds[0], group->mBounds[1]);
|
||||
}
|
||||
//drawBox(group->mBounds[0], group->mBounds[1]);
|
||||
}*/
|
||||
}
|
||||
|
||||
void pushVertsColorCoded(LLSpatialGroup* group, U32 mask)
|
||||
|
|
@ -2705,17 +2714,53 @@ void renderOctree(LLSpatialGroup* group)
|
|||
// drawBoxOutline(LLVector3(node->getCenter()), LLVector3(node->getSize()));
|
||||
}
|
||||
|
||||
std::set<LLSpatialGroup*> visible_selected_groups;
|
||||
|
||||
void renderVisibility(LLSpatialGroup* group, LLCamera* camera)
|
||||
{
|
||||
LLGLEnable blend(GL_BLEND);
|
||||
/*LLGLEnable blend(GL_BLEND);
|
||||
gGL.setSceneBlendType(LLRender::BT_ALPHA);
|
||||
LLGLEnable cull(GL_CULL_FACE);
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);*/
|
||||
|
||||
BOOL render_objects = (!LLPipeline::sUseOcclusion || !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) && group->isVisible() &&
|
||||
/*BOOL render_objects = (!LLPipeline::sUseOcclusion || !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) && group->isVisible() &&
|
||||
!group->isEmpty();
|
||||
|
||||
|
||||
if (render_objects)
|
||||
{
|
||||
LLGLDepthTest depth(GL_TRUE, GL_FALSE);
|
||||
|
||||
LLGLDisable blend(GL_BLEND);
|
||||
gGL.diffuseColor4f(0.f, 0.75f, 0.f,0.5f);
|
||||
pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX, false);
|
||||
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
glLineWidth(4.f);
|
||||
gGL.diffuseColor4f(0.f, 0.5f, 0.f, 1.f);
|
||||
pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX, false);
|
||||
glLineWidth(1.f);
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
|
||||
bool selected = false;
|
||||
|
||||
for (LLSpatialGroup::element_iter iter = group->getDataBegin(); iter != group->getDataEnd(); ++iter)
|
||||
{
|
||||
LLDrawable* drawable = *iter;
|
||||
if (drawable->getVObj().notNull() && drawable->getVObj()->isSelected())
|
||||
{
|
||||
selected = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (selected)
|
||||
{ //store for rendering occlusion volume as overlay
|
||||
visible_selected_groups.insert(group);
|
||||
}
|
||||
}*/
|
||||
|
||||
/*if (render_objects)
|
||||
{
|
||||
LLGLDepthTest depth_under(GL_TRUE, GL_FALSE, GL_GREATER);
|
||||
gGL.diffuseColor4f(0, 0.5f, 0, 0.5f);
|
||||
|
|
@ -2740,6 +2785,59 @@ void renderVisibility(LLSpatialGroup* group, LLCamera* camera)
|
|||
gGL.diffuseColor4f(0.f, 0.75f, 0.f,0.5f);
|
||||
gGL.diffuseColor4f(0.f, 0.75f, 0.f, 0.5f);
|
||||
pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX);
|
||||
|
||||
bool selected = false;
|
||||
|
||||
for (LLSpatialGroup::element_iter iter = group->getDataBegin(); iter != group->getDataEnd(); ++iter)
|
||||
{
|
||||
LLDrawable* drawable = *iter;
|
||||
if (drawable->getVObj().notNull() && drawable->getVObj()->isSelected())
|
||||
{
|
||||
selected = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (selected)
|
||||
{ //store for rendering occlusion volume as overlay
|
||||
visible_selected_groups.insert(group);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
void renderXRay(LLSpatialGroup* group, LLCamera* camera)
|
||||
{
|
||||
BOOL render_objects = (!LLPipeline::sUseOcclusion || !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) && group->isVisible() &&
|
||||
!group->isEmpty();
|
||||
|
||||
if (render_objects)
|
||||
{
|
||||
pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX, false);
|
||||
|
||||
bool selected = false;
|
||||
|
||||
for (LLSpatialGroup::element_iter iter = group->getDataBegin(); iter != group->getDataEnd(); ++iter)
|
||||
{
|
||||
LLDrawable* drawable = *iter;
|
||||
if (drawable->getVObj().notNull() && drawable->getVObj()->isSelected())
|
||||
{
|
||||
selected = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (selected)
|
||||
{ //store for rendering occlusion volume as overlay
|
||||
|
||||
if (!group->mSpatialPartition->isBridge())
|
||||
{
|
||||
visible_selected_groups.insert(group);
|
||||
}
|
||||
else
|
||||
{
|
||||
visible_selected_groups.insert(group->mSpatialPartition->asBridge()->getSpatialGroup());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4210,6 +4308,48 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class LLOctreeRenderXRay : public LLOctreeTraveler<LLDrawable>
|
||||
{
|
||||
public:
|
||||
LLCamera* mCamera;
|
||||
LLOctreeRenderXRay(LLCamera* camera): mCamera(camera) {}
|
||||
|
||||
virtual void traverse(const LLSpatialGroup::OctreeNode* node)
|
||||
{
|
||||
LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0);
|
||||
|
||||
if (!mCamera || mCamera->AABBInFrustumNoFarClip(group->mBounds[0], group->mBounds[1]))
|
||||
{
|
||||
node->accept(this);
|
||||
stop_glerror();
|
||||
|
||||
for (U32 i = 0; i < node->getChildCount(); i++)
|
||||
{
|
||||
traverse(node->getChild(i));
|
||||
stop_glerror();
|
||||
}
|
||||
|
||||
//render visibility wireframe
|
||||
if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION))
|
||||
{
|
||||
group->rebuildGeom();
|
||||
group->rebuildMesh();
|
||||
|
||||
gGL.flush();
|
||||
gGL.pushMatrix();
|
||||
gGLLastMatrix = NULL;
|
||||
gGL.loadMatrix(gGLModelView);
|
||||
renderXRay(group, mCamera);
|
||||
stop_glerror();
|
||||
gGLLastMatrix = NULL;
|
||||
gGL.popMatrix();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual void visit(const LLSpatialGroup::OctreeNode* node) {}
|
||||
|
||||
};
|
||||
|
||||
class LLOctreeRenderPhysicsShapes : public LLOctreeTraveler<LLDrawable>
|
||||
{
|
||||
|
|
@ -4437,6 +4577,26 @@ void LLSpatialPartition::renderDebug()
|
|||
LLOctreeRenderNonOccluded render_debug(camera);
|
||||
render_debug.traverse(mOctree);
|
||||
|
||||
|
||||
if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION))
|
||||
{
|
||||
{
|
||||
LLGLEnable cull(GL_CULL_FACE);
|
||||
|
||||
LLGLEnable blend(GL_BLEND);
|
||||
LLGLDepthTest depth_under(GL_TRUE, GL_FALSE, GL_GREATER);
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
gGL.diffuseColor4f(0.5f, 0.0f, 0, 0.25f);
|
||||
|
||||
LLGLEnable offset(GL_POLYGON_OFFSET_LINE);
|
||||
glPolygonOffset(-1.f, -1.f);
|
||||
|
||||
LLOctreeRenderXRay xray(camera);
|
||||
xray.traverse(mOctree);
|
||||
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
}
|
||||
}
|
||||
if (LLGLSLShader::sNoFixedFunction)
|
||||
{
|
||||
gDebugProgram.unbind();
|
||||
|
|
|
|||
|
|
@ -661,6 +661,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
|
|||
|
||||
static LLCullResult result;
|
||||
LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
|
||||
LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater() ? TRUE : FALSE;
|
||||
gPipeline.updateCull(*LLViewerCamera::getInstance(), result, water_clip);
|
||||
stop_glerror();
|
||||
|
||||
|
|
@ -867,7 +868,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
|
|||
//}
|
||||
|
||||
LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater() ? TRUE : FALSE;
|
||||
|
||||
|
||||
LLGLState::checkStates();
|
||||
LLGLState::checkClientArrays();
|
||||
|
||||
|
|
|
|||
|
|
@ -93,6 +93,8 @@ LLGLSLShader gTwoTextureAddProgram;
|
|||
LLGLSLShader gOneTextureNoColorProgram;
|
||||
LLGLSLShader gDebugProgram;
|
||||
LLGLSLShader gClipProgram;
|
||||
LLGLSLShader gDownsampleDepthProgram;
|
||||
LLGLSLShader gDownsampleDepthRectProgram;
|
||||
LLGLSLShader gAlphaMaskProgram;
|
||||
|
||||
//object shaders
|
||||
|
|
@ -702,6 +704,8 @@ void LLViewerShaderMgr::unloadShaders()
|
|||
gOcclusionCubeProgram.unload();
|
||||
gDebugProgram.unload();
|
||||
gClipProgram.unload();
|
||||
gDownsampleDepthProgram.unload();
|
||||
gDownsampleDepthRectProgram.unload();
|
||||
gAlphaMaskProgram.unload();
|
||||
gUIProgram.unload();
|
||||
gPathfindingProgram.unload();
|
||||
|
|
@ -3001,6 +3005,26 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
|
|||
success = gClipProgram.createShader(NULL, NULL);
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
gDownsampleDepthProgram.mName = "DownsampleDepth Shader";
|
||||
gDownsampleDepthProgram.mShaderFiles.clear();
|
||||
gDownsampleDepthProgram.mShaderFiles.push_back(make_pair("interface/downsampleDepthV.glsl", GL_VERTEX_SHADER_ARB));
|
||||
gDownsampleDepthProgram.mShaderFiles.push_back(make_pair("interface/downsampleDepthF.glsl", GL_FRAGMENT_SHADER_ARB));
|
||||
gDownsampleDepthProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
|
||||
success = gDownsampleDepthProgram.createShader(NULL, NULL);
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
gDownsampleDepthRectProgram.mName = "DownsampleDepthRect Shader";
|
||||
gDownsampleDepthRectProgram.mShaderFiles.clear();
|
||||
gDownsampleDepthRectProgram.mShaderFiles.push_back(make_pair("interface/downsampleDepthV.glsl", GL_VERTEX_SHADER_ARB));
|
||||
gDownsampleDepthRectProgram.mShaderFiles.push_back(make_pair("interface/downsampleDepthRectF.glsl", GL_FRAGMENT_SHADER_ARB));
|
||||
gDownsampleDepthRectProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
|
||||
success = gDownsampleDepthRectProgram.createShader(NULL, NULL);
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
gAlphaMaskProgram.mName = "Alpha Mask Shader";
|
||||
|
|
|
|||
|
|
@ -230,6 +230,8 @@ extern LLGLSLShader gSplatTextureRectProgram;
|
|||
extern LLGLSLShader gGlowCombineFXAAProgram;
|
||||
extern LLGLSLShader gDebugProgram;
|
||||
extern LLGLSLShader gClipProgram;
|
||||
extern LLGLSLShader gDownsampleDepthProgram;
|
||||
extern LLGLSLShader gDownsampleDepthRectProgram;
|
||||
|
||||
//output tex0[tc0] + tex1[tc1]
|
||||
extern LLGLSLShader gTwoTextureAddProgram;
|
||||
|
|
@ -322,6 +324,7 @@ extern LLGLSLShader gWLCloudProgram;
|
|||
extern LLGLSLShader gPostColorFilterProgram;
|
||||
extern LLGLSLShader gPostNightVisionProgram;
|
||||
|
||||
|
||||
// Deferred rendering shaders
|
||||
extern LLGLSLShader gDeferredImpostorProgram;
|
||||
extern LLGLSLShader gDeferredWaterProgram;
|
||||
|
|
@ -369,7 +372,6 @@ extern LLGLSLShader gDeferredSkinnedFullbrightShinyProgram;
|
|||
extern LLGLSLShader gDeferredSkinnedFullbrightProgram;
|
||||
extern LLGLSLShader gNormalMapGenProgram;
|
||||
|
||||
|
||||
// Deferred materials shaders
|
||||
extern LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2];
|
||||
|
||||
|
|
|
|||
|
|
@ -3515,7 +3515,12 @@ F32 LLVOVolume::getBinRadius()
|
|||
}
|
||||
else if (mDrawable->isStatic())
|
||||
{
|
||||
radius = llmax((S32) mDrawable->getRadius(), 1)*size_factor;
|
||||
F32 szf = size_factor;
|
||||
|
||||
radius = llmax(mDrawable->getRadius(), szf);
|
||||
|
||||
radius = powf(radius, 1.f+szf/radius);
|
||||
|
||||
radius *= 1.f + mDrawable->mDistanceWRTCamera * distance_factor[1];
|
||||
radius += mDrawable->mDistanceWRTCamera * distance_factor[0];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -279,7 +279,7 @@ std::string gPoolNames[] =
|
|||
"POOL_ALPHA"
|
||||
};
|
||||
|
||||
void drawBox(const LLVector3& c, const LLVector3& r);
|
||||
void drawBox(const LLVector4a& c, const LLVector4a& r);
|
||||
void drawBoxOutline(const LLVector3& pos, const LLVector3& size);
|
||||
U32 nhpo2(U32 v);
|
||||
LLVertexBuffer* ll_create_cube_vb(U32 type_mask, U32 usage);
|
||||
|
|
@ -929,9 +929,12 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
|
|||
S32 shadow_detail = RenderShadowDetail;
|
||||
BOOL ssao = RenderDeferredSSAO;
|
||||
|
||||
const U32 occlusion_divisor = 3;
|
||||
|
||||
//allocate deferred rendering color buffers
|
||||
if (!mDeferredScreen.allocate(resX, resY, GL_SRGB8_ALPHA8, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
|
||||
if (!mDeferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
|
||||
if (!mOcclusionDepth.allocate(resX/occlusion_divisor, resY/occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
|
||||
if (!addDeferredAttachments(mDeferredScreen)) return false;
|
||||
|
||||
GLuint screenFormat = GL_RGBA16;
|
||||
|
|
@ -972,6 +975,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
|
|||
for (U32 i = 0; i < 4; i++)
|
||||
{
|
||||
if (!mShadow[i].allocate(sun_shadow_map_width,U32(resY*scale), 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE)) return false;
|
||||
if (!mShadowOcclusion[i].allocate(mShadow[i].getWidth()/occlusion_divisor, mShadow[i].getHeight()/occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE)) return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -979,6 +983,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
|
|||
for (U32 i = 0; i < 4; i++)
|
||||
{
|
||||
mShadow[i].release();
|
||||
mShadowOcclusion[i].release();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -991,6 +996,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
|
|||
for (U32 i = 4; i < 6; i++)
|
||||
{
|
||||
if (!mShadow[i].allocate(spot_shadow_map_width, height, 0, TRUE, FALSE)) return false;
|
||||
if (!mShadowOcclusion[i].allocate(mShadow[i].getWidth()/occlusion_divisor, mShadow[i].getHeight()/occlusion_divisor, 0, TRUE, FALSE)) return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -998,6 +1004,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
|
|||
for (U32 i = 4; i < 6; i++)
|
||||
{
|
||||
mShadow[i].release();
|
||||
mShadowOcclusion[i].release();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1014,11 +1021,13 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
|
|||
for (U32 i = 0; i < 6; i++)
|
||||
{
|
||||
mShadow[i].release();
|
||||
mShadowOcclusion[i].release();
|
||||
}
|
||||
mFXAABuffer.release();
|
||||
mScreen.release();
|
||||
mDeferredScreen.release(); //make sure to release any render targets that share a depth buffer with mDeferredScreen first
|
||||
mDeferredDepth.release();
|
||||
mOcclusionDepth.release();
|
||||
|
||||
if (!mScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false;
|
||||
}
|
||||
|
|
@ -2433,7 +2442,14 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
|
|||
|
||||
if (to_texture)
|
||||
{
|
||||
mScreen.bindTarget();
|
||||
if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender)
|
||||
{
|
||||
mOcclusionDepth.bindTarget();
|
||||
}
|
||||
else
|
||||
{
|
||||
mScreen.bindTarget();
|
||||
}
|
||||
}
|
||||
|
||||
if (sUseOcclusion > 1)
|
||||
|
|
@ -2571,7 +2587,14 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
|
|||
|
||||
if (to_texture)
|
||||
{
|
||||
mScreen.flush();
|
||||
if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender)
|
||||
{
|
||||
mOcclusionDepth.flush();
|
||||
}
|
||||
else
|
||||
{
|
||||
mScreen.flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2639,6 +2662,75 @@ void LLPipeline::markOccluder(LLSpatialGroup* group)
|
|||
}
|
||||
}
|
||||
|
||||
void LLPipeline::downsampleDepthBuffer(LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space)
|
||||
{
|
||||
LLGLSLShader* last_shader = LLGLSLShader::sCurBoundShaderPtr;
|
||||
|
||||
LLGLSLShader* shader = NULL;
|
||||
|
||||
if (scratch_space)
|
||||
{
|
||||
scratch_space->copyContents(source,
|
||||
0, 0, source.getWidth(), source.getHeight(),
|
||||
0, 0, scratch_space->getWidth(), scratch_space->getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);
|
||||
}
|
||||
|
||||
dest.bindTarget();
|
||||
|
||||
|
||||
gDownsampleDepthProgram.bind();
|
||||
|
||||
LLStrider<LLVector3> vert;
|
||||
mDeferredVB->getVertexStrider(vert);
|
||||
LLStrider<LLVector2> tc0;
|
||||
|
||||
vert[0].set(-1,1,0);
|
||||
vert[1].set(-1,-3,0);
|
||||
vert[2].set(3,1,0);
|
||||
|
||||
if (source.getUsage() == LLTexUnit::TT_RECT_TEXTURE)
|
||||
{
|
||||
shader = &gDownsampleDepthRectProgram;
|
||||
shader->bind();
|
||||
shader->uniform2f("delta", 1.f, 1.f);
|
||||
shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, source.getWidth(), source.getHeight());
|
||||
}
|
||||
else
|
||||
{
|
||||
shader = &gDownsampleDepthProgram;
|
||||
shader->bind();
|
||||
shader->uniform2f("delta", 1.f/source.getWidth(), 1.f/source.getHeight());
|
||||
shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, 1.f, 1.f);
|
||||
}
|
||||
|
||||
gGL.getTexUnit(0)->bind(scratch_space ? scratch_space : &source, TRUE);
|
||||
|
||||
{
|
||||
LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS);
|
||||
mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
|
||||
mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
|
||||
}
|
||||
|
||||
dest.flush();
|
||||
|
||||
if (last_shader)
|
||||
{
|
||||
last_shader->bind();
|
||||
}
|
||||
else
|
||||
{
|
||||
gDownsampleDepthProgram.unbind();
|
||||
}
|
||||
}
|
||||
|
||||
void LLPipeline::doOcclusion(LLCamera& camera, LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space)
|
||||
{
|
||||
downsampleDepthBuffer(source, dest, scratch_space);
|
||||
dest.bindTarget();
|
||||
doOcclusion(camera);
|
||||
dest.flush();
|
||||
}
|
||||
|
||||
void LLPipeline::doOcclusion(LLCamera& camera)
|
||||
{
|
||||
if (LLPipeline::sUseOcclusion > 1 && sCull->hasOcclusionGroups())
|
||||
|
|
@ -4551,7 +4643,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)
|
|||
gGL.setColorMask(true, false);
|
||||
}
|
||||
|
||||
void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
|
||||
void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion)
|
||||
{
|
||||
LLFastTimer t(FTM_POST_DEFERRED_POOLS);
|
||||
U32 cur_type = 0;
|
||||
|
|
@ -4566,7 +4658,7 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
|
|||
gGL.setColorMask(true, false);
|
||||
|
||||
pool_set_t::iterator iter1 = mPools.begin();
|
||||
BOOL occlude = LLPipeline::sUseOcclusion > 1;
|
||||
BOOL occlude = LLPipeline::sUseOcclusion > 1 && do_occlusion;
|
||||
|
||||
while ( iter1 != mPools.end() )
|
||||
{
|
||||
|
|
@ -4580,7 +4672,7 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
|
|||
gGLLastMatrix = NULL;
|
||||
gGL.loadMatrix(gGLModelView);
|
||||
LLGLSLShader::bindNoShader();
|
||||
doOcclusion(camera);
|
||||
doOcclusion(camera, mScreen, mOcclusionDepth, &mDeferredDepth);
|
||||
gGL.setColorMask(true, false);
|
||||
}
|
||||
|
||||
|
|
@ -4798,6 +4890,7 @@ void LLPipeline::renderPhysicsDisplay()
|
|||
mPhysicsDisplay.flush();
|
||||
}
|
||||
|
||||
extern std::set<LLSpatialGroup*> visible_selected_groups;
|
||||
|
||||
void LLPipeline::renderDebug()
|
||||
{
|
||||
|
|
@ -5208,6 +5301,27 @@ void LLPipeline::renderDebug()
|
|||
}
|
||||
}
|
||||
|
||||
if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION) && LLGLSLShader::sNoFixedFunction)
|
||||
{ //render visible selected group occlusion geometry
|
||||
gDebugProgram.bind();
|
||||
LLGLDepthTest depth(GL_TRUE, GL_FALSE);
|
||||
gGL.diffuseColor3f(1,0,1);
|
||||
for (std::set<LLSpatialGroup*>::iterator iter = visible_selected_groups.begin(); iter != visible_selected_groups.end(); ++iter)
|
||||
{
|
||||
LLSpatialGroup* group = *iter;
|
||||
|
||||
LLVector4a fudge;
|
||||
fudge.splat(0.25f); //SG_OCCLUSION_FUDGE
|
||||
|
||||
LLVector4a size;
|
||||
size.setAdd(fudge, group->mBounds[1]);
|
||||
|
||||
drawBox(group->mBounds[0], size);
|
||||
}
|
||||
}
|
||||
|
||||
visible_selected_groups.clear();
|
||||
|
||||
if (LLGLSLShader::sNoFixedFunction)
|
||||
{
|
||||
gUIProgram.bind();
|
||||
|
|
@ -8205,11 +8319,7 @@ void LLPipeline::renderDeferredLighting()
|
|||
|
||||
LLStrider<LLVector3> vert;
|
||||
mDeferredVB->getVertexStrider(vert);
|
||||
LLStrider<LLVector2> tc0;
|
||||
LLStrider<LLVector2> tc1;
|
||||
mDeferredVB->getTexCoord0Strider(tc0);
|
||||
mDeferredVB->getTexCoord1Strider(tc1);
|
||||
|
||||
|
||||
vert[0].set(-1,1,0);
|
||||
vert[1].set(-1,-3,0);
|
||||
vert[2].set(3,1,0);
|
||||
|
|
@ -8390,7 +8500,7 @@ void LLPipeline::renderDeferredLighting()
|
|||
LLPipeline::END_RENDER_TYPES);
|
||||
|
||||
|
||||
renderGeomPostDeferred(*LLViewerCamera::getInstance());
|
||||
renderGeomPostDeferred(*LLViewerCamera::getInstance(), false);
|
||||
gPipeline.popRenderTypeMask();
|
||||
}
|
||||
|
||||
|
|
@ -9324,9 +9434,15 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
|
|||
gDeferredShadowCubeProgram.bind();
|
||||
}
|
||||
|
||||
LLRenderTarget& occlusion_target = mShadowOcclusion[LLViewerCamera::sCurCameraID-1];
|
||||
|
||||
occlusion_target.bindTarget();
|
||||
updateCull(shadow_cam, result);
|
||||
occlusion_target.flush();
|
||||
|
||||
stateSort(shadow_cam, result);
|
||||
|
||||
|
||||
//generate shadow map
|
||||
gGL.matrixMode(LLRender::MM_PROJECTION);
|
||||
gGL.pushMatrix();
|
||||
|
|
@ -9414,7 +9530,10 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
|
|||
gDeferredShadowCubeProgram.bind();
|
||||
gGLLastMatrix = NULL;
|
||||
gGL.loadMatrix(gGLModelView);
|
||||
doOcclusion(shadow_cam);
|
||||
|
||||
LLRenderTarget& occlusion_source = mShadow[LLViewerCamera::sCurCameraID-1];
|
||||
|
||||
doOcclusion(shadow_cam, occlusion_source, occlusion_target);
|
||||
|
||||
if (use_shader)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -176,6 +176,12 @@ public:
|
|||
// Object related methods
|
||||
void markVisible(LLDrawable *drawablep, LLCamera& camera);
|
||||
void markOccluder(LLSpatialGroup* group);
|
||||
|
||||
//downsample source to dest, taking the maximum depth value per pixel in source and writing to dest
|
||||
// if source's depth buffer cannot be bound for reading, a scratch space depth buffer must be provided
|
||||
void downsampleDepthBuffer(LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space = NULL);
|
||||
|
||||
void doOcclusion(LLCamera& camera, LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space = NULL);
|
||||
void doOcclusion(LLCamera& camera);
|
||||
void markNotCulled(LLSpatialGroup* group, LLCamera &camera);
|
||||
void markMoved(LLDrawable *drawablep, BOOL damped_motion = FALSE);
|
||||
|
|
@ -275,7 +281,7 @@ public:
|
|||
|
||||
void renderGeom(LLCamera& camera, BOOL forceVBOUpdate = FALSE);
|
||||
void renderGeomDeferred(LLCamera& camera);
|
||||
void renderGeomPostDeferred(LLCamera& camera);
|
||||
void renderGeomPostDeferred(LLCamera& camera, bool do_occlusion=true);
|
||||
void renderGeomShadow(LLCamera& camera);
|
||||
void bindDeferredShader(LLGLSLShader& shader, U32 light_index = 0, U32 noise_map = 0xFFFFFFFF);
|
||||
void setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep);
|
||||
|
|
@ -603,6 +609,7 @@ public:
|
|||
LLRenderTarget mFXAABuffer;
|
||||
LLRenderTarget mEdgeMap;
|
||||
LLRenderTarget mDeferredDepth;
|
||||
LLRenderTarget mOcclusionDepth;
|
||||
LLRenderTarget mDeferredLight;
|
||||
LLRenderTarget mHighlight;
|
||||
LLRenderTarget mPhysicsDisplay;
|
||||
|
|
@ -615,6 +622,7 @@ public:
|
|||
|
||||
//sun shadow map
|
||||
LLRenderTarget mShadow[6];
|
||||
LLRenderTarget mShadowOcclusion[6];
|
||||
std::vector<LLVector3> mShadowFrustPoints[4];
|
||||
LLVector4 mShadowError;
|
||||
LLVector4 mShadowFOV;
|
||||
|
|
|
|||
Loading…
Reference in New Issue