diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 38482edd225fd697900baccce9ea31f1d5c7c8ea..a69fcd8ca81115b00f0206a143ffc87532fa8806 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -1354,6 +1354,153 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt stop_glerror(); } +void LLImageGL::setManualImage3D(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, S32 depth, U32 pixformat, U32 pixtype, const void* pixels, bool allow_compression) +{ + LL_RECORD_BLOCK_TIME(FTM_SET_MANUAL_IMAGE); + std::vector<U32> scratch; + if (LLRender::sGLCoreProfile) + { +#ifdef GL_ARB_texture_swizzle + if (gGLManager.mHasTextureSwizzle) + { + if (pixformat == GL_ALPHA) + { //GL_ALPHA is deprecated, convert to RGBA + const GLint mask[] = { GL_ZERO, GL_ZERO, GL_ZERO, GL_RED }; + glTexParameteriv(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_RGBA, mask); + pixformat = GL_RED; + intformat = GL_R8; + } + + if (pixformat == GL_LUMINANCE) + { //GL_LUMINANCE is deprecated, convert to GL_RGBA + const GLint mask[] = { GL_RED, GL_RED, GL_RED, GL_ONE }; + glTexParameteriv(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_RGBA, mask); + pixformat = GL_RED; + intformat = GL_R8; + } + + if (pixformat == GL_LUMINANCE_ALPHA) + { //GL_LUMINANCE_ALPHA is deprecated, convert to RGBA + const GLint mask[] = { GL_RED, GL_RED, GL_RED, GL_GREEN }; + glTexParameteriv(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_RGBA, mask); + pixformat = GL_RG; + intformat = GL_RG8; + } + } + else +#endif + { + if (pixformat == GL_ALPHA && pixtype == GL_UNSIGNED_BYTE) + { //GL_ALPHA is deprecated, convert to RGBA + scratch.resize(width * height); + + U32 pixel_count = (U32)(width * height); + for (U32 i = 0; i < pixel_count; i++) + { + U8* pix = (U8*)&scratch[i]; + pix[0] = pix[1] = pix[2] = 0; + pix[3] = ((U8*)pixels)[i]; + } + + pixels = &scratch[0]; + + pixformat = GL_RGBA; + intformat = GL_RGBA8; + } + + if (pixformat == GL_LUMINANCE_ALPHA && pixtype == GL_UNSIGNED_BYTE) + { //GL_LUMINANCE_ALPHA is deprecated, convert to RGBA + scratch.resize(width * height); + + U32 pixel_count = (U32)(width * height); + for (U32 i = 0; i < pixel_count; i++) + { + U8 lum = ((U8*)pixels)[i * 2 + 0]; + U8 alpha = ((U8*)pixels)[i * 2 + 1]; + + U8* pix = (U8*)&scratch[i]; + pix[0] = pix[1] = pix[2] = lum; + pix[3] = alpha; + } + + pixels = &scratch[0]; + + pixformat = GL_RGBA; + intformat = GL_RGBA8; + } + + if (pixformat == GL_LUMINANCE && pixtype == GL_UNSIGNED_BYTE) + { //GL_LUMINANCE_ALPHA is deprecated, convert to RGB + scratch.resize(width * height); + + U32 pixel_count = (U32)(width * height); + for (U32 i = 0; i < pixel_count; i++) + { + U8 lum = ((U8*)pixels)[i]; + + U8* pix = (U8*)&scratch[i]; + pix[0] = pix[1] = pix[2] = lum; + pix[3] = 255; + } + + pixels = &scratch[0]; + + pixformat = GL_RGBA; + intformat = GL_RGB8; + } + } + } + if (LLImageGL::sCompressTextures && allow_compression) + { + switch (intformat) + { + case GL_RED: + case GL_R8: + intformat = GL_COMPRESSED_RED; + break; + case GL_RG: + case GL_RG8: + intformat = GL_COMPRESSED_RG; + break; + case GL_RGB: + case GL_RGB8: + intformat = GL_COMPRESSED_RGB; + break; + case GL_SRGB: + case GL_SRGB8: + intformat = GL_COMPRESSED_SRGB; + break; + case GL_RGBA: + case GL_RGBA8: + intformat = GL_COMPRESSED_RGBA; + break; + case GL_SRGB_ALPHA: + case GL_SRGB8_ALPHA8: + intformat = GL_COMPRESSED_SRGB_ALPHA; + break; + case GL_LUMINANCE: + case GL_LUMINANCE8: + intformat = GL_COMPRESSED_LUMINANCE; + break; + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE8_ALPHA8: + intformat = GL_COMPRESSED_LUMINANCE_ALPHA; + break; + case GL_ALPHA: + case GL_ALPHA8: + intformat = GL_COMPRESSED_ALPHA; + break; + default: + LL_WARNS() << "Could not compress format: " << std::hex << intformat << std::dec << LL_ENDL; + break; + } + } + + stop_glerror(); + glTexImage3D(target, miplevel, intformat, width, height, depth, 0, pixformat, pixtype, pixels); + stop_glerror(); +} + //create an empty GL texture: just create a texture name //the texture is assiciate with some image by calling glTexImage outside LLImageGL static LLTrace::BlockTimerStatHandle FTM_CREATE_GL_TEXTURE1("createGLTexture()"); diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index c452a17a8c5df905e32789b9d01a7e35e50bef19..27d7d30b048401803f223f42391627840e73364f 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -102,6 +102,7 @@ class LLImageGL : public LLRefCount, public LLTrace::MemTrackable<LLImageGL> 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); + static void setManualImage3D(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, S32 depth, 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, diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 5d62ef03be632051d3423aef7939d2ea66c7ddec..0c041f6071e20fcc5cc2e3b21b583e8352a430aa 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -472,9 +472,9 @@ void LLTexUnit::setTextureAddressMode(eTextureAddressMode mode) glTexParameteri (sGLTextureType[mCurrTexType], GL_TEXTURE_WRAP_S, sGLAddressMode[mode]); glTexParameteri (sGLTextureType[mCurrTexType], GL_TEXTURE_WRAP_T, sGLAddressMode[mode]); - if (mCurrTexType == TT_CUBE_MAP) + if (mCurrTexType == TT_CUBE_MAP || mCurrTexType == TT_TEXTURE_3D) { - glTexParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, sGLAddressMode[mode]); + glTexParameteri (sGLTextureType[mCurrTexType], GL_TEXTURE_WRAP_R, sGLAddressMode[mode]); } } @@ -2397,6 +2397,9 @@ void LLRender::debugTexUnits(void) case LLTexUnit::TT_CUBE_MAP: LL_CONT << "Cube Map"; break; + case LLTexUnit::TT_TEXTURE_3D: + LL_CONT << "Texture 3D"; + break; default: LL_CONT << "ARGH!!! NONE!"; break; diff --git a/indra/newview/alrenderutils.cpp b/indra/newview/alrenderutils.cpp index 5cab2e9ec082189706f3fc2175daa529cd5552f4..857b13599cf8572ea505aedbdb38fba855063109 100644 --- a/indra/newview/alrenderutils.cpp +++ b/indra/newview/alrenderutils.cpp @@ -246,14 +246,14 @@ bool ALRenderUtil::setupColorGrade() mCGLutSize = LLVector4(1.f / image_width, 1.f / image_height, (F32)image_width, (F32)image_height); LLImageGL::generateTextures(1, &mCGLut); - gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mCGLut); - LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, int_format, image_width, - image_height, primary_format, GL_UNSIGNED_BYTE, raw_image->getData(), false); + gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE_3D, mCGLut); + LLImageGL::setManualImage3D(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE_3D), 0, int_format, image_height, + image_height, image_height, primary_format, GL_UNSIGNED_BYTE, raw_image->getData(), false); stop_glerror(); gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); - gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_WRAP); + gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); gGL.getTexUnit(0)->setTextureColorSpace(LLTexUnit::TCS_LINEAR); - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE_3D); } else { @@ -331,12 +331,12 @@ void ALRenderUtil::renderTonemap(LLRenderTarget* src, LLRenderTarget* dst, LLRen if (mCGLut != 0) { - S32 channel = tone_shader->enableTexture(LLShaderMgr::COLORGRADE_LUT, LLTexUnit::TT_TEXTURE); + S32 channel = tone_shader->enableTexture(LLShaderMgr::COLORGRADE_LUT, LLTexUnit::TT_TEXTURE_3D); if (channel > -1) { - gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE, mCGLut); + gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE_3D, mCGLut); gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); - gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_WRAP); + gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); gGL.getTexUnit(channel)->setTextureColorSpace(LLTexUnit::TCS_LINEAR); } diff --git a/indra/newview/app_settings/shaders/class1/alchemy/toneMapF.glsl b/indra/newview/app_settings/shaders/class1/alchemy/toneMapF.glsl index e64b4c9200177215da67f991571ac5fabaf2b83b..403fbf6ff1cfc7d904afe976c37668bafd90a604 100644 --- a/indra/newview/app_settings/shaders/class1/alchemy/toneMapF.glsl +++ b/indra/newview/app_settings/shaders/class1/alchemy/toneMapF.glsl @@ -42,7 +42,7 @@ vec3 srgb_to_linear(vec3 cl); vec3 linear_to_srgb(vec3 cl); #if COLOR_GRADE_LUT != 0 -uniform sampler2D colorgrade_lut; +uniform sampler3D colorgrade_lut; uniform vec4 colorgrade_lut_size; #endif @@ -223,25 +223,13 @@ void main() #if COLOR_GRADE_LUT != 0 // Invert coord for compat with DX-style LUT - diff.y = 1.0 - diff.y; + diff.g = 1.0 - diff.g; - // Convert to texel coords - vec3 lutRange = diff.rgb * ( colorgrade_lut_size.w - 1); - - // Calculate coords in texel space - vec2 lutX = vec2(floor(lutRange.z)*colorgrade_lut_size.w+lutRange.x, lutRange.y); - vec2 lutY = vec2(ceil(lutRange.z)*colorgrade_lut_size.w+lutRange.x, lutRange.y); - - // texel to ndc - lutX = (lutX+0.5)*colorgrade_lut_size.xy; - lutY = (lutY+0.5)*colorgrade_lut_size.xy; - - // LUT interpolation - diff.rgb = mix( - linear_to_srgb(texture2D(colorgrade_lut, lutX).rgb), - linear_to_srgb(texture2D(colorgrade_lut, lutY).rgb), - fract(lutRange.z) - ); + //see https://developer.nvidia.com/gpugems/GPUGems2/gpugems2_chapter24.html + vec3 scale = (vec3(colorgrade_lut_size.w) - 1.0) / vec3(colorgrade_lut_size.w); + vec3 offset = 1.0 / (2.0 * vec3(colorgrade_lut_size.w)); + + diff = vec4(linear_to_srgb(textureLod(colorgrade_lut, scale * diff.rbg + offset, 0).rgb), diff.a); #endif frag_color = diff;