diff options
Diffstat (limited to 'indra/llrender')
| -rw-r--r-- | indra/llrender/llcubemap.cpp | 14 | ||||
| -rw-r--r-- | indra/llrender/llgl.cpp | 111 | ||||
| -rw-r--r-- | indra/llrender/llgl.h | 12 | ||||
| -rw-r--r-- | indra/llrender/llglslshader.cpp | 12 | ||||
| -rw-r--r-- | indra/llrender/llglslshader.h | 3 | ||||
| -rw-r--r-- | indra/llrender/llpostprocess.cpp | 22 | ||||
| -rw-r--r-- | indra/llrender/llrender.cpp | 338 | ||||
| -rw-r--r-- | indra/llrender/llrender.h | 42 | ||||
| -rw-r--r-- | indra/llrender/llrendersphere.cpp | 97 | ||||
| -rw-r--r-- | indra/llrender/llrendersphere.h | 5 | ||||
| -rw-r--r-- | indra/llrender/llshadermgr.cpp | 18 | ||||
| -rw-r--r-- | indra/llrender/llvertexbuffer.cpp | 476 | ||||
| -rw-r--r-- | indra/llrender/llvertexbuffer.h | 13 | 
13 files changed, 851 insertions, 312 deletions
diff --git a/indra/llrender/llcubemap.cpp b/indra/llrender/llcubemap.cpp index 1b10354c22..5eb29efbfa 100644 --- a/indra/llrender/llcubemap.cpp +++ b/indra/llrender/llcubemap.cpp @@ -273,10 +273,10 @@ void LLCubeMap::setMatrix(S32 stage)  	LLMatrix4 trans(mat3);  	trans.transpose(); -	glMatrixMode(GL_TEXTURE); -	glPushMatrix(); -	glLoadMatrixf((F32 *)trans.mMatrix); -	glMatrixMode(GL_MODELVIEW); +	gGL.matrixMode(LLRender::MM_TEXTURE); +	gGL.pushMatrix(); +	gGL.loadMatrix((F32 *)trans.mMatrix); +	gGL.matrixMode(LLRender::MM_MODELVIEW);  	/*if (stage > 0)  	{ @@ -292,9 +292,9 @@ void LLCubeMap::restoreMatrix()  	{  		gGL.getTexUnit(mMatrixStage)->activate();  	} -	glMatrixMode(GL_TEXTURE); -	glPopMatrix(); -	glMatrixMode(GL_MODELVIEW); +	gGL.matrixMode(LLRender::MM_TEXTURE); +	gGL.popMatrix(); +	gGL.matrixMode(LLRender::MM_MODELVIEW);  	/*if (mMatrixStage > 0)  	{ diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index 4e3cfb9c8a..1667afe179 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -582,6 +582,8 @@ bool LLGLManager::initGL()  		glGetIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &mMaxSampleMaskWords);  	} +	//HACK always disable texture multisample, use FXAA instead +	mHasTextureMultisample = FALSE;  #if LL_WINDOWS  	if (mIsATI)  	{ //using multisample textures on ATI results in black screen for some reason @@ -1193,7 +1195,7 @@ void rotate_quat(LLQuaternion& rotation)  {  	F32 angle_radians, x, y, z;  	rotation.getAngleAxis(&angle_radians, &x, &y, &z); -	glRotatef(angle_radians * RAD_TO_DEG, x, y, z); +	gGL.rotatef(angle_radians * RAD_TO_DEG, x, y, z);  }  void flush_glerror() @@ -1329,8 +1331,6 @@ void LLGLState::initClass()  	sStateMap[GL_MULTISAMPLE_ARB] = GL_FALSE;  	glDisable(GL_MULTISAMPLE_ARB); - -	glEnableClientState(GL_VERTEX_ARRAY);  }  //static @@ -1604,7 +1604,7 @@ void LLGLState::checkTextureChannels(const std::string& msg)  void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)  { -	if (!gDebugGL) +	if (!gDebugGL || LLGLSLShader::sNoFixedFunction)  	{  		return;  	} @@ -1661,7 +1661,7 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)  	}; -	for (S32 j = 0; j < 4; j++) +	for (S32 j = 1; j < 4; j++)  	{  		if (glIsEnabled(value[j]))  		{ @@ -1875,79 +1875,6 @@ void LLGLManager::initGLStates()  //////////////////////////////////////////////////////////////////////////////// -void enable_vertex_weighting(const S32 index) -{ -#if GL_ARB_vertex_program -	if (index > 0) glEnableVertexAttribArrayARB(index);	// vertex weights -#endif -} - -void disable_vertex_weighting(const S32 index) -{ -#if GL_ARB_vertex_program -	if (index > 0) glDisableVertexAttribArrayARB(index);	// vertex weights -#endif -} - -void enable_binormals(const S32 index) -{ -#if GL_ARB_vertex_program -	if (index > 0) -	{ -		glEnableVertexAttribArrayARB(index);	// binormals -	} -#endif -} - -void disable_binormals(const S32 index) -{ -#if GL_ARB_vertex_program -	if (index > 0) -	{ -		glDisableVertexAttribArrayARB(index);	// binormals -	} -#endif -} - - -void enable_cloth_weights(const S32 index) -{ -#if GL_ARB_vertex_program -	if (index > 0)	glEnableVertexAttribArrayARB(index); -#endif -} - -void disable_cloth_weights(const S32 index) -{ -#if GL_ARB_vertex_program -	if (index > 0) glDisableVertexAttribArrayARB(index); -#endif -} - -void set_vertex_weights(const S32 index, const U32 stride, const F32 *weights) -{ -#if GL_ARB_vertex_program -	if (index > 0) glVertexAttribPointerARB(index, 1, GL_FLOAT, FALSE, stride, weights); -	stop_glerror(); -#endif -} - -void set_vertex_clothing_weights(const S32 index, const U32 stride, const LLVector4 *weights) -{ -#if GL_ARB_vertex_program -	if (index > 0) glVertexAttribPointerARB(index, 4, GL_FLOAT, TRUE, stride, weights); -	stop_glerror(); -#endif -} - -void set_binormals(const S32 index, const U32 stride,const LLVector3 *binormals) -{ -#if GL_ARB_vertex_program -	if (index > 0) glVertexAttribPointerARB(index, 3, GL_FLOAT, FALSE, stride, binormals); -	stop_glerror(); -#endif -} -  void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor_specific )  {  	// GL_VERSION returns a null-terminated string with the format:  @@ -2060,20 +1987,20 @@ void LLGLUserClipPlane::setPlane(F32 a, F32 b, F32 c, F32 d)      glh::matrix4f suffix;      suffix.set_row(2, cplane);      glh::matrix4f newP = suffix * P; -    glMatrixMode(GL_PROJECTION); -	glPushMatrix(); -    glLoadMatrixf(newP.m); +    gGL.matrixMode(LLRender::MM_PROJECTION); +	gGL.pushMatrix(); +    gGL.loadMatrix(newP.m);  	gGLObliqueProjectionInverse = LLMatrix4(newP.inverse().transpose().m); -    glMatrixMode(GL_MODELVIEW); +    gGL.matrixMode(LLRender::MM_MODELVIEW);  }  LLGLUserClipPlane::~LLGLUserClipPlane()  {  	if (mApply)  	{ -		glMatrixMode(GL_PROJECTION); -		glPopMatrix(); -		glMatrixMode(GL_MODELVIEW); +		gGL.matrixMode(LLRender::MM_PROJECTION); +		gGL.popMatrix(); +		gGL.matrixMode(LLRender::MM_MODELVIEW);  	}  } @@ -2263,16 +2190,16 @@ LLGLSquashToFarClip::LLGLSquashToFarClip(glh::matrix4f P, U32 layer)  		P.element(2, i) = P.element(3, i) * depth;  	} -	glMatrixMode(GL_PROJECTION); -	glPushMatrix(); -	glLoadMatrixf(P.m); -	glMatrixMode(GL_MODELVIEW); +	gGL.matrixMode(LLRender::MM_PROJECTION); +	gGL.pushMatrix(); +	gGL.loadMatrix(P.m); +	gGL.matrixMode(LLRender::MM_MODELVIEW);  }  LLGLSquashToFarClip::~LLGLSquashToFarClip()  { -	glMatrixMode(GL_PROJECTION); -	glPopMatrix(); -	glMatrixMode(GL_MODELVIEW); +	gGL.matrixMode(LLRender::MM_PROJECTION); +	gGL.popMatrix(); +	gGL.matrixMode(LLRender::MM_MODELVIEW);  } diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h index d736133f3f..495e523c31 100644 --- a/indra/llrender/llgl.h +++ b/indra/llrender/llgl.h @@ -252,7 +252,7 @@ public:  	static void dumpStates();  	static void checkStates(const std::string& msg = "");  	static void checkTextureChannels(const std::string& msg = ""); -	static void checkClientArrays(const std::string& msg = "", U32 data_mask = 0x0001); +	static void checkClientArrays(const std::string& msg = "", U32 data_mask = 0);  protected:  	static boost::unordered_map<LLGLenum, LLGLboolean> sStateMap; @@ -419,15 +419,7 @@ extern LLMatrix4 gGLObliqueProjectionInverse;  #include "llglstates.h"  void init_glstates(); -void enable_vertex_weighting(const S32 index); -void disable_vertex_weighting(const S32 index); -void enable_binormals(const S32 index); -void disable_binormals(const S32 index); -void enable_cloth_weights(const S32 index); -void disable_cloth_weights(const S32 index); -void set_vertex_weights(const S32 index, const U32 stride, const F32 *weights); -void set_vertex_clothing_weights(const S32 index, const U32 stride, const LLVector4 *weights); -void set_binormals(const S32 index, const U32 stride, const LLVector3 *binormals); +  void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor_specific );  extern BOOL gClothRipple; diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index f51d83abe4..95ce227171 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -31,6 +31,7 @@  #include "llshadermgr.h"  #include "llfile.h"  #include "llrender.h" +#include "llvertexbuffer.h"  #if LL_DARWIN  #include "OpenGL/OpenGL.h" @@ -75,6 +76,10 @@ hasAlphaMask(false)  LLGLSLShader::LLGLSLShader()  	: mProgramObject(0), mActiveTextureChannels(0), mShaderLevel(0), mShaderGroup(SG_DEFAULT), mUniformsDirty(FALSE)  { +	for (U32 i = 0; i < LLRender::NUM_MATRIX_MODES; ++i) +	{ +		mMatHash[i] = 0xFFFFFFFF; +	}  }  void LLGLSLShader::unload() @@ -116,10 +121,12 @@ BOOL LLGLSLShader::createShader(vector<string> * attributes,  	// Create program  	mProgramObject = glCreateProgramObjectARB(); +#if !LL_DARWIN  	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);  	} +#endif // !LL_DARWIN  	//compile new source  	vector< pair<string,GLenum> >::iterator fileIter = mShaderFiles.begin(); @@ -386,6 +393,7 @@ void LLGLSLShader::bind()  	gGL.flush();  	if (gGLManager.mHasShaderObjects)  	{ +		LLVertexBuffer::unbind();  		glUseProgramObjectARB(mProgramObject);  		sCurBoundShader = mProgramObject;  		sCurBoundShaderPtr = this; @@ -411,6 +419,7 @@ void LLGLSLShader::unbind()  				stop_glerror();  			}  		} +		LLVertexBuffer::unbind();  		glUseProgramObjectARB(0);  		sCurBoundShader = 0;  		sCurBoundShaderPtr = NULL; @@ -420,6 +429,7 @@ void LLGLSLShader::unbind()  void LLGLSLShader::bindNoShader(void)  { +	LLVertexBuffer::unbind();  	glUseProgramObjectARB(0);  	sCurBoundShader = 0;  	sCurBoundShaderPtr = NULL; @@ -930,7 +940,9 @@ void LLGLSLShader::uniform4fv(const string& uniform, U32 count, const GLfloat* v  		std::map<GLint, LLVector4>::iterator iter = mValue.find(location);  		if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)  		{ +			stop_glerror();  			glUniform4fvARB(location, count, v); +			stop_glerror();  			mValue[location] = vec;  		}  	} diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h index 558ea66b50..c1765e2701 100644 --- a/indra/llrender/llglslshader.h +++ b/indra/llrender/llglslshader.h @@ -117,7 +117,6 @@ public:  	GLint getAttribLocation(U32 attrib);  	GLint mapUniformTextureChannel(GLint location, GLenum type); -  	//enable/disable texture channel for specified uniform  	//if given texture uniform is active in the shader,   	//the corresponding channel will be active upon return @@ -132,6 +131,8 @@ public:  	// Unbinds any previously bound shader by explicitly binding no shader.  	static void bindNoShader(void); +	U32 mMatHash[LLRender::NUM_MATRIX_MODES]; +  	GLhandleARB mProgramObject;  	std::vector<GLint> mAttribute; //lookup table of attribute enum to attribute channel  	std::vector<GLint> mUniform;   //lookup table of uniform enum to uniform location diff --git a/indra/llrender/llpostprocess.cpp b/indra/llrender/llpostprocess.cpp index d76b2d9004..c0045c8044 100644 --- a/indra/llrender/llpostprocess.cpp +++ b/indra/llrender/llpostprocess.cpp @@ -466,21 +466,21 @@ void LLPostProcess::drawOrthoQuad(unsigned int width, unsigned int height, QuadT  void LLPostProcess::viewOrthogonal(unsigned int width, unsigned int height)  { -	glMatrixMode(GL_PROJECTION); -	glPushMatrix(); -	glLoadIdentity(); -	glOrtho( 0.f, (GLdouble) width , (GLdouble) height , 0.f, -1.f, 1.f ); -	glMatrixMode(GL_MODELVIEW); -	glPushMatrix(); -	glLoadIdentity(); +	gGL.matrixMode(LLRender::MM_PROJECTION); +	gGL.pushMatrix(); +	gGL.loadIdentity(); +	gGL.ortho( 0.f, (GLdouble) width , (GLdouble) height , 0.f, -1.f, 1.f ); +	gGL.matrixMode(LLRender::MM_MODELVIEW); +	gGL.pushMatrix(); +	gGL.loadIdentity();  }  void LLPostProcess::viewPerspective(void)  { -	glMatrixMode( GL_PROJECTION ); -	glPopMatrix(); -	glMatrixMode( GL_MODELVIEW ); -	glPopMatrix(); +	gGL.matrixMode(LLRender::MM_PROJECTION); +	gGL.popMatrix(); +	gGL.matrixMode(LLRender::MM_MODELVIEW); +	gGL.popMatrix();  }  void LLPostProcess::changeOrthogonal(unsigned int width, unsigned int height) diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index edcc47aa14..359e6fd560 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -951,6 +951,15 @@ LLRender::LLRender()  	mCurrBlendAlphaSFactor = BF_UNDEF;  	mCurrBlendColorDFactor = BF_UNDEF;  	mCurrBlendAlphaDFactor = BF_UNDEF; + +	mMatrixMode = LLRender::MM_MODELVIEW; +	 +	for (U32 i = 0; i < NUM_MATRIX_MODES; ++i) +	{ +		mMatIdx[i] = 0; +		mMatHash[i] = 0; +		mCurMatHash[i] = 0xFFFFFFFF; +	}  }  LLRender::~LLRender() @@ -1007,28 +1016,262 @@ void LLRender::refreshState(void)  	mDirty = false;  } +void LLRender::syncMatrices() +{ +	stop_glerror(); + +	GLenum mode[] =  +	{ +		GL_MODELVIEW, +		GL_PROJECTION, +		GL_TEXTURE, +		GL_TEXTURE, +		GL_TEXTURE, +		GL_TEXTURE, +	}; + +	std::string name[] =  +	{ +		"modelview_matrix", +		"projection_matrix", +		"texture_matrix0", +		"texture_matrix1", +		"texture_matrix2", +		"texture_matrix3", +	}; + +	LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; + +	if (shader) +	{ +		 +		llassert(shader); + +		bool do_normal = false; +		bool do_mvp = false; + +		for (U32 i = 0; i < NUM_MATRIX_MODES; ++i) +		{ +			if (mMatHash[i] != shader->mMatHash[i]) +			{ +				shader->uniformMatrix4fv(name[i], 1, GL_FALSE, mMatrix[i][mMatIdx[i]].m); +				shader->mMatHash[i] = mMatHash[i]; + +				if (i == MM_MODELVIEW) +				{ +					do_normal = true; +					do_mvp = true; +				} +				else if (i == MM_PROJECTION) +				{ +					do_mvp = true; +				} +			} +		} + +		if (do_normal) +		{ +			S32 loc = shader->getUniformLocation("normal_matrix"); +			if (loc > -1) +			{ +				U32 i = MM_MODELVIEW; + +				glh::matrix4f norm = mMatrix[i][mMatIdx[i]].inverse().transpose(); + +				F32 norm_mat[] =  +				{ +					norm.m[0], norm.m[1], norm.m[2], +					norm.m[4], norm.m[5], norm.m[6], +					norm.m[8], norm.m[9], norm.m[10]  +				}; + +				shader->uniformMatrix3fv("normal_matrix", 1, GL_FALSE, norm_mat); +			} +		} + +		if (do_mvp) +		{ +			S32 loc = shader->getUniformLocation("modelview_projection_matrix"); +			if (loc > -1) +			{ +				U32 mv = MM_MODELVIEW; +				U32 proj = MM_PROJECTION; + +				glh::matrix4f mvp = mMatrix[mv][mMatIdx[mv]]; +				mvp.mult_left(mMatrix[proj][mMatIdx[proj]]); +				 +				shader->uniformMatrix4fv("modelview_projection_matrix", 1, GL_FALSE, mvp.m); +			} +		} +	} +	else +	{ +		for (U32 i = 0; i < 2; ++i) +		{ +			if (mMatHash[i] != mCurMatHash[i]) +			{ +				glMatrixMode(mode[i]); +				glLoadMatrixf(mMatrix[i][mMatIdx[i]].m); +				mCurMatHash[i] = mMatHash[i]; +			} +		} + +		for (U32 i = 2; i < NUM_MATRIX_MODES; ++i) +		{ +			if (mMatHash[i] != mCurMatHash[i]) +			{ +				gGL.getTexUnit(i-2)->activate(); +				glMatrixMode(mode[i]); +				glLoadMatrixf(mMatrix[i][mMatIdx[i]].m); +				mCurMatHash[i] = mMatHash[i]; +			} +		} +	} + +	stop_glerror(); +} +  void LLRender::translatef(const GLfloat& x, const GLfloat& y, const GLfloat& z)  {  	flush(); -	glTranslatef(x,y,z); + +	glh::matrix4f trans_mat(1,0,0,x, +							0,1,0,y, +							0,0,1,z, +							0,0,0,1); +	 +	mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mult_right(trans_mat); +	mMatHash[mMatrixMode]++;  }  void LLRender::scalef(const GLfloat& x, const GLfloat& y, const GLfloat& z)  {  	flush(); -	glScalef(x,y,z); +	 +	glh::matrix4f scale_mat(x,0,0,0, +							0,y,0,0, +							0,0,z,0, +							0,0,0,1); +	 +	mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mult_right(scale_mat); +	mMatHash[mMatrixMode]++; +} + +void LLRender::ortho(F32 left, F32 right, F32 bottom, F32 top, F32 zNear, F32 zFar) +{ +	flush(); + +	glh::matrix4f ortho_mat(2.f/(right-left),0,0,	-(right+left)/(right-left), +							0,2.f/(top-bottom),0,	-(top+bottom)/(top-bottom), +							0,0,-2.f/(zFar-zNear),	-(zFar+zNear)/(zFar-zNear), +							0,0,0,1); +	 +	mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mult_right(ortho_mat); +	mMatHash[mMatrixMode]++; +} + +void LLRender::rotatef(const GLfloat& a, const GLfloat& x, const GLfloat& y, const GLfloat& z) +{ +	flush(); +	 +	F32 r = a * DEG_TO_RAD; + +	F32 c = cosf(r); +	F32 s = sinf(r); + +	F32 ic = 1.f-c; + +	glh::matrix4f rot_mat(x*x*ic+c,		x*y*ic-z*s,		x*z*ic+y*s,		0, +						  x*y*ic+z*s,	y*y*ic+c,		y*z*ic-x*s,		0, +						  x*z*ic-y*s,	y*z*ic+x*s,		z*z*ic+c,		0, +						  0,0,0,1); +	 +	mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mult_right(rot_mat); +	mMatHash[mMatrixMode]++;  }  void LLRender::pushMatrix()  {  	flush(); -	glPushMatrix(); +	 +	if (mMatIdx[mMatrixMode] < LL_MATRIX_STACK_DEPTH-1) +	{ +		mMatrix[mMatrixMode][mMatIdx[mMatrixMode]+1] = mMatrix[mMatrixMode][mMatIdx[mMatrixMode]]; +		++mMatIdx[mMatrixMode]; +	} +	else +	{ +		llwarns << "Matrix stack overflow." << llendl; +	}  }  void LLRender::popMatrix()  {  	flush(); -	glPopMatrix(); +	if (mMatIdx[mMatrixMode] > 0) +	{ +		--mMatIdx[mMatrixMode]; +		mMatHash[mMatrixMode]++; +	} +	else +	{ +		llwarns << "Matrix stack underflow." << llendl; +	} +} + +void LLRender::loadMatrix(const GLfloat* m) +{ +	mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].set_value((GLfloat*) m); +	mMatHash[mMatrixMode]++; +} + +void LLRender::loadMatrix(const GLdouble* dm) +{ +	F32 m[16]; +	for (U32 i = 0; i < 16; i++) +	{ +		m[i] = (F32) dm[i]; +	} + +	loadMatrix(m); +} + +void LLRender::multMatrix(const GLfloat* m) +{ +	flush(); + +	glh::matrix4f mat((GLfloat*) m); +	 +	mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mult_right(mat); +	mMatHash[mMatrixMode]++; +} + +void LLRender::matrixMode(U32 mode) +{ +	if (mode == MM_TEXTURE) +	{ +		mode = MM_TEXTURE0 + gGL.getCurrentTexUnitIndex(); +	} + +	llassert(mode < NUM_MATRIX_MODES); +	mMatrixMode = mode; +} + +void LLRender::multMatrix(const GLdouble* dm) +{ +	F32 m[16]; +	for (U32 i = 0; i < 16; i++) +	{ +		m[i] = (F32) dm[i]; +	} + +	multMatrix(m); +} + +void LLRender::loadIdentity() +{ +	mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].make_identity(); +	mMatHash[mMatrixMode]++;  }  void LLRender::translateUI(F32 x, F32 y, F32 z) @@ -1421,12 +1664,16 @@ void LLRender::flush()  			}  		} +		//store mCount in a local variable to avoid re-entrance (drawArrays may call flush) +		U32 count = mCount; +		mCount = 0; +  		mBuffer->setBuffer(immediate_mask); -		mBuffer->drawArrays(mMode, 0, mCount); +		mBuffer->drawArrays(mMode, 0, count); -		mVerticesp[0] = mVerticesp[mCount]; -		mTexcoordsp[0] = mTexcoordsp[mCount]; -		mColorsp[0] = mColorsp[mCount]; +		mVerticesp[0] = mVerticesp[count]; +		mTexcoordsp[0] = mTexcoordsp[count]; +		mColorsp[0] = mColorsp[count];  		mCount = 0;  	}  } @@ -1586,6 +1833,81 @@ void LLRender::color3fv(const GLfloat* c)  	color4f(c[0],c[1],c[2],1);  } +void LLRender::diffuseColor3f(F32 r, F32 g, F32 b) +{ +	LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; +	llassert(!LLGLSLShader::sNoFixedFunction || shader != NULL); + +	if (shader) +	{ +		shader->uniform4f("color", r,g,b,1.f); +	} +	else +	{ +		glColor3f(r,g,b); +	} +} + +void LLRender::diffuseColor3fv(const F32* c) +{ +	LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; +	llassert(!LLGLSLShader::sNoFixedFunction || shader != NULL); + +	if (shader) +	{ +		shader->uniform4f("color", c[0], c[1], c[2], 1.f); +	} +	else +	{ +		glColor3fv(c); +	} +} + +void LLRender::diffuseColor4f(F32 r, F32 g, F32 b, F32 a) +{ +	LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; +	llassert(!LLGLSLShader::sNoFixedFunction || shader != NULL); + +	if (shader) +	{ +		shader->uniform4f("color", r,g,b,a); +	} +	else +	{ +		glColor4f(r,g,b,a); +	} +} + +void LLRender::diffuseColor4fv(const F32* c) +{ +	LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; +	llassert(!LLGLSLShader::sNoFixedFunction || shader != NULL); + +	if (shader) +	{ +		shader->uniform4fv("color", 1, c); +	} +	else +	{ +		glColor4fv(c); +	} +} + +void LLRender::diffuseColor4ubv(const U8* c) +{ +	LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; +	llassert(!LLGLSLShader::sNoFixedFunction || shader != NULL); + +	if (shader) +	{ +		shader->uniform4f("color", c[0]/255.f, c[1]/255.f, c[2]/255.f, c[3]/255.f); +	} +	else +	{ +		glColor4ubv(c); +	} +} +  void LLRender::debugTexUnits(void)  {  	LL_INFOS("TextureUnit") << "Active TexUnit: " << mCurrTextureUnitIndex << LL_ENDL; diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index 8f7ee30d87..465c16f0de 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -41,6 +41,8 @@  #include "llstrider.h"  #include "llpointer.h"  #include "llglheaders.h" +#include "llmatrix4a.h" +#include "glh/glh_linear.h"  class LLVertexBuffer;  class LLCubeMap; @@ -48,6 +50,8 @@ class LLImageGL;  class LLRenderTarget;  class LLTexture ; +#define LL_MATRIX_STACK_DEPTH 32 +  class LLTexUnit  {  	friend class LLRender; @@ -308,6 +312,18 @@ public:  		BF_UNDEF  	} eBlendFactor; +	typedef enum +	{ +		MM_MODELVIEW = 0, +		MM_PROJECTION, +		MM_TEXTURE0, +		MM_TEXTURE1, +		MM_TEXTURE2, +		MM_TEXTURE3, +		NUM_MATRIX_MODES, +		MM_TEXTURE +	} eMatrixMode; +  	LLRender();  	~LLRender();  	void init() ; @@ -319,8 +335,19 @@ public:  	void translatef(const GLfloat& x, const GLfloat& y, const GLfloat& z);  	void scalef(const GLfloat& x, const GLfloat& y, const GLfloat& z); +	void rotatef(const GLfloat& a, const GLfloat& x, const GLfloat& y, const GLfloat& z); +	void ortho(F32 left, F32 right, F32 bottom, F32 top, F32 zNear, F32 zFar); +  	void pushMatrix();  	void popMatrix(); +	void loadMatrix(const GLfloat* m); +	void loadMatrix(const GLdouble* m); +	void loadIdentity(); +	void multMatrix(const GLfloat* m); +	void multMatrix(const GLdouble* m); +	void matrixMode(U32 mode);	 + +	void syncMatrices();  	void translateUI(F32 x, F32 y, F32 z);  	void scaleUI(F32 x, F32 y, F32 z); @@ -351,6 +378,12 @@ public:  	void color3fv(const GLfloat* c);  	void color4ubv(const GLubyte* c); +	void diffuseColor3f(F32 r, F32 g, F32 b); +	void diffuseColor3fv(const F32* c); +	void diffuseColor4f(F32 r, F32 g, F32 b, F32 a); +	void diffuseColor4fv(const F32* c); +	void diffuseColor4ubv(const U8* c); +  	void vertexBatchPreTransformed(LLVector3* verts, S32 vert_count);  	void vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, S32 vert_count);  	void vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, LLColor4U*, S32 vert_count); @@ -391,7 +424,14 @@ public:  	static U32 sUIVerts;  private: -	bool				mDirty; +	U32 mMatrixMode; +	U32 mMatIdx[NUM_MATRIX_MODES]; +	U32 mMatHash[NUM_MATRIX_MODES]; +	glh::matrix4f mMatrix[NUM_MATRIX_MODES][LL_MATRIX_STACK_DEPTH]; + +	U32 mCurMatHash[NUM_MATRIX_MODES]; +	 +	bool			mDirty;  	U32				mCount;  	U32				mMode;  	U32				mCurrTextureUnitIndex; diff --git a/indra/llrender/llrendersphere.cpp b/indra/llrender/llrendersphere.cpp index a5cd70445f..e7e07a1ab2 100644 --- a/indra/llrender/llrendersphere.cpp +++ b/indra/llrender/llrendersphere.cpp @@ -35,106 +35,11 @@  #include "llglheaders.h" -GLUquadricObj *gQuadObj2 = NULL;  LLRenderSphere gSphere; -void drawSolidSphere(GLdouble radius, GLint slices, GLint stacks); - -void drawSolidSphere(GLdouble radius, GLint slices, GLint stacks) -{ -	if (!gQuadObj2) -	{ -		gQuadObj2 = gluNewQuadric(); -		if (!gQuadObj2) -		{ -			llwarns << "drawSolidSphere couldn't allocate quadric" << llendl; -			return; -		} -	} - -	gluQuadricDrawStyle(gQuadObj2, GLU_FILL); -	gluQuadricNormals(gQuadObj2, GLU_SMOOTH); -	// If we ever changed/used the texture or orientation state -	// of quadObj, we'd need to change it to the defaults here -	// with gluQuadricTexture and/or gluQuadricOrientation. -	gluQuadricTexture(gQuadObj2, GL_TRUE); -	gluSphere(gQuadObj2, radius, slices, stacks); -} - - -// A couple thoughts on sphere drawing: -// 1) You need more slices than stacks, but little less than 2:1 -// 2) At low LOD, setting stacks to an odd number avoids a "band" around the equator, making things look smoother -void LLRenderSphere::prerender() -{ -	//  Create a series of display lists for different LODs -	mDList[0] = glGenLists(1); -	glNewList(mDList[0], GL_COMPILE); -	drawSolidSphere(1.0, 30, 20); -	glEndList(); - -	mDList[1] = glGenLists(1); -	glNewList(mDList[1], GL_COMPILE); -	drawSolidSphere(1.0, 20, 15); -	glEndList(); - -	mDList[2] = glGenLists(1); -	glNewList(mDList[2], GL_COMPILE); -	drawSolidSphere(1.0, 12, 8); -	glEndList(); - -	mDList[3] = glGenLists(1); -	glNewList(mDList[3], GL_COMPILE); -	drawSolidSphere(1.0, 8, 5); -	glEndList(); -} - -void LLRenderSphere::cleanupGL() -{ -	for (S32 detail = 0; detail < 4; detail++) -	{ -		glDeleteLists(mDList[detail], 1); -		mDList[detail] = 0; -	} -	 -	if (gQuadObj2) -	{ -		gluDeleteQuadric(gQuadObj2); -		gQuadObj2 = NULL; -	} -} - -// Constants here are empirically derived from my eyeballs, JNC -// -// The toughest adjustment is the cutoff for the lowest LOD -// Maybe we should have more LODs at the low end? -void LLRenderSphere::render(F32 pixel_area) -{ -	S32 level_of_detail; - -	if (pixel_area > 10000.f) -	{ -		level_of_detail = 0; -	} -	else if (pixel_area > 800.f) -	{ -		level_of_detail = 1; -	} -	else if (pixel_area > 100.f) -	{ -		level_of_detail = 2; -	} -	else -	{ -		level_of_detail = 3; -	} -	glCallList(mDList[level_of_detail]); -} - -  void LLRenderSphere::render()  { -	glCallList(mDList[0]); +	renderGGL();  }  inline LLVector3 polar_to_cart(F32 latitude, F32 longitude) diff --git a/indra/llrender/llrendersphere.h b/indra/llrender/llrendersphere.h index 96a6bec80c..f8e9e86e7f 100644 --- a/indra/llrender/llrendersphere.h +++ b/indra/llrender/llrendersphere.h @@ -40,11 +40,6 @@ void lat2xyz(LLVector3 * result, F32 lat, F32 lon);			// utility routine  class LLRenderSphere    {  public: -	LLGLuint	mDList[5]; - -	void prerender(); -	void cleanupGL(); -	void render(F32 pixel_area);		// of a box of size 1.0 at that position  	void render();						// render at highest LOD  	void renderGGL();                   // render using LLRender diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 986c1f2774..db3d7becd9 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -531,9 +531,9 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade  	}  	//we can't have any lines longer than 1024 characters  -	//or any shaders longer than 1024 lines... deal - DaveP +	//or any shaders longer than 4096 lines... deal - DaveP  	GLcharARB buff[1024]; -	GLcharARB* text[1024]; +	GLcharARB* text[4096];  	GLuint count = 0;  	if (gGLManager.mGLVersion < 2.1f) @@ -544,10 +544,13 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade  	{  		//set version to 1.20  		text[count++] = strdup("#version 120\n"); +		text[count++] = strdup("#define FXAA_GLSL_120 1\n"); +		text[count++] = strdup("#define FXAA_FAST_PIXEL_OFFSET 0\n");  	}  	else  	{  //set version to 1.30  		text[count++] = strdup("#version 130\n"); +		text[count++] = strdup("#define FXAA_GLSL_130 1\n");  	}  	//copy preprocessor definitions into buffer @@ -649,7 +652,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade  	}  	//copy file into memory -	while( fgets((char *)buff, 1024, file) != NULL && count < LL_ARRAY_SIZE(buff) )  +	while( fgets((char *)buff, 1024, file) != NULL && count < LL_ARRAY_SIZE(text) )   	{  		text[count++] = (GLcharARB *)strdup((char *)buff);   	} @@ -704,14 +707,23 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade  				LL_WARNS("ShaderLoading") << "GLSL Compilation Error: (" << error << ") in " << filename << LL_ENDL;  				dumpObjectLog(ret); +#if LL_WINDOWS  				std::stringstream ostr;  				//dump shader source for debugging  				for (GLuint i = 0; i < count; i++)  				{  					ostr << i << ": " << text[i]; + +					if (i % 128 == 0) +					{ //dump every 128 lines +						LL_WARNS("ShaderLoading") << "\n" << ostr.str() << llendl; +						ostr = std::stringstream(); +					} +  				}  				LL_WARNS("ShaderLoading") << "\n" << ostr.str() << llendl; +#endif // LL_WINDOWS  				ret = 0;  			} diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 8fd1193780..090da765ac 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -63,11 +63,8 @@ U32 LLVertexBuffer::sAllocatedBytes = 0;  BOOL LLVertexBuffer::sMapped = FALSE;  BOOL LLVertexBuffer::sUseStreamDraw = TRUE;  BOOL LLVertexBuffer::sPreferStreamDraw = FALSE; -S32	LLVertexBuffer::sWeight4Loc = -1; -  std::vector<U32> LLVertexBuffer::sDeleteList; -  const U32 FENCE_WAIT_TIME_NANOSECONDS = 10000;  //1 ms  class LLGLSyncFence : public LLGLFence @@ -131,6 +128,7 @@ S32 LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_MAX] =  	sizeof(LLVector2), // TYPE_TEXCOORD2,  	sizeof(LLVector2), // TYPE_TEXCOORD3,  	sizeof(LLColor4U), // TYPE_COLOR, +	sizeof(U8),		   // TYPE_EMISSIVE  	sizeof(LLVector4), // TYPE_BINORMAL,  	sizeof(F32),	   // TYPE_WEIGHT,  	sizeof(LLVector4), // TYPE_WEIGHT4, @@ -149,6 +147,7 @@ U32 LLVertexBuffer::sGLMode[LLRender::NUM_MODES] =  	GL_LINE_LOOP,  }; +  //static  void LLVertexBuffer::setupClientArrays(U32 data_mask)  { @@ -157,36 +156,79 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)  		llerrs << "Cannot use LLGLImmediate and LLVertexBuffer simultaneously!" << llendl;  	}*/ +	LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; +  	if (sLastMask != data_mask)  	{ +		llassert(!LLGLSLShader::sNoFixedFunction || shader != NULL); +		static LLGLSLShader* last_shader = LLGLSLShader::sCurBoundShaderPtr; +		llassert(sLastMask == 0 || last_shader == shader); +		last_shader = shader; +  		U32 mask[] =  		{  			MAP_VERTEX,  			MAP_NORMAL,  			MAP_TEXCOORD0,  			MAP_COLOR, +			MAP_EMISSIVE, +			MAP_WEIGHT, +			MAP_WEIGHT4, +			MAP_BINORMAL, +			MAP_CLOTHWEIGHT,  		}; +		U32 type[] = +		{ +			TYPE_VERTEX, +			TYPE_NORMAL, +			TYPE_TEXCOORD0, +			TYPE_COLOR, +			TYPE_EMISSIVE, +			TYPE_WEIGHT, +			TYPE_WEIGHT4, +			TYPE_BINORMAL, +			TYPE_CLOTHWEIGHT, +		}; +  		GLenum array[] =  		{  			GL_VERTEX_ARRAY,  			GL_NORMAL_ARRAY,  			GL_TEXTURE_COORD_ARRAY,  			GL_COLOR_ARRAY, +			0, +			0, +			0, +			0, +			0,  		};  		BOOL error = FALSE; -		for (U32 i = 0; i < 4; ++i) +		for (U32 i = 0; i < 9; ++i)  		{ +			S32 loc = -1; +			if (shader) +			{ +				loc = shader->getAttribLocation(type[i]); +			} +  			if (sLastMask & mask[i])  			{ //was enabled -				if (!(data_mask & mask[i]) && i > 0) +				if (!(data_mask & mask[i]))  				{ //needs to be disabled -					glDisableClientState(array[i]); +					if (loc >= 0) +					{ +						glDisableVertexAttribArrayARB(loc); +					} +					else if (!shader) +					{ +						glDisableClientState(array[i]); +					}  				} -				else if (gDebugGL) -				{ //needs to be enabled, make sure it was (DEBUG TEMPORARY) -					if (i > 0 && !glIsEnabled(array[i])) +				else if (gDebugGL && !shader && array[i]) +				{ //needs to be enabled, make sure it was (DEBUG) +					if (loc < 0 && !glIsEnabled(array[i]))  					{  						if (gDebugSession)  						{ @@ -202,11 +244,18 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)  			}  			else   			{	//was disabled -				if (data_mask & mask[i] && i > 0) +				if (data_mask & mask[i])  				{ //needs to be enabled -					glEnableClientState(array[i]); +					if (loc >= 0) +					{ +						glEnableVertexAttribArrayARB(loc); +					} +					else if (!shader) +					{ +						glEnableClientState(array[i]); +					}  				} -				else if (gDebugGL && i > 0 && glIsEnabled(array[i])) +				else if (!shader && array[i] && gDebugGL && glIsEnabled(array[i]))  				{ //needs to be disabled, make sure it was (DEBUG TEMPORARY)  					if (gDebugSession)  					{ @@ -233,62 +282,71 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)  			MAP_TEXCOORD3  		}; +		U32 type_tc[] =  +		{ +			TYPE_TEXCOORD1, +			TYPE_TEXCOORD2, +			TYPE_TEXCOORD3 +		}; +  		for (U32 i = 0; i < 3; i++)  		{ +			S32 loc = -1; +			if (shader) +			{ +				loc = shader->getAttribLocation(type_tc[i]); +			} +  			if (sLastMask & map_tc[i])  			{  				if (!(data_mask & map_tc[i])) -				{ -					glClientActiveTextureARB(GL_TEXTURE1_ARB+i); -					glDisableClientState(GL_TEXTURE_COORD_ARRAY); -					glClientActiveTextureARB(GL_TEXTURE0_ARB); +				{ //disable +					if (loc >= 0) +					{ +						glDisableVertexAttribArrayARB(loc); +					} +					else if (!shader) +					{ +						glClientActiveTextureARB(GL_TEXTURE1_ARB+i); +						glDisableClientState(GL_TEXTURE_COORD_ARRAY); +						glClientActiveTextureARB(GL_TEXTURE0_ARB); +					}  				}  			}  			else if (data_mask & map_tc[i])  			{ -				glClientActiveTextureARB(GL_TEXTURE1_ARB+i); -				glEnableClientState(GL_TEXTURE_COORD_ARRAY); -				glClientActiveTextureARB(GL_TEXTURE0_ARB); +				if (loc >= 0) +				{ +					glEnableVertexAttribArrayARB(loc); +				} +				else if (!shader) +				{ +					glClientActiveTextureARB(GL_TEXTURE1_ARB+i); +					glEnableClientState(GL_TEXTURE_COORD_ARRAY); +					glClientActiveTextureARB(GL_TEXTURE0_ARB); +				}  			}  		} -		if (sLastMask & MAP_BINORMAL) +		if (!shader)  		{ -			if (!(data_mask & MAP_BINORMAL)) +			if (sLastMask & MAP_BINORMAL)  			{ -				glClientActiveTextureARB(GL_TEXTURE2_ARB); -				glDisableClientState(GL_TEXTURE_COORD_ARRAY); -				glClientActiveTextureARB(GL_TEXTURE0_ARB); +				if (!(data_mask & MAP_BINORMAL)) +				{ +					glClientActiveTextureARB(GL_TEXTURE2_ARB); +					glDisableClientState(GL_TEXTURE_COORD_ARRAY); +					glClientActiveTextureARB(GL_TEXTURE0_ARB); +				}  			} -		} -		else if (data_mask & MAP_BINORMAL) -		{ -			glClientActiveTextureARB(GL_TEXTURE2_ARB); -			glEnableClientState(GL_TEXTURE_COORD_ARRAY); -			glClientActiveTextureARB(GL_TEXTURE0_ARB); -		} -	 -		if (sLastMask & MAP_WEIGHT4) -		{ -			if (sWeight4Loc < 0) +			else if (data_mask & MAP_BINORMAL)  			{ -				llerrs << "Weighting disabled but vertex buffer still bound!" << llendl; -			} - -			if (!(data_mask & MAP_WEIGHT4)) -			{ //disable 4-component skin weight			 -				glDisableVertexAttribArrayARB(sWeight4Loc); -			} -		} -		else if (data_mask & MAP_WEIGHT4) -		{ -			if (sWeight4Loc >= 0) -			{ //enable 4-component skin weight -				glEnableVertexAttribArrayARB(sWeight4Loc); +				glClientActiveTextureARB(GL_TEXTURE2_ARB); +				glEnableClientState(GL_TEXTURE_COORD_ARRAY); +				glClientActiveTextureARB(GL_TEXTURE0_ARB);  			}  		} -				 - +		  		sLastMask = data_mask;  	}  } @@ -296,6 +354,9 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)  //static  void LLVertexBuffer::drawArrays(U32 mode, const std::vector<LLVector3>& pos, const std::vector<LLVector3>& norm)  { +	llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL); +	gGL.syncMatrices(); +  	U32 count = pos.size();  	llassert_always(norm.size() >= pos.size());  	llassert_always(count > 0) ; @@ -304,12 +365,75 @@ void LLVertexBuffer::drawArrays(U32 mode, const std::vector<LLVector3>& pos, con  	setupClientArrays(MAP_VERTEX | MAP_NORMAL); -	glVertexPointer(3, GL_FLOAT, 0, pos[0].mV); -	glNormalPointer(GL_FLOAT, 0, norm[0].mV); +	LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; + +	if (shader) +	{ +		S32 loc = shader->getAttribLocation(LLVertexBuffer::TYPE_VERTEX); +		if (loc > -1) +		{ +			glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, 0, pos[0].mV); +		} +		loc = shader->getAttribLocation(LLVertexBuffer::TYPE_NORMAL); +		if (loc > -1) +		{ +			glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, 0, norm[0].mV); +		} +	} +	else +	{ +		glVertexPointer(3, GL_FLOAT, 0, pos[0].mV); +		glNormalPointer(GL_FLOAT, 0, norm[0].mV); +	}  	glDrawArrays(sGLMode[mode], 0, count);  } +//static +void LLVertexBuffer::drawElements(U32 mode, const LLVector4a* pos, const LLVector2* tc, S32 num_indices, const U16* indicesp) +{ +	llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL); + +	gGL.syncMatrices(); + +	U32 mask = LLVertexBuffer::MAP_VERTEX; +	if (tc) +	{ +		mask = mask | LLVertexBuffer::MAP_TEXCOORD0; +	} + +	unbind(); +	 +	setupClientArrays(mask); + +	LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; + +	if (shader) +	{ +		S32 loc = shader->getAttribLocation(LLVertexBuffer::TYPE_VERTEX); +		if (loc > -1) +		{ +			glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, 16, pos); + +			if (tc) +			{ +				loc = shader->getAttribLocation(LLVertexBuffer::TYPE_TEXCOORD0); +				if (loc > -1) +				{ +					glVertexAttribPointerARB(loc, 2, GL_FLOAT, GL_FALSE, 0, tc); +				} +			} +		} +	} +	else +	{ +		glTexCoordPointer(2, GL_FLOAT, 0, tc); +		glVertexPointer(3, GL_FLOAT, 16, pos); +	} + +	glDrawElements(sGLMode[mode], num_indices, GL_UNSIGNED_SHORT, indicesp); +} +  void LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_offset) const  {  	if (start >= (U32) mRequestedNumVerts || @@ -343,7 +467,10 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi  {  	validateRange(start, end, count, indices_offset); +	gGL.syncMatrices(); +  	llassert(mRequestedNumVerts >= 0); +	llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);  	if (mGLIndices != sGLRenderIndices)  	{ @@ -372,6 +499,10 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi  void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const  { +	llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL); + +	gGL.syncMatrices(); +  	llassert(mRequestedNumIndices >= 0);  	if (indices_offset >= (U32) mRequestedNumIndices ||  	    indices_offset + count > (U32) mRequestedNumIndices) @@ -404,6 +535,10 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const  void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const  { +	llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL); +	 +	gGL.syncMatrices(); +	  	llassert(mRequestedNumVerts >= 0);  	if (first >= (U32) mRequestedNumVerts ||  	    first + count > (U32) mRequestedNumVerts) @@ -1601,6 +1736,10 @@ bool LLVertexBuffer::getColorStrider(LLStrider<LLColor4U>& strider, S32 index, S  {  	return VertexBufferStrider<LLColor4U,TYPE_COLOR>::get(*this, strider, index, count, map_range);  } +bool LLVertexBuffer::getEmissiveStrider(LLStrider<U8>& strider, S32 index, S32 count, bool map_range) +{ +	return VertexBufferStrider<U8,TYPE_EMISSIVE>::get(*this, strider, index, count, map_range); +}  bool LLVertexBuffer::getWeightStrider(LLStrider<F32>& strider, S32 index, S32 count, bool map_range)  {  	return VertexBufferStrider<F32,TYPE_WEIGHT>::get(*this, strider, index, count, map_range); @@ -1625,6 +1764,34 @@ void LLVertexBuffer::setBuffer(U32 data_mask, S32 type)  	//set up pointers if the data mask is different ...  	BOOL setup = (sLastMask != data_mask); +	if (gDebugGL && data_mask != 0) +	{ +		LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; +		if (shader) +		{ +			U32 required_mask = 0; +			for (U32 i = 0; i < LLVertexBuffer::TYPE_MAX; ++i) +			{ +				if (shader->getAttribLocation(i) > -1) +				{ +					U32 required = 1 << i; +					if ((data_mask & required) == 0) +					{ +						llwarns << "Missing attribute: " << i << llendl; +					} + +					required_mask |= required; + +				} +			} + +			if ((data_mask & required_mask) != required_mask) +			{ +				llerrs << "Shader consumption mismatches data provision." << llendl; +			} +		} +	} +  	if (useVBOs())  	{  		if (mGLBuffer && (mGLBuffer != sGLRenderBuffer || !sVBOActive)) @@ -1819,66 +1986,223 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const  		llerrs << "LLVertexBuffer::setupVertexBuffer missing required components for supplied data mask." << llendl;  	} +	LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; + +	//assert that fixed function is allowed OR a shader is currently bound +	llassert(!LLGLSLShader::sNoFixedFunction || shader != NULL); +  	if (data_mask & MAP_NORMAL)  	{ -		glNormalPointer(GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_NORMAL], (void*)(base + mOffsets[TYPE_NORMAL])); +		S32 loc = -1; +		if (shader) +		{ +			loc = shader->getAttribLocation(TYPE_NORMAL); +		} + +		if (loc >= 0) +		{ +			glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_NORMAL], (void*)(base + mOffsets[TYPE_NORMAL])); +		} +		else if (!shader) +		{ +			glNormalPointer(GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_NORMAL], (void*)(base + mOffsets[TYPE_NORMAL])); +		}  	}  	if (data_mask & MAP_TEXCOORD3)  	{ -		glClientActiveTextureARB(GL_TEXTURE3_ARB); -		glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], (void*)(base + mOffsets[TYPE_TEXCOORD3])); -		glClientActiveTextureARB(GL_TEXTURE0_ARB); +		S32 loc = -1; +		if (shader) +		{ +			loc = shader->getAttribLocation(TYPE_TEXCOORD3); +		} + +		if (loc >= 0) +		{ +			glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], (void*)(base + mOffsets[TYPE_TEXCOORD3])); +		} +		else if (!shader) +		{ +			glClientActiveTextureARB(GL_TEXTURE3_ARB); +			glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], (void*)(base + mOffsets[TYPE_TEXCOORD3])); +			glClientActiveTextureARB(GL_TEXTURE0_ARB); +		}  	}  	if (data_mask & MAP_TEXCOORD2)  	{ -		glClientActiveTextureARB(GL_TEXTURE2_ARB); -		glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], (void*)(base + mOffsets[TYPE_TEXCOORD2])); -		glClientActiveTextureARB(GL_TEXTURE0_ARB); +		S32 loc = -1; +		if (shader) +		{ +			loc = shader->getAttribLocation(TYPE_TEXCOORD2); +		} + +		if (loc >= 0) +		{ +			glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], (void*)(base + mOffsets[TYPE_TEXCOORD2])); +		} +		else if (!shader) +		{ +			glClientActiveTextureARB(GL_TEXTURE2_ARB); +			glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], (void*)(base + mOffsets[TYPE_TEXCOORD2])); +			glClientActiveTextureARB(GL_TEXTURE0_ARB); +		}  	}  	if (data_mask & MAP_TEXCOORD1)  	{ -		glClientActiveTextureARB(GL_TEXTURE1_ARB); -		glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1])); -		glClientActiveTextureARB(GL_TEXTURE0_ARB); +		S32 loc = -1; +		if (shader) +		{ +			loc = shader->getAttribLocation(TYPE_TEXCOORD1); +		} + +		if (loc >= 0) +		{ +			glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1])); +		} +		else if (!shader) +		{ +			glClientActiveTextureARB(GL_TEXTURE1_ARB); +			glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1])); +			glClientActiveTextureARB(GL_TEXTURE0_ARB); +		}  	}  	if (data_mask & MAP_BINORMAL)  	{ -		glClientActiveTextureARB(GL_TEXTURE2_ARB); -		glTexCoordPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], (void*)(base + mOffsets[TYPE_BINORMAL])); -		glClientActiveTextureARB(GL_TEXTURE0_ARB); +		S32 loc = -1; +		if (shader) +		{ +			loc = shader->getAttribLocation(TYPE_BINORMAL); +		} + +		if (loc >= 0) +		{ +			glVertexAttribPointerARB(loc, 3,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], (void*)(base + mOffsets[TYPE_BINORMAL])); +		} +		else if (!shader) +		{ +			glClientActiveTextureARB(GL_TEXTURE2_ARB); +			glTexCoordPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], (void*)(base + mOffsets[TYPE_BINORMAL])); +			glClientActiveTextureARB(GL_TEXTURE0_ARB); +		}  	}  	if (data_mask & MAP_TEXCOORD0)  	{ -		glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], (void*)(base + mOffsets[TYPE_TEXCOORD0])); +		S32 loc = -1; +		if (shader) +		{ +			loc = shader->getAttribLocation(TYPE_TEXCOORD0); +		} + +		if (loc >= 0) +		{ +			glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], (void*)(base + mOffsets[TYPE_TEXCOORD0])); +		} +		else if (!shader) +		{ +			glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], (void*)(base + mOffsets[TYPE_TEXCOORD0])); +		}  	}  	if (data_mask & MAP_COLOR)  	{ -		glColorPointer(4, GL_UNSIGNED_BYTE, LLVertexBuffer::sTypeSize[TYPE_COLOR], (void*)(base + mOffsets[TYPE_COLOR])); +		S32 loc = -1; +		if (shader) +		{ +			loc = shader->getAttribLocation(TYPE_COLOR); +		} + +		if (loc >= 0) +		{ +			glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_COLOR], (void*)(base + mOffsets[TYPE_COLOR])); +		} +		else if (!shader) +		{ +			glColorPointer(4, GL_UNSIGNED_BYTE, LLVertexBuffer::sTypeSize[TYPE_COLOR], (void*)(base + mOffsets[TYPE_COLOR])); +		} +	} +	if (data_mask & MAP_EMISSIVE) +	{ +		S32 loc = -1; +		if (shader) +		{ +			loc = shader->getAttribLocation(TYPE_EMISSIVE); +		} + +		if (loc >= 0) +		{ +			glVertexAttribPointerARB(loc, 1, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], (void*)(base + mOffsets[TYPE_EMISSIVE])); +		}  	} -	  	if (data_mask & MAP_WEIGHT)  	{ -		glVertexAttribPointerARB(1, 1, GL_FLOAT, FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT], (void*)(base + mOffsets[TYPE_WEIGHT])); +		S32 loc = -1; +		if (shader) +		{ +			loc = shader->getAttribLocation(TYPE_WEIGHT); +		} + +		if (loc < 0) +		{ //legacy behavior, some shaders have weight hardcoded to location 1 +			loc = 1; +		} +		 +		glVertexAttribPointerARB(loc, 1, GL_FLOAT, FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT], (void*)(base + mOffsets[TYPE_WEIGHT])); +		  	} -	if (data_mask & MAP_WEIGHT4 && sWeight4Loc != -1) +	if (data_mask & MAP_WEIGHT4)  	{ -		glVertexAttribPointerARB(sWeight4Loc, 4, GL_FLOAT, FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT4], (void*)(base+mOffsets[TYPE_WEIGHT4])); +		if (shader) +		{ +			S32 loc = shader->getAttribLocation(TYPE_WEIGHT4); +			if (loc > -1) +			{ +				glVertexAttribPointerARB(loc, 4, GL_FLOAT, FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT4], (void*)(base+mOffsets[TYPE_WEIGHT4])); +			} +		}  	}  	if (data_mask & MAP_CLOTHWEIGHT)  	{ -		glVertexAttribPointerARB(4, 4, GL_FLOAT, TRUE,  LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], (void*)(base + mOffsets[TYPE_CLOTHWEIGHT])); +		S32 loc = -1; +		if (shader) +		{ +			loc = shader->getAttribLocation(TYPE_CLOTHWEIGHT); +		} + +		if (loc < 0) +		{ //legacy behavior, some shaders have weight hardcoded to location 4 +			loc = 4; +		} +		glVertexAttribPointerARB(loc, 4, GL_FLOAT, TRUE,  LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], (void*)(base + mOffsets[TYPE_CLOTHWEIGHT]));  	}  	if (data_mask & MAP_VERTEX)  	{ -		if (data_mask & MAP_TEXTURE_INDEX) +		S32 loc = -1; +		if (shader)  		{ -			glVertexPointer(4,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0)); +			loc = shader->getAttribLocation(TYPE_VERTEX);  		} -		else + +		if (loc >= 0)  		{ -			glVertexPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0)); +			if (data_mask & MAP_TEXTURE_INDEX) +			{ +				glVertexAttribPointerARB(loc, 4,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0)); +			} +			else +			{ +				glVertexAttribPointerARB(loc, 3,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0)); +			} +		} +		else if (!shader) +		{ +			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)); +			}  		}  	} diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index 578cec3885..7aa5928524 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -111,8 +111,6 @@ public:  	static LLVBOPool sStreamIBOPool;  	static LLVBOPool sDynamicIBOPool; -	static S32	sWeight4Loc; -  	static BOOL	sUseStreamDraw;  	static BOOL	sPreferStreamDraw; @@ -120,6 +118,7 @@ public:  	static void cleanupClass();  	static void setupClientArrays(U32 data_mask);  	static void drawArrays(U32 mode, const std::vector<LLVector3>& pos, const std::vector<LLVector3>& norm); +	static void drawElements(U32 mode, const LLVector4a* pos, const LLVector2* tc, S32 num_indices, const U16* indicesp);   	static void clientCopy(F64 max_time = 0.005); //copy data from client to GL  	static void unbind(); //unbind any bound vertex buffer @@ -133,6 +132,12 @@ public:  	static S32 calcOffsets(const U32& typemask, S32* offsets, S32 num_vertices);		 +	//WARNING -- when updating these enums you MUST  +	// 1 - update LLVertexBuffer::sTypeSize +	// 2 - add a strider accessor +	// 3 - modify LLVertexBuffer::setupVertexBuffer +	// 4 - modify LLVertexBuffer::setupClientArray +	// 5 - modify LLViewerShaderMgr::mReservedAttribs  	enum {  		TYPE_VERTEX,  		TYPE_NORMAL, @@ -141,6 +146,7 @@ public:  		TYPE_TEXCOORD2,  		TYPE_TEXCOORD3,  		TYPE_COLOR, +		TYPE_EMISSIVE,  		// These use VertexAttribPointer and should possibly be made generic  		TYPE_BINORMAL,  		TYPE_WEIGHT, @@ -160,6 +166,7 @@ public:  		MAP_TEXCOORD2 = (1<<TYPE_TEXCOORD2),  		MAP_TEXCOORD3 = (1<<TYPE_TEXCOORD3),  		MAP_COLOR = (1<<TYPE_COLOR), +		MAP_EMISSIVE = (1<<TYPE_EMISSIVE),  		// These use VertexAttribPointer and should possibly be made generic  		MAP_BINORMAL = (1<<TYPE_BINORMAL),  		MAP_WEIGHT = (1<<TYPE_WEIGHT), @@ -218,10 +225,12 @@ public:  	bool getNormalStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false);  	bool getBinormalStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false);  	bool getColorStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false); +	bool getEmissiveStrider(LLStrider<U8>& strider, S32 index=0, S32 count = -1, bool map_range = false);  	bool getWeightStrider(LLStrider<F32>& strider, S32 index=0, S32 count = -1, bool map_range = false);  	bool getWeight4Strider(LLStrider<LLVector4>& strider, S32 index=0, S32 count = -1, bool map_range = false);  	bool getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index=0, S32 count = -1, bool map_range = false); +  	BOOL isEmpty() const					{ return mEmpty; }  	BOOL isLocked() const					{ return mVertexLocked || mIndexLocked; }  	S32 getNumVerts() const					{ return mNumVerts; }  | 
