diff options
Diffstat (limited to 'indra')
23 files changed, 398 insertions, 113 deletions
| diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 049dd4346b..0532510996 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -203,7 +203,9 @@ void LLTexUnit::disable(void)  		if (mCurrTexType != LLTexUnit::TT_MULTISAMPLE_TEXTURE &&  			mIndex < gGLManager.mNumTextureUnits)  		{ +			stop_glerror();  			glDisable(sGLTextureType[mCurrTexType]); +			stop_glerror();  		}  		mCurrTexType = TT_NONE; @@ -403,6 +405,7 @@ void LLTexUnit::unbind(eTextureType type)  		activate();  		mCurrTexture = 0;  		glBindTexture(sGLTextureType[type], 0); +		stop_glerror();  	}  } diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 8c9171ccf4..f715a8e9ba 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -1497,7 +1497,14 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const  	}  	if (data_mask & MAP_VERTEX)  	{ -		glVertexPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0)); +		if (data_mask & MAP_TEXTURE_INDEX) +		{ +			glVertexPointer(4,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0)); +		} +		else +		{ +			glVertexPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0)); +		}  	}  	llglassertok(); diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index a9f22193f8..0c4b241537 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -130,6 +130,9 @@ public:  		TYPE_CLOTHWEIGHT,  		TYPE_MAX,  		TYPE_INDEX, +		 +		//no actual additional data, but indicates position.w is texture index +		TYPE_TEXTURE_INDEX,  	};  	enum {  		MAP_VERTEX = (1<<TYPE_VERTEX), @@ -144,6 +147,7 @@ public:  		MAP_WEIGHT = (1<<TYPE_WEIGHT),  		MAP_WEIGHT4 = (1<<TYPE_WEIGHT4),  		MAP_CLOTHWEIGHT = (1<<TYPE_CLOTHWEIGHT), +		MAP_TEXTURE_INDEX = (1<<TYPE_TEXTURE_INDEX),  	};  protected: diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 2c6d75e3c9..22d8ce49c1 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -7489,7 +7489,7 @@        <key>Type</key>        <string>Boolean</string>        <key>Value</key> -      <integer>0</integer> +      <integer>1</integer>      </map>    <key>RenderDebugNormalScale</key>    <map> diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl index 35cfb80c93..f71d9f0b49 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl @@ -20,3 +20,4 @@ void main()  	vec3 nvn = normalize(vary_normal);  	gl_FragData[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);  } + diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl index 03d3322cb6..b8de629fc8 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl @@ -8,13 +8,15 @@  #version 120  varying vec3 vary_normal; +varying float vary_texture_index;  void main()  {  	//transform vertex -	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;  +	gl_Position = gl_ModelViewProjectionMatrix * vec4(gl_Vertex.xyz, 1.0);   	gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; +	vary_texture_index = gl_Vertex.w;  	vary_normal = normalize(gl_NormalMatrix * gl_Normal);  	gl_FrontColor = gl_Color; diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl index 3429877397..30231039b0 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl @@ -9,56 +9,48 @@  #extension GL_ARB_texture_rectangle : enable -uniform sampler2D diffuseMap; -uniform sampler2DRect depthMap; -uniform sampler2D noiseMap; - -uniform vec4 shadow_clip; -uniform vec2 screen_res; +varying float vary_texture_index; + +uniform sampler2D tex0; +uniform sampler2D tex1; +uniform sampler2D tex2; +uniform sampler2D tex3; +uniform sampler2D tex4; +uniform sampler2D tex5; +uniform sampler2D tex6; +uniform sampler2D tex7; + +vec4 textureLookup(vec2 texcoord) +{ +	switch (int(vary_texture_index+0.25)) +	{ +		case 0: return texture2D(tex0, texcoord); +		case 1: return texture2D(tex1, texcoord); +		case 2: return texture2D(tex2, texcoord); +		case 3: return texture2D(tex3, texcoord); +		case 4: return texture2D(tex4, texcoord); +		case 5: return texture2D(tex5, texcoord); +		case 6: return texture2D(tex6, texcoord); +		case 7: return texture2D(tex7, texcoord); +	} + +	return vec4(0,0,0,0); +}  vec3 fullbrightAtmosTransport(vec3 light);  vec3 fullbrightScaleSoftClip(vec3 light); -varying vec3 vary_ambient; -varying vec3 vary_directional; -varying vec4 vary_position; -varying vec3 vary_normal; -varying vec3 vary_fragcoord; - -uniform mat4 inv_proj; - -vec4 getPosition(vec2 pos_screen) -{ -	float depth = texture2DRect(depthMap, pos_screen.xy).a; -	vec2 sc = pos_screen.xy*2.0; -	sc /= screen_res; -	sc -= vec2(1.0,1.0); -	vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); -	vec4 pos = inv_proj * ndc; -	pos /= pos.w; -	pos.w = 1.0; -	return pos; -}  void main()   { -	vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5; -	frag *= screen_res; -	 -	vec3 samp_pos = getPosition(frag).xyz;  -	  	float shadow = 1.0; -	vec4 pos = vary_position; -	vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy)*gl_Color; +	vec4 color = textureLookup(gl_TexCoord[0].xy)*gl_Color;  	color.rgb = fullbrightAtmosTransport(color.rgb);  	color.rgb = fullbrightScaleSoftClip(color.rgb); -	//gl_FragColor = gl_Color;  	gl_FragColor = color; -	//gl_FragColor = vec4(1,0,1,1); -	  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl index 6c38d220e2..6890360c56 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl @@ -14,30 +14,23 @@ vec3 atmosAffectDirectionalLight(float lightIntensity);  vec3 scaleDownLight(vec3 light);  vec3 scaleUpLight(vec3 light); -varying vec3 vary_ambient; -varying vec3 vary_directional; -varying vec3 vary_normal; -varying vec3 vary_fragcoord; -uniform float near_clip; -varying vec4 vary_position; +varying float vary_texture_index;  void main()  {  	//transform vertex -	gl_Position = ftransform();  +	vec4 vert = vec4(gl_Vertex.xyz, 1.0); +	vary_texture_index = gl_Vertex.w; + +	gl_Position = gl_ModelViewProjectionMatrix*vert;   	gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; -	vec4 pos = (gl_ModelViewMatrix * gl_Vertex); -	vary_position = pos; -		 +	vec4 pos = (gl_ModelViewMatrix * vert); +				  	calcAtmospherics(pos.xyz);  	gl_FrontColor = gl_Color;  	gl_FogFragCoord = pos.z; -	 -	pos = gl_ModelViewProjectionMatrix * gl_Vertex; -	vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip); -	  } diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index 25e4bc847c..9645693493 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -430,14 +430,14 @@ void LLRenderPass::renderTexture(U32 type, U32 mask)  	pushBatches(type, mask, TRUE);  } -void LLRenderPass::pushBatches(U32 type, U32 mask, BOOL texture) +void LLRenderPass::pushBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures)  {  	for (LLCullResult::drawinfo_list_t::iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)	  	{  		LLDrawInfo* pparams = *i;  		if (pparams)   		{ -			pushBatch(*pparams, mask, texture); +			pushBatch(*pparams, mask, texture, batch_textures);  		}  	}  } @@ -456,26 +456,42 @@ void LLRenderPass::applyModelMatrix(LLDrawInfo& params)  	}  } -void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture) +void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures)  {  	applyModelMatrix(params); +	bool tex_setup = false; +  	if (texture)  	{ -		if (params.mTexture.notNull()) +		if (batch_textures && params.mTextureList.size() > 1)  		{ -			params.mTexture->addTextureStats(params.mVSize); -			gGL.getTexUnit(0)->bind(params.mTexture, TRUE) ; -			if (params.mTextureMatrix) +			for (U32 i = 0; i < params.mTextureList.size(); ++i)  			{ -				glMatrixMode(GL_TEXTURE); -				glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix); -				gPipeline.mTextureMatrixOps++; +				if (params.mTextureList[i].notNull()) +				{ +					gGL.getTexUnit(i)->bind(params.mTextureList[i], TRUE); +				}  			}  		}  		else -		{ -			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); +		{ //not batching textures or batch has only 1 texture -- might need a texture matrix +			if (params.mTexture.notNull()) +			{ +				params.mTexture->addTextureStats(params.mVSize); +				gGL.getTexUnit(0)->bind(params.mTexture, TRUE) ; +				if (params.mTextureMatrix) +				{ +					tex_setup = true; +					glMatrixMode(GL_TEXTURE); +					glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix); +					gPipeline.mTextureMatrixOps++; +				} +			} +			else +			{ +				gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); +			}  		}  	} @@ -490,7 +506,7 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture)  		gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);  	} -	if (params.mTextureMatrix && texture && params.mTexture.notNull()) +	if (tex_setup)  	{  		glLoadIdentity();  		glMatrixMode(GL_MODELVIEW); diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h index d3fd9ead0d..c7acbb42c6 100644 --- a/indra/newview/lldrawpool.h +++ b/indra/newview/lldrawpool.h @@ -146,8 +146,8 @@ public:  	void resetDrawOrders() { }  	static void applyModelMatrix(LLDrawInfo& params); -	virtual void pushBatches(U32 type, U32 mask, BOOL texture = TRUE); -	virtual void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture); +	virtual void pushBatches(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE); +	virtual void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures = FALSE);  	virtual void renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture = TRUE);  	virtual void renderGroups(U32 type, U32 mask, BOOL texture = TRUE);  	virtual void renderTexture(U32 type, U32 mask); diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 8b5a2ce781..3b3d48ab36 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -124,7 +124,7 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass)  	if (pass == 0)  	{  		simple_shader = &gDeferredAlphaProgram; -		fullbright_shader = &gDeferredFullbrightProgram; +		fullbright_shader = &gObjectFullbrightProgram;  	}  	else  	{ diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index 5f89d11391..3531073896 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -1292,7 +1292,7 @@ void LLDrawPoolBump::renderBump(U32 type, U32 mask)  	}  } -void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture) +void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures)  {  	applyModelMatrix(params); diff --git a/indra/newview/lldrawpoolbump.h b/indra/newview/lldrawpoolbump.h index f4702bf61d..476b1d41b7 100644 --- a/indra/newview/lldrawpoolbump.h +++ b/indra/newview/lldrawpoolbump.h @@ -55,7 +55,7 @@ public:  	virtual void endRenderPass( S32 pass );  	virtual S32	 getNumPasses();  	/*virtual*/ void prerender(); -	/*virtual*/ void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture); +	/*virtual*/ void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures = FALSE);  	void renderBump(U32 type, U32 mask);  	void renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture); diff --git a/indra/newview/lldrawpoolsimple.cpp b/indra/newview/lldrawpoolsimple.cpp index 2e83167851..8ff60f73cc 100644 --- a/indra/newview/lldrawpoolsimple.cpp +++ b/indra/newview/lldrawpoolsimple.cpp @@ -44,6 +44,43 @@ static LLGLSLShader* fullbright_shader = NULL;  static LLFastTimer::DeclareTimer FTM_RENDER_SIMPLE_DEFERRED("Deferred Simple");  static LLFastTimer::DeclareTimer FTM_RENDER_GRASS_DEFERRED("Deferred Grass"); +void LLDrawPoolGlow::beginPostDeferredPass(S32 pass) +{ +	gDeferredFullbrightProgram.bind(); +} + +void LLDrawPoolGlow::renderPostDeferred(S32 pass) +{ +	LLFastTimer t(FTM_RENDER_GLOW); +	LLGLEnable blend(GL_BLEND); +	LLGLDisable test(GL_ALPHA_TEST); +	gGL.flush(); +	/// Get rid of z-fighting with non-glow pass. +	LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL); +	glPolygonOffset(-1.0f, -1.0f); +	gGL.setSceneBlendType(LLRender::BT_ADD); +	 +	LLGLDepthTest depth(GL_TRUE, GL_FALSE); +	gGL.setColorMask(false, true); +	pushBatches(LLRenderPass::PASS_GLOW, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); +	 +	gGL.setColorMask(true, false); +	gGL.setSceneBlendType(LLRender::BT_ALPHA);	 +} + +void LLDrawPoolGlow::endPostDeferredPass(S32 pass) +{ +	gDeferredFullbrightProgram.unbind(); +	for (U32 i = 0; i < 8; i++) +	{ +		if (gGL.getTexUnit(i)->getCurrType() != LLTexUnit::TT_NONE) +		{ +			gGL.getTexUnit(i)->unbind(gGL.getTexUnit(i)->getCurrType()); +			gGL.getTexUnit(i)->disable(); +		} +	} +} +  void LLDrawPoolGlow::render(S32 pass)  {  	LLFastTimer t(FTM_RENDER_GLOW); @@ -79,10 +116,10 @@ void LLDrawPoolGlow::render(S32 pass)  	}  } -void LLDrawPoolGlow::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture) +void LLDrawPoolGlow::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures)  {  	glColor4ubv(params.mGlowColor.mV); -	LLRenderPass::pushBatch(params, mask, texture); +	LLRenderPass::pushBatch(params, mask, texture, batch_textures);  } @@ -128,8 +165,8 @@ void LLDrawPoolSimple::endRenderPass(S32 pass)  	LLFastTimer t(FTM_RENDER_SIMPLE);  	LLRenderPass::endRenderPass(pass); -	if (mVertexShaderLevel > 0){ - +	if (mVertexShaderLevel > 0) +	{  		simple_shader->unbind();  	}  } @@ -168,6 +205,15 @@ void LLDrawPoolSimple::endDeferredPass(S32 pass)  	LLRenderPass::endRenderPass(pass);  	gDeferredDiffuseProgram.unbind(); + +	for (U32 i = 0; i < 8; i++) +	{ +		if (gGL.getTexUnit(i)->getCurrType() != LLTexUnit::TT_NONE) +		{ +			gGL.getTexUnit(i)->unbind(gGL.getTexUnit(i)->getCurrType()); +			gGL.getTexUnit(i)->disable(); +		} +	}  }  void LLDrawPoolSimple::renderDeferred(S32 pass) @@ -177,7 +223,7 @@ void LLDrawPoolSimple::renderDeferred(S32 pass)  	{ //render simple  		LLFastTimer t(FTM_RENDER_SIMPLE_DEFERRED); -		renderTexture(LLRenderPass::PASS_SIMPLE, getVertexDataMask()); +		pushBatches(LLRenderPass::PASS_SIMPLE, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);  	}  } @@ -285,6 +331,33 @@ void LLDrawPoolFullbright::prerender()  	mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);  } +void LLDrawPoolFullbright::beginPostDeferredPass(S32 pass) +{ +	gDeferredFullbrightProgram.bind(); +} + +void LLDrawPoolFullbright::renderPostDeferred(S32 pass) +{ +	LLFastTimer t(FTM_RENDER_FULLBRIGHT); +	 +	gGL.setSceneBlendType(LLRender::BT_ALPHA); +	U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX; +	pushBatches(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask, TRUE, TRUE); +} + +void LLDrawPoolFullbright::endPostDeferredPass(S32 pass) +{ +	gDeferredFullbrightProgram.unbind(); +	for (U32 i = 0; i < 8; i++) +	{ +		if (gGL.getTexUnit(i)->getCurrType() != LLTexUnit::TT_NONE) +		{ +			gGL.getTexUnit(i)->unbind(gGL.getTexUnit(i)->getCurrType()); +			gGL.getTexUnit(i)->disable(); +		} +	} +} +  void LLDrawPoolFullbright::beginRenderPass(S32 pass)  {  	LLFastTimer t(FTM_RENDER_FULLBRIGHT); diff --git a/indra/newview/lldrawpoolsimple.h b/indra/newview/lldrawpoolsimple.h index 5f3bbebbda..3811b3d398 100644 --- a/indra/newview/lldrawpoolsimple.h +++ b/indra/newview/lldrawpoolsimple.h @@ -98,9 +98,9 @@ public:  	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 beginPostDeferredPass(S32 pass); +	/*virtual*/ void endPostDeferredPass(S32 pass); +	/*virtual*/ void renderPostDeferred(S32 pass);  	/*virtual*/ void beginRenderPass(S32 pass);  	/*virtual*/ void endRenderPass(S32 pass); @@ -126,12 +126,12 @@ public:  	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); } +	/*virtual*/ void beginPostDeferredPass(S32 pass);  +	/*virtual*/ void endPostDeferredPass(S32 pass); +	/*virtual*/ void renderPostDeferred(S32 pass);  	void render(S32 pass = 0); -	void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture = TRUE); +	void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE);  }; diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 9f9e50ad0a..e30522d380 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -165,6 +165,7 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp)  	mIndexInTex = 0;  	mTexture		= NULL;  	mTEOffset		= -1; +	mTextureIndex = 255;  	setDrawable(drawablep);  	mVObjp = objp; @@ -386,6 +387,26 @@ void LLFace::setGeomIndex(U16 idx)  	}  } +void LLFace::setTextureIndex(U8 index) +{ +	if (index != mTextureIndex) +	{ +		mTextureIndex = index; + +		if (mTextureIndex != 255) +		{ +			mDrawablep->setState(LLDrawable::REBUILD_POSITION); +		} +		else +		{ +			if (mDrawInfo && !mDrawInfo->mTextureList.empty()) +			{ +				llerrs << "Face with no texture index references indexed texture draw info." << llendl; +			} +		} +	} +} +  void LLFace::setIndicesIndex(S32 idx)   {   	if (mIndicesIndex != idx) @@ -1573,6 +1594,20 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  			mat_vert.affineTransform(*src++, *dst++);  		}  		while(dst < end); + +		F32 index = (F32) (mTextureIndex < 255 ? mTextureIndex : 0); +		F32 *index_dst = (F32*) vertices; +		F32 *index_end = (F32*) end; + +		index_dst += 3; +		index_end += 3; +		do +		{ +			*index_dst = index; +			index_dst += 4; +		} +		while (index_dst < index_end); +		  	}  	if (rebuild_normal) diff --git a/indra/newview/llface.h b/indra/newview/llface.h index b2170c4cf3..b5eaeecd60 100644 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -94,6 +94,8 @@ public:  	U16				getGeomCount()		const	{ return mGeomCount; }		// vertex count for this face  	U16				getGeomIndex()		const	{ return mGeomIndex; }		// index into draw pool  	U16				getGeomStart()		const	{ return mGeomIndex; }		// index into draw pool +	void			setTextureIndex(U8 index); +	U8				getTextureIndex() const		{ return mTextureIndex; }  	void			setTexture(LLViewerTexture* tex) ;  	void            switchTexture(LLViewerTexture* new_texture);  	void            dirtyTexture(); @@ -262,6 +264,7 @@ private:  	U16			mGeomCount;			// vertex count for this face  	U16			mGeomIndex;			// index into draw pool +	U8			mTextureIndex;		// index of texture channel to use for pseudo-atlasing  	U32			mIndicesCount;  	U32			mIndicesIndex;		// index into draw pool for indices (yeah, I know!)  	S32         mIndexInTex ; diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 8143d6a41f..7f91f9a952 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -3439,6 +3439,8 @@ void renderTextureAnim(LLDrawInfo* params)  void renderBatchSize(LLDrawInfo* params)  { +	LLGLEnable offset(GL_POLYGON_OFFSET_FILL); +	glPolygonOffset(-1.f, 1.f);  	glColor3ubv((GLubyte*) &(params->mDebugColor));  	pushVerts(params, LLVertexBuffer::MAP_VERTEX);  } @@ -3876,6 +3878,28 @@ public:  				renderAgentTarget(avatar);  			} +			if (gDebugGL) +			{ +				for (U32 i = 0; i < drawable->getNumFaces(); ++i) +				{ +					LLFace* facep = drawable->getFace(i); +					U8 index = facep->getTextureIndex(); +					if (facep->mDrawInfo) +					{ +						if (index < 255) +						{ +							if (facep->mDrawInfo->mTextureList.size() <= index) +							{ +								llerrs << "Face texture index out of bounds." << llendl; +							} +							else if (facep->mDrawInfo->mTextureList[index] != facep->getTexture()) +							{ +								llerrs << "Face texture index incorrect." << llendl; +							} +						} +					} +				} +			}  		}  		for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i) diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index 0d9cad914a..ae5d4fa463 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -91,6 +91,8 @@ public:  	LLPointer<LLVertexBuffer> mVertexBuffer;  	LLPointer<LLViewerTexture>     mTexture; +	std::vector<LLPointer<LLViewerTexture> > mTextureList; +  	LLColor4U mGlowColor;  	S32 mDebugColor;  	const LLMatrix4* mTextureMatrix; @@ -684,7 +686,7 @@ class LLVolumeGeometryManager: public LLGeometryManager  	virtual void rebuildGeom(LLSpatialGroup* group);  	virtual void rebuildMesh(LLSpatialGroup* group);  	virtual void getGeometry(LLSpatialGroup* group); -	void genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector<LLFace*>& faces, BOOL distance_sort = FALSE); +	void genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector<LLFace*>& faces, BOOL distance_sort = FALSE, BOOL batch_textures = FALSE);  	void registerFace(LLSpatialGroup* group, LLFace* facep, U32 type);  }; diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index b818da205e..29f3acdf91 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -354,6 +354,7 @@ void LLViewerShaderMgr::setShaders()  	//setup preprocessor definitions  	LLShaderMgr::instance()->mDefinitions["samples"] = llformat("%d", gGLManager.getNumFBOFSAASamples(gSavedSettings.getU32("RenderFSAASamples"))); +	LLShaderMgr::instance()->mDefinitions["NUM_TEX_UNITS"] = llformat("%d", gGLManager.mNumTextureImageUnits);  	reentrance = true; @@ -941,6 +942,20 @@ BOOL LLViewerShaderMgr::loadShadersEffects()  } +void setup_indexed_texture(LLGLSLShader& shader) +{ +	shader.bind(); +	shader.uniform1i("tex0", 0); +	shader.uniform1i("tex1", 1); +	shader.uniform1i("tex2", 2); +	shader.uniform1i("tex3", 3); +	shader.uniform1i("tex4", 4); +	shader.uniform1i("tex5", 5); +	shader.uniform1i("tex6", 6); +	shader.uniform1i("tex7", 7); +	shader.unbind(); +} +  BOOL LLViewerShaderMgr::loadShadersDeferred()  {  	if (mVertexShaderLevel[SHADER_DEFERRED] == 0) @@ -992,9 +1007,14 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredDiffuseProgram.mName = "Deferred Diffuse Shader";  		gDeferredDiffuseProgram.mShaderFiles.clear();  		gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER_ARB)); -		gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseIndexedF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredDiffuseProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];  		success = gDeferredDiffuseProgram.createShader(NULL, NULL); + +		if (success) +		{ //force tex0-7 to appropriate texture channels +			setup_indexed_texture(gDeferredDiffuseProgram); +		}  	}  	if (success) @@ -1231,6 +1251,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredFullbrightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];  		success = gDeferredFullbrightProgram.createShader(NULL, NULL); + +		if (success) +		{ +			setup_indexed_texture(gDeferredFullbrightProgram); +		}  	}  	if (success) diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp index 6f354b78b1..85b740d819 100644 --- a/indra/newview/llvopartgroup.cpp +++ b/indra/newview/llvopartgroup.cpp @@ -418,6 +418,7 @@ void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_co  			mFaceList.push_back(facep);  			vertex_count += facep->getGeomCount();  			index_count += facep->getIndicesCount(); +			llassert(facep->getIndicesCount() < 65536);  		}  		obj->mDepth /= count; diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index dbcd4f50ca..510525259f 100644 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -375,6 +375,8 @@ void LLVOSurfacePatch::updateMainGeometry(LLFace *facep,  	S32 num_vertices, num_indices;  	U32 index; +	llassert(mLastStride > 0); +  	render_stride = mLastStride;  	patch_size = mPatchp->getSurface()->getGridsPerPatchEdge();  	S32 vert_size = patch_size / render_stride; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index cc443d32fb..87de064ad1 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1247,17 +1247,7 @@ BOOL LLVOVolume::calcLOD()  	{  		//setDebugText(llformat("%.2f:%.2f, %d", debug_distance, radius, cur_detail)); -		F32 bin_radius = getBinRadius(); -		F32 node_size = 0.f;  - -		LLSpatialGroup* group = mDrawable->getSpatialGroup(); -		if (group) -		{ -			LLSpatialGroup::OctreeNode* node = group->mOctreeNode; -			node_size = node->getSize()[0]; -		} - -		setDebugText(llformat("%.2f:%.2f", bin_radius, node_size)); +		setDebugText(llformat("%d", mDrawable->getFace(0)->getTextureIndex()));  	}  	if (cur_detail != mLOD) @@ -3734,6 +3724,21 @@ LLVolumeBridge::LLVolumeBridge(LLDrawable* drawablep)  	mSlopRatio = 0.25f;  } +bool can_batch_texture(LLFace* facep) +{ +	if (facep->getTextureEntry()->getBumpmap()) +	{ //bump maps aren't worked into texture batching yet +		return false; +	} + +	if (facep->isState(LLFace::TEXTURE_ANIM) && facep->getVirtualSize() > MIN_TEX_ANIM_SIZE) +	{ //texture animation breaks batches +		return false; +	} +	 +	return true; +} +  void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, U32 type)  {  	LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); @@ -3784,12 +3789,36 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,  	LLViewerTexture* tex = facep->getTexture(); +	U8 index = facep->getTextureIndex(); + +	bool batchable = false; + +	if (index < 255 && idx >= 0) +	{ +		if (index < draw_vec[idx]->mTextureList.size()) +		{ +			if (draw_vec[idx]->mTextureList[index].isNull()) +			{ +				batchable = true; +				draw_vec[idx]->mTextureList[index] = tex; +			} +			else if (draw_vec[idx]->mTextureList[index] == tex) +			{ //this face's texture index can be used with this batch +				batchable = true; +			} +		} +		else +		{ //texture list can be expanded to fit this texture index +			batchable = true; +		} +	} +	  	U8 glow = (U8) (facep->getTextureEntry()->getGlow() * 255);  	if (idx >= 0 &&   		draw_vec[idx]->mVertexBuffer == facep->getVertexBuffer() &&  		draw_vec[idx]->mEnd == facep->getGeomIndex()-1 && -		(LLPipeline::sTextureBindTest || draw_vec[idx]->mTexture == tex) && +		(LLPipeline::sTextureBindTest || draw_vec[idx]->mTexture == tex || batchable) &&  #if LL_DARWIN  		draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() <= (U32) gGLManager.mGLMaxVertexRange &&  		draw_vec[idx]->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange && @@ -3803,6 +3832,12 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,  		draw_vec[idx]->mCount += facep->getIndicesCount();  		draw_vec[idx]->mEnd += facep->getGeomCount();  		draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, facep->getVirtualSize()); + +		if (index >= draw_vec[idx]->mTextureList.size()) +		{ +			draw_vec[idx]->mTextureList.resize(index+1); +			draw_vec[idx]->mTextureList[index] = tex; +		}  		draw_vec[idx]->validate();  		update_min_max(draw_vec[idx]->mExtents[0], draw_vec[idx]->mExtents[1], facep->mExtents[0]);  		update_min_max(draw_vec[idx]->mExtents[0], draw_vec[idx]->mExtents[1], facep->mExtents[1]); @@ -3833,6 +3868,11 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,  			draw_info->mDrawMode = LLRender::TRIANGLE_STRIP;  		} +		if (index < 255) +		{ //initialize texture list for texture batching +			draw_info->mTextureList.resize(index+1); +			draw_info->mTextureList[index] = tex; +		}  		draw_info->validate();  	}  } @@ -4258,11 +4298,16 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  	if (LLPipeline::sRenderDeferred)  	{  		bump_mask |= LLVertexBuffer::MAP_BINORMAL; +		genDrawInfo(group, simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, simple_faces, FALSE, TRUE); +		genDrawInfo(group, fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, fullbright_faces, FALSE, TRUE); +		genDrawInfo(group, bump_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, bump_faces, FALSE, TRUE); +	} +	else +	{ +		genDrawInfo(group, simple_mask, simple_faces); +		genDrawInfo(group, fullbright_mask, fullbright_faces); +		genDrawInfo(group, bump_mask, bump_faces, FALSE, TRUE);  	} -	 -	genDrawInfo(group, simple_mask, simple_faces); -	genDrawInfo(group, bump_mask, bump_faces); -	genDrawInfo(group, fullbright_mask, fullbright_faces);  	genDrawInfo(group, alpha_mask, alpha_faces, TRUE);  	if (!LLPipeline::sDelayVBUpdate) @@ -4376,7 +4421,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)  	llassert(!group || !group->isState(LLSpatialGroup::NEW_DRAWINFO));  } -void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector<LLFace*>& faces, BOOL distance_sort) +void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector<LLFace*>& faces, BOOL distance_sort, BOOL batch_textures)  {  	//calculate maximum number of vertices to store in a single buffer  	U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcVertexSize(group->mSpatialPartition->mVertexDataMask); @@ -4435,19 +4480,71 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  		std::vector<LLFace*>::iterator i = face_iter;  		++i; -		while (i != faces.end() &&  -			(LLPipeline::sTextureBindTest || (distance_sort || (*i)->getTexture() == tex))) +		std::vector<LLViewerTexture*> texture_list; + +		if (!distance_sort && batch_textures)  		{ -			facep = *i; -			 -			if (geom_count + facep->getGeomCount() > max_vertices) -			{ //cut batches on geom count too big -				break; +			U8 cur_tex = 0; +			facep->setTextureIndex(cur_tex); +			texture_list.push_back(tex); + +			if (can_batch_texture(facep)) +			{ +				while (i != faces.end()) +				{ +					facep = *i; +					if (facep->getTexture() != tex) +					{ +						cur_tex++; +						if (cur_tex >= 8) +						{ //cut batches on every 8 textures +							break; +						} +						tex = facep->getTexture(); +						texture_list.push_back(tex); +					} + +					if (geom_count + facep->getGeomCount() > max_vertices) +					{ //cut batches on geom count too big +						break; +					} + +					if (!can_batch_texture(facep)) +					{ //cut batches on things that require single texture rendering (animated texture, bump maps) +						break; +					} +					 +					++i; +					index_count += facep->getIndicesCount(); +					geom_count += facep->getGeomCount(); + +					facep->setTextureIndex(cur_tex); +				}  			} -			++i; -			index_count += facep->getIndicesCount(); -			geom_count += facep->getGeomCount(); +			tex = texture_list[0]; +		} +		else +		{ +			while (i != faces.end() &&  +				(LLPipeline::sTextureBindTest || (distance_sort || (*i)->getTexture() == tex))) +			{ +				facep = *i; +			 + +				//face has no texture index +				facep->mDrawInfo = NULL; +				facep->setTextureIndex(255); + +				if (geom_count + facep->getGeomCount() > max_vertices) +				{ //cut batches on geom count too big +					break; +				} + +				++i; +				index_count += facep->getIndicesCount(); +				geom_count += facep->getGeomCount(); +			}  		}  		//create/delete/resize vertex buffer if needed @@ -4497,6 +4594,11 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  			facep->setGeomIndex(index_offset);  			facep->setVertexBuffer(buffer);	 +			if (batch_textures && facep->getTextureIndex() == 255) +			{ +				llerrs << "Invalid texture index." << llendl; +			} +			  			{  				//for debugging, set last time face was updated vs moved  				facep->updateRebuildFlags(); @@ -4695,7 +4797,7 @@ void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_coun  			{  				vertex_count += facep->getGeomCount();  				index_count += facep->getIndicesCount(); - +				llassert(facep->getIndicesCount() < 65536);  				//remember face (for sorting)  				mFaceList.push_back(facep);  			} | 
