diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index b29155187..7795e0183 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -59,6 +59,7 @@ PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers; PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer; PFNGLFRAMEBUFFERTEXTUREPROC glFramebufferTexture; PFNGLTEXIMAGE3DPROC glTexImage3D; +PFNGLGENERATEMIPMAPPROC glGenerateMipmap; PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus; #endif @@ -198,6 +199,7 @@ void initGL() glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)IRR_OGL_LOAD_EXTENSION("glBindFramebuffer"); glFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREPROC)IRR_OGL_LOAD_EXTENSION("glFramebufferTexture"); glTexImage3D = (PFNGLTEXIMAGE3DPROC)IRR_OGL_LOAD_EXTENSION("glTexImage3D"); + glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC)IRR_OGL_LOAD_EXTENSION("glGenerateMipmap"); glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)IRR_OGL_LOAD_EXTENSION("glCheckFramebufferStatus"); #ifdef DEBUG glDebugMessageCallbackARB = (PFNGLDEBUGMESSAGECALLBACKARBPROC)IRR_OGL_LOAD_EXTENSION("glDebugMessageCallbackARB"); @@ -291,6 +293,26 @@ GLuint getDepthTexture(irr::video::ITexture *tex) return static_cast(tex)->DepthBufferTexture; } +std::set AlreadyTransformedTexture; + +void transformTexturesTosRGB(irr::video::ITexture *tex) +{ + if (AlreadyTransformedTexture.find(tex) != AlreadyTransformedTexture.end()) + return; + AlreadyTransformedTexture.insert(tex); + size_t w = tex->getSize().Width, h = tex->getSize().Height; + char *data = new char[w * h * 4]; + memcpy(data, tex->lock(), w * h * 4); + tex->unlock(); + glBindTexture(GL_TEXTURE_2D, getTextureGLuint(tex)); + if (tex->hasAlpha()) + glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB_ALPHA, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid *)data); + else + glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB, w, h, 0, GL_BGR, GL_UNSIGNED_BYTE, (GLvoid *)data); + glGenerateMipmap(GL_TEXTURE_2D); + delete[] data; +} + void setTexture(unsigned TextureUnit, GLuint TextureId, GLenum MagFilter, GLenum MinFilter, bool allowAF) { glActiveTexture(GL_TEXTURE0 + TextureUnit); diff --git a/src/graphics/glwrap.hpp b/src/graphics/glwrap.hpp index a2c7d954f..96ac80700 100644 --- a/src/graphics/glwrap.hpp +++ b/src/graphics/glwrap.hpp @@ -76,6 +76,7 @@ extern PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers; extern PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer; extern PFNGLFRAMEBUFFERTEXTUREPROC glFramebufferTexture; extern PFNGLTEXIMAGE3DPROC glTexImage3D; +extern PFNGLGENERATEMIPMAPPROC glGenerateMipmap; extern PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus; #ifdef DEBUG extern PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARB; @@ -151,6 +152,7 @@ GLint LoadProgram(Types ... args) GLuint getTextureGLuint(irr::video::ITexture *tex); GLuint getDepthTexture(irr::video::ITexture *tex); +void transformTexturesTosRGB(irr::video::ITexture *tex); void draw2DImage(const irr::video::ITexture* texture, const irr::core::rect& destRect, const irr::core::rect& sourceRect, const irr::core::rect* clipRect, diff --git a/src/graphics/gpuparticles.cpp b/src/graphics/gpuparticles.cpp index d962d410a..03b0b7037 100644 --- a/src/graphics/gpuparticles.cpp +++ b/src/graphics/gpuparticles.cpp @@ -382,7 +382,8 @@ void ParticleSystemProxy::setEmitter(scene::IParticleEmitter* emitter) glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); - + video::ITexture *tex = getMaterial(0).getTexture(0); + transformTexturesTosRGB(tex); texture = getTextureGLuint(getMaterial(0).getTexture(0)); } diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index ba32f9ee6..a43fc1881 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -855,12 +855,14 @@ void PostProcessing::render() // Final blit // TODO : Use glBlitFramebuffer drv->setRenderTarget(ERT_FRAME_BUFFER, false, false); + glEnable(GL_FRAMEBUFFER_SRGB); if (irr_driver->getNormals()) renderPassThrough(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)); else if (irr_driver->getSSAOViz()) renderPassThrough(irr_driver->getRTT(RTT_SSAO)); else renderColorLevel(in); + glDisable(GL_FRAMEBUFFER_SRGB); } } // render diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index e3c1fd636..bb55d73d1 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -1026,9 +1026,10 @@ static void projectSH(float *color[], size_t width, size_t height, // Constant obtained by projecting unprojected ref values float solidangle = 2.75 / (wh * pow(d, 1.5f)); - float b = color[face][4 * height * i + 4 * j] / 255.; - float g = color[face][4 * height * i + 4 * j + 1] / 255.; - float r = color[face][4 * height * i + 4 * j + 2] / 255.; + // pow(., 2.2) to convert from srgb + float b = pow(color[face][4 * height * i + 4 * j] / 255., 2.2); + float g = pow(color[face][4 * height * i + 4 * j + 1] / 255., 2.2); + float r = pow(color[face][4 * height * i + 4 * j + 2] / 255., 2.2); assert(b >= 0.); @@ -1242,7 +1243,7 @@ void IrrDriver::generateSkyboxCubemap() image->drop(); glBindTexture(GL_TEXTURE_CUBE_MAP, SkyboxCubeMap); - glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid*)rgba[i]); + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_SRGB_ALPHA, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid*)rgba[i]); } testSH(rgba, w, h, blueSHCoeff, greenSHCoeff, redSHCoeff); @@ -1250,7 +1251,7 @@ void IrrDriver::generateSkyboxCubemap() for (unsigned i = 0; i < 6; i++) { glBindTexture(GL_TEXTURE_CUBE_MAP, ConvolutedSkyboxCubeMap); - glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid*)rgba[i]); + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_SRGB_ALPHA, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid*)rgba[i]); } for (unsigned i = 0; i < 6; i++) delete[] rgba[i]; diff --git a/src/graphics/stkbillboard.cpp b/src/graphics/stkbillboard.cpp index d6de5085f..12bf85e92 100644 --- a/src/graphics/stkbillboard.cpp +++ b/src/graphics/stkbillboard.cpp @@ -34,7 +34,9 @@ void STKBillboard::render() return; core::vector3df pos = getAbsolutePosition(); glBindVertexArray(billboardvao); - GLuint texid = getTextureGLuint(Material.getTexture(0)); + video::ITexture *tex = Material.getTexture(0); + transformTexturesTosRGB(tex); + GLuint texid = getTextureGLuint(tex); setTexture(0, texid, GL_LINEAR, GL_LINEAR); glUseProgram(MeshShader::BillboardShader::Program); MeshShader::BillboardShader::setUniforms(irr_driver->getViewMatrix(), irr_driver->getProjMatrix(), pos, Size, 0); diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp index 36635ff50..ab2733512 100644 --- a/src/graphics/stkmesh.cpp +++ b/src/graphics/stkmesh.cpp @@ -180,8 +180,11 @@ GLMesh allocateMeshBuffer(scene::IMeshBuffer* mb) for (unsigned i = 0; i < 6; i++) { tex = mb->getMaterial().getTexture(i); - if (tex) - result.textures[i] = getTextureGLuint(tex); + if (tex) + { + transformTexturesTosRGB(tex); + result.textures[i] = getTextureGLuint(tex); + } else result.textures[i] = 0; }