diff options
Diffstat (limited to 'indra/llrender')
-rw-r--r-- | indra/llrender/llfontgl.cpp | 1 | ||||
-rw-r--r-- | indra/llrender/llgl.cpp | 128 | ||||
-rw-r--r-- | indra/llrender/llgl.h | 67 | ||||
-rw-r--r-- | indra/llrender/llglheaders.h | 105 | ||||
-rw-r--r-- | indra/llrender/llglslshader.cpp | 41 | ||||
-rw-r--r-- | indra/llrender/llglslshader.h | 3 | ||||
-rw-r--r-- | indra/llrender/llglstates.h | 32 | ||||
-rw-r--r-- | indra/llrender/llimagegl.cpp | 1 | ||||
-rw-r--r-- | indra/llrender/llrender.cpp | 192 | ||||
-rw-r--r-- | indra/llrender/llrender.h | 39 | ||||
-rw-r--r-- | indra/llrender/llrendertarget.cpp | 264 | ||||
-rw-r--r-- | indra/llrender/llrendertarget.h | 24 | ||||
-rw-r--r-- | indra/llrender/llshadermgr.cpp | 79 | ||||
-rw-r--r-- | indra/llrender/llvertexbuffer.cpp | 247 | ||||
-rw-r--r-- | indra/llrender/llvertexbuffer.h | 548 |
15 files changed, 1080 insertions, 691 deletions
diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index 13008292f6..d6a31dc862 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -271,7 +271,6 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons } } - const LLFontGlyphInfo* next_glyph = NULL; const S32 GLYPH_BATCH_SIZE = 30; diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index 6ea63809f8..9354373dba 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -154,30 +154,27 @@ PFNGLGETQUERYOBJECTUIVARBPROC glGetQueryObjectuivARB = NULL; PFNGLPOINTPARAMETERFARBPROC glPointParameterfARB = NULL; PFNGLPOINTPARAMETERFVARBPROC glPointParameterfvARB = NULL; -// GL_EXT_framebuffer_object -PFNGLISRENDERBUFFEREXTPROC glIsRenderbufferEXT = NULL; -PFNGLBINDRENDERBUFFEREXTPROC glBindRenderbufferEXT = NULL; -PFNGLDELETERENDERBUFFERSEXTPROC glDeleteRenderbuffersEXT = NULL; -PFNGLGENRENDERBUFFERSEXTPROC glGenRenderbuffersEXT = NULL; -PFNGLRENDERBUFFERSTORAGEEXTPROC glRenderbufferStorageEXT = NULL; -PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC glGetRenderbufferParameterivEXT = NULL; -PFNGLISFRAMEBUFFEREXTPROC glIsFramebufferEXT = NULL; -PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebufferEXT = NULL; -PFNGLDELETEFRAMEBUFFERSEXTPROC glDeleteFramebuffersEXT = NULL; -PFNGLGENFRAMEBUFFERSEXTPROC glGenFramebuffersEXT = NULL; -PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatusEXT = NULL; -PFNGLFRAMEBUFFERTEXTURE1DEXTPROC glFramebufferTexture1DEXT = NULL; -PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2DEXT = NULL; -PFNGLFRAMEBUFFERTEXTURE3DEXTPROC glFramebufferTexture3DEXT = NULL; -PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glFramebufferRenderbufferEXT = NULL; -PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glGetFramebufferAttachmentParameterivEXT = NULL; -PFNGLGENERATEMIPMAPEXTPROC glGenerateMipmapEXT = NULL; - -// GL_EXT_framebuffer_multisample -PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glRenderbufferStorageMultisampleEXT = NULL; - -// GL_EXT_framebuffer_blit -PFNGLBLITFRAMEBUFFEREXTPROC glBlitFramebufferEXT = NULL; +// GL_ARB_framebuffer_object +PFNGLISRENDERBUFFERPROC glIsRenderbuffer = NULL; +PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer = NULL; +PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers = NULL; +PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers = NULL; +PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage = NULL; +PFNGLGETRENDERBUFFERPARAMETERIVPROC glGetRenderbufferParameteriv = NULL; +PFNGLISFRAMEBUFFERPROC glIsFramebuffer = NULL; +PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer = NULL; +PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers = NULL; +PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers = NULL; +PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus = NULL; +PFNGLFRAMEBUFFERTEXTURE1DPROC glFramebufferTexture1D = NULL; +PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D = NULL; +PFNGLFRAMEBUFFERTEXTURE3DPROC glFramebufferTexture3D = NULL; +PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer = NULL; +PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glGetFramebufferAttachmentParameteriv = NULL; +PFNGLGENERATEMIPMAPPROC glGenerateMipmap = NULL; +PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer = NULL; +PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glRenderbufferStorageMultisample = NULL; +PFNGLFRAMEBUFFERTEXTURELAYERPROC glFramebufferTextureLayer = NULL; // GL_EXT_blend_func_separate PFNGLBLENDFUNCSEPARATEEXTPROC glBlendFuncSeparateEXT = NULL; @@ -320,7 +317,6 @@ LLGLManager::LLGLManager() : mHasMipMapGeneration(FALSE), mHasCompressedTextures(FALSE), mHasFramebufferObject(FALSE), - mHasFramebufferMultisample(FALSE), mHasBlendFuncSeparate(FALSE), mHasVertexBufferObject(FALSE), @@ -329,6 +325,7 @@ LLGLManager::LLGLManager() : mHasVertexShader(FALSE), mHasFragmentShader(FALSE), mHasOcclusionQuery(FALSE), + mHasOcclusionQuery2(FALSE), mHasPointParameters(FALSE), mHasDrawBuffers(FALSE), mHasTextureRectangle(FALSE), @@ -635,11 +632,6 @@ void LLGLManager::initExtensions() # else mHasFramebufferObject = FALSE; # endif -# ifdef GL_EXT_framebuffer_multisample - mHasFramebufferMultisample = TRUE; -# else - mHasFramebufferMultisample = FALSE; -# endif # ifdef GL_ARB_draw_buffers mHasDrawBuffers = TRUE; #else @@ -675,12 +667,19 @@ void LLGLManager::initExtensions() mHasARBEnvCombine = ExtensionExists("GL_ARB_texture_env_combine", gGLHExts.mSysExts); mHasCompressedTextures = glh_init_extensions("GL_ARB_texture_compression"); mHasOcclusionQuery = ExtensionExists("GL_ARB_occlusion_query", gGLHExts.mSysExts); + mHasOcclusionQuery2 = ExtensionExists("GL_ARB_occlusion_query2", gGLHExts.mSysExts); mHasVertexBufferObject = ExtensionExists("GL_ARB_vertex_buffer_object", gGLHExts.mSysExts); mHasDepthClamp = ExtensionExists("GL_ARB_depth_clamp", gGLHExts.mSysExts) || ExtensionExists("GL_NV_depth_clamp", gGLHExts.mSysExts); // mask out FBO support when packed_depth_stencil isn't there 'cause we need it for LLRenderTarget -Brad - mHasFramebufferObject = ExtensionExists("GL_EXT_framebuffer_object", gGLHExts.mSysExts) - && ExtensionExists("GL_EXT_packed_depth_stencil", gGLHExts.mSysExts); - mHasFramebufferMultisample = mHasFramebufferObject && ExtensionExists("GL_EXT_framebuffer_multisample", gGLHExts.mSysExts); +#ifdef GL_ARB_framebuffer_object + mHasFramebufferObject = ExtensionExists("GL_ARB_framebuffer_object", gGLHExts.mSysExts); +#else + mHasFramebufferObject = ExtensionExists("GL_EXT_framebuffer_object", gGLHExts.mSysExts) && + ExtensionExists("GL_EXT_framebuffer_blit", gGLHExts.mSysExts) && + ExtensionExists("GL_EXT_framebuffer_multisample", gGLHExts.mSysExts) && + ExtensionExists("GL_EXT_packed_depth_stencil", gGLHExts.mSysExts); +#endif + 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); @@ -705,7 +704,6 @@ void LLGLManager::initExtensions() mHasCompressedTextures = FALSE; mHasVertexBufferObject = FALSE; mHasFramebufferObject = FALSE; - mHasFramebufferMultisample = FALSE; mHasDrawBuffers = FALSE; mHasBlendFuncSeparate = FALSE; mHasMipMapGeneration = FALSE; @@ -759,10 +757,9 @@ void LLGLManager::initExtensions() if (strchr(blacklist,'p')) mHasPointParameters = FALSE;//S if (strchr(blacklist,'q')) mHasFramebufferObject = FALSE;//S 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 - if (strchr(blacklist,'v')) mHasDepthClamp = FALSE; + if (strchr(blacklist,'s')) mHasTextureRectangle = FALSE; + if (strchr(blacklist,'t')) mHasBlendFuncSeparate = FALSE;//S + if (strchr(blacklist,'u')) mHasDepthClamp = FALSE; } #endif // LL_LINUX || LL_SOLARIS @@ -795,6 +792,10 @@ void LLGLManager::initExtensions() { LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_occlusion_query" << LL_ENDL; } + if (!mHasOcclusionQuery2) + { + LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_occlusion_query2" << LL_ENDL; + } if (!mHasPointParameters) { LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_point_parameters" << LL_ENDL; @@ -862,28 +863,26 @@ void LLGLManager::initExtensions() if (mHasFramebufferObject) { llinfos << "initExtensions() FramebufferObject-related procs..." << llendl; - glIsRenderbufferEXT = (PFNGLISRENDERBUFFEREXTPROC) GLH_EXT_GET_PROC_ADDRESS("glIsRenderbufferEXT"); - glBindRenderbufferEXT = (PFNGLBINDRENDERBUFFEREXTPROC) GLH_EXT_GET_PROC_ADDRESS("glBindRenderbufferEXT"); - glDeleteRenderbuffersEXT = (PFNGLDELETERENDERBUFFERSEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glDeleteRenderbuffersEXT"); - glGenRenderbuffersEXT = (PFNGLGENRENDERBUFFERSEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glGenRenderbuffersEXT"); - glRenderbufferStorageEXT = (PFNGLRENDERBUFFERSTORAGEEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glRenderbufferStorageEXT"); - glGetRenderbufferParameterivEXT = (PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glGetRenderbufferParameterivEXT"); - glIsFramebufferEXT = (PFNGLISFRAMEBUFFEREXTPROC) GLH_EXT_GET_PROC_ADDRESS("glIsFramebufferEXT"); - glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC) GLH_EXT_GET_PROC_ADDRESS("glBindFramebufferEXT"); - glDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glDeleteFramebuffersEXT"); - glGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glGenFramebuffersEXT"); - glCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glCheckFramebufferStatusEXT"); - glFramebufferTexture1DEXT = (PFNGLFRAMEBUFFERTEXTURE1DEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glFramebufferTexture1DEXT"); - glFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glFramebufferTexture2DEXT"); - glFramebufferTexture3DEXT = (PFNGLFRAMEBUFFERTEXTURE3DEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glFramebufferTexture3DEXT"); - glFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) GLH_EXT_GET_PROC_ADDRESS("glFramebufferRenderbufferEXT"); - glGetFramebufferAttachmentParameterivEXT = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glGetFramebufferAttachmentParameterivEXT"); - glGenerateMipmapEXT = (PFNGLGENERATEMIPMAPEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glGenerateMipmapEXT"); - } - if (mHasFramebufferMultisample) - { - glRenderbufferStorageMultisampleEXT = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glRenderbufferStorageMultisampleEXT"); - glBlitFramebufferEXT = (PFNGLBLITFRAMEBUFFEREXTPROC) GLH_EXT_GET_PROC_ADDRESS("glBlitFramebufferEXT"); + glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC) GLH_EXT_GET_PROC_ADDRESS("glIsRenderbuffer"); + glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC) GLH_EXT_GET_PROC_ADDRESS("glBindRenderbuffer"); + glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC) GLH_EXT_GET_PROC_ADDRESS("glDeleteRenderbuffers"); + glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC) GLH_EXT_GET_PROC_ADDRESS("glGenRenderbuffers"); + glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC) GLH_EXT_GET_PROC_ADDRESS("glRenderbufferStorage"); + glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC) GLH_EXT_GET_PROC_ADDRESS("glGetRenderbufferParameteriv"); + glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC) GLH_EXT_GET_PROC_ADDRESS("glIsFramebuffer"); + glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC) GLH_EXT_GET_PROC_ADDRESS("glBindFramebuffer"); + glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC) GLH_EXT_GET_PROC_ADDRESS("glDeleteFramebuffers"); + glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC) GLH_EXT_GET_PROC_ADDRESS("glGenFramebuffers"); + glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC) GLH_EXT_GET_PROC_ADDRESS("glCheckFramebufferStatus"); + glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC) GLH_EXT_GET_PROC_ADDRESS("glFramebufferTexture1D"); + glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC) GLH_EXT_GET_PROC_ADDRESS("glFramebufferTexture2D"); + glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC) GLH_EXT_GET_PROC_ADDRESS("glFramebufferTexture3D"); + glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC) GLH_EXT_GET_PROC_ADDRESS("glFramebufferRenderbuffer"); + glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) GLH_EXT_GET_PROC_ADDRESS("glGetFramebufferAttachmentParameteriv"); + glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC) GLH_EXT_GET_PROC_ADDRESS("glGenerateMipmap"); + glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC) GLH_EXT_GET_PROC_ADDRESS("glBlitFramebuffer"); + glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) GLH_EXT_GET_PROC_ADDRESS("glRenderbufferStorageMultisample"); + glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC) GLH_EXT_GET_PROC_ADDRESS("glFramebufferTextureLayer"); } if (mHasDrawBuffers) { @@ -1846,7 +1845,7 @@ LLGLUserClipPlane::LLGLUserClipPlane(const LLPlane& p, const glh::matrix4f& mode mModelview = modelview; mProjection = projection; - setPlane(p.mV[0], p.mV[1], p.mV[2], p.mV[3]); + setPlane(p[0], p[1], p[2], p[3]); } void LLGLUserClipPlane::setPlane(F32 a, F32 b, F32 c, F32 d) @@ -2072,11 +2071,14 @@ void LLGLDepthTest::checkState() } } -LLGLSquashToFarClip::LLGLSquashToFarClip(glh::matrix4f P) +LLGLSquashToFarClip::LLGLSquashToFarClip(glh::matrix4f P, U32 layer) { + + F32 depth = 0.99999f - 0.0001f * layer; + for (U32 i = 0; i < 4; i++) { - P.element(2, i) = P.element(3, i) * 0.99999f; + P.element(2, i) = P.element(3, i) * depth; } glMatrixMode(GL_PROJECTION); diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h index 85fab7a0f8..df110613e3 100644 --- a/indra/llrender/llgl.h +++ b/indra/llrender/llgl.h @@ -80,7 +80,6 @@ public: BOOL mHasMipMapGeneration; BOOL mHasCompressedTextures; BOOL mHasFramebufferObject; - BOOL mHasFramebufferMultisample; BOOL mHasBlendFuncSeparate; // ARB Extensions @@ -90,6 +89,7 @@ public: BOOL mHasVertexShader; BOOL mHasFragmentShader; BOOL mHasOcclusionQuery; + BOOL mHasOcclusionQuery2; BOOL mHasPointParameters; BOOL mHasDrawBuffers; BOOL mHasDepthClamp; @@ -320,7 +320,7 @@ private: class LLGLSquashToFarClip { public: - LLGLSquashToFarClip(glh::matrix4f projection); + LLGLSquashToFarClip(glh::matrix4f projection, U32 layer = 0); ~LLGLSquashToFarClip(); }; @@ -418,4 +418,67 @@ extern BOOL gClothRipple; extern BOOL gNoRender; extern BOOL gGLActive; +// Deal with changing glext.h definitions for newer SDK versions, specifically +// with MAC OSX 10.5 -> 10.6 + + +#ifndef GL_DEPTH_ATTACHMENT +#define GL_DEPTH_ATTACHMENT GL_DEPTH_ATTACHMENT_EXT +#endif + +#ifndef GL_STENCIL_ATTACHMENT +#define GL_STENCIL_ATTACHMENT GL_STENCIL_ATTACHMENT_EXT +#endif + +#ifndef GL_FRAMEBUFFER +#define GL_FRAMEBUFFER GL_FRAMEBUFFER_EXT +#define GL_DRAW_FRAMEBUFFER GL_DRAW_FRAMEBUFFER_EXT +#define GL_READ_FRAMEBUFFER GL_READ_FRAMEBUFFER_EXT +#define GL_FRAMEBUFFER_COMPLETE GL_FRAMEBUFFER_COMPLETE_EXT +#define GL_FRAMEBUFFER_UNSUPPORTED GL_FRAMEBUFFER_UNSUPPORTED_EXT +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT +#define glGenFramebuffers glGenFramebuffersEXT +#define glBindFramebuffer glBindFramebufferEXT +#define glCheckFramebufferStatus glCheckFramebufferStatusEXT +#define glBlitFramebuffer glBlitFramebufferEXT +#define glDeleteFramebuffers glDeleteFramebuffersEXT +#define glFramebufferRenderbuffer glFramebufferRenderbufferEXT +#define glFramebufferTexture2D glFramebufferTexture2DEXT +#endif + +#ifndef GL_RENDERBUFFER +#define GL_RENDERBUFFER GL_RENDERBUFFER_EXT +#define glGenRenderbuffers glGenRenderbuffersEXT +#define glBindRenderbuffer glBindRenderbufferEXT +#define glRenderbufferStorage glRenderbufferStorageEXT +#define glRenderbufferStorageMultisample glRenderbufferStorageMultisampleEXT +#define glDeleteRenderbuffers glDeleteRenderbuffersEXT +#endif + +#ifndef GL_COLOR_ATTACHMENT +#define GL_COLOR_ATTACHMENT GL_COLOR_ATTACHMENT_EXT +#endif + +#ifndef GL_COLOR_ATTACHMENT0 +#define GL_COLOR_ATTACHMENT0 GL_COLOR_ATTACHMENT0_EXT +#endif + +#ifndef GL_COLOR_ATTACHMENT1 +#define GL_COLOR_ATTACHMENT1 GL_COLOR_ATTACHMENT1_EXT +#endif + +#ifndef GL_COLOR_ATTACHMENT2 +#define GL_COLOR_ATTACHMENT2 GL_COLOR_ATTACHMENT2_EXT +#endif + +#ifndef GL_COLOR_ATTACHMENT3 +#define GL_COLOR_ATTACHMENT3 GL_COLOR_ATTACHMENT3_EXT +#endif + + +#ifndef GL_DEPTH24_STENCIL8 +#define GL_DEPTH24_STENCIL8 GL_DEPTH24_STENCIL8_EXT +#endif + #endif // LL_LLGL_H diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h index 576969b81a..46bc282436 100644 --- a/indra/llrender/llglheaders.h +++ b/indra/llrender/llglheaders.h @@ -1,25 +1,25 @@ -/** +/** * @file llglheaders.h * @brief LLGL definitions * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -449,30 +449,27 @@ extern PFNGLGETCOMPRESSEDTEXIMAGEARBPROC glGetCompressedTexImageARB; //GL_EXT_blend_func_separate extern PFNGLBLENDFUNCSEPARATEEXTPROC glBlendFuncSeparateEXT; -//GL_EXT_framebuffer_object -extern PFNGLISRENDERBUFFEREXTPROC glIsRenderbufferEXT; -extern PFNGLBINDRENDERBUFFEREXTPROC glBindRenderbufferEXT; -extern PFNGLDELETERENDERBUFFERSEXTPROC glDeleteRenderbuffersEXT; -extern PFNGLGENRENDERBUFFERSEXTPROC glGenRenderbuffersEXT; -extern PFNGLRENDERBUFFERSTORAGEEXTPROC glRenderbufferStorageEXT; -extern PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC glGetRenderbufferParameterivEXT; -extern PFNGLISFRAMEBUFFEREXTPROC glIsFramebufferEXT; -extern PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebufferEXT; -extern PFNGLDELETEFRAMEBUFFERSEXTPROC glDeleteFramebuffersEXT; -extern PFNGLGENFRAMEBUFFERSEXTPROC glGenFramebuffersEXT; -extern PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatusEXT; -extern PFNGLFRAMEBUFFERTEXTURE1DEXTPROC glFramebufferTexture1DEXT; -extern PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2DEXT; -extern PFNGLFRAMEBUFFERTEXTURE3DEXTPROC glFramebufferTexture3DEXT; -extern PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glFramebufferRenderbufferEXT; -extern PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glGetFramebufferAttachmentParameterivEXT; -extern PFNGLGENERATEMIPMAPEXTPROC glGenerateMipmapEXT; - -// GL_EXT_framebuffer_multisample -extern PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glRenderbufferStorageMultisampleEXT; - -// GL_EXT_framebuffer_blit -extern PFNGLBLITFRAMEBUFFEREXTPROC glBlitFramebufferEXT; +//GL_ARB_framebuffer_object +extern PFNGLISRENDERBUFFERPROC glIsRenderbuffer; +extern PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer; +extern PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers; +extern PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers; +extern PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage; +extern PFNGLGETRENDERBUFFERPARAMETERIVPROC glGetRenderbufferParameteriv; +extern PFNGLISFRAMEBUFFERPROC glIsFramebuffer; +extern PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer; +extern PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers; +extern PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers; +extern PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus; +extern PFNGLFRAMEBUFFERTEXTURE1DPROC glFramebufferTexture1D; +extern PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D; +extern PFNGLFRAMEBUFFERTEXTURE3DPROC glFramebufferTexture3D; +extern PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer; +extern PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glGetFramebufferAttachmentParameteriv; +extern PFNGLGENERATEMIPMAPPROC glGenerateMipmap; +extern PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer; +extern PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glRenderbufferStorageMultisample; +extern PFNGLFRAMEBUFFERTEXTURELAYERPROC glFramebufferTextureLayer; //GL_ARB_draw_buffers extern PFNGLDRAWBUFFERSARBPROC glDrawBuffersARB; @@ -651,30 +648,27 @@ extern PFNGLGETATTRIBLOCATIONARBPROC glGetAttribLocationARB; //GL_EXT_blend_func_separate extern PFNGLBLENDFUNCSEPARATEEXTPROC glBlendFuncSeparateEXT; -//GL_EXT_framebuffer_object -extern PFNGLISRENDERBUFFEREXTPROC glIsRenderbufferEXT; -extern PFNGLBINDRENDERBUFFEREXTPROC glBindRenderbufferEXT; -extern PFNGLDELETERENDERBUFFERSEXTPROC glDeleteRenderbuffersEXT; -extern PFNGLGENRENDERBUFFERSEXTPROC glGenRenderbuffersEXT; -extern PFNGLRENDERBUFFERSTORAGEEXTPROC glRenderbufferStorageEXT; -extern PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC glGetRenderbufferParameterivEXT; -extern PFNGLISFRAMEBUFFEREXTPROC glIsFramebufferEXT; -extern PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebufferEXT; -extern PFNGLDELETEFRAMEBUFFERSEXTPROC glDeleteFramebuffersEXT; -extern PFNGLGENFRAMEBUFFERSEXTPROC glGenFramebuffersEXT; -extern PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatusEXT; -extern PFNGLFRAMEBUFFERTEXTURE1DEXTPROC glFramebufferTexture1DEXT; -extern PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2DEXT; -extern PFNGLFRAMEBUFFERTEXTURE3DEXTPROC glFramebufferTexture3DEXT; -extern PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glFramebufferRenderbufferEXT; -extern PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glGetFramebufferAttachmentParameterivEXT; -extern PFNGLGENERATEMIPMAPEXTPROC glGenerateMipmapEXT; - -// GL_EXT_framebuffer_multisample -extern PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glRenderbufferStorageMultisampleEXT; - -// GL_EXT_framebuffer_blit -extern PFNGLBLITFRAMEBUFFEREXTPROC glBlitFramebufferEXT; +//GL_ARB_framebuffer_object +extern PFNGLISRENDERBUFFERPROC glIsRenderbuffer; +extern PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer; +extern PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers; +extern PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers; +extern PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage; +extern PFNGLGETRENDERBUFFERPARAMETERIVPROC glGetRenderbufferParameteriv; +extern PFNGLISFRAMEBUFFERPROC glIsFramebuffer; +extern PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer; +extern PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers; +extern PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers; +extern PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus; +extern PFNGLFRAMEBUFFERTEXTURE1DPROC glFramebufferTexture1D; +extern PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D; +extern PFNGLFRAMEBUFFERTEXTURE3DPROC glFramebufferTexture3D; +extern PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer; +extern PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glGetFramebufferAttachmentParameteriv; +extern PFNGLGENERATEMIPMAPPROC glGenerateMipmap; +extern PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer; +extern PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glRenderbufferStorageMultisample; +extern PFNGLFRAMEBUFFERTEXTURELAYERPROC glFramebufferTextureLayer; //GL_ARB_draw_buffers extern PFNGLDRAWBUFFERSARBPROC glDrawBuffersARB; @@ -697,7 +691,7 @@ extern PFNGLDRAWBUFFERSARBPROC glDrawBuffersARB; #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; +extern void glBlendFuncSeparateEXT(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) ; // GL_EXT_framebuffer_object extern GLboolean glIsRenderbufferEXT(GLuint renderbuffer) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER; @@ -718,6 +712,9 @@ extern void glFramebufferRenderbufferEXT(GLenum target, GLenum attachment, GLenu extern void glGetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment, GLenum pname, GLint *params) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER; extern void glGenerateMipmapEXT(GLenum target) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER; +#ifndef GL_ARB_framebuffer_object +#define glGenerateMipmap glGenerateMipmapEXT +#endif // GL_ARB_draw_buffers extern void glDrawBuffersARB(GLsizei n, const GLenum* bufs) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER; diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index 16534fa9a5..257bcd9380 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -55,7 +55,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) { } @@ -118,7 +118,7 @@ BOOL LLGLSLShader::createShader(vector<string> * attributes, { GLhandleARB shaderhandle = LLShaderMgr::instance()->loadShaderFile((*fileIter).first, mShaderLevel, (*fileIter).second); LL_DEBUGS("ShaderLoading") << "SHADER FILE: " << (*fileIter).first << " mShaderLevel=" << mShaderLevel << LL_ENDL; - if (mShaderLevel > 0) + if (shaderhandle > 0) { attachObject(shaderhandle); } @@ -698,17 +698,46 @@ void LLGLSLShader::uniformMatrix4fv(U32 index, U32 count, GLboolean transpose, c GLint LLGLSLShader::getUniformLocation(const string& uniform) { + GLint ret = -1; if (mProgramObject > 0) { std::map<string, GLint>::iterator iter = mUniformMap.find(uniform); if (iter != mUniformMap.end()) { - llassert(iter->second == glGetUniformLocationARB(mProgramObject, uniform.c_str())); - return iter->second; + if (gDebugGL) + { + stop_glerror(); + if (iter->second != glGetUniformLocationARB(mProgramObject, uniform.c_str())) + { + llerrs << "Uniform does not match." << llendl; + } + stop_glerror(); + } + ret = iter->second; } } - return -1; + /*if (gDebugGL) + { + if (ret == -1 && ret != glGetUniformLocationARB(mProgramObject, uniform.c_str())) + { + llerrs << "Uniform map invalid." << llendl; + } + }*/ + + return ret; +} + +GLint LLGLSLShader::getAttribLocation(U32 attrib) +{ + if (attrib < mAttribute.size()) + { + return mAttribute[attrib]; + } + else + { + return -1; + } } void LLGLSLShader::uniform1i(const string& uniform, GLint v) @@ -882,7 +911,9 @@ void LLGLSLShader::uniformMatrix4fv(const string& uniform, U32 count, GLboolean if (location >= 0) { + stop_glerror(); glUniformMatrix4fvARB(location, count, transpose, v); + stop_glerror(); } } diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h index c11bd50716..d46ddbbe18 100644 --- a/indra/llrender/llglslshader.h +++ b/indra/llrender/llglslshader.h @@ -42,6 +42,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; @@ -103,7 +104,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/llglstates.h b/indra/llrender/llglstates.h index d5a29dcd0c..e26aead676 100644 --- a/indra/llrender/llglstates.h +++ b/indra/llrender/llglstates.h @@ -238,9 +238,11 @@ public: class LLGLSSpecular { public: + F32 mShininess; LLGLSSpecular(const LLColor4& color, F32 shininess) { - if (shininess > 0.0f) + mShininess = shininess; + if (mShininess > 0.0f) { glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color.mV); S32 shiny = (S32)(shininess*128.f); @@ -250,32 +252,14 @@ public: } ~LLGLSSpecular() { - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, LLColor4(0.f,0.f,0.f,0.f).mV); - glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 0); + if (mShininess > 0.f) + { + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, LLColor4(0.f,0.f,0.f,0.f).mV); + glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 0); + } } }; //---------------------------------------------------------------------------- - -class LLGLSBlendFunc : public LLGLSPipeline { -protected: - GLint mSavedSrc, mSavedDst; - LLGLEnable mBlend; - -public: - LLGLSBlendFunc(GLenum srcFunc, GLenum dstFunc) : - mBlend(GL_BLEND) - { - glGetIntegerv(GL_BLEND_SRC, &mSavedSrc); - glGetIntegerv(GL_BLEND_DST, &mSavedDst); - glBlendFunc(srcFunc, dstFunc); - } - - ~LLGLSBlendFunc(void) { - glBlendFunc(mSavedSrc, mSavedDst); - } -}; - - #endif diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index e8e98211f1..dfd72d13b0 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -1706,6 +1706,7 @@ void LLImageGL::analyzeAlpha(const void* data_in, U32 w, U32 h) sample[asum/(16*4)] += 4; } + rowstart += 2 * w * mAlphaStride; } length *= 2; // we sampled everything twice, essentially diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 8eb160f4e7..49e10c4790 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -47,6 +47,7 @@ U32 LLRender::sUICalls = 0; U32 LLRender::sUIVerts = 0; static const U32 LL_NUM_TEXTURE_LAYERS = 16; +static const U32 LL_NUM_LIGHT_UNITS = 8; static GLenum sGLTextureType[] = { @@ -747,6 +748,130 @@ void LLTexUnit::debugTextureUnit(void) } } +LLLightState::LLLightState(S32 index) +: mIndex(index), + mEnabled(false), + mConstantAtten(1.f), + mLinearAtten(0.f), + mQuadraticAtten(0.f), + mSpotExponent(0.f), + mSpotCutoff(180.f) +{ + if (mIndex == 0) + { + mDiffuse.set(1,1,1,1); + mSpecular.set(1,1,1,1); + } + + mAmbient.set(0,0,0,1); + mPosition.set(0,0,1,0); + mSpotDirection.set(0,0,-1); + +} + +void LLLightState::enable() +{ + if (!mEnabled) + { + glEnable(GL_LIGHT0+mIndex); + mEnabled = true; + } +} + +void LLLightState::disable() +{ + if (mEnabled) + { + glDisable(GL_LIGHT0+mIndex); + mEnabled = false; + } +} + +void LLLightState::setDiffuse(const LLColor4& diffuse) +{ + if (mDiffuse != diffuse) + { + mDiffuse = diffuse; + glLightfv(GL_LIGHT0+mIndex, GL_DIFFUSE, mDiffuse.mV); + } +} + +void LLLightState::setAmbient(const LLColor4& ambient) +{ + if (mAmbient != ambient) + { + mAmbient = ambient; + glLightfv(GL_LIGHT0+mIndex, GL_AMBIENT, mAmbient.mV); + } +} + +void LLLightState::setSpecular(const LLColor4& specular) +{ + if (mSpecular != specular) + { + mSpecular = specular; + glLightfv(GL_LIGHT0+mIndex, GL_SPECULAR, mSpecular.mV); + } +} + +void LLLightState::setPosition(const LLVector4& position) +{ + //always set position because modelview matrix may have changed + mPosition = position; + glLightfv(GL_LIGHT0+mIndex, GL_POSITION, mPosition.mV); +} + +void LLLightState::setConstantAttenuation(const F32& atten) +{ + if (mConstantAtten != atten) + { + mConstantAtten = atten; + glLightf(GL_LIGHT0+mIndex, GL_CONSTANT_ATTENUATION, atten); + } +} + +void LLLightState::setLinearAttenuation(const F32& atten) +{ + if (mLinearAtten != atten) + { + mLinearAtten = atten; + glLightf(GL_LIGHT0+mIndex, GL_LINEAR_ATTENUATION, atten); + } +} + +void LLLightState::setQuadraticAttenuation(const F32& atten) +{ + if (mQuadraticAtten != atten) + { + mQuadraticAtten = atten; + glLightf(GL_LIGHT0+mIndex, GL_QUADRATIC_ATTENUATION, atten); + } +} + +void LLLightState::setSpotExponent(const F32& exponent) +{ + if (mSpotExponent != exponent) + { + mSpotExponent = exponent; + glLightf(GL_LIGHT0+mIndex, GL_SPOT_EXPONENT, exponent); + } +} + +void LLLightState::setSpotCutoff(const F32& cutoff) +{ + if (mSpotCutoff != cutoff) + { + mSpotCutoff = cutoff; + glLightf(GL_LIGHT0+mIndex, GL_SPOT_CUTOFF, cutoff); + } +} + +void LLLightState::setSpotDirection(const LLVector3& direction) +{ + //always set direction because modelview matrix may have changed + mSpotDirection = direction; + glLightfv(GL_LIGHT0+mIndex, GL_SPOT_DIRECTION, direction.mV); +} LLRender::LLRender() : mDirty(false), @@ -768,6 +893,11 @@ LLRender::LLRender() } mDummyTexUnit = new LLTexUnit(-1); + for (U32 i = 0; i < LL_NUM_LIGHT_UNITS; ++i) + { + mLightState.push_back(new LLLightState(i)); + } + for (U32 i = 0; i < 4; i++) { mCurrColorMask[i] = true; @@ -795,6 +925,12 @@ void LLRender::shutdown() mTexUnits.clear(); delete mDummyTexUnit; mDummyTexUnit = NULL; + + for (U32 i = 0; i < mLightState.size(); ++i) + { + delete mLightState[i]; + } + mLightState.clear(); } void LLRender::refreshState(void) @@ -898,7 +1034,7 @@ LLVector3 LLRender::getUITranslation() { if (mUIOffset.empty()) { - return LLVector3::zero; + return LLVector3(0,0,0); } return mUIOffset.back(); } @@ -907,7 +1043,7 @@ LLVector3 LLRender::getUIScale() { if (mUIScale.empty()) { - return LLVector3(1.f, 1.f, 1.f); + return LLVector3(1,1,1); } return mUIScale.back(); } @@ -932,15 +1068,21 @@ void LLRender::setColorMask(bool writeColorR, bool writeColorG, bool writeColorB { flush(); - mCurrColorMask[0] = writeColorR; - mCurrColorMask[1] = writeColorG; - mCurrColorMask[2] = writeColorB; - mCurrColorMask[3] = writeAlpha; + if (mCurrColorMask[0] != writeColorR || + mCurrColorMask[1] != writeColorG || + mCurrColorMask[2] != writeColorB || + mCurrColorMask[3] != writeAlpha) + { + mCurrColorMask[0] = writeColorR; + mCurrColorMask[1] = writeColorG; + mCurrColorMask[2] = writeColorB; + mCurrColorMask[3] = writeAlpha; - glColorMask(writeColorR ? GL_TRUE : GL_FALSE, - writeColorG ? GL_TRUE : GL_FALSE, - writeColorB ? GL_TRUE : GL_FALSE, - writeAlpha ? GL_TRUE : GL_FALSE); + glColorMask(writeColorR ? GL_TRUE : GL_FALSE, + writeColorG ? GL_TRUE : GL_FALSE, + writeColorB ? GL_TRUE : GL_FALSE, + writeAlpha ? GL_TRUE : GL_FALSE); + } } void LLRender::setSceneBlendType(eBlendType type) @@ -978,15 +1120,19 @@ void LLRender::setAlphaRejectSettings(eCompareFunc func, F32 value) { flush(); - mCurrAlphaFunc = func; - mCurrAlphaFuncVal = value; - if (func == CF_DEFAULT) - { - glAlphaFunc(GL_GREATER, 0.01f); - } - else + if (mCurrAlphaFunc != func || + mCurrAlphaFuncVal != value) { - glAlphaFunc(sGLCompareFunc[func], value); + mCurrAlphaFunc = func; + mCurrAlphaFuncVal = value; + if (func == CF_DEFAULT) + { + glAlphaFunc(GL_GREATER, 0.01f); + } + else + { + glAlphaFunc(sGLCompareFunc[func], value); + } } } @@ -1045,6 +1191,16 @@ LLTexUnit* LLRender::getTexUnit(U32 index) } } +LLLightState* LLRender::getLight(U32 index) +{ + if (index < mLightState.size()) + { + return mLightState[index]; + } + + return NULL; +} + bool LLRender::verifyTexUnitActive(U32 unitToVerify) { if (mCurrTextureUnitIndex == unitToVerify) diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index 2767aa64a8..7ba14f7b40 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -37,6 +37,7 @@ #include "v2math.h" #include "v3math.h" #include "v4coloru.h" +#include "v4math.h" #include "llstrider.h" #include "llpointer.h" #include "llglheaders.h" @@ -212,6 +213,41 @@ protected: void setTextureCombiner(eTextureBlendOp op, eTextureBlendSrc src1, eTextureBlendSrc src2, bool isAlpha = false); }; +class LLLightState +{ +public: + LLLightState(S32 index); + + void enable(); + void disable(); + void setDiffuse(const LLColor4& diffuse); + void setAmbient(const LLColor4& ambient); + void setSpecular(const LLColor4& specular); + void setPosition(const LLVector4& position); + void setConstantAttenuation(const F32& atten); + void setLinearAttenuation(const F32& atten); + void setQuadraticAttenuation(const F32& atten); + void setSpotExponent(const F32& exponent); + void setSpotCutoff(const F32& cutoff); + void setSpotDirection(const LLVector3& direction); + +protected: + S32 mIndex; + bool mEnabled; + LLColor4 mDiffuse; + LLColor4 mAmbient; + LLColor4 mSpecular; + LLVector4 mPosition; + LLVector3 mSpotDirection; + + F32 mConstantAtten; + F32 mLinearAtten; + F32 mQuadraticAtten; + + F32 mSpotExponent; + F32 mSpotCutoff; +}; + class LLRender { friend class LLTexUnit; @@ -327,6 +363,8 @@ public: void blendFunc(eBlendFactor color_sfactor, eBlendFactor color_dfactor, eBlendFactor alpha_sfactor, eBlendFactor alpha_dfactor); + LLLightState* getLight(U32 index); + LLTexUnit* getTexUnit(U32 index); U32 getCurrentTexUnitIndex(void) const { return mCurrTextureUnitIndex; } @@ -363,6 +401,7 @@ private: LLStrider<LLColor4U> mColorsp; std::vector<LLTexUnit*> mTexUnits; LLTexUnit* mDummyTexUnit; + std::vector<LLLightState*> mLightState; eBlendFactor mCurrBlendColorSFactor; eBlendFactor mCurrBlendColorDFactor; diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp index 7205210fcc..cd2556d435 100644 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -38,10 +38,10 @@ void check_framebuffer_status() { if (gDebugGL) { - GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); + GLenum status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); switch (status) { - case GL_FRAMEBUFFER_COMPLETE_EXT: + case GL_FRAMEBUFFER_COMPLETE: break; default: ll_fail("check_framebuffer_status failed"); @@ -50,7 +50,7 @@ void check_framebuffer_status() } } -BOOL LLRenderTarget::sUseFBO = FALSE; +bool LLRenderTarget::sUseFBO = false; LLRenderTarget::LLRenderTarget() : mResX(0), @@ -59,8 +59,8 @@ LLRenderTarget::LLRenderTarget() : mFBO(0), mDepth(0), mStencil(0), - mUseDepth(FALSE), - mRenderDepth(FALSE), + mUseDepth(false), + mRenderDepth(false), mUsage(LLTexUnit::TT_TEXTURE), mSamples(0), mSampleBuffer(NULL) @@ -78,7 +78,7 @@ void LLRenderTarget::setSampleBuffer(LLMultisampleBuffer* buffer) mSampleBuffer = buffer; } -void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, BOOL stencil, LLTexUnit::eTextureType usage, BOOL use_fbo) +void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo) { stop_glerror(); mResX = resx; @@ -99,24 +99,24 @@ void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, BOO stop_glerror(); } - glGenFramebuffersEXT(1, (GLuint *) &mFBO); + glGenFramebuffers(1, (GLuint *) &mFBO); if (mDepth) { - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBO); + glBindFramebuffer(GL_FRAMEBUFFER, mFBO); if (mStencil) { - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mDepth); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepth); stop_glerror(); - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mDepth); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mDepth); stop_glerror(); } else { - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, LLTexUnit::getInternalType(mUsage), mDepth, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), mDepth, 0); stop_glerror(); } - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + glBindFramebuffer(GL_FRAMEBUFFER, 0); } stop_glerror(); @@ -168,14 +168,14 @@ void LLRenderTarget::addColorAttachment(U32 color_fmt) } if (mFBO) { - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBO); - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT+offset, + glBindFramebuffer(GL_FRAMEBUFFER, mFBO); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+offset, LLTexUnit::getInternalType(mUsage), tex, 0); stop_glerror(); check_framebuffer_status(); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + glBindFramebuffer(GL_FRAMEBUFFER, 0); } mTex.push_back(tex); @@ -187,10 +187,10 @@ void LLRenderTarget::allocateDepth() if (mStencil) { //use render buffers where stencil buffers are in play - glGenRenderbuffersEXT(1, (GLuint *) &mDepth); - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, mDepth); - glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, mResX, mResY); - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); + glGenRenderbuffers(1, (GLuint *) &mDepth); + glBindRenderbuffer(GL_RENDERBUFFER, mDepth); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, mResX, mResY); + glBindRenderbuffer(GL_RENDERBUFFER, 0); } else { @@ -198,7 +198,7 @@ void LLRenderTarget::allocateDepth() gGL.getTexUnit(0)->bindManual(mUsage, mDepth); U32 internal_type = LLTexUnit::getInternalType(mUsage); gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); - LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT32_ARB, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL); + LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT32, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL); } } @@ -209,54 +209,48 @@ void LLRenderTarget::shareDepthBuffer(LLRenderTarget& target) llerrs << "Cannot share depth buffer between non FBO render targets." << llendl; } + if (target.mDepth) + { + llerrs << "Attempting to override existing depth buffer. Detach existing buffer first." << llendl; + } + + if (target.mUseDepth) + { + llerrs << "Attempting to override existing shared depth buffer. Detach existing buffer first." << llendl; + } + if (mDepth) { stop_glerror(); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, target.mFBO); + glBindFramebuffer(GL_FRAMEBUFFER, target.mFBO); stop_glerror(); if (mStencil) { - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mDepth); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepth); stop_glerror(); - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mDepth); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mDepth); stop_glerror(); + target.mStencil = true; } else { - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, LLTexUnit::getInternalType(mUsage), mDepth, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), mDepth, 0); stop_glerror(); - if (mStencil) - { - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, LLTexUnit::getInternalType(mUsage), mDepth, 0); - stop_glerror(); - } } - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + glBindFramebuffer(GL_FRAMEBUFFER, 0); - target.mUseDepth = TRUE; + target.mUseDepth = true; } } void LLRenderTarget::release() { - if (mFBO) - { - glDeleteFramebuffersEXT(1, (GLuint *) &mFBO); - mFBO = 0; - } - - if (mTex.size() > 0) - { - LLImageGL::deleteTextures(mTex.size(), &mTex[0]); - mTex.clear(); - } - if (mDepth) { if (mStencil) { - glDeleteRenderbuffersEXT(1, (GLuint*) &mDepth); + glDeleteRenderbuffers(1, (GLuint*) &mDepth); stop_glerror(); } else @@ -266,6 +260,33 @@ void LLRenderTarget::release() } mDepth = 0; } + else if (mUseDepth && mFBO) + { //detach shared depth buffer + glBindFramebuffer(GL_FRAMEBUFFER, mFBO); + if (mStencil) + { //attached as a renderbuffer + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0); + mStencil = false; + } + else + { //attached as a texture + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), 0, 0); + } + mUseDepth = false; + } + + if (mFBO) + { + glDeleteFramebuffers(1, (GLuint *) &mFBO); + mFBO = 0; + } + + if (mTex.size() > 0) + { + LLImageGL::deleteTextures(mTex.size(), &mTex[0]); + mTex.clear(); + } mSampleBuffer = NULL; sBoundTarget = NULL; @@ -283,14 +304,14 @@ void LLRenderTarget::bindTarget() } else { - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBO); + glBindFramebuffer(GL_FRAMEBUFFER, mFBO); stop_glerror(); if (gGLManager.mHasDrawBuffers) { //setup multiple render targets - GLenum drawbuffers[] = {GL_COLOR_ATTACHMENT0_EXT, - GL_COLOR_ATTACHMENT1_EXT, - GL_COLOR_ATTACHMENT2_EXT, - GL_COLOR_ATTACHMENT3_EXT}; + GLenum drawbuffers[] = {GL_COLOR_ATTACHMENT0, + GL_COLOR_ATTACHMENT1, + GL_COLOR_ATTACHMENT2, + GL_COLOR_ATTACHMENT3}; glDrawBuffersARB(mTex.size(), drawbuffers); } @@ -315,7 +336,7 @@ void LLRenderTarget::unbindTarget() { if (gGLManager.mHasFramebufferObject) { - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + glBindFramebuffer(GL_FRAMEBUFFER, 0); } sBoundTarget = NULL; } @@ -349,19 +370,19 @@ U32 LLRenderTarget::getTexture(U32 attachment) const { llerrs << "Invalid attachment index." << llendl; } + if (mTex.empty()) + { + return 0; + } return mTex[attachment]; } void LLRenderTarget::bindTexture(U32 index, S32 channel) { - if (index > mTex.size()-1) - { - llerrs << "Invalid attachment index." << llendl; - } - gGL.getTexUnit(channel)->bindManual(mUsage, mTex[index]); + gGL.getTexUnit(channel)->bindManual(mUsage, getTexture(index)); } -void LLRenderTarget::flush(BOOL fetch_depth) +void LLRenderTarget::flush(bool fetch_depth) { gGL.flush(); if (!mFBO) @@ -377,7 +398,7 @@ void LLRenderTarget::flush(BOOL fetch_depth) } gGL.getTexUnit(0)->bind(this); - glCopyTexImage2D(LLTexUnit::getInternalType(mUsage), 0, GL_DEPTH24_STENCIL8_EXT, 0, 0, mResX, mResY, 0); + glCopyTexImage2D(LLTexUnit::getInternalType(mUsage), 0, GL_DEPTH24_STENCIL8, 0, 0, mResX, mResY, 0); } gGL.getTexUnit(0)->disable(); @@ -386,55 +407,59 @@ void LLRenderTarget::flush(BOOL fetch_depth) { stop_glerror(); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + glBindFramebuffer(GL_FRAMEBUFFER, 0); stop_glerror(); if (mSampleBuffer) { - LLGLEnable multisample(GL_MULTISAMPLE_ARB); + LLGLEnable multisample(GL_MULTISAMPLE); stop_glerror(); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBO); + glBindFramebuffer(GL_FRAMEBUFFER, mFBO); stop_glerror(); check_framebuffer_status(); - glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, mSampleBuffer->mFBO); + glBindFramebuffer(GL_READ_FRAMEBUFFER, mSampleBuffer->mFBO); check_framebuffer_status(); stop_glerror(); - glBlitFramebufferEXT(0, 0, mResX, mResY, 0, 0, mResX, mResY, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); + glBlitFramebuffer(0, 0, mResX, mResY, 0, 0, mResX, mResY, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); stop_glerror(); if (mTex.size() > 1) { for (U32 i = 1; i < mTex.size(); ++i) { - glFramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, LLTexUnit::getInternalType(mUsage), mTex[i], 0); stop_glerror(); - glFramebufferRenderbufferEXT(GL_READ_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, mSampleBuffer->mTex[i]); + glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mSampleBuffer->mTex[i]); stop_glerror(); - glBlitFramebufferEXT(0, 0, mResX, mResY, 0, 0, mResX, mResY, GL_COLOR_BUFFER_BIT, GL_NEAREST); + glBlitFramebuffer(0, 0, mResX, mResY, 0, 0, mResX, mResY, GL_COLOR_BUFFER_BIT, GL_NEAREST); stop_glerror(); } for (U32 i = 0; i < mTex.size(); ++i) { - glFramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT+i, + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+i, LLTexUnit::getInternalType(mUsage), mTex[i], 0); stop_glerror(); - glFramebufferRenderbufferEXT(GL_READ_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT+i, GL_RENDERBUFFER_EXT, mSampleBuffer->mTex[i]); + glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+i, GL_RENDERBUFFER, mSampleBuffer->mTex[i]); stop_glerror(); } } } - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + glBindFramebuffer(GL_FRAMEBUFFER, 0); } } 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) { + GLboolean write_depth = mask & GL_DEPTH_BUFFER_BIT ? TRUE : FALSE; + + LLGLDepthTest depth(write_depth, write_depth); + gGL.flush(); if (!source.mFBO || !mFBO) { @@ -451,25 +476,25 @@ void LLRenderTarget::copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0, { stop_glerror(); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, source.mFBO); + glBindFramebuffer(GL_FRAMEBUFFER, source.mFBO); gGL.getTexUnit(0)->bind(this, true); stop_glerror(); glCopyTexSubImage2D(LLTexUnit::getInternalType(mUsage), 0, srcX0, srcY0, dstX0, dstY0, dstX1, dstY1); stop_glerror(); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + glBindFramebuffer(GL_FRAMEBUFFER, 0); stop_glerror(); } else { - glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, source.mFBO); + glBindFramebuffer(GL_READ_FRAMEBUFFER, source.mFBO); stop_glerror(); - glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, mFBO); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFBO); stop_glerror(); check_framebuffer_status(); stop_glerror(); - glBlitFramebufferEXT(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); + glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); stop_glerror(); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + glBindFramebuffer(GL_FRAMEBUFFER, 0); stop_glerror(); } } @@ -484,22 +509,26 @@ void LLRenderTarget::copyContentsToFramebuffer(LLRenderTarget& source, S32 srcX0 llerrs << "Cannot copy framebuffer contents for non FBO render targets." << llendl; } { - glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, source.mFBO); + GLboolean write_depth = mask & GL_DEPTH_BUFFER_BIT ? TRUE : FALSE; + + LLGLDepthTest depth(write_depth, write_depth); + + glBindFramebuffer(GL_READ_FRAMEBUFFER, source.mFBO); stop_glerror(); - glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); stop_glerror(); check_framebuffer_status(); stop_glerror(); - glBlitFramebufferEXT(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); + glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); stop_glerror(); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + glBindFramebuffer(GL_FRAMEBUFFER, 0); stop_glerror(); } } -BOOL LLRenderTarget::isComplete() const +bool LLRenderTarget::isComplete() const { - return (!mTex.empty() || mDepth) ? TRUE : FALSE; + return (!mTex.empty() || mDepth) ? true : false; } void LLRenderTarget::getViewport(S32* viewport) @@ -520,26 +549,26 @@ LLMultisampleBuffer::LLMultisampleBuffer() LLMultisampleBuffer::~LLMultisampleBuffer() { - releaseSampleBuffer(); + release(); } -void LLMultisampleBuffer::releaseSampleBuffer() +void LLMultisampleBuffer::release() { if (mFBO) { - glDeleteFramebuffersEXT(1, (GLuint *) &mFBO); + glDeleteFramebuffers(1, (GLuint *) &mFBO); mFBO = 0; } if (mTex.size() > 0) { - glDeleteRenderbuffersEXT(mTex.size(), (GLuint *) &mTex[0]); + glDeleteRenderbuffers(mTex.size(), (GLuint *) &mTex[0]); mTex.clear(); } if (mDepth) { - glDeleteRenderbuffersEXT(1, (GLuint *) &mDepth); + glDeleteRenderbuffers(1, (GLuint *) &mDepth); mDepth = 0; } } @@ -556,13 +585,13 @@ void LLMultisampleBuffer::bindTarget(LLRenderTarget* ref) ref = this; } - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBO); + glBindFramebuffer(GL_FRAMEBUFFER, mFBO); if (gGLManager.mHasDrawBuffers) { //setup multiple render targets - GLenum drawbuffers[] = {GL_COLOR_ATTACHMENT0_EXT, - GL_COLOR_ATTACHMENT1_EXT, - GL_COLOR_ATTACHMENT2_EXT, - GL_COLOR_ATTACHMENT3_EXT}; + GLenum drawbuffers[] = {GL_COLOR_ATTACHMENT0, + GL_COLOR_ATTACHMENT1, + GL_COLOR_ATTACHMENT2, + GL_COLOR_ATTACHMENT3}; glDrawBuffersARB(ref->mTex.size(), drawbuffers); } @@ -573,12 +602,12 @@ void LLMultisampleBuffer::bindTarget(LLRenderTarget* ref) sBoundTarget = this; } -void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, BOOL stencil, LLTexUnit::eTextureType usage, BOOL use_fbo ) +void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo ) { allocate(resx,resy,color_fmt,depth,stencil,usage,use_fbo,2); } -void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, BOOL stencil, LLTexUnit::eTextureType usage, BOOL use_fbo, U32 samples ) +void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo, U32 samples ) { stop_glerror(); mResX = resx; @@ -588,12 +617,7 @@ void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth mUseDepth = depth; mStencil = stencil; - releaseSampleBuffer(); - - if (!gGLManager.mHasFramebufferMultisample) - { - llerrs << "Attempting to allocate unsupported render target type!" << llendl; - } + release(); mSamples = samples; @@ -614,23 +638,21 @@ void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth stop_glerror(); } - glGenFramebuffersEXT(1, (GLuint *) &mFBO); + glGenFramebuffers(1, (GLuint *) &mFBO); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBO); + glBindFramebuffer(GL_FRAMEBUFFER, mFBO); if (mDepth) { - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mDepth); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepth); if (mStencil) { - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mDepth); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mDepth); } - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); } - + stop_glerror(); - - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + glBindFramebuffer(GL_FRAMEBUFFER, 0); stop_glerror(); } @@ -652,30 +674,28 @@ void LLMultisampleBuffer::addColorAttachment(U32 color_fmt) } U32 tex; - glGenRenderbuffersEXT(1, &tex); + glGenRenderbuffers(1, &tex); - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, tex); - glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, mSamples, color_fmt, mResX, mResY); + glBindRenderbuffer(GL_RENDERBUFFER, tex); + glRenderbufferStorageMultisample(GL_RENDERBUFFER, mSamples, color_fmt, mResX, mResY); stop_glerror(); if (mFBO) { - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBO); - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT+offset, GL_RENDERBUFFER_EXT, tex); + glBindFramebuffer(GL_FRAMEBUFFER, mFBO); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+offset, GL_RENDERBUFFER, tex); stop_glerror(); - GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); switch (status) { - case GL_FRAMEBUFFER_COMPLETE_EXT: - break; - case GL_FRAMEBUFFER_UNSUPPORTED_EXT: - llerrs << "WTF?" << llendl; + case GL_FRAMEBUFFER_COMPLETE: break; default: - llerrs << "WTF?" << llendl; + llerrs << "WTF? " << std::hex << status << llendl; + break; } - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + glBindFramebuffer(GL_FRAMEBUFFER, 0); } mTex.push_back(tex); @@ -683,15 +703,15 @@ void LLMultisampleBuffer::addColorAttachment(U32 color_fmt) void LLMultisampleBuffer::allocateDepth() { - glGenRenderbuffersEXT(1, (GLuint* ) &mDepth); - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, mDepth); + glGenRenderbuffers(1, (GLuint* ) &mDepth); + glBindRenderbuffer(GL_RENDERBUFFER, mDepth); if (mStencil) { - glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, mSamples, GL_DEPTH24_STENCIL8_EXT, mResX, mResY); + glRenderbufferStorageMultisample(GL_RENDERBUFFER, mSamples, GL_DEPTH24_STENCIL8, mResX, mResY); } else { - glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, mSamples, GL_DEPTH_COMPONENT16_ARB, mResX, mResY); + glRenderbufferStorageMultisample(GL_RENDERBUFFER, mSamples, GL_DEPTH_COMPONENT16, mResX, mResY); } } diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h index ae8613d9be..12dd1c8b90 100644 --- a/indra/llrender/llrendertarget.h +++ b/indra/llrender/llrendertarget.h @@ -63,7 +63,7 @@ class LLRenderTarget { public: //whether or not to use FBO implementation - static BOOL sUseFBO; + static bool sUseFBO; LLRenderTarget(); virtual ~LLRenderTarget(); @@ -71,7 +71,7 @@ public: //allocate resources for rendering //must be called before use //multiple calls will release previously allocated resources - void allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, BOOL stencil, LLTexUnit::eTextureType usage = LLTexUnit::TT_TEXTURE, BOOL use_fbo = FALSE); + void allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage = LLTexUnit::TT_TEXTURE, bool use_fbo = FALSE); //provide this render target with a multisample resource. void setSampleBuffer(LLMultisampleBuffer* buffer); @@ -88,7 +88,7 @@ public: //free any allocated resources //safe to call redundantly - void release(); + virtual void release(); //bind target for rendering //applies appropriate viewport @@ -115,7 +115,7 @@ public: U32 getTexture(U32 attachment = 0) const; U32 getDepth(void) const { return mDepth; } - BOOL hasStencil() const { return mStencil; } + bool hasStencil() const { return mStencil; } void bindTexture(U32 index, S32 channel); @@ -125,7 +125,7 @@ public: // call bindTarget once, do all your rendering, call flush once // if fetch_depth is TRUE, every effort will be made to copy the depth buffer into // the current depth texture. A depth texture will be allocated if needed. - void flush(BOOL fetch_depth = FALSE); + void flush(bool fetch_depth = FALSE); void copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0, S32 srcX1, S32 srcY1, S32 dstX0, S32 dstY0, S32 dstX1, S32 dstY1, U32 mask, U32 filter); @@ -136,7 +136,7 @@ public: //Returns TRUE if target is ready to be rendered into. //That is, if the target has been allocated with at least //one renderable attachment (i.e. color buffer, depth buffer). - BOOL isComplete() const; + bool isComplete() const; static LLRenderTarget* getCurrentBoundTarget() { return sBoundTarget; } @@ -147,9 +147,9 @@ protected: std::vector<U32> mTex; U32 mFBO; U32 mDepth; - BOOL mStencil; - BOOL mUseDepth; - BOOL mRenderDepth; + bool mStencil; + bool mUseDepth; + bool mRenderDepth; LLTexUnit::eTextureType mUsage; U32 mSamples; LLMultisampleBuffer* mSampleBuffer; @@ -164,12 +164,12 @@ public: LLMultisampleBuffer(); virtual ~LLMultisampleBuffer(); - void releaseSampleBuffer(); + virtual void release(); virtual void bindTarget(); void bindTarget(LLRenderTarget* ref); - virtual void allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, BOOL stencil, LLTexUnit::eTextureType usage, BOOL use_fbo); - void allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, BOOL stencil, LLTexUnit::eTextureType usage, BOOL use_fbo, U32 samples); + virtual void allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo); + void allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo, U32 samples); virtual void addColorAttachment(U32 color_fmt); virtual void allocateDepth(); }; diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index c859d41e17..21b02fdb71 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -146,6 +146,14 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader) return FALSE; } } + + if (features->hasObjectSkinning) + { + if (!shader->attachObject("avatar/objectSkinV.glsl")) + { + return FALSE; + } + } /////////////////////////////////////// // Attach Fragment Shader Features Next @@ -220,7 +228,14 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader) else if (features->isFullbright) { - if (features->hasWaterFog) + if (features->isShiny && features->hasWaterFog) + { + if (!shader->attachObject("lighting/lightFullbrightShinyWaterF.glsl")) + { + return FALSE; + } + } + else if (features->hasWaterFog) { if (!shader->attachObject("lighting/lightFullbrightWaterF.glsl")) { @@ -307,11 +322,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; @@ -366,31 +384,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++) { @@ -401,13 +427,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 71bdca60e5..7a1ccb0cb4 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -25,6 +25,7 @@ */ #include "linden_common.h" +#include "llmemory.h" #include <boost/static_assert.hpp> #include "llsys.h" @@ -33,6 +34,7 @@ #include "llglheaders.h" #include "llmemtype.h" #include "llrender.h" +#include "llvector4a.h" //============================================================================ @@ -57,20 +59,24 @@ BOOL LLVertexBuffer::sIBOActive = FALSE; 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; -S32 LLVertexBuffer::sTypeOffsets[LLVertexBuffer::TYPE_MAX] = + +S32 LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_MAX] = { - sizeof(LLVector3), // TYPE_VERTEX, - sizeof(LLVector3), // TYPE_NORMAL, + sizeof(LLVector4), // TYPE_VERTEX, + sizeof(LLVector4), // TYPE_NORMAL, sizeof(LLVector2), // TYPE_TEXCOORD0, sizeof(LLVector2), // TYPE_TEXCOORD1, sizeof(LLVector2), // TYPE_TEXCOORD2, sizeof(LLVector2), // TYPE_TEXCOORD3, sizeof(LLColor4U), // TYPE_COLOR, - sizeof(LLVector3), // TYPE_BINORMAL, + sizeof(LLVector4), // TYPE_BINORMAL, sizeof(F32), // TYPE_WEIGHT, + sizeof(LLVector4), // TYPE_WEIGHT4, sizeof(LLVector4), // TYPE_CLOTHWEIGHT, }; @@ -139,11 +145,11 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask) } else { //was disabled - if (data_mask & mask[i]) + if (data_mask & mask[i] && i > 0) { //needs to be enabled glEnableClientState(array[i]); } - else if (gDebugGL && glIsEnabled(array[i])) + else if (gDebugGL && i > 0 && glIsEnabled(array[i])) { //needs to be disabled, make sure it was (DEBUG TEMPORARY) if (gDebugSession) { @@ -205,18 +211,37 @@ 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; } } -void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const +void LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_offset) const { - llassert(mRequestedNumVerts >= 0); - if (start >= (U32) mRequestedNumVerts || end >= (U32) mRequestedNumVerts) { - llerrs << "Bad vertex buffer draw range: [" << start << ", " << end << "]" << llendl; + llerrs << "Bad vertex buffer draw range: [" << start << ", " << end << "] vs " << mRequestedNumVerts << llendl; } llassert(mRequestedNumIndices >= 0); @@ -227,6 +252,25 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi llerrs << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << llendl; } + if (gDebugGL && !useVBOs()) + { + U16* idx = ((U16*) getIndicesPointer())+indices_offset; + 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; + } + } + } +} + +void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const +{ + validateRange(start, end, count, indices_offset); + + llassert(mRequestedNumVerts >= 0); + if (mGLIndices != sGLRenderIndices) { llerrs << "Wrong index buffer bound." << llendl; @@ -243,9 +287,11 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi return; } + U16* idx = ((U16*) getIndicesPointer())+indices_offset; + stop_glerror(); glDrawRangeElements(sGLMode[mode], start, end, count, GL_UNSIGNED_SHORT, - ((U16*) getIndicesPointer()) + indices_offset); + idx); stop_glerror(); } @@ -386,22 +432,29 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) : mUsage = 0; } - if (mUsage == GL_STREAM_DRAW_ARB && !sUseStreamDraw) + if (mUsage == GL_DYNAMIC_DRAW_ARB && sPreferStreamDraw) { - mUsage = 0; + mUsage = GL_STREAM_DRAW_ARB; } - S32 stride = calcStride(typemask, mOffsets); + //zero out offsets + for (U32 i = 0; i < TYPE_MAX; i++) + { + mOffsets[i] = 0; + } mTypeMask = typemask; - mStride = stride; + mSize = 0; + mAlignedOffset = 0; + mAlignedIndexOffset = 0; + sCount++; } //static -S32 LLVertexBuffer::calcStride(const U32& typemask, S32* offsets) +S32 LLVertexBuffer::calcOffsets(const U32& typemask, S32* offsets, S32 num_vertices) { - S32 stride = 0; + S32 offset = 0; for (S32 i=0; i<TYPE_MAX; i++) { U32 mask = 1<<i; @@ -409,13 +462,35 @@ S32 LLVertexBuffer::calcStride(const U32& typemask, S32* offsets) { if (offsets) { - offsets[i] = stride; + offsets[i] = offset; + offset += LLVertexBuffer::sTypeSize[i]*num_vertices; + offset = (offset + 0xF) & ~0xF; } - stride += sTypeOffsets[i]; } } - return stride; + return offset+16; +} + +//static +S32 LLVertexBuffer::calcVertexSize(const U32& typemask) +{ + S32 size = 0; + for (S32 i = 0; i < TYPE_MAX; i++) + { + U32 mask = 1<<i; + if (typemask & mask) + { + size += LLVertexBuffer::sTypeSize[i]; + } + } + + return size; +} + +S32 LLVertexBuffer::getSize() const +{ + return mSize; } // protected, use unref() @@ -529,8 +604,7 @@ void LLVertexBuffer::createGLBuffer() { static int gl_buffer_idx = 0; mGLBuffer = ++gl_buffer_idx; - mMappedData = new U8[size]; - memset(mMappedData, 0, size); + mMappedData = (U8*) malloc(size); } } @@ -551,16 +625,20 @@ void LLVertexBuffer::createGLIndices() mEmpty = TRUE; + //pad by 16 bytes for aligned copies + size += 16; + if (useVBOs()) { + //pad by another 16 bytes for VBO pointer adjustment + size += 16; mMappedIndexData = NULL; genIndices(); mResized = TRUE; } else { - mMappedIndexData = new U8[size]; - memset(mMappedIndexData, 0, size); + mMappedIndexData = (U8*) malloc(size); static int gl_buffer_idx = 0; mGLIndices = ++gl_buffer_idx; } @@ -583,7 +661,7 @@ void LLVertexBuffer::destroyGLBuffer() } else { - delete [] mMappedData; + free(mMappedData); mMappedData = NULL; mEmpty = TRUE; } @@ -592,7 +670,7 @@ void LLVertexBuffer::destroyGLBuffer() } mGLBuffer = 0; - unbind(); + //unbind(); } void LLVertexBuffer::destroyGLIndices() @@ -612,7 +690,7 @@ void LLVertexBuffer::destroyGLIndices() } else { - delete [] mMappedIndexData; + free(mMappedIndexData); mMappedIndexData = NULL; mEmpty = TRUE; } @@ -621,7 +699,7 @@ void LLVertexBuffer::destroyGLIndices() } mGLIndices = 0; - unbind(); + //unbind(); } void LLVertexBuffer::updateNumVerts(S32 nverts) @@ -637,7 +715,7 @@ void LLVertexBuffer::updateNumVerts(S32 nverts) } mRequestedNumVerts = nverts; - + if (!mDynamicSize) { mNumVerts = nverts; @@ -652,7 +730,7 @@ void LLVertexBuffer::updateNumVerts(S32 nverts) } mNumVerts = nverts; } - + mSize = calcOffsets(mTypeMask, mOffsets, mNumVerts); } void LLVertexBuffer::updateNumIndices(S32 nindices) @@ -683,6 +761,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); @@ -721,9 +805,6 @@ void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices) { sAllocatedBytes -= getSize() + getIndicesSize(); - S32 oldsize = getSize(); - S32 old_index_size = getIndicesSize(); - updateNumVerts(newnverts); updateNumIndices(newnindices); @@ -740,26 +821,10 @@ void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices) } else { - //delete old buffer, keep GL buffer for now if (!useVBOs()) { - U8* old = mMappedData; - mMappedData = new U8[newsize]; - if (old) - { - memcpy(mMappedData, old, llmin(newsize, oldsize)); - if (newsize > oldsize) - { - memset(mMappedData+oldsize, 0, newsize-oldsize); - } - - delete [] old; - } - else - { - memset(mMappedData, 0, newsize); - mEmpty = TRUE; - } + free(mMappedData); + mMappedData = (U8*) malloc(newsize); } mResized = TRUE; } @@ -779,24 +844,8 @@ void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices) { if (!useVBOs()) { - //delete old buffer, keep GL buffer for now - U8* old = mMappedIndexData; - mMappedIndexData = new U8[new_index_size]; - - if (old) - { - memcpy(mMappedIndexData, old, llmin(new_index_size, old_index_size)); - if (new_index_size > old_index_size) - { - memset(mMappedIndexData+old_index_size, 0, new_index_size - old_index_size); - } - delete [] old; - } - else - { - memset(mMappedIndexData, 0, new_index_size); - mEmpty = TRUE; - } + free(mMappedIndexData); + mMappedIndexData = (U8*) malloc(new_index_size); } mResized = TRUE; } @@ -897,6 +946,9 @@ U8* LLVertexBuffer::mapBuffer(S32 access) } { LLMemType mt_v(LLMemType::MTYPE_VERTEX_MAP_BUFFER_INDICES); + U8* src = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); + mMappedIndexData = LL_NEXT_ALIGNED_ADDRESS<U8>(src); + mAlignedIndexOffset = mMappedIndexData - src; if(sDisableVBOMapping) { @@ -1060,8 +1112,8 @@ template <class T,S32 type> struct VertexBufferStrider } else if (vbo.hasDataType(type)) { - S32 stride = vbo.getStride(); - strider = (T*)(vbo.getMappedData() + vbo.getOffset(type) + index*stride); + S32 stride = LLVertexBuffer::sTypeSize[type]; + strider = (T*)(vbo.getMappedData() + vbo.getOffset(type)+index*stride); strider.setStride(stride); return TRUE; } @@ -1073,7 +1125,6 @@ template <class T,S32 type> struct VertexBufferStrider } }; - bool LLVertexBuffer::getVertexStrider(LLStrider<LLVector3>& strider, S32 index) { return VertexBufferStrider<LLVector3,TYPE_VERTEX>::get(*this, strider, index); @@ -1114,28 +1165,15 @@ bool LLVertexBuffer::getWeightStrider(LLStrider<F32>& strider, S32 index) { return VertexBufferStrider<F32,TYPE_WEIGHT>::get(*this, strider, index); } -bool LLVertexBuffer::getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index) + +bool LLVertexBuffer::getWeight4Strider(LLStrider<LLVector4>& strider, S32 index) { - return VertexBufferStrider<LLVector4,TYPE_CLOTHWEIGHT>::get(*this, strider, index); + return VertexBufferStrider<LLVector4,TYPE_WEIGHT4>::get(*this, strider, index); } -void LLVertexBuffer::setStride(S32 type, S32 new_stride) +bool LLVertexBuffer::getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index) { - LLMemType mt2(LLMemType::MTYPE_VERTEX_SET_STRIDE); - if (mNumVerts) - { - llerrs << "LLVertexBuffer::setOffset called with mNumVerts = " << mNumVerts << llendl; - } - // This code assumes that setStride() will only be called once per VBO per type. - S32 delta = new_stride - sTypeOffsets[type]; - for (S32 i=type+1; i<TYPE_MAX; i++) - { - if (mTypeMask & (1<<i)) - { - mOffsets[i] += delta; - } - } - mStride += delta; + return VertexBufferStrider<LLVector4,TYPE_CLOTHWEIGHT>::get(*this, strider, index); } //---------------------------------------------------------------------------- @@ -1334,8 +1372,7 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const { LLMemType mt2(LLMemType::MTYPE_VERTEX_SETUP_VERTEX_BUFFER); stop_glerror(); - U8* base = useVBOs() ? NULL : mMappedData; - S32 stride = mStride; + U8* base = useVBOs() ? (U8*) mAlignedOffset : mMappedData; if ((data_mask & mTypeMask) != data_mask) { @@ -1344,52 +1381,58 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const if (data_mask & MAP_NORMAL) { - glNormalPointer(GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_NORMAL])); + 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, stride, (void*)(base + mOffsets[TYPE_TEXCOORD3])); + 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, stride, (void*)(base + mOffsets[TYPE_TEXCOORD2])); + 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, stride, (void*)(base + mOffsets[TYPE_TEXCOORD1])); + 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, stride, (void*)(base + mOffsets[TYPE_BINORMAL])); + 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, stride, (void*)(base + mOffsets[TYPE_TEXCOORD0])); + glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], (void*)(base + mOffsets[TYPE_TEXCOORD0])); } if (data_mask & MAP_COLOR) { - glColorPointer(4, GL_UNSIGNED_BYTE, stride, (void*)(base + mOffsets[TYPE_COLOR])); + glColorPointer(4, GL_UNSIGNED_BYTE, LLVertexBuffer::sTypeSize[TYPE_COLOR], (void*)(base + mOffsets[TYPE_COLOR])); } if (data_mask & MAP_WEIGHT) { - glVertexAttribPointerARB(1, 1, GL_FLOAT, FALSE, stride, (void*)(base + mOffsets[TYPE_WEIGHT])); + glVertexAttribPointerARB(1, 1, GL_FLOAT, FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT], (void*)(base + mOffsets[TYPE_WEIGHT])); } + + if (data_mask & MAP_WEIGHT4 && sWeight4Loc != -1) + { + glVertexAttribPointerARB(sWeight4Loc, 4, GL_FLOAT, FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT4], (void*)(base+mOffsets[TYPE_WEIGHT4])); + } + if (data_mask & MAP_CLOTHWEIGHT) { - glVertexAttribPointerARB(4, 4, GL_FLOAT, TRUE, stride, (void*)(base + mOffsets[TYPE_CLOTHWEIGHT])); + glVertexAttribPointerARB(4, 4, GL_FLOAT, TRUE, LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], (void*)(base + mOffsets[TYPE_CLOTHWEIGHT])); } if (data_mask & MAP_VERTEX) { - glVertexPointer(3,GL_FLOAT, stride, (void*)(base + 0)); + glVertexPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0)); } llglassertok(); diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index 09a16d5b9d..fb81720c86 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -1,262 +1,286 @@ -/** - * @file llvertexbuffer.h - * @brief LLVertexBuffer wrapper for OpengGL vertex buffer objects - * - * $LicenseInfo:firstyear=2003&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#ifndef LL_LLVERTEXBUFFER_H -#define LL_LLVERTEXBUFFER_H - -#include "llgl.h" -#include "v2math.h" -#include "v3math.h" -#include "v4math.h" -#include "v4coloru.h" -#include "llstrider.h" -#include "llrender.h" -#include <set> -#include <vector> -#include <list> - -//============================================================================ -// NOTES -// Threading: -// All constructors should take an 'create' paramater which should only be -// 'true' when called from the main thread. Otherwise createGLBuffer() will -// be called as soon as getVertexPointer(), etc is called (which MUST ONLY be -// called from the main (i.e OpenGL) thread) - - -//============================================================================ -// gl name pools for dynamic and streaming buffers - -class LLVBOPool : public LLGLNamePool -{ -protected: - virtual GLuint allocateName() - { - GLuint name; - glGenBuffersARB(1, &name); - return name; - } - - virtual void releaseName(GLuint name) - { - glDeleteBuffersARB(1, &name); - } -}; - - -//============================================================================ -// base class - -class LLVertexBuffer : public LLRefCount -{ -public: - static LLVBOPool sStreamVBOPool; - static LLVBOPool sDynamicVBOPool; - static LLVBOPool sStreamIBOPool; - static LLVBOPool sDynamicIBOPool; - - static BOOL sUseStreamDraw; - - static void initClass(bool use_vbo, bool no_vbo_mapping); - static void cleanupClass(); - static void setupClientArrays(U32 data_mask); - static void clientCopy(F64 max_time = 0.005); //copy data from client to GL - static void unbind(); //unbind any bound vertex buffer - - //get the size of a vertex with the given typemask - //if offsets is not NULL, its contents will be filled - //with the offset of each vertex component in the buffer, - // indexed by the following enum - static S32 calcStride(const U32& typemask, S32* offsets = NULL); - - enum { - TYPE_VERTEX, - TYPE_NORMAL, - TYPE_TEXCOORD0, - TYPE_TEXCOORD1, - TYPE_TEXCOORD2, - TYPE_TEXCOORD3, - TYPE_COLOR, - // These use VertexAttribPointer and should possibly be made generic - TYPE_BINORMAL, - TYPE_WEIGHT, - TYPE_CLOTHWEIGHT, - TYPE_MAX, - TYPE_INDEX, - }; - enum { - MAP_VERTEX = (1<<TYPE_VERTEX), - MAP_NORMAL = (1<<TYPE_NORMAL), - MAP_TEXCOORD0 = (1<<TYPE_TEXCOORD0), - MAP_TEXCOORD1 = (1<<TYPE_TEXCOORD1), - MAP_TEXCOORD2 = (1<<TYPE_TEXCOORD2), - MAP_TEXCOORD3 = (1<<TYPE_TEXCOORD3), - MAP_COLOR = (1<<TYPE_COLOR), - // These use VertexAttribPointer and should possibly be made generic - MAP_BINORMAL = (1<<TYPE_BINORMAL), - MAP_WEIGHT = (1<<TYPE_WEIGHT), - MAP_CLOTHWEIGHT = (1<<TYPE_CLOTHWEIGHT), - }; - -protected: - friend class LLRender; - - virtual ~LLVertexBuffer(); // use unref() - - virtual void setupVertexBuffer(U32 data_mask) const; // pure virtual, called from mapBuffer() - - void genBuffer(); - void genIndices(); - void releaseBuffer(); - void releaseIndices(); - void createGLBuffer(); - void createGLIndices(); - void destroyGLBuffer(); - void destroyGLIndices(); - void updateNumVerts(S32 nverts); - void updateNumIndices(S32 nindices); - virtual BOOL useVBOs() const; - void unmapBuffer(); - -public: - LLVertexBuffer(U32 typemask, S32 usage); - - // map for data access - U8* mapBuffer(S32 access = -1); - // set for rendering - virtual void setBuffer(U32 data_mask); // calls setupVertexBuffer() if data_mask is not 0 - // allocate buffer - void allocateBuffer(S32 nverts, S32 nindices, bool create); - virtual void resizeBuffer(S32 newnverts, S32 newnindices); - - void freeClientBuffer() ; - void allocateClientVertexBuffer() ; - void allocateClientIndexBuffer() ; - - // Only call each getVertexPointer, etc, once before calling unmapBuffer() - // call unmapBuffer() after calls to getXXXStrider() before any cals to setBuffer() - // example: - // vb->getVertexBuffer(verts); - // vb->getNormalStrider(norms); - // setVertsNorms(verts, norms); - // vb->unmapBuffer(); - bool getVertexStrider(LLStrider<LLVector3>& strider, S32 index=0); - bool getIndexStrider(LLStrider<U16>& strider, S32 index=0); - bool getTexCoord0Strider(LLStrider<LLVector2>& strider, S32 index=0); - bool getTexCoord1Strider(LLStrider<LLVector2>& strider, S32 index=0); - bool getNormalStrider(LLStrider<LLVector3>& strider, S32 index=0); - 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 getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index=0); - - BOOL isEmpty() const { return mEmpty; } - BOOL isLocked() const { return mLocked; } - S32 getNumVerts() const { return mNumVerts; } - S32 getNumIndices() const { return mNumIndices; } - S32 getRequestedVerts() const { return mRequestedNumVerts; } - S32 getRequestedIndices() const { return mRequestedNumIndices; } - - U8* getIndicesPointer() const { return useVBOs() ? NULL : mMappedIndexData; } - U8* getVerticesPointer() const { return useVBOs() ? NULL : mMappedData; } - S32 getStride() const { return mStride; } - S32 getTypeMask() const { return mTypeMask; } - BOOL hasDataType(S32 type) const { return ((1 << type) & getTypeMask()) ? TRUE : FALSE; } - S32 getSize() const { return mNumVerts*mStride; } - S32 getIndicesSize() const { return mNumIndices * sizeof(U16); } - U8* getMappedData() const { return mMappedData; } - U8* getMappedIndices() const { return mMappedIndexData; } - S32 getOffset(S32 type) const { return mOffsets[type]; } - S32 getUsage() const { return mUsage; } - - void setStride(S32 type, S32 new_stride); - - void markDirty(U32 vert_index, U32 vert_count, U32 indices_index, U32 indices_count); - - void draw(U32 mode, U32 count, U32 indices_offset) const; - void drawArrays(U32 mode, U32 offset, U32 count) const; - void drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const; - -protected: - S32 mNumVerts; // Number of vertices allocated - S32 mNumIndices; // Number of indices allocated - S32 mRequestedNumVerts; // Number of vertices requested - S32 mRequestedNumIndices; // Number of indices requested - - S32 mStride; - U32 mTypeMask; - S32 mUsage; // GL usage - U32 mGLBuffer; // GL VBO handle - U32 mGLIndices; // GL IBO handle - U8* mMappedData; // pointer to currently mapped data (NULL if unmapped) - U8* mMappedIndexData; // pointer to currently mapped indices (NULL if unmapped) - BOOL mLocked; // if TRUE, buffer is being or has been written to in client memory - BOOL mFinal; // if TRUE, buffer can not be mapped again - BOOL mFilthy; // if TRUE, entire buffer must be copied (used to prevent redundant dirty flags) - BOOL mEmpty; // if TRUE, client buffer is empty (or NULL). Old values have been discarded. - S32 mOffsets[TYPE_MAX]; - BOOL mResized; // if TRUE, client buffer has been resized and GL buffer has not - BOOL mDynamicSize; // if TRUE, buffer has been resized at least once (and should be padded) - - class DirtyRegion - { - public: - U32 mIndex; - U32 mCount; - U32 mIndicesIndex; - U32 mIndicesCount; - - DirtyRegion(U32 vi, U32 vc, U32 ii, U32 ic) - : mIndex(vi), mCount(vc), mIndicesIndex(ii), mIndicesCount(ic) - { } - }; - - std::vector<DirtyRegion> mDirtyRegions; //vector of dirty regions to rebuild - -public: - static S32 sCount; - static S32 sGLCount; - static S32 sMappedCount; - static BOOL sMapped; - static std::vector<U32> sDeleteList; - typedef std::list<LLVertexBuffer*> buffer_list_t; - - static BOOL sDisableVBOMapping; //disable glMapBufferARB - static BOOL sEnableVBOs; - static BOOL sVBOActive; - static BOOL sIBOActive; - static S32 sTypeOffsets[TYPE_MAX]; - static U32 sGLMode[LLRender::NUM_MODES]; - static U32 sGLRenderBuffer; - static U32 sGLRenderIndices; - static U32 sLastMask; - static U32 sAllocatedBytes; - static U32 sBindCount; - static U32 sSetCount; -}; - - -#endif // LL_LLVERTEXBUFFER_H +/**
+ * @file llvertexbuffer.h
+ * @brief LLVertexBuffer wrapper for OpengGL vertex buffer objects
+ *
+ * $LicenseInfo:firstyear=2003&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLVERTEXBUFFER_H
+#define LL_LLVERTEXBUFFER_H
+
+#include "llgl.h"
+#include "v2math.h"
+#include "v3math.h"
+#include "v4math.h"
+#include "v4coloru.h"
+#include "llstrider.h"
+#include "llrender.h"
+#include <set>
+#include <vector>
+#include <list>
+
+//============================================================================
+// NOTES
+// Threading:
+// All constructors should take an 'create' paramater which should only be
+// 'true' when called from the main thread. Otherwise createGLBuffer() will
+// be called as soon as getVertexPointer(), etc is called (which MUST ONLY be
+// called from the main (i.e OpenGL) thread)
+
+
+//============================================================================
+// gl name pools for dynamic and streaming buffers
+
+class LLVBOPool : public LLGLNamePool
+{
+protected:
+ virtual GLuint allocateName()
+ {
+ GLuint name;
+ glGenBuffersARB(1, &name);
+ return name;
+ }
+
+ virtual void releaseName(GLuint name)
+ {
+ glDeleteBuffersARB(1, &name);
+ }
+};
+
+
+//============================================================================
+// base class
+
+class LLVertexBuffer : public LLRefCount
+{
+public:
+ LLVertexBuffer(const LLVertexBuffer& rhs)
+ {
+ *this = rhs;
+ }
+
+ const LLVertexBuffer& operator=(const LLVertexBuffer& rhs)
+ {
+ llerrs << "Illegal operation!" << llendl;
+ return *this;
+ }
+
+ static LLVBOPool sStreamVBOPool;
+ static LLVBOPool sDynamicVBOPool;
+ static LLVBOPool sStreamIBOPool;
+ static LLVBOPool sDynamicIBOPool;
+
+ static S32 sWeight4Loc;
+
+ static BOOL sUseStreamDraw;
+ static BOOL sPreferStreamDraw;
+
+ static void initClass(bool use_vbo, bool no_vbo_mapping);
+ static void cleanupClass();
+ static void setupClientArrays(U32 data_mask);
+ static void clientCopy(F64 max_time = 0.005); //copy data from client to GL
+ static void unbind(); //unbind any bound vertex buffer
+
+ //get the size of a vertex with the given typemask
+ static S32 calcVertexSize(const U32& typemask);
+
+ //get the size of a buffer with the given typemask and vertex count
+ //fill offsets with the offset of each vertex component array into the buffer
+ // indexed by the following enum
+ static S32 calcOffsets(const U32& typemask, S32* offsets, S32 num_vertices);
+
+
+ enum {
+ TYPE_VERTEX,
+ TYPE_NORMAL,
+ TYPE_TEXCOORD0,
+ TYPE_TEXCOORD1,
+ TYPE_TEXCOORD2,
+ TYPE_TEXCOORD3,
+ TYPE_COLOR,
+ // These use VertexAttribPointer and should possibly be made generic
+ TYPE_BINORMAL,
+ TYPE_WEIGHT,
+ TYPE_WEIGHT4,
+ TYPE_CLOTHWEIGHT,
+ TYPE_MAX,
+ TYPE_INDEX,
+ };
+ enum {
+ MAP_VERTEX = (1<<TYPE_VERTEX),
+ MAP_NORMAL = (1<<TYPE_NORMAL),
+ MAP_TEXCOORD0 = (1<<TYPE_TEXCOORD0),
+ MAP_TEXCOORD1 = (1<<TYPE_TEXCOORD1),
+ MAP_TEXCOORD2 = (1<<TYPE_TEXCOORD2),
+ MAP_TEXCOORD3 = (1<<TYPE_TEXCOORD3),
+ MAP_COLOR = (1<<TYPE_COLOR),
+ // 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),
+ };
+
+protected:
+ friend class LLRender;
+
+ virtual ~LLVertexBuffer(); // use unref()
+
+ virtual void setupVertexBuffer(U32 data_mask) const; // pure virtual, called from mapBuffer()
+
+ void genBuffer();
+ void genIndices();
+ void releaseBuffer();
+ void releaseIndices();
+ void createGLBuffer();
+ void createGLIndices();
+ void destroyGLBuffer();
+ void destroyGLIndices();
+ void updateNumVerts(S32 nverts);
+ void updateNumIndices(S32 nindices);
+ virtual BOOL useVBOs() const;
+ void unmapBuffer();
+
+public:
+ LLVertexBuffer(U32 typemask, S32 usage);
+
+ // map for data access
+ U8* mapBuffer(S32 access = -1);
+ // set for rendering
+ virtual void setBuffer(U32 data_mask); // calls setupVertexBuffer() if data_mask is not 0
+ // allocate buffer
+ void allocateBuffer(S32 nverts, S32 nindices, bool create);
+ virtual void resizeBuffer(S32 newnverts, S32 newnindices);
+
+ void freeClientBuffer() ;
+ void allocateClientVertexBuffer() ;
+ void allocateClientIndexBuffer() ;
+
+ // Only call each getVertexPointer, etc, once before calling unmapBuffer()
+ // call unmapBuffer() after calls to getXXXStrider() before any cals to setBuffer()
+ // example:
+ // vb->getVertexBuffer(verts);
+ // vb->getNormalStrider(norms);
+ // setVertsNorms(verts, norms);
+ // vb->unmapBuffer();
+ bool getVertexStrider(LLStrider<LLVector3>& strider, S32 index=0);
+ bool getIndexStrider(LLStrider<U16>& strider, S32 index=0);
+ bool getTexCoord0Strider(LLStrider<LLVector2>& strider, S32 index=0);
+ bool getTexCoord1Strider(LLStrider<LLVector2>& strider, S32 index=0);
+ bool getNormalStrider(LLStrider<LLVector3>& strider, S32 index=0);
+ 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; }
+ BOOL isLocked() const { return mLocked; }
+ S32 getNumVerts() const { return mNumVerts; }
+ S32 getNumIndices() const { return mNumIndices; }
+ S32 getRequestedVerts() const { return mRequestedNumVerts; }
+ S32 getRequestedIndices() const { return mRequestedNumIndices; }
+
+ U8* getIndicesPointer() const { return useVBOs() ? (U8*) mAlignedIndexOffset : mMappedIndexData; }
+ U8* getVerticesPointer() const { return useVBOs() ? (U8*) mAlignedOffset : mMappedData; }
+ U32 getTypeMask() const { return mTypeMask; }
+ bool hasDataType(S32 type) const { return ((1 << type) & getTypeMask()); }
+ S32 getSize() const;
+ S32 getIndicesSize() const { return mNumIndices * sizeof(U16); }
+ U8* getMappedData() const { return mMappedData; }
+ U8* getMappedIndices() const { return mMappedIndexData; }
+ S32 getOffset(S32 type) const { return mOffsets[type]; }
+ S32 getUsage() const { return mUsage; }
+
+ void markDirty(U32 vert_index, U32 vert_count, U32 indices_index, U32 indices_count);
+
+ void draw(U32 mode, U32 count, U32 indices_offset) const;
+ void drawArrays(U32 mode, U32 offset, U32 count) const;
+ void drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const;
+
+ //for debugging, validate data in given range is valid
+ void validateRange(U32 start, U32 end, U32 count, U32 offset) const;
+
+
+
+protected:
+ S32 mNumVerts; // Number of vertices allocated
+ S32 mNumIndices; // Number of indices allocated
+ S32 mRequestedNumVerts; // Number of vertices requested
+ S32 mRequestedNumIndices; // Number of indices requested
+
+ ptrdiff_t mAlignedOffset;
+ ptrdiff_t mAlignedIndexOffset;
+ S32 mSize;
+ U32 mTypeMask;
+ S32 mUsage; // GL usage
+ U32 mGLBuffer; // GL VBO handle
+ U32 mGLIndices; // GL IBO handle
+ U8* mMappedData; // pointer to currently mapped data (NULL if unmapped)
+ U8* mMappedIndexData; // pointer to currently mapped indices (NULL if unmapped)
+ BOOL mLocked; // if TRUE, buffer is being or has been written to in client memory
+ BOOL mFinal; // if TRUE, buffer can not be mapped again
+ BOOL mFilthy; // if TRUE, entire buffer must be copied (used to prevent redundant dirty flags)
+ BOOL mEmpty; // if TRUE, client buffer is empty (or NULL). Old values have been discarded.
+ S32 mOffsets[TYPE_MAX];
+ BOOL mResized; // if TRUE, client buffer has been resized and GL buffer has not
+ BOOL mDynamicSize; // if TRUE, buffer has been resized at least once (and should be padded)
+
+ class DirtyRegion
+ {
+ public:
+ U32 mIndex;
+ U32 mCount;
+ U32 mIndicesIndex;
+ U32 mIndicesCount;
+
+ DirtyRegion(U32 vi, U32 vc, U32 ii, U32 ic)
+ : mIndex(vi), mCount(vc), mIndicesIndex(ii), mIndicesCount(ic)
+ { }
+ };
+
+ std::vector<DirtyRegion> mDirtyRegions; //vector of dirty regions to rebuild
+
+public:
+ static S32 sCount;
+ static S32 sGLCount;
+ static S32 sMappedCount;
+ static BOOL sMapped;
+ static std::vector<U32> sDeleteList;
+ typedef std::list<LLVertexBuffer*> buffer_list_t;
+
+ static BOOL sDisableVBOMapping; //disable glMapBufferARB
+ static BOOL sEnableVBOs;
+ static S32 sTypeSize[TYPE_MAX];
+ static BOOL sVBOActive;
+ static BOOL sIBOActive;
+ static U32 sGLMode[LLRender::NUM_MODES];
+ static U32 sGLRenderBuffer;
+ static U32 sGLRenderIndices;
+ static U32 sLastMask;
+ static U32 sAllocatedBytes;
+ static U32 sBindCount;
+ static U32 sSetCount;
+};
+
+
+#endif // LL_LLVERTEXBUFFER_H
|