Browse Source

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.

Alex Szpakowski 10 years ago
parent
commit
06fa7bd7a4

+ 18 - 0
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

+ 8 - 0
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.

+ 9 - 2
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);
 

+ 5 - 0
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)