diff options
Diffstat (limited to 'indra/llrender/llcubemap.cpp')
-rw-r--r-- | indra/llrender/llcubemap.cpp | 275 |
1 files changed, 79 insertions, 196 deletions
diff --git a/indra/llrender/llcubemap.cpp b/indra/llrender/llcubemap.cpp index 834084674e..254288a86e 100644 --- a/indra/llrender/llcubemap.cpp +++ b/indra/llrender/llcubemap.cpp @@ -40,8 +40,9 @@ #include "llglheaders.h" -const F32 epsilon = 1e-7f; -const U16 RESOLUTION = 64; +namespace { + const U16 RESOLUTION = 64; +} bool LLCubeMap::sUseCubeMaps = true; @@ -50,12 +51,12 @@ LLCubeMap::LLCubeMap(bool init_as_srgb) 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; + 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() @@ -66,7 +67,7 @@ void LLCubeMap::initGL() { llassert(gGLManager.mInited); - if (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps) + if (LLCubeMap::sUseCubeMaps) { // Not initialized, do stuff. if (mImages[0].isNull()) @@ -166,6 +167,73 @@ void LLCubeMap::init(const std::vector<LLPointer<LLImageRaw> >& rawimages) } } +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(); @@ -184,7 +252,7 @@ void LLCubeMap::enable(S32 stage) void LLCubeMap::enableTexture(S32 stage) { mTextureStage = stage; - if (gGLManager.mHasCubeMap && stage >= 0 && LLCubeMap::sUseCubeMaps) + if (stage >= 0 && LLCubeMap::sUseCubeMaps) { gGL.getTexUnit(stage)->enable(LLTexUnit::TT_CUBE_MAP); } @@ -197,7 +265,7 @@ void LLCubeMap::disable(void) void LLCubeMap::disableTexture(void) { - if (gGLManager.mHasCubeMap && mTextureStage >= 0 && LLCubeMap::sUseCubeMaps) + if (mTextureStage >= 0 && LLCubeMap::sUseCubeMaps) { gGL.getTexUnit(mTextureStage)->disable(); if (mTextureStage == 0) @@ -256,191 +324,6 @@ void LLCubeMap::restoreMatrix() }*/ } -void LLCubeMap::setReflection (void) -{ - gGL.getTexUnit(mTextureStage)->bindManual(LLTexUnit::TT_CUBE_MAP, getGLName()); - mImages[0]->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC); - mImages[0]->setAddressMode(LLTexUnit::TAM_CLAMP); -} - -LLVector3 LLCubeMap::map(U8 side, U16 v_val, U16 h_val) const -{ - LLVector3 dir; - - const U8 curr_coef = side >> 1; // 0/1 = X axis, 2/3 = Y, 4/5 = Z - const S8 side_dir = (((side & 1) << 1) - 1); // even = -1, odd = 1 - const U8 i_coef = (curr_coef + 1) % 3; - const U8 j_coef = (i_coef + 1) % 3; - - dir.mV[curr_coef] = side_dir; - - switch (side) - { - case 0: // negative X - dir.mV[i_coef] = -F32((v_val<<1) + 1) / RESOLUTION + 1; - dir.mV[j_coef] = F32((h_val<<1) + 1) / RESOLUTION - 1; - break; - case 1: // positive X - dir.mV[i_coef] = -F32((v_val<<1) + 1) / RESOLUTION + 1; - dir.mV[j_coef] = -F32((h_val<<1) + 1) / RESOLUTION + 1; - break; - case 2: // negative Y - dir.mV[i_coef] = -F32((v_val<<1) + 1) / RESOLUTION + 1; - dir.mV[j_coef] = F32((h_val<<1) + 1) / RESOLUTION - 1; - break; - case 3: // positive Y - dir.mV[i_coef] = F32((v_val<<1) + 1) / RESOLUTION - 1; - dir.mV[j_coef] = F32((h_val<<1) + 1) / RESOLUTION - 1; - break; - case 4: // negative Z - dir.mV[i_coef] = -F32((h_val<<1) + 1) / RESOLUTION + 1; - dir.mV[j_coef] = -F32((v_val<<1) + 1) / RESOLUTION + 1; - break; - case 5: // positive Z - dir.mV[i_coef] = -F32((h_val<<1) + 1) / RESOLUTION + 1; - dir.mV[j_coef] = F32((v_val<<1) + 1) / RESOLUTION - 1; - break; - default: - dir.mV[i_coef] = F32((v_val<<1) + 1) / RESOLUTION - 1; - dir.mV[j_coef] = F32((h_val<<1) + 1) / RESOLUTION - 1; - } - - dir.normVec(); - return dir; -} - - -BOOL LLCubeMap::project(F32& v_val, F32& h_val, BOOL& outside, - U8 side, const LLVector3& dir) const -{ - const U8 curr_coef = side >> 1; // 0/1 = X axis, 2/3 = Y, 4/5 = Z - const S8 side_dir = (((side & 1) << 1) - 1); // even = -1, odd = 1 - const U8 i_coef = (curr_coef + 1) % 3; - const U8 j_coef = (i_coef + 1) % 3; - - outside = TRUE; - if (side_dir * dir.mV[curr_coef] < 0) - return FALSE; - - LLVector3 ray; - - F32 norm_val = fabs(dir.mV[curr_coef]); - - if (norm_val < epsilon) - norm_val = 1e-5f; - - ray.mV[curr_coef] = side_dir; - ray.mV[i_coef] = dir.mV[i_coef] / norm_val; - ray.mV[j_coef] = dir.mV[j_coef] / norm_val; - - - const F32 i_val = (ray.mV[i_coef] + 1) * 0.5f * RESOLUTION; - const F32 j_val = (ray.mV[j_coef] + 1) * 0.5f * RESOLUTION; - - switch (side) - { - case 0: // negative X - v_val = RESOLUTION - i_val; - h_val = j_val; - break; - case 1: // positive X - v_val = RESOLUTION - i_val; - h_val = RESOLUTION - j_val; - break; - case 2: // negative Y - v_val = RESOLUTION - i_val; - h_val = j_val; - break; - case 3: // positive Y - v_val = i_val; - h_val = j_val; - break; - case 4: // negative Z - v_val = RESOLUTION - j_val; - h_val = RESOLUTION - i_val; - break; - case 5: // positive Z - v_val = RESOLUTION - j_val; - h_val = i_val; - break; - default: - v_val = i_val; - h_val = j_val; - } - - outside = ((v_val < 0) || (v_val > RESOLUTION) || - (h_val < 0) || (h_val > RESOLUTION)); - - return TRUE; -} - -BOOL LLCubeMap::project(F32& v_min, F32& v_max, F32& h_min, F32& h_max, - U8 side, LLVector3 dir[4]) const -{ - v_min = h_min = RESOLUTION; - v_max = h_max = 0; - - BOOL fully_outside = TRUE; - for (U8 vtx = 0; vtx < 4; ++vtx) - { - F32 v_val, h_val; - BOOL outside; - BOOL consider = project(v_val, h_val, outside, side, dir[vtx]); - if (!outside) - fully_outside = FALSE; - if (consider) - { - if (v_val < v_min) v_min = v_val; - if (v_val > v_max) v_max = v_val; - if (h_val < h_min) h_min = h_val; - if (h_val > h_max) h_max = h_val; - } - } - - v_min = llmax(0.0f, v_min); - v_max = llmin(RESOLUTION - epsilon, v_max); - h_min = llmax(0.0f, h_min); - h_max = llmin(RESOLUTION - epsilon, h_max); - - return !fully_outside; -} - - -void LLCubeMap::paintIn(LLVector3 dir[4], const LLColor4U& col) -{ - LL_PROFILE_ZONE_SCOPED; - F32 v_min, v_max, h_min, h_max; - LLVector3 center = dir[0] + dir[1] + dir[2] + dir[3]; - center.normVec(); - - for (U8 side = 0; side < 6; ++side) - { - if (!project(v_min, v_max, h_min, h_max, side, dir)) - continue; - - U8 *td = mRawImages[side]->getData(); - - U16 v_minu = (U16) v_min; - U16 v_maxu = (U16) (ceil(v_max) + 0.5); - U16 h_minu = (U16) h_min; - U16 h_maxu = (U16) (ceil(h_max) + 0.5); - - for (U16 v = v_minu; v < v_maxu; ++v) - for (U16 h = h_minu; h < h_maxu; ++h) - //for (U16 v = 0; v < RESOLUTION; ++v) - // for (U16 h = 0; h < RESOLUTION; ++h) - { - const LLVector3 ray = map(side, v, h); - if (ray * center > 0.999) - { - const U32 offset = (RESOLUTION * v + h) * 4; - for (U8 cc = 0; cc < 3; ++cc) - td[offset + cc] = U8((td[offset + cc] + col.mV[cc]) * 0.5); - } - } - mImages[side]->setSubImage(mRawImages[side], 0, 0, RESOLUTION, RESOLUTION); - } -} void LLCubeMap::destroyGL() { |