From 06fa7bd7a4656db06ccb909a3aca671bc2ca1965 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Tue, 3 Mar 2015 17:48:19 -0400 Subject: [PATCH] Don't enable SDL_GL_FRAMEBUFFER_SRGB_CAPABLE in Linux when creating the window, to work around a potential bug. sRGB windows are still possible even without that. --- src/modules/graphics/opengl/OpenGL.cpp | 18 ++++++++++++++++++ src/modules/graphics/opengl/OpenGL.h | 8 ++++++++ src/modules/graphics/opengl/Shader.cpp | 11 +++++++++-- src/modules/window/sdl/Window.cpp | 5 +++++ 4 files changed, 40 insertions(+), 2 deletions(-) diff --git a/src/modules/graphics/opengl/OpenGL.cpp b/src/modules/graphics/opengl/OpenGL.cpp index 5828c0421..facdf8b13 100644 --- a/src/modules/graphics/opengl/OpenGL.cpp +++ b/src/modules/graphics/opengl/OpenGL.cpp @@ -510,6 +510,24 @@ void OpenGL::bindTextures(GLuint first, GLsizei count, const GLuint *textures) } } +void OpenGL::bindTextureToUnit(GLuint texture, int textureunit, bool restoreprev) +{ + if (textureunit < 0 || (size_t) textureunit >= state.boundTextures.size()) + throw love::Exception("Invalid texture unit index."); + + if (texture != state.boundTextures[textureunit]) + { + int oldtextureunit = state.curTextureUnit; + setTextureUnit(textureunit); + + state.boundTextures[textureunit] = texture; + glBindTexture(GL_TEXTURE_2D, texture); + + if (restoreprev) + setTextureUnit(oldtextureunit); + } +} + void OpenGL::deleteTexture(GLuint texture) { // glDeleteTextures binds texture 0 to all texture units the deleted texture diff --git a/src/modules/graphics/opengl/OpenGL.h b/src/modules/graphics/opengl/OpenGL.h index e902b81d0..676324f83 100644 --- a/src/modules/graphics/opengl/OpenGL.h +++ b/src/modules/graphics/opengl/OpenGL.h @@ -267,6 +267,14 @@ public: **/ void bindTextures(GLuint first, GLsizei count, const GLuint *textures); + /** + * Helper for binding a texture to a specific texture unit. + * + * @param textureunit Index in the range of [0, maxtextureunits-1] + * @param restoreprev Restore previously bound texture unit when done. + **/ + void bindTextureToUnit(GLuint texture, int textureunit, bool restoreprev); + /** * Helper for deleting an OpenGL texture. * Cleans up if the texture is currently bound. diff --git a/src/modules/graphics/opengl/Shader.cpp b/src/modules/graphics/opengl/Shader.cpp index 8a386fa99..c3d296aa6 100644 --- a/src/modules/graphics/opengl/Shader.cpp +++ b/src/modules/graphics/opengl/Shader.cpp @@ -382,7 +382,14 @@ void Shader::attach(bool temporary) { // make sure all sent textures are properly bound to their respective texture units // note: list potentially contains texture ids of deleted/invalid textures! - gl.bindTextures(1, (GLsizei) activeTexUnits.size(), &activeTexUnits[0]); + for (size_t i = 0; i < activeTexUnits.size(); ++i) + { + if (activeTexUnits[i] > 0) + gl.bindTextureToUnit(activeTexUnits[i], i + 1, false); + } + + // We always want to use texture unit 0 for everyhing else. + gl.setTextureUnit(0); } } @@ -523,7 +530,7 @@ void Shader::sendTexture(const std::string &name, Texture *texture) checkSetUniformError(u, 1, 1, UNIFORM_SAMPLER); // bind texture to assigned texture unit and send uniform to shader program - gl.bindTextures(texunit, 1, &gltex); + gl.bindTextureToUnit(gltex, texunit, true); glUniform1i(u.location, texunit); diff --git a/src/modules/window/sdl/Window.cpp b/src/modules/window/sdl/Window.cpp index 3b6676d3c..8982ce0b5 100644 --- a/src/modules/window/sdl/Window.cpp +++ b/src/modules/window/sdl/Window.cpp @@ -89,7 +89,12 @@ void Window::setGLFramebufferAttributes(int msaa, bool sRGB) SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, (msaa > 0) ? 1 : 0); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, (msaa > 0) ? msaa : 0); + // SDL or GLX may have bugs with this: https://bugzilla.libsdl.org/show_bug.cgi?id=2897 + // It's fine to leave the attribute disabled on desktops though, because in + // practice the framebuffer will be sRGB-capable even if it's not requested. +#if !defined(LOVE_LINUX) SDL_GL_SetAttribute(SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, sRGB ? 1 : 0); +#endif } void Window::setGLContextAttributes(const ContextAttribs &attribs)