summaryrefslogtreecommitdiff
path: root/indra/llrender
diff options
context:
space:
mode:
authorSteven Bennetts <steve@lindenlab.com>2008-06-06 22:43:38 +0000
committerSteven Bennetts <steve@lindenlab.com>2008-06-06 22:43:38 +0000
commitad332810078a0bbb8fa08fcbfdf3d756de6914f6 (patch)
tree1608b2db5d620d323673607ea7ddadfba9d58bda /indra/llrender
parenta7d9a543e587ffe84b355db7a2e8193bfe6c68b6 (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.txt6
-rw-r--r--indra/llrender/llfontgl.cpp5
-rw-r--r--indra/llrender/llimagegl.cpp114
-rw-r--r--indra/llrender/llimagegl.h19
-rw-r--r--indra/llrender/llrender.cpp704
-rw-r--r--indra/llrender/llrender.h239
-rw-r--r--indra/llrender/llrendertarget.cpp3
-rw-r--r--indra/llrender/llvertexbuffer.cpp33
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)