diff options
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/llcharacter/llcharacter.cpp | 25 | ||||
| -rw-r--r-- | indra/llcharacter/llcharacter.h | 1 | ||||
| -rw-r--r-- | indra/llcharacter/llkeyframemotion.cpp | 73 | ||||
| -rw-r--r-- | indra/llcharacter/llkeyframemotion.h | 2 | ||||
| -rw-r--r-- | indra/llrender/llgl.cpp | 7 | ||||
| -rw-r--r-- | indra/llrender/llglslshader.cpp | 10 | ||||
| -rw-r--r-- | indra/llrender/llshadermgr.cpp | 42 | ||||
| -rw-r--r-- | indra/newview/featuretable.txt | 3 | ||||
| -rw-r--r-- | indra/newview/featuretable_xp.txt | 3 | ||||
| -rw-r--r-- | indra/newview/llviewershadermgr.cpp | 9 | ||||
| -rw-r--r-- | indra/newview/llviewertexturelist.cpp | 19 | ||||
| -rw-r--r-- | indra/newview/llviewertexturelist.h | 7 | ||||
| -rw-r--r-- | indra/newview/llvoavatar.cpp | 4 | ||||
| -rw-r--r-- | indra/newview/llvovolume.cpp | 5 | 
14 files changed, 162 insertions, 48 deletions
diff --git a/indra/llcharacter/llcharacter.cpp b/indra/llcharacter/llcharacter.cpp index 5f84be2c5d..c9fb8534f1 100644 --- a/indra/llcharacter/llcharacter.cpp +++ b/indra/llcharacter/llcharacter.cpp @@ -38,7 +38,7 @@  LLStringTable LLCharacter::sVisualParamNames(1024);  std::vector< LLCharacter* > LLCharacter::sInstances; - +BOOL LLCharacter::sAllowInstancesChange = TRUE ;  //-----------------------------------------------------------------------------  // LLCharacter() @@ -51,8 +51,10 @@ LLCharacter::LLCharacter()  	mAppearanceSerialNum( 0 ),  	mSkeletonSerialNum( 0 )  { -	mMotionController.setCharacter( this ); +	llassert_always(sAllowInstancesChange) ;  	sInstances.push_back(this); + +	mMotionController.setCharacter( this );	  	mPauseRequest = new LLPauseRequestHandle();  } @@ -62,18 +64,29 @@ LLCharacter::LLCharacter()  // Class Destructor  //-----------------------------------------------------------------------------  LLCharacter::~LLCharacter() -{ +{	  	for (LLVisualParam *param = getFirstVisualParam();   		param;  		param = getNextVisualParam())  	{  		delete param;  	} -	std::vector<LLCharacter*>::iterator iter = std::find(sInstances.begin(), sInstances.end(), this); -	if (iter != sInstances.end()) + +	U32 i ; +	U32 size = sInstances.size() ; +	for(i = 0 ; i < size ; i++)  	{ -		sInstances.erase(iter); +		if(sInstances[i] == this) +		{ +			break ; +		}  	} + +	llassert_always(i < size) ; + +	llassert_always(sAllowInstancesChange) ; +	sInstances[i] = sInstances[size - 1] ; +	sInstances.pop_back() ;  } diff --git a/indra/llcharacter/llcharacter.h b/indra/llcharacter/llcharacter.h index a6347fcc3c..e81a27c2bc 100644 --- a/indra/llcharacter/llcharacter.h +++ b/indra/llcharacter/llcharacter.h @@ -266,6 +266,7 @@ public:  	void			setSkeletonSerialNum( U32 num )	{ mSkeletonSerialNum = num; }  	static std::vector< LLCharacter* > sInstances; +	static BOOL sAllowInstancesChange ; //debug use  protected:  	LLMotionController	mMotionController; diff --git a/indra/llcharacter/llkeyframemotion.cpp b/indra/llcharacter/llkeyframemotion.cpp index 9df033a4ca..c6f45bffa2 100644 --- a/indra/llcharacter/llkeyframemotion.cpp +++ b/indra/llcharacter/llkeyframemotion.cpp @@ -467,13 +467,15 @@ LLPointer<LLJointState>& LLKeyframeMotion::getJointState(U32 index)  }  //----------------------------------------------------------------------------- -// getJoin() +// getJoint()  //-----------------------------------------------------------------------------  LLJoint* LLKeyframeMotion::getJoint(U32 index)  {  	llassert_always (index < mJointStates.size());  	LLJoint* joint = mJointStates[index]->getJoint(); -	llassert_always (joint); +	 +	//Commented out 06-28-11 by Aura. +	//llassert_always (joint);  	return joint;  } @@ -821,7 +823,11 @@ void LLKeyframeMotion::initializeConstraint(JointConstraint* constraint)  	S32 joint_num;  	LLVector3 source_pos = mCharacter->getVolumePos(shared_data->mSourceConstraintVolume, shared_data->mSourceConstraintOffset);  	LLJoint* cur_joint = getJoint(shared_data->mJointStateIndices[0]); - +	if ( !cur_joint ) +	{ +		return; +	} +	  	F32 source_pos_offset = dist_vec(source_pos, cur_joint->getWorldPosition());  	constraint->mTotalLength = constraint->mJointLengths[0] = dist_vec(cur_joint->getParent()->getWorldPosition(), source_pos); @@ -872,6 +878,10 @@ void LLKeyframeMotion::activateConstraint(JointConstraint* constraint)  	for (joint_num = 1; joint_num < shared_data->mChainLength; joint_num++)  	{  		LLJoint* cur_joint = getJoint(shared_data->mJointStateIndices[joint_num]); +		if ( !cur_joint ) +		{ +			return; +		}  		constraint->mPositions[joint_num] = (cur_joint->getWorldPosition() - mPelvisp->getWorldPosition()) * ~mPelvisp->getWorldRotation();  	} @@ -932,6 +942,11 @@ void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8  	}  	LLJoint* root_joint = getJoint(shared_data->mJointStateIndices[shared_data->mChainLength]); +	if (! root_joint)  +	{ +		return; +	} +	  	LLVector3 root_pos = root_joint->getWorldPosition();  //	LLQuaternion root_rot =   	root_joint->getParent()->getWorldRotation(); @@ -943,6 +958,11 @@ void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8  	for (joint_num = 0; joint_num <= shared_data->mChainLength; joint_num++)  	{  		LLJoint* cur_joint = getJoint(shared_data->mJointStateIndices[joint_num]); +		if (!cur_joint) +		{ +			return; +		} +		  		if (joint_mask[cur_joint->getJointNum()] >= (0xff >> (7 - getPriority())))  		{  			// skip constraint @@ -1033,7 +1053,14 @@ void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8  	if (shared_data->mChainLength)  	{ -		LLQuaternion end_rot = getJoint(shared_data->mJointStateIndices[0])->getWorldRotation(); +		LLJoint* end_joint = getJoint(shared_data->mJointStateIndices[0]); +		 +		if (!end_joint) +		{ +			return; +		} +		 +		LLQuaternion end_rot = end_joint->getWorldRotation();  		// slam start and end of chain to the proper positions (rest of chain stays put)  		positions[0] = lerp(keyframe_source_pos, target_pos, weight); @@ -1042,7 +1069,14 @@ void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8  		// grab keyframe-specified positions of joints	  		for (joint_num = 1; joint_num < shared_data->mChainLength; joint_num++)  		{ -			LLVector3 kinematic_position = getJoint(shared_data->mJointStateIndices[joint_num])->getWorldPosition() +  +			LLJoint* cur_joint = getJoint(shared_data->mJointStateIndices[joint_num]); +			 +			if (!cur_joint) +			{ +				return; +			} +			 +			LLVector3 kinematic_position = cur_joint->getWorldPosition() +   				(source_to_target * constraint->mJointLengthFractions[joint_num]);  			// convert intermediate joint positions to world coordinates @@ -1088,7 +1122,17 @@ void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8  		for (joint_num = shared_data->mChainLength; joint_num > 0; joint_num--)  		{  			LLJoint* cur_joint = getJoint(shared_data->mJointStateIndices[joint_num]); +			 +			if (!cur_joint) +			{ +				return; +			}  			LLJoint* child_joint = getJoint(shared_data->mJointStateIndices[joint_num - 1]); +			if (!child_joint) +			{ +				return; +			} +			  			LLQuaternion parent_rot = cur_joint->getParent()->getWorldRotation();  			LLQuaternion cur_rot = cur_joint->getWorldRotation(); @@ -1122,7 +1166,6 @@ void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8  			cur_joint->setRotation(target_rot);  		} -		LLJoint* end_joint = getJoint(shared_data->mJointStateIndices[0]);  		LLQuaternion end_local_rot = end_rot * ~end_joint->getParent()->getWorldRotation();  		if (weight == 1.f) @@ -1150,7 +1193,13 @@ void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8  		//reset old joint rots  		for (joint_num = 0; joint_num <= shared_data->mChainLength; joint_num++)  		{ -			getJoint(shared_data->mJointStateIndices[joint_num])->setRotation(old_rots[joint_num]); +			LLJoint* cur_joint = getJoint(shared_data->mJointStateIndices[joint_num]); +			if (!cur_joint) +			{ +				return; +			} + +			cur_joint->setRotation(old_rots[joint_num]);  		}  	}  	// simple positional constraint (pelvis only) @@ -1775,7 +1824,15 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)  				constraintp->mJointStateIndices[i] = -1;  				for (U32 j = 0; j < mJointMotionList->getNumJointMotions(); j++)  				{ -					if(getJoint(j) == joint) +					LLJoint* constraint_joint = getJoint(j); +					 +					if ( !constraint_joint ) +					{ +						llwarns << "Invalid joint " << j << llendl; +						return FALSE; +					} +					 +					if(constraint_joint == joint)  					{  						constraintp->mJointStateIndices[i] = (S32)j;  						break; diff --git a/indra/llcharacter/llkeyframemotion.h b/indra/llcharacter/llkeyframemotion.h index 1fe9af40b3..b1422b2b90 100644 --- a/indra/llcharacter/llkeyframemotion.h +++ b/indra/llcharacter/llkeyframemotion.h @@ -70,7 +70,7 @@ public:  private:  	// private helper functions to wrap some asserts  	LLPointer<LLJointState>& getJointState(U32 index); -	LLJoint* getJoint(U32 index); +	LLJoint* getJoint(U32 index );  public:  	//------------------------------------------------------------------------- diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index a3aed4dd8a..c224ab0e9b 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -568,6 +568,13 @@ bool LLGLManager::initGL()  		glGetIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &mMaxSampleMaskWords);  	} +#if LL_WINDOWS +	if (mIsATI) +	{ //using multisample textures on ATI results in black screen for some reason +		mHasTextureMultisample = FALSE; +	} +#endif +  	if (mHasFramebufferObject)  	{  		glGetIntegerv(GL_MAX_SAMPLES, &mMaxSamples); diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index 8e99f62de6..ad2c662dfc 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -109,6 +109,11 @@ BOOL LLGLSLShader::createShader(vector<string> * attributes,  	// Create program  	mProgramObject = glCreateProgramObjectARB(); +	if (gGLManager.mGLVersion < 3.1f) +	{ //force indexed texture channels to 1 if GL version is old (performance improvement for drivers with poor branching shader model support) +		mFeatures.mIndexedTextureChannels = llmin(mFeatures.mIndexedTextureChannels, 1); +	} +  	//compile new source  	vector< pair<string,GLenum> >::iterator fileIter = mShaderFiles.begin();  	for ( ; fileIter != mShaderFiles.end(); fileIter++ ) @@ -131,6 +136,11 @@ BOOL LLGLSLShader::createShader(vector<string> * attributes,  		return FALSE;  	} +	if (gGLManager.mGLVersion < 3.1f) +	{ //attachShaderFeatures may have set the number of indexed texture channels, so set to 1 again +		mFeatures.mIndexedTextureChannels = llmin(mFeatures.mIndexedTextureChannels, 1); +	} +  	// Map attributes and uniforms  	if (success)  	{ diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index bdc103b917..751b250d96 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -462,7 +462,11 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade  	GLcharARB* text[1024];  	GLuint count = 0; -	if (gGLManager.mGLVersion < 3.f) +	if (gGLManager.mGLVersion < 2.1f) +	{ +		text[count++] = strdup("#version 110\n"); +	} +	else if (gGLManager.mGLVersion < 3.f)  	{  		//set version to 1.20  		text[count++] = strdup("#version 120\n"); @@ -524,7 +528,12 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade  		text[count++] = strdup("{\n"); -		if (gGLManager.mGLVersion >= 3.f) +		if (texture_index_channels == 1) +		{ //don't use flow control, that's silly +			text[count++] = strdup("return texture2D(tex0, texcoord);\n"); +			text[count++] = strdup("}\n"); +		} +		else if (gGLManager.mGLVersion >= 3.f)  		{   			text[count++] = strdup("\tswitch (int(vary_texture_index+0.25))\n");  			text[count++] = strdup("\t{\n"); @@ -537,6 +546,8 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade  			}  			text[count++] = strdup("\t}\n"); +			text[count++] = strdup("\treturn vec4(0,0,0,0);\n"); +			text[count++] = strdup("}\n");  		}  		else  		{ @@ -557,10 +568,10 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade  				std::string if_str = llformat("if (ti == %d) return texture2D(tex%d, texcoord);\n", i, i);  				text[count++] = strdup(if_str.c_str());  			} -		}			 -		text[count++] = strdup("\treturn vec4(0,0,0,0);\n"); -		text[count++] = strdup("}\n"); +			text[count++] = strdup("\treturn vec4(0,0,0,0);\n"); +			text[count++] = strdup("}\n"); +		}			  	}  	//copy file into memory @@ -605,11 +616,6 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade  		}  	} -	//free memory -	for (GLuint i = 0; i < count; i++) -	{ -		free(text[i]); -	}  	if (error == GL_NO_ERROR)  	{  		//check for errors @@ -623,6 +629,16 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade  				//an error occured, print log  				LL_WARNS("ShaderLoading") << "GLSL Compilation Error: (" << error << ") in " << filename << LL_ENDL;  				dumpObjectLog(ret); + +				std::stringstream ostr; +				//dump shader source for debugging +				for (GLuint i = 0; i < count; i++) +				{ +					ostr << i << ": " << text[i]; +				} + +				LL_WARNS("ShaderLoading") << "\n" << ostr.str() << llendl; +  				ret = 0;  			}  		} @@ -633,6 +649,12 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade  	}  	stop_glerror(); +	//free memory +	for (GLuint i = 0; i < count; i++) +	{ +		free(text[i]); +	} +  	//successfully loaded, save results  	if (ret)  	{ diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index 4da155efda..5384660d4c 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -1,4 +1,4 @@ -version 29 +version 30  // NOTE: This is mostly identical to featuretable_mac.txt with a few differences  // Should be combined into one table @@ -297,6 +297,7 @@ RenderDeferred				0	0  list Intel  RenderAnisotropic			1	0 +RenderVBOEnable				1	0  list GeForce2  RenderAnisotropic			1	0 diff --git a/indra/newview/featuretable_xp.txt b/indra/newview/featuretable_xp.txt index abe4ec9928..ce2adac221 100644 --- a/indra/newview/featuretable_xp.txt +++ b/indra/newview/featuretable_xp.txt @@ -1,4 +1,4 @@ -version 29 +version 30  // NOTE: This is mostly identical to featuretable_mac.txt with a few differences  // Should be combined into one table @@ -295,6 +295,7 @@ RenderDeferred				0	0  list Intel  RenderAnisotropic			1	0 +RenderVBOEnable				1	0  list GeForce2  RenderAnisotropic			1	0 diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index da4d0548d0..592923ee07 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -722,6 +722,11 @@ BOOL LLViewerShaderMgr::loadBasicShaders()  	shaders.reserve(13);  	S32 ch = gGLManager.mNumTextureImageUnits-1; +	if (gGLManager.mGLVersion < 3.1f) +	{ //force to 1 texture index channel for old drivers +		ch = 1; +	} +  	std::vector<S32> index_channels;  	index_channels.push_back(-1);	 shaders.push_back( make_pair( "windlight/atmosphericsVarsF.glsl",		mVertexShaderLevel[SHADER_WINDLIGHT] ) );  	index_channels.push_back(-1);	 shaders.push_back( make_pair( "windlight/gammaF.glsl",					mVertexShaderLevel[SHADER_WINDLIGHT]) ); @@ -1209,7 +1214,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		{  			if (multisample)  			{ -				fragment = "deferred/sunlightSSAOMSF.glsl"; +				fragment = "deferred/sunLightSSAOMSF.glsl";  			}  			else  			{ @@ -1220,7 +1225,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		{  			if (multisample)  			{ -				fragment = "deferred/sunlightMSF.glsl"; +				fragment = "deferred/sunLightMSF.glsl";  			}  			else  			{ diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index a1d9434d44..d24174adea 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -76,7 +76,6 @@ LLStat LLViewerTextureList::sFormattedMemStat(32, TRUE);  LLViewerTextureList gTextureList;  static LLFastTimer::DeclareTimer FTM_PROCESS_IMAGES("Process Images"); -U32 LLViewerTextureList::sRenderThreadID = 0 ;  ///////////////////////////////////////////////////////////////////////////////  LLViewerTextureList::LLViewerTextureList()  @@ -90,7 +89,6 @@ LLViewerTextureList::LLViewerTextureList()  void LLViewerTextureList::init()  {			 -	sRenderThreadID = LLThread::currentID() ;  	mInitialized = TRUE ;  	sNumImages = 0;  	mUpdateStats = TRUE; @@ -502,10 +500,9 @@ LLViewerFetchedTexture *LLViewerTextureList::findImage(const LLUUID &image_id)  	return iter->second;  } -void LLViewerTextureList::addImageToList(LLViewerFetchedTexture *image, U32 thread_id) +void LLViewerTextureList::addImageToList(LLViewerFetchedTexture *image)  {  	llassert_always(mInitialized) ; -	llassert_always(sRenderThreadID == thread_id);  	llassert(image);  	if (image->isInImageList())  	{ @@ -519,10 +516,9 @@ void LLViewerTextureList::addImageToList(LLViewerFetchedTexture *image, U32 thre  	image->setInImageList(TRUE) ;  } -void LLViewerTextureList::removeImageFromList(LLViewerFetchedTexture *image, U32 thread_id) +void LLViewerTextureList::removeImageFromList(LLViewerFetchedTexture *image)  {  	llassert_always(mInitialized) ; -	llassert_always(sRenderThreadID == thread_id);  	llassert(image);  	if (!image->isInImageList())  	{ @@ -659,10 +655,7 @@ void LLViewerTextureList::updateImagesDecodePriorities()  			const F32 LAZY_FLUSH_TIMEOUT = 30.f; // stop decoding  			const F32 MAX_INACTIVE_TIME  = 50.f; // actually delete  			S32 min_refs = 3; // 1 for mImageList, 1 for mUUIDMap, 1 for local reference -			if (imagep->hasCallbacks()) -			{ -				min_refs++; // Add an extra reference if we're on the loaded callback list -			} +			  			S32 num_refs = imagep->getNumRefs();  			if (num_refs == min_refs)  			{ @@ -719,9 +712,9 @@ void LLViewerTextureList::updateImagesDecodePriorities()  			if ((decode_priority_test < old_priority_test * .8f) ||  				(decode_priority_test > old_priority_test * 1.25f))  			{ -				removeImageFromList(imagep, sRenderThreadID); +				removeImageFromList(imagep);  				imagep->setDecodePriority(decode_priority); -				addImageToList(imagep, sRenderThreadID); +				addImageToList(imagep);  			}  			update_counter--;  		} @@ -893,8 +886,6 @@ void LLViewerTextureList::decodeAllImages(F32 max_time)  {  	LLTimer timer; -	llassert_always(sRenderThreadID == LLThread::currentID()); -  	// Update texture stats and priorities  	std::vector<LLPointer<LLViewerFetchedTexture> > image_list;  	for (image_priority_list_t::iterator iter = mImageList.begin(); diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h index d02b6be6b5..7f4dd0ae88 100644 --- a/indra/newview/llviewertexturelist.h +++ b/indra/newview/llviewertexturelist.h @@ -121,8 +121,8 @@ private:  	void addImage(LLViewerFetchedTexture *image);  	void deleteImage(LLViewerFetchedTexture *image); -	void addImageToList(LLViewerFetchedTexture *image, U32 thread_id = LLThread::currentID()); -	void removeImageFromList(LLViewerFetchedTexture *image, U32 thread_id = LLThread::currentID()); +	void addImageToList(LLViewerFetchedTexture *image); +	void removeImageFromList(LLViewerFetchedTexture *image);  	LLViewerFetchedTexture * getImage(const LLUUID &image_id,									   									 BOOL usemipmap = TRUE, @@ -208,9 +208,6 @@ public:  private:  	static S32 sNumImages;  	static void (*sUUIDCallback)(void**, const LLUUID &); - -	//debug use -	static U32 sRenderThreadID;  };  class LLUIImageList : public LLImageProviderInterface, public LLSingleton<LLUIImageList> diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 1b53348b43..8eda6346b0 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -8242,6 +8242,8 @@ U32 LLVOAvatar::getPartitionType() const  //static  void LLVOAvatar::updateImpostors()   { +	LLCharacter::sAllowInstancesChange = FALSE ; +  	for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();  		 iter != LLCharacter::sInstances.end(); ++iter)  	{ @@ -8251,6 +8253,8 @@ void LLVOAvatar::updateImpostors()  			gPipeline.generateImpostor(avatar);  		}  	} + +	LLCharacter::sAllowInstancesChange = TRUE ;  }  BOOL LLVOAvatar::isImpostor() const diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index c5e2c56e4b..e6da8eb89d 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -4495,6 +4495,11 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  	S32 texture_index_channels = gGLManager.mNumTextureImageUnits-1; //always reserve one for shiny for now just for simplicity +	if (gGLManager.mGLVersion < 3.1f) +	{ +		texture_index_channels = 1; +	} +  	if (LLPipeline::sRenderDeferred && distance_sort)  	{  		texture_index_channels = gDeferredAlphaProgram.mFeatures.mIndexedTextureChannels;  | 
