diff options
| author | Dave Parks <davep@lindenlab.com> | 2010-05-29 04:19:25 -0500 | 
|---|---|---|
| committer | Dave Parks <davep@lindenlab.com> | 2010-05-29 04:19:25 -0500 | 
| commit | 0a54fb6b24790263c45f096415fee0e2d03323e0 (patch) | |
| tree | 601460e5665b7dc6e357da22350ff82278269897 | |
| parent | 1655256c0c1f536593292d81b89f3580ad1dee73 (diff) | |
Faster texture coordinate updates.
| -rw-r--r-- | indra/newview/llface.cpp | 581 | 
1 files changed, 334 insertions, 247 deletions
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 7a0aa9244d..98a50ca4e7 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -1073,8 +1073,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  		mVertexBuffer->getColorStrider(colors, mGeomIndex);  	} -	F32 r = 0, os = 0, ot = 0, ms = 0, mt = 0, cos_ang = 0, sin_ang = 0; -	  	BOOL is_static = mDrawablep->isStatic();  	BOOL is_global = is_static; @@ -1089,57 +1087,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  		clearState(GLOBAL);  	} -	LLVector2 tmin, tmax; -	 -	if (rebuild_tcoord) -	{ -		if (tep) -		{ -			r  = tep->getRotation(); -			os = tep->mOffsetS; -			ot = tep->mOffsetT; -			ms = tep->mScaleS; -			mt = tep->mScaleT; -			cos_ang = cos(r); -			sin_ang = sin(r); -		} -		else -		{ -			cos_ang = 1.0f; -			sin_ang = 0.0f; -			os = 0.0f; -			ot = 0.0f; -			ms = 1.0f; -			mt = 1.0f; -		} -	} - -	U8 tex_mode = 0; -	 -	if (isState(TEXTURE_ANIM)) -	{ -		LLVOVolume* vobj = (LLVOVolume*) (LLViewerObject*) mVObjp;	 -		tex_mode = vobj->mTexAnimMode; - -		if (!tex_mode) -		{ -			clearState(TEXTURE_ANIM); -		} -		else -		{ -			os = ot = 0.f; -			r = 0.f; -			cos_ang = 1.f; -			sin_ang = 0.f; -			ms = mt = 1.f; -		} - -		if (getVirtualSize() >= MIN_TEX_ANIM_SIZE) -		{ //don't override texture transform during tc bake -			tex_mode = 0; -		} -	} -  	LLColor4U color = tep->getColor();  	if (rebuild_color) @@ -1183,242 +1130,382 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  		}  	} +	LLMatrix4a mat_normal; +	mat_normal.loadu(mat_norm_in); -	//bump setup -	LLVector4a binormal_dir( -sin_ang, cos_ang, 0.f ); -	LLVector4a bump_s_primary_light_ray(0.f, 0.f, 0.f); -	LLVector4a bump_t_primary_light_ray(0.f, 0.f, 0.f); +	//if it's not fullbright and has no normals, bake sunlight based on face normal +	//bool bake_sunlight = !getTextureEntry()->getFullbright() && +	//  !mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL); -	LLQuaternion bump_quat; -	if (mDrawablep->isActive()) -	{ -		bump_quat = LLQuaternion(mDrawablep->getRenderMatrix()); -	} -	 -	if (bump_code) +	F32 r = 0, os = 0, ot = 0, ms = 0, mt = 0, cos_ang = 0, sin_ang = 0; + +	if (rebuild_tcoord)  	{ -		mVObjp->getVolume()->genBinormals(f); -		F32 offset_multiple;  -		switch( bump_code ) +		bool do_xform; +			 +		if (tep)  		{ -			case BE_NO_BUMP: -			offset_multiple = 0.f; -			break; -			case BE_BRIGHTNESS: -			case BE_DARKNESS: -			if( mTexture.notNull() && mTexture->hasGLTexture()) +			r  = tep->getRotation(); +			os = tep->mOffsetS; +			ot = tep->mOffsetT; +			ms = tep->mScaleS; +			mt = tep->mScaleT; +			cos_ang = cos(r); +			sin_ang = sin(r); + +			if (cos_ang != 1.f ||  +				sin_ang != 0.f || +				os != 0.f || +				ot != 0.f || +				ms != 1.f || +				mt != 1.f)  			{ -				// Offset by approximately one texel -				S32 cur_discard = mTexture->getDiscardLevel(); -				S32 max_size = llmax( mTexture->getWidth(), mTexture->getHeight() ); -				max_size <<= cur_discard; -				const F32 ARTIFICIAL_OFFSET = 2.f; -				offset_multiple = ARTIFICIAL_OFFSET / (F32)max_size; +				do_xform = true;  			}  			else  			{ -				offset_multiple = 1.f/256; -			} -			break; - -			default:  // Standard bumpmap textures.  Assumed to be 256x256 -			offset_multiple = 1.f / 256; -			break; +				do_xform = false; +			}	  		} - -		F32 s_scale = 1.f; -		F32 t_scale = 1.f; -		if( tep ) +		else  		{ -			tep->getScale( &s_scale, &t_scale ); +			do_xform = false;  		} -		// Use the nudged south when coming from above sun angle, such -		// that emboss mapping always shows up on the upward faces of cubes when  -		// it's noon (since a lot of builders build with the sun forced to noon). -		LLVector3   sun_ray  = gSky.mVOSkyp->mBumpSunDir; -		LLVector3   moon_ray = gSky.getMoonDirection(); -		LLVector3& primary_light_ray = (sun_ray.mV[VZ] > 0) ? sun_ray : moon_ray; +						 +		//bump setup +		LLVector4a binormal_dir( -sin_ang, cos_ang, 0.f ); +		LLVector4a bump_s_primary_light_ray(0.f, 0.f, 0.f); +		LLVector4a bump_t_primary_light_ray(0.f, 0.f, 0.f); -		bump_s_primary_light_ray.load3((offset_multiple * s_scale * primary_light_ray).mV); -		bump_t_primary_light_ray.load3((offset_multiple * t_scale * primary_light_ray).mV); -	} +		LLQuaternion bump_quat; +		if (mDrawablep->isActive()) +		{ +			bump_quat = LLQuaternion(mDrawablep->getRenderMatrix()); +		} -	U8 texgen = getTextureEntry()->getTexGen(); -	if (rebuild_tcoord && texgen != LLTextureEntry::TEX_GEN_DEFAULT) -	{ //planar texgen needs binormals -		mVObjp->getVolume()->genBinormals(f); -	} - -	LLMatrix4a mat_normal; -	mat_normal.loadu(mat_norm_in); -	 -	//if it's not fullbright and has no normals, bake sunlight based on face normal -	//bool bake_sunlight = !getTextureEntry()->getFullbright() && -	//  !mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL); - -	if (rebuild_tcoord) -	{ -		LLVector4a scalea; -		scalea.load3(scale.mV); - +		if (bump_code) +		{ +			mVObjp->getVolume()->genBinormals(f); +			F32 offset_multiple;  +			switch( bump_code ) +			{ +				case BE_NO_BUMP: +				offset_multiple = 0.f; +				break; +				case BE_BRIGHTNESS: +				case BE_DARKNESS: +				if( mTexture.notNull() && mTexture->hasGLTexture()) +				{ +					// Offset by approximately one texel +					S32 cur_discard = mTexture->getDiscardLevel(); +					S32 max_size = llmax( mTexture->getWidth(), mTexture->getHeight() ); +					max_size <<= cur_discard; +					const F32 ARTIFICIAL_OFFSET = 2.f; +					offset_multiple = ARTIFICIAL_OFFSET / (F32)max_size; +				} +				else +				{ +					offset_multiple = 1.f/256; +				} +				break; -		for (S32 i = 0; i < num_vertices; i++) -		{	 -			LLVector2 tc(vf.mTexCoords[i]); -		 -			LLVector4a& norm = vf.mNormals[i]; -			 -			LLVector4a& center = *(vf.mCenter); +				default:  // Standard bumpmap textures.  Assumed to be 256x256 +				offset_multiple = 1.f / 256; +				break; +			} -			if (texgen != LLTextureEntry::TEX_GEN_DEFAULT) +			F32 s_scale = 1.f; +			F32 t_scale = 1.f; +			if( tep )  			{ -				LLVector4a vec = vf.mPositions[i]; -			 -				vec.mul(scalea); - -				switch (texgen) -				{ -					case LLTextureEntry::TEX_GEN_PLANAR: -						planarProjection(tc, norm, center, vec); -						break; -					case LLTextureEntry::TEX_GEN_SPHERICAL: -						sphericalProjection(tc, norm, center, vec); -						break; -					case LLTextureEntry::TEX_GEN_CYLINDRICAL: -						cylindricalProjection(tc, norm, center, vec); -						break; -					default: -						break; -				}		 +				tep->getScale( &s_scale, &t_scale );  			} +			// Use the nudged south when coming from above sun angle, such +			// that emboss mapping always shows up on the upward faces of cubes when  +			// it's noon (since a lot of builders build with the sun forced to noon). +			LLVector3   sun_ray  = gSky.mVOSkyp->mBumpSunDir; +			LLVector3   moon_ray = gSky.getMoonDirection(); +			LLVector3& primary_light_ray = (sun_ray.mV[VZ] > 0) ? sun_ray : moon_ray; + +			bump_s_primary_light_ray.load3((offset_multiple * s_scale * primary_light_ray).mV); +			bump_t_primary_light_ray.load3((offset_multiple * t_scale * primary_light_ray).mV); +		} -			if (tex_mode && mTextureMatrix) +		U8 texgen = getTextureEntry()->getTexGen(); +		if (rebuild_tcoord && texgen != LLTextureEntry::TEX_GEN_DEFAULT) +		{ //planar texgen needs binormals +			mVObjp->getVolume()->genBinormals(f); +		} + +		U8 tex_mode = 0; +	 +		if (isState(TEXTURE_ANIM)) +		{ +			LLVOVolume* vobj = (LLVOVolume*) (LLViewerObject*) mVObjp;	 +			tex_mode = vobj->mTexAnimMode; + +			if (!tex_mode)  			{ -				LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f); -				tmp = tmp * *mTextureMatrix; -				tc.mV[0] = tmp.mV[0]; -				tc.mV[1] = tmp.mV[1]; +				clearState(TEXTURE_ANIM);  			}  			else  			{ -				xform(tc, cos_ang, sin_ang, os, ot, ms, mt); +				os = ot = 0.f; +				r = 0.f; +				cos_ang = 1.f; +				sin_ang = 0.f; +				ms = mt = 1.f; + +				do_xform = false;  			} -			if(in_atlas) -			{ -				// -				//manually calculate tex-coord per vertex for varying address modes. -				//should be removed if shader can handle this. -				// +			if (getVirtualSize() >= MIN_TEX_ANIM_SIZE) +			{ //don't override texture transform during tc bake +				tex_mode = 0; +			} +		} -				S32 int_part = 0 ; -				switch(mTexture->getAddressMode()) -				{ -				case LLTexUnit::TAM_CLAMP: -					if(tc.mV[0] < 0.f) -					{ -						tc.mV[0] = 0.f ; -					} -					else if(tc.mV[0] > 1.f) -					{ -						tc.mV[0] = 1.f; -					} +		LLVector4a scalea; +		scalea.load3(scale.mV); -					if(tc.mV[1] < 0.f) -					{ -						tc.mV[1] = 0.f ; -					} -					else if(tc.mV[1] > 1.f) -					{ -						tc.mV[1] = 1.f; -					} -					break; -				case LLTexUnit::TAM_MIRROR: -					if(tc.mV[0] < 0.f) -					{ -						tc.mV[0] = -tc.mV[0] ; -					} -					int_part = (S32)tc.mV[0] ; -					if(int_part & 1) //odd number -					{ -						tc.mV[0] = int_part + 1 - tc.mV[0] ; -					} -					else //even number -					{ -						tc.mV[0] -= int_part ; -					} +		bool do_bump = bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1); +		bool do_tex_mat = tex_mode && mTextureMatrix; -					if(tc.mV[1] < 0.f) +		if (!in_atlas && !do_bump) +		{ //not in atlas or not bump mapped, might be able to do a cheap update +			if (texgen != LLTextureEntry::TEX_GEN_PLANAR) +			{ +				if (!do_tex_mat) +				{ +					if (!do_xform)  					{ -						tc.mV[1] = -tc.mV[1] ; +						LLVector4a::memcpyNonAliased16((F32*) tex_coords.get(), (F32*) vf.mTexCoords, num_vertices*2);  					} -					int_part = (S32)tc.mV[1] ; -					if(int_part & 1) //odd number +					else  					{ -						tc.mV[1] = int_part + 1 - tc.mV[1] ; +						for (S32 i = 0; i < num_vertices; i++) +						{	 +							LLVector2 tc(vf.mTexCoords[i]); +							xform(tc, cos_ang, sin_ang, os, ot, ms, mt); +							*tex_coords++ = tc;	 +						}  					} -					else //even number -					{ -						tc.mV[1] -= int_part ; +				} +				else +				{ //do tex mat, no texgen, no atlas, no bump +					for (S32 i = 0; i < num_vertices; i++) +					{	 +						LLVector2 tc(vf.mTexCoords[i]); +						LLVector4a& norm = vf.mNormals[i]; +						LLVector4a& center = *(vf.mCenter); + +						LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f); +						tmp = tmp * *mTextureMatrix; +						tc.mV[0] = tmp.mV[0]; +						tc.mV[1] = tmp.mV[1]; +						*tex_coords++ = tc;	  					} -					break; -				case LLTexUnit::TAM_WRAP: -					if(tc.mV[0] > 1.f) -						tc.mV[0] -= (S32)(tc.mV[0] - 0.00001f) ; -					else if(tc.mV[0] < -1.f) -						tc.mV[0] -= (S32)(tc.mV[0] + 0.00001f) ; - -					if(tc.mV[1] > 1.f) -						tc.mV[1] -= (S32)(tc.mV[1] - 0.00001f) ; -					else if(tc.mV[1] < -1.f) -						tc.mV[1] -= (S32)(tc.mV[1] + 0.00001f) ; - -					if(tc.mV[0] < 0.f) -					{ -						tc.mV[0] = 1.0f + tc.mV[0] ; +				} +			} +			else +			{ //no bump, no atlas, tex gen planar +				if (do_tex_mat) +				{ +					for (S32 i = 0; i < num_vertices; i++) +					{	 +						LLVector2 tc(vf.mTexCoords[i]); +						LLVector4a& norm = vf.mNormals[i]; +						LLVector4a& center = *(vf.mCenter); +						LLVector4a vec = vf.mPositions[i];	 +						vec.mul(scalea); +						planarProjection(tc, norm, center, vec); +						 +						LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f); +						tmp = tmp * *mTextureMatrix; +						tc.mV[0] = tmp.mV[0]; +						tc.mV[1] = tmp.mV[1]; +				 +						*tex_coords++ = tc;	  					} -					if(tc.mV[1] < 0.f) -					{ -						tc.mV[1] = 1.0f + tc.mV[1] ; +				} +				else +				{ +					for (S32 i = 0; i < num_vertices; i++) +					{	 +						LLVector2 tc(vf.mTexCoords[i]); +						LLVector4a& norm = vf.mNormals[i]; +						LLVector4a& center = *(vf.mCenter); +						LLVector4a vec = vf.mPositions[i];	 +						vec.mul(scalea); +						planarProjection(tc, norm, center, vec); +						 +						xform(tc, cos_ang, sin_ang, os, ot, ms, mt); + +						*tex_coords++ = tc;	  					} -					break; -				default: -					break;  				} -			 -				tc.mV[0] = tcoord_xoffset + tcoord_xscale * tc.mV[0] ; -				tc.mV[1] = tcoord_yoffset + tcoord_yscale * tc.mV[1] ;  			} +		} +		else +		{ //either bump mapped or in atlas, just do the whole expensive loop +			for (S32 i = 0; i < num_vertices; i++) +			{	 +				LLVector2 tc(vf.mTexCoords[i]); +				LLVector4a& norm = vf.mNormals[i]; +				 +				LLVector4a& center = *(vf.mCenter); -			*tex_coords++ = tc; -			 -			if (bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1)) -			{ -				LLVector4a tangent; -				tangent.setCross3(vf.mBinormals[i], vf.mNormals[i]); - -				LLMatrix4a tangent_to_object; -				tangent_to_object.setRows(tangent, vf.mBinormals[i], vf.mNormals[i]); -				LLVector4a t; -				tangent_to_object.rotate(binormal_dir, t); -				LLVector4a binormal; -				mat_normal.rotate(t, binormal); -					 -				//VECTORIZE THIS -				if (mDrawablep->isActive()) +				if (texgen != LLTextureEntry::TEX_GEN_DEFAULT) +				{ +					LLVector4a vec = vf.mPositions[i]; +				 +					vec.mul(scalea); + +					switch (texgen) +					{ +						case LLTextureEntry::TEX_GEN_PLANAR: +							planarProjection(tc, norm, center, vec); +							break; +						case LLTextureEntry::TEX_GEN_SPHERICAL: +							sphericalProjection(tc, norm, center, vec); +							break; +						case LLTextureEntry::TEX_GEN_CYLINDRICAL: +							cylindricalProjection(tc, norm, center, vec); +							break; +						default: +							break; +					}		 +				} + +				if (tex_mode && mTextureMatrix)  				{ -					LLVector3 t; -					t.set(binormal.getF32()); -					t *= bump_quat; -					binormal.load3(t.mV); +					LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f); +					tmp = tmp * *mTextureMatrix; +					tc.mV[0] = tmp.mV[0]; +					tc.mV[1] = tmp.mV[1]; +				} +				else +				{ +					xform(tc, cos_ang, sin_ang, os, ot, ms, mt);  				} -				binormal.normalize3fast(); -				tc += LLVector2( bump_s_primary_light_ray.dot3(tangent), bump_t_primary_light_ray.dot3(binormal) ); +				if(in_atlas) +				{ +					// +					//manually calculate tex-coord per vertex for varying address modes. +					//should be removed if shader can handle this. +					// + +					S32 int_part = 0 ; +					switch(mTexture->getAddressMode()) +					{ +					case LLTexUnit::TAM_CLAMP: +						if(tc.mV[0] < 0.f) +						{ +							tc.mV[0] = 0.f ; +						} +						else if(tc.mV[0] > 1.f) +						{ +							tc.mV[0] = 1.f; +						} + +						if(tc.mV[1] < 0.f) +						{ +							tc.mV[1] = 0.f ; +						} +						else if(tc.mV[1] > 1.f) +						{ +							tc.mV[1] = 1.f; +						} +						break; +					case LLTexUnit::TAM_MIRROR: +						if(tc.mV[0] < 0.f) +						{ +							tc.mV[0] = -tc.mV[0] ; +						} +						int_part = (S32)tc.mV[0] ; +						if(int_part & 1) //odd number +						{ +							tc.mV[0] = int_part + 1 - tc.mV[0] ; +						} +						else //even number +						{ +							tc.mV[0] -= int_part ; +						} + +						if(tc.mV[1] < 0.f) +						{ +							tc.mV[1] = -tc.mV[1] ; +						} +						int_part = (S32)tc.mV[1] ; +						if(int_part & 1) //odd number +						{ +							tc.mV[1] = int_part + 1 - tc.mV[1] ; +						} +						else //even number +						{ +							tc.mV[1] -= int_part ; +						} +						break; +					case LLTexUnit::TAM_WRAP: +						if(tc.mV[0] > 1.f) +							tc.mV[0] -= (S32)(tc.mV[0] - 0.00001f) ; +						else if(tc.mV[0] < -1.f) +							tc.mV[0] -= (S32)(tc.mV[0] + 0.00001f) ; + +						if(tc.mV[1] > 1.f) +							tc.mV[1] -= (S32)(tc.mV[1] - 0.00001f) ; +						else if(tc.mV[1] < -1.f) +							tc.mV[1] -= (S32)(tc.mV[1] + 0.00001f) ; + +						if(tc.mV[0] < 0.f) +						{ +							tc.mV[0] = 1.0f + tc.mV[0] ; +						} +						if(tc.mV[1] < 0.f) +						{ +							tc.mV[1] = 1.0f + tc.mV[1] ; +						} +						break; +					default: +						break; +					} -				*tex_coords2++ = tc; -			}	 +					tc.mV[0] = tcoord_xoffset + tcoord_xscale * tc.mV[0] ; +					tc.mV[1] = tcoord_yoffset + tcoord_yscale * tc.mV[1] ; +				} +				 + +				*tex_coords++ = tc; +				 +				if (bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1)) +				{ +					LLVector4a tangent; +					tangent.setCross3(vf.mBinormals[i], vf.mNormals[i]); + +					LLMatrix4a tangent_to_object; +					tangent_to_object.setRows(tangent, vf.mBinormals[i], vf.mNormals[i]); +					LLVector4a t; +					tangent_to_object.rotate(binormal_dir, t); +					LLVector4a binormal; +					mat_normal.rotate(t, binormal); +						 +					//VECTORIZE THIS +					if (mDrawablep->isActive()) +					{ +						LLVector3 t; +						t.set(binormal.getF32()); +						t *= bump_quat; +						binormal.load3(t.mV); +					} + +					binormal.normalize3fast(); +					tc += LLVector2( bump_s_primary_light_ray.dot3(tangent), bump_t_primary_light_ray.dot3(binormal) ); +					 +					*tex_coords2++ = tc; +				}	 +			}  		}  	}  | 
