diff options
Diffstat (limited to 'indra/newview')
| -rwxr-xr-x | indra/newview/app_settings/settings.xml | 3 | ||||
| -rwxr-xr-x | indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl | 94 | ||||
| -rw-r--r-- | indra/newview/app_settings/shaders/class1/interface/downsampleDepthF.glsl | 67 | ||||
| -rw-r--r-- | indra/newview/app_settings/shaders/class1/interface/downsampleDepthRectF.glsl | 67 | ||||
| -rw-r--r-- | indra/newview/app_settings/shaders/class1/interface/downsampleDepthV.glsl | 59 | ||||
| -rwxr-xr-x | indra/newview/llmeshrepository.cpp | 1 | ||||
| -rwxr-xr-x | indra/newview/llspatialpartition.cpp | 180 | ||||
| -rwxr-xr-x | indra/newview/llviewerdisplay.cpp | 3 | ||||
| -rwxr-xr-x | indra/newview/llviewershadermgr.cpp | 24 | ||||
| -rwxr-xr-x | indra/newview/llviewershadermgr.h | 4 | ||||
| -rwxr-xr-x | indra/newview/llvovolume.cpp | 7 | ||||
| -rwxr-xr-x | indra/newview/pipeline.cpp | 145 | ||||
| -rwxr-xr-x | indra/newview/pipeline.h | 10 | 
13 files changed, 588 insertions, 76 deletions
| diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 12ca902c59..344079b640 100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -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> diff --git a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl index 589ace086d..968a5f6b3d 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl @@ -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;  		}  	} diff --git a/indra/newview/app_settings/shaders/class1/interface/downsampleDepthF.glsl b/indra/newview/app_settings/shaders/class1/interface/downsampleDepthF.glsl new file mode 100644 index 0000000000..6523a06d22 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/downsampleDepthF.glsl @@ -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; +} diff --git a/indra/newview/app_settings/shaders/class1/interface/downsampleDepthRectF.glsl b/indra/newview/app_settings/shaders/class1/interface/downsampleDepthRectF.glsl new file mode 100644 index 0000000000..2f89b8ed72 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/downsampleDepthRectF.glsl @@ -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; +} diff --git a/indra/newview/app_settings/shaders/class1/interface/downsampleDepthV.glsl b/indra/newview/app_settings/shaders/class1/interface/downsampleDepthV.glsl new file mode 100644 index 0000000000..71d80911d6 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/downsampleDepthV.glsl @@ -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); +} + diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index b47fe9d4b1..8d3539d297 100755 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -1,3 +1,4 @@ +  /**    * @file llmeshrepository.cpp   * @brief Mesh repository implementation. diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 78401020a6..941c578783 100755 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -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,18 +2714,54 @@ 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);  		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(); diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 9117bf1c01..23038e529b 100755 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -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(); diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index b9e0847935..e24237522a 100755 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -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(); @@ -3003,6 +3007,26 @@ BOOL LLViewerShaderMgr::loadShadersInterface()  	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";  		gAlphaMaskProgram.mShaderFiles.clear();  		gAlphaMaskProgram.mShaderFiles.push_back(make_pair("interface/alphamaskV.glsl", GL_VERTEX_SHADER_ARB)); diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index 8c7de05062..438853cd6f 100755 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -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]; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index bd3be5b9cf..f41057fd1f 100755 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -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];  	} diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 9a4a233b54..6efdf47ec5 100755 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -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)  	{ diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 2c023a6f70..70dcf80407 100755 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -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; | 
