Reasonably safe changes.
Using accessor for vertexbuffer in LLFace Extra occlusion query lookup in llgl (unused) Const changes.
This commit is contained in:
@@ -64,7 +64,6 @@ LLMatrix4 gGLObliqueProjectionInverse;
|
||||
|
||||
#define LL_GL_NAME_POOLING 0
|
||||
|
||||
LLGLNamePool::pool_list_t LLGLNamePool::sInstances;
|
||||
std::list<LLGLUpdate*> LLGLUpdate::sGLQ;
|
||||
|
||||
#if (LL_WINDOWS || LL_LINUX || LL_SOLARIS) && !LL_MESA_HEADLESS
|
||||
@@ -291,6 +290,7 @@ LLGLManager::LLGLManager() :
|
||||
mHasVertexShader(FALSE),
|
||||
mHasFragmentShader(FALSE),
|
||||
mHasOcclusionQuery(FALSE),
|
||||
mHasOcclusionQuery2(FALSE),
|
||||
mHasPointParameters(FALSE),
|
||||
mHasDrawBuffers(FALSE),
|
||||
mHasTextureRectangle(FALSE),
|
||||
@@ -623,6 +623,7 @@ 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
|
||||
@@ -741,6 +742,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;
|
||||
@@ -1620,12 +1625,17 @@ void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor
|
||||
}
|
||||
}
|
||||
|
||||
LLGLUserClipPlane::LLGLUserClipPlane(const LLPlane& p, const glh::matrix4f& modelview, const glh::matrix4f& projection)
|
||||
LLGLUserClipPlane::LLGLUserClipPlane(const LLPlane& p, const glh::matrix4f& modelview, const glh::matrix4f& projection, bool apply)
|
||||
{
|
||||
mModelview = modelview;
|
||||
mProjection = projection;
|
||||
mApply = apply;
|
||||
|
||||
setPlane(p.mV[0], p.mV[1], p.mV[2], p.mV[3]);
|
||||
if (mApply)
|
||||
{
|
||||
mModelview = modelview;
|
||||
mProjection = projection;
|
||||
|
||||
setPlane(p[0], p[1], p[2], p[3]);
|
||||
}
|
||||
}
|
||||
|
||||
void LLGLUserClipPlane::setPlane(F32 a, F32 b, F32 c, F32 d)
|
||||
@@ -1656,31 +1666,20 @@ void LLGLUserClipPlane::setPlane(F32 a, F32 b, F32 c, F32 d)
|
||||
|
||||
LLGLUserClipPlane::~LLGLUserClipPlane()
|
||||
{
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
if (mApply)
|
||||
{
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
}
|
||||
}
|
||||
|
||||
LLGLNamePool::LLGLNamePool()
|
||||
{
|
||||
}
|
||||
|
||||
void LLGLNamePool::registerPool(LLGLNamePool* pool)
|
||||
{
|
||||
pool_list_t::iterator iter = std::find(sInstances.begin(), sInstances.end(), pool);
|
||||
if (iter == sInstances.end())
|
||||
{
|
||||
sInstances.push_back(pool);
|
||||
}
|
||||
}
|
||||
|
||||
LLGLNamePool::~LLGLNamePool()
|
||||
{
|
||||
pool_list_t::iterator iter = std::find(sInstances.begin(), sInstances.end(), this);
|
||||
if (iter != sInstances.end())
|
||||
{
|
||||
sInstances.erase(iter);
|
||||
}
|
||||
}
|
||||
|
||||
void LLGLNamePool::upkeep()
|
||||
@@ -1748,20 +1747,22 @@ void LLGLNamePool::release(GLuint name)
|
||||
//static
|
||||
void LLGLNamePool::upkeepPools()
|
||||
{
|
||||
for (pool_list_t::iterator iter = sInstances.begin(); iter != sInstances.end(); ++iter)
|
||||
tracker_t::LLInstanceTrackerScopedGuard guard;
|
||||
for (tracker_t::instance_iter iter = guard.beginInstances(); iter != guard.endInstances(); ++iter)
|
||||
{
|
||||
LLGLNamePool* pool = *iter;
|
||||
pool->upkeep();
|
||||
LLGLNamePool & pool = *iter;
|
||||
pool.upkeep();
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
void LLGLNamePool::cleanupPools()
|
||||
{
|
||||
for (pool_list_t::iterator iter = sInstances.begin(); iter != sInstances.end(); ++iter)
|
||||
tracker_t::LLInstanceTrackerScopedGuard guard;
|
||||
for (tracker_t::instance_iter iter = guard.beginInstances(); iter != guard.endInstances(); ++iter)
|
||||
{
|
||||
LLGLNamePool* pool = *iter;
|
||||
pool->cleanup();
|
||||
LLGLNamePool & pool = *iter;
|
||||
pool.cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1844,11 +1845,15 @@ 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);
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
#include "v4math.h"
|
||||
#include "llplane.h"
|
||||
#include "llgltypes.h"
|
||||
#include "llinstancetracker.h"
|
||||
|
||||
#include "llglheaders.h"
|
||||
#include "glh/glh_linear.h"
|
||||
@@ -88,6 +89,7 @@ public:
|
||||
BOOL mHasVertexShader;
|
||||
BOOL mHasFragmentShader;
|
||||
BOOL mHasOcclusionQuery;
|
||||
BOOL mHasOcclusionQuery2;
|
||||
BOOL mHasPointParameters;
|
||||
BOOL mHasDrawBuffers;
|
||||
BOOL mHasDepthClamp;
|
||||
@@ -292,12 +294,14 @@ class LLGLUserClipPlane
|
||||
{
|
||||
public:
|
||||
|
||||
LLGLUserClipPlane(const LLPlane& plane, const glh::matrix4f& modelview, const glh::matrix4f& projection);
|
||||
LLGLUserClipPlane(const LLPlane& plane, const glh::matrix4f& modelview, const glh::matrix4f& projection, bool apply = true);
|
||||
~LLGLUserClipPlane();
|
||||
|
||||
void setPlane(F32 a, F32 b, F32 c, F32 d);
|
||||
|
||||
private:
|
||||
bool mApply;
|
||||
|
||||
glh::matrix4f mProjection;
|
||||
glh::matrix4f mModelview;
|
||||
};
|
||||
@@ -313,7 +317,7 @@ private:
|
||||
class LLGLSquashToFarClip
|
||||
{
|
||||
public:
|
||||
LLGLSquashToFarClip(glh::matrix4f projection);
|
||||
LLGLSquashToFarClip(glh::matrix4f projection, U32 layer = 0);
|
||||
~LLGLSquashToFarClip();
|
||||
};
|
||||
|
||||
@@ -321,9 +325,11 @@ public:
|
||||
Generic pooling scheme for things which use GL names (used for occlusion queries and vertex buffer objects).
|
||||
Prevents thrashing of GL name caches by avoiding calls to glGenFoo and glDeleteFoo.
|
||||
*/
|
||||
class LLGLNamePool
|
||||
class LLGLNamePool : public LLInstanceTracker<LLGLNamePool>
|
||||
{
|
||||
public:
|
||||
typedef LLInstanceTracker<LLGLNamePool> tracker_t;
|
||||
|
||||
struct NameEntry
|
||||
{
|
||||
GLuint name;
|
||||
@@ -350,13 +356,11 @@ public:
|
||||
GLuint allocate();
|
||||
void release(GLuint name);
|
||||
|
||||
static void registerPool(LLGLNamePool* pool);
|
||||
static void upkeepPools();
|
||||
static void cleanupPools();
|
||||
|
||||
protected:
|
||||
typedef std::vector<LLGLNamePool*> pool_list_t;
|
||||
static pool_list_t sInstances;
|
||||
|
||||
virtual GLuint allocateName() = 0;
|
||||
virtual void releaseName(GLuint name) = 0;
|
||||
|
||||
@@ -717,10 +717,21 @@ GLint LLGLSLShader::getUniformLocation(const string& uniform)
|
||||
return iter->second;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
GLint LLGLSLShader::getAttribLocation(U32 attrib)
|
||||
{
|
||||
if (attrib < mAttribute.size())
|
||||
{
|
||||
return mAttribute[attrib];
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
void LLGLSLShader::uniform1i(const string& uniform, GLint v)
|
||||
{
|
||||
GLint location = getUniformLocation(uniform);
|
||||
|
||||
@@ -109,7 +109,7 @@ public:
|
||||
void vertexAttrib4fv(U32 index, GLfloat* v);
|
||||
|
||||
GLint getUniformLocation(const std::string& uniform);
|
||||
|
||||
GLint getAttribLocation(U32 attrib);
|
||||
GLint mapUniformTextureChannel(GLint location, GLenum type);
|
||||
|
||||
|
||||
|
||||
@@ -262,25 +262,4 @@ public:
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
|
||||
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
|
||||
|
||||
@@ -50,6 +50,7 @@ F64 gGLProjection[16];
|
||||
S32 gGLViewport[4];
|
||||
|
||||
static const U32 LL_NUM_TEXTURE_LAYERS = 8;
|
||||
static const U32 LL_NUM_LIGHT_UNITS = 8;
|
||||
|
||||
static GLenum sGLTextureType[] =
|
||||
{
|
||||
@@ -730,6 +731,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),
|
||||
@@ -751,6 +876,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;
|
||||
@@ -778,6 +908,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)
|
||||
@@ -955,6 +1091,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)
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include "v2math.h"
|
||||
#include "v3math.h"
|
||||
#include "v4coloru.h"
|
||||
#include "v4math.h"
|
||||
#include "llstrider.h"
|
||||
#include "llmemory.h"
|
||||
#include "llglheaders.h"
|
||||
@@ -218,6 +219,40 @@ 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;
|
||||
@@ -324,6 +359,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; }
|
||||
@@ -358,6 +395,7 @@ private:
|
||||
LLStrider<LLColor4U> mColorsp;
|
||||
std::vector<LLTexUnit*> mTexUnits;
|
||||
LLTexUnit* mDummyTexUnit;
|
||||
std::vector<LLLightState*> mLightState;
|
||||
|
||||
eBlendFactor mCurrBlendColorSFactor;
|
||||
eBlendFactor mCurrBlendColorDFactor;
|
||||
|
||||
@@ -46,16 +46,14 @@ void check_framebuffer_status()
|
||||
{
|
||||
case GL_FRAMEBUFFER_COMPLETE_EXT:
|
||||
break;
|
||||
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
|
||||
llerrs << "WTF?" << llendl;
|
||||
break;
|
||||
default:
|
||||
llerrs << "WTF?" << llendl;
|
||||
llerrs <<"check_framebuffer_status failed" << llendl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOL LLRenderTarget::sUseFBO = FALSE;
|
||||
bool LLRenderTarget::sUseFBO = false;
|
||||
|
||||
LLRenderTarget::LLRenderTarget() :
|
||||
mResX(0),
|
||||
@@ -64,8 +62,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)
|
||||
@@ -83,7 +81,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;
|
||||
@@ -226,6 +224,7 @@ void LLRenderTarget::shareDepthBuffer(LLRenderTarget& target)
|
||||
stop_glerror();
|
||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mDepth);
|
||||
stop_glerror();
|
||||
target.mStencil = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -245,18 +244,6 @@ void LLRenderTarget::shareDepthBuffer(LLRenderTarget& target)
|
||||
|
||||
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)
|
||||
@@ -271,7 +258,33 @@ void LLRenderTarget::release()
|
||||
}
|
||||
mDepth = 0;
|
||||
}
|
||||
else if (mUseDepth && mFBO)
|
||||
{ //detach shared depth buffer
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBO);
|
||||
if (mStencil)
|
||||
{ //attached as a renderbuffer
|
||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0);
|
||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0);
|
||||
mStencil = false;
|
||||
}
|
||||
else
|
||||
{ //attached as a texture
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, LLTexUnit::getInternalType(mUsage), 0, 0);
|
||||
}
|
||||
mUseDepth = false;
|
||||
}
|
||||
|
||||
if (mFBO)
|
||||
{
|
||||
glDeleteFramebuffersEXT(1, (GLuint *) &mFBO);
|
||||
mFBO = 0;
|
||||
}
|
||||
|
||||
if (mTex.size() > 0)
|
||||
{
|
||||
LLImageGL::deleteTextures(mTex.size(), &mTex[0]);
|
||||
mTex.clear();
|
||||
}
|
||||
mSampleBuffer = NULL;
|
||||
}
|
||||
|
||||
@@ -351,19 +364,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)
|
||||
@@ -439,6 +452,10 @@ void LLRenderTarget::flush(BOOL fetch_depth)
|
||||
void LLRenderTarget::copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0, S32 srcX1, S32 srcY1,
|
||||
S32 dstX0, S32 dstY0, S32 dstX1, S32 dstY1, U32 mask, U32 filter)
|
||||
{
|
||||
GLboolean write_depth = mask & GL_DEPTH_BUFFER_BIT ? TRUE : FALSE;
|
||||
|
||||
LLGLDepthTest depth(write_depth, write_depth);
|
||||
|
||||
gGL.flush();
|
||||
if (!source.mFBO || !mFBO)
|
||||
{
|
||||
@@ -494,6 +511,10 @@ void LLRenderTarget::copyContentsToFramebuffer(LLRenderTarget& source, S32 srcX0
|
||||
llerrs << "Cannot copy framebuffer contents for non FBO render targets." << llendl;
|
||||
}
|
||||
{
|
||||
GLboolean write_depth = mask & GL_DEPTH_BUFFER_BIT ? TRUE : FALSE;
|
||||
|
||||
LLGLDepthTest depth(write_depth, write_depth);
|
||||
|
||||
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, source.mSampleBuffer ? source.mSampleBuffer->mFBO : source.mFBO);
|
||||
stop_glerror();
|
||||
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0);
|
||||
@@ -513,9 +534,9 @@ void LLRenderTarget::copyContentsToFramebuffer(LLRenderTarget& source, S32 srcX0
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
@@ -536,10 +557,10 @@ LLMultisampleBuffer::LLMultisampleBuffer()
|
||||
|
||||
LLMultisampleBuffer::~LLMultisampleBuffer()
|
||||
{
|
||||
releaseSampleBuffer();
|
||||
release();
|
||||
}
|
||||
|
||||
void LLMultisampleBuffer::releaseSampleBuffer()
|
||||
void LLMultisampleBuffer::release()
|
||||
{
|
||||
if (mFBO)
|
||||
{
|
||||
@@ -588,12 +609,12 @@ void LLMultisampleBuffer::bindTarget(LLRenderTarget* ref)
|
||||
|
||||
}
|
||||
|
||||
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;
|
||||
@@ -603,7 +624,7 @@ void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth
|
||||
mUseDepth = depth;
|
||||
mStencil = stencil;
|
||||
|
||||
releaseSampleBuffer();
|
||||
release();
|
||||
|
||||
if (!gGLManager.mHasFramebufferMultisample)
|
||||
{
|
||||
@@ -640,11 +661,9 @@ void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth
|
||||
{
|
||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mDepth);
|
||||
}
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
}
|
||||
|
||||
stop_glerror();
|
||||
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
stop_glerror();
|
||||
}
|
||||
@@ -683,11 +702,9 @@ void LLMultisampleBuffer::addColorAttachment(U32 color_fmt)
|
||||
{
|
||||
case GL_FRAMEBUFFER_COMPLETE_EXT:
|
||||
break;
|
||||
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
|
||||
llerrs << "WTF?" << llendl;
|
||||
break;
|
||||
default:
|
||||
llerrs << "WTF?" << llendl;
|
||||
llerrs << "WTF? " << std::hex << status << llendl;
|
||||
break;
|
||||
}
|
||||
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
|
||||
@@ -69,7 +69,7 @@ class LLRenderTarget
|
||||
{
|
||||
public:
|
||||
//whether or not to use FBO implementation
|
||||
static BOOL sUseFBO;
|
||||
static bool sUseFBO;
|
||||
|
||||
LLRenderTarget();
|
||||
virtual ~LLRenderTarget();
|
||||
@@ -77,7 +77,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);
|
||||
@@ -94,7 +94,7 @@ public:
|
||||
|
||||
//free any allocated resources
|
||||
//safe to call redundantly
|
||||
void release();
|
||||
virtual void release();
|
||||
|
||||
//bind target for rendering
|
||||
//applies appropriate viewport
|
||||
@@ -121,7 +121,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);
|
||||
|
||||
@@ -131,7 +131,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);
|
||||
@@ -142,7 +142,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;
|
||||
|
||||
protected:
|
||||
friend class LLMultisampleBuffer;
|
||||
@@ -151,9 +151,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;
|
||||
@@ -166,12 +166,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();
|
||||
};
|
||||
|
||||
@@ -67,6 +67,8 @@ U32 LLVertexBuffer::sAllocatedBytes = 0;
|
||||
BOOL LLVertexBuffer::sMapped = FALSE;
|
||||
BOOL LLVertexBuffer::sUseStreamDraw = TRUE;
|
||||
BOOL LLVertexBuffer::sOmitBlank = FALSE;
|
||||
BOOL LLVertexBuffer::sPreferStreamDraw = FALSE;
|
||||
S32 LLVertexBuffer::sWeight4Loc = -1;
|
||||
|
||||
std::vector<U32> LLVertexBuffer::sDeleteList;
|
||||
|
||||
@@ -88,15 +90,16 @@ void LLVBOPool::releaseName(GLuint name)
|
||||
|
||||
S32 LLVertexBuffer::sTypeOffsets[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,
|
||||
};
|
||||
|
||||
@@ -156,11 +159,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)
|
||||
llerrs << "Bad client state! " << array[i] << " enabled." << llendl;
|
||||
}
|
||||
@@ -209,23 +212,69 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
void LLVertexBuffer::drawArrays(U32 mode, const std::vector<LLVector3>& pos, const std::vector<LLVector3>& norm)
|
||||
{
|
||||
U32 count = pos.size();
|
||||
llassert(norm.size() >= pos.size());
|
||||
|
||||
unbind();
|
||||
|
||||
setupClientArrays(MAP_VERTEX | MAP_NORMAL);
|
||||
|
||||
glVertexPointer(3, GL_FLOAT, 0, pos[0].mV);
|
||||
glNormalPointer(GL_FLOAT, 0, norm[0].mV);
|
||||
|
||||
glDrawArrays(sGLMode[mode], 0, count);
|
||||
}
|
||||
|
||||
void LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_offset) const
|
||||
{
|
||||
if (start >= (U32) mRequestedNumVerts ||
|
||||
end >= (U32) mRequestedNumVerts)
|
||||
{
|
||||
llerrs << "Bad vertex buffer draw range: [" << start << ", " << end << "] vs " << mRequestedNumVerts << llendl;
|
||||
}
|
||||
|
||||
llassert(mRequestedNumIndices >= 0);
|
||||
|
||||
if (indices_offset >= (U32) mRequestedNumIndices ||
|
||||
indices_offset + count > (U32) mRequestedNumIndices)
|
||||
{
|
||||
llerrs << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << llendl;
|
||||
}
|
||||
}
|
||||
|
||||
void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const
|
||||
{
|
||||
if (start >= (U32) mRequestedNumVerts ||
|
||||
end >= (U32) mRequestedNumVerts)
|
||||
{
|
||||
llerrs << "Bad vertex buffer draw range: [" << start << ", " << end << "]" << llendl;
|
||||
}
|
||||
validateRange(start, end, count, indices_offset);
|
||||
|
||||
if (indices_offset >= (U32) mRequestedNumIndices ||
|
||||
indices_offset + count > (U32) mRequestedNumIndices)
|
||||
{
|
||||
llerrs << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << llendl;
|
||||
}
|
||||
llassert(mRequestedNumVerts >= 0);
|
||||
|
||||
if (mGLIndices != sGLRenderIndices)
|
||||
{
|
||||
@@ -243,16 +292,19 @@ 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();
|
||||
}
|
||||
|
||||
void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
|
||||
{
|
||||
llassert(mRequestedNumIndices >= 0);
|
||||
if (indices_offset >= (U32) mRequestedNumIndices ||
|
||||
indices_offset + count > (U32) mRequestedNumIndices)
|
||||
indices_offset + count > (U32) mRequestedNumIndices)
|
||||
{
|
||||
llerrs << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << llendl;
|
||||
}
|
||||
@@ -281,6 +333,7 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
|
||||
|
||||
void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
|
||||
{
|
||||
llassert(mRequestedNumVerts >= 0);
|
||||
if (first >= (U32) mRequestedNumVerts ||
|
||||
first + count > (U32) mRequestedNumVerts)
|
||||
{
|
||||
@@ -317,12 +370,8 @@ void LLVertexBuffer::initClass(bool use_vbo, bool no_vbo_mapping)
|
||||
{
|
||||
llinfos << "VBO is disabled." << llendl ;
|
||||
}
|
||||
|
||||
|
||||
sDisableVBOMapping = sEnableVBOs && no_vbo_mapping ;
|
||||
LLGLNamePool::registerPool(&sDynamicVBOPool);
|
||||
LLGLNamePool::registerPool(&sDynamicIBOPool);
|
||||
LLGLNamePool::registerPool(&sStreamVBOPool);
|
||||
LLGLNamePool::registerPool(&sStreamIBOPool);
|
||||
}
|
||||
|
||||
//static
|
||||
@@ -395,6 +444,11 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :
|
||||
{
|
||||
mUsage = 0;
|
||||
}
|
||||
|
||||
if (mUsage == GL_DYNAMIC_DRAW_ARB && sPreferStreamDraw)
|
||||
{
|
||||
mUsage = GL_STREAM_DRAW_ARB;
|
||||
}
|
||||
|
||||
S32 stride = calcStride(typemask, mOffsets);
|
||||
|
||||
@@ -431,6 +485,8 @@ LLVertexBuffer::~LLVertexBuffer()
|
||||
destroyGLBuffer();
|
||||
destroyGLIndices();
|
||||
sCount--;
|
||||
|
||||
llassert_always(!mMappedData && !mMappedIndexData) ;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -679,6 +735,11 @@ void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)
|
||||
{
|
||||
LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
|
||||
|
||||
if (nverts < 0 || nindices < 0 ||
|
||||
nverts > 65536)
|
||||
{
|
||||
llerrs << "Bad vertex buffer allocation: " << nverts << " : " << nindices << llendl;
|
||||
}
|
||||
updateNumVerts(nverts);
|
||||
updateNumIndices(nindices);
|
||||
|
||||
@@ -697,6 +758,9 @@ void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)
|
||||
|
||||
void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices)
|
||||
{
|
||||
llassert(newnverts >= 0);
|
||||
llassert(newnindices >= 0);
|
||||
|
||||
mRequestedNumVerts = newnverts;
|
||||
mRequestedNumIndices = newnindices;
|
||||
|
||||
@@ -1129,6 +1193,12 @@ bool LLVertexBuffer::getWeightStrider(LLStrider<F32>& strider, S32 index)
|
||||
{
|
||||
return VertexBufferStrider<F32,TYPE_WEIGHT>::get(*this, strider, index);
|
||||
}
|
||||
|
||||
bool LLVertexBuffer::getWeight4Strider(LLStrider<LLVector4>& strider, S32 index)
|
||||
{
|
||||
return VertexBufferStrider<LLVector4,TYPE_WEIGHT4>::get(*this, strider, index);
|
||||
}
|
||||
|
||||
bool LLVertexBuffer::getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index)
|
||||
{
|
||||
return VertexBufferStrider<LLVector4,TYPE_CLOTHWEIGHT>::get(*this, strider, index);
|
||||
@@ -1382,6 +1452,12 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const
|
||||
{
|
||||
glVertexAttribPointerARB(1, 1, GL_FLOAT, FALSE, stride, (void*)(base + mOffsets[TYPE_WEIGHT]));
|
||||
}
|
||||
|
||||
if (data_mask & MAP_WEIGHT4 && sWeight4Loc != -1)
|
||||
{
|
||||
glVertexAttribPointerARB(sWeight4Loc, 4, GL_FLOAT, FALSE, stride, (void*)(base+mOffsets[TYPE_WEIGHT4]));
|
||||
}
|
||||
|
||||
if (data_mask & MAP_CLOTHWEIGHT)
|
||||
{
|
||||
glVertexAttribPointerARB(4, 4, GL_FLOAT, TRUE, stride, (void*)(base + mOffsets[TYPE_CLOTHWEIGHT]));
|
||||
|
||||
@@ -64,23 +64,38 @@ protected:
|
||||
virtual void releaseName(GLuint 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 sOmitBlank;
|
||||
|
||||
static BOOL sPreferStreamDraw;
|
||||
|
||||
static void initClass(bool use_vbo, bool no_vbo_mapping);
|
||||
static void cleanupClass();
|
||||
static void setupClientArrays(U32 data_mask);
|
||||
static void drawArrays(U32 mode, const std::vector<LLVector3>& pos, const std::vector<LLVector3>& norm);
|
||||
static void clientCopy(F64 max_time = 0.005); //copy data from client to GL
|
||||
static void unbind(); //unbind any bound vertex buffer
|
||||
|
||||
@@ -101,6 +116,7 @@ public:
|
||||
// These use VertexAttribPointer and should possibly be made generic
|
||||
TYPE_BINORMAL,
|
||||
TYPE_WEIGHT,
|
||||
TYPE_WEIGHT4,
|
||||
TYPE_CLOTHWEIGHT,
|
||||
TYPE_MAX,
|
||||
TYPE_INDEX,
|
||||
@@ -116,6 +132,7 @@ public:
|
||||
// These use VertexAttribPointer and should possibly be made generic
|
||||
MAP_BINORMAL = (1<<TYPE_BINORMAL),
|
||||
MAP_WEIGHT = (1<<TYPE_WEIGHT),
|
||||
MAP_WEIGHT4 = (1<<TYPE_WEIGHT4),
|
||||
MAP_CLOTHWEIGHT = (1<<TYPE_CLOTHWEIGHT),
|
||||
};
|
||||
|
||||
@@ -170,6 +187,7 @@ public:
|
||||
bool getBinormalStrider(LLStrider<LLVector3>& strider, S32 index=0);
|
||||
bool getColorStrider(LLStrider<LLColor4U>& strider, S32 index=0);
|
||||
bool getWeightStrider(LLStrider<F32>& strider, S32 index=0);
|
||||
bool getWeight4Strider(LLStrider<LLVector4>& strider, S32 index=0);
|
||||
bool getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index=0);
|
||||
|
||||
BOOL isEmpty() const { return mEmpty; }
|
||||
@@ -199,6 +217,11 @@ public:
|
||||
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
|
||||
@@ -246,12 +269,12 @@ public:
|
||||
|
||||
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 BOOL sVBOActive;
|
||||
static BOOL sIBOActive;
|
||||
static U32 sLastMask;
|
||||
static U32 sAllocatedBytes;
|
||||
static U32 sBindCount;
|
||||
|
||||
Reference in New Issue
Block a user