diff options
author | Dave Parks <davep@lindenlab.com> | 2011-09-13 16:11:22 -0500 |
---|---|---|
committer | Dave Parks <davep@lindenlab.com> | 2011-09-13 16:11:22 -0500 |
commit | c0ca2c62fd6b9a90542907ce46bf1fe0ab379e13 (patch) | |
tree | 69bed5c3a72357e183384917b5495c2990e1ac13 /indra/llrender | |
parent | 19371a9abed3198f9f6083c3b2483e65778e944a (diff) | |
parent | 38c19f4e55c0f6a104de87dfb57313a6c529b4d6 (diff) |
merge
Diffstat (limited to 'indra/llrender')
-rw-r--r-- | indra/llrender/llgl.cpp | 81 | ||||
-rw-r--r-- | indra/llrender/llgl.h | 12 | ||||
-rw-r--r-- | indra/llrender/llglslshader.cpp | 8 | ||||
-rw-r--r-- | indra/llrender/llrender.cpp | 75 | ||||
-rw-r--r-- | indra/llrender/llrender.h | 6 | ||||
-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 | 464 | ||||
-rw-r--r-- | indra/llrender/llvertexbuffer.h | 13 |
10 files changed, 512 insertions, 267 deletions
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index 4e3cfb9c8a..1a2fe0ea0e 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 @@ -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: 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..61648e527d 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" @@ -116,10 +117,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 +389,7 @@ void LLGLSLShader::bind() gGL.flush(); if (gGLManager.mHasShaderObjects) { + LLVertexBuffer::unbind(); glUseProgramObjectARB(mProgramObject); sCurBoundShader = mProgramObject; sCurBoundShaderPtr = this; @@ -411,6 +415,7 @@ void LLGLSLShader::unbind() stop_glerror(); } } + LLVertexBuffer::unbind(); glUseProgramObjectARB(0); sCurBoundShader = 0; sCurBoundShaderPtr = NULL; @@ -420,6 +425,7 @@ void LLGLSLShader::unbind() void LLGLSLShader::bindNoShader(void) { + LLVertexBuffer::unbind(); glUseProgramObjectARB(0); sCurBoundShader = 0; sCurBoundShaderPtr = NULL; @@ -930,7 +936,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/llrender.cpp b/indra/llrender/llrender.cpp index edcc47aa14..426419f912 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -1586,6 +1586,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..c202aa4b73 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -351,6 +351,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); 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..bb8f067e8d 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -63,7 +63,6 @@ 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; @@ -131,6 +130,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, @@ -157,36 +157,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 +245,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 +283,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 +355,8 @@ 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); + U32 count = pos.size(); llassert_always(norm.size() >= pos.size()); llassert_always(count > 0) ; @@ -304,12 +365,73 @@ 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); + + 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 || @@ -344,6 +466,7 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi validateRange(start, end, count, indices_offset); llassert(mRequestedNumVerts >= 0); + llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL); if (mGLIndices != sGLRenderIndices) { @@ -372,6 +495,8 @@ 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); + llassert(mRequestedNumIndices >= 0); if (indices_offset >= (U32) mRequestedNumIndices || indices_offset + count > (U32) mRequestedNumIndices) @@ -404,6 +529,8 @@ 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); + llassert(mRequestedNumVerts >= 0); if (first >= (U32) mRequestedNumVerts || first + count > (U32) mRequestedNumVerts) @@ -1601,6 +1728,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 +1756,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 +1978,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; } |