diff --git a/data/graphical_restrictions.xml b/data/graphical_restrictions.xml index 999b5520a..d45e2da4d 100644 --- a/data/graphical_restrictions.xml +++ b/data/graphical_restrictions.xml @@ -4,17 +4,17 @@ - + - + - + diff --git a/data/shaders/instanced_object_pass2.frag b/data/shaders/instanced_object_pass2.frag index 38198e916..f83c8fb8a 100644 --- a/data/shaders/instanced_object_pass2.frag +++ b/data/shaders/instanced_object_pass2.frag @@ -44,7 +44,11 @@ void main(void) col = vec4(new_color.r, new_color.g, new_color.b, col.a); } +#if defined(sRGB_Framebuffer_Usable) || defined(Advanced_Lighting_Enabled) col.xyz *= pow(color.xyz, vec3(2.2)); +#else + col.xyz *= color.xyz; +#endif FragColor = vec4(getLightFactor(col.xyz, vec3(1.), specmap, emitmap) , 1.); } diff --git a/data/shaders/instanced_object_unlit.frag b/data/shaders/instanced_object_unlit.frag index ab0e3c8f0..dba78dc0b 100644 --- a/data/shaders/instanced_object_unlit.frag +++ b/data/shaders/instanced_object_unlit.frag @@ -20,7 +20,13 @@ void main(void) #else vec4 col = texture(tex, uv); #endif - col.xyz *= pow(color.xyz, vec3(2.2)); if (col.a < 0.5) discard; + +#if defined(sRGB_Framebuffer_Usable) || defined(Advanced_Lighting_Enabled) + col.xyz *= pow(color.xyz, vec3(2.2)); +#else + col.xyz *= color.xyz; +#endif + FragColor = vec4(col.xyz, 1.); } diff --git a/data/shaders/instanced_objectref_pass2.frag b/data/shaders/instanced_objectref_pass2.frag index 3363f674f..c2b3cd5e7 100644 --- a/data/shaders/instanced_objectref_pass2.frag +++ b/data/shaders/instanced_objectref_pass2.frag @@ -32,8 +32,13 @@ void main(void) float emitmap = texture(SpecMap, uv).b; float mask = texture(colorization_mask, uv).a; #endif - col.xyz *= pow(color.xyz, vec3(2.2)); if (col.a * color.a < 0.5) discard; + +#if defined(sRGB_Framebuffer_Usable) || defined(Advanced_Lighting_Enabled) + col.xyz *= pow(color.xyz, vec3(2.2)); +#else + col.xyz *= color.xyz; +#endif if (color_change.x > 0.0) { diff --git a/data/shaders/object_pass2.frag b/data/shaders/object_pass2.frag index 93f0a0fb0..9bad5d93b 100644 --- a/data/shaders/object_pass2.frag +++ b/data/shaders/object_pass2.frag @@ -40,11 +40,12 @@ void main(void) col = vec4(new_color.r, new_color.g, new_color.b, col.a); } -#if defined(GL_ES) && !defined(Advanced_Lighting_Enabled) - col.xyz *= color.xyz; -#else +#if defined(sRGB_Framebuffer_Usable) || defined(Advanced_Lighting_Enabled) col.xyz *= pow(color.xyz, vec3(2.2)); +#else + col.xyz *= color.xyz; #endif + float specmap = texture(SpecMap, uv).g; float emitmap = texture(SpecMap, uv).b; FragColor = vec4(getLightFactor(col.xyz, vec3(1.), specmap, emitmap), 1.); diff --git a/data/shaders/object_unlit.frag b/data/shaders/object_unlit.frag index d13305612..2087e0426 100644 --- a/data/shaders/object_unlit.frag +++ b/data/shaders/object_unlit.frag @@ -18,10 +18,10 @@ void main(void) #endif if (col.a < 0.5) discard; -#if defined(GL_ES) && !defined(Advanced_Lighting_Enabled) - col.xyz *= color.xyz; -#else +#if defined(sRGB_Framebuffer_Usable) || defined(Advanced_Lighting_Enabled) col.xyz *= pow(color.xyz, vec3(2.2)); +#else + col.xyz *= color.xyz; #endif FragColor = vec4(col.xyz, 1.); diff --git a/data/shaders/objectref_pass2.frag b/data/shaders/objectref_pass2.frag index 3dacf6bdb..8f5bb9ad7 100644 --- a/data/shaders/objectref_pass2.frag +++ b/data/shaders/objectref_pass2.frag @@ -27,10 +27,10 @@ void main(void) #endif if (col.a * color.a < 0.5) discard; -#if defined(GL_ES) && !defined(Advanced_Lighting_Enabled) - col.xyz *= color.xyz; -#else +#if defined(sRGB_Framebuffer_Usable) || defined(Advanced_Lighting_Enabled) col.xyz *= pow(color.xyz, vec3(2.2)); +#else + col.xyz *= color.xyz; #endif float mask = texture(colorization_mask, uv).a; diff --git a/data/shaders/tonemap.frag b/data/shaders/tonemap.frag index 251f18ac1..a97e158e1 100644 --- a/data/shaders/tonemap.frag +++ b/data/shaders/tonemap.frag @@ -13,7 +13,7 @@ void main() // Uncharted2 tonemap with Auria's custom coefficients vec4 perChannel = (col * (6.9 * col + .5)) / (col * (5.2 * col + 1.7) + 0.06); -#if !(defined(GL_ES) && defined(Advanced_Lighting_Enabled)) +#if !(!defined(sRGB_Framebuffer_Usable) && defined(Advanced_Lighting_Enabled)) perChannel = pow(perChannel, vec4(2.2)); #endif diff --git a/data/shaders/utils/getLightFactor.frag b/data/shaders/utils/getLightFactor.frag index c7584c6a1..327f98e3e 100644 --- a/data/shaders/utils/getLightFactor.frag +++ b/data/shaders/utils/getLightFactor.frag @@ -19,7 +19,7 @@ vec3 getLightFactor(vec3 diffuseMatColor, vec3 specularMatColor, float specMapVa vec3 emitCol = diffuseMatColor.xyz * diffuseMatColor.xyz * diffuseMatColor.xyz * 15.; return tmp * ao + (emitMapValue * emitCol); #else -#if defined(GL_ES) +#if !defined(sRGB_Framebuffer_Usable) return diffuseMatColor * 0.73; // 0.5 ^ (1. / 2.2) #else return diffuseMatColor * 0.5; diff --git a/src/graphics/central_settings.cpp b/src/graphics/central_settings.cpp index a7925643a..b844d583f 100644 --- a/src/graphics/central_settings.cpp +++ b/src/graphics/central_settings.cpp @@ -53,6 +53,7 @@ void CentralVideoSettings::init() hasTextureFilterAnisotropic = false; hasTextureSwizzle = false; hasPixelBufferObject = false; + hasSRGBFramebuffer = false; #if defined(USE_GLES2) hasBGRA = false; @@ -203,6 +204,12 @@ void CentralVideoSettings::init() hasPixelBufferObject = true; Log::info("GLDriver", "ARB Pixel Buffer Object Present"); } + if (!GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_FRAMEBUFFER_SRGB) && + (hasGLExtension("GL_ARB_framebuffer_sRGB") || m_glsl == true)) + { + hasSRGBFramebuffer = true; + Log::info("GLDriver", "ARB framebuffer sRGB Present"); + } // Only unset the high def textures if they are set as default. If the // user has enabled them (bit 1 set), then leave them enabled. if (GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_HIGHDEFINITION_TEXTURES) && @@ -231,7 +238,7 @@ void CentralVideoSettings::init() } // Check if visual is sRGB-capable - if (GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_FRAMEBUFFER_SRGB_CAPABLE) && + if (GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_FRAMEBUFFER_SRGB_WORKAROUND2) && m_glsl == true) { GLint param = GL_SRGB; @@ -415,6 +422,11 @@ bool CentralVideoSettings::isEXTTextureFilterAnisotropicUsable() const return hasTextureFilterAnisotropic; } +bool CentralVideoSettings::isARBSRGBFramebufferUsable() const +{ + return hasSRGBFramebuffer; +} + #if defined(USE_GLES2) bool CentralVideoSettings::isEXTTextureFormatBGRA8888Usable() const { @@ -452,6 +464,11 @@ bool CentralVideoSettings::supportsAsyncInstanceUpload() const return isARBBufferStorageUsable() && isARBImageLoadStoreUsable(); } +bool CentralVideoSettings::supportsTextureCompression() const +{ + return isEXTTextureCompressionS3TCUsable() && isARBSRGBFramebufferUsable(); +} + bool CentralVideoSettings::isShadowEnabled() const { return supportsShadows() && (UserConfigParams::m_shadows_resolution > 0); @@ -464,7 +481,7 @@ bool CentralVideoSettings::isGlobalIlluminationEnabled() const bool CentralVideoSettings::isTextureCompressionEnabled() const { - return isEXTTextureCompressionS3TCUsable() && UserConfigParams::m_texture_compression; + return supportsTextureCompression() && UserConfigParams::m_texture_compression; } // See http://visual-computing.intel-research.net/art/publications/sdsm/ diff --git a/src/graphics/central_settings.hpp b/src/graphics/central_settings.hpp index 422846f81..1ec847a69 100644 --- a/src/graphics/central_settings.hpp +++ b/src/graphics/central_settings.hpp @@ -45,6 +45,7 @@ private: bool hasTextureFilterAnisotropic; bool hasTextureSwizzle; bool hasPixelBufferObject; + bool hasSRGBFramebuffer; #if defined(USE_GLES2) bool hasBGRA; @@ -88,6 +89,7 @@ public: bool isEXTTextureFilterAnisotropicUsable() const; bool isARBTextureSwizzleUsable() const; bool isARBPixelBufferObjectUsable() const; + bool isARBSRGBFramebufferUsable() const; #if defined(USE_GLES2) bool isEXTTextureFormatBGRA8888Usable() const; @@ -103,6 +105,7 @@ public: bool supportsAsyncInstanceUpload() const; bool supportsHardwareSkinning() const; bool supportsThreadedTextureLoading() const; + bool supportsTextureCompression() const; // "Macro" around feature support and user config bool isShadowEnabled() const; diff --git a/src/graphics/graphics_restrictions.cpp b/src/graphics/graphics_restrictions.cpp index cfebc4c1a..8f447c5e2 100644 --- a/src/graphics/graphics_restrictions.cpp +++ b/src/graphics/graphics_restrictions.cpp @@ -44,7 +44,7 @@ namespace GraphicsRestrictions /** The list of names used in the XML file for the graphics * restriction types. They must be in the same order as the types. */ - std::array m_names_of_restrictions = { + std::array m_names_of_restrictions = { "UniformBufferObject", "GeometryShader", "DrawIndirect", @@ -68,8 +68,9 @@ namespace GraphicsRestrictions "DriverRecentEnough", "HighDefinitionTextures", "AdvancedPipeline", - "FramebufferSRGBWorking", - "FramebufferSRGBCapable", + "FramebufferSRGB", + "FramebufferSRGBWorkaround1", + "FramebufferSRGBWorkaround2", "GI", "ForceLegacyDevice", "VertexIdWorking" diff --git a/src/graphics/graphics_restrictions.hpp b/src/graphics/graphics_restrictions.hpp index af00509a6..593a0ee3b 100644 --- a/src/graphics/graphics_restrictions.hpp +++ b/src/graphics/graphics_restrictions.hpp @@ -57,8 +57,9 @@ namespace GraphicsRestrictions GR_DRIVER_RECENT_ENOUGH, GR_HIGHDEFINITION_TEXTURES, GR_ADVANCED_PIPELINE, - GR_FRAMEBUFFER_SRGB_WORKING, - GR_FRAMEBUFFER_SRGB_CAPABLE, + GR_FRAMEBUFFER_SRGB, + GR_FRAMEBUFFER_SRGB_WORKAROUND1, + GR_FRAMEBUFFER_SRGB_WORKAROUND2, GR_GI, GR_FORCE_LEGACY_DEVICE, GR_VERTEX_ID_WORKING, diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index 2ec6ef4b3..5d0034696 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -490,7 +490,8 @@ void IrrDriver::initDevice() // Though we are able to force to use the proper format on mesa side by // setting WithAlphaChannel parameter. #ifndef SERVER_ONLY - else if (CVS->needsSRGBCapableVisualWorkaround()) + else if (CVS->isARBSRGBFramebufferUsable() && + CVS->needsSRGBCapableVisualWorkaround()) { Log::warn("irr_driver", "Created visual is not sRGB-capable. " "Re-creating device to workaround the issue."); diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index b26a35678..0ed9f4206 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -1574,11 +1574,13 @@ FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode, } // Workaround a bug with srgb fbo on sandy bridge windows - if (GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_FRAMEBUFFER_SRGB_WORKING)) + if (GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_FRAMEBUFFER_SRGB_WORKAROUND1) && + CVS->isARBSRGBFramebufferUsable()) return in_fbo; #if !defined(USE_GLES2) - glEnable(GL_FRAMEBUFFER_SRGB); + if (CVS->isARBSRGBFramebufferUsable()) + glEnable(GL_FRAMEBUFFER_SRGB); #endif out_fbo = &rtts->getFBO(FBO_MLAA_COLORS); out_fbo->bind(); @@ -1596,7 +1598,8 @@ FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode, PROFILER_POP_CPU_MARKER(); } #if !defined(USE_GLES2) - glDisable(GL_FRAMEBUFFER_SRGB); + if (CVS->isARBSRGBFramebufferUsable()) + glDisable(GL_FRAMEBUFFER_SRGB); #endif return out_fbo; diff --git a/src/graphics/render_target.cpp b/src/graphics/render_target.cpp index eafe919d4..3e96ada3c 100644 --- a/src/graphics/render_target.cpp +++ b/src/graphics/render_target.cpp @@ -19,6 +19,7 @@ #include "graphics/render_target.hpp" #include "graphics/2dutils.hpp" +#include "graphics/central_settings.hpp" #include "graphics/glwrap.hpp" #include "graphics/irr_driver.hpp" #include "graphics/rtts.hpp" @@ -148,14 +149,16 @@ void GL3RenderTarget::draw2DImage(const irr::core::rect& dest_rect, irr::core::rect source_rect(0, 0, m_frame_buffer->getWidth(), m_frame_buffer->getHeight()); #if !defined(USE_GLES2) - glEnable(GL_FRAMEBUFFER_SRGB); + if (CVS->isARBSRGBFramebufferUsable()) + glEnable(GL_FRAMEBUFFER_SRGB); #endif draw2DImageFromRTT(m_frame_buffer->getRTT()[0], m_frame_buffer->getWidth(), m_frame_buffer->getHeight(), dest_rect, source_rect, clip_rect, colors, use_alpha_channel_of_texture); #if !defined(USE_GLES2) - glDisable(GL_FRAMEBUFFER_SRGB); + if (CVS->isARBSRGBFramebufferUsable()) + glDisable(GL_FRAMEBUFFER_SRGB); #endif } // draw2DImage diff --git a/src/graphics/rtts.cpp b/src/graphics/rtts.cpp index 1dba56660..8ac4636ee 100644 --- a/src/graphics/rtts.cpp +++ b/src/graphics/rtts.cpp @@ -101,10 +101,11 @@ RTT::RTT(size_t width, size_t height, float rtt_scale) diffuse_specular_internal_format = GL_RGBA8; type = GL_UNSIGNED_BYTE; } - - srgb_internal_format = GL_RGBA8; #endif + if (!CVS->isARBSRGBFramebufferUsable()) + srgb_internal_format = GL_RGBA8; + RenderTargetTextures[RTT_TMP1] = generateRTT(res, rgba_internal_format, rgba_format, type); RenderTargetTextures[RTT_TMP2] = generateRTT(res, rgba_internal_format, rgba_format, type); RenderTargetTextures[RTT_TMP3] = generateRTT(res, rgba_internal_format, rgba_format, type); diff --git a/src/graphics/shader_based_renderer.cpp b/src/graphics/shader_based_renderer.cpp index 27d18124d..5db75edd4 100644 --- a/src/graphics/shader_based_renderer.cpp +++ b/src/graphics/shader_based_renderer.cpp @@ -305,7 +305,8 @@ void ShaderBasedRenderer::renderScene(scene::ICameraSceneNode * const camnode, { // We need a cleared depth buffer for some effect (eg particles depth blending) #if !defined(USE_GLES2) - if (GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_FRAMEBUFFER_SRGB_WORKING)) + if (GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_FRAMEBUFFER_SRGB_WORKAROUND1) && + CVS->isARBSRGBFramebufferUsable()) glDisable(GL_FRAMEBUFFER_SRGB); #endif m_rtts->getFBO(FBO_NORMAL_AND_DEPTHS).bind(); @@ -318,7 +319,8 @@ void ShaderBasedRenderer::renderScene(scene::ICameraSceneNode * const camnode, vp.LowerRightCorner.Y - vp.UpperLeftCorner.Y); glClear(GL_DEPTH_BUFFER_BIT); #if !defined(USE_GLES2) - if (GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_FRAMEBUFFER_SRGB_WORKING)) + if (GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_FRAMEBUFFER_SRGB_WORKAROUND1) && + CVS->isARBSRGBFramebufferUsable()) glEnable(GL_FRAMEBUFFER_SRGB); #endif glBindFramebuffer(GL_FRAMEBUFFER, 0); @@ -495,7 +497,8 @@ void ShaderBasedRenderer::renderScene(scene::ICameraSceneNode * const camnode, if (!CVS->isDefferedEnabled() && !forceRTT) { #if !defined(USE_GLES2) - glDisable(GL_FRAMEBUFFER_SRGB); + if (CVS->isARBSRGBFramebufferUsable()) + glDisable(GL_FRAMEBUFFER_SRGB); #endif glDisable(GL_DEPTH_TEST); glDepthMask(GL_FALSE); @@ -603,13 +606,15 @@ void ShaderBasedRenderer::renderPostProcessing(Camera * const camera) else { #if !defined(USE_GLES2) - glEnable(GL_FRAMEBUFFER_SRGB); + if (CVS->isARBSRGBFramebufferUsable()) + glEnable(GL_FRAMEBUFFER_SRGB); #endif glBindFramebuffer(GL_FRAMEBUFFER, 0); camera->activate(); m_post_processing->renderPassThrough(fbo->getRTT()[0], viewport.LowerRightCorner.X - viewport.UpperLeftCorner.X, viewport.LowerRightCorner.Y - viewport.UpperLeftCorner.Y); #if !defined(USE_GLES2) - glDisable(GL_FRAMEBUFFER_SRGB); + if (CVS->isARBSRGBFramebufferUsable()) + glDisable(GL_FRAMEBUFFER_SRGB); #endif } } //renderPostProcessing @@ -811,7 +816,7 @@ void ShaderBasedRenderer::render(float dt) irr_driver->getSceneManager()->setActiveCamera(camnode); #if !defined(USE_GLES2) - if (!CVS->isDefferedEnabled()) + if (!CVS->isDefferedEnabled() && CVS->isARBSRGBFramebufferUsable()) glEnable(GL_FRAMEBUFFER_SRGB); #endif @@ -961,7 +966,7 @@ void ShaderBasedRenderer::preloadShaderFiles() sfm->addShaderFile("screenquad.vert", GL_VERTEX_SHADER); sfm->addShaderFile("tonemap.frag", GL_FRAGMENT_SHADER); if (!GraphicsRestrictions::isDisabled - (GraphicsRestrictions::GR_FRAMEBUFFER_SRGB_WORKING)) + (GraphicsRestrictions::GR_FRAMEBUFFER_SRGB_WORKAROUND1)) sfm->addShaderFile("passthrough.frag", GL_FRAGMENT_SHADER); sfm->addShaderFile("billboard.vert", GL_VERTEX_SHADER); diff --git a/src/graphics/shader_files_manager.cpp b/src/graphics/shader_files_manager.cpp index 15c28f090..6e882c5d3 100644 --- a/src/graphics/shader_files_manager.cpp +++ b/src/graphics/shader_files_manager.cpp @@ -168,6 +168,8 @@ GLuint ShaderFilesManager::loadShader(const std::string &file, unsigned type) code << "#define Needs_Vertex_Id_Workaround\n"; if (CVS->isDefferedEnabled()) code << "#define Advanced_Lighting_Enabled\n"; + if (CVS->isARBSRGBFramebufferUsable()) + code << "#define sRGB_Framebuffer_Usable\n"; #if !defined(USE_GLES2) // shader compilation fails with some drivers if there is no precision diff --git a/src/graphics/skybox.cpp b/src/graphics/skybox.cpp index f9fd4f7af..98211dcde 100644 --- a/src/graphics/skybox.cpp +++ b/src/graphics/skybox.cpp @@ -178,14 +178,17 @@ void Skybox::generateCubeMapFromTextures() } glBindTexture(GL_TEXTURE_CUBE_MAP, m_cube_map); -#if !defined(USE_GLES2) - GLint internal_format = CVS->isTextureCompressionEnabled() ? - GL_COMPRESSED_SRGB_ALPHA : GL_SRGB_ALPHA; - GLint format = GL_BGRA; -#else - GLint internal_format = CVS->isDefferedEnabled() ? GL_SRGB8_ALPHA8 - : GL_RGBA8; + + bool needs_srgb_format = CVS->isARBSRGBFramebufferUsable() || + CVS->isDefferedEnabled(); + GLint format = GL_RGBA; + GLint internal_format = needs_srgb_format ? GL_SRGB8_ALPHA8 : GL_RGBA8; +#if !defined(USE_GLES2) + if (CVS->isTextureCompressionEnabled()) + internal_format = needs_srgb_format ? GL_COMPRESSED_SRGB_ALPHA + : GL_COMPRESSED_RGBA; + format = GL_BGRA; #endif glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, diff --git a/src/graphics/stk_texture.cpp b/src/graphics/stk_texture.cpp index 7c6323be4..feb8d11ef 100644 --- a/src/graphics/stk_texture.cpp +++ b/src/graphics/stk_texture.cpp @@ -50,12 +50,14 @@ STKTexture::STKTexture(const std::string& path, TexConfig* tc, bool no_upload) m_material = material_manager->getMaterialFor(this); } #ifndef SERVER_ONLY - if (m_tex_config && !CVS->isGLSL()) - m_tex_config->m_srgb = false; -#ifdef USE_GLES2 - if (m_tex_config && !CVS->isDefferedEnabled()) - m_tex_config->m_srgb = false; -#endif + if (m_tex_config) + { + if ((!CVS->isARBSRGBFramebufferUsable() && !CVS->isDefferedEnabled()) || + !CVS->isGLSL()) + { + m_tex_config->m_srgb = false; + } + } if (!CVS->isARBTextureSwizzleUsable()) m_single_channel = false; #endif @@ -332,10 +334,12 @@ void STKTexture::formatConversion(uint8_t* data, unsigned int* format, if (alpha > 0.0f) { alpha /= 255.0f; -#if defined(USE_GLES2) - if (CVS->isDefferedEnabled()) -#endif + + if (CVS->isARBSRGBFramebufferUsable() || + CVS->isDefferedEnabled()) + { alpha = pow(alpha, 1.0f / 2.2f); + } } data[i * 4] = (uint8_t)(data[i * 4] * alpha); data[i * 4 + 1] = (uint8_t)(data[i * 4 + 1] * alpha);