diff options
Diffstat (limited to 'indra/llrender')
-rw-r--r-- | indra/llrender/llfontgl.cpp | 1 | ||||
-rw-r--r-- | indra/llrender/llgl.cpp | 69 | ||||
-rw-r--r-- | indra/llrender/llgl.h | 1 | ||||
-rw-r--r-- | indra/llrender/llglheaders.h | 22 | ||||
-rw-r--r-- | indra/llrender/llglslshader.cpp | 14 | ||||
-rw-r--r-- | indra/llrender/llglslshader.h | 3 | ||||
-rw-r--r-- | indra/llrender/llimagegl.cpp | 62 | ||||
-rw-r--r-- | indra/llrender/llimagegl.h | 2 | ||||
-rw-r--r-- | indra/llrender/llrender.cpp | 42 | ||||
-rw-r--r-- | indra/llrender/llrender.h | 11 | ||||
-rw-r--r-- | indra/llrender/llrendertarget.cpp | 11 | ||||
-rw-r--r-- | indra/llrender/llshadermgr.cpp | 70 | ||||
-rw-r--r-- | indra/llrender/llvertexbuffer.cpp | 66 | ||||
-rw-r--r-- | indra/llrender/llvertexbuffer.h | 7 |
14 files changed, 298 insertions, 83 deletions
diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index d9e1976341..82db922368 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -247,7 +247,6 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons } } - const LLFontGlyphInfo* next_glyph = NULL; for (i = begin_offset; i < begin_offset + length; i++) diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index a3f7a946ec..7ff68fe34b 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -185,6 +185,9 @@ PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glRenderbufferStorageMultisampleEXT = // GL_EXT_framebuffer_blit PFNGLBLITFRAMEBUFFEREXTPROC glBlitFramebufferEXT = NULL; +// GL_EXT_blend_func_separate +PFNGLBLENDFUNCSEPARATEEXTPROC glBlendFuncSeparateEXT = NULL; + // GL_ARB_draw_buffers PFNGLDRAWBUFFERSARBPROC glDrawBuffersARB = NULL; @@ -324,6 +327,7 @@ LLGLManager::LLGLManager() : mHasCompressedTextures(FALSE), mHasFramebufferObject(FALSE), mHasFramebufferMultisample(FALSE), + mHasBlendFuncSeparate(FALSE), mHasVertexBufferObject(FALSE), mHasPBuffer(FALSE), @@ -633,6 +637,11 @@ void LLGLManager::initExtensions() #else mHasDrawBuffers = FALSE; # endif +# if GL_EXT_blend_func_separate + mHasBlendFuncSeparate = TRUE; +#else + mHasBlendFuncSeparate = FALSE; +# endif mHasMipMapGeneration = FALSE; mHasSeparateSpecularColor = FALSE; mHasAnisotropic = FALSE; @@ -659,6 +668,7 @@ void LLGLManager::initExtensions() && ExtensionExists("GL_EXT_packed_depth_stencil", gGLHExts.mSysExts); mHasFramebufferMultisample = mHasFramebufferObject && ExtensionExists("GL_EXT_framebuffer_multisample", gGLHExts.mSysExts); mHasDrawBuffers = ExtensionExists("GL_ARB_draw_buffers", gGLHExts.mSysExts); + mHasBlendFuncSeparate = ExtensionExists("GL_EXT_blend_func_separate", gGLHExts.mSysExts); mHasTextureRectangle = ExtensionExists("GL_ARB_texture_rectangle", gGLHExts.mSysExts); #if !LL_DARWIN mHasPointParameters = !mIsATI && ExtensionExists("GL_ARB_point_parameters", gGLHExts.mSysExts); @@ -682,6 +692,7 @@ void LLGLManager::initExtensions() mHasFramebufferObject = FALSE; mHasFramebufferMultisample = FALSE; mHasDrawBuffers = FALSE; + mHasBlendFuncSeparate = FALSE; mHasMipMapGeneration = FALSE; mHasSeparateSpecularColor = FALSE; mHasAnisotropic = FALSE; @@ -706,6 +717,7 @@ void LLGLManager::initExtensions() mHasShaderObjects = FALSE; mHasVertexShader = FALSE; mHasFragmentShader = FALSE; + mHasBlendFuncSeparate = FALSE; LL_WARNS("RenderInit") << "GL extension support forced to SIMPLE level via LL_GL_BASICEXT" << LL_ENDL; } if (getenv("LL_GL_BLACKLIST")) /* Flawfinder: ignore */ @@ -734,7 +746,8 @@ void LLGLManager::initExtensions() if (strchr(blacklist,'r')) mHasDrawBuffers = FALSE;//S if (strchr(blacklist,'s')) mHasFramebufferMultisample = FALSE; if (strchr(blacklist,'t')) mHasTextureRectangle = FALSE; - + if (strchr(blacklist,'u')) mHasBlendFuncSeparate = FALSE;//S + } #endif // LL_LINUX || LL_SOLARIS @@ -782,6 +795,14 @@ void LLGLManager::initExtensions() { LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_fragment_shader" << LL_ENDL; } + if (!mHasBlendFuncSeparate) + { + LL_INFOS("RenderInit") << "Couldn't initialize GL_EXT_blend_func_separate" << LL_ENDL; + } + if (!mHasDrawBuffers) + { + LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_draw_buffers" << LL_ENDL; + } // Disable certain things due to known bugs if (mIsIntel && mHasMipMapGeneration) @@ -852,6 +873,10 @@ void LLGLManager::initExtensions() { glDrawBuffersARB = (PFNGLDRAWBUFFERSARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDrawBuffersARB"); } + if (mHasBlendFuncSeparate) + { + glBlendFuncSeparateEXT = (PFNGLBLENDFUNCSEPARATEEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glBlendFuncSeparateEXT"); + } #if (!LL_LINUX && !LL_SOLARIS) || LL_LINUX_NV_GL_HEADERS // This is expected to be a static symbol on Linux GL implementations, except if we use the nvidia headers - bah glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawRangeElements"); @@ -1014,24 +1039,9 @@ void flush_glerror() glGetError(); } -void assert_glerror() +void do_assert_glerror() { - if (!gGLActive) - { - //llwarns << "GL used while not active!" << llendl; - - if (gDebugSession) - { - //ll_fail("GL used while not active"); - } - } - - if (gNoRender || !gDebugGL) - { - return; - } - - if (!gGLManager.mInited) + if (LL_UNLIKELY(!gGLManager.mInited)) { LL_ERRS("RenderInit") << "GL not initialized" << LL_ENDL; } @@ -1039,10 +1049,9 @@ void assert_glerror() GLenum error; error = glGetError(); BOOL quit = FALSE; - while (error) + while (LL_UNLIKELY(error)) { quit = TRUE; -#ifndef LL_LINUX // *FIX: ! This should be an error for linux as well. GLubyte const * gl_error_msg = gluErrorString(error); if (NULL != gl_error_msg) { @@ -1066,7 +1075,6 @@ void assert_glerror() } } error = glGetError(); -#endif } if (quit) @@ -1082,6 +1090,25 @@ void assert_glerror() } } +void assert_glerror() +{ + if (!gGLActive) + { + //llwarns << "GL used while not active!" << llendl; + + if (gDebugSession) + { + //ll_fail("GL used while not active"); + } + } + + if (!gNoRender && gDebugGL) + { + do_assert_glerror(); + } +} + + void clear_glerror() { // Create or update texture to be used with this data diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h index 91421f3c95..0c2da7dd08 100644 --- a/indra/llrender/llgl.h +++ b/indra/llrender/llgl.h @@ -87,6 +87,7 @@ public: BOOL mHasCompressedTextures; BOOL mHasFramebufferObject; BOOL mHasFramebufferMultisample; + BOOL mHasBlendFuncSeparate; // ARB Extensions BOOL mHasVertexBufferObject; diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h index f33ae7d8f0..f6d35bc766 100644 --- a/indra/llrender/llglheaders.h +++ b/indra/llrender/llglheaders.h @@ -216,6 +216,9 @@ extern PFNGLGETCOMPRESSEDTEXIMAGEARBPROC glGetCompressedTexImageARB; extern PFNGLCOLORTABLEEXTPROC glColorTableEXT; +//GL_EXT_blend_func_separate +extern PFNGLBLENDFUNCSEPARATEEXTPROC glBlendFuncSeparateEXT; + //GL_EXT_framebuffer_object extern PFNGLISRENDERBUFFEREXTPROC glIsRenderbufferEXT; extern PFNGLBINDRENDERBUFFEREXTPROC glBindRenderbufferEXT; @@ -249,7 +252,10 @@ extern PFNGLGENERATEMIPMAPEXTPROC glGenerateMipmapEXT; # include "GL/glh_extensions.h" # undef __APPLE__ -#elif LL_LINUX +#elif LL_LINUX +//---------------------------------------------------------------------------- +// LL_LINUX + //---------------------------------------------------------------------------- // Linux, MESA headers, but not necessarily assuming MESA runtime. // quotes so we get libraries/.../GL/ version @@ -285,6 +291,7 @@ extern PFNGLGENERATEMIPMAPEXTPROC glGenerateMipmapEXT; # define LL_LINUX_NV_GL_HEADERS 0 #endif // LL_LINUX && defined(WINGDIAPI) + #if LL_LINUX_NV_GL_HEADERS // Missing functions when using nvidia headers: extern PFNGLACTIVETEXTUREARBPROC glActiveTextureARB; @@ -445,6 +452,9 @@ extern PFNGLGETATTRIBLOCATIONARBPROC glGetAttribLocationARB; extern PFNGLCOMPRESSEDTEXIMAGE2DARBPROC glCompressedTexImage2DARB; extern PFNGLGETCOMPRESSEDTEXIMAGEARBPROC glGetCompressedTexImageARB; +//GL_EXT_blend_func_separate +extern PFNGLBLENDFUNCSEPARATEEXTPROC glBlendFuncSeparateEXT; + //GL_EXT_framebuffer_object extern PFNGLISRENDERBUFFEREXTPROC glIsRenderbufferEXT; extern PFNGLBINDRENDERBUFFEREXTPROC glBindRenderbufferEXT; @@ -473,7 +483,10 @@ extern PFNGLBLITFRAMEBUFFEREXTPROC glBlitFramebufferEXT; //GL_ARB_draw_buffers extern PFNGLDRAWBUFFERSARBPROC glDrawBuffersARB; + #elif LL_WINDOWS +//---------------------------------------------------------------------------- +// LL_WINDOWS // windows gl headers depend on things like APIENTRY, so include windows. #define WIN32_LEAN_AND_MEAN @@ -641,6 +654,9 @@ extern PFNGLBINDATTRIBLOCATIONARBPROC glBindAttribLocationARB; extern PFNGLGETACTIVEATTRIBARBPROC glGetActiveAttribARB; extern PFNGLGETATTRIBLOCATIONARBPROC glGetAttribLocationARB; +//GL_EXT_blend_func_separate +extern PFNGLBLENDFUNCSEPARATEEXTPROC glBlendFuncSeparateEXT; + //GL_EXT_framebuffer_object extern PFNGLISRENDERBUFFEREXTPROC glIsRenderbufferEXT; extern PFNGLBINDRENDERBUFFEREXTPROC glBindRenderbufferEXT; @@ -669,6 +685,7 @@ extern PFNGLBLITFRAMEBUFFEREXTPROC glBlitFramebufferEXT; //GL_ARB_draw_buffers extern PFNGLDRAWBUFFERSARBPROC glDrawBuffersARB; + #elif LL_DARWIN //---------------------------------------------------------------------------- // LL_DARWIN @@ -685,6 +702,9 @@ extern PFNGLDRAWBUFFERSARBPROC glDrawBuffersARB; // Note that they also must not be called on 10.3.9. This should be taken care of by a runtime check for the existence of the GL extension. #include <AvailabilityMacros.h> +//GL_EXT_blend_func_separate +extern void glBlendFuncSeparateEXT(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER; + // GL_EXT_framebuffer_object extern GLboolean glIsRenderbufferEXT(GLuint renderbuffer) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER; extern void glBindRenderbufferEXT(GLenum target, GLuint renderbuffer) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER; diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index ca92cb6580..949057df04 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -61,7 +61,7 @@ BOOL shouldChange(const LLVector4& v1, const LLVector4& v2) LLShaderFeatures::LLShaderFeatures() : calculatesLighting(false), isShiny(false), isFullbright(false), hasWaterFog(false), -hasTransport(false), hasSkinning(false), hasAtmospherics(false), isSpecular(false), +hasTransport(false), hasSkinning(false), hasObjectSkinning(false), hasAtmospherics(false), isSpecular(false), hasGamma(false), hasLighting(false), calculatesAtmospherics(false) { } @@ -717,6 +717,18 @@ GLint LLGLSLShader::getUniformLocation(const string& uniform) return -1; } +GLint LLGLSLShader::getAttribLocation(U32 attrib) +{ + if (attrib < mAttribute.size()) + { + return mAttribute[attrib]; + } + else + { + return -1; + } +} + void LLGLSLShader::uniform1i(const string& uniform, GLint v) { GLint location = getUniformLocation(uniform); diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h index 166d4af04c..dc493ba162 100644 --- a/indra/llrender/llglslshader.h +++ b/indra/llrender/llglslshader.h @@ -48,6 +48,7 @@ public: bool hasWaterFog; // implies no gamma bool hasTransport; // implies no lighting (it's possible to have neither though) bool hasSkinning; + bool hasObjectSkinning; bool hasAtmospherics; bool hasGamma; @@ -109,7 +110,7 @@ public: void vertexAttrib4fv(U32 index, GLfloat* v); GLint getUniformLocation(const std::string& uniform); - + GLint getAttribLocation(U32 attrib); GLint mapUniformTextureChannel(GLint location, GLenum type); diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index ff47c57c70..00f0fd5b9a 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -1645,7 +1645,7 @@ void LLImageGL::calcAlphaChannelOffsetAndStride() } } -void LLImageGL::analyzeAlpha(const void* data_in, S32 w, S32 h) +void LLImageGL::analyzeAlpha(const void* data_in, U32 w, U32 h) { if(!mNeedsAlphaAndPickMask) { @@ -1653,24 +1653,64 @@ void LLImageGL::analyzeAlpha(const void* data_in, S32 w, S32 h) } U32 length = w * h; - const GLubyte* current = ((const GLubyte*) data_in) + mAlphaOffset ; - S32 sample[16]; - memset(sample, 0, sizeof(S32)*16); - - for (U32 i = 0; i < length; i++) + U32 sample[16]; + memset(sample, 0, sizeof(U32)*16); + + // generate histogram of quantized alpha. + // also add-in the histogram of a 2x2 box-sampled version. The idea is + // this will mid-skew the data (and thus increase the chances of not + // being used as a mask) from high-frequency alpha maps which + // suffer the worst from aliasing when used as alpha masks. + if (w >= 2 && h >= 2) + { + llassert(w%2 == 0); + llassert(h%2 == 0); + const GLubyte* rowstart = ((const GLubyte*) data_in) + mAlphaOffset; + for (U32 y = 0; y < h; y+=2) + { + const GLubyte* current = rowstart; + for (U32 x = 0; x < w; x+=2) + { + U32 s1 = current[0]; + U32 s2 = current[w * mAlphaStride]; + current += mAlphaStride; + U32 s3 = current[0]; + U32 s4 = current[w * mAlphaStride]; + current += mAlphaStride; + + ++sample[s1/16]; + ++sample[s2/16]; + ++sample[s3/16]; + ++sample[s4/16]; + + sample[(s1+s2+s3+s4)/(16 * 4)] += 4; + } + + rowstart += 2 * w * mAlphaStride; + } + length += length; + } + else { - ++sample[*current/16]; - current += mAlphaStride ; + const GLubyte* current = ((const GLubyte*) data_in) + mAlphaOffset; + for (U32 i = 0; i < length; i++) + { + ++sample[*current/16]; + current += mAlphaStride; + } } + + // if more than 1/16th of alpha samples are mid-range, this + // shouldn't be treated as a 1-bit mask - U32 total = 0; + U32 midrangetotal = 0; for (U32 i = 4; i < 11; i++) { - total += sample[i]; + midrangetotal += sample[i]; } - if (total > length/16) + if (midrangetotal > length/16) { mIsMask = FALSE; } diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index 41239d24c8..03939888a5 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -91,7 +91,7 @@ public: protected: virtual ~LLImageGL(); - void analyzeAlpha(const void* data_in, S32 w, S32 h); + void analyzeAlpha(const void* data_in, U32 w, U32 h); void calcAlphaChannelOffsetAndStride(); public: diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index c3540a717c..43662fbb5c 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -778,8 +778,11 @@ LLRender::LLRender() mCurrAlphaFunc = CF_DEFAULT; mCurrAlphaFuncVal = 0.01f; - mCurrBlendSFactor = BF_UNDEF; - mCurrBlendDFactor = BF_UNDEF; + + mCurrBlendColorSFactor = BF_UNDEF; + mCurrBlendAlphaSFactor = BF_UNDEF; + mCurrBlendColorDFactor = BF_UNDEF; + mCurrBlendAlphaDFactor = BF_UNDEF; } LLRender::~LLRender() @@ -995,15 +998,44 @@ void LLRender::blendFunc(eBlendFactor sfactor, eBlendFactor dfactor) { llassert(sfactor < BF_UNDEF); llassert(dfactor < BF_UNDEF); - if (mCurrBlendSFactor != sfactor || mCurrBlendDFactor != dfactor) + if (mCurrBlendColorSFactor != sfactor || mCurrBlendColorDFactor != dfactor || + mCurrBlendAlphaSFactor != sfactor || mCurrBlendAlphaDFactor != dfactor) { - mCurrBlendSFactor = sfactor; - mCurrBlendDFactor = dfactor; + mCurrBlendColorSFactor = sfactor; + mCurrBlendAlphaSFactor = sfactor; + mCurrBlendColorDFactor = dfactor; + mCurrBlendAlphaDFactor = dfactor; flush(); glBlendFunc(sGLBlendFactor[sfactor], sGLBlendFactor[dfactor]); } } +void LLRender::blendFunc(eBlendFactor color_sfactor, eBlendFactor color_dfactor, + eBlendFactor alpha_sfactor, eBlendFactor alpha_dfactor) +{ + llassert(color_sfactor < BF_UNDEF); + llassert(color_dfactor < BF_UNDEF); + llassert(alpha_sfactor < BF_UNDEF); + llassert(alpha_dfactor < BF_UNDEF); + if (!gGLManager.mHasBlendFuncSeparate) + { + LL_WARNS_ONCE("render") << "no glBlendFuncSeparateEXT(), using color-only blend func" << llendl; + blendFunc(color_sfactor, color_dfactor); + return; + } + if (mCurrBlendColorSFactor != color_sfactor || mCurrBlendColorDFactor != color_dfactor || + mCurrBlendAlphaSFactor != alpha_sfactor || mCurrBlendAlphaDFactor != alpha_dfactor) + { + mCurrBlendColorSFactor = color_sfactor; + mCurrBlendAlphaSFactor = alpha_sfactor; + mCurrBlendColorDFactor = color_dfactor; + mCurrBlendAlphaDFactor = alpha_dfactor; + flush(); + glBlendFuncSeparateEXT(sGLBlendFactor[color_sfactor], sGLBlendFactor[color_dfactor], + sGLBlendFactor[alpha_sfactor], sGLBlendFactor[alpha_dfactor]); + } +} + LLTexUnit* LLRender::getTexUnit(U32 index) { if (index < mTexUnits.size()) diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index a90fbd4a5c..3cda4b5770 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -323,7 +323,11 @@ public: void setAlphaRejectSettings(eCompareFunc func, F32 value = 0.01f); + // applies blend func to both color and alpha void blendFunc(eBlendFactor sfactor, eBlendFactor dfactor); + // applies separate blend functions to color and alpha + void blendFunc(eBlendFactor color_sfactor, eBlendFactor color_dfactor, + eBlendFactor alpha_sfactor, eBlendFactor alpha_dfactor); LLTexUnit* getTexUnit(U32 index); @@ -362,9 +366,10 @@ private: std::vector<LLTexUnit*> mTexUnits; LLTexUnit* mDummyTexUnit; - eBlendFactor mCurrBlendSFactor; - eBlendFactor mCurrBlendDFactor; - + eBlendFactor mCurrBlendColorSFactor; + eBlendFactor mCurrBlendColorDFactor; + eBlendFactor mCurrBlendAlphaSFactor; + eBlendFactor mCurrBlendAlphaDFactor; F32 mMaxAnisotropy; std::list<LLVector3> mUIOffset; diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp index d9520b3bf6..3f2558f1f5 100644 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -390,8 +390,6 @@ void LLRenderTarget::flush(BOOL fetch_depth) } else { -#if !LL_DARWIN - stop_glerror(); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); @@ -435,7 +433,6 @@ void LLRenderTarget::flush(BOOL fetch_depth) } } } -#endif glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); } @@ -444,7 +441,6 @@ void LLRenderTarget::flush(BOOL fetch_depth) void LLRenderTarget::copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0, S32 srcX1, S32 srcY1, S32 dstX0, S32 dstY0, S32 dstX1, S32 dstY1, U32 mask, U32 filter) { -#if !LL_DARWIN gGL.flush(); if (!source.mFBO || !mFBO) { @@ -483,14 +479,12 @@ void LLRenderTarget::copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0, stop_glerror(); } } -#endif } //static void LLRenderTarget::copyContentsToFramebuffer(LLRenderTarget& source, S32 srcX0, S32 srcY0, S32 srcX1, S32 srcY1, S32 dstX0, S32 dstY0, S32 dstX1, S32 dstY1, U32 mask, U32 filter) { -#if !LL_DARWIN if (!source.mFBO) { llerrs << "Cannot copy framebuffer contents for non FBO render targets." << llendl; @@ -507,7 +501,6 @@ void LLRenderTarget::copyContentsToFramebuffer(LLRenderTarget& source, S32 srcX0 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); stop_glerror(); } -#endif } BOOL LLRenderTarget::isComplete() const @@ -652,7 +645,6 @@ void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth void LLMultisampleBuffer::addColorAttachment(U32 color_fmt) { -#if !LL_DARWIN if (color_fmt == 0) { return; @@ -693,12 +685,10 @@ void LLMultisampleBuffer::addColorAttachment(U32 color_fmt) } mTex.push_back(tex); -#endif } void LLMultisampleBuffer::allocateDepth() { -#if !LL_DARWIN glGenRenderbuffersEXT(1, (GLuint* ) &mDepth); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, mDepth); if (mStencil) @@ -709,6 +699,5 @@ void LLMultisampleBuffer::allocateDepth() { glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, mSamples, GL_DEPTH_COMPONENT16_ARB, mResX, mResY); } -#endif } diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 1286e91e49..0f54ebeb69 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -152,6 +152,14 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader) return FALSE; } } + + if (features->hasObjectSkinning) + { + if (!shader->attachObject("avatar/objectSkinV.glsl")) + { + return FALSE; + } + } /////////////////////////////////////// // Attach Fragment Shader Features Next @@ -313,11 +321,14 @@ void LLShaderMgr::dumpObjectLog(GLhandleARB ret, BOOL warns) GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type) { - GLenum error; - error = glGetError(); - if (error != GL_NO_ERROR) + GLenum error = GL_NO_ERROR; + if (gDebugGL) { - LL_WARNS("ShaderLoading") << "GL ERROR entering loadShaderFile(): " << error << LL_ENDL; + error = glGetError(); + if (error != GL_NO_ERROR) + { + LL_WARNS("ShaderLoading") << "GL ERROR entering loadShaderFile(): " << error << LL_ENDL; + } } LL_DEBUGS("ShaderLoading") << "Loading shader file: " << filename << " class " << shader_level << LL_ENDL; @@ -372,31 +383,39 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade //create shader object GLhandleARB ret = glCreateShaderObjectARB(type); - error = glGetError(); - if (error != GL_NO_ERROR) + if (gDebugGL) { - LL_WARNS("ShaderLoading") << "GL ERROR in glCreateShaderObjectARB: " << error << LL_ENDL; + error = glGetError(); + if (error != GL_NO_ERROR) + { + LL_WARNS("ShaderLoading") << "GL ERROR in glCreateShaderObjectARB: " << error << LL_ENDL; + } } - else + + //load source + glShaderSourceARB(ret, count, (const GLcharARB**) text, NULL); + + if (gDebugGL) { - //load source - glShaderSourceARB(ret, count, (const GLcharARB**) text, NULL); error = glGetError(); if (error != GL_NO_ERROR) { LL_WARNS("ShaderLoading") << "GL ERROR in glShaderSourceARB: " << error << LL_ENDL; } - else + } + + //compile source + glCompileShaderARB(ret); + + if (gDebugGL) + { + error = glGetError(); + if (error != GL_NO_ERROR) { - //compile source - glCompileShaderARB(ret); - error = glGetError(); - if (error != GL_NO_ERROR) - { - LL_WARNS("ShaderLoading") << "GL ERROR in glCompileShaderARB: " << error << LL_ENDL; - } + LL_WARNS("ShaderLoading") << "GL ERROR in glCompileShaderARB: " << error << LL_ENDL; } } + //free memory for (GLuint i = 0; i < count; i++) { @@ -407,13 +426,16 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade //check for errors GLint success = GL_TRUE; glGetObjectParameterivARB(ret, GL_OBJECT_COMPILE_STATUS_ARB, &success); - error = glGetError(); - if (error != GL_NO_ERROR || success == GL_FALSE) + if (gDebugGL || success == GL_FALSE) { - //an error occured, print log - LL_WARNS("ShaderLoading") << "GLSL Compilation Error: (" << error << ") in " << filename << LL_ENDL; - dumpObjectLog(ret); - ret = 0; + error = glGetError(); + if (error != GL_NO_ERROR || success == GL_FALSE) + { + //an error occured, print log + LL_WARNS("ShaderLoading") << "GLSL Compilation Error: (" << error << ") in " << filename << LL_ENDL; + dumpObjectLog(ret); + ret = 0; + } } } else diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index bf5eda21eb..7fa47cd171 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -61,6 +61,8 @@ BOOL LLVertexBuffer::sVBOActive = FALSE; BOOL LLVertexBuffer::sIBOActive = FALSE; U32 LLVertexBuffer::sAllocatedBytes = 0; BOOL LLVertexBuffer::sMapped = FALSE; +BOOL LLVertexBuffer::sUseStreamDraw = TRUE; +S32 LLVertexBuffer::sWeight4Loc = -1; std::vector<U32> LLVertexBuffer::sDeleteList; @@ -75,6 +77,7 @@ S32 LLVertexBuffer::sTypeOffsets[LLVertexBuffer::TYPE_MAX] = sizeof(LLColor4U), // TYPE_COLOR, sizeof(LLVector3), // TYPE_BINORMAL, sizeof(F32), // TYPE_WEIGHT, + sizeof(LLVector4), // TYPE_WEIGHT4, sizeof(LLVector4), // TYPE_CLOTHWEIGHT, }; @@ -209,6 +212,27 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask) glClientActiveTextureARB(GL_TEXTURE0_ARB); } + if (sLastMask & MAP_WEIGHT4) + { + if (sWeight4Loc < 0) + { + 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); + } + } + + sLastMask = data_mask; } } @@ -247,9 +271,22 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi return; } + U16* idx = ((U16*) getIndicesPointer())+indices_offset; + + if (gDebugGL && !useVBOs()) + { + for (U32 i = 0; i < count; ++i) + { + if (idx[i] < start || idx[i] > end) + { + llerrs << "Index out of range: " << idx[i] << " not in [" << start << ", " << end << "]" << llendl; + } + } + } + stop_glerror(); glDrawRangeElements(sGLMode[mode], start, end, count, GL_UNSIGNED_SHORT, - ((U16*) getIndicesPointer()) + indices_offset); + idx); stop_glerror(); } @@ -381,6 +418,11 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) : { mUsage = 0 ; } + + if (mUsage == GL_STREAM_DRAW_ARB && !sUseStreamDraw) + { + mUsage = 0; + } S32 stride = calcStride(typemask, mOffsets); @@ -579,7 +621,7 @@ void LLVertexBuffer::destroyGLBuffer() } mGLBuffer = 0; - unbind(); + //unbind(); } void LLVertexBuffer::destroyGLIndices() @@ -606,7 +648,7 @@ void LLVertexBuffer::destroyGLIndices() } mGLIndices = 0; - unbind(); + //unbind(); } void LLVertexBuffer::updateNumVerts(S32 nverts) @@ -668,6 +710,12 @@ void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create) { LLMemType mt2(LLMemType::MTYPE_VERTEX_ALLOCATE_BUFFER); + if (nverts < 0 || nindices < 0 || + nverts > 65536) + { + llerrs << "Bad vertex buffer allocation: " << nverts << " : " << nindices << llendl; + } + updateNumVerts(nverts); updateNumIndices(nindices); @@ -1003,6 +1051,12 @@ bool LLVertexBuffer::getWeightStrider(LLStrider<F32>& strider, S32 index) { return VertexBufferStrider<F32,TYPE_WEIGHT>::get(*this, strider, index); } + +bool LLVertexBuffer::getWeight4Strider(LLStrider<LLVector4>& strider, S32 index) +{ + return VertexBufferStrider<LLVector4,TYPE_WEIGHT4>::get(*this, strider, index); +} + bool LLVertexBuffer::getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index) { return VertexBufferStrider<LLVector4,TYPE_CLOTHWEIGHT>::get(*this, strider, index); @@ -1272,6 +1326,12 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const { glVertexAttribPointerARB(1, 1, GL_FLOAT, FALSE, stride, (void*)(base + mOffsets[TYPE_WEIGHT])); } + + if (data_mask & MAP_WEIGHT4 && sWeight4Loc != -1) + { + glVertexAttribPointerARB(sWeight4Loc, 4, GL_FLOAT, FALSE, stride, (void*)(base+mOffsets[TYPE_WEIGHT4])); + } + if (data_mask & MAP_CLOTHWEIGHT) { glVertexAttribPointerARB(4, 4, GL_FLOAT, TRUE, stride, (void*)(base + mOffsets[TYPE_CLOTHWEIGHT])); diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index b785a22976..225237215c 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -83,6 +83,10 @@ public: static LLVBOPool sDynamicVBOPool; static LLVBOPool sStreamIBOPool; static LLVBOPool sDynamicIBOPool; + + static S32 sWeight4Loc; + + static BOOL sUseStreamDraw; static void initClass(bool use_vbo); static void cleanupClass(); @@ -107,6 +111,7 @@ public: // These use VertexAttribPointer and should possibly be made generic TYPE_BINORMAL, TYPE_WEIGHT, + TYPE_WEIGHT4, TYPE_CLOTHWEIGHT, TYPE_MAX, TYPE_INDEX, @@ -122,6 +127,7 @@ public: // These use VertexAttribPointer and should possibly be made generic MAP_BINORMAL = (1<<TYPE_BINORMAL), MAP_WEIGHT = (1<<TYPE_WEIGHT), + MAP_WEIGHT4 = (1<<TYPE_WEIGHT4), MAP_CLOTHWEIGHT = (1<<TYPE_CLOTHWEIGHT), }; @@ -171,6 +177,7 @@ public: bool getBinormalStrider(LLStrider<LLVector3>& strider, S32 index=0); bool getColorStrider(LLStrider<LLColor4U>& strider, S32 index=0); bool getWeightStrider(LLStrider<F32>& strider, S32 index=0); + bool getWeight4Strider(LLStrider<LLVector4>& strider, S32 index=0); bool getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index=0); BOOL isEmpty() const { return mEmpty; } |