123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296 |
- /**
- * @file llcubemap.cpp
- * @brief LLCubeMap class implementation
- *
- * $LicenseInfo:firstyear=2002&license=viewergpl$
- *
- * Copyright (c) 2002-2009, Linden Research, Inc.
- *
- * Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- *
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
- *
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- *
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
- #include "linden_common.h"
- #include "llcubemap.h"
- #include "llglslshader.h"
- #include "llmatrix4a.h"
- #include "llrender.h"
- #include "llvector3.h"
- constexpr U16 RESOLUTION = 64;
- LLCubeMap::LLCubeMap(bool 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;
- }
- void LLCubeMap::initGL()
- {
- llassert(gGLManager.mInited);
- if (mImages[0].isNull())
- {
- U32 texname = 0;
- LLImageGL::generateTextures(1, &texname);
- LLTexUnit* unit0 = gGL.getTexUnit(0);
- for (S32 i = 0; i < 6; ++i)
- {
- mImages[i] = new LLImageGL(RESOLUTION, RESOLUTION, 4, false);
- mImages[i]->setTarget(mTargets[i], LLTexUnit::TT_CUBE_MAP);
- mRawImages[i] = new LLImageRaw(RESOLUTION, RESOLUTION, 4);
- mImages[i]->createGLTexture(0, mRawImages[i], texname);
- unit0->bindManual(LLTexUnit::TT_CUBE_MAP, texname);
- mImages[i]->setAddressMode(LLTexUnit::TAM_CLAMP);
- stop_glerror();
- }
- unit0->disable();
- }
- disableTexture();
- }
- void LLCubeMap::destroyGL()
- {
- for (S32 i = 0; i < 6; ++i)
- {
- mImages[i] = NULL;
- }
- }
- 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 (S32 i = 0; i < 6; ++i)
- {
- const U8* sd = rawimages[i]->getData();
- U8* td = mRawImages[i]->getData();
- if (!sd || !td)
- {
- continue;
- }
- S32 offset = 0;
- S32 sx, sy, so;
- for (S32 y = 0; y < RESOLUTION; ++y)
- {
- for (S32 x = 0; x < RESOLUTION; ++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 = RESOLUTION * sy + sx;
- so *= 4;
- *(td + offset++) = *(sd + so++);
- *(td + offset++) = *(sd + so++);
- *(td + offset++) = *(sd + so++);
- *(td + offset++) = *(sd + so++);
- }
- }
- }
- }
- void LLCubeMap::initGLData()
- {
- for (S32 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::bind()
- {
- gGL.getTexUnit(mTextureStage)->bind(this);
- }
- void LLCubeMap::enableTexture(S32 stage)
- {
- mTextureStage = stage;
- if (stage >= 0)
- {
- gGL.getTexUnit(stage)->enable(LLTexUnit::TT_CUBE_MAP);
- }
- }
- void LLCubeMap::disableTexture()
- {
- if (mTextureStage >= 0)
- {
- LLTexUnit* unit = gGL.getTexUnit(mTextureStage);
- unit->disable();
- if (mTextureStage == 0)
- {
- unit->enable(LLTexUnit::TT_TEXTURE);
- }
- }
- }
- void LLCubeMap::setMatrix(S32 stage)
- {
- mMatrixStage = stage;
- if (mMatrixStage < 0) return;
- #if 0
- if (stage > 0)
- #endif
- {
- gGL.getTexUnit(stage)->activate();
- }
- LLMatrix4a trans(gGLModelView);
- trans.setRow<3>(LLVector4a::getZero());
- trans.transpose();
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.pushMatrix();
- gGL.loadMatrix(trans);
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- #if 0
- if (stage > 0)
- {
- gGL.getTexUnit(0)->activate();
- }
- #endif
- }
- void LLCubeMap::restoreMatrix()
- {
- if (mMatrixStage < 0) return;
- #if 0
- if (mMatrixStage > 0)
- #endif
- {
- gGL.getTexUnit(mMatrixStage)->activate();
- }
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.popMatrix();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- #if 0
- if (mMatrixStage > 0)
- {
- gGL.getTexUnit(0)->activate();
- }
- #endif
- }
- 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();
- LLTexUnit* unit0 = gGL.getTexUnit(0);
- for (U32 i = 0; i < 6; ++i)
- {
- llassert(rawimages[i]->getWidth() == resolution &&
- rawimages[i]->getHeight() == resolution &&
- (U32)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);
- unit0->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);
- unit0->disable();
- disableTexture();
- }
- void LLCubeMap::generateMipMaps()
- {
- mImages[0]->setUseMipMaps(true);
- mImages[0]->setHasMipMaps(true);
- enableTexture(0);
- bind();
- mImages[0]->setFilteringOption(LLTexUnit::TFO_BILINEAR);
- glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
- gGL.getTexUnit(0)->disable();
- disableTexture();
- }
|