summaryrefslogtreecommitdiff
path: root/indra/llrender
diff options
context:
space:
mode:
authorAndrey Lihatskiy <alihatskiy@productengine.com>2024-05-15 12:46:26 +0300
committerAndrey Lihatskiy <alihatskiy@productengine.com>2024-05-15 12:46:26 +0300
commitbf1235b017b254ba989b156c73c4ce18ba4e6c23 (patch)
tree8dd5dad68be3aa5cda16938cc3bfaa70f6faad41 /indra/llrender
parent1e9e5a7b7629276d509c352699fb5891c2dc6587 (diff)
parente7eced3c87310b15ac20cc3cd470d67686104a14 (diff)
Merge branch 'marchcat/w-whitespace' into marchcat/x-mf-merge
Diffstat (limited to 'indra/llrender')
-rw-r--r--indra/llrender/llatmosphere.cpp14
-rw-r--r--indra/llrender/llatmosphere.h12
-rw-r--r--indra/llrender/llcubemap.cpp316
-rw-r--r--indra/llrender/llcubemap.h66
-rw-r--r--indra/llrender/llcubemaparray.cpp20
-rw-r--r--indra/llrender/llcubemaparray.h32
-rw-r--r--indra/llrender/llfontbitmapcache.cpp218
-rw-r--r--indra/llrender/llfontbitmapcache.h68
-rw-r--r--indra/llrender/llfontfreetype.cpp1128
-rw-r--r--indra/llrender/llfontfreetype.h200
-rw-r--r--indra/llrender/llfontfreetypesvg.cpp262
-rw-r--r--indra/llrender/llfontfreetypesvg.h24
-rw-r--r--indra/llrender/llfontgl.cpp1794
-rw-r--r--indra/llrender/llfontgl.h372
-rw-r--r--indra/llrender/llfontregistry.cpp1156
-rw-r--r--indra/llrender/llfontregistry.h170
-rw-r--r--indra/llrender/llgl.cpp1590
-rw-r--r--indra/llrender/llgl.h332
-rw-r--r--indra/llrender/llglcommonfunc.cpp12
-rw-r--r--indra/llrender/llglcommonfunc.h2
-rw-r--r--indra/llrender/llglheaders.h18
-rw-r--r--indra/llrender/llglstates.h180
-rw-r--r--indra/llrender/llgltypes.h10
-rw-r--r--indra/llrender/llimagegl.cpp2702
-rw-r--r--indra/llrender/llimagegl.h382
-rw-r--r--indra/llrender/llpostprocess.cpp518
-rw-r--r--indra/llrender/llpostprocess.h358
-rw-r--r--indra/llrender/llrender.h778
-rw-r--r--indra/llrender/llrender2dutils.cpp2328
-rw-r--r--indra/llrender/llrender2dutils.h90
-rw-r--r--indra/llrender/llrendernavprim.cpp20
-rw-r--r--indra/llrender/llrendernavprim.h10
-rw-r--r--indra/llrender/llrendersphere.cpp88
-rw-r--r--indra/llrender/llrendersphere.h20
-rw-r--r--indra/llrender/lltexture.cpp16
-rw-r--r--indra/llrender/lltexture.h54
-rw-r--r--indra/llrender/lltexturemanagerbridge.cpp10
-rw-r--r--indra/llrender/lltexturemanagerbridge.h16
-rw-r--r--indra/llrender/lluiimage.cpp216
-rw-r--r--indra/llrender/lluiimage.h150
-rw-r--r--indra/llrender/lluiimage.inl56
41 files changed, 7904 insertions, 7904 deletions
diff --git a/indra/llrender/llatmosphere.cpp b/indra/llrender/llatmosphere.cpp
index 8e37ca9b90..eae5623a3c 100644
--- a/indra/llrender/llatmosphere.cpp
+++ b/indra/llrender/llatmosphere.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llatmosphere.cpp
* @brief LLAtmosphere integration impl
*
* $LicenseInfo:firstyear=2018&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2018, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -175,8 +175,8 @@ bool AtmosphericModelSettings::operator==(const AtmosphericModelSettings& rhs) c
void LLAtmosphere::initClass()
{
if (!gAtmosphere)
- {
- gAtmosphere = new LLAtmosphere;
+ {
+ gAtmosphere = new LLAtmosphere;
}
}
diff --git a/indra/llrender/llatmosphere.h b/indra/llrender/llatmosphere.h
index 572365d864..4b8c7d0819 100644
--- a/indra/llrender/llatmosphere.h
+++ b/indra/llrender/llatmosphere.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file llatmosphere.h
* @brief LLAtmosphere class
*
* $LicenseInfo:firstyear=2018&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2018, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -146,7 +146,7 @@ public:
bool configureAtmosphericModel(AtmosphericModelSettings& settings);
-protected:
+protected:
LLAtmosphere(const LLAtmosphere& rhs)
{
*this = rhs;
diff --git a/indra/llrender/llcubemap.cpp b/indra/llrender/llcubemap.cpp
index 254288a86e..f16d5b6e53 100644
--- a/indra/llrender/llcubemap.cpp
+++ b/indra/llrender/llcubemap.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llcubemap.cpp
* @brief LLCubeMap class implementation
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -47,16 +47,16 @@ namespace {
bool LLCubeMap::sUseCubeMaps = true;
LLCubeMap::LLCubeMap(bool init_as_srgb)
- : mTextureStage(0),
- mMatrixStage(0),
- mIssRGB(init_as_srgb)
+ : mTextureStage(0),
+ mMatrixStage(0),
+ mIssRGB(init_as_srgb)
{
- mTargets[0] = GL_TEXTURE_CUBE_MAP_NEGATIVE_X;
- mTargets[1] = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
- mTargets[2] = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y;
- mTargets[3] = GL_TEXTURE_CUBE_MAP_POSITIVE_Y;
- mTargets[4] = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
- mTargets[5] = GL_TEXTURE_CUBE_MAP_POSITIVE_Z;
+ mTargets[0] = GL_TEXTURE_CUBE_MAP_NEGATIVE_X;
+ mTargets[1] = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
+ mTargets[2] = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y;
+ mTargets[3] = GL_TEXTURE_CUBE_MAP_POSITIVE_Y;
+ mTargets[4] = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
+ mTargets[5] = GL_TEXTURE_CUBE_MAP_POSITIVE_Z;
}
LLCubeMap::~LLCubeMap()
@@ -65,106 +65,106 @@ LLCubeMap::~LLCubeMap()
void LLCubeMap::initGL()
{
- llassert(gGLManager.mInited);
-
- if (LLCubeMap::sUseCubeMaps)
- {
- // Not initialized, do stuff.
- if (mImages[0].isNull())
- {
- U32 texname = 0;
-
- LLImageGL::generateTextures(1, &texname);
-
- for (int i = 0; i < 6; i++)
- {
- mImages[i] = new LLImageGL(RESOLUTION, RESOLUTION, 4, FALSE);
+ llassert(gGLManager.mInited);
+
+ if (LLCubeMap::sUseCubeMaps)
+ {
+ // Not initialized, do stuff.
+ if (mImages[0].isNull())
+ {
+ U32 texname = 0;
+
+ LLImageGL::generateTextures(1, &texname);
+
+ for (int i = 0; i < 6; i++)
+ {
+ mImages[i] = new LLImageGL(RESOLUTION, RESOLUTION, 4, FALSE);
#if USE_SRGB_DECODE
if (mIssRGB) {
mImages[i]->setExplicitFormat(GL_SRGB8_ALPHA8, GL_RGBA);
}
#endif
- mImages[i]->setTarget(mTargets[i], LLTexUnit::TT_CUBE_MAP);
- mRawImages[i] = new LLImageRaw(RESOLUTION, RESOLUTION, 4);
- mImages[i]->createGLTexture(0, mRawImages[i], texname);
-
- gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_CUBE_MAP, texname);
- mImages[i]->setAddressMode(LLTexUnit::TAM_CLAMP);
- stop_glerror();
- }
- gGL.getTexUnit(0)->disable();
- }
- disable();
- }
- else
- {
- LL_WARNS() << "Using cube map without extension!" << LL_ENDL;
- }
+ mImages[i]->setTarget(mTargets[i], LLTexUnit::TT_CUBE_MAP);
+ mRawImages[i] = new LLImageRaw(RESOLUTION, RESOLUTION, 4);
+ mImages[i]->createGLTexture(0, mRawImages[i], texname);
+
+ gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_CUBE_MAP, texname);
+ mImages[i]->setAddressMode(LLTexUnit::TAM_CLAMP);
+ stop_glerror();
+ }
+ gGL.getTexUnit(0)->disable();
+ }
+ disable();
+ }
+ else
+ {
+ LL_WARNS() << "Using cube map without extension!" << LL_ENDL;
+ }
}
void LLCubeMap::initRawData(const std::vector<LLPointer<LLImageRaw> >& rawimages)
{
- bool flip_x[6] = { false, true, false, false, true, false };
- bool flip_y[6] = { true, true, true, false, true, true };
- bool transpose[6] = { false, false, false, false, true, true };
-
- // Yes, I know that this is inefficient! - djs 08/08/02
- for (int i = 0; i < 6; i++)
- {
- const U8 *sd = rawimages[i]->getData();
- U8 *td = mRawImages[i]->getData();
-
- S32 offset = 0;
- S32 sx, sy, so;
- for (int y = 0; y < 64; y++)
- {
- for (int x = 0; x < 64; x++)
- {
- sx = x;
- sy = y;
- if (flip_y[i])
- {
- sy = 63 - y;
- }
- if (flip_x[i])
- {
- sx = 63 - x;
- }
- if (transpose[i])
- {
- S32 temp = sx;
- sx = sy;
- sy = temp;
- }
-
- so = 64*sy + sx;
- so *= 4;
- *(td + offset++) = *(sd + so++);
- *(td + offset++) = *(sd + so++);
- *(td + offset++) = *(sd + so++);
- *(td + offset++) = *(sd + so++);
- }
- }
- }
+ bool flip_x[6] = { false, true, false, false, true, false };
+ bool flip_y[6] = { true, true, true, false, true, true };
+ bool transpose[6] = { false, false, false, false, true, true };
+
+ // Yes, I know that this is inefficient! - djs 08/08/02
+ for (int i = 0; i < 6; i++)
+ {
+ const U8 *sd = rawimages[i]->getData();
+ U8 *td = mRawImages[i]->getData();
+
+ S32 offset = 0;
+ S32 sx, sy, so;
+ for (int y = 0; y < 64; y++)
+ {
+ for (int x = 0; x < 64; x++)
+ {
+ sx = x;
+ sy = y;
+ if (flip_y[i])
+ {
+ sy = 63 - y;
+ }
+ if (flip_x[i])
+ {
+ sx = 63 - x;
+ }
+ if (transpose[i])
+ {
+ S32 temp = sx;
+ sx = sy;
+ sy = temp;
+ }
+
+ so = 64*sy + sx;
+ so *= 4;
+ *(td + offset++) = *(sd + so++);
+ *(td + offset++) = *(sd + so++);
+ *(td + offset++) = *(sd + so++);
+ *(td + offset++) = *(sd + so++);
+ }
+ }
+ }
}
void LLCubeMap::initGLData()
{
LL_PROFILE_ZONE_SCOPED;
- for (int i = 0; i < 6; i++)
- {
- mImages[i]->setSubImage(mRawImages[i], 0, 0, RESOLUTION, RESOLUTION);
- }
+ for (int i = 0; i < 6; i++)
+ {
+ mImages[i]->setSubImage(mRawImages[i], 0, 0, RESOLUTION, RESOLUTION);
+ }
}
void LLCubeMap::init(const std::vector<LLPointer<LLImageRaw> >& rawimages)
{
- if (!gGLManager.mIsDisabled)
- {
- initGL();
- initRawData(rawimages);
- initGLData();
- }
+ if (!gGLManager.mIsDisabled)
+ {
+ initGL();
+ initRawData(rawimages);
+ initGLData();
+ }
}
void LLCubeMap::initReflectionMap(U32 resolution, U32 components)
@@ -236,99 +236,99 @@ void LLCubeMap::generateMipMaps()
GLuint LLCubeMap::getGLName()
{
- return mImages[0]->getTexName();
+ return mImages[0]->getTexName();
}
void LLCubeMap::bind()
{
- gGL.getTexUnit(mTextureStage)->bind(this);
+ gGL.getTexUnit(mTextureStage)->bind(this);
}
void LLCubeMap::enable(S32 stage)
{
- enableTexture(stage);
+ enableTexture(stage);
}
void LLCubeMap::enableTexture(S32 stage)
{
- mTextureStage = stage;
- if (stage >= 0 && LLCubeMap::sUseCubeMaps)
- {
- gGL.getTexUnit(stage)->enable(LLTexUnit::TT_CUBE_MAP);
- }
+ mTextureStage = stage;
+ if (stage >= 0 && LLCubeMap::sUseCubeMaps)
+ {
+ gGL.getTexUnit(stage)->enable(LLTexUnit::TT_CUBE_MAP);
+ }
}
void LLCubeMap::disable(void)
{
- disableTexture();
+ disableTexture();
}
void LLCubeMap::disableTexture(void)
{
- if (mTextureStage >= 0 && LLCubeMap::sUseCubeMaps)
- {
- gGL.getTexUnit(mTextureStage)->disable();
- if (mTextureStage == 0)
- {
- gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
- }
- }
+ if (mTextureStage >= 0 && LLCubeMap::sUseCubeMaps)
+ {
+ gGL.getTexUnit(mTextureStage)->disable();
+ if (mTextureStage == 0)
+ {
+ gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
+ }
+ }
}
void LLCubeMap::setMatrix(S32 stage)
{
- mMatrixStage = stage;
-
- if (mMatrixStage < 0) return;
-
- //if (stage > 0)
- {
- gGL.getTexUnit(stage)->activate();
- }
-
- LLVector3 x(gGLModelView+0);
- LLVector3 y(gGLModelView+4);
- LLVector3 z(gGLModelView+8);
-
- LLMatrix3 mat3;
- mat3.setRows(x,y,z);
- LLMatrix4 trans(mat3);
- trans.transpose();
-
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.pushMatrix();
- gGL.loadMatrix((F32 *)trans.mMatrix);
- gGL.matrixMode(LLRender::MM_MODELVIEW);
-
- /*if (stage > 0)
- {
- gGL.getTexUnit(0)->activate();
- }*/
+ mMatrixStage = stage;
+
+ if (mMatrixStage < 0) return;
+
+ //if (stage > 0)
+ {
+ gGL.getTexUnit(stage)->activate();
+ }
+
+ LLVector3 x(gGLModelView+0);
+ LLVector3 y(gGLModelView+4);
+ LLVector3 z(gGLModelView+8);
+
+ LLMatrix3 mat3;
+ mat3.setRows(x,y,z);
+ LLMatrix4 trans(mat3);
+ trans.transpose();
+
+ gGL.matrixMode(LLRender::MM_TEXTURE);
+ gGL.pushMatrix();
+ gGL.loadMatrix((F32 *)trans.mMatrix);
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+
+ /*if (stage > 0)
+ {
+ gGL.getTexUnit(0)->activate();
+ }*/
}
void LLCubeMap::restoreMatrix()
{
- if (mMatrixStage < 0) return;
-
- //if (mMatrixStage > 0)
- {
- gGL.getTexUnit(mMatrixStage)->activate();
- }
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.popMatrix();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
-
- /*if (mMatrixStage > 0)
- {
- gGL.getTexUnit(0)->activate();
- }*/
+ if (mMatrixStage < 0) return;
+
+ //if (mMatrixStage > 0)
+ {
+ gGL.getTexUnit(mMatrixStage)->activate();
+ }
+ gGL.matrixMode(LLRender::MM_TEXTURE);
+ gGL.popMatrix();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+
+ /*if (mMatrixStage > 0)
+ {
+ gGL.getTexUnit(0)->activate();
+ }*/
}
void LLCubeMap::destroyGL()
{
- for (S32 i = 0; i < 6; i++)
- {
- mImages[i] = NULL;
- }
+ for (S32 i = 0; i < 6; i++)
+ {
+ mImages[i] = NULL;
+ }
}
diff --git a/indra/llrender/llcubemap.h b/indra/llrender/llcubemap.h
index b9e081cea3..fa5c0ecbf3 100644
--- a/indra/llrender/llcubemap.h
+++ b/indra/llrender/llcubemap.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file llcubemap.h
* @brief LLCubeMap class definition
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -36,10 +36,10 @@ class LLVector3;
// Environment map hack!
class LLCubeMap : public LLRefCount
{
- bool mIssRGB;
+ bool mIssRGB;
public:
- LLCubeMap(bool init_as_srgb);
- void init(const std::vector<LLPointer<LLImageRaw> >& rawimages);
+ LLCubeMap(bool init_as_srgb);
+ void init(const std::vector<LLPointer<LLImageRaw> >& rawimages);
// initialize as an undefined cubemap at the given resolution
// used for render-to-cubemap operations
@@ -51,42 +51,42 @@ public:
// respect the resolution of rawimages
// Raw images must point to array of six square images that are all the same resolution
void initEnvironmentMap(const std::vector<LLPointer<LLImageRaw> >& rawimages);
- void initGL();
- void initRawData(const std::vector<LLPointer<LLImageRaw> >& rawimages);
- void initGLData();
-
- void bind();
- void enable(S32 stage);
-
- void enableTexture(S32 stage);
- S32 getStage(void) { return mTextureStage; }
-
- void disable(void);
- void disableTexture(void);
- void setMatrix(S32 stage);
- void restoreMatrix();
+ void initGL();
+ void initRawData(const std::vector<LLPointer<LLImageRaw> >& rawimages);
+ void initGLData();
+
+ void bind();
+ void enable(S32 stage);
+
+ void enableTexture(S32 stage);
+ S32 getStage(void) { return mTextureStage; }
+
+ void disable(void);
+ void disableTexture(void);
+ void setMatrix(S32 stage);
+ void restoreMatrix();
U32 getResolution() { return mImages[0].notNull() ? mImages[0]->getWidth(0) : 0; }
-
+
// generate mip maps for this Cube Map using GL
// NOTE: Cube Map MUST already be resident in VRAM
void generateMipMaps();
- GLuint getGLName();
+ GLuint getGLName();
- void destroyGL();
+ void destroyGL();
public:
- static bool sUseCubeMaps;
+ static bool sUseCubeMaps;
protected:
- friend class LLTexUnit;
- ~LLCubeMap();
- LLGLenum mTargets[6];
- LLPointer<LLImageGL> mImages[6];
- LLPointer<LLImageRaw> mRawImages[6];
- S32 mTextureStage;
- S32 mMatrixStage;
+ friend class LLTexUnit;
+ ~LLCubeMap();
+ LLGLenum mTargets[6];
+ LLPointer<LLImageGL> mImages[6];
+ LLPointer<LLImageRaw> mRawImages[6];
+ S32 mTextureStage;
+ S32 mMatrixStage;
};
#endif
diff --git a/indra/llrender/llcubemaparray.cpp b/indra/llrender/llcubemaparray.cpp
index 1debd33953..03fbb90bf6 100644
--- a/indra/llrender/llcubemaparray.cpp
+++ b/indra/llrender/llcubemaparray.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llcubemaparray.cpp
* @brief LLCubeMap class implementation
*
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2022, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -63,7 +63,7 @@ LLVector3 LLCubeMapArray::sLookVecs[6] =
LLVector3(0, 0, -1)
};
-LLVector3 LLCubeMapArray::sUpVecs[6] =
+LLVector3 LLCubeMapArray::sUpVecs[6] =
{
LLVector3(0, -1, 0),
LLVector3(0, -1, 0),
@@ -77,7 +77,7 @@ LLVector3 LLCubeMapArray::sClipToCubeLookVecs[6] =
{
LLVector3(0, 0, -1), //GOOD
LLVector3(0, 0, 1), //GOOD
-
+
LLVector3(1, 0, 0), // GOOD
LLVector3(1, 0, 0), // GOOD
@@ -98,9 +98,9 @@ LLVector3 LLCubeMapArray::sClipToCubeUpVecs[6] =
};
LLCubeMapArray::LLCubeMapArray()
- : mTextureStage(0)
+ : mTextureStage(0)
{
-
+
}
LLCubeMapArray::~LLCubeMapArray()
@@ -170,7 +170,7 @@ void LLCubeMapArray::unbind()
GLuint LLCubeMapArray::getGLName()
{
- return mImage->getTexName();
+ return mImage->getTexName();
}
void LLCubeMapArray::destroyGL()
diff --git a/indra/llrender/llcubemaparray.h b/indra/llrender/llcubemaparray.h
index 6c3f7dc890..9d78c5b0d4 100644
--- a/indra/llrender/llcubemaparray.h
+++ b/indra/llrender/llcubemaparray.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file llcubemaparray.h
* @brief LLCubeMap class definition
*
* $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2022, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -35,10 +35,10 @@ class LLVector3;
class LLCubeMapArray : public LLRefCount
{
public:
- LLCubeMapArray();
+ LLCubeMapArray();
static GLenum sTargets[6];
-
+
// look and up vectors for each cube face (agent space)
static LLVector3 sLookVecs[6];
static LLVector3 sUpVecs[6];
@@ -47,18 +47,18 @@ public:
static LLVector3 sClipToCubeLookVecs[6];
static LLVector3 sClipToCubeUpVecs[6];
- // allocate a cube map array
+ // allocate a cube map array
// res - resolution of each cube face
// components - number of components per pixel
// count - number of cube maps in the array
// use_mips - if TRUE, mipmaps will be allocated for this cube map array and anisotropic filtering will be used
void allocate(U32 res, U32 components, U32 count, BOOL use_mips = TRUE);
- void bind(S32 stage);
+ void bind(S32 stage);
void unbind();
-
- GLuint getGLName();
- void destroyGL();
+ GLuint getGLName();
+
+ void destroyGL();
// get width of cubemaps in array (they're cubes, so this is also the height)
U32 getWidth() const { return mWidth; }
@@ -67,10 +67,10 @@ public:
U32 getCount() const { return mCount; }
protected:
- friend class LLTexUnit;
- ~LLCubeMapArray();
- LLPointer<LLImageGL> mImage;
+ friend class LLTexUnit;
+ ~LLCubeMapArray();
+ LLPointer<LLImageGL> mImage;
U32 mWidth = 0;
U32 mCount = 0;
- S32 mTextureStage;
+ S32 mTextureStage;
};
diff --git a/indra/llrender/llfontbitmapcache.cpp b/indra/llrender/llfontbitmapcache.cpp
index 42b0045cf3..243041945a 100644
--- a/indra/llrender/llfontbitmapcache.cpp
+++ b/indra/llrender/llfontbitmapcache.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llfontbitmapcache.cpp
* @brief Storage for previously rendered glyphs.
*
* $LicenseInfo:firstyear=2008&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -39,60 +39,60 @@ LLFontBitmapCache::~LLFontBitmapCache()
}
void LLFontBitmapCache::init(S32 max_char_width,
- S32 max_char_height)
+ S32 max_char_height)
{
- reset();
-
- mMaxCharWidth = max_char_width;
- mMaxCharHeight = max_char_height;
-
- S32 image_width = mMaxCharWidth * 20;
- S32 pow_iw = 2;
- while (pow_iw < image_width)
- {
- pow_iw <<= 1;
- }
- image_width = pow_iw;
- image_width = llmin(512, image_width); // Don't make bigger than 512x512, ever.
-
- mBitmapWidth = image_width;
- mBitmapHeight = image_width;
+ reset();
+
+ mMaxCharWidth = max_char_width;
+ mMaxCharHeight = max_char_height;
+
+ S32 image_width = mMaxCharWidth * 20;
+ S32 pow_iw = 2;
+ while (pow_iw < image_width)
+ {
+ pow_iw <<= 1;
+ }
+ image_width = pow_iw;
+ image_width = llmin(512, image_width); // Don't make bigger than 512x512, ever.
+
+ mBitmapWidth = image_width;
+ mBitmapHeight = image_width;
}
LLImageRaw *LLFontBitmapCache::getImageRaw(EFontGlyphType bitmap_type, U32 bitmap_num) const
{
- const U32 bitmap_idx = static_cast<U32>(bitmap_type);
- if (bitmap_type >= EFontGlyphType::Count || bitmap_num >= mImageRawVec[bitmap_idx].size())
- return nullptr;
+ const U32 bitmap_idx = static_cast<U32>(bitmap_type);
+ if (bitmap_type >= EFontGlyphType::Count || bitmap_num >= mImageRawVec[bitmap_idx].size())
+ return nullptr;
- return mImageRawVec[bitmap_idx][bitmap_num];
+ return mImageRawVec[bitmap_idx][bitmap_num];
}
LLImageGL *LLFontBitmapCache::getImageGL(EFontGlyphType bitmap_type, U32 bitmap_num) const
{
- const U32 bitmap_idx = static_cast<U32>(bitmap_type);
- if (bitmap_type >= EFontGlyphType::Count || bitmap_num >= mImageGLVec[bitmap_idx].size())
- return nullptr;
+ const U32 bitmap_idx = static_cast<U32>(bitmap_type);
+ if (bitmap_type >= EFontGlyphType::Count || bitmap_num >= mImageGLVec[bitmap_idx].size())
+ return nullptr;
- return mImageGLVec[bitmap_idx][bitmap_num];
+ return mImageGLVec[bitmap_idx][bitmap_num];
}
BOOL LLFontBitmapCache::nextOpenPos(S32 width, S32& pos_x, S32& pos_y, EFontGlyphType bitmap_type, U32& bitmap_num)
{
- if (bitmap_type >= EFontGlyphType::Count)
- {
- return FALSE;
- }
-
- const U32 bitmap_idx = static_cast<U32>(bitmap_type);
- if (mImageRawVec[bitmap_idx].empty() || (mCurrentOffsetX[bitmap_idx] + width + 1) > mBitmapWidth)
- {
- if ((mImageRawVec[bitmap_idx].empty()) || (mCurrentOffsetY[bitmap_idx] + 2*mMaxCharHeight + 2) > mBitmapHeight)
- {
- // We're out of space in the current image, or no image
- // has been allocated yet. Make a new one.
-
+ if (bitmap_type >= EFontGlyphType::Count)
+ {
+ return FALSE;
+ }
+
+ const U32 bitmap_idx = static_cast<U32>(bitmap_type);
+ if (mImageRawVec[bitmap_idx].empty() || (mCurrentOffsetX[bitmap_idx] + width + 1) > mBitmapWidth)
+ {
+ if ((mImageRawVec[bitmap_idx].empty()) || (mCurrentOffsetY[bitmap_idx] + 2*mMaxCharHeight + 2) > mBitmapHeight)
+ {
+ // We're out of space in the current image, or no image
+ // has been allocated yet. Make a new one.
+
S32 image_width = mMaxCharWidth * 20;
S32 pow_iw = 2;
while (pow_iw < image_width)
@@ -102,85 +102,85 @@ BOOL LLFontBitmapCache::nextOpenPos(S32 width, S32& pos_x, S32& pos_y, EFontGlyp
image_width = pow_iw;
image_width = llmin(512, image_width); // Don't make bigger than 512x512, ever.
S32 image_height = image_width;
-
+
mBitmapWidth = image_width;
mBitmapHeight = image_height;
-
- S32 num_components = getNumComponents(bitmap_type);
- mImageRawVec[bitmap_idx].push_back(new LLImageRaw(mBitmapWidth, mBitmapHeight, num_components));
- bitmap_num = mImageRawVec[bitmap_idx].size() - 1;
-
- LLImageRaw* image_raw = getImageRaw(bitmap_type, bitmap_num);
- if (EFontGlyphType::Grayscale == bitmap_type)
- {
- image_raw->clear(255, 0);
- }
-
- // Make corresponding GL image.
- mImageGLVec[bitmap_idx].push_back(new LLImageGL(image_raw, false));
- LLImageGL* image_gl = getImageGL(bitmap_type, bitmap_num);
-
- // Start at beginning of the new image.
- mCurrentOffsetX[bitmap_idx] = 1;
- mCurrentOffsetY[bitmap_idx] = 1;
-
- // Attach corresponding GL texture. (*TODO: is this needed?)
- gGL.getTexUnit(0)->bind(image_gl);
- image_gl->setFilteringOption(LLTexUnit::TFO_POINT); // was setMipFilterNearest(TRUE, TRUE);
- }
- else
- {
- // Move to next row in current image.
- mCurrentOffsetX[bitmap_idx] = 1;
- mCurrentOffsetY[bitmap_idx] += mMaxCharHeight + 1;
- }
- }
-
- pos_x = mCurrentOffsetX[bitmap_idx];
- pos_y = mCurrentOffsetY[bitmap_idx];
- bitmap_num = getNumBitmaps(bitmap_type) - 1;
-
- mCurrentOffsetX[bitmap_idx] += width + 1;
-
- return TRUE;
+
+ S32 num_components = getNumComponents(bitmap_type);
+ mImageRawVec[bitmap_idx].push_back(new LLImageRaw(mBitmapWidth, mBitmapHeight, num_components));
+ bitmap_num = mImageRawVec[bitmap_idx].size() - 1;
+
+ LLImageRaw* image_raw = getImageRaw(bitmap_type, bitmap_num);
+ if (EFontGlyphType::Grayscale == bitmap_type)
+ {
+ image_raw->clear(255, 0);
+ }
+
+ // Make corresponding GL image.
+ mImageGLVec[bitmap_idx].push_back(new LLImageGL(image_raw, false));
+ LLImageGL* image_gl = getImageGL(bitmap_type, bitmap_num);
+
+ // Start at beginning of the new image.
+ mCurrentOffsetX[bitmap_idx] = 1;
+ mCurrentOffsetY[bitmap_idx] = 1;
+
+ // Attach corresponding GL texture. (*TODO: is this needed?)
+ gGL.getTexUnit(0)->bind(image_gl);
+ image_gl->setFilteringOption(LLTexUnit::TFO_POINT); // was setMipFilterNearest(TRUE, TRUE);
+ }
+ else
+ {
+ // Move to next row in current image.
+ mCurrentOffsetX[bitmap_idx] = 1;
+ mCurrentOffsetY[bitmap_idx] += mMaxCharHeight + 1;
+ }
+ }
+
+ pos_x = mCurrentOffsetX[bitmap_idx];
+ pos_y = mCurrentOffsetY[bitmap_idx];
+ bitmap_num = getNumBitmaps(bitmap_type) - 1;
+
+ mCurrentOffsetX[bitmap_idx] += width + 1;
+
+ return TRUE;
}
void LLFontBitmapCache::destroyGL()
{
- for (U32 idx = 0, cnt = static_cast<U32>(EFontGlyphType::Count); idx < cnt; idx++)
- {
- for (LLImageGL* image_gl : mImageGLVec[idx])
- {
- image_gl->destroyGLTexture();
- }
- }
+ for (U32 idx = 0, cnt = static_cast<U32>(EFontGlyphType::Count); idx < cnt; idx++)
+ {
+ for (LLImageGL* image_gl : mImageGLVec[idx])
+ {
+ image_gl->destroyGLTexture();
+ }
+ }
}
void LLFontBitmapCache::reset()
{
- for (U32 idx = 0, cnt = static_cast<U32>(EFontGlyphType::Count); idx < cnt; idx++)
- {
- mImageRawVec[idx].clear();
- mImageGLVec[idx].clear();
- mCurrentOffsetX[idx] = 1;
- mCurrentOffsetY[idx] = 1;
- }
-
- mBitmapWidth = 0;
- mBitmapHeight = 0;
+ for (U32 idx = 0, cnt = static_cast<U32>(EFontGlyphType::Count); idx < cnt; idx++)
+ {
+ mImageRawVec[idx].clear();
+ mImageGLVec[idx].clear();
+ mCurrentOffsetX[idx] = 1;
+ mCurrentOffsetY[idx] = 1;
+ }
+
+ mBitmapWidth = 0;
+ mBitmapHeight = 0;
}
//static
U32 LLFontBitmapCache::getNumComponents(EFontGlyphType bitmap_type)
{
- switch (bitmap_type)
- {
- case EFontGlyphType::Grayscale:
- return 2;
- case EFontGlyphType::Color:
- return 4;
- default:
- llassert(false);
- return 2;
- }
+ switch (bitmap_type)
+ {
+ case EFontGlyphType::Grayscale:
+ return 2;
+ case EFontGlyphType::Color:
+ return 4;
+ default:
+ llassert(false);
+ return 2;
+ }
}
diff --git a/indra/llrender/llfontbitmapcache.h b/indra/llrender/llfontbitmapcache.h
index c63281ab70..8f704df44f 100644
--- a/indra/llrender/llfontbitmapcache.h
+++ b/indra/llrender/llfontbitmapcache.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file llfontbitmapcache.h
* @brief Storage for previously rendered glyphs.
*
* $LicenseInfo:firstyear=2008&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -32,10 +32,10 @@
enum class EFontGlyphType : U32
{
- Grayscale = 0,
- Color,
- Count,
- Unspecified,
+ Grayscale = 0,
+ Color,
+ Count,
+ Unspecified,
};
// Maintain a collection of bitmaps containing rendered glyphs.
@@ -43,39 +43,39 @@ enum class EFontGlyphType : U32
class LLFontBitmapCache
{
public:
- LLFontBitmapCache();
- ~LLFontBitmapCache();
+ LLFontBitmapCache();
+ ~LLFontBitmapCache();
+
+ // Need to call this once, before caching any glyphs.
+ void init(S32 max_char_width,
+ S32 max_char_height);
+
+ void reset();
- // Need to call this once, before caching any glyphs.
- void init(S32 max_char_width,
- S32 max_char_height);
+ BOOL nextOpenPos(S32 width, S32& posX, S32& posY, EFontGlyphType bitmapType, U32& bitmapNum);
- void reset();
+ void destroyGL();
- BOOL nextOpenPos(S32 width, S32& posX, S32& posY, EFontGlyphType bitmapType, U32& bitmapNum);
-
- void destroyGL();
-
- LLImageRaw* getImageRaw(EFontGlyphType bitmapType, U32 bitmapNum) const;
- LLImageGL* getImageGL(EFontGlyphType bitmapType, U32 bitmapNum) const;
+ LLImageRaw* getImageRaw(EFontGlyphType bitmapType, U32 bitmapNum) const;
+ LLImageGL* getImageGL(EFontGlyphType bitmapType, U32 bitmapNum) const;
- S32 getMaxCharWidth() const { return mMaxCharWidth; }
- U32 getNumBitmaps(EFontGlyphType bitmapType) const { return (bitmapType < EFontGlyphType::Count) ? mImageRawVec[static_cast<U32>(bitmapType)].size() : 0; }
- S32 getBitmapWidth() const { return mBitmapWidth; }
- S32 getBitmapHeight() const { return mBitmapHeight; }
+ S32 getMaxCharWidth() const { return mMaxCharWidth; }
+ U32 getNumBitmaps(EFontGlyphType bitmapType) const { return (bitmapType < EFontGlyphType::Count) ? mImageRawVec[static_cast<U32>(bitmapType)].size() : 0; }
+ S32 getBitmapWidth() const { return mBitmapWidth; }
+ S32 getBitmapHeight() const { return mBitmapHeight; }
protected:
- static U32 getNumComponents(EFontGlyphType bitmap_type);
+ static U32 getNumComponents(EFontGlyphType bitmap_type);
private:
- S32 mBitmapWidth = 0;
- S32 mBitmapHeight = 0;
- S32 mCurrentOffsetX[static_cast<U32>(EFontGlyphType::Count)] = { 1 };
- S32 mCurrentOffsetY[static_cast<U32>(EFontGlyphType::Count)] = { 1 };
- S32 mMaxCharWidth = 0;
- S32 mMaxCharHeight = 0;
- std::vector<LLPointer<LLImageRaw>> mImageRawVec[static_cast<U32>(EFontGlyphType::Count)];
- std::vector<LLPointer<LLImageGL>> mImageGLVec[static_cast<U32>(EFontGlyphType::Count)];
+ S32 mBitmapWidth = 0;
+ S32 mBitmapHeight = 0;
+ S32 mCurrentOffsetX[static_cast<U32>(EFontGlyphType::Count)] = { 1 };
+ S32 mCurrentOffsetY[static_cast<U32>(EFontGlyphType::Count)] = { 1 };
+ S32 mMaxCharWidth = 0;
+ S32 mMaxCharHeight = 0;
+ std::vector<LLPointer<LLImageRaw>> mImageRawVec[static_cast<U32>(EFontGlyphType::Count)];
+ std::vector<LLPointer<LLImageGL>> mImageGLVec[static_cast<U32>(EFontGlyphType::Count)];
};
#endif //LL_LLFONTBITMAPCACHE_H
diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp
index d87fb5245c..1e5e441689 100644
--- a/indra/llrender/llfontfreetype.cpp
+++ b/indra/llrender/llfontfreetype.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llfontfreetype.cpp
* @brief Freetype font library wrapper
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -46,7 +46,7 @@
#include "llimage.h"
#include "llimagepng.h"
//#include "llimagej2c.h"
-#include "llmath.h" // Linden math
+#include "llmath.h" // Linden math
#include "llstring.h"
//#include "imdebug.h"
#include "llfontbitmapcache.h"
@@ -63,779 +63,779 @@ FT_Library gFTLibrary = NULL;
//static
void LLFontManager::initClass()
{
- if (!gFontManagerp)
- {
- gFontManagerp = new LLFontManager;
- }
+ if (!gFontManagerp)
+ {
+ gFontManagerp = new LLFontManager;
+ }
}
//static
void LLFontManager::cleanupClass()
{
- delete gFontManagerp;
- gFontManagerp = NULL;
+ delete gFontManagerp;
+ gFontManagerp = NULL;
}
LLFontManager::LLFontManager()
{
- int error;
- error = FT_Init_FreeType(&gFTLibrary);
- if (error)
- {
- // Clean up freetype libs.
- LL_ERRS() << "Freetype initialization failure!" << LL_ENDL;
- FT_Done_FreeType(gFTLibrary);
- }
+ int error;
+ error = FT_Init_FreeType(&gFTLibrary);
+ if (error)
+ {
+ // Clean up freetype libs.
+ LL_ERRS() << "Freetype initialization failure!" << LL_ENDL;
+ FT_Done_FreeType(gFTLibrary);
+ }
#ifdef ENABLE_OT_SVG_SUPPORT
- SVG_RendererHooks hooks = {
- LLFontFreeTypeSvgRenderer::OnInit,
- LLFontFreeTypeSvgRenderer::OnFree,
- LLFontFreeTypeSvgRenderer::OnRender,
- LLFontFreeTypeSvgRenderer::OnPresetGlypthSlot,
- };
- FT_Property_Set(gFTLibrary, "ot-svg", "svg-hooks", &hooks);
+ SVG_RendererHooks hooks = {
+ LLFontFreeTypeSvgRenderer::OnInit,
+ LLFontFreeTypeSvgRenderer::OnFree,
+ LLFontFreeTypeSvgRenderer::OnRender,
+ LLFontFreeTypeSvgRenderer::OnPresetGlypthSlot,
+ };
+ FT_Property_Set(gFTLibrary, "ot-svg", "svg-hooks", &hooks);
#endif
}
LLFontManager::~LLFontManager()
{
- FT_Done_FreeType(gFTLibrary);
+ FT_Done_FreeType(gFTLibrary);
}
LLFontGlyphInfo::LLFontGlyphInfo(U32 index, EFontGlyphType glyph_type)
-: mGlyphIndex(index),
- mGlyphType(glyph_type),
- mWidth(0), // In pixels
- mHeight(0), // In pixels
- mXAdvance(0.f), // In pixels
- mYAdvance(0.f), // In pixels
- mXBitmapOffset(0), // Offset to the origin in the bitmap
- mYBitmapOffset(0), // Offset to the origin in the bitmap
- mXBearing(0), // Distance from baseline to left in pixels
- mYBearing(0), // Distance from baseline to top in pixels
- mBitmapEntry(std::make_pair(EFontGlyphType::Unspecified, -1)) // Which bitmap in the bitmap cache contains this glyph
+: mGlyphIndex(index),
+ mGlyphType(glyph_type),
+ mWidth(0), // In pixels
+ mHeight(0), // In pixels
+ mXAdvance(0.f), // In pixels
+ mYAdvance(0.f), // In pixels
+ mXBitmapOffset(0), // Offset to the origin in the bitmap
+ mYBitmapOffset(0), // Offset to the origin in the bitmap
+ mXBearing(0), // Distance from baseline to left in pixels
+ mYBearing(0), // Distance from baseline to top in pixels
+ mBitmapEntry(std::make_pair(EFontGlyphType::Unspecified, -1)) // Which bitmap in the bitmap cache contains this glyph
{
}
LLFontGlyphInfo::LLFontGlyphInfo(const LLFontGlyphInfo& fgi)
- : mGlyphIndex(fgi.mGlyphIndex)
- , mGlyphType(fgi.mGlyphType)
- , mWidth(fgi.mWidth)
- , mHeight(fgi.mHeight)
- , mXAdvance(fgi.mXAdvance)
- , mYAdvance(fgi.mYAdvance)
- , mXBitmapOffset(fgi.mXBitmapOffset)
- , mYBitmapOffset(fgi.mYBitmapOffset)
- , mXBearing(fgi.mXBearing)
- , mYBearing(fgi.mYBearing)
+ : mGlyphIndex(fgi.mGlyphIndex)
+ , mGlyphType(fgi.mGlyphType)
+ , mWidth(fgi.mWidth)
+ , mHeight(fgi.mHeight)
+ , mXAdvance(fgi.mXAdvance)
+ , mYAdvance(fgi.mYAdvance)
+ , mXBitmapOffset(fgi.mXBitmapOffset)
+ , mYBitmapOffset(fgi.mYBitmapOffset)
+ , mXBearing(fgi.mXBearing)
+ , mYBearing(fgi.mYBearing)
{
- mBitmapEntry = fgi.mBitmapEntry;
+ mBitmapEntry = fgi.mBitmapEntry;
}
LLFontFreetype::LLFontFreetype()
-: mFontBitmapCachep(new LLFontBitmapCache),
- mAscender(0.f),
- mDescender(0.f),
- mLineHeight(0.f),
+: mFontBitmapCachep(new LLFontBitmapCache),
+ mAscender(0.f),
+ mDescender(0.f),
+ mLineHeight(0.f),
#ifdef LL_WINDOWS
- pFileStream(NULL),
- pFtStream(NULL),
+ pFileStream(NULL),
+ pFtStream(NULL),
#endif
- mIsFallback(FALSE),
- mFTFace(NULL),
- mRenderGlyphCount(0),
- mAddGlyphCount(0),
- mStyle(0),
- mPointSize(0)
+ mIsFallback(FALSE),
+ mFTFace(NULL),
+ mRenderGlyphCount(0),
+ mAddGlyphCount(0),
+ mStyle(0),
+ mPointSize(0)
{
}
LLFontFreetype::~LLFontFreetype()
{
- // Clean up freetype libs.
- if (mFTFace)
- FT_Done_Face(mFTFace);
- mFTFace = NULL;
+ // Clean up freetype libs.
+ if (mFTFace)
+ FT_Done_Face(mFTFace);
+ mFTFace = NULL;
- // Delete glyph info
- std::for_each(mCharGlyphInfoMap.begin(), mCharGlyphInfoMap.end(), DeletePairedPointer());
- mCharGlyphInfoMap.clear();
+ // Delete glyph info
+ std::for_each(mCharGlyphInfoMap.begin(), mCharGlyphInfoMap.end(), DeletePairedPointer());
+ mCharGlyphInfoMap.clear();
#ifdef LL_WINDOWS
- delete pFileStream; // closed by FT_Done_Face
- delete pFtStream;
+ delete pFileStream; // closed by FT_Done_Face
+ delete pFtStream;
#endif
- delete mFontBitmapCachep;
- // mFallbackFonts cleaned up by LLPointer destructor
+ delete mFontBitmapCachep;
+ // mFallbackFonts cleaned up by LLPointer destructor
}
#ifdef LL_WINDOWS
unsigned long ft_read_cb(FT_Stream stream, unsigned long offset, unsigned char *buffer, unsigned long count) {
- if (count <= 0) return count;
- llifstream *file_stream = static_cast<llifstream *>(stream->descriptor.pointer);
- file_stream->seekg(offset, std::ios::beg);
- file_stream->read((char*)buffer, count);
- return file_stream->gcount();
+ if (count <= 0) return count;
+ llifstream *file_stream = static_cast<llifstream *>(stream->descriptor.pointer);
+ file_stream->seekg(offset, std::ios::beg);
+ file_stream->read((char*)buffer, count);
+ return file_stream->gcount();
}
void ft_close_cb(FT_Stream stream) {
- llifstream *file_stream = static_cast<llifstream *>(stream->descriptor.pointer);
- file_stream->close();
+ llifstream *file_stream = static_cast<llifstream *>(stream->descriptor.pointer);
+ file_stream->close();
}
#endif
BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, bool is_fallback, S32 face_n)
{
- // Don't leak face objects. This is also needed to deal with
- // changed font file names.
- if (mFTFace)
- {
- FT_Done_Face(mFTFace);
- mFTFace = NULL;
- }
-
- int error;
+ // Don't leak face objects. This is also needed to deal with
+ // changed font file names.
+ if (mFTFace)
+ {
+ FT_Done_Face(mFTFace);
+ mFTFace = NULL;
+ }
+
+ int error;
#ifdef LL_WINDOWS
- error = ftOpenFace(filename, face_n);
+ error = ftOpenFace(filename, face_n);
#else
- error = FT_New_Face( gFTLibrary,
- filename.c_str(),
- 0,
- &mFTFace);
+ error = FT_New_Face( gFTLibrary,
+ filename.c_str(),
+ 0,
+ &mFTFace);
#endif
- if (error)
- {
+ if (error)
+ {
#ifdef LL_WINDOWS
- clearFontStreams();
+ clearFontStreams();
#endif
- return FALSE;
- }
-
- mIsFallback = is_fallback;
- F32 pixels_per_em = (point_size / 72.f)*vert_dpi; // Size in inches * dpi
-
- error = FT_Set_Char_Size(mFTFace, /* handle to face object */
- 0, /* char_width in 1/64th of points */
- (S32)(point_size*64), /* char_height in 1/64th of points */
- (U32)horz_dpi, /* horizontal device resolution */
- (U32)vert_dpi); /* vertical device resolution */
-
- if (error)
- {
- // Clean up freetype libs.
- FT_Done_Face(mFTFace);
+ return FALSE;
+ }
+
+ mIsFallback = is_fallback;
+ F32 pixels_per_em = (point_size / 72.f)*vert_dpi; // Size in inches * dpi
+
+ error = FT_Set_Char_Size(mFTFace, /* handle to face object */
+ 0, /* char_width in 1/64th of points */
+ (S32)(point_size*64), /* char_height in 1/64th of points */
+ (U32)horz_dpi, /* horizontal device resolution */
+ (U32)vert_dpi); /* vertical device resolution */
+
+ if (error)
+ {
+ // Clean up freetype libs.
+ FT_Done_Face(mFTFace);
#ifdef LL_WINDOWS
- clearFontStreams();
+ clearFontStreams();
#endif
- mFTFace = NULL;
- return FALSE;
- }
+ mFTFace = NULL;
+ return FALSE;
+ }
- F32 y_max, y_min, x_max, x_min;
- F32 ems_per_unit = 1.f/ mFTFace->units_per_EM;
- F32 pixels_per_unit = pixels_per_em * ems_per_unit;
+ F32 y_max, y_min, x_max, x_min;
+ F32 ems_per_unit = 1.f/ mFTFace->units_per_EM;
+ F32 pixels_per_unit = pixels_per_em * ems_per_unit;
- // Get size of bbox in pixels
- y_max = mFTFace->bbox.yMax * pixels_per_unit;
- y_min = mFTFace->bbox.yMin * pixels_per_unit;
- x_max = mFTFace->bbox.xMax * pixels_per_unit;
- x_min = mFTFace->bbox.xMin * pixels_per_unit;
- mAscender = mFTFace->ascender * pixels_per_unit;
- mDescender = -mFTFace->descender * pixels_per_unit;
- mLineHeight = mFTFace->height * pixels_per_unit;
+ // Get size of bbox in pixels
+ y_max = mFTFace->bbox.yMax * pixels_per_unit;
+ y_min = mFTFace->bbox.yMin * pixels_per_unit;
+ x_max = mFTFace->bbox.xMax * pixels_per_unit;
+ x_min = mFTFace->bbox.xMin * pixels_per_unit;
+ mAscender = mFTFace->ascender * pixels_per_unit;
+ mDescender = -mFTFace->descender * pixels_per_unit;
+ mLineHeight = mFTFace->height * pixels_per_unit;
- S32 max_char_width = ll_round(0.5f + (x_max - x_min));
- S32 max_char_height = ll_round(0.5f + (y_max - y_min));
+ S32 max_char_width = ll_round(0.5f + (x_max - x_min));
+ S32 max_char_height = ll_round(0.5f + (y_max - y_min));
- mFontBitmapCachep->init(max_char_width, max_char_height);
+ mFontBitmapCachep->init(max_char_width, max_char_height);
- if (!mFTFace->charmap)
- {
- //LL_INFOS() << " no unicode encoding, set whatever encoding there is..." << LL_ENDL;
- FT_Set_Charmap(mFTFace, mFTFace->charmaps[0]);
- }
+ if (!mFTFace->charmap)
+ {
+ //LL_INFOS() << " no unicode encoding, set whatever encoding there is..." << LL_ENDL;
+ FT_Set_Charmap(mFTFace, mFTFace->charmaps[0]);
+ }
- if (!mIsFallback)
- {
- // Add the default glyph
- addGlyphFromFont(this, 0, 0, EFontGlyphType::Grayscale);
- }
+ if (!mIsFallback)
+ {
+ // Add the default glyph
+ addGlyphFromFont(this, 0, 0, EFontGlyphType::Grayscale);
+ }
- mName = filename;
- mPointSize = point_size;
+ mName = filename;
+ mPointSize = point_size;
- mStyle = LLFontGL::NORMAL;
- if(mFTFace->style_flags & FT_STYLE_FLAG_BOLD)
- {
- mStyle |= LLFontGL::BOLD;
- }
+ mStyle = LLFontGL::NORMAL;
+ if(mFTFace->style_flags & FT_STYLE_FLAG_BOLD)
+ {
+ mStyle |= LLFontGL::BOLD;
+ }
- if(mFTFace->style_flags & FT_STYLE_FLAG_ITALIC)
- {
- mStyle |= LLFontGL::ITALIC;
- }
+ if(mFTFace->style_flags & FT_STYLE_FLAG_ITALIC)
+ {
+ mStyle |= LLFontGL::ITALIC;
+ }
- return TRUE;
+ return TRUE;
}
S32 LLFontFreetype::getNumFaces(const std::string& filename)
{
- if (mFTFace)
- {
- FT_Done_Face(mFTFace);
- mFTFace = NULL;
- }
+ if (mFTFace)
+ {
+ FT_Done_Face(mFTFace);
+ mFTFace = NULL;
+ }
- S32 num_faces = 1;
+ S32 num_faces = 1;
#ifdef LL_WINDOWS
- int error = ftOpenFace(filename, 0);
-
- if (error)
- {
- return 0;
- }
- else
- {
- num_faces = mFTFace->num_faces;
- }
-
- FT_Done_Face(mFTFace);
- clearFontStreams();
- mFTFace = NULL;
+ int error = ftOpenFace(filename, 0);
+
+ if (error)
+ {
+ return 0;
+ }
+ else
+ {
+ num_faces = mFTFace->num_faces;
+ }
+
+ FT_Done_Face(mFTFace);
+ clearFontStreams();
+ mFTFace = NULL;
#endif
- return num_faces;
+ return num_faces;
}
#ifdef LL_WINDOWS
S32 LLFontFreetype::ftOpenFace(const std::string& filename, S32 face_n)
{
- S32 error = -1;
- pFileStream = new llifstream(filename, std::ios::binary);
- if (pFileStream->is_open())
- {
- std::streampos beg = pFileStream->tellg();
- pFileStream->seekg(0, std::ios::end);
- std::streampos end = pFileStream->tellg();
- std::size_t file_size = end - beg;
- pFileStream->seekg(0, std::ios::beg);
-
- pFtStream = new LLFT_Stream();
- pFtStream->base = 0;
- pFtStream->pos = 0;
- pFtStream->size = file_size;
- pFtStream->descriptor.pointer = pFileStream;
- pFtStream->read = ft_read_cb;
- pFtStream->close = ft_close_cb;
-
- FT_Open_Args args;
- args.flags = FT_OPEN_STREAM;
- args.stream = (FT_StreamRec*)pFtStream;
- error = FT_Open_Face(gFTLibrary, &args, face_n, &mFTFace);
- }
- return error;
+ S32 error = -1;
+ pFileStream = new llifstream(filename, std::ios::binary);
+ if (pFileStream->is_open())
+ {
+ std::streampos beg = pFileStream->tellg();
+ pFileStream->seekg(0, std::ios::end);
+ std::streampos end = pFileStream->tellg();
+ std::size_t file_size = end - beg;
+ pFileStream->seekg(0, std::ios::beg);
+
+ pFtStream = new LLFT_Stream();
+ pFtStream->base = 0;
+ pFtStream->pos = 0;
+ pFtStream->size = file_size;
+ pFtStream->descriptor.pointer = pFileStream;
+ pFtStream->read = ft_read_cb;
+ pFtStream->close = ft_close_cb;
+
+ FT_Open_Args args;
+ args.flags = FT_OPEN_STREAM;
+ args.stream = (FT_StreamRec*)pFtStream;
+ error = FT_Open_Face(gFTLibrary, &args, face_n, &mFTFace);
+ }
+ return error;
}
void LLFontFreetype::clearFontStreams()
{
- if (pFileStream)
- {
- pFileStream->close();
- }
- delete pFileStream;
- delete pFtStream;
- pFileStream = NULL;
- pFtStream = NULL;
+ if (pFileStream)
+ {
+ pFileStream->close();
+ }
+ delete pFileStream;
+ delete pFtStream;
+ pFileStream = NULL;
+ pFtStream = NULL;
}
#endif
void LLFontFreetype::addFallbackFont(const LLPointer<LLFontFreetype>& fallback_font, const char_functor_t& functor)
{
- // Insert functor fallbacks before generic fallbacks
- mFallbackFonts.insert((functor) ? std::find_if(mFallbackFonts.begin(), mFallbackFonts.end(), [](const fallback_font_t& fe) { return !fe.second; }) : mFallbackFonts.end(),
- std::make_pair(fallback_font, functor));
+ // Insert functor fallbacks before generic fallbacks
+ mFallbackFonts.insert((functor) ? std::find_if(mFallbackFonts.begin(), mFallbackFonts.end(), [](const fallback_font_t& fe) { return !fe.second; }) : mFallbackFonts.end(),
+ std::make_pair(fallback_font, functor));
}
F32 LLFontFreetype::getLineHeight() const
{
- return mLineHeight;
+ return mLineHeight;
}
F32 LLFontFreetype::getAscenderHeight() const
{
- return mAscender;
+ return mAscender;
}
F32 LLFontFreetype::getDescenderHeight() const
{
- return mDescender;
+ return mDescender;
}
F32 LLFontFreetype::getXAdvance(llwchar wch) const
{
- if (mFTFace == NULL)
- return 0.0;
+ if (mFTFace == NULL)
+ return 0.0;
- // Return existing info only if it is current
- LLFontGlyphInfo* gi = getGlyphInfo(wch, EFontGlyphType::Unspecified);
- if (gi)
- {
- return gi->mXAdvance;
- }
- else
- {
- char_glyph_info_map_t::iterator found_it = mCharGlyphInfoMap.find((llwchar)0);
- if (found_it != mCharGlyphInfoMap.end())
- {
- return found_it->second->mXAdvance;
- }
- }
+ // Return existing info only if it is current
+ LLFontGlyphInfo* gi = getGlyphInfo(wch, EFontGlyphType::Unspecified);
+ if (gi)
+ {
+ return gi->mXAdvance;
+ }
+ else
+ {
+ char_glyph_info_map_t::iterator found_it = mCharGlyphInfoMap.find((llwchar)0);
+ if (found_it != mCharGlyphInfoMap.end())
+ {
+ return found_it->second->mXAdvance;
+ }
+ }
- // Last ditch fallback - no glyphs defined at all.
- return (F32)mFontBitmapCachep->getMaxCharWidth();
+ // Last ditch fallback - no glyphs defined at all.
+ return (F32)mFontBitmapCachep->getMaxCharWidth();
}
F32 LLFontFreetype::getXAdvance(const LLFontGlyphInfo* glyph) const
{
- if (mFTFace == NULL)
- return 0.0;
+ if (mFTFace == NULL)
+ return 0.0;
- return glyph->mXAdvance;
+ return glyph->mXAdvance;
}
F32 LLFontFreetype::getXKerning(llwchar char_left, llwchar char_right) const
{
- if (mFTFace == NULL)
- return 0.0;
+ if (mFTFace == NULL)
+ return 0.0;
- //llassert(!mIsFallback);
- LLFontGlyphInfo* left_glyph_info = getGlyphInfo(char_left, EFontGlyphType::Unspecified);;
- U32 left_glyph = left_glyph_info ? left_glyph_info->mGlyphIndex : 0;
- // Kern this puppy.
- LLFontGlyphInfo* right_glyph_info = getGlyphInfo(char_right, EFontGlyphType::Unspecified);
- U32 right_glyph = right_glyph_info ? right_glyph_info->mGlyphIndex : 0;
+ //llassert(!mIsFallback);
+ LLFontGlyphInfo* left_glyph_info = getGlyphInfo(char_left, EFontGlyphType::Unspecified);;
+ U32 left_glyph = left_glyph_info ? left_glyph_info->mGlyphIndex : 0;
+ // Kern this puppy.
+ LLFontGlyphInfo* right_glyph_info = getGlyphInfo(char_right, EFontGlyphType::Unspecified);
+ U32 right_glyph = right_glyph_info ? right_glyph_info->mGlyphIndex : 0;
- FT_Vector delta;
+ FT_Vector delta;
- llverify(!FT_Get_Kerning(mFTFace, left_glyph, right_glyph, ft_kerning_unfitted, &delta));
+ llverify(!FT_Get_Kerning(mFTFace, left_glyph, right_glyph, ft_kerning_unfitted, &delta));
- return delta.x*(1.f/64.f);
+ return delta.x*(1.f/64.f);
}
F32 LLFontFreetype::getXKerning(const LLFontGlyphInfo* left_glyph_info, const LLFontGlyphInfo* right_glyph_info) const
{
- if (mFTFace == NULL)
- return 0.0;
+ if (mFTFace == NULL)
+ return 0.0;
- U32 left_glyph = left_glyph_info ? left_glyph_info->mGlyphIndex : 0;
- U32 right_glyph = right_glyph_info ? right_glyph_info->mGlyphIndex : 0;
+ U32 left_glyph = left_glyph_info ? left_glyph_info->mGlyphIndex : 0;
+ U32 right_glyph = right_glyph_info ? right_glyph_info->mGlyphIndex : 0;
- FT_Vector delta;
+ FT_Vector delta;
- llverify(!FT_Get_Kerning(mFTFace, left_glyph, right_glyph, ft_kerning_unfitted, &delta));
+ llverify(!FT_Get_Kerning(mFTFace, left_glyph, right_glyph, ft_kerning_unfitted, &delta));
- return delta.x*(1.f/64.f);
+ return delta.x*(1.f/64.f);
}
BOOL LLFontFreetype::hasGlyph(llwchar wch) const
{
- llassert(!mIsFallback);
- return(mCharGlyphInfoMap.find(wch) != mCharGlyphInfoMap.end());
+ llassert(!mIsFallback);
+ return(mCharGlyphInfoMap.find(wch) != mCharGlyphInfoMap.end());
}
LLFontGlyphInfo* LLFontFreetype::addGlyph(llwchar wch, EFontGlyphType glyph_type) const
{
- if (mFTFace == NULL)
- return FALSE;
-
- llassert(!mIsFallback);
- llassert(glyph_type < EFontGlyphType::Count);
- //LL_DEBUGS() << "Adding new glyph for " << wch << " to font" << LL_ENDL;
-
- FT_UInt glyph_index;
-
- // Fallback fonts with a functor have precedence over everything else
- fallback_font_vector_t::const_iterator it_fallback = mFallbackFonts.cbegin();
- /* This leads to a bug SL-19831 "Check marks in the menu are less visible."
- ** Also, LLFontRegistry::createFont() says: "Fallback fonts don't render"
- for (; it_fallback != mFallbackFonts.cend() && it_fallback->second; ++it_fallback)
- {
- if (it_fallback->second(wch))
- {
- glyph_index = FT_Get_Char_Index(it_fallback->first->mFTFace, wch);
- if (glyph_index)
- {
- return addGlyphFromFont(it_fallback->first, wch, glyph_index, glyph_type);
- }
- }
- }
- */
-
- // Initialize char to glyph map
- glyph_index = FT_Get_Char_Index(mFTFace, wch);
- if (glyph_index == 0)
- {
- //LL_INFOS() << "Trying to add glyph from fallback font!" << LL_ENDL;
- for (; it_fallback != mFallbackFonts.cend(); ++it_fallback)
- {
- glyph_index = FT_Get_Char_Index(it_fallback->first->mFTFace, wch);
- if (glyph_index)
- {
- return addGlyphFromFont(it_fallback->first, wch, glyph_index, glyph_type);
- }
- }
- }
-
- std::pair<char_glyph_info_map_t::iterator, char_glyph_info_map_t::iterator> range_it = mCharGlyphInfoMap.equal_range(wch);
- char_glyph_info_map_t::iterator iter =
- std::find_if(range_it.first, range_it.second, [&glyph_type](const char_glyph_info_map_t::value_type& entry) { return entry.second->mGlyphType == glyph_type; });
- if (iter == range_it.second)
- {
- return addGlyphFromFont(this, wch, glyph_index, glyph_type);
- }
- return NULL;
+ if (mFTFace == NULL)
+ return FALSE;
+
+ llassert(!mIsFallback);
+ llassert(glyph_type < EFontGlyphType::Count);
+ //LL_DEBUGS() << "Adding new glyph for " << wch << " to font" << LL_ENDL;
+
+ FT_UInt glyph_index;
+
+ // Fallback fonts with a functor have precedence over everything else
+ fallback_font_vector_t::const_iterator it_fallback = mFallbackFonts.cbegin();
+ /* This leads to a bug SL-19831 "Check marks in the menu are less visible."
+ ** Also, LLFontRegistry::createFont() says: "Fallback fonts don't render"
+ for (; it_fallback != mFallbackFonts.cend() && it_fallback->second; ++it_fallback)
+ {
+ if (it_fallback->second(wch))
+ {
+ glyph_index = FT_Get_Char_Index(it_fallback->first->mFTFace, wch);
+ if (glyph_index)
+ {
+ return addGlyphFromFont(it_fallback->first, wch, glyph_index, glyph_type);
+ }
+ }
+ }
+ */
+
+ // Initialize char to glyph map
+ glyph_index = FT_Get_Char_Index(mFTFace, wch);
+ if (glyph_index == 0)
+ {
+ //LL_INFOS() << "Trying to add glyph from fallback font!" << LL_ENDL;
+ for (; it_fallback != mFallbackFonts.cend(); ++it_fallback)
+ {
+ glyph_index = FT_Get_Char_Index(it_fallback->first->mFTFace, wch);
+ if (glyph_index)
+ {
+ return addGlyphFromFont(it_fallback->first, wch, glyph_index, glyph_type);
+ }
+ }
+ }
+
+ std::pair<char_glyph_info_map_t::iterator, char_glyph_info_map_t::iterator> range_it = mCharGlyphInfoMap.equal_range(wch);
+ char_glyph_info_map_t::iterator iter =
+ std::find_if(range_it.first, range_it.second, [&glyph_type](const char_glyph_info_map_t::value_type& entry) { return entry.second->mGlyphType == glyph_type; });
+ if (iter == range_it.second)
+ {
+ return addGlyphFromFont(this, wch, glyph_index, glyph_type);
+ }
+ return NULL;
}
LLFontGlyphInfo* LLFontFreetype::addGlyphFromFont(const LLFontFreetype *fontp, llwchar wch, U32 glyph_index, EFontGlyphType requested_glyph_type) const
{
LL_PROFILE_ZONE_SCOPED;
- if (mFTFace == NULL)
- return NULL;
-
- llassert(!mIsFallback);
- fontp->renderGlyph(requested_glyph_type, glyph_index);
-
- EFontGlyphType bitmap_glyph_type = EFontGlyphType::Unspecified;
- switch (fontp->mFTFace->glyph->bitmap.pixel_mode)
- {
- case FT_PIXEL_MODE_MONO:
- case FT_PIXEL_MODE_GRAY:
- bitmap_glyph_type = EFontGlyphType::Grayscale;
- break;
- case FT_PIXEL_MODE_BGRA:
- bitmap_glyph_type = EFontGlyphType::Color;
- break;
- default:
- llassert_always(true);
- break;
- }
- S32 width = fontp->mFTFace->glyph->bitmap.width;
- S32 height = fontp->mFTFace->glyph->bitmap.rows;
-
- S32 pos_x, pos_y;
- U32 bitmap_num;
- mFontBitmapCachep->nextOpenPos(width, pos_x, pos_y, bitmap_glyph_type, bitmap_num);
- mAddGlyphCount++;
-
- LLFontGlyphInfo* gi = new LLFontGlyphInfo(glyph_index, requested_glyph_type);
- gi->mXBitmapOffset = pos_x;
- gi->mYBitmapOffset = pos_y;
- gi->mBitmapEntry = std::make_pair(bitmap_glyph_type, bitmap_num);
- gi->mWidth = width;
- gi->mHeight = height;
- gi->mXBearing = fontp->mFTFace->glyph->bitmap_left;
- gi->mYBearing = fontp->mFTFace->glyph->bitmap_top;
- // Convert these from 26.6 units to float pixels.
- gi->mXAdvance = fontp->mFTFace->glyph->advance.x / 64.f;
- gi->mYAdvance = fontp->mFTFace->glyph->advance.y / 64.f;
-
- insertGlyphInfo(wch, gi);
-
- if (requested_glyph_type != bitmap_glyph_type)
- {
- LLFontGlyphInfo* gi_temp = new LLFontGlyphInfo(*gi);
- gi_temp->mGlyphType = bitmap_glyph_type;
- insertGlyphInfo(wch, gi_temp);
- }
-
- if (fontp->mFTFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO
- || fontp->mFTFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_GRAY)
- {
- U8 *buffer_data = fontp->mFTFace->glyph->bitmap.buffer;
- S32 buffer_row_stride = fontp->mFTFace->glyph->bitmap.pitch;
- U8 *tmp_graydata = NULL;
-
- if (fontp->mFTFace->glyph->bitmap.pixel_mode
- == FT_PIXEL_MODE_MONO)
- {
- // need to expand 1-bit bitmap to 8-bit graymap.
- tmp_graydata = new U8[width * height];
- S32 xpos, ypos;
- for (ypos = 0; ypos < height; ++ypos)
- {
- S32 bm_row_offset = buffer_row_stride * ypos;
- for (xpos = 0; xpos < width; ++xpos)
- {
- U32 bm_col_offsetbyte = xpos / 8;
- U32 bm_col_offsetbit = 7 - (xpos % 8);
- U32 bit =
- !!(buffer_data[bm_row_offset
- + bm_col_offsetbyte
- ] & (1 << bm_col_offsetbit) );
- tmp_graydata[width*ypos + xpos] =
- 255 * bit;
- }
- }
- // use newly-built graymap.
- buffer_data = tmp_graydata;
- buffer_row_stride = width;
- }
-
- setSubImageLuminanceAlpha(pos_x,
- pos_y,
- bitmap_num,
- width,
- height,
- buffer_data,
- buffer_row_stride);
-
- if (tmp_graydata)
- delete[] tmp_graydata;
- }
- else if (fontp->mFTFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_BGRA)
- {
- setSubImageBGRA(pos_x,
- pos_y,
- bitmap_num,
- fontp->mFTFace->glyph->bitmap.width,
- fontp->mFTFace->glyph->bitmap.rows,
- fontp->mFTFace->glyph->bitmap.buffer,
- llabs(fontp->mFTFace->glyph->bitmap.pitch));
- } else {
- llassert(false);
- }
-
- LLImageGL *image_gl = mFontBitmapCachep->getImageGL(bitmap_glyph_type, bitmap_num);
- LLImageRaw *image_raw = mFontBitmapCachep->getImageRaw(bitmap_glyph_type, bitmap_num);
- image_gl->setSubImage(image_raw, 0, 0, image_gl->getWidth(), image_gl->getHeight());
-
- return gi;
+ if (mFTFace == NULL)
+ return NULL;
+
+ llassert(!mIsFallback);
+ fontp->renderGlyph(requested_glyph_type, glyph_index);
+
+ EFontGlyphType bitmap_glyph_type = EFontGlyphType::Unspecified;
+ switch (fontp->mFTFace->glyph->bitmap.pixel_mode)
+ {
+ case FT_PIXEL_MODE_MONO:
+ case FT_PIXEL_MODE_GRAY:
+ bitmap_glyph_type = EFontGlyphType::Grayscale;
+ break;
+ case FT_PIXEL_MODE_BGRA:
+ bitmap_glyph_type = EFontGlyphType::Color;
+ break;
+ default:
+ llassert_always(true);
+ break;
+ }
+ S32 width = fontp->mFTFace->glyph->bitmap.width;
+ S32 height = fontp->mFTFace->glyph->bitmap.rows;
+
+ S32 pos_x, pos_y;
+ U32 bitmap_num;
+ mFontBitmapCachep->nextOpenPos(width, pos_x, pos_y, bitmap_glyph_type, bitmap_num);
+ mAddGlyphCount++;
+
+ LLFontGlyphInfo* gi = new LLFontGlyphInfo(glyph_index, requested_glyph_type);
+ gi->mXBitmapOffset = pos_x;
+ gi->mYBitmapOffset = pos_y;
+ gi->mBitmapEntry = std::make_pair(bitmap_glyph_type, bitmap_num);
+ gi->mWidth = width;
+ gi->mHeight = height;
+ gi->mXBearing = fontp->mFTFace->glyph->bitmap_left;
+ gi->mYBearing = fontp->mFTFace->glyph->bitmap_top;
+ // Convert these from 26.6 units to float pixels.
+ gi->mXAdvance = fontp->mFTFace->glyph->advance.x / 64.f;
+ gi->mYAdvance = fontp->mFTFace->glyph->advance.y / 64.f;
+
+ insertGlyphInfo(wch, gi);
+
+ if (requested_glyph_type != bitmap_glyph_type)
+ {
+ LLFontGlyphInfo* gi_temp = new LLFontGlyphInfo(*gi);
+ gi_temp->mGlyphType = bitmap_glyph_type;
+ insertGlyphInfo(wch, gi_temp);
+ }
+
+ if (fontp->mFTFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO
+ || fontp->mFTFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_GRAY)
+ {
+ U8 *buffer_data = fontp->mFTFace->glyph->bitmap.buffer;
+ S32 buffer_row_stride = fontp->mFTFace->glyph->bitmap.pitch;
+ U8 *tmp_graydata = NULL;
+
+ if (fontp->mFTFace->glyph->bitmap.pixel_mode
+ == FT_PIXEL_MODE_MONO)
+ {
+ // need to expand 1-bit bitmap to 8-bit graymap.
+ tmp_graydata = new U8[width * height];
+ S32 xpos, ypos;
+ for (ypos = 0; ypos < height; ++ypos)
+ {
+ S32 bm_row_offset = buffer_row_stride * ypos;
+ for (xpos = 0; xpos < width; ++xpos)
+ {
+ U32 bm_col_offsetbyte = xpos / 8;
+ U32 bm_col_offsetbit = 7 - (xpos % 8);
+ U32 bit =
+ !!(buffer_data[bm_row_offset
+ + bm_col_offsetbyte
+ ] & (1 << bm_col_offsetbit) );
+ tmp_graydata[width*ypos + xpos] =
+ 255 * bit;
+ }
+ }
+ // use newly-built graymap.
+ buffer_data = tmp_graydata;
+ buffer_row_stride = width;
+ }
+
+ setSubImageLuminanceAlpha(pos_x,
+ pos_y,
+ bitmap_num,
+ width,
+ height,
+ buffer_data,
+ buffer_row_stride);
+
+ if (tmp_graydata)
+ delete[] tmp_graydata;
+ }
+ else if (fontp->mFTFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_BGRA)
+ {
+ setSubImageBGRA(pos_x,
+ pos_y,
+ bitmap_num,
+ fontp->mFTFace->glyph->bitmap.width,
+ fontp->mFTFace->glyph->bitmap.rows,
+ fontp->mFTFace->glyph->bitmap.buffer,
+ llabs(fontp->mFTFace->glyph->bitmap.pitch));
+ } else {
+ llassert(false);
+ }
+
+ LLImageGL *image_gl = mFontBitmapCachep->getImageGL(bitmap_glyph_type, bitmap_num);
+ LLImageRaw *image_raw = mFontBitmapCachep->getImageRaw(bitmap_glyph_type, bitmap_num);
+ image_gl->setSubImage(image_raw, 0, 0, image_gl->getWidth(), image_gl->getHeight());
+
+ return gi;
}
LLFontGlyphInfo* LLFontFreetype::getGlyphInfo(llwchar wch, EFontGlyphType glyph_type) const
{
- std::pair<char_glyph_info_map_t::iterator, char_glyph_info_map_t::iterator> range_it = mCharGlyphInfoMap.equal_range(wch);
+ std::pair<char_glyph_info_map_t::iterator, char_glyph_info_map_t::iterator> range_it = mCharGlyphInfoMap.equal_range(wch);
- char_glyph_info_map_t::iterator iter = (EFontGlyphType::Unspecified != glyph_type)
- ? std::find_if(range_it.first, range_it.second, [&glyph_type](const char_glyph_info_map_t::value_type& entry) { return entry.second->mGlyphType == glyph_type; })
- : range_it.first;
- if (iter != range_it.second)
- {
- return iter->second;
- }
- else
- {
- // this glyph doesn't yet exist, so render it and return the result
- return addGlyph(wch, (EFontGlyphType::Unspecified != glyph_type) ? glyph_type : EFontGlyphType::Grayscale);
- }
+ char_glyph_info_map_t::iterator iter = (EFontGlyphType::Unspecified != glyph_type)
+ ? std::find_if(range_it.first, range_it.second, [&glyph_type](const char_glyph_info_map_t::value_type& entry) { return entry.second->mGlyphType == glyph_type; })
+ : range_it.first;
+ if (iter != range_it.second)
+ {
+ return iter->second;
+ }
+ else
+ {
+ // this glyph doesn't yet exist, so render it and return the result
+ return addGlyph(wch, (EFontGlyphType::Unspecified != glyph_type) ? glyph_type : EFontGlyphType::Grayscale);
+ }
}
void LLFontFreetype::insertGlyphInfo(llwchar wch, LLFontGlyphInfo* gi) const
{
- llassert(gi->mGlyphType < EFontGlyphType::Count);
- std::pair<char_glyph_info_map_t::iterator, char_glyph_info_map_t::iterator> range_it = mCharGlyphInfoMap.equal_range(wch);
+ llassert(gi->mGlyphType < EFontGlyphType::Count);
+ std::pair<char_glyph_info_map_t::iterator, char_glyph_info_map_t::iterator> range_it = mCharGlyphInfoMap.equal_range(wch);
- char_glyph_info_map_t::iterator iter =
- std::find_if(range_it.first, range_it.second, [&gi](const char_glyph_info_map_t::value_type& entry) { return entry.second->mGlyphType == gi->mGlyphType; });
- if (iter != range_it.second)
- {
- delete iter->second;
- iter->second = gi;
- }
- else
- {
- mCharGlyphInfoMap.insert(std::make_pair(wch, gi));
- }
+ char_glyph_info_map_t::iterator iter =
+ std::find_if(range_it.first, range_it.second, [&gi](const char_glyph_info_map_t::value_type& entry) { return entry.second->mGlyphType == gi->mGlyphType; });
+ if (iter != range_it.second)
+ {
+ delete iter->second;
+ iter->second = gi;
+ }
+ else
+ {
+ mCharGlyphInfoMap.insert(std::make_pair(wch, gi));
+ }
}
void LLFontFreetype::renderGlyph(EFontGlyphType bitmap_type, U32 glyph_index) const
{
- if (mFTFace == NULL)
- return;
+ if (mFTFace == NULL)
+ return;
- FT_Int32 load_flags = FT_LOAD_FORCE_AUTOHINT;
- if (EFontGlyphType::Color == bitmap_type)
- {
- // We may not actually get a color render so our caller should always examine mFTFace->glyph->bitmap.pixel_mode
- load_flags |= FT_LOAD_COLOR;
- }
+ FT_Int32 load_flags = FT_LOAD_FORCE_AUTOHINT;
+ if (EFontGlyphType::Color == bitmap_type)
+ {
+ // We may not actually get a color render so our caller should always examine mFTFace->glyph->bitmap.pixel_mode
+ load_flags |= FT_LOAD_COLOR;
+ }
- FT_Error error = FT_Load_Glyph(mFTFace, glyph_index, load_flags);
- if (FT_Err_Ok != error)
- {
- std::string message = llformat(
- "Error %d (%s) loading glyph %u: bitmap_type=%u, load_flags=%d",
- error, FT_Error_String(error), glyph_index, bitmap_type, load_flags);
- LL_WARNS_ONCE() << message << LL_ENDL;
- error = FT_Load_Glyph(mFTFace, glyph_index, load_flags ^ FT_LOAD_COLOR);
- llassert_always_msg(FT_Err_Ok == error, message.c_str());
- }
+ FT_Error error = FT_Load_Glyph(mFTFace, glyph_index, load_flags);
+ if (FT_Err_Ok != error)
+ {
+ std::string message = llformat(
+ "Error %d (%s) loading glyph %u: bitmap_type=%u, load_flags=%d",
+ error, FT_Error_String(error), glyph_index, bitmap_type, load_flags);
+ LL_WARNS_ONCE() << message << LL_ENDL;
+ error = FT_Load_Glyph(mFTFace, glyph_index, load_flags ^ FT_LOAD_COLOR);
+ llassert_always_msg(FT_Err_Ok == error, message.c_str());
+ }
- llassert_always(! FT_Render_Glyph(mFTFace->glyph, gFontRenderMode) );
+ llassert_always(! FT_Render_Glyph(mFTFace->glyph, gFontRenderMode) );
- mRenderGlyphCount++;
+ mRenderGlyphCount++;
}
void LLFontFreetype::reset(F32 vert_dpi, F32 horz_dpi)
{
- resetBitmapCache();
- loadFace(mName, mPointSize, vert_dpi ,horz_dpi, mIsFallback, 0);
- if (!mIsFallback)
- {
- // This is the head of the list - need to rebuild ourself and all fallbacks.
- if (mFallbackFonts.empty())
- {
- LL_WARNS() << "LLFontGL::reset(), no fallback fonts present" << LL_ENDL;
- }
- else
- {
- for (fallback_font_vector_t::iterator it = mFallbackFonts.begin(); it != mFallbackFonts.end(); ++it)
- {
- it->first->reset(vert_dpi, horz_dpi);
- }
- }
- }
+ resetBitmapCache();
+ loadFace(mName, mPointSize, vert_dpi ,horz_dpi, mIsFallback, 0);
+ if (!mIsFallback)
+ {
+ // This is the head of the list - need to rebuild ourself and all fallbacks.
+ if (mFallbackFonts.empty())
+ {
+ LL_WARNS() << "LLFontGL::reset(), no fallback fonts present" << LL_ENDL;
+ }
+ else
+ {
+ for (fallback_font_vector_t::iterator it = mFallbackFonts.begin(); it != mFallbackFonts.end(); ++it)
+ {
+ it->first->reset(vert_dpi, horz_dpi);
+ }
+ }
+ }
}
void LLFontFreetype::resetBitmapCache()
{
- for (char_glyph_info_map_t::iterator it = mCharGlyphInfoMap.begin(), end_it = mCharGlyphInfoMap.end();
- it != end_it;
- ++it)
- {
- delete it->second;
- }
- mCharGlyphInfoMap.clear();
- mFontBitmapCachep->reset();
+ for (char_glyph_info_map_t::iterator it = mCharGlyphInfoMap.begin(), end_it = mCharGlyphInfoMap.end();
+ it != end_it;
+ ++it)
+ {
+ delete it->second;
+ }
+ mCharGlyphInfoMap.clear();
+ mFontBitmapCachep->reset();
- // Adding default glyph is skipped for fallback fonts here as well as in loadFace().
- // This if was added as fix for EXT-4971.
- if(!mIsFallback)
- {
- // Add the empty glyph
- addGlyphFromFont(this, 0, 0, EFontGlyphType::Grayscale);
- }
+ // Adding default glyph is skipped for fallback fonts here as well as in loadFace().
+ // This if was added as fix for EXT-4971.
+ if(!mIsFallback)
+ {
+ // Add the empty glyph
+ addGlyphFromFont(this, 0, 0, EFontGlyphType::Grayscale);
+ }
}
void LLFontFreetype::destroyGL()
{
- mFontBitmapCachep->destroyGL();
+ mFontBitmapCachep->destroyGL();
}
const std::string &LLFontFreetype::getName() const
{
- return mName;
+ return mName;
}
static void dumpFontBitmap(const LLImageRaw* image_raw, const std::string& file_name)
{
- LLPointer<LLImagePNG> tmpImage = new LLImagePNG();
- if ( (tmpImage->encode(image_raw, 0.0f)) && (tmpImage->save(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, file_name))) )
- {
- LL_INFOS("Font") << "Successfully saved " << file_name << LL_ENDL;
- }
- else
- {
- LL_WARNS("Font") << "Failed to save " << file_name << LL_ENDL;
- }
+ LLPointer<LLImagePNG> tmpImage = new LLImagePNG();
+ if ( (tmpImage->encode(image_raw, 0.0f)) && (tmpImage->save(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, file_name))) )
+ {
+ LL_INFOS("Font") << "Successfully saved " << file_name << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS("Font") << "Failed to save " << file_name << LL_ENDL;
+ }
}
void LLFontFreetype::dumpFontBitmaps() const
{
- // Dump all the regular bitmaps (if any)
- for (int idx = 0, cnt = mFontBitmapCachep->getNumBitmaps(EFontGlyphType::Grayscale); idx < cnt; idx++)
- {
- dumpFontBitmap(mFontBitmapCachep->getImageRaw(EFontGlyphType::Grayscale, idx), llformat("%s_%d_%d_%d.png", mFTFace->family_name, (int)(mPointSize * 10), mStyle, idx));
- }
+ // Dump all the regular bitmaps (if any)
+ for (int idx = 0, cnt = mFontBitmapCachep->getNumBitmaps(EFontGlyphType::Grayscale); idx < cnt; idx++)
+ {
+ dumpFontBitmap(mFontBitmapCachep->getImageRaw(EFontGlyphType::Grayscale, idx), llformat("%s_%d_%d_%d.png", mFTFace->family_name, (int)(mPointSize * 10), mStyle, idx));
+ }
- // Dump all the color bitmaps (if any)
- for (int idx = 0, cnt = mFontBitmapCachep->getNumBitmaps(EFontGlyphType::Color); idx < cnt; idx++)
- {
- dumpFontBitmap(mFontBitmapCachep->getImageRaw(EFontGlyphType::Color, idx), llformat("%s_%d_%d_%d_clr.png", mFTFace->family_name, (int)(mPointSize * 10), mStyle, idx));
- }
+ // Dump all the color bitmaps (if any)
+ for (int idx = 0, cnt = mFontBitmapCachep->getNumBitmaps(EFontGlyphType::Color); idx < cnt; idx++)
+ {
+ dumpFontBitmap(mFontBitmapCachep->getImageRaw(EFontGlyphType::Color, idx), llformat("%s_%d_%d_%d_clr.png", mFTFace->family_name, (int)(mPointSize * 10), mStyle, idx));
+ }
}
const LLFontBitmapCache* LLFontFreetype::getFontBitmapCache() const
{
- return mFontBitmapCachep;
+ return mFontBitmapCachep;
}
void LLFontFreetype::setStyle(U8 style)
{
- mStyle = style;
+ mStyle = style;
}
U8 LLFontFreetype::getStyle() const
{
- return mStyle;
+ return mStyle;
}
bool LLFontFreetype::setSubImageBGRA(U32 x, U32 y, U32 bitmap_num, U16 width, U16 height, const U8* data, U32 stride) const
{
- LLImageRaw* image_raw = mFontBitmapCachep->getImageRaw(EFontGlyphType::Color, bitmap_num);
- llassert(!mIsFallback);
- llassert(image_raw && (image_raw->getComponents() == 4));
+ LLImageRaw* image_raw = mFontBitmapCachep->getImageRaw(EFontGlyphType::Color, bitmap_num);
+ llassert(!mIsFallback);
+ llassert(image_raw && (image_raw->getComponents() == 4));
- // NOTE: inspired by LLImageRaw::setSubImage()
- U32* image_data = (U32*)image_raw->getData();
- if (!image_data)
- {
- return false;
- }
+ // NOTE: inspired by LLImageRaw::setSubImage()
+ U32* image_data = (U32*)image_raw->getData();
+ if (!image_data)
+ {
+ return false;
+ }
- for (U32 idxRow = 0; idxRow < height; idxRow++)
- {
- const U32 nSrcRow = height - 1 - idxRow;
- const U32 nSrcOffset = nSrcRow * width * image_raw->getComponents();
- const U32 nDstOffset = (y + idxRow) * image_raw->getWidth() + x;
+ for (U32 idxRow = 0; idxRow < height; idxRow++)
+ {
+ const U32 nSrcRow = height - 1 - idxRow;
+ const U32 nSrcOffset = nSrcRow * width * image_raw->getComponents();
+ const U32 nDstOffset = (y + idxRow) * image_raw->getWidth() + x;
- for (U32 idxCol = 0; idxCol < width; idxCol++)
- {
- U32 nTemp = nSrcOffset + idxCol * 4;
- image_data[nDstOffset + idxCol] = data[nTemp + 3] << 24 | data[nTemp] << 16 | data[nTemp + 1] << 8 | data[nTemp + 2];
- }
- }
+ for (U32 idxCol = 0; idxCol < width; idxCol++)
+ {
+ U32 nTemp = nSrcOffset + idxCol * 4;
+ image_data[nDstOffset + idxCol] = data[nTemp + 3] << 24 | data[nTemp] << 16 | data[nTemp + 1] << 8 | data[nTemp + 2];
+ }
+ }
- return true;
+ return true;
}
void LLFontFreetype::setSubImageLuminanceAlpha(U32 x, U32 y, U32 bitmap_num, U32 width, U32 height, U8 *data, S32 stride) const
{
- LLImageRaw *image_raw = mFontBitmapCachep->getImageRaw(EFontGlyphType::Grayscale, bitmap_num);
+ LLImageRaw *image_raw = mFontBitmapCachep->getImageRaw(EFontGlyphType::Grayscale, bitmap_num);
+
+ llassert(!mIsFallback);
+ llassert(image_raw && (image_raw->getComponents() == 2));
- llassert(!mIsFallback);
- llassert(image_raw && (image_raw->getComponents() == 2));
-
- U8 *target = image_raw->getData();
+ U8 *target = image_raw->getData();
llassert(target);
- if (!data || !target)
- {
- return;
- }
-
- if (0 == stride)
- stride = width;
-
- U32 i, j;
- U32 to_offset;
- U32 from_offset;
- U32 target_width = image_raw->getWidth();
- for (i = 0; i < height; i++)
- {
- to_offset = (y + i)*target_width + x;
- from_offset = (height - 1 - i)*stride;
- for (j = 0; j < width; j++)
- {
- *(target + to_offset*2 + 1) = *(data + from_offset);
- to_offset++;
- from_offset++;
- }
- }
+ if (!data || !target)
+ {
+ return;
+ }
+
+ if (0 == stride)
+ stride = width;
+
+ U32 i, j;
+ U32 to_offset;
+ U32 from_offset;
+ U32 target_width = image_raw->getWidth();
+ for (i = 0; i < height; i++)
+ {
+ to_offset = (y + i)*target_width + x;
+ from_offset = (height - 1 - i)*stride;
+ for (j = 0; j < width; j++)
+ {
+ *(target + to_offset*2 + 1) = *(data + from_offset);
+ to_offset++;
+ from_offset++;
+ }
+ }
}
diff --git a/indra/llrender/llfontfreetype.h b/indra/llrender/llfontfreetype.h
index b036d337ba..19112830a4 100644
--- a/indra/llrender/llfontfreetype.h
+++ b/indra/llrender/llfontfreetype.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file llfontfreetype.h
* @brief Font library wrapper
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -35,8 +35,8 @@
#include "llfontbitmapcache.h"
// Hack. FT_Face is just a typedef for a pointer to a struct,
-// but there's no simple forward declarations file for FreeType,
-// and the main include file is 200K.
+// but there's no simple forward declarations file for FreeType,
+// and the main include file is 200K.
// We'll forward declare the struct here. JC
struct FT_FaceRec_;
typedef struct FT_FaceRec_* LLFT_Face;
@@ -46,34 +46,34 @@ typedef struct FT_StreamRec_ LLFT_Stream;
class LLFontManager
{
public:
- static void initClass();
- static void cleanupClass();
+ static void initClass();
+ static void cleanupClass();
private:
- LLFontManager();
- ~LLFontManager();
+ LLFontManager();
+ ~LLFontManager();
};
struct LLFontGlyphInfo
{
- LLFontGlyphInfo(U32 index, EFontGlyphType glyph_type);
- LLFontGlyphInfo(const LLFontGlyphInfo& fgi);
-
- U32 mGlyphIndex;
- EFontGlyphType mGlyphType;
-
- // Metrics
- S32 mWidth; // In pixels
- S32 mHeight; // In pixels
- F32 mXAdvance; // In pixels
- F32 mYAdvance; // In pixels
-
- // Information for actually rendering
- S32 mXBitmapOffset; // Offset to the origin in the bitmap
- S32 mYBitmapOffset; // Offset to the origin in the bitmap
- S32 mXBearing; // Distance from baseline to left in pixels
- S32 mYBearing; // Distance from baseline to top in pixels
- std::pair<EFontGlyphType, S32> mBitmapEntry; // Which bitmap in the bitmap cache contains this glyph
+ LLFontGlyphInfo(U32 index, EFontGlyphType glyph_type);
+ LLFontGlyphInfo(const LLFontGlyphInfo& fgi);
+
+ U32 mGlyphIndex;
+ EFontGlyphType mGlyphType;
+
+ // Metrics
+ S32 mWidth; // In pixels
+ S32 mHeight; // In pixels
+ F32 mXAdvance; // In pixels
+ F32 mYAdvance; // In pixels
+
+ // Information for actually rendering
+ S32 mXBitmapOffset; // Offset to the origin in the bitmap
+ S32 mYBitmapOffset; // Offset to the origin in the bitmap
+ S32 mXBearing; // Distance from baseline to left in pixels
+ S32 mYBearing; // Distance from baseline to top in pixels
+ std::pair<EFontGlyphType, S32> mBitmapEntry; // Which bitmap in the bitmap cache contains this glyph
};
extern LLFontManager *gFontManagerp;
@@ -81,113 +81,113 @@ extern LLFontManager *gFontManagerp;
class LLFontFreetype : public LLRefCount
{
public:
- LLFontFreetype();
- ~LLFontFreetype();
+ LLFontFreetype();
+ ~LLFontFreetype();
- // is_fallback should be true for fallback fonts that aren't used
- // to render directly (Unicode backup, primarily)
- BOOL loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, bool is_fallback, S32 face_n);
+ // is_fallback should be true for fallback fonts that aren't used
+ // to render directly (Unicode backup, primarily)
+ BOOL loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, bool is_fallback, S32 face_n);
- S32 getNumFaces(const std::string& filename);
+ S32 getNumFaces(const std::string& filename);
#ifdef LL_WINDOWS
- S32 ftOpenFace(const std::string& filename, S32 face_n);
- void clearFontStreams();
+ S32 ftOpenFace(const std::string& filename, S32 face_n);
+ void clearFontStreams();
#endif
- typedef std::function<bool(llwchar)> char_functor_t;
- void addFallbackFont(const LLPointer<LLFontFreetype>& fallback_font, const char_functor_t& functor = nullptr);
+ typedef std::function<bool(llwchar)> char_functor_t;
+ void addFallbackFont(const LLPointer<LLFontFreetype>& fallback_font, const char_functor_t& functor = nullptr);
- // Global font metrics - in units of pixels
- F32 getLineHeight() const;
- F32 getAscenderHeight() const;
- F32 getDescenderHeight() const;
+ // Global font metrics - in units of pixels
+ F32 getLineHeight() const;
+ F32 getAscenderHeight() const;
+ F32 getDescenderHeight() const;
// For a lowercase "g":
//
-// ------------------------------
-// ^ ^
-// | |
-// xxx x |Ascender
-// x x v |
-// --------- xxxx-------------- Baseline
-// ^ x |
+// ------------------------------
+// ^ ^
+// | |
+// xxx x |Ascender
+// x x v |
+// --------- xxxx-------------- Baseline
+// ^ x |
// | Descender x |
-// v xxxx |LineHeight
+// v xxxx |LineHeight
// ----------------------- |
// v
-// ------------------------------
+// ------------------------------
- enum
- {
- FIRST_CHAR = 32,
- NUM_CHARS = 127 - 32,
- LAST_CHAR_BASIC = 127,
+ enum
+ {
+ FIRST_CHAR = 32,
+ NUM_CHARS = 127 - 32,
+ LAST_CHAR_BASIC = 127,
- // Need full 8-bit ascii range for spanish
- NUM_CHARS_FULL = 255 - 32,
- LAST_CHAR_FULL = 255
- };
+ // Need full 8-bit ascii range for spanish
+ NUM_CHARS_FULL = 255 - 32,
+ LAST_CHAR_FULL = 255
+ };
- F32 getXAdvance(llwchar wc) const;
- F32 getXAdvance(const LLFontGlyphInfo* glyph) const;
- F32 getXKerning(llwchar char_left, llwchar char_right) const; // Get the kerning between the two characters
- F32 getXKerning(const LLFontGlyphInfo* left_glyph_info, const LLFontGlyphInfo* right_glyph_info) const; // Get the kerning between the two characters
+ F32 getXAdvance(llwchar wc) const;
+ F32 getXAdvance(const LLFontGlyphInfo* glyph) const;
+ F32 getXKerning(llwchar char_left, llwchar char_right) const; // Get the kerning between the two characters
+ F32 getXKerning(const LLFontGlyphInfo* left_glyph_info, const LLFontGlyphInfo* right_glyph_info) const; // Get the kerning between the two characters
- LLFontGlyphInfo* getGlyphInfo(llwchar wch, EFontGlyphType glyph_type) const;
+ LLFontGlyphInfo* getGlyphInfo(llwchar wch, EFontGlyphType glyph_type) const;
- void reset(F32 vert_dpi, F32 horz_dpi);
+ void reset(F32 vert_dpi, F32 horz_dpi);
- void destroyGL();
+ void destroyGL();
- const std::string& getName() const;
+ const std::string& getName() const;
- void dumpFontBitmaps() const;
- const LLFontBitmapCache* getFontBitmapCache() const;
+ void dumpFontBitmaps() const;
+ const LLFontBitmapCache* getFontBitmapCache() const;
- void setStyle(U8 style);
- U8 getStyle() const;
+ void setStyle(U8 style);
+ U8 getStyle() const;
private:
- void resetBitmapCache();
- void setSubImageLuminanceAlpha(U32 x, U32 y, U32 bitmap_num, U32 width, U32 height, U8 *data, S32 stride = 0) const;
- bool setSubImageBGRA(U32 x, U32 y, U32 bitmap_num, U16 width, U16 height, const U8* data, U32 stride) const;
- BOOL hasGlyph(llwchar wch) const; // Has a glyph for this character
- LLFontGlyphInfo* addGlyph(llwchar wch, EFontGlyphType glyph_type) const; // Add a new character to the font if necessary
- LLFontGlyphInfo* addGlyphFromFont(const LLFontFreetype *fontp, llwchar wch, U32 glyph_index, EFontGlyphType bitmap_type) const; // Add a glyph from this font to the other (returns the glyph_index, 0 if not found)
- void renderGlyph(EFontGlyphType bitmap_type, U32 glyph_index) const;
- void insertGlyphInfo(llwchar wch, LLFontGlyphInfo* gi) const;
+ void resetBitmapCache();
+ void setSubImageLuminanceAlpha(U32 x, U32 y, U32 bitmap_num, U32 width, U32 height, U8 *data, S32 stride = 0) const;
+ bool setSubImageBGRA(U32 x, U32 y, U32 bitmap_num, U16 width, U16 height, const U8* data, U32 stride) const;
+ BOOL hasGlyph(llwchar wch) const; // Has a glyph for this character
+ LLFontGlyphInfo* addGlyph(llwchar wch, EFontGlyphType glyph_type) const; // Add a new character to the font if necessary
+ LLFontGlyphInfo* addGlyphFromFont(const LLFontFreetype *fontp, llwchar wch, U32 glyph_index, EFontGlyphType bitmap_type) const; // Add a glyph from this font to the other (returns the glyph_index, 0 if not found)
+ void renderGlyph(EFontGlyphType bitmap_type, U32 glyph_index) const;
+ void insertGlyphInfo(llwchar wch, LLFontGlyphInfo* gi) const;
- std::string mName;
+ std::string mName;
- U8 mStyle;
+ U8 mStyle;
- F32 mPointSize;
- F32 mAscender;
- F32 mDescender;
- F32 mLineHeight;
+ F32 mPointSize;
+ F32 mAscender;
+ F32 mDescender;
+ F32 mLineHeight;
- LLFT_Face mFTFace;
+ LLFT_Face mFTFace;
#ifdef LL_WINDOWS
- llifstream *pFileStream;
- LLFT_Stream *pFtStream;
+ llifstream *pFileStream;
+ LLFT_Stream *pFtStream;
#endif
- BOOL mIsFallback;
- typedef std::pair<LLPointer<LLFontFreetype>, char_functor_t> fallback_font_t;
- typedef std::vector<fallback_font_t> fallback_font_vector_t;
- fallback_font_vector_t mFallbackFonts; // A list of fallback fonts to look for glyphs in (for Unicode chars)
+ BOOL mIsFallback;
+ typedef std::pair<LLPointer<LLFontFreetype>, char_functor_t> fallback_font_t;
+ typedef std::vector<fallback_font_t> fallback_font_vector_t;
+ fallback_font_vector_t mFallbackFonts; // A list of fallback fonts to look for glyphs in (for Unicode chars)
- // *NOTE: the same glyph can be present with multiple representations (but the pointer is always unique)
- typedef boost::unordered_multimap<llwchar, LLFontGlyphInfo*> char_glyph_info_map_t;
- mutable char_glyph_info_map_t mCharGlyphInfoMap; // Information about glyph location in bitmap
+ // *NOTE: the same glyph can be present with multiple representations (but the pointer is always unique)
+ typedef boost::unordered_multimap<llwchar, LLFontGlyphInfo*> char_glyph_info_map_t;
+ mutable char_glyph_info_map_t mCharGlyphInfoMap; // Information about glyph location in bitmap
- mutable LLFontBitmapCache* mFontBitmapCachep;
+ mutable LLFontBitmapCache* mFontBitmapCachep;
- mutable S32 mRenderGlyphCount;
- mutable S32 mAddGlyphCount;
+ mutable S32 mRenderGlyphCount;
+ mutable S32 mAddGlyphCount;
};
#endif // LL_FONTFREETYPE_H
diff --git a/indra/llrender/llfontfreetypesvg.cpp b/indra/llrender/llfontfreetypesvg.cpp
index 19d327a4c9..355e8432aa 100644
--- a/indra/llrender/llfontfreetypesvg.cpp
+++ b/indra/llrender/llfontfreetypesvg.cpp
@@ -44,21 +44,21 @@
struct LLSvgRenderData
{
- FT_UInt GlyphIndex = 0;
- FT_Error Error = FT_Err_Ok; // FreeType currently (@2.12.1) ignores the error value returned by the preset glyph slot callback so we return it at render time
- // (See https://github.com/freetype/freetype/blob/5faa1df8b93ebecf0f8fd5fe8fda7b9082eddced/src/base/ftobjs.c#L1170)
- NSVGimage* pNSvgImage = nullptr;
- float Scale = 0.f;
+ FT_UInt GlyphIndex = 0;
+ FT_Error Error = FT_Err_Ok; // FreeType currently (@2.12.1) ignores the error value returned by the preset glyph slot callback so we return it at render time
+ // (See https://github.com/freetype/freetype/blob/5faa1df8b93ebecf0f8fd5fe8fda7b9082eddced/src/base/ftobjs.c#L1170)
+ NSVGimage* pNSvgImage = nullptr;
+ float Scale = 0.f;
};
// static
FT_Error LLFontFreeTypeSvgRenderer::OnInit(FT_Pointer* state)
{
- // The SVG driver hook state is shared across all callback invocations; since our state is lightweight
- // we store it in the glyph instead.
- *state = nullptr;
+ // The SVG driver hook state is shared across all callback invocations; since our state is lightweight
+ // we store it in the glyph instead.
+ *state = nullptr;
- return FT_Err_Ok;
+ return FT_Err_Ok;
}
// static
@@ -69,137 +69,137 @@ void LLFontFreeTypeSvgRenderer::OnFree(FT_Pointer* state)
// static
void LLFontFreeTypeSvgRenderer::OnDataFinalizer(void* objectp)
{
- FT_GlyphSlot glyph_slot = static_cast<FT_GlyphSlot>(objectp);
+ FT_GlyphSlot glyph_slot = static_cast<FT_GlyphSlot>(objectp);
- LLSvgRenderData* pData = static_cast<LLSvgRenderData*>(glyph_slot->generic.data);
- glyph_slot->generic.data = nullptr;
- glyph_slot->generic.finalizer = nullptr;
- delete(pData);
+ LLSvgRenderData* pData = static_cast<LLSvgRenderData*>(glyph_slot->generic.data);
+ glyph_slot->generic.data = nullptr;
+ glyph_slot->generic.finalizer = nullptr;
+ delete(pData);
}
//static
FT_Error LLFontFreeTypeSvgRenderer::OnPresetGlypthSlot(FT_GlyphSlot glyph_slot, FT_Bool cache, FT_Pointer*)
{
- FT_SVG_Document document = static_cast<FT_SVG_Document>(glyph_slot->other);
-
- llassert(!glyph_slot->generic.data || !cache || glyph_slot->glyph_index == ((LLSvgRenderData*)glyph_slot->generic.data)->GlyphIndex);
- if (!glyph_slot->generic.data)
- {
- glyph_slot->generic.data = new LLSvgRenderData();
- glyph_slot->generic.finalizer = LLFontFreeTypeSvgRenderer::OnDataFinalizer;
- }
- LLSvgRenderData* datap = static_cast<LLSvgRenderData*>(glyph_slot->generic.data);
- if (!cache)
- {
- datap->GlyphIndex = glyph_slot->glyph_index;
- datap->Error = FT_Err_Ok;
- }
-
- // NOTE: nsvgParse modifies the input string so we need a temporary copy
- llassert(!datap->pNSvgImage || cache);
- if (!datap->pNSvgImage)
- {
- char* document_buffer = new char[document->svg_document_length + 1];
- memcpy(document_buffer, document->svg_document, document->svg_document_length);
- document_buffer[document->svg_document_length] = '\0';
-
- datap->pNSvgImage = nsvgParse(document_buffer, "px", 0.);
-
- delete[] document_buffer;
- }
-
- if (!datap->pNSvgImage)
- {
- datap->Error = FT_Err_Invalid_SVG_Document;
- return FT_Err_Invalid_SVG_Document;
- }
-
- // We don't (currently) support transformations so test for an identity rotation matrix + zero translation
- if (document->transform.xx != 1 << 16 || document->transform.yx != 0 ||
- document->transform.xy != 0 || document->transform.yy != 1 << 16 ||
- document->delta.x > 0 || document->delta.y > 0)
- {
- datap->Error = FT_Err_Unimplemented_Feature;
- return FT_Err_Unimplemented_Feature;
- }
-
- float svg_width = datap->pNSvgImage->width;
- float svg_height = datap->pNSvgImage->height;
- if (svg_width == 0.f || svg_height == 0.f)
- {
- svg_width = document->units_per_EM;
- svg_height = document->units_per_EM;
- }
-
- float svg_x_scale = (float)document->metrics.x_ppem / floorf(svg_width);
- float svg_y_scale = (float)document->metrics.y_ppem / floorf(svg_height);
- float svg_scale = llmin(svg_x_scale, svg_y_scale);
- datap->Scale = svg_scale;
-
- glyph_slot->bitmap.width = floorf(svg_width) * svg_scale;
- glyph_slot->bitmap.rows = floorf(svg_height) * svg_scale;
- glyph_slot->bitmap_left = (document->metrics.x_ppem - glyph_slot->bitmap.width) / 2;
- glyph_slot->bitmap_top = glyph_slot->face->size->metrics.ascender / 64.f;
- glyph_slot->bitmap.pitch = glyph_slot->bitmap.width * 4;
- glyph_slot->bitmap.pixel_mode = FT_PIXEL_MODE_BGRA;
-
- /* Copied as-is from fcft (MIT license) */
-
- // Compute all the bearings and set them correctly. The outline is scaled already, we just need to use the bounding box.
- float horiBearingX = 0.;
- float horiBearingY = -glyph_slot->bitmap_top;
-
- // XXX parentheses correct?
- float vertBearingX = glyph_slot->metrics.horiBearingX / 64.0f - glyph_slot->metrics.horiAdvance / 64.0f / 2;
- float vertBearingY = (glyph_slot->metrics.vertAdvance / 64.0f - glyph_slot->metrics.height / 64.0f) / 2;
-
- // Do conversion in two steps to avoid 'bad function cast' warning
- glyph_slot->metrics.width = glyph_slot->bitmap.width * 64;
- glyph_slot->metrics.height = glyph_slot->bitmap.rows * 64;
- glyph_slot->metrics.horiBearingX = horiBearingX * 64;
- glyph_slot->metrics.horiBearingY = horiBearingY * 64;
- glyph_slot->metrics.vertBearingX = vertBearingX * 64;
- glyph_slot->metrics.vertBearingY = vertBearingY * 64;
- if (glyph_slot->metrics.vertAdvance == 0)
- {
- glyph_slot->metrics.vertAdvance = glyph_slot->bitmap.rows * 1.2f * 64;
- }
-
- return FT_Err_Ok;
+ FT_SVG_Document document = static_cast<FT_SVG_Document>(glyph_slot->other);
+
+ llassert(!glyph_slot->generic.data || !cache || glyph_slot->glyph_index == ((LLSvgRenderData*)glyph_slot->generic.data)->GlyphIndex);
+ if (!glyph_slot->generic.data)
+ {
+ glyph_slot->generic.data = new LLSvgRenderData();
+ glyph_slot->generic.finalizer = LLFontFreeTypeSvgRenderer::OnDataFinalizer;
+ }
+ LLSvgRenderData* datap = static_cast<LLSvgRenderData*>(glyph_slot->generic.data);
+ if (!cache)
+ {
+ datap->GlyphIndex = glyph_slot->glyph_index;
+ datap->Error = FT_Err_Ok;
+ }
+
+ // NOTE: nsvgParse modifies the input string so we need a temporary copy
+ llassert(!datap->pNSvgImage || cache);
+ if (!datap->pNSvgImage)
+ {
+ char* document_buffer = new char[document->svg_document_length + 1];
+ memcpy(document_buffer, document->svg_document, document->svg_document_length);
+ document_buffer[document->svg_document_length] = '\0';
+
+ datap->pNSvgImage = nsvgParse(document_buffer, "px", 0.);
+
+ delete[] document_buffer;
+ }
+
+ if (!datap->pNSvgImage)
+ {
+ datap->Error = FT_Err_Invalid_SVG_Document;
+ return FT_Err_Invalid_SVG_Document;
+ }
+
+ // We don't (currently) support transformations so test for an identity rotation matrix + zero translation
+ if (document->transform.xx != 1 << 16 || document->transform.yx != 0 ||
+ document->transform.xy != 0 || document->transform.yy != 1 << 16 ||
+ document->delta.x > 0 || document->delta.y > 0)
+ {
+ datap->Error = FT_Err_Unimplemented_Feature;
+ return FT_Err_Unimplemented_Feature;
+ }
+
+ float svg_width = datap->pNSvgImage->width;
+ float svg_height = datap->pNSvgImage->height;
+ if (svg_width == 0.f || svg_height == 0.f)
+ {
+ svg_width = document->units_per_EM;
+ svg_height = document->units_per_EM;
+ }
+
+ float svg_x_scale = (float)document->metrics.x_ppem / floorf(svg_width);
+ float svg_y_scale = (float)document->metrics.y_ppem / floorf(svg_height);
+ float svg_scale = llmin(svg_x_scale, svg_y_scale);
+ datap->Scale = svg_scale;
+
+ glyph_slot->bitmap.width = floorf(svg_width) * svg_scale;
+ glyph_slot->bitmap.rows = floorf(svg_height) * svg_scale;
+ glyph_slot->bitmap_left = (document->metrics.x_ppem - glyph_slot->bitmap.width) / 2;
+ glyph_slot->bitmap_top = glyph_slot->face->size->metrics.ascender / 64.f;
+ glyph_slot->bitmap.pitch = glyph_slot->bitmap.width * 4;
+ glyph_slot->bitmap.pixel_mode = FT_PIXEL_MODE_BGRA;
+
+ /* Copied as-is from fcft (MIT license) */
+
+ // Compute all the bearings and set them correctly. The outline is scaled already, we just need to use the bounding box.
+ float horiBearingX = 0.;
+ float horiBearingY = -glyph_slot->bitmap_top;
+
+ // XXX parentheses correct?
+ float vertBearingX = glyph_slot->metrics.horiBearingX / 64.0f - glyph_slot->metrics.horiAdvance / 64.0f / 2;
+ float vertBearingY = (glyph_slot->metrics.vertAdvance / 64.0f - glyph_slot->metrics.height / 64.0f) / 2;
+
+ // Do conversion in two steps to avoid 'bad function cast' warning
+ glyph_slot->metrics.width = glyph_slot->bitmap.width * 64;
+ glyph_slot->metrics.height = glyph_slot->bitmap.rows * 64;
+ glyph_slot->metrics.horiBearingX = horiBearingX * 64;
+ glyph_slot->metrics.horiBearingY = horiBearingY * 64;
+ glyph_slot->metrics.vertBearingX = vertBearingX * 64;
+ glyph_slot->metrics.vertBearingY = vertBearingY * 64;
+ if (glyph_slot->metrics.vertAdvance == 0)
+ {
+ glyph_slot->metrics.vertAdvance = glyph_slot->bitmap.rows * 1.2f * 64;
+ }
+
+ return FT_Err_Ok;
}
// static
FT_Error LLFontFreeTypeSvgRenderer::OnRender(FT_GlyphSlot glyph_slot, FT_Pointer*)
{
- LLSvgRenderData* datap = static_cast<LLSvgRenderData*>(glyph_slot->generic.data);
- llassert(FT_Err_Ok == datap->Error);
- if (FT_Err_Ok != datap->Error)
- {
- return datap->Error;
- }
-
- // Render to glyph bitmap
- NSVGrasterizer* nsvgRasterizer = nsvgCreateRasterizer();
- nsvgRasterize(nsvgRasterizer, datap->pNSvgImage, 0, 0, datap->Scale, glyph_slot->bitmap.buffer, glyph_slot->bitmap.width, glyph_slot->bitmap.rows, glyph_slot->bitmap.pitch);
- nsvgDeleteRasterizer(nsvgRasterizer);
- nsvgDelete(datap->pNSvgImage);
- datap->pNSvgImage = nullptr;
-
- // Convert from RGBA to BGRA
- U32* pixel_buffer = (U32*)glyph_slot->bitmap.buffer; U8* byte_buffer = glyph_slot->bitmap.buffer;
- for (size_t y = 0, h = glyph_slot->bitmap.rows; y < h; y++)
- {
- for (size_t x = 0, w = glyph_slot->bitmap.pitch / 4; x < w; x++)
- {
- size_t pixel_idx = y * w + x;
- size_t byte_idx = pixel_idx * 4;
- U8 alpha = byte_buffer[byte_idx + 3];
- // Store as ARGB (*TODO - do we still have to care about endianness?)
- pixel_buffer[y * w + x] = alpha << 24 | (byte_buffer[byte_idx] * alpha / 0xFF) << 16 | (byte_buffer[byte_idx + 1] * alpha / 0xFF) << 8 | (byte_buffer[byte_idx + 2] * alpha / 0xFF);
- }
- }
-
- glyph_slot->format = FT_GLYPH_FORMAT_BITMAP;
- glyph_slot->bitmap.pixel_mode = FT_PIXEL_MODE_BGRA;
- return FT_Err_Ok;
+ LLSvgRenderData* datap = static_cast<LLSvgRenderData*>(glyph_slot->generic.data);
+ llassert(FT_Err_Ok == datap->Error);
+ if (FT_Err_Ok != datap->Error)
+ {
+ return datap->Error;
+ }
+
+ // Render to glyph bitmap
+ NSVGrasterizer* nsvgRasterizer = nsvgCreateRasterizer();
+ nsvgRasterize(nsvgRasterizer, datap->pNSvgImage, 0, 0, datap->Scale, glyph_slot->bitmap.buffer, glyph_slot->bitmap.width, glyph_slot->bitmap.rows, glyph_slot->bitmap.pitch);
+ nsvgDeleteRasterizer(nsvgRasterizer);
+ nsvgDelete(datap->pNSvgImage);
+ datap->pNSvgImage = nullptr;
+
+ // Convert from RGBA to BGRA
+ U32* pixel_buffer = (U32*)glyph_slot->bitmap.buffer; U8* byte_buffer = glyph_slot->bitmap.buffer;
+ for (size_t y = 0, h = glyph_slot->bitmap.rows; y < h; y++)
+ {
+ for (size_t x = 0, w = glyph_slot->bitmap.pitch / 4; x < w; x++)
+ {
+ size_t pixel_idx = y * w + x;
+ size_t byte_idx = pixel_idx * 4;
+ U8 alpha = byte_buffer[byte_idx + 3];
+ // Store as ARGB (*TODO - do we still have to care about endianness?)
+ pixel_buffer[y * w + x] = alpha << 24 | (byte_buffer[byte_idx] * alpha / 0xFF) << 16 | (byte_buffer[byte_idx + 1] * alpha / 0xFF) << 8 | (byte_buffer[byte_idx + 2] * alpha / 0xFF);
+ }
+ }
+
+ glyph_slot->format = FT_GLYPH_FORMAT_BITMAP;
+ glyph_slot->bitmap.pixel_mode = FT_PIXEL_MODE_BGRA;
+ return FT_Err_Ok;
}
diff --git a/indra/llrender/llfontfreetypesvg.h b/indra/llrender/llfontfreetypesvg.h
index b5f541991a..72ac5293ce 100644
--- a/indra/llrender/llfontfreetypesvg.h
+++ b/indra/llrender/llfontfreetypesvg.h
@@ -35,20 +35,20 @@
class LLFontFreeTypeSvgRenderer
{
public:
- // Called when the very first OT-SVG glyph is rendered (across the entire lifetime of our FT_Library object)
- static FT_Error OnInit(FT_Pointer* state);
+ // Called when the very first OT-SVG glyph is rendered (across the entire lifetime of our FT_Library object)
+ static FT_Error OnInit(FT_Pointer* state);
- // Called when the ot-svg module is being freed (but only called if the init hook was called previously)
- static void OnFree(FT_Pointer* state);
+ // Called when the ot-svg module is being freed (but only called if the init hook was called previously)
+ static void OnFree(FT_Pointer* state);
- // Called to preset the glyph slot, twice per glyph:
- // - when FT_Load_Glyph needs to preset the glyph slot (with cache == false)
- // - right before the svg module calls the render callback hook. (with cache == true)
- static FT_Error OnPresetGlypthSlot(FT_GlyphSlot glyph_slot, FT_Bool cache, FT_Pointer* state);
+ // Called to preset the glyph slot, twice per glyph:
+ // - when FT_Load_Glyph needs to preset the glyph slot (with cache == false)
+ // - right before the svg module calls the render callback hook. (with cache == true)
+ static FT_Error OnPresetGlypthSlot(FT_GlyphSlot glyph_slot, FT_Bool cache, FT_Pointer* state);
- // Called to render an OT-SVG glyph (right after the preset hook OnPresetGlypthSlot was called with cache set to TRUE)
- static FT_Error OnRender(FT_GlyphSlot glyph_slot, FT_Pointer* state);
+ // Called to render an OT-SVG glyph (right after the preset hook OnPresetGlypthSlot was called with cache set to TRUE)
+ static FT_Error OnRender(FT_GlyphSlot glyph_slot, FT_Pointer* state);
- // Called to deallocate our per glyph slot data
- static void OnDataFinalizer(void* objectp);
+ // Called to deallocate our per glyph slot data
+ static void OnDataFinalizer(void* objectp);
};
diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp
index 53661b6a63..8d0fed7829 100644
--- a/indra/llrender/llfontgl.cpp
+++ b/indra/llrender/llfontgl.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llfontgl.cpp
* @brief Wrapper around FreeType
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -81,32 +81,32 @@ LLFontGL::~LLFontGL()
void LLFontGL::reset()
{
- mFontFreetype->reset(sVertDPI, sHorizDPI);
+ mFontFreetype->reset(sVertDPI, sHorizDPI);
}
void LLFontGL::destroyGL()
{
- mFontFreetype->destroyGL();
+ mFontFreetype->destroyGL();
}
BOOL LLFontGL::loadFace(const std::string& filename, F32 point_size, const F32 vert_dpi, const F32 horz_dpi, bool is_fallback, S32 face_n)
{
- if(mFontFreetype == reinterpret_cast<LLFontFreetype*>(NULL))
- {
- mFontFreetype = new LLFontFreetype;
- }
+ if(mFontFreetype == reinterpret_cast<LLFontFreetype*>(NULL))
+ {
+ mFontFreetype = new LLFontFreetype;
+ }
- return mFontFreetype->loadFace(filename, point_size, vert_dpi, horz_dpi, is_fallback, face_n);
+ return mFontFreetype->loadFace(filename, point_size, vert_dpi, horz_dpi, is_fallback, face_n);
}
S32 LLFontGL::getNumFaces(const std::string& filename)
{
- if (mFontFreetype == reinterpret_cast<LLFontFreetype*>(NULL))
- {
- mFontFreetype = new LLFontFreetype;
- }
+ if (mFontFreetype == reinterpret_cast<LLFontFreetype*>(NULL))
+ {
+ mFontFreetype = new LLFontFreetype;
+ }
- return mFontFreetype->getNumFaces(filename);
+ return mFontFreetype->getNumFaces(filename);
}
S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, const LLRect& rect, const LLColor4 &color, HAlign halign, VAlign valign, U8 style,
@@ -116,439 +116,439 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, const LLRect& rect
return render(wstr, begin_offset, rect_float, color, halign, valign, style, shadow, max_chars, right_x, use_ellipses, use_color);
}
-S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, const LLRectf& rect, const LLColor4 &color, HAlign halign, VAlign valign, U8 style,
- ShadowType shadow, S32 max_chars, F32* right_x, BOOL use_ellipses, BOOL use_color) const
+S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, const LLRectf& rect, const LLColor4 &color, HAlign halign, VAlign valign, U8 style,
+ ShadowType shadow, S32 max_chars, F32* right_x, BOOL use_ellipses, BOOL use_color) const
{
- F32 x = rect.mLeft;
- F32 y = 0.f;
+ F32 x = rect.mLeft;
+ F32 y = 0.f;
- switch(valign)
- {
- case TOP:
- y = rect.mTop;
- break;
- case VCENTER:
- y = rect.getCenterY();
- break;
- case BASELINE:
- case BOTTOM:
- y = rect.mBottom;
- break;
- default:
- y = rect.mBottom;
- break;
- }
- return render(wstr, begin_offset, x, y, color, halign, valign, style, shadow, max_chars, rect.getWidth(), right_x, use_ellipses, use_color);
+ switch(valign)
+ {
+ case TOP:
+ y = rect.mTop;
+ break;
+ case VCENTER:
+ y = rect.getCenterY();
+ break;
+ case BASELINE:
+ case BOTTOM:
+ y = rect.mBottom;
+ break;
+ default:
+ y = rect.mBottom;
+ break;
+ }
+ return render(wstr, begin_offset, x, y, color, halign, valign, style, shadow, max_chars, rect.getWidth(), right_x, use_ellipses, use_color);
}
-S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style,
- ShadowType shadow, S32 max_chars, S32 max_pixels, F32* right_x, BOOL use_ellipses, BOOL use_color) const
+S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style,
+ ShadowType shadow, S32 max_chars, S32 max_pixels, F32* right_x, BOOL use_ellipses, BOOL use_color) const
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
- if(!sDisplayFont) //do not display texts
- {
- return wstr.length() ;
- }
-
- if (wstr.empty())
- {
- return 0;
- }
-
- gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
-
- S32 scaled_max_pixels = max_pixels == S32_MAX ? S32_MAX : llceil((F32)max_pixels * sScaleX);
-
- // determine which style flags need to be added programmatically by stripping off the
- // style bits that are drawn by the underlying Freetype font
- U8 style_to_add = (style | mFontDescriptor.getStyle()) & ~mFontFreetype->getStyle();
-
- F32 drop_shadow_strength = 0.f;
- if (shadow != NO_SHADOW)
- {
- F32 luminance;
- color.calcHSL(NULL, NULL, &luminance);
- drop_shadow_strength = clamp_rescale(luminance, 0.35f, 0.6f, 0.f, 1.f);
- if (luminance < 0.35f)
- {
- shadow = NO_SHADOW;
- }
- }
-
- gGL.pushUIMatrix();
-
- gGL.loadUIIdentity();
-
- LLVector2 origin(floorf(sCurOrigin.mX*sScaleX), floorf(sCurOrigin.mY*sScaleY));
-
- // Depth translation, so that floating text appears 'in-world'
- // and is correctly occluded.
- gGL.translatef(0.f,0.f,sCurDepth);
-
- S32 chars_drawn = 0;
- S32 i;
- S32 length;
-
- if (-1 == max_chars)
- {
- max_chars = length = (S32)wstr.length() - begin_offset;
- }
- else
- {
- length = llmin((S32)wstr.length() - begin_offset, max_chars );
- }
-
- F32 cur_x, cur_y, cur_render_x, cur_render_y;
-
- // Not guaranteed to be set correctly
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
-
- cur_x = ((F32)x * sScaleX) + origin.mV[VX];
- cur_y = ((F32)y * sScaleY) + origin.mV[VY];
-
- // Offset y by vertical alignment.
- // use unscaled font metrics here
- switch (valign)
- {
- case TOP:
- cur_y -= llceil(mFontFreetype->getAscenderHeight());
- break;
- case BOTTOM:
- cur_y += llceil(mFontFreetype->getDescenderHeight());
- break;
- case VCENTER:
- cur_y -= llceil((llceil(mFontFreetype->getAscenderHeight()) - llceil(mFontFreetype->getDescenderHeight())) / 2.f);
- break;
- case BASELINE:
- // Baseline, do nothing.
- break;
- default:
- break;
- }
-
- switch (halign)
- {
- case LEFT:
- break;
- case RIGHT:
- cur_x -= llmin(scaled_max_pixels, ll_round(getWidthF32(wstr.c_str(), begin_offset, length) * sScaleX));
- break;
- case HCENTER:
- cur_x -= llmin(scaled_max_pixels, ll_round(getWidthF32(wstr.c_str(), begin_offset, length) * sScaleX)) / 2;
- break;
- default:
- break;
- }
-
- cur_render_y = cur_y;
- cur_render_x = cur_x;
-
- F32 start_x = (F32)ll_round(cur_x);
-
- const LLFontBitmapCache* font_bitmap_cache = mFontFreetype->getFontBitmapCache();
-
- F32 inv_width = 1.f / font_bitmap_cache->getBitmapWidth();
- F32 inv_height = 1.f / font_bitmap_cache->getBitmapHeight();
-
- const S32 LAST_CHARACTER = LLFontFreetype::LAST_CHAR_FULL;
-
- BOOL draw_ellipses = FALSE;
- if (use_ellipses)
- {
- // check for too long of a string
- S32 string_width = ll_round(getWidthF32(wstr.c_str(), begin_offset, max_chars) * sScaleX);
- if (string_width > scaled_max_pixels)
- {
- // use four dots for ellipsis width to generate padding
- const LLWString dots(utf8str_to_wstring(std::string("....")));
- scaled_max_pixels = llmax(0, scaled_max_pixels - ll_round(getWidthF32(dots.c_str())));
- draw_ellipses = TRUE;
- }
- }
-
- const LLFontGlyphInfo* next_glyph = NULL;
-
- const S32 GLYPH_BATCH_SIZE = 30;
- LLVector3 vertices[GLYPH_BATCH_SIZE * 4];
- LLVector2 uvs[GLYPH_BATCH_SIZE * 4];
- LLColor4U colors[GLYPH_BATCH_SIZE * 4];
-
- LLColor4U text_color(color);
-
- std::pair<EFontGlyphType, S32> bitmap_entry = std::make_pair(EFontGlyphType::Grayscale, -1);
- S32 glyph_count = 0;
- for (i = begin_offset; i < begin_offset + length; i++)
- {
- llwchar wch = wstr[i];
-
- const LLFontGlyphInfo* fgi = next_glyph;
- next_glyph = NULL;
- if(!fgi)
- {
- fgi = mFontFreetype->getGlyphInfo(wch, (!use_color) ? EFontGlyphType::Grayscale : EFontGlyphType::Color);
- }
- if (!fgi)
- {
- LL_ERRS() << "Missing Glyph Info" << LL_ENDL;
- break;
- }
- // Per-glyph bitmap texture.
- std::pair<EFontGlyphType, S32> next_bitmap_entry = fgi->mBitmapEntry;
- if (next_bitmap_entry != bitmap_entry)
- {
- // Actually draw the queued glyphs before switching their texture;
- // otherwise the queued glyphs will be taken from wrong textures.
- if (glyph_count > 0)
- {
- gGL.begin(LLRender::QUADS);
- {
- gGL.vertexBatchPreTransformed(vertices, uvs, colors, glyph_count * 4);
- }
- gGL.end();
- glyph_count = 0;
- }
-
- bitmap_entry = next_bitmap_entry;
- LLImageGL* font_image = font_bitmap_cache->getImageGL(bitmap_entry.first, bitmap_entry.second);
- gGL.getTexUnit(0)->bind(font_image);
- }
-
- if ((start_x + scaled_max_pixels) < (cur_x + fgi->mXBearing + fgi->mWidth))
- {
- // Not enough room for this character.
- break;
- }
-
- // Draw the text at the appropriate location
- //Specify vertices and texture coordinates
- LLRectf uv_rect((fgi->mXBitmapOffset) * inv_width,
- (fgi->mYBitmapOffset + fgi->mHeight + PAD_UVY) * inv_height,
- (fgi->mXBitmapOffset + fgi->mWidth) * inv_width,
- (fgi->mYBitmapOffset - PAD_UVY) * inv_height);
- // snap glyph origin to whole screen pixel
- LLRectf screen_rect((F32)ll_round(cur_render_x + (F32)fgi->mXBearing),
- (F32)ll_round(cur_render_y + (F32)fgi->mYBearing),
- (F32)ll_round(cur_render_x + (F32)fgi->mXBearing) + (F32)fgi->mWidth,
- (F32)ll_round(cur_render_y + (F32)fgi->mYBearing) - (F32)fgi->mHeight);
-
- if (glyph_count >= GLYPH_BATCH_SIZE)
- {
- gGL.begin(LLRender::QUADS);
- {
- gGL.vertexBatchPreTransformed(vertices, uvs, colors, glyph_count * 4);
- }
- gGL.end();
-
- glyph_count = 0;
- }
-
- drawGlyph(glyph_count, vertices, uvs, colors, screen_rect, uv_rect, (bitmap_entry.first == EFontGlyphType::Grayscale) ? text_color : LLColor4U::white, style_to_add, shadow, drop_shadow_strength);
-
- chars_drawn++;
- cur_x += fgi->mXAdvance;
- cur_y += fgi->mYAdvance;
-
- llwchar next_char = wstr[i+1];
- if (next_char && (next_char < LAST_CHARACTER))
- {
- // Kern this puppy.
- next_glyph = mFontFreetype->getGlyphInfo(next_char, (!use_color) ? EFontGlyphType::Grayscale : EFontGlyphType::Color);
- cur_x += mFontFreetype->getXKerning(fgi, next_glyph);
- }
-
- // Round after kerning.
- // Must do this to cur_x, not just to cur_render_x, otherwise you
- // will squish sub-pixel kerned characters too close together.
- // For example, "CCCCC" looks bad.
- cur_x = (F32)ll_round(cur_x);
- //cur_y = (F32)ll_round(cur_y);
-
- cur_render_x = cur_x;
- cur_render_y = cur_y;
- }
-
- gGL.begin(LLRender::QUADS);
- {
- gGL.vertexBatchPreTransformed(vertices, uvs, colors, glyph_count * 4);
- }
- gGL.end();
-
-
- if (right_x)
- {
- *right_x = (cur_x - origin.mV[VX]) / sScaleX;
- }
-
- //FIXME: add underline as glyph?
- if (style_to_add & UNDERLINE)
- {
- F32 descender = (F32)llfloor(mFontFreetype->getDescenderHeight());
-
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.begin(LLRender::LINES);
- gGL.vertex2f(start_x, cur_y - descender);
- gGL.vertex2f(cur_x, cur_y - descender);
- gGL.end();
- }
-
- if (draw_ellipses)
- {
-
- // recursively render ellipses at end of string
- // we've already reserved enough room
- gGL.pushUIMatrix();
- renderUTF8(std::string("..."),
- 0,
- (cur_x - origin.mV[VX]) / sScaleX, (F32)y,
- color,
- LEFT, valign,
- style_to_add,
- shadow,
- S32_MAX, max_pixels,
- right_x,
- FALSE,
- use_color);
- gGL.popUIMatrix();
- }
-
- gGL.popUIMatrix();
-
- return chars_drawn;
+ if(!sDisplayFont) //do not display texts
+ {
+ return wstr.length() ;
+ }
+
+ if (wstr.empty())
+ {
+ return 0;
+ }
+
+ gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
+
+ S32 scaled_max_pixels = max_pixels == S32_MAX ? S32_MAX : llceil((F32)max_pixels * sScaleX);
+
+ // determine which style flags need to be added programmatically by stripping off the
+ // style bits that are drawn by the underlying Freetype font
+ U8 style_to_add = (style | mFontDescriptor.getStyle()) & ~mFontFreetype->getStyle();
+
+ F32 drop_shadow_strength = 0.f;
+ if (shadow != NO_SHADOW)
+ {
+ F32 luminance;
+ color.calcHSL(NULL, NULL, &luminance);
+ drop_shadow_strength = clamp_rescale(luminance, 0.35f, 0.6f, 0.f, 1.f);
+ if (luminance < 0.35f)
+ {
+ shadow = NO_SHADOW;
+ }
+ }
+
+ gGL.pushUIMatrix();
+
+ gGL.loadUIIdentity();
+
+ LLVector2 origin(floorf(sCurOrigin.mX*sScaleX), floorf(sCurOrigin.mY*sScaleY));
+
+ // Depth translation, so that floating text appears 'in-world'
+ // and is correctly occluded.
+ gGL.translatef(0.f,0.f,sCurDepth);
+
+ S32 chars_drawn = 0;
+ S32 i;
+ S32 length;
+
+ if (-1 == max_chars)
+ {
+ max_chars = length = (S32)wstr.length() - begin_offset;
+ }
+ else
+ {
+ length = llmin((S32)wstr.length() - begin_offset, max_chars );
+ }
+
+ F32 cur_x, cur_y, cur_render_x, cur_render_y;
+
+ // Not guaranteed to be set correctly
+ gGL.setSceneBlendType(LLRender::BT_ALPHA);
+
+ cur_x = ((F32)x * sScaleX) + origin.mV[VX];
+ cur_y = ((F32)y * sScaleY) + origin.mV[VY];
+
+ // Offset y by vertical alignment.
+ // use unscaled font metrics here
+ switch (valign)
+ {
+ case TOP:
+ cur_y -= llceil(mFontFreetype->getAscenderHeight());
+ break;
+ case BOTTOM:
+ cur_y += llceil(mFontFreetype->getDescenderHeight());
+ break;
+ case VCENTER:
+ cur_y -= llceil((llceil(mFontFreetype->getAscenderHeight()) - llceil(mFontFreetype->getDescenderHeight())) / 2.f);
+ break;
+ case BASELINE:
+ // Baseline, do nothing.
+ break;
+ default:
+ break;
+ }
+
+ switch (halign)
+ {
+ case LEFT:
+ break;
+ case RIGHT:
+ cur_x -= llmin(scaled_max_pixels, ll_round(getWidthF32(wstr.c_str(), begin_offset, length) * sScaleX));
+ break;
+ case HCENTER:
+ cur_x -= llmin(scaled_max_pixels, ll_round(getWidthF32(wstr.c_str(), begin_offset, length) * sScaleX)) / 2;
+ break;
+ default:
+ break;
+ }
+
+ cur_render_y = cur_y;
+ cur_render_x = cur_x;
+
+ F32 start_x = (F32)ll_round(cur_x);
+
+ const LLFontBitmapCache* font_bitmap_cache = mFontFreetype->getFontBitmapCache();
+
+ F32 inv_width = 1.f / font_bitmap_cache->getBitmapWidth();
+ F32 inv_height = 1.f / font_bitmap_cache->getBitmapHeight();
+
+ const S32 LAST_CHARACTER = LLFontFreetype::LAST_CHAR_FULL;
+
+ BOOL draw_ellipses = FALSE;
+ if (use_ellipses)
+ {
+ // check for too long of a string
+ S32 string_width = ll_round(getWidthF32(wstr.c_str(), begin_offset, max_chars) * sScaleX);
+ if (string_width > scaled_max_pixels)
+ {
+ // use four dots for ellipsis width to generate padding
+ const LLWString dots(utf8str_to_wstring(std::string("....")));
+ scaled_max_pixels = llmax(0, scaled_max_pixels - ll_round(getWidthF32(dots.c_str())));
+ draw_ellipses = TRUE;
+ }
+ }
+
+ const LLFontGlyphInfo* next_glyph = NULL;
+
+ const S32 GLYPH_BATCH_SIZE = 30;
+ LLVector3 vertices[GLYPH_BATCH_SIZE * 4];
+ LLVector2 uvs[GLYPH_BATCH_SIZE * 4];
+ LLColor4U colors[GLYPH_BATCH_SIZE * 4];
+
+ LLColor4U text_color(color);
+
+ std::pair<EFontGlyphType, S32> bitmap_entry = std::make_pair(EFontGlyphType::Grayscale, -1);
+ S32 glyph_count = 0;
+ for (i = begin_offset; i < begin_offset + length; i++)
+ {
+ llwchar wch = wstr[i];
+
+ const LLFontGlyphInfo* fgi = next_glyph;
+ next_glyph = NULL;
+ if(!fgi)
+ {
+ fgi = mFontFreetype->getGlyphInfo(wch, (!use_color) ? EFontGlyphType::Grayscale : EFontGlyphType::Color);
+ }
+ if (!fgi)
+ {
+ LL_ERRS() << "Missing Glyph Info" << LL_ENDL;
+ break;
+ }
+ // Per-glyph bitmap texture.
+ std::pair<EFontGlyphType, S32> next_bitmap_entry = fgi->mBitmapEntry;
+ if (next_bitmap_entry != bitmap_entry)
+ {
+ // Actually draw the queued glyphs before switching their texture;
+ // otherwise the queued glyphs will be taken from wrong textures.
+ if (glyph_count > 0)
+ {
+ gGL.begin(LLRender::QUADS);
+ {
+ gGL.vertexBatchPreTransformed(vertices, uvs, colors, glyph_count * 4);
+ }
+ gGL.end();
+ glyph_count = 0;
+ }
+
+ bitmap_entry = next_bitmap_entry;
+ LLImageGL* font_image = font_bitmap_cache->getImageGL(bitmap_entry.first, bitmap_entry.second);
+ gGL.getTexUnit(0)->bind(font_image);
+ }
+
+ if ((start_x + scaled_max_pixels) < (cur_x + fgi->mXBearing + fgi->mWidth))
+ {
+ // Not enough room for this character.
+ break;
+ }
+
+ // Draw the text at the appropriate location
+ //Specify vertices and texture coordinates
+ LLRectf uv_rect((fgi->mXBitmapOffset) * inv_width,
+ (fgi->mYBitmapOffset + fgi->mHeight + PAD_UVY) * inv_height,
+ (fgi->mXBitmapOffset + fgi->mWidth) * inv_width,
+ (fgi->mYBitmapOffset - PAD_UVY) * inv_height);
+ // snap glyph origin to whole screen pixel
+ LLRectf screen_rect((F32)ll_round(cur_render_x + (F32)fgi->mXBearing),
+ (F32)ll_round(cur_render_y + (F32)fgi->mYBearing),
+ (F32)ll_round(cur_render_x + (F32)fgi->mXBearing) + (F32)fgi->mWidth,
+ (F32)ll_round(cur_render_y + (F32)fgi->mYBearing) - (F32)fgi->mHeight);
+
+ if (glyph_count >= GLYPH_BATCH_SIZE)
+ {
+ gGL.begin(LLRender::QUADS);
+ {
+ gGL.vertexBatchPreTransformed(vertices, uvs, colors, glyph_count * 4);
+ }
+ gGL.end();
+
+ glyph_count = 0;
+ }
+
+ drawGlyph(glyph_count, vertices, uvs, colors, screen_rect, uv_rect, (bitmap_entry.first == EFontGlyphType::Grayscale) ? text_color : LLColor4U::white, style_to_add, shadow, drop_shadow_strength);
+
+ chars_drawn++;
+ cur_x += fgi->mXAdvance;
+ cur_y += fgi->mYAdvance;
+
+ llwchar next_char = wstr[i+1];
+ if (next_char && (next_char < LAST_CHARACTER))
+ {
+ // Kern this puppy.
+ next_glyph = mFontFreetype->getGlyphInfo(next_char, (!use_color) ? EFontGlyphType::Grayscale : EFontGlyphType::Color);
+ cur_x += mFontFreetype->getXKerning(fgi, next_glyph);
+ }
+
+ // Round after kerning.
+ // Must do this to cur_x, not just to cur_render_x, otherwise you
+ // will squish sub-pixel kerned characters too close together.
+ // For example, "CCCCC" looks bad.
+ cur_x = (F32)ll_round(cur_x);
+ //cur_y = (F32)ll_round(cur_y);
+
+ cur_render_x = cur_x;
+ cur_render_y = cur_y;
+ }
+
+ gGL.begin(LLRender::QUADS);
+ {
+ gGL.vertexBatchPreTransformed(vertices, uvs, colors, glyph_count * 4);
+ }
+ gGL.end();
+
+
+ if (right_x)
+ {
+ *right_x = (cur_x - origin.mV[VX]) / sScaleX;
+ }
+
+ //FIXME: add underline as glyph?
+ if (style_to_add & UNDERLINE)
+ {
+ F32 descender = (F32)llfloor(mFontFreetype->getDescenderHeight());
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.begin(LLRender::LINES);
+ gGL.vertex2f(start_x, cur_y - descender);
+ gGL.vertex2f(cur_x, cur_y - descender);
+ gGL.end();
+ }
+
+ if (draw_ellipses)
+ {
+
+ // recursively render ellipses at end of string
+ // we've already reserved enough room
+ gGL.pushUIMatrix();
+ renderUTF8(std::string("..."),
+ 0,
+ (cur_x - origin.mV[VX]) / sScaleX, (F32)y,
+ color,
+ LEFT, valign,
+ style_to_add,
+ shadow,
+ S32_MAX, max_pixels,
+ right_x,
+ FALSE,
+ use_color);
+ gGL.popUIMatrix();
+ }
+
+ gGL.popUIMatrix();
+
+ return chars_drawn;
}
S32 LLFontGL::render(const LLWString &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color) const
{
- return render(text, begin_offset, x, y, color, LEFT, BASELINE, NORMAL, NO_SHADOW);
+ return render(text, begin_offset, x, y, color, LEFT, BASELINE, NORMAL, NO_SHADOW);
}
S32 LLFontGL::renderUTF8(const std::string &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style, ShadowType shadow, S32 max_chars, S32 max_pixels, F32* right_x, BOOL use_ellipses, BOOL use_color) const
{
- return render(utf8str_to_wstring(text), begin_offset, x, y, color, halign, valign, style, shadow, max_chars, max_pixels, right_x, use_ellipses, use_color);
+ return render(utf8str_to_wstring(text), begin_offset, x, y, color, halign, valign, style, shadow, max_chars, max_pixels, right_x, use_ellipses, use_color);
}
S32 LLFontGL::renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y, const LLColor4 &color) const
{
- return renderUTF8(text, begin_offset, (F32)x, (F32)y, color, LEFT, BASELINE, NORMAL, NO_SHADOW);
+ return renderUTF8(text, begin_offset, (F32)x, (F32)y, color, LEFT, BASELINE, NORMAL, NO_SHADOW);
}
S32 LLFontGL::renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style, ShadowType shadow) const
{
- return renderUTF8(text, begin_offset, (F32)x, (F32)y, color, halign, valign, style, shadow);
+ return renderUTF8(text, begin_offset, (F32)x, (F32)y, color, halign, valign, style, shadow);
}
// font metrics - override for LLFontFreetype that returns units of virtual pixels
F32 LLFontGL::getAscenderHeight() const
-{
- return mFontFreetype->getAscenderHeight() / sScaleY;
+{
+ return mFontFreetype->getAscenderHeight() / sScaleY;
}
F32 LLFontGL::getDescenderHeight() const
-{
- return mFontFreetype->getDescenderHeight() / sScaleY;
+{
+ return mFontFreetype->getDescenderHeight() / sScaleY;
}
S32 LLFontGL::getLineHeight() const
-{
- return llceil(mFontFreetype->getAscenderHeight() / sScaleY) + llceil(mFontFreetype->getDescenderHeight() / sScaleY);
+{
+ return llceil(mFontFreetype->getAscenderHeight() / sScaleY) + llceil(mFontFreetype->getDescenderHeight() / sScaleY);
}
S32 LLFontGL::getWidth(const std::string& utf8text) const
{
- LLWString wtext = utf8str_to_wstring(utf8text);
- return getWidth(wtext.c_str(), 0, S32_MAX);
+ LLWString wtext = utf8str_to_wstring(utf8text);
+ return getWidth(wtext.c_str(), 0, S32_MAX);
}
S32 LLFontGL::getWidth(const llwchar* wchars) const
{
- return getWidth(wchars, 0, S32_MAX);
+ return getWidth(wchars, 0, S32_MAX);
}
S32 LLFontGL::getWidth(const std::string& utf8text, S32 begin_offset, S32 max_chars) const
{
- LLWString wtext = utf8str_to_wstring(utf8text);
- return getWidth(wtext.c_str(), begin_offset, max_chars);
+ LLWString wtext = utf8str_to_wstring(utf8text);
+ return getWidth(wtext.c_str(), begin_offset, max_chars);
}
S32 LLFontGL::getWidth(const llwchar* wchars, S32 begin_offset, S32 max_chars) const
{
- F32 width = getWidthF32(wchars, begin_offset, max_chars);
- return ll_round(width);
+ F32 width = getWidthF32(wchars, begin_offset, max_chars);
+ return ll_round(width);
}
F32 LLFontGL::getWidthF32(const std::string& utf8text) const
{
- LLWString wtext = utf8str_to_wstring(utf8text);
- return getWidthF32(wtext.c_str(), 0, S32_MAX);
+ LLWString wtext = utf8str_to_wstring(utf8text);
+ return getWidthF32(wtext.c_str(), 0, S32_MAX);
}
F32 LLFontGL::getWidthF32(const llwchar* wchars) const
{
- return getWidthF32(wchars, 0, S32_MAX);
+ return getWidthF32(wchars, 0, S32_MAX);
}
F32 LLFontGL::getWidthF32(const std::string& utf8text, S32 begin_offset, S32 max_chars) const
{
- LLWString wtext = utf8str_to_wstring(utf8text);
- return getWidthF32(wtext.c_str(), begin_offset, max_chars);
+ LLWString wtext = utf8str_to_wstring(utf8text);
+ return getWidthF32(wtext.c_str(), begin_offset, max_chars);
}
F32 LLFontGL::getWidthF32(const llwchar* wchars, S32 begin_offset, S32 max_chars, bool no_padding) const
{
- const S32 LAST_CHARACTER = LLFontFreetype::LAST_CHAR_FULL;
-
- F32 cur_x = 0;
- const S32 max_index = begin_offset + max_chars;
-
- const LLFontGlyphInfo* next_glyph = NULL;
-
- F32 width_padding = 0.f;
- for (S32 i = begin_offset; i < max_index && wchars[i] != 0; i++)
- {
- llwchar wch = wchars[i];
-
- const LLFontGlyphInfo* fgi = next_glyph;
- next_glyph = NULL;
- if(!fgi)
- {
- fgi = mFontFreetype->getGlyphInfo(wch, EFontGlyphType::Unspecified);
- }
-
- F32 advance = mFontFreetype->getXAdvance(fgi);
-
- if (!no_padding)
- {
- // for the last character we want to measure the greater of its width and xadvance values
- // so keep track of the difference between these values for the each character we measure
- // so we can fix things up at the end
- width_padding = llmax(0.f, // always use positive padding amount
- width_padding - advance, // previous padding left over after advance of current character
- (F32)(fgi->mWidth + fgi->mXBearing) - advance); // difference between width of this character and advance to next character
- }
-
- cur_x += advance;
- llwchar next_char = wchars[i+1];
-
- if (((i + 1) < begin_offset + max_chars)
- && next_char
- && (next_char < LAST_CHARACTER))
- {
- // Kern this puppy.
- next_glyph = mFontFreetype->getGlyphInfo(next_char, EFontGlyphType::Unspecified);
- cur_x += mFontFreetype->getXKerning(fgi, next_glyph);
- }
- // Round after kerning.
- cur_x = (F32)ll_round(cur_x);
- }
-
- if (!no_padding)
- {
- // add in extra pixels for last character's width past its xadvance
- cur_x += width_padding;
- }
-
- return cur_x / sScaleX;
+ const S32 LAST_CHARACTER = LLFontFreetype::LAST_CHAR_FULL;
+
+ F32 cur_x = 0;
+ const S32 max_index = begin_offset + max_chars;
+
+ const LLFontGlyphInfo* next_glyph = NULL;
+
+ F32 width_padding = 0.f;
+ for (S32 i = begin_offset; i < max_index && wchars[i] != 0; i++)
+ {
+ llwchar wch = wchars[i];
+
+ const LLFontGlyphInfo* fgi = next_glyph;
+ next_glyph = NULL;
+ if(!fgi)
+ {
+ fgi = mFontFreetype->getGlyphInfo(wch, EFontGlyphType::Unspecified);
+ }
+
+ F32 advance = mFontFreetype->getXAdvance(fgi);
+
+ if (!no_padding)
+ {
+ // for the last character we want to measure the greater of its width and xadvance values
+ // so keep track of the difference between these values for the each character we measure
+ // so we can fix things up at the end
+ width_padding = llmax(0.f, // always use positive padding amount
+ width_padding - advance, // previous padding left over after advance of current character
+ (F32)(fgi->mWidth + fgi->mXBearing) - advance); // difference between width of this character and advance to next character
+ }
+
+ cur_x += advance;
+ llwchar next_char = wchars[i+1];
+
+ if (((i + 1) < begin_offset + max_chars)
+ && next_char
+ && (next_char < LAST_CHARACTER))
+ {
+ // Kern this puppy.
+ next_glyph = mFontFreetype->getGlyphInfo(next_char, EFontGlyphType::Unspecified);
+ cur_x += mFontFreetype->getXKerning(fgi, next_glyph);
+ }
+ // Round after kerning.
+ cur_x = (F32)ll_round(cur_x);
+ }
+
+ if (!no_padding)
+ {
+ // add in extra pixels for last character's width past its xadvance
+ cur_x += width_padding;
+ }
+
+ return cur_x / sScaleX;
}
void LLFontGL::generateASCIIglyphs()
@@ -563,308 +563,308 @@ void LLFontGL::generateASCIIglyphs()
// Returns the max number of complete characters from text (up to max_chars) that can be drawn in max_pixels
S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_chars, EWordWrapStyle end_on_word_boundary) const
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_UI
- if (!wchars || !wchars[0] || max_chars == 0)
- {
- return 0;
- }
-
- llassert(max_pixels >= 0.f);
- llassert(max_chars >= 0);
-
- BOOL clip = FALSE;
- F32 cur_x = 0;
-
- S32 start_of_last_word = 0;
- BOOL in_word = FALSE;
-
- // avoid S32 overflow when max_pixels == S32_MAX by staying in floating point
- F32 scaled_max_pixels = max_pixels * sScaleX;
- F32 width_padding = 0.f;
-
- LLFontGlyphInfo* next_glyph = NULL;
-
- S32 i;
- for (i=0; (i < max_chars); i++)
- {
- llwchar wch = wchars[i];
-
- if(wch == 0)
- {
- // Null terminator. We're done.
- break;
- }
-
- if (in_word)
- {
- if (iswspace(wch))
- {
- if(wch !=(0x00A0))
- {
- in_word = FALSE;
- }
- }
- if (iswindividual(wch))
- {
- if (iswpunct(wchars[i+1]))
- {
- in_word=TRUE;
- }
- else
- {
- in_word=FALSE;
- start_of_last_word = i;
- }
- }
- }
- else
- {
- start_of_last_word = i;
- if (!iswspace(wch)||!iswindividual(wch))
- {
- in_word = TRUE;
- }
- }
-
- LLFontGlyphInfo* fgi = next_glyph;
- next_glyph = NULL;
- if(!fgi)
- {
- fgi = mFontFreetype->getGlyphInfo(wch, EFontGlyphType::Unspecified);
-
- if (NULL == fgi)
- {
- return 0;
- }
- }
-
- // account for glyphs that run beyond the starting point for the next glyphs
- width_padding = llmax( 0.f, // always use positive padding amount
- width_padding - fgi->mXAdvance, // previous padding left over after advance of current character
- (F32)(fgi->mWidth + fgi->mXBearing) - fgi->mXAdvance); // difference between width of this character and advance to next character
-
- cur_x += fgi->mXAdvance;
-
- // clip if current character runs past scaled_max_pixels (using width_padding)
- if (scaled_max_pixels < cur_x + width_padding)
- {
- clip = TRUE;
- break;
- }
-
- if (((i+1) < max_chars) && wchars[i+1])
- {
- // Kern this puppy.
- next_glyph = mFontFreetype->getGlyphInfo(wchars[i+1], EFontGlyphType::Unspecified);
- cur_x += mFontFreetype->getXKerning(fgi, next_glyph);
- }
-
- // Round after kerning.
- cur_x = (F32)ll_round(cur_x);
- }
-
- if( clip )
- {
- switch (end_on_word_boundary)
- {
- case ONLY_WORD_BOUNDARIES:
- i = start_of_last_word;
- break;
- case WORD_BOUNDARY_IF_POSSIBLE:
- if (start_of_last_word != 0)
- {
- i = start_of_last_word;
- }
- break;
- default:
- case ANYWHERE:
- // do nothing
- break;
- }
- }
- return i;
-}
-
-S32 LLFontGL::firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_len, S32 start_pos, S32 max_chars) const
-{
- if (!wchars || !wchars[0] || max_chars == 0)
- {
- return 0;
- }
-
- F32 total_width = 0.0;
- S32 drawable_chars = 0;
-
- F32 scaled_max_pixels = max_pixels * sScaleX;
-
- S32 start = llmin(start_pos, text_len - 1);
- for (S32 i = start; i >= 0; i--)
- {
- llwchar wch = wchars[i];
-
- const LLFontGlyphInfo* fgi= mFontFreetype->getGlyphInfo(wch, EFontGlyphType::Unspecified);
-
- // last character uses character width, since the whole character needs to be visible
- // other characters just use advance
- F32 width = (i == start)
- ? (F32)(fgi->mWidth + fgi->mXBearing) // use actual width for last character
- : fgi->mXAdvance; // use advance for all other characters
-
- if( scaled_max_pixels < (total_width + width) )
- {
- break;
- }
-
- total_width += width;
- drawable_chars++;
-
- if( max_chars >= 0 && drawable_chars >= max_chars )
- {
- break;
- }
-
- if ( i > 0 )
- {
- // kerning
- total_width += mFontFreetype->getXKerning(wchars[i-1], wch);
- }
-
- // Round after kerning.
- total_width = (F32)ll_round(total_width);
- }
-
- if (drawable_chars == 0)
- {
- return start_pos; // just draw last character
- }
- else
- {
- // if only 1 character is drawable, we want to return start_pos as the first character to draw
- // if 2 are drawable, return start_pos and character before start_pos, etc.
- return start_pos + 1 - drawable_chars;
- }
-
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_UI
+ if (!wchars || !wchars[0] || max_chars == 0)
+ {
+ return 0;
+ }
+
+ llassert(max_pixels >= 0.f);
+ llassert(max_chars >= 0);
+
+ BOOL clip = FALSE;
+ F32 cur_x = 0;
+
+ S32 start_of_last_word = 0;
+ BOOL in_word = FALSE;
+
+ // avoid S32 overflow when max_pixels == S32_MAX by staying in floating point
+ F32 scaled_max_pixels = max_pixels * sScaleX;
+ F32 width_padding = 0.f;
+
+ LLFontGlyphInfo* next_glyph = NULL;
+
+ S32 i;
+ for (i=0; (i < max_chars); i++)
+ {
+ llwchar wch = wchars[i];
+
+ if(wch == 0)
+ {
+ // Null terminator. We're done.
+ break;
+ }
+
+ if (in_word)
+ {
+ if (iswspace(wch))
+ {
+ if(wch !=(0x00A0))
+ {
+ in_word = FALSE;
+ }
+ }
+ if (iswindividual(wch))
+ {
+ if (iswpunct(wchars[i+1]))
+ {
+ in_word=TRUE;
+ }
+ else
+ {
+ in_word=FALSE;
+ start_of_last_word = i;
+ }
+ }
+ }
+ else
+ {
+ start_of_last_word = i;
+ if (!iswspace(wch)||!iswindividual(wch))
+ {
+ in_word = TRUE;
+ }
+ }
+
+ LLFontGlyphInfo* fgi = next_glyph;
+ next_glyph = NULL;
+ if(!fgi)
+ {
+ fgi = mFontFreetype->getGlyphInfo(wch, EFontGlyphType::Unspecified);
+
+ if (NULL == fgi)
+ {
+ return 0;
+ }
+ }
+
+ // account for glyphs that run beyond the starting point for the next glyphs
+ width_padding = llmax( 0.f, // always use positive padding amount
+ width_padding - fgi->mXAdvance, // previous padding left over after advance of current character
+ (F32)(fgi->mWidth + fgi->mXBearing) - fgi->mXAdvance); // difference between width of this character and advance to next character
+
+ cur_x += fgi->mXAdvance;
+
+ // clip if current character runs past scaled_max_pixels (using width_padding)
+ if (scaled_max_pixels < cur_x + width_padding)
+ {
+ clip = TRUE;
+ break;
+ }
+
+ if (((i+1) < max_chars) && wchars[i+1])
+ {
+ // Kern this puppy.
+ next_glyph = mFontFreetype->getGlyphInfo(wchars[i+1], EFontGlyphType::Unspecified);
+ cur_x += mFontFreetype->getXKerning(fgi, next_glyph);
+ }
+
+ // Round after kerning.
+ cur_x = (F32)ll_round(cur_x);
+ }
+
+ if( clip )
+ {
+ switch (end_on_word_boundary)
+ {
+ case ONLY_WORD_BOUNDARIES:
+ i = start_of_last_word;
+ break;
+ case WORD_BOUNDARY_IF_POSSIBLE:
+ if (start_of_last_word != 0)
+ {
+ i = start_of_last_word;
+ }
+ break;
+ default:
+ case ANYWHERE:
+ // do nothing
+ break;
+ }
+ }
+ return i;
+}
+
+S32 LLFontGL::firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_len, S32 start_pos, S32 max_chars) const
+{
+ if (!wchars || !wchars[0] || max_chars == 0)
+ {
+ return 0;
+ }
+
+ F32 total_width = 0.0;
+ S32 drawable_chars = 0;
+
+ F32 scaled_max_pixels = max_pixels * sScaleX;
+
+ S32 start = llmin(start_pos, text_len - 1);
+ for (S32 i = start; i >= 0; i--)
+ {
+ llwchar wch = wchars[i];
+
+ const LLFontGlyphInfo* fgi= mFontFreetype->getGlyphInfo(wch, EFontGlyphType::Unspecified);
+
+ // last character uses character width, since the whole character needs to be visible
+ // other characters just use advance
+ F32 width = (i == start)
+ ? (F32)(fgi->mWidth + fgi->mXBearing) // use actual width for last character
+ : fgi->mXAdvance; // use advance for all other characters
+
+ if( scaled_max_pixels < (total_width + width) )
+ {
+ break;
+ }
+
+ total_width += width;
+ drawable_chars++;
+
+ if( max_chars >= 0 && drawable_chars >= max_chars )
+ {
+ break;
+ }
+
+ if ( i > 0 )
+ {
+ // kerning
+ total_width += mFontFreetype->getXKerning(wchars[i-1], wch);
+ }
+
+ // Round after kerning.
+ total_width = (F32)ll_round(total_width);
+ }
+
+ if (drawable_chars == 0)
+ {
+ return start_pos; // just draw last character
+ }
+ else
+ {
+ // if only 1 character is drawable, we want to return start_pos as the first character to draw
+ // if 2 are drawable, return start_pos and character before start_pos, etc.
+ return start_pos + 1 - drawable_chars;
+ }
+
}
S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, S32 begin_offset, F32 target_x, F32 max_pixels, S32 max_chars, BOOL round) const
{
- if (!wchars || !wchars[0] || max_chars == 0)
- {
- return 0;
- }
-
- F32 cur_x = 0;
-
- target_x *= sScaleX;
-
- // max_chars is S32_MAX by default, so make sure we don't get overflow
- const S32 max_index = begin_offset + llmin(S32_MAX - begin_offset, max_chars - 1);
-
- F32 scaled_max_pixels = max_pixels * sScaleX;
-
- const LLFontGlyphInfo* next_glyph = NULL;
-
- S32 pos;
- for (pos = begin_offset; pos < max_index; pos++)
- {
- llwchar wch = wchars[pos];
- if (!wch)
- {
- break; // done
- }
-
- const LLFontGlyphInfo* glyph = next_glyph;
- next_glyph = NULL;
- if(!glyph)
- {
- glyph = mFontFreetype->getGlyphInfo(wch, EFontGlyphType::Unspecified);
- }
-
- F32 char_width = mFontFreetype->getXAdvance(glyph);
-
- if (round)
- {
- // Note: if the mouse is on the left half of the character, the pick is to the character's left
- // If it's on the right half, the pick is to the right.
- if (target_x < cur_x + char_width*0.5f)
- {
- break;
- }
- }
- else if (target_x < cur_x + char_width)
- {
- break;
- }
-
- if (scaled_max_pixels < cur_x + char_width)
- {
- break;
- }
-
- cur_x += char_width;
-
- if (((pos + 1) < max_index)
- && (wchars[(pos + 1)]))
- {
- // Kern this puppy.
- next_glyph = mFontFreetype->getGlyphInfo(wchars[pos + 1], EFontGlyphType::Unspecified);
- cur_x += mFontFreetype->getXKerning(glyph, next_glyph);
- }
-
-
- // Round after kerning.
- cur_x = (F32)ll_round(cur_x);
- }
-
- return llmin(max_chars, pos - begin_offset);
+ if (!wchars || !wchars[0] || max_chars == 0)
+ {
+ return 0;
+ }
+
+ F32 cur_x = 0;
+
+ target_x *= sScaleX;
+
+ // max_chars is S32_MAX by default, so make sure we don't get overflow
+ const S32 max_index = begin_offset + llmin(S32_MAX - begin_offset, max_chars - 1);
+
+ F32 scaled_max_pixels = max_pixels * sScaleX;
+
+ const LLFontGlyphInfo* next_glyph = NULL;
+
+ S32 pos;
+ for (pos = begin_offset; pos < max_index; pos++)
+ {
+ llwchar wch = wchars[pos];
+ if (!wch)
+ {
+ break; // done
+ }
+
+ const LLFontGlyphInfo* glyph = next_glyph;
+ next_glyph = NULL;
+ if(!glyph)
+ {
+ glyph = mFontFreetype->getGlyphInfo(wch, EFontGlyphType::Unspecified);
+ }
+
+ F32 char_width = mFontFreetype->getXAdvance(glyph);
+
+ if (round)
+ {
+ // Note: if the mouse is on the left half of the character, the pick is to the character's left
+ // If it's on the right half, the pick is to the right.
+ if (target_x < cur_x + char_width*0.5f)
+ {
+ break;
+ }
+ }
+ else if (target_x < cur_x + char_width)
+ {
+ break;
+ }
+
+ if (scaled_max_pixels < cur_x + char_width)
+ {
+ break;
+ }
+
+ cur_x += char_width;
+
+ if (((pos + 1) < max_index)
+ && (wchars[(pos + 1)]))
+ {
+ // Kern this puppy.
+ next_glyph = mFontFreetype->getGlyphInfo(wchars[pos + 1], EFontGlyphType::Unspecified);
+ cur_x += mFontFreetype->getXKerning(glyph, next_glyph);
+ }
+
+
+ // Round after kerning.
+ cur_x = (F32)ll_round(cur_x);
+ }
+
+ return llmin(max_chars, pos - begin_offset);
}
const LLFontDescriptor& LLFontGL::getFontDesc() const
{
- return mFontDescriptor;
+ return mFontDescriptor;
}
// static
void LLFontGL::initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, const std::string& app_dir, bool create_gl_textures)
{
- sVertDPI = (F32)llfloor(screen_dpi * y_scale);
- sHorizDPI = (F32)llfloor(screen_dpi * x_scale);
- sScaleX = x_scale;
- sScaleY = y_scale;
- sAppDir = app_dir;
-
- // Font registry init
- if (!sFontRegistry)
- {
- sFontRegistry = new LLFontRegistry(create_gl_textures);
- sFontRegistry->parseFontInfo("fonts.xml");
- }
- else
- {
- sFontRegistry->reset();
- }
+ sVertDPI = (F32)llfloor(screen_dpi * y_scale);
+ sHorizDPI = (F32)llfloor(screen_dpi * x_scale);
+ sScaleX = x_scale;
+ sScaleY = y_scale;
+ sAppDir = app_dir;
+
+ // Font registry init
+ if (!sFontRegistry)
+ {
+ sFontRegistry = new LLFontRegistry(create_gl_textures);
+ sFontRegistry->parseFontInfo("fonts.xml");
+ }
+ else
+ {
+ sFontRegistry->reset();
+ }
- LLFontGL::loadDefaultFonts();
+ LLFontGL::loadDefaultFonts();
}
void LLFontGL::dumpTextures()
{
- if (mFontFreetype.notNull())
- {
- mFontFreetype->dumpFontBitmaps();
- }
+ if (mFontFreetype.notNull())
+ {
+ mFontFreetype->dumpFontBitmaps();
+ }
}
// static
void LLFontGL::dumpFonts()
{
- sFontRegistry->dump();
+ sFontRegistry->dump();
}
// static
void LLFontGL::dumpFontTextures()
{
- sFontRegistry->dumpTextures();
+ sFontRegistry->dumpTextures();
}
// Force standard fonts to get generated up front.
@@ -874,15 +874,15 @@ void LLFontGL::dumpFontTextures()
// static
bool LLFontGL::loadDefaultFonts()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_UI
- bool succ = true;
- succ &= (NULL != getFontSansSerifSmall());
- succ &= (NULL != getFontSansSerif());
- succ &= (NULL != getFontSansSerifBig());
- succ &= (NULL != getFontSansSerifHuge());
- succ &= (NULL != getFontSansSerifBold());
- succ &= (NULL != getFontMonospace());
- return succ;
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_UI
+ bool succ = true;
+ succ &= (NULL != getFontSansSerifSmall());
+ succ &= (NULL != getFontSansSerif());
+ succ &= (NULL != getFontSansSerifBig());
+ succ &= (NULL != getFontSansSerifHuge());
+ succ &= (NULL != getFontSansSerifBold());
+ succ &= (NULL != getFontMonospace());
+ return succ;
}
void LLFontGL::loadCommonFonts()
@@ -897,164 +897,164 @@ void LLFontGL::loadCommonFonts()
// static
void LLFontGL::destroyDefaultFonts()
{
- // Remove the actual fonts.
- delete sFontRegistry;
- sFontRegistry = NULL;
+ // Remove the actual fonts.
+ delete sFontRegistry;
+ sFontRegistry = NULL;
}
-//static
+//static
void LLFontGL::destroyAllGL()
{
- if (sFontRegistry)
- {
- sFontRegistry->destroyGL();
- }
+ if (sFontRegistry)
+ {
+ sFontRegistry->destroyGL();
+ }
}
// static
U8 LLFontGL::getStyleFromString(const std::string &style)
{
- S32 ret = 0;
- if (style.find("BOLD") != style.npos)
- {
- ret |= BOLD;
- }
- if (style.find("ITALIC") != style.npos)
- {
- ret |= ITALIC;
- }
- if (style.find("UNDERLINE") != style.npos)
- {
- ret |= UNDERLINE;
- }
- return ret;
+ S32 ret = 0;
+ if (style.find("BOLD") != style.npos)
+ {
+ ret |= BOLD;
+ }
+ if (style.find("ITALIC") != style.npos)
+ {
+ ret |= ITALIC;
+ }
+ if (style.find("UNDERLINE") != style.npos)
+ {
+ ret |= UNDERLINE;
+ }
+ return ret;
}
// static
std::string LLFontGL::getStringFromStyle(U8 style)
{
- std::string style_string;
- if (style == NORMAL)
- {
- style_string += "|NORMAL";
- }
- if (style & BOLD)
- {
- style_string += "|BOLD";
- }
- if (style & ITALIC)
- {
- style_string += "|ITALIC";
- }
- if (style & UNDERLINE)
- {
- style_string += "|UNDERLINE";
- }
- return style_string;
+ std::string style_string;
+ if (style == NORMAL)
+ {
+ style_string += "|NORMAL";
+ }
+ if (style & BOLD)
+ {
+ style_string += "|BOLD";
+ }
+ if (style & ITALIC)
+ {
+ style_string += "|ITALIC";
+ }
+ if (style & UNDERLINE)
+ {
+ style_string += "|UNDERLINE";
+ }
+ return style_string;
}
// static
std::string LLFontGL::nameFromFont(const LLFontGL* fontp)
{
- return fontp->mFontDescriptor.getName();
+ return fontp->mFontDescriptor.getName();
}
// static
std::string LLFontGL::sizeFromFont(const LLFontGL* fontp)
{
- return fontp->mFontDescriptor.getSize();
+ return fontp->mFontDescriptor.getSize();
}
// static
std::string LLFontGL::nameFromHAlign(LLFontGL::HAlign align)
{
- if (align == LEFT) return std::string("left");
- else if (align == RIGHT) return std::string("right");
- else if (align == HCENTER) return std::string("center");
- else return std::string();
+ if (align == LEFT) return std::string("left");
+ else if (align == RIGHT) return std::string("right");
+ else if (align == HCENTER) return std::string("center");
+ else return std::string();
}
// static
LLFontGL::HAlign LLFontGL::hAlignFromName(const std::string& name)
{
- LLFontGL::HAlign gl_hfont_align = LLFontGL::LEFT;
- if (name == "left")
- {
- gl_hfont_align = LLFontGL::LEFT;
- }
- else if (name == "right")
- {
- gl_hfont_align = LLFontGL::RIGHT;
- }
- else if (name == "center")
- {
- gl_hfont_align = LLFontGL::HCENTER;
- }
- //else leave left
- return gl_hfont_align;
+ LLFontGL::HAlign gl_hfont_align = LLFontGL::LEFT;
+ if (name == "left")
+ {
+ gl_hfont_align = LLFontGL::LEFT;
+ }
+ else if (name == "right")
+ {
+ gl_hfont_align = LLFontGL::RIGHT;
+ }
+ else if (name == "center")
+ {
+ gl_hfont_align = LLFontGL::HCENTER;
+ }
+ //else leave left
+ return gl_hfont_align;
}
// static
std::string LLFontGL::nameFromVAlign(LLFontGL::VAlign align)
{
- if (align == TOP) return std::string("top");
- else if (align == VCENTER) return std::string("center");
- else if (align == BASELINE) return std::string("baseline");
- else if (align == BOTTOM) return std::string("bottom");
- else return std::string();
+ if (align == TOP) return std::string("top");
+ else if (align == VCENTER) return std::string("center");
+ else if (align == BASELINE) return std::string("baseline");
+ else if (align == BOTTOM) return std::string("bottom");
+ else return std::string();
}
// static
LLFontGL::VAlign LLFontGL::vAlignFromName(const std::string& name)
{
- LLFontGL::VAlign gl_vfont_align = LLFontGL::BASELINE;
- if (name == "top")
- {
- gl_vfont_align = LLFontGL::TOP;
- }
- else if (name == "center")
- {
- gl_vfont_align = LLFontGL::VCENTER;
- }
- else if (name == "baseline")
- {
- gl_vfont_align = LLFontGL::BASELINE;
- }
- else if (name == "bottom")
- {
- gl_vfont_align = LLFontGL::BOTTOM;
- }
- //else leave baseline
- return gl_vfont_align;
+ LLFontGL::VAlign gl_vfont_align = LLFontGL::BASELINE;
+ if (name == "top")
+ {
+ gl_vfont_align = LLFontGL::TOP;
+ }
+ else if (name == "center")
+ {
+ gl_vfont_align = LLFontGL::VCENTER;
+ }
+ else if (name == "baseline")
+ {
+ gl_vfont_align = LLFontGL::BASELINE;
+ }
+ else if (name == "bottom")
+ {
+ gl_vfont_align = LLFontGL::BOTTOM;
+ }
+ //else leave baseline
+ return gl_vfont_align;
}
//static
LLFontGL* LLFontGL::getFontEmoji()
{
- static LLFontGL* fontp = getFont(LLFontDescriptor("Emoji", "Large", 0));
- return fontp;;
+ static LLFontGL* fontp = getFont(LLFontDescriptor("Emoji", "Large", 0));
+ return fontp;;
}
//static
LLFontGL* LLFontGL::getFontEmojiHuge()
{
- static LLFontGL* fontp = getFont(LLFontDescriptor("Emoji", "Huge", 0));
- return fontp;;
+ static LLFontGL* fontp = getFont(LLFontDescriptor("Emoji", "Huge", 0));
+ return fontp;;
}
//static
LLFontGL* LLFontGL::getFontMonospace()
{
- static LLFontGL* fontp = getFont(LLFontDescriptor("Monospace","Monospace",0));
- return fontp;
+ static LLFontGL* fontp = getFont(LLFontDescriptor("Monospace","Monospace",0));
+ return fontp;
}
//static
LLFontGL* LLFontGL::getFontSansSerifSmall()
{
- static LLFontGL* fontp = getFont(LLFontDescriptor("SansSerif","Small",0));
- return fontp;
+ static LLFontGL* fontp = getFont(LLFontDescriptor("SansSerif","Small",0));
+ return fontp;
}
//static
@@ -1074,73 +1074,73 @@ LLFontGL* LLFontGL::getFontSansSerifSmallItalic()
//static
LLFontGL* LLFontGL::getFontSansSerif()
{
- static LLFontGL* fontp = getFont(LLFontDescriptor("SansSerif","Medium",0));
- return fontp;
+ static LLFontGL* fontp = getFont(LLFontDescriptor("SansSerif","Medium",0));
+ return fontp;
}
//static
LLFontGL* LLFontGL::getFontSansSerifBig()
{
- static LLFontGL* fontp = getFont(LLFontDescriptor("SansSerif","Large",0));
- return fontp;
+ static LLFontGL* fontp = getFont(LLFontDescriptor("SansSerif","Large",0));
+ return fontp;
}
-//static
+//static
LLFontGL* LLFontGL::getFontSansSerifHuge()
{
- static LLFontGL* fontp = getFont(LLFontDescriptor("SansSerif","Huge",0));
- return fontp;
+ static LLFontGL* fontp = getFont(LLFontDescriptor("SansSerif","Huge",0));
+ return fontp;
}
-//static
+//static
LLFontGL* LLFontGL::getFontSansSerifBold()
{
- static LLFontGL* fontp = getFont(LLFontDescriptor("SansSerif","Medium",BOLD));
- return fontp;
+ static LLFontGL* fontp = getFont(LLFontDescriptor("SansSerif","Medium",BOLD));
+ return fontp;
}
-//static
+//static
LLFontGL* LLFontGL::getFont(const LLFontDescriptor& desc)
{
- return sFontRegistry->getFont(desc);
+ return sFontRegistry->getFont(desc);
}
//static
LLFontGL* LLFontGL::getFontByName(const std::string& name)
{
- // check for most common fonts first
- if (name == "SANSSERIF")
- {
- return getFontSansSerif();
- }
- else if (name == "SANSSERIF_SMALL")
- {
- return getFontSansSerifSmall();
- }
- else if (name == "SANSSERIF_BIG")
- {
- return getFontSansSerifBig();
- }
- else if (name == "SMALL" || name == "OCRA")
- {
- // *BUG: Should this be "MONOSPACE"? Do we use "OCRA" anymore?
- // Does "SMALL" mean "SERIF"?
- return getFontMonospace();
- }
- else
- {
- return NULL;
- }
+ // check for most common fonts first
+ if (name == "SANSSERIF")
+ {
+ return getFontSansSerif();
+ }
+ else if (name == "SANSSERIF_SMALL")
+ {
+ return getFontSansSerifSmall();
+ }
+ else if (name == "SANSSERIF_BIG")
+ {
+ return getFontSansSerifBig();
+ }
+ else if (name == "SMALL" || name == "OCRA")
+ {
+ // *BUG: Should this be "MONOSPACE"? Do we use "OCRA" anymore?
+ // Does "SMALL" mean "SERIF"?
+ return getFontMonospace();
+ }
+ else
+ {
+ return NULL;
+ }
}
//static
LLFontGL* LLFontGL::getFontDefault()
{
- return getFontSansSerif(); // Fallback to sans serif as default font
+ return getFontSansSerif(); // Fallback to sans serif as default font
}
-// static
+// static
std::string LLFontGL::getFontPathSystem()
{
#if LL_DARWIN
@@ -1173,127 +1173,127 @@ std::string LLFontGL::getFontPathSystem()
}
-// static
+// static
std::string LLFontGL::getFontPathLocal()
{
- std::string local_path;
+ std::string local_path;
- // Backup files if we can't load from system fonts directory.
- // We could store this in an end-user writable directory to allow
- // end users to switch fonts.
- if (LLFontGL::sAppDir.length())
- {
- // use specified application dir to look for fonts
- local_path = LLFontGL::sAppDir + "/fonts/";
- }
- else
- {
- // assume working directory is executable directory
- local_path = "./fonts/";
- }
- return local_path;
+ // Backup files if we can't load from system fonts directory.
+ // We could store this in an end-user writable directory to allow
+ // end users to switch fonts.
+ if (LLFontGL::sAppDir.length())
+ {
+ // use specified application dir to look for fonts
+ local_path = LLFontGL::sAppDir + "/fonts/";
+ }
+ else
+ {
+ // assume working directory is executable directory
+ local_path = "./fonts/";
+ }
+ return local_path;
}
LLFontGL::LLFontGL(const LLFontGL &source)
{
- LL_ERRS() << "Not implemented!" << LL_ENDL;
+ LL_ERRS() << "Not implemented!" << LL_ENDL;
}
LLFontGL &LLFontGL::operator=(const LLFontGL &source)
{
- LL_ERRS() << "Not implemented" << LL_ENDL;
- return *this;
+ LL_ERRS() << "Not implemented" << LL_ENDL;
+ return *this;
}
void LLFontGL::renderQuad(LLVector3* vertex_out, LLVector2* uv_out, LLColor4U* colors_out, const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4U& color, F32 slant_amt) const
{
- S32 index = 0;
+ S32 index = 0;
- vertex_out[index] = LLVector3(screen_rect.mRight, screen_rect.mTop, 0.f);
- uv_out[index] = LLVector2(uv_rect.mRight, uv_rect.mTop);
- colors_out[index] = color;
- index++;
+ vertex_out[index] = LLVector3(screen_rect.mRight, screen_rect.mTop, 0.f);
+ uv_out[index] = LLVector2(uv_rect.mRight, uv_rect.mTop);
+ colors_out[index] = color;
+ index++;
- vertex_out[index] = LLVector3(screen_rect.mLeft, screen_rect.mTop, 0.f);
- uv_out[index] = LLVector2(uv_rect.mLeft, uv_rect.mTop);
- colors_out[index] = color;
- index++;
+ vertex_out[index] = LLVector3(screen_rect.mLeft, screen_rect.mTop, 0.f);
+ uv_out[index] = LLVector2(uv_rect.mLeft, uv_rect.mTop);
+ colors_out[index] = color;
+ index++;
- vertex_out[index] = LLVector3(screen_rect.mLeft, screen_rect.mBottom, 0.f);
- uv_out[index] = LLVector2(uv_rect.mLeft, uv_rect.mBottom);
- colors_out[index] = color;
- index++;
+ vertex_out[index] = LLVector3(screen_rect.mLeft, screen_rect.mBottom, 0.f);
+ uv_out[index] = LLVector2(uv_rect.mLeft, uv_rect.mBottom);
+ colors_out[index] = color;
+ index++;
- vertex_out[index] = LLVector3(screen_rect.mRight, screen_rect.mBottom, 0.f);
- uv_out[index] = LLVector2(uv_rect.mRight, uv_rect.mBottom);
- colors_out[index] = color;
+ vertex_out[index] = LLVector3(screen_rect.mRight, screen_rect.mBottom, 0.f);
+ uv_out[index] = LLVector2(uv_rect.mRight, uv_rect.mBottom);
+ colors_out[index] = color;
}
void LLFontGL::drawGlyph(S32& glyph_count, LLVector3* vertex_out, LLVector2* uv_out, LLColor4U* colors_out, const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4U& color, U8 style, ShadowType shadow, F32 drop_shadow_strength) const
{
- F32 slant_offset;
- slant_offset = ((style & ITALIC) ? ( -mFontFreetype->getAscenderHeight() * 0.2f) : 0.f);
-
- //FIXME: bold and drop shadow are mutually exclusive only for convenience
- //Allow both when we need them.
- if (style & BOLD)
- {
- for (S32 pass = 0; pass < 2; pass++)
- {
- LLRectf screen_rect_offset = screen_rect;
-
- screen_rect_offset.translate((F32)(pass * BOLD_OFFSET), 0.f);
- renderQuad(&vertex_out[glyph_count * 4], &uv_out[glyph_count * 4], &colors_out[glyph_count * 4], screen_rect_offset, uv_rect, color, slant_offset);
- glyph_count++;
- }
- }
- else if (shadow == DROP_SHADOW_SOFT)
- {
- LLColor4U shadow_color = LLFontGL::sShadowColor;
- shadow_color.mV[VALPHA] = U8(color.mV[VALPHA] * drop_shadow_strength * DROP_SHADOW_SOFT_STRENGTH);
- for (S32 pass = 0; pass < 5; pass++)
- {
- LLRectf screen_rect_offset = screen_rect;
-
- switch(pass)
- {
- case 0:
- screen_rect_offset.translate(-1.f, -1.f);
- break;
- case 1:
- screen_rect_offset.translate(1.f, -1.f);
- break;
- case 2:
- screen_rect_offset.translate(1.f, 1.f);
- break;
- case 3:
- screen_rect_offset.translate(-1.f, 1.f);
- break;
- case 4:
- screen_rect_offset.translate(0, -2.f);
- break;
- }
-
- renderQuad(&vertex_out[glyph_count * 4], &uv_out[glyph_count * 4], &colors_out[glyph_count * 4], screen_rect_offset, uv_rect, shadow_color, slant_offset);
- glyph_count++;
- }
- renderQuad(&vertex_out[glyph_count * 4], &uv_out[glyph_count * 4], &colors_out[glyph_count * 4], screen_rect, uv_rect, color, slant_offset);
- glyph_count++;
- }
- else if (shadow == DROP_SHADOW)
- {
- LLColor4U shadow_color = LLFontGL::sShadowColor;
- shadow_color.mV[VALPHA] = U8(color.mV[VALPHA] * drop_shadow_strength);
- LLRectf screen_rect_shadow = screen_rect;
- screen_rect_shadow.translate(1.f, -1.f);
- renderQuad(&vertex_out[glyph_count * 4], &uv_out[glyph_count * 4], &colors_out[glyph_count * 4], screen_rect_shadow, uv_rect, shadow_color, slant_offset);
- glyph_count++;
- renderQuad(&vertex_out[glyph_count * 4], &uv_out[glyph_count * 4], &colors_out[glyph_count * 4], screen_rect, uv_rect, color, slant_offset);
- glyph_count++;
- }
- else // normal rendering
- {
- renderQuad(&vertex_out[glyph_count * 4], &uv_out[glyph_count * 4], &colors_out[glyph_count * 4], screen_rect, uv_rect, color, slant_offset);
- glyph_count++;
- }
+ F32 slant_offset;
+ slant_offset = ((style & ITALIC) ? ( -mFontFreetype->getAscenderHeight() * 0.2f) : 0.f);
+
+ //FIXME: bold and drop shadow are mutually exclusive only for convenience
+ //Allow both when we need them.
+ if (style & BOLD)
+ {
+ for (S32 pass = 0; pass < 2; pass++)
+ {
+ LLRectf screen_rect_offset = screen_rect;
+
+ screen_rect_offset.translate((F32)(pass * BOLD_OFFSET), 0.f);
+ renderQuad(&vertex_out[glyph_count * 4], &uv_out[glyph_count * 4], &colors_out[glyph_count * 4], screen_rect_offset, uv_rect, color, slant_offset);
+ glyph_count++;
+ }
+ }
+ else if (shadow == DROP_SHADOW_SOFT)
+ {
+ LLColor4U shadow_color = LLFontGL::sShadowColor;
+ shadow_color.mV[VALPHA] = U8(color.mV[VALPHA] * drop_shadow_strength * DROP_SHADOW_SOFT_STRENGTH);
+ for (S32 pass = 0; pass < 5; pass++)
+ {
+ LLRectf screen_rect_offset = screen_rect;
+
+ switch(pass)
+ {
+ case 0:
+ screen_rect_offset.translate(-1.f, -1.f);
+ break;
+ case 1:
+ screen_rect_offset.translate(1.f, -1.f);
+ break;
+ case 2:
+ screen_rect_offset.translate(1.f, 1.f);
+ break;
+ case 3:
+ screen_rect_offset.translate(-1.f, 1.f);
+ break;
+ case 4:
+ screen_rect_offset.translate(0, -2.f);
+ break;
+ }
+
+ renderQuad(&vertex_out[glyph_count * 4], &uv_out[glyph_count * 4], &colors_out[glyph_count * 4], screen_rect_offset, uv_rect, shadow_color, slant_offset);
+ glyph_count++;
+ }
+ renderQuad(&vertex_out[glyph_count * 4], &uv_out[glyph_count * 4], &colors_out[glyph_count * 4], screen_rect, uv_rect, color, slant_offset);
+ glyph_count++;
+ }
+ else if (shadow == DROP_SHADOW)
+ {
+ LLColor4U shadow_color = LLFontGL::sShadowColor;
+ shadow_color.mV[VALPHA] = U8(color.mV[VALPHA] * drop_shadow_strength);
+ LLRectf screen_rect_shadow = screen_rect;
+ screen_rect_shadow.translate(1.f, -1.f);
+ renderQuad(&vertex_out[glyph_count * 4], &uv_out[glyph_count * 4], &colors_out[glyph_count * 4], screen_rect_shadow, uv_rect, shadow_color, slant_offset);
+ glyph_count++;
+ renderQuad(&vertex_out[glyph_count * 4], &uv_out[glyph_count * 4], &colors_out[glyph_count * 4], screen_rect, uv_rect, color, slant_offset);
+ glyph_count++;
+ }
+ else // normal rendering
+ {
+ renderQuad(&vertex_out[glyph_count * 4], &uv_out[glyph_count * 4], &colors_out[glyph_count * 4], screen_rect, uv_rect, color, slant_offset);
+ glyph_count++;
+ }
}
diff --git a/indra/llrender/llfontgl.h b/indra/llrender/llfontgl.h
index f6ec416c8b..2e1d04a2b9 100644
--- a/indra/llrender/llfontgl.h
+++ b/indra/llrender/llfontgl.h
@@ -1,4 +1,4 @@
-/**
+/**
* @file llfontgl.h
* @author Doug Soo
* @brief Wrapper around FreeType
@@ -6,21 +6,21 @@
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -46,201 +46,201 @@ class LLFontRegistry;
class LLFontGL
{
public:
- enum HAlign
- {
- // Horizontal location of x,y coord to render.
- LEFT = 0, // Left align
- RIGHT = 1, // Right align
- HCENTER = 2, // Center
- };
-
- enum VAlign
- {
- // Vertical location of x,y coord to render.
- TOP = 3, // Top align
- VCENTER = 4, // Center
- BASELINE = 5, // Baseline
- BOTTOM = 6 // Bottom
- };
-
- enum StyleFlags
- {
- // text style to render. May be combined (these are bit flags)
- NORMAL = 0x00,
- BOLD = 0x01,
- ITALIC = 0x02,
- UNDERLINE = 0x04
- };
-
- enum ShadowType
- {
- NO_SHADOW,
- DROP_SHADOW,
- DROP_SHADOW_SOFT
- };
-
- LLFontGL();
- ~LLFontGL();
-
-
- void reset(); // Reset a font after GL cleanup. ONLY works on an already loaded font.
-
- void destroyGL();
-
- BOOL loadFace(const std::string& filename, F32 point_size, const F32 vert_dpi, const F32 horz_dpi, bool is_fallback, S32 face_n);
-
- S32 getNumFaces(const std::string& filename);
-
- S32 render(const LLWString &text, S32 begin_offset,
- const LLRect& rect,
- const LLColor4 &color,
- HAlign halign = LEFT, VAlign valign = BASELINE,
- U8 style = NORMAL, ShadowType shadow = NO_SHADOW,
- S32 max_chars = S32_MAX,
- F32* right_x=NULL,
- BOOL use_ellipses = FALSE,
- BOOL use_color = TRUE) const;
-
- S32 render(const LLWString &text, S32 begin_offset,
- const LLRectf& rect,
- const LLColor4 &color,
- HAlign halign = LEFT, VAlign valign = BASELINE,
- U8 style = NORMAL, ShadowType shadow = NO_SHADOW,
- S32 max_chars = S32_MAX,
- F32* right_x=NULL,
- BOOL use_ellipses = FALSE,
- BOOL use_color = TRUE) const;
-
- S32 render(const LLWString &text, S32 begin_offset,
- F32 x, F32 y,
- const LLColor4 &color,
- HAlign halign = LEFT, VAlign valign = BASELINE,
- U8 style = NORMAL, ShadowType shadow = NO_SHADOW,
- S32 max_chars = S32_MAX, S32 max_pixels = S32_MAX,
- F32* right_x=NULL,
- BOOL use_ellipses = FALSE,
- BOOL use_color = TRUE) const;
-
- S32 render(const LLWString &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color) const;
-
- // renderUTF8 does a conversion, so is slower!
- S32 renderUTF8(const std::string &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style, ShadowType shadow, S32 max_chars = S32_MAX, S32 max_pixels = S32_MAX, F32* right_x = NULL, BOOL use_ellipses = FALSE, BOOL use_color = TRUE) const;
- S32 renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y, const LLColor4 &color) const;
- S32 renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style = NORMAL, ShadowType shadow = NO_SHADOW) const;
-
- // font metrics - override for LLFontFreetype that returns units of virtual pixels
- F32 getAscenderHeight() const;
- F32 getDescenderHeight() const;
- S32 getLineHeight() const;
-
- S32 getWidth(const std::string& utf8text) const;
- S32 getWidth(const llwchar* wchars) const;
- S32 getWidth(const std::string& utf8text, S32 offset, S32 max_chars) const;
- S32 getWidth(const llwchar* wchars, S32 offset, S32 max_chars) const;
-
- F32 getWidthF32(const std::string& utf8text) const;
- F32 getWidthF32(const llwchar* wchars) const;
- F32 getWidthF32(const std::string& text, S32 offset, S32 max_chars) const;
- F32 getWidthF32(const llwchar* wchars, S32 offset, S32 max_chars, bool no_padding = false) const;
-
- // The following are called often, frequently with large buffers, so do not use a string interface
-
- // Returns the max number of complete characters from text (up to max_chars) that can be drawn in max_pixels
- typedef enum e_word_wrap_style
- {
- ONLY_WORD_BOUNDARIES,
- WORD_BOUNDARY_IF_POSSIBLE,
- ANYWHERE
- } EWordWrapStyle ;
- S32 maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_chars = S32_MAX, EWordWrapStyle end_on_word_boundary = ANYWHERE) const;
-
- // Returns the index of the first complete characters from text that can be drawn in max_pixels
- // given that the character at start_pos should be the last character (or as close to last as possible).
- S32 firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_len, S32 start_pos=S32_MAX, S32 max_chars = S32_MAX) const;
-
- // Returns the index of the character closest to pixel position x (ignoring text to the right of max_pixels and max_chars)
- S32 charFromPixelOffset(const llwchar* wchars, S32 char_offset, F32 x, F32 max_pixels=F32_MAX, S32 max_chars = S32_MAX, BOOL round = TRUE) const;
-
- const LLFontDescriptor& getFontDesc() const;
-
- void generateASCIIglyphs();
-
-
- static void initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, const std::string& app_dir, bool create_gl_textures = true);
-
- void dumpTextures();
- static void dumpFonts();
- static void dumpFontTextures();
-
- // Load sans-serif, sans-serif-small, etc.
- // Slow, requires multiple seconds to load fonts.
- static bool loadDefaultFonts();
+ enum HAlign
+ {
+ // Horizontal location of x,y coord to render.
+ LEFT = 0, // Left align
+ RIGHT = 1, // Right align
+ HCENTER = 2, // Center
+ };
+
+ enum VAlign
+ {
+ // Vertical location of x,y coord to render.
+ TOP = 3, // Top align
+ VCENTER = 4, // Center
+ BASELINE = 5, // Baseline
+ BOTTOM = 6 // Bottom
+ };
+
+ enum StyleFlags
+ {
+ // text style to render. May be combined (these are bit flags)
+ NORMAL = 0x00,
+ BOLD = 0x01,
+ ITALIC = 0x02,
+ UNDERLINE = 0x04
+ };
+
+ enum ShadowType
+ {
+ NO_SHADOW,
+ DROP_SHADOW,
+ DROP_SHADOW_SOFT
+ };
+
+ LLFontGL();
+ ~LLFontGL();
+
+
+ void reset(); // Reset a font after GL cleanup. ONLY works on an already loaded font.
+
+ void destroyGL();
+
+ BOOL loadFace(const std::string& filename, F32 point_size, const F32 vert_dpi, const F32 horz_dpi, bool is_fallback, S32 face_n);
+
+ S32 getNumFaces(const std::string& filename);
+
+ S32 render(const LLWString &text, S32 begin_offset,
+ const LLRect& rect,
+ const LLColor4 &color,
+ HAlign halign = LEFT, VAlign valign = BASELINE,
+ U8 style = NORMAL, ShadowType shadow = NO_SHADOW,
+ S32 max_chars = S32_MAX,
+ F32* right_x=NULL,
+ BOOL use_ellipses = FALSE,
+ BOOL use_color = TRUE) const;
+
+ S32 render(const LLWString &text, S32 begin_offset,
+ const LLRectf& rect,
+ const LLColor4 &color,
+ HAlign halign = LEFT, VAlign valign = BASELINE,
+ U8 style = NORMAL, ShadowType shadow = NO_SHADOW,
+ S32 max_chars = S32_MAX,
+ F32* right_x=NULL,
+ BOOL use_ellipses = FALSE,
+ BOOL use_color = TRUE) const;
+
+ S32 render(const LLWString &text, S32 begin_offset,
+ F32 x, F32 y,
+ const LLColor4 &color,
+ HAlign halign = LEFT, VAlign valign = BASELINE,
+ U8 style = NORMAL, ShadowType shadow = NO_SHADOW,
+ S32 max_chars = S32_MAX, S32 max_pixels = S32_MAX,
+ F32* right_x=NULL,
+ BOOL use_ellipses = FALSE,
+ BOOL use_color = TRUE) const;
+
+ S32 render(const LLWString &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color) const;
+
+ // renderUTF8 does a conversion, so is slower!
+ S32 renderUTF8(const std::string &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style, ShadowType shadow, S32 max_chars = S32_MAX, S32 max_pixels = S32_MAX, F32* right_x = NULL, BOOL use_ellipses = FALSE, BOOL use_color = TRUE) const;
+ S32 renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y, const LLColor4 &color) const;
+ S32 renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style = NORMAL, ShadowType shadow = NO_SHADOW) const;
+
+ // font metrics - override for LLFontFreetype that returns units of virtual pixels
+ F32 getAscenderHeight() const;
+ F32 getDescenderHeight() const;
+ S32 getLineHeight() const;
+
+ S32 getWidth(const std::string& utf8text) const;
+ S32 getWidth(const llwchar* wchars) const;
+ S32 getWidth(const std::string& utf8text, S32 offset, S32 max_chars) const;
+ S32 getWidth(const llwchar* wchars, S32 offset, S32 max_chars) const;
+
+ F32 getWidthF32(const std::string& utf8text) const;
+ F32 getWidthF32(const llwchar* wchars) const;
+ F32 getWidthF32(const std::string& text, S32 offset, S32 max_chars) const;
+ F32 getWidthF32(const llwchar* wchars, S32 offset, S32 max_chars, bool no_padding = false) const;
+
+ // The following are called often, frequently with large buffers, so do not use a string interface
+
+ // Returns the max number of complete characters from text (up to max_chars) that can be drawn in max_pixels
+ typedef enum e_word_wrap_style
+ {
+ ONLY_WORD_BOUNDARIES,
+ WORD_BOUNDARY_IF_POSSIBLE,
+ ANYWHERE
+ } EWordWrapStyle ;
+ S32 maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_chars = S32_MAX, EWordWrapStyle end_on_word_boundary = ANYWHERE) const;
+
+ // Returns the index of the first complete characters from text that can be drawn in max_pixels
+ // given that the character at start_pos should be the last character (or as close to last as possible).
+ S32 firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_len, S32 start_pos=S32_MAX, S32 max_chars = S32_MAX) const;
+
+ // Returns the index of the character closest to pixel position x (ignoring text to the right of max_pixels and max_chars)
+ S32 charFromPixelOffset(const llwchar* wchars, S32 char_offset, F32 x, F32 max_pixels=F32_MAX, S32 max_chars = S32_MAX, BOOL round = TRUE) const;
+
+ const LLFontDescriptor& getFontDesc() const;
+
+ void generateASCIIglyphs();
+
+
+ static void initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, const std::string& app_dir, bool create_gl_textures = true);
+
+ void dumpTextures();
+ static void dumpFonts();
+ static void dumpFontTextures();
+
+ // Load sans-serif, sans-serif-small, etc.
+ // Slow, requires multiple seconds to load fonts.
+ static bool loadDefaultFonts();
static void loadCommonFonts();
- static void destroyDefaultFonts();
- static void destroyAllGL();
+ static void destroyDefaultFonts();
+ static void destroyAllGL();
+
+ // Takes a string with potentially several flags, i.e. "NORMAL|BOLD|ITALIC"
+ static U8 getStyleFromString(const std::string &style);
+ static std::string getStringFromStyle(U8 style);
- // Takes a string with potentially several flags, i.e. "NORMAL|BOLD|ITALIC"
- static U8 getStyleFromString(const std::string &style);
- static std::string getStringFromStyle(U8 style);
+ static std::string nameFromFont(const LLFontGL* fontp);
+ static std::string sizeFromFont(const LLFontGL* fontp);
- static std::string nameFromFont(const LLFontGL* fontp);
- static std::string sizeFromFont(const LLFontGL* fontp);
+ static std::string nameFromHAlign(LLFontGL::HAlign align);
+ static LLFontGL::HAlign hAlignFromName(const std::string& name);
- static std::string nameFromHAlign(LLFontGL::HAlign align);
- static LLFontGL::HAlign hAlignFromName(const std::string& name);
+ static std::string nameFromVAlign(LLFontGL::VAlign align);
+ static LLFontGL::VAlign vAlignFromName(const std::string& name);
- static std::string nameFromVAlign(LLFontGL::VAlign align);
- static LLFontGL::VAlign vAlignFromName(const std::string& name);
+ static void setFontDisplay(BOOL flag) { sDisplayFont = flag; }
- static void setFontDisplay(BOOL flag) { sDisplayFont = flag; }
-
- static LLFontGL* getFontEmoji();
- static LLFontGL* getFontEmojiHuge();
- static LLFontGL* getFontMonospace();
- static LLFontGL* getFontSansSerifSmall();
+ static LLFontGL* getFontEmoji();
+ static LLFontGL* getFontEmojiHuge();
+ static LLFontGL* getFontMonospace();
+ static LLFontGL* getFontSansSerifSmall();
static LLFontGL* getFontSansSerifSmallBold();
static LLFontGL* getFontSansSerifSmallItalic();
- static LLFontGL* getFontSansSerif();
- static LLFontGL* getFontSansSerifBig();
- static LLFontGL* getFontSansSerifHuge();
- static LLFontGL* getFontSansSerifBold();
- static LLFontGL* getFont(const LLFontDescriptor& desc);
- // Use with legacy names like "SANSSERIF_SMALL" or "OCRA"
- static LLFontGL* getFontByName(const std::string& name);
- static LLFontGL* getFontDefault(); // default fallback font
-
- static std::string getFontPathLocal();
- static std::string getFontPathSystem();
-
- static LLCoordGL sCurOrigin;
- static F32 sCurDepth;
- static std::vector<std::pair<LLCoordGL, F32> > sOriginStack;
-
- static LLColor4 sShadowColor;
-
- static F32 sVertDPI;
- static F32 sHorizDPI;
- static F32 sScaleX;
- static F32 sScaleY;
- static BOOL sDisplayFont ;
- static std::string sAppDir; // For loading fonts
+ static LLFontGL* getFontSansSerif();
+ static LLFontGL* getFontSansSerifBig();
+ static LLFontGL* getFontSansSerifHuge();
+ static LLFontGL* getFontSansSerifBold();
+ static LLFontGL* getFont(const LLFontDescriptor& desc);
+ // Use with legacy names like "SANSSERIF_SMALL" or "OCRA"
+ static LLFontGL* getFontByName(const std::string& name);
+ static LLFontGL* getFontDefault(); // default fallback font
+
+ static std::string getFontPathLocal();
+ static std::string getFontPathSystem();
+
+ static LLCoordGL sCurOrigin;
+ static F32 sCurDepth;
+ static std::vector<std::pair<LLCoordGL, F32> > sOriginStack;
+
+ static LLColor4 sShadowColor;
+
+ static F32 sVertDPI;
+ static F32 sHorizDPI;
+ static F32 sScaleX;
+ static F32 sScaleY;
+ static BOOL sDisplayFont ;
+ static std::string sAppDir; // For loading fonts
private:
- friend class LLFontRegistry;
- friend class LLTextBillboard;
- friend class LLHUDText;
+ friend class LLFontRegistry;
+ friend class LLTextBillboard;
+ friend class LLHUDText;
- LLFontGL(const LLFontGL &source);
- LLFontGL &operator=(const LLFontGL &source);
+ LLFontGL(const LLFontGL &source);
+ LLFontGL &operator=(const LLFontGL &source);
- LLFontDescriptor mFontDescriptor;
- LLPointer<LLFontFreetype> mFontFreetype;
+ LLFontDescriptor mFontDescriptor;
+ LLPointer<LLFontFreetype> mFontFreetype;
- void renderQuad(LLVector3* vertex_out, LLVector2* uv_out, LLColor4U* colors_out, const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4U& color, F32 slant_amt) const;
- void drawGlyph(S32& glyph_count, LLVector3* vertex_out, LLVector2* uv_out, LLColor4U* colors_out, const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4U& color, U8 style, ShadowType shadow, F32 drop_shadow_fade) const;
+ void renderQuad(LLVector3* vertex_out, LLVector2* uv_out, LLColor4U* colors_out, const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4U& color, F32 slant_amt) const;
+ void drawGlyph(S32& glyph_count, LLVector3* vertex_out, LLVector2* uv_out, LLColor4U* colors_out, const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4U& color, U8 style, ShadowType shadow, F32 drop_shadow_fade) const;
- // Registry holds all instantiated fonts.
- static LLFontRegistry* sFontRegistry;
+ // Registry holds all instantiated fonts.
+ static LLFontRegistry* sFontRegistry;
};
#endif
diff --git a/indra/llrender/llfontregistry.cpp b/indra/llrender/llfontregistry.cpp
index d2c7e466e6..546211aac8 100644
--- a/indra/llrender/llfontregistry.cpp
+++ b/indra/llrender/llfontregistry.cpp
@@ -1,4 +1,4 @@
-/**
+/**
* @file llfontregistry.cpp
* @author Brad Payne
* @brief Storage for fonts.
@@ -6,21 +6,21 @@
* $LicenseInfo:firstyear=2008&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -48,90 +48,90 @@ const std::string MACOSX_FONT_PATH_LIBRARY = "/Library/Fonts/";
const std::string MACOSX_FONT_SUPPLEMENTAL = "Supplemental/";
LLFontDescriptor::char_functor_map_t LLFontDescriptor::mCharFunctors({
- { "is_emoji", LLStringOps::isEmoji }
+ { "is_emoji", LLStringOps::isEmoji }
});
LLFontDescriptor::LLFontDescriptor():
- mStyle(0)
+ mStyle(0)
{
}
LLFontDescriptor::LLFontDescriptor(const std::string& name,
- const std::string& size,
- const U8 style,
- const font_file_info_vec_t& font_files):
- mName(name),
- mSize(size),
- mStyle(style),
- mFontFiles(font_files)
+ const std::string& size,
+ const U8 style,
+ const font_file_info_vec_t& font_files):
+ mName(name),
+ mSize(size),
+ mStyle(style),
+ mFontFiles(font_files)
{
}
LLFontDescriptor::LLFontDescriptor(const std::string& name,
- const std::string& size,
- const U8 style,
- const font_file_info_vec_t& font_list,
- const font_file_info_vec_t& font_collection_files) :
- LLFontDescriptor(name, size, style, font_list)
+ const std::string& size,
+ const U8 style,
+ const font_file_info_vec_t& font_list,
+ const font_file_info_vec_t& font_collection_files) :
+ LLFontDescriptor(name, size, style, font_list)
{
- mFontCollectionFiles = font_collection_files;
+ mFontCollectionFiles = font_collection_files;
}
LLFontDescriptor::LLFontDescriptor(const std::string& name,
- const std::string& size,
- const U8 style):
- mName(name),
- mSize(size),
- mStyle(style)
+ const std::string& size,
+ const U8 style):
+ mName(name),
+ mSize(size),
+ mStyle(style)
{
}
bool LLFontDescriptor::operator<(const LLFontDescriptor& b) const
{
- if (mName < b.mName)
- return true;
- else if (mName > b.mName)
- return false;
-
- if (mStyle < b.mStyle)
- return true;
- else if (mStyle > b.mStyle)
- return false;
-
- if (mSize < b.mSize)
- return true;
- else
- return false;
+ if (mName < b.mName)
+ return true;
+ else if (mName > b.mName)
+ return false;
+
+ if (mStyle < b.mStyle)
+ return true;
+ else if (mStyle > b.mStyle)
+ return false;
+
+ if (mSize < b.mSize)
+ return true;
+ else
+ return false;
}
static const std::string s_template_string("TEMPLATE");
bool LLFontDescriptor::isTemplate() const
{
- return getSize() == s_template_string;
+ return getSize() == s_template_string;
}
// Look for substring match and remove substring if matched.
bool removeSubString(std::string& str, const std::string& substr)
{
- size_t pos = str.find(substr);
- if (pos != string::npos)
- {
- str.erase(pos, substr.size());
- return true;
- }
- return false;
+ size_t pos = str.find(substr);
+ if (pos != string::npos)
+ {
+ str.erase(pos, substr.size());
+ return true;
+ }
+ return false;
}
// Check for substring match without modifying the source string.
bool findSubString(std::string& str, const std::string& substr)
{
- size_t pos = str.find(substr);
- if (pos != string::npos)
- {
- return true;
- }
- return false;
+ size_t pos = str.find(substr);
+ if (pos != string::npos)
+ {
+ return true;
+ }
+ return false;
}
@@ -145,618 +145,618 @@ bool findSubString(std::string& str, const std::string& substr)
// - "SansSerifBold" would normalize to { "SansSerifBold", "Medium", BOLD }
LLFontDescriptor LLFontDescriptor::normalize() const
{
- std::string new_name(mName);
- std::string new_size(mSize);
- U8 new_style(mStyle);
-
- // Only care about style to extent it can be picked up by font.
- new_style &= (LLFontGL::BOLD | LLFontGL::ITALIC);
-
- // All these transformations are to support old-style font specifications.
- if (removeSubString(new_name,"Small"))
- new_size = "Small";
- if (removeSubString(new_name,"Big"))
- new_size = "Large";
- if (removeSubString(new_name,"Medium"))
- new_size = "Medium";
- if (removeSubString(new_name,"Large"))
- new_size = "Large";
- if (removeSubString(new_name,"Huge"))
- new_size = "Huge";
-
- // HACK - Monospace is the only one we don't remove, so
- // name "Monospace" doesn't get taken down to ""
- // For other fonts, there's no ambiguity between font name and size specifier.
- if (new_size != s_template_string && new_size.empty() && findSubString(new_name,"Monospace"))
- new_size = "Monospace";
- if (new_size.empty())
- new_size = "Medium";
-
- if (removeSubString(new_name,"Bold"))
- new_style |= LLFontGL::BOLD;
-
- if (removeSubString(new_name,"Italic"))
- new_style |= LLFontGL::ITALIC;
-
- return LLFontDescriptor(new_name,new_size,new_style, getFontFiles(), getFontCollectionFiles());
+ std::string new_name(mName);
+ std::string new_size(mSize);
+ U8 new_style(mStyle);
+
+ // Only care about style to extent it can be picked up by font.
+ new_style &= (LLFontGL::BOLD | LLFontGL::ITALIC);
+
+ // All these transformations are to support old-style font specifications.
+ if (removeSubString(new_name,"Small"))
+ new_size = "Small";
+ if (removeSubString(new_name,"Big"))
+ new_size = "Large";
+ if (removeSubString(new_name,"Medium"))
+ new_size = "Medium";
+ if (removeSubString(new_name,"Large"))
+ new_size = "Large";
+ if (removeSubString(new_name,"Huge"))
+ new_size = "Huge";
+
+ // HACK - Monospace is the only one we don't remove, so
+ // name "Monospace" doesn't get taken down to ""
+ // For other fonts, there's no ambiguity between font name and size specifier.
+ if (new_size != s_template_string && new_size.empty() && findSubString(new_name,"Monospace"))
+ new_size = "Monospace";
+ if (new_size.empty())
+ new_size = "Medium";
+
+ if (removeSubString(new_name,"Bold"))
+ new_style |= LLFontGL::BOLD;
+
+ if (removeSubString(new_name,"Italic"))
+ new_style |= LLFontGL::ITALIC;
+
+ return LLFontDescriptor(new_name,new_size,new_style, getFontFiles(), getFontCollectionFiles());
}
void LLFontDescriptor::addFontFile(const std::string& file_name, const std::string& char_functor)
{
- char_functor_map_t::const_iterator it = mCharFunctors.find(char_functor);
- mFontFiles.push_back(LLFontFileInfo(file_name, (mCharFunctors.end() != it) ? it->second : nullptr));
+ char_functor_map_t::const_iterator it = mCharFunctors.find(char_functor);
+ mFontFiles.push_back(LLFontFileInfo(file_name, (mCharFunctors.end() != it) ? it->second : nullptr));
}
void LLFontDescriptor::addFontCollectionFile(const std::string& file_name, const std::string& char_functor)
{
- char_functor_map_t::const_iterator it = mCharFunctors.find(char_functor);
- mFontCollectionFiles.push_back(LLFontFileInfo(file_name, (mCharFunctors.end() != it) ? it->second : nullptr));
+ char_functor_map_t::const_iterator it = mCharFunctors.find(char_functor);
+ mFontCollectionFiles.push_back(LLFontFileInfo(file_name, (mCharFunctors.end() != it) ? it->second : nullptr));
}
LLFontRegistry::LLFontRegistry(bool create_gl_textures)
-: mCreateGLTextures(create_gl_textures)
+: mCreateGLTextures(create_gl_textures)
{
- // This is potentially a slow directory traversal, so we want to
- // cache the result.
- mUltimateFallbackList = LLWindow::getDynamicFallbackFontList();
+ // This is potentially a slow directory traversal, so we want to
+ // cache the result.
+ mUltimateFallbackList = LLWindow::getDynamicFallbackFontList();
}
LLFontRegistry::~LLFontRegistry()
{
- clear();
+ clear();
}
bool LLFontRegistry::parseFontInfo(const std::string& xml_filename)
{
- bool success = false; // Succeed if we find and read at least one XUI file
- const string_vec_t xml_paths = gDirUtilp->findSkinnedFilenames(LLDir::XUI, xml_filename);
- if (xml_paths.empty())
- {
- // We didn't even find one single XUI file
- return false;
- }
-
- for (string_vec_t::const_iterator path_it = xml_paths.begin();
- path_it != xml_paths.end();
- ++path_it)
- {
- LLXMLNodePtr root;
- bool parsed_file = LLXMLNode::parseFile(*path_it, root, NULL);
-
- if (!parsed_file)
- continue;
-
- if ( root.isNull() || ! root->hasName( "fonts" ) )
- {
- LL_WARNS() << "Bad font info file: " << *path_it << LL_ENDL;
- continue;
- }
-
- std::string root_name;
- root->getAttributeString("name",root_name);
- if (root->hasName("fonts"))
- {
- // Expect a collection of children consisting of "font" or "font_size" entries
- bool init_succ = init_from_xml(this, root);
- success = success || init_succ;
- }
- }
-
- //if (success)
- // dump();
-
- return success;
+ bool success = false; // Succeed if we find and read at least one XUI file
+ const string_vec_t xml_paths = gDirUtilp->findSkinnedFilenames(LLDir::XUI, xml_filename);
+ if (xml_paths.empty())
+ {
+ // We didn't even find one single XUI file
+ return false;
+ }
+
+ for (string_vec_t::const_iterator path_it = xml_paths.begin();
+ path_it != xml_paths.end();
+ ++path_it)
+ {
+ LLXMLNodePtr root;
+ bool parsed_file = LLXMLNode::parseFile(*path_it, root, NULL);
+
+ if (!parsed_file)
+ continue;
+
+ if ( root.isNull() || ! root->hasName( "fonts" ) )
+ {
+ LL_WARNS() << "Bad font info file: " << *path_it << LL_ENDL;
+ continue;
+ }
+
+ std::string root_name;
+ root->getAttributeString("name",root_name);
+ if (root->hasName("fonts"))
+ {
+ // Expect a collection of children consisting of "font" or "font_size" entries
+ bool init_succ = init_from_xml(this, root);
+ success = success || init_succ;
+ }
+ }
+
+ //if (success)
+ // dump();
+
+ return success;
}
std::string currentOsName()
{
#if LL_WINDOWS
- return "Windows";
+ return "Windows";
#elif LL_DARWIN
- return "Mac";
+ return "Mac";
#elif LL_LINUX
- return "Linux";
+ return "Linux";
#else
- return "";
+ return "";
#endif
}
bool font_desc_init_from_xml(LLXMLNodePtr node, LLFontDescriptor& desc)
{
- if (node->hasName("font"))
- {
- std::string attr_name;
- if (node->getAttributeString("name",attr_name))
- {
- desc.setName(attr_name);
- }
-
- std::string attr_style;
- if (node->getAttributeString("font_style",attr_style))
- {
- desc.setStyle(LLFontGL::getStyleFromString(attr_style));
- }
-
- desc.setSize(s_template_string);
- }
-
- LLXMLNodePtr child;
- for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling())
- {
- std::string child_name;
- child->getAttributeString("name",child_name);
- if (child->hasName("file"))
- {
- std::string font_file_name = child->getTextContents();
- std::string char_functor;
-
- if (child->hasAttribute("functor"))
- {
- child->getAttributeString("functor", char_functor);
- }
-
- if (child->hasAttribute("load_collection"))
- {
- BOOL col = FALSE;
- child->getAttributeBOOL("load_collection", col);
- if (col)
- {
- desc.addFontCollectionFile(font_file_name, char_functor);
- }
- }
-
- desc.addFontFile(font_file_name, char_functor);
- }
- else if (child->hasName("os"))
- {
- if (child_name == currentOsName())
- {
- font_desc_init_from_xml(child, desc);
- }
- }
- }
- return true;
+ if (node->hasName("font"))
+ {
+ std::string attr_name;
+ if (node->getAttributeString("name",attr_name))
+ {
+ desc.setName(attr_name);
+ }
+
+ std::string attr_style;
+ if (node->getAttributeString("font_style",attr_style))
+ {
+ desc.setStyle(LLFontGL::getStyleFromString(attr_style));
+ }
+
+ desc.setSize(s_template_string);
+ }
+
+ LLXMLNodePtr child;
+ for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling())
+ {
+ std::string child_name;
+ child->getAttributeString("name",child_name);
+ if (child->hasName("file"))
+ {
+ std::string font_file_name = child->getTextContents();
+ std::string char_functor;
+
+ if (child->hasAttribute("functor"))
+ {
+ child->getAttributeString("functor", char_functor);
+ }
+
+ if (child->hasAttribute("load_collection"))
+ {
+ BOOL col = FALSE;
+ child->getAttributeBOOL("load_collection", col);
+ if (col)
+ {
+ desc.addFontCollectionFile(font_file_name, char_functor);
+ }
+ }
+
+ desc.addFontFile(font_file_name, char_functor);
+ }
+ else if (child->hasName("os"))
+ {
+ if (child_name == currentOsName())
+ {
+ font_desc_init_from_xml(child, desc);
+ }
+ }
+ }
+ return true;
}
bool init_from_xml(LLFontRegistry* registry, LLXMLNodePtr node)
{
- LLXMLNodePtr child;
-
- for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling())
- {
- std::string child_name;
- child->getAttributeString("name",child_name);
- if (child->hasName("font"))
- {
- LLFontDescriptor desc;
- bool font_succ = font_desc_init_from_xml(child, desc);
- LLFontDescriptor norm_desc = desc.normalize();
- if (font_succ)
- {
- // if this is the first time we've seen this font name,
- // create a new template map entry for it.
- const LLFontDescriptor *match_desc = registry->getMatchingFontDesc(desc);
- if (match_desc == NULL)
- {
- // Create a new entry (with no corresponding font).
- registry->mFontMap[norm_desc] = NULL;
- }
- // otherwise, find the existing entry and combine data.
- else
- {
- // Prepend files from desc.
- // A little roundabout because the map key is const,
- // so we have to fetch it, make a new map key, and
- // replace the old entry.
- font_file_info_vec_t font_files = match_desc->getFontFiles();
- font_files.insert(font_files.begin(),
- desc.getFontFiles().begin(),
- desc.getFontFiles().end());
-
- font_file_info_vec_t font_collection_files = match_desc->getFontCollectionFiles();
- font_collection_files.insert(font_collection_files.begin(),
- desc.getFontCollectionFiles().begin(),
- desc.getFontCollectionFiles().end());
-
- LLFontDescriptor new_desc = *match_desc;
- new_desc.setFontFiles(font_files);
- new_desc.setFontCollectionFiles(font_collection_files);
- registry->mFontMap.erase(*match_desc);
- registry->mFontMap[new_desc] = NULL;
- }
- }
- }
- else if (child->hasName("font_size"))
- {
- std::string size_name;
- F32 size_value;
- if (child->getAttributeString("name",size_name) &&
- child->getAttributeF32("size",size_value))
- {
- registry->mFontSizes[size_name] = size_value;
- }
-
- }
- }
- return true;
+ LLXMLNodePtr child;
+
+ for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling())
+ {
+ std::string child_name;
+ child->getAttributeString("name",child_name);
+ if (child->hasName("font"))
+ {
+ LLFontDescriptor desc;
+ bool font_succ = font_desc_init_from_xml(child, desc);
+ LLFontDescriptor norm_desc = desc.normalize();
+ if (font_succ)
+ {
+ // if this is the first time we've seen this font name,
+ // create a new template map entry for it.
+ const LLFontDescriptor *match_desc = registry->getMatchingFontDesc(desc);
+ if (match_desc == NULL)
+ {
+ // Create a new entry (with no corresponding font).
+ registry->mFontMap[norm_desc] = NULL;
+ }
+ // otherwise, find the existing entry and combine data.
+ else
+ {
+ // Prepend files from desc.
+ // A little roundabout because the map key is const,
+ // so we have to fetch it, make a new map key, and
+ // replace the old entry.
+ font_file_info_vec_t font_files = match_desc->getFontFiles();
+ font_files.insert(font_files.begin(),
+ desc.getFontFiles().begin(),
+ desc.getFontFiles().end());
+
+ font_file_info_vec_t font_collection_files = match_desc->getFontCollectionFiles();
+ font_collection_files.insert(font_collection_files.begin(),
+ desc.getFontCollectionFiles().begin(),
+ desc.getFontCollectionFiles().end());
+
+ LLFontDescriptor new_desc = *match_desc;
+ new_desc.setFontFiles(font_files);
+ new_desc.setFontCollectionFiles(font_collection_files);
+ registry->mFontMap.erase(*match_desc);
+ registry->mFontMap[new_desc] = NULL;
+ }
+ }
+ }
+ else if (child->hasName("font_size"))
+ {
+ std::string size_name;
+ F32 size_value;
+ if (child->getAttributeString("name",size_name) &&
+ child->getAttributeF32("size",size_value))
+ {
+ registry->mFontSizes[size_name] = size_value;
+ }
+
+ }
+ }
+ return true;
}
bool LLFontRegistry::nameToSize(const std::string& size_name, F32& size)
{
- font_size_map_t::iterator it = mFontSizes.find(size_name);
- if (it != mFontSizes.end())
- {
- size = it->second;
- return true;
- }
- return false;
+ font_size_map_t::iterator it = mFontSizes.find(size_name);
+ if (it != mFontSizes.end())
+ {
+ size = it->second;
+ return true;
+ }
+ return false;
}
LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc)
{
- // Name should hold a font name recognized as a setting; the value
- // of the setting should be a list of font files.
- // Size should be a recognized string value
- // Style should be a set of flags including any implied by the font name.
-
- // First decipher the requested size.
- LLFontDescriptor norm_desc = desc.normalize();
- F32 point_size;
- bool found_size = nameToSize(norm_desc.getSize(),point_size);
- if (!found_size)
- {
- LL_WARNS() << "createFont unrecognized size " << norm_desc.getSize() << LL_ENDL;
- return NULL;
- }
- LL_INFOS() << "createFont " << norm_desc.getName() << " size " << norm_desc.getSize() << " style " << ((S32) norm_desc.getStyle()) << LL_ENDL;
- F32 fallback_scale = 1.0;
-
- // Find corresponding font template (based on same descriptor with no size specified)
- LLFontDescriptor template_desc(norm_desc);
- template_desc.setSize(s_template_string);
- const LLFontDescriptor *match_desc = getClosestFontTemplate(template_desc);
- if (!match_desc)
- {
- LL_WARNS() << "createFont failed, no template found for "
- << norm_desc.getName() << " style [" << ((S32)norm_desc.getStyle()) << "]" << LL_ENDL;
- return NULL;
- }
-
- // See whether this best-match font has already been instantiated in the requested size.
- LLFontDescriptor nearest_exact_desc = *match_desc;
- nearest_exact_desc.setSize(norm_desc.getSize());
- font_reg_map_t::iterator it = mFontMap.find(nearest_exact_desc);
- // If we fail to find a font in the fonts directory, it->second might be NULL.
- // We shouldn't construcnt a font with a NULL mFontFreetype.
- // This may not be the best solution, but it at least prevents a crash.
- if (it != mFontMap.end() && it->second != NULL)
- {
- LL_INFOS() << "-- matching font exists: " << nearest_exact_desc.getName() << " size " << nearest_exact_desc.getSize() << " style " << ((S32) nearest_exact_desc.getStyle()) << LL_ENDL;
-
- // copying underlying Freetype font, and storing in LLFontGL with requested font descriptor
- LLFontGL *font = new LLFontGL;
- font->mFontDescriptor = desc;
- font->mFontFreetype = it->second->mFontFreetype;
- mFontMap[desc] = font;
-
- return font;
- }
-
- // Build list of font names to look for.
- // Files specified for this font come first, followed by those from the default descriptor.
- font_file_info_vec_t font_files = match_desc->getFontFiles();
- font_file_info_vec_t font_collection_files = match_desc->getFontCollectionFiles();
- LLFontDescriptor default_desc("default",s_template_string,0);
- const LLFontDescriptor *match_default_desc = getMatchingFontDesc(default_desc);
- if (match_default_desc)
- {
- font_files.insert(font_files.end(),
- match_default_desc->getFontFiles().begin(),
- match_default_desc->getFontFiles().end());
- font_collection_files.insert(font_collection_files.end(),
- match_default_desc->getFontCollectionFiles().begin(),
- match_default_desc->getFontCollectionFiles().end());
- }
-
- // Add ultimate fallback list - generated dynamically on linux,
- // null elsewhere.
- std::transform(getUltimateFallbackList().begin(), getUltimateFallbackList().end(), std::back_inserter(font_files),
- [](const std::string& file_name) { return LLFontFileInfo(file_name); });
-
- // Load fonts based on names.
- if (font_files.empty())
- {
- LL_WARNS() << "createFont failed, no file names specified" << LL_ENDL;
- return NULL;
- }
-
- LLFontGL *result = NULL;
-
- // The first font will get pulled will be the "head" font, set to non-fallback.
- // Rest will consitute the fallback list.
- BOOL is_first_found = TRUE;
-
- string_vec_t font_search_paths;
- font_search_paths.push_back(LLFontGL::getFontPathLocal());
- font_search_paths.push_back(LLFontGL::getFontPathSystem());
+ // Name should hold a font name recognized as a setting; the value
+ // of the setting should be a list of font files.
+ // Size should be a recognized string value
+ // Style should be a set of flags including any implied by the font name.
+
+ // First decipher the requested size.
+ LLFontDescriptor norm_desc = desc.normalize();
+ F32 point_size;
+ bool found_size = nameToSize(norm_desc.getSize(),point_size);
+ if (!found_size)
+ {
+ LL_WARNS() << "createFont unrecognized size " << norm_desc.getSize() << LL_ENDL;
+ return NULL;
+ }
+ LL_INFOS() << "createFont " << norm_desc.getName() << " size " << norm_desc.getSize() << " style " << ((S32) norm_desc.getStyle()) << LL_ENDL;
+ F32 fallback_scale = 1.0;
+
+ // Find corresponding font template (based on same descriptor with no size specified)
+ LLFontDescriptor template_desc(norm_desc);
+ template_desc.setSize(s_template_string);
+ const LLFontDescriptor *match_desc = getClosestFontTemplate(template_desc);
+ if (!match_desc)
+ {
+ LL_WARNS() << "createFont failed, no template found for "
+ << norm_desc.getName() << " style [" << ((S32)norm_desc.getStyle()) << "]" << LL_ENDL;
+ return NULL;
+ }
+
+ // See whether this best-match font has already been instantiated in the requested size.
+ LLFontDescriptor nearest_exact_desc = *match_desc;
+ nearest_exact_desc.setSize(norm_desc.getSize());
+ font_reg_map_t::iterator it = mFontMap.find(nearest_exact_desc);
+ // If we fail to find a font in the fonts directory, it->second might be NULL.
+ // We shouldn't construcnt a font with a NULL mFontFreetype.
+ // This may not be the best solution, but it at least prevents a crash.
+ if (it != mFontMap.end() && it->second != NULL)
+ {
+ LL_INFOS() << "-- matching font exists: " << nearest_exact_desc.getName() << " size " << nearest_exact_desc.getSize() << " style " << ((S32) nearest_exact_desc.getStyle()) << LL_ENDL;
+
+ // copying underlying Freetype font, and storing in LLFontGL with requested font descriptor
+ LLFontGL *font = new LLFontGL;
+ font->mFontDescriptor = desc;
+ font->mFontFreetype = it->second->mFontFreetype;
+ mFontMap[desc] = font;
+
+ return font;
+ }
+
+ // Build list of font names to look for.
+ // Files specified for this font come first, followed by those from the default descriptor.
+ font_file_info_vec_t font_files = match_desc->getFontFiles();
+ font_file_info_vec_t font_collection_files = match_desc->getFontCollectionFiles();
+ LLFontDescriptor default_desc("default",s_template_string,0);
+ const LLFontDescriptor *match_default_desc = getMatchingFontDesc(default_desc);
+ if (match_default_desc)
+ {
+ font_files.insert(font_files.end(),
+ match_default_desc->getFontFiles().begin(),
+ match_default_desc->getFontFiles().end());
+ font_collection_files.insert(font_collection_files.end(),
+ match_default_desc->getFontCollectionFiles().begin(),
+ match_default_desc->getFontCollectionFiles().end());
+ }
+
+ // Add ultimate fallback list - generated dynamically on linux,
+ // null elsewhere.
+ std::transform(getUltimateFallbackList().begin(), getUltimateFallbackList().end(), std::back_inserter(font_files),
+ [](const std::string& file_name) { return LLFontFileInfo(file_name); });
+
+ // Load fonts based on names.
+ if (font_files.empty())
+ {
+ LL_WARNS() << "createFont failed, no file names specified" << LL_ENDL;
+ return NULL;
+ }
+
+ LLFontGL *result = NULL;
+
+ // The first font will get pulled will be the "head" font, set to non-fallback.
+ // Rest will consitute the fallback list.
+ BOOL is_first_found = TRUE;
+
+ string_vec_t font_search_paths;
+ font_search_paths.push_back(LLFontGL::getFontPathLocal());
+ font_search_paths.push_back(LLFontGL::getFontPathSystem());
#if LL_DARWIN
- font_search_paths.push_back(MACOSX_FONT_PATH_LIBRARY);
- font_search_paths.push_back(MACOSX_FONT_PATH_LIBRARY + MACOSX_FONT_SUPPLEMENTAL);
- font_search_paths.push_back(LLFontGL::getFontPathSystem() + MACOSX_FONT_SUPPLEMENTAL);
+ font_search_paths.push_back(MACOSX_FONT_PATH_LIBRARY);
+ font_search_paths.push_back(MACOSX_FONT_PATH_LIBRARY + MACOSX_FONT_SUPPLEMENTAL);
+ font_search_paths.push_back(LLFontGL::getFontPathSystem() + MACOSX_FONT_SUPPLEMENTAL);
#endif
- // The fontname string may contain multiple font file names separated by semicolons.
- // Break it apart and try loading each one, in order.
- for(font_file_info_vec_t::iterator font_file_it = font_files.begin();
- font_file_it != font_files.end();
- ++font_file_it)
- {
- LLFontGL *fontp = NULL;
-
- bool is_ft_collection = (std::find_if(font_collection_files.begin(), font_collection_files.end(),
- [&font_file_it](const LLFontFileInfo& ffi) { return font_file_it->FileName == ffi.FileName; }) != font_collection_files.end());
-
- // *HACK: Fallback fonts don't render, so we can use that to suppress
- // creation of OpenGL textures for test apps. JC
- BOOL is_fallback = !is_first_found || !mCreateGLTextures;
- F32 extra_scale = (is_fallback)?fallback_scale:1.0;
- F32 point_size_scale = extra_scale * point_size;
- bool is_font_loaded = false;
- for(string_vec_t::iterator font_search_path_it = font_search_paths.begin();
- font_search_path_it != font_search_paths.end();
- ++font_search_path_it)
- {
- const std::string font_path = *font_search_path_it + font_file_it->FileName;
-
- fontp = new LLFontGL;
- S32 num_faces = is_ft_collection ? fontp->getNumFaces(font_path) : 1;
- for (S32 i = 0; i < num_faces; i++)
- {
- if (fontp == NULL)
- {
- fontp = new LLFontGL;
- }
- if (fontp->loadFace(font_path, point_size_scale,
- LLFontGL::sVertDPI, LLFontGL::sHorizDPI, is_fallback, i))
- {
- is_font_loaded = true;
- if (is_first_found)
- {
- result = fontp;
- is_first_found = false;
- }
- else
- {
- result->mFontFreetype->addFallbackFont(fontp->mFontFreetype, font_file_it->CharFunctor);
-
- delete fontp;
- fontp = NULL;
- }
- }
- else
- {
- delete fontp;
- fontp = NULL;
- }
- }
- if (is_font_loaded) break;
- }
- if(!is_font_loaded)
- {
- LL_INFOS_ONCE("LLFontRegistry") << "Couldn't load font " << font_file_it->FileName << LL_ENDL;
- delete fontp;
- fontp = NULL;
- }
- }
-
- if (result)
- {
- result->mFontDescriptor = desc;
- }
- else
- {
- LL_WARNS() << "createFont failed in some way" << LL_ENDL;
- }
-
- mFontMap[desc] = result;
- return result;
+ // The fontname string may contain multiple font file names separated by semicolons.
+ // Break it apart and try loading each one, in order.
+ for(font_file_info_vec_t::iterator font_file_it = font_files.begin();
+ font_file_it != font_files.end();
+ ++font_file_it)
+ {
+ LLFontGL *fontp = NULL;
+
+ bool is_ft_collection = (std::find_if(font_collection_files.begin(), font_collection_files.end(),
+ [&font_file_it](const LLFontFileInfo& ffi) { return font_file_it->FileName == ffi.FileName; }) != font_collection_files.end());
+
+ // *HACK: Fallback fonts don't render, so we can use that to suppress
+ // creation of OpenGL textures for test apps. JC
+ BOOL is_fallback = !is_first_found || !mCreateGLTextures;
+ F32 extra_scale = (is_fallback)?fallback_scale:1.0;
+ F32 point_size_scale = extra_scale * point_size;
+ bool is_font_loaded = false;
+ for(string_vec_t::iterator font_search_path_it = font_search_paths.begin();
+ font_search_path_it != font_search_paths.end();
+ ++font_search_path_it)
+ {
+ const std::string font_path = *font_search_path_it + font_file_it->FileName;
+
+ fontp = new LLFontGL;
+ S32 num_faces = is_ft_collection ? fontp->getNumFaces(font_path) : 1;
+ for (S32 i = 0; i < num_faces; i++)
+ {
+ if (fontp == NULL)
+ {
+ fontp = new LLFontGL;
+ }
+ if (fontp->loadFace(font_path, point_size_scale,
+ LLFontGL::sVertDPI, LLFontGL::sHorizDPI, is_fallback, i))
+ {
+ is_font_loaded = true;
+ if (is_first_found)
+ {
+ result = fontp;
+ is_first_found = false;
+ }
+ else
+ {
+ result->mFontFreetype->addFallbackFont(fontp->mFontFreetype, font_file_it->CharFunctor);
+
+ delete fontp;
+ fontp = NULL;
+ }
+ }
+ else
+ {
+ delete fontp;
+ fontp = NULL;
+ }
+ }
+ if (is_font_loaded) break;
+ }
+ if(!is_font_loaded)
+ {
+ LL_INFOS_ONCE("LLFontRegistry") << "Couldn't load font " << font_file_it->FileName << LL_ENDL;
+ delete fontp;
+ fontp = NULL;
+ }
+ }
+
+ if (result)
+ {
+ result->mFontDescriptor = desc;
+ }
+ else
+ {
+ LL_WARNS() << "createFont failed in some way" << LL_ENDL;
+ }
+
+ mFontMap[desc] = result;
+ return result;
}
void LLFontRegistry::reset()
{
- for (font_reg_map_t::iterator it = mFontMap.begin();
- it != mFontMap.end();
- ++it)
- {
- // Reset the corresponding font but preserve the entry.
- if (it->second)
- it->second->reset();
- }
+ for (font_reg_map_t::iterator it = mFontMap.begin();
+ it != mFontMap.end();
+ ++it)
+ {
+ // Reset the corresponding font but preserve the entry.
+ if (it->second)
+ it->second->reset();
+ }
}
void LLFontRegistry::clear()
{
- for (font_reg_map_t::iterator it = mFontMap.begin();
- it != mFontMap.end();
- ++it)
- {
- LLFontGL *fontp = it->second;
- delete fontp;
- }
- mFontMap.clear();
+ for (font_reg_map_t::iterator it = mFontMap.begin();
+ it != mFontMap.end();
+ ++it)
+ {
+ LLFontGL *fontp = it->second;
+ delete fontp;
+ }
+ mFontMap.clear();
}
void LLFontRegistry::destroyGL()
{
- for (font_reg_map_t::iterator it = mFontMap.begin();
- it != mFontMap.end();
- ++it)
- {
- // Reset the corresponding font but preserve the entry.
- if (it->second)
- it->second->destroyGL();
- }
+ for (font_reg_map_t::iterator it = mFontMap.begin();
+ it != mFontMap.end();
+ ++it)
+ {
+ // Reset the corresponding font but preserve the entry.
+ if (it->second)
+ it->second->destroyGL();
+ }
}
LLFontGL *LLFontRegistry::getFont(const LLFontDescriptor& desc)
{
- font_reg_map_t::iterator it = mFontMap.find(desc);
- if (it != mFontMap.end())
- return it->second;
- else
- {
- LLFontGL *fontp = createFont(desc);
- if (!fontp)
- {
- LL_WARNS() << "getFont failed, name " << desc.getName()
- <<" style=[" << ((S32) desc.getStyle()) << "]"
- << " size=[" << desc.getSize() << "]" << LL_ENDL;
- }
- else
- {
- //generate glyphs for ASCII chars to avoid stalls later
- fontp->generateASCIIglyphs();
- }
- return fontp;
- }
+ font_reg_map_t::iterator it = mFontMap.find(desc);
+ if (it != mFontMap.end())
+ return it->second;
+ else
+ {
+ LLFontGL *fontp = createFont(desc);
+ if (!fontp)
+ {
+ LL_WARNS() << "getFont failed, name " << desc.getName()
+ <<" style=[" << ((S32) desc.getStyle()) << "]"
+ << " size=[" << desc.getSize() << "]" << LL_ENDL;
+ }
+ else
+ {
+ //generate glyphs for ASCII chars to avoid stalls later
+ fontp->generateASCIIglyphs();
+ }
+ return fontp;
+ }
}
const LLFontDescriptor *LLFontRegistry::getMatchingFontDesc(const LLFontDescriptor& desc)
{
- LLFontDescriptor norm_desc = desc.normalize();
+ LLFontDescriptor norm_desc = desc.normalize();
- font_reg_map_t::iterator it = mFontMap.find(norm_desc);
- if (it != mFontMap.end())
- return &(it->first);
- else
- return NULL;
+ font_reg_map_t::iterator it = mFontMap.find(norm_desc);
+ if (it != mFontMap.end())
+ return &(it->first);
+ else
+ return NULL;
}
static U32 bitCount(U8 c)
{
- U32 count = 0;
- if (c & 1)
- count++;
- if (c & 2)
- count++;
- if (c & 4)
- count++;
- if (c & 8)
- count++;
- if (c & 16)
- count++;
- if (c & 32)
- count++;
- if (c & 64)
- count++;
- if (c & 128)
- count++;
- return count;
+ U32 count = 0;
+ if (c & 1)
+ count++;
+ if (c & 2)
+ count++;
+ if (c & 4)
+ count++;
+ if (c & 8)
+ count++;
+ if (c & 16)
+ count++;
+ if (c & 32)
+ count++;
+ if (c & 64)
+ count++;
+ if (c & 128)
+ count++;
+ return count;
}
// Find nearest match for the requested descriptor.
const LLFontDescriptor *LLFontRegistry::getClosestFontTemplate(const LLFontDescriptor& desc)
{
- const LLFontDescriptor *exact_match_desc = getMatchingFontDesc(desc);
- if (exact_match_desc)
- {
- return exact_match_desc;
- }
-
- LLFontDescriptor norm_desc = desc.normalize();
-
- const LLFontDescriptor *best_match_desc = NULL;
- for (font_reg_map_t::iterator it = mFontMap.begin();
- it != mFontMap.end();
- ++it)
- {
- const LLFontDescriptor* curr_desc = &(it->first);
-
- // Ignore if not a template.
- if (!curr_desc->isTemplate())
- continue;
-
- // Ignore if font name is wrong.
- if (curr_desc->getName() != norm_desc.getName())
- continue;
-
- // Reject font if it matches any bits we don't want
- if (curr_desc->getStyle() & ~norm_desc.getStyle())
- {
- continue;
- }
-
- // Take if it's the first plausible candidate we've found.
- if (!best_match_desc)
- {
- best_match_desc = curr_desc;
- continue;
- }
-
- // Take if it matches more bits than anything before.
- U8 best_style_match_bits =
- norm_desc.getStyle() & best_match_desc->getStyle();
- U8 curr_style_match_bits =
- norm_desc.getStyle() & curr_desc->getStyle();
- if (bitCount(curr_style_match_bits) > bitCount(best_style_match_bits))
- {
- best_match_desc = curr_desc;
- continue;
- }
-
- // Tie-breaker: take if it matches bold.
- if (curr_style_match_bits & LLFontGL::BOLD) // Bold is requested and this descriptor matches it.
- {
- best_match_desc = curr_desc;
- continue;
- }
- }
-
- // Nothing matched.
- return best_match_desc;
+ const LLFontDescriptor *exact_match_desc = getMatchingFontDesc(desc);
+ if (exact_match_desc)
+ {
+ return exact_match_desc;
+ }
+
+ LLFontDescriptor norm_desc = desc.normalize();
+
+ const LLFontDescriptor *best_match_desc = NULL;
+ for (font_reg_map_t::iterator it = mFontMap.begin();
+ it != mFontMap.end();
+ ++it)
+ {
+ const LLFontDescriptor* curr_desc = &(it->first);
+
+ // Ignore if not a template.
+ if (!curr_desc->isTemplate())
+ continue;
+
+ // Ignore if font name is wrong.
+ if (curr_desc->getName() != norm_desc.getName())
+ continue;
+
+ // Reject font if it matches any bits we don't want
+ if (curr_desc->getStyle() & ~norm_desc.getStyle())
+ {
+ continue;
+ }
+
+ // Take if it's the first plausible candidate we've found.
+ if (!best_match_desc)
+ {
+ best_match_desc = curr_desc;
+ continue;
+ }
+
+ // Take if it matches more bits than anything before.
+ U8 best_style_match_bits =
+ norm_desc.getStyle() & best_match_desc->getStyle();
+ U8 curr_style_match_bits =
+ norm_desc.getStyle() & curr_desc->getStyle();
+ if (bitCount(curr_style_match_bits) > bitCount(best_style_match_bits))
+ {
+ best_match_desc = curr_desc;
+ continue;
+ }
+
+ // Tie-breaker: take if it matches bold.
+ if (curr_style_match_bits & LLFontGL::BOLD) // Bold is requested and this descriptor matches it.
+ {
+ best_match_desc = curr_desc;
+ continue;
+ }
+ }
+
+ // Nothing matched.
+ return best_match_desc;
}
void LLFontRegistry::dump()
{
- LL_INFOS() << "LLFontRegistry dump: " << LL_ENDL;
- for (font_size_map_t::iterator size_it = mFontSizes.begin();
- size_it != mFontSizes.end();
- ++size_it)
- {
- LL_INFOS() << "Size: " << size_it->first << " => " << size_it->second << LL_ENDL;
- }
- for (font_reg_map_t::iterator font_it = mFontMap.begin();
- font_it != mFontMap.end();
- ++font_it)
- {
- const LLFontDescriptor& desc = font_it->first;
- LL_INFOS() << "Font: name=" << desc.getName()
- << " style=[" << ((S32)desc.getStyle()) << "]"
- << " size=[" << desc.getSize() << "]"
- << " fileNames="
- << LL_ENDL;
- for (font_file_info_vec_t::const_iterator file_it=desc.getFontFiles().begin();
- file_it != desc.getFontFiles().end();
- ++file_it)
- {
- LL_INFOS() << " file: " << file_it->FileName << LL_ENDL;
- }
- }
+ LL_INFOS() << "LLFontRegistry dump: " << LL_ENDL;
+ for (font_size_map_t::iterator size_it = mFontSizes.begin();
+ size_it != mFontSizes.end();
+ ++size_it)
+ {
+ LL_INFOS() << "Size: " << size_it->first << " => " << size_it->second << LL_ENDL;
+ }
+ for (font_reg_map_t::iterator font_it = mFontMap.begin();
+ font_it != mFontMap.end();
+ ++font_it)
+ {
+ const LLFontDescriptor& desc = font_it->first;
+ LL_INFOS() << "Font: name=" << desc.getName()
+ << " style=[" << ((S32)desc.getStyle()) << "]"
+ << " size=[" << desc.getSize() << "]"
+ << " fileNames="
+ << LL_ENDL;
+ for (font_file_info_vec_t::const_iterator file_it=desc.getFontFiles().begin();
+ file_it != desc.getFontFiles().end();
+ ++file_it)
+ {
+ LL_INFOS() << " file: " << file_it->FileName << LL_ENDL;
+ }
+ }
}
void LLFontRegistry::dumpTextures()
{
- for (const auto& fontEntry : mFontMap)
- {
- if (fontEntry.second)
- {
- fontEntry.second->dumpTextures();
- }
- }
+ for (const auto& fontEntry : mFontMap)
+ {
+ if (fontEntry.second)
+ {
+ fontEntry.second->dumpTextures();
+ }
+ }
}
-const string_vec_t& LLFontRegistry::getUltimateFallbackList() const
-{
- return mUltimateFallbackList;
+const string_vec_t& LLFontRegistry::getUltimateFallbackList() const
+{
+ return mUltimateFallbackList;
}
diff --git a/indra/llrender/llfontregistry.h b/indra/llrender/llfontregistry.h
index b0ef72c5de..8bbf5aa30c 100644
--- a/indra/llrender/llfontregistry.h
+++ b/indra/llrender/llfontregistry.h
@@ -1,4 +1,4 @@
-/**
+/**
* @file llfontregistry.h
* @author Brad Payne
* @brief Storage for fonts.
@@ -6,21 +6,21 @@
* $LicenseInfo:firstyear=2008&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -36,107 +36,107 @@ typedef std::vector<std::string> string_vec_t;
struct LLFontFileInfo
{
- LLFontFileInfo(const std::string& file_name, const std::function<bool(llwchar)>& char_functor = nullptr)
- : FileName(file_name)
- , CharFunctor(char_functor)
- {
- }
-
- LLFontFileInfo(const LLFontFileInfo& ffi)
- : FileName(ffi.FileName)
- , CharFunctor(ffi.CharFunctor)
- {
- }
-
- std::string FileName;
- std::function<bool(llwchar)> CharFunctor;
+ LLFontFileInfo(const std::string& file_name, const std::function<bool(llwchar)>& char_functor = nullptr)
+ : FileName(file_name)
+ , CharFunctor(char_functor)
+ {
+ }
+
+ LLFontFileInfo(const LLFontFileInfo& ffi)
+ : FileName(ffi.FileName)
+ , CharFunctor(ffi.CharFunctor)
+ {
+ }
+
+ std::string FileName;
+ std::function<bool(llwchar)> CharFunctor;
};
typedef std::vector<LLFontFileInfo> font_file_info_vec_t;
class LLFontDescriptor
{
public:
- LLFontDescriptor();
- LLFontDescriptor(const std::string& name, const std::string& size, const U8 style);
- LLFontDescriptor(const std::string& name, const std::string& size, const U8 style, const font_file_info_vec_t& font_list);
- LLFontDescriptor(const std::string& name, const std::string& size, const U8 style, const font_file_info_vec_t& font_list, const font_file_info_vec_t& font_collection_list);
- LLFontDescriptor normalize() const;
-
- bool operator<(const LLFontDescriptor& b) const;
-
- bool isTemplate() const;
-
- const std::string& getName() const { return mName; }
- void setName(const std::string& name) { mName = name; }
- const std::string& getSize() const { return mSize; }
- void setSize(const std::string& size) { mSize = size; }
-
- void addFontFile(const std::string& file_name, const std::string& char_functor = LLStringUtil::null);
- const font_file_info_vec_t & getFontFiles() const { return mFontFiles; }
- void setFontFiles(const font_file_info_vec_t& font_files) { mFontFiles = font_files; }
- void addFontCollectionFile(const std::string& file_name, const std::string& char_functor = LLStringUtil::null);
- const font_file_info_vec_t& getFontCollectionFiles() const { return mFontCollectionFiles; }
- void setFontCollectionFiles(const font_file_info_vec_t& font_collection_files) { mFontCollectionFiles = font_collection_files; }
-
- const U8 getStyle() const { return mStyle; }
- void setStyle(U8 style) { mStyle = style; }
+ LLFontDescriptor();
+ LLFontDescriptor(const std::string& name, const std::string& size, const U8 style);
+ LLFontDescriptor(const std::string& name, const std::string& size, const U8 style, const font_file_info_vec_t& font_list);
+ LLFontDescriptor(const std::string& name, const std::string& size, const U8 style, const font_file_info_vec_t& font_list, const font_file_info_vec_t& font_collection_list);
+ LLFontDescriptor normalize() const;
+
+ bool operator<(const LLFontDescriptor& b) const;
+
+ bool isTemplate() const;
+
+ const std::string& getName() const { return mName; }
+ void setName(const std::string& name) { mName = name; }
+ const std::string& getSize() const { return mSize; }
+ void setSize(const std::string& size) { mSize = size; }
+
+ void addFontFile(const std::string& file_name, const std::string& char_functor = LLStringUtil::null);
+ const font_file_info_vec_t & getFontFiles() const { return mFontFiles; }
+ void setFontFiles(const font_file_info_vec_t& font_files) { mFontFiles = font_files; }
+ void addFontCollectionFile(const std::string& file_name, const std::string& char_functor = LLStringUtil::null);
+ const font_file_info_vec_t& getFontCollectionFiles() const { return mFontCollectionFiles; }
+ void setFontCollectionFiles(const font_file_info_vec_t& font_collection_files) { mFontCollectionFiles = font_collection_files; }
+
+ const U8 getStyle() const { return mStyle; }
+ void setStyle(U8 style) { mStyle = style; }
private:
- std::string mName;
- std::string mSize;
- font_file_info_vec_t mFontFiles;
- font_file_info_vec_t mFontCollectionFiles;
- U8 mStyle;
-
- typedef std::map<std::string, std::function<bool(llwchar)>> char_functor_map_t;
- static char_functor_map_t mCharFunctors;
+ std::string mName;
+ std::string mSize;
+ font_file_info_vec_t mFontFiles;
+ font_file_info_vec_t mFontCollectionFiles;
+ U8 mStyle;
+
+ typedef std::map<std::string, std::function<bool(llwchar)>> char_functor_map_t;
+ static char_functor_map_t mCharFunctors;
};
class LLFontRegistry
{
public:
- friend bool init_from_xml(LLFontRegistry*, LLPointer<class LLXMLNode>);
- // create_gl_textures - set to false for test apps with no OpenGL window,
- // such as llui_libtest
- LLFontRegistry(bool create_gl_textures);
- ~LLFontRegistry();
+ friend bool init_from_xml(LLFontRegistry*, LLPointer<class LLXMLNode>);
+ // create_gl_textures - set to false for test apps with no OpenGL window,
+ // such as llui_libtest
+ LLFontRegistry(bool create_gl_textures);
+ ~LLFontRegistry();
+
+ // Load standard font info from XML file(s).
+ bool parseFontInfo(const std::string& xml_filename);
+
+ // Clear cached glyphs for all fonts.
+ void reset();
- // Load standard font info from XML file(s).
- bool parseFontInfo(const std::string& xml_filename);
+ // Destroy all fonts.
+ void clear();
- // Clear cached glyphs for all fonts.
- void reset();
+ // GL cleanup
+ void destroyGL();
- // Destroy all fonts.
- void clear();
+ LLFontGL *getFont(const LLFontDescriptor& desc);
+ const LLFontDescriptor *getMatchingFontDesc(const LLFontDescriptor& desc);
+ const LLFontDescriptor *getClosestFontTemplate(const LLFontDescriptor& desc);
- // GL cleanup
- void destroyGL();
-
- LLFontGL *getFont(const LLFontDescriptor& desc);
- const LLFontDescriptor *getMatchingFontDesc(const LLFontDescriptor& desc);
- const LLFontDescriptor *getClosestFontTemplate(const LLFontDescriptor& desc);
+ bool nameToSize(const std::string& size_name, F32& size);
- bool nameToSize(const std::string& size_name, F32& size);
+ void dump();
+ void dumpTextures();
- void dump();
- void dumpTextures();
-
- const string_vec_t& getUltimateFallbackList() const;
+ const string_vec_t& getUltimateFallbackList() const;
private:
- LLFontRegistry(const LLFontRegistry& other); // no-copy
- LLFontGL *createFont(const LLFontDescriptor& desc);
- typedef std::map<LLFontDescriptor,LLFontGL*> font_reg_map_t;
- typedef std::map<std::string,F32> font_size_map_t;
-
- // Given a descriptor, look up specific font instantiation.
- font_reg_map_t mFontMap;
- // Given a size name, look up the point size.
- font_size_map_t mFontSizes;
-
- string_vec_t mUltimateFallbackList;
- bool mCreateGLTextures;
+ LLFontRegistry(const LLFontRegistry& other); // no-copy
+ LLFontGL *createFont(const LLFontDescriptor& desc);
+ typedef std::map<LLFontDescriptor,LLFontGL*> font_reg_map_t;
+ typedef std::map<std::string,F32> font_size_map_t;
+
+ // Given a descriptor, look up specific font instantiation.
+ font_reg_map_t mFontMap;
+ // Given a size name, look up the point size.
+ font_size_map_t mFontSizes;
+
+ string_vec_t mUltimateFallbackList;
+ bool mCreateGLTextures;
};
#endif // LL_LLFONTREGISTRY_H
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index a4a56af981..1b5566a3f7 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -1,30 +1,30 @@
-/**
+/**
* @file llgl.cpp
* @brief LLGL implementation
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-// This file sets some global GL parameters, and implements some
+// This file sets some global GL parameters, and implements some
// useful functions for GL operations.
#define GLH_EXT_SINGLE_FILE
@@ -172,37 +172,37 @@ void parse_glsl_version(S32& major, S32& minor);
void ll_init_fail_log(std::string filename)
{
- gFailLog.open(filename.c_str());
+ gFailLog.open(filename.c_str());
}
void ll_fail(std::string msg)
{
-
- if (gDebugSession)
- {
- std::vector<std::string> lines;
- gFailLog << LLError::utcTime() << " " << msg << std::endl;
+ if (gDebugSession)
+ {
+ std::vector<std::string> lines;
- gFailLog << "Stack Trace:" << std::endl;
+ gFailLog << LLError::utcTime() << " " << msg << std::endl;
- ll_get_stack_trace(lines);
-
- for(size_t i = 0; i < lines.size(); ++i)
- {
- gFailLog << lines[i] << std::endl;
- }
+ gFailLog << "Stack Trace:" << std::endl;
+
+ ll_get_stack_trace(lines);
+
+ for(size_t i = 0; i < lines.size(); ++i)
+ {
+ gFailLog << lines[i] << std::endl;
+ }
- gFailLog << "End of Stack Trace." << std::endl << std::endl;
+ gFailLog << "End of Stack Trace." << std::endl << std::endl;
- gFailLog.flush();
- }
+ gFailLog.flush();
+ }
};
void ll_close_fail_log()
{
- gFailLog.close();
+ gFailLog.close();
}
LLMatrix4 gGLObliqueProjectionInverse;
@@ -983,30 +983,30 @@ PFNGLPOLYGONOFFSETCLAMPPROC glPolygonOffsetClamp = nullptr;
LLGLManager gGLManager;
LLGLManager::LLGLManager() :
- mInited(FALSE),
- mIsDisabled(FALSE),
- mMaxSamples(0),
- mNumTextureImageUnits(1),
- mMaxSampleMaskWords(0),
- mMaxColorTextureSamples(0),
- mMaxDepthTextureSamples(0),
- mMaxIntegerSamples(0),
- mIsAMD(FALSE),
- mIsNVIDIA(FALSE),
- mIsIntel(FALSE),
+ mInited(FALSE),
+ mIsDisabled(FALSE),
+ mMaxSamples(0),
+ mNumTextureImageUnits(1),
+ mMaxSampleMaskWords(0),
+ mMaxColorTextureSamples(0),
+ mMaxDepthTextureSamples(0),
+ mMaxIntegerSamples(0),
+ mIsAMD(FALSE),
+ mIsNVIDIA(FALSE),
+ mIsIntel(FALSE),
#if LL_DARWIN
- mIsMobileGF(FALSE),
+ mIsMobileGF(FALSE),
#endif
- mHasRequirements(TRUE),
- mDriverVersionMajor(1),
- mDriverVersionMinor(0),
- mDriverVersionRelease(0),
- mGLVersion(1.0f),
- mGLSLVersionMajor(0),
- mGLSLVersionMinor(0),
- mVRAM(0),
- mGLMaxVertexRange(0),
- mGLMaxIndexRange(0)
+ mHasRequirements(TRUE),
+ mDriverVersionMajor(1),
+ mDriverVersionMinor(0),
+ mDriverVersionRelease(0),
+ mGLVersion(1.0f),
+ mGLSLVersionMajor(0),
+ mGLSLVersionMinor(0),
+ mVRAM(0),
+ mGLMaxVertexRange(0),
+ mGLMaxIndexRange(0)
{
}
@@ -1016,227 +1016,227 @@ LLGLManager::LLGLManager() :
void LLGLManager::initWGL()
{
#if LL_WINDOWS && !LL_MESA_HEADLESS
- if (!glh_init_extensions("WGL_ARB_pixel_format"))
- {
- LL_WARNS("RenderInit") << "No ARB pixel format extensions" << LL_ENDL;
- }
-
- if (ExtensionExists("WGL_ARB_create_context",gGLHExts.mSysExts))
- {
- GLH_EXT_NAME(wglCreateContextAttribsARB) = (PFNWGLCREATECONTEXTATTRIBSARBPROC)GLH_EXT_GET_PROC_ADDRESS("wglCreateContextAttribsARB");
- }
- else
- {
- LL_WARNS("RenderInit") << "No ARB create context extensions" << LL_ENDL;
- }
-
- // For retreiving information per AMD adapter,
- // because we can't trust curently selected/default one when there are multiple
- mHasAMDAssociations = ExtensionExists("WGL_AMD_gpu_association", gGLHExts.mSysExts);
- if (mHasAMDAssociations)
- {
- GLH_EXT_NAME(wglGetGPUIDsAMD) = (PFNWGLGETGPUIDSAMDPROC)GLH_EXT_GET_PROC_ADDRESS("wglGetGPUIDsAMD");
- GLH_EXT_NAME(wglGetGPUInfoAMD) = (PFNWGLGETGPUINFOAMDPROC)GLH_EXT_GET_PROC_ADDRESS("wglGetGPUInfoAMD");
- }
-
- if (ExtensionExists("WGL_EXT_swap_control", gGLHExts.mSysExts))
- {
+ if (!glh_init_extensions("WGL_ARB_pixel_format"))
+ {
+ LL_WARNS("RenderInit") << "No ARB pixel format extensions" << LL_ENDL;
+ }
+
+ if (ExtensionExists("WGL_ARB_create_context",gGLHExts.mSysExts))
+ {
+ GLH_EXT_NAME(wglCreateContextAttribsARB) = (PFNWGLCREATECONTEXTATTRIBSARBPROC)GLH_EXT_GET_PROC_ADDRESS("wglCreateContextAttribsARB");
+ }
+ else
+ {
+ LL_WARNS("RenderInit") << "No ARB create context extensions" << LL_ENDL;
+ }
+
+ // For retreiving information per AMD adapter,
+ // because we can't trust curently selected/default one when there are multiple
+ mHasAMDAssociations = ExtensionExists("WGL_AMD_gpu_association", gGLHExts.mSysExts);
+ if (mHasAMDAssociations)
+ {
+ GLH_EXT_NAME(wglGetGPUIDsAMD) = (PFNWGLGETGPUIDSAMDPROC)GLH_EXT_GET_PROC_ADDRESS("wglGetGPUIDsAMD");
+ GLH_EXT_NAME(wglGetGPUInfoAMD) = (PFNWGLGETGPUINFOAMDPROC)GLH_EXT_GET_PROC_ADDRESS("wglGetGPUInfoAMD");
+ }
+
+ if (ExtensionExists("WGL_EXT_swap_control", gGLHExts.mSysExts))
+ {
GLH_EXT_NAME(wglSwapIntervalEXT) = (PFNWGLSWAPINTERVALEXTPROC)GLH_EXT_GET_PROC_ADDRESS("wglSwapIntervalEXT");
- }
+ }
- if( !glh_init_extensions("WGL_ARB_pbuffer") )
- {
- LL_WARNS("RenderInit") << "No ARB WGL PBuffer extensions" << LL_ENDL;
- }
+ if( !glh_init_extensions("WGL_ARB_pbuffer") )
+ {
+ LL_WARNS("RenderInit") << "No ARB WGL PBuffer extensions" << LL_ENDL;
+ }
- if( !glh_init_extensions("WGL_ARB_render_texture") )
- {
- LL_WARNS("RenderInit") << "No ARB WGL render texture extensions" << LL_ENDL;
- }
+ if( !glh_init_extensions("WGL_ARB_render_texture") )
+ {
+ LL_WARNS("RenderInit") << "No ARB WGL render texture extensions" << LL_ENDL;
+ }
#endif
}
// return false if unable (or unwilling due to old drivers) to init GL
bool LLGLManager::initGL()
{
- if (mInited)
- {
- LL_ERRS("RenderInit") << "Calling init on LLGLManager after already initialized!" << LL_ENDL;
- }
+ if (mInited)
+ {
+ LL_ERRS("RenderInit") << "Calling init on LLGLManager after already initialized!" << LL_ENDL;
+ }
#if 0 && LL_WINDOWS
- if (!glGetStringi)
- {
- glGetStringi = (PFNGLGETSTRINGIPROC) GLH_EXT_GET_PROC_ADDRESS("glGetStringi");
- }
-
- //reload extensions string (may have changed after using wglCreateContextAttrib)
- if (glGetStringi)
- {
- std::stringstream str;
-
- GLint count = 0;
- glGetIntegerv(GL_NUM_EXTENSIONS, &count);
- for (GLint i = 0; i < count; ++i)
- {
- std::string ext = ll_safe_string((const char*) glGetStringi(GL_EXTENSIONS, i));
- str << ext << " ";
- LL_DEBUGS("GLExtensions") << ext << LL_ENDL;
- }
-
- {
- PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = 0;
- wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB");
- if(wglGetExtensionsStringARB)
- {
- str << (const char*) wglGetExtensionsStringARB(wglGetCurrentDC());
- }
- }
-
- free(gGLHExts.mSysExts);
- std::string extensions = str.str();
- gGLHExts.mSysExts = strdup(extensions.c_str());
- }
+ if (!glGetStringi)
+ {
+ glGetStringi = (PFNGLGETSTRINGIPROC) GLH_EXT_GET_PROC_ADDRESS("glGetStringi");
+ }
+
+ //reload extensions string (may have changed after using wglCreateContextAttrib)
+ if (glGetStringi)
+ {
+ std::stringstream str;
+
+ GLint count = 0;
+ glGetIntegerv(GL_NUM_EXTENSIONS, &count);
+ for (GLint i = 0; i < count; ++i)
+ {
+ std::string ext = ll_safe_string((const char*) glGetStringi(GL_EXTENSIONS, i));
+ str << ext << " ";
+ LL_DEBUGS("GLExtensions") << ext << LL_ENDL;
+ }
+
+ {
+ PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = 0;
+ wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB");
+ if(wglGetExtensionsStringARB)
+ {
+ str << (const char*) wglGetExtensionsStringARB(wglGetCurrentDC());
+ }
+ }
+
+ free(gGLHExts.mSysExts);
+ std::string extensions = str.str();
+ gGLHExts.mSysExts = strdup(extensions.c_str());
+ }
#endif
-
- // Extract video card strings and convert to upper case to
- // work around driver-to-driver variation in capitalization.
- mGLVendor = ll_safe_string((const char *)glGetString(GL_VENDOR));
- LLStringUtil::toUpper(mGLVendor);
- mGLRenderer = ll_safe_string((const char *)glGetString(GL_RENDERER));
- LLStringUtil::toUpper(mGLRenderer);
+ // Extract video card strings and convert to upper case to
+ // work around driver-to-driver variation in capitalization.
+ mGLVendor = ll_safe_string((const char *)glGetString(GL_VENDOR));
+ LLStringUtil::toUpper(mGLVendor);
- parse_gl_version( &mDriverVersionMajor,
- &mDriverVersionMinor,
- &mDriverVersionRelease,
- &mDriverVersionVendorString,
- &mGLVersionString);
+ mGLRenderer = ll_safe_string((const char *)glGetString(GL_RENDERER));
+ LLStringUtil::toUpper(mGLRenderer);
- mGLVersion = mDriverVersionMajor + mDriverVersionMinor * .1f;
+ parse_gl_version( &mDriverVersionMajor,
+ &mDriverVersionMinor,
+ &mDriverVersionRelease,
+ &mDriverVersionVendorString,
+ &mGLVersionString);
- if (mGLVersion >= 2.f)
- {
- parse_glsl_version(mGLSLVersionMajor, mGLSLVersionMinor);
+ mGLVersion = mDriverVersionMajor + mDriverVersionMinor * .1f;
+
+ if (mGLVersion >= 2.f)
+ {
+ parse_glsl_version(mGLSLVersionMajor, mGLSLVersionMinor);
#if 0 && LL_DARWIN
- // TODO maybe switch to using a core profile for GL 3.2?
- // https://stackoverflow.com/a/19868861
- //never use GLSL greater than 1.20 on OSX
- if (mGLSLVersionMajor > 1 || mGLSLVersionMinor > 30)
- {
- mGLSLVersionMajor = 1;
- mGLSLVersionMinor = 30;
- }
+ // TODO maybe switch to using a core profile for GL 3.2?
+ // https://stackoverflow.com/a/19868861
+ //never use GLSL greater than 1.20 on OSX
+ if (mGLSLVersionMajor > 1 || mGLSLVersionMinor > 30)
+ {
+ mGLSLVersionMajor = 1;
+ mGLSLVersionMinor = 30;
+ }
#endif
- }
-
- if (mGLVersion >= 2.1f && LLImageGL::sCompressTextures)
- { //use texture compression
- glHint(GL_TEXTURE_COMPRESSION_HINT, GL_NICEST);
- }
- else
- { //GL version is < 3.0, always disable texture compression
- LLImageGL::sCompressTextures = false;
- }
-
- // Trailing space necessary to keep "nVidia Corpor_ati_on" cards
- // from being recognized as ATI.
+ }
+
+ if (mGLVersion >= 2.1f && LLImageGL::sCompressTextures)
+ { //use texture compression
+ glHint(GL_TEXTURE_COMPRESSION_HINT, GL_NICEST);
+ }
+ else
+ { //GL version is < 3.0, always disable texture compression
+ LLImageGL::sCompressTextures = false;
+ }
+
+ // Trailing space necessary to keep "nVidia Corpor_ati_on" cards
+ // from being recognized as ATI.
// NOTE: AMD has been pretty good about not breaking this check, do not rename without good reason
- if (mGLVendor.substr(0,4) == "ATI ")
- {
- mGLVendorShort = "AMD";
- // *TODO: Fix this?
- mIsAMD = TRUE;
- }
- else if (mGLVendor.find("NVIDIA ") != std::string::npos)
- {
- mGLVendorShort = "NVIDIA";
- mIsNVIDIA = TRUE;
- }
- else if (mGLVendor.find("INTEL") != std::string::npos
+ if (mGLVendor.substr(0,4) == "ATI ")
+ {
+ mGLVendorShort = "AMD";
+ // *TODO: Fix this?
+ mIsAMD = TRUE;
+ }
+ else if (mGLVendor.find("NVIDIA ") != std::string::npos)
+ {
+ mGLVendorShort = "NVIDIA";
+ mIsNVIDIA = TRUE;
+ }
+ else if (mGLVendor.find("INTEL") != std::string::npos
#if LL_LINUX
- // The Mesa-based drivers put this in the Renderer string,
- // not the Vendor string.
- || mGLRenderer.find("INTEL") != std::string::npos
+ // The Mesa-based drivers put this in the Renderer string,
+ // not the Vendor string.
+ || mGLRenderer.find("INTEL") != std::string::npos
#endif //LL_LINUX
- )
- {
- mGLVendorShort = "INTEL";
- mIsIntel = TRUE;
- }
- else
- {
- mGLVendorShort = "MISC";
- }
-
- // This is called here because it depends on the setting of mIsGF2or4MX, and sets up mHasMultitexture.
- initExtensions();
-
- S32 old_vram = mVRAM;
- mVRAM = 0;
+ )
+ {
+ mGLVendorShort = "INTEL";
+ mIsIntel = TRUE;
+ }
+ else
+ {
+ mGLVendorShort = "MISC";
+ }
+
+ // This is called here because it depends on the setting of mIsGF2or4MX, and sets up mHasMultitexture.
+ initExtensions();
+
+ S32 old_vram = mVRAM;
+ mVRAM = 0;
#if LL_WINDOWS
- if (mHasAMDAssociations)
- {
- GLuint gl_gpus_count = wglGetGPUIDsAMD(0, 0);
- if (gl_gpus_count > 0)
- {
- GLuint* ids = new GLuint[gl_gpus_count];
- wglGetGPUIDsAMD(gl_gpus_count, ids);
-
- GLuint mem_mb = 0;
- for (U32 i = 0; i < gl_gpus_count; i++)
- {
- wglGetGPUInfoAMD(ids[i],
- WGL_GPU_RAM_AMD,
- GL_UNSIGNED_INT,
- sizeof(GLuint),
- &mem_mb);
- if (mVRAM < mem_mb)
- {
- // basically pick the best AMD and trust driver/OS to know to switch
- mVRAM = mem_mb;
- }
- }
- }
- if (mVRAM != 0)
- {
- LL_WARNS("RenderInit") << "VRAM Detected (AMDAssociations):" << mVRAM << LL_ENDL;
- }
- }
+ if (mHasAMDAssociations)
+ {
+ GLuint gl_gpus_count = wglGetGPUIDsAMD(0, 0);
+ if (gl_gpus_count > 0)
+ {
+ GLuint* ids = new GLuint[gl_gpus_count];
+ wglGetGPUIDsAMD(gl_gpus_count, ids);
+
+ GLuint mem_mb = 0;
+ for (U32 i = 0; i < gl_gpus_count; i++)
+ {
+ wglGetGPUInfoAMD(ids[i],
+ WGL_GPU_RAM_AMD,
+ GL_UNSIGNED_INT,
+ sizeof(GLuint),
+ &mem_mb);
+ if (mVRAM < mem_mb)
+ {
+ // basically pick the best AMD and trust driver/OS to know to switch
+ mVRAM = mem_mb;
+ }
+ }
+ }
+ if (mVRAM != 0)
+ {
+ LL_WARNS("RenderInit") << "VRAM Detected (AMDAssociations):" << mVRAM << LL_ENDL;
+ }
+ }
#endif
#if LL_WINDOWS
- if (mVRAM < 256)
- {
- // Something likely went wrong using the above extensions
- // try WMI first and fall back to old method (from dxdiag) if all else fails
- // Function will check all GPUs WMI knows of and will pick up the one with most
- // memory. We need to check all GPUs because system can switch active GPU to
- // weaker one, to preserve power when not under load.
- S32 mem = LLDXHardware::getMBVideoMemoryViaWMI();
- if (mem != 0)
- {
- mVRAM = mem;
- LL_WARNS("RenderInit") << "VRAM Detected (WMI):" << mVRAM<< LL_ENDL;
- }
- }
+ if (mVRAM < 256)
+ {
+ // Something likely went wrong using the above extensions
+ // try WMI first and fall back to old method (from dxdiag) if all else fails
+ // Function will check all GPUs WMI knows of and will pick up the one with most
+ // memory. We need to check all GPUs because system can switch active GPU to
+ // weaker one, to preserve power when not under load.
+ S32 mem = LLDXHardware::getMBVideoMemoryViaWMI();
+ if (mem != 0)
+ {
+ mVRAM = mem;
+ LL_WARNS("RenderInit") << "VRAM Detected (WMI):" << mVRAM<< LL_ENDL;
+ }
+ }
#endif
- if (mVRAM < 256 && old_vram > 0)
- {
- // fall back to old method
- // Note: on Windows value will be from LLDXHardware.
- // Either received via dxdiag or via WMI by id from dxdiag.
- mVRAM = old_vram;
- }
-
- glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &mNumTextureImageUnits);
- glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &mMaxColorTextureSamples);
- glGetIntegerv(GL_MAX_DEPTH_TEXTURE_SAMPLES, &mMaxDepthTextureSamples);
- glGetIntegerv(GL_MAX_INTEGER_SAMPLES, &mMaxIntegerSamples);
- glGetIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &mMaxSampleMaskWords);
+ if (mVRAM < 256 && old_vram > 0)
+ {
+ // fall back to old method
+ // Note: on Windows value will be from LLDXHardware.
+ // Either received via dxdiag or via WMI by id from dxdiag.
+ mVRAM = old_vram;
+ }
+
+ glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &mNumTextureImageUnits);
+ glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &mMaxColorTextureSamples);
+ glGetIntegerv(GL_MAX_DEPTH_TEXTURE_SAMPLES, &mMaxDepthTextureSamples);
+ glGetIntegerv(GL_MAX_INTEGER_SAMPLES, &mMaxIntegerSamples);
+ glGetIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &mMaxSampleMaskWords);
glGetIntegerv(GL_MAX_SAMPLES, &mMaxSamples);
if (mGLVersion >= 4.59f)
@@ -1244,136 +1244,136 @@ bool LLGLManager::initGL()
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY, &mMaxAnisotropy);
}
- initGLStates();
+ initGLStates();
- return true;
+ return true;
}
void LLGLManager::getGLInfo(LLSD& info)
{
- if (gHeadlessClient)
- {
- info["GLInfo"]["GLVendor"] = HEADLESS_VENDOR_STRING;
- info["GLInfo"]["GLRenderer"] = HEADLESS_RENDERER_STRING;
- info["GLInfo"]["GLVersion"] = HEADLESS_VERSION_STRING;
- return;
- }
- else
- {
- info["GLInfo"]["GLVendor"] = ll_safe_string((const char *)glGetString(GL_VENDOR));
- info["GLInfo"]["GLRenderer"] = ll_safe_string((const char *)glGetString(GL_RENDERER));
- info["GLInfo"]["GLVersion"] = ll_safe_string((const char *)glGetString(GL_VERSION));
- }
+ if (gHeadlessClient)
+ {
+ info["GLInfo"]["GLVendor"] = HEADLESS_VENDOR_STRING;
+ info["GLInfo"]["GLRenderer"] = HEADLESS_RENDERER_STRING;
+ info["GLInfo"]["GLVersion"] = HEADLESS_VERSION_STRING;
+ return;
+ }
+ else
+ {
+ info["GLInfo"]["GLVendor"] = ll_safe_string((const char *)glGetString(GL_VENDOR));
+ info["GLInfo"]["GLRenderer"] = ll_safe_string((const char *)glGetString(GL_RENDERER));
+ info["GLInfo"]["GLVersion"] = ll_safe_string((const char *)glGetString(GL_VERSION));
+ }
#if !LL_MESA_HEADLESS
- std::string all_exts = ll_safe_string((const char *)gGLHExts.mSysExts);
- boost::char_separator<char> sep(" ");
- boost::tokenizer<boost::char_separator<char> > tok(all_exts, sep);
- for(boost::tokenizer<boost::char_separator<char> >::iterator i = tok.begin(); i != tok.end(); ++i)
- {
- info["GLInfo"]["GLExtensions"].append(*i);
- }
+ std::string all_exts = ll_safe_string((const char *)gGLHExts.mSysExts);
+ boost::char_separator<char> sep(" ");
+ boost::tokenizer<boost::char_separator<char> > tok(all_exts, sep);
+ for(boost::tokenizer<boost::char_separator<char> >::iterator i = tok.begin(); i != tok.end(); ++i)
+ {
+ info["GLInfo"]["GLExtensions"].append(*i);
+ }
#endif
}
std::string LLGLManager::getGLInfoString()
{
- std::string info_str;
-
- if (gHeadlessClient)
- {
- info_str += std::string("GL_VENDOR ") + HEADLESS_VENDOR_STRING + std::string("\n");
- info_str += std::string("GL_RENDERER ") + HEADLESS_RENDERER_STRING + std::string("\n");
- info_str += std::string("GL_VERSION ") + HEADLESS_VERSION_STRING + std::string("\n");
- }
- else
- {
- info_str += std::string("GL_VENDOR ") + ll_safe_string((const char *)glGetString(GL_VENDOR)) + std::string("\n");
- info_str += std::string("GL_RENDERER ") + ll_safe_string((const char *)glGetString(GL_RENDERER)) + std::string("\n");
- info_str += std::string("GL_VERSION ") + ll_safe_string((const char *)glGetString(GL_VERSION)) + std::string("\n");
- }
-
-#if !LL_MESA_HEADLESS
- std::string all_exts= ll_safe_string(((const char *)gGLHExts.mSysExts));
- LLStringUtil::replaceChar(all_exts, ' ', '\n');
- info_str += std::string("GL_EXTENSIONS:\n") + all_exts + std::string("\n");
+ std::string info_str;
+
+ if (gHeadlessClient)
+ {
+ info_str += std::string("GL_VENDOR ") + HEADLESS_VENDOR_STRING + std::string("\n");
+ info_str += std::string("GL_RENDERER ") + HEADLESS_RENDERER_STRING + std::string("\n");
+ info_str += std::string("GL_VERSION ") + HEADLESS_VERSION_STRING + std::string("\n");
+ }
+ else
+ {
+ info_str += std::string("GL_VENDOR ") + ll_safe_string((const char *)glGetString(GL_VENDOR)) + std::string("\n");
+ info_str += std::string("GL_RENDERER ") + ll_safe_string((const char *)glGetString(GL_RENDERER)) + std::string("\n");
+ info_str += std::string("GL_VERSION ") + ll_safe_string((const char *)glGetString(GL_VERSION)) + std::string("\n");
+ }
+
+#if !LL_MESA_HEADLESS
+ std::string all_exts= ll_safe_string(((const char *)gGLHExts.mSysExts));
+ LLStringUtil::replaceChar(all_exts, ' ', '\n');
+ info_str += std::string("GL_EXTENSIONS:\n") + all_exts + std::string("\n");
#endif
-
- return info_str;
+
+ return info_str;
}
void LLGLManager::printGLInfoString()
{
- if (gHeadlessClient)
- {
- LL_INFOS("RenderInit") << "GL_VENDOR: " << HEADLESS_VENDOR_STRING << LL_ENDL;
- LL_INFOS("RenderInit") << "GL_RENDERER: " << HEADLESS_RENDERER_STRING << LL_ENDL;
- LL_INFOS("RenderInit") << "GL_VERSION: " << HEADLESS_VERSION_STRING << LL_ENDL;
- }
- else
- {
- LL_INFOS("RenderInit") << "GL_VENDOR: " << ll_safe_string((const char *)glGetString(GL_VENDOR)) << LL_ENDL;
- LL_INFOS("RenderInit") << "GL_RENDERER: " << ll_safe_string((const char *)glGetString(GL_RENDERER)) << LL_ENDL;
- LL_INFOS("RenderInit") << "GL_VERSION: " << ll_safe_string((const char *)glGetString(GL_VERSION)) << LL_ENDL;
- }
+ if (gHeadlessClient)
+ {
+ LL_INFOS("RenderInit") << "GL_VENDOR: " << HEADLESS_VENDOR_STRING << LL_ENDL;
+ LL_INFOS("RenderInit") << "GL_RENDERER: " << HEADLESS_RENDERER_STRING << LL_ENDL;
+ LL_INFOS("RenderInit") << "GL_VERSION: " << HEADLESS_VERSION_STRING << LL_ENDL;
+ }
+ else
+ {
+ LL_INFOS("RenderInit") << "GL_VENDOR: " << ll_safe_string((const char *)glGetString(GL_VENDOR)) << LL_ENDL;
+ LL_INFOS("RenderInit") << "GL_RENDERER: " << ll_safe_string((const char *)glGetString(GL_RENDERER)) << LL_ENDL;
+ LL_INFOS("RenderInit") << "GL_VERSION: " << ll_safe_string((const char *)glGetString(GL_VERSION)) << LL_ENDL;
+ }
#if !LL_MESA_HEADLESS
- std::string all_exts= ll_safe_string(((const char *)gGLHExts.mSysExts));
- LLStringUtil::replaceChar(all_exts, ' ', '\n');
- LL_DEBUGS("RenderInit") << "GL_EXTENSIONS:\n" << all_exts << LL_ENDL;
+ std::string all_exts= ll_safe_string(((const char *)gGLHExts.mSysExts));
+ LLStringUtil::replaceChar(all_exts, ' ', '\n');
+ LL_DEBUGS("RenderInit") << "GL_EXTENSIONS:\n" << all_exts << LL_ENDL;
#endif
}
std::string LLGLManager::getRawGLString()
{
- std::string gl_string;
- if (gHeadlessClient)
- {
- gl_string = HEADLESS_VENDOR_STRING + " " + HEADLESS_RENDERER_STRING;
- }
- else
- {
- gl_string = ll_safe_string((char*)glGetString(GL_VENDOR)) + " " + ll_safe_string((char*)glGetString(GL_RENDERER));
- }
- return gl_string;
+ std::string gl_string;
+ if (gHeadlessClient)
+ {
+ gl_string = HEADLESS_VENDOR_STRING + " " + HEADLESS_RENDERER_STRING;
+ }
+ else
+ {
+ gl_string = ll_safe_string((char*)glGetString(GL_VENDOR)) + " " + ll_safe_string((char*)glGetString(GL_RENDERER));
+ }
+ return gl_string;
}
void LLGLManager::asLLSD(LLSD& info)
{
- // Currently these are duplicates of fields in "system".
- info["gpu_vendor"] = mGLVendorShort;
- info["gpu_version"] = mDriverVersionVendorString;
- info["opengl_version"] = mGLVersionString;
-
- info["vram"] = mVRAM;
-
- // OpenGL limits
- info["max_samples"] = mMaxSamples;
- info["num_texture_image_units"] = mNumTextureImageUnits;
- info["max_sample_mask_words"] = mMaxSampleMaskWords;
- info["max_color_texture_samples"] = mMaxColorTextureSamples;
- info["max_depth_texture_samples"] = mMaxDepthTextureSamples;
- info["max_integer_samples"] = mMaxIntegerSamples;
+ // Currently these are duplicates of fields in "system".
+ info["gpu_vendor"] = mGLVendorShort;
+ info["gpu_version"] = mDriverVersionVendorString;
+ info["opengl_version"] = mGLVersionString;
+
+ info["vram"] = mVRAM;
+
+ // OpenGL limits
+ info["max_samples"] = mMaxSamples;
+ info["num_texture_image_units"] = mNumTextureImageUnits;
+ info["max_sample_mask_words"] = mMaxSampleMaskWords;
+ info["max_color_texture_samples"] = mMaxColorTextureSamples;
+ info["max_depth_texture_samples"] = mMaxDepthTextureSamples;
+ info["max_integer_samples"] = mMaxIntegerSamples;
info["max_vertex_range"] = mGLMaxVertexRange;
info["max_index_range"] = mGLMaxIndexRange;
info["max_texture_size"] = mGLMaxTextureSize;
- // Which vendor
- info["is_ati"] = mIsAMD; // note, do not rename is_ati to is_amd without coordinating with DW
- info["is_nvidia"] = mIsNVIDIA;
- info["is_intel"] = mIsIntel;
+ // Which vendor
+ info["is_ati"] = mIsAMD; // note, do not rename is_ati to is_amd without coordinating with DW
+ info["is_nvidia"] = mIsNVIDIA;
+ info["is_intel"] = mIsIntel;
- info["gl_renderer"] = mGLRenderer;
+ info["gl_renderer"] = mGLRenderer;
}
void LLGLManager::shutdownGL()
{
- if (mInited)
- {
- glFinish();
- stop_glerror();
- mInited = FALSE;
- }
+ if (mInited)
+ {
+ glFinish();
+ stop_glerror();
+ mInited = FALSE;
+ }
}
// these are used to turn software blending on. They appear in the Debug/Avatar menu
@@ -1398,22 +1398,22 @@ void LLGLManager::initExtensions()
#endif
// NOTE: version checks against mGLVersion should bias down by 0.01 because of F32 errors
-
+
// OpenGL 4.x capabilities
- mHasCubeMapArray = mGLVersion >= 3.99f;
+ mHasCubeMapArray = mGLVersion >= 3.99f;
mHasTransformFeedback = mGLVersion >= 3.99f;
mHasDebugOutput = mGLVersion >= 4.29f;
// Misc
- glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, (GLint*) &mGLMaxVertexRange);
- glGetIntegerv(GL_MAX_ELEMENTS_INDICES, (GLint*) &mGLMaxIndexRange);
- glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint*) &mGLMaxTextureSize);
+ glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, (GLint*) &mGLMaxVertexRange);
+ glGetIntegerv(GL_MAX_ELEMENTS_INDICES, (GLint*) &mGLMaxIndexRange);
+ glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint*) &mGLMaxTextureSize);
mInited = TRUE;
#if (LL_WINDOWS || LL_LINUX) && !LL_MESA_HEADLESS
- LL_DEBUGS("RenderInit") << "GL Probe: Getting symbols" << LL_ENDL;
-
+ LL_DEBUGS("RenderInit") << "GL Probe: Getting symbols" << LL_ENDL;
+
#if LL_WINDOWS
// WGL_AMD_gpu_association
wglGetGPUIDsAMD = (PFNWGLGETGPUIDSAMDPROC)GLH_EXT_GET_PROC_ADDRESS("wglGetGPUIDsAMD");
@@ -2249,123 +2249,123 @@ void LLGLManager::initExtensions()
glMultiDrawArraysIndirectCount = (PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiDrawArraysIndirectCount");
glMultiDrawElementsIndirectCount = (PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC)GLH_EXT_GET_PROC_ADDRESS("glMultiDrawElementsIndirectCount");
glPolygonOffsetClamp = (PFNGLPOLYGONOFFSETCLAMPPROC)GLH_EXT_GET_PROC_ADDRESS("glPolygonOffsetClamp");
-
+
#endif
}
void rotate_quat(LLQuaternion& rotation)
{
- F32 angle_radians, x, y, z;
- rotation.getAngleAxis(&angle_radians, &x, &y, &z);
- gGL.rotatef(angle_radians * RAD_TO_DEG, x, y, z);
+ F32 angle_radians, x, y, z;
+ rotation.getAngleAxis(&angle_radians, &x, &y, &z);
+ gGL.rotatef(angle_radians * RAD_TO_DEG, x, y, z);
}
void flush_glerror()
{
- glGetError();
+ glGetError();
}
//this function outputs gl error to the log file, does not crash the code.
void log_glerror()
{
- if (LL_UNLIKELY(!gGLManager.mInited))
- {
- return ;
- }
- // Create or update texture to be used with this data
- GLenum error;
- error = glGetError();
- while (LL_UNLIKELY(error))
- {
- GLubyte const * gl_error_msg = gluErrorString(error);
- if (NULL != gl_error_msg)
- {
- LL_WARNS() << "GL Error: " << error << " GL Error String: " << gl_error_msg << LL_ENDL ;
- }
- else
- {
- // gluErrorString returns NULL for some extensions' error codes.
- // you'll probably have to grep for the number in glext.h.
- LL_WARNS() << "GL Error: UNKNOWN 0x" << std::hex << error << std::dec << LL_ENDL;
- }
- error = glGetError();
- }
+ if (LL_UNLIKELY(!gGLManager.mInited))
+ {
+ return ;
+ }
+ // Create or update texture to be used with this data
+ GLenum error;
+ error = glGetError();
+ while (LL_UNLIKELY(error))
+ {
+ GLubyte const * gl_error_msg = gluErrorString(error);
+ if (NULL != gl_error_msg)
+ {
+ LL_WARNS() << "GL Error: " << error << " GL Error String: " << gl_error_msg << LL_ENDL ;
+ }
+ else
+ {
+ // gluErrorString returns NULL for some extensions' error codes.
+ // you'll probably have to grep for the number in glext.h.
+ LL_WARNS() << "GL Error: UNKNOWN 0x" << std::hex << error << std::dec << LL_ENDL;
+ }
+ error = glGetError();
+ }
}
void do_assert_glerror()
{
- // Create or update texture to be used with this data
- GLenum error;
- error = glGetError();
- BOOL quit = FALSE;
- if (LL_UNLIKELY(error))
- {
- quit = TRUE;
- GLubyte const * gl_error_msg = gluErrorString(error);
- if (NULL != gl_error_msg)
- {
- LL_WARNS("RenderState") << "GL Error:" << error<< LL_ENDL;
- LL_WARNS("RenderState") << "GL Error String:" << gl_error_msg << LL_ENDL;
-
- if (gDebugSession)
- {
- gFailLog << "GL Error:" << gl_error_msg << std::endl;
- }
- }
- else
- {
- // gluErrorString returns NULL for some extensions' error codes.
- // you'll probably have to grep for the number in glext.h.
- LL_WARNS("RenderState") << "GL Error: UNKNOWN 0x" << std::hex << error << std::dec << LL_ENDL;
-
- if (gDebugSession)
- {
- gFailLog << "GL Error: UNKNOWN 0x" << std::hex << error << std::dec << std::endl;
- }
- }
- }
-
- if (quit)
- {
- if (gDebugSession)
- {
- ll_fail("assert_glerror failed");
- }
- else
- {
- LL_ERRS() << "One or more unhandled GL errors." << LL_ENDL;
- }
- }
+ // Create or update texture to be used with this data
+ GLenum error;
+ error = glGetError();
+ BOOL quit = FALSE;
+ if (LL_UNLIKELY(error))
+ {
+ quit = TRUE;
+ GLubyte const * gl_error_msg = gluErrorString(error);
+ if (NULL != gl_error_msg)
+ {
+ LL_WARNS("RenderState") << "GL Error:" << error<< LL_ENDL;
+ LL_WARNS("RenderState") << "GL Error String:" << gl_error_msg << LL_ENDL;
+
+ if (gDebugSession)
+ {
+ gFailLog << "GL Error:" << gl_error_msg << std::endl;
+ }
+ }
+ else
+ {
+ // gluErrorString returns NULL for some extensions' error codes.
+ // you'll probably have to grep for the number in glext.h.
+ LL_WARNS("RenderState") << "GL Error: UNKNOWN 0x" << std::hex << error << std::dec << LL_ENDL;
+
+ if (gDebugSession)
+ {
+ gFailLog << "GL Error: UNKNOWN 0x" << std::hex << error << std::dec << std::endl;
+ }
+ }
+ }
+
+ if (quit)
+ {
+ if (gDebugSession)
+ {
+ ll_fail("assert_glerror failed");
+ }
+ else
+ {
+ LL_ERRS() << "One or more unhandled GL errors." << LL_ENDL;
+ }
+ }
}
void assert_glerror()
{
-/* if (!gGLActive)
- {
- //LL_WARNS() << "GL used while not active!" << LL_ENDL;
-
- if (gDebugSession)
- {
- //ll_fail("GL used while not active");
- }
- }
+/* if (!gGLActive)
+ {
+ //LL_WARNS() << "GL used while not active!" << LL_ENDL;
+
+ if (gDebugSession)
+ {
+ //ll_fail("GL used while not active");
+ }
+ }
*/
- if (!gDebugGL)
- {
- //funny looking if for branch prediction -- gDebugGL is almost always false and assert_glerror is called often
- }
- else
- {
- do_assert_glerror();
- }
+ if (!gDebugGL)
+ {
+ //funny looking if for branch prediction -- gDebugGL is almost always false and assert_glerror is called often
+ }
+ else
+ {
+ do_assert_glerror();
+ }
}
-
+
void clear_glerror()
{
- glGetError();
- glGetError();
+ glGetError();
+ glGetError();
}
///////////////////////////////////////////////////////////////
@@ -2381,333 +2381,333 @@ GLenum LLGLDepthTest::sDepthFunc = GL_LESS; // OpenGL default
GLboolean LLGLDepthTest::sWriteEnabled = GL_TRUE; // OpenGL default
//static
-void LLGLState::initClass()
+void LLGLState::initClass()
{
- sStateMap[GL_DITHER] = GL_TRUE;
- // sStateMap[GL_TEXTURE_2D] = GL_TRUE;
-
- //make sure multisample defaults to disabled
- sStateMap[GL_MULTISAMPLE] = GL_FALSE;
- glDisable(GL_MULTISAMPLE);
+ sStateMap[GL_DITHER] = GL_TRUE;
+ // sStateMap[GL_TEXTURE_2D] = GL_TRUE;
+
+ //make sure multisample defaults to disabled
+ sStateMap[GL_MULTISAMPLE] = GL_FALSE;
+ glDisable(GL_MULTISAMPLE);
}
//static
void LLGLState::restoreGL()
{
- sStateMap.clear();
- initClass();
+ sStateMap.clear();
+ initClass();
}
//static
// Really shouldn't be needed, but seems we sometimes do.
void LLGLState::resetTextureStates()
{
- gGL.flush();
- GLint maxTextureUnits;
-
- glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &maxTextureUnits);
- for (S32 j = maxTextureUnits-1; j >=0; j--)
- {
- gGL.getTexUnit(j)->activate();
- glClientActiveTexture(GL_TEXTURE0+j);
- j == 0 ? gGL.getTexUnit(j)->enable(LLTexUnit::TT_TEXTURE) : gGL.getTexUnit(j)->disable();
- }
+ gGL.flush();
+ GLint maxTextureUnits;
+
+ glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &maxTextureUnits);
+ for (S32 j = maxTextureUnits-1; j >=0; j--)
+ {
+ gGL.getTexUnit(j)->activate();
+ glClientActiveTexture(GL_TEXTURE0+j);
+ j == 0 ? gGL.getTexUnit(j)->enable(LLTexUnit::TT_TEXTURE) : gGL.getTexUnit(j)->disable();
+ }
}
-void LLGLState::dumpStates()
+void LLGLState::dumpStates()
{
- LL_INFOS("RenderState") << "GL States:" << LL_ENDL;
- for (boost::unordered_map<LLGLenum, LLGLboolean>::iterator iter = sStateMap.begin();
- iter != sStateMap.end(); ++iter)
- {
- LL_INFOS("RenderState") << llformat(" 0x%04x : %s",(S32)iter->first,iter->second?"TRUE":"FALSE") << LL_ENDL;
- }
+ LL_INFOS("RenderState") << "GL States:" << LL_ENDL;
+ for (boost::unordered_map<LLGLenum, LLGLboolean>::iterator iter = sStateMap.begin();
+ iter != sStateMap.end(); ++iter)
+ {
+ LL_INFOS("RenderState") << llformat(" 0x%04x : %s",(S32)iter->first,iter->second?"TRUE":"FALSE") << LL_ENDL;
+ }
}
void LLGLState::checkStates(GLboolean writeAlpha)
{
- if (!gDebugGL)
- {
- return;
- }
-
- GLint src;
- GLint dst;
- glGetIntegerv(GL_BLEND_SRC, &src);
- glGetIntegerv(GL_BLEND_DST, &dst);
+ if (!gDebugGL)
+ {
+ return;
+ }
+
+ GLint src;
+ GLint dst;
+ glGetIntegerv(GL_BLEND_SRC, &src);
+ glGetIntegerv(GL_BLEND_DST, &dst);
llassert_always(src == GL_SRC_ALPHA);
llassert_always(dst == GL_ONE_MINUS_SRC_ALPHA);
-
+
// disable for now until usage is consistent
//GLboolean colorMask[4];
//glGetBooleanv(GL_COLOR_WRITEMASK, colorMask);
//llassert_always(colorMask[0]);
//llassert_always(colorMask[1]);
//llassert_always(colorMask[2]);
- // llassert_always(colorMask[3] == writeAlpha);
-
- for (boost::unordered_map<LLGLenum, LLGLboolean>::iterator iter = sStateMap.begin();
- iter != sStateMap.end(); ++iter)
- {
- LLGLenum state = iter->first;
- LLGLboolean cur_state = iter->second;
- LLGLboolean gl_state = glIsEnabled(state);
- if(cur_state != gl_state)
- {
- dumpStates();
- LL_GL_ERRS << llformat("LLGLState error. State: 0x%04x",state) << LL_ENDL;
- }
- }
+ // llassert_always(colorMask[3] == writeAlpha);
+
+ for (boost::unordered_map<LLGLenum, LLGLboolean>::iterator iter = sStateMap.begin();
+ iter != sStateMap.end(); ++iter)
+ {
+ LLGLenum state = iter->first;
+ LLGLboolean cur_state = iter->second;
+ LLGLboolean gl_state = glIsEnabled(state);
+ if(cur_state != gl_state)
+ {
+ dumpStates();
+ LL_GL_ERRS << llformat("LLGLState error. State: 0x%04x",state) << LL_ENDL;
+ }
+ }
}
///////////////////////////////////////////////////////////////////////
LLGLState::LLGLState(LLGLenum state, S32 enabled) :
- mState(state), mWasEnabled(FALSE), mIsEnabled(FALSE)
+ mState(state), mWasEnabled(FALSE), mIsEnabled(FALSE)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
- if (mState)
- {
- mWasEnabled = sStateMap[state];
- setEnabled(enabled);
- }
+ if (mState)
+ {
+ mWasEnabled = sStateMap[state];
+ setEnabled(enabled);
+ }
}
void LLGLState::setEnabled(S32 enabled)
{
- if (!mState)
- {
- return;
- }
- if (enabled == CURRENT_STATE)
- {
- enabled = sStateMap[mState] == GL_TRUE ? TRUE : FALSE;
- }
- else if (enabled == TRUE && sStateMap[mState] != GL_TRUE)
- {
- gGL.flush();
- glEnable(mState);
- sStateMap[mState] = GL_TRUE;
- }
- else if (enabled == FALSE && sStateMap[mState] != GL_FALSE)
- {
- gGL.flush();
- glDisable(mState);
- sStateMap[mState] = GL_FALSE;
- }
- mIsEnabled = enabled;
+ if (!mState)
+ {
+ return;
+ }
+ if (enabled == CURRENT_STATE)
+ {
+ enabled = sStateMap[mState] == GL_TRUE ? TRUE : FALSE;
+ }
+ else if (enabled == TRUE && sStateMap[mState] != GL_TRUE)
+ {
+ gGL.flush();
+ glEnable(mState);
+ sStateMap[mState] = GL_TRUE;
+ }
+ else if (enabled == FALSE && sStateMap[mState] != GL_FALSE)
+ {
+ gGL.flush();
+ glDisable(mState);
+ sStateMap[mState] = GL_FALSE;
+ }
+ mIsEnabled = enabled;
}
-LLGLState::~LLGLState()
+LLGLState::~LLGLState()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
- if (mState)
- {
- if (gDebugGL)
- {
- if (!gDebugSession)
- {
- llassert_always(sStateMap[mState] == glIsEnabled(mState));
- }
- else
- {
- if (sStateMap[mState] != glIsEnabled(mState))
- {
- ll_fail("GL enabled state does not match expected");
- }
- }
- }
-
- if (mIsEnabled != mWasEnabled)
- {
- gGL.flush();
- if (mWasEnabled)
- {
- glEnable(mState);
- sStateMap[mState] = GL_TRUE;
- }
- else
- {
- glDisable(mState);
- sStateMap[mState] = GL_FALSE;
- }
- }
- }
+ if (mState)
+ {
+ if (gDebugGL)
+ {
+ if (!gDebugSession)
+ {
+ llassert_always(sStateMap[mState] == glIsEnabled(mState));
+ }
+ else
+ {
+ if (sStateMap[mState] != glIsEnabled(mState))
+ {
+ ll_fail("GL enabled state does not match expected");
+ }
+ }
+ }
+
+ if (mIsEnabled != mWasEnabled)
+ {
+ gGL.flush();
+ if (mWasEnabled)
+ {
+ glEnable(mState);
+ sStateMap[mState] = GL_TRUE;
+ }
+ else
+ {
+ glDisable(mState);
+ sStateMap[mState] = GL_FALSE;
+ }
+ }
+ }
}
////////////////////////////////////////////////////////////////////////////////
void LLGLManager::initGLStates()
{
- //gl states moved to classes in llglstates.h
- LLGLState::initClass();
+ //gl states moved to classes in llglstates.h
+ LLGLState::initClass();
}
////////////////////////////////////////////////////////////////////////////////
void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor_specific, std::string* version_string )
{
- // GL_VERSION returns a null-terminated string with the format:
- // <major>.<minor>[.<release>] [<vendor specific>]
-
- const char* version = (const char*) glGetString(GL_VERSION);
- *major = 0;
- *minor = 0;
- *release = 0;
- vendor_specific->assign("");
-
- if( !version )
- {
- return;
- }
-
- version_string->assign(version);
-
- std::string ver_copy( version );
- S32 len = (S32)strlen( version ); /* Flawfinder: ignore */
- S32 i = 0;
- S32 start;
- // Find the major version
- start = i;
- for( ; i < len; i++ )
- {
- if( '.' == version[i] )
- {
- break;
- }
- }
- std::string major_str = ver_copy.substr(start,i-start);
- LLStringUtil::convertToS32(major_str, *major);
-
- if( '.' == version[i] )
- {
- i++;
- }
-
- // Find the minor version
- start = i;
- for( ; i < len; i++ )
- {
- if( ('.' == version[i]) || isspace(version[i]) )
- {
- break;
- }
- }
- std::string minor_str = ver_copy.substr(start,i-start);
- LLStringUtil::convertToS32(minor_str, *minor);
-
- // Find the release number (optional)
- if( '.' == version[i] )
- {
- i++;
-
- start = i;
- for( ; i < len; i++ )
- {
- if( isspace(version[i]) )
- {
- break;
- }
- }
-
- std::string release_str = ver_copy.substr(start,i-start);
- LLStringUtil::convertToS32(release_str, *release);
- }
-
- // Skip over any white space
- while( version[i] && isspace( version[i] ) )
- {
- i++;
- }
-
- // Copy the vendor-specific string (optional)
- if( version[i] )
- {
- vendor_specific->assign( version + i );
- }
+ // GL_VERSION returns a null-terminated string with the format:
+ // <major>.<minor>[.<release>] [<vendor specific>]
+
+ const char* version = (const char*) glGetString(GL_VERSION);
+ *major = 0;
+ *minor = 0;
+ *release = 0;
+ vendor_specific->assign("");
+
+ if( !version )
+ {
+ return;
+ }
+
+ version_string->assign(version);
+
+ std::string ver_copy( version );
+ S32 len = (S32)strlen( version ); /* Flawfinder: ignore */
+ S32 i = 0;
+ S32 start;
+ // Find the major version
+ start = i;
+ for( ; i < len; i++ )
+ {
+ if( '.' == version[i] )
+ {
+ break;
+ }
+ }
+ std::string major_str = ver_copy.substr(start,i-start);
+ LLStringUtil::convertToS32(major_str, *major);
+
+ if( '.' == version[i] )
+ {
+ i++;
+ }
+
+ // Find the minor version
+ start = i;
+ for( ; i < len; i++ )
+ {
+ if( ('.' == version[i]) || isspace(version[i]) )
+ {
+ break;
+ }
+ }
+ std::string minor_str = ver_copy.substr(start,i-start);
+ LLStringUtil::convertToS32(minor_str, *minor);
+
+ // Find the release number (optional)
+ if( '.' == version[i] )
+ {
+ i++;
+
+ start = i;
+ for( ; i < len; i++ )
+ {
+ if( isspace(version[i]) )
+ {
+ break;
+ }
+ }
+
+ std::string release_str = ver_copy.substr(start,i-start);
+ LLStringUtil::convertToS32(release_str, *release);
+ }
+
+ // Skip over any white space
+ while( version[i] && isspace( version[i] ) )
+ {
+ i++;
+ }
+
+ // Copy the vendor-specific string (optional)
+ if( version[i] )
+ {
+ vendor_specific->assign( version + i );
+ }
}
void parse_glsl_version(S32& major, S32& minor)
{
- // GL_SHADING_LANGUAGE_VERSION returns a null-terminated string with the format:
- // <major>.<minor>[.<release>] [<vendor specific>]
-
- const char* version = (const char*) glGetString(GL_SHADING_LANGUAGE_VERSION);
- major = 0;
- minor = 0;
-
- if( !version )
- {
- return;
- }
-
- std::string ver_copy( version );
- S32 len = (S32)strlen( version ); /* Flawfinder: ignore */
- S32 i = 0;
- S32 start;
- // Find the major version
- start = i;
- for( ; i < len; i++ )
- {
- if( '.' == version[i] )
- {
- break;
- }
- }
- std::string major_str = ver_copy.substr(start,i-start);
- LLStringUtil::convertToS32(major_str, major);
-
- if( '.' == version[i] )
- {
- i++;
- }
-
- // Find the minor version
- start = i;
- for( ; i < len; i++ )
- {
- if( ('.' == version[i]) || isspace(version[i]) )
- {
- break;
- }
- }
- std::string minor_str = ver_copy.substr(start,i-start);
- LLStringUtil::convertToS32(minor_str, minor);
+ // GL_SHADING_LANGUAGE_VERSION returns a null-terminated string with the format:
+ // <major>.<minor>[.<release>] [<vendor specific>]
+
+ const char* version = (const char*) glGetString(GL_SHADING_LANGUAGE_VERSION);
+ major = 0;
+ minor = 0;
+
+ if( !version )
+ {
+ return;
+ }
+
+ std::string ver_copy( version );
+ S32 len = (S32)strlen( version ); /* Flawfinder: ignore */
+ S32 i = 0;
+ S32 start;
+ // Find the major version
+ start = i;
+ for( ; i < len; i++ )
+ {
+ if( '.' == version[i] )
+ {
+ break;
+ }
+ }
+ std::string major_str = ver_copy.substr(start,i-start);
+ LLStringUtil::convertToS32(major_str, major);
+
+ if( '.' == version[i] )
+ {
+ i++;
+ }
+
+ // Find the minor version
+ start = i;
+ for( ; i < len; i++ )
+ {
+ if( ('.' == version[i]) || isspace(version[i]) )
+ {
+ break;
+ }
+ }
+ std::string minor_str = ver_copy.substr(start,i-start);
+ LLStringUtil::convertToS32(minor_str, minor);
}
LLGLUserClipPlane::LLGLUserClipPlane(const LLPlane& p, const glh::matrix4f& modelview, const glh::matrix4f& projection, bool apply)
{
- mApply = apply;
+ mApply = apply;
- if (mApply)
- {
- mModelview = modelview;
- mProjection = projection;
+ if (mApply)
+ {
+ mModelview = modelview;
+ mProjection = projection;
//flip incoming LLPlane to get consistent behavior compared to frustum culling
- setPlane(-p[0], -p[1], -p[2], -p[3]);
- }
+ setPlane(-p[0], -p[1], -p[2], -p[3]);
+ }
}
void LLGLUserClipPlane::disable()
{
if (mApply)
- {
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.popMatrix();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- }
+ {
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.popMatrix();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ }
mApply = false;
}
void LLGLUserClipPlane::setPlane(F32 a, F32 b, F32 c, F32 d)
{
- glh::matrix4f& P = mProjection;
- glh::matrix4f& M = mModelview;
-
- glh::matrix4f invtrans_MVP = (P * M).inverse().transpose();
+ glh::matrix4f& P = mProjection;
+ glh::matrix4f& M = mModelview;
+
+ glh::matrix4f invtrans_MVP = (P * M).inverse().transpose();
glh::vec4f oplane(a,b,c,d);
glh::vec4f cplane;
invtrans_MVP.mult_matrix_vec(oplane, cplane);
@@ -2722,100 +2722,100 @@ void LLGLUserClipPlane::setPlane(F32 a, F32 b, F32 c, F32 d)
suffix.set_row(2, cplane);
glh::matrix4f newP = suffix * P;
gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.pushMatrix();
+ gGL.pushMatrix();
gGL.loadMatrix(newP.m);
- gGLObliqueProjectionInverse = LLMatrix4(newP.inverse().transpose().m);
+ gGLObliqueProjectionInverse = LLMatrix4(newP.inverse().transpose().m);
gGL.matrixMode(LLRender::MM_MODELVIEW);
}
LLGLUserClipPlane::~LLGLUserClipPlane()
{
- disable();
+ disable();
}
LLGLDepthTest::LLGLDepthTest(GLboolean depth_enabled, GLboolean write_enabled, GLenum depth_func)
: mPrevDepthEnabled(sDepthEnabled), mPrevDepthFunc(sDepthFunc), mPrevWriteEnabled(sWriteEnabled)
{
- stop_glerror();
-
- checkState();
-
- if (!depth_enabled)
- { // always disable depth writes if depth testing is disabled
- // GL spec defines this as a requirement, but some implementations allow depth writes with testing disabled
- // The proper way to write to depth buffer with testing disabled is to enable testing and use a depth_func of GL_ALWAYS
- write_enabled = FALSE;
- }
-
- if (depth_enabled != sDepthEnabled)
- {
- gGL.flush();
- if (depth_enabled) glEnable(GL_DEPTH_TEST);
- else glDisable(GL_DEPTH_TEST);
- sDepthEnabled = depth_enabled;
- }
- if (depth_func != sDepthFunc)
- {
- gGL.flush();
- glDepthFunc(depth_func);
- sDepthFunc = depth_func;
- }
- if (write_enabled != sWriteEnabled)
- {
- gGL.flush();
- glDepthMask(write_enabled);
- sWriteEnabled = write_enabled;
- }
+ stop_glerror();
+
+ checkState();
+
+ if (!depth_enabled)
+ { // always disable depth writes if depth testing is disabled
+ // GL spec defines this as a requirement, but some implementations allow depth writes with testing disabled
+ // The proper way to write to depth buffer with testing disabled is to enable testing and use a depth_func of GL_ALWAYS
+ write_enabled = FALSE;
+ }
+
+ if (depth_enabled != sDepthEnabled)
+ {
+ gGL.flush();
+ if (depth_enabled) glEnable(GL_DEPTH_TEST);
+ else glDisable(GL_DEPTH_TEST);
+ sDepthEnabled = depth_enabled;
+ }
+ if (depth_func != sDepthFunc)
+ {
+ gGL.flush();
+ glDepthFunc(depth_func);
+ sDepthFunc = depth_func;
+ }
+ if (write_enabled != sWriteEnabled)
+ {
+ gGL.flush();
+ glDepthMask(write_enabled);
+ sWriteEnabled = write_enabled;
+ }
}
LLGLDepthTest::~LLGLDepthTest()
{
- checkState();
- if (sDepthEnabled != mPrevDepthEnabled )
- {
- gGL.flush();
- if (mPrevDepthEnabled) glEnable(GL_DEPTH_TEST);
- else glDisable(GL_DEPTH_TEST);
- sDepthEnabled = mPrevDepthEnabled;
- }
- if (sDepthFunc != mPrevDepthFunc)
- {
- gGL.flush();
- glDepthFunc(mPrevDepthFunc);
- sDepthFunc = mPrevDepthFunc;
- }
- if (sWriteEnabled != mPrevWriteEnabled )
- {
- gGL.flush();
- glDepthMask(mPrevWriteEnabled);
- sWriteEnabled = mPrevWriteEnabled;
- }
+ checkState();
+ if (sDepthEnabled != mPrevDepthEnabled )
+ {
+ gGL.flush();
+ if (mPrevDepthEnabled) glEnable(GL_DEPTH_TEST);
+ else glDisable(GL_DEPTH_TEST);
+ sDepthEnabled = mPrevDepthEnabled;
+ }
+ if (sDepthFunc != mPrevDepthFunc)
+ {
+ gGL.flush();
+ glDepthFunc(mPrevDepthFunc);
+ sDepthFunc = mPrevDepthFunc;
+ }
+ if (sWriteEnabled != mPrevWriteEnabled )
+ {
+ gGL.flush();
+ glDepthMask(mPrevWriteEnabled);
+ sWriteEnabled = mPrevWriteEnabled;
+ }
}
void LLGLDepthTest::checkState()
{
- if (gDebugGL)
- {
- GLint func = 0;
- GLboolean mask = FALSE;
-
- glGetIntegerv(GL_DEPTH_FUNC, &func);
- glGetBooleanv(GL_DEPTH_WRITEMASK, &mask);
-
- if (glIsEnabled(GL_DEPTH_TEST) != sDepthEnabled ||
- sWriteEnabled != mask ||
- sDepthFunc != func)
- {
- if (gDebugSession)
- {
- gFailLog << "Unexpected depth testing state." << std::endl;
- }
- else
- {
- LL_GL_ERRS << "Unexpected depth testing state." << LL_ENDL;
- }
- }
- }
+ if (gDebugGL)
+ {
+ GLint func = 0;
+ GLboolean mask = FALSE;
+
+ glGetIntegerv(GL_DEPTH_FUNC, &func);
+ glGetBooleanv(GL_DEPTH_WRITEMASK, &mask);
+
+ if (glIsEnabled(GL_DEPTH_TEST) != sDepthEnabled ||
+ sWriteEnabled != mask ||
+ sDepthFunc != func)
+ {
+ if (gDebugSession)
+ {
+ gFailLog << "Unexpected depth testing state." << std::endl;
+ }
+ else
+ {
+ LL_GL_ERRS << "Unexpected depth testing state." << LL_ENDL;
+ }
+ }
+ }
}
LLGLSquashToFarClip::LLGLSquashToFarClip()
@@ -2833,84 +2833,84 @@ LLGLSquashToFarClip::LLGLSquashToFarClip(glh::matrix4f& P, U32 layer)
void LLGLSquashToFarClip::setProjectionMatrix(glh::matrix4f& projection, U32 layer)
{
- F32 depth = 0.99999f - 0.0001f * layer;
+ F32 depth = 0.99999f - 0.0001f * layer;
- for (U32 i = 0; i < 4; i++)
- {
- projection.element(2, i) = projection.element(3, i) * depth;
- }
+ for (U32 i = 0; i < 4; i++)
+ {
+ projection.element(2, i) = projection.element(3, i) * depth;
+ }
LLRender::eMatrixMode last_matrix_mode = gGL.getMatrixMode();
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.pushMatrix();
- gGL.loadMatrix(projection.m);
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.pushMatrix();
+ gGL.loadMatrix(projection.m);
- gGL.matrixMode(last_matrix_mode);
+ gGL.matrixMode(last_matrix_mode);
}
LLGLSquashToFarClip::~LLGLSquashToFarClip()
{
LLRender::eMatrixMode last_matrix_mode = gGL.getMatrixMode();
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.popMatrix();
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.popMatrix();
- gGL.matrixMode(last_matrix_mode);
+ gGL.matrixMode(last_matrix_mode);
}
-
+
LLGLSyncFence::LLGLSyncFence()
{
- mSync = 0;
+ mSync = 0;
}
LLGLSyncFence::~LLGLSyncFence()
{
- if (mSync)
- {
- glDeleteSync(mSync);
- }
+ if (mSync)
+ {
+ glDeleteSync(mSync);
+ }
}
void LLGLSyncFence::placeFence()
{
- if (mSync)
- {
- glDeleteSync(mSync);
- }
- mSync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
+ if (mSync)
+ {
+ glDeleteSync(mSync);
+ }
+ mSync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
}
bool LLGLSyncFence::isCompleted()
{
- bool ret = true;
- if (mSync)
- {
- GLenum status = glClientWaitSync(mSync, 0, 1);
- if (status == GL_TIMEOUT_EXPIRED)
- {
- ret = false;
- }
- }
- return ret;
+ bool ret = true;
+ if (mSync)
+ {
+ GLenum status = glClientWaitSync(mSync, 0, 1);
+ if (status == GL_TIMEOUT_EXPIRED)
+ {
+ ret = false;
+ }
+ }
+ return ret;
}
void LLGLSyncFence::wait()
{
- if (mSync)
- {
- while (glClientWaitSync(mSync, 0, FENCE_WAIT_TIME_NANOSECONDS) == GL_TIMEOUT_EXPIRED)
- { //track the number of times we've waited here
- }
- }
+ if (mSync)
+ {
+ while (glClientWaitSync(mSync, 0, FENCE_WAIT_TIME_NANOSECONDS) == GL_TIMEOUT_EXPIRED)
+ { //track the number of times we've waited here
+ }
+ }
}
LLGLSPipelineSkyBox::LLGLSPipelineSkyBox()
: mCullFace(GL_CULL_FACE)
, mSquashClip()
-{
+{
}
LLGLSPipelineSkyBox::~LLGLSPipelineSkyBox()
@@ -2925,17 +2925,17 @@ LLGLSPipelineDepthTestSkyBox::LLGLSPipelineDepthTestSkyBox(bool depth_test, bool
}
LLGLSPipelineBlendSkyBox::LLGLSPipelineBlendSkyBox(bool depth_test, bool depth_write)
-: LLGLSPipelineDepthTestSkyBox(depth_test, depth_write)
+: LLGLSPipelineDepthTestSkyBox(depth_test, depth_write)
, mBlend(GL_BLEND)
-{
+{
gGL.setSceneBlendType(LLRender::BT_ALPHA);
}
#if LL_WINDOWS
// Expose desired use of high-performance graphics processor to Optimus driver and to AMD driver
// https://docs.nvidia.com/gameworks/content/technologies/desktop/optimus.htm
-extern "C"
-{
+extern "C"
+{
__declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
}
diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h
index 4b0fbc0466..5a7ad943df 100644
--- a/indra/llrender/llgl.h
+++ b/indra/llrender/llgl.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file llgl.h
* @brief LLGL definition
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -64,81 +64,81 @@ class LLSD;
class LLGLManager
{
public:
- LLGLManager();
+ LLGLManager();
- bool initGL();
- void shutdownGL();
+ bool initGL();
+ void shutdownGL();
- void initWGL(); // Initializes stupid WGL extensions
+ void initWGL(); // Initializes stupid WGL extensions
- std::string getRawGLString(); // For sending to simulator
+ std::string getRawGLString(); // For sending to simulator
- BOOL mInited;
- BOOL mIsDisabled;
+ BOOL mInited;
+ BOOL mIsDisabled;
- // OpenGL limits
- S32 mMaxSamples;
- S32 mNumTextureImageUnits;
- S32 mMaxSampleMaskWords;
- S32 mMaxColorTextureSamples;
- S32 mMaxDepthTextureSamples;
- S32 mMaxIntegerSamples;
+ // OpenGL limits
+ S32 mMaxSamples;
+ S32 mNumTextureImageUnits;
+ S32 mMaxSampleMaskWords;
+ S32 mMaxColorTextureSamples;
+ S32 mMaxDepthTextureSamples;
+ S32 mMaxIntegerSamples;
S32 mGLMaxVertexRange;
S32 mGLMaxIndexRange;
S32 mGLMaxTextureSize;
F32 mMaxAnisotropy = 0.f;
- // GL 4.x capabilities
- bool mHasCubeMapArray = false;
- bool mHasDebugOutput = false;
+ // GL 4.x capabilities
+ bool mHasCubeMapArray = false;
+ bool mHasDebugOutput = false;
bool mHasTransformFeedback = false;
bool mHasAnisotropic = false;
-
- // Vendor-specific extensions
+
+ // Vendor-specific extensions
bool mHasAMDAssociations = false;
- BOOL mIsAMD;
- BOOL mIsNVIDIA;
- BOOL mIsIntel;
+ BOOL mIsAMD;
+ BOOL mIsNVIDIA;
+ BOOL mIsIntel;
#if LL_DARWIN
- // Needed to distinguish problem cards on older Macs that break with Materials
- BOOL mIsMobileGF;
+ // Needed to distinguish problem cards on older Macs that break with Materials
+ BOOL mIsMobileGF;
#endif
-
- // Whether this version of GL is good enough for SL to use
- BOOL mHasRequirements;
- S32 mDriverVersionMajor;
- S32 mDriverVersionMinor;
- S32 mDriverVersionRelease;
- F32 mGLVersion; // e.g = 1.4
- S32 mGLSLVersionMajor;
- S32 mGLSLVersionMinor;
- std::string mDriverVersionVendorString;
- std::string mGLVersionString;
+ // Whether this version of GL is good enough for SL to use
+ BOOL mHasRequirements;
+
+ S32 mDriverVersionMajor;
+ S32 mDriverVersionMinor;
+ S32 mDriverVersionRelease;
+ F32 mGLVersion; // e.g = 1.4
+ S32 mGLSLVersionMajor;
+ S32 mGLSLVersionMinor;
+ std::string mDriverVersionVendorString;
+ std::string mGLVersionString;
- S32 mVRAM; // VRAM in MB
-
- void getPixelFormat(); // Get the best pixel format
+ S32 mVRAM; // VRAM in MB
- std::string getGLInfoString();
- void printGLInfoString();
- void getGLInfo(LLSD& info);
+ void getPixelFormat(); // Get the best pixel format
- void asLLSD(LLSD& info);
+ std::string getGLInfoString();
+ void printGLInfoString();
+ void getGLInfo(LLSD& info);
- // In ALL CAPS
- std::string mGLVendor;
- std::string mGLVendorShort;
+ void asLLSD(LLSD& info);
- // In ALL CAPS
- std::string mGLRenderer;
+ // In ALL CAPS
+ std::string mGLVendor;
+ std::string mGLVendorShort;
+
+ // In ALL CAPS
+ std::string mGLRenderer;
private:
- void initExtensions();
- void initGLStates();
- void initGLImages();
+ void initExtensions();
+ void initGLStates();
+ void initGLImages();
};
extern LLGLManager gGLManager;
@@ -173,51 +173,51 @@ void clear_glerror();
// This is a class for GL state management
/*
- GL STATE MANAGEMENT DESCRIPTION
+ GL STATE MANAGEMENT DESCRIPTION
- LLGLState and its two subclasses, LLGLEnable and LLGLDisable, manage the current
- enable/disable states of the GL to prevent redundant setting of state within a
- render path or the accidental corruption of what state the next path expects.
+ LLGLState and its two subclasses, LLGLEnable and LLGLDisable, manage the current
+ enable/disable states of the GL to prevent redundant setting of state within a
+ render path or the accidental corruption of what state the next path expects.
- Essentially, wherever you would call glEnable set a state and then
- subsequently reset it by calling glDisable (or vice versa), make an instance of
- LLGLEnable with the state you want to set, and assume it will be restored to its
- original state when that instance of LLGLEnable is destroyed. It is good practice
- to exploit stack frame controls for optimal setting/unsetting and readability of
- code. In llglstates.h, there are a collection of helper classes that define groups
- of enables/disables that can cause multiple states to be set with the creation of
- one instance.
+ Essentially, wherever you would call glEnable set a state and then
+ subsequently reset it by calling glDisable (or vice versa), make an instance of
+ LLGLEnable with the state you want to set, and assume it will be restored to its
+ original state when that instance of LLGLEnable is destroyed. It is good practice
+ to exploit stack frame controls for optimal setting/unsetting and readability of
+ code. In llglstates.h, there are a collection of helper classes that define groups
+ of enables/disables that can cause multiple states to be set with the creation of
+ one instance.
- Sample usage:
+ Sample usage:
- //disable lighting for rendering hud objects
- //INCORRECT USAGE
- LLGLEnable blend(GL_BLEND);
- renderHUD();
- LLGLDisable blend(GL_BLEND);
+ //disable lighting for rendering hud objects
+ //INCORRECT USAGE
+ LLGLEnable blend(GL_BLEND);
+ renderHUD();
+ LLGLDisable blend(GL_BLEND);
- //CORRECT USAGE
- {
- LLGLEnable blend(GL_BLEND);
- renderHUD();
- }
+ //CORRECT USAGE
+ {
+ LLGLEnable blend(GL_BLEND);
+ renderHUD();
+ }
- If a state is to be set on a conditional, the following mechanism
- is useful:
+ If a state is to be set on a conditional, the following mechanism
+ is useful:
- {
- LLGLEnable blend(blend_hud ? GL_GL_BLEND: 0);
- renderHUD();
- }
+ {
+ LLGLEnable blend(blend_hud ? GL_GL_BLEND: 0);
+ renderHUD();
+ }
- A LLGLState initialized with a parameter of 0 does nothing.
+ A LLGLState initialized with a parameter of 0 does nothing.
- LLGLState works by maintaining a map of the current GL states, and ignoring redundant
- enables/disables. If a redundant call is attempted, it becomes a noop, otherwise,
- it is set in the constructor and reset in the destructor.
+ LLGLState works by maintaining a map of the current GL states, and ignoring redundant
+ enables/disables. If a redundant call is attempted, it becomes a noop, otherwise,
+ it is set in the constructor and reset in the destructor.
- For debugging GL state corruption, running with debug enabled will trigger asserts
- if the existing GL state does not match the expected GL state.
+ For debugging GL state corruption, running with debug enabled will trigger asserts
+ if the existing GL state does not match the expected GL state.
*/
@@ -226,79 +226,79 @@ void clear_glerror();
class LLGLState
{
public:
- static void initClass();
- static void restoreGL();
+ static void initClass();
+ static void restoreGL();
- static void resetTextureStates();
- static void dumpStates();
+ static void resetTextureStates();
+ static void dumpStates();
// make sure GL blend function, GL states, and GL color mask match
- // what we expect
+ // what we expect
// writeAlpha - whether or not writing to alpha channel is expected
- static void checkStates(GLboolean writeAlpha = GL_TRUE);
+ static void checkStates(GLboolean writeAlpha = GL_TRUE);
protected:
- static boost::unordered_map<LLGLenum, LLGLboolean> sStateMap;
-
+ static boost::unordered_map<LLGLenum, LLGLboolean> sStateMap;
+
public:
- enum { CURRENT_STATE = -2 };
- LLGLState(LLGLenum state, S32 enabled = CURRENT_STATE);
- ~LLGLState();
- void setEnabled(S32 enabled);
- void enable() { setEnabled(TRUE); }
- void disable() { setEnabled(FALSE); }
+ enum { CURRENT_STATE = -2 };
+ LLGLState(LLGLenum state, S32 enabled = CURRENT_STATE);
+ ~LLGLState();
+ void setEnabled(S32 enabled);
+ void enable() { setEnabled(TRUE); }
+ void disable() { setEnabled(FALSE); }
protected:
- LLGLenum mState;
- BOOL mWasEnabled;
- BOOL mIsEnabled;
+ LLGLenum mState;
+ BOOL mWasEnabled;
+ BOOL mIsEnabled;
};
// New LLGLState class wrappers that don't depend on actual GL flags.
class LLGLEnableBlending : public LLGLState
{
public:
- LLGLEnableBlending(bool enable);
+ LLGLEnableBlending(bool enable);
};
class LLGLEnableAlphaReject : public LLGLState
{
public:
- LLGLEnableAlphaReject(bool enable);
+ LLGLEnableAlphaReject(bool enable);
};
// Enable with functor
class LLGLEnableFunc : LLGLState
{
public:
- LLGLEnableFunc(LLGLenum state, bool enable, boost::function<void()> func)
- : LLGLState(state, enable)
- {
- if (enable)
- {
- func();
- }
- }
+ LLGLEnableFunc(LLGLenum state, bool enable, boost::function<void()> func)
+ : LLGLState(state, enable)
+ {
+ if (enable)
+ {
+ func();
+ }
+ }
};
/// TODO: Being deprecated.
class LLGLEnable : public LLGLState
{
public:
- LLGLEnable(LLGLenum state) : LLGLState(state, TRUE) {}
+ LLGLEnable(LLGLenum state) : LLGLState(state, TRUE) {}
};
/// TODO: Being deprecated.
class LLGLDisable : public LLGLState
{
public:
- LLGLDisable(LLGLenum state) : LLGLState(state, FALSE) {}
+ LLGLDisable(LLGLenum state) : LLGLState(state, FALSE) {}
};
/*
Store and modify projection matrix to create an oblique
projection that clips to the specified plane. Oblique
projections alter values in the depth buffer, so this
- class should not be used mid-renderpass.
+ class should not be used mid-renderpass.
Restores projection matrix on destruction.
GL_MODELVIEW_MATRIX is active whenever program execution
@@ -306,21 +306,21 @@ public:
Does not stack.
Caches inverse of projection matrix used in gGLObliqueProjectionInverse
*/
-class LLGLUserClipPlane
+class LLGLUserClipPlane
{
public:
-
- 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);
+ 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);
void disable();
private:
- bool mApply;
+ bool mApply;
- glh::matrix4f mProjection;
- glh::matrix4f mModelview;
+ glh::matrix4f mProjection;
+ glh::matrix4f mModelview;
};
/*
@@ -334,40 +334,40 @@ class LLGLSquashToFarClip
{
public:
LLGLSquashToFarClip();
- LLGLSquashToFarClip(glh::matrix4f& projection, U32 layer = 0);
+ LLGLSquashToFarClip(glh::matrix4f& projection, U32 layer = 0);
void setProjectionMatrix(glh::matrix4f& projection, U32 layer);
- ~LLGLSquashToFarClip();
+ ~LLGLSquashToFarClip();
};
/*
- Interface for objects that need periodic GL updates applied to them.
- Used to synchronize GL updates with GL thread.
+ Interface for objects that need periodic GL updates applied to them.
+ Used to synchronize GL updates with GL thread.
*/
class LLGLUpdate
{
public:
- static std::list<LLGLUpdate*> sGLQ;
-
- BOOL mInQ;
- LLGLUpdate()
- : mInQ(FALSE)
- {
- }
- virtual ~LLGLUpdate()
- {
- if (mInQ)
- {
- std::list<LLGLUpdate*>::iterator iter = std::find(sGLQ.begin(), sGLQ.end(), this);
- if (iter != sGLQ.end())
- {
- sGLQ.erase(iter);
- }
- }
- }
- virtual void updateGL() = 0;
+ static std::list<LLGLUpdate*> sGLQ;
+
+ BOOL mInQ;
+ LLGLUpdate()
+ : mInQ(FALSE)
+ {
+ }
+ virtual ~LLGLUpdate()
+ {
+ if (mInQ)
+ {
+ std::list<LLGLUpdate*>::iterator iter = std::find(sGLQ.begin(), sGLQ.end(), this);
+ if (iter != sGLQ.end())
+ {
+ sGLQ.erase(iter);
+ }
+ }
+ }
+ virtual void updateGL() = 0;
};
const U32 FENCE_WAIT_TIME_NANOSECONDS = 1000; //1 ms
@@ -375,26 +375,26 @@ const U32 FENCE_WAIT_TIME_NANOSECONDS = 1000; //1 ms
class LLGLFence
{
public:
- virtual ~LLGLFence()
- {
- }
+ virtual ~LLGLFence()
+ {
+ }
- virtual void placeFence() = 0;
- virtual bool isCompleted() = 0;
- virtual void wait() = 0;
+ virtual void placeFence() = 0;
+ virtual bool isCompleted() = 0;
+ virtual void wait() = 0;
};
class LLGLSyncFence : public LLGLFence
{
public:
- GLsync mSync;
-
- LLGLSyncFence();
- virtual ~LLGLSyncFence();
-
- void placeFence();
- bool isCompleted();
- void wait();
+ GLsync mSync;
+
+ LLGLSyncFence();
+ virtual ~LLGLSyncFence();
+
+ void placeFence();
+ bool isCompleted();
+ void wait();
};
extern LLMatrix4 gGLObliqueProjectionInverse;
@@ -471,6 +471,6 @@ extern BOOL gGLActive;
#ifndef GL_DEPTH24_STENCIL8
#define GL_DEPTH24_STENCIL8 GL_DEPTH24_STENCIL8_EXT
-#endif
+#endif
#endif // LL_LLGL_H
diff --git a/indra/llrender/llglcommonfunc.cpp b/indra/llrender/llglcommonfunc.cpp
index 04d29b9430..13b08de7cc 100644
--- a/indra/llrender/llglcommonfunc.cpp
+++ b/indra/llrender/llglcommonfunc.cpp
@@ -27,12 +27,12 @@
#include "llglheaders.h"
#include "llglcommonfunc.h"
-namespace LLGLCommonFunc
+namespace LLGLCommonFunc
{
- void selected_stencil_test()
- {
+ void selected_stencil_test()
+ {
// deprecated
- //glStencilFunc(GL_ALWAYS, 2, 0xffff);
- //glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
- }
+ //glStencilFunc(GL_ALWAYS, 2, 0xffff);
+ //glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
+ }
}
diff --git a/indra/llrender/llglcommonfunc.h b/indra/llrender/llglcommonfunc.h
index e6d3755755..bb995fc199 100644
--- a/indra/llrender/llglcommonfunc.h
+++ b/indra/llrender/llglcommonfunc.h
@@ -26,5 +26,5 @@
namespace LLGLCommonFunc
{
- void selected_stencil_test();
+ void selected_stencil_test();
}
diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h
index b80680a3d2..c5e1ff3e23 100644
--- a/indra/llrender/llglheaders.h
+++ b/indra/llrender/llglheaders.h
@@ -855,7 +855,7 @@ extern void glGenerateMipmapEXT(GLenum target) AVAILABLE_MAC_OS_X_VERSION_10_4_A
#ifndef GL_ARB_framebuffer_object
#define glGenerateMipmap glGenerateMipmapEXT
-#define GL_MAX_SAMPLES 0x8D57
+#define GL_MAX_SAMPLES 0x8D57
#endif
#ifdef __cplusplus
@@ -937,7 +937,7 @@ extern "C" {
#define GL_DYNAMIC_READ_ARB 0x88E9
#define GL_DYNAMIC_COPY_ARB 0x88EA
#endif
-
+
#ifndef GL_ARB_vertex_buffer_object
@@ -957,7 +957,7 @@ typedef GLboolean (* glIsBufferARBProcPtr) (GLuint buffer);
typedef void (* glBufferDataARBProcPtr) (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage);
typedef void (* glBufferSubDataARBProcPtr) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data);
typedef void (* glGetBufferSubDataARBProcPtr) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data);
-typedef GLvoid* (* glMapBufferARBProcPtr) (GLenum target, GLenum access); /* Flawfinder: ignore */
+typedef GLvoid* (* glMapBufferARBProcPtr) (GLenum target, GLenum access); /* Flawfinder: ignore */
typedef GLboolean (* glUnmapBufferARBProcPtr) (GLenum target);
typedef void (* glGetBufferParameterivARBProcPtr) (GLenum target, GLenum pname, GLint *params);
typedef void (* glGetBufferPointervARBProcPtr) (GLenum target, GLenum pname, GLvoid* *params);
@@ -1045,11 +1045,11 @@ extern void glGetBufferPointervARB (GLenum, GLenum, GLvoid* *);
//GL_NVX_gpu_memory_info constants
#ifndef GL_NVX_gpu_memory_info
#define GL_NVX_gpu_memory_info
-#define GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX 0x9047
-#define GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX 0x9048
-#define GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX 0x9049
-#define GL_GPU_MEMORY_INFO_EVICTION_COUNT_NVX 0x904A
-#define GL_GPU_MEMORY_INFO_EVICTED_MEMORY_NVX 0x904B
+#define GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX 0x9047
+#define GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX 0x9048
+#define GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX 0x9049
+#define GL_GPU_MEMORY_INFO_EVICTION_COUNT_NVX 0x904A
+#define GL_GPU_MEMORY_INFO_EVICTED_MEMORY_NVX 0x904B
#endif
//GL_ATI_meminfo constants
@@ -1063,6 +1063,6 @@ extern void glGetBufferPointervARB (GLenum, GLenum, GLvoid* *);
#if defined(TRACY_ENABLE) && LL_PROFILER_ENABLE_TRACY_OPENGL
#include <tracy/TracyOpenGL.hpp>
#endif
-
+
#endif // LL_LLGLHEADERS_H
diff --git a/indra/llrender/llglstates.h b/indra/llrender/llglstates.h
index 930c5e3ed7..9bb980d7ad 100644
--- a/indra/llrender/llglstates.h
+++ b/indra/llrender/llglstates.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file llglstates.h
* @brief LLGL states definitions
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -34,21 +34,21 @@
class LLGLDepthTest
{
- // Enabled by default
+ // Enabled by default
public:
- LLGLDepthTest(GLboolean depth_enabled, GLboolean write_enabled = GL_TRUE, GLenum depth_func = GL_LEQUAL);
-
- ~LLGLDepthTest();
-
- void checkState();
-
- GLboolean mPrevDepthEnabled;
- GLenum mPrevDepthFunc;
- GLboolean mPrevWriteEnabled;
+ LLGLDepthTest(GLboolean depth_enabled, GLboolean write_enabled = GL_TRUE, GLenum depth_func = GL_LEQUAL);
+
+ ~LLGLDepthTest();
+
+ void checkState();
+
+ GLboolean mPrevDepthEnabled;
+ GLenum mPrevDepthFunc;
+ GLboolean mPrevWriteEnabled;
private:
- static GLboolean sDepthEnabled; // defaults to GL_FALSE
- static GLenum sDepthFunc; // defaults to GL_LESS
- static GLboolean sWriteEnabled; // defaults to GL_TRUE
+ static GLboolean sDepthEnabled; // defaults to GL_FALSE
+ static GLenum sDepthFunc; // defaults to GL_LESS
+ static GLboolean sWriteEnabled; // defaults to GL_TRUE
};
//----------------------------------------------------------------------------
@@ -58,110 +58,110 @@ class LLGLSDefault
protected:
LLGLDisable mBlend, mCullFace;
public:
- LLGLSDefault()
- :
- // Disable
- mBlend(GL_BLEND),
- mCullFace(GL_CULL_FACE)
- { }
+ LLGLSDefault()
+ :
+ // Disable
+ mBlend(GL_BLEND),
+ mCullFace(GL_CULL_FACE)
+ { }
};
class LLGLSObjectSelect
-{
+{
protected:
- LLGLDisable mBlend;
- LLGLEnable mCullFace;
+ LLGLDisable mBlend;
+ LLGLEnable mCullFace;
public:
- LLGLSObjectSelect()
- : mBlend(GL_BLEND),
- mCullFace(GL_CULL_FACE)
- { }
+ LLGLSObjectSelect()
+ : mBlend(GL_BLEND),
+ mCullFace(GL_CULL_FACE)
+ { }
};
//----------------------------------------------------------------------------
class LLGLSUIDefault
-{
+{
protected:
- LLGLEnable mBlend;
- LLGLDisable mCullFace;
- LLGLDepthTest mDepthTest;
+ LLGLEnable mBlend;
+ LLGLDisable mCullFace;
+ LLGLDepthTest mDepthTest;
public:
- LLGLSUIDefault()
- : mBlend(GL_BLEND),
- mCullFace(GL_CULL_FACE),
- mDepthTest(GL_FALSE, GL_TRUE, GL_LEQUAL)
- {}
+ LLGLSUIDefault()
+ : mBlend(GL_BLEND),
+ mCullFace(GL_CULL_FACE),
+ mDepthTest(GL_FALSE, GL_TRUE, GL_LEQUAL)
+ {}
};
//----------------------------------------------------------------------------
class LLGLSPipeline
-{
+{
protected:
- LLGLEnable mCullFace;
- LLGLDepthTest mDepthTest;
+ LLGLEnable mCullFace;
+ LLGLDepthTest mDepthTest;
public:
- LLGLSPipeline()
- : mCullFace(GL_CULL_FACE),
- mDepthTest(GL_TRUE, GL_TRUE, GL_LEQUAL)
- { }
+ LLGLSPipeline()
+ : mCullFace(GL_CULL_FACE),
+ mDepthTest(GL_TRUE, GL_TRUE, GL_LEQUAL)
+ { }
};
class LLGLSPipelineAlpha // : public LLGLSPipeline
-{
+{
protected:
- LLGLEnable mBlend;
+ LLGLEnable mBlend;
public:
- LLGLSPipelineAlpha()
- : mBlend(GL_BLEND)
- { }
+ LLGLSPipelineAlpha()
+ : mBlend(GL_BLEND)
+ { }
};
class LLGLSPipelineSelection
-{
+{
protected:
- LLGLDisable mCullFace;
+ LLGLDisable mCullFace;
public:
- LLGLSPipelineSelection()
- : mCullFace(GL_CULL_FACE)
- {}
+ LLGLSPipelineSelection()
+ : mCullFace(GL_CULL_FACE)
+ {}
};
class LLGLSPipelineSkyBox
-{
+{
protected:
LLGLDisable mCullFace;
LLGLSquashToFarClip mSquashClip;
public:
- LLGLSPipelineSkyBox();
+ LLGLSPipelineSkyBox();
~LLGLSPipelineSkyBox();
};
class LLGLSPipelineDepthTestSkyBox : public LLGLSPipelineSkyBox
-{
+{
public:
- LLGLSPipelineDepthTestSkyBox(bool depth_test, bool depth_write);
+ LLGLSPipelineDepthTestSkyBox(bool depth_test, bool depth_write);
LLGLDepthTest mDepth;
};
-class LLGLSPipelineBlendSkyBox : public LLGLSPipelineDepthTestSkyBox
-{
+class LLGLSPipelineBlendSkyBox : public LLGLSPipelineDepthTestSkyBox
+{
public:
- LLGLSPipelineBlendSkyBox(bool depth_test, bool depth_write);
- LLGLEnable mBlend;
+ LLGLSPipelineBlendSkyBox(bool depth_test, bool depth_write);
+ LLGLEnable mBlend;
};
class LLGLSTracker
{
protected:
- LLGLEnable mCullFace, mBlend;
+ LLGLEnable mCullFace, mBlend;
public:
- LLGLSTracker() :
- mCullFace(GL_CULL_FACE),
- mBlend(GL_BLEND)
- { }
+ LLGLSTracker() :
+ mCullFace(GL_CULL_FACE),
+ mBlend(GL_BLEND)
+ { }
};
//----------------------------------------------------------------------------
@@ -169,26 +169,26 @@ public:
class LLGLSSpecular
{
public:
- F32 mShininess;
- LLGLSSpecular(const LLColor4& color, F32 shininess)
- {
- mShininess = shininess;
- if (mShininess > 0.0f)
- {
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color.mV);
- S32 shiny = (S32)(shininess*128.f);
- shiny = llclamp(shiny,0,128);
- glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, shiny);
- }
- }
- ~LLGLSSpecular()
- {
- if (mShininess > 0.f)
- {
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, LLColor4(0.f,0.f,0.f,0.f).mV);
- glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 0);
- }
- }
+ F32 mShininess;
+ LLGLSSpecular(const LLColor4& color, F32 shininess)
+ {
+ mShininess = shininess;
+ if (mShininess > 0.0f)
+ {
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color.mV);
+ S32 shiny = (S32)(shininess*128.f);
+ shiny = llclamp(shiny,0,128);
+ glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, shiny);
+ }
+ }
+ ~LLGLSSpecular()
+ {
+ if (mShininess > 0.f)
+ {
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, LLColor4(0.f,0.f,0.f,0.f).mV);
+ glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 0);
+ }
+ }
};
//----------------------------------------------------------------------------
diff --git a/indra/llrender/llgltypes.h b/indra/llrender/llgltypes.h
index 6c217ef727..b593a0532f 100644
--- a/indra/llrender/llgltypes.h
+++ b/indra/llrender/llgltypes.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file llgltypes.h
* @brief LLGL definition
*
* $LicenseInfo:firstyear=2006&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index 56a12b07b1..1609afb7ef 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llimagegl.cpp
* @brief Generic GL image handler
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -114,7 +114,7 @@ static void free_cur_tex_image()
free_tex_image(texName);
}
-// static
+// static
U64 LLImageGL::getTextureBytesAllocated()
{
return sTextureBytes;
@@ -122,12 +122,12 @@ U64 LLImageGL::getTextureBytesAllocated()
//statics
-U32 LLImageGL::sUniqueCount = 0;
-U32 LLImageGL::sBindCount = 0;
-S32 LLImageGL::sCount = 0;
+U32 LLImageGL::sUniqueCount = 0;
+U32 LLImageGL::sBindCount = 0;
+S32 LLImageGL::sCount = 0;
-BOOL LLImageGL::sGlobalUseAnisotropic = FALSE;
-F32 LLImageGL::sLastFrameTime = 0.f;
+BOOL LLImageGL::sGlobalUseAnisotropic = FALSE;
+F32 LLImageGL::sLastFrameTime = 0.f;
BOOL LLImageGL::sAllowReadBackRaw = FALSE ;
LLImageGL* LLImageGL::sDefaultGLTexture = NULL ;
bool LLImageGL::sCompressTextures = false;
@@ -159,78 +159,78 @@ BOOL LLImageGL::sSkipAnalyzeAlpha;
//do not delete them even though they are not currently being used.
void check_all_images()
{
- for (std::set<LLImageGL*>::iterator iter = LLImageGL::sImageList.begin();
- iter != LLImageGL::sImageList.end(); iter++)
- {
- LLImageGL* glimage = *iter;
- if (glimage->getTexName() && glimage->isGLTextureCreated())
- {
- gGL.getTexUnit(0)->bind(glimage) ;
- glimage->checkTexSize() ;
- gGL.getTexUnit(0)->unbind(glimage->getTarget()) ;
- }
- }
+ for (std::set<LLImageGL*>::iterator iter = LLImageGL::sImageList.begin();
+ iter != LLImageGL::sImageList.end(); iter++)
+ {
+ LLImageGL* glimage = *iter;
+ if (glimage->getTexName() && glimage->isGLTextureCreated())
+ {
+ gGL.getTexUnit(0)->bind(glimage) ;
+ glimage->checkTexSize() ;
+ gGL.getTexUnit(0)->unbind(glimage->getTarget()) ;
+ }
+ }
}
void LLImageGL::checkTexSize(bool forced) const
{
- if ((forced || gDebugGL) && mTarget == GL_TEXTURE_2D)
- {
- {
- //check viewport
- GLint vp[4] ;
- glGetIntegerv(GL_VIEWPORT, vp) ;
- llcallstacks << "viewport: " << vp[0] << " : " << vp[1] << " : " << vp[2] << " : " << vp[3] << llcallstacksendl ;
- }
-
- GLint texname;
- glGetIntegerv(GL_TEXTURE_BINDING_2D, &texname);
- BOOL error = FALSE;
- if (texname != mTexName)
- {
- LL_INFOS() << "Bound: " << texname << " Should bind: " << mTexName << " Default: " << LLImageGL::sDefaultGLTexture->getTexName() << LL_ENDL;
-
- error = TRUE;
- if (gDebugSession)
- {
- gFailLog << "Invalid texture bound!" << std::endl;
- }
- else
- {
- LL_ERRS() << "Invalid texture bound!" << LL_ENDL;
- }
- }
- stop_glerror() ;
- LLGLint x = 0, y = 0 ;
- glGetTexLevelParameteriv(mTarget, 0, GL_TEXTURE_WIDTH, (GLint*)&x);
- glGetTexLevelParameteriv(mTarget, 0, GL_TEXTURE_HEIGHT, (GLint*)&y) ;
- stop_glerror() ;
- llcallstacks << "w: " << x << " h: " << y << llcallstacksendl ;
-
- if(!x || !y)
- {
- return ;
- }
- if(x != (mWidth >> mCurrentDiscardLevel) || y != (mHeight >> mCurrentDiscardLevel))
- {
- error = TRUE;
- if (gDebugSession)
- {
- gFailLog << "wrong texture size and discard level!" <<
- mWidth << " Height: " << mHeight << " Current Level: " << (S32)mCurrentDiscardLevel << std::endl;
- }
- else
- {
- LL_ERRS() << "wrong texture size and discard level: width: " <<
- mWidth << " Height: " << mHeight << " Current Level: " << (S32)mCurrentDiscardLevel << LL_ENDL ;
- }
- }
-
- if (error)
- {
- ll_fail("LLImageGL::checkTexSize failed.");
- }
- }
+ if ((forced || gDebugGL) && mTarget == GL_TEXTURE_2D)
+ {
+ {
+ //check viewport
+ GLint vp[4] ;
+ glGetIntegerv(GL_VIEWPORT, vp) ;
+ llcallstacks << "viewport: " << vp[0] << " : " << vp[1] << " : " << vp[2] << " : " << vp[3] << llcallstacksendl ;
+ }
+
+ GLint texname;
+ glGetIntegerv(GL_TEXTURE_BINDING_2D, &texname);
+ BOOL error = FALSE;
+ if (texname != mTexName)
+ {
+ LL_INFOS() << "Bound: " << texname << " Should bind: " << mTexName << " Default: " << LLImageGL::sDefaultGLTexture->getTexName() << LL_ENDL;
+
+ error = TRUE;
+ if (gDebugSession)
+ {
+ gFailLog << "Invalid texture bound!" << std::endl;
+ }
+ else
+ {
+ LL_ERRS() << "Invalid texture bound!" << LL_ENDL;
+ }
+ }
+ stop_glerror() ;
+ LLGLint x = 0, y = 0 ;
+ glGetTexLevelParameteriv(mTarget, 0, GL_TEXTURE_WIDTH, (GLint*)&x);
+ glGetTexLevelParameteriv(mTarget, 0, GL_TEXTURE_HEIGHT, (GLint*)&y) ;
+ stop_glerror() ;
+ llcallstacks << "w: " << x << " h: " << y << llcallstacksendl ;
+
+ if(!x || !y)
+ {
+ return ;
+ }
+ if(x != (mWidth >> mCurrentDiscardLevel) || y != (mHeight >> mCurrentDiscardLevel))
+ {
+ error = TRUE;
+ if (gDebugSession)
+ {
+ gFailLog << "wrong texture size and discard level!" <<
+ mWidth << " Height: " << mHeight << " Current Level: " << (S32)mCurrentDiscardLevel << std::endl;
+ }
+ else
+ {
+ LL_ERRS() << "wrong texture size and discard level: width: " <<
+ mWidth << " Height: " << mHeight << " Current Level: " << (S32)mCurrentDiscardLevel << LL_ENDL ;
+ }
+ }
+
+ if (error)
+ {
+ ll_fail("LLImageGL::checkTexSize failed.");
+ }
+ }
}
//end of debug functions
//**************************************************************************************
@@ -238,17 +238,17 @@ void LLImageGL::checkTexSize(bool forced) const
//----------------------------------------------------------------------------
BOOL is_little_endian()
{
- S32 a = 0x12345678;
+ S32 a = 0x12345678;
U8 *c = (U8*)(&a);
-
- return (*c == 0x78) ;
+
+ return (*c == 0x78) ;
}
-//static
+//static
void LLImageGL::initClass(LLWindow* window, S32 num_catagories, BOOL skip_analyze_alpha /* = false */, bool thread_texture_loads /* = false */, bool thread_media_updates /* = false */)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- sSkipAnalyzeAlpha = skip_analyze_alpha;
+ sSkipAnalyzeAlpha = skip_analyze_alpha;
if (thread_texture_loads || thread_media_updates)
{
@@ -258,8 +258,8 @@ void LLImageGL::initClass(LLWindow* window, S32 num_catagories, BOOL skip_analyz
}
}
-//static
-void LLImageGL::cleanupClass()
+//static
+void LLImageGL::cleanupClass()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
LLImageGLThread::deleteSingleton();
@@ -271,23 +271,23 @@ S32 LLImageGL::dataFormatBits(S32 dataformat)
{
switch (dataformat)
{
- case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: return 4;
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: return 4;
case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: return 4;
- case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: return 8;
+ case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: return 8;
case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: return 8;
- case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: return 8;
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: return 8;
case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: return 8;
- case GL_LUMINANCE: return 8;
- case GL_ALPHA: return 8;
+ case GL_LUMINANCE: return 8;
+ case GL_ALPHA: return 8;
case GL_RED: return 8;
- case GL_COLOR_INDEX: return 8;
- case GL_LUMINANCE_ALPHA: return 16;
- case GL_RGB: return 24;
- case GL_SRGB: return 24;
- case GL_RGB8: return 24;
- case GL_RGBA: return 32;
- case GL_SRGB_ALPHA: return 32;
- case GL_BGRA: return 32; // Used for QuickTime media textures on the Mac
+ case GL_COLOR_INDEX: return 8;
+ case GL_LUMINANCE_ALPHA: return 16;
+ case GL_RGB: return 24;
+ case GL_SRGB: return 24;
+ case GL_RGB8: return 24;
+ case GL_RGBA: return 32;
+ case GL_SRGB_ALPHA: return 32;
+ case GL_BGRA: return 32; // Used for QuickTime media textures on the Mac
case GL_DEPTH_COMPONENT: return 24;
default:
LL_ERRS() << "LLImageGL::Unknown format: " << dataformat << LL_ENDL;
@@ -312,36 +312,36 @@ S64 LLImageGL::dataFormatBytes(S32 dataformat, S32 width, S32 height)
default:
break;
}
- S64 bytes (((S64)width * (S64)height * (S64)dataFormatBits(dataformat)+7)>>3);
- S64 aligned = (bytes+3)&~3;
- return aligned;
+ S64 bytes (((S64)width * (S64)height * (S64)dataFormatBits(dataformat)+7)>>3);
+ S64 aligned = (bytes+3)&~3;
+ return aligned;
}
//static
S32 LLImageGL::dataFormatComponents(S32 dataformat)
{
- switch (dataformat)
- {
- case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: return 3;
- case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: return 3;
- case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: return 4;
- case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: return 4;
- case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: return 4;
- case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: return 4;
- case GL_LUMINANCE: return 1;
- case GL_ALPHA: return 1;
+ switch (dataformat)
+ {
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: return 3;
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: return 3;
+ case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: return 4;
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: return 4;
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: return 4;
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: return 4;
+ case GL_LUMINANCE: return 1;
+ case GL_ALPHA: return 1;
case GL_RED: return 1;
- case GL_COLOR_INDEX: return 1;
- case GL_LUMINANCE_ALPHA: return 2;
- case GL_RGB: return 3;
- case GL_SRGB: return 3;
- case GL_RGBA: return 4;
- case GL_SRGB_ALPHA: return 4;
- case GL_BGRA: return 4; // Used for QuickTime media textures on the Mac
- default:
- LL_ERRS() << "LLImageGL::Unknown format: " << dataformat << LL_ENDL;
- return 0;
- }
+ case GL_COLOR_INDEX: return 1;
+ case GL_LUMINANCE_ALPHA: return 2;
+ case GL_RGB: return 3;
+ case GL_SRGB: return 3;
+ case GL_RGBA: return 4;
+ case GL_SRGB_ALPHA: return 4;
+ case GL_BGRA: return 4; // Used for QuickTime media textures on the Mac
+ default:
+ LL_ERRS() << "LLImageGL::Unknown format: " << dataformat << LL_ENDL;
+ return 0;
+ }
}
//----------------------------------------------------------------------------
@@ -350,131 +350,131 @@ S32 LLImageGL::dataFormatComponents(S32 dataformat)
void LLImageGL::updateStats(F32 current_time)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- sLastFrameTime = current_time;
+ sLastFrameTime = current_time;
}
//----------------------------------------------------------------------------
-//static
+//static
void LLImageGL::destroyGL(BOOL save_state)
{
- for (S32 stage = 0; stage < gGLManager.mNumTextureImageUnits; stage++)
- {
- gGL.getTexUnit(stage)->unbind(LLTexUnit::TT_TEXTURE);
- }
-
- sAllowReadBackRaw = true ;
- for (std::set<LLImageGL*>::iterator iter = sImageList.begin();
- iter != sImageList.end(); iter++)
- {
- LLImageGL* glimage = *iter;
- if (glimage->mTexName)
- {
- if (save_state && glimage->isGLTextureCreated() && glimage->mComponents)
- {
- glimage->mSaveData = new LLImageRaw;
- if(!glimage->readBackRaw(glimage->mCurrentDiscardLevel, glimage->mSaveData, false)) //necessary, keep it.
- {
- glimage->mSaveData = NULL ;
- }
- }
-
- glimage->destroyGLTexture();
- stop_glerror();
- }
- }
- sAllowReadBackRaw = false ;
-}
-
-//static
+ for (S32 stage = 0; stage < gGLManager.mNumTextureImageUnits; stage++)
+ {
+ gGL.getTexUnit(stage)->unbind(LLTexUnit::TT_TEXTURE);
+ }
+
+ sAllowReadBackRaw = true ;
+ for (std::set<LLImageGL*>::iterator iter = sImageList.begin();
+ iter != sImageList.end(); iter++)
+ {
+ LLImageGL* glimage = *iter;
+ if (glimage->mTexName)
+ {
+ if (save_state && glimage->isGLTextureCreated() && glimage->mComponents)
+ {
+ glimage->mSaveData = new LLImageRaw;
+ if(!glimage->readBackRaw(glimage->mCurrentDiscardLevel, glimage->mSaveData, false)) //necessary, keep it.
+ {
+ glimage->mSaveData = NULL ;
+ }
+ }
+
+ glimage->destroyGLTexture();
+ stop_glerror();
+ }
+ }
+ sAllowReadBackRaw = false ;
+}
+
+//static
void LLImageGL::restoreGL()
{
- for (std::set<LLImageGL*>::iterator iter = sImageList.begin();
- iter != sImageList.end(); iter++)
- {
- LLImageGL* glimage = *iter;
- if(glimage->getTexName())
- {
- LL_ERRS() << "tex name is not 0." << LL_ENDL ;
- }
- if (glimage->mSaveData.notNull())
- {
- if (glimage->getComponents() && glimage->mSaveData->getComponents())
- {
- glimage->createGLTexture(glimage->mCurrentDiscardLevel, glimage->mSaveData, 0, TRUE, glimage->getCategory());
- stop_glerror();
- }
- glimage->mSaveData = NULL; // deletes data
- }
- }
-}
-
-//static
+ for (std::set<LLImageGL*>::iterator iter = sImageList.begin();
+ iter != sImageList.end(); iter++)
+ {
+ LLImageGL* glimage = *iter;
+ if(glimage->getTexName())
+ {
+ LL_ERRS() << "tex name is not 0." << LL_ENDL ;
+ }
+ if (glimage->mSaveData.notNull())
+ {
+ if (glimage->getComponents() && glimage->mSaveData->getComponents())
+ {
+ glimage->createGLTexture(glimage->mCurrentDiscardLevel, glimage->mSaveData, 0, TRUE, glimage->getCategory());
+ stop_glerror();
+ }
+ glimage->mSaveData = NULL; // deletes data
+ }
+ }
+}
+
+//static
void LLImageGL::dirtyTexOptions()
{
- for (std::set<LLImageGL*>::iterator iter = sImageList.begin();
- iter != sImageList.end(); iter++)
- {
- LLImageGL* glimage = *iter;
- glimage->mTexOptionsDirty = true;
- stop_glerror();
- }
-
+ for (std::set<LLImageGL*>::iterator iter = sImageList.begin();
+ iter != sImageList.end(); iter++)
+ {
+ LLImageGL* glimage = *iter;
+ glimage->mTexOptionsDirty = true;
+ stop_glerror();
+ }
+
}
//----------------------------------------------------------------------------
//for server side use only.
-//static
+//static
BOOL LLImageGL::create(LLPointer<LLImageGL>& dest, BOOL usemipmaps)
{
- dest = new LLImageGL(usemipmaps);
- return TRUE;
+ dest = new LLImageGL(usemipmaps);
+ return TRUE;
}
//for server side use only.
BOOL LLImageGL::create(LLPointer<LLImageGL>& dest, U32 width, U32 height, U8 components, BOOL usemipmaps)
{
- dest = new LLImageGL(width, height, components, usemipmaps);
- return TRUE;
+ dest = new LLImageGL(width, height, components, usemipmaps);
+ return TRUE;
}
//for server side use only.
BOOL LLImageGL::create(LLPointer<LLImageGL>& dest, const LLImageRaw* imageraw, BOOL usemipmaps)
{
- dest = new LLImageGL(imageraw, usemipmaps);
- return TRUE;
+ dest = new LLImageGL(imageraw, usemipmaps);
+ return TRUE;
}
//----------------------------------------------------------------------------
LLImageGL::LLImageGL(BOOL usemipmaps)
-: mSaveData(0), mExternalTexture(FALSE)
+: mSaveData(0), mExternalTexture(FALSE)
{
- init(usemipmaps);
- setSize(0, 0, 0);
- sImageList.insert(this);
- sCount++;
+ init(usemipmaps);
+ setSize(0, 0, 0);
+ sImageList.insert(this);
+ sCount++;
}
LLImageGL::LLImageGL(U32 width, U32 height, U8 components, BOOL usemipmaps)
-: mSaveData(0), mExternalTexture(FALSE)
+: mSaveData(0), mExternalTexture(FALSE)
{
- llassert( components <= 4 );
- init(usemipmaps);
- setSize(width, height, components);
- sImageList.insert(this);
- sCount++;
+ llassert( components <= 4 );
+ init(usemipmaps);
+ setSize(width, height, components);
+ sImageList.insert(this);
+ sCount++;
}
LLImageGL::LLImageGL(const LLImageRaw* imageraw, BOOL usemipmaps)
-: mSaveData(0), mExternalTexture(FALSE)
+: mSaveData(0), mExternalTexture(FALSE)
{
- init(usemipmaps);
- setSize(0, 0, 0);
- sImageList.insert(this);
- sCount++;
+ init(usemipmaps);
+ setSize(0, 0, 0);
+ sImageList.insert(this);
+ sCount++;
- createGLTexture(0, imageraw);
+ createGLTexture(0, imageraw);
}
LLImageGL::LLImageGL(
@@ -501,10 +501,10 @@ LLImageGL::~LLImageGL()
{
if (!mExternalTexture && gGLManager.mInited)
{
- LLImageGL::cleanup();
- sImageList.erase(this);
- freePickMask();
- sCount--;
+ LLImageGL::cleanup();
+ sImageList.erase(this);
+ freePickMask();
+ sCount--;
}
}
@@ -514,74 +514,74 @@ void LLImageGL::init(BOOL usemipmaps)
mActiveThread = LLThread::currentID();
#endif
- // keep these members in the same order as declared in llimagehl.h
- // so that it is obvious by visual inspection if we forgot to
- // init a field.
-
- mTextureMemory = S64Bytes(0);
- mLastBindTime = 0.f;
-
- mPickMask = NULL;
- mPickMaskWidth = 0;
- mPickMaskHeight = 0;
- mUseMipMaps = usemipmaps;
- mHasExplicitFormat = FALSE;
-
- mIsMask = FALSE;
- mNeedsAlphaAndPickMask = TRUE ;
- mAlphaStride = 0 ;
- mAlphaOffset = 0 ;
-
- mGLTextureCreated = FALSE ;
- mTexName = 0;
- mWidth = 0;
- mHeight = 0;
- mCurrentDiscardLevel = -1;
-
- mDiscardLevelInAtlas = -1 ;
- mTexelsInAtlas = 0 ;
- mTexelsInGLTexture = 0 ;
-
- mAllowCompression = true;
-
- mTarget = GL_TEXTURE_2D;
- mBindTarget = LLTexUnit::TT_TEXTURE;
- mHasMipMaps = false;
- mMipLevels = -1;
-
- mIsResident = 0;
-
- mComponents = 0;
- mMaxDiscardLevel = MAX_DISCARD_LEVEL;
-
- mTexOptionsDirty = true;
- mAddressMode = LLTexUnit::TAM_WRAP;
- mFilterOption = LLTexUnit::TFO_ANISOTROPIC;
-
- mFormatInternal = -1;
- mFormatPrimary = (LLGLenum) 0;
- mFormatType = GL_UNSIGNED_BYTE;
- mFormatSwapBytes = FALSE;
+ // keep these members in the same order as declared in llimagehl.h
+ // so that it is obvious by visual inspection if we forgot to
+ // init a field.
+
+ mTextureMemory = S64Bytes(0);
+ mLastBindTime = 0.f;
+
+ mPickMask = NULL;
+ mPickMaskWidth = 0;
+ mPickMaskHeight = 0;
+ mUseMipMaps = usemipmaps;
+ mHasExplicitFormat = FALSE;
+
+ mIsMask = FALSE;
+ mNeedsAlphaAndPickMask = TRUE ;
+ mAlphaStride = 0 ;
+ mAlphaOffset = 0 ;
+
+ mGLTextureCreated = FALSE ;
+ mTexName = 0;
+ mWidth = 0;
+ mHeight = 0;
+ mCurrentDiscardLevel = -1;
+
+ mDiscardLevelInAtlas = -1 ;
+ mTexelsInAtlas = 0 ;
+ mTexelsInGLTexture = 0 ;
+
+ mAllowCompression = true;
+
+ mTarget = GL_TEXTURE_2D;
+ mBindTarget = LLTexUnit::TT_TEXTURE;
+ mHasMipMaps = false;
+ mMipLevels = -1;
+
+ mIsResident = 0;
+
+ mComponents = 0;
+ mMaxDiscardLevel = MAX_DISCARD_LEVEL;
+
+ mTexOptionsDirty = true;
+ mAddressMode = LLTexUnit::TAM_WRAP;
+ mFilterOption = LLTexUnit::TFO_ANISOTROPIC;
+
+ mFormatInternal = -1;
+ mFormatPrimary = (LLGLenum) 0;
+ mFormatType = GL_UNSIGNED_BYTE;
+ mFormatSwapBytes = FALSE;
#ifdef DEBUG_MISS
- mMissed = FALSE;
+ mMissed = FALSE;
#endif
- mCategory = -1;
+ mCategory = -1;
- // Sometimes we have to post work for the main thread.
- mMainQueue = LL::WorkQueue::getInstance("mainloop");
+ // Sometimes we have to post work for the main thread.
+ mMainQueue = LL::WorkQueue::getInstance("mainloop");
}
void LLImageGL::cleanup()
{
- if (!gGLManager.mIsDisabled)
- {
- destroyGLTexture();
- }
- freePickMask();
+ if (!gGLManager.mIsDisabled)
+ {
+ destroyGLTexture();
+ }
+ freePickMask();
- mSaveData = NULL; // deletes data
+ mSaveData = NULL; // deletes data
}
//----------------------------------------------------------------------------
@@ -590,62 +590,62 @@ void LLImageGL::cleanup()
//so dim should be a positive number
static bool check_power_of_two(S32 dim)
{
- if(dim < 0)
- {
- return false ;
- }
- if(!dim)//0 is a power-of-two number
- {
- return true ;
- }
- return !(dim & (dim - 1)) ;
+ if(dim < 0)
+ {
+ return false ;
+ }
+ if(!dim)//0 is a power-of-two number
+ {
+ return true ;
+ }
+ return !(dim & (dim - 1)) ;
}
//static
bool LLImageGL::checkSize(S32 width, S32 height)
{
- return check_power_of_two(width) && check_power_of_two(height);
+ return check_power_of_two(width) && check_power_of_two(height);
}
bool LLImageGL::setSize(S32 width, S32 height, S32 ncomponents, S32 discard_level)
{
- if (width != mWidth || height != mHeight || ncomponents != mComponents)
- {
- // Check if dimensions are a power of two!
- if (!checkSize(width, height))
- {
- LL_WARNS() << llformat("Texture has non power of two dimension: %dx%d",width,height) << LL_ENDL;
- return false;
- }
-
- // pickmask validity depends on old image size, delete it
- freePickMask();
-
- mWidth = width;
- mHeight = height;
- mComponents = ncomponents;
- if (ncomponents > 0)
- {
- mMaxDiscardLevel = 0;
- while (width > 1 && height > 1 && mMaxDiscardLevel < MAX_DISCARD_LEVEL)
- {
- mMaxDiscardLevel++;
- width >>= 1;
- height >>= 1;
- }
-
- if(discard_level > 0)
- {
- mMaxDiscardLevel = llmax(mMaxDiscardLevel, (S8)discard_level);
- }
- }
- else
- {
- mMaxDiscardLevel = MAX_DISCARD_LEVEL;
- }
- }
-
- return true;
+ if (width != mWidth || height != mHeight || ncomponents != mComponents)
+ {
+ // Check if dimensions are a power of two!
+ if (!checkSize(width, height))
+ {
+ LL_WARNS() << llformat("Texture has non power of two dimension: %dx%d",width,height) << LL_ENDL;
+ return false;
+ }
+
+ // pickmask validity depends on old image size, delete it
+ freePickMask();
+
+ mWidth = width;
+ mHeight = height;
+ mComponents = ncomponents;
+ if (ncomponents > 0)
+ {
+ mMaxDiscardLevel = 0;
+ while (width > 1 && height > 1 && mMaxDiscardLevel < MAX_DISCARD_LEVEL)
+ {
+ mMaxDiscardLevel++;
+ width >>= 1;
+ height >>= 1;
+ }
+
+ if(discard_level > 0)
+ {
+ mMaxDiscardLevel = llmax(mMaxDiscardLevel, (S8)discard_level);
+ }
+ }
+ else
+ {
+ mMaxDiscardLevel = MAX_DISCARD_LEVEL;
+ }
+ }
+
+ return true;
}
//----------------------------------------------------------------------------
@@ -653,74 +653,74 @@ bool LLImageGL::setSize(S32 width, S32 height, S32 ncomponents, S32 discard_leve
// virtual
void LLImageGL::dump()
{
- LL_INFOS() << "mMaxDiscardLevel " << S32(mMaxDiscardLevel)
- << " mLastBindTime " << mLastBindTime
- << " mTarget " << S32(mTarget)
- << " mBindTarget " << S32(mBindTarget)
- << " mUseMipMaps " << S32(mUseMipMaps)
- << " mHasMipMaps " << S32(mHasMipMaps)
- << " mCurrentDiscardLevel " << S32(mCurrentDiscardLevel)
- << " mFormatInternal " << S32(mFormatInternal)
- << " mFormatPrimary " << S32(mFormatPrimary)
- << " mFormatType " << S32(mFormatType)
- << " mFormatSwapBytes " << S32(mFormatSwapBytes)
- << " mHasExplicitFormat " << S32(mHasExplicitFormat)
+ LL_INFOS() << "mMaxDiscardLevel " << S32(mMaxDiscardLevel)
+ << " mLastBindTime " << mLastBindTime
+ << " mTarget " << S32(mTarget)
+ << " mBindTarget " << S32(mBindTarget)
+ << " mUseMipMaps " << S32(mUseMipMaps)
+ << " mHasMipMaps " << S32(mHasMipMaps)
+ << " mCurrentDiscardLevel " << S32(mCurrentDiscardLevel)
+ << " mFormatInternal " << S32(mFormatInternal)
+ << " mFormatPrimary " << S32(mFormatPrimary)
+ << " mFormatType " << S32(mFormatType)
+ << " mFormatSwapBytes " << S32(mFormatSwapBytes)
+ << " mHasExplicitFormat " << S32(mHasExplicitFormat)
#if DEBUG_MISS
- << " mMissed " << mMissed
+ << " mMissed " << mMissed
#endif
- << LL_ENDL;
+ << LL_ENDL;
- LL_INFOS() << " mTextureMemory " << mTextureMemory
- << " mTexNames " << mTexName
- << " mIsResident " << S32(mIsResident)
- << LL_ENDL;
+ LL_INFOS() << " mTextureMemory " << mTextureMemory
+ << " mTexNames " << mTexName
+ << " mIsResident " << S32(mIsResident)
+ << LL_ENDL;
}
//----------------------------------------------------------------------------
void LLImageGL::forceUpdateBindStats(void) const
{
- mLastBindTime = sLastFrameTime;
+ mLastBindTime = sLastFrameTime;
}
BOOL LLImageGL::updateBindStats() const
-{
- if (mTexName != 0)
- {
+{
+ if (mTexName != 0)
+ {
#ifdef DEBUG_MISS
- mMissed = ! getIsResident(TRUE);
+ mMissed = ! getIsResident(TRUE);
#endif
- sBindCount++;
- if (mLastBindTime != sLastFrameTime)
- {
- // we haven't accounted for this texture yet this frame
- sUniqueCount++;
- mLastBindTime = sLastFrameTime;
+ sBindCount++;
+ if (mLastBindTime != sLastFrameTime)
+ {
+ // we haven't accounted for this texture yet this frame
+ sUniqueCount++;
+ mLastBindTime = sLastFrameTime;
- return TRUE ;
- }
- }
- return FALSE ;
+ return TRUE ;
+ }
+ }
+ return FALSE ;
}
F32 LLImageGL::getTimePassedSinceLastBound()
{
- return sLastFrameTime - mLastBindTime ;
+ return sLastFrameTime - mLastBindTime ;
}
void LLImageGL::setExplicitFormat( LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes )
{
- // Note: must be called before createTexture()
- // Note: it's up to the caller to ensure that the format matches the number of components.
- mHasExplicitFormat = TRUE;
- mFormatInternal = internal_format;
- mFormatPrimary = primary_format;
- if(type_format == 0)
- mFormatType = GL_UNSIGNED_BYTE;
- else
- mFormatType = type_format;
- mFormatSwapBytes = swap_bytes;
+ // Note: must be called before createTexture()
+ // Note: it's up to the caller to ensure that the format matches the number of components.
+ mHasExplicitFormat = TRUE;
+ mFormatInternal = internal_format;
+ mFormatPrimary = primary_format;
+ if(type_format == 0)
+ mFormatType = GL_UNSIGNED_BYTE;
+ else
+ mFormatType = type_format;
+ mFormatSwapBytes = swap_bytes;
- calcAlphaChannelOffsetAndStride() ;
+ calcAlphaChannelOffsetAndStride() ;
}
//----------------------------------------------------------------------------
@@ -728,33 +728,33 @@ void LLImageGL::setExplicitFormat( LLGLint internal_format, LLGLenum primary_for
void LLImageGL::setImage(const LLImageRaw* imageraw)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- llassert((imageraw->getWidth() == getWidth(mCurrentDiscardLevel)) &&
- (imageraw->getHeight() == getHeight(mCurrentDiscardLevel)) &&
- (imageraw->getComponents() == getComponents()));
- const U8* rawdata = imageraw->getData();
- setImage(rawdata, FALSE);
+ llassert((imageraw->getWidth() == getWidth(mCurrentDiscardLevel)) &&
+ (imageraw->getHeight() == getHeight(mCurrentDiscardLevel)) &&
+ (imageraw->getComponents() == getComponents()));
+ const U8* rawdata = imageraw->getData();
+ setImage(rawdata, FALSE);
}
BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips /* = FALSE */, S32 usename /* = 0 */)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- const bool is_compressed = isCompressed();
-
- if (mUseMipMaps)
- {
- //set has mip maps to true before binding image so tex parameters get set properly
+ const bool is_compressed = isCompressed();
+
+ if (mUseMipMaps)
+ {
+ //set has mip maps to true before binding image so tex parameters get set properly
gGL.getTexUnit(0)->unbind(mBindTarget);
-
- mHasMipMaps = true;
- mTexOptionsDirty = true;
- setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
- }
- else
- {
- mHasMipMaps = false;
- }
-
+
+ mHasMipMaps = true;
+ mTexOptionsDirty = true;
+ setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
+ }
+ else
+ {
+ mHasMipMaps = false;
+ }
+
gGL.getTexUnit(0)->bind(this, false, false, usename);
if (data_in == nullptr)
@@ -765,291 +765,291 @@ BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips /* = FALSE */, S32
mFormatPrimary, mFormatType, (GLvoid*)data_in, mAllowCompression);
}
else if (mUseMipMaps)
- {
- if (data_hasmips)
- {
- // NOTE: data_in points to largest image; smaller images
- // are stored BEFORE the largest image
- for (S32 d=mCurrentDiscardLevel; d<=mMaxDiscardLevel; d++)
- {
-
- S32 w = getWidth(d);
- S32 h = getHeight(d);
- S32 gl_level = d-mCurrentDiscardLevel;
-
- mMipLevels = llmax(mMipLevels, gl_level);
-
- if (d > mCurrentDiscardLevel)
- {
- data_in -= dataFormatBytes(mFormatPrimary, w, h); // see above comment
- }
- if (is_compressed)
- {
- S32 tex_size = dataFormatBytes(mFormatPrimary, w, h);
- glCompressedTexImage2D(mTarget, gl_level, mFormatPrimary, w, h, 0, tex_size, (GLvoid *)data_in);
- stop_glerror();
- }
- else
- {
- if(mFormatSwapBytes)
- {
- glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
- stop_glerror();
- }
-
- LLImageGL::setManualImage(mTarget, gl_level, mFormatInternal, w, h, mFormatPrimary, GL_UNSIGNED_BYTE, (GLvoid*)data_in, mAllowCompression);
- if (gl_level == 0)
- {
- analyzeAlpha(data_in, w, h);
- }
- updatePickMask(w, h, data_in);
-
- if(mFormatSwapBytes)
- {
- glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
- stop_glerror();
- }
-
- stop_glerror();
- }
- stop_glerror();
- }
- }
- else if (!is_compressed)
- {
- if (mAutoGenMips)
- {
- stop_glerror();
- {
- if(mFormatSwapBytes)
- {
- glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
- stop_glerror();
- }
-
- S32 w = getWidth(mCurrentDiscardLevel);
- S32 h = getHeight(mCurrentDiscardLevel);
-
- mMipLevels = wpo2(llmax(w, h));
-
- //use legacy mipmap generation mode (note: making this condional can cause rendering issues)
- // -- but making it not conditional triggers deprecation warnings when core profile is enabled
- // (some rendering issues while core profile is enabled are acceptable at this point in time)
- if (!LLRender::sGLCoreProfile)
- {
- glTexParameteri(mTarget, GL_GENERATE_MIPMAP, GL_TRUE);
- }
+ {
+ if (data_hasmips)
+ {
+ // NOTE: data_in points to largest image; smaller images
+ // are stored BEFORE the largest image
+ for (S32 d=mCurrentDiscardLevel; d<=mMaxDiscardLevel; d++)
+ {
+
+ S32 w = getWidth(d);
+ S32 h = getHeight(d);
+ S32 gl_level = d-mCurrentDiscardLevel;
+
+ mMipLevels = llmax(mMipLevels, gl_level);
+
+ if (d > mCurrentDiscardLevel)
+ {
+ data_in -= dataFormatBytes(mFormatPrimary, w, h); // see above comment
+ }
+ if (is_compressed)
+ {
+ S32 tex_size = dataFormatBytes(mFormatPrimary, w, h);
+ glCompressedTexImage2D(mTarget, gl_level, mFormatPrimary, w, h, 0, tex_size, (GLvoid *)data_in);
+ stop_glerror();
+ }
+ else
+ {
+ if(mFormatSwapBytes)
+ {
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
+ stop_glerror();
+ }
+
+ LLImageGL::setManualImage(mTarget, gl_level, mFormatInternal, w, h, mFormatPrimary, GL_UNSIGNED_BYTE, (GLvoid*)data_in, mAllowCompression);
+ if (gl_level == 0)
+ {
+ analyzeAlpha(data_in, w, h);
+ }
+ updatePickMask(w, h, data_in);
+
+ if(mFormatSwapBytes)
+ {
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
+ stop_glerror();
+ }
+
+ stop_glerror();
+ }
+ stop_glerror();
+ }
+ }
+ else if (!is_compressed)
+ {
+ if (mAutoGenMips)
+ {
+ stop_glerror();
+ {
+ if(mFormatSwapBytes)
+ {
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
+ stop_glerror();
+ }
+
+ S32 w = getWidth(mCurrentDiscardLevel);
+ S32 h = getHeight(mCurrentDiscardLevel);
+
+ mMipLevels = wpo2(llmax(w, h));
+
+ //use legacy mipmap generation mode (note: making this condional can cause rendering issues)
+ // -- but making it not conditional triggers deprecation warnings when core profile is enabled
+ // (some rendering issues while core profile is enabled are acceptable at this point in time)
+ if (!LLRender::sGLCoreProfile)
+ {
+ glTexParameteri(mTarget, GL_GENERATE_MIPMAP, GL_TRUE);
+ }
LLImageGL::setManualImage(mTarget, 0, mFormatInternal,
- w, h,
- mFormatPrimary, mFormatType,
- data_in, mAllowCompression);
- analyzeAlpha(data_in, w, h);
- stop_glerror();
-
- updatePickMask(w, h, data_in);
-
- if(mFormatSwapBytes)
- {
- glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
- stop_glerror();
- }
-
- if (LLRender::sGLCoreProfile)
- {
+ w, h,
+ mFormatPrimary, mFormatType,
+ data_in, mAllowCompression);
+ analyzeAlpha(data_in, w, h);
+ stop_glerror();
+
+ updatePickMask(w, h, data_in);
+
+ if(mFormatSwapBytes)
+ {
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
+ stop_glerror();
+ }
+
+ if (LLRender::sGLCoreProfile)
+ {
LL_PROFILE_GPU_ZONE("generate mip map");
- glGenerateMipmap(mTarget);
- }
- stop_glerror();
- }
- }
- else
- {
- // Create mips by hand
- // ~4x faster than gluBuild2DMipmaps
- S32 width = getWidth(mCurrentDiscardLevel);
- S32 height = getHeight(mCurrentDiscardLevel);
- S32 nummips = mMaxDiscardLevel - mCurrentDiscardLevel + 1;
- S32 w = width, h = height;
-
-
- const U8* new_data = 0;
- (void)new_data;
-
- const U8* prev_mip_data = 0;
- const U8* cur_mip_data = 0;
+ glGenerateMipmap(mTarget);
+ }
+ stop_glerror();
+ }
+ }
+ else
+ {
+ // Create mips by hand
+ // ~4x faster than gluBuild2DMipmaps
+ S32 width = getWidth(mCurrentDiscardLevel);
+ S32 height = getHeight(mCurrentDiscardLevel);
+ S32 nummips = mMaxDiscardLevel - mCurrentDiscardLevel + 1;
+ S32 w = width, h = height;
+
+
+ const U8* new_data = 0;
+ (void)new_data;
+
+ const U8* prev_mip_data = 0;
+ const U8* cur_mip_data = 0;
#ifdef SHOW_ASSERT
- S32 cur_mip_size = 0;
+ S32 cur_mip_size = 0;
#endif
- mMipLevels = nummips;
+ mMipLevels = nummips;
- for (int m=0; m<nummips; m++)
- {
- if (m==0)
- {
- cur_mip_data = data_in;
+ for (int m=0; m<nummips; m++)
+ {
+ if (m==0)
+ {
+ cur_mip_data = data_in;
#ifdef SHOW_ASSERT
- cur_mip_size = width * height * mComponents;
+ cur_mip_size = width * height * mComponents;
#endif
- }
- else
- {
- S32 bytes = w * h * mComponents;
+ }
+ else
+ {
+ S32 bytes = w * h * mComponents;
#ifdef SHOW_ASSERT
- llassert(prev_mip_data);
- llassert(cur_mip_size == bytes*4);
+ llassert(prev_mip_data);
+ llassert(cur_mip_size == bytes*4);
#endif
- U8* new_data = new(std::nothrow) U8[bytes];
- if (!new_data)
- {
- stop_glerror();
-
- if (prev_mip_data)
- {
- if (prev_mip_data != cur_mip_data)
- delete[] prev_mip_data;
- prev_mip_data = nullptr;
- }
- if (cur_mip_data)
- {
- delete[] cur_mip_data;
- cur_mip_data = nullptr;
- }
-
- mGLTextureCreated = false;
- return FALSE;
- }
- else
- {
+ U8* new_data = new(std::nothrow) U8[bytes];
+ if (!new_data)
+ {
+ stop_glerror();
+
+ if (prev_mip_data)
+ {
+ if (prev_mip_data != cur_mip_data)
+ delete[] prev_mip_data;
+ prev_mip_data = nullptr;
+ }
+ if (cur_mip_data)
+ {
+ delete[] cur_mip_data;
+ cur_mip_data = nullptr;
+ }
+
+ mGLTextureCreated = false;
+ return FALSE;
+ }
+ else
+ {
#ifdef SHOW_ASSERT
- llassert(prev_mip_data);
- llassert(cur_mip_size == bytes * 4);
+ llassert(prev_mip_data);
+ llassert(cur_mip_size == bytes * 4);
#endif
- LLImageBase::generateMip(prev_mip_data, new_data, w, h, mComponents);
- cur_mip_data = new_data;
+ LLImageBase::generateMip(prev_mip_data, new_data, w, h, mComponents);
+ cur_mip_data = new_data;
#ifdef SHOW_ASSERT
- cur_mip_size = bytes;
+ cur_mip_size = bytes;
#endif
- }
-
- }
- llassert(w > 0 && h > 0 && cur_mip_data);
- (void)cur_mip_data;
- {
- if(mFormatSwapBytes)
- {
- glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
- stop_glerror();
- }
+ }
+
+ }
+ llassert(w > 0 && h > 0 && cur_mip_data);
+ (void)cur_mip_data;
+ {
+ if(mFormatSwapBytes)
+ {
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
+ stop_glerror();
+ }
LLImageGL::setManualImage(mTarget, m, mFormatInternal, w, h, mFormatPrimary, mFormatType, cur_mip_data, mAllowCompression);
- if (m == 0)
- {
- analyzeAlpha(data_in, w, h);
- }
- stop_glerror();
- if (m == 0)
- {
- updatePickMask(w, h, cur_mip_data);
- }
-
- if(mFormatSwapBytes)
- {
- glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
- stop_glerror();
- }
- }
- if (prev_mip_data && prev_mip_data != data_in)
- {
- delete[] prev_mip_data;
- }
- prev_mip_data = cur_mip_data;
- w >>= 1;
- h >>= 1;
- }
- if (prev_mip_data && prev_mip_data != data_in)
- {
- delete[] prev_mip_data;
- prev_mip_data = NULL;
- }
- }
- }
- else
- {
- LL_ERRS() << "Compressed Image has mipmaps but data does not (can not auto generate compressed mips)" << LL_ENDL;
- }
- }
- else
- {
- mMipLevels = 0;
- S32 w = getWidth();
- S32 h = getHeight();
- if (is_compressed)
- {
- S32 tex_size = dataFormatBytes(mFormatPrimary, w, h);
- glCompressedTexImage2D(mTarget, 0, mFormatPrimary, w, h, 0, tex_size, (GLvoid *)data_in);
- stop_glerror();
- }
- else
- {
- if(mFormatSwapBytes)
- {
- glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
- stop_glerror();
- }
-
- LLImageGL::setManualImage(mTarget, 0, mFormatInternal, w, h,
- mFormatPrimary, mFormatType, (GLvoid *)data_in, mAllowCompression);
- analyzeAlpha(data_in, w, h);
-
- updatePickMask(w, h, data_in);
-
- stop_glerror();
-
- if(mFormatSwapBytes)
- {
- glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
- stop_glerror();
- }
-
- }
- }
- stop_glerror();
- mGLTextureCreated = true;
- return TRUE;
+ if (m == 0)
+ {
+ analyzeAlpha(data_in, w, h);
+ }
+ stop_glerror();
+ if (m == 0)
+ {
+ updatePickMask(w, h, cur_mip_data);
+ }
+
+ if(mFormatSwapBytes)
+ {
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
+ stop_glerror();
+ }
+ }
+ if (prev_mip_data && prev_mip_data != data_in)
+ {
+ delete[] prev_mip_data;
+ }
+ prev_mip_data = cur_mip_data;
+ w >>= 1;
+ h >>= 1;
+ }
+ if (prev_mip_data && prev_mip_data != data_in)
+ {
+ delete[] prev_mip_data;
+ prev_mip_data = NULL;
+ }
+ }
+ }
+ else
+ {
+ LL_ERRS() << "Compressed Image has mipmaps but data does not (can not auto generate compressed mips)" << LL_ENDL;
+ }
+ }
+ else
+ {
+ mMipLevels = 0;
+ S32 w = getWidth();
+ S32 h = getHeight();
+ if (is_compressed)
+ {
+ S32 tex_size = dataFormatBytes(mFormatPrimary, w, h);
+ glCompressedTexImage2D(mTarget, 0, mFormatPrimary, w, h, 0, tex_size, (GLvoid *)data_in);
+ stop_glerror();
+ }
+ else
+ {
+ if(mFormatSwapBytes)
+ {
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
+ stop_glerror();
+ }
+
+ LLImageGL::setManualImage(mTarget, 0, mFormatInternal, w, h,
+ mFormatPrimary, mFormatType, (GLvoid *)data_in, mAllowCompression);
+ analyzeAlpha(data_in, w, h);
+
+ updatePickMask(w, h, data_in);
+
+ stop_glerror();
+
+ if(mFormatSwapBytes)
+ {
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
+ stop_glerror();
+ }
+
+ }
+ }
+ stop_glerror();
+ mGLTextureCreated = true;
+ return TRUE;
}
BOOL LLImageGL::preAddToAtlas(S32 discard_level, const LLImageRaw* raw_image)
{
- //not compatible with core GL profile
- llassert(!LLRender::sGLCoreProfile);
-
- if (gGLManager.mIsDisabled)
- {
- LL_WARNS() << "Trying to create a texture while GL is disabled!" << LL_ENDL;
- return FALSE;
- }
- llassert(gGLManager.mInited);
- stop_glerror();
-
- if (discard_level < 0)
- {
- llassert(mCurrentDiscardLevel >= 0);
- discard_level = mCurrentDiscardLevel;
- }
-
- // Actual image width/height = raw image width/height * 2^discard_level
- S32 w = raw_image->getWidth() << discard_level;
- S32 h = raw_image->getHeight() << discard_level;
-
- // setSize may call destroyGLTexture if the size does not match
- if (!setSize(w, h, raw_image->getComponents(), discard_level))
- {
- LL_WARNS() << "Trying to create a texture with incorrect dimensions!" << LL_ENDL;
- return FALSE;
- }
+ //not compatible with core GL profile
+ llassert(!LLRender::sGLCoreProfile);
+
+ if (gGLManager.mIsDisabled)
+ {
+ LL_WARNS() << "Trying to create a texture while GL is disabled!" << LL_ENDL;
+ return FALSE;
+ }
+ llassert(gGLManager.mInited);
+ stop_glerror();
+
+ if (discard_level < 0)
+ {
+ llassert(mCurrentDiscardLevel >= 0);
+ discard_level = mCurrentDiscardLevel;
+ }
+
+ // Actual image width/height = raw image width/height * 2^discard_level
+ S32 w = raw_image->getWidth() << discard_level;
+ S32 h = raw_image->getHeight() << discard_level;
+
+ // setSize may call destroyGLTexture if the size does not match
+ if (!setSize(w, h, raw_image->getComponents(), discard_level))
+ {
+ LL_WARNS() << "Trying to create a texture with incorrect dimensions!" << LL_ENDL;
+ return FALSE;
+ }
if (!mHasExplicitFormat)
{
@@ -1082,35 +1082,35 @@ BOOL LLImageGL::preAddToAtlas(S32 discard_level, const LLImageRaw* raw_image)
}
}
- mCurrentDiscardLevel = discard_level;
- mDiscardLevelInAtlas = discard_level;
- mTexelsInAtlas = raw_image->getWidth() * raw_image->getHeight() ;
- mLastBindTime = sLastFrameTime;
- mGLTextureCreated = false ;
-
- glPixelStorei(GL_UNPACK_ROW_LENGTH, raw_image->getWidth());
- stop_glerror();
+ mCurrentDiscardLevel = discard_level;
+ mDiscardLevelInAtlas = discard_level;
+ mTexelsInAtlas = raw_image->getWidth() * raw_image->getHeight() ;
+ mLastBindTime = sLastFrameTime;
+ mGLTextureCreated = false ;
+
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, raw_image->getWidth());
+ stop_glerror();
- if(mFormatSwapBytes)
- {
- glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
- stop_glerror();
- }
+ if(mFormatSwapBytes)
+ {
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
+ stop_glerror();
+ }
- return TRUE ;
+ return TRUE ;
}
void LLImageGL::postAddToAtlas()
{
- if(mFormatSwapBytes)
- {
- glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
- stop_glerror();
- }
+ if(mFormatSwapBytes)
+ {
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
+ stop_glerror();
+ }
- glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
- gGL.getTexUnit(0)->setTextureFilteringOption(mFilterOption);
- stop_glerror();
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ gGL.getTexUnit(0)->setTextureFilteringOption(mFilterOption);
+ stop_glerror();
}
U32 type_width_from_pixtype(U32 pixtype)
@@ -1170,82 +1170,82 @@ void sub_image_lines(U32 target, S32 miplevel, S32 x_offset, S32 y_offset, S32 w
BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update /* = FALSE */, LLGLuint use_name)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- if (!width || !height)
- {
- return TRUE;
- }
+ if (!width || !height)
+ {
+ return TRUE;
+ }
LLGLuint tex_name = use_name != 0 ? use_name : mTexName;
- if (0 == tex_name)
- {
- // *TODO: Re-enable warning? Ran into thread locking issues? DK 2011-02-18
- //LL_WARNS() << "Setting subimage on image without GL texture" << LL_ENDL;
- return FALSE;
- }
- if (datap == NULL)
- {
- // *TODO: Re-enable warning? Ran into thread locking issues? DK 2011-02-18
- //LL_WARNS() << "Setting subimage on image with NULL datap" << LL_ENDL;
- return FALSE;
- }
-
- // HACK: allow the caller to explicitly force the fast path (i.e. using glTexSubImage2D here instead of calling setImage) even when updating the full texture.
- if (!force_fast_update && x_pos == 0 && y_pos == 0 && width == getWidth() && height == getHeight() && data_width == width && data_height == height)
- {
- setImage(datap, FALSE, tex_name);
- }
- else
- {
- if (mUseMipMaps)
- {
- dump();
- LL_ERRS() << "setSubImage called with mipmapped image (not supported)" << LL_ENDL;
- }
- llassert_always(mCurrentDiscardLevel == 0);
- llassert_always(x_pos >= 0 && y_pos >= 0);
-
- if (((x_pos + width) > getWidth()) ||
- (y_pos + height) > getHeight())
- {
- dump();
- LL_ERRS() << "Subimage not wholly in target image!"
- << " x_pos " << x_pos
- << " y_pos " << y_pos
- << " width " << width
- << " height " << height
- << " getWidth() " << getWidth()
- << " getHeight() " << getHeight()
- << LL_ENDL;
- }
-
- if ((x_pos + width) > data_width ||
- (y_pos + height) > data_height)
- {
- dump();
- LL_ERRS() << "Subimage not wholly in source image!"
- << " x_pos " << x_pos
- << " y_pos " << y_pos
- << " width " << width
- << " height " << height
- << " source_width " << data_width
- << " source_height " << data_height
- << LL_ENDL;
- }
-
-
- glPixelStorei(GL_UNPACK_ROW_LENGTH, data_width);
- stop_glerror();
-
- if(mFormatSwapBytes)
- {
- glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
- stop_glerror();
- }
-
- const U8* sub_datap = datap + (y_pos * data_width + x_pos) * getComponents();
- // Update the GL texture
- BOOL res = gGL.getTexUnit(0)->bindManual(mBindTarget, tex_name);
- if (!res) LL_ERRS() << "LLImageGL::setSubImage(): bindTexture failed" << LL_ENDL;
- stop_glerror();
+ if (0 == tex_name)
+ {
+ // *TODO: Re-enable warning? Ran into thread locking issues? DK 2011-02-18
+ //LL_WARNS() << "Setting subimage on image without GL texture" << LL_ENDL;
+ return FALSE;
+ }
+ if (datap == NULL)
+ {
+ // *TODO: Re-enable warning? Ran into thread locking issues? DK 2011-02-18
+ //LL_WARNS() << "Setting subimage on image with NULL datap" << LL_ENDL;
+ return FALSE;
+ }
+
+ // HACK: allow the caller to explicitly force the fast path (i.e. using glTexSubImage2D here instead of calling setImage) even when updating the full texture.
+ if (!force_fast_update && x_pos == 0 && y_pos == 0 && width == getWidth() && height == getHeight() && data_width == width && data_height == height)
+ {
+ setImage(datap, FALSE, tex_name);
+ }
+ else
+ {
+ if (mUseMipMaps)
+ {
+ dump();
+ LL_ERRS() << "setSubImage called with mipmapped image (not supported)" << LL_ENDL;
+ }
+ llassert_always(mCurrentDiscardLevel == 0);
+ llassert_always(x_pos >= 0 && y_pos >= 0);
+
+ if (((x_pos + width) > getWidth()) ||
+ (y_pos + height) > getHeight())
+ {
+ dump();
+ LL_ERRS() << "Subimage not wholly in target image!"
+ << " x_pos " << x_pos
+ << " y_pos " << y_pos
+ << " width " << width
+ << " height " << height
+ << " getWidth() " << getWidth()
+ << " getHeight() " << getHeight()
+ << LL_ENDL;
+ }
+
+ if ((x_pos + width) > data_width ||
+ (y_pos + height) > data_height)
+ {
+ dump();
+ LL_ERRS() << "Subimage not wholly in source image!"
+ << " x_pos " << x_pos
+ << " y_pos " << y_pos
+ << " width " << width
+ << " height " << height
+ << " source_width " << data_width
+ << " source_height " << data_height
+ << LL_ENDL;
+ }
+
+
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, data_width);
+ stop_glerror();
+
+ if(mFormatSwapBytes)
+ {
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
+ stop_glerror();
+ }
+
+ const U8* sub_datap = datap + (y_pos * data_width + x_pos) * getComponents();
+ // Update the GL texture
+ BOOL res = gGL.getTexUnit(0)->bindManual(mBindTarget, tex_name);
+ if (!res) LL_ERRS() << "LLImageGL::setSubImage(): bindTexture failed" << LL_ENDL;
+ stop_glerror();
const bool use_sub_image = should_stagger_image_set(isCompressed());
if (!use_sub_image)
@@ -1260,42 +1260,42 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3
{
sub_image_lines(mTarget, 0, x_pos, y_pos, width, height, mFormatPrimary, mFormatType, sub_datap, data_width);
}
- gGL.getTexUnit(0)->disable();
- stop_glerror();
+ gGL.getTexUnit(0)->disable();
+ stop_glerror();
- if(mFormatSwapBytes)
- {
- glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
- stop_glerror();
- }
+ if(mFormatSwapBytes)
+ {
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
+ stop_glerror();
+ }
- glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
- stop_glerror();
- mGLTextureCreated = true;
- }
- return TRUE;
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ stop_glerror();
+ mGLTextureCreated = true;
+ }
+ return TRUE;
}
BOOL LLImageGL::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update /* = FALSE */, LLGLuint use_name)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- return setSubImage(imageraw->getData(), imageraw->getWidth(), imageraw->getHeight(), x_pos, y_pos, width, height, force_fast_update, use_name);
+ return setSubImage(imageraw->getData(), imageraw->getWidth(), imageraw->getHeight(), x_pos, y_pos, width, height, force_fast_update, use_name);
}
// Copy sub image from frame buffer
BOOL LLImageGL::setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_pos, S32 width, S32 height)
{
- if (gGL.getTexUnit(0)->bind(this, false, true))
- {
- glCopyTexSubImage2D(GL_TEXTURE_2D, 0, fb_x, fb_y, x_pos, y_pos, width, height);
- mGLTextureCreated = true;
- stop_glerror();
- return TRUE;
- }
- else
- {
- return FALSE;
- }
+ if (gGL.getTexUnit(0)->bind(this, false, true))
+ {
+ glCopyTexSubImage2D(GL_TEXTURE_2D, 0, fb_x, fb_y, x_pos, y_pos, width, height);
+ mGLTextureCreated = true;
+ stop_glerror();
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
}
// static
@@ -1330,11 +1330,11 @@ void LLImageGL::generateTextures(S32 numTextures, U32 *textures)
// static
void LLImageGL::deleteTextures(S32 numTextures, const U32 *textures)
{
- if (gGLManager.mInited)
- {
+ if (gGLManager.mInited)
+ {
free_tex_images(numTextures, textures);
- glDeleteTextures(numTextures, textures);
- }
+ glDeleteTextures(numTextures, textures);
+ }
}
// static
@@ -1516,33 +1516,33 @@ BOOL LLImageGL::createGLTexture()
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
checkActiveThread();
- if (gGLManager.mIsDisabled)
- {
- LL_WARNS() << "Trying to create a texture while GL is disabled!" << LL_ENDL;
- return FALSE;
- }
-
- mGLTextureCreated = false ; //do not save this texture when gl is destroyed.
+ if (gGLManager.mIsDisabled)
+ {
+ LL_WARNS() << "Trying to create a texture while GL is disabled!" << LL_ENDL;
+ return FALSE;
+ }
+
+ mGLTextureCreated = false ; //do not save this texture when gl is destroyed.
- llassert(gGLManager.mInited);
- stop_glerror();
+ llassert(gGLManager.mInited);
+ stop_glerror();
- if(mTexName)
- {
- LLImageGL::deleteTextures(1, (reinterpret_cast<GLuint*>(&mTexName))) ;
+ if(mTexName)
+ {
+ LLImageGL::deleteTextures(1, (reinterpret_cast<GLuint*>(&mTexName))) ;
mTexName = 0;
- }
-
+ }
- LLImageGL::generateTextures(1, &mTexName);
- stop_glerror();
- if (!mTexName)
- {
- LL_WARNS() << "LLImageGL::createGLTexture failed to make an empty texture" << LL_ENDL;
- return FALSE;
- }
- return TRUE ;
+ LLImageGL::generateTextures(1, &mTexName);
+ stop_glerror();
+ if (!mTexName)
+ {
+ LL_WARNS() << "LLImageGL::createGLTexture failed to make an empty texture" << LL_ENDL;
+ return FALSE;
+ }
+
+ return TRUE ;
}
BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename/*=0*/, BOOL to_create, S32 category, bool defer_copy, LLGLuint* tex_name)
@@ -1550,54 +1550,54 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
checkActiveThread();
- if (gGLManager.mIsDisabled)
- {
- LL_WARNS() << "Trying to create a texture while GL is disabled!" << LL_ENDL;
- return FALSE;
- }
+ if (gGLManager.mIsDisabled)
+ {
+ LL_WARNS() << "Trying to create a texture while GL is disabled!" << LL_ENDL;
+ return FALSE;
+ }
- llassert(gGLManager.mInited);
- stop_glerror();
+ llassert(gGLManager.mInited);
+ stop_glerror();
- if (!imageraw || imageraw->isBufferInvalid())
- {
- LL_WARNS() << "Trying to create a texture from invalid image data" << LL_ENDL;
+ if (!imageraw || imageraw->isBufferInvalid())
+ {
+ LL_WARNS() << "Trying to create a texture from invalid image data" << LL_ENDL;
mGLTextureCreated = false;
- return FALSE;
- }
-
- if (discard_level < 0)
- {
- llassert(mCurrentDiscardLevel >= 0);
- discard_level = mCurrentDiscardLevel;
- }
-
- // Actual image width/height = raw image width/height * 2^discard_level
- S32 raw_w = imageraw->getWidth() ;
- S32 raw_h = imageraw->getHeight() ;
-
- S32 w = raw_w << discard_level;
- S32 h = raw_h << discard_level;
-
- // setSize may call destroyGLTexture if the size does not match
- if (!setSize(w, h, imageraw->getComponents(), discard_level))
- {
- LL_WARNS() << "Trying to create a texture with incorrect dimensions!" << LL_ENDL;
+ return FALSE;
+ }
+
+ if (discard_level < 0)
+ {
+ llassert(mCurrentDiscardLevel >= 0);
+ discard_level = mCurrentDiscardLevel;
+ }
+
+ // Actual image width/height = raw image width/height * 2^discard_level
+ S32 raw_w = imageraw->getWidth() ;
+ S32 raw_h = imageraw->getHeight() ;
+
+ S32 w = raw_w << discard_level;
+ S32 h = raw_h << discard_level;
+
+ // setSize may call destroyGLTexture if the size does not match
+ if (!setSize(w, h, imageraw->getComponents(), discard_level))
+ {
+ LL_WARNS() << "Trying to create a texture with incorrect dimensions!" << LL_ENDL;
mGLTextureCreated = false;
- return FALSE;
- }
+ return FALSE;
+ }
- if (mHasExplicitFormat &&
- ((mFormatPrimary == GL_RGBA && mComponents < 4) ||
- (mFormatPrimary == GL_RGB && mComponents < 3)))
+ if (mHasExplicitFormat &&
+ ((mFormatPrimary == GL_RGBA && mComponents < 4) ||
+ (mFormatPrimary == GL_RGB && mComponents < 3)))
- {
- LL_WARNS() << "Incorrect format: " << std::hex << mFormatPrimary << " components: " << (U32)mComponents << LL_ENDL;
- mHasExplicitFormat = FALSE;
- }
+ {
+ LL_WARNS() << "Incorrect format: " << std::hex << mFormatPrimary << " components: " << (U32)mComponents << LL_ENDL;
+ mHasExplicitFormat = FALSE;
+ }
- if( !mHasExplicitFormat )
- {
+ if( !mHasExplicitFormat )
+ {
switch (mComponents)
{
case 1:
@@ -1626,21 +1626,21 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S
LL_ERRS() << "Bad number of components for texture: " << (U32)getComponents() << LL_ENDL;
}
- calcAlphaChannelOffsetAndStride() ;
- }
+ calcAlphaChannelOffsetAndStride() ;
+ }
- if(!to_create) //not create a gl texture
- {
- destroyGLTexture();
- mCurrentDiscardLevel = discard_level;
- mLastBindTime = sLastFrameTime;
+ if(!to_create) //not create a gl texture
+ {
+ destroyGLTexture();
+ mCurrentDiscardLevel = discard_level;
+ mLastBindTime = sLastFrameTime;
mGLTextureCreated = false;
- return TRUE ;
- }
+ return TRUE ;
+ }
- setCategory(category);
- const U8* rawdata = imageraw->getData();
- return createGLTexture(discard_level, rawdata, FALSE, usename, defer_copy, tex_name);
+ setCategory(category);
+ const U8* rawdata = imageraw->getData();
+ return createGLTexture(discard_level, rawdata, FALSE, usename, defer_copy, tex_name);
}
BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_hasmips, S32 usename, bool defer_copy, LLGLuint* tex_name)
@@ -1746,7 +1746,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
}
}
-
+
mTextureMemory = (S64Bytes)getMipBytes(mCurrentDiscardLevel);
mTexelsInGLTexture = getWidth() * getHeight();
@@ -1826,302 +1826,302 @@ void LLImageGL::syncTexName(LLGLuint texname)
BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok) const
{
- llassert_always(sAllowReadBackRaw) ;
- //LL_ERRS() << "should not call this function!" << LL_ENDL ;
-
- if (discard_level < 0)
- {
- discard_level = mCurrentDiscardLevel;
- }
-
- if (mTexName == 0 || discard_level < mCurrentDiscardLevel || discard_level > mMaxDiscardLevel )
- {
- return FALSE;
- }
-
- S32 gl_discard = discard_level - mCurrentDiscardLevel;
-
- //explicitly unbind texture
- gGL.getTexUnit(0)->unbind(mBindTarget);
- llverify(gGL.getTexUnit(0)->bindManual(mBindTarget, mTexName));
-
- //debug code, leave it there commented.
- //checkTexSize() ;
-
- LLGLint glwidth = 0;
- glGetTexLevelParameteriv(mTarget, gl_discard, GL_TEXTURE_WIDTH, (GLint*)&glwidth);
- if (glwidth == 0)
- {
- // No mip data smaller than current discard level
- return FALSE;
- }
-
- S32 width = getWidth(discard_level);
- S32 height = getHeight(discard_level);
- S32 ncomponents = getComponents();
- if (ncomponents == 0)
- {
- return FALSE;
- }
- if(width < glwidth)
- {
- LL_WARNS() << "texture size is smaller than it should be." << LL_ENDL ;
- LL_WARNS() << "width: " << width << " glwidth: " << glwidth << " mWidth: " << mWidth <<
- " mCurrentDiscardLevel: " << (S32)mCurrentDiscardLevel << " discard_level: " << (S32)discard_level << LL_ENDL ;
- return FALSE ;
- }
-
- if (width <= 0 || width > 2048 || height <= 0 || height > 2048 || ncomponents < 1 || ncomponents > 4)
- {
- LL_ERRS() << llformat("LLImageGL::readBackRaw: bogus params: %d x %d x %d",width,height,ncomponents) << LL_ENDL;
- }
-
- LLGLint is_compressed = 0;
- if (compressed_ok)
- {
- glGetTexLevelParameteriv(mTarget, is_compressed, GL_TEXTURE_COMPRESSED, (GLint*)&is_compressed);
- }
-
- //-----------------------------------------------------------------------------------------------
- GLenum error ;
- while((error = glGetError()) != GL_NO_ERROR)
- {
- LL_WARNS() << "GL Error happens before reading back texture. Error code: " << error << LL_ENDL ;
- }
- //-----------------------------------------------------------------------------------------------
-
- if (is_compressed)
- {
- LLGLint glbytes;
- glGetTexLevelParameteriv(mTarget, gl_discard, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, (GLint*)&glbytes);
- if(!imageraw->allocateDataSize(width, height, ncomponents, glbytes))
- {
- LL_WARNS() << "Memory allocation failed for reading back texture. Size is: " << glbytes << LL_ENDL ;
- LL_WARNS() << "width: " << width << "height: " << height << "components: " << ncomponents << LL_ENDL ;
- return FALSE ;
- }
-
- glGetCompressedTexImage(mTarget, gl_discard, (GLvoid*)(imageraw->getData()));
- //stop_glerror();
- }
- else
- {
- if(!imageraw->allocateDataSize(width, height, ncomponents))
- {
- LL_WARNS() << "Memory allocation failed for reading back texture." << LL_ENDL ;
- LL_WARNS() << "width: " << width << "height: " << height << "components: " << ncomponents << LL_ENDL ;
- return FALSE ;
- }
-
- glGetTexImage(GL_TEXTURE_2D, gl_discard, mFormatPrimary, mFormatType, (GLvoid*)(imageraw->getData()));
- //stop_glerror();
- }
-
- //-----------------------------------------------------------------------------------------------
- if((error = glGetError()) != GL_NO_ERROR)
- {
- LL_WARNS() << "GL Error happens after reading back texture. Error code: " << error << LL_ENDL ;
- imageraw->deleteData() ;
-
- while((error = glGetError()) != GL_NO_ERROR)
- {
- LL_WARNS() << "GL Error happens after reading back texture. Error code: " << error << LL_ENDL ;
- }
-
- return FALSE ;
- }
- //-----------------------------------------------------------------------------------------------
-
- return TRUE ;
+ llassert_always(sAllowReadBackRaw) ;
+ //LL_ERRS() << "should not call this function!" << LL_ENDL ;
+
+ if (discard_level < 0)
+ {
+ discard_level = mCurrentDiscardLevel;
+ }
+
+ if (mTexName == 0 || discard_level < mCurrentDiscardLevel || discard_level > mMaxDiscardLevel )
+ {
+ return FALSE;
+ }
+
+ S32 gl_discard = discard_level - mCurrentDiscardLevel;
+
+ //explicitly unbind texture
+ gGL.getTexUnit(0)->unbind(mBindTarget);
+ llverify(gGL.getTexUnit(0)->bindManual(mBindTarget, mTexName));
+
+ //debug code, leave it there commented.
+ //checkTexSize() ;
+
+ LLGLint glwidth = 0;
+ glGetTexLevelParameteriv(mTarget, gl_discard, GL_TEXTURE_WIDTH, (GLint*)&glwidth);
+ if (glwidth == 0)
+ {
+ // No mip data smaller than current discard level
+ return FALSE;
+ }
+
+ S32 width = getWidth(discard_level);
+ S32 height = getHeight(discard_level);
+ S32 ncomponents = getComponents();
+ if (ncomponents == 0)
+ {
+ return FALSE;
+ }
+ if(width < glwidth)
+ {
+ LL_WARNS() << "texture size is smaller than it should be." << LL_ENDL ;
+ LL_WARNS() << "width: " << width << " glwidth: " << glwidth << " mWidth: " << mWidth <<
+ " mCurrentDiscardLevel: " << (S32)mCurrentDiscardLevel << " discard_level: " << (S32)discard_level << LL_ENDL ;
+ return FALSE ;
+ }
+
+ if (width <= 0 || width > 2048 || height <= 0 || height > 2048 || ncomponents < 1 || ncomponents > 4)
+ {
+ LL_ERRS() << llformat("LLImageGL::readBackRaw: bogus params: %d x %d x %d",width,height,ncomponents) << LL_ENDL;
+ }
+
+ LLGLint is_compressed = 0;
+ if (compressed_ok)
+ {
+ glGetTexLevelParameteriv(mTarget, is_compressed, GL_TEXTURE_COMPRESSED, (GLint*)&is_compressed);
+ }
+
+ //-----------------------------------------------------------------------------------------------
+ GLenum error ;
+ while((error = glGetError()) != GL_NO_ERROR)
+ {
+ LL_WARNS() << "GL Error happens before reading back texture. Error code: " << error << LL_ENDL ;
+ }
+ //-----------------------------------------------------------------------------------------------
+
+ if (is_compressed)
+ {
+ LLGLint glbytes;
+ glGetTexLevelParameteriv(mTarget, gl_discard, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, (GLint*)&glbytes);
+ if(!imageraw->allocateDataSize(width, height, ncomponents, glbytes))
+ {
+ LL_WARNS() << "Memory allocation failed for reading back texture. Size is: " << glbytes << LL_ENDL ;
+ LL_WARNS() << "width: " << width << "height: " << height << "components: " << ncomponents << LL_ENDL ;
+ return FALSE ;
+ }
+
+ glGetCompressedTexImage(mTarget, gl_discard, (GLvoid*)(imageraw->getData()));
+ //stop_glerror();
+ }
+ else
+ {
+ if(!imageraw->allocateDataSize(width, height, ncomponents))
+ {
+ LL_WARNS() << "Memory allocation failed for reading back texture." << LL_ENDL ;
+ LL_WARNS() << "width: " << width << "height: " << height << "components: " << ncomponents << LL_ENDL ;
+ return FALSE ;
+ }
+
+ glGetTexImage(GL_TEXTURE_2D, gl_discard, mFormatPrimary, mFormatType, (GLvoid*)(imageraw->getData()));
+ //stop_glerror();
+ }
+
+ //-----------------------------------------------------------------------------------------------
+ if((error = glGetError()) != GL_NO_ERROR)
+ {
+ LL_WARNS() << "GL Error happens after reading back texture. Error code: " << error << LL_ENDL ;
+ imageraw->deleteData() ;
+
+ while((error = glGetError()) != GL_NO_ERROR)
+ {
+ LL_WARNS() << "GL Error happens after reading back texture. Error code: " << error << LL_ENDL ;
+ }
+
+ return FALSE ;
+ }
+ //-----------------------------------------------------------------------------------------------
+
+ return TRUE ;
}
void LLImageGL::destroyGLTexture()
{
checkActiveThread();
- if (mTexName != 0)
- {
- if(mTextureMemory != S64Bytes(0))
- {
- mTextureMemory = (S64Bytes)0;
- }
-
- LLImageGL::deleteTextures(1, &mTexName);
- mCurrentDiscardLevel = -1 ; //invalidate mCurrentDiscardLevel.
- mTexName = 0;
- mGLTextureCreated = FALSE ;
- }
+ if (mTexName != 0)
+ {
+ if(mTextureMemory != S64Bytes(0))
+ {
+ mTextureMemory = (S64Bytes)0;
+ }
+
+ LLImageGL::deleteTextures(1, &mTexName);
+ mCurrentDiscardLevel = -1 ; //invalidate mCurrentDiscardLevel.
+ mTexName = 0;
+ mGLTextureCreated = FALSE ;
+ }
}
//force to invalidate the gl texture, most likely a sculpty texture
void LLImageGL::forceToInvalidateGLTexture()
{
checkActiveThread();
- if (mTexName != 0)
- {
- destroyGLTexture();
- }
- else
- {
- mCurrentDiscardLevel = -1 ; //invalidate mCurrentDiscardLevel.
- }
+ if (mTexName != 0)
+ {
+ destroyGLTexture();
+ }
+ else
+ {
+ mCurrentDiscardLevel = -1 ; //invalidate mCurrentDiscardLevel.
+ }
}
//----------------------------------------------------------------------------
void LLImageGL::setAddressMode(LLTexUnit::eTextureAddressMode mode)
{
- if (mAddressMode != mode)
- {
- mTexOptionsDirty = true;
- mAddressMode = mode;
- }
+ if (mAddressMode != mode)
+ {
+ mTexOptionsDirty = true;
+ mAddressMode = mode;
+ }
- if (gGL.getTexUnit(gGL.getCurrentTexUnitIndex())->getCurrTexture() == mTexName)
- {
- gGL.getTexUnit(gGL.getCurrentTexUnitIndex())->setTextureAddressMode(mode);
- mTexOptionsDirty = false;
- }
+ if (gGL.getTexUnit(gGL.getCurrentTexUnitIndex())->getCurrTexture() == mTexName)
+ {
+ gGL.getTexUnit(gGL.getCurrentTexUnitIndex())->setTextureAddressMode(mode);
+ mTexOptionsDirty = false;
+ }
}
void LLImageGL::setFilteringOption(LLTexUnit::eTextureFilterOptions option)
{
- if (mFilterOption != option)
- {
- mTexOptionsDirty = true;
- mFilterOption = option;
- }
+ if (mFilterOption != option)
+ {
+ mTexOptionsDirty = true;
+ mFilterOption = option;
+ }
- if (mTexName != 0 && gGL.getTexUnit(gGL.getCurrentTexUnitIndex())->getCurrTexture() == mTexName)
- {
- gGL.getTexUnit(gGL.getCurrentTexUnitIndex())->setTextureFilteringOption(option);
- mTexOptionsDirty = false;
- stop_glerror();
- }
+ if (mTexName != 0 && gGL.getTexUnit(gGL.getCurrentTexUnitIndex())->getCurrTexture() == mTexName)
+ {
+ gGL.getTexUnit(gGL.getCurrentTexUnitIndex())->setTextureFilteringOption(option);
+ mTexOptionsDirty = false;
+ stop_glerror();
+ }
}
BOOL LLImageGL::getIsResident(BOOL test_now)
{
- if (test_now)
- {
- if (mTexName != 0)
- {
- glAreTexturesResident(1, (GLuint*)&mTexName, &mIsResident);
- }
- else
- {
- mIsResident = FALSE;
- }
- }
+ if (test_now)
+ {
+ if (mTexName != 0)
+ {
+ glAreTexturesResident(1, (GLuint*)&mTexName, &mIsResident);
+ }
+ else
+ {
+ mIsResident = FALSE;
+ }
+ }
- return mIsResident;
+ return mIsResident;
}
S32 LLImageGL::getHeight(S32 discard_level) const
{
- if (discard_level < 0)
- {
- discard_level = mCurrentDiscardLevel;
- }
- S32 height = mHeight >> discard_level;
- if (height < 1) height = 1;
- return height;
+ if (discard_level < 0)
+ {
+ discard_level = mCurrentDiscardLevel;
+ }
+ S32 height = mHeight >> discard_level;
+ if (height < 1) height = 1;
+ return height;
}
S32 LLImageGL::getWidth(S32 discard_level) const
{
- if (discard_level < 0)
- {
- discard_level = mCurrentDiscardLevel;
- }
- S32 width = mWidth >> discard_level;
- if (width < 1) width = 1;
- return width;
+ if (discard_level < 0)
+ {
+ discard_level = mCurrentDiscardLevel;
+ }
+ S32 width = mWidth >> discard_level;
+ if (width < 1) width = 1;
+ return width;
}
S64 LLImageGL::getBytes(S32 discard_level) const
{
- if (discard_level < 0)
- {
- discard_level = mCurrentDiscardLevel;
- }
- S32 w = mWidth>>discard_level;
- S32 h = mHeight>>discard_level;
- if (w == 0) w = 1;
- if (h == 0) h = 1;
- return dataFormatBytes(mFormatPrimary, w, h);
+ if (discard_level < 0)
+ {
+ discard_level = mCurrentDiscardLevel;
+ }
+ S32 w = mWidth>>discard_level;
+ S32 h = mHeight>>discard_level;
+ if (w == 0) w = 1;
+ if (h == 0) h = 1;
+ return dataFormatBytes(mFormatPrimary, w, h);
}
S64 LLImageGL::getMipBytes(S32 discard_level) const
{
- if (discard_level < 0)
- {
- discard_level = mCurrentDiscardLevel;
- }
- S32 w = mWidth>>discard_level;
- S32 h = mHeight>>discard_level;
- S64 res = dataFormatBytes(mFormatPrimary, w, h);
- if (mUseMipMaps)
- {
- while (w > 1 && h > 1)
- {
- w >>= 1; if (w == 0) w = 1;
- h >>= 1; if (h == 0) h = 1;
- res += dataFormatBytes(mFormatPrimary, w, h);
- }
- }
- return res;
+ if (discard_level < 0)
+ {
+ discard_level = mCurrentDiscardLevel;
+ }
+ S32 w = mWidth>>discard_level;
+ S32 h = mHeight>>discard_level;
+ S64 res = dataFormatBytes(mFormatPrimary, w, h);
+ if (mUseMipMaps)
+ {
+ while (w > 1 && h > 1)
+ {
+ w >>= 1; if (w == 0) w = 1;
+ h >>= 1; if (h == 0) h = 1;
+ res += dataFormatBytes(mFormatPrimary, w, h);
+ }
+ }
+ return res;
}
BOOL LLImageGL::isJustBound() const
{
- return (BOOL)(sLastFrameTime - mLastBindTime < 0.5f);
+ return (BOOL)(sLastFrameTime - mLastBindTime < 0.5f);
}
BOOL LLImageGL::getBoundRecently() const
{
- return (BOOL)(sLastFrameTime - mLastBindTime < MIN_TEXTURE_LIFETIME);
+ return (BOOL)(sLastFrameTime - mLastBindTime < MIN_TEXTURE_LIFETIME);
}
BOOL LLImageGL::getIsAlphaMask() const
{
- llassert_always(!sSkipAnalyzeAlpha);
- return mIsMask;
+ llassert_always(!sSkipAnalyzeAlpha);
+ return mIsMask;
}
void LLImageGL::setTarget(const LLGLenum target, const LLTexUnit::eTextureType bind_target)
{
- mTarget = target;
- mBindTarget = bind_target;
+ mTarget = target;
+ mBindTarget = bind_target;
}
const S8 INVALID_OFFSET = -99 ;
-void LLImageGL::setNeedsAlphaAndPickMask(BOOL need_mask)
+void LLImageGL::setNeedsAlphaAndPickMask(BOOL need_mask)
{
- if(mNeedsAlphaAndPickMask != need_mask)
- {
- mNeedsAlphaAndPickMask = need_mask;
+ if(mNeedsAlphaAndPickMask != need_mask)
+ {
+ mNeedsAlphaAndPickMask = need_mask;
- if(mNeedsAlphaAndPickMask)
- {
- mAlphaOffset = 0 ;
- }
- else //do not need alpha mask
- {
- mAlphaOffset = INVALID_OFFSET ;
- mIsMask = FALSE;
- }
- }
+ if(mNeedsAlphaAndPickMask)
+ {
+ mAlphaOffset = 0 ;
+ }
+ else //do not need alpha mask
+ {
+ mAlphaOffset = INVALID_OFFSET ;
+ mIsMask = FALSE;
+ }
+ }
}
void LLImageGL::calcAlphaChannelOffsetAndStride()
{
- if(mAlphaOffset == INVALID_OFFSET)//do not need alpha mask
- {
- return ;
- }
+ if(mAlphaOffset == INVALID_OFFSET)//do not need alpha mask
+ {
+ return ;
+ }
- mAlphaStride = -1 ;
+ mAlphaStride = -1 ;
switch (mFormatPrimary)
{
case GL_LUMINANCE:
@@ -2148,173 +2148,173 @@ void LLImageGL::calcAlphaChannelOffsetAndStride()
break;
}
- mAlphaOffset = -1 ;
- if (mFormatType == GL_UNSIGNED_BYTE)
- {
- mAlphaOffset = mAlphaStride - 1 ;
- }
- else if(is_little_endian())
- {
- if (mFormatType == GL_UNSIGNED_INT_8_8_8_8)
- {
- mAlphaOffset = 0 ;
- }
- else if (mFormatType == GL_UNSIGNED_INT_8_8_8_8_REV)
- {
- mAlphaOffset = 3 ;
- }
- }
- else //big endian
- {
- if (mFormatType == GL_UNSIGNED_INT_8_8_8_8)
- {
- mAlphaOffset = 3 ;
- }
- else if (mFormatType == GL_UNSIGNED_INT_8_8_8_8_REV)
- {
- mAlphaOffset = 0 ;
- }
- }
-
- if( mAlphaStride < 1 || //unsupported format
- mAlphaOffset < 0 || //unsupported type
- (mFormatPrimary == GL_BGRA_EXT && mFormatType != GL_UNSIGNED_BYTE)) //unknown situation
- {
- LL_WARNS() << "Cannot analyze alpha for image with format type " << std::hex << mFormatType << std::dec << LL_ENDL;
-
- mNeedsAlphaAndPickMask = FALSE ;
- mIsMask = FALSE;
- }
+ mAlphaOffset = -1 ;
+ if (mFormatType == GL_UNSIGNED_BYTE)
+ {
+ mAlphaOffset = mAlphaStride - 1 ;
+ }
+ else if(is_little_endian())
+ {
+ if (mFormatType == GL_UNSIGNED_INT_8_8_8_8)
+ {
+ mAlphaOffset = 0 ;
+ }
+ else if (mFormatType == GL_UNSIGNED_INT_8_8_8_8_REV)
+ {
+ mAlphaOffset = 3 ;
+ }
+ }
+ else //big endian
+ {
+ if (mFormatType == GL_UNSIGNED_INT_8_8_8_8)
+ {
+ mAlphaOffset = 3 ;
+ }
+ else if (mFormatType == GL_UNSIGNED_INT_8_8_8_8_REV)
+ {
+ mAlphaOffset = 0 ;
+ }
+ }
+
+ if( mAlphaStride < 1 || //unsupported format
+ mAlphaOffset < 0 || //unsupported type
+ (mFormatPrimary == GL_BGRA_EXT && mFormatType != GL_UNSIGNED_BYTE)) //unknown situation
+ {
+ LL_WARNS() << "Cannot analyze alpha for image with format type " << std::hex << mFormatType << std::dec << LL_ENDL;
+
+ mNeedsAlphaAndPickMask = FALSE ;
+ mIsMask = FALSE;
+ }
}
void LLImageGL::analyzeAlpha(const void* data_in, U32 w, U32 h)
{
- if(sSkipAnalyzeAlpha || !mNeedsAlphaAndPickMask)
- {
- return ;
- }
-
- U32 length = w * h;
- U32 alphatotal = 0;
-
- U32 sample[16];
- memset(sample, 0, sizeof(U32)*16);
-
- // generate histogram of quantized alpha.
- // also add-in the histogram of a 2x2 box-sampled version. The idea is
- // this will mid-skew the data (and thus increase the chances of not
- // being used as a mask) from high-frequency alpha maps which
- // suffer the worst from aliasing when used as alpha masks.
- if (w >= 2 && h >= 2)
- {
- llassert(w%2 == 0);
- llassert(h%2 == 0);
- const GLubyte* rowstart = ((const GLubyte*) data_in) + mAlphaOffset;
- for (U32 y = 0; y < h; y+=2)
- {
- const GLubyte* current = rowstart;
- for (U32 x = 0; x < w; x+=2)
- {
- const U32 s1 = current[0];
- alphatotal += s1;
- const U32 s2 = current[w * mAlphaStride];
- alphatotal += s2;
- current += mAlphaStride;
- const U32 s3 = current[0];
- alphatotal += s3;
- const U32 s4 = current[w * mAlphaStride];
- alphatotal += s4;
- current += mAlphaStride;
-
- ++sample[s1/16];
- ++sample[s2/16];
- ++sample[s3/16];
- ++sample[s4/16];
-
- const U32 asum = (s1+s2+s3+s4);
- alphatotal += asum;
- sample[asum/(16*4)] += 4;
- }
-
-
- rowstart += 2 * w * mAlphaStride;
- }
- length *= 2; // we sampled everything twice, essentially
- }
- else
- {
- const GLubyte* current = ((const GLubyte*) data_in) + mAlphaOffset;
- for (U32 i = 0; i < length; i++)
- {
- const U32 s1 = *current;
- alphatotal += s1;
- ++sample[s1/16];
- current += mAlphaStride;
- }
- }
-
- // if more than 1/16th of alpha samples are mid-range, this
- // shouldn't be treated as a 1-bit mask
-
- // also, if all of the alpha samples are clumped on one half
- // of the range (but not at an absolute extreme), then consider
- // this to be an intentional effect and don't treat as a mask.
-
- U32 midrangetotal = 0;
- for (U32 i = 2; i < 13; i++)
- {
- midrangetotal += sample[i];
- }
- U32 lowerhalftotal = 0;
- for (U32 i = 0; i < 8; i++)
- {
- lowerhalftotal += sample[i];
- }
- U32 upperhalftotal = 0;
- for (U32 i = 8; i < 16; i++)
- {
- upperhalftotal += sample[i];
- }
-
- if (midrangetotal > length/48 || // lots of midrange, or
- (lowerhalftotal == length && alphatotal != 0) || // all close to transparent but not all totally transparent, or
- (upperhalftotal == length && alphatotal != 255*length)) // all close to opaque but not all totally opaque
- {
- mIsMask = FALSE; // not suitable for masking
- }
- else
- {
- mIsMask = TRUE;
- }
+ if(sSkipAnalyzeAlpha || !mNeedsAlphaAndPickMask)
+ {
+ return ;
+ }
+
+ U32 length = w * h;
+ U32 alphatotal = 0;
+
+ U32 sample[16];
+ memset(sample, 0, sizeof(U32)*16);
+
+ // generate histogram of quantized alpha.
+ // also add-in the histogram of a 2x2 box-sampled version. The idea is
+ // this will mid-skew the data (and thus increase the chances of not
+ // being used as a mask) from high-frequency alpha maps which
+ // suffer the worst from aliasing when used as alpha masks.
+ if (w >= 2 && h >= 2)
+ {
+ llassert(w%2 == 0);
+ llassert(h%2 == 0);
+ const GLubyte* rowstart = ((const GLubyte*) data_in) + mAlphaOffset;
+ for (U32 y = 0; y < h; y+=2)
+ {
+ const GLubyte* current = rowstart;
+ for (U32 x = 0; x < w; x+=2)
+ {
+ const U32 s1 = current[0];
+ alphatotal += s1;
+ const U32 s2 = current[w * mAlphaStride];
+ alphatotal += s2;
+ current += mAlphaStride;
+ const U32 s3 = current[0];
+ alphatotal += s3;
+ const U32 s4 = current[w * mAlphaStride];
+ alphatotal += s4;
+ current += mAlphaStride;
+
+ ++sample[s1/16];
+ ++sample[s2/16];
+ ++sample[s3/16];
+ ++sample[s4/16];
+
+ const U32 asum = (s1+s2+s3+s4);
+ alphatotal += asum;
+ sample[asum/(16*4)] += 4;
+ }
+
+
+ rowstart += 2 * w * mAlphaStride;
+ }
+ length *= 2; // we sampled everything twice, essentially
+ }
+ else
+ {
+ const GLubyte* current = ((const GLubyte*) data_in) + mAlphaOffset;
+ for (U32 i = 0; i < length; i++)
+ {
+ const U32 s1 = *current;
+ alphatotal += s1;
+ ++sample[s1/16];
+ current += mAlphaStride;
+ }
+ }
+
+ // if more than 1/16th of alpha samples are mid-range, this
+ // shouldn't be treated as a 1-bit mask
+
+ // also, if all of the alpha samples are clumped on one half
+ // of the range (but not at an absolute extreme), then consider
+ // this to be an intentional effect and don't treat as a mask.
+
+ U32 midrangetotal = 0;
+ for (U32 i = 2; i < 13; i++)
+ {
+ midrangetotal += sample[i];
+ }
+ U32 lowerhalftotal = 0;
+ for (U32 i = 0; i < 8; i++)
+ {
+ lowerhalftotal += sample[i];
+ }
+ U32 upperhalftotal = 0;
+ for (U32 i = 8; i < 16; i++)
+ {
+ upperhalftotal += sample[i];
+ }
+
+ if (midrangetotal > length/48 || // lots of midrange, or
+ (lowerhalftotal == length && alphatotal != 0) || // all close to transparent but not all totally transparent, or
+ (upperhalftotal == length && alphatotal != 255*length)) // all close to opaque but not all totally opaque
+ {
+ mIsMask = FALSE; // not suitable for masking
+ }
+ else
+ {
+ mIsMask = TRUE;
+ }
}
//----------------------------------------------------------------------------
U32 LLImageGL::createPickMask(S32 pWidth, S32 pHeight)
{
- U32 pick_width = pWidth/2 + 1;
- U32 pick_height = pHeight/2 + 1;
+ U32 pick_width = pWidth/2 + 1;
+ U32 pick_height = pHeight/2 + 1;
- U32 size = pick_width * pick_height;
- size = (size + 7) / 8; // pixelcount-to-bits
- mPickMask = new U8[size];
- mPickMaskWidth = pick_width - 1;
- mPickMaskHeight = pick_height - 1;
+ U32 size = pick_width * pick_height;
+ size = (size + 7) / 8; // pixelcount-to-bits
+ mPickMask = new U8[size];
+ mPickMaskWidth = pick_width - 1;
+ mPickMaskHeight = pick_height - 1;
- memset(mPickMask, 0, sizeof(U8) * size);
+ memset(mPickMask, 0, sizeof(U8) * size);
- return size;
+ return size;
}
//----------------------------------------------------------------------------
void LLImageGL::freePickMask()
{
- // pickmask validity depends on old image size, delete it
- if (mPickMask != NULL)
- {
- delete [] mPickMask;
- }
- mPickMask = NULL;
- mPickMaskWidth = mPickMaskHeight = 0;
+ // pickmask validity depends on old image size, delete it
+ if (mPickMask != NULL)
+ {
+ delete [] mPickMask;
+ }
+ mPickMask = NULL;
+ mPickMaskWidth = mPickMaskHeight = 0;
}
bool LLImageGL::isCompressed()
@@ -2341,12 +2341,12 @@ bool LLImageGL::isCompressed()
//----------------------------------------------------------------------------
void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in)
{
- if(!mNeedsAlphaAndPickMask)
- {
- return ;
- }
+ if(!mNeedsAlphaAndPickMask)
+ {
+ return ;
+ }
- freePickMask();
+ freePickMask();
if (mFormatType != GL_UNSIGNED_BYTE ||
((mFormatPrimary != GL_RGBA)
@@ -2357,102 +2357,102 @@ void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in)
}
#ifdef SHOW_ASSERT
- const U32 pickSize = createPickMask(width, height);
+ const U32 pickSize = createPickMask(width, height);
#else // SHOW_ASSERT
- createPickMask(width, height);
+ createPickMask(width, height);
#endif // SHOW_ASSERT
- U32 pick_bit = 0;
-
- for (S32 y = 0; y < height; y += 2)
- {
- for (S32 x = 0; x < width; x += 2)
- {
- U8 alpha = data_in[(y*width+x)*4+3];
+ U32 pick_bit = 0;
- if (alpha > 32)
- {
- U32 pick_idx = pick_bit/8;
- U32 pick_offset = pick_bit%8;
- llassert(pick_idx < pickSize);
+ for (S32 y = 0; y < height; y += 2)
+ {
+ for (S32 x = 0; x < width; x += 2)
+ {
+ U8 alpha = data_in[(y*width+x)*4+3];
+
+ if (alpha > 32)
+ {
+ U32 pick_idx = pick_bit/8;
+ U32 pick_offset = pick_bit%8;
+ llassert(pick_idx < pickSize);
- mPickMask[pick_idx] |= 1 << pick_offset;
- }
-
- ++pick_bit;
- }
- }
+ mPickMask[pick_idx] |= 1 << pick_offset;
+ }
+
+ ++pick_bit;
+ }
+ }
}
BOOL LLImageGL::getMask(const LLVector2 &tc)
{
- BOOL res = TRUE;
-
- if (mPickMask)
- {
- F32 u,v;
- if (LL_LIKELY(tc.isFinite()))
- {
- u = tc.mV[0] - floorf(tc.mV[0]);
- v = tc.mV[1] - floorf(tc.mV[1]);
- }
- else
- {
- LL_WARNS_ONCE("render") << "Ugh, non-finite u/v in mask pick" << LL_ENDL;
- u = v = 0.f;
- // removing assert per EXT-4388
- // llassert(false);
- }
-
- if (LL_UNLIKELY(u < 0.f || u > 1.f ||
- v < 0.f || v > 1.f))
- {
- LL_WARNS_ONCE("render") << "Ugh, u/v out of range in image mask pick" << LL_ENDL;
- u = v = 0.f;
- // removing assert per EXT-4388
- // llassert(false);
- }
-
- S32 x = llfloor(u * mPickMaskWidth);
- S32 y = llfloor(v * mPickMaskHeight);
-
- if (LL_UNLIKELY(x > mPickMaskWidth))
- {
- LL_WARNS_ONCE("render") << "Ooh, width overrun on pick mask read, that coulda been bad." << LL_ENDL;
- x = llmax((U16)0, mPickMaskWidth);
- }
- if (LL_UNLIKELY(y > mPickMaskHeight))
- {
- LL_WARNS_ONCE("render") << "Ooh, height overrun on pick mask read, that woulda been bad." << LL_ENDL;
- y = llmax((U16)0, mPickMaskHeight);
- }
-
- S32 idx = y*mPickMaskWidth+x;
- S32 offset = idx%8;
-
- res = mPickMask[idx/8] & (1 << offset) ? TRUE : FALSE;
- }
-
- return res;
+ BOOL res = TRUE;
+
+ if (mPickMask)
+ {
+ F32 u,v;
+ if (LL_LIKELY(tc.isFinite()))
+ {
+ u = tc.mV[0] - floorf(tc.mV[0]);
+ v = tc.mV[1] - floorf(tc.mV[1]);
+ }
+ else
+ {
+ LL_WARNS_ONCE("render") << "Ugh, non-finite u/v in mask pick" << LL_ENDL;
+ u = v = 0.f;
+ // removing assert per EXT-4388
+ // llassert(false);
+ }
+
+ if (LL_UNLIKELY(u < 0.f || u > 1.f ||
+ v < 0.f || v > 1.f))
+ {
+ LL_WARNS_ONCE("render") << "Ugh, u/v out of range in image mask pick" << LL_ENDL;
+ u = v = 0.f;
+ // removing assert per EXT-4388
+ // llassert(false);
+ }
+
+ S32 x = llfloor(u * mPickMaskWidth);
+ S32 y = llfloor(v * mPickMaskHeight);
+
+ if (LL_UNLIKELY(x > mPickMaskWidth))
+ {
+ LL_WARNS_ONCE("render") << "Ooh, width overrun on pick mask read, that coulda been bad." << LL_ENDL;
+ x = llmax((U16)0, mPickMaskWidth);
+ }
+ if (LL_UNLIKELY(y > mPickMaskHeight))
+ {
+ LL_WARNS_ONCE("render") << "Ooh, height overrun on pick mask read, that woulda been bad." << LL_ENDL;
+ y = llmax((U16)0, mPickMaskHeight);
+ }
+
+ S32 idx = y*mPickMaskWidth+x;
+ S32 offset = idx%8;
+
+ res = mPickMask[idx/8] & (1 << offset) ? TRUE : FALSE;
+ }
+
+ return res;
}
void LLImageGL::setCurTexSizebar(S32 index, BOOL set_pick_size)
{
- sCurTexSizeBar = index ;
+ sCurTexSizeBar = index ;
- if(set_pick_size)
- {
- sCurTexPickSize = (1 << index) ;
- }
- else
- {
- sCurTexPickSize = -1 ;
- }
+ if(set_pick_size)
+ {
+ sCurTexPickSize = (1 << index) ;
+ }
+ else
+ {
+ sCurTexPickSize = -1 ;
+ }
}
void LLImageGL::resetCurTexSizebar()
{
- sCurTexSizeBar = -1 ;
- sCurTexPickSize = -1 ;
+ sCurTexSizeBar = -1 ;
+ sCurTexPickSize = -1 ;
}
//----------------------------------------------------------------------------
#if LL_IMAGEGL_THREAD_CHECK
@@ -2467,53 +2467,53 @@ void LLImageGL::checkActiveThread()
// Manual Mip Generation
/*
- S32 width = getWidth(discard_level);
- S32 height = getHeight(discard_level);
- S32 w = width, h = height;
- S32 nummips = 1;
- while (w > 4 && h > 4)
- {
- w >>= 1; h >>= 1;
- nummips++;
- }
- stop_glerror();
- w = width, h = height;
- const U8* prev_mip_data = 0;
- const U8* cur_mip_data = 0;
- for (int m=0; m<nummips; m++)
- {
- if (m==0)
- {
- cur_mip_data = rawdata;
- }
- else
- {
- S32 bytes = w * h * mComponents;
- U8* new_data = new U8[bytes];
- LLImageBase::generateMip(prev_mip_data, new_data, w, h, mComponents);
- cur_mip_data = new_data;
- }
- llassert(w > 0 && h > 0 && cur_mip_data);
- U8 test = cur_mip_data[w*h*mComponents-1];
- {
- LLImageGL::setManualImage(mTarget, m, mFormatInternal, w, h, mFormatPrimary, mFormatType, cur_mip_data);
- stop_glerror();
- }
- if (prev_mip_data && prev_mip_data != rawdata)
- {
- delete prev_mip_data;
- }
- prev_mip_data = cur_mip_data;
- w >>= 1;
- h >>= 1;
- }
- if (prev_mip_data && prev_mip_data != rawdata)
- {
- delete prev_mip_data;
- }
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, nummips);
-*/
+ S32 width = getWidth(discard_level);
+ S32 height = getHeight(discard_level);
+ S32 w = width, h = height;
+ S32 nummips = 1;
+ while (w > 4 && h > 4)
+ {
+ w >>= 1; h >>= 1;
+ nummips++;
+ }
+ stop_glerror();
+ w = width, h = height;
+ const U8* prev_mip_data = 0;
+ const U8* cur_mip_data = 0;
+ for (int m=0; m<nummips; m++)
+ {
+ if (m==0)
+ {
+ cur_mip_data = rawdata;
+ }
+ else
+ {
+ S32 bytes = w * h * mComponents;
+ U8* new_data = new U8[bytes];
+ LLImageBase::generateMip(prev_mip_data, new_data, w, h, mComponents);
+ cur_mip_data = new_data;
+ }
+ llassert(w > 0 && h > 0 && cur_mip_data);
+ U8 test = cur_mip_data[w*h*mComponents-1];
+ {
+ LLImageGL::setManualImage(mTarget, m, mFormatInternal, w, h, mFormatPrimary, mFormatType, cur_mip_data);
+ stop_glerror();
+ }
+ if (prev_mip_data && prev_mip_data != rawdata)
+ {
+ delete prev_mip_data;
+ }
+ prev_mip_data = cur_mip_data;
+ w >>= 1;
+ h >>= 1;
+ }
+ if (prev_mip_data && prev_mip_data != rawdata)
+ {
+ delete prev_mip_data;
+ }
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, nummips);
+*/
LLImageGLThread::LLImageGLThread(LLWindow* window)
// We want exactly one thread.
diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h
index a9a6b93cb3..89e35d2226 100644
--- a/indra/llrender/llimagegl.h
+++ b/indra/llrender/llimagegl.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file llimagegl.h
* @brief Object for managing images and their textures
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -50,7 +50,7 @@ class LLWindow;
//============================================================================
class LLImageGL : public LLRefCount
{
- friend class LLTexUnit;
+ friend class LLTexUnit;
public:
// Get an estimate of how many bytes have been allocated in vram for textures.
@@ -59,146 +59,146 @@ public:
// video memory usage based on testing in lagland against an NVIDIA GPU.
static U64 getTextureBytesAllocated();
- // These 2 functions replace glGenTextures() and glDeleteTextures()
- static void generateTextures(S32 numTextures, U32 *textures);
- static void deleteTextures(S32 numTextures, const U32 *textures);
+ // These 2 functions replace glGenTextures() and glDeleteTextures()
+ static void generateTextures(S32 numTextures, U32 *textures);
+ static void deleteTextures(S32 numTextures, const U32 *textures);
+
+ // Size calculation
+ static S32 dataFormatBits(S32 dataformat);
+ static S64 dataFormatBytes(S32 dataformat, S32 width, S32 height);
+ static S32 dataFormatComponents(S32 dataformat);
- // Size calculation
- static S32 dataFormatBits(S32 dataformat);
- static S64 dataFormatBytes(S32 dataformat, S32 width, S32 height);
- static S32 dataFormatComponents(S32 dataformat);
+ BOOL updateBindStats() const ;
+ F32 getTimePassedSinceLastBound();
+ void forceUpdateBindStats(void) const;
- BOOL updateBindStats() const ;
- F32 getTimePassedSinceLastBound();
- void forceUpdateBindStats(void) const;
+ // needs to be called every frame
+ static void updateStats(F32 current_time);
- // needs to be called every frame
- static void updateStats(F32 current_time);
+ // Save off / restore GL textures
+ static void destroyGL(BOOL save_state = TRUE);
+ static void restoreGL();
+ static void dirtyTexOptions();
- // Save off / restore GL textures
- static void destroyGL(BOOL save_state = TRUE);
- static void restoreGL();
- static void dirtyTexOptions();
+ static bool checkSize(S32 width, S32 height);
- static bool checkSize(S32 width, S32 height);
+ //for server side use only.
+ // Not currently necessary for LLImageGL, but required in some derived classes,
+ // so include for compatability
+ static BOOL create(LLPointer<LLImageGL>& dest, BOOL usemipmaps = TRUE);
+ static BOOL create(LLPointer<LLImageGL>& dest, U32 width, U32 height, U8 components, BOOL usemipmaps = TRUE);
+ static BOOL create(LLPointer<LLImageGL>& dest, const LLImageRaw* imageraw, BOOL usemipmaps = TRUE);
- //for server side use only.
- // Not currently necessary for LLImageGL, but required in some derived classes,
- // so include for compatability
- static BOOL create(LLPointer<LLImageGL>& dest, BOOL usemipmaps = TRUE);
- static BOOL create(LLPointer<LLImageGL>& dest, U32 width, U32 height, U8 components, BOOL usemipmaps = TRUE);
- static BOOL create(LLPointer<LLImageGL>& dest, const LLImageRaw* imageraw, BOOL usemipmaps = TRUE);
-
public:
- LLImageGL(BOOL usemipmaps = TRUE);
- LLImageGL(U32 width, U32 height, U8 components, BOOL usemipmaps = TRUE);
- LLImageGL(const LLImageRaw* imageraw, BOOL usemipmaps = TRUE);
+ LLImageGL(BOOL usemipmaps = TRUE);
+ LLImageGL(U32 width, U32 height, U8 components, BOOL usemipmaps = TRUE);
+ LLImageGL(const LLImageRaw* imageraw, BOOL usemipmaps = TRUE);
// For wrapping textures created via GL elsewhere with our API only. Use with caution.
LLImageGL(LLGLuint mTexName, U32 components, LLGLenum target, LLGLint formatInternal, LLGLenum formatPrimary, LLGLenum formatType, LLTexUnit::eTextureAddressMode addressMode);
protected:
- virtual ~LLImageGL();
+ virtual ~LLImageGL();
- void analyzeAlpha(const void* data_in, U32 w, U32 h);
- void calcAlphaChannelOffsetAndStride();
+ void analyzeAlpha(const void* data_in, U32 w, U32 h);
+ void calcAlphaChannelOffsetAndStride();
public:
- virtual void dump(); // debugging info to LL_INFOS()
-
- bool setSize(S32 width, S32 height, S32 ncomponents, S32 discard_level = -1);
- void setComponents(S32 ncomponents) { mComponents = (S8)ncomponents ;}
- void setAllowCompression(bool allow) { mAllowCompression = allow; }
-
- static void setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels, bool allow_compression = true);
-
- BOOL createGLTexture() ;
- BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0, BOOL to_create = TRUE,
- S32 category = sMaxCategories-1, bool defer_copy = false, LLGLuint* tex_name = nullptr);
- BOOL createGLTexture(S32 discard_level, const U8* data, BOOL data_hasmips = FALSE, S32 usename = 0, bool defer_copy = false, LLGLuint* tex_name = nullptr);
- void setImage(const LLImageRaw* imageraw);
- BOOL setImage(const U8* data_in, BOOL data_hasmips = FALSE, S32 usename = 0);
+ virtual void dump(); // debugging info to LL_INFOS()
+
+ bool setSize(S32 width, S32 height, S32 ncomponents, S32 discard_level = -1);
+ void setComponents(S32 ncomponents) { mComponents = (S8)ncomponents ;}
+ void setAllowCompression(bool allow) { mAllowCompression = allow; }
+
+ static void setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels, bool allow_compression = true);
+
+ BOOL createGLTexture() ;
+ BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0, BOOL to_create = TRUE,
+ S32 category = sMaxCategories-1, bool defer_copy = false, LLGLuint* tex_name = nullptr);
+ BOOL createGLTexture(S32 discard_level, const U8* data, BOOL data_hasmips = FALSE, S32 usename = 0, bool defer_copy = false, LLGLuint* tex_name = nullptr);
+ void setImage(const LLImageRaw* imageraw);
+ BOOL setImage(const U8* data_in, BOOL data_hasmips = FALSE, S32 usename = 0);
// *TODO: This function may not work if the textures is compressed (i.e.
// RenderCompressTextures is 0). Partial image updates do not work on
// compressed textures.
- BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE, LLGLuint use_name = 0);
- BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE, LLGLuint use_name = 0);
- BOOL setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_pos, S32 width, S32 height);
+ BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE, LLGLuint use_name = 0);
+ BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE, LLGLuint use_name = 0);
+ BOOL setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_pos, S32 width, S32 height);
// wait for gl commands to finish on current thread and push
// a lambda to main thread to swap mNewTexName and mTexName
void syncToMainThread(LLGLuint new_tex_name);
- // Read back a raw image for this discard level, if it exists
- BOOL readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok) const;
- void destroyGLTexture();
- void forceToInvalidateGLTexture();
+ // Read back a raw image for this discard level, if it exists
+ BOOL readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok) const;
+ void destroyGLTexture();
+ void forceToInvalidateGLTexture();
- void setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format = 0, BOOL swap_bytes = FALSE);
- void setComponents(S8 ncomponents) { mComponents = ncomponents; }
+ void setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format = 0, BOOL swap_bytes = FALSE);
+ void setComponents(S8 ncomponents) { mComponents = ncomponents; }
- S32 getDiscardLevel() const { return mCurrentDiscardLevel; }
- S32 getMaxDiscardLevel() const { return mMaxDiscardLevel; }
+ S32 getDiscardLevel() const { return mCurrentDiscardLevel; }
+ S32 getMaxDiscardLevel() const { return mMaxDiscardLevel; }
- S32 getCurrentWidth() const { return mWidth ;}
- S32 getCurrentHeight() const { return mHeight ;}
- S32 getWidth(S32 discard_level = -1) const;
- S32 getHeight(S32 discard_level = -1) const;
- U8 getComponents() const { return mComponents; }
- S64 getBytes(S32 discard_level = -1) const;
- S64 getMipBytes(S32 discard_level = -1) const;
- BOOL getBoundRecently() const;
- BOOL isJustBound() const;
- BOOL getHasExplicitFormat() const { return mHasExplicitFormat; }
- LLGLenum getPrimaryFormat() const { return mFormatPrimary; }
- LLGLenum getFormatType() const { return mFormatType; }
+ S32 getCurrentWidth() const { return mWidth ;}
+ S32 getCurrentHeight() const { return mHeight ;}
+ S32 getWidth(S32 discard_level = -1) const;
+ S32 getHeight(S32 discard_level = -1) const;
+ U8 getComponents() const { return mComponents; }
+ S64 getBytes(S32 discard_level = -1) const;
+ S64 getMipBytes(S32 discard_level = -1) const;
+ BOOL getBoundRecently() const;
+ BOOL isJustBound() const;
+ BOOL getHasExplicitFormat() const { return mHasExplicitFormat; }
+ LLGLenum getPrimaryFormat() const { return mFormatPrimary; }
+ LLGLenum getFormatType() const { return mFormatType; }
- BOOL getHasGLTexture() const { return mTexName != 0; }
- LLGLuint getTexName() const { return mTexName; }
+ BOOL getHasGLTexture() const { return mTexName != 0; }
+ LLGLuint getTexName() const { return mTexName; }
- BOOL getIsAlphaMask() const;
+ BOOL getIsAlphaMask() const;
- BOOL getIsResident(BOOL test_now = FALSE); // not const
+ BOOL getIsResident(BOOL test_now = FALSE); // not const
- void setTarget(const LLGLenum target, const LLTexUnit::eTextureType bind_target);
+ void setTarget(const LLGLenum target, const LLTexUnit::eTextureType bind_target);
- LLTexUnit::eTextureType getTarget(void) const { return mBindTarget; }
- bool isGLTextureCreated(void) const { return mGLTextureCreated ; }
- void setGLTextureCreated (bool initialized) { mGLTextureCreated = initialized; }
+ LLTexUnit::eTextureType getTarget(void) const { return mBindTarget; }
+ bool isGLTextureCreated(void) const { return mGLTextureCreated ; }
+ void setGLTextureCreated (bool initialized) { mGLTextureCreated = initialized; }
- BOOL getUseMipMaps() const { return mUseMipMaps; }
- void setUseMipMaps(BOOL usemips) { mUseMipMaps = usemips; }
+ BOOL getUseMipMaps() const { return mUseMipMaps; }
+ void setUseMipMaps(BOOL usemips) { mUseMipMaps = usemips; }
void setHasMipMaps(BOOL hasmips) { mHasMipMaps = hasmips; }
- void updatePickMask(S32 width, S32 height, const U8* data_in);
- BOOL getMask(const LLVector2 &tc);
+ void updatePickMask(S32 width, S32 height, const U8* data_in);
+ BOOL getMask(const LLVector2 &tc);
void checkTexSize(bool forced = false) const ;
-
- // Sets the addressing mode used to sample the texture
- // (such as wrapping, mirrored wrapping, and clamp)
- // Note: this actually gets set the next time the texture is bound.
- void setAddressMode(LLTexUnit::eTextureAddressMode mode);
- LLTexUnit::eTextureAddressMode getAddressMode(void) const { return mAddressMode; }
- // Sets the filtering options used to sample the texture
- // (such as point sampling, bilinear interpolation, mipmapping, and anisotropic filtering)
- // Note: this actually gets set the next time the texture is bound.
- void setFilteringOption(LLTexUnit::eTextureFilterOptions option);
- LLTexUnit::eTextureFilterOptions getFilteringOption(void) const { return mFilterOption; }
+ // Sets the addressing mode used to sample the texture
+ // (such as wrapping, mirrored wrapping, and clamp)
+ // Note: this actually gets set the next time the texture is bound.
+ void setAddressMode(LLTexUnit::eTextureAddressMode mode);
+ LLTexUnit::eTextureAddressMode getAddressMode(void) const { return mAddressMode; }
+
+ // Sets the filtering options used to sample the texture
+ // (such as point sampling, bilinear interpolation, mipmapping, and anisotropic filtering)
+ // Note: this actually gets set the next time the texture is bound.
+ void setFilteringOption(LLTexUnit::eTextureFilterOptions option);
+ LLTexUnit::eTextureFilterOptions getFilteringOption(void) const { return mFilterOption; }
- LLGLenum getTexTarget()const { return mTarget ;}
- S8 getDiscardLevelInAtlas()const {return mDiscardLevelInAtlas;}
- U32 getTexelsInAtlas()const { return mTexelsInAtlas ;}
- U32 getTexelsInGLTexture()const {return mTexelsInGLTexture;}
+ LLGLenum getTexTarget()const { return mTarget ;}
+ S8 getDiscardLevelInAtlas()const {return mDiscardLevelInAtlas;}
+ U32 getTexelsInAtlas()const { return mTexelsInAtlas ;}
+ U32 getTexelsInGLTexture()const {return mTexelsInGLTexture;}
-
- void init(BOOL usemipmaps);
- virtual void cleanup(); // Clean up the LLImageGL so it can be reinitialized. Be careful when using this in derived class destructors
- void setNeedsAlphaAndPickMask(BOOL need_mask);
+ void init(BOOL usemipmaps);
+ virtual void cleanup(); // Clean up the LLImageGL so it can be reinitialized. Be careful when using this in derived class destructors
- BOOL preAddToAtlas(S32 discard_level, const LLImageRaw* raw_image);
- void postAddToAtlas() ;
+ void setNeedsAlphaAndPickMask(BOOL need_mask);
+
+ BOOL preAddToAtlas(S32 discard_level, const LLImageRaw* raw_image);
+ void postAddToAtlas() ;
#if LL_IMAGEGL_THREAD_CHECK
// thread debugging
@@ -207,118 +207,118 @@ public:
#endif
public:
- // Various GL/Rendering options
- S64Bytes mTextureMemory;
- mutable F32 mLastBindTime; // last time this was bound, by discard level
-
+ // Various GL/Rendering options
+ S64Bytes mTextureMemory;
+ mutable F32 mLastBindTime; // last time this was bound, by discard level
+
private:
- U32 createPickMask(S32 pWidth, S32 pHeight);
- void freePickMask();
+ U32 createPickMask(S32 pWidth, S32 pHeight);
+ void freePickMask();
bool isCompressed();
- LLPointer<LLImageRaw> mSaveData; // used for destroyGL/restoreGL
- LL::WorkQueue::weak_t mMainQueue;
- U8* mPickMask; //downsampled bitmap approximation of alpha channel. NULL if no alpha channel
- U16 mPickMaskWidth;
- U16 mPickMaskHeight;
- S8 mUseMipMaps;
- BOOL mHasExplicitFormat; // If false (default), GL format is f(mComponents)
- bool mAutoGenMips = false;
-
- BOOL mIsMask;
- BOOL mNeedsAlphaAndPickMask;
- S8 mAlphaStride ;
- S8 mAlphaOffset ;
-
- bool mGLTextureCreated ;
- LLGLuint mTexName;
+ LLPointer<LLImageRaw> mSaveData; // used for destroyGL/restoreGL
+ LL::WorkQueue::weak_t mMainQueue;
+ U8* mPickMask; //downsampled bitmap approximation of alpha channel. NULL if no alpha channel
+ U16 mPickMaskWidth;
+ U16 mPickMaskHeight;
+ S8 mUseMipMaps;
+ BOOL mHasExplicitFormat; // If false (default), GL format is f(mComponents)
+ bool mAutoGenMips = false;
+
+ BOOL mIsMask;
+ BOOL mNeedsAlphaAndPickMask;
+ S8 mAlphaStride ;
+ S8 mAlphaOffset ;
+
+ bool mGLTextureCreated ;
+ LLGLuint mTexName;
//LLGLuint mNewTexName = 0; // tex name set by background thread to be applied in main thread
- U16 mWidth;
- U16 mHeight;
- S8 mCurrentDiscardLevel;
-
- S8 mDiscardLevelInAtlas;
- U32 mTexelsInAtlas ;
- U32 mTexelsInGLTexture;
+ U16 mWidth;
+ U16 mHeight;
+ S8 mCurrentDiscardLevel;
- bool mAllowCompression;
+ S8 mDiscardLevelInAtlas;
+ U32 mTexelsInAtlas ;
+ U32 mTexelsInGLTexture;
+
+ bool mAllowCompression;
protected:
- LLGLenum mTarget; // Normally GL_TEXTURE2D, sometimes something else (ex. cube maps)
- LLTexUnit::eTextureType mBindTarget; // Normally TT_TEXTURE, sometimes something else (ex. cube maps)
- bool mHasMipMaps;
- S32 mMipLevels;
-
- LLGLboolean mIsResident;
-
- S8 mComponents;
- S8 mMaxDiscardLevel;
-
- bool mTexOptionsDirty;
- LLTexUnit::eTextureAddressMode mAddressMode; // Defaults to TAM_WRAP
- LLTexUnit::eTextureFilterOptions mFilterOption; // Defaults to TFO_ANISOTROPIC
-
- LLGLint mFormatInternal; // = GL internalformat
- LLGLenum mFormatPrimary; // = GL format (pixel data format)
- LLGLenum mFormatType;
- BOOL mFormatSwapBytes;// if true, use glPixelStorei(GL_UNPACK_SWAP_BYTES, 1)
-
+ LLGLenum mTarget; // Normally GL_TEXTURE2D, sometimes something else (ex. cube maps)
+ LLTexUnit::eTextureType mBindTarget; // Normally TT_TEXTURE, sometimes something else (ex. cube maps)
+ bool mHasMipMaps;
+ S32 mMipLevels;
+
+ LLGLboolean mIsResident;
+
+ S8 mComponents;
+ S8 mMaxDiscardLevel;
+
+ bool mTexOptionsDirty;
+ LLTexUnit::eTextureAddressMode mAddressMode; // Defaults to TAM_WRAP
+ LLTexUnit::eTextureFilterOptions mFilterOption; // Defaults to TFO_ANISOTROPIC
+
+ LLGLint mFormatInternal; // = GL internalformat
+ LLGLenum mFormatPrimary; // = GL format (pixel data format)
+ LLGLenum mFormatType;
+ BOOL mFormatSwapBytes;// if true, use glPixelStorei(GL_UNPACK_SWAP_BYTES, 1)
+
BOOL mExternalTexture;
- // STATICS
-public:
- static std::set<LLImageGL*> sImageList;
- static S32 sCount;
-
- static F32 sLastFrameTime;
-
- // Global memory statistics
- static U32 sBindCount; // Tracks number of texture binds for current frame
- static U32 sUniqueCount; // Tracks number of unique texture binds for current frame
- static BOOL sGlobalUseAnisotropic;
- static LLImageGL* sDefaultGLTexture ;
- static BOOL sAutomatedTest;
- static bool sCompressTextures; //use GL texture compression
+ // STATICS
+public:
+ static std::set<LLImageGL*> sImageList;
+ static S32 sCount;
+
+ static F32 sLastFrameTime;
+
+ // Global memory statistics
+ static U32 sBindCount; // Tracks number of texture binds for current frame
+ static U32 sUniqueCount; // Tracks number of unique texture binds for current frame
+ static BOOL sGlobalUseAnisotropic;
+ static LLImageGL* sDefaultGLTexture ;
+ static BOOL sAutomatedTest;
+ static bool sCompressTextures; //use GL texture compression
#if DEBUG_MISS
- BOOL mMissed; // Missed on last bind?
- BOOL getMissed() const { return mMissed; };
+ BOOL mMissed; // Missed on last bind?
+ BOOL getMissed() const { return mMissed; };
#else
- BOOL getMissed() const { return FALSE; };
+ BOOL getMissed() const { return FALSE; };
#endif
public:
- static void initClass(LLWindow* window, S32 num_catagories, BOOL skip_analyze_alpha = false, bool thread_texture_loads = false, bool thread_media_updates = false);
- static void cleanupClass() ;
+ static void initClass(LLWindow* window, S32 num_catagories, BOOL skip_analyze_alpha = false, bool thread_texture_loads = false, bool thread_media_updates = false);
+ static void cleanupClass() ;
private:
- static S32 sMaxCategories;
- static BOOL sSkipAnalyzeAlpha;
-
- //the flag to allow to call readBackRaw(...).
- //can be removed if we do not use that function at all.
- static BOOL sAllowReadBackRaw ;
+ static S32 sMaxCategories;
+ static BOOL sSkipAnalyzeAlpha;
+
+ //the flag to allow to call readBackRaw(...).
+ //can be removed if we do not use that function at all.
+ static BOOL sAllowReadBackRaw ;
//
//****************************************************************************************************
//The below for texture auditing use only
//****************************************************************************************************
private:
- S32 mCategory ;
+ S32 mCategory ;
public:
- void setCategory(S32 category) {mCategory = category;}
- S32 getCategory()const {return mCategory;}
-
+ void setCategory(S32 category) {mCategory = category;}
+ S32 getCategory()const {return mCategory;}
+
void setTexName(GLuint texName) { mTexName = texName; }
//similar to setTexName, but will call deleteTextures on mTexName if mTexName is not 0 or texname
void syncTexName(LLGLuint texname);
- //for debug use: show texture size distribution
- //----------------------------------------
- static S32 sCurTexSizeBar ;
- static S32 sCurTexPickSize ;
+ //for debug use: show texture size distribution
+ //----------------------------------------
+ static S32 sCurTexSizeBar ;
+ static S32 sCurTexPickSize ;
- static void setCurTexSizebar(S32 index, BOOL set_pick_size = TRUE) ;
- static void resetCurTexSizebar();
+ static void setCurTexSizebar(S32 index, BOOL set_pick_size = TRUE) ;
+ static void resetCurTexSizebar();
//****************************************************************************************************
//End of definitions for texture auditing use only
@@ -333,7 +333,7 @@ public:
static bool sEnabledTextures;
// follows gSavedSettings "RenderGLMultiThreadedMedia"
static bool sEnabledMedia;
-
+
LLImageGLThread(LLWindow* window);
// post a function to be executed on the LLImageGL background thread
diff --git a/indra/llrender/llpostprocess.cpp b/indra/llrender/llpostprocess.cpp
index 0f8655132b..4242e330f4 100644
--- a/indra/llrender/llpostprocess.cpp
+++ b/indra/llrender/llpostprocess.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llpostprocess.cpp
* @brief LLPostProcess class implementation
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -51,214 +51,214 @@ LLPostProcess * gPostProcess = NULL;
static const unsigned int NOISE_SIZE = 512;
-LLPostProcess::LLPostProcess(void) :
- initialized(false),
- mAllEffects(LLSD::emptyMap()),
- screenW(1), screenH(1)
+LLPostProcess::LLPostProcess(void) :
+ initialized(false),
+ mAllEffects(LLSD::emptyMap()),
+ screenW(1), screenH(1)
{
- mSceneRenderTexture = NULL ;
- mNoiseTexture = NULL ;
- mTempBloomTexture = NULL ;
-
- noiseTextureScale = 1.0f;
-
- /* Do nothing. Needs to be updated to use our current shader system, and to work with the move into llrender.
- std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight", XML_FILENAME));
- LL_DEBUGS("AppInit", "Shaders") << "Loading PostProcess Effects settings from " << pathName << LL_ENDL;
-
- llifstream effectsXML(pathName);
-
- if (effectsXML)
- {
- LLPointer<LLSDParser> parser = new LLSDXMLParser();
-
- parser->parse(effectsXML, mAllEffects, LLSDSerialize::SIZE_UNLIMITED);
- }
-
- if (!mAllEffects.has("default"))
- {
- LLSD & defaultEffect = (mAllEffects["default"] = LLSD::emptyMap());
-
- defaultEffect["enable_night_vision"] = LLSD::Boolean(false);
- defaultEffect["enable_bloom"] = LLSD::Boolean(false);
- defaultEffect["enable_color_filter"] = LLSD::Boolean(false);
-
- /// NVG Defaults
- defaultEffect["brightness_multiplier"] = 3.0;
- defaultEffect["noise_size"] = 25.0;
- defaultEffect["noise_strength"] = 0.4;
-
- // TODO BTest potentially add this to tweaks?
- noiseTextureScale = 1.0f;
-
- /// Bloom Defaults
- defaultEffect["extract_low"] = 0.95;
- defaultEffect["extract_high"] = 1.0;
- defaultEffect["bloom_width"] = 2.25;
- defaultEffect["bloom_strength"] = 1.5;
-
- /// Color Filter Defaults
- defaultEffect["brightness"] = 1.0;
- defaultEffect["contrast"] = 1.0;
- defaultEffect["saturation"] = 1.0;
-
- LLSD& contrastBase = (defaultEffect["contrast_base"] = LLSD::emptyArray());
- contrastBase.append(1.0);
- contrastBase.append(1.0);
- contrastBase.append(1.0);
- contrastBase.append(0.5);
- }
-
- setSelectedEffect("default");
- */
+ mSceneRenderTexture = NULL ;
+ mNoiseTexture = NULL ;
+ mTempBloomTexture = NULL ;
+
+ noiseTextureScale = 1.0f;
+
+ /* Do nothing. Needs to be updated to use our current shader system, and to work with the move into llrender.
+ std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight", XML_FILENAME));
+ LL_DEBUGS("AppInit", "Shaders") << "Loading PostProcess Effects settings from " << pathName << LL_ENDL;
+
+ llifstream effectsXML(pathName);
+
+ if (effectsXML)
+ {
+ LLPointer<LLSDParser> parser = new LLSDXMLParser();
+
+ parser->parse(effectsXML, mAllEffects, LLSDSerialize::SIZE_UNLIMITED);
+ }
+
+ if (!mAllEffects.has("default"))
+ {
+ LLSD & defaultEffect = (mAllEffects["default"] = LLSD::emptyMap());
+
+ defaultEffect["enable_night_vision"] = LLSD::Boolean(false);
+ defaultEffect["enable_bloom"] = LLSD::Boolean(false);
+ defaultEffect["enable_color_filter"] = LLSD::Boolean(false);
+
+ /// NVG Defaults
+ defaultEffect["brightness_multiplier"] = 3.0;
+ defaultEffect["noise_size"] = 25.0;
+ defaultEffect["noise_strength"] = 0.4;
+
+ // TODO BTest potentially add this to tweaks?
+ noiseTextureScale = 1.0f;
+
+ /// Bloom Defaults
+ defaultEffect["extract_low"] = 0.95;
+ defaultEffect["extract_high"] = 1.0;
+ defaultEffect["bloom_width"] = 2.25;
+ defaultEffect["bloom_strength"] = 1.5;
+
+ /// Color Filter Defaults
+ defaultEffect["brightness"] = 1.0;
+ defaultEffect["contrast"] = 1.0;
+ defaultEffect["saturation"] = 1.0;
+
+ LLSD& contrastBase = (defaultEffect["contrast_base"] = LLSD::emptyArray());
+ contrastBase.append(1.0);
+ contrastBase.append(1.0);
+ contrastBase.append(1.0);
+ contrastBase.append(0.5);
+ }
+
+ setSelectedEffect("default");
+ */
}
LLPostProcess::~LLPostProcess(void)
{
- invalidate() ;
+ invalidate() ;
}
// static
void LLPostProcess::initClass(void)
{
- //this will cause system to crash at second time login
- //if first time login fails due to network connection --- bao
- //***llassert_always(gPostProcess == NULL);
- //replaced by the following line:
- if(gPostProcess)
- return ;
-
-
- gPostProcess = new LLPostProcess();
+ //this will cause system to crash at second time login
+ //if first time login fails due to network connection --- bao
+ //***llassert_always(gPostProcess == NULL);
+ //replaced by the following line:
+ if(gPostProcess)
+ return ;
+
+
+ gPostProcess = new LLPostProcess();
}
// static
void LLPostProcess::cleanupClass()
{
- delete gPostProcess;
- gPostProcess = NULL;
+ delete gPostProcess;
+ gPostProcess = NULL;
}
void LLPostProcess::setSelectedEffect(std::string const & effectName)
{
- mSelectedEffectName = effectName;
- static_cast<LLSD &>(tweaks) = mAllEffects[effectName];
+ mSelectedEffectName = effectName;
+ static_cast<LLSD &>(tweaks) = mAllEffects[effectName];
}
void LLPostProcess::saveEffect(std::string const & effectName)
{
- /* Do nothing. Needs to be updated to use our current shader system, and to work with the move into llrender.
- mAllEffects[effectName] = tweaks;
+ /* Do nothing. Needs to be updated to use our current shader system, and to work with the move into llrender.
+ mAllEffects[effectName] = tweaks;
- std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight", XML_FILENAME));
- //LL_INFOS() << "Saving PostProcess Effects settings to " << pathName << LL_ENDL;
+ std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight", XML_FILENAME));
+ //LL_INFOS() << "Saving PostProcess Effects settings to " << pathName << LL_ENDL;
- llofstream effectsXML(pathName);
+ llofstream effectsXML(pathName);
- LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter();
+ LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter();
- formatter->format(mAllEffects, effectsXML);
- */
+ formatter->format(mAllEffects, effectsXML);
+ */
}
void LLPostProcess::invalidate()
{
- mSceneRenderTexture = NULL ;
- mNoiseTexture = NULL ;
- mTempBloomTexture = NULL ;
- initialized = FALSE ;
+ mSceneRenderTexture = NULL ;
+ mNoiseTexture = NULL ;
+ mTempBloomTexture = NULL ;
+ initialized = FALSE ;
}
void LLPostProcess::apply(unsigned int width, unsigned int height)
{
- if (!initialized || width != screenW || height != screenH){
- initialize(width, height);
- }
- if (shadersEnabled()){
- doEffects();
- }
+ if (!initialized || width != screenW || height != screenH){
+ initialize(width, height);
+ }
+ if (shadersEnabled()){
+ doEffects();
+ }
}
void LLPostProcess::initialize(unsigned int width, unsigned int height)
{
- screenW = width;
- screenH = height;
- createTexture(mSceneRenderTexture, screenW, screenH);
- initialized = true;
-
- checkError();
- createNightVisionShader();
- createBloomShader();
- createColorFilterShader();
- checkError();
+ screenW = width;
+ screenH = height;
+ createTexture(mSceneRenderTexture, screenW, screenH);
+ initialized = true;
+
+ checkError();
+ createNightVisionShader();
+ createBloomShader();
+ createColorFilterShader();
+ checkError();
}
inline bool LLPostProcess::shadersEnabled(void)
{
- return (tweaks.useColorFilter().asBoolean() ||
- tweaks.useNightVisionShader().asBoolean() ||
- tweaks.useBloomShader().asBoolean() );
+ return (tweaks.useColorFilter().asBoolean() ||
+ tweaks.useNightVisionShader().asBoolean() ||
+ tweaks.useBloomShader().asBoolean() );
}
void LLPostProcess::applyShaders(void)
{
- if (tweaks.useColorFilter()){
- applyColorFilterShader();
- checkError();
- }
- if (tweaks.useNightVisionShader()){
- /// If any of the above shaders have been called update the frame buffer;
- if (tweaks.useColorFilter())
- {
- U32 tex = mSceneRenderTexture->getTexName() ;
- copyFrameBuffer(tex, screenW, screenH);
- }
- applyNightVisionShader();
- checkError();
- }
- if (tweaks.useBloomShader()){
- /// If any of the above shaders have been called update the frame buffer;
- if (tweaks.useColorFilter().asBoolean() || tweaks.useNightVisionShader().asBoolean())
- {
- U32 tex = mSceneRenderTexture->getTexName() ;
- copyFrameBuffer(tex, screenW, screenH);
- }
- applyBloomShader();
- checkError();
- }
+ if (tweaks.useColorFilter()){
+ applyColorFilterShader();
+ checkError();
+ }
+ if (tweaks.useNightVisionShader()){
+ /// If any of the above shaders have been called update the frame buffer;
+ if (tweaks.useColorFilter())
+ {
+ U32 tex = mSceneRenderTexture->getTexName() ;
+ copyFrameBuffer(tex, screenW, screenH);
+ }
+ applyNightVisionShader();
+ checkError();
+ }
+ if (tweaks.useBloomShader()){
+ /// If any of the above shaders have been called update the frame buffer;
+ if (tweaks.useColorFilter().asBoolean() || tweaks.useNightVisionShader().asBoolean())
+ {
+ U32 tex = mSceneRenderTexture->getTexName() ;
+ copyFrameBuffer(tex, screenW, screenH);
+ }
+ applyBloomShader();
+ checkError();
+ }
}
void LLPostProcess::applyColorFilterShader(void)
-{
-
+{
+
}
void LLPostProcess::createColorFilterShader(void)
{
- /// Define uniform names
- colorFilterUniforms[sRenderTexture] = 0;
- colorFilterUniforms[sBrightness] = 0;
- colorFilterUniforms[sContrast] = 0;
- colorFilterUniforms[sContrastBase] = 0;
- colorFilterUniforms[sSaturation] = 0;
- colorFilterUniforms[sLumWeights] = 0;
+ /// Define uniform names
+ colorFilterUniforms[sRenderTexture] = 0;
+ colorFilterUniforms[sBrightness] = 0;
+ colorFilterUniforms[sContrast] = 0;
+ colorFilterUniforms[sContrastBase] = 0;
+ colorFilterUniforms[sSaturation] = 0;
+ colorFilterUniforms[sLumWeights] = 0;
}
void LLPostProcess::applyNightVisionShader(void)
-{
-
+{
+
}
void LLPostProcess::createNightVisionShader(void)
{
- /// Define uniform names
- nightVisionUniforms[sRenderTexture] = 0;
- nightVisionUniforms[sNoiseTexture] = 0;
- nightVisionUniforms[sBrightMult] = 0;
- nightVisionUniforms[sNoiseStrength] = 0;
- nightVisionUniforms[sLumWeights] = 0;
-
- createNoiseTexture(mNoiseTexture);
+ /// Define uniform names
+ nightVisionUniforms[sRenderTexture] = 0;
+ nightVisionUniforms[sNoiseTexture] = 0;
+ nightVisionUniforms[sBrightMult] = 0;
+ nightVisionUniforms[sNoiseStrength] = 0;
+ nightVisionUniforms[sLumWeights] = 0;
+
+ createNoiseTexture(mNoiseTexture);
}
void LLPostProcess::applyBloomShader(void)
@@ -268,69 +268,69 @@ void LLPostProcess::applyBloomShader(void)
void LLPostProcess::createBloomShader(void)
{
- createTexture(mTempBloomTexture, unsigned(screenW * 0.5), unsigned(screenH * 0.5));
-
- /// Create Bloom Extract Shader
- bloomExtractUniforms[sRenderTexture] = 0;
- bloomExtractUniforms[sExtractLow] = 0;
- bloomExtractUniforms[sExtractHigh] = 0;
- bloomExtractUniforms[sLumWeights] = 0;
-
- /// Create Bloom Blur Shader
- bloomBlurUniforms[sRenderTexture] = 0;
- bloomBlurUniforms[sBloomStrength] = 0;
- bloomBlurUniforms[sTexelSize] = 0;
- bloomBlurUniforms[sBlurDirection] = 0;
- bloomBlurUniforms[sBlurWidth] = 0;
+ createTexture(mTempBloomTexture, unsigned(screenW * 0.5), unsigned(screenH * 0.5));
+
+ /// Create Bloom Extract Shader
+ bloomExtractUniforms[sRenderTexture] = 0;
+ bloomExtractUniforms[sExtractLow] = 0;
+ bloomExtractUniforms[sExtractHigh] = 0;
+ bloomExtractUniforms[sLumWeights] = 0;
+
+ /// Create Bloom Blur Shader
+ bloomBlurUniforms[sRenderTexture] = 0;
+ bloomBlurUniforms[sBloomStrength] = 0;
+ bloomBlurUniforms[sTexelSize] = 0;
+ bloomBlurUniforms[sBlurDirection] = 0;
+ bloomBlurUniforms[sBlurWidth] = 0;
}
void LLPostProcess::getShaderUniforms(glslUniforms & uniforms, GLuint & prog)
{
- /// Find uniform locations and insert into map
- glslUniforms::iterator i;
- for (i = uniforms.begin(); i != uniforms.end(); ++i){
- i->second = glGetUniformLocation(prog, i->first.String().c_str());
- }
+ /// Find uniform locations and insert into map
+ glslUniforms::iterator i;
+ for (i = uniforms.begin(); i != uniforms.end(); ++i){
+ i->second = glGetUniformLocation(prog, i->first.String().c_str());
+ }
}
void LLPostProcess::doEffects(void)
{
- /// Save GL State
- glPushAttrib(GL_ALL_ATTRIB_BITS);
- glPushClientAttrib(GL_ALL_ATTRIB_BITS);
-
- /// Copy the screen buffer to the render texture
- {
- U32 tex = mSceneRenderTexture->getTexName() ;
- copyFrameBuffer(tex, screenW, screenH);
- }
-
- /// Clear the frame buffer.
- glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT);
-
- /// Change to an orthogonal view
- viewOrthogonal(screenW, screenH);
-
- checkError();
- applyShaders();
-
- LLGLSLShader::unbind();
- checkError();
-
- /// Change to a perspective view
- viewPerspective();
-
- /// Reset GL State
- glPopClientAttrib();
- glPopAttrib();
- checkError();
+ /// Save GL State
+ glPushAttrib(GL_ALL_ATTRIB_BITS);
+ glPushClientAttrib(GL_ALL_ATTRIB_BITS);
+
+ /// Copy the screen buffer to the render texture
+ {
+ U32 tex = mSceneRenderTexture->getTexName() ;
+ copyFrameBuffer(tex, screenW, screenH);
+ }
+
+ /// Clear the frame buffer.
+ glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ /// Change to an orthogonal view
+ viewOrthogonal(screenW, screenH);
+
+ checkError();
+ applyShaders();
+
+ LLGLSLShader::unbind();
+ checkError();
+
+ /// Change to a perspective view
+ viewPerspective();
+
+ /// Reset GL State
+ glPopClientAttrib();
+ glPopAttrib();
+ checkError();
}
void LLPostProcess::copyFrameBuffer(U32 & texture, unsigned int width, unsigned int height)
{
- gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, texture);
- glCopyTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA, 0, 0, width, height, 0);
+ gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, texture);
+ glCopyTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA, 0, 0, width, height, 0);
}
void LLPostProcess::drawOrthoQuad(unsigned int width, unsigned int height, QuadType type)
@@ -340,84 +340,84 @@ void LLPostProcess::drawOrthoQuad(unsigned int width, unsigned int height, QuadT
void LLPostProcess::viewOrthogonal(unsigned int width, unsigned int height)
{
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.pushMatrix();
- gGL.loadIdentity();
- gGL.ortho( 0.f, (GLdouble) width , (GLdouble) height , 0.f, -1.f, 1.f );
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.pushMatrix();
- gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+ gGL.ortho( 0.f, (GLdouble) width , (GLdouble) height , 0.f, -1.f, 1.f );
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
}
void LLPostProcess::viewPerspective(void)
{
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.popMatrix();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.popMatrix();
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.popMatrix();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.popMatrix();
}
void LLPostProcess::changeOrthogonal(unsigned int width, unsigned int height)
{
- viewPerspective();
- viewOrthogonal(width, height);
+ viewPerspective();
+ viewOrthogonal(width, height);
}
void LLPostProcess::createTexture(LLPointer<LLImageGL>& texture, unsigned int width, unsigned int height)
{
- std::vector<GLubyte> data(width * height * 4, 0) ;
-
- texture = new LLImageGL(FALSE) ;
- if(texture->createGLTexture())
- {
- gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, texture->getTexName());
- glTexImage2D(GL_TEXTURE_RECTANGLE, 0, 4, width, height, 0,
- GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
- gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
- gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
- }
+ std::vector<GLubyte> data(width * height * 4, 0) ;
+
+ texture = new LLImageGL(FALSE) ;
+ if(texture->createGLTexture())
+ {
+ gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, texture->getTexName());
+ glTexImage2D(GL_TEXTURE_RECTANGLE, 0, 4, width, height, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
+ gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
+ gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
+ }
}
void LLPostProcess::createNoiseTexture(LLPointer<LLImageGL>& texture)
-{
- std::vector<GLubyte> buffer(NOISE_SIZE * NOISE_SIZE);
- for (unsigned int i = 0; i < NOISE_SIZE; i++){
- for (unsigned int k = 0; k < NOISE_SIZE; k++){
- buffer[(i * NOISE_SIZE) + k] = (GLubyte)((double) rand() / ((double) RAND_MAX + 1.f) * 255.f);
- }
- }
-
- texture = new LLImageGL(FALSE) ;
- if(texture->createGLTexture())
- {
- gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, texture->getTexName());
- LLImageGL::setManualImage(GL_TEXTURE_2D, 0, GL_LUMINANCE, NOISE_SIZE, NOISE_SIZE, GL_LUMINANCE, GL_UNSIGNED_BYTE, &buffer[0]);
- gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
- gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_WRAP);
- }
+{
+ std::vector<GLubyte> buffer(NOISE_SIZE * NOISE_SIZE);
+ for (unsigned int i = 0; i < NOISE_SIZE; i++){
+ for (unsigned int k = 0; k < NOISE_SIZE; k++){
+ buffer[(i * NOISE_SIZE) + k] = (GLubyte)((double) rand() / ((double) RAND_MAX + 1.f) * 255.f);
+ }
+ }
+
+ texture = new LLImageGL(FALSE) ;
+ if(texture->createGLTexture())
+ {
+ gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, texture->getTexName());
+ LLImageGL::setManualImage(GL_TEXTURE_2D, 0, GL_LUMINANCE, NOISE_SIZE, NOISE_SIZE, GL_LUMINANCE, GL_UNSIGNED_BYTE, &buffer[0]);
+ gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
+ gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_WRAP);
+ }
}
bool LLPostProcess::checkError(void)
{
- GLenum glErr;
+ GLenum glErr;
bool retCode = false;
glErr = glGetError();
while (glErr != GL_NO_ERROR)
{
- // shaderErrorLog << (const char *) gluErrorString(glErr) << std::endl;
- char const * err_str_raw = (const char *) gluErrorString(glErr);
-
- if(err_str_raw == NULL)
- {
- std::ostringstream err_builder;
- err_builder << "unknown error number " << glErr;
- mShaderErrorString = err_builder.str();
- }
- else
- {
- mShaderErrorString = err_str_raw;
- }
+ // shaderErrorLog << (const char *) gluErrorString(glErr) << std::endl;
+ char const * err_str_raw = (const char *) gluErrorString(glErr);
+
+ if(err_str_raw == NULL)
+ {
+ std::ostringstream err_builder;
+ err_builder << "unknown error number " << glErr;
+ mShaderErrorString = err_builder.str();
+ }
+ else
+ {
+ mShaderErrorString = err_str_raw;
+ }
retCode = true;
glErr = glGetError();
@@ -446,8 +446,8 @@ void LLPostProcess::checkShaderError(GLuint shader)
return;
}
glGetProgramInfoLog(shader, infologLength, &charsWritten, infoLog);
- // shaderErrorLog << (char *) infoLog << std::endl;
- mShaderErrorString = (char *) infoLog;
+ // shaderErrorLog << (char *) infoLog << std::endl;
+ mShaderErrorString = (char *) infoLog;
free(infoLog);
}
checkError(); // Check for OpenGL errors
diff --git a/indra/llrender/llpostprocess.h b/indra/llrender/llpostprocess.h
index bdfc632831..b5b7549efb 100644
--- a/indra/llrender/llpostprocess.h
+++ b/indra/llrender/llpostprocess.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file llpostprocess.h
* @brief LLPostProcess class definition
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -33,232 +33,232 @@
#include "llglheaders.h"
#include "llstaticstringtable.h"
-class LLPostProcess
+class LLPostProcess
{
public:
- typedef enum _QuadType {
- QUAD_NORMAL,
- QUAD_NOISE,
- QUAD_BLOOM_EXTRACT,
- QUAD_BLOOM_COMBINE
- } QuadType;
+ typedef enum _QuadType {
+ QUAD_NORMAL,
+ QUAD_NOISE,
+ QUAD_BLOOM_EXTRACT,
+ QUAD_BLOOM_COMBINE
+ } QuadType;
+
+ /// GLSL Shader Encapsulation Struct
+ typedef LLStaticStringTable<GLuint> glslUniforms;
- /// GLSL Shader Encapsulation Struct
- typedef LLStaticStringTable<GLuint> glslUniforms;
+ struct PostProcessTweaks : public LLSD {
+ inline PostProcessTweaks() : LLSD(LLSD::emptyMap())
+ {
+ }
- struct PostProcessTweaks : public LLSD {
- inline PostProcessTweaks() : LLSD(LLSD::emptyMap())
- {
- }
+ inline LLSD & brightMult() {
+ return (*this)["brightness_multiplier"];
+ }
- inline LLSD & brightMult() {
- return (*this)["brightness_multiplier"];
- }
+ inline LLSD & noiseStrength() {
+ return (*this)["noise_strength"];
+ }
- inline LLSD & noiseStrength() {
- return (*this)["noise_strength"];
- }
+ inline LLSD & noiseSize() {
+ return (*this)["noise_size"];
+ }
- inline LLSD & noiseSize() {
- return (*this)["noise_size"];
- }
+ inline LLSD & extractLow() {
+ return (*this)["extract_low"];
+ }
- inline LLSD & extractLow() {
- return (*this)["extract_low"];
- }
+ inline LLSD & extractHigh() {
+ return (*this)["extract_high"];
+ }
- inline LLSD & extractHigh() {
- return (*this)["extract_high"];
- }
+ inline LLSD & bloomWidth() {
+ return (*this)["bloom_width"];
+ }
- inline LLSD & bloomWidth() {
- return (*this)["bloom_width"];
- }
+ inline LLSD & bloomStrength() {
+ return (*this)["bloom_strength"];
+ }
- inline LLSD & bloomStrength() {
- return (*this)["bloom_strength"];
- }
+ inline LLSD & brightness() {
+ return (*this)["brightness"];
+ }
- inline LLSD & brightness() {
- return (*this)["brightness"];
- }
+ inline LLSD & contrast() {
+ return (*this)["contrast"];
+ }
- inline LLSD & contrast() {
- return (*this)["contrast"];
- }
+ inline LLSD & contrastBaseR() {
+ return (*this)["contrast_base"][0];
+ }
- inline LLSD & contrastBaseR() {
- return (*this)["contrast_base"][0];
- }
+ inline LLSD & contrastBaseG() {
+ return (*this)["contrast_base"][1];
+ }
- inline LLSD & contrastBaseG() {
- return (*this)["contrast_base"][1];
- }
+ inline LLSD & contrastBaseB() {
+ return (*this)["contrast_base"][2];
+ }
- inline LLSD & contrastBaseB() {
- return (*this)["contrast_base"][2];
- }
+ inline LLSD & contrastBaseIntensity() {
+ return (*this)["contrast_base"][3];
+ }
- inline LLSD & contrastBaseIntensity() {
- return (*this)["contrast_base"][3];
- }
+ inline LLSD & saturation() {
+ return (*this)["saturation"];
+ }
- inline LLSD & saturation() {
- return (*this)["saturation"];
- }
+ inline LLSD & useNightVisionShader() {
+ return (*this)["enable_night_vision"];
+ }
- inline LLSD & useNightVisionShader() {
- return (*this)["enable_night_vision"];
- }
+ inline LLSD & useBloomShader() {
+ return (*this)["enable_bloom"];
+ }
- inline LLSD & useBloomShader() {
- return (*this)["enable_bloom"];
- }
+ inline LLSD & useColorFilter() {
+ return (*this)["enable_color_filter"];
+ }
- inline LLSD & useColorFilter() {
- return (*this)["enable_color_filter"];
- }
+ inline F32 getBrightMult() const {
+ return F32((*this)["brightness_multiplier"].asReal());
+ }
- inline F32 getBrightMult() const {
- return F32((*this)["brightness_multiplier"].asReal());
- }
+ inline F32 getNoiseStrength() const {
+ return F32((*this)["noise_strength"].asReal());
+ }
- inline F32 getNoiseStrength() const {
- return F32((*this)["noise_strength"].asReal());
- }
+ inline F32 getNoiseSize() const {
+ return F32((*this)["noise_size"].asReal());
+ }
- inline F32 getNoiseSize() const {
- return F32((*this)["noise_size"].asReal());
- }
+ inline F32 getExtractLow() const {
+ return F32((*this)["extract_low"].asReal());
+ }
- inline F32 getExtractLow() const {
- return F32((*this)["extract_low"].asReal());
- }
+ inline F32 getExtractHigh() const {
+ return F32((*this)["extract_high"].asReal());
+ }
- inline F32 getExtractHigh() const {
- return F32((*this)["extract_high"].asReal());
- }
+ inline F32 getBloomWidth() const {
+ return F32((*this)["bloom_width"].asReal());
+ }
- inline F32 getBloomWidth() const {
- return F32((*this)["bloom_width"].asReal());
- }
+ inline F32 getBloomStrength() const {
+ return F32((*this)["bloom_strength"].asReal());
+ }
- inline F32 getBloomStrength() const {
- return F32((*this)["bloom_strength"].asReal());
- }
+ inline F32 getBrightness() const {
+ return F32((*this)["brightness"].asReal());
+ }
- inline F32 getBrightness() const {
- return F32((*this)["brightness"].asReal());
- }
+ inline F32 getContrast() const {
+ return F32((*this)["contrast"].asReal());
+ }
- inline F32 getContrast() const {
- return F32((*this)["contrast"].asReal());
- }
+ inline F32 getContrastBaseR() const {
+ return F32((*this)["contrast_base"][0].asReal());
+ }
- inline F32 getContrastBaseR() const {
- return F32((*this)["contrast_base"][0].asReal());
- }
+ inline F32 getContrastBaseG() const {
+ return F32((*this)["contrast_base"][1].asReal());
+ }
- inline F32 getContrastBaseG() const {
- return F32((*this)["contrast_base"][1].asReal());
- }
+ inline F32 getContrastBaseB() const {
+ return F32((*this)["contrast_base"][2].asReal());
+ }
- inline F32 getContrastBaseB() const {
- return F32((*this)["contrast_base"][2].asReal());
- }
+ inline F32 getContrastBaseIntensity() const {
+ return F32((*this)["contrast_base"][3].asReal());
+ }
- inline F32 getContrastBaseIntensity() const {
- return F32((*this)["contrast_base"][3].asReal());
- }
+ inline F32 getSaturation() const {
+ return F32((*this)["saturation"].asReal());
+ }
- inline F32 getSaturation() const {
- return F32((*this)["saturation"].asReal());
- }
+ };
- };
-
- bool initialized;
- PostProcessTweaks tweaks;
+ bool initialized;
+ PostProcessTweaks tweaks;
- // the map of all availible effects
- LLSD mAllEffects;
+ // the map of all availible effects
+ LLSD mAllEffects;
private:
- LLPointer<LLImageGL> mSceneRenderTexture ;
- LLPointer<LLImageGL> mNoiseTexture ;
- LLPointer<LLImageGL> mTempBloomTexture ;
+ LLPointer<LLImageGL> mSceneRenderTexture ;
+ LLPointer<LLImageGL> mNoiseTexture ;
+ LLPointer<LLImageGL> mTempBloomTexture ;
public:
- LLPostProcess(void);
+ LLPostProcess(void);
- ~LLPostProcess(void);
+ ~LLPostProcess(void);
- void apply(unsigned int width, unsigned int height);
- void invalidate() ;
+ void apply(unsigned int width, unsigned int height);
+ void invalidate() ;
- /// Perform global initialization for this class.
- static void initClass(void);
+ /// Perform global initialization for this class.
+ static void initClass(void);
- // Cleanup of global data that's only inited once per class.
- static void cleanupClass();
+ // Cleanup of global data that's only inited once per class.
+ static void cleanupClass();
- void setSelectedEffect(std::string const & effectName);
+ void setSelectedEffect(std::string const & effectName);
- inline std::string const & getSelectedEffect(void) const {
- return mSelectedEffectName;
- }
+ inline std::string const & getSelectedEffect(void) const {
+ return mSelectedEffectName;
+ }
- void saveEffect(std::string const & effectName);
+ void saveEffect(std::string const & effectName);
private:
- /// read in from file
- std::string mShaderErrorString;
- unsigned int screenW;
- unsigned int screenH;
-
- float noiseTextureScale;
-
- /// Shader Uniforms
- glslUniforms nightVisionUniforms;
- glslUniforms bloomExtractUniforms;
- glslUniforms bloomBlurUniforms;
- glslUniforms colorFilterUniforms;
-
- // the name of currently selected effect in mAllEffects
- // invariant: tweaks == mAllEffects[mSelectedEffectName]
- std::string mSelectedEffectName;
-
- /// General functions
- void initialize(unsigned int width, unsigned int height);
- void doEffects(void);
- void applyShaders(void);
- bool shadersEnabled(void);
-
- /// Night Vision Functions
- void createNightVisionShader(void);
- void applyNightVisionShader(void);
-
- /// Bloom Functions
- void createBloomShader(void);
- void applyBloomShader(void);
-
- /// Color Filter Functions
- void createColorFilterShader(void);
- void applyColorFilterShader(void);
-
- /// OpenGL Helper Functions
- void getShaderUniforms(glslUniforms & uniforms, GLuint & prog);
- void createTexture(LLPointer<LLImageGL>& texture, unsigned int width, unsigned int height);
- void copyFrameBuffer(U32 & texture, unsigned int width, unsigned int height);
- void createNoiseTexture(LLPointer<LLImageGL>& texture);
- bool checkError(void);
- void checkShaderError(GLuint shader);
- void drawOrthoQuad(unsigned int width, unsigned int height, QuadType type);
- void viewOrthogonal(unsigned int width, unsigned int height);
- void changeOrthogonal(unsigned int width, unsigned int height);
- void viewPerspective(void);
+ /// read in from file
+ std::string mShaderErrorString;
+ unsigned int screenW;
+ unsigned int screenH;
+
+ float noiseTextureScale;
+
+ /// Shader Uniforms
+ glslUniforms nightVisionUniforms;
+ glslUniforms bloomExtractUniforms;
+ glslUniforms bloomBlurUniforms;
+ glslUniforms colorFilterUniforms;
+
+ // the name of currently selected effect in mAllEffects
+ // invariant: tweaks == mAllEffects[mSelectedEffectName]
+ std::string mSelectedEffectName;
+
+ /// General functions
+ void initialize(unsigned int width, unsigned int height);
+ void doEffects(void);
+ void applyShaders(void);
+ bool shadersEnabled(void);
+
+ /// Night Vision Functions
+ void createNightVisionShader(void);
+ void applyNightVisionShader(void);
+
+ /// Bloom Functions
+ void createBloomShader(void);
+ void applyBloomShader(void);
+
+ /// Color Filter Functions
+ void createColorFilterShader(void);
+ void applyColorFilterShader(void);
+
+ /// OpenGL Helper Functions
+ void getShaderUniforms(glslUniforms & uniforms, GLuint & prog);
+ void createTexture(LLPointer<LLImageGL>& texture, unsigned int width, unsigned int height);
+ void copyFrameBuffer(U32 & texture, unsigned int width, unsigned int height);
+ void createNoiseTexture(LLPointer<LLImageGL>& texture);
+ bool checkError(void);
+ void checkShaderError(GLuint shader);
+ void drawOrthoQuad(unsigned int width, unsigned int height, QuadType type);
+ void viewOrthogonal(unsigned int width, unsigned int height);
+ void changeOrthogonal(unsigned int width, unsigned int height);
+ void viewPerspective(void);
};
extern LLPostProcess * gPostProcess;
diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h
index 716b52354d..ebdc9e751d 100644
--- a/indra/llrender/llrender.h
+++ b/indra/llrender/llrender.h
@@ -1,30 +1,30 @@
-/**
+/**
* @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.
+ * 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=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -57,89 +57,89 @@ class LLTexture ;
constexpr U32 LL_NUM_TEXTURE_LAYERS = 32;
constexpr U32 LL_NUM_LIGHT_UNITS = 8;
-class LLTexUnit
+class LLTexUnit
{
- friend class LLRender;
+ friend class LLRender;
public:
- static U32 sWhiteTexture;
-
- typedef enum
- {
- TT_TEXTURE = 0, // Standard 2D Texture
- TT_RECT_TEXTURE, // Non power of 2 texture
- TT_CUBE_MAP, // 6-sided cube map texture
- TT_CUBE_MAP_ARRAY, // Array of cube maps
- TT_MULTISAMPLE_TEXTURE, // see GL_ARB_texture_multisample
+ static U32 sWhiteTexture;
+
+ typedef enum
+ {
+ TT_TEXTURE = 0, // Standard 2D Texture
+ TT_RECT_TEXTURE, // Non power of 2 texture
+ TT_CUBE_MAP, // 6-sided cube map texture
+ TT_CUBE_MAP_ARRAY, // Array of cube maps
+ TT_MULTISAMPLE_TEXTURE, // see GL_ARB_texture_multisample
TT_TEXTURE_3D, // standard 3D Texture
- TT_NONE, // No texture type is currently enabled
- } eTextureType;
-
- typedef enum
- {
- TAM_WRAP = 0, // Standard 2D Texture
- TAM_MIRROR, // Non power of 2 texture
- TAM_CLAMP // No texture type is currently enabled
- } eTextureAddressMode;
-
- typedef enum
- { // Note: If mipmapping or anisotropic are not enabled or supported it should fall back gracefully
- TFO_POINT = 0, // Equal to: min=point, mag=point, mip=none.
- TFO_BILINEAR, // Equal to: min=linear, mag=linear, mip=point.
- TFO_TRILINEAR, // Equal to: min=linear, mag=linear, mip=linear.
- TFO_ANISOTROPIC // Equal to: min=anisotropic, max=anisotropic, mip=linear.
- } eTextureFilterOptions;
-
- typedef enum
- {
- TMG_NONE = 0, // Mipmaps are not automatically generated for this texture.
- TMG_AUTO, // Mipmaps are automatically generated for this texture.
- TMG_MANUAL // Mipmaps are manually generated for this texture.
- } eTextureMipGeneration;
-
- 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) )
- } 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;
+ TT_NONE, // No texture type is currently enabled
+ } eTextureType;
+
+ typedef enum
+ {
+ TAM_WRAP = 0, // Standard 2D Texture
+ TAM_MIRROR, // Non power of 2 texture
+ TAM_CLAMP // No texture type is currently enabled
+ } eTextureAddressMode;
+
+ typedef enum
+ { // Note: If mipmapping or anisotropic are not enabled or supported it should fall back gracefully
+ TFO_POINT = 0, // Equal to: min=point, mag=point, mip=none.
+ TFO_BILINEAR, // Equal to: min=linear, mag=linear, mip=point.
+ TFO_TRILINEAR, // Equal to: min=linear, mag=linear, mip=linear.
+ TFO_ANISOTROPIC // Equal to: min=anisotropic, max=anisotropic, mip=linear.
+ } eTextureFilterOptions;
+
+ typedef enum
+ {
+ TMG_NONE = 0, // Mipmaps are not automatically generated for this texture.
+ TMG_AUTO, // Mipmaps are automatically generated for this texture.
+ TMG_MANUAL // Mipmaps are manually generated for this texture.
+ } eTextureMipGeneration;
+
+ 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) )
+ } 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;
typedef enum
{
@@ -147,77 +147,77 @@ public:
TCS_SRGB
} eTextureColorSpace;
- LLTexUnit(S32 index = -1);
+ LLTexUnit(S32 index = -1);
+
+ // Refreshes renderer state of the texture unit to the cached values
+ // Needed when the render context has changed and invalidated the current state
+ void refreshState(void);
- // Refreshes renderer state of the texture unit to the cached values
- // Needed when the render context has changed and invalidated the current state
- void refreshState(void);
+ // returns the index of this texture unit
+ S32 getIndex(void) const { return mIndex; }
- // returns the index of this texture unit
- S32 getIndex(void) const { return mIndex; }
+ // Sets this tex unit to be the currently active one
+ void activate(void);
- // Sets this tex unit to be the currently active one
- void activate(void);
+ // Enables this texture unit for the given texture type
+ // (automatically disables any previously enabled texture type)
+ void enable(eTextureType type);
- // Enables this texture unit for the given texture type
- // (automatically disables any previously enabled texture type)
- void enable(eTextureType type);
+ // Disables the current texture unit
+ void disable(void);
- // Disables the current texture unit
- void disable(void);
-
- // Binds the LLImageGL to this texture unit
- // (automatically enables the unit for the LLImageGL's texture type)
- bool bind(LLImageGL* texture, bool for_rendering = false, bool forceBind = false, S32 usename = 0);
+ // Binds the LLImageGL to this texture unit
+ // (automatically enables the unit for the LLImageGL's texture type)
+ bool bind(LLImageGL* texture, bool for_rendering = false, bool forceBind = false, S32 usename = 0);
bool bind(LLTexture* texture, bool for_rendering = false, bool forceBind = false);
// bind implementation for inner loops
// makes the following assumptions:
- // - No need for gGL.flush()
+ // - No need for gGL.flush()
// - texture is not null
// - gl_tex->getTexName() is not zero
// - This texture is not being bound redundantly
// - USE_SRGB_DECODE is disabled
// - mTexOptionsDirty is false
- // -
+ // -
void bindFast(LLTexture* texture);
- // Binds a cubemap to this texture unit
- // (automatically enables the texture unit for cubemaps)
- bool bind(LLCubeMap* cubeMap);
+ // Binds a cubemap to this texture unit
+ // (automatically enables the texture unit for cubemaps)
+ bool bind(LLCubeMap* cubeMap);
- // Binds a render target to this texture unit
- // (automatically enables the texture unit for the RT's texture type)
- bool bind(LLRenderTarget * renderTarget, bool bindDepth = false);
+ // Binds a render target to this texture unit
+ // (automatically enables the texture unit for the RT's texture type)
+ bool bind(LLRenderTarget * renderTarget, bool bindDepth = false);
- // Manually binds a texture to the texture unit
- // (automatically enables the tex unit for the given texture type)
- bool bindManual(eTextureType type, U32 texture, bool hasMips = false);
-
- // Unbinds the currently bound texture of the given type
- // (only if there's a texture of the given type currently bound)
- void unbind(eTextureType type);
+ // Manually binds a texture to the texture unit
+ // (automatically enables the tex unit for the given texture type)
+ bool bindManual(eTextureType type, U32 texture, bool hasMips = false);
+
+ // Unbinds the currently bound texture of the given type
+ // (only if there's a texture of the given type currently bound)
+ void unbind(eTextureType type);
// Fast but unsafe version of unbind
void unbindFast(eTextureType type);
- // Sets the addressing mode used to sample the texture
- // Warning: this stays set for the bound texture forever,
- // make sure you want to permanently change the address mode for the bound texture.
- void setTextureAddressMode(eTextureAddressMode mode);
+ // Sets the addressing mode used to sample the texture
+ // Warning: this stays set for the bound texture forever,
+ // make sure you want to permanently change the address mode for the bound texture.
+ void setTextureAddressMode(eTextureAddressMode mode);
- // Sets the filtering options used to sample the texture
- // Warning: this stays set for the bound texture forever,
- // make sure you want to permanently change the filtering for the bound texture.
- void setTextureFilteringOption(LLTexUnit::eTextureFilterOptions option);
+ // Sets the filtering options used to sample the texture
+ // Warning: this stays set for the bound texture forever,
+ // make sure you want to permanently change the filtering for the bound texture.
+ void setTextureFilteringOption(LLTexUnit::eTextureFilterOptions option);
- static U32 getInternalType(eTextureType type);
+ static U32 getInternalType(eTextureType type);
- U32 getCurrTexture(void) { return mCurrTexture; }
+ U32 getCurrTexture(void) { return mCurrTexture; }
- eTextureType getCurrType(void) { return mCurrTexType; }
+ eTextureType getCurrType(void) { return mCurrTexType; }
- void setHasMipMaps(bool hasMips) { mHasMipMaps = hasMips; }
+ void setHasMipMaps(bool hasMips) { mHasMipMaps = hasMips; }
void setTextureColorSpace(eTextureColorSpace space);
@@ -226,293 +226,293 @@ public:
protected:
friend class LLRender;
- S32 mIndex;
- U32 mCurrTexture;
- eTextureType mCurrTexType;
+ S32 mIndex;
+ U32 mCurrTexture;
+ eTextureType mCurrTexType;
eTextureColorSpace mTexColorSpace;
- S32 mCurrColorScale;
- S32 mCurrAlphaScale;
- bool mHasMipMaps;
-
- void debugTextureUnit(void);
- void setColorScale(S32 scale);
- void setAlphaScale(S32 scale);
- GLint getTextureSource(eTextureBlendSrc src);
- GLint getTextureSourceType(eTextureBlendSrc src, bool isAlpha = false);
+ S32 mCurrColorScale;
+ S32 mCurrAlphaScale;
+ bool mHasMipMaps;
+
+ void debugTextureUnit(void);
+ void setColorScale(S32 scale);
+ void setAlphaScale(S32 scale);
+ GLint getTextureSource(eTextureBlendSrc src);
+ GLint getTextureSourceType(eTextureBlendSrc src, bool isAlpha = false);
};
class LLLightState
{
public:
- LLLightState(S32 index = -1);
+ LLLightState(S32 index = -1);
- void enable();
- void disable();
- void setDiffuse(const LLColor4& diffuse);
+ void enable();
+ void disable();
+ void setDiffuse(const LLColor4& diffuse);
void setDiffuseB(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);
+ 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);
void setSunPrimary(bool v);
void setSize(F32 size);
void setFalloff(F32 falloff);
protected:
- friend class LLRender;
+ friend class LLRender;
- S32 mIndex;
- bool mEnabled;
- LLColor4 mDiffuse;
+ S32 mIndex;
+ bool mEnabled;
+ LLColor4 mDiffuse;
LLColor4 mDiffuseB;
bool mSunIsPrimary;
- LLColor4 mAmbient;
- LLColor4 mSpecular;
- LLVector4 mPosition;
- LLVector3 mSpotDirection;
+ LLColor4 mAmbient;
+ LLColor4 mSpecular;
+ LLVector4 mPosition;
+ LLVector3 mSpotDirection;
- F32 mConstantAtten;
- F32 mLinearAtten;
- F32 mQuadraticAtten;
+ F32 mConstantAtten;
+ F32 mLinearAtten;
+ F32 mQuadraticAtten;
- F32 mSpotExponent;
- F32 mSpotCutoff;
+ F32 mSpotExponent;
+ F32 mSpotCutoff;
F32 mSize = 0.f;
F32 mFalloff = 0.f;
};
class LLRender
{
- friend class LLTexUnit;
+ friend class LLTexUnit;
public:
- enum eTexIndex : U8
- {
- DIFFUSE_MAP = 0,
+ enum eTexIndex : U8
+ {
+ DIFFUSE_MAP = 0,
ALTERNATE_DIFFUSE_MAP = 1,
- NORMAL_MAP = 1,
- SPECULAR_MAP = 2,
- NUM_TEXTURE_CHANNELS = 3,
- };
-
- enum eVolumeTexIndex : U8
- {
- LIGHT_TEX = 0,
- SCULPT_TEX,
- NUM_VOLUME_TEXTURE_CHANNELS,
- };
-
- enum eGeomModes : U8
+ NORMAL_MAP = 1,
+ SPECULAR_MAP = 2,
+ NUM_TEXTURE_CHANNELS = 3,
+ };
+
+ enum eVolumeTexIndex : U8
+ {
+ LIGHT_TEX = 0,
+ SCULPT_TEX,
+ NUM_VOLUME_TEXTURE_CHANNELS,
+ };
+
+ enum eGeomModes : U8
+ {
+ TRIANGLES = 0,
+ TRIANGLE_STRIP,
+ TRIANGLE_FAN,
+ POINTS,
+ LINES,
+ LINE_STRIP,
+ QUADS,
+ LINE_LOOP,
+ NUM_MODES
+ };
+
+ enum eCompareFunc : U8
{
- TRIANGLES = 0,
- TRIANGLE_STRIP,
- TRIANGLE_FAN,
- POINTS,
- LINES,
- LINE_STRIP,
- QUADS,
- LINE_LOOP,
- NUM_MODES
- };
-
- enum eCompareFunc : U8
- {
- CF_NEVER = 0,
- CF_ALWAYS,
- CF_LESS,
- CF_LESS_EQUAL,
- CF_EQUAL,
- CF_NOT_EQUAL,
- CF_GREATER_EQUAL,
- CF_GREATER,
- CF_DEFAULT
- };
-
- enum eBlendType : U8
- {
- BT_ALPHA = 0,
- BT_ADD,
- BT_ADD_WITH_ALPHA, // Additive blend modulated by the fragment's alpha.
- BT_MULT,
- BT_MULT_ALPHA,
- BT_MULT_X2,
- BT_REPLACE
- };
-
- // WARNING: this MUST match the LL_PART_BF enum in LLPartData, so set values explicitly in case someone
+ CF_NEVER = 0,
+ CF_ALWAYS,
+ CF_LESS,
+ CF_LESS_EQUAL,
+ CF_EQUAL,
+ CF_NOT_EQUAL,
+ CF_GREATER_EQUAL,
+ CF_GREATER,
+ CF_DEFAULT
+ };
+
+ enum eBlendType : U8
+ {
+ BT_ALPHA = 0,
+ BT_ADD,
+ BT_ADD_WITH_ALPHA, // Additive blend modulated by the fragment's alpha.
+ BT_MULT,
+ BT_MULT_ALPHA,
+ BT_MULT_X2,
+ BT_REPLACE
+ };
+
+ // WARNING: this MUST match the LL_PART_BF enum in LLPartData, so set values explicitly in case someone
// decides to add more or reorder them
- enum eBlendFactor : U8
- {
- BF_ONE = 0,
- BF_ZERO = 1,
- BF_DEST_COLOR = 2,
- BF_SOURCE_COLOR = 3,
- BF_ONE_MINUS_DEST_COLOR = 4,
- BF_ONE_MINUS_SOURCE_COLOR = 5,
- BF_DEST_ALPHA = 6,
- BF_SOURCE_ALPHA = 7,
- BF_ONE_MINUS_DEST_ALPHA = 8,
- BF_ONE_MINUS_SOURCE_ALPHA = 9,
- BF_UNDEF
- };
-
- enum eMatrixMode : U8
- {
- MM_MODELVIEW = 0,
- MM_PROJECTION,
- MM_TEXTURE0,
- MM_TEXTURE1,
- MM_TEXTURE2,
- MM_TEXTURE3,
- NUM_MATRIX_MODES,
- MM_TEXTURE
- };
-
- LLRender();
- ~LLRender();
+ enum eBlendFactor : U8
+ {
+ BF_ONE = 0,
+ BF_ZERO = 1,
+ BF_DEST_COLOR = 2,
+ BF_SOURCE_COLOR = 3,
+ BF_ONE_MINUS_DEST_COLOR = 4,
+ BF_ONE_MINUS_SOURCE_COLOR = 5,
+ BF_DEST_ALPHA = 6,
+ BF_SOURCE_ALPHA = 7,
+ BF_ONE_MINUS_DEST_ALPHA = 8,
+ BF_ONE_MINUS_SOURCE_ALPHA = 9,
+ BF_UNDEF
+ };
+
+ enum eMatrixMode : U8
+ {
+ MM_MODELVIEW = 0,
+ MM_PROJECTION,
+ MM_TEXTURE0,
+ MM_TEXTURE1,
+ MM_TEXTURE2,
+ MM_TEXTURE3,
+ NUM_MATRIX_MODES,
+ MM_TEXTURE
+ };
+
+ LLRender();
+ ~LLRender();
bool init(bool needs_vertex_buffer);
void initVertexBuffer();
void resetVertexBuffer();
- void shutdown();
-
- // Refreshes renderer state to the cached values
- // Needed when the render context has changed and invalidated the current state
- void refreshState(void);
-
- void translatef(const GLfloat& x, const GLfloat& y, const GLfloat& z);
- void scalef(const GLfloat& x, const GLfloat& y, const GLfloat& z);
- void rotatef(const GLfloat& a, const GLfloat& x, const GLfloat& y, const GLfloat& z);
- void ortho(F32 left, F32 right, F32 bottom, F32 top, F32 zNear, F32 zFar);
-
- void pushMatrix();
- void popMatrix();
- void loadMatrix(const GLfloat* m);
- void loadIdentity();
- void multMatrix(const GLfloat* m);
- void matrixMode(eMatrixMode mode);
- eMatrixMode getMatrixMode();
-
- const glh::matrix4f& getModelviewMatrix();
- const glh::matrix4f& getProjectionMatrix();
-
- void syncMatrices();
- void syncLightState();
-
- void translateUI(F32 x, F32 y, F32 z);
- void scaleUI(F32 x, F32 y, F32 z);
- void pushUIMatrix();
- void popUIMatrix();
- void loadUIIdentity();
- LLVector3 getUITranslation();
- LLVector3 getUIScale();
-
- 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 diffuseColor3f(F32 r, F32 g, F32 b);
- void diffuseColor3fv(const F32* c);
- void diffuseColor4f(F32 r, F32 g, F32 b, F32 a);
- void diffuseColor4fv(const F32* c);
- void diffuseColor4ubv(const U8* c);
- void diffuseColor4ub(U8 r, U8 g, U8 b, U8 a);
-
- void vertexBatchPreTransformed(LLVector3* verts, S32 vert_count);
- void vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, S32 vert_count);
- void vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, LLColor4U*, S32 vert_count);
-
- void setColorMask(bool writeColor, bool writeAlpha);
- void setColorMask(bool writeColorR, bool writeColorG, bool writeColorB, bool writeAlpha);
- void setSceneBlendType(eBlendType type);
-
- // applies blend func to both color and alpha
- void blendFunc(eBlendFactor sfactor, eBlendFactor dfactor);
- // applies separate blend functions to color and alpha
- void blendFunc(eBlendFactor color_sfactor, eBlendFactor color_dfactor,
- eBlendFactor alpha_sfactor, eBlendFactor alpha_dfactor);
-
- LLLightState* getLight(U32 index);
- void setAmbientLightColor(const LLColor4& color);
-
- LLTexUnit* getTexUnit(U32 index);
-
- U32 getCurrentTexUnitIndex(void) const { return mCurrTextureUnitIndex; }
-
- bool verifyTexUnitActive(U32 unitToVerify);
-
- void debugTexUnits(void);
-
- void clearErrors();
-
- struct Vertex
- {
- GLfloat v[3];
- GLubyte c[4];
- GLfloat uv[2];
- };
+ void shutdown();
+
+ // Refreshes renderer state to the cached values
+ // Needed when the render context has changed and invalidated the current state
+ void refreshState(void);
+
+ void translatef(const GLfloat& x, const GLfloat& y, const GLfloat& z);
+ void scalef(const GLfloat& x, const GLfloat& y, const GLfloat& z);
+ void rotatef(const GLfloat& a, const GLfloat& x, const GLfloat& y, const GLfloat& z);
+ void ortho(F32 left, F32 right, F32 bottom, F32 top, F32 zNear, F32 zFar);
+
+ void pushMatrix();
+ void popMatrix();
+ void loadMatrix(const GLfloat* m);
+ void loadIdentity();
+ void multMatrix(const GLfloat* m);
+ void matrixMode(eMatrixMode mode);
+ eMatrixMode getMatrixMode();
+
+ const glh::matrix4f& getModelviewMatrix();
+ const glh::matrix4f& getProjectionMatrix();
+
+ void syncMatrices();
+ void syncLightState();
+
+ void translateUI(F32 x, F32 y, F32 z);
+ void scaleUI(F32 x, F32 y, F32 z);
+ void pushUIMatrix();
+ void popUIMatrix();
+ void loadUIIdentity();
+ LLVector3 getUITranslation();
+ LLVector3 getUIScale();
+
+ 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 diffuseColor3f(F32 r, F32 g, F32 b);
+ void diffuseColor3fv(const F32* c);
+ void diffuseColor4f(F32 r, F32 g, F32 b, F32 a);
+ void diffuseColor4fv(const F32* c);
+ void diffuseColor4ubv(const U8* c);
+ void diffuseColor4ub(U8 r, U8 g, U8 b, U8 a);
+
+ void vertexBatchPreTransformed(LLVector3* verts, S32 vert_count);
+ void vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, S32 vert_count);
+ void vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, LLColor4U*, S32 vert_count);
+
+ void setColorMask(bool writeColor, bool writeAlpha);
+ void setColorMask(bool writeColorR, bool writeColorG, bool writeColorB, bool writeAlpha);
+ void setSceneBlendType(eBlendType type);
+
+ // applies blend func to both color and alpha
+ void blendFunc(eBlendFactor sfactor, eBlendFactor dfactor);
+ // applies separate blend functions to color and alpha
+ void blendFunc(eBlendFactor color_sfactor, eBlendFactor color_dfactor,
+ eBlendFactor alpha_sfactor, eBlendFactor alpha_dfactor);
+
+ LLLightState* getLight(U32 index);
+ void setAmbientLightColor(const LLColor4& color);
+
+ LLTexUnit* getTexUnit(U32 index);
+
+ U32 getCurrentTexUnitIndex(void) const { return mCurrTextureUnitIndex; }
+
+ bool verifyTexUnitActive(U32 unitToVerify);
+
+ void debugTexUnits(void);
+
+ void clearErrors();
+
+ struct Vertex
+ {
+ GLfloat v[3];
+ GLubyte c[4];
+ GLfloat uv[2];
+ };
public:
- static U32 sUICalls;
- static U32 sUIVerts;
- static bool sGLCoreProfile;
- static bool sNsightDebugSupport;
- static LLVector2 sUIGLScaleFactor;
+ static U32 sUICalls;
+ static U32 sUIVerts;
+ static bool sGLCoreProfile;
+ static bool sNsightDebugSupport;
+ static LLVector2 sUIGLScaleFactor;
private:
- friend class LLLightState;
-
- eMatrixMode mMatrixMode;
- U32 mMatIdx[NUM_MATRIX_MODES];
- U32 mMatHash[NUM_MATRIX_MODES];
- glh::matrix4f mMatrix[NUM_MATRIX_MODES][LL_MATRIX_STACK_DEPTH];
- U32 mCurMatHash[NUM_MATRIX_MODES];
- U32 mLightHash;
- LLColor4 mAmbientLightColor;
-
- bool mDirty;
- U32 mQuadCycle;
- U32 mCount;
- U32 mMode;
- U32 mCurrTextureUnitIndex;
- bool mCurrColorMask[4];
-
- LLPointer<LLVertexBuffer> mBuffer;
- LLStrider<LLVector3> mVerticesp;
- LLStrider<LLVector2> mTexcoordsp;
- LLStrider<LLColor4U> mColorsp;
- std::array<LLTexUnit, LL_NUM_TEXTURE_LAYERS> mTexUnits;
- LLTexUnit mDummyTexUnit;
- std::array<LLLightState, LL_NUM_LIGHT_UNITS> mLightState;
-
- eBlendFactor mCurrBlendColorSFactor;
- eBlendFactor mCurrBlendColorDFactor;
- eBlendFactor mCurrBlendAlphaSFactor;
- eBlendFactor mCurrBlendAlphaDFactor;
-
- std::vector<LLVector3> mUIOffset;
- std::vector<LLVector3> mUIScale;
+ friend class LLLightState;
+
+ eMatrixMode mMatrixMode;
+ U32 mMatIdx[NUM_MATRIX_MODES];
+ U32 mMatHash[NUM_MATRIX_MODES];
+ glh::matrix4f mMatrix[NUM_MATRIX_MODES][LL_MATRIX_STACK_DEPTH];
+ U32 mCurMatHash[NUM_MATRIX_MODES];
+ U32 mLightHash;
+ LLColor4 mAmbientLightColor;
+
+ bool mDirty;
+ U32 mQuadCycle;
+ U32 mCount;
+ U32 mMode;
+ U32 mCurrTextureUnitIndex;
+ bool mCurrColorMask[4];
+
+ LLPointer<LLVertexBuffer> mBuffer;
+ LLStrider<LLVector3> mVerticesp;
+ LLStrider<LLVector2> mTexcoordsp;
+ LLStrider<LLColor4U> mColorsp;
+ std::array<LLTexUnit, LL_NUM_TEXTURE_LAYERS> mTexUnits;
+ LLTexUnit mDummyTexUnit;
+ std::array<LLLightState, LL_NUM_LIGHT_UNITS> mLightState;
+
+ eBlendFactor mCurrBlendColorSFactor;
+ eBlendFactor mCurrBlendColorDFactor;
+ eBlendFactor mCurrBlendAlphaSFactor;
+ eBlendFactor mCurrBlendAlphaDFactor;
+
+ std::vector<LLVector3> mUIOffset;
+ std::vector<LLVector3> mUIScale;
};
@@ -526,12 +526,12 @@ extern F32 gGLInverseDeltaModelView[16];
extern thread_local LLRender gGL;
-// This rotation matrix moves the default OpenGL reference frame
+// This rotation matrix moves the default OpenGL reference frame
// (-Z at, Y up) to Cory's favorite reference frame (X at, Z up)
-const F32 OGL_TO_CFR_ROTATION[16] = { 0.f, 0.f, -1.f, 0.f, // -Z becomes X
- -1.f, 0.f, 0.f, 0.f, // -X becomes Y
- 0.f, 1.f, 0.f, 0.f, // Y becomes Z
- 0.f, 0.f, 0.f, 1.f };
+const F32 OGL_TO_CFR_ROTATION[16] = { 0.f, 0.f, -1.f, 0.f, // -Z becomes X
+ -1.f, 0.f, 0.f, 0.f, // -X becomes Y
+ 0.f, 1.f, 0.f, 0.f, // Y becomes Z
+ 0.f, 0.f, 0.f, 1.f };
glh::matrix4f copy_matrix(F32* src);
glh::matrix4f get_current_modelview();
diff --git a/indra/llrender/llrender2dutils.cpp b/indra/llrender/llrender2dutils.cpp
index 52869406d2..e1742f84a1 100644
--- a/indra/llrender/llrender2dutils.cpp
+++ b/indra/llrender/llrender2dutils.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llrender2dutils.cpp
* @brief GL function implementations for immediate-mode gl drawing.
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -53,9 +53,9 @@ const LLColor4 UI_VERTEX_COLOR(1.f, 1.f, 1.f, 1.f);
BOOL ui_point_in_rect(S32 x, S32 y, S32 left, S32 top, S32 right, S32 bottom)
{
- if (x < left || right < x) return FALSE;
- if (y < bottom || top < y) return FALSE;
- return TRUE;
+ if (x < left || right < x) return FALSE;
+ if (y < bottom || top < y) return FALSE;
+ return TRUE;
}
@@ -63,97 +63,97 @@ BOOL ui_point_in_rect(S32 x, S32 y, S32 left, S32 top, S32 right, S32 bottom)
// orthographic projection, etc.
void gl_state_for_2d(S32 width, S32 height)
{
- stop_glerror();
- F32 window_width = (F32) width;//gViewerWindow->getWindowWidth();
- F32 window_height = (F32) height;//gViewerWindow->getWindowHeight();
-
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.loadIdentity();
- gGL.ortho(0.0f, llmax(window_width, 1.f), 0.0f, llmax(window_height,1.f), -1.0f, 1.0f);
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.loadIdentity();
- stop_glerror();
+ stop_glerror();
+ F32 window_width = (F32) width;//gViewerWindow->getWindowWidth();
+ F32 window_height = (F32) height;//gViewerWindow->getWindowHeight();
+
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.loadIdentity();
+ gGL.ortho(0.0f, llmax(window_width, 1.f), 0.0f, llmax(window_height,1.f), -1.0f, 1.0f);
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.loadIdentity();
+ stop_glerror();
}
void gl_draw_x(const LLRect& rect, const LLColor4& color)
{
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.color4fv( color.mV );
+ gGL.color4fv( color.mV );
- gGL.begin( LLRender::LINES );
- gGL.vertex2i( rect.mLeft, rect.mTop );
- gGL.vertex2i( rect.mRight, rect.mBottom );
- gGL.vertex2i( rect.mLeft, rect.mBottom );
- gGL.vertex2i( rect.mRight, rect.mTop );
- gGL.end();
+ gGL.begin( LLRender::LINES );
+ gGL.vertex2i( rect.mLeft, rect.mTop );
+ gGL.vertex2i( rect.mRight, rect.mBottom );
+ gGL.vertex2i( rect.mLeft, rect.mBottom );
+ gGL.vertex2i( rect.mRight, rect.mTop );
+ gGL.end();
}
void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, S32 pixel_offset, BOOL filled)
{
- gGL.color4fv(color.mV);
- gl_rect_2d_offset_local(left, top, right, bottom, pixel_offset, filled);
+ gGL.color4fv(color.mV);
+ gl_rect_2d_offset_local(left, top, right, bottom, pixel_offset, filled);
}
void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, S32 pixel_offset, BOOL filled)
{
- gGL.pushUIMatrix();
- left += LLFontGL::sCurOrigin.mX;
- right += LLFontGL::sCurOrigin.mX;
- bottom += LLFontGL::sCurOrigin.mY;
- top += LLFontGL::sCurOrigin.mY;
-
- gGL.loadUIIdentity();
- gl_rect_2d(llfloor((F32)left * LLRender::sUIGLScaleFactor.mV[VX]) - pixel_offset,
- llfloor((F32)top * LLRender::sUIGLScaleFactor.mV[VY]) + pixel_offset,
- llfloor((F32)right * LLRender::sUIGLScaleFactor.mV[VX]) + pixel_offset,
- llfloor((F32)bottom * LLRender::sUIGLScaleFactor.mV[VY]) - pixel_offset,
- filled);
- gGL.popUIMatrix();
+ gGL.pushUIMatrix();
+ left += LLFontGL::sCurOrigin.mX;
+ right += LLFontGL::sCurOrigin.mX;
+ bottom += LLFontGL::sCurOrigin.mY;
+ top += LLFontGL::sCurOrigin.mY;
+
+ gGL.loadUIIdentity();
+ gl_rect_2d(llfloor((F32)left * LLRender::sUIGLScaleFactor.mV[VX]) - pixel_offset,
+ llfloor((F32)top * LLRender::sUIGLScaleFactor.mV[VY]) + pixel_offset,
+ llfloor((F32)right * LLRender::sUIGLScaleFactor.mV[VX]) + pixel_offset,
+ llfloor((F32)bottom * LLRender::sUIGLScaleFactor.mV[VY]) - pixel_offset,
+ filled);
+ gGL.popUIMatrix();
}
void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, BOOL filled )
{
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- // Counterclockwise quad will face the viewer
- if( filled )
- {
- gGL.begin( LLRender::QUADS );
- gGL.vertex2i(left, top);
- gGL.vertex2i(left, bottom);
- gGL.vertex2i(right, bottom);
- gGL.vertex2i(right, top);
- gGL.end();
- }
- else
- {
- top--;
- right--;
- gGL.begin( LLRender::LINE_STRIP );
- gGL.vertex2i(left, top);
- gGL.vertex2i(left, bottom);
- gGL.vertex2i(right, bottom);
- gGL.vertex2i(right, top);
- gGL.vertex2i(left, top);
- gGL.end();
- }
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ // Counterclockwise quad will face the viewer
+ if( filled )
+ {
+ gGL.begin( LLRender::QUADS );
+ gGL.vertex2i(left, top);
+ gGL.vertex2i(left, bottom);
+ gGL.vertex2i(right, bottom);
+ gGL.vertex2i(right, top);
+ gGL.end();
+ }
+ else
+ {
+ top--;
+ right--;
+ gGL.begin( LLRender::LINE_STRIP );
+ gGL.vertex2i(left, top);
+ gGL.vertex2i(left, bottom);
+ gGL.vertex2i(right, bottom);
+ gGL.vertex2i(right, top);
+ gGL.vertex2i(left, top);
+ gGL.end();
+ }
}
void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, BOOL filled )
{
- gGL.color4fv( color.mV );
- gl_rect_2d( left, top, right, bottom, filled );
+ gGL.color4fv( color.mV );
+ gl_rect_2d( left, top, right, bottom, filled );
}
void gl_rect_2d( const LLRect& rect, const LLColor4& color, BOOL filled )
{
- gGL.color4fv( color.mV );
- gl_rect_2d( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, filled );
+ gGL.color4fv( color.mV );
+ gl_rect_2d( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, filled );
}
// Given a rectangle on the screen, draws a drop shadow _outside_
@@ -161,715 +161,715 @@ void gl_rect_2d( const LLRect& rect, const LLColor4& color, BOOL filled )
// and along the bottom it has height "lines".
void gl_drop_shadow(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &start_color, S32 lines)
{
- stop_glerror();
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- // HACK: Overlap with the rectangle by a single pixel.
- right--;
- bottom++;
- lines++;
-
- LLColor4 end_color = start_color;
- end_color.mV[VALPHA] = 0.f;
-
- gGL.begin(LLRender::QUADS);
-
- // Right edge, CCW faces screen
- gGL.color4fv(start_color.mV);
- gGL.vertex2i(right, top-lines);
- gGL.vertex2i(right, bottom);
- gGL.color4fv(end_color.mV);
- gGL.vertex2i(right+lines, bottom);
- gGL.vertex2i(right+lines, top-lines);
-
- // Bottom edge, CCW faces screen
- gGL.color4fv(start_color.mV);
- gGL.vertex2i(right, bottom);
- gGL.vertex2i(left+lines, bottom);
- gGL.color4fv(end_color.mV);
- gGL.vertex2i(left+lines, bottom-lines);
- gGL.vertex2i(right, bottom-lines);
-
- // bottom left Corner
- gGL.color4fv(start_color.mV);
- gGL.vertex2i(left+lines, bottom);
- gGL.color4fv(end_color.mV);
- gGL.vertex2i(left, bottom);
- // make the bottom left corner not sharp
- gGL.vertex2i(left+1, bottom-lines+1);
- gGL.vertex2i(left+lines, bottom-lines);
-
- // bottom right corner
- gGL.color4fv(start_color.mV);
- gGL.vertex2i(right, bottom);
- gGL.color4fv(end_color.mV);
- gGL.vertex2i(right, bottom-lines);
- // make the rightmost corner not sharp
- gGL.vertex2i(right+lines-1, bottom-lines+1);
- gGL.vertex2i(right+lines, bottom);
-
- // top right corner
- gGL.color4fv(start_color.mV);
- gGL.vertex2i( right, top-lines );
- gGL.color4fv(end_color.mV);
- gGL.vertex2i( right+lines, top-lines );
- // make the corner not sharp
- gGL.vertex2i( right+lines-1, top-1 );
- gGL.vertex2i( right, top );
-
- gGL.end();
- stop_glerror();
+ stop_glerror();
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ // HACK: Overlap with the rectangle by a single pixel.
+ right--;
+ bottom++;
+ lines++;
+
+ LLColor4 end_color = start_color;
+ end_color.mV[VALPHA] = 0.f;
+
+ gGL.begin(LLRender::QUADS);
+
+ // Right edge, CCW faces screen
+ gGL.color4fv(start_color.mV);
+ gGL.vertex2i(right, top-lines);
+ gGL.vertex2i(right, bottom);
+ gGL.color4fv(end_color.mV);
+ gGL.vertex2i(right+lines, bottom);
+ gGL.vertex2i(right+lines, top-lines);
+
+ // Bottom edge, CCW faces screen
+ gGL.color4fv(start_color.mV);
+ gGL.vertex2i(right, bottom);
+ gGL.vertex2i(left+lines, bottom);
+ gGL.color4fv(end_color.mV);
+ gGL.vertex2i(left+lines, bottom-lines);
+ gGL.vertex2i(right, bottom-lines);
+
+ // bottom left Corner
+ gGL.color4fv(start_color.mV);
+ gGL.vertex2i(left+lines, bottom);
+ gGL.color4fv(end_color.mV);
+ gGL.vertex2i(left, bottom);
+ // make the bottom left corner not sharp
+ gGL.vertex2i(left+1, bottom-lines+1);
+ gGL.vertex2i(left+lines, bottom-lines);
+
+ // bottom right corner
+ gGL.color4fv(start_color.mV);
+ gGL.vertex2i(right, bottom);
+ gGL.color4fv(end_color.mV);
+ gGL.vertex2i(right, bottom-lines);
+ // make the rightmost corner not sharp
+ gGL.vertex2i(right+lines-1, bottom-lines+1);
+ gGL.vertex2i(right+lines, bottom);
+
+ // top right corner
+ gGL.color4fv(start_color.mV);
+ gGL.vertex2i( right, top-lines );
+ gGL.color4fv(end_color.mV);
+ gGL.vertex2i( right+lines, top-lines );
+ // make the corner not sharp
+ gGL.vertex2i( right+lines-1, top-1 );
+ gGL.vertex2i( right, top );
+
+ gGL.end();
+ stop_glerror();
}
void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2 )
{
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- gGL.begin(LLRender::LINES);
- gGL.vertex2i(x1, y1);
- gGL.vertex2i(x2, y2);
- gGL.end();
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ gGL.begin(LLRender::LINES);
+ gGL.vertex2i(x1, y1);
+ gGL.vertex2i(x2, y2);
+ gGL.end();
}
void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2, const LLColor4 &color )
{
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.color4fv( color.mV );
+ gGL.color4fv( color.mV );
- gGL.begin(LLRender::LINES);
- gGL.vertex2i(x1, y1);
- gGL.vertex2i(x2, y2);
- gGL.end();
+ gGL.begin(LLRender::LINES);
+ gGL.vertex2i(x1, y1);
+ gGL.vertex2i(x2, y2);
+ gGL.end();
}
void gl_triangle_2d(S32 x1, S32 y1, S32 x2, S32 y2, S32 x3, S32 y3, const LLColor4& color, BOOL filled)
{
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- gGL.color4fv(color.mV);
-
- if (filled)
- {
- gGL.begin(LLRender::TRIANGLES);
- }
- else
- {
- gGL.begin(LLRender::LINE_LOOP);
- }
- gGL.vertex2i(x1, y1);
- gGL.vertex2i(x2, y2);
- gGL.vertex2i(x3, y3);
- gGL.end();
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ gGL.color4fv(color.mV);
+
+ if (filled)
+ {
+ gGL.begin(LLRender::TRIANGLES);
+ }
+ else
+ {
+ gGL.begin(LLRender::LINE_LOOP);
+ }
+ gGL.vertex2i(x1, y1);
+ gGL.vertex2i(x2, y2);
+ gGL.vertex2i(x3, y3);
+ gGL.end();
}
void gl_corners_2d(S32 left, S32 top, S32 right, S32 bottom, S32 length, F32 max_frac)
{
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- length = llmin((S32)(max_frac*(right - left)), length);
- length = llmin((S32)(max_frac*(top - bottom)), length);
- gGL.begin(LLRender::LINES);
- gGL.vertex2i(left, top);
- gGL.vertex2i(left + length, top);
-
- gGL.vertex2i(left, top);
- gGL.vertex2i(left, top - length);
-
- gGL.vertex2i(left, bottom);
- gGL.vertex2i(left + length, bottom);
-
- gGL.vertex2i(left, bottom);
- gGL.vertex2i(left, bottom + length);
-
- gGL.vertex2i(right, top);
- gGL.vertex2i(right - length, top);
-
- gGL.vertex2i(right, top);
- gGL.vertex2i(right, top - length);
-
- gGL.vertex2i(right, bottom);
- gGL.vertex2i(right - length, bottom);
-
- gGL.vertex2i(right, bottom);
- gGL.vertex2i(right, bottom + length);
- gGL.end();
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ length = llmin((S32)(max_frac*(right - left)), length);
+ length = llmin((S32)(max_frac*(top - bottom)), length);
+ gGL.begin(LLRender::LINES);
+ gGL.vertex2i(left, top);
+ gGL.vertex2i(left + length, top);
+
+ gGL.vertex2i(left, top);
+ gGL.vertex2i(left, top - length);
+
+ gGL.vertex2i(left, bottom);
+ gGL.vertex2i(left + length, bottom);
+
+ gGL.vertex2i(left, bottom);
+ gGL.vertex2i(left, bottom + length);
+
+ gGL.vertex2i(right, top);
+ gGL.vertex2i(right - length, top);
+
+ gGL.vertex2i(right, top);
+ gGL.vertex2i(right, top - length);
+
+ gGL.vertex2i(right, bottom);
+ gGL.vertex2i(right - length, bottom);
+
+ gGL.vertex2i(right, bottom);
+ gGL.vertex2i(right, bottom + length);
+ gGL.end();
}
void gl_draw_image( S32 x, S32 y, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect )
{
- if (NULL == image)
- {
- LL_WARNS() << "image == NULL; aborting function" << LL_ENDL;
- return;
- }
- gl_draw_scaled_rotated_image( x, y, image->getWidth(0), image->getHeight(0), 0.f, image, color, uv_rect );
+ if (NULL == image)
+ {
+ LL_WARNS() << "image == NULL; aborting function" << LL_ENDL;
+ return;
+ }
+ gl_draw_scaled_rotated_image( x, y, image->getWidth(0), image->getHeight(0), 0.f, image, color, uv_rect );
}
void gl_draw_scaled_target(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* target, const LLColor4& color, const LLRectf& uv_rect)
{
- gl_draw_scaled_rotated_image(x, y, width, height, 0.f, NULL, color, uv_rect, target);
+ gl_draw_scaled_rotated_image(x, y, width, height, 0.f, NULL, color, uv_rect, target);
}
void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect)
{
- if (NULL == image)
- {
- LL_WARNS() << "image == NULL; aborting function" << LL_ENDL;
- return;
- }
- gl_draw_scaled_rotated_image( x, y, width, height, 0.f, image, color, uv_rect );
+ if (NULL == image)
+ {
+ LL_WARNS() << "image == NULL; aborting function" << LL_ENDL;
+ return;
+ }
+ gl_draw_scaled_rotated_image( x, y, width, height, 0.f, image, color, uv_rect );
}
void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_rect, bool scale_inner)
{
- if (NULL == image)
- {
- LL_WARNS() << "image == NULL; aborting function" << LL_ENDL;
- return;
- }
-
- // scale screen size of borders down
- F32 border_width_fraction = (F32)border_width / (F32)image->getWidth(0);
- F32 border_height_fraction = (F32)border_height / (F32)image->getHeight(0);
-
- LLRectf scale_rect(border_width_fraction, 1.f - border_height_fraction, 1.f - border_width_fraction, border_height_fraction);
- gl_draw_scaled_image_with_border(x, y, width, height, image, color, solid_color, uv_rect, scale_rect, scale_inner);
+ if (NULL == image)
+ {
+ LL_WARNS() << "image == NULL; aborting function" << LL_ENDL;
+ return;
+ }
+
+ // scale screen size of borders down
+ F32 border_width_fraction = (F32)border_width / (F32)image->getWidth(0);
+ F32 border_height_fraction = (F32)border_height / (F32)image->getHeight(0);
+
+ LLRectf scale_rect(border_width_fraction, 1.f - border_height_fraction, 1.f - border_width_fraction, border_height_fraction);
+ gl_draw_scaled_image_with_border(x, y, width, height, image, color, solid_color, uv_rect, scale_rect, scale_inner);
}
void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_outer_rect, const LLRectf& center_rect, bool scale_inner)
{
- stop_glerror();
-
- if (NULL == image)
- {
- LL_WARNS() << "image == NULL; aborting function" << LL_ENDL;
- return;
- }
-
- if (solid_color)
- {
- gSolidColorProgram.bind();
- }
-
- if (center_rect.mLeft == 0.f
- && center_rect.mRight == 1.f
- && center_rect.mBottom == 0.f
- && center_rect.mTop == 1.f)
- {
- gl_draw_scaled_image(x, y, width, height, image, color, uv_outer_rect);
- }
- else
- {
- // add in offset of current image to current UI translation
- const LLVector3 ui_scale = gGL.getUIScale();
- const LLVector3 ui_translation = (gGL.getUITranslation() + LLVector3(x, y, 0.f)).scaledVec(ui_scale);
-
- F32 uv_width = uv_outer_rect.getWidth();
- F32 uv_height = uv_outer_rect.getHeight();
-
- // shrink scaling region to be proportional to clipped image region
- LLRectf uv_center_rect( uv_outer_rect.mLeft + (center_rect.mLeft * uv_width),
- uv_outer_rect.mBottom + (center_rect.mTop * uv_height),
- uv_outer_rect.mLeft + (center_rect.mRight * uv_width),
- uv_outer_rect.mBottom + (center_rect.mBottom * uv_height));
-
- F32 image_width = image->getWidth(0);
- F32 image_height = image->getHeight(0);
-
- S32 image_natural_width = ll_round(image_width * uv_width);
- S32 image_natural_height = ll_round(image_height * uv_height);
-
- LLRectf draw_center_rect( uv_center_rect.mLeft * image_width,
- uv_center_rect.mTop * image_height,
- uv_center_rect.mRight * image_width,
- uv_center_rect.mBottom * image_height);
-
- if (scale_inner)
- {
- // scale center region of image to drawn region
- draw_center_rect.mRight += width - image_natural_width;
- draw_center_rect.mTop += height - image_natural_height;
-
- const F32 border_shrink_width = llmax(0.f, draw_center_rect.mLeft - draw_center_rect.mRight);
- const F32 border_shrink_height = llmax(0.f, draw_center_rect.mBottom - draw_center_rect.mTop);
-
- const F32 shrink_width_ratio = center_rect.getWidth() == 1.f ? 0.f : border_shrink_width / ((F32)image_natural_width * (1.f - center_rect.getWidth()));
- const F32 shrink_height_ratio = center_rect.getHeight() == 1.f ? 0.f : border_shrink_height / ((F32)image_natural_height * (1.f - center_rect.getHeight()));
-
- const F32 border_shrink_scale = 1.f - llmax(shrink_width_ratio, shrink_height_ratio);
- draw_center_rect.mLeft *= border_shrink_scale;
- draw_center_rect.mTop = lerp((F32)height, (F32)draw_center_rect.mTop, border_shrink_scale);
- draw_center_rect.mRight = lerp((F32)width, (F32)draw_center_rect.mRight, border_shrink_scale);
- draw_center_rect.mBottom *= border_shrink_scale;
- }
- else
- {
- // keep center region of image at fixed scale, but in same relative position
- F32 scale_factor = llmin((F32)width / draw_center_rect.getWidth(), (F32)height / draw_center_rect.getHeight(), 1.f);
- F32 scaled_width = draw_center_rect.getWidth() * scale_factor;
- F32 scaled_height = draw_center_rect.getHeight() * scale_factor;
- draw_center_rect.setCenterAndSize(uv_center_rect.getCenterX() * width, uv_center_rect.getCenterY() * height, scaled_width, scaled_height);
- }
-
- draw_center_rect.mLeft = ll_round(ui_translation.mV[VX] + (F32)draw_center_rect.mLeft * ui_scale.mV[VX]);
- draw_center_rect.mTop = ll_round(ui_translation.mV[VY] + (F32)draw_center_rect.mTop * ui_scale.mV[VY]);
- draw_center_rect.mRight = ll_round(ui_translation.mV[VX] + (F32)draw_center_rect.mRight * ui_scale.mV[VX]);
- draw_center_rect.mBottom = ll_round(ui_translation.mV[VY] + (F32)draw_center_rect.mBottom * ui_scale.mV[VY]);
-
- LLRectf draw_outer_rect(ui_translation.mV[VX],
- ui_translation.mV[VY] + height * ui_scale.mV[VY],
- ui_translation.mV[VX] + width * ui_scale.mV[VX],
- ui_translation.mV[VY]);
-
- LLGLSUIDefault gls_ui;
-
- gGL.getTexUnit(0)->bind(image, true);
-
- gGL.color4fv(color.mV);
-
- const S32 NUM_VERTICES = 9 * 4; // 9 quads
- LLVector2 uv[NUM_VERTICES];
- LLVector3 pos[NUM_VERTICES];
-
- S32 index = 0;
-
- gGL.begin(LLRender::QUADS);
- {
- // draw bottom left
- uv[index] = LLVector2(uv_outer_rect.mLeft, uv_outer_rect.mBottom);
- pos[index] = LLVector3(draw_outer_rect.mLeft, draw_outer_rect.mBottom, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mBottom);
- pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mBottom, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
- pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mBottom);
- pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mBottom, 0.f);
- index++;
-
- // draw bottom middle
- uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mBottom);
- pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mBottom, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mBottom);
- pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mBottom, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
- pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
- pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
- index++;
-
- // draw bottom right
- uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mBottom);
- pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mBottom, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_outer_rect.mRight, uv_outer_rect.mBottom);
- pos[index] = LLVector3(draw_outer_rect.mRight, draw_outer_rect.mBottom, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mBottom);
- pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mBottom, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
- pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
- index++;
-
- // draw left
- uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mBottom);
- pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mBottom, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
- pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
- pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mTop);
- pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mTop, 0.f);
- index++;
-
- // draw middle
- uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
- pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
- pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
- pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
- pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
- index++;
-
- // draw right
- uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
- pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mBottom);
- pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mBottom, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mTop);
- pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mTop, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
- pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
- index++;
-
- // draw top left
- uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mTop);
- pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mTop, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
- pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mTop);
- pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mTop, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_outer_rect.mLeft, uv_outer_rect.mTop);
- pos[index] = LLVector3(draw_outer_rect.mLeft, draw_outer_rect.mTop, 0.f);
- index++;
-
- // draw top middle
- uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
- pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
- pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mTop);
- pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mTop, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mTop);
- pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mTop, 0.f);
- index++;
-
- // draw top right
- uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
- pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mTop);
- pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mTop, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_outer_rect.mRight, uv_outer_rect.mTop);
- pos[index] = LLVector3(draw_outer_rect.mRight, draw_outer_rect.mTop, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mTop);
- pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mTop, 0.f);
- index++;
-
- gGL.vertexBatchPreTransformed(pos, uv, NUM_VERTICES);
- }
- gGL.end();
- }
-
- if (solid_color)
- {
- gUIProgram.bind();
- }
+ stop_glerror();
+
+ if (NULL == image)
+ {
+ LL_WARNS() << "image == NULL; aborting function" << LL_ENDL;
+ return;
+ }
+
+ if (solid_color)
+ {
+ gSolidColorProgram.bind();
+ }
+
+ if (center_rect.mLeft == 0.f
+ && center_rect.mRight == 1.f
+ && center_rect.mBottom == 0.f
+ && center_rect.mTop == 1.f)
+ {
+ gl_draw_scaled_image(x, y, width, height, image, color, uv_outer_rect);
+ }
+ else
+ {
+ // add in offset of current image to current UI translation
+ const LLVector3 ui_scale = gGL.getUIScale();
+ const LLVector3 ui_translation = (gGL.getUITranslation() + LLVector3(x, y, 0.f)).scaledVec(ui_scale);
+
+ F32 uv_width = uv_outer_rect.getWidth();
+ F32 uv_height = uv_outer_rect.getHeight();
+
+ // shrink scaling region to be proportional to clipped image region
+ LLRectf uv_center_rect( uv_outer_rect.mLeft + (center_rect.mLeft * uv_width),
+ uv_outer_rect.mBottom + (center_rect.mTop * uv_height),
+ uv_outer_rect.mLeft + (center_rect.mRight * uv_width),
+ uv_outer_rect.mBottom + (center_rect.mBottom * uv_height));
+
+ F32 image_width = image->getWidth(0);
+ F32 image_height = image->getHeight(0);
+
+ S32 image_natural_width = ll_round(image_width * uv_width);
+ S32 image_natural_height = ll_round(image_height * uv_height);
+
+ LLRectf draw_center_rect( uv_center_rect.mLeft * image_width,
+ uv_center_rect.mTop * image_height,
+ uv_center_rect.mRight * image_width,
+ uv_center_rect.mBottom * image_height);
+
+ if (scale_inner)
+ {
+ // scale center region of image to drawn region
+ draw_center_rect.mRight += width - image_natural_width;
+ draw_center_rect.mTop += height - image_natural_height;
+
+ const F32 border_shrink_width = llmax(0.f, draw_center_rect.mLeft - draw_center_rect.mRight);
+ const F32 border_shrink_height = llmax(0.f, draw_center_rect.mBottom - draw_center_rect.mTop);
+
+ const F32 shrink_width_ratio = center_rect.getWidth() == 1.f ? 0.f : border_shrink_width / ((F32)image_natural_width * (1.f - center_rect.getWidth()));
+ const F32 shrink_height_ratio = center_rect.getHeight() == 1.f ? 0.f : border_shrink_height / ((F32)image_natural_height * (1.f - center_rect.getHeight()));
+
+ const F32 border_shrink_scale = 1.f - llmax(shrink_width_ratio, shrink_height_ratio);
+ draw_center_rect.mLeft *= border_shrink_scale;
+ draw_center_rect.mTop = lerp((F32)height, (F32)draw_center_rect.mTop, border_shrink_scale);
+ draw_center_rect.mRight = lerp((F32)width, (F32)draw_center_rect.mRight, border_shrink_scale);
+ draw_center_rect.mBottom *= border_shrink_scale;
+ }
+ else
+ {
+ // keep center region of image at fixed scale, but in same relative position
+ F32 scale_factor = llmin((F32)width / draw_center_rect.getWidth(), (F32)height / draw_center_rect.getHeight(), 1.f);
+ F32 scaled_width = draw_center_rect.getWidth() * scale_factor;
+ F32 scaled_height = draw_center_rect.getHeight() * scale_factor;
+ draw_center_rect.setCenterAndSize(uv_center_rect.getCenterX() * width, uv_center_rect.getCenterY() * height, scaled_width, scaled_height);
+ }
+
+ draw_center_rect.mLeft = ll_round(ui_translation.mV[VX] + (F32)draw_center_rect.mLeft * ui_scale.mV[VX]);
+ draw_center_rect.mTop = ll_round(ui_translation.mV[VY] + (F32)draw_center_rect.mTop * ui_scale.mV[VY]);
+ draw_center_rect.mRight = ll_round(ui_translation.mV[VX] + (F32)draw_center_rect.mRight * ui_scale.mV[VX]);
+ draw_center_rect.mBottom = ll_round(ui_translation.mV[VY] + (F32)draw_center_rect.mBottom * ui_scale.mV[VY]);
+
+ LLRectf draw_outer_rect(ui_translation.mV[VX],
+ ui_translation.mV[VY] + height * ui_scale.mV[VY],
+ ui_translation.mV[VX] + width * ui_scale.mV[VX],
+ ui_translation.mV[VY]);
+
+ LLGLSUIDefault gls_ui;
+
+ gGL.getTexUnit(0)->bind(image, true);
+
+ gGL.color4fv(color.mV);
+
+ const S32 NUM_VERTICES = 9 * 4; // 9 quads
+ LLVector2 uv[NUM_VERTICES];
+ LLVector3 pos[NUM_VERTICES];
+
+ S32 index = 0;
+
+ gGL.begin(LLRender::QUADS);
+ {
+ // draw bottom left
+ uv[index] = LLVector2(uv_outer_rect.mLeft, uv_outer_rect.mBottom);
+ pos[index] = LLVector3(draw_outer_rect.mLeft, draw_outer_rect.mBottom, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mBottom);
+ pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mBottom, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
+ pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mBottom);
+ pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mBottom, 0.f);
+ index++;
+
+ // draw bottom middle
+ uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mBottom);
+ pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mBottom, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mBottom);
+ pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mBottom, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
+ pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
+ pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
+ index++;
+
+ // draw bottom right
+ uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mBottom);
+ pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mBottom, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_outer_rect.mRight, uv_outer_rect.mBottom);
+ pos[index] = LLVector3(draw_outer_rect.mRight, draw_outer_rect.mBottom, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mBottom);
+ pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mBottom, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
+ pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
+ index++;
+
+ // draw left
+ uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mBottom);
+ pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mBottom, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
+ pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
+ pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mTop);
+ pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mTop, 0.f);
+ index++;
+
+ // draw middle
+ uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
+ pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
+ pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
+ pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
+ pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
+ index++;
+
+ // draw right
+ uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
+ pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mBottom);
+ pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mBottom, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mTop);
+ pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mTop, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
+ pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
+ index++;
+
+ // draw top left
+ uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mTop);
+ pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mTop, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
+ pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mTop);
+ pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mTop, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_outer_rect.mLeft, uv_outer_rect.mTop);
+ pos[index] = LLVector3(draw_outer_rect.mLeft, draw_outer_rect.mTop, 0.f);
+ index++;
+
+ // draw top middle
+ uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
+ pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
+ pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mTop);
+ pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mTop, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mTop);
+ pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mTop, 0.f);
+ index++;
+
+ // draw top right
+ uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
+ pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mTop);
+ pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mTop, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_outer_rect.mRight, uv_outer_rect.mTop);
+ pos[index] = LLVector3(draw_outer_rect.mRight, draw_outer_rect.mTop, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mTop);
+ pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mTop, 0.f);
+ index++;
+
+ gGL.vertexBatchPreTransformed(pos, uv, NUM_VERTICES);
+ }
+ gGL.end();
+ }
+
+ if (solid_color)
+ {
+ gUIProgram.bind();
+ }
}
void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect)
{
- gl_draw_scaled_rotated_image( x, y, image->getWidth(0), image->getHeight(0), degrees, image, color, uv_rect );
+ gl_draw_scaled_rotated_image( x, y, image->getWidth(0), image->getHeight(0), degrees, image, color, uv_rect );
}
void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect, LLRenderTarget* target)
{
- if (!image && !target)
- {
- LL_WARNS() << "image == NULL; aborting function" << LL_ENDL;
- return;
- }
-
- LLGLSUIDefault gls_ui;
-
- if(image != NULL)
- {
- gGL.getTexUnit(0)->bind(image, true);
- }
- else
- {
- gGL.getTexUnit(0)->bind(target);
- }
-
- gGL.color4fv(color.mV);
-
- if (degrees == 0.f)
- {
- const S32 NUM_VERTICES = 4; // 9 quads
- LLVector2 uv[NUM_VERTICES];
- LLVector3 pos[NUM_VERTICES];
-
- gGL.begin(LLRender::QUADS);
- {
- LLVector3 ui_scale = gGL.getUIScale();
- LLVector3 ui_translation = gGL.getUITranslation();
- ui_translation.mV[VX] += x;
- ui_translation.mV[VY] += y;
- ui_translation.scaleVec(ui_scale);
- S32 index = 0;
- S32 scaled_width = ll_round(width * ui_scale.mV[VX]);
- S32 scaled_height = ll_round(height * ui_scale.mV[VY]);
-
- uv[index] = LLVector2(uv_rect.mRight, uv_rect.mTop);
- pos[index] = LLVector3(ui_translation.mV[VX] + scaled_width, ui_translation.mV[VY] + scaled_height, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_rect.mLeft, uv_rect.mTop);
- pos[index] = LLVector3(ui_translation.mV[VX], ui_translation.mV[VY] + scaled_height, 0.f);
- index++;
-
- uv[index] = LLVector2(uv_rect.mLeft, uv_rect.mBottom);
- pos[index] = LLVector3(ui_translation.mV[VX], ui_translation.mV[VY], 0.f);
- index++;
-
- uv[index] = LLVector2(uv_rect.mRight, uv_rect.mBottom);
- pos[index] = LLVector3(ui_translation.mV[VX] + scaled_width, ui_translation.mV[VY], 0.f);
- index++;
-
- gGL.vertexBatchPreTransformed(pos, uv, NUM_VERTICES);
- }
- gGL.end();
- }
- else
- {
- gGL.pushUIMatrix();
- gGL.translateUI((F32)x, (F32)y, 0.f);
-
- F32 offset_x = F32(width/2);
- F32 offset_y = F32(height/2);
-
- gGL.translateUI(offset_x, offset_y, 0.f);
-
- LLMatrix3 quat(0.f, 0.f, degrees*DEG_TO_RAD);
-
- if(image != NULL)
- {
- gGL.getTexUnit(0)->bind(image, true);
- }
- else
- {
- gGL.getTexUnit(0)->bind(target);
- }
-
- gGL.color4fv(color.mV);
-
- gGL.begin(LLRender::QUADS);
- {
- LLVector3 v;
-
- v = LLVector3(offset_x, offset_y, 0.f) * quat;
- gGL.texCoord2f(uv_rect.mRight, uv_rect.mTop);
- gGL.vertex2f(v.mV[0], v.mV[1] );
-
- v = LLVector3(-offset_x, offset_y, 0.f) * quat;
- gGL.texCoord2f(uv_rect.mLeft, uv_rect.mTop);
- gGL.vertex2f(v.mV[0], v.mV[1] );
-
- v = LLVector3(-offset_x, -offset_y, 0.f) * quat;
- gGL.texCoord2f(uv_rect.mLeft, uv_rect.mBottom);
- gGL.vertex2f(v.mV[0], v.mV[1] );
-
- v = LLVector3(offset_x, -offset_y, 0.f) * quat;
- gGL.texCoord2f(uv_rect.mRight, uv_rect.mBottom);
- gGL.vertex2f(v.mV[0], v.mV[1] );
- }
- gGL.end();
- gGL.popUIMatrix();
- }
+ if (!image && !target)
+ {
+ LL_WARNS() << "image == NULL; aborting function" << LL_ENDL;
+ return;
+ }
+
+ LLGLSUIDefault gls_ui;
+
+ if(image != NULL)
+ {
+ gGL.getTexUnit(0)->bind(image, true);
+ }
+ else
+ {
+ gGL.getTexUnit(0)->bind(target);
+ }
+
+ gGL.color4fv(color.mV);
+
+ if (degrees == 0.f)
+ {
+ const S32 NUM_VERTICES = 4; // 9 quads
+ LLVector2 uv[NUM_VERTICES];
+ LLVector3 pos[NUM_VERTICES];
+
+ gGL.begin(LLRender::QUADS);
+ {
+ LLVector3 ui_scale = gGL.getUIScale();
+ LLVector3 ui_translation = gGL.getUITranslation();
+ ui_translation.mV[VX] += x;
+ ui_translation.mV[VY] += y;
+ ui_translation.scaleVec(ui_scale);
+ S32 index = 0;
+ S32 scaled_width = ll_round(width * ui_scale.mV[VX]);
+ S32 scaled_height = ll_round(height * ui_scale.mV[VY]);
+
+ uv[index] = LLVector2(uv_rect.mRight, uv_rect.mTop);
+ pos[index] = LLVector3(ui_translation.mV[VX] + scaled_width, ui_translation.mV[VY] + scaled_height, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_rect.mLeft, uv_rect.mTop);
+ pos[index] = LLVector3(ui_translation.mV[VX], ui_translation.mV[VY] + scaled_height, 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_rect.mLeft, uv_rect.mBottom);
+ pos[index] = LLVector3(ui_translation.mV[VX], ui_translation.mV[VY], 0.f);
+ index++;
+
+ uv[index] = LLVector2(uv_rect.mRight, uv_rect.mBottom);
+ pos[index] = LLVector3(ui_translation.mV[VX] + scaled_width, ui_translation.mV[VY], 0.f);
+ index++;
+
+ gGL.vertexBatchPreTransformed(pos, uv, NUM_VERTICES);
+ }
+ gGL.end();
+ }
+ else
+ {
+ gGL.pushUIMatrix();
+ gGL.translateUI((F32)x, (F32)y, 0.f);
+
+ F32 offset_x = F32(width/2);
+ F32 offset_y = F32(height/2);
+
+ gGL.translateUI(offset_x, offset_y, 0.f);
+
+ LLMatrix3 quat(0.f, 0.f, degrees*DEG_TO_RAD);
+
+ if(image != NULL)
+ {
+ gGL.getTexUnit(0)->bind(image, true);
+ }
+ else
+ {
+ gGL.getTexUnit(0)->bind(target);
+ }
+
+ gGL.color4fv(color.mV);
+
+ gGL.begin(LLRender::QUADS);
+ {
+ LLVector3 v;
+
+ v = LLVector3(offset_x, offset_y, 0.f) * quat;
+ gGL.texCoord2f(uv_rect.mRight, uv_rect.mTop);
+ gGL.vertex2f(v.mV[0], v.mV[1] );
+
+ v = LLVector3(-offset_x, offset_y, 0.f) * quat;
+ gGL.texCoord2f(uv_rect.mLeft, uv_rect.mTop);
+ gGL.vertex2f(v.mV[0], v.mV[1] );
+
+ v = LLVector3(-offset_x, -offset_y, 0.f) * quat;
+ gGL.texCoord2f(uv_rect.mLeft, uv_rect.mBottom);
+ gGL.vertex2f(v.mV[0], v.mV[1] );
+
+ v = LLVector3(offset_x, -offset_y, 0.f) * quat;
+ gGL.texCoord2f(uv_rect.mRight, uv_rect.mBottom);
+ gGL.vertex2f(v.mV[0], v.mV[1] );
+ }
+ gGL.end();
+ gGL.popUIMatrix();
+ }
}
void gl_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color)
{
- gGL.color4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], color.mV[VALPHA]);
+ gGL.color4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], color.mV[VALPHA]);
- gGL.flush();
- glLineWidth(2.5f);
+ gGL.flush();
+ glLineWidth(2.5f);
- gGL.begin(LLRender::LINES);
- {
- gGL.vertex3fv( start.mV );
- gGL.vertex3fv( end.mV );
- }
- gGL.end();
+ gGL.begin(LLRender::LINES);
+ {
+ gGL.vertex3fv( start.mV );
+ gGL.vertex3fv( end.mV );
+ }
+ gGL.end();
- LLRender2D::getInstance()->setLineWidth(1.f);
+ LLRender2D::getInstance()->setLineWidth(1.f);
}
void gl_arc_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled, F32 start_angle, F32 end_angle)
{
- if (end_angle < start_angle)
- {
- end_angle += F_TWO_PI;
- }
-
- gGL.pushUIMatrix();
- {
- gGL.translateUI(center_x, center_y, 0.f);
-
- // Inexact, but reasonably fast.
- F32 delta = (end_angle - start_angle) / steps;
- F32 sin_delta = sin( delta );
- F32 cos_delta = cos( delta );
- F32 x = cosf(start_angle) * radius;
- F32 y = sinf(start_angle) * radius;
-
- if (filled)
- {
- gGL.begin(LLRender::TRIANGLE_FAN);
- gGL.vertex2f(0.f, 0.f);
- // make sure circle is complete
- steps += 1;
- }
- else
- {
- gGL.begin(LLRender::LINE_STRIP);
- }
-
- while( steps-- )
- {
- // Successive rotations
- gGL.vertex2f( x, y );
- F32 x_new = x * cos_delta - y * sin_delta;
- y = x * sin_delta + y * cos_delta;
- x = x_new;
- }
- gGL.end();
- }
- gGL.popUIMatrix();
+ if (end_angle < start_angle)
+ {
+ end_angle += F_TWO_PI;
+ }
+
+ gGL.pushUIMatrix();
+ {
+ gGL.translateUI(center_x, center_y, 0.f);
+
+ // Inexact, but reasonably fast.
+ F32 delta = (end_angle - start_angle) / steps;
+ F32 sin_delta = sin( delta );
+ F32 cos_delta = cos( delta );
+ F32 x = cosf(start_angle) * radius;
+ F32 y = sinf(start_angle) * radius;
+
+ if (filled)
+ {
+ gGL.begin(LLRender::TRIANGLE_FAN);
+ gGL.vertex2f(0.f, 0.f);
+ // make sure circle is complete
+ steps += 1;
+ }
+ else
+ {
+ gGL.begin(LLRender::LINE_STRIP);
+ }
+
+ while( steps-- )
+ {
+ // Successive rotations
+ gGL.vertex2f( x, y );
+ F32 x_new = x * cos_delta - y * sin_delta;
+ y = x * sin_delta + y * cos_delta;
+ x = x_new;
+ }
+ gGL.end();
+ }
+ gGL.popUIMatrix();
}
void gl_circle_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled)
{
- gGL.pushUIMatrix();
- {
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.translateUI(center_x, center_y, 0.f);
-
- // Inexact, but reasonably fast.
- F32 delta = F_TWO_PI / steps;
- F32 sin_delta = sin( delta );
- F32 cos_delta = cos( delta );
- F32 x = radius;
- F32 y = 0.f;
-
- if (filled)
- {
- gGL.begin(LLRender::TRIANGLE_FAN);
- gGL.vertex2f(0.f, 0.f);
- // make sure circle is complete
- steps += 1;
- }
- else
- {
- gGL.begin(LLRender::LINE_LOOP);
- }
-
- while( steps-- )
- {
- // Successive rotations
- gGL.vertex2f( x, y );
- F32 x_new = x * cos_delta - y * sin_delta;
- y = x * sin_delta + y * cos_delta;
- x = x_new;
- }
- gGL.end();
- }
- gGL.popUIMatrix();
+ gGL.pushUIMatrix();
+ {
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.translateUI(center_x, center_y, 0.f);
+
+ // Inexact, but reasonably fast.
+ F32 delta = F_TWO_PI / steps;
+ F32 sin_delta = sin( delta );
+ F32 cos_delta = cos( delta );
+ F32 x = radius;
+ F32 y = 0.f;
+
+ if (filled)
+ {
+ gGL.begin(LLRender::TRIANGLE_FAN);
+ gGL.vertex2f(0.f, 0.f);
+ // make sure circle is complete
+ steps += 1;
+ }
+ else
+ {
+ gGL.begin(LLRender::LINE_LOOP);
+ }
+
+ while( steps-- )
+ {
+ // Successive rotations
+ gGL.vertex2f( x, y );
+ F32 x_new = x * cos_delta - y * sin_delta;
+ y = x * sin_delta + y * cos_delta;
+ x = x_new;
+ }
+ gGL.end();
+ }
+ gGL.popUIMatrix();
}
// Renders a ring with sides (tube shape)
void gl_deep_circle( F32 radius, F32 depth, S32 steps )
{
- F32 x = radius;
- F32 y = 0.f;
- F32 angle_delta = F_TWO_PI / (F32)steps;
- gGL.begin( LLRender::TRIANGLE_STRIP );
- {
- S32 step = steps + 1; // An extra step to close the circle.
- while( step-- )
- {
- gGL.vertex3f( x, y, depth );
- gGL.vertex3f( x, y, 0.f );
-
- F32 x_new = x * cosf(angle_delta) - y * sinf(angle_delta);
- y = x * sinf(angle_delta) + y * cosf(angle_delta);
- x = x_new;
- }
- }
- gGL.end();
+ F32 x = radius;
+ F32 y = 0.f;
+ F32 angle_delta = F_TWO_PI / (F32)steps;
+ gGL.begin( LLRender::TRIANGLE_STRIP );
+ {
+ S32 step = steps + 1; // An extra step to close the circle.
+ while( step-- )
+ {
+ gGL.vertex3f( x, y, depth );
+ gGL.vertex3f( x, y, 0.f );
+
+ F32 x_new = x * cosf(angle_delta) - y * sinf(angle_delta);
+ y = x * sinf(angle_delta) + y * cosf(angle_delta);
+ x = x_new;
+ }
+ }
+ gGL.end();
}
void gl_ring( F32 radius, F32 width, const LLColor4& center_color, const LLColor4& side_color, S32 steps, BOOL render_center )
{
- gGL.pushUIMatrix();
- {
- gGL.translateUI(0.f, 0.f, -width / 2);
- if( render_center )
- {
- gGL.color4fv(center_color.mV);
- gGL.diffuseColor4fv(center_color.mV);
- gl_deep_circle( radius, width, steps );
- }
- else
- {
- gGL.diffuseColor4fv(side_color.mV);
- gl_washer_2d(radius, radius - width, steps, side_color, side_color);
- gGL.translateUI(0.f, 0.f, width);
- gl_washer_2d(radius - width, radius, steps, side_color, side_color);
- }
- }
- gGL.popUIMatrix();
+ gGL.pushUIMatrix();
+ {
+ gGL.translateUI(0.f, 0.f, -width / 2);
+ if( render_center )
+ {
+ gGL.color4fv(center_color.mV);
+ gGL.diffuseColor4fv(center_color.mV);
+ gl_deep_circle( radius, width, steps );
+ }
+ else
+ {
+ gGL.diffuseColor4fv(side_color.mV);
+ gl_washer_2d(radius, radius - width, steps, side_color, side_color);
+ gGL.translateUI(0.f, 0.f, width);
+ gl_washer_2d(radius - width, radius, steps, side_color, side_color);
+ }
+ }
+ gGL.popUIMatrix();
}
// Draw gray and white checkerboard with black border
void gl_rect_2d_checkerboard(const LLRect& rect, GLfloat alpha)
{
- //polygon stipple is deprecated, use "Checker" texture
- LLPointer<LLUIImage> img = LLRender2D::getInstance()->getUIImage("Checker");
- gGL.getTexUnit(0)->bind(img->getImage());
- gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_WRAP);
- gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
-
- LLColor4 color(1.f, 1.f, 1.f, alpha);
- LLRectf uv_rect(0, 0, rect.getWidth()/32.f, rect.getHeight()/32.f);
-
- gl_draw_scaled_image(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(), img->getImage(), color, uv_rect);
-
- gGL.flush();
+ //polygon stipple is deprecated, use "Checker" texture
+ LLPointer<LLUIImage> img = LLRender2D::getInstance()->getUIImage("Checker");
+ gGL.getTexUnit(0)->bind(img->getImage());
+ gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_WRAP);
+ gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
+
+ LLColor4 color(1.f, 1.f, 1.f, alpha);
+ LLRectf uv_rect(0, 0, rect.getWidth()/32.f, rect.getHeight()/32.f);
+
+ gl_draw_scaled_image(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(), img->getImage(), color, uv_rect);
+
+ gGL.flush();
}
@@ -877,640 +877,640 @@ void gl_rect_2d_checkerboard(const LLRect& rect, GLfloat alpha)
// a doughnut or washer.
void gl_washer_2d(F32 outer_radius, F32 inner_radius, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color)
{
- const F32 DELTA = F_TWO_PI / steps;
- const F32 SIN_DELTA = sin( DELTA );
- const F32 COS_DELTA = cos( DELTA );
-
- F32 x1 = outer_radius;
- F32 y1 = 0.f;
- F32 x2 = inner_radius;
- F32 y2 = 0.f;
-
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- gGL.begin( LLRender::TRIANGLE_STRIP );
- {
- steps += 1; // An extra step to close the circle.
- while( steps-- )
- {
- gGL.color4fv(outer_color.mV);
- gGL.vertex2f( x1, y1 );
- gGL.color4fv(inner_color.mV);
- gGL.vertex2f( x2, y2 );
-
- F32 x1_new = x1 * COS_DELTA - y1 * SIN_DELTA;
- y1 = x1 * SIN_DELTA + y1 * COS_DELTA;
- x1 = x1_new;
-
- F32 x2_new = x2 * COS_DELTA - y2 * SIN_DELTA;
- y2 = x2 * SIN_DELTA + y2 * COS_DELTA;
- x2 = x2_new;
- }
- }
- gGL.end();
+ const F32 DELTA = F_TWO_PI / steps;
+ const F32 SIN_DELTA = sin( DELTA );
+ const F32 COS_DELTA = cos( DELTA );
+
+ F32 x1 = outer_radius;
+ F32 y1 = 0.f;
+ F32 x2 = inner_radius;
+ F32 y2 = 0.f;
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ gGL.begin( LLRender::TRIANGLE_STRIP );
+ {
+ steps += 1; // An extra step to close the circle.
+ while( steps-- )
+ {
+ gGL.color4fv(outer_color.mV);
+ gGL.vertex2f( x1, y1 );
+ gGL.color4fv(inner_color.mV);
+ gGL.vertex2f( x2, y2 );
+
+ F32 x1_new = x1 * COS_DELTA - y1 * SIN_DELTA;
+ y1 = x1 * SIN_DELTA + y1 * COS_DELTA;
+ x1 = x1_new;
+
+ F32 x2_new = x2 * COS_DELTA - y2 * SIN_DELTA;
+ y2 = x2 * SIN_DELTA + y2 * COS_DELTA;
+ x2 = x2_new;
+ }
+ }
+ gGL.end();
}
// Draws the area between two concentric circles, like
// a doughnut or washer.
void gl_washer_segment_2d(F32 outer_radius, F32 inner_radius, F32 start_radians, F32 end_radians, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color)
{
- const F32 DELTA = (end_radians - start_radians) / steps;
- const F32 SIN_DELTA = sin( DELTA );
- const F32 COS_DELTA = cos( DELTA );
-
- F32 x1 = outer_radius * cos( start_radians );
- F32 y1 = outer_radius * sin( start_radians );
- F32 x2 = inner_radius * cos( start_radians );
- F32 y2 = inner_radius * sin( start_radians );
-
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.begin( LLRender::TRIANGLE_STRIP );
- {
- steps += 1; // An extra step to close the circle.
- while( steps-- )
- {
- gGL.color4fv(outer_color.mV);
- gGL.vertex2f( x1, y1 );
- gGL.color4fv(inner_color.mV);
- gGL.vertex2f( x2, y2 );
-
- F32 x1_new = x1 * COS_DELTA - y1 * SIN_DELTA;
- y1 = x1 * SIN_DELTA + y1 * COS_DELTA;
- x1 = x1_new;
-
- F32 x2_new = x2 * COS_DELTA - y2 * SIN_DELTA;
- y2 = x2 * SIN_DELTA + y2 * COS_DELTA;
- x2 = x2_new;
- }
- }
- gGL.end();
+ const F32 DELTA = (end_radians - start_radians) / steps;
+ const F32 SIN_DELTA = sin( DELTA );
+ const F32 COS_DELTA = cos( DELTA );
+
+ F32 x1 = outer_radius * cos( start_radians );
+ F32 y1 = outer_radius * sin( start_radians );
+ F32 x2 = inner_radius * cos( start_radians );
+ F32 y2 = inner_radius * sin( start_radians );
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.begin( LLRender::TRIANGLE_STRIP );
+ {
+ steps += 1; // An extra step to close the circle.
+ while( steps-- )
+ {
+ gGL.color4fv(outer_color.mV);
+ gGL.vertex2f( x1, y1 );
+ gGL.color4fv(inner_color.mV);
+ gGL.vertex2f( x2, y2 );
+
+ F32 x1_new = x1 * COS_DELTA - y1 * SIN_DELTA;
+ y1 = x1 * SIN_DELTA + y1 * COS_DELTA;
+ x1 = x1_new;
+
+ F32 x2_new = x2 * COS_DELTA - y2 * SIN_DELTA;
+ y2 = x2 * SIN_DELTA + y2 * COS_DELTA;
+ x2 = x2_new;
+ }
+ }
+ gGL.end();
}
void gl_rect_2d_simple_tex( S32 width, S32 height )
{
- gGL.begin( LLRender::QUADS );
+ gGL.begin( LLRender::QUADS );
- gGL.texCoord2f(1.f, 1.f);
- gGL.vertex2i(width, height);
+ gGL.texCoord2f(1.f, 1.f);
+ gGL.vertex2i(width, height);
- gGL.texCoord2f(0.f, 1.f);
- gGL.vertex2i(0, height);
+ gGL.texCoord2f(0.f, 1.f);
+ gGL.vertex2i(0, height);
- gGL.texCoord2f(0.f, 0.f);
- gGL.vertex2i(0, 0);
+ gGL.texCoord2f(0.f, 0.f);
+ gGL.vertex2i(0, 0);
- gGL.texCoord2f(1.f, 0.f);
- gGL.vertex2i(width, 0);
-
- gGL.end();
+ gGL.texCoord2f(1.f, 0.f);
+ gGL.vertex2i(width, 0);
+
+ gGL.end();
}
void gl_rect_2d_simple( S32 width, S32 height )
{
- gGL.begin( LLRender::QUADS );
- gGL.vertex2i(width, height);
- gGL.vertex2i(0, height);
- gGL.vertex2i(0, 0);
- gGL.vertex2i(width, 0);
- gGL.end();
+ gGL.begin( LLRender::QUADS );
+ gGL.vertex2i(width, height);
+ gGL.vertex2i(0, height);
+ gGL.vertex2i(0, 0);
+ gGL.vertex2i(width, 0);
+ gGL.end();
}
-void gl_segmented_rect_2d_tex(const S32 left,
- const S32 top,
- const S32 right,
- const S32 bottom,
- const S32 texture_width,
- const S32 texture_height,
- const S32 border_size,
- const U32 edges)
+void gl_segmented_rect_2d_tex(const S32 left,
+ const S32 top,
+ const S32 right,
+ const S32 bottom,
+ const S32 texture_width,
+ const S32 texture_height,
+ const S32 border_size,
+ const U32 edges)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
- S32 width = llabs(right - left);
- S32 height = llabs(top - bottom);
+ S32 width = llabs(right - left);
+ S32 height = llabs(top - bottom);
- gGL.pushUIMatrix();
+ gGL.pushUIMatrix();
- gGL.translateUI((F32)left, (F32)bottom, 0.f);
- LLVector2 border_uv_scale((F32)border_size / (F32)texture_width, (F32)border_size / (F32)texture_height);
+ gGL.translateUI((F32)left, (F32)bottom, 0.f);
+ LLVector2 border_uv_scale((F32)border_size / (F32)texture_width, (F32)border_size / (F32)texture_height);
- if (border_uv_scale.mV[VX] > 0.5f)
- {
- border_uv_scale *= 0.5f / border_uv_scale.mV[VX];
- }
- if (border_uv_scale.mV[VY] > 0.5f)
- {
- border_uv_scale *= 0.5f / border_uv_scale.mV[VY];
- }
+ if (border_uv_scale.mV[VX] > 0.5f)
+ {
+ border_uv_scale *= 0.5f / border_uv_scale.mV[VX];
+ }
+ if (border_uv_scale.mV[VY] > 0.5f)
+ {
+ border_uv_scale *= 0.5f / border_uv_scale.mV[VY];
+ }
- F32 border_scale = llmin((F32)border_size, (F32)width * 0.5f, (F32)height * 0.5f);
- LLVector2 border_width_left = ((edges & (~(U32)ROUNDED_RECT_RIGHT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero;
- LLVector2 border_width_right = ((edges & (~(U32)ROUNDED_RECT_LEFT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero;
- LLVector2 border_height_bottom = ((edges & (~(U32)ROUNDED_RECT_TOP)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero;
- LLVector2 border_height_top = ((edges & (~(U32)ROUNDED_RECT_BOTTOM)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero;
- LLVector2 width_vec((F32)width, 0.f);
- LLVector2 height_vec(0.f, (F32)height);
+ F32 border_scale = llmin((F32)border_size, (F32)width * 0.5f, (F32)height * 0.5f);
+ LLVector2 border_width_left = ((edges & (~(U32)ROUNDED_RECT_RIGHT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero;
+ LLVector2 border_width_right = ((edges & (~(U32)ROUNDED_RECT_LEFT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero;
+ LLVector2 border_height_bottom = ((edges & (~(U32)ROUNDED_RECT_TOP)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero;
+ LLVector2 border_height_top = ((edges & (~(U32)ROUNDED_RECT_BOTTOM)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero;
+ LLVector2 width_vec((F32)width, 0.f);
+ LLVector2 height_vec(0.f, (F32)height);
- gGL.begin(LLRender::QUADS);
- {
- // draw bottom left
- gGL.texCoord2f(0.f, 0.f);
- gGL.vertex2f(0.f, 0.f);
+ gGL.begin(LLRender::QUADS);
+ {
+ // draw bottom left
+ gGL.texCoord2f(0.f, 0.f);
+ gGL.vertex2f(0.f, 0.f);
- gGL.texCoord2f(border_uv_scale.mV[VX], 0.f);
- gGL.vertex2fv(border_width_left.mV);
+ gGL.texCoord2f(border_uv_scale.mV[VX], 0.f);
+ gGL.vertex2fv(border_width_left.mV);
- gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
- gGL.vertex2fv((border_width_left + border_height_bottom).mV);
+ gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+ gGL.vertex2fv((border_width_left + border_height_bottom).mV);
- gGL.texCoord2f(0.f, border_uv_scale.mV[VY]);
- gGL.vertex2fv(border_height_bottom.mV);
+ gGL.texCoord2f(0.f, border_uv_scale.mV[VY]);
+ gGL.vertex2fv(border_height_bottom.mV);
- // draw bottom middle
- gGL.texCoord2f(border_uv_scale.mV[VX], 0.f);
- gGL.vertex2fv(border_width_left.mV);
+ // draw bottom middle
+ gGL.texCoord2f(border_uv_scale.mV[VX], 0.f);
+ gGL.vertex2fv(border_width_left.mV);
- gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 0.f);
- gGL.vertex2fv((width_vec - border_width_right).mV);
+ gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 0.f);
+ gGL.vertex2fv((width_vec - border_width_right).mV);
- gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
- gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV);
+ gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+ gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV);
- gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
- gGL.vertex2fv((border_width_left + border_height_bottom).mV);
+ gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+ gGL.vertex2fv((border_width_left + border_height_bottom).mV);
- // draw bottom right
- gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 0.f);
- gGL.vertex2fv((width_vec - border_width_right).mV);
+ // draw bottom right
+ gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 0.f);
+ gGL.vertex2fv((width_vec - border_width_right).mV);
- gGL.texCoord2f(1.f, 0.f);
- gGL.vertex2fv(width_vec.mV);
+ gGL.texCoord2f(1.f, 0.f);
+ gGL.vertex2fv(width_vec.mV);
- gGL.texCoord2f(1.f, border_uv_scale.mV[VY]);
- gGL.vertex2fv((width_vec + border_height_bottom).mV);
+ gGL.texCoord2f(1.f, border_uv_scale.mV[VY]);
+ gGL.vertex2fv((width_vec + border_height_bottom).mV);
- gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
- gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV);
+ gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+ gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV);
- // draw left
- gGL.texCoord2f(0.f, border_uv_scale.mV[VY]);
- gGL.vertex2fv(border_height_bottom.mV);
+ // draw left
+ gGL.texCoord2f(0.f, border_uv_scale.mV[VY]);
+ gGL.vertex2fv(border_height_bottom.mV);
- gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
- gGL.vertex2fv((border_width_left + border_height_bottom).mV);
+ gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+ gGL.vertex2fv((border_width_left + border_height_bottom).mV);
- gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
- gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV);
+ gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV);
- gGL.texCoord2f(0.f, 1.f - border_uv_scale.mV[VY]);
- gGL.vertex2fv((height_vec - border_height_top).mV);
+ gGL.texCoord2f(0.f, 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((height_vec - border_height_top).mV);
- // draw middle
- gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
- gGL.vertex2fv((border_width_left + border_height_bottom).mV);
+ // draw middle
+ gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+ gGL.vertex2fv((border_width_left + border_height_bottom).mV);
- gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
- gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV);
+ gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+ gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV);
- gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
- gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV);
+ gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV);
- gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
- gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV);
+ gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV);
- // draw right
- gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
- gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV);
+ // draw right
+ gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+ gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV);
- gGL.texCoord2f(1.f, border_uv_scale.mV[VY]);
- gGL.vertex2fv((width_vec + border_height_bottom).mV);
+ gGL.texCoord2f(1.f, border_uv_scale.mV[VY]);
+ gGL.vertex2fv((width_vec + border_height_bottom).mV);
- gGL.texCoord2f(1.f, 1.f - border_uv_scale.mV[VY]);
- gGL.vertex2fv((width_vec + height_vec - border_height_top).mV);
+ gGL.texCoord2f(1.f, 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((width_vec + height_vec - border_height_top).mV);
- gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
- gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV);
+ gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV);
- // draw top left
- gGL.texCoord2f(0.f, 1.f - border_uv_scale.mV[VY]);
- gGL.vertex2fv((height_vec - border_height_top).mV);
+ // draw top left
+ gGL.texCoord2f(0.f, 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((height_vec - border_height_top).mV);
- gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
- gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV);
+ gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV);
- gGL.texCoord2f(border_uv_scale.mV[VX], 1.f);
- gGL.vertex2fv((border_width_left + height_vec).mV);
+ gGL.texCoord2f(border_uv_scale.mV[VX], 1.f);
+ gGL.vertex2fv((border_width_left + height_vec).mV);
- gGL.texCoord2f(0.f, 1.f);
- gGL.vertex2fv((height_vec).mV);
+ gGL.texCoord2f(0.f, 1.f);
+ gGL.vertex2fv((height_vec).mV);
- // draw top middle
- gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
- gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV);
+ // draw top middle
+ gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV);
- gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
- gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV);
+ gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV);
- gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f);
- gGL.vertex2fv((width_vec - border_width_right + height_vec).mV);
+ gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f);
+ gGL.vertex2fv((width_vec - border_width_right + height_vec).mV);
- gGL.texCoord2f(border_uv_scale.mV[VX], 1.f);
- gGL.vertex2fv((border_width_left + height_vec).mV);
+ gGL.texCoord2f(border_uv_scale.mV[VX], 1.f);
+ gGL.vertex2fv((border_width_left + height_vec).mV);
- // draw top right
- gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
- gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV);
+ // draw top right
+ gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV);
- gGL.texCoord2f(1.f, 1.f - border_uv_scale.mV[VY]);
- gGL.vertex2fv((width_vec + height_vec - border_height_top).mV);
+ gGL.texCoord2f(1.f, 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((width_vec + height_vec - border_height_top).mV);
- gGL.texCoord2f(1.f, 1.f);
- gGL.vertex2fv((width_vec + height_vec).mV);
+ gGL.texCoord2f(1.f, 1.f);
+ gGL.vertex2fv((width_vec + height_vec).mV);
- gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f);
- gGL.vertex2fv((width_vec - border_width_right + height_vec).mV);
- }
- gGL.end();
+ gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f);
+ gGL.vertex2fv((width_vec - border_width_right + height_vec).mV);
+ }
+ gGL.end();
- gGL.popUIMatrix();
+ gGL.popUIMatrix();
}
-void gl_segmented_rect_2d_fragment_tex(const LLRect& rect,
- const S32 texture_width,
- const S32 texture_height,
- const S32 border_size,
- const F32 start_fragment,
- const F32 end_fragment,
- const U32 edges)
+void gl_segmented_rect_2d_fragment_tex(const LLRect& rect,
+ const S32 texture_width,
+ const S32 texture_height,
+ const S32 border_size,
+ const F32 start_fragment,
+ const F32 end_fragment,
+ const U32 edges)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
- const S32 left = rect.mLeft;
- const S32 right = rect.mRight;
- const S32 top = rect.mTop;
- const S32 bottom = rect.mBottom;
- S32 width = llabs(right - left);
- S32 height = llabs(top - bottom);
-
- gGL.pushUIMatrix();
-
- gGL.translateUI((F32)left, (F32)bottom, 0.f);
- LLVector2 border_uv_scale((F32)border_size / (F32)texture_width, (F32)border_size / (F32)texture_height);
-
- if (border_uv_scale.mV[VX] > 0.5f)
- {
- border_uv_scale *= 0.5f / border_uv_scale.mV[VX];
- }
- if (border_uv_scale.mV[VY] > 0.5f)
- {
- border_uv_scale *= 0.5f / border_uv_scale.mV[VY];
- }
+ const S32 left = rect.mLeft;
+ const S32 right = rect.mRight;
+ const S32 top = rect.mTop;
+ const S32 bottom = rect.mBottom;
+ S32 width = llabs(right - left);
+ S32 height = llabs(top - bottom);
- F32 border_scale = llmin((F32)border_size, (F32)width * 0.5f, (F32)height * 0.5f);
- LLVector2 border_width_left = ((edges & (~(U32)ROUNDED_RECT_RIGHT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero;
- LLVector2 border_width_right = ((edges & (~(U32)ROUNDED_RECT_LEFT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero;
- LLVector2 border_height_bottom = ((edges & (~(U32)ROUNDED_RECT_TOP)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero;
- LLVector2 border_height_top = ((edges & (~(U32)ROUNDED_RECT_BOTTOM)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero;
- LLVector2 width_vec((F32)width, 0.f);
- LLVector2 height_vec(0.f, (F32)height);
+ gGL.pushUIMatrix();
- F32 middle_start = border_scale / (F32)width;
- F32 middle_end = 1.f - middle_start;
+ gGL.translateUI((F32)left, (F32)bottom, 0.f);
+ LLVector2 border_uv_scale((F32)border_size / (F32)texture_width, (F32)border_size / (F32)texture_height);
- F32 u_min;
- F32 u_max;
- LLVector2 x_min;
- LLVector2 x_max;
-
- gGL.begin(LLRender::QUADS);
- {
- if (start_fragment < middle_start)
- {
- u_min = (start_fragment / middle_start) * border_uv_scale.mV[VX];
- u_max = llmin(end_fragment / middle_start, 1.f) * border_uv_scale.mV[VX];
- x_min = (start_fragment / middle_start) * border_width_left;
- x_max = llmin(end_fragment / middle_start, 1.f) * border_width_left;
+ if (border_uv_scale.mV[VX] > 0.5f)
+ {
+ border_uv_scale *= 0.5f / border_uv_scale.mV[VX];
+ }
+ if (border_uv_scale.mV[VY] > 0.5f)
+ {
+ border_uv_scale *= 0.5f / border_uv_scale.mV[VY];
+ }
- // draw bottom left
- gGL.texCoord2f(u_min, 0.f);
- gGL.vertex2fv(x_min.mV);
+ F32 border_scale = llmin((F32)border_size, (F32)width * 0.5f, (F32)height * 0.5f);
+ LLVector2 border_width_left = ((edges & (~(U32)ROUNDED_RECT_RIGHT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero;
+ LLVector2 border_width_right = ((edges & (~(U32)ROUNDED_RECT_LEFT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero;
+ LLVector2 border_height_bottom = ((edges & (~(U32)ROUNDED_RECT_TOP)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero;
+ LLVector2 border_height_top = ((edges & (~(U32)ROUNDED_RECT_BOTTOM)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero;
+ LLVector2 width_vec((F32)width, 0.f);
+ LLVector2 height_vec(0.f, (F32)height);
- gGL.texCoord2f(border_uv_scale.mV[VX], 0.f);
- gGL.vertex2fv(x_max.mV);
+ F32 middle_start = border_scale / (F32)width;
+ F32 middle_end = 1.f - middle_start;
- gGL.texCoord2f(u_max, border_uv_scale.mV[VY]);
- gGL.vertex2fv((x_max + border_height_bottom).mV);
+ F32 u_min;
+ F32 u_max;
+ LLVector2 x_min;
+ LLVector2 x_max;
- gGL.texCoord2f(u_min, border_uv_scale.mV[VY]);
- gGL.vertex2fv((x_min + border_height_bottom).mV);
+ gGL.begin(LLRender::QUADS);
+ {
+ if (start_fragment < middle_start)
+ {
+ u_min = (start_fragment / middle_start) * border_uv_scale.mV[VX];
+ u_max = llmin(end_fragment / middle_start, 1.f) * border_uv_scale.mV[VX];
+ x_min = (start_fragment / middle_start) * border_width_left;
+ x_max = llmin(end_fragment / middle_start, 1.f) * border_width_left;
- // draw left
- gGL.texCoord2f(u_min, border_uv_scale.mV[VY]);
- gGL.vertex2fv((x_min + border_height_bottom).mV);
+ // draw bottom left
+ gGL.texCoord2f(u_min, 0.f);
+ gGL.vertex2fv(x_min.mV);
- gGL.texCoord2f(u_max, border_uv_scale.mV[VY]);
- gGL.vertex2fv((x_max + border_height_bottom).mV);
+ gGL.texCoord2f(border_uv_scale.mV[VX], 0.f);
+ gGL.vertex2fv(x_max.mV);
- gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]);
- gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
+ gGL.texCoord2f(u_max, border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_max + border_height_bottom).mV);
- gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);
- gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
+ gGL.texCoord2f(u_min, border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_min + border_height_bottom).mV);
- // draw top left
- gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);
- gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
+ // draw left
+ gGL.texCoord2f(u_min, border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_min + border_height_bottom).mV);
- gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]);
- gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
+ gGL.texCoord2f(u_max, border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_max + border_height_bottom).mV);
- gGL.texCoord2f(u_max, 1.f);
- gGL.vertex2fv((x_max + height_vec).mV);
+ gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
- gGL.texCoord2f(u_min, 1.f);
- gGL.vertex2fv((x_min + height_vec).mV);
- }
+ gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
- if (end_fragment > middle_start || start_fragment < middle_end)
- {
- x_min = border_width_left + ((llclamp(start_fragment, middle_start, middle_end) - middle_start)) * width_vec;
- x_max = border_width_left + ((llclamp(end_fragment, middle_start, middle_end) - middle_start)) * width_vec;
+ // draw top left
+ gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
- // draw bottom middle
- gGL.texCoord2f(border_uv_scale.mV[VX], 0.f);
- gGL.vertex2fv(x_min.mV);
+ gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
- gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 0.f);
- gGL.vertex2fv((x_max).mV);
+ gGL.texCoord2f(u_max, 1.f);
+ gGL.vertex2fv((x_max + height_vec).mV);
- gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
- gGL.vertex2fv((x_max + border_height_bottom).mV);
+ gGL.texCoord2f(u_min, 1.f);
+ gGL.vertex2fv((x_min + height_vec).mV);
+ }
- gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
- gGL.vertex2fv((x_min + border_height_bottom).mV);
+ if (end_fragment > middle_start || start_fragment < middle_end)
+ {
+ x_min = border_width_left + ((llclamp(start_fragment, middle_start, middle_end) - middle_start)) * width_vec;
+ x_max = border_width_left + ((llclamp(end_fragment, middle_start, middle_end) - middle_start)) * width_vec;
- // draw middle
- gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
- gGL.vertex2fv((x_min + border_height_bottom).mV);
+ // draw bottom middle
+ gGL.texCoord2f(border_uv_scale.mV[VX], 0.f);
+ gGL.vertex2fv(x_min.mV);
- gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
- gGL.vertex2fv((x_max + border_height_bottom).mV);
+ gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 0.f);
+ gGL.vertex2fv((x_max).mV);
- gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
- gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
+ gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_max + border_height_bottom).mV);
- gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
- gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
+ gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_min + border_height_bottom).mV);
- // draw top middle
- gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
- gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
+ // draw middle
+ gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_min + border_height_bottom).mV);
- gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
- gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
+ gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_max + border_height_bottom).mV);
- gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f);
- gGL.vertex2fv((x_max + height_vec).mV);
+ gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
- gGL.texCoord2f(border_uv_scale.mV[VX], 1.f);
- gGL.vertex2fv((x_min + height_vec).mV);
- }
+ gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
- if (end_fragment > middle_end)
- {
- u_min = 1.f - ((1.f - llmax(0.f, (start_fragment - middle_end) / middle_start)) * border_uv_scale.mV[VX]);
- u_max = 1.f - ((1.f - ((end_fragment - middle_end) / middle_start)) * border_uv_scale.mV[VX]);
- x_min = width_vec - ((1.f - llmax(0.f, (start_fragment - middle_end) / middle_start)) * border_width_right);
- x_max = width_vec - ((1.f - ((end_fragment - middle_end) / middle_start)) * border_width_right);
+ // draw top middle
+ gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
- // draw bottom right
- gGL.texCoord2f(u_min, 0.f);
- gGL.vertex2fv((x_min).mV);
+ gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
- gGL.texCoord2f(u_max, 0.f);
- gGL.vertex2fv(x_max.mV);
+ gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f);
+ gGL.vertex2fv((x_max + height_vec).mV);
- gGL.texCoord2f(u_max, border_uv_scale.mV[VY]);
- gGL.vertex2fv((x_max + border_height_bottom).mV);
+ gGL.texCoord2f(border_uv_scale.mV[VX], 1.f);
+ gGL.vertex2fv((x_min + height_vec).mV);
+ }
- gGL.texCoord2f(u_min, border_uv_scale.mV[VY]);
- gGL.vertex2fv((x_min + border_height_bottom).mV);
+ if (end_fragment > middle_end)
+ {
+ u_min = 1.f - ((1.f - llmax(0.f, (start_fragment - middle_end) / middle_start)) * border_uv_scale.mV[VX]);
+ u_max = 1.f - ((1.f - ((end_fragment - middle_end) / middle_start)) * border_uv_scale.mV[VX]);
+ x_min = width_vec - ((1.f - llmax(0.f, (start_fragment - middle_end) / middle_start)) * border_width_right);
+ x_max = width_vec - ((1.f - ((end_fragment - middle_end) / middle_start)) * border_width_right);
- // draw right
- gGL.texCoord2f(u_min, border_uv_scale.mV[VY]);
- gGL.vertex2fv((x_min + border_height_bottom).mV);
+ // draw bottom right
+ gGL.texCoord2f(u_min, 0.f);
+ gGL.vertex2fv((x_min).mV);
- gGL.texCoord2f(u_max, border_uv_scale.mV[VY]);
- gGL.vertex2fv((x_max + border_height_bottom).mV);
+ gGL.texCoord2f(u_max, 0.f);
+ gGL.vertex2fv(x_max.mV);
- gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]);
- gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
+ gGL.texCoord2f(u_max, border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_max + border_height_bottom).mV);
- gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);
- gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
+ gGL.texCoord2f(u_min, border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_min + border_height_bottom).mV);
- // draw top right
- gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);
- gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
+ // draw right
+ gGL.texCoord2f(u_min, border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_min + border_height_bottom).mV);
- gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]);
- gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
+ gGL.texCoord2f(u_max, border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_max + border_height_bottom).mV);
- gGL.texCoord2f(u_max, 1.f);
- gGL.vertex2fv((x_max + height_vec).mV);
+ gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
- gGL.texCoord2f(u_min, 1.f);
- gGL.vertex2fv((x_min + height_vec).mV);
- }
- }
- gGL.end();
+ gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
- gGL.popUIMatrix();
+ // draw top right
+ gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
+
+ gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]);
+ gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
+
+ gGL.texCoord2f(u_max, 1.f);
+ gGL.vertex2fv((x_max + height_vec).mV);
+
+ gGL.texCoord2f(u_min, 1.f);
+ gGL.vertex2fv((x_min + height_vec).mV);
+ }
+ }
+ gGL.end();
+
+ gGL.popUIMatrix();
}
-void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv_rect, const LLRectf& center_draw_rect,
- const LLVector3& width_vec, const LLVector3& height_vec)
+void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv_rect, const LLRectf& center_draw_rect,
+ const LLVector3& width_vec, const LLVector3& height_vec)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
- gGL.begin(LLRender::QUADS);
- {
- // draw bottom left
- gGL.texCoord2f(clip_rect.mLeft, clip_rect.mBottom);
- gGL.vertex3f(0.f, 0.f, 0.f);
+ gGL.begin(LLRender::QUADS);
+ {
+ // draw bottom left
+ gGL.texCoord2f(clip_rect.mLeft, clip_rect.mBottom);
+ gGL.vertex3f(0.f, 0.f, 0.f);
- gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mBottom);
- gGL.vertex3fv((center_draw_rect.mLeft * width_vec).mV);
+ gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mBottom);
+ gGL.vertex3fv((center_draw_rect.mLeft * width_vec).mV);
- gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom);
- gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV);
+ gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom);
+ gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV);
- gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mBottom);
- gGL.vertex3fv((center_draw_rect.mBottom * height_vec).mV);
+ gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mBottom);
+ gGL.vertex3fv((center_draw_rect.mBottom * height_vec).mV);
- // draw bottom middle
- gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mBottom);
- gGL.vertex3fv((center_draw_rect.mLeft * width_vec).mV);
+ // draw bottom middle
+ gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mBottom);
+ gGL.vertex3fv((center_draw_rect.mLeft * width_vec).mV);
- gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mBottom);
- gGL.vertex3fv((center_draw_rect.mRight * width_vec).mV);
+ gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mBottom);
+ gGL.vertex3fv((center_draw_rect.mRight * width_vec).mV);
- gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom);
- gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV);
+ gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom);
+ gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV);
- gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom);
- gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV);
+ gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom);
+ gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV);
- // draw bottom right
- gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mBottom);
- gGL.vertex3fv((center_draw_rect.mRight * width_vec).mV);
+ // draw bottom right
+ gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mBottom);
+ gGL.vertex3fv((center_draw_rect.mRight * width_vec).mV);
- gGL.texCoord2f(clip_rect.mRight, clip_rect.mBottom);
- gGL.vertex3fv(width_vec.mV);
+ gGL.texCoord2f(clip_rect.mRight, clip_rect.mBottom);
+ gGL.vertex3fv(width_vec.mV);
- gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mBottom);
- gGL.vertex3fv((width_vec + center_draw_rect.mBottom * height_vec).mV);
+ gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mBottom);
+ gGL.vertex3fv((width_vec + center_draw_rect.mBottom * height_vec).mV);
- gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom);
- gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV);
+ gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom);
+ gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV);
- // draw left
- gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mBottom);
- gGL.vertex3fv((center_draw_rect.mBottom * height_vec).mV);
+ // draw left
+ gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mBottom);
+ gGL.vertex3fv((center_draw_rect.mBottom * height_vec).mV);
- gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom);
- gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV);
+ gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom);
+ gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV);
- gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop);
- gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV);
+ gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop);
+ gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV);
- gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mTop);
- gGL.vertex3fv((center_draw_rect.mTop * height_vec).mV);
+ gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mTop);
+ gGL.vertex3fv((center_draw_rect.mTop * height_vec).mV);
- // draw middle
- gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom);
- gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV);
+ // draw middle
+ gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom);
+ gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV);
- gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom);
- gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV);
+ gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom);
+ gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV);
- gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop);
- gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV);
+ gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop);
+ gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV);
- gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop);
- gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV);
+ gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop);
+ gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV);
- // draw right
- gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom);
- gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV);
+ // draw right
+ gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom);
+ gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV);
- gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mBottom);
- gGL.vertex3fv((width_vec + center_draw_rect.mBottom * height_vec).mV);
+ gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mBottom);
+ gGL.vertex3fv((width_vec + center_draw_rect.mBottom * height_vec).mV);
- gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mTop);
- gGL.vertex3fv((width_vec + center_draw_rect.mTop * height_vec).mV);
+ gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mTop);
+ gGL.vertex3fv((width_vec + center_draw_rect.mTop * height_vec).mV);
- gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop);
- gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV);
+ gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop);
+ gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV);
- // draw top left
- gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mTop);
- gGL.vertex3fv((center_draw_rect.mTop * height_vec).mV);
+ // draw top left
+ gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mTop);
+ gGL.vertex3fv((center_draw_rect.mTop * height_vec).mV);
- gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop);
- gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV);
+ gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop);
+ gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV);
- gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mTop);
- gGL.vertex3fv((center_draw_rect.mLeft * width_vec + height_vec).mV);
+ gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mTop);
+ gGL.vertex3fv((center_draw_rect.mLeft * width_vec + height_vec).mV);
- gGL.texCoord2f(clip_rect.mLeft, clip_rect.mTop);
- gGL.vertex3fv((height_vec).mV);
+ gGL.texCoord2f(clip_rect.mLeft, clip_rect.mTop);
+ gGL.vertex3fv((height_vec).mV);
- // draw top middle
- gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop);
- gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV);
+ // draw top middle
+ gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop);
+ gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV);
- gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop);
- gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV);
+ gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop);
+ gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV);
- gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mTop);
- gGL.vertex3fv((center_draw_rect.mRight * width_vec + height_vec).mV);
+ gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mTop);
+ gGL.vertex3fv((center_draw_rect.mRight * width_vec + height_vec).mV);
- gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mTop);
- gGL.vertex3fv((center_draw_rect.mLeft * width_vec + height_vec).mV);
+ gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mTop);
+ gGL.vertex3fv((center_draw_rect.mLeft * width_vec + height_vec).mV);
- // draw top right
- gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop);
- gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV);
+ // draw top right
+ gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop);
+ gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV);
- gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mTop);
- gGL.vertex3fv((width_vec + center_draw_rect.mTop * height_vec).mV);
+ gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mTop);
+ gGL.vertex3fv((width_vec + center_draw_rect.mTop * height_vec).mV);
- gGL.texCoord2f(clip_rect.mRight, clip_rect.mTop);
- gGL.vertex3fv((width_vec + height_vec).mV);
+ gGL.texCoord2f(clip_rect.mRight, clip_rect.mTop);
+ gGL.vertex3fv((width_vec + height_vec).mV);
- gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mTop);
- gGL.vertex3fv((center_draw_rect.mRight * width_vec + height_vec).mV);
- }
- gGL.end();
+ gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mTop);
+ gGL.vertex3fv((center_draw_rect.mRight * width_vec + height_vec).mV);
+ }
+ gGL.end();
}
LLRender2D::LLRender2D(LLImageProviderInterface* image_provider)
{
- mImageProvider = image_provider;
- if(mImageProvider)
- {
- mImageProvider->addOnRemovalCallback(resetProvider);
- }
+ mImageProvider = image_provider;
+ if(mImageProvider)
+ {
+ mImageProvider->addOnRemovalCallback(resetProvider);
+ }
}
LLRender2D::~LLRender2D()
{
- if(mImageProvider)
- {
- mImageProvider->cleanUp();
- mImageProvider->deleteOnRemovalCallback(resetProvider);
- }
+ if(mImageProvider)
+ {
+ mImageProvider->cleanUp();
+ mImageProvider->deleteOnRemovalCallback(resetProvider);
+ }
}
// static
void LLRender2D::translate(F32 x, F32 y, F32 z)
{
- gGL.translateUI(x,y,z);
- LLFontGL::sCurOrigin.mX += (S32) x;
- LLFontGL::sCurOrigin.mY += (S32) y;
- LLFontGL::sCurDepth += z;
+ gGL.translateUI(x,y,z);
+ LLFontGL::sCurOrigin.mX += (S32) x;
+ LLFontGL::sCurOrigin.mY += (S32) y;
+ LLFontGL::sCurDepth += z;
}
// static
void LLRender2D::pushMatrix()
{
- gGL.pushUIMatrix();
- LLFontGL::sOriginStack.push_back(std::make_pair(LLFontGL::sCurOrigin, LLFontGL::sCurDepth));
+ gGL.pushUIMatrix();
+ LLFontGL::sOriginStack.push_back(std::make_pair(LLFontGL::sCurOrigin, LLFontGL::sCurDepth));
}
// static
void LLRender2D::popMatrix()
{
- gGL.popUIMatrix();
- LLFontGL::sCurOrigin = LLFontGL::sOriginStack.back().first;
- LLFontGL::sCurDepth = LLFontGL::sOriginStack.back().second;
- LLFontGL::sOriginStack.pop_back();
+ gGL.popUIMatrix();
+ LLFontGL::sCurOrigin = LLFontGL::sOriginStack.back().first;
+ LLFontGL::sCurDepth = LLFontGL::sOriginStack.back().second;
+ LLFontGL::sOriginStack.pop_back();
}
// static
void LLRender2D::loadIdentity()
{
- gGL.loadUIIdentity();
- LLFontGL::sCurOrigin.mX = 0;
- LLFontGL::sCurOrigin.mY = 0;
- LLFontGL::sCurDepth = 0.f;
+ gGL.loadUIIdentity();
+ LLFontGL::sCurOrigin.mX = 0;
+ LLFontGL::sCurOrigin.mY = 0;
+ LLFontGL::sCurDepth = 0.f;
}
// static
void LLRender2D::setLineWidth(F32 width)
{
- gGL.flush();
+ gGL.flush();
// If outside the allowed range, glLineWidth fails with "invalid value".
// On Darwin, the range is [1, 1].
static GLfloat range[2]{0.0};
@@ -1524,22 +1524,22 @@ void LLRender2D::setLineWidth(F32 width)
LLPointer<LLUIImage> LLRender2D::getUIImageByID(const LLUUID& image_id, S32 priority)
{
- if (mImageProvider)
- {
- return mImageProvider->getUIImageByID(image_id, priority);
- }
- else
- {
- return NULL;
- }
+ if (mImageProvider)
+ {
+ return mImageProvider->getUIImageByID(image_id, priority);
+ }
+ else
+ {
+ return NULL;
+ }
}
LLPointer<LLUIImage> LLRender2D::getUIImage(const std::string& name, S32 priority)
{
- if (!name.empty() && mImageProvider)
- return mImageProvider->getUIImage(name, priority);
- else
- return NULL;
+ if (!name.empty() && mImageProvider)
+ return mImageProvider->getUIImage(name, priority);
+ else
+ return NULL;
}
// static
diff --git a/indra/llrender/llrender2dutils.h b/indra/llrender/llrender2dutils.h
index 135738c3ba..c3c6d66b8e 100644
--- a/indra/llrender/llrender2dutils.h
+++ b/indra/llrender/llrender2dutils.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file llrender2dutils.h
* @brief GL function declarations for immediate-mode gl drawing.
*
* $LicenseInfo:firstyear=2012&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -30,12 +30,12 @@
#ifndef LL_RENDER2DUTILS_H
#define LL_RENDER2DUTILS_H
-#include "llpointer.h" // LLPointer<>
+#include "llpointer.h" // LLPointer<>
#include "llrect.h"
#include "llsingleton.h"
#include "llglslshader.h"
-class LLColor4;
+class LLColor4;
class LLVector3;
class LLVector2;
class LLUIImage;
@@ -79,30 +79,30 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre
void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f), bool scale_inner = true);
void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f), const LLRectf& scale_rect = LLRectf(0.f, 1.f, 1.f, 0.f), bool scale_inner = true);
-void gl_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color);
+void gl_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color);
void gl_rect_2d_simple_tex( S32 width, S32 height );
// segmented rectangles
/*
- TL |______TOP_________| TR
- /| |\
+ TL |______TOP_________| TR
+ /| |\
_/_|__________________|_\_
L| | MIDDLE | |R
_|_|__________________|_|_
- \ | BOTTOM | /
+ \ | BOTTOM | /
BL\|__________________|/ BR
- | |
+ | |
*/
typedef enum e_rounded_edge
{
- ROUNDED_RECT_LEFT = 0x1,
- ROUNDED_RECT_TOP = 0x2,
- ROUNDED_RECT_RIGHT = 0x4,
- ROUNDED_RECT_BOTTOM = 0x8,
- ROUNDED_RECT_ALL = 0xf
+ ROUNDED_RECT_LEFT = 0x1,
+ ROUNDED_RECT_TOP = 0x2,
+ ROUNDED_RECT_RIGHT = 0x4,
+ ROUNDED_RECT_BOTTOM = 0x8,
+ ROUNDED_RECT_ALL = 0xf
}ERoundedEdge;
@@ -112,61 +112,61 @@ void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv
inline void gl_rect_2d( const LLRect& rect, BOOL filled )
{
- gl_rect_2d( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, filled );
+ gl_rect_2d( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, filled );
}
inline void gl_rect_2d_offset_local( const LLRect& rect, S32 pixel_offset, BOOL filled)
{
- gl_rect_2d_offset_local( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, pixel_offset, filled );
+ gl_rect_2d_offset_local( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, pixel_offset, filled );
}
class LLImageProviderInterface;
class LLRender2D : public LLParamSingleton<LLRender2D>
{
- LLSINGLETON(LLRender2D, LLImageProviderInterface* image_provider);
- LOG_CLASS(LLRender2D);
- ~LLRender2D();
+ LLSINGLETON(LLRender2D, LLImageProviderInterface* image_provider);
+ LOG_CLASS(LLRender2D);
+ ~LLRender2D();
public:
- static void pushMatrix();
- static void popMatrix();
- static void loadIdentity();
- static void translate(F32 x, F32 y, F32 z = 0.0f);
+ static void pushMatrix();
+ static void popMatrix();
+ static void loadIdentity();
+ static void translate(F32 x, F32 y, F32 z = 0.0f);
- static void setLineWidth(F32 width);
+ static void setLineWidth(F32 width);
- LLPointer<LLUIImage> getUIImageByID(const LLUUID& image_id, S32 priority = 0);
- LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority = 0);
+ LLPointer<LLUIImage> getUIImageByID(const LLUUID& image_id, S32 priority = 0);
+ LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority = 0);
protected:
- // since LLRender2D has no control of image provider's lifecycle
- // we need a way to tell LLRender2D that provider died and
- // LLRender2D needs to be updated.
- static void resetProvider();
+ // since LLRender2D has no control of image provider's lifecycle
+ // we need a way to tell LLRender2D that provider died and
+ // LLRender2D needs to be updated.
+ static void resetProvider();
private:
- LLImageProviderInterface* mImageProvider;
+ LLImageProviderInterface* mImageProvider;
};
class LLImageProviderInterface
{
protected:
- LLImageProviderInterface() {};
- virtual ~LLImageProviderInterface();
+ LLImageProviderInterface() {};
+ virtual ~LLImageProviderInterface();
public:
- virtual LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority) = 0;
- virtual LLPointer<LLUIImage> getUIImageByID(const LLUUID& id, S32 priority) = 0;
- virtual void cleanUp() = 0;
+ virtual LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority) = 0;
+ virtual LLPointer<LLUIImage> getUIImageByID(const LLUUID& id, S32 priority) = 0;
+ virtual void cleanUp() = 0;
- // to notify holders when pointer gets deleted
- typedef void(*callback_t)();
- void addOnRemovalCallback(callback_t func);
- void deleteOnRemovalCallback(callback_t func);
+ // to notify holders when pointer gets deleted
+ typedef void(*callback_t)();
+ void addOnRemovalCallback(callback_t func);
+ void deleteOnRemovalCallback(callback_t func);
private:
- typedef std::list< callback_t > callback_list_t;
- callback_list_t mCallbackList;
+ typedef std::list< callback_t > callback_list_t;
+ callback_list_t mCallbackList;
};
diff --git a/indra/llrender/llrendernavprim.cpp b/indra/llrender/llrendernavprim.cpp
index eea3077632..419c8e8755 100644
--- a/indra/llrender/llrendernavprim.cpp
+++ b/indra/llrender/llrendernavprim.cpp
@@ -1,4 +1,4 @@
-/**
+/**
* @file llrendernavprim.cpp
* @brief Implementation of llrendernavprim
* @author Prep@lindenlab.com
@@ -43,17 +43,17 @@ void LLRenderNavPrim::renderLLTri( const LLVector3& a, const LLVector3& b, const
gGL.color4ubv(color.mV);
gGL.begin(LLRender::TRIANGLES);
- {
- gGL.vertex3fv( a.mV );
- gGL.vertex3fv( b.mV );
- gGL.vertex3fv( c.mV );
- }
- gGL.end();
+ {
+ gGL.vertex3fv( a.mV );
+ gGL.vertex3fv( b.mV );
+ gGL.vertex3fv( c.mV );
+ }
+ gGL.end();
}
//=============================================================================
void LLRenderNavPrim::renderNavMeshVB( U32 mode, LLVertexBuffer* pVBO, int vertCnt )
-{
- pVBO->setBuffer();
- pVBO->drawArrays( mode, 0, vertCnt );
+{
+ pVBO->setBuffer();
+ pVBO->drawArrays( mode, 0, vertCnt );
}
//=============================================================================
diff --git a/indra/llrender/llrendernavprim.h b/indra/llrender/llrendernavprim.h
index a3a5dfec3a..a7b003a6cf 100644
--- a/indra/llrender/llrendernavprim.h
+++ b/indra/llrender/llrendernavprim.h
@@ -1,4 +1,4 @@
-/**
+/**
* @file llrendernavprim.h
* @brief Header file for llrendernavprim
* @author Prep@lindenlab.com
@@ -37,10 +37,10 @@ class LLVertexBuffer;
class LLRenderNavPrim
{
public:
- //Draw simple tri
- void renderLLTri( const LLVector3& a, const LLVector3& b, const LLVector3& c, const LLColor4U& color ) const;
- //Draw the contents of vertex buffer
- void renderNavMeshVB( U32 mode, LLVertexBuffer* pVBO, int vertCnt );
+ //Draw simple tri
+ void renderLLTri( const LLVector3& a, const LLVector3& b, const LLVector3& c, const LLColor4U& color ) const;
+ //Draw the contents of vertex buffer
+ void renderNavMeshVB( U32 mode, LLVertexBuffer* pVBO, int vertCnt );
private:
};
diff --git a/indra/llrender/llrendersphere.cpp b/indra/llrender/llrendersphere.cpp
index 26bfe036e8..9570180554 100644
--- a/indra/llrender/llrendersphere.cpp
+++ b/indra/llrender/llrendersphere.cpp
@@ -1,32 +1,32 @@
-/**
+/**
* @file llrendersphere.cpp
* @brief implementation of the LLRenderSphere class.
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-// Sphere creates a set of display lists that can then be called to create
-// a lit sphere at different LOD levels. You only need one instance of sphere
-// per viewer - then call the appropriate list.
+// Sphere creates a set of display lists that can then be called to create
+// a lit sphere at different LOD levels. You only need one instance of sphere
+// per viewer - then call the appropriate list.
#include "linden_common.h"
@@ -39,53 +39,53 @@ LLRenderSphere gSphere;
void LLRenderSphere::render()
{
- renderGGL();
- gGL.flush();
+ renderGGL();
+ gGL.flush();
}
inline LLVector3 polar_to_cart(F32 latitude, F32 longitude)
{
- return LLVector3(sin(F_TWO_PI * latitude) * cos(F_TWO_PI * longitude),
- sin(F_TWO_PI * latitude) * sin(F_TWO_PI * longitude),
- cos(F_TWO_PI * latitude));
+ return LLVector3(sin(F_TWO_PI * latitude) * cos(F_TWO_PI * longitude),
+ sin(F_TWO_PI * latitude) * sin(F_TWO_PI * longitude),
+ cos(F_TWO_PI * latitude));
}
void LLRenderSphere::renderGGL()
{
- S32 const LATITUDE_SLICES = 20;
- S32 const LONGITUDE_SLICES = 30;
+ S32 const LATITUDE_SLICES = 20;
+ S32 const LONGITUDE_SLICES = 30;
+
+ if (mSpherePoints.empty())
+ {
+ mSpherePoints.resize(LATITUDE_SLICES + 1);
+ for (S32 lat_i = 0; lat_i < LATITUDE_SLICES + 1; lat_i++)
+ {
+ mSpherePoints[lat_i].resize(LONGITUDE_SLICES + 1);
+ for (S32 lon_i = 0; lon_i < LONGITUDE_SLICES + 1; lon_i++)
+ {
+ F32 lat = (F32)lat_i / LATITUDE_SLICES;
+ F32 lon = (F32)lon_i / LONGITUDE_SLICES;
- if (mSpherePoints.empty())
- {
- mSpherePoints.resize(LATITUDE_SLICES + 1);
- for (S32 lat_i = 0; lat_i < LATITUDE_SLICES + 1; lat_i++)
- {
- mSpherePoints[lat_i].resize(LONGITUDE_SLICES + 1);
- for (S32 lon_i = 0; lon_i < LONGITUDE_SLICES + 1; lon_i++)
- {
- F32 lat = (F32)lat_i / LATITUDE_SLICES;
- F32 lon = (F32)lon_i / LONGITUDE_SLICES;
+ mSpherePoints[lat_i][lon_i] = polar_to_cart(lat, lon);
+ }
+ }
+ }
- mSpherePoints[lat_i][lon_i] = polar_to_cart(lat, lon);
- }
- }
- }
-
- gGL.begin(LLRender::TRIANGLES);
+ gGL.begin(LLRender::TRIANGLES);
- for (S32 lat_i = 0; lat_i < LATITUDE_SLICES; lat_i++)
- {
- for (S32 lon_i = 0; lon_i < LONGITUDE_SLICES; lon_i++)
- {
- gGL.vertex3fv(mSpherePoints[lat_i][lon_i].mV);
- gGL.vertex3fv(mSpherePoints[lat_i][lon_i+1].mV);
- gGL.vertex3fv(mSpherePoints[lat_i+1][lon_i].mV);
+ for (S32 lat_i = 0; lat_i < LATITUDE_SLICES; lat_i++)
+ {
+ for (S32 lon_i = 0; lon_i < LONGITUDE_SLICES; lon_i++)
+ {
+ gGL.vertex3fv(mSpherePoints[lat_i][lon_i].mV);
+ gGL.vertex3fv(mSpherePoints[lat_i][lon_i+1].mV);
+ gGL.vertex3fv(mSpherePoints[lat_i+1][lon_i].mV);
- gGL.vertex3fv(mSpherePoints[lat_i+1][lon_i].mV);
- gGL.vertex3fv(mSpherePoints[lat_i][lon_i+1].mV);
- gGL.vertex3fv(mSpherePoints[lat_i+1][lon_i+1].mV);
- }
- }
- gGL.end();
+ gGL.vertex3fv(mSpherePoints[lat_i+1][lon_i].mV);
+ gGL.vertex3fv(mSpherePoints[lat_i][lon_i+1].mV);
+ gGL.vertex3fv(mSpherePoints[lat_i+1][lon_i+1].mV);
+ }
+ }
+ gGL.end();
}
diff --git a/indra/llrender/llrendersphere.h b/indra/llrender/llrendersphere.h
index f8e9e86e7f..e2e886fa06 100644
--- a/indra/llrender/llrendersphere.h
+++ b/indra/llrender/llrendersphere.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file llrendersphere.h
* @brief interface for the LLRenderSphere class.
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -35,16 +35,16 @@
#include "v4color.h"
#include "llgl.h"
-void lat2xyz(LLVector3 * result, F32 lat, F32 lon); // utility routine
+void lat2xyz(LLVector3 * result, F32 lat, F32 lon); // utility routine
-class LLRenderSphere
+class LLRenderSphere
{
public:
- void render(); // render at highest LOD
- void renderGGL(); // render using LLRender
+ void render(); // render at highest LOD
+ void renderGGL(); // render using LLRender
private:
- std::vector< std::vector<LLVector3> > mSpherePoints;
+ std::vector< std::vector<LLVector3> > mSpherePoints;
};
extern LLRenderSphere gSphere;
diff --git a/indra/llrender/lltexture.cpp b/indra/llrender/lltexture.cpp
index 6eef36216c..980c0950f9 100644
--- a/indra/llrender/lltexture.cpp
+++ b/indra/llrender/lltexture.cpp
@@ -1,31 +1,31 @@
-/**
+/**
* @file lltexture.cpp
*
* $LicenseInfo:firstyear=2000&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "lltexture.h"
-//virtual
+//virtual
LLTexture::~LLTexture()
{
}
@@ -36,8 +36,8 @@ bool LLTexture::bindDefaultImage(const S32 stage) { llassert(false); return fals
bool LLTexture::bindDebugImage(const S32 stage) { llassert(false); return false; }
void LLTexture::forceImmediateUpdate() { llassert(false); }
void LLTexture::setActive() { llassert(false); }
-S32 LLTexture::getWidth(S32 discard_level) const { llassert(false); return 0; }
-S32 LLTexture::getHeight(S32 discard_level) const { llassert(false); return 0; }
+S32 LLTexture::getWidth(S32 discard_level) const { llassert(false); return 0; }
+S32 LLTexture::getHeight(S32 discard_level) const { llassert(false); return 0; }
bool LLTexture::isActiveFetching() { llassert(false); return false; }
LLImageGL* LLTexture::getGLTexture() const { llassert(false); return nullptr; }
void LLTexture::updateBindStatsForTester() { }
diff --git a/indra/llrender/lltexture.h b/indra/llrender/lltexture.h
index e890a5a30b..35cded86f2 100644
--- a/indra/llrender/lltexture.h
+++ b/indra/llrender/lltexture.h
@@ -1,30 +1,30 @@
-/**
+/**
* @file lltexture.h
* @brief LLTexture 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.
+ * 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=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -44,32 +44,32 @@ class LLFontGL ;
//
class LLTexture : public virtual LLRefCount
{
- friend class LLTexUnit ;
- friend class LLFontGL ;
+ friend class LLTexUnit ;
+ friend class LLFontGL ;
protected:
- virtual ~LLTexture();
+ virtual ~LLTexture();
public:
- LLTexture()
- {}
+ LLTexture()
+ {}
- //
- //interfaces to access LLGLTexture
- //
- virtual S8 getType() const;
- virtual void setKnownDrawSize(S32 width, S32 height);
- virtual bool bindDefaultImage(const S32 stage = 0);
- virtual bool bindDebugImage(const S32 stage = 0);
- virtual void forceImmediateUpdate();
- virtual void setActive();
- virtual S32 getWidth(S32 discard_level = -1) const;
- virtual S32 getHeight(S32 discard_level = -1) const;
- virtual bool isActiveFetching();
+ //
+ //interfaces to access LLGLTexture
+ //
+ virtual S8 getType() const;
+ virtual void setKnownDrawSize(S32 width, S32 height);
+ virtual bool bindDefaultImage(const S32 stage = 0);
+ virtual bool bindDebugImage(const S32 stage = 0);
+ virtual void forceImmediateUpdate();
+ virtual void setActive();
+ virtual S32 getWidth(S32 discard_level = -1) const;
+ virtual S32 getHeight(S32 discard_level = -1) const;
+ virtual bool isActiveFetching();
virtual LLImageGL* getGLTexture() const;
private:
- virtual void updateBindStatsForTester();
+ virtual void updateBindStatsForTester();
};
#endif
diff --git a/indra/llrender/lltexturemanagerbridge.cpp b/indra/llrender/lltexturemanagerbridge.cpp
index 33f2185e4f..c243f0697a 100644
--- a/indra/llrender/lltexturemanagerbridge.cpp
+++ b/indra/llrender/lltexturemanagerbridge.cpp
@@ -1,25 +1,25 @@
- /**
+ /**
* @file lltexturemanagerbridge.cpp
* @brief Defined a null texture manager bridge. Applications must provide their own bridge implementaton.
*
* $LicenseInfo:firstyear=2012&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
diff --git a/indra/llrender/lltexturemanagerbridge.h b/indra/llrender/lltexturemanagerbridge.h
index f61433ea4d..0b76ee4de8 100644
--- a/indra/llrender/lltexturemanagerbridge.h
+++ b/indra/llrender/lltexturemanagerbridge.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file lltexturemanagerbridge.h
* @brief Bridge to an application-specific texture manager.
*
* $LicenseInfo:firstyear=2012&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -36,9 +36,9 @@ class LLTextureManagerBridge
public:
virtual ~LLTextureManagerBridge() {}
- virtual LLPointer<LLGLTexture> getLocalTexture(BOOL usemipmaps = TRUE, BOOL generate_gl_tex = TRUE) = 0;
- virtual LLPointer<LLGLTexture> getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex = TRUE) = 0;
- virtual LLGLTexture* getFetchedTexture(const LLUUID &image_id) = 0;
+ virtual LLPointer<LLGLTexture> getLocalTexture(BOOL usemipmaps = TRUE, BOOL generate_gl_tex = TRUE) = 0;
+ virtual LLPointer<LLGLTexture> getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex = TRUE) = 0;
+ virtual LLGLTexture* getFetchedTexture(const LLUUID &image_id) = 0;
};
extern LLTextureManagerBridge* gTextureManagerBridgep;
diff --git a/indra/llrender/lluiimage.cpp b/indra/llrender/lluiimage.cpp
index 424672fe8e..bcf665ca18 100644
--- a/indra/llrender/lluiimage.cpp
+++ b/indra/llrender/lluiimage.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file lluiimage.cpp
* @brief UI implementation
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -33,12 +33,12 @@
#include "lluiimage.h"
LLUIImage::LLUIImage(const std::string& name, LLPointer<LLTexture> image)
-: mName(name),
- mImage(image),
- mScaleRegion(0.f, 1.f, 1.f, 0.f),
- mClipRegion(0.f, 1.f, 1.f, 0.f),
- mImageLoaded(NULL),
- mScaleStyle(SCALE_INNER),
+: mName(name),
+ mImage(image),
+ mScaleRegion(0.f, 1.f, 1.f, 0.f),
+ mClipRegion(0.f, 1.f, 1.f, 0.f),
+ mImageLoaded(NULL),
+ mScaleStyle(SCALE_INNER),
mCachedW(-1),
mCachedH(-1)
{
@@ -48,125 +48,125 @@ LLUIImage::LLUIImage(const std::string& name, LLPointer<LLTexture> image)
LLUIImage::~LLUIImage()
{
- delete mImageLoaded;
+ delete mImageLoaded;
}
S32 LLUIImage::getWidth() const
-{
- // return clipped dimensions of actual image area
- return ll_round((F32)mImage->getWidth(0) * mClipRegion.getWidth());
+{
+ // return clipped dimensions of actual image area
+ return ll_round((F32)mImage->getWidth(0) * mClipRegion.getWidth());
}
S32 LLUIImage::getHeight() const
-{
- // return clipped dimensions of actual image area
- return ll_round((F32)mImage->getHeight(0) * mClipRegion.getHeight());
+{
+ // return clipped dimensions of actual image area
+ return ll_round((F32)mImage->getHeight(0) * mClipRegion.getHeight());
}
-void LLUIImage::draw3D(const LLVector3& origin_agent, const LLVector3& x_axis, const LLVector3& y_axis,
- const LLRect& rect, const LLColor4& color)
+void LLUIImage::draw3D(const LLVector3& origin_agent, const LLVector3& x_axis, const LLVector3& y_axis,
+ const LLRect& rect, const LLColor4& color)
{
- F32 border_scale = 1.f;
- F32 border_height = (1.f - mScaleRegion.getHeight()) * getHeight();
- F32 border_width = (1.f - mScaleRegion.getWidth()) * getWidth();
- if (rect.getHeight() < border_height || rect.getWidth() < border_width)
- {
- if(border_height - rect.getHeight() > border_width - rect.getWidth())
- {
- border_scale = (F32)rect.getHeight() / border_height;
- }
- else
- {
- border_scale = (F32)rect.getWidth() / border_width;
- }
- }
-
- LLRender2D::getInstance()->pushMatrix();
- {
- LLVector3 rect_origin = origin_agent + (rect.mLeft * x_axis) + (rect.mBottom * y_axis);
- LLRender2D::getInstance()->translate(rect_origin.mV[VX],
- rect_origin.mV[VY],
- rect_origin.mV[VZ]);
- gGL.getTexUnit(0)->bind(getImage());
- gGL.color4fv(color.mV);
-
- LLRectf center_uv_rect(mClipRegion.mLeft + mScaleRegion.mLeft * mClipRegion.getWidth(),
- mClipRegion.mBottom + mScaleRegion.mTop * mClipRegion.getHeight(),
- mClipRegion.mLeft + mScaleRegion.mRight * mClipRegion.getWidth(),
- mClipRegion.mBottom + mScaleRegion.mBottom * mClipRegion.getHeight());
- gl_segmented_rect_3d_tex(mClipRegion,
- center_uv_rect,
- LLRectf(border_width * border_scale * 0.5f / (F32)rect.getWidth(),
- (rect.getHeight() - (border_height * border_scale * 0.5f)) / (F32)rect.getHeight(),
- (rect.getWidth() - (border_width * border_scale * 0.5f)) / (F32)rect.getWidth(),
- (border_height * border_scale * 0.5f) / (F32)rect.getHeight()),
- rect.getWidth() * x_axis,
- rect.getHeight() * y_axis);
-
- } LLRender2D::getInstance()->popMatrix();
+ F32 border_scale = 1.f;
+ F32 border_height = (1.f - mScaleRegion.getHeight()) * getHeight();
+ F32 border_width = (1.f - mScaleRegion.getWidth()) * getWidth();
+ if (rect.getHeight() < border_height || rect.getWidth() < border_width)
+ {
+ if(border_height - rect.getHeight() > border_width - rect.getWidth())
+ {
+ border_scale = (F32)rect.getHeight() / border_height;
+ }
+ else
+ {
+ border_scale = (F32)rect.getWidth() / border_width;
+ }
+ }
+
+ LLRender2D::getInstance()->pushMatrix();
+ {
+ LLVector3 rect_origin = origin_agent + (rect.mLeft * x_axis) + (rect.mBottom * y_axis);
+ LLRender2D::getInstance()->translate(rect_origin.mV[VX],
+ rect_origin.mV[VY],
+ rect_origin.mV[VZ]);
+ gGL.getTexUnit(0)->bind(getImage());
+ gGL.color4fv(color.mV);
+
+ LLRectf center_uv_rect(mClipRegion.mLeft + mScaleRegion.mLeft * mClipRegion.getWidth(),
+ mClipRegion.mBottom + mScaleRegion.mTop * mClipRegion.getHeight(),
+ mClipRegion.mLeft + mScaleRegion.mRight * mClipRegion.getWidth(),
+ mClipRegion.mBottom + mScaleRegion.mBottom * mClipRegion.getHeight());
+ gl_segmented_rect_3d_tex(mClipRegion,
+ center_uv_rect,
+ LLRectf(border_width * border_scale * 0.5f / (F32)rect.getWidth(),
+ (rect.getHeight() - (border_height * border_scale * 0.5f)) / (F32)rect.getHeight(),
+ (rect.getWidth() - (border_width * border_scale * 0.5f)) / (F32)rect.getWidth(),
+ (border_height * border_scale * 0.5f) / (F32)rect.getHeight()),
+ rect.getWidth() * x_axis,
+ rect.getHeight() * y_axis);
+
+ } LLRender2D::getInstance()->popMatrix();
}
//#include "lluiimage.inl"
-boost::signals2::connection LLUIImage::addLoadedCallback( const image_loaded_signal_t::slot_type& cb )
+boost::signals2::connection LLUIImage::addLoadedCallback( const image_loaded_signal_t::slot_type& cb )
{
- if (!mImageLoaded)
- {
- mImageLoaded = new image_loaded_signal_t();
- }
- return mImageLoaded->connect(cb);
+ if (!mImageLoaded)
+ {
+ mImageLoaded = new image_loaded_signal_t();
+ }
+ return mImageLoaded->connect(cb);
}
void LLUIImage::onImageLoaded()
{
- if (mImageLoaded)
- {
- (*mImageLoaded)();
- }
+ if (mImageLoaded)
+ {
+ (*mImageLoaded)();
+ }
}
namespace LLInitParam
{
- void ParamValue<LLUIImage*>::updateValueFromBlock()
- {
- // The keyword "none" is specifically requesting a null image
- // do not default to current value. Used to overwrite template images.
- if (name() == "none")
- {
- updateValue(NULL);
- return;
- }
-
- LLUIImage* imagep = LLRender2D::getInstance()->getUIImage(name());
- if (imagep)
- {
- updateValue(imagep);
- }
- }
-
- void ParamValue<LLUIImage*>::updateBlockFromValue(bool make_block_authoritative)
- {
- if (getValue() == NULL)
- {
- name.set("none", make_block_authoritative);
- }
- else
- {
- name.set(getValue()->getName(), make_block_authoritative);
- }
- }
-
-
- bool ParamCompare<LLUIImage*, false>::equals(
- LLUIImage* const &a,
- LLUIImage* const &b)
- {
- // force all LLUIImages for XML UI export to be "non-default"
- if (!a && !b)
- return false;
- else
- return (a == b);
- }
+ void ParamValue<LLUIImage*>::updateValueFromBlock()
+ {
+ // The keyword "none" is specifically requesting a null image
+ // do not default to current value. Used to overwrite template images.
+ if (name() == "none")
+ {
+ updateValue(NULL);
+ return;
+ }
+
+ LLUIImage* imagep = LLRender2D::getInstance()->getUIImage(name());
+ if (imagep)
+ {
+ updateValue(imagep);
+ }
+ }
+
+ void ParamValue<LLUIImage*>::updateBlockFromValue(bool make_block_authoritative)
+ {
+ if (getValue() == NULL)
+ {
+ name.set("none", make_block_authoritative);
+ }
+ else
+ {
+ name.set(getValue()->getName(), make_block_authoritative);
+ }
+ }
+
+
+ bool ParamCompare<LLUIImage*, false>::equals(
+ LLUIImage* const &a,
+ LLUIImage* const &b)
+ {
+ // force all LLUIImages for XML UI export to be "non-default"
+ if (!a && !b)
+ return false;
+ else
+ return (a == b);
+ }
}
diff --git a/indra/llrender/lluiimage.h b/indra/llrender/lluiimage.h
index e462e19004..7988243a89 100644
--- a/indra/llrender/lluiimage.h
+++ b/indra/llrender/lluiimage.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file lluiimage.h
* @brief wrapper for images used in the UI that handles smart scaling, etc.
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -43,70 +43,70 @@ extern const LLColor4 UI_VERTEX_COLOR;
class LLUIImage : public LLRefCount
{
public:
- enum EScaleStyle
- {
- SCALE_INNER,
- SCALE_OUTER
- };
+ enum EScaleStyle
+ {
+ SCALE_INNER,
+ SCALE_OUTER
+ };
- typedef boost::signals2::signal<void (void)> image_loaded_signal_t;
+ typedef boost::signals2::signal<void (void)> image_loaded_signal_t;
- LLUIImage(const std::string& name, LLPointer<LLTexture> image);
- virtual ~LLUIImage();
+ LLUIImage(const std::string& name, LLPointer<LLTexture> image);
+ virtual ~LLUIImage();
- LL_FORCE_INLINE void setClipRegion(const LLRectf& region)
- {
- mClipRegion = region;
+ LL_FORCE_INLINE void setClipRegion(const LLRectf& region)
+ {
+ mClipRegion = region;
}
- LL_FORCE_INLINE void setScaleRegion(const LLRectf& region)
- {
- mScaleRegion = region;
+ LL_FORCE_INLINE void setScaleRegion(const LLRectf& region)
+ {
+ mScaleRegion = region;
}
- LL_FORCE_INLINE void setScaleStyle(EScaleStyle style)
+ LL_FORCE_INLINE void setScaleStyle(EScaleStyle style)
{
- mScaleStyle = style;
+ mScaleStyle = style;
}
- LL_FORCE_INLINE LLPointer<LLTexture> getImage() { return mImage; }
- LL_FORCE_INLINE const LLPointer<LLTexture>& getImage() const { return mImage; }
+ LL_FORCE_INLINE LLPointer<LLTexture> getImage() { return mImage; }
+ LL_FORCE_INLINE const LLPointer<LLTexture>& getImage() const { return mImage; }
+
+ LL_FORCE_INLINE void draw(S32 x, S32 y, S32 width, S32 height, const LLColor4& color = UI_VERTEX_COLOR) const;
+ LL_FORCE_INLINE void draw(S32 x, S32 y, const LLColor4& color = UI_VERTEX_COLOR) const;
+ LL_FORCE_INLINE void draw(const LLRect& rect, const LLColor4& color = UI_VERTEX_COLOR) const { draw(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(), color); }
- LL_FORCE_INLINE void draw(S32 x, S32 y, S32 width, S32 height, const LLColor4& color = UI_VERTEX_COLOR) const;
- LL_FORCE_INLINE void draw(S32 x, S32 y, const LLColor4& color = UI_VERTEX_COLOR) const;
- LL_FORCE_INLINE void draw(const LLRect& rect, const LLColor4& color = UI_VERTEX_COLOR) const { draw(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(), color); }
-
- LL_FORCE_INLINE void drawSolid(S32 x, S32 y, S32 width, S32 height, const LLColor4& color) const;
- LL_FORCE_INLINE void drawSolid(const LLRect& rect, const LLColor4& color) const { drawSolid(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(), color); }
- LL_FORCE_INLINE void drawSolid(S32 x, S32 y, const LLColor4& color) const { drawSolid(x, y, getWidth(), getHeight(), color); }
+ LL_FORCE_INLINE void drawSolid(S32 x, S32 y, S32 width, S32 height, const LLColor4& color) const;
+ LL_FORCE_INLINE void drawSolid(const LLRect& rect, const LLColor4& color) const { drawSolid(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(), color); }
+ LL_FORCE_INLINE void drawSolid(S32 x, S32 y, const LLColor4& color) const { drawSolid(x, y, getWidth(), getHeight(), color); }
- LL_FORCE_INLINE void drawBorder(S32 x, S32 y, S32 width, S32 height, const LLColor4& color, S32 border_width) const;
- LL_FORCE_INLINE void drawBorder(const LLRect& rect, const LLColor4& color, S32 border_width) const { drawBorder(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(), color, border_width); }
- LL_FORCE_INLINE void drawBorder(S32 x, S32 y, const LLColor4& color, S32 border_width) const { drawBorder(x, y, getWidth(), getHeight(), color, border_width); }
+ LL_FORCE_INLINE void drawBorder(S32 x, S32 y, S32 width, S32 height, const LLColor4& color, S32 border_width) const;
+ LL_FORCE_INLINE void drawBorder(const LLRect& rect, const LLColor4& color, S32 border_width) const { drawBorder(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(), color, border_width); }
+ LL_FORCE_INLINE void drawBorder(S32 x, S32 y, const LLColor4& color, S32 border_width) const { drawBorder(x, y, getWidth(), getHeight(), color, border_width); }
- void draw3D(const LLVector3& origin_agent, const LLVector3& x_axis, const LLVector3& y_axis, const LLRect& rect, const LLColor4& color);
+ void draw3D(const LLVector3& origin_agent, const LLVector3& x_axis, const LLVector3& y_axis, const LLRect& rect, const LLColor4& color);
- LL_FORCE_INLINE const std::string& getName() const { return mName; }
+ LL_FORCE_INLINE const std::string& getName() const { return mName; }
- virtual S32 getWidth() const;
- virtual S32 getHeight() const;
+ virtual S32 getWidth() const;
+ virtual S32 getHeight() const;
- // returns dimensions of underlying textures, which might not be equal to ui image portion
- LL_FORCE_INLINE S32 getTextureWidth() const;
- LL_FORCE_INLINE S32 getTextureHeight() const;
+ // returns dimensions of underlying textures, which might not be equal to ui image portion
+ LL_FORCE_INLINE S32 getTextureWidth() const;
+ LL_FORCE_INLINE S32 getTextureHeight() const;
- boost::signals2::connection addLoadedCallback( const image_loaded_signal_t::slot_type& cb );
+ boost::signals2::connection addLoadedCallback( const image_loaded_signal_t::slot_type& cb );
- void onImageLoaded();
+ void onImageLoaded();
protected:
- image_loaded_signal_t* mImageLoaded;
+ image_loaded_signal_t* mImageLoaded;
- std::string mName;
- LLRectf mScaleRegion;
- LLRectf mClipRegion;
- LLPointer<LLTexture> mImage;
- EScaleStyle mScaleStyle;
+ std::string mName;
+ LLRectf mScaleRegion;
+ LLRectf mClipRegion;
+ LLPointer<LLTexture> mImage;
+ EScaleStyle mScaleStyle;
mutable S32 mCachedW;
mutable S32 mCachedH;
};
@@ -115,33 +115,33 @@ protected:
namespace LLInitParam
{
- template<>
- class ParamValue<LLUIImage*>
- : public CustomParamValue<LLUIImage*>
- {
- typedef boost::add_reference<boost::add_const<LLUIImage*>::type>::type T_const_ref;
- typedef CustomParamValue<LLUIImage*> super_t;
- public:
- Optional<std::string> name;
-
- ParamValue(LLUIImage* const& image = NULL)
- : super_t(image)
- {
- updateBlockFromValue(false);
- addSynonym(name, "name");
- }
-
- void updateValueFromBlock();
- void updateBlockFromValue(bool make_block_authoritative);
- };
-
- // Need custom comparison function for our test app, which only loads
- // LLUIImage* as NULL.
- template<>
- struct ParamCompare<LLUIImage*, false>
- {
- static bool equals(LLUIImage* const &a, LLUIImage* const &b);
- };
+ template<>
+ class ParamValue<LLUIImage*>
+ : public CustomParamValue<LLUIImage*>
+ {
+ typedef boost::add_reference<boost::add_const<LLUIImage*>::type>::type T_const_ref;
+ typedef CustomParamValue<LLUIImage*> super_t;
+ public:
+ Optional<std::string> name;
+
+ ParamValue(LLUIImage* const& image = NULL)
+ : super_t(image)
+ {
+ updateBlockFromValue(false);
+ addSynonym(name, "name");
+ }
+
+ void updateValueFromBlock();
+ void updateBlockFromValue(bool make_block_authoritative);
+ };
+
+ // Need custom comparison function for our test app, which only loads
+ // LLUIImage* as NULL.
+ template<>
+ struct ParamCompare<LLUIImage*, false>
+ {
+ static bool equals(LLUIImage* const &a, LLUIImage* const &b);
+ };
}
typedef LLPointer<LLUIImage> LLUIImagePtr;
diff --git a/indra/llrender/lluiimage.inl b/indra/llrender/lluiimage.inl
index f5227556f0..a69616c0c1 100644
--- a/indra/llrender/lluiimage.inl
+++ b/indra/llrender/lluiimage.inl
@@ -1,66 +1,66 @@
-/**
+/**
* @file lluiimage.inl
* @brief UI inline func implementation
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
void LLUIImage::draw(S32 x, S32 y, const LLColor4& color) const
{
- draw(x, y, getWidth(), getHeight(), color);
+ draw(x, y, getWidth(), getHeight(), color);
}
void LLUIImage::draw(S32 x, S32 y, S32 width, S32 height, const LLColor4& color) const
{
- gl_draw_scaled_image_with_border(
- x, y,
- width, height,
- mImage,
- color,
- FALSE,
- mClipRegion,
- mScaleRegion,
- mScaleStyle == SCALE_INNER);
+ gl_draw_scaled_image_with_border(
+ x, y,
+ width, height,
+ mImage,
+ color,
+ FALSE,
+ mClipRegion,
+ mScaleRegion,
+ mScaleStyle == SCALE_INNER);
}
void LLUIImage::drawSolid(S32 x, S32 y, S32 width, S32 height, const LLColor4& color) const
{
- gl_draw_scaled_image_with_border(
- x, y,
- width, height,
- mImage,
- color,
- TRUE,
- mClipRegion,
- mScaleRegion,
- mScaleStyle == SCALE_INNER);
+ gl_draw_scaled_image_with_border(
+ x, y,
+ width, height,
+ mImage,
+ color,
+ TRUE,
+ mClipRegion,
+ mScaleRegion,
+ mScaleStyle == SCALE_INNER);
}
void LLUIImage::drawBorder(S32 x, S32 y, S32 width, S32 height, const LLColor4& color, S32 border_width) const
{
- LLRect border_rect;
- border_rect.setOriginAndSize(x, y, width, height);
- border_rect.stretch(border_width, border_width);
- drawSolid(border_rect, color);
+ LLRect border_rect;
+ border_rect.setOriginAndSize(x, y, width, height);
+ border_rect.stretch(border_width, border_width);
+ drawSolid(border_rect, color);
}
// returns dimensions of underlying textures, which might not be equal to ui image portion