335 lines
7.7 KiB
C++
335 lines
7.7 KiB
C++
/**
|
|
* @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$
|
|
*/
|
|
#include "linden_common.h"
|
|
|
|
#include "llworkerthread.h"
|
|
|
|
#include "llcubemap.h"
|
|
|
|
#include "v4coloru.h"
|
|
#include "v3math.h"
|
|
#include "v3dmath.h"
|
|
#include "m3math.h"
|
|
#include "m4math.h"
|
|
|
|
#include "llrender.h"
|
|
#include "llglslshader.h"
|
|
|
|
#include "llglheaders.h"
|
|
|
|
namespace {
|
|
const U16 RESOLUTION = 64;
|
|
}
|
|
|
|
bool LLCubeMap::sUseCubeMaps = true;
|
|
|
|
LLCubeMap::LLCubeMap(bool init_as_srgb)
|
|
: mTextureStage(0),
|
|
mMatrixStage(0),
|
|
mIssRGB(init_as_srgb)
|
|
{
|
|
mTargets[0] = GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB;
|
|
mTargets[1] = GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB;
|
|
mTargets[2] = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB;
|
|
mTargets[3] = GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB;
|
|
mTargets[4] = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB;
|
|
mTargets[5] = GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB;
|
|
}
|
|
|
|
LLCubeMap::~LLCubeMap()
|
|
{
|
|
}
|
|
|
|
void LLCubeMap::initGL()
|
|
{
|
|
llassert(gGLManager.mInited);
|
|
|
|
if (gGLManager.mHasCubeMap && 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;
|
|
}
|
|
}
|
|
|
|
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++);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void LLCubeMap::initGLData()
|
|
{
|
|
LL_PROFILE_ZONE_SCOPED;
|
|
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();
|
|
}
|
|
}
|
|
|
|
void LLCubeMap::initReflectionMap(U32 resolution, U32 components)
|
|
{
|
|
U32 texname = 0;
|
|
|
|
LLImageGL::generateTextures(1, &texname);
|
|
|
|
mImages[0] = new LLImageGL(resolution, resolution, components, TRUE);
|
|
mImages[0]->setTexName(texname);
|
|
mImages[0]->setTarget(mTargets[0], LLTexUnit::TT_CUBE_MAP);
|
|
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_CUBE_MAP, texname);
|
|
mImages[0]->setAddressMode(LLTexUnit::TAM_CLAMP);
|
|
}
|
|
|
|
void LLCubeMap::initEnvironmentMap(const std::vector<LLPointer<LLImageRaw> >& rawimages)
|
|
{
|
|
llassert(rawimages.size() == 6);
|
|
|
|
U32 texname = 0;
|
|
|
|
LLImageGL::generateTextures(1, &texname);
|
|
|
|
U32 resolution = rawimages[0]->getWidth();
|
|
U32 components = rawimages[0]->getComponents();
|
|
|
|
for (int i = 0; i < 6; i++)
|
|
{
|
|
llassert(rawimages[i]->getWidth() == resolution);
|
|
llassert(rawimages[i]->getHeight() == resolution);
|
|
llassert(rawimages[i]->getComponents() == components);
|
|
|
|
mImages[i] = new LLImageGL(resolution, resolution, components, TRUE);
|
|
mImages[i]->setTarget(mTargets[i], LLTexUnit::TT_CUBE_MAP);
|
|
mRawImages[i] = rawimages[i];
|
|
mImages[i]->createGLTexture(0, mRawImages[i], texname);
|
|
|
|
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_CUBE_MAP, texname);
|
|
mImages[i]->setAddressMode(LLTexUnit::TAM_CLAMP);
|
|
stop_glerror();
|
|
|
|
mImages[i]->setSubImage(mRawImages[i], 0, 0, resolution, resolution);
|
|
}
|
|
enableTexture(0);
|
|
bind();
|
|
mImages[0]->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
|
|
glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
|
|
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
|
|
gGL.getTexUnit(0)->disable();
|
|
disable();
|
|
}
|
|
|
|
void LLCubeMap::generateMipMaps()
|
|
{
|
|
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
|
|
|
mImages[0]->setUseMipMaps(TRUE);
|
|
mImages[0]->setHasMipMaps(TRUE);
|
|
enableTexture(0);
|
|
bind();
|
|
mImages[0]->setFilteringOption(LLTexUnit::TFO_BILINEAR);
|
|
{
|
|
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("cmgmm - glGenerateMipmap");
|
|
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
|
|
}
|
|
gGL.getTexUnit(0)->disable();
|
|
disable();
|
|
}
|
|
|
|
GLuint LLCubeMap::getGLName()
|
|
{
|
|
return mImages[0]->getTexName();
|
|
}
|
|
|
|
void LLCubeMap::bind()
|
|
{
|
|
gGL.getTexUnit(mTextureStage)->bind(this);
|
|
}
|
|
|
|
void LLCubeMap::enable(S32 stage)
|
|
{
|
|
enableTexture(stage);
|
|
}
|
|
|
|
void LLCubeMap::enableTexture(S32 stage)
|
|
{
|
|
mTextureStage = stage;
|
|
if (gGLManager.mHasCubeMap && stage >= 0 && LLCubeMap::sUseCubeMaps)
|
|
{
|
|
gGL.getTexUnit(stage)->enable(LLTexUnit::TT_CUBE_MAP);
|
|
}
|
|
}
|
|
|
|
void LLCubeMap::disable(void)
|
|
{
|
|
disableTexture();
|
|
}
|
|
|
|
void LLCubeMap::disableTexture(void)
|
|
{
|
|
if (gGLManager.mHasCubeMap && 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();
|
|
}*/
|
|
}
|
|
|
|
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();
|
|
}*/
|
|
}
|
|
|
|
|
|
void LLCubeMap::destroyGL()
|
|
{
|
|
for (S32 i = 0; i < 6; i++)
|
|
{
|
|
mImages[i] = NULL;
|
|
}
|
|
}
|