diff options
author | Steven Bennetts <steve@lindenlab.com> | 2008-06-06 22:43:38 +0000 |
---|---|---|
committer | Steven Bennetts <steve@lindenlab.com> | 2008-06-06 22:43:38 +0000 |
commit | ad332810078a0bbb8fa08fcbfdf3d756de6914f6 (patch) | |
tree | 1608b2db5d620d323673607ea7ddadfba9d58bda /indra/llrender | |
parent | a7d9a543e587ffe84b355db7a2e8193bfe6c68b6 (diff) |
QAR-650 - Viewer RC 9 merge -> release (post cmake)
merge release@88802 Branch_1-20-Viewer-2-merge-1@89178 -> release
Diffstat (limited to 'indra/llrender')
-rw-r--r-- | indra/llrender/CMakeLists.txt | 6 | ||||
-rw-r--r-- | indra/llrender/llfontgl.cpp | 5 | ||||
-rw-r--r-- | indra/llrender/llimagegl.cpp | 114 | ||||
-rw-r--r-- | indra/llrender/llimagegl.h | 19 | ||||
-rw-r--r-- | indra/llrender/llrender.cpp | 704 | ||||
-rw-r--r-- | indra/llrender/llrender.h | 239 | ||||
-rw-r--r-- | indra/llrender/llrendertarget.cpp | 3 | ||||
-rw-r--r-- | indra/llrender/llvertexbuffer.cpp | 33 |
8 files changed, 1083 insertions, 40 deletions
diff --git a/indra/llrender/CMakeLists.txt b/indra/llrender/CMakeLists.txt index 9938a0198b..2dba8ef60d 100644 --- a/indra/llrender/CMakeLists.txt +++ b/indra/llrender/CMakeLists.txt @@ -23,11 +23,10 @@ set(llrender_SOURCE_FILES llfont.cpp llfontgl.cpp llgldbg.cpp - llglimmediate.cpp llimagegl.cpp + llrender.cpp llrendertarget.cpp llvertexbuffer.cpp - llvertexprogramgl.cpp ) set(llrender_HEADER_FILES @@ -36,11 +35,10 @@ set(llrender_HEADER_FILES llfontgl.h llfont.h llgldbg.h - llglimmediate.h llimagegl.h + llrender.h llrendertarget.h llvertexbuffer.h - llvertexprogramgl.h ) set_source_files_properties(${llrender_HEADER_FILES} diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index 3a408b5550..1e0d9767ca 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -36,7 +36,7 @@ #include "llfont.h" #include "llfontgl.h" #include "llgl.h" -#include "llglimmediate.h" +#include "llrender.h" #include "v4color.h" #include "llstl.h" @@ -665,7 +665,8 @@ S32 LLFontGL::render(const LLWString &wstr, mImageGLp->bind(0); - gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Not guaranteed to be set correctly + // Not guaranteed to be set correctly + gGL.setSceneBlendType(LLRender::BT_ALPHA); cur_x = ((F32)x * sScaleX); cur_y = ((F32)y * sScaleY); diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 55fa48f437..dd9f22361f 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -41,7 +41,7 @@ #include "llmath.h" #include "llgl.h" -#include "llglimmediate.h" +#include "llrender.h" //---------------------------------------------------------------------------- @@ -61,6 +61,8 @@ S32 LLImageGL::sCount = 0; BOOL LLImageGL::sGlobalUseAnisotropic = FALSE; F32 LLImageGL::sLastFrameTime = 0.f; +BOOL LLImageGL::sRefCheck = TRUE ; + std::set<LLImageGL*> LLImageGL::sImageList; //---------------------------------------------------------------------------- @@ -130,13 +132,13 @@ void LLImageGL::bindExternalTexture(LLGLuint gl_name, S32 stage, LLGLenum bind_t gGL.flush(); if (stage > 0) { - glActiveTextureARB(GL_TEXTURE0_ARB + stage); + gGL.getTexUnit(stage)->activate(); } glBindTexture(bind_target, gl_name); sCurrentBoundTextures[stage] = gl_name; if (stage > 0) { - glActiveTextureARB(GL_TEXTURE0_ARB); + gGL.getTexUnit(0)->activate(); } } @@ -149,9 +151,9 @@ void LLImageGL::unbindTexture(S32 stage, LLGLenum bind_target) gGL.flush(); if (stage > 0) { - glActiveTextureARB(GL_TEXTURE0_ARB + stage); + gGL.getTexUnit(stage)->activate(); glBindTexture(GL_TEXTURE_2D, 0); - glActiveTextureARB(GL_TEXTURE0_ARB); + gGL.getTexUnit(0)->activate(); } else { @@ -276,7 +278,10 @@ LLImageGL::LLImageGL(const LLImageRaw* imageraw, BOOL usemipmaps) setSize(0, 0, 0); sImageList.insert(this); sCount++; + + sRefCheck = FALSE ; createGLTexture(0, imageraw); + sRefCheck = TRUE ; } LLImageGL::~LLImageGL() @@ -304,7 +309,9 @@ void LLImageGL::init(BOOL usemipmaps) mIsResident = 0; mClampS = FALSE; mClampT = FALSE; - mMipFilterNearest = FALSE; + mClampR = FALSE; + mMagFilterNearest = FALSE; + mMinFilterNearest = FALSE; mWidth = 0; mHeight = 0; mComponents = 0; @@ -331,17 +338,19 @@ void LLImageGL::cleanup() //---------------------------------------------------------------------------- +//this function is used to check the size of a texture image. +//so dim should be a positive number static bool check_power_of_two(S32 dim) { - while(dim > 1) + if(dim < 0) { - if (dim & 1) - { - return false; - } - dim >>= 1; + return false ; + } + if(!dim)//0 is a power-of-two number + { + return true ; } - return true; + return !(dim & (dim - 1)) ; } //static @@ -418,6 +427,8 @@ void LLImageGL::dump() BOOL LLImageGL::bindTextureInternal(const S32 stage) const { + llassert_always(!sRefCheck || (getNumRefs() > 0 && getNumRefs() < 100000)) ; + if (gGLManager.mIsDisabled) { llwarns << "Trying to bind a texture while GL is disabled!" << llendl; @@ -439,7 +450,7 @@ BOOL LLImageGL::bindTextureInternal(const S32 stage) const gGL.flush(); if (stage > 0) { - glActiveTextureARB(GL_TEXTURE0_ARB + stage); + gGL.getTexUnit(stage)->activate(); } glBindTexture(mBindTarget, mTexName); @@ -448,7 +459,7 @@ BOOL LLImageGL::bindTextureInternal(const S32 stage) const if (stage > 0) { - glActiveTextureARB(GL_TEXTURE0_ARB); + gGL.getTexUnit(0)->activate(); } if (mLastBindTime != sLastFrameTime) @@ -466,12 +477,12 @@ BOOL LLImageGL::bindTextureInternal(const S32 stage) const gGL.flush(); if (stage > 0) { - glActiveTextureARB(GL_TEXTURE0_ARB+stage); + gGL.getTexUnit(stage)->activate(); } glBindTexture(mBindTarget, 0); if (stage > 0) { - glActiveTextureARB(GL_TEXTURE0_ARB+stage); + gGL.getTexUnit(0)->activate(); } sCurrentBoundTextures[stage] = 0; return FALSE; @@ -941,7 +952,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_ setImage(data_in, data_hasmips); setClamp(mClampS, mClampT); - setMipFilterNearest(mMipFilterNearest); + setMipFilterNearest(mMagFilterNearest); // things will break if we don't unbind after creation unbindTexture(0, mBindTarget); @@ -1044,8 +1055,23 @@ BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre S32 gl_discard = discard_level - mCurrentDiscardLevel; + //explicitly unbind texture + LLImageGL::unbindTexture(0, mTarget); llverify(bindTextureInternal(0)); + if (gDebugGL) + { + if (mTarget == GL_TEXTURE_2D) + { + GLint texname; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &texname); + if (texname != mTexName) + { + llerrs << "Invalid texture bound!" << llendl; + } + } + } + LLGLint glwidth = 0; glGetTexLevelParameteriv(mTarget, gl_discard, GL_TEXTURE_WIDTH, (GLint*)&glwidth); if (glwidth == 0) @@ -1153,25 +1179,55 @@ void LLImageGL::destroyGLTexture() //---------------------------------------------------------------------------- -void LLImageGL::setClamp(BOOL clamps, BOOL clampt) +void LLImageGL::glClampCubemap (BOOL clamps, BOOL clampt, BOOL clampr) +{ + glTexParameteri (GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, clamps ? GL_CLAMP_TO_EDGE : GL_REPEAT); + glTexParameteri (GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, clamps ? GL_CLAMP_TO_EDGE : GL_REPEAT); + glTexParameteri (GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_R, clamps ? GL_CLAMP_TO_EDGE : GL_REPEAT); +} + +void LLImageGL::glClamp (BOOL clamps, BOOL clampt) { - mClampS = clamps; - mClampT = clampt; if (mTexName != 0) { - glTexParameteri(mBindTarget, GL_TEXTURE_WRAP_S, clamps ? GL_CLAMP_TO_EDGE : GL_REPEAT); - glTexParameteri(mBindTarget, GL_TEXTURE_WRAP_T, clampt ? GL_CLAMP_TO_EDGE : GL_REPEAT); + glTexParameteri (mBindTarget, GL_TEXTURE_WRAP_S, clamps ? GL_CLAMP_TO_EDGE : GL_REPEAT); + glTexParameteri (mBindTarget, GL_TEXTURE_WRAP_T, clampt ? GL_CLAMP_TO_EDGE : GL_REPEAT); } - stop_glerror(); } -void LLImageGL::setMipFilterNearest(BOOL nearest, BOOL min_nearest) +void LLImageGL::setClampCubemap (BOOL clamps, BOOL clampt, BOOL clampr) +{ + mClampS = clamps; + mClampT = clampt; + mClampR = clampr; + glClampCubemap (clamps, clampt, clampr); +} + +void LLImageGL::setClamp(BOOL clamps, BOOL clampt) +{ + mClampS = clamps; + mClampT = clampt; + glClamp (clamps, clampt); +} + +void LLImageGL::overrideClamp (BOOL clamps, BOOL clampt) +{ + glClamp (clamps, clampt); +} + +void LLImageGL::restoreClamp (void) +{ + glClamp (mClampS, mClampT); +} + +void LLImageGL::setMipFilterNearest(BOOL mag_nearest, BOOL min_nearest) { - mMipFilterNearest = nearest; + mMagFilterNearest = mag_nearest; + mMinFilterNearest = min_nearest; if (mTexName != 0) { - if (min_nearest) + if (mMinFilterNearest) { glTexParameteri(mBindTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST); } @@ -1183,7 +1239,7 @@ void LLImageGL::setMipFilterNearest(BOOL nearest, BOOL min_nearest) { glTexParameteri(mBindTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } - if (mMipFilterNearest) + if (mMagFilterNearest) { glTexParameteri(mBindTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST); } @@ -1193,7 +1249,7 @@ void LLImageGL::setMipFilterNearest(BOOL nearest, BOOL min_nearest) } if (gGLManager.mHasAnisotropic) { - if (sGlobalUseAnisotropic && !mMipFilterNearest) + if (sGlobalUseAnisotropic && !mMagFilterNearest) { F32 largest_anisotropy; glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &largest_anisotropy); diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index 82ea147d6e..c5fe9b7299 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -81,6 +81,10 @@ protected: virtual ~LLImageGL(); BOOL bindTextureInternal(const S32 stage = 0) const; +private: + void glClamp (BOOL clamps, BOOL clampt); + void glClampCubemap (BOOL clamps, BOOL clampt, BOOL clampr = FALSE); + public: virtual void dump(); // debugging info to llinfos virtual BOOL bind(const S32 stage = 0) const; @@ -99,8 +103,11 @@ public: BOOL readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok); void destroyGLTexture(); + void setClampCubemap (BOOL clamps, BOOL clampt, BOOL clampr = FALSE); void setClamp(BOOL clamps, BOOL clampt); - void setMipFilterNearest(BOOL nearest, BOOL min_nearest = FALSE); + void overrideClamp (BOOL clamps, BOOL clampt); + void restoreClamp (void); + void setMipFilterNearest(BOOL mag_nearest, BOOL min_nearest = FALSE); void setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format = 0, BOOL swap_bytes = FALSE); void dontDiscard() { mDontDiscard = 1; } @@ -117,7 +124,8 @@ public: BOOL getClampS() const { return mClampS; } BOOL getClampT() const { return mClampT; } - BOOL getMipFilterNearest() const { return mMipFilterNearest; } + BOOL getClampR() const { return mClampR; } + BOOL getMipFilterNearest() const { return mMagFilterNearest; } BOOL getHasGLTexture() const { return mTexName != 0; } LLGLuint getTexName() const { return mTexName; } @@ -167,7 +175,9 @@ protected: S8 mClampS; // Need to save clamp state S8 mClampT; - S8 mMipFilterNearest; // if TRUE, set magfilter to GL_NEAREST + S8 mClampR; + S8 mMagFilterNearest; // if TRUE, set magfilter to GL_NEAREST + S8 mMinFilterNearest; // if TRUE, set minfilter to GL_NEAREST LLGLint mFormatInternal; // = GL internalformat LLGLenum mFormatPrimary; // = GL format (pixel data format) @@ -197,6 +207,9 @@ public: #else BOOL getMissed() const { return FALSE; }; #endif + +private://paranoia error check + static BOOL sRefCheck ; }; #endif // LL_LLIMAGEGL_H diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp new file mode 100644 index 0000000000..1168155f8b --- /dev/null +++ b/indra/llrender/llrender.cpp @@ -0,0 +1,704 @@ +/** + * @file llrender.cpp + * @brief LLRender implementation + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2007, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "llrender.h" +#include "llvertexbuffer.h" + +LLRender gGL; + +static const U32 LL_NUM_TEXTURE_LAYERS = 8; + +static GLenum sGLCompareFunc[] = +{ + GL_NEVER, + GL_ALWAYS, + GL_LESS, + GL_LEQUAL, + GL_EQUAL, + GL_NOTEQUAL, + GL_GEQUAL, + GL_GREATER +}; + +const U32 immediate_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXCOORD; + +static GLenum sGLBlendFactor[] = +{ + GL_ONE, + GL_ZERO, + GL_DST_COLOR, + GL_SRC_COLOR, + GL_ONE_MINUS_DST_COLOR, + GL_ONE_MINUS_SRC_COLOR, + GL_DST_ALPHA, + GL_SRC_ALPHA, + GL_ONE_MINUS_DST_ALPHA, + GL_ONE_MINUS_SRC_ALPHA +}; + +LLTexUnit::LLTexUnit(U32 index) +: mIsEnabled(false), mCurrBlendType(TB_MULT), +mCurrColorOp(TBO_MULT), mCurrAlphaOp(TBO_MULT), +mCurrColorSrc1(TBS_TEX_COLOR), mCurrColorSrc2(TBS_PREV_COLOR), +mCurrAlphaSrc1(TBS_TEX_ALPHA), mCurrAlphaSrc2(TBS_PREV_ALPHA), +mCurrColorScale(1), mCurrAlphaScale(1) +{ + llassert_always(index < LL_NUM_TEXTURE_LAYERS); + mIndex = index; +} + +U32 LLTexUnit::getIndex(void) +{ + return mIndex; +} + +void LLTexUnit::enable(void) +{ + if (!mIsEnabled) + { + activate(); + glEnable(GL_TEXTURE_2D); + mIsEnabled = true; + } +} + +void LLTexUnit::disable(void) +{ + if (mIsEnabled) + { + activate(); + glDisable(GL_TEXTURE_2D); + mIsEnabled = false; + } +} + +void LLTexUnit::activate(void) +{ + //if (gGL.mCurrTextureUnitIndex != mIndex) + { + glActiveTextureARB(GL_TEXTURE0_ARB + mIndex); + gGL.mCurrTextureUnitIndex = mIndex; + } +} + +// Useful for debugging that you've manually assigned a texture operation to the correct +// texture unit based on the currently set active texture in opengl. +void LLTexUnit::debugTextureUnit(void) +{ + GLint activeTexture; + glGetIntegerv(GL_ACTIVE_TEXTURE_ARB, &activeTexture); + if ((GL_TEXTURE0_ARB + mIndex) != activeTexture) + { + llerrs << "Incorrect Texture Unit! Expected: " << (activeTexture - GL_TEXTURE0_ARB) << " Actual: " << mIndex << llendl; + } +} + +void LLTexUnit::bindTexture(const LLImageGL* texture) +{ + if (texture != NULL) + { + activate(); + texture->bind(mIndex); + } +} + +void LLTexUnit::unbindTexture(void) +{ + activate(); + glBindTexture(GL_TEXTURE_2D, 0); +} + +void LLTexUnit::setTextureBlendType(eTextureBlendType type) +{ + // Do nothing if it's already correctly set. + if (mCurrBlendType == type) + { + return; + } + + activate(); + mCurrBlendType = type; + S32 scale_amount = 1; + switch (type) + { + case TB_REPLACE: + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + break; + case TB_ADD: + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD); + break; + case TB_MULT: + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + break; + case TB_MULT_X2: + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + scale_amount = 2; + break; + case TB_ALPHA_BLEND: + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); + break; + case TB_COMBINE: + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); + break; + default: + llerrs << "Unknown Texture Blend Type: " << type << llendl; + break; + } + setColorScale(scale_amount); + setAlphaScale(1); +} + +GLint LLTexUnit::getTextureSource(eTextureBlendSrc src) +{ + switch(src) + { + // All four cases should return the same value. + case TBS_PREV_COLOR: + case TBS_PREV_ALPHA: + case TBS_ONE_MINUS_PREV_COLOR: + case TBS_ONE_MINUS_PREV_ALPHA: + return GL_PREVIOUS_ARB; + + // All four cases should return the same value. + case TBS_TEX_COLOR: + case TBS_TEX_ALPHA: + case TBS_ONE_MINUS_TEX_COLOR: + case TBS_ONE_MINUS_TEX_ALPHA: + return GL_TEXTURE; + + // All four cases should return the same value. + case TBS_VERT_COLOR: + case TBS_VERT_ALPHA: + case TBS_ONE_MINUS_VERT_COLOR: + case TBS_ONE_MINUS_VERT_ALPHA: + return GL_PRIMARY_COLOR_ARB; + + // All four cases should return the same value. + case TBS_CONST_COLOR: + case TBS_CONST_ALPHA: + case TBS_ONE_MINUS_CONST_COLOR: + case TBS_ONE_MINUS_CONST_ALPHA: + return GL_CONSTANT_ARB; + + default: + llwarns << "Unknown eTextureBlendSrc: " << src << ". Using Vertex Color instead." << llendl; + return GL_PRIMARY_COLOR_ARB; + } +} + +GLint LLTexUnit::getTextureSourceType(eTextureBlendSrc src, bool isAlpha) +{ + switch(src) + { + // All four cases should return the same value. + case TBS_PREV_COLOR: + case TBS_TEX_COLOR: + case TBS_VERT_COLOR: + case TBS_CONST_COLOR: + return (isAlpha) ? GL_SRC_ALPHA: GL_SRC_COLOR; + + // All four cases should return the same value. + case TBS_PREV_ALPHA: + case TBS_TEX_ALPHA: + case TBS_VERT_ALPHA: + case TBS_CONST_ALPHA: + return GL_SRC_ALPHA; + + // All four cases should return the same value. + case TBS_ONE_MINUS_PREV_COLOR: + case TBS_ONE_MINUS_TEX_COLOR: + case TBS_ONE_MINUS_VERT_COLOR: + case TBS_ONE_MINUS_CONST_COLOR: + return (isAlpha) ? GL_ONE_MINUS_SRC_ALPHA : GL_ONE_MINUS_SRC_COLOR; + + // All four cases should return the same value. + case TBS_ONE_MINUS_PREV_ALPHA: + case TBS_ONE_MINUS_TEX_ALPHA: + case TBS_ONE_MINUS_VERT_ALPHA: + case TBS_ONE_MINUS_CONST_ALPHA: + return GL_ONE_MINUS_SRC_ALPHA; + + default: + llwarns << "Unknown eTextureBlendSrc: " << src << ". Using Source Color or Alpha instead." << llendl; + return (isAlpha) ? GL_SRC_ALPHA: GL_SRC_COLOR; + } +} + +void LLTexUnit::setTextureCombiner(eTextureBlendOp op, eTextureBlendSrc src1, eTextureBlendSrc src2, bool isAlpha) +{ + activate(); + if (mCurrBlendType != TB_COMBINE) + { + mCurrBlendType = TB_COMBINE; + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); + } + + // We want an early out, because this function does a LOT of stuff. + if ( (isAlpha && (mCurrAlphaOp == op) && (mCurrAlphaSrc1 == src1) && (mCurrAlphaSrc2 == src2) ) + || (!isAlpha && (mCurrColorOp == op) && (mCurrColorSrc1 == src1) && (mCurrColorSrc2 == src2) )) + { + return; + } + + // Get the gl source enums according to the eTextureBlendSrc sources passed in + GLint source1 = getTextureSource(src1); + GLint source2 = getTextureSource(src2); + // Get the gl operand enums according to the eTextureBlendSrc sources passed in + GLint operand1 = getTextureSourceType(src1, isAlpha); + GLint operand2 = getTextureSourceType(src2, isAlpha); + // Default the scale amount to 1 + S32 scale_amount = 1; + GLenum comb_enum, src0_enum, src1_enum, src2_enum, operand0_enum, operand1_enum, operand2_enum; + + if (isAlpha) + { + // Set enums to ALPHA ones + comb_enum = GL_COMBINE_ALPHA_ARB; + src0_enum = GL_SOURCE0_ALPHA_ARB; + src1_enum = GL_SOURCE1_ALPHA_ARB; + src2_enum = GL_SOURCE2_ALPHA_ARB; + operand0_enum = GL_OPERAND0_ALPHA_ARB; + operand1_enum = GL_OPERAND1_ALPHA_ARB; + operand2_enum = GL_OPERAND2_ALPHA_ARB; + + // cache current combiner + mCurrAlphaOp = op; + mCurrAlphaSrc1 = src1; + mCurrAlphaSrc2 = src2; + } + else + { + // Set enums to ALPHA ones + comb_enum = GL_COMBINE_RGB_ARB; + src0_enum = GL_SOURCE0_RGB_ARB; + src1_enum = GL_SOURCE1_RGB_ARB; + src2_enum = GL_SOURCE2_RGB_ARB; + operand0_enum = GL_OPERAND0_RGB_ARB; + operand1_enum = GL_OPERAND1_RGB_ARB; + operand2_enum = GL_OPERAND2_RGB_ARB; + + // cache current combiner + mCurrColorOp = op; + mCurrColorSrc1 = src1; + mCurrColorSrc2 = src2; + } + + switch(op) + { + case TBO_REPLACE: + // Slightly special syntax (no second sources), just set all and return. + glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_REPLACE); + glTexEnvi(GL_TEXTURE_ENV, src0_enum, source1); + glTexEnvi(GL_TEXTURE_ENV, operand0_enum, operand1); + (isAlpha) ? setAlphaScale(1) : setColorScale(1); + return; + + case TBO_MULT: + glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_MODULATE); + break; + + case TBO_MULT_X2: + glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_MODULATE); + scale_amount = 2; + break; + + case TBO_MULT_X4: + glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_MODULATE); + scale_amount = 4; + break; + + case TBO_ADD: + glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_ADD); + break; + + case TBO_ADD_SIGNED: + glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_ADD_SIGNED_ARB); + break; + + case TBO_SUBTRACT: + glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_SUBTRACT_ARB); + break; + + case TBO_LERP_VERT_ALPHA: + glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_INTERPOLATE); + glTexEnvi(GL_TEXTURE_ENV, src2_enum, GL_PRIMARY_COLOR_ARB); + glTexEnvi(GL_TEXTURE_ENV, operand2_enum, GL_SRC_ALPHA); + break; + + case TBO_LERP_TEX_ALPHA: + glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_INTERPOLATE); + glTexEnvi(GL_TEXTURE_ENV, src2_enum, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, operand2_enum, GL_SRC_ALPHA); + break; + + case TBO_LERP_PREV_ALPHA: + glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_INTERPOLATE); + glTexEnvi(GL_TEXTURE_ENV, src2_enum, GL_PREVIOUS_ARB); + glTexEnvi(GL_TEXTURE_ENV, operand2_enum, GL_SRC_ALPHA); + break; + + case TBO_LERP_CONST_ALPHA: + glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_INTERPOLATE); + glTexEnvi(GL_TEXTURE_ENV, src2_enum, GL_CONSTANT_ARB); + glTexEnvi(GL_TEXTURE_ENV, operand2_enum, GL_SRC_ALPHA); + break; + + case TBO_LERP_VERT_COLOR: + glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_INTERPOLATE); + glTexEnvi(GL_TEXTURE_ENV, src2_enum, GL_PRIMARY_COLOR_ARB); + glTexEnvi(GL_TEXTURE_ENV, operand2_enum, (isAlpha) ? GL_SRC_ALPHA : GL_SRC_COLOR); + break; + + default: + llwarns << "Unknown eTextureBlendOp: " << op << ". Setting op to replace." << llendl; + // Slightly special syntax (no second sources), just set all and return. + glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_REPLACE); + glTexEnvi(GL_TEXTURE_ENV, src0_enum, source1); + glTexEnvi(GL_TEXTURE_ENV, operand0_enum, operand1); + (isAlpha) ? setAlphaScale(1) : setColorScale(1); + return; + } + + // Set sources, operands, and scale accordingly + glTexEnvi(GL_TEXTURE_ENV, src0_enum, source1); + glTexEnvi(GL_TEXTURE_ENV, operand0_enum, operand1); + glTexEnvi(GL_TEXTURE_ENV, src1_enum, source2); + glTexEnvi(GL_TEXTURE_ENV, operand1_enum, operand2); + (isAlpha) ? setAlphaScale(scale_amount) : setColorScale(scale_amount); +} + +void LLTexUnit::setColorScale(S32 scale) +{ + if (mCurrColorScale != scale) + { + mCurrColorScale = scale; + glTexEnvi( GL_TEXTURE_ENV, GL_RGB_SCALE, scale ); + } +} + +void LLTexUnit::setAlphaScale(S32 scale) +{ + if (mCurrAlphaScale != scale) + { + mCurrAlphaScale = scale; + glTexEnvi( GL_TEXTURE_ENV, GL_ALPHA_SCALE, scale ); + } +} + +LLRender::LLRender() +{ + mCount = 0; + mMode = LLVertexBuffer::TRIANGLES; + mBuffer = new LLVertexBuffer(immediate_mask, 0); + mBuffer->allocateBuffer(4096, 0, TRUE); + mBuffer->getVertexStrider(mVerticesp); + mBuffer->getTexCoordStrider(mTexcoordsp); + mBuffer->getColorStrider(mColorsp); + + for (unsigned int i = 0; i < LL_NUM_TEXTURE_LAYERS; i++) + { + mTexUnits.push_back(new LLTexUnit(i)); + } +} + +LLRender::~LLRender() +{ + for (U32 i = 0; i < mTexUnits.size(); i++) + { + delete mTexUnits[i]; + } +} + +void LLRender::translatef(const GLfloat& x, const GLfloat& y, const GLfloat& z) +{ + flush(); + glTranslatef(x,y,z); +} + +void LLRender::pushMatrix() +{ + flush(); + glPushMatrix(); +} + +void LLRender::popMatrix() +{ + flush(); + glPopMatrix(); +} + +void LLRender::setColorMask(bool writeColor, bool writeAlpha) +{ + setColorMask(writeColor, writeColor, writeColor, writeAlpha); +} + +void LLRender::setColorMask(bool writeColorR, bool writeColorG, bool writeColorB, bool writeAlpha) +{ + flush(); + glColorMask(writeColorR, writeColorG, writeColorB, writeAlpha); +} + +void LLRender::setSceneBlendType(eBlendType type) +{ + flush(); + switch (type) + { + case BT_ALPHA: + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + break; + case BT_ADD: + glBlendFunc(GL_ONE, GL_ONE); + break; + case BT_ADD_WITH_ALPHA: + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + break; + case BT_MULT: + glBlendFunc(GL_DST_COLOR, GL_ZERO); + break; + case BT_MULT_X2: + glBlendFunc(GL_DST_COLOR, GL_SRC_COLOR); + break; + case BT_REPLACE: + glBlendFunc(GL_ONE, GL_ZERO); + break; + default: + llerrs << "Unknown Scene Blend Type: " << type << llendl; + break; + } +} + +void LLRender::setAlphaRejectSettings(eCompareFunc func, F32 value) +{ + flush(); + if (func == CF_DEFAULT) + { + glAlphaFunc(GL_GREATER, 0.01f); + } + else + { + glAlphaFunc(sGLCompareFunc[func], value); + } +} + +void LLRender::blendFunc(eBlendFactor sfactor, eBlendFactor dfactor) +{ + flush(); + glBlendFunc(sGLBlendFactor[sfactor], sGLBlendFactor[dfactor]); +} + +LLTexUnit* LLRender::getTexUnit(U32 index) +{ + if (index < mTexUnits.size()) + { + return mTexUnits[index]; + } + llerrs << "Non-existing texture unit layer requested: " << index << llendl; + return NULL; +} + +void LLRender::begin(const GLuint& mode) +{ + if (mode != mMode) + { + if (mMode == LLVertexBuffer::QUADS || + mMode == LLVertexBuffer::LINES || + mMode == LLVertexBuffer::TRIANGLES || + mMode == LLVertexBuffer::POINTS) + { + flush(); + } + else if (mCount != 0) + { + llerrs << "gGL.begin() called redundantly." << llendl; + } + + mMode = mode; + } +} + +void LLRender::end() +{ + if (mCount == 0) + { + return; + //IMM_ERRS << "GL begin and end called with no vertices specified." << llendl; + } + + if ((mMode != LLVertexBuffer::QUADS && + mMode != LLVertexBuffer::LINES && + mMode != LLVertexBuffer::TRIANGLES && + mMode != LLVertexBuffer::POINTS) || + mCount > 2048) + { + flush(); + } +} +void LLRender::flush() +{ + if (mCount > 0) + { +#if 0 + if (!glIsEnabled(GL_VERTEX_ARRAY)) + { + llerrs << "foo 1" << llendl; + } + + if (!glIsEnabled(GL_COLOR_ARRAY)) + { + llerrs << "foo 2" << llendl; + } + + if (!glIsEnabled(GL_TEXTURE_COORD_ARRAY)) + { + llerrs << "foo 3" << llendl; + } + + if (glIsEnabled(GL_NORMAL_ARRAY)) + { + llerrs << "foo 7" << llendl; + } + + GLvoid* pointer; + + glGetPointerv(GL_VERTEX_ARRAY_POINTER, &pointer); + if (pointer != &(mBuffer[0].v)) + { + llerrs << "foo 4" << llendl; + } + + glGetPointerv(GL_COLOR_ARRAY_POINTER, &pointer); + if (pointer != &(mBuffer[0].c)) + { + llerrs << "foo 5" << llendl; + } + + glGetPointerv(GL_TEXTURE_COORD_ARRAY_POINTER, &pointer); + if (pointer != &(mBuffer[0].uv)) + { + llerrs << "foo 6" << llendl; + } +#endif + + mBuffer->setBuffer(immediate_mask); + mBuffer->drawArrays(mMode, 0, mCount); + + mVerticesp[0] = mVerticesp[mCount]; + mTexcoordsp[0] = mTexcoordsp[mCount]; + mColorsp[0] = mColorsp[mCount]; + mCount = 0; + } +} +void LLRender::vertex3f(const GLfloat& x, const GLfloat& y, const GLfloat& z) +{ + if (mCount >= 4096) + { + // llwarns << "GL immediate mode overflow. Some geometry not drawn." << llendl; + return; + } + + mVerticesp[mCount] = LLVector3(x,y,z); + mCount++; + if (mCount < 4096) + { + mVerticesp[mCount] = mVerticesp[mCount-1]; + mColorsp[mCount] = mColorsp[mCount-1]; + mTexcoordsp[mCount] = mTexcoordsp[mCount-1]; + } +} +void LLRender::vertex2i(const GLint& x, const GLint& y) +{ + vertex3f((GLfloat) x, (GLfloat) y, 0); +} + +void LLRender::vertex2f(const GLfloat& x, const GLfloat& y) +{ + vertex3f(x,y,0); +} + +void LLRender::vertex2fv(const GLfloat* v) +{ + vertex3f(v[0], v[1], 0); +} + +void LLRender::vertex3fv(const GLfloat* v) +{ + vertex3f(v[0], v[1], v[2]); +} + +void LLRender::texCoord2f(const GLfloat& x, const GLfloat& y) +{ + mTexcoordsp[mCount] = LLVector2(x,y); +} + +void LLRender::texCoord2i(const GLint& x, const GLint& y) +{ + texCoord2f((GLfloat) x, (GLfloat) y); +} + +void LLRender::texCoord2fv(const GLfloat* tc) +{ + texCoord2f(tc[0], tc[1]); +} + +void LLRender::color4ub(const GLubyte& r, const GLubyte& g, const GLubyte& b, const GLubyte& a) +{ + mColorsp[mCount] = LLColor4U(r,g,b,a); +} +void LLRender::color4ubv(const GLubyte* c) +{ + color4ub(c[0], c[1], c[2], c[3]); +} + +void LLRender::color4f(const GLfloat& r, const GLfloat& g, const GLfloat& b, const GLfloat& a) +{ + color4ub((GLubyte) (llclamp(r, 0.f, 1.f)*255), + (GLubyte) (llclamp(g, 0.f, 1.f)*255), + (GLubyte) (llclamp(b, 0.f, 1.f)*255), + (GLubyte) (llclamp(a, 0.f, 1.f)*255)); +} + +void LLRender::color4fv(const GLfloat* c) +{ + color4f(c[0],c[1],c[2],c[3]); +} + +void LLRender::color3f(const GLfloat& r, const GLfloat& g, const GLfloat& b) +{ + color4f(r,g,b,1); +} + +void LLRender::color3fv(const GLfloat* c) +{ + color4f(c[0],c[1],c[2],1); +} + diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h new file mode 100644 index 0000000000..2fa3237ef9 --- /dev/null +++ b/indra/llrender/llrender.h @@ -0,0 +1,239 @@ +/** + * @file llrender.h + * @brief LLRender definition + * + * This class acts as a wrapper for OpenGL calls. + * The goal of this class is to minimize the number of api calls due to legacy rendering + * code, to define an interface for a multiple rendering API abstraction of the UI + * rendering, and to abstract out direct rendering calls in a way that is cleaner and easier to maintain. + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2007, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLGLRENDER_H +#define LL_LLGLRENDER_H + +#include "stdtypes.h" +#include "llgltypes.h" +#include "llglheaders.h" +#include "llvertexbuffer.h" + +class LLTexUnit +{ +public: + typedef enum + { + TB_REPLACE = 0, + TB_ADD, + TB_MULT, + TB_MULT_X2, + TB_ALPHA_BLEND, + TB_COMBINE // Doesn't need to be set directly, setTexture___Blend() set TB_COMBINE automatically + } eTextureBlendType; + + typedef enum + { + TBO_REPLACE = 0, // Use Source 1 + TBO_MULT, // Multiply: ( Source1 * Source2 ) + TBO_MULT_X2, // Multiply then scale by 2: ( 2.0 * ( Source1 * Source2 ) ) + TBO_MULT_X4, // Multiply then scale by 4: ( 4.0 * ( Source1 * Source2 ) ) + TBO_ADD, // Add: ( Source1 + Source2 ) + TBO_ADD_SIGNED, // Add then subtract 0.5: ( ( Source1 + Source2 ) - 0.5 ) + TBO_SUBTRACT, // Subtract Source2 from Source1: ( Source1 - Source2 ) + TBO_LERP_VERT_ALPHA, // Interpolate based on Vertex Alpha (VA): ( Source1 * VA + Source2 * (1-VA) ) + TBO_LERP_TEX_ALPHA, // Interpolate based on Texture Alpha (TA): ( Source1 * TA + Source2 * (1-TA) ) + TBO_LERP_PREV_ALPHA, // Interpolate based on Previous Alpha (PA): ( Source1 * PA + Source2 * (1-PA) ) + TBO_LERP_CONST_ALPHA, // Interpolate based on Const Alpha (CA): ( Source1 * CA + Source2 * (1-CA) ) + TBO_LERP_VERT_COLOR // Interpolate based on Vertex Col (VC): ( Source1 * VC + Source2 * (1-VC) ) + // *Note* TBO_LERP_VERTEX_COLOR only works with setTextureColorBlend(), + // and falls back to TBO_LERP_VERTEX_ALPHA for setTextureAlphaBlend(). + } eTextureBlendOp; + + typedef enum + { + TBS_PREV_COLOR = 0, // Color from the previous texture stage + TBS_PREV_ALPHA, + TBS_ONE_MINUS_PREV_COLOR, + TBS_ONE_MINUS_PREV_ALPHA, + TBS_TEX_COLOR, // Color from the texture bound to this stage + TBS_TEX_ALPHA, + TBS_ONE_MINUS_TEX_COLOR, + TBS_ONE_MINUS_TEX_ALPHA, + TBS_VERT_COLOR, // The vertex color currently set + TBS_VERT_ALPHA, + TBS_ONE_MINUS_VERT_COLOR, + TBS_ONE_MINUS_VERT_ALPHA, + TBS_CONST_COLOR, // The constant color value currently set + TBS_CONST_ALPHA, + TBS_ONE_MINUS_CONST_COLOR, + TBS_ONE_MINUS_CONST_ALPHA + } eTextureBlendSrc; + + LLTexUnit(U32 index); + U32 getIndex(void); + + void enable(void); + void disable(void); + void activate(void); + + void bindTexture(const LLImageGL* texture); + void unbindTexture(void); + + void setTextureBlendType(eTextureBlendType type); + + inline void setTextureColorBlend(eTextureBlendOp op, eTextureBlendSrc src1, eTextureBlendSrc src2 = TBS_PREV_COLOR) + { setTextureCombiner(op, src1, src2, false); } + + // NOTE: If *_COLOR enums are passed to src1 or src2, the corresponding *_ALPHA enum will be used instead. + inline void setTextureAlphaBlend(eTextureBlendOp op, eTextureBlendSrc src1, eTextureBlendSrc src2 = TBS_PREV_ALPHA) + { setTextureCombiner(op, src1, src2, true); } + +private: + U32 mIndex; + bool mIsEnabled; + eTextureBlendType mCurrBlendType; + eTextureBlendOp mCurrColorOp; + eTextureBlendSrc mCurrColorSrc1; + eTextureBlendSrc mCurrColorSrc2; + eTextureBlendOp mCurrAlphaOp; + eTextureBlendSrc mCurrAlphaSrc1; + eTextureBlendSrc mCurrAlphaSrc2; + S32 mCurrColorScale; + S32 mCurrAlphaScale; + + void debugTextureUnit(void); + void setColorScale(S32 scale); + void setAlphaScale(S32 scale); + GLint getTextureSource(eTextureBlendSrc src); + GLint getTextureSourceType(eTextureBlendSrc src, bool isAlpha = false); + void setTextureCombiner(eTextureBlendOp op, eTextureBlendSrc src1, eTextureBlendSrc src2, bool isAlpha = false); +}; + +class LLRender +{ + friend class LLTexUnit; +public: + typedef enum + { + CF_NEVER = 0, + CF_ALWAYS, + CF_LESS, + CF_LESS_EQUAL, + CF_EQUAL, + CF_NOT_EQUAL, + CF_GREATER_EQUAL, + CF_GREATER, + CF_DEFAULT + } eCompareFunc; + + typedef enum + { + BT_ALPHA = 0, + BT_ADD, + BT_ADD_WITH_ALPHA, // Additive blend modulated by the fragment's alpha. + BT_MULT, + BT_MULT_X2, + BT_REPLACE + } eBlendType; + + typedef enum + { + BF_ONE = 0, + BF_ZERO, + BF_DEST_COLOR, + BF_SOURCE_COLOR, + BF_ONE_MINUS_DEST_COLOR, + BF_ONE_MINUS_SOURCE_COLOR, + BF_DEST_ALPHA, + BF_SOURCE_ALPHA, + BF_ONE_MINUS_DEST_ALPHA, + BF_ONE_MINUS_SOURCE_ALPHA + } eBlendFactor; + + LLRender(); + ~LLRender(); + + void translatef(const GLfloat& x, const GLfloat& y, const GLfloat& z); + void pushMatrix(); + void popMatrix(); + + void flush(); + + void begin(const GLuint& mode); + void end(); + void vertex2i(const GLint& x, const GLint& y); + void vertex2f(const GLfloat& x, const GLfloat& y); + void vertex3f(const GLfloat& x, const GLfloat& y, const GLfloat& z); + void vertex2fv(const GLfloat* v); + void vertex3fv(const GLfloat* v); + + void texCoord2i(const GLint& x, const GLint& y); + void texCoord2f(const GLfloat& x, const GLfloat& y); + void texCoord2fv(const GLfloat* tc); + + void color4ub(const GLubyte& r, const GLubyte& g, const GLubyte& b, const GLubyte& a); + void color4f(const GLfloat& r, const GLfloat& g, const GLfloat& b, const GLfloat& a); + void color4fv(const GLfloat* c); + void color3f(const GLfloat& r, const GLfloat& g, const GLfloat& b); + void color3fv(const GLfloat* c); + void color4ubv(const GLubyte* c); + + void setColorMask(bool writeColor, bool writeAlpha); + void setColorMask(bool writeColorR, bool writeColorG, bool writeColorB, bool writeAlpha); + void setSceneBlendType(eBlendType type); + + void setAlphaRejectSettings(eCompareFunc func, F32 value = 0.01f); + + void blendFunc(eBlendFactor sfactor, eBlendFactor dfactor); + + LLTexUnit* getTexUnit(U32 index); + + typedef struct Vertex + { + GLfloat v[3]; + GLubyte c[4]; + GLfloat uv[2]; + }; + +public: + +private: + U32 mCount; + U32 mMode; + U32 mCurrTextureUnitIndex; + LLPointer<LLVertexBuffer> mBuffer; + LLStrider<LLVector3> mVerticesp; + LLStrider<LLVector2> mTexcoordsp; + LLStrider<LLColor4U> mColorsp; + std::vector<LLTexUnit*> mTexUnits; +}; + + + +extern LLRender gGL; + +#endif diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp index 5111c7ae2d..885ccde2d1 100644 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -32,7 +32,7 @@ #include "linden_common.h" #include "llrendertarget.h" -#include "llglimmediate.h" +#include "llrender.h" #include "llgl.h" @@ -181,6 +181,7 @@ void LLRenderTarget::clear() { LLGLEnable scissor(GL_SCISSOR_TEST); glScissor(0, 0, mResX, mResY); + stop_glerror(); glClear(mask); } } diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 2f053a6493..d79a0d6034 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -38,7 +38,7 @@ #include "llglheaders.h" #include "llmemory.h" #include "llmemtype.h" -#include "llglimmediate.h" +#include "llrender.h" //============================================================================ @@ -768,11 +768,26 @@ U8* LLVertexBuffer::mapBuffer(S32 access) sMapped = TRUE;*/ if (!mMappedData) { + GLint buff; + glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff); + if (buff != mGLBuffer) + { + llerrs << "Invalid GL vertex buffer bound: " << buff << llendl; + } + + llerrs << "glMapBuffer returned NULL (no vertex data)" << llendl; } if (!mMappedIndexData) { + GLint buff; + glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff); + if (buff != mGLIndices) + { + llerrs << "Invalid GL index buffer bound: " << buff << llendl; + } + llerrs << "glMapBuffer returned NULL (no index data)" << llendl; } @@ -952,6 +967,22 @@ void LLVertexBuffer::setBuffer(U32 data_mask) sIBOActive = TRUE; } + if (gDebugGL) + { + GLint buff; + glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff); + if (buff != mGLBuffer) + { + llerrs << "Invalid GL vertex buffer bound: " << buff << llendl; + } + + glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff); + if (buff != mGLIndices) + { + llerrs << "Invalid GL index buffer bound: " << buff << llendl; + } + } + if (mResized) { if (gDebugGL) |