summaryrefslogtreecommitdiff
path: root/indra/llrender/llrender.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llrender/llrender.cpp')
-rw-r--r--indra/llrender/llrender.cpp1020
1 files changed, 481 insertions, 539 deletions
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index fd34a94ae8..a0025968f7 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -36,8 +36,9 @@
#include "lltexture.h"
#include "llshadermgr.h"
#include "hbxxh.h"
+#include "glm/gtc/type_ptr.hpp"
-#if LL_WINDOWS
+#if GL_ARB_debug_output && !LL_DARWIN
extern void APIENTRY gl_debug_callback(GLenum source,
GLenum type,
GLuint id,
@@ -50,8 +51,6 @@ extern void APIENTRY gl_debug_callback(GLenum source,
thread_local LLRender gGL;
-const U32 BATCH_SIZE = 16334;
-
// Handy copies of last good GL matrices
F32 gGLModelView[16];
F32 gGLLastModelView[16];
@@ -59,8 +58,8 @@ F32 gGLLastProjection[16];
F32 gGLProjection[16];
// transform from last frame's camera space to this frame's camera space (and inverse)
-F32 gGLDeltaModelView[16];
-F32 gGLInverseDeltaModelView[16];
+glm::mat4 gGLDeltaModelView;
+glm::mat4 gGLInverseDeltaModelView;
S32 gGLViewport[4];
@@ -68,7 +67,7 @@ S32 gGLViewport[4];
U32 LLRender::sUICalls = 0;
U32 LLRender::sUIVerts = 0;
U32 LLTexUnit::sWhiteTexture = 0;
-bool LLRender::sGLCoreProfile = true;
+bool LLRender::sGLCoreProfile = false;
bool LLRender::sNsightDebugSupport = false;
LLVector2 LLRender::sUIGLScaleFactor = LLVector2(1.f, 1.f);
@@ -79,6 +78,7 @@ struct LLVBCache
};
static std::unordered_map<U64, LLVBCache> sVBCache;
+static thread_local std::list<LLVertexBufferData> *sBufferDataList = nullptr;
static const GLenum sGLTextureType[] =
{
@@ -123,7 +123,7 @@ static const GLenum sGLBlendFactor[] =
LLTexUnit::LLTexUnit(S32 index)
: mCurrTexType(TT_NONE),
- mCurrColorScale(1), mCurrAlphaScale(1), mCurrTexture(0), mTexColorSpace(TCS_LINEAR),
+ mCurrColorScale(1), mCurrAlphaScale(1), mCurrTexture(0),
mHasMipMaps(false),
mIndex(index)
{
@@ -153,13 +153,12 @@ void LLTexUnit::refreshState(void)
{
glBindTexture(GL_TEXTURE_2D, 0);
}
-
- setTextureColorSpace(mTexColorSpace);
}
void LLTexUnit::activate(void)
{
- if (mIndex < 0) return;
+ if (mIndex < 0)
+ return;
if ((S32)gGL.mCurrTextureUnitIndex != mIndex || gGL.mDirty)
{
@@ -171,7 +170,8 @@ void LLTexUnit::activate(void)
void LLTexUnit::enable(eTextureType type)
{
- if (mIndex < 0) return;
+ if (mIndex < 0)
+ return;
if ( (mCurrTexType != type || gGL.mDirty) && (type != TT_NONE) )
{
@@ -188,7 +188,8 @@ void LLTexUnit::enable(eTextureType type)
void LLTexUnit::disable(void)
{
- if (mIndex < 0) return;
+ if (mIndex < 0)
+ return;
if (mCurrTexType != TT_NONE)
{
@@ -224,7 +225,7 @@ bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind)
{
gGL.flush();
- LLImageGL* gl_tex = NULL ;
+ LLImageGL* gl_tex = NULL;
if (texture != NULL && (gl_tex = texture->getGLTexture()))
{
@@ -239,8 +240,8 @@ bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind)
glBindTexture(sGLTextureType[gl_tex->getTarget()], mCurrTexture);
if(gl_tex->updateBindStats())
{
- texture->setActive() ;
- texture->updateBindStatsForTester() ;
+ texture->setActive();
+ texture->updateBindStatsForTester();
}
mHasMipMaps = gl_tex->mHasMipMaps;
if (gl_tex->mTexOptionsDirty)
@@ -249,15 +250,14 @@ bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind)
setTextureAddressMode(gl_tex->mAddressMode);
setTextureFilteringOption(gl_tex->mFilterOption);
}
- setTextureColorSpace(mTexColorSpace);
}
}
else
{
//if deleted, will re-generate it immediately
- texture->forceImmediateUpdate() ;
+ texture->forceImmediateUpdate();
- gl_tex->forceUpdateBindStats() ;
+ gl_tex->forceUpdateBindStats();
return texture->bindDefaultImage(mIndex);
}
}
@@ -285,24 +285,27 @@ bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind)
bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind, S32 usename)
{
stop_glerror();
- if (mIndex < 0) return false;
+ if (mIndex < 0)
+ {
+ return false;
+ }
U32 texname = usename ? usename : texture->getTexName();
- if(!texture)
+ if (!texture)
{
LL_DEBUGS() << "NULL LLTexUnit::bind texture" << LL_ENDL;
return false;
}
- if(!texname)
+ if (!texname)
{
if(LLImageGL::sDefaultGLTexture && LLImageGL::sDefaultGLTexture->getTexName())
{
- return bind(LLImageGL::sDefaultGLTexture) ;
+ return bind(LLImageGL::sDefaultGLTexture);
}
stop_glerror();
- return false ;
+ return false;
}
if ((mCurrTexture != texname) || forceBind)
@@ -326,7 +329,6 @@ bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind, S32
setTextureFilteringOption(texture->mFilterOption);
stop_glerror();
}
- setTextureColorSpace(mTexColorSpace);
}
stop_glerror();
@@ -336,7 +338,10 @@ bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind, S32
bool LLTexUnit::bind(LLCubeMap* cubeMap)
{
- if (mIndex < 0) return false;
+ if (mIndex < 0)
+ {
+ return false;
+ }
gGL.flush();
@@ -362,7 +367,6 @@ bool LLTexUnit::bind(LLCubeMap* cubeMap)
setTextureAddressMode(cubeMap->mImages[0]->mAddressMode);
setTextureFilteringOption(cubeMap->mImages[0]->mFilterOption);
}
- setTextureColorSpace(mTexColorSpace);
return true;
}
else
@@ -377,7 +381,10 @@ bool LLTexUnit::bind(LLCubeMap* cubeMap)
// LLRenderTarget is unavailible on the mapserver since it uses FBOs.
bool LLTexUnit::bind(LLRenderTarget* renderTarget, bool bindDepth)
{
- if (mIndex < 0) return false;
+ if (mIndex < 0)
+ {
+ return false;
+ }
gGL.flush();
@@ -402,7 +409,7 @@ bool LLTexUnit::bindManual(eTextureType type, U32 texture, bool hasMips)
return false;
}
- if(mCurrTexture != texture)
+ if (mCurrTexture != texture)
{
gGL.flush();
@@ -411,8 +418,8 @@ bool LLTexUnit::bindManual(eTextureType type, U32 texture, bool hasMips)
mCurrTexture = texture;
glBindTexture(sGLTextureType[type], texture);
mHasMipMaps = hasMips;
- setTextureColorSpace(mTexColorSpace);
}
+
return true;
}
@@ -420,7 +427,8 @@ void LLTexUnit::unbind(eTextureType type)
{
stop_glerror();
- if (mIndex < 0) return;
+ if (mIndex < 0)
+ return;
//always flush and activate for consistency
// some code paths assume unbind always flushes and sets the active texture
@@ -432,8 +440,6 @@ void LLTexUnit::unbind(eTextureType type)
{
mCurrTexture = 0;
- // Always make sure our texture color space is reset to linear. SRGB sampling should be opt-in in the vast majority of cases. Also prevents color space "popping".
- mTexColorSpace = TCS_LINEAR;
if (type == LLTexUnit::TT_TEXTURE)
{
glBindTexture(sGLTextureType[type], sWhiteTexture);
@@ -455,8 +461,6 @@ void LLTexUnit::unbindFast(eTextureType type)
{
mCurrTexture = 0;
- // Always make sure our texture color space is reset to linear. SRGB sampling should be opt-in in the vast majority of cases. Also prevents color space "popping".
- mTexColorSpace = TCS_LINEAR;
if (type == LLTexUnit::TT_TEXTURE)
{
glBindTexture(sGLTextureType[type], sWhiteTexture);
@@ -470,7 +474,8 @@ void LLTexUnit::unbindFast(eTextureType type)
void LLTexUnit::setTextureAddressMode(eTextureAddressMode mode)
{
- if (mIndex < 0 || mCurrTexture == 0) return;
+ if (mIndex < 0 || mCurrTexture == 0)
+ return;
gGL.flush();
@@ -486,7 +491,8 @@ void LLTexUnit::setTextureAddressMode(eTextureAddressMode mode)
void LLTexUnit::setTextureFilteringOption(LLTexUnit::eTextureFilterOptions option)
{
- if (mIndex < 0 || mCurrTexture == 0 || mCurrTexType == LLTexUnit::TT_MULTISAMPLE_TEXTURE) return;
+ if (mIndex < 0 || mCurrTexture == 0 || mCurrTexType == LLTexUnit::TT_MULTISAMPLE_TEXTURE)
+ return;
gGL.flush();
@@ -542,7 +548,7 @@ void LLTexUnit::setTextureFilteringOption(LLTexUnit::eTextureFilterOptions optio
GLint LLTexUnit::getTextureSource(eTextureBlendSrc src)
{
#if GL_VERSION_1_3
- switch(src)
+ switch (src)
{
// All four cases should return the same value.
case TBS_PREV_COLOR:
@@ -583,14 +589,14 @@ GLint LLTexUnit::getTextureSource(eTextureBlendSrc src)
GLint LLTexUnit::getTextureSourceType(eTextureBlendSrc src, bool isAlpha)
{
- switch(src)
+ 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;
+ return isAlpha ? GL_SRC_ALPHA : GL_SRC_COLOR;
// All four cases should return the same value.
case TBS_PREV_ALPHA:
@@ -604,7 +610,7 @@ GLint LLTexUnit::getTextureSourceType(eTextureBlendSrc src, bool isAlpha)
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;
+ 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:
@@ -615,7 +621,7 @@ GLint LLTexUnit::getTextureSourceType(eTextureBlendSrc src, bool isAlpha)
default:
LL_WARNS() << "Unknown eTextureBlendSrc: " << src << ". Using Source Color or Alpha instead." << LL_ENDL;
- return (isAlpha) ? GL_SRC_ALPHA: GL_SRC_COLOR;
+ return isAlpha ? GL_SRC_ALPHA : GL_SRC_COLOR;
}
}
@@ -626,7 +632,7 @@ void LLTexUnit::setColorScale(S32 scale)
mCurrColorScale = scale;
gGL.flush();
#if GL_VERSION_1_1
- glTexEnvi( GL_TEXTURE_ENV, GL_RGB_SCALE, scale );
+ glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE, scale);
#endif
}
}
@@ -638,7 +644,7 @@ void LLTexUnit::setAlphaScale(S32 scale)
mCurrAlphaScale = scale;
gGL.flush();
#if GL_VERSION_1_1
- glTexEnvi( GL_TEXTURE_ENV, GL_ALPHA_SCALE, scale );
+ glTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, scale);
#endif
}
}
@@ -647,7 +653,8 @@ void LLTexUnit::setAlphaScale(S32 scale)
// texture unit based on the currently set active texture in opengl.
void LLTexUnit::debugTextureUnit(void)
{
- if (mIndex < 0) return;
+ if (mIndex < 0)
+ return;
GLint activeTexture;
glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTexture);
@@ -658,11 +665,6 @@ void LLTexUnit::debugTextureUnit(void)
}
}
-void LLTexUnit::setTextureColorSpace(eTextureColorSpace space)
-{
- mTexColorSpace = space;
-}
-
LLLightState::LLLightState(S32 index)
: mIndex(index),
mEnabled(false),
@@ -674,16 +676,16 @@ LLLightState::LLLightState(S32 index)
{
if (mIndex == 0)
{
- mDiffuse.set(1,1,1,1);
- mDiffuseB.set(0,0,0,0);
- mSpecular.set(1,1,1,1);
+ mDiffuse.set(1, 1, 1, 1);
+ mDiffuseB.set(0, 0, 0, 0);
+ mSpecular.set(1, 1, 1, 1);
}
mSunIsPrimary = true;
- mAmbient.set(0,0,0,1);
- mPosition.set(0,0,1,0);
- mSpotDirection.set(0,0,-1);
+ mAmbient.set(0, 0, 0, 1);
+ mPosition.set(0, 0, 1, 0);
+ mSpotDirection.set(0, 0, -1);
}
void LLLightState::enable()
@@ -765,10 +767,10 @@ void LLLightState::setPosition(const LLVector4& position)
++gGL.mLightHash;
mPosition = position;
//transform position by current modelview matrix
- glh::vec4f pos(position.mV);
- const glh::matrix4f& mat = gGL.getModelviewMatrix();
- mat.mult_matrix_vec(pos);
- mPosition.set(pos.v);
+ glm::vec4 pos(glm::make_vec4(position.mV));
+ const glm::mat4& mat = gGL.getModelviewMatrix();
+ pos = mat * pos;
+ mPosition.set(glm::value_ptr(pos));
}
void LLLightState::setConstantAttenuation(const F32& atten)
@@ -820,19 +822,18 @@ void LLLightState::setSpotDirection(const LLVector3& direction)
{
//always set direction because modelview matrix may have changed
++gGL.mLightHash;
- mSpotDirection = direction;
+
//transform direction by current modelview matrix
- glh::vec3f dir(direction.mV);
- const glh::matrix4f& mat = gGL.getModelviewMatrix();
- mat.mult_matrix_dir(dir);
+ glm::vec3 dir(glm::make_vec3(direction.mV));
+ const glm::mat3 mat(gGL.getModelviewMatrix());
+ dir = mat * dir;
- mSpotDirection.set(dir.v);
+ mSpotDirection.set(glm::value_ptr(dir));
}
LLRender::LLRender()
: mDirty(false),
mCount(0),
- mQuadCycle(0),
mMode(LLRender::TRIANGLES),
mCurrTextureUnitIndex(0)
{
@@ -860,6 +861,10 @@ LLRender::LLRender()
for (U32 i = 0; i < NUM_MATRIX_MODES; ++i)
{
+ for (U32 j = 0; j < LL_MATRIX_STACK_DEPTH; ++j)
+ {
+ mMatrix[i][j] = glm::identity<glm::mat4>();
+ }
mMatIdx[i] = 0;
mMatHash[i] = 0;
mCurMatHash[i] = 0xFFFFFFFF;
@@ -875,7 +880,7 @@ LLRender::~LLRender()
bool LLRender::init(bool needs_vertex_buffer)
{
-#if LL_WINDOWS
+#if GL_ARB_debug_output && !LL_DARWIN
if (gGLManager.mHasDebugOutput && gDebugGL)
{ //setup debug output callback
//glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW_ARB, 0, NULL, GL_TRUE);
@@ -914,6 +919,7 @@ bool LLRender::init(bool needs_vertex_buffer)
{
initVertexBuffer();
}
+
return true;
}
@@ -922,7 +928,7 @@ void LLRender::initVertexBuffer()
llassert_always(mBuffer.isNull());
stop_glerror();
mBuffer = new LLVertexBuffer(immediate_mask);
- mBuffer->allocateBuffer(BATCH_SIZE, 0);
+ mBuffer->allocateBuffer(4096, 0);
mBuffer->getVertexStrider(mVerticesp);
mBuffer->getTexCoord0Strider(mTexcoordsp);
mBuffer->getColorStrider(mColorsp);
@@ -1023,12 +1029,12 @@ void LLRender::syncMatrices()
LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
- static glh::matrix4f cached_mvp;
- static glh::matrix4f cached_inv_mdv;
+ static glm::mat4 cached_mvp;
+ static glm::mat4 cached_inv_mdv;
static U32 cached_mvp_mdv_hash = 0xFFFFFFFF;
static U32 cached_mvp_proj_hash = 0xFFFFFFFF;
- static glh::matrix4f cached_normal;
+ static glm::mat4 cached_normal;
static U32 cached_normal_hash = 0xFFFFFFFF;
if (shader)
@@ -1038,15 +1044,15 @@ void LLRender::syncMatrices()
U32 i = MM_MODELVIEW;
if (mMatHash[MM_MODELVIEW] != shader->mMatHash[MM_MODELVIEW])
{ //update modelview, normal, and MVP
- glh::matrix4f& mat = mMatrix[MM_MODELVIEW][mMatIdx[MM_MODELVIEW]];
+ const glm::mat4& mat = mMatrix[MM_MODELVIEW][mMatIdx[MM_MODELVIEW]];
// if MDV has changed, update the cached inverse as well
if (cached_mvp_mdv_hash != mMatHash[MM_MODELVIEW])
{
- cached_inv_mdv = mat.inverse();
+ cached_inv_mdv = glm::inverse(mat);
}
- shader->uniformMatrix4fv(name[MM_MODELVIEW], 1, GL_FALSE, mat.m);
+ shader->uniformMatrix4fv(name[MM_MODELVIEW], 1, GL_FALSE, glm::value_ptr(mat));
shader->mMatHash[MM_MODELVIEW] = mMatHash[MM_MODELVIEW];
//update normal matrix
@@ -1055,17 +1061,17 @@ void LLRender::syncMatrices()
{
if (cached_normal_hash != mMatHash[i])
{
- cached_normal = cached_inv_mdv.transpose();
+ cached_normal = glm::transpose(cached_inv_mdv);
cached_normal_hash = mMatHash[i];
}
- glh::matrix4f& norm = cached_normal;
+ auto norm = glm::value_ptr(cached_normal);
F32 norm_mat[] =
{
- norm.m[0], norm.m[1], norm.m[2],
- norm.m[4], norm.m[5], norm.m[6],
- norm.m[8], norm.m[9], norm.m[10]
+ norm[0], norm[1], norm[2],
+ norm[4], norm[5], norm[6],
+ norm[8], norm[9], norm[10]
};
shader->uniformMatrix3fv(LLShaderMgr::NORMAL_MATRIX, 1, GL_FALSE, norm_mat);
@@ -1073,7 +1079,7 @@ void LLRender::syncMatrices()
if (shader->getUniformLocation(LLShaderMgr::INVERSE_MODELVIEW_MATRIX))
{
- shader->uniformMatrix4fv(LLShaderMgr::INVERSE_MODELVIEW_MATRIX, 1, GL_FALSE, cached_inv_mdv.m);
+ shader->uniformMatrix4fv(LLShaderMgr::INVERSE_MODELVIEW_MATRIX, 1, GL_FALSE, glm::value_ptr(cached_inv_mdv));
}
//update MVP matrix
@@ -1086,36 +1092,36 @@ void LLRender::syncMatrices()
if (cached_mvp_mdv_hash != mMatHash[i] || cached_mvp_proj_hash != mMatHash[MM_PROJECTION])
{
cached_mvp = mat;
- cached_mvp.mult_left(mMatrix[proj][mMatIdx[proj]]);
+ cached_mvp = mMatrix[proj][mMatIdx[proj]] * cached_mvp;
cached_mvp_mdv_hash = mMatHash[i];
cached_mvp_proj_hash = mMatHash[MM_PROJECTION];
}
- shader->uniformMatrix4fv(LLShaderMgr::MODELVIEW_PROJECTION_MATRIX, 1, GL_FALSE, cached_mvp.m);
+ shader->uniformMatrix4fv(LLShaderMgr::MODELVIEW_PROJECTION_MATRIX, 1, GL_FALSE, glm::value_ptr(cached_mvp));
}
}
i = MM_PROJECTION;
if (mMatHash[MM_PROJECTION] != shader->mMatHash[MM_PROJECTION])
{ //update projection matrix, normal, and MVP
- glh::matrix4f& mat = mMatrix[MM_PROJECTION][mMatIdx[MM_PROJECTION]];
+ const glm::mat4& mat = mMatrix[MM_PROJECTION][mMatIdx[MM_PROJECTION]];
// GZ: This was previously disabled seemingly due to a bug involving the deferred renderer's regular pushing and popping of mats.
// We're reenabling this and cleaning up the code around that - that would've been the appropriate course initially.
// Anything beyond the standard proj and inv proj mats are special cases. Please setup special uniforms accordingly in the future.
if (shader->getUniformLocation(LLShaderMgr::INVERSE_PROJECTION_MATRIX))
{
- glh::matrix4f inv_proj = mat.inverse();
- shader->uniformMatrix4fv(LLShaderMgr::INVERSE_PROJECTION_MATRIX, 1, false, inv_proj.m);
+ glm::mat4 inv_proj = glm::inverse(mat);
+ shader->uniformMatrix4fv(LLShaderMgr::INVERSE_PROJECTION_MATRIX, 1, false, glm::value_ptr(inv_proj));
}
// Used by some full screen effects - such as full screen lights, glow, etc.
if (shader->getUniformLocation(LLShaderMgr::IDENTITY_MATRIX))
{
- shader->uniformMatrix4fv(LLShaderMgr::IDENTITY_MATRIX, 1, GL_FALSE, glh::matrix4f::identity().m);
+ shader->uniformMatrix4fv(LLShaderMgr::IDENTITY_MATRIX, 1, GL_FALSE, glm::value_ptr(glm::identity<glm::mat4>()));
}
- shader->uniformMatrix4fv(name[MM_PROJECTION], 1, GL_FALSE, mat.m);
+ shader->uniformMatrix4fv(name[MM_PROJECTION], 1, GL_FALSE, glm::value_ptr(mat));
shader->mMatHash[MM_PROJECTION] = mMatHash[MM_PROJECTION];
if (!mvp_done)
@@ -1128,12 +1134,12 @@ void LLRender::syncMatrices()
{
U32 mdv = MM_MODELVIEW;
cached_mvp = mat;
- cached_mvp.mult_right(mMatrix[mdv][mMatIdx[mdv]]);
+ cached_mvp *= mMatrix[mdv][mMatIdx[mdv]];
cached_mvp_mdv_hash = mMatHash[MM_MODELVIEW];
cached_mvp_proj_hash = mMatHash[MM_PROJECTION];
}
- shader->uniformMatrix4fv(LLShaderMgr::MODELVIEW_PROJECTION_MATRIX, 1, GL_FALSE, cached_mvp.m);
+ shader->uniformMatrix4fv(LLShaderMgr::MODELVIEW_PROJECTION_MATRIX, 1, GL_FALSE, glm::value_ptr(cached_mvp));
}
}
}
@@ -1142,12 +1148,11 @@ void LLRender::syncMatrices()
{
if (mMatHash[i] != shader->mMatHash[i])
{
- shader->uniformMatrix4fv(name[i], 1, GL_FALSE, mMatrix[i][mMatIdx[i]].m);
+ shader->uniformMatrix4fv(name[i], 1, GL_FALSE, glm::value_ptr(mMatrix[i][mMatIdx[i]]));
shader->mMatHash[i] = mMatHash[i];
}
}
-
if (shader->mFeatures.hasLighting || shader->mFeatures.calculatesLighting || shader->mFeatures.calculatesAtmospherics)
{ //also sync light state
syncLightState();
@@ -1160,121 +1165,78 @@ void LLRender::translatef(const GLfloat& x, const GLfloat& y, const GLfloat& z)
{
flush();
- {
- glh::matrix4f trans_mat(1,0,0,x,
- 0,1,0,y,
- 0,0,1,z,
- 0,0,0,1);
-
- mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mult_right(trans_mat);
- mMatHash[mMatrixMode]++;
- }
+ mMatrix[mMatrixMode][mMatIdx[mMatrixMode]] = glm::translate(mMatrix[mMatrixMode][mMatIdx[mMatrixMode]], glm::vec3(x, y, z));
+ mMatHash[mMatrixMode]++;
}
void LLRender::scalef(const GLfloat& x, const GLfloat& y, const GLfloat& z)
{
flush();
- {
- glh::matrix4f scale_mat(x,0,0,0,
- 0,y,0,0,
- 0,0,z,0,
- 0,0,0,1);
-
- mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mult_right(scale_mat);
- mMatHash[mMatrixMode]++;
- }
+ mMatrix[mMatrixMode][mMatIdx[mMatrixMode]] = glm::scale(mMatrix[mMatrixMode][mMatIdx[mMatrixMode]], glm::vec3(x, y, z));
+ mMatHash[mMatrixMode]++;
}
void LLRender::ortho(F32 left, F32 right, F32 bottom, F32 top, F32 zNear, F32 zFar)
{
flush();
- {
-
- glh::matrix4f ortho_mat(2.f/(right-left),0,0, -(right+left)/(right-left),
- 0,2.f/(top-bottom),0, -(top+bottom)/(top-bottom),
- 0,0,-2.f/(zFar-zNear), -(zFar+zNear)/(zFar-zNear),
- 0,0,0,1);
-
- mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mult_right(ortho_mat);
- mMatHash[mMatrixMode]++;
- }
+ mMatrix[mMatrixMode][mMatIdx[mMatrixMode]] *= glm::ortho(left, right, bottom, top, zNear, zFar);
+ mMatHash[mMatrixMode]++;
}
void LLRender::rotatef(const GLfloat& a, const GLfloat& x, const GLfloat& y, const GLfloat& z)
{
flush();
- {
- F32 r = a * DEG_TO_RAD;
-
- F32 c = cosf(r);
- F32 s = sinf(r);
-
- F32 ic = 1.f-c;
-
- glh::matrix4f rot_mat(x*x*ic+c, x*y*ic-z*s, x*z*ic+y*s, 0,
- x*y*ic+z*s, y*y*ic+c, y*z*ic-x*s, 0,
- x*z*ic-y*s, y*z*ic+x*s, z*z*ic+c, 0,
- 0,0,0,1);
-
- mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mult_right(rot_mat);
- mMatHash[mMatrixMode]++;
- }
+ mMatrix[mMatrixMode][mMatIdx[mMatrixMode]] = glm::rotate(mMatrix[mMatrixMode][mMatIdx[mMatrixMode]], glm::radians(a), glm::vec3(x,y,z));
+ mMatHash[mMatrixMode]++;
}
void LLRender::pushMatrix()
{
flush();
+ if (mMatIdx[mMatrixMode] < LL_MATRIX_STACK_DEPTH-1)
{
- if (mMatIdx[mMatrixMode] < LL_MATRIX_STACK_DEPTH-1)
- {
- mMatrix[mMatrixMode][mMatIdx[mMatrixMode]+1] = mMatrix[mMatrixMode][mMatIdx[mMatrixMode]];
- ++mMatIdx[mMatrixMode];
- }
- else
- {
- LL_WARNS() << "Matrix stack overflow." << LL_ENDL;
- }
+ mMatrix[mMatrixMode][mMatIdx[mMatrixMode]+1] = mMatrix[mMatrixMode][mMatIdx[mMatrixMode]];
+ ++mMatIdx[mMatrixMode];
+ }
+ else
+ {
+ LL_WARNS() << "Matrix stack overflow." << LL_ENDL;
}
}
void LLRender::popMatrix()
{
flush();
+
+ if (mMatIdx[mMatrixMode] > 0)
{
- if (mMatIdx[mMatrixMode] > 0)
- {
- --mMatIdx[mMatrixMode];
- mMatHash[mMatrixMode]++;
- }
- else
- {
- LL_WARNS() << "Matrix stack underflow." << LL_ENDL;
- }
+ --mMatIdx[mMatrixMode];
+ mMatHash[mMatrixMode]++;
+ }
+ else
+ {
+ LL_WARNS() << "Matrix stack underflow." << LL_ENDL;
}
}
void LLRender::loadMatrix(const GLfloat* m)
{
flush();
- {
- mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].set_value((GLfloat*) m);
- mMatHash[mMatrixMode]++;
- }
+
+ mMatrix[mMatrixMode][mMatIdx[mMatrixMode]] = glm::make_mat4((GLfloat*) m);
+ mMatHash[mMatrixMode]++;
}
void LLRender::multMatrix(const GLfloat* m)
{
flush();
- {
- glh::matrix4f mat((GLfloat*) m);
- mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].mult_right(mat);
- mMatHash[mMatrixMode]++;
- }
+ mMatrix[mMatrixMode][mMatIdx[mMatrixMode]] *= glm::make_mat4(m);
+ mMatHash[mMatrixMode]++;
}
void LLRender::matrixMode(eMatrixMode mode)
@@ -1312,20 +1274,18 @@ void LLRender::loadIdentity()
{
flush();
- {
- llassert_always(mMatrixMode < NUM_MATRIX_MODES) ;
+ llassert_always(mMatrixMode < NUM_MATRIX_MODES);
- mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].make_identity();
- mMatHash[mMatrixMode]++;
- }
+ mMatrix[mMatrixMode][mMatIdx[mMatrixMode]] = glm::identity<glm::mat4>();
+ mMatHash[mMatrixMode]++;
}
-const glh::matrix4f& LLRender::getModelviewMatrix()
+const glm::mat4& LLRender::getModelviewMatrix()
{
return mMatrix[MM_MODELVIEW][mMatIdx[MM_MODELVIEW]];
}
-const glh::matrix4f& LLRender::getProjectionMatrix()
+const glm::mat4& LLRender::getProjectionMatrix()
{
return mMatrix[MM_PROJECTION][mMatIdx[MM_PROJECTION]];
}
@@ -1337,8 +1297,7 @@ void LLRender::translateUI(F32 x, F32 y, F32 z)
LL_ERRS() << "Need to push a UI translation frame before offsetting" << LL_ENDL;
}
- LLVector4a add(x,y,z);
- mUIOffset.back().add(add);
+ mUIOffset.back().add(LLVector4a(x, y, z));
}
void LLRender::scaleUI(F32 x, F32 y, F32 z)
@@ -1348,15 +1307,14 @@ void LLRender::scaleUI(F32 x, F32 y, F32 z)
LL_ERRS() << "Need to push a UI transformation frame before scaling." << LL_ENDL;
}
- LLVector4a scale(x,y,z);
- mUIScale.back().mul(scale);
+ mUIScale.back().mul(LLVector4a(x, y, z));
}
void LLRender::pushUIMatrix()
{
if (mUIOffset.empty())
{
- mUIOffset.emplace_back(LLVector4a::getZero());
+ mUIOffset.emplace_back(0.f);
}
else
{
@@ -1365,7 +1323,7 @@ void LLRender::pushUIMatrix()
if (mUIScale.empty())
{
- mUIScale.emplace_back(LLVector4a(1.f));
+ mUIScale.emplace_back(1.f);
}
else
{
@@ -1387,8 +1345,9 @@ LLVector3 LLRender::getUITranslation()
{
if (mUIOffset.empty())
{
- return LLVector3(0,0,0);
+ return LLVector3::zero;
}
+
return LLVector3(mUIOffset.back().getF32ptr());
}
@@ -1396,19 +1355,22 @@ LLVector3 LLRender::getUIScale()
{
if (mUIScale.empty())
{
- return LLVector3(1,1,1);
+ return LLVector3::all_one;
}
+
return LLVector3(mUIScale.back().getF32ptr());
}
+
void LLRender::loadUIIdentity()
{
if (mUIOffset.empty())
{
LL_ERRS() << "Need to push UI translation frame before clearing offset." << LL_ENDL;
}
- mUIOffset.back().splat(0.f);
- mUIScale.back().splat(1.f);
+
+ mUIOffset.back().clear();
+ mUIScale.back().splat(1);
}
void LLRender::setColorMask(bool writeColor, bool writeAlpha)
@@ -1502,7 +1464,7 @@ void LLRender::blendFunc(eBlendFactor color_sfactor, eBlendFactor color_dfactor,
flush();
glBlendFuncSeparate(sGLBlendFactor[color_sfactor], sGLBlendFactor[color_dfactor],
- sGLBlendFactor[alpha_sfactor], sGLBlendFactor[alpha_dfactor]);
+ sGLBlendFactor[alpha_sfactor], sGLBlendFactor[alpha_dfactor]);
}
}
@@ -1512,11 +1474,9 @@ LLTexUnit* LLRender::getTexUnit(U32 index)
{
return &mTexUnits[index];
}
- else
- {
- LL_DEBUGS() << "Non-existing texture unit layer requested: " << index << LL_ENDL;
- return &mDummyTexUnit;
- }
+
+ LL_DEBUGS() << "Non-existing texture unit layer requested: " << index << LL_ENDL;
+ return &mDummyTexUnit;
}
LLLightState* LLRender::getLight(U32 index)
@@ -1545,11 +1505,9 @@ bool LLRender::verifyTexUnitActive(U32 unitToVerify)
{
return true;
}
- else
- {
- LL_WARNS() << "TexUnit currently active: " << mCurrTextureUnitIndex << " (expecting " << unitToVerify << ")" << LL_ENDL;
- return false;
- }
+
+ LL_WARNS() << "TexUnit currently active: " << mCurrTextureUnitIndex << " (expecting " << unitToVerify << ")" << LL_ENDL;
+ return false;
}
void LLRender::clearErrors()
@@ -1560,17 +1518,36 @@ void LLRender::clearErrors()
}
}
+void LLRender::beginList(std::list<LLVertexBufferData> *list)
+{
+ if (sBufferDataList)
+ {
+ LL_ERRS() << "beginList called while another list is open." << LL_ENDL;
+ }
+
+ llassert(LLGLSLShader::sCurBoundShaderPtr == &gUIProgram);
+ flush();
+ sBufferDataList = list;
+}
+
+void LLRender::endList()
+{
+ if (sBufferDataList)
+ {
+ flush();
+ sBufferDataList = nullptr;
+ }
+ else
+ {
+ llassert(false); // endList called without an open list
+ }
+}
+
void LLRender::begin(const GLuint& mode)
{
if (mode != mMode)
{
- if (mode == LLRender::QUADS)
- {
- mQuadCycle = 1;
- }
-
- if (mMode == LLRender::QUADS ||
- mMode == LLRender::LINES ||
+ if (mMode == LLRender::LINES ||
mMode == LLRender::TRIANGLES ||
mMode == LLRender::POINTS)
{
@@ -1593,15 +1570,15 @@ void LLRender::end()
//IMM_ERRS << "GL begin and end called with no vertices specified." << LL_ENDL;
}
- if ((mMode != LLRender::QUADS &&
- mMode != LLRender::LINES &&
+ if ((mMode != LLRender::LINES &&
mMode != LLRender::TRIANGLES &&
mMode != LLRender::POINTS) ||
- mCount > (BATCH_SIZE / 2))
+ mCount > 2048)
{
flush();
}
}
+
void LLRender::flush()
{
STOP_GLERROR;
@@ -1618,27 +1595,18 @@ void LLRender::flush()
//store mCount in a local variable to avoid re-entrance (drawArrays may call flush)
U32 count = mCount;
- if (mMode == LLRender::QUADS && !sGLCoreProfile)
- {
- if (mCount%4 != 0)
- {
- count -= (mCount % 4);
- LL_WARNS() << "Incomplete quad requested." << LL_ENDL;
- }
- }
-
if (mMode == LLRender::TRIANGLES)
{
- if (mCount%3 != 0)
+ if (mCount % 3 != 0)
{
- count -= (mCount % 3);
- LL_WARNS() << "Incomplete triangle requested." << LL_ENDL;
+ count -= (mCount % 3);
+ LL_WARNS() << "Incomplete triangle requested." << LL_ENDL;
}
}
if (mMode == LLRender::LINES)
{
- if (mCount%2 != 0)
+ if (mCount % 2 != 0)
{
count -= (mCount % 2);
LL_WARNS() << "Incomplete line requested." << LL_ENDL;
@@ -1649,296 +1617,284 @@ void LLRender::flush()
if (mBuffer)
{
+ LLVertexBuffer *vb;
- HBXXH64 hash;
U32 attribute_mask = LLGLSLShader::sCurBoundShaderPtr->mAttributeMask;
+ if (sBufferDataList)
{
- LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("vb cache hash");
+ vb = genBuffer(attribute_mask, count);
+ sBufferDataList->emplace_back(
+ vb,
+ mMode,
+ count,
+ gGL.getTexUnit(0)->mCurrTexture,
+ mMatrix[MM_MODELVIEW][mMatIdx[MM_MODELVIEW]],
+ mMatrix[MM_PROJECTION][mMatIdx[MM_PROJECTION]],
+ mMatrix[MM_TEXTURE0][mMatIdx[MM_TEXTURE0]]
+ );
+ }
+ else
+ {
+ vb = bufferfromCache(attribute_mask, count);
+ }
- hash.update((U8*)mVerticesp.get(), count * sizeof(LLVector4a));
- if (attribute_mask & LLVertexBuffer::MAP_TEXCOORD0)
- {
- hash.update((U8*)mTexcoordsp.get(), count * sizeof(LLVector2));
- }
+ drawBuffer(vb, mMode, count);
+ }
+ else
+ {
+ // mBuffer is present in main thread and not present in an image thread
+ LL_ERRS() << "A flush call from outside main rendering thread" << LL_ENDL;
+ }
- if (attribute_mask & LLVertexBuffer::MAP_COLOR)
- {
- hash.update((U8*)mColorsp.get(), count * sizeof(LLColor4U));
- }
+ resetStriders(count);
+ }
+}
- hash.finalize();
- }
+LLVertexBuffer* LLRender::bufferfromCache(U32 attribute_mask, U32 count)
+{
+ LLVertexBuffer *vb = nullptr;
+ HBXXH64 hash;
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("vb cache hash");
- U64 vhash = hash.digest();
+ hash.update((U8*)mVerticesp.get(), count * sizeof(LLVector4a));
+ if (attribute_mask & LLVertexBuffer::MAP_TEXCOORD0)
+ {
+ hash.update((U8*)mTexcoordsp.get(), count * sizeof(LLVector2));
+ }
- // check the VB cache before making a new vertex buffer
- // This is a giant hack to deal with (mostly) our terrible UI rendering code
- // that was built on top of OpenGL immediate mode. Huge performance wins
- // can be had by not uploading geometry to VRAM unless absolutely necessary.
- // Most of our usage of the "immediate mode" style draw calls is actually
- // sending the same geometry over and over again.
- // To leverage this, we maintain a running hash of the vertex stream being
- // built up before a flush, and then check that hash against a VB
- // cache just before creating a vertex buffer in VRAM
- std::unordered_map<U64, LLVBCache>::iterator cache = sVBCache.find(vhash);
+ if (attribute_mask & LLVertexBuffer::MAP_COLOR)
+ {
+ hash.update((U8*)mColorsp.get(), count * sizeof(LLColor4U));
+ }
- LLPointer<LLVertexBuffer> vb;
+ hash.finalize();
+ }
- if (cache != sVBCache.end())
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("vb cache hit");
- // cache hit, just use the cached buffer
- vb = cache->second.vb;
- cache->second.touched = std::chrono::steady_clock::now();
- }
- else
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("vb cache miss");
- vb = new LLVertexBuffer(attribute_mask);
- vb->allocateBuffer(count, 0);
+ U64 vhash = hash.digest();
- vb->setBuffer();
+ // check the VB cache before making a new vertex buffer
+ // This is a giant hack to deal with (mostly) our terrible UI rendering code
+ // that was built on top of OpenGL immediate mode. Huge performance wins
+ // can be had by not uploading geometry to VRAM unless absolutely necessary.
+ // Most of our usage of the "immediate mode" style draw calls is actually
+ // sending the same geometry over and over again.
+ // To leverage this, we maintain a running hash of the vertex stream being
+ // built up before a flush, and then check that hash against a VB
+ // cache just before creating a vertex buffer in VRAM
+ std::unordered_map<U64, LLVBCache>::iterator cache = sVBCache.find(vhash);
+
+ if (cache != sVBCache.end())
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("vb cache hit");
+ // cache hit, just use the cached buffer
+ vb = cache->second.vb;
+ cache->second.touched = std::chrono::steady_clock::now();
+ }
+ else
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("vb cache miss");
+ vb = genBuffer(attribute_mask, count);
- vb->setPositionData(mVerticesp.get());
+ sVBCache[vhash] = { vb , std::chrono::steady_clock::now() };
- if (attribute_mask & LLVertexBuffer::MAP_TEXCOORD0)
- {
- vb->setTexCoord0Data(mTexcoordsp.get());
- }
+ static U32 miss_count = 0;
+ miss_count++;
+ if (miss_count > 1024)
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("vb cache clean");
+ miss_count = 0;
+ auto now = std::chrono::steady_clock::now();
- if (attribute_mask & LLVertexBuffer::MAP_COLOR)
+ using namespace std::chrono_literals;
+ // every 1024 misses, clean the cache of any VBs that haven't been touched in the last second
+ for (std::unordered_map<U64, LLVBCache>::iterator iter = sVBCache.begin(); iter != sVBCache.end(); )
+ {
+ if (now - iter->second.touched > 1s)
{
- vb->setColorData(mColorsp.get());
+ iter = sVBCache.erase(iter);
}
-
- //LL_INFOS() << "LLVertexBuffer::sMappingMode " << LLVertexBuffer::sMappingMode << LL_ENDL;
- if(LLVertexBuffer::sMappingMode == 3)
+ else
{
- vb->unmapBuffer();
+ ++iter;
}
+ }
+ }
+ }
- vb->unbind();
+ return vb;
+}
- sVBCache[vhash] = { vb , std::chrono::steady_clock::now() };
+LLVertexBuffer* LLRender::genBuffer(U32 attribute_mask, S32 count)
+{
+ LLVertexBuffer * vb = new LLVertexBuffer(attribute_mask);
+ vb->allocateBuffer(count, 0);
- static U32 miss_count = 0;
- miss_count++;
- if (miss_count > 1024)
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("vb cache clean");
- miss_count = 0;
- auto now = std::chrono::steady_clock::now();
+ vb->setBuffer();
- using namespace std::chrono_literals;
- // every 1024 misses, clean the cache of any VBs that haven't been touched in the last second
- for (std::unordered_map<U64, LLVBCache>::iterator iter = sVBCache.begin(); iter != sVBCache.end(); )
- {
- if (now - iter->second.touched > 1s)
- {
- iter = sVBCache.erase(iter);
- }
- else
- {
- ++iter;
- }
- }
- }
- }
+ vb->setPositionData(mVerticesp.get());
- vb->setBuffer();
+ if (attribute_mask & LLVertexBuffer::MAP_TEXCOORD0)
+ {
+ vb->setTexCoord0Data(mTexcoordsp.get());
+ }
- if (mMode == LLRender::QUADS && sGLCoreProfile)
- {
- vb->drawArrays(LLRender::TRIANGLES, 0, count);
- mQuadCycle = 1;
- }
- else
- {
- vb->drawArrays(mMode, 0, count);
- }
- }
- else
- {
- // mBuffer is present in main thread and not present in an image thread
- LL_ERRS() << "A flush call from outside main rendering thread" << LL_ENDL;
- }
+ if (attribute_mask & LLVertexBuffer::MAP_COLOR)
+ {
+ vb->setColorData(mColorsp.get());
+ }
+
+#if LL_DARWIN
+ vb->unmapBuffer();
+#endif
+ vb->unbind();
+ return vb;
+}
- mVerticesp[0] = mVerticesp[count];
- mTexcoordsp[0] = mTexcoordsp[count];
- mColorsp[0] = mColorsp[count];
+void LLRender::drawBuffer(LLVertexBuffer* vb, U32 mode, S32 count)
+{
+ vb->setBuffer();
+ vb->drawArrays(mode, 0, count);
+}
- mCount = 0;
- }
+void LLRender::resetStriders(S32 count)
+{
+ mVerticesp[0] = mVerticesp[count];
+ mTexcoordsp[0] = mTexcoordsp[count];
+ mColorsp[0] = mColorsp[count];
+
+ mCount = 0;
}
-void LLRender::vertex4a(const LLVector4a& vertex)
+void LLRender::vertex3f(const GLfloat& x, const GLfloat& y, const GLfloat& z)
{
- //the range of mVerticesp, mColorsp and mTexcoordsp is [0, 4095]
- if (mCount > BATCH_SIZE / 2)
- { //break when buffer gets reasonably full to keep GL command buffers happy and avoid overflow below
+ // the range of mVerticesp, mColorsp and mTexcoordsp is [0, 4095]
+ if (mCount > 2048)
+ { // break when buffer gets reasonably full to keep GL command buffers happy and avoid overflow below
switch (mMode)
{
- case LLRender::POINTS: flush(); break;
- case LLRender::TRIANGLES: if (mCount%3==0) flush(); break;
- case LLRender::QUADS: if(mCount%4 == 0) flush(); break;
- case LLRender::LINES: if (mCount%2 == 0) flush(); break;
+ case LLRender::POINTS:
+ flush();
+ break;
+ case LLRender::TRIANGLES:
+ if (mCount % 3 == 0)
+ {
+ flush();
+ }
+ break;
+ case LLRender::LINES:
+ if (mCount % 2 == 0)
+ {
+ flush();
+ }
+ break;
}
}
- if (mCount > BATCH_SIZE - 2)
+ if (mCount > 4094)
{
- LL_WARNS() << "GL immediate mode overflow. Some geometry not drawn." << LL_ENDL;
+ // LL_WARNS() << "GL immediate mode overflow. Some geometry not drawn." << LL_ENDL;
return;
}
- if (mUIOffset.empty())
+ LLVector4a vert(x, y, z);
+ transform(vert);
+ mVerticesp[mCount] = vert;
+
+ mCount++;
+ mVerticesp[mCount] = vert;
+ mColorsp[mCount] = mColorsp[mCount-1];
+ mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
+}
+
+void LLRender::transform(LLVector3& vert)
+{
+ if (!mUIOffset.empty())
{
- mVerticesp[mCount] = vertex;
+ vert += LLVector3(mUIOffset.back().getF32ptr());
+ vert *= LLVector3(mUIScale.back().getF32ptr());
}
- else
+}
+
+void LLRender::transform(LLVector4a& vert)
+{
+ if (!mUIOffset.empty())
{
- mVerticesp[mCount].setAdd(vertex, mUIOffset.back());
- mVerticesp[mCount].mul(mUIScale.back());
+ vert.add(mUIOffset.back());
+ vert.mul(mUIScale.back());
}
+}
- if (mMode == LLRender::QUADS && LLRender::sGLCoreProfile)
+void LLRender::untransform(LLVector3& vert)
+{
+ if (!mUIOffset.empty())
{
- mQuadCycle++;
- if (mQuadCycle == 4)
- { //copy two vertices so fourth quad element will add a triangle
- mQuadCycle = 0;
+ vert /= LLVector3(mUIScale.back().getF32ptr());
+ vert -= LLVector3(mUIOffset.back().getF32ptr());
+ }
+}
- mCount++;
- mVerticesp[mCount] = mVerticesp[mCount-3];
- mColorsp[mCount] = mColorsp[mCount-3];
- mTexcoordsp[mCount] = mTexcoordsp[mCount-3];
+void LLRender::batchTransform(LLVector4a* verts, U32 vert_count)
+{
+ if (!mUIOffset.empty())
+ {
+ const LLVector4a& offset = mUIOffset.back();
+ const LLVector4a& scale = mUIScale.back();
- mCount++;
- mVerticesp[mCount] = mVerticesp[mCount-2];
- mColorsp[mCount] = mColorsp[mCount-2];
- mTexcoordsp[mCount] = mTexcoordsp[mCount-2];
+ for (U32 i = 0; i < vert_count; ++i)
+ {
+ verts[i].add(offset);
+ verts[i].mul(scale);
}
}
+}
- mCount++;
- mVerticesp[mCount] = mVerticesp[mCount-1];
- mColorsp[mCount] = mColorsp[mCount-1];
- mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
+void LLRender::vertexBatchPreTransformed(const std::vector<LLVector4a>& verts)
+{
+ vertexBatchPreTransformed(verts.data(), verts.size());
}
-void LLRender::vertexBatchPreTransformed(LLVector4a* verts, S32 vert_count)
+void LLRender::vertexBatchPreTransformed(const LLVector4a* verts, std::size_t vert_count)
{
- if (mCount + vert_count > BATCH_SIZE - 2)
+ if (mCount + vert_count > 4094)
{
// LL_WARNS() << "GL immediate mode overflow. Some geometry not drawn." << LL_ENDL;
return;
}
- if (sGLCoreProfile && mMode == LLRender::QUADS)
- { //quads are deprecated, convert to triangle list
- S32 i = 0;
-
- while (i < vert_count)
- {
- //read first three
- mVerticesp[mCount++] = verts[i++];
- mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
- mColorsp[mCount] = mColorsp[mCount-1];
-
- mVerticesp[mCount++] = verts[i++];
- mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
- mColorsp[mCount] = mColorsp[mCount-1];
-
- mVerticesp[mCount++] = verts[i++];
- mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
- mColorsp[mCount] = mColorsp[mCount-1];
-
- //copy two
- mVerticesp[mCount++] = verts[i-3];
- mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
- mColorsp[mCount] = mColorsp[mCount-1];
-
- mVerticesp[mCount++] = verts[i-1];
- mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
- mColorsp[mCount] = mColorsp[mCount-1];
-
- //copy last one
- mVerticesp[mCount++] = verts[i++];
- mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
- mColorsp[mCount] = mColorsp[mCount-1];
- }
- }
- else
+ for (S32 i = 0; i < vert_count; i++)
{
- for (S32 i = 0; i < vert_count; i++)
- {
- mVerticesp[mCount] = verts[i];
+ mVerticesp[mCount] = verts[i];
- mCount++;
- mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
- mColorsp[mCount] = mColorsp[mCount-1];
- }
+ mCount++;
+ mTexcoordsp[mCount] = mTexcoordsp[mCount - 1];
+ mColorsp[mCount] = mColorsp[mCount - 1];
}
- if( mCount > 0 ) // ND: Guard against crashes if mCount is zero, yes it can happen
- mVerticesp[mCount] = mVerticesp[mCount-1];
+ if (mCount > 0) // ND: Guard against crashes if mCount is zero, yes it can happen
+ {
+ mVerticesp[mCount] = mVerticesp[mCount - 1];
+ }
}
-void LLRender::vertexBatchPreTransformed(LLVector4a* verts, LLVector2* uvs, S32 vert_count)
+void LLRender::vertexBatchPreTransformed(const LLVector4a* verts, const LLVector2* uvs, std::size_t vert_count)
{
- if (mCount + vert_count > BATCH_SIZE - 2)
+ if (mCount + vert_count > 4094)
{
// LL_WARNS() << "GL immediate mode overflow. Some geometry not drawn." << LL_ENDL;
return;
}
- if (sGLCoreProfile && mMode == LLRender::QUADS)
- { //quads are deprecated, convert to triangle list
- S32 i = 0;
-
- while (i < vert_count)
- {
- //read first three
- mVerticesp[mCount] = verts[i];
- mTexcoordsp[mCount++] = uvs[i++];
- mColorsp[mCount] = mColorsp[mCount-1];
-
- mVerticesp[mCount] = verts[i];
- mTexcoordsp[mCount++] = uvs[i++];
- mColorsp[mCount] = mColorsp[mCount-1];
-
- mVerticesp[mCount] = verts[i];
- mTexcoordsp[mCount++] = uvs[i++];
- mColorsp[mCount] = mColorsp[mCount-1];
-
- //copy last two
- mVerticesp[mCount] = verts[i-3];
- mTexcoordsp[mCount++] = uvs[i-3];
- mColorsp[mCount] = mColorsp[mCount-1];
-
- mVerticesp[mCount] = verts[i-1];
- mTexcoordsp[mCount++] = uvs[i-1];
- mColorsp[mCount] = mColorsp[mCount-1];
-
- //copy last one
- mVerticesp[mCount] = verts[i];
- mTexcoordsp[mCount++] = uvs[i++];
- mColorsp[mCount] = mColorsp[mCount-1];
- }
- }
- else
+ for (S32 i = 0; i < vert_count; i++)
{
- for (S32 i = 0; i < vert_count; i++)
- {
- mVerticesp[mCount] = verts[i];
- mTexcoordsp[mCount] = uvs[i];
+ mVerticesp[mCount] = verts[i];
+ mTexcoordsp[mCount] = uvs[i];
- mCount++;
- mColorsp[mCount] = mColorsp[mCount-1];
- }
+ mCount++;
+ mColorsp[mCount] = mColorsp[mCount-1];
}
if (mCount > 0)
@@ -1948,59 +1904,21 @@ void LLRender::vertexBatchPreTransformed(LLVector4a* verts, LLVector2* uvs, S32
}
}
-void LLRender::vertexBatchPreTransformed(LLVector4a* verts, LLVector2* uvs, LLColor4U* colors, S32 vert_count)
+void LLRender::vertexBatchPreTransformed(const LLVector4a* verts, const LLVector2* uvs, const LLColor4U* colors, std::size_t vert_count)
{
- if (mCount + vert_count > BATCH_SIZE - 2)
+ if (mCount + vert_count > 4094)
{
// LL_WARNS() << "GL immediate mode overflow. Some geometry not drawn." << LL_ENDL;
return;
}
-
- if (sGLCoreProfile && mMode == LLRender::QUADS)
- { //quads are deprecated, convert to triangle list
- S32 i = 0;
-
- while (i < vert_count)
- {
- //read first three
- mVerticesp[mCount] = verts[i];
- mTexcoordsp[mCount] = uvs[i];
- mColorsp[mCount++] = colors[i++];
-
- mVerticesp[mCount] = verts[i];
- mTexcoordsp[mCount] = uvs[i];
- mColorsp[mCount++] = colors[i++];
-
- mVerticesp[mCount] = verts[i];
- mTexcoordsp[mCount] = uvs[i];
- mColorsp[mCount++] = colors[i++];
-
- //copy last two
- mVerticesp[mCount] = verts[i-3];
- mTexcoordsp[mCount] = uvs[i-3];
- mColorsp[mCount++] = colors[i-3];
-
- mVerticesp[mCount] = verts[i-1];
- mTexcoordsp[mCount] = uvs[i-1];
- mColorsp[mCount++] = colors[i-1];
-
- //copy last one
- mVerticesp[mCount] = verts[i];
- mTexcoordsp[mCount] = uvs[i];
- mColorsp[mCount++] = colors[i++];
- }
- }
- else
+ for (S32 i = 0; i < vert_count; i++)
{
- for (S32 i = 0; i < vert_count; i++)
- {
- mVerticesp[mCount] = verts[i];
- mTexcoordsp[mCount] = uvs[i];
- mColorsp[mCount] = colors[i];
+ mVerticesp[mCount] = verts[i];
+ mTexcoordsp[mCount] = uvs[i];
+ mColorsp[mCount] = colors[i];
- mCount++;
- }
+ mCount++;
}
if (mCount > 0)
@@ -2011,10 +1929,29 @@ void LLRender::vertexBatchPreTransformed(LLVector4a* verts, LLVector2* uvs, LLCo
}
}
+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[VX], v[VY], 0);
+}
+
+void LLRender::vertex3fv(const GLfloat* v)
+{
+ vertex3f(v[VX], v[VY], v[VZ]);
+}
void LLRender::texCoord2f(const GLfloat& x, const GLfloat& y)
{
- mTexcoordsp[mCount] = LLVector2(x,y);
+ mTexcoordsp[mCount].set(x,y);
}
void LLRender::texCoord2i(const GLint& x, const GLint& y)
@@ -2024,46 +1961,47 @@ void LLRender::texCoord2i(const GLint& x, const GLint& y)
void LLRender::texCoord2fv(const GLfloat* tc)
{
- texCoord2f(tc[0], tc[1]);
+ texCoord2f(tc[VX], tc[VY]);
}
void LLRender::color4ub(const GLubyte& r, const GLubyte& g, const GLubyte& b, const GLubyte& a)
{
- if (!LLGLSLShader::sCurBoundShaderPtr || LLGLSLShader::sCurBoundShaderPtr->mAttributeMask & LLVertexBuffer::MAP_COLOR)
+ if (!LLGLSLShader::sCurBoundShaderPtr ||
+ LLGLSLShader::sCurBoundShaderPtr->mAttributeMask & LLVertexBuffer::MAP_COLOR)
{
- mColorsp[mCount] = LLColor4U(r,g,b,a);
+ mColorsp[mCount].set(r, g, b, a);
}
else
{ //not using shaders or shader reads color from a uniform
- diffuseColor4ub(r,g,b,a);
+ diffuseColor4ub(r, g, b, a);
}
}
void LLRender::color4ubv(const GLubyte* c)
{
- color4ub(c[0], c[1], c[2], c[3]);
+ color4ub(c[VX], c[VY], c[VZ], c[VW]);
}
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));
+ 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]);
+ color4f(c[VX], c[VY], c[VZ], c[VW]);
}
void LLRender::color3f(const GLfloat& r, const GLfloat& g, const GLfloat& b)
{
- color4f(r,g,b,1);
+ color4f(r, g, b, 1);
}
void LLRender::color3fv(const GLfloat* c)
{
- color4f(c[0],c[1],c[2],1);
+ color4f(c[VX], c[VY], c[VZ], 1);
}
void LLRender::diffuseColor3f(F32 r, F32 g, F32 b)
@@ -2073,7 +2011,7 @@ void LLRender::diffuseColor3f(F32 r, F32 g, F32 b)
if (shader)
{
- shader->uniform4f(LLShaderMgr::DIFFUSE_COLOR, r,g,b,1.f);
+ shader->uniform4f(LLShaderMgr::DIFFUSE_COLOR, r, g, b, 1.f);
}
}
@@ -2084,7 +2022,7 @@ void LLRender::diffuseColor3fv(const F32* c)
if (shader)
{
- shader->uniform4f(LLShaderMgr::DIFFUSE_COLOR, c[0], c[1], c[2], 1.f);
+ shader->uniform4f(LLShaderMgr::DIFFUSE_COLOR, c[VX], c[VY], c[VZ], 1.f);
}
}
@@ -2095,7 +2033,7 @@ void LLRender::diffuseColor4f(F32 r, F32 g, F32 b, F32 a)
if (shader)
{
- shader->uniform4f(LLShaderMgr::DIFFUSE_COLOR, r,g,b,a);
+ shader->uniform4f(LLShaderMgr::DIFFUSE_COLOR, r, g, b, a);
}
}
@@ -2117,7 +2055,7 @@ void LLRender::diffuseColor4ubv(const U8* c)
if (shader)
{
- shader->uniform4f(LLShaderMgr::DIFFUSE_COLOR, c[0]/255.f, c[1]/255.f, c[2]/255.f, c[3]/255.f);
+ shader->uniform4f(LLShaderMgr::DIFFUSE_COLOR, c[0] / 255.f, c[1] / 255.f, c[2] / 255.f, c[3] / 255.f);
}
}
@@ -2128,11 +2066,10 @@ void LLRender::diffuseColor4ub(U8 r, U8 g, U8 b, U8 a)
if (shader)
{
- shader->uniform4f(LLShaderMgr::DIFFUSE_COLOR, r/255.f, g/255.f, b/255.f, a/255.f);
+ shader->uniform4f(LLShaderMgr::DIFFUSE_COLOR, r / 255.f, g / 255.f, b / 255.f, a / 255.f);
}
}
-
void LLRender::debugTexUnits(void)
{
LL_INFOS("TextureUnit") << "Active TexUnit: " << mCurrTextureUnitIndex << LL_ENDL;
@@ -2143,7 +2080,7 @@ void LLRender::debugTexUnits(void)
{
if (i == mCurrTextureUnitIndex) active_enabled = "true";
LL_INFOS("TextureUnit") << "TexUnit: " << i << " Enabled" << LL_ENDL;
- LL_INFOS("TextureUnit") << "Enabled As: " ;
+ LL_INFOS("TextureUnit") << "Enabled As: ";
switch (getTexUnit(i)->mCurrTexType)
{
case LLTexUnit::TT_TEXTURE:
@@ -2167,85 +2104,90 @@ void LLRender::debugTexUnits(void)
LL_INFOS("TextureUnit") << "Active TexUnit Enabled : " << active_enabled << LL_ENDL;
}
-
-
-glh::matrix4f copy_matrix(F32* src)
+glm::mat4 get_current_modelview()
{
- glh::matrix4f ret;
- ret.set_value(src);
- return ret;
+ return glm::make_mat4(gGLModelView);
}
-glh::matrix4f get_current_modelview()
+glm::mat4 get_current_projection()
{
- return copy_matrix(gGLModelView);
+ return glm::make_mat4(gGLProjection);
}
-glh::matrix4f get_current_projection()
+glm::mat4 get_last_modelview()
{
- return copy_matrix(gGLProjection);
+ return glm::make_mat4(gGLLastModelView);
}
-glh::matrix4f get_last_modelview()
+glm::mat4 get_last_projection()
{
- return copy_matrix(gGLLastModelView);
+ return glm::make_mat4(gGLLastProjection);
}
-glh::matrix4f get_last_projection()
-{
- return copy_matrix(gGLLastProjection);
-}
-
-void copy_matrix(const glh::matrix4f& src, F32* dst)
+void copy_matrix(const glm::mat4& src, F32* dst)
{
+ auto matp = glm::value_ptr(src);
for (U32 i = 0; i < 16; i++)
{
- dst[i] = src.m[i];
+ dst[i] = matp[i];
}
}
-void set_current_modelview(const glh::matrix4f& mat)
+void set_current_modelview(const glm::mat4& mat)
{
copy_matrix(mat, gGLModelView);
}
-void set_current_projection(glh::matrix4f& mat)
+void set_current_projection(const glm::mat4& mat)
{
copy_matrix(mat, gGLProjection);
}
-glh::matrix4f gl_ortho(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat znear, GLfloat zfar)
+void set_last_modelview(const glm::mat4& mat)
{
- glh::matrix4f ret(
- 2.f/(right-left), 0.f, 0.f, -(right+left)/(right-left),
- 0.f, 2.f/(top-bottom), 0.f, -(top+bottom)/(top-bottom),
- 0.f, 0.f, -2.f/(zfar-znear), -(zfar+znear)/(zfar-znear),
- 0.f, 0.f, 0.f, 1.f);
-
- return ret;
+ copy_matrix(mat, gGLLastModelView);
}
-glh::matrix4f gl_perspective(GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar)
+void set_last_projection(const glm::mat4& mat)
{
- GLfloat f = 1.f/tanf(DEG_TO_RAD*fovy/2.f);
-
- return glh::matrix4f(f/aspect, 0, 0, 0,
- 0, f, 0, 0,
- 0, 0, (zFar+zNear)/(zNear-zFar), (2.f*zFar*zNear)/(zNear-zFar),
- 0, 0, -1.f, 0);
+ copy_matrix(mat, gGLLastProjection);
}
-glh::matrix4f gl_lookat(LLVector3 eye, LLVector3 center, LLVector3 up)
+glm::vec3 mul_mat4_vec3(const glm::mat4& mat, const glm::vec3& vec)
{
- LLVector3 f = center-eye;
- f.normVec();
- up.normVec();
- LLVector3 s = f % up;
- LLVector3 u = s % f;
+ //const float w = vec[0] * mat[0][3] + vec[1] * mat[1][3] + vec[2] * mat[2][3] + mat[3][3];
+ //return glm::vec3(
+ // (vec[0] * mat[0][0] + vec[1] * mat[1][0] + vec[2] * mat[2][0] + mat[3][0]) / w,
+ // (vec[0] * mat[0][1] + vec[1] * mat[1][1] + vec[2] * mat[2][1] + mat[3][1]) / w,
+ // (vec[0] * mat[0][2] + vec[1] * mat[1][2] + vec[2] * mat[2][2] + mat[3][2]) / w
+ //);
+ LLVector4a x, y, z, s, t, p, q;
+
+ x.splat(vec.x);
+ y.splat(vec.y);
+ z.splat(vec.z);
+
+ s.splat<3>(mat[VX].data);
+ t.splat<3>(mat[VY].data);
+ p.splat<3>(mat[VZ].data);
+ q.splat<3>(mat[VW].data);
+
+ s.mul(x);
+ t.mul(y);
+ p.mul(z);
+ q.add(s);
+ t.add(p);
+ q.add(t);
- return glh::matrix4f(s[0], s[1], s[2], 0,
- u[0], u[1], u[2], 0,
- -f[0], -f[1], -f[2], 0,
- 0, 0, 0, 1);
+ x.mul(mat[VX].data);
+ y.mul(mat[VY].data);
+ z.mul(mat[VZ].data);
+ x.add(y);
+ z.add(mat[VW].data);
+ LLVector4a res;
+ res.load3(glm::value_ptr(vec));
+ res.setAdd(x, z);
+ res.div(q);
+ return glm::make_vec3(res.getF32ptr());
}