[Scummvm-cvs-logs] scummvm master -> 114ef5817fe661275f7cb99d490b72f1d287b30e

lordhoto lordhoto at gmail.com
Wed Mar 23 15:56:37 CET 2016


This automated email contains information about 60 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
e5e234b864 OPENGL: Refactor GL extension handling slightly.
8f3783da09 OPENGL: Add functionality to query OpenGL functions on runtime.
b3b3d37e3b OPENGL: Define GLCALL in opengl-sys.h.
4a781737c1 OPENGL: Resolve OpenGL functions on run-time.
e11f4df111 OPENGL: Rename GLCALL to GL_CALL.
9816e4f350 OPENGL: Remove support for ARGB8888.
d6d3e17d53 OPENGL: Allow runtime specification of OpenGL mode.
2277144623 OPENGL: Support RGB555 for OpenGL ES output.
da062ad1ea OPENGLSDL: Try to use GL(ES) context SDL2 defaults to.
af727afe0c OPENGL: Simplify context type setting.
67e2790beb OPENGLSDL: Slight cleanup.
c5ce812711 OPENGL: Simplify orthogonal projection setup.
e931018673 OPENGL: Typo.
fe88375ff3 OPENGL: Support GLES2 contexts.
1c61e017a0 OPENGL: Reset full context structure.
19abd8ccbb OPENGL: Reset context description on context destroy.
fee1aa5502 OPENGL: Add support for shaders with GL contexts.
d029f16799 OPENGL: Handle destruction gracefully when no context is setup.
b7e64c6eeb OPENGLSDL: Destroy GL context on exit with SDL2.
1802c939a1 OPENGL: Slight simplifcation for opengl-func.h usage.
5752f125e1 OPENGL: Make Context::reset explicitly reset state.
c7c870bf7f OPENGL: (Partly) move context specific handling to Context.
fc52f73050 OPENGL: Slightly cleanup programmable pipeline handling.
8a3eecb73a OPENGL: Unify shader implementation for GL and GLES2.
b8d79261ed OPENGLSDL: Request "standard" GL contexts.
5eb0ac0c9e OPENGL: Remove (some) unused GL definitions.
b081fe63e8 OPENGL: Create new abstraction for GL texture objects.
9844d89231 OPENGL: Move max texture size information to Context.
db2917dde5 OPENGL: Fix texture format for BGR565.
618adec7b0 OPENGL: Move color key handling for CLUT8 to TextureCLUT8.
8b0cf0c5f7 OPENGL: Cleanup. Remove Texture::getHardwareFormat.
de3846923c OPENGL: Introduce simple abstraction for surfaces.
e66e9e44d3 OPENGL: Accelerate palette lookups with shaders.
2319fcd228 OPENGL: Handle GLES2 and GL shaders uniformly.
397ce9b947 OPENGL: Keep feature state for all contexts and log them.
18306ee206 OPENGL: Simplify shader support checks.
bf2735cd53 OPENGL: Detect NPOT support for GLES.
08553a09cf OPENGL: Support GLSL based CLUT8 look up for GLES2+.
f5f1b6eba0 OPENGL: Introduce pipeline abstraction to cleanup code.
5498982a37 OPENGL: Introduce ShaderManager to handle builtin shaders.
c4e65732be OPENGL: Introduce abstraction for framebuffer.
472dbc4a84 CONFIGURE: Abort configure stage when invalid OpenGL mode is specified.
0b46af2f0e OPENGL: Don't prefix maxTextureSize variable for consistency.
0fe580d10c OPENGL: Make shader/framebuffer part of pipeline state.
b17c035642 OPENGL: Implement texture drawing in Pipeline instead of Surface.
ed6689d4fc OPENGL: Do not allow direct access to Context::activePipeline.
bec2088d6c OPENGL: Only allow Pipeline to switch active Framebuffers.
8a4938f82b OPENGL: Move pipeline code to pipelines/.
26f106497a OPENGL: Implement CLUT8 look up as Pipeline.
3f9852eb20 OPENGL: Make shader pipelines use fixed shaders.
8b80e9d36c OPENGL: Properly deactivate old pipeline.
6dacc96d1f OPENGL: Only set projection matrix once on pipeline activation.
baca885cfc OPENGL: Let Shader store the uniform state.
39100b6132 OPENGL: Do not hardcode any uniform/attribute handling in Shader.
2b3340474e OPENGL: Introduce convenience wrappers for get*Location in Shader.
1e1272a8c4 OPENGL: Store logical texture dimensions in GLTexture.
17b1124a5a OPENGL: Do not keep uniform state for nonexistent uniforms.
b7a269947f OPENGL: Flag texture dirty on allocation.
6b2424b635 OPENGL: Log extensions available on debuglevel 5+.
114ef5817f Merge pull request #711 from lordhoto/opengl-revamp


Commit: e5e234b864e75862a2de72ee6c3b8bda47f41c23
    https://github.com/scummvm/scummvm/commit/e5e234b864e75862a2de72ee6c3b8bda47f41c23
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:24+01:00

Commit Message:
OPENGL: Refactor GL extension handling slightly.

Changed paths:
    backends/graphics/opengl/extensions.cpp
    backends/graphics/opengl/extensions.h
    backends/graphics/opengl/opengl-graphics.cpp
    backends/graphics/opengl/opengl-graphics.h
    backends/graphics/opengl/texture.cpp



diff --git a/backends/graphics/opengl/extensions.cpp b/backends/graphics/opengl/extensions.cpp
index 4482ef8..c76f8d7 100644
--- a/backends/graphics/opengl/extensions.cpp
+++ b/backends/graphics/opengl/extensions.cpp
@@ -22,25 +22,30 @@
 
 #include "backends/graphics/opengl/extensions.h"
 #include "backends/graphics/opengl/opengl-sys.h"
+#include "backends/graphics/opengl/opengl-graphics.h"
 
 #include "common/tokenizer.h"
 
 namespace OpenGL {
 
-bool g_extNPOTSupported = false;
+void ExtensionsDesc::reset() {
+	NPOTSupported = false;
+}
+
+ExtensionsDesc g_extensions;
 
-void initializeGLExtensions() {
+void OpenGLGraphicsManager::initializeGLExtensions() {
 	const char *extString = (const char *)glGetString(GL_EXTENSIONS);
 
 	// Initialize default state.
-	g_extNPOTSupported = false;
+	g_extensions.reset();
 
 	Common::StringTokenizer tokenizer(extString, " ");
 	while (!tokenizer.empty()) {
 		Common::String token = tokenizer.nextToken();
 
 		if (token == "GL_ARB_texture_non_power_of_two") {
-			g_extNPOTSupported = true;
+			g_extensions.NPOTSupported = true;
 		}
 	}
 }
diff --git a/backends/graphics/opengl/extensions.h b/backends/graphics/opengl/extensions.h
index 8745242..5b9eb53 100644
--- a/backends/graphics/opengl/extensions.h
+++ b/backends/graphics/opengl/extensions.h
@@ -26,15 +26,28 @@
 namespace OpenGL {
 
 /**
- * Checks for availability of extensions we want to use and initializes them
- * when available.
+ * Description structure of all available extensions.
+ *
+ * This includes information whether extensions we are interested in is
+ * available or not. If extensions we are interested in add additional
+ * functions, we keep function pointers around in here too.
  */
-void initializeGLExtensions();
+struct ExtensionsDesc {
+	/**
+	 * Reset extension state.
+	 *
+	 * This marks all extensions as unavailable.
+	 */
+	void reset();
+
+	/** Whether GL_ARB_texture_non_power_of_two is available or not. */
+	bool NPOTSupported;
+};
 
 /**
- * Whether non power of two textures are supported
+ * Description of all available extensions.
  */
-extern bool g_extNPOTSupported;
+extern ExtensionsDesc g_extensions;
 
 } // End of namespace OpenGL
 
diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index ac6d41d..d738f31 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -58,6 +58,7 @@ OpenGLGraphicsManager::OpenGLGraphicsManager()
 #endif
     {
 	memset(_gamePalette, 0, sizeof(_gamePalette));
+	g_extensions.reset();
 }
 
 OpenGLGraphicsManager::~OpenGLGraphicsManager() {
diff --git a/backends/graphics/opengl/opengl-graphics.h b/backends/graphics/opengl/opengl-graphics.h
index 9578839..2a03b87 100644
--- a/backends/graphics/opengl/opengl-graphics.h
+++ b/backends/graphics/opengl/opengl-graphics.h
@@ -281,6 +281,12 @@ private:
 	//
 
 	/**
+	 * Checks for availability of extensions we want to use and initializes them
+	 * when available.
+	 */
+	void initializeGLExtensions();
+
+	/**
 	 * Try to determine the internal parameters for a given pixel format.
 	 *
 	 * @return true when the format can be used, false otherwise.
diff --git a/backends/graphics/opengl/texture.cpp b/backends/graphics/opengl/texture.cpp
index 7b0b22d..36fe5ab 100644
--- a/backends/graphics/opengl/texture.cpp
+++ b/backends/graphics/opengl/texture.cpp
@@ -105,7 +105,7 @@ void Texture::enableLinearFiltering(bool enable) {
 
 void Texture::allocate(uint width, uint height) {
 	uint texWidth = width, texHeight = height;
-	if (!g_extNPOTSupported) {
+	if (!g_extensions.NPOTSupported) {
 		texWidth  = nextHigher2(texWidth);
 		texHeight = nextHigher2(texHeight);
 	}


Commit: 8f3783da0994703e9fe6fcfc666d194c9eb00865
    https://github.com/scummvm/scummvm/commit/8f3783da0994703e9fe6fcfc666d194c9eb00865
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:24+01:00

Commit Message:
OPENGL: Add functionality to query OpenGL functions on runtime.

This can and will be used for future extension usage support.

Tizen changes have been untested.

Changed paths:
    backends/graphics/opengl/opengl-graphics.h
    backends/graphics/opengl/opengl-sys.h
    backends/graphics/openglsdl/openglsdl-graphics.cpp
    backends/graphics/openglsdl/openglsdl-graphics.h
    backends/platform/tizen/graphics.cpp
    backends/platform/tizen/graphics.h



diff --git a/backends/graphics/opengl/opengl-graphics.h b/backends/graphics/opengl/opengl-graphics.h
index 2a03b87..f83c953 100644
--- a/backends/graphics/opengl/opengl-graphics.h
+++ b/backends/graphics/opengl/opengl-graphics.h
@@ -286,6 +286,21 @@ private:
 	 */
 	void initializeGLExtensions();
 
+protected:
+	/**
+	 * Query the address of an OpenGL function by name.
+	 *
+	 * This can only be used after a context has been created.
+	 * Please note that this function can return valid addresses even if the
+	 * OpenGL context does not support the function.
+	 *
+	 * @param name The name of the OpenGL function.
+	 * @return An function pointer for the requested OpenGL function or
+	 *         nullptr in case of failure.
+	 */
+	virtual void *getProcAddress(const char *name) const = 0;
+
+private:
 	/**
 	 * Try to determine the internal parameters for a given pixel format.
 	 *
diff --git a/backends/graphics/opengl/opengl-sys.h b/backends/graphics/opengl/opengl-sys.h
index 4e21894..f4d8488 100644
--- a/backends/graphics/opengl/opengl-sys.h
+++ b/backends/graphics/opengl/opengl-sys.h
@@ -54,4 +54,10 @@ using namespace Tizen::Graphics::Opengl;
 #include <GL/gl.h>
 #endif
 
+#ifdef SDL_BACKEND
+#define GLCALLCONV APIENTRY
+#else
+#define GLCALLCONV
+#endif
+
 #endif
diff --git a/backends/graphics/openglsdl/openglsdl-graphics.cpp b/backends/graphics/openglsdl/openglsdl-graphics.cpp
index 0d140ee..d1e798e 100644
--- a/backends/graphics/openglsdl/openglsdl-graphics.cpp
+++ b/backends/graphics/openglsdl/openglsdl-graphics.cpp
@@ -305,6 +305,10 @@ void OpenGLSdlGraphicsManager::refreshScreen() {
 #endif
 }
 
+void *OpenGLSdlGraphicsManager::getProcAddress(const char *name) const {
+	return SDL_GL_GetProcAddress(name);
+}
+
 bool OpenGLSdlGraphicsManager::setupMode(uint width, uint height) {
 	// In case we request a fullscreen mode we will use the mode the user
 	// has chosen last time or the biggest mode available.
diff --git a/backends/graphics/openglsdl/openglsdl-graphics.h b/backends/graphics/openglsdl/openglsdl-graphics.h
index 1552593..fe289d6 100644
--- a/backends/graphics/openglsdl/openglsdl-graphics.h
+++ b/backends/graphics/openglsdl/openglsdl-graphics.h
@@ -67,6 +67,8 @@ protected:
 	virtual bool loadVideoMode(uint requestedWidth, uint requestedHeight, const Graphics::PixelFormat &format);
 
 	virtual void refreshScreen();
+
+	virtual void *getProcAddress(const char *name) const;
 private:
 	bool setupMode(uint width, uint height);
 
diff --git a/backends/platform/tizen/graphics.cpp b/backends/platform/tizen/graphics.cpp
index 759c4e5..971be46 100644
--- a/backends/platform/tizen/graphics.cpp
+++ b/backends/platform/tizen/graphics.cpp
@@ -206,3 +206,7 @@ bool TizenGraphicsManager::loadVideoMode(uint requestedWidth, uint requestedHeig
 void TizenGraphicsManager::refreshScreen() {
 	eglSwapBuffers(_eglDisplay, _eglSurface);
 }
+
+void *TizenGraphicsManager::getProcAddress(const char *name) const {
+	return eglGetProcAddress(name);
+}
diff --git a/backends/platform/tizen/graphics.h b/backends/platform/tizen/graphics.h
index 1522d66..1798b07 100644
--- a/backends/platform/tizen/graphics.h
+++ b/backends/platform/tizen/graphics.h
@@ -63,6 +63,8 @@ protected:
 
 	void refreshScreen();
 
+	void *getProcAddress(const char *name) const;
+
 	const Graphics::Font *getFontOSD();
 
 private:


Commit: b3b3d37e3b8231ec345a2d4172279373d53a0c79
    https://github.com/scummvm/scummvm/commit/b3b3d37e3b8231ec345a2d4172279373d53a0c79
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:24+01:00

Commit Message:
OPENGL: Define GLCALL in opengl-sys.h.

debug.h is now always included and all calls should be made through GLCALL.

Changed paths:
    backends/graphics/opengl/debug.h
    backends/graphics/opengl/opengl-graphics.cpp
    backends/graphics/opengl/opengl-sys.h
    backends/graphics/opengl/texture.cpp



diff --git a/backends/graphics/opengl/debug.h b/backends/graphics/opengl/debug.h
index ff6b678..abaa654 100644
--- a/backends/graphics/opengl/debug.h
+++ b/backends/graphics/opengl/debug.h
@@ -31,9 +31,9 @@ namespace OpenGL {
 void checkGLError(const char *expr, const char *file, int line);
 } // End of namespace OpenGL
 
-#define GLCALL(x) do { (x); OpenGL::checkGLError(#x, __FILE__, __LINE__); } while (false)
+#define GL_WRAP_DEBUG(call, name) do { (call); OpenGL::checkGLError(#name, __FILE__, __LINE__); } while (false)
 #else
-#define GLCALL(x) do { (x); } while (false)
+#define GL_WRAP_DEBUG(call, name) do { (call); } while (false)
 #endif
 
 #endif
diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index d738f31..54c4906 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -23,7 +23,6 @@
 
 #include "backends/graphics/opengl/opengl-graphics.h"
 #include "backends/graphics/opengl/texture.h"
-#include "backends/graphics/opengl/debug.h"
 #include "backends/graphics/opengl/extensions.h"
 
 #include "common/textconsole.h"
diff --git a/backends/graphics/opengl/opengl-sys.h b/backends/graphics/opengl/opengl-sys.h
index f4d8488..8d8fecf 100644
--- a/backends/graphics/opengl/opengl-sys.h
+++ b/backends/graphics/opengl/opengl-sys.h
@@ -28,6 +28,8 @@
 
 #include "common/scummsys.h"
 
+#include "backends/graphics/opengl/debug.h"
+
 #ifdef WIN32
 #if defined(ARRAYSIZE) && !defined(_WINDOWS_)
 #undef ARRAYSIZE
@@ -60,4 +62,6 @@ using namespace Tizen::Graphics::Opengl;
 #define GLCALLCONV
 #endif
 
+#define GLCALL(x) GL_WRAP_DEBUG(x, x)
+
 #endif
diff --git a/backends/graphics/opengl/texture.cpp b/backends/graphics/opengl/texture.cpp
index 36fe5ab..696e1e6 100644
--- a/backends/graphics/opengl/texture.cpp
+++ b/backends/graphics/opengl/texture.cpp
@@ -22,7 +22,7 @@
 
 #include "backends/graphics/opengl/texture.h"
 #include "backends/graphics/opengl/extensions.h"
-#include "backends/graphics/opengl/debug.h"
+#include "backends/graphics/opengl/opengl-graphics.h"
 
 #include "common/rect.h"
 #include "common/textconsole.h"


Commit: 4a781737c1da77015df4547f64f2f88966816343
    https://github.com/scummvm/scummvm/commit/4a781737c1da77015df4547f64f2f88966816343
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:24+01:00

Commit Message:
OPENGL: Resolve OpenGL functions on run-time.

Formerly we relied on static linkage. However, in the presense of modern
OpenGL (ES) implementations it is not easily identifable which library to link
against. For example, on Linux amd64 with nVidia drivers and SDL2 setup to
create a GLES 1.1 context one would need to link against libGL.so. However,
traditionally GLES 1.1 required to link against libGLESv1_CM.so. To prevent a
huge mess we simply resolve the OpenGL functions on run-time now and stop
linking against a static library (in most cases).

GLES support needs to be enabled manually on configure time for now.

Tizen changes have NOT been tested.

Changed paths:
  A backends/graphics/opengl/context.cpp
  A backends/graphics/opengl/opengl-defs.h
  A backends/graphics/opengl/opengl-func.h
  R backends/graphics/opengl/extensions.cpp
  R backends/graphics/opengl/extensions.h
    backends/graphics/opengl/debug.cpp
    backends/graphics/opengl/opengl-graphics.cpp
    backends/graphics/opengl/opengl-graphics.h
    backends/graphics/opengl/opengl-sys.h
    backends/graphics/opengl/texture.cpp
    backends/module.mk
    configure
    devtools/create_project/create_project.cpp
    devtools/create_project/xcode.cpp



diff --git a/backends/graphics/opengl/context.cpp b/backends/graphics/opengl/context.cpp
new file mode 100644
index 0000000..c4869c2
--- /dev/null
+++ b/backends/graphics/opengl/context.cpp
@@ -0,0 +1,69 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "backends/graphics/opengl/opengl-sys.h"
+#include "backends/graphics/opengl/opengl-graphics.h"
+
+#include "common/tokenizer.h"
+
+namespace OpenGL {
+
+void Context::reset() {
+	NPOTSupported = false;
+}
+
+Context g_context;
+
+void OpenGLGraphicsManager::initializeGLContext() {
+	// Initialize default state.
+	g_context.reset();
+
+	// Load all functions.
+	// We use horrible trickery to silence C++ compilers.
+	// See backends/plugins/sdl/sdl-provider.cpp for more information.
+	assert(sizeof(void (*)()) == sizeof(void *));
+	void *fn = nullptr;
+#define GL_EXT_FUNC_DEF(ret, name, param) \
+	fn = getProcAddress(#name); \
+	memcpy(&g_context.name, &fn, sizeof(fn))
+#ifdef USE_BUILTIN_OPENGL
+#define GL_FUNC_DEF(ret, name, param) g_context.name = &name
+#else
+#define GL_FUNC_DEF GL_EXT_FUNC_DEF
+#endif
+#include "backends/graphics/opengl/opengl-func.h"
+#undef GL_EXT_FUNC_DEF
+#undef GL_FUNC_DEF
+
+	const char *extString = (const char *)g_context.glGetString(GL_EXTENSIONS);
+
+	Common::StringTokenizer tokenizer(extString, " ");
+	while (!tokenizer.empty()) {
+		Common::String token = tokenizer.nextToken();
+
+		if (token == "GL_ARB_texture_non_power_of_two") {
+			g_context.NPOTSupported = true;
+		}
+	}
+}
+
+} // End of namespace OpenGL
diff --git a/backends/graphics/opengl/debug.cpp b/backends/graphics/opengl/debug.cpp
index d5d73fb..c4319f5 100644
--- a/backends/graphics/opengl/debug.cpp
+++ b/backends/graphics/opengl/debug.cpp
@@ -54,7 +54,7 @@ Common::String getGLErrStr(GLenum error) {
 void checkGLError(const char *expr, const char *file, int line) {
 	GLenum error;
 
-	while ((error = glGetError()) != GL_NO_ERROR) {
+	while ((error = g_context.glGetError()) != GL_NO_ERROR) {
 		// We cannot use error here because we do not know whether we have a
 		// working screen or not.
 		warning("GL ERROR: %s on %s (%s:%d)", getGLErrStr(error).c_str(), expr, file, line);
diff --git a/backends/graphics/opengl/extensions.cpp b/backends/graphics/opengl/extensions.cpp
deleted file mode 100644
index c76f8d7..0000000
--- a/backends/graphics/opengl/extensions.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "backends/graphics/opengl/extensions.h"
-#include "backends/graphics/opengl/opengl-sys.h"
-#include "backends/graphics/opengl/opengl-graphics.h"
-
-#include "common/tokenizer.h"
-
-namespace OpenGL {
-
-void ExtensionsDesc::reset() {
-	NPOTSupported = false;
-}
-
-ExtensionsDesc g_extensions;
-
-void OpenGLGraphicsManager::initializeGLExtensions() {
-	const char *extString = (const char *)glGetString(GL_EXTENSIONS);
-
-	// Initialize default state.
-	g_extensions.reset();
-
-	Common::StringTokenizer tokenizer(extString, " ");
-	while (!tokenizer.empty()) {
-		Common::String token = tokenizer.nextToken();
-
-		if (token == "GL_ARB_texture_non_power_of_two") {
-			g_extensions.NPOTSupported = true;
-		}
-	}
-}
-
-} // End of namespace OpenGL
diff --git a/backends/graphics/opengl/extensions.h b/backends/graphics/opengl/extensions.h
deleted file mode 100644
index 5b9eb53..0000000
--- a/backends/graphics/opengl/extensions.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef BACKENDS_GRAPHICS_OPENGL_EXTENSIONS_H
-#define BACKENDS_GRAPHICS_OPENGL_EXTENSIONS_H
-
-namespace OpenGL {
-
-/**
- * Description structure of all available extensions.
- *
- * This includes information whether extensions we are interested in is
- * available or not. If extensions we are interested in add additional
- * functions, we keep function pointers around in here too.
- */
-struct ExtensionsDesc {
-	/**
-	 * Reset extension state.
-	 *
-	 * This marks all extensions as unavailable.
-	 */
-	void reset();
-
-	/** Whether GL_ARB_texture_non_power_of_two is available or not. */
-	bool NPOTSupported;
-};
-
-/**
- * Description of all available extensions.
- */
-extern ExtensionsDesc g_extensions;
-
-} // End of namespace OpenGL
-
-#endif
diff --git a/backends/graphics/opengl/opengl-defs.h b/backends/graphics/opengl/opengl-defs.h
new file mode 100644
index 0000000..4b82d7e
--- /dev/null
+++ b/backends/graphics/opengl/opengl-defs.h
@@ -0,0 +1,219 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/* This file is based on Mesa 3-D's gl.h and GLES/gl.h from Khronos Registry.
+ *
+ * Mesa 3-D's gl.h file is distributed under the following license:
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
+ * Copyright (C) 2009  VMware, Inc.  All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ * GLES/gl.h from Khronos Registry is distributed under the following license:
+ * This document is licensed under the SGI Free Software B License Version
+ * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ .
+ */
+
+#ifndef BACKENDS_GRAPHICS_OPENGL_OPENGL_DEFS_H
+#define BACKENDS_GRAPHICS_OPENGL_OPENGL_DEFS_H
+
+#include "common/scummsys.h"
+
+/*
+ * Datatypes
+ */
+typedef uint   GLenum;
+typedef uint8  GLboolean;
+typedef uint   GLbitfield;
+typedef void   GLvoid;
+typedef int8   GLbyte;   /* 1-byte signed */
+typedef int16  GLshort;  /* 2-byte signed */
+typedef int32  GLint;    /* 4-byte signed */
+typedef uint8  GLubyte;  /* 1-byte unsigned */
+typedef uint16 GLushort; /* 2-byte unsigned */
+typedef uint32 GLuint;   /* 4-byte unsigned */
+typedef int32  GLsizei;  /* 4-byte signed */
+typedef float  GLfloat;  /* single precision float */
+typedef float  GLclampf; /* single precision float in [0,1] */
+typedef double GLdouble; /* double precision float */
+typedef double GLclampd; /* double precision float in [0,1] */
+
+/*
+ * Constants
+ */
+
+/* StringName */
+#define GL_VENDOR                         0x1F00
+#define GL_RENDERER                       0x1F01
+#define GL_VERSION                        0x1F02
+#define GL_EXTENSIONS                     0x1F03
+
+/* ErrorCode */
+#define GL_NO_ERROR                       0
+#define GL_INVALID_ENUM                   0x0500
+#define GL_INVALID_VALUE                  0x0501
+#define GL_INVALID_OPERATION              0x0502
+#define GL_STACK_OVERFLOW                 0x0503
+#define GL_STACK_UNDERFLOW                0x0504
+#define GL_OUT_OF_MEMORY                  0x0505
+
+/* ClearBufferMask */
+#define GL_DEPTH_BUFFER_BIT               0x00000100
+#define GL_STENCIL_BUFFER_BIT             0x00000400
+#define GL_COLOR_BUFFER_BIT               0x00004000
+
+/* Scissor box */
+#define GL_SCISSOR_BOX                    0x0C10
+#define GL_SCISSOR_TEST                   0x0C11
+
+/* MatrixMode */
+#define GL_MATRIX_MODE                    0x0BA0
+#define GL_MODELVIEW                      0x1700
+#define GL_PROJECTION                     0x1701
+#define GL_TEXTURE                        0x1702
+
+/* EnableCap */
+#define GL_FOG                            0x0B60
+#define GL_LIGHTING                       0x0B50
+#define GL_TEXTURE_2D                     0x0DE1
+#define GL_CULL_FACE                      0x0B44
+#define GL_ALPHA_TEST                     0x0BC0
+#define GL_BLEND                          0x0BE2
+#define GL_DITHER                         0x0BD0
+#define GL_DEPTH_TEST                     0x0B71
+#define GL_VERTEX_ARRAY                   0x8074
+#define GL_COLOR_ARRAY                    0x8076
+#define GL_TEXTURE_COORD_ARRAY            0x8078
+
+/* ShadingModel */
+#define GL_FLAT                           0x1D00
+#define GL_SMOOTH                         0x1D01
+
+/* HintMode */
+#define GL_DONT_CARE                      0x1100
+#define GL_FASTEST                        0x1101
+#define GL_NICEST                         0x1102
+
+/* HintTarget */
+#define GL_PERSPECTIVE_CORRECTION_HINT    0x0C50
+#define GL_POINT_SMOOTH_HINT              0x0C51
+#define GL_LINE_SMOOTH_HINT               0x0C52
+#define GL_FOG_HINT                       0x0C54
+#define GL_GENERATE_MIPMAP_HINT           0x8192
+
+/* BlendingFactorDest */
+#define GL_ZERO                           0
+#define GL_ONE                            1
+#define GL_SRC_COLOR                      0x0300
+#define GL_ONE_MINUS_SRC_COLOR            0x0301
+#define GL_SRC_ALPHA                      0x0302
+#define GL_ONE_MINUS_SRC_ALPHA            0x0303
+#define GL_DST_ALPHA                      0x0304
+#define GL_ONE_MINUS_DST_ALPHA            0x0305
+
+/* BlendingFactorSrc */
+/*      GL_ZERO */
+/*      GL_ONE */
+#define GL_DST_COLOR                      0x0306
+#define GL_ONE_MINUS_DST_COLOR            0x0307
+#define GL_SRC_ALPHA_SATURATE             0x0308
+/*      GL_SRC_ALPHA */
+/*      GL_ONE_MINUS_SRC_ALPHA */
+/*      GL_DST_ALPHA */
+/*      GL_ONE_MINUS_DST_ALPHA */
+
+/* PixelFormat */
+#define GL_ALPHA                          0x1906
+#define GL_RGB                            0x1907
+#define GL_RGBA                           0x1908
+#define GL_BGR                            0x80E0
+#define GL_BGRA                           0x80E1
+
+/* PixelStoreParameter */
+#define GL_UNPACK_ALIGNMENT               0x0CF5
+#define GL_PACK_ALIGNMENT                 0x0D05
+
+/* DataType */
+#define GL_BYTE                           0x1400
+#define GL_UNSIGNED_BYTE                  0x1401
+#define GL_SHORT                          0x1402
+#define GL_UNSIGNED_SHORT                 0x1403
+#define GL_FLOAT                          0x1406
+#define GL_FIXED                          0x140C
+
+/* PixelType */
+/*      GL_UNSIGNED_BYTE */
+#define GL_UNSIGNED_SHORT_4_4_4_4         0x8033
+#define GL_UNSIGNED_SHORT_5_5_5_1         0x8034
+#define GL_UNSIGNED_SHORT_5_6_5           0x8363
+
+#define GL_UNSIGNED_SHORT_4_4_4_4_REV     0x8365
+#define GL_UNSIGNED_SHORT_1_5_5_5_REV     0x8366
+#define GL_UNSIGNED_INT_8_8_8_8           0x8035
+#define GL_UNSIGNED_INT_8_8_8_8_REV       0x8367
+
+/* Implementation limits */
+#define GL_MAX_TEXTURE_SIZE               0x0D33
+
+/* TextureMagFilter */
+#define GL_NEAREST                        0x2600
+#define GL_LINEAR                         0x2601
+
+/* TextureParameterName */
+#define GL_TEXTURE_MAG_FILTER             0x2800
+#define GL_TEXTURE_MIN_FILTER             0x2801
+#define GL_TEXTURE_WRAP_S                 0x2802
+#define GL_TEXTURE_WRAP_T                 0x2803
+
+/* TextureWrapMode */
+#define GL_REPEAT                         0x2901
+#define GL_CLAMP_TO_EDGE                  0x812F
+
+/* BeginMode */
+#define GL_POINTS                         0x0000
+#define GL_LINES                          0x0001
+#define GL_LINE_LOOP                      0x0002
+#define GL_LINE_STRIP                     0x0003
+#define GL_TRIANGLES                      0x0004
+#define GL_TRIANGLE_STRIP                 0x0005
+#define GL_TRIANGLE_FAN                   0x0006
+
+#endif
diff --git a/backends/graphics/opengl/opengl-func.h b/backends/graphics/opengl/opengl-func.h
new file mode 100644
index 0000000..75bc0b4
--- /dev/null
+++ b/backends/graphics/opengl/opengl-func.h
@@ -0,0 +1,97 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/* This file is based on Mesa 3-D's gl.h and GLES/gl.h from Khronos Registry.
+ *
+ * Mesa 3-D's gl.h file is distributed under the following license:
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
+ * Copyright (C) 2009  VMware, Inc.  All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ * GLES/gl.h from Khronos Registry is distributed under the following license:
+ * This document is licensed under the SGI Free Software B License Version
+ * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ .
+ */
+
+/*
+ * This file is a template file to be used inside specific locations in the
+ * OpenGL graphics code. It is not to be included otherwise. It intentionally
+ * does not contain include guards because it can be required to include it
+ * multiple times in a source file.
+ *
+ * Functions are defined by two different user supplied macros:
+ * GL_FUNC_DEF: Define a (builtin) OpenGL (ES) function.
+ * GL_EXT_FUNC_DEF: Define an OpenGL (ES) extension function.
+ */
+
+GL_FUNC_DEF(void, glEnable, (GLenum cap));
+GL_FUNC_DEF(void, glDisable, (GLenum cap));
+GL_FUNC_DEF(void, glClear, (GLbitfield mask));
+GL_FUNC_DEF(void, glColor4f, (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha));
+GL_FUNC_DEF(void, glViewport, (GLint x, GLint y, GLsizei width, GLsizei height));
+GL_FUNC_DEF(void, glMatrixMode, (GLenum mode));
+GL_FUNC_DEF(void, glLoadIdentity, ());
+#ifdef USE_GLES
+GL_FUNC_DEF(void, glOrthof, (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar));
+#else
+GL_FUNC_DEF(void, glOrtho, (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val));
+#endif
+GL_FUNC_DEF(void, glShadeModel, (GLenum mode));
+GL_FUNC_DEF(void, glHint, (GLenum target, GLenum mode));
+GL_FUNC_DEF(void, glClearColor, (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha));
+GL_FUNC_DEF(void, glBlendFunc, (GLenum sfactor, GLenum dfactor));
+GL_FUNC_DEF(void, glEnableClientState, (GLenum array));
+GL_FUNC_DEF(void, glPixelStorei, (GLenum pname, GLint param));
+GL_FUNC_DEF(void, glScissor, (GLint x, GLint y, GLsizei width, GLsizei height));
+GL_FUNC_DEF(void, glReadPixels, (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels));
+GL_FUNC_DEF(void, glGetIntegerv, (GLenum pname, GLint *params));
+GL_FUNC_DEF(void, glDeleteTextures, (GLsizei n, const GLuint *textures));
+GL_FUNC_DEF(void, glGenTextures, (GLsizei n, GLuint *textures));
+GL_FUNC_DEF(void, glBindTexture, (GLenum target, GLuint texture));
+GL_FUNC_DEF(void, glTexParameteri, (GLenum target, GLenum pname, GLint param));
+GL_FUNC_DEF(void, glTexImage2D, (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels));
+GL_FUNC_DEF(void, glTexCoordPointer, (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer));
+GL_FUNC_DEF(void, glVertexPointer, (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer));
+GL_FUNC_DEF(void, glDrawArrays, (GLenum mode, GLint first, GLsizei count));
+GL_FUNC_DEF(void, glTexSubImage2D, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels));
+GL_FUNC_DEF(const GLubyte *, glGetString, (GLenum name));
+GL_FUNC_DEF(GLenum, glGetError, ());
diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index 54c4906..2af7da5 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -23,7 +23,6 @@
 
 #include "backends/graphics/opengl/opengl-graphics.h"
 #include "backends/graphics/opengl/texture.h"
-#include "backends/graphics/opengl/extensions.h"
 
 #include "common/textconsole.h"
 #include "common/translation.h"
@@ -57,7 +56,7 @@ OpenGLGraphicsManager::OpenGLGraphicsManager()
 #endif
     {
 	memset(_gamePalette, 0, sizeof(_gamePalette));
-	g_extensions.reset();
+	g_context.reset();
 }
 
 OpenGLGraphicsManager::~OpenGLGraphicsManager() {
@@ -836,8 +835,8 @@ void OpenGLGraphicsManager::setActualScreenSize(uint width, uint height) {
 }
 
 void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &defaultFormat, const Graphics::PixelFormat &defaultFormatAlpha) {
-	// Initialize all extensions.
-	initializeGLExtensions();
+	// Initialize context for use.
+	initializeGLContext();
 
 	// Disable 3D properties.
 	GLCALL(glDisable(GL_CULL_FACE));
diff --git a/backends/graphics/opengl/opengl-graphics.h b/backends/graphics/opengl/opengl-graphics.h
index f83c953..3d5f74b 100644
--- a/backends/graphics/opengl/opengl-graphics.h
+++ b/backends/graphics/opengl/opengl-graphics.h
@@ -281,10 +281,9 @@ private:
 	//
 
 	/**
-	 * Checks for availability of extensions we want to use and initializes them
-	 * when available.
+	 * Initialize the active context for use.
 	 */
-	void initializeGLExtensions();
+	void initializeGLContext();
 
 protected:
 	/**
diff --git a/backends/graphics/opengl/opengl-sys.h b/backends/graphics/opengl/opengl-sys.h
index 8d8fecf..08b3b45 100644
--- a/backends/graphics/opengl/opengl-sys.h
+++ b/backends/graphics/opengl/opengl-sys.h
@@ -23,45 +23,70 @@
 #ifndef BACKENDS_GRAPHICS_OPENGL_OPENGL_SYS_H
 #define BACKENDS_GRAPHICS_OPENGL_OPENGL_SYS_H
 
-// The purpose of this header is to include the OpenGL headers in an uniform
-// fashion. A notable example for a non standard port is the Tizen port.
-
 #include "common/scummsys.h"
 
 #include "backends/graphics/opengl/debug.h"
-
-#ifdef WIN32
-#if defined(ARRAYSIZE) && !defined(_WINDOWS_)
-#undef ARRAYSIZE
-#endif
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#undef ARRAYSIZE
-#endif
-
-// HACK: In case common/util.h has been included already we need to make sure
-// to define ARRAYSIZE again in case of Windows.
-#if !defined(ARRAYSIZE) && defined(COMMON_UTIL_H)
-#define ARRAYSIZE(x) ((int)(sizeof(x) / sizeof(x[0])))
+#ifdef SDL_BACKEND
+#include "backends/platform/sdl/sdl-sys.h"
 #endif
 
+// On Tizen we include the toolchain's OpenGL file. This is something we
+// actually want to avoid. However, since Tizen uses eglGetProcAddress which
+// is not required to return valid function pointers to non OpenGL extension
+// functions, we need the system's definitions to resolve all OpenGL
+// functions.
+// TODO: See if there is an alternative which allows us to avoid including
+// Tizen's OpenGL header here.
 #if defined(TIZEN)
-#include <FGraphicsOpengl.h>
-using namespace Tizen::Graphics::Opengl;
-#elif defined(USE_GLES)
-#include <GLES/gl.h>
-#elif defined(SDL_BACKEND)
-#include <SDL_opengl.h>
+	#include <FGraphicsOpengl.h>
+	using namespace Tizen::Graphics::Opengl;
+	#define USE_BUILTIN_OPENGL
 #else
-#include <GL/gl.h>
+	#include "backends/graphics/opengl/opengl-defs.h"
 #endif
 
 #ifdef SDL_BACKEND
-#define GLCALLCONV APIENTRY
+	// Win32 needs OpenGL functions declared with APIENTRY.
+	// However, SDL does not define APIENTRY in it's SDL.h file on non-Windows
+	// targets, thus if it is not available, we just dummy define it.
+	#ifndef APIENTRY
+		#define APIENTRY
+	#endif
+	#define GL_CALL_CONV APIENTRY
 #else
-#define GLCALLCONV
+	#define GL_CALL_CONV
 #endif
 
-#define GLCALL(x) GL_WRAP_DEBUG(x, x)
+namespace OpenGL {
+
+/**
+ * Description structure of the OpenGL (ES) context.
+ */
+struct Context {
+	/**
+	 * Reset context.
+	 *
+	 * This marks all extensions as unavailable.
+	 */
+	void reset();
+
+	/** Whether GL_ARB_texture_non_power_of_two is available or not. */
+	bool NPOTSupported;
+
+#define GL_FUNC_DEF(ret, name, param) ret (GL_CALL_CONV *name)param
+#define GL_EXT_FUNC_DEF GL_FUNC_DEF
+#include "backends/graphics/opengl/opengl-func.h"
+#undef GL_EXT_FUNC_DEF
+#undef GL_FUNC_DEF
+};
+
+/**
+ * The (active) OpenGL context.
+ */
+extern Context g_context;
+
+} // End of namespace OpenGL
+
+#define GLCALL(x) GL_WRAP_DEBUG(g_context.x, x)
 
 #endif
diff --git a/backends/graphics/opengl/texture.cpp b/backends/graphics/opengl/texture.cpp
index 696e1e6..bc25500 100644
--- a/backends/graphics/opengl/texture.cpp
+++ b/backends/graphics/opengl/texture.cpp
@@ -21,8 +21,6 @@
  */
 
 #include "backends/graphics/opengl/texture.h"
-#include "backends/graphics/opengl/extensions.h"
-#include "backends/graphics/opengl/opengl-graphics.h"
 
 #include "common/rect.h"
 #include "common/textconsole.h"
@@ -44,7 +42,7 @@ static GLuint nextHigher2(GLuint v) {
 GLint Texture::_maxTextureSize = 0;
 
 void Texture::queryTextureInformation() {
-	glGetIntegerv(GL_MAX_TEXTURE_SIZE, &_maxTextureSize);
+	GLCALL(glGetIntegerv(GL_MAX_TEXTURE_SIZE, &_maxTextureSize));
 	debug(5, "OpenGL maximum texture size: %d", _maxTextureSize);
 }
 
@@ -105,7 +103,7 @@ void Texture::enableLinearFiltering(bool enable) {
 
 void Texture::allocate(uint width, uint height) {
 	uint texWidth = width, texHeight = height;
-	if (!g_extensions.NPOTSupported) {
+	if (!g_context.NPOTSupported) {
 		texWidth  = nextHigher2(texWidth);
 		texHeight = nextHigher2(texHeight);
 	}
diff --git a/backends/module.mk b/backends/module.mk
index 3d412c0..e1c3483 100644
--- a/backends/module.mk
+++ b/backends/module.mk
@@ -52,8 +52,8 @@ endif
 # OpenGL specific source files.
 ifdef USE_OPENGL
 MODULE_OBJS += \
+	graphics/opengl/context.o \
 	graphics/opengl/debug.o \
-	graphics/opengl/extensions.o \
 	graphics/opengl/opengl-graphics.o \
 	graphics/opengl/texture.o
 endif
diff --git a/configure b/configure
index 0e7a5a9..8d465bc 100755
--- a/configure
+++ b/configure
@@ -134,7 +134,7 @@ _theoradec=auto
 _faad=auto
 _fluidsynth=auto
 _opengl=auto
-_opengles=auto
+_opengles=no
 _readline=auto
 _freetype2=auto
 _taskbar=auto
@@ -964,8 +964,8 @@ Optional Libraries:
   --with-mpeg2-prefix=DIR  Prefix where libmpeg2 is installed (optional)
   --enable-mpeg2           enable mpeg2 codec for cutscenes [autodetect]
 
-  --with-opengl-prefix=DIR Prefix where OpenGL (ES) is installed (optional)
   --disable-opengl         disable OpenGL (ES) support [autodetect]
+  --enable-opengles        enable forced OpenGL ES mode [disabled]
 
   --with-jpeg-prefix=DIR   Prefix where libjpeg is installed (optional)
   --disable-jpeg           disable JPEG decoder [autodetect]
@@ -1073,6 +1073,8 @@ for ac_option in $@; do
 	--disable-libunity)       _libunity=no    ;;
 	--enable-opengl)          _opengl=yes     ;;
 	--disable-opengl)         _opengl=no      ;;
+	--enable-opengles)        _opengles=yes   ;;
+	--disable-opengles)       _opengles=no    ;;
 	--enable-bink)            _bink=yes       ;;
 	--disable-bink)           _bink=no        ;;
 	--enable-verbose-build)   _verbose_build=yes ;;
@@ -1175,11 +1177,6 @@ for ac_option in $@; do
 		LIBUNITY_CFLAGS="-I$arg/include"
 		LIBUNITY_LIBS="-L$arg/lib"
 		;;
-	--with-opengl-prefix=*)
-		arg=`echo $ac_option | cut -d '=' -f 2`
-		OPENGL_CFLAGS="-I$arg/include"
-		OPENGL_LIBS="-L$arg/lib"
-		;;
 	--backend=*)
 		_backend=`echo $ac_option | cut -d '=' -f 2`
 		;;
@@ -2990,6 +2987,9 @@ if test -n "$_host"; then
 			_mt32emu=no
 			_timidity=no
 			_vkeybd=yes
+			# Tizen relies on the OpenGL ES output thus we always enable it.
+			_opengl=yes
+			_opengles=yes
 			;;
 		webos)
 			_backend="webos"
@@ -4154,101 +4154,23 @@ case $_backend in
 		if test "$_opengl" = yes ; then
 			_opengl=yes
 			_opengles=yes
-			OPENGL_LIBS="-lGLES_CM -lEGL -lX11"
-			OPENGL_CFLAGS="$OPENGL_LIBS"
-			append_var LIBS "$OPENGL_LIBS"
-			append_var INCLUDES "$OPENGL_CFLAGS"
+			append_var LIBS "-lGLES_CM -lEGL -lX11"
 		fi
 		;;
 esac
 
 if test "$_opengl" = auto ; then
-	_opengl=no
-	if test "$_backend" = "sdl" ; then
-		# Try different header filenames
-		# 1) GL/gl.h         This is usually used on POSIX and Windows systems
-		# 2) OpenGL/gl.h     This is used on Mac OS X
-		# 3) GLES/gl.h       This is used for OpenGL ES 1.x
-		for i in "GL/gl.h" "OpenGL/gl.h" "GLES/gl.h"; do
-			# Test the current header for OpenGL
-			cat > $TMPC << EOF
-#include <$i>
-#include <stdio.h>
-int main(void) { printf("ANTIVIRUS FALSE POSITIVE WORKAROUND"); return GL_VERSION_1_1; }
-EOF
-			cc_check $DEFINES $OPENGL_CFLAGS $OPENGL_LIBS && _opengl=yes && break
-
-			# Test the current header for OpenGL ES
-			cat > $TMPC << EOF
-#include <$i>
-int main(void) { return GL_OES_VERSION_1_1; }
-EOF
-			cc_check $DEFINES $OPENGL_CFLAGS $OPENGL_LIBS && _opengl=yes && _opengles=yes && break
-
-			# Test the current header for OpenGL ES on SBCs (Raspberry Pi, Cubieboard, etc)
-			cat > $TMPC << EOF
-#include <$i>
-int main(void) { return GL_VERSION_ES_CM_1_1; }
-EOF
-			cc_check $DEFINES $OPENGL_CFLAGS $OPENGL_LIBS && _opengl=yes && _opengles=yes && break
-		done
-	fi
-fi
-if test "$_opengl" = yes ; then
-	# Our simple test case
-	cat > $TMPC << EOF
-int main(void) { return 0; }
-EOF
-
-	_opengl=no
-	# Try different library names
-	if test "$_opengles" = "yes" ; then
-		# 1) GLES_CM    This is usually used for OpenGL ES 1.1 (Common profile)
-		# 2) GLESv1_CM  This is used by the Windows Mali OpenGL ES 1.1 Emulator
-		# 3) glesv1     This is used by the Linux Mali OpenGL ES 1.1 Emulator
-		_opengles=no
-		for lib in "-lGLES_CM" "-lGLESv1_CM" "-lglesv1"; do
-			if cc_check_no_clean $DEFINES $OPENGL_CFLAGS $OPENGL_LIBS $lib
-				then
-				_opengl=yes
-				_opengles=yes
-				OPENGL_LIBS="$OPENGL_LIBS $lib"
-				break
-			fi
-		done
-	else
-		# 1) -framework OpenGL  This is used on Mac OS X
-		# 2) GL                 This is usually used on POSIX systems
-		# 3) opengl32           This is used on Windows
-		#
-		# We try "-framework OpenGL" first here to assure it will always be
-		# picked up by the configure script on Mac OS X, even when a libGL
-		# exists.
-		for lib in "-framework OpenGL" "-lGL" "-lopengl32"; do
-			if cc_check_no_clean $DEFINES $OPENGL_CFLAGS $OPENGL_LIBS $lib
-				then
-				_opengl=yes
-				OPENGL_LIBS="$OPENGL_LIBS $lib"
-				break
-			fi
-		done
-	fi
-	cc_check_clean
+	case $_backend in
+		sdl)
+			_opengl=yes
+			;;
 
-	if test "$_opengl" = yes ; then
-		append_var LIBS "$OPENGL_LIBS"
-		append_var INCLUDES "$OPENGL_CFLAGS"
-	fi
+		*)
+			_opengl=no
+			;;
+	esac
 fi
 
-case $_host_os in
-	tizen)
-		# components live in non-standard locations so just assume sane SDK
-		_opengl=yes
-		_opengles=yes
-		;;
-esac
-
 if test "$_opengles" = "yes" ; then
 	echo "yes (OpenGL ES)"
 else
diff --git a/devtools/create_project/create_project.cpp b/devtools/create_project/create_project.cpp
index aa450f1..adfe75c 100644
--- a/devtools/create_project/create_project.cpp
+++ b/devtools/create_project/create_project.cpp
@@ -954,7 +954,8 @@ const Feature s_features[] = {
 	{           "16bit",        "USE_RGB_COLOR",         "", true,  "16bit color support" },
 	{         "mt32emu",          "USE_MT32EMU",         "", true,  "integrated MT-32 emulator" },
 	{            "nasm",             "USE_NASM",         "", true,  "IA-32 assembly support" }, // This feature is special in the regard, that it needs additional handling.
-	{          "opengl",           "USE_OPENGL", "opengl32", true,  "OpenGL support" },
+	{          "opengl",           "USE_OPENGL",         "", true,  "OpenGL support" },
+	{        "opengles",             "USE_GLES",         "", true,  "forced OpenGL ES mode" },
 	{         "taskbar",          "USE_TASKBAR",         "", true,  "Taskbar integration support" },
 	{     "translation",      "USE_TRANSLATION",         "", true,  "Translation support" },
 	{          "vkeybd",        "ENABLE_VKEYBD",         "", false, "Virtual keyboard support"},
diff --git a/devtools/create_project/xcode.cpp b/devtools/create_project/xcode.cpp
index a43730f..ac7a1d0 100644
--- a/devtools/create_project/xcode.cpp
+++ b/devtools/create_project/xcode.cpp
@@ -447,9 +447,6 @@ void XcodeProvider::setupFrameworksBuildPhase(const BuildSetup &setup) {
 	DEF_SYSFRAMEWORK("UIKit");
 	DEF_SYSTBD("libiconv");
 
-	// Optionals:
-	DEF_SYSFRAMEWORK("OpenGL");
-
 	// Local libraries
 	DEF_LOCALLIB_STATIC("libFLAC");
 	DEF_LOCALLIB_STATIC("libmad");
@@ -570,8 +567,6 @@ void XcodeProvider::setupFrameworksBuildPhase(const BuildSetup &setup) {
 	frameworks_osx.push_back("IOKit.framework");
 	frameworks_osx.push_back("Cocoa.framework");
 	frameworks_osx.push_back("AudioUnit.framework");
-	// Optionals:
-	frameworks_osx.push_back("OpenGL.framework");
 
 	order = 0;
 	for (ValueList::iterator framework = frameworks_osx.begin(); framework != frameworks_osx.end(); framework++) {


Commit: e11f4df1118eb0858f4d3bfda697e63174d5e2d1
    https://github.com/scummvm/scummvm/commit/e11f4df1118eb0858f4d3bfda697e63174d5e2d1
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:24+01:00

Commit Message:
OPENGL: Rename GLCALL to GL_CALL.

Changed paths:
    backends/graphics/opengl/opengl-graphics.cpp
    backends/graphics/opengl/opengl-sys.h
    backends/graphics/opengl/texture.cpp



diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index 2af7da5..34d4ca8 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -370,13 +370,13 @@ void OpenGLGraphicsManager::updateScreen() {
 		// cleared. For example, when switching from overlay visible to
 		// invisible, we need to assure that all contents are cleared to
 		// properly remove all overlay contents.
-		GLCALL(glDisable(GL_SCISSOR_TEST));
-		GLCALL(glClear(GL_COLOR_BUFFER_BIT));
-		GLCALL(glEnable(GL_SCISSOR_TEST));
+		GL_CALL(glDisable(GL_SCISSOR_TEST));
+		GL_CALL(glClear(GL_COLOR_BUFFER_BIT));
+		GL_CALL(glEnable(GL_SCISSOR_TEST));
 
 		--_scissorOverride;
 	} else {
-		GLCALL(glClear(GL_COLOR_BUFFER_BIT));
+		GL_CALL(glClear(GL_COLOR_BUFFER_BIT));
 	}
 
 	const GLfloat shakeOffset = _gameScreenShakeOffset * (GLfloat)_displayHeight / _gameScreen->getHeight();
@@ -418,13 +418,13 @@ void OpenGLGraphicsManager::updateScreen() {
 		}
 
 		// Set the OSD transparency.
-		GLCALL(glColor4f(1.0f, 1.0f, 1.0f, _osdAlpha / 100.0f));
+		GL_CALL(glColor4f(1.0f, 1.0f, 1.0f, _osdAlpha / 100.0f));
 
 		// Draw the OSD texture.
 		_osd->draw(0, 0, _outputScreenWidth, _outputScreenHeight);
 
 		// Reset color.
-		GLCALL(glColor4f(1.0f, 1.0f, 1.0f, 1.0f));
+		GL_CALL(glColor4f(1.0f, 1.0f, 1.0f, 1.0f));
 	}
 #endif
 
@@ -466,7 +466,7 @@ void OpenGLGraphicsManager::showOverlay() {
 	_forceRedraw = true;
 
 	// Allow drawing inside full screen area.
-	GLCALL(glDisable(GL_SCISSOR_TEST));
+	GL_CALL(glDisable(GL_SCISSOR_TEST));
 
 	// Update cursor position.
 	setMousePosition(_cursorX, _cursorY);
@@ -477,7 +477,7 @@ void OpenGLGraphicsManager::hideOverlay() {
 	_forceRedraw = true;
 
 	// Limit drawing to screen area.
-	GLCALL(glEnable(GL_SCISSOR_TEST));
+	GL_CALL(glEnable(GL_SCISSOR_TEST));
 	_scissorOverride = 3;
 
 	// Update cursor position.
@@ -755,17 +755,17 @@ void OpenGLGraphicsManager::setActualScreenSize(uint width, uint height) {
 	_outputScreenHeight = height;
 
 	// Setup coordinates system.
-	GLCALL(glViewport(0, 0, _outputScreenWidth, _outputScreenHeight));
+	GL_CALL(glViewport(0, 0, _outputScreenWidth, _outputScreenHeight));
 
-	GLCALL(glMatrixMode(GL_PROJECTION));
-	GLCALL(glLoadIdentity());
+	GL_CALL(glMatrixMode(GL_PROJECTION));
+	GL_CALL(glLoadIdentity());
 #ifdef USE_GLES
-	GLCALL(glOrthof(0, _outputScreenWidth, _outputScreenHeight, 0, -1, 1));
+	GL_CALL(glOrthof(0, _outputScreenWidth, _outputScreenHeight, 0, -1, 1));
 #else
-	GLCALL(glOrtho(0, _outputScreenWidth, _outputScreenHeight, 0, -1, 1));
+	GL_CALL(glOrtho(0, _outputScreenWidth, _outputScreenHeight, 0, -1, 1));
 #endif
-	GLCALL(glMatrixMode(GL_MODELVIEW));
-	GLCALL(glLoadIdentity());
+	GL_CALL(glMatrixMode(GL_MODELVIEW));
+	GL_CALL(glLoadIdentity());
 
 	uint overlayWidth = width;
 	uint overlayHeight = height;
@@ -839,33 +839,33 @@ void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &def
 	initializeGLContext();
 
 	// Disable 3D properties.
-	GLCALL(glDisable(GL_CULL_FACE));
-	GLCALL(glDisable(GL_DEPTH_TEST));
-	GLCALL(glDisable(GL_LIGHTING));
-	GLCALL(glDisable(GL_FOG));
-	GLCALL(glDisable(GL_DITHER));
-	GLCALL(glShadeModel(GL_FLAT));
-	GLCALL(glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST));
+	GL_CALL(glDisable(GL_CULL_FACE));
+	GL_CALL(glDisable(GL_DEPTH_TEST));
+	GL_CALL(glDisable(GL_LIGHTING));
+	GL_CALL(glDisable(GL_FOG));
+	GL_CALL(glDisable(GL_DITHER));
+	GL_CALL(glShadeModel(GL_FLAT));
+	GL_CALL(glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST));
 
 	// Default to black as clear color.
-	GLCALL(glClearColor(0.0f, 0.0f, 0.0f, 0.0f));
-	GLCALL(glColor4f(1.0f, 1.0f, 1.0f, 1.0f));
+	GL_CALL(glClearColor(0.0f, 0.0f, 0.0f, 0.0f));
+	GL_CALL(glColor4f(1.0f, 1.0f, 1.0f, 1.0f));
 
 	// Setup alpha blend (for overlay and cursor).
-	GLCALL(glEnable(GL_BLEND));
-	GLCALL(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
+	GL_CALL(glEnable(GL_BLEND));
+	GL_CALL(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
 
 	// Enable rendering with vertex and coord arrays.
-	GLCALL(glEnableClientState(GL_VERTEX_ARRAY));
-	GLCALL(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
+	GL_CALL(glEnableClientState(GL_VERTEX_ARRAY));
+	GL_CALL(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
 
-	GLCALL(glEnable(GL_TEXTURE_2D));
+	GL_CALL(glEnable(GL_TEXTURE_2D));
 
 	// Setup scissor state accordingly.
 	if (_overlayVisible) {
-		GLCALL(glDisable(GL_SCISSOR_TEST));
+		GL_CALL(glDisable(GL_SCISSOR_TEST));
 	} else {
-		GLCALL(glEnable(GL_SCISSOR_TEST));
+		GL_CALL(glEnable(GL_SCISSOR_TEST));
 	}
 	// Clear the whole screen for the first three frames to assure any
 	// leftovers are cleared.
@@ -874,7 +874,7 @@ void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &def
 	// We use a "pack" alignment (when reading from textures) to 4 here,
 	// since the only place where we really use it is the BMP screenshot
 	// code and that requires the same alignment too.
-	GLCALL(glPixelStorei(GL_PACK_ALIGNMENT, 4));
+	GL_CALL(glPixelStorei(GL_PACK_ALIGNMENT, 4));
 
 	// Query information needed by textures.
 	Texture::queryTextureInformation();
@@ -1118,7 +1118,7 @@ void OpenGLGraphicsManager::recalculateDisplayArea() {
 	// Setup drawing limitation for game graphics.
 	// This invovles some trickery because OpenGL's viewport coordinate system
 	// is upside down compared to ours.
-	GLCALL(glScissor(_displayX,
+	GL_CALL(glScissor(_displayX,
 	                 _outputScreenHeight - _displayHeight - _displayY,
 	                 _displayWidth,
 	                 _displayHeight));
@@ -1206,7 +1206,7 @@ void OpenGLGraphicsManager::saveScreenshot(const Common::String &filename) const
 	uint8 *pixels = new uint8[lineSize * height];
 
 	// Get pixel data from OpenGL buffer
-	GLCALL(glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels));
+	GL_CALL(glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels));
 
 	// BMP stores as BGR. Since we can't assume that GL_BGR is supported we
 	// will swap the components from the RGB we read to BGR on our own.
diff --git a/backends/graphics/opengl/opengl-sys.h b/backends/graphics/opengl/opengl-sys.h
index 08b3b45..f78b337 100644
--- a/backends/graphics/opengl/opengl-sys.h
+++ b/backends/graphics/opengl/opengl-sys.h
@@ -87,6 +87,6 @@ extern Context g_context;
 
 } // End of namespace OpenGL
 
-#define GLCALL(x) GL_WRAP_DEBUG(g_context.x, x)
+#define GL_CALL(x) GL_WRAP_DEBUG(g_context.x, x)
 
 #endif
diff --git a/backends/graphics/opengl/texture.cpp b/backends/graphics/opengl/texture.cpp
index bc25500..b866b15 100644
--- a/backends/graphics/opengl/texture.cpp
+++ b/backends/graphics/opengl/texture.cpp
@@ -42,7 +42,7 @@ static GLuint nextHigher2(GLuint v) {
 GLint Texture::_maxTextureSize = 0;
 
 void Texture::queryTextureInformation() {
-	GLCALL(glGetIntegerv(GL_MAX_TEXTURE_SIZE, &_maxTextureSize));
+	GL_CALL(glGetIntegerv(GL_MAX_TEXTURE_SIZE, &_maxTextureSize));
 	debug(5, "OpenGL maximum texture size: %d", _maxTextureSize);
 }
 
@@ -58,7 +58,7 @@ Texture::~Texture() {
 }
 
 void Texture::releaseInternalTexture() {
-	GLCALL(glDeleteTextures(1, &_glTexture));
+	GL_CALL(glDeleteTextures(1, &_glTexture));
 	_glTexture = 0;
 }
 
@@ -67,20 +67,20 @@ void Texture::recreateInternalTexture() {
 	releaseInternalTexture();
 
 	// Get a new texture name.
-	GLCALL(glGenTextures(1, &_glTexture));
+	GL_CALL(glGenTextures(1, &_glTexture));
 
 	// Set up all texture parameters.
-	GLCALL(glBindTexture(GL_TEXTURE_2D, _glTexture));
-	GLCALL(glPixelStorei(GL_UNPACK_ALIGNMENT, 1));
-	GLCALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, _glFilter));
-	GLCALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, _glFilter));
-	GLCALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
-	GLCALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
+	GL_CALL(glBindTexture(GL_TEXTURE_2D, _glTexture));
+	GL_CALL(glPixelStorei(GL_UNPACK_ALIGNMENT, 1));
+	GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, _glFilter));
+	GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, _glFilter));
+	GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
+	GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
 
 	// In case there is an actual texture setup we reinitialize it.
 	if (_textureData.getPixels()) {
 		// Allocate storage for OpenGL texture.
-		GLCALL(glTexImage2D(GL_TEXTURE_2D, 0, _glIntFormat, _textureData.w,
+		GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, _glIntFormat, _textureData.w,
 		       _textureData.h, 0, _glFormat, _glType, NULL));
 
 		// Mark dirts such that it will be completely refreshed the next time.
@@ -95,10 +95,10 @@ void Texture::enableLinearFiltering(bool enable) {
 		_glFilter = GL_NEAREST;
 	}
 
-	GLCALL(glBindTexture(GL_TEXTURE_2D, _glTexture));
+	GL_CALL(glBindTexture(GL_TEXTURE_2D, _glTexture));
 
-	GLCALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, _glFilter));
-	GLCALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, _glFilter));
+	GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, _glFilter));
+	GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, _glFilter));
 }
 
 void Texture::allocate(uint width, uint height) {
@@ -115,10 +115,10 @@ void Texture::allocate(uint width, uint height) {
 		_textureData.create(texWidth, texHeight, _format);
 
 		// Set the texture.
-		GLCALL(glBindTexture(GL_TEXTURE_2D, _glTexture));
+		GL_CALL(glBindTexture(GL_TEXTURE_2D, _glTexture));
 
 		// Allocate storage for OpenGL texture.
-		GLCALL(glTexImage2D(GL_TEXTURE_2D, 0, _glIntFormat, _textureData.w,
+		GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, _glIntFormat, _textureData.w,
 		       _textureData.h, 0, _glFormat, _glType, NULL));
 	}
 
@@ -174,7 +174,7 @@ void Texture::draw(GLfloat x, GLfloat y, GLfloat w, GLfloat h) {
 	updateTexture();
 
 	// Set the texture.
-	GLCALL(glBindTexture(GL_TEXTURE_2D, _glTexture));
+	GL_CALL(glBindTexture(GL_TEXTURE_2D, _glTexture));
 
 	// Calculate the texture rect that will be drawn.
 	const GLfloat texWidth = (GLfloat)_userPixelData.w / _textureData.w;
@@ -185,7 +185,7 @@ void Texture::draw(GLfloat x, GLfloat y, GLfloat w, GLfloat h) {
 		0,        texHeight,
 		texWidth, texHeight
 	};
-	GLCALL(glTexCoordPointer(2, GL_FLOAT, 0, texcoords));
+	GL_CALL(glTexCoordPointer(2, GL_FLOAT, 0, texcoords));
 
 	// Calculate the screen rect where the texture will be drawn.
 	const GLfloat vertices[4*2] = {
@@ -194,10 +194,10 @@ void Texture::draw(GLfloat x, GLfloat y, GLfloat w, GLfloat h) {
 		x,     y + h,
 		x + w, y + h
 	};
-	GLCALL(glVertexPointer(2, GL_FLOAT, 0, vertices));
+	GL_CALL(glVertexPointer(2, GL_FLOAT, 0, vertices));
 
 	// Draw the texture to the screen buffer.
-	GLCALL(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
+	GL_CALL(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
 }
 
 void Texture::updateTexture() {
@@ -237,7 +237,7 @@ void Texture::updateTexture() {
 	}
 
 	// Set the texture.
-	GLCALL(glBindTexture(GL_TEXTURE_2D, _glTexture));
+	GL_CALL(glBindTexture(GL_TEXTURE_2D, _glTexture));
 
 	// Update the actual texture.
 	// Although we keep track of the dirty part of the texture buffer we
@@ -257,7 +257,7 @@ void Texture::updateTexture() {
 	//
 	// 3) Use glTexSubImage2D per line changed. This is what the old OpenGL
 	//    graphics manager did but it is much slower! Thus, we do not use it.
-	GLCALL(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, dirtyArea.top, _textureData.w, dirtyArea.height(),
+	GL_CALL(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, dirtyArea.top, _textureData.w, dirtyArea.height(),
 	                       _glFormat, _glType, _textureData.getBasePtr(0, dirtyArea.top)));
 
 	// We should have handled everything, thus not dirty anymore.


Commit: 9816e4f35035b6fa461dc1bc255ced533f5feaf9
    https://github.com/scummvm/scummvm/commit/9816e4f35035b6fa461dc1bc255ced533f5feaf9
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:24+01:00

Commit Message:
OPENGL: Remove support for ARGB8888.

This used to be used by Sword25. Since it is not supported by GLES and no
engine code uses it we drop support. Hopefully, this helps people to realize
they should not use that format in their engine.

Changed paths:
    backends/graphics/opengl/opengl-graphics.cpp
    backends/graphics/openglsdl/openglsdl-graphics.cpp



diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index 34d4ca8..1024ee5 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -1029,11 +1029,6 @@ bool OpenGLGraphicsManager::getGLPixelFormat(const Graphics::PixelFormat &pixelF
 		glFormat = GL_BGRA;
 		glType = GL_UNSIGNED_SHORT_1_5_5_5_REV;
 		return true;
-	} else if (pixelFormat == Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24)) { // ARGB8888
-		glIntFormat = GL_RGBA;
-		glFormat = GL_BGRA;
-		glType = GL_UNSIGNED_INT_8_8_8_8_REV;
-		return true;
 	} else if (pixelFormat == Graphics::PixelFormat(2, 4, 4, 4, 4, 8, 4, 0, 12)) { // ARGB4444
 		glIntFormat = GL_RGBA;
 		glFormat = GL_BGRA;
diff --git a/backends/graphics/openglsdl/openglsdl-graphics.cpp b/backends/graphics/openglsdl/openglsdl-graphics.cpp
index d1e798e..1992925 100644
--- a/backends/graphics/openglsdl/openglsdl-graphics.cpp
+++ b/backends/graphics/openglsdl/openglsdl-graphics.cpp
@@ -218,9 +218,6 @@ Common::List<Graphics::PixelFormat> OpenGLSdlGraphicsManager::getSupportedFormat
 	// ABGR8888
 	formats.push_back(Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
 #endif
-	// ARGB8888, this should not be here, but Sword25 requires it. :-/
-	formats.push_back(Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24));
-
 	// RGB555, this is used by SCUMM HE 16 bit games.
 	formats.push_back(Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0));
 #endif


Commit: d6d3e17d53754acedce0b1706e73f929d29b5eb8
    https://github.com/scummvm/scummvm/commit/d6d3e17d53754acedce0b1706e73f929d29b5eb8
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:25+01:00

Commit Message:
OPENGL: Allow runtime specification of OpenGL mode.

Formerly, we required that the OpenGL mode was fixed at compile time. Now we
allow the code to work with whatever it is given at runtime.

It is still possible to force a context type on compile time.

Changed paths:
    backends/graphics/opengl/context.cpp
    backends/graphics/opengl/opengl-func.h
    backends/graphics/opengl/opengl-graphics.cpp
    backends/graphics/opengl/opengl-graphics.h
    backends/graphics/opengl/opengl-sys.h
    backends/graphics/openglsdl/openglsdl-graphics.cpp
    backends/platform/tizen/graphics.cpp
    configure



diff --git a/backends/graphics/opengl/context.cpp b/backends/graphics/opengl/context.cpp
index c4869c2..d1776f8 100644
--- a/backends/graphics/opengl/context.cpp
+++ b/backends/graphics/opengl/context.cpp
@@ -28,15 +28,23 @@
 namespace OpenGL {
 
 void Context::reset() {
+	ready = false;
+	type = kContextGL;
 	NPOTSupported = false;
 }
 
 Context g_context;
 
-void OpenGLGraphicsManager::initializeGLContext() {
+void OpenGLGraphicsManager::initializeGLContext(ContextType type) {
 	// Initialize default state.
 	g_context.reset();
 
+#if USE_FORCED_GL
+	type = kContextGL;
+#elif USE_FORCED_GLES
+	type = kContextGLES;
+#endif
+
 	// Load all functions.
 	// We use horrible trickery to silence C++ compilers.
 	// See backends/plugins/sdl/sdl-provider.cpp for more information.
@@ -64,6 +72,9 @@ void OpenGLGraphicsManager::initializeGLContext() {
 			g_context.NPOTSupported = true;
 		}
 	}
+
+	g_context.ready = true;
+	g_context.type = type;
 }
 
 } // End of namespace OpenGL
diff --git a/backends/graphics/opengl/opengl-func.h b/backends/graphics/opengl/opengl-func.h
index 75bc0b4..0ff39c8 100644
--- a/backends/graphics/opengl/opengl-func.h
+++ b/backends/graphics/opengl/opengl-func.h
@@ -70,9 +70,10 @@ GL_FUNC_DEF(void, glColor4f, (GLfloat red, GLfloat green, GLfloat blue, GLfloat
 GL_FUNC_DEF(void, glViewport, (GLint x, GLint y, GLsizei width, GLsizei height));
 GL_FUNC_DEF(void, glMatrixMode, (GLenum mode));
 GL_FUNC_DEF(void, glLoadIdentity, ());
-#ifdef USE_GLES
+#if !USE_FORCED_GL
 GL_FUNC_DEF(void, glOrthof, (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar));
-#else
+#endif
+#if !USE_FORCED_GLES
 GL_FUNC_DEF(void, glOrtho, (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val));
 #endif
 GL_FUNC_DEF(void, glShadeModel, (GLenum mode));
diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index 1024ee5..78ae27d 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -759,10 +759,16 @@ void OpenGLGraphicsManager::setActualScreenSize(uint width, uint height) {
 
 	GL_CALL(glMatrixMode(GL_PROJECTION));
 	GL_CALL(glLoadIdentity());
-#ifdef USE_GLES
+#if   USE_FORCED_GLES
 	GL_CALL(glOrthof(0, _outputScreenWidth, _outputScreenHeight, 0, -1, 1));
-#else
+#elif USE_FORCED_GL
 	GL_CALL(glOrtho(0, _outputScreenWidth, _outputScreenHeight, 0, -1, 1));
+#else
+	if (isGLESContext()) {
+		GL_CALL(glOrthof(0, _outputScreenWidth, _outputScreenHeight, 0, -1, 1));
+	} else {
+		GL_CALL(glOrtho(0, _outputScreenWidth, _outputScreenHeight, 0, -1, 1));
+	}
 #endif
 	GL_CALL(glMatrixMode(GL_MODELVIEW));
 	GL_CALL(glLoadIdentity());
@@ -834,9 +840,9 @@ void OpenGLGraphicsManager::setActualScreenSize(uint width, uint height) {
 	++_screenChangeID;
 }
 
-void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &defaultFormat, const Graphics::PixelFormat &defaultFormatAlpha) {
+void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &defaultFormat, const Graphics::PixelFormat &defaultFormatAlpha, ContextType type) {
 	// Initialize context for use.
-	initializeGLContext();
+	initializeGLContext(type);
 
 	// Disable 3D properties.
 	GL_CALL(glDisable(GL_CULL_FACE));
@@ -1014,7 +1020,11 @@ bool OpenGLGraphicsManager::getGLPixelFormat(const Graphics::PixelFormat &pixelF
 		glFormat = GL_RGBA;
 		glType = GL_UNSIGNED_SHORT_4_4_4_4;
 		return true;
-#ifndef USE_GLES
+#if !USE_FORCED_GLES
+	// The formats below are not supported by every GLES implementation.
+	// Thus, we do not mark them as supported when a GLES context is setup.
+	} else if (isGLESContext()) {
+		return false;
 #ifdef SCUMM_LITTLE_ENDIAN
 	} else if (pixelFormat == Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0)) { // RGBA8888
 		glIntFormat = GL_RGBA;
@@ -1023,8 +1033,6 @@ bool OpenGLGraphicsManager::getGLPixelFormat(const Graphics::PixelFormat &pixelF
 		return true;
 #endif
 	} else if (pixelFormat == Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0)) { // RGB555
-		// GL_BGRA does not exist in every GLES implementation so should not be configured if
-		// USE_GLES is set.
 		glIntFormat = GL_RGB;
 		glFormat = GL_BGRA;
 		glType = GL_UNSIGNED_SHORT_1_5_5_5_REV;
@@ -1066,7 +1074,7 @@ bool OpenGLGraphicsManager::getGLPixelFormat(const Graphics::PixelFormat &pixelF
 		glFormat = GL_BGRA;
 		glType = GL_UNSIGNED_SHORT_4_4_4_4;
 		return true;
-#endif
+#endif // !USE_FORCED_GLES
 	} else {
 		return false;
 	}
diff --git a/backends/graphics/opengl/opengl-graphics.h b/backends/graphics/opengl/opengl-graphics.h
index 3d5f74b..5f0436c 100644
--- a/backends/graphics/opengl/opengl-graphics.h
+++ b/backends/graphics/opengl/opengl-graphics.h
@@ -117,6 +117,16 @@ public:
 
 protected:
 	/**
+	 * Whether an OpenGL (context) is active.
+	 */
+	bool isInitialized() const { return g_context.ready; }
+
+	/**
+	 * Whether an GLES context is active.
+	 */
+	bool isGLESContext() const { return g_context.type == kContextGLES; }
+
+	/**
 	 * Set up the actual screen size available for the OpenGL code to do any
 	 * drawing.
 	 *
@@ -133,8 +143,9 @@ protected:
 	 *                           (this is used for the CLUT8 game screens).
 	 * @param defaultFormatAlpha The new default format with an alpha channel
 	 *                           (this is used for the overlay and cursor).
+	 * @param type               Type of the created context.
 	 */
-	void notifyContextCreate(const Graphics::PixelFormat &defaultFormat, const Graphics::PixelFormat &defaultFormatAlpha);
+	void notifyContextCreate(const Graphics::PixelFormat &defaultFormat, const Graphics::PixelFormat &defaultFormatAlpha, ContextType type);
 
 	/**
 	 * Notify the manager that the OpenGL context is about to be destroyed.
@@ -282,8 +293,10 @@ private:
 
 	/**
 	 * Initialize the active context for use.
+	 *
+	 * @param type Type of the context to initialize.
 	 */
-	void initializeGLContext();
+	void initializeGLContext(ContextType type);
 
 protected:
 	/**
diff --git a/backends/graphics/opengl/opengl-sys.h b/backends/graphics/opengl/opengl-sys.h
index f78b337..550dbb4 100644
--- a/backends/graphics/opengl/opengl-sys.h
+++ b/backends/graphics/opengl/opengl-sys.h
@@ -30,6 +30,14 @@
 #include "backends/platform/sdl/sdl-sys.h"
 #endif
 
+// We allow to force GL or GLES modes on compile time.
+// For this the USE_GLES_MODE define is used. The following values represent
+// the given selection choices:
+//  0 - Force OpenGL context
+//  1 - Force OpenGL ES context
+#define USE_FORCED_GL   (defined(USE_GLES_MODE) && USE_GLES_MODE == 0)
+#define USE_FORCED_GLES (defined(USE_GLES_MODE) && USE_GLES_MODE == 1)
+
 // On Tizen we include the toolchain's OpenGL file. This is something we
 // actually want to avoid. However, since Tizen uses eglGetProcAddress which
 // is not required to return valid function pointers to non OpenGL extension
@@ -59,10 +67,21 @@
 
 namespace OpenGL {
 
+enum ContextType {
+	kContextGL,
+	kContextGLES
+};
+
 /**
  * Description structure of the OpenGL (ES) context.
  */
 struct Context {
+	/** Whether the context is properly initalized or not. */
+	bool ready;
+
+	/** The type of the active context. */
+	ContextType type;
+
 	/**
 	 * Reset context.
 	 *
diff --git a/backends/graphics/openglsdl/openglsdl-graphics.cpp b/backends/graphics/openglsdl/openglsdl-graphics.cpp
index 1992925..a945138 100644
--- a/backends/graphics/openglsdl/openglsdl-graphics.cpp
+++ b/backends/graphics/openglsdl/openglsdl-graphics.cpp
@@ -210,16 +210,22 @@ Common::List<Graphics::PixelFormat> OpenGLSdlGraphicsManager::getSupportedFormat
 	// RGBA4444
 	formats.push_back(Graphics::PixelFormat(2, 4, 4, 4, 4, 12, 8, 4, 0));
 
-#ifndef USE_GLES
+#if !USE_FORCED_GLES
+#if !USE_FORCED_GL
+	if (isInitialized() && !isGLESContext()) {
+#endif
 #ifdef SCUMM_LITTLE_ENDIAN
-	// RGBA8888
-	formats.push_back(Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0));
+		// RGBA8888
+		formats.push_back(Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0));
 #else
-	// ABGR8888
-	formats.push_back(Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
+		// ABGR8888
+		formats.push_back(Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
+#endif
+		// RGB555, this is used by SCUMM HE 16 bit games.
+		formats.push_back(Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0));
+#if !USE_FORCED_GL
+	}
 #endif
-	// RGB555, this is used by SCUMM HE 16 bit games.
-	formats.push_back(Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0));
 #endif
 
 	formats.push_back(Graphics::PixelFormat::createFormatCLUT8());
@@ -391,7 +397,7 @@ bool OpenGLSdlGraphicsManager::setupMode(uint width, uint height) {
 		}
 	}
 
-#ifdef USE_GLES
+#if USE_FORCED_GLES
 	// SDL2 will create a GLES2 context by default, so this is needed for GLES1-profile
 	// functions to work.
 	SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
@@ -403,7 +409,13 @@ bool OpenGLSdlGraphicsManager::setupMode(uint width, uint height) {
 		return false;
 	}
 
-	notifyContextCreate(rgba8888, rgba8888);
+	notifyContextCreate(rgba8888, rgba8888,
+#if USE_FORCED_GLES
+	                    OpenGL::kContextGLES
+#else
+	                    OpenGL::kContextGL
+#endif
+	                   );
 	int actualWidth, actualHeight;
 	getWindowDimensions(&actualWidth, &actualHeight);
 	setActualScreenSize(actualWidth, actualHeight);
@@ -451,7 +463,7 @@ bool OpenGLSdlGraphicsManager::setupMode(uint width, uint height) {
 	_lastVideoModeLoad = SDL_GetTicks();
 
 	if (_hwScreen) {
-		notifyContextCreate(rgba8888, rgba8888);
+		notifyContextCreate(rgba8888, rgba8888, OpenGL::kContextGL);
 		setActualScreenSize(_hwScreen->w, _hwScreen->h);
 		_eventSource->resetKeyboadEmulation(_hwScreen->w - 1, _hwScreen->h - 1);
 	}
diff --git a/backends/platform/tizen/graphics.cpp b/backends/platform/tizen/graphics.cpp
index 971be46..caa18c5 100644
--- a/backends/platform/tizen/graphics.cpp
+++ b/backends/platform/tizen/graphics.cpp
@@ -59,7 +59,7 @@ result TizenGraphicsManager::Construct() {
 
 	// We default to RGB565 and RGBA5551 which is closest to the actual output
 	// mode we setup.
-	notifyContextCreate(Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0), Graphics::PixelFormat(2, 5, 5, 5, 1, 11, 6, 1, 0));
+	notifyContextCreate(Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0), Graphics::PixelFormat(2, 5, 5, 5, 1, 11, 6, 1, 0), OpenGL::kContextGLES);
 
 	// Tell our size.
 	int x, y, width, height;
diff --git a/configure b/configure
index 8d465bc..2367466 100755
--- a/configure
+++ b/configure
@@ -133,8 +133,7 @@ _png=auto
 _theoradec=auto
 _faad=auto
 _fluidsynth=auto
-_opengl=auto
-_opengles=no
+_opengl_mode=auto
 _readline=auto
 _freetype2=auto
 _taskbar=auto
@@ -940,6 +939,14 @@ Optional Features:
   --enable-verbose-build   enable regular echoing of commands during build
                            process
   --disable-bink           don't build with Bink video support
+  --opengl-mode=MODE       OpenGL (ES) mode to use for OpenGL output [auto]
+                           available modes: auto for autodetection
+                                            none for disabling any OpenGL usage
+                                            any for runtime detection
+                                            gl for forcing OpenGL
+                                            gles for forcing OpenGL ES
+                           WARNING: only specify this manually if you know what
+                           you are doing!
 
 Optional Libraries:
   --with-alsa-prefix=DIR   Prefix where alsa is installed (optional)
@@ -964,9 +971,6 @@ Optional Libraries:
   --with-mpeg2-prefix=DIR  Prefix where libmpeg2 is installed (optional)
   --enable-mpeg2           enable mpeg2 codec for cutscenes [autodetect]
 
-  --disable-opengl         disable OpenGL (ES) support [autodetect]
-  --enable-opengles        enable forced OpenGL ES mode [disabled]
-
   --with-jpeg-prefix=DIR   Prefix where libjpeg is installed (optional)
   --disable-jpeg           disable JPEG decoder [autodetect]
 
@@ -1071,12 +1075,11 @@ for ac_option in $@; do
 	--disable-updates)        _updates=no     ;;
 	--enable-libunity)        _libunity=yes   ;;
 	--disable-libunity)       _libunity=no    ;;
-	--enable-opengl)          _opengl=yes     ;;
-	--disable-opengl)         _opengl=no      ;;
-	--enable-opengles)        _opengles=yes   ;;
-	--disable-opengles)       _opengles=no    ;;
 	--enable-bink)            _bink=yes       ;;
 	--disable-bink)           _bink=no        ;;
+	--opengl-mode=*)
+		_opengl_mode=`echo $ac_option | cut -d '=' -f 2`
+		;;
 	--enable-verbose-build)   _verbose_build=yes ;;
 	--enable-plugins)         _dynamic_modules=yes ;;
 	--default-dynamic)        _plugins_default=dynamic ;;
@@ -2658,8 +2661,7 @@ if test -n "$_host"; then
 			_sdlconfig=sdl2-config
 			# OpenGL(ES) support is mature enough as to be the best option on
 			# the Raspberry Pi, so it's enabled by default.
-			_opengl=yes
-			_opengles=yes
+			_opengl_mode=gles
 			;;
 		dreamcast)
 			append_var DEFINES "-DDISABLE_DEFAULT_SAVEFILEMANAGER"
@@ -2988,8 +2990,7 @@ if test -n "$_host"; then
 			_timidity=no
 			_vkeybd=yes
 			# Tizen relies on the OpenGL ES output thus we always enable it.
-			_opengl=yes
-			_opengles=yes
+			_opengl_mode=gles
 			;;
 		webos)
 			_backend="webos"
@@ -4150,35 +4151,82 @@ echocheck "OpenGL"
 
 case $_backend in
 	openpandora)
-		# Only enable OpenGL ES on the OpanPandora if --enable-opengl is passed in explicitly.
-		if test "$_opengl" = yes ; then
-			_opengl=yes
-			_opengles=yes
+		# Only enable OpenGL ES on the OpanPandora if --opengl-mode=gles is passed in explicitly.
+		if test "$_opengl_mode" = "gles" ; then
 			append_var LIBS "-lGLES_CM -lEGL -lX11"
+		else
+			_opengl_mode=none
 		fi
 		;;
 esac
 
-if test "$_opengl" = auto ; then
+if test "$_opengl_mode" = auto ; then
 	case $_backend in
 		sdl)
-			_opengl=yes
+			case $_sdlversion in
+				1.2.*)
+					# Stock SDL 1.2 only supports OpenGL contexts.
+					_opengl_mode=gl
+					;;
+
+				2.0.*)
+					# SDL2 supports both OpenGL + OpenGL ES contexts.
+					# However, Mac OS X only allows OpenGL context creation at
+					# this time, thus we limit us to OpenGL on that platform.
+					case $_host_os in
+						darwin*)
+							_opengl_mode=gl
+							;;
+
+						*)
+							_opengl_mode=any
+							;;
+					esac
+					;;
+			esac
+			;;
+
+		tizen)
+			# Tizen always runs in GLES mode
+			_opengl_mode=gles
 			;;
 
 		*)
-			_opengl=no
+			_opengl_mode=none
 			;;
 	esac
 fi
 
-if test "$_opengles" = "yes" ; then
-	echo "yes (OpenGL ES)"
-else
-	echo "$_opengl"
-fi
+_opengl=yes
+case $_opengl_mode in
+	auto)
+		# This case should never occur but better safe than sorry.
+		echo "no"
+		_opengl=no
+		;;
+
+	none)
+		echo "no"
+		_opengl=no
+		;;
+
+	any)
+		echo "yes (runtime detection)"
+		add_line_to_config_h "#undef USE_GLES_MODE"
+		;;
+
+	gl)
+		echo "yes (OpenGL)"
+		add_line_to_config_h "#define USE_GLES_MODE 0"
+		;;
+
+	gles)
+		echo "yes (OpenGL ES)"
+		add_line_to_config_h "#define USE_GLES_MODE 1"
+		;;
+esac
 
 define_in_config_if_yes "$_opengl" "USE_OPENGL"
-define_in_config_if_yes "$_opengles" "USE_GLES"
 
 #
 # Check for nasm


Commit: 22771446238784eede905b5471c3ae8784523641
    https://github.com/scummvm/scummvm/commit/22771446238784eede905b5471c3ae8784523641
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:25+01:00

Commit Message:
OPENGL: Support RGB555 for OpenGL ES output.

This mode should *not* be used by any new engines/code. If someone is going
to use it and says it works with the OpenGL output, please make them wear a
red uniform and beam them onto a remote planet.

Changed paths:
    backends/graphics/opengl/opengl-graphics.cpp
    backends/graphics/opengl/texture.cpp
    backends/graphics/opengl/texture.h
    backends/graphics/openglsdl/openglsdl-graphics.cpp



diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index 78ae27d..8db5f6a 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -985,6 +985,15 @@ Texture *OpenGLGraphicsManager::createTexture(const Graphics::PixelFormat &forma
 		} else {
 			return new TextureCLUT8(glIntFormat, glFormat, glType, virtFormat);
 		}
+#if !USE_FORCED_GL
+	} else if (isGLESContext() && format == Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0)) {
+		// OpenGL ES does not support a texture format usable for RGB555.
+		// Since SCUMM uses this pixel format for some games (and there is no
+		// hope for this to change anytime soon) we use pixel format
+		// conversion to a supported texture format. However, this is a one
+		// time exception.
+		return new TextureRGB555();
+#endif // !USE_FORCED_GL
 	} else {
 		const bool supported = getGLPixelFormat(format, glIntFormat, glFormat, glType);
 		if (!supported) {
diff --git a/backends/graphics/opengl/texture.cpp b/backends/graphics/opengl/texture.cpp
index b866b15..fadfd99 100644
--- a/backends/graphics/opengl/texture.cpp
+++ b/backends/graphics/opengl/texture.cpp
@@ -369,4 +369,64 @@ void TextureCLUT8::updateTexture() {
 	Texture::updateTexture();
 }
 
+#if !USE_FORCED_GL
+TextureRGB555::TextureRGB555()
+    : Texture(GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0)),
+      _rgb555Data() {
+}
+
+TextureRGB555::~TextureRGB555() {
+	_rgb555Data.free();
+}
+
+void TextureRGB555::allocate(uint width, uint height) {
+	Texture::allocate(width, height);
+
+	// We only need to reinitialize our RGB555 surface when the output size
+	// changed.
+	if (width == _rgb555Data.w && height == _rgb555Data.h) {
+		return;
+	}
+
+	_rgb555Data.create(width, height, Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0));
+}
+
+Graphics::PixelFormat TextureRGB555::getFormat() const {
+	return Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0);
+}
+
+void TextureRGB555::updateTexture() {
+	if (!isDirty()) {
+		return;
+	}
+
+	// Convert color space.
+	Graphics::Surface *outSurf = Texture::getSurface();
+
+	const Common::Rect dirtyArea = getDirtyArea();
+
+	uint16 *dst = (uint16 *)outSurf->getBasePtr(dirtyArea.left, dirtyArea.top);
+	const uint dstAdd = outSurf->pitch - 2 * dirtyArea.width();
+
+	const uint16 *src = (const uint16 *)_rgb555Data.getBasePtr(dirtyArea.left, dirtyArea.top);
+	const uint srcAdd = _rgb555Data.pitch - 2 * dirtyArea.width();
+
+	for (int height = dirtyArea.height(); height > 0; --height) {
+		for (int width = dirtyArea.width(); width > 0; --width) {
+			const uint16 color = *src++;
+
+			*dst++ =   ((color & 0x7C00) << 1)                             // R
+			         | (((color & 0x03E0) << 1) | ((color & 0x0200) >> 4)) // G
+			         | (color & 0x001F);                                   // B
+		}
+
+		src = (const uint16 *)((const byte *)src + srcAdd);
+		dst = (uint16 *)((byte *)dst + dstAdd);
+	}
+
+	// Do generic handling of updating the texture.
+	Texture::updateTexture();
+}
+#endif // !USE_FORCED_GL
+
 } // End of namespace OpenGL
diff --git a/backends/graphics/opengl/texture.h b/backends/graphics/opengl/texture.h
index ad70833..4c21267 100644
--- a/backends/graphics/opengl/texture.h
+++ b/backends/graphics/opengl/texture.h
@@ -170,6 +170,27 @@ private:
 	byte *_palette;
 };
 
+#if !USE_FORCED_GL
+class TextureRGB555 : public Texture {
+public:
+	TextureRGB555();
+	virtual ~TextureRGB555();
+
+	virtual void allocate(uint width, uint height);
+
+	virtual Graphics::PixelFormat getFormat() const;
+
+	virtual Graphics::Surface *getSurface() { return &_rgb555Data; }
+	virtual const Graphics::Surface *getSurface() const { return &_rgb555Data; }
+
+protected:
+	virtual void updateTexture();
+
+private:
+	Graphics::Surface _rgb555Data;
+};
+#endif // !USE_FORCED_GL
+
 } // End of namespace OpenGL
 
 #endif
diff --git a/backends/graphics/openglsdl/openglsdl-graphics.cpp b/backends/graphics/openglsdl/openglsdl-graphics.cpp
index a945138..583d54b 100644
--- a/backends/graphics/openglsdl/openglsdl-graphics.cpp
+++ b/backends/graphics/openglsdl/openglsdl-graphics.cpp
@@ -221,13 +221,16 @@ Common::List<Graphics::PixelFormat> OpenGLSdlGraphicsManager::getSupportedFormat
 		// ABGR8888
 		formats.push_back(Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
 #endif
-		// RGB555, this is used by SCUMM HE 16 bit games.
-		formats.push_back(Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0));
 #if !USE_FORCED_GL
 	}
 #endif
 #endif
 
+	// RGB555, this is used by SCUMM HE 16 bit games.
+	// This is not natively supported by OpenGL ES implementations, we convert
+	// the pixel format internally.
+	formats.push_back(Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0));
+
 	formats.push_back(Graphics::PixelFormat::createFormatCLUT8());
 
 	return formats;


Commit: da062ad1ea2d933ae7c4b56f84f34c5fb2186196
    https://github.com/scummvm/scummvm/commit/da062ad1ea2d933ae7c4b56f84f34c5fb2186196
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:25+01:00

Commit Message:
OPENGLSDL: Try to use GL(ES) context SDL2 defaults to.

Changed paths:
    backends/graphics/openglsdl/openglsdl-graphics.cpp
    backends/graphics/openglsdl/openglsdl-graphics.h



diff --git a/backends/graphics/openglsdl/openglsdl-graphics.cpp b/backends/graphics/openglsdl/openglsdl-graphics.cpp
index 583d54b..e7b6da2 100644
--- a/backends/graphics/openglsdl/openglsdl-graphics.cpp
+++ b/backends/graphics/openglsdl/openglsdl-graphics.cpp
@@ -45,6 +45,87 @@ OpenGLSdlGraphicsManager::OpenGLSdlGraphicsManager(uint desktopWidth, uint deskt
 	SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
 	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
 
+	// Setup proper SDL OpenGL context creation.
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+#if USE_FORCED_GL
+	_glContextType = OpenGL::kContextGL;
+	_glContextProfileMask = SDL_GL_CONTEXT_PROFILE_COMPATIBILITY;
+	// Context version 1.4 is choosen arbitrarily based on what most shader
+	// extensions were written against.
+	_glContextMajor = 1;
+	_glContextMinor = 4;
+#elif USE_FORCED_GLES
+	_glContextType = OpenGL::kContextGLES;
+	_glContextProfileMask = SDL_GL_CONTEXT_PROFILE_ES;
+	_glContextMajor = 1;
+	_glContextMinor = 1;
+#else
+	int forceMode = -1;
+
+	// Obtain the default GL(ES) context SDL2 tries to setup.
+	//
+	// Please note this might not actually be SDL2's defaults when multiple
+	// instances of this object have been created. But that is no issue
+	// because then we already set up what we want to use.
+	//
+	// In case no defaults are given we prefer OpenGL over OpenGL ES.
+	if (SDL_GL_GetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, &_glContextProfileMask) != 0) {
+		_glContextProfileMask = SDL_GL_CONTEXT_PROFILE_COMPATIBILITY;
+		forceMode = 0;
+	}
+
+	if (SDL_GL_GetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, &_glContextMajor) != 0) {
+		if (_glContextProfileMask == SDL_GL_CONTEXT_PROFILE_ES) {
+			forceMode = 1;
+		} else {
+			forceMode = 0;
+		}
+	}
+
+	if (SDL_GL_GetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, &_glContextMinor) != 0) {
+		if (_glContextProfileMask == SDL_GL_CONTEXT_PROFILE_ES) {
+			forceMode = 1;
+		} else {
+			forceMode = 0;
+		}
+	}
+
+	if (forceMode == 1) {
+		_glContextProfileMask = SDL_GL_CONTEXT_PROFILE_ES;
+		_glContextMajor = 1;
+		_glContextMinor = 1;
+	} else if (forceMode == 0) {
+		_glContextProfileMask = SDL_GL_CONTEXT_PROFILE_COMPATIBILITY;
+		// Context version 1.4 is choosen arbitrarily based on what most shader
+		// extensions were written against.
+		_glContextMajor = 1;
+		_glContextMinor = 4;
+	}
+
+	if (_glContextProfileMask == SDL_GL_CONTEXT_PROFILE_ES) {
+		_glContextType = OpenGL::kContextGLES;
+
+		// We do not support GLES2 contexts right now. Force a GLES1 context.
+		if (_glContextMajor >= 2) {
+			_glContextMajor = 1;
+			_glContextMinor = 1;
+		}
+	} else if (_glContextProfileMask == SDL_GL_CONTEXT_PROFILE_CORE) {
+		_glContextType = OpenGL::kContextGL;
+
+		// Core profile does not allow legacy functionality, which we use.
+		// Thus we always request a compatibility profile.
+		_glContextProfileMask = SDL_GL_CONTEXT_PROFILE_COMPATIBILITY;
+		// Context version 1.4 is choosen arbitrarily based on what most shader
+		// extensions were written against.
+		_glContextMajor = 1;
+		_glContextMinor = 4;
+	} else {
+		_glContextType = OpenGL::kContextGL;
+	}
+#endif
+#endif
+
 	// Retrieve a list of working fullscreen modes
 #if SDL_VERSION_ATLEAST(2, 0, 0)
 	const int numModes = SDL_GetNumDisplayModes(0);
@@ -388,6 +469,11 @@ bool OpenGLSdlGraphicsManager::setupMode(uint width, uint height) {
 		flags |= SDL_WINDOW_RESIZABLE;
 	}
 
+	// Request a OpenGL (ES) context we can use.
+	SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, _glContextProfileMask);
+	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, _glContextMajor);
+	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, _glContextMinor);
+
 	if (!_window->createWindow(width, height, flags)) {
 		// We treat fullscreen requests as a "hint" for now. This means in
 		// case it is not available we simply ignore it.
@@ -400,25 +486,12 @@ bool OpenGLSdlGraphicsManager::setupMode(uint width, uint height) {
 		}
 	}
 
-#if USE_FORCED_GLES
-	// SDL2 will create a GLES2 context by default, so this is needed for GLES1-profile
-	// functions to work.
-	SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
-	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1);
-	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
-#endif
 	_glContext = SDL_GL_CreateContext(_window->getSDLWindow());
 	if (!_glContext) {
 		return false;
 	}
 
-	notifyContextCreate(rgba8888, rgba8888,
-#if USE_FORCED_GLES
-	                    OpenGL::kContextGLES
-#else
-	                    OpenGL::kContextGL
-#endif
-	                   );
+	notifyContextCreate(rgba8888, rgba8888, _glContextType);
 	int actualWidth, actualHeight;
 	getWindowDimensions(&actualWidth, &actualHeight);
 	setActualScreenSize(actualWidth, actualHeight);
diff --git a/backends/graphics/openglsdl/openglsdl-graphics.h b/backends/graphics/openglsdl/openglsdl-graphics.h
index fe289d6..7921163 100644
--- a/backends/graphics/openglsdl/openglsdl-graphics.h
+++ b/backends/graphics/openglsdl/openglsdl-graphics.h
@@ -73,6 +73,8 @@ private:
 	bool setupMode(uint width, uint height);
 
 #if SDL_VERSION_ATLEAST(2, 0, 0)
+	int _glContextProfileMask, _glContextMajor, _glContextMinor;
+	OpenGL::ContextType _glContextType;
 	SDL_GLContext _glContext;
 #else
 	uint32 _lastVideoModeLoad;


Commit: af727afe0ceb66eaf51985ceceb2ac842b3358ee
    https://github.com/scummvm/scummvm/commit/af727afe0ceb66eaf51985ceceb2ac842b3358ee
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:25+01:00

Commit Message:
OPENGL: Simplify context type setting.

Changed paths:
    backends/graphics/opengl/context.cpp
    backends/graphics/opengl/opengl-graphics.cpp
    backends/graphics/opengl/opengl-graphics.h
    backends/graphics/opengl/opengl-sys.h
    backends/graphics/openglsdl/openglsdl-graphics.cpp
    backends/graphics/openglsdl/openglsdl-graphics.h
    backends/platform/tizen/graphics.cpp



diff --git a/backends/graphics/opengl/context.cpp b/backends/graphics/opengl/context.cpp
index d1776f8..0077cc2 100644
--- a/backends/graphics/opengl/context.cpp
+++ b/backends/graphics/opengl/context.cpp
@@ -27,24 +27,32 @@
 
 namespace OpenGL {
 
-void Context::reset() {
-	ready = false;
-	type = kContextGL;
+void Context::reset(bool full) {
+	if (full) {
+		// GLES supports least features, thus we initialize the context type
+		// to this on full reset.
+		type = kContextGLES;
+	}
+
 	NPOTSupported = false;
 }
 
 Context g_context;
 
-void OpenGLGraphicsManager::initializeGLContext(ContextType type) {
-	// Initialize default state.
-	g_context.reset();
-
+void OpenGLGraphicsManager::setContextType(ContextType type) {
 #if USE_FORCED_GL
 	type = kContextGL;
 #elif USE_FORCED_GLES
 	type = kContextGLES;
 #endif
 
+	g_context.type = type;
+}
+
+void OpenGLGraphicsManager::initializeGLContext() {
+	// Initialize default state.
+	g_context.reset();
+
 	// Load all functions.
 	// We use horrible trickery to silence C++ compilers.
 	// See backends/plugins/sdl/sdl-provider.cpp for more information.
@@ -72,9 +80,6 @@ void OpenGLGraphicsManager::initializeGLContext(ContextType type) {
 			g_context.NPOTSupported = true;
 		}
 	}
-
-	g_context.ready = true;
-	g_context.type = type;
 }
 
 } // End of namespace OpenGL
diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index 8db5f6a..78c6b2a 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -56,7 +56,7 @@ OpenGLGraphicsManager::OpenGLGraphicsManager()
 #endif
     {
 	memset(_gamePalette, 0, sizeof(_gamePalette));
-	g_context.reset();
+	g_context.reset(true);
 }
 
 OpenGLGraphicsManager::~OpenGLGraphicsManager() {
@@ -840,9 +840,9 @@ void OpenGLGraphicsManager::setActualScreenSize(uint width, uint height) {
 	++_screenChangeID;
 }
 
-void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &defaultFormat, const Graphics::PixelFormat &defaultFormatAlpha, ContextType type) {
+void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &defaultFormat, const Graphics::PixelFormat &defaultFormatAlpha) {
 	// Initialize context for use.
-	initializeGLContext(type);
+	initializeGLContext();
 
 	// Disable 3D properties.
 	GL_CALL(glDisable(GL_CULL_FACE));
diff --git a/backends/graphics/opengl/opengl-graphics.h b/backends/graphics/opengl/opengl-graphics.h
index 5f0436c..5a2b1bb 100644
--- a/backends/graphics/opengl/opengl-graphics.h
+++ b/backends/graphics/opengl/opengl-graphics.h
@@ -117,11 +117,6 @@ public:
 
 protected:
 	/**
-	 * Whether an OpenGL (context) is active.
-	 */
-	bool isInitialized() const { return g_context.ready; }
-
-	/**
 	 * Whether an GLES context is active.
 	 */
 	bool isGLESContext() const { return g_context.type == kContextGLES; }
@@ -136,6 +131,16 @@ protected:
 	void setActualScreenSize(uint width, uint height);
 
 	/**
+	 * Sets the OpenGL (ES) type the graphics manager shall work with.
+	 *
+	 * This needs to be called at least once (and before ever calling
+	 * notifyContextCreate).
+	 *
+	 * @param type Type of the OpenGL (ES) contexts to be created.
+	 */
+	void setContextType(ContextType type);
+
+	/**
 	 * Notify the manager of a OpenGL context change. This should be the first
 	 * thing to call after you created an OpenGL (ES) context!
 	 *
@@ -143,9 +148,8 @@ protected:
 	 *                           (this is used for the CLUT8 game screens).
 	 * @param defaultFormatAlpha The new default format with an alpha channel
 	 *                           (this is used for the overlay and cursor).
-	 * @param type               Type of the created context.
 	 */
-	void notifyContextCreate(const Graphics::PixelFormat &defaultFormat, const Graphics::PixelFormat &defaultFormatAlpha, ContextType type);
+	void notifyContextCreate(const Graphics::PixelFormat &defaultFormat, const Graphics::PixelFormat &defaultFormatAlpha);
 
 	/**
 	 * Notify the manager that the OpenGL context is about to be destroyed.
@@ -293,10 +297,8 @@ private:
 
 	/**
 	 * Initialize the active context for use.
-	 *
-	 * @param type Type of the context to initialize.
 	 */
-	void initializeGLContext(ContextType type);
+	void initializeGLContext();
 
 protected:
 	/**
diff --git a/backends/graphics/opengl/opengl-sys.h b/backends/graphics/opengl/opengl-sys.h
index 550dbb4..250357f 100644
--- a/backends/graphics/opengl/opengl-sys.h
+++ b/backends/graphics/opengl/opengl-sys.h
@@ -76,9 +76,6 @@ enum ContextType {
  * Description structure of the OpenGL (ES) context.
  */
 struct Context {
-	/** Whether the context is properly initalized or not. */
-	bool ready;
-
 	/** The type of the active context. */
 	ContextType type;
 
@@ -87,7 +84,7 @@ struct Context {
 	 *
 	 * This marks all extensions as unavailable.
 	 */
-	void reset();
+	void reset(bool full = false);
 
 	/** Whether GL_ARB_texture_non_power_of_two is available or not. */
 	bool NPOTSupported;
diff --git a/backends/graphics/openglsdl/openglsdl-graphics.cpp b/backends/graphics/openglsdl/openglsdl-graphics.cpp
index e7b6da2..75d3fa1 100644
--- a/backends/graphics/openglsdl/openglsdl-graphics.cpp
+++ b/backends/graphics/openglsdl/openglsdl-graphics.cpp
@@ -47,15 +47,17 @@ OpenGLSdlGraphicsManager::OpenGLSdlGraphicsManager(uint desktopWidth, uint deskt
 
 	// Setup proper SDL OpenGL context creation.
 #if SDL_VERSION_ATLEAST(2, 0, 0)
+	OpenGL::ContextType glContextType;
+
 #if USE_FORCED_GL
-	_glContextType = OpenGL::kContextGL;
+	glContextType = OpenGL::kContextGL;
 	_glContextProfileMask = SDL_GL_CONTEXT_PROFILE_COMPATIBILITY;
 	// Context version 1.4 is choosen arbitrarily based on what most shader
 	// extensions were written against.
 	_glContextMajor = 1;
 	_glContextMinor = 4;
 #elif USE_FORCED_GLES
-	_glContextType = OpenGL::kContextGLES;
+	glContextType = OpenGL::kContextGLES;
 	_glContextProfileMask = SDL_GL_CONTEXT_PROFILE_ES;
 	_glContextMajor = 1;
 	_glContextMinor = 1;
@@ -103,7 +105,7 @@ OpenGLSdlGraphicsManager::OpenGLSdlGraphicsManager(uint desktopWidth, uint deskt
 	}
 
 	if (_glContextProfileMask == SDL_GL_CONTEXT_PROFILE_ES) {
-		_glContextType = OpenGL::kContextGLES;
+		glContextType = OpenGL::kContextGLES;
 
 		// We do not support GLES2 contexts right now. Force a GLES1 context.
 		if (_glContextMajor >= 2) {
@@ -111,7 +113,7 @@ OpenGLSdlGraphicsManager::OpenGLSdlGraphicsManager(uint desktopWidth, uint deskt
 			_glContextMinor = 1;
 		}
 	} else if (_glContextProfileMask == SDL_GL_CONTEXT_PROFILE_CORE) {
-		_glContextType = OpenGL::kContextGL;
+		glContextType = OpenGL::kContextGL;
 
 		// Core profile does not allow legacy functionality, which we use.
 		// Thus we always request a compatibility profile.
@@ -121,9 +123,12 @@ OpenGLSdlGraphicsManager::OpenGLSdlGraphicsManager(uint desktopWidth, uint deskt
 		_glContextMajor = 1;
 		_glContextMinor = 4;
 	} else {
-		_glContextType = OpenGL::kContextGL;
+		glContextType = OpenGL::kContextGL;
 	}
 #endif
+	setContextType(glContextType);
+#else
+	setContextType(OpenGL::kContextGL);
 #endif
 
 	// Retrieve a list of working fullscreen modes
@@ -293,7 +298,7 @@ Common::List<Graphics::PixelFormat> OpenGLSdlGraphicsManager::getSupportedFormat
 
 #if !USE_FORCED_GLES
 #if !USE_FORCED_GL
-	if (isInitialized() && !isGLESContext()) {
+	if (!isGLESContext()) {
 #endif
 #ifdef SCUMM_LITTLE_ENDIAN
 		// RGBA8888
@@ -491,7 +496,7 @@ bool OpenGLSdlGraphicsManager::setupMode(uint width, uint height) {
 		return false;
 	}
 
-	notifyContextCreate(rgba8888, rgba8888, _glContextType);
+	notifyContextCreate(rgba8888, rgba8888);
 	int actualWidth, actualHeight;
 	getWindowDimensions(&actualWidth, &actualHeight);
 	setActualScreenSize(actualWidth, actualHeight);
@@ -539,7 +544,7 @@ bool OpenGLSdlGraphicsManager::setupMode(uint width, uint height) {
 	_lastVideoModeLoad = SDL_GetTicks();
 
 	if (_hwScreen) {
-		notifyContextCreate(rgba8888, rgba8888, OpenGL::kContextGL);
+		notifyContextCreate(rgba8888, rgba8888);
 		setActualScreenSize(_hwScreen->w, _hwScreen->h);
 		_eventSource->resetKeyboadEmulation(_hwScreen->w - 1, _hwScreen->h - 1);
 	}
diff --git a/backends/graphics/openglsdl/openglsdl-graphics.h b/backends/graphics/openglsdl/openglsdl-graphics.h
index 7921163..51edcb4 100644
--- a/backends/graphics/openglsdl/openglsdl-graphics.h
+++ b/backends/graphics/openglsdl/openglsdl-graphics.h
@@ -74,7 +74,6 @@ private:
 
 #if SDL_VERSION_ATLEAST(2, 0, 0)
 	int _glContextProfileMask, _glContextMajor, _glContextMinor;
-	OpenGL::ContextType _glContextType;
 	SDL_GLContext _glContext;
 #else
 	uint32 _lastVideoModeLoad;
diff --git a/backends/platform/tizen/graphics.cpp b/backends/platform/tizen/graphics.cpp
index caa18c5..61dbfc3 100644
--- a/backends/platform/tizen/graphics.cpp
+++ b/backends/platform/tizen/graphics.cpp
@@ -56,10 +56,11 @@ result TizenGraphicsManager::Construct() {
 	loadEgl();
 
 	// Notify the OpenGL code about our context.
+	setContextType(OpenGL::kContextGLES);
 
 	// We default to RGB565 and RGBA5551 which is closest to the actual output
 	// mode we setup.
-	notifyContextCreate(Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0), Graphics::PixelFormat(2, 5, 5, 5, 1, 11, 6, 1, 0), OpenGL::kContextGLES);
+	notifyContextCreate(Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0), Graphics::PixelFormat(2, 5, 5, 5, 1, 11, 6, 1, 0));
 
 	// Tell our size.
 	int x, y, width, height;


Commit: 67e2790beba8e309dccfe9c64ea3f636fdeed5b9
    https://github.com/scummvm/scummvm/commit/67e2790beba8e309dccfe9c64ea3f636fdeed5b9
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:25+01:00

Commit Message:
OPENGLSDL: Slight cleanup.

Changed paths:
    backends/graphics/openglsdl/openglsdl-graphics.cpp



diff --git a/backends/graphics/openglsdl/openglsdl-graphics.cpp b/backends/graphics/openglsdl/openglsdl-graphics.cpp
index 75d3fa1..94f5f7a 100644
--- a/backends/graphics/openglsdl/openglsdl-graphics.cpp
+++ b/backends/graphics/openglsdl/openglsdl-graphics.cpp
@@ -49,20 +49,26 @@ OpenGLSdlGraphicsManager::OpenGLSdlGraphicsManager(uint desktopWidth, uint deskt
 #if SDL_VERSION_ATLEAST(2, 0, 0)
 	OpenGL::ContextType glContextType;
 
+	// Context version 1.4 is choosen arbitrarily based on what most shader
+	// extensions were written against.
+#define DEFAULT_GL_MAJOR 1
+#define DEFAULT_GL_MINOR 4
+
+#define DEFAULT_GLES_MAJOR 1
+#define DEFAULT_GLES_MINOR 1
+
 #if USE_FORCED_GL
 	glContextType = OpenGL::kContextGL;
 	_glContextProfileMask = SDL_GL_CONTEXT_PROFILE_COMPATIBILITY;
-	// Context version 1.4 is choosen arbitrarily based on what most shader
-	// extensions were written against.
-	_glContextMajor = 1;
-	_glContextMinor = 4;
+	_glContextMajor = DEFAULT_GL_MAJOR;
+	_glContextMinor = DEFAULT_GL_MINOR;
 #elif USE_FORCED_GLES
 	glContextType = OpenGL::kContextGLES;
 	_glContextProfileMask = SDL_GL_CONTEXT_PROFILE_ES;
-	_glContextMajor = 1;
-	_glContextMinor = 1;
+	_glContextMajor = DEFAULT_GLES_MAJOR;
+	_glContextMinor = DEFAULT_GLES_MINOR;
 #else
-	int forceMode = -1;
+	bool noDefaults = false;
 
 	// Obtain the default GL(ES) context SDL2 tries to setup.
 	//
@@ -73,44 +79,35 @@ OpenGLSdlGraphicsManager::OpenGLSdlGraphicsManager(uint desktopWidth, uint deskt
 	// In case no defaults are given we prefer OpenGL over OpenGL ES.
 	if (SDL_GL_GetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, &_glContextProfileMask) != 0) {
 		_glContextProfileMask = SDL_GL_CONTEXT_PROFILE_COMPATIBILITY;
-		forceMode = 0;
+		noDefaults = true;
 	}
 
 	if (SDL_GL_GetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, &_glContextMajor) != 0) {
-		if (_glContextProfileMask == SDL_GL_CONTEXT_PROFILE_ES) {
-			forceMode = 1;
-		} else {
-			forceMode = 0;
-		}
+		noDefaults = true;
 	}
 
 	if (SDL_GL_GetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, &_glContextMinor) != 0) {
+		noDefaults = true;
+	}
+
+	if (noDefaults) {
 		if (_glContextProfileMask == SDL_GL_CONTEXT_PROFILE_ES) {
-			forceMode = 1;
+			_glContextMajor = DEFAULT_GLES_MAJOR;
+			_glContextMinor = DEFAULT_GLES_MINOR;
 		} else {
-			forceMode = 0;
+			_glContextProfileMask = SDL_GL_CONTEXT_PROFILE_COMPATIBILITY;
+			_glContextMajor = DEFAULT_GL_MAJOR;
+			_glContextMinor = DEFAULT_GL_MINOR;
 		}
 	}
 
-	if (forceMode == 1) {
-		_glContextProfileMask = SDL_GL_CONTEXT_PROFILE_ES;
-		_glContextMajor = 1;
-		_glContextMinor = 1;
-	} else if (forceMode == 0) {
-		_glContextProfileMask = SDL_GL_CONTEXT_PROFILE_COMPATIBILITY;
-		// Context version 1.4 is choosen arbitrarily based on what most shader
-		// extensions were written against.
-		_glContextMajor = 1;
-		_glContextMinor = 4;
-	}
-
 	if (_glContextProfileMask == SDL_GL_CONTEXT_PROFILE_ES) {
 		glContextType = OpenGL::kContextGLES;
 
 		// We do not support GLES2 contexts right now. Force a GLES1 context.
 		if (_glContextMajor >= 2) {
-			_glContextMajor = 1;
-			_glContextMinor = 1;
+			_glContextMajor = DEFAULT_GLES_MAJOR;
+			_glContextMinor = DEFAULT_GLES_MINOR;
 		}
 	} else if (_glContextProfileMask == SDL_GL_CONTEXT_PROFILE_CORE) {
 		glContextType = OpenGL::kContextGL;
@@ -118,14 +115,17 @@ OpenGLSdlGraphicsManager::OpenGLSdlGraphicsManager(uint desktopWidth, uint deskt
 		// Core profile does not allow legacy functionality, which we use.
 		// Thus we always request a compatibility profile.
 		_glContextProfileMask = SDL_GL_CONTEXT_PROFILE_COMPATIBILITY;
-		// Context version 1.4 is choosen arbitrarily based on what most shader
-		// extensions were written against.
-		_glContextMajor = 1;
-		_glContextMinor = 4;
+		_glContextMajor = DEFAULT_GL_MAJOR;
+		_glContextMinor = DEFAULT_GL_MINOR;
 	} else {
 		glContextType = OpenGL::kContextGL;
 	}
+#undef DEFAULT_GL_MAJOR
+#undef DEFAULT_GL_MINOR
+#undef DEFAULT_GLES_MAJOR
+#undef DEFAULT_GLES_MINOR
 #endif
+
 	setContextType(glContextType);
 #else
 	setContextType(OpenGL::kContextGL);


Commit: c5ce812711c68ea546926f243b9f6f0ece8ca736
    https://github.com/scummvm/scummvm/commit/c5ce812711c68ea546926f243b9f6f0ece8ca736
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:25+01:00

Commit Message:
OPENGL: Simplify orthogonal projection setup.

Changed paths:
    backends/graphics/opengl/opengl-func.h
    backends/graphics/opengl/opengl-graphics.cpp



diff --git a/backends/graphics/opengl/opengl-func.h b/backends/graphics/opengl/opengl-func.h
index 0ff39c8..d13dece 100644
--- a/backends/graphics/opengl/opengl-func.h
+++ b/backends/graphics/opengl/opengl-func.h
@@ -70,12 +70,7 @@ GL_FUNC_DEF(void, glColor4f, (GLfloat red, GLfloat green, GLfloat blue, GLfloat
 GL_FUNC_DEF(void, glViewport, (GLint x, GLint y, GLsizei width, GLsizei height));
 GL_FUNC_DEF(void, glMatrixMode, (GLenum mode));
 GL_FUNC_DEF(void, glLoadIdentity, ());
-#if !USE_FORCED_GL
-GL_FUNC_DEF(void, glOrthof, (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar));
-#endif
-#if !USE_FORCED_GLES
-GL_FUNC_DEF(void, glOrtho, (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val));
-#endif
+GL_FUNC_DEF(void, glLoadMatrixf, (const GLfloat *m));
 GL_FUNC_DEF(void, glShadeModel, (GLenum mode));
 GL_FUNC_DEF(void, glHint, (GLenum target, GLenum mode));
 GL_FUNC_DEF(void, glClearColor, (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha));
diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index 78c6b2a..1083667 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -757,19 +757,17 @@ void OpenGLGraphicsManager::setActualScreenSize(uint width, uint height) {
 	// Setup coordinates system.
 	GL_CALL(glViewport(0, 0, _outputScreenWidth, _outputScreenHeight));
 
+	// Orthogonal projection matrix in column major order.
+	const GLfloat orthoProjection[4*4] = {
+		 2.0f / _outputScreenWidth,  0.0f                      ,  0.0f, 0.0f,
+		 0.0f                     , -2.0f / _outputScreenHeight,  0.0f, 0.0f,
+		 0.0f                     ,  0.0f                      , -1.0f, 0.0f,
+		-1.0f                     ,  1.0f                      ,  0.0f, 1.0f
+	};
+
 	GL_CALL(glMatrixMode(GL_PROJECTION));
-	GL_CALL(glLoadIdentity());
-#if   USE_FORCED_GLES
-	GL_CALL(glOrthof(0, _outputScreenWidth, _outputScreenHeight, 0, -1, 1));
-#elif USE_FORCED_GL
-	GL_CALL(glOrtho(0, _outputScreenWidth, _outputScreenHeight, 0, -1, 1));
-#else
-	if (isGLESContext()) {
-		GL_CALL(glOrthof(0, _outputScreenWidth, _outputScreenHeight, 0, -1, 1));
-	} else {
-		GL_CALL(glOrtho(0, _outputScreenWidth, _outputScreenHeight, 0, -1, 1));
-	}
-#endif
+	GL_CALL(glLoadMatrixf(orthoProjection));
+
 	GL_CALL(glMatrixMode(GL_MODELVIEW));
 	GL_CALL(glLoadIdentity());
 


Commit: e9310186735f34c6b085a58629b140a031d1da4e
    https://github.com/scummvm/scummvm/commit/e9310186735f34c6b085a58629b140a031d1da4e
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:25+01:00

Commit Message:
OPENGL: Typo.

Changed paths:
    backends/graphics/opengl/opengl-graphics.cpp



diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index 1083667..15e6f40 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -754,7 +754,7 @@ void OpenGLGraphicsManager::setActualScreenSize(uint width, uint height) {
 	_outputScreenWidth = width;
 	_outputScreenHeight = height;
 
-	// Setup coordinates system.
+	// Setup coordinate system.
 	GL_CALL(glViewport(0, 0, _outputScreenWidth, _outputScreenHeight));
 
 	// Orthogonal projection matrix in column major order.


Commit: fe88375ff376cbb0d940c96ac6ec1667be4acab0
    https://github.com/scummvm/scummvm/commit/fe88375ff376cbb0d940c96ac6ec1667be4acab0
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:25+01:00

Commit Message:
OPENGL: Support GLES2 contexts.

Changed paths:
  A backends/graphics/opengl/shader.cpp
  A backends/graphics/opengl/shader.h
    backends/graphics/opengl/context.cpp
    backends/graphics/opengl/opengl-defs.h
    backends/graphics/opengl/opengl-func.h
    backends/graphics/opengl/opengl-graphics.cpp
    backends/graphics/opengl/opengl-graphics.h
    backends/graphics/opengl/opengl-sys.h
    backends/graphics/opengl/texture.cpp
    backends/graphics/openglsdl/openglsdl-graphics.cpp
    backends/module.mk
    configure



diff --git a/backends/graphics/opengl/context.cpp b/backends/graphics/opengl/context.cpp
index 0077cc2..0944e05 100644
--- a/backends/graphics/opengl/context.cpp
+++ b/backends/graphics/opengl/context.cpp
@@ -44,6 +44,8 @@ void OpenGLGraphicsManager::setContextType(ContextType type) {
 	type = kContextGL;
 #elif USE_FORCED_GLES
 	type = kContextGLES;
+#elif USE_FORCED_GLES2
+	type = kContextGLES2;
 #endif
 
 	g_context.type = type;
diff --git a/backends/graphics/opengl/opengl-defs.h b/backends/graphics/opengl/opengl-defs.h
index 4b82d7e..fe79caa 100644
--- a/backends/graphics/opengl/opengl-defs.h
+++ b/backends/graphics/opengl/opengl-defs.h
@@ -75,11 +75,16 @@ typedef float  GLfloat;  /* single precision float */
 typedef float  GLclampf; /* single precision float in [0,1] */
 typedef double GLdouble; /* double precision float */
 typedef double GLclampd; /* double precision float in [0,1] */
+typedef char   GLchar;
 
 /*
  * Constants
  */
 
+/* Boolean constants */
+#define GL_FALSE                          0
+#define GL_TRUE                           1
+
 /* StringName */
 #define GL_VENDOR                         0x1F00
 #define GL_RENDERER                       0x1F01
@@ -216,4 +221,16 @@ typedef double GLclampd; /* double precision float in [0,1] */
 #define GL_TRIANGLE_STRIP                 0x0005
 #define GL_TRIANGLE_FAN                   0x0006
 
+/* Shaders */
+#define GL_FRAGMENT_SHADER                0x8B30
+#define GL_VERTEX_SHADER                  0x8B31
+
+/* Programs */
+#define GL_COMPILE_STATUS                 0x8B81
+#define GL_LINK_STATUS                    0x8B82
+#define GL_INFO_LOG_LENGTH                0x8B84
+
+/* Textures */
+#define GL_TEXTURE0                       0x84C0
+
 #endif
diff --git a/backends/graphics/opengl/opengl-func.h b/backends/graphics/opengl/opengl-func.h
index d13dece..633385a 100644
--- a/backends/graphics/opengl/opengl-func.h
+++ b/backends/graphics/opengl/opengl-func.h
@@ -91,3 +91,28 @@ GL_FUNC_DEF(void, glDrawArrays, (GLenum mode, GLint first, GLsizei count));
 GL_FUNC_DEF(void, glTexSubImage2D, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels));
 GL_FUNC_DEF(const GLubyte *, glGetString, (GLenum name));
 GL_FUNC_DEF(GLenum, glGetError, ());
+
+#if !USE_FORCED_GL && !USE_FORCED_GLES
+GL_FUNC_DEF(void, glVertexAttrib4f, (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w));
+GL_FUNC_DEF(void, glVertexAttribPointer, (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer));
+GL_FUNC_DEF(void, glUniformMatrix4fv, (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value));
+GL_FUNC_DEF(void, glUniform1i, (GLint location, GLint v0));
+GL_FUNC_DEF(void, glDeleteProgram, (GLuint program));
+GL_FUNC_DEF(void, glDeleteShader, (GLuint shader));
+GL_FUNC_DEF(GLuint, glCreateProgram, ());
+GL_FUNC_DEF(void, glAttachShader, (GLuint program, GLuint shader));
+GL_FUNC_DEF(void, glBindAttribLocation, (GLuint program, GLuint index, const GLchar *name));
+GL_FUNC_DEF(void, glLinkProgram, (GLuint program));
+GL_FUNC_DEF(void, glDetachShader, (GLuint program, GLuint shader));
+GL_FUNC_DEF(void, glGetProgramiv, (GLuint program, GLenum pname, GLint *params));
+GL_FUNC_DEF(void, glGetProgramInfoLog, (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog));
+GL_FUNC_DEF(GLint, glGetUniformLocation, (GLuint program, const GLchar *name));
+GL_FUNC_DEF(void, glUseProgram, (GLuint program));
+GL_FUNC_DEF(GLuint, glCreateShader, (GLenum type));
+GL_FUNC_DEF(void, glShaderSource, (GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length));
+GL_FUNC_DEF(void, glCompileShader, (GLuint shader));
+GL_FUNC_DEF(void, glGetShaderiv, (GLuint shader, GLenum pname, GLint *params));
+GL_FUNC_DEF(void, glGetShaderInfoLog, (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog));
+GL_FUNC_DEF(void, glEnableVertexAttribArray, (GLuint index));
+GL_FUNC_DEF(void, glActiveTexture, (GLenum texture));
+#endif
diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index 15e6f40..1b20a31 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -23,6 +23,7 @@
 
 #include "backends/graphics/opengl/opengl-graphics.h"
 #include "backends/graphics/opengl/texture.h"
+#include "backends/graphics/opengl/shader.h"
 
 #include "common/textconsole.h"
 #include "common/translation.h"
@@ -54,6 +55,9 @@ OpenGLGraphicsManager::OpenGLGraphicsManager()
 #ifdef USE_OSD
       , _osdAlpha(0), _osdFadeStartTime(0), _osd(nullptr)
 #endif
+#if !USE_FORCED_GL && !USE_FORCED_GLES
+      , _shader(nullptr), _projectionMatrix()
+#endif
     {
 	memset(_gamePalette, 0, sizeof(_gamePalette));
 	g_context.reset(true);
@@ -66,6 +70,9 @@ OpenGLGraphicsManager::~OpenGLGraphicsManager() {
 #ifdef USE_OSD
 	delete _osd;
 #endif
+#if !USE_FORCED_GL && !USE_FORCED_GLES
+	delete _shader;
+#endif
 }
 
 bool OpenGLGraphicsManager::hasFeature(OSystem::Feature f) {
@@ -418,13 +425,13 @@ void OpenGLGraphicsManager::updateScreen() {
 		}
 
 		// Set the OSD transparency.
-		GL_CALL(glColor4f(1.0f, 1.0f, 1.0f, _osdAlpha / 100.0f));
+		setColor(1.0f, 1.0f, 1.0f, _osdAlpha / 100.0f);
 
 		// Draw the OSD texture.
 		_osd->draw(0, 0, _outputScreenWidth, _outputScreenHeight);
 
 		// Reset color.
-		GL_CALL(glColor4f(1.0f, 1.0f, 1.0f, 1.0f));
+		setColor(1.0f, 1.0f, 1.0f, 1.0f);
 	}
 #endif
 
@@ -765,11 +772,29 @@ void OpenGLGraphicsManager::setActualScreenSize(uint width, uint height) {
 		-1.0f                     ,  1.0f                      ,  0.0f, 1.0f
 	};
 
-	GL_CALL(glMatrixMode(GL_PROJECTION));
-	GL_CALL(glLoadMatrixf(orthoProjection));
+#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
+	if (g_context.type != kContextGLES2) {
+#endif
+#if !USE_FORCED_GLES2
+		GL_CALL(glMatrixMode(GL_PROJECTION));
+		GL_CALL(glLoadMatrixf(orthoProjection));
 
-	GL_CALL(glMatrixMode(GL_MODELVIEW));
-	GL_CALL(glLoadIdentity());
+		GL_CALL(glMatrixMode(GL_MODELVIEW));
+		GL_CALL(glLoadIdentity());
+#endif
+#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
+	} else {
+#endif
+#if !USE_FORCED_GL && !USE_FORCED_GLES
+		assert(sizeof(_projectionMatrix) == sizeof(orthoProjection));
+		memcpy(_projectionMatrix, orthoProjection, sizeof(_projectionMatrix));
+		if (_shader) {
+			_shader->activate(_projectionMatrix);
+		}
+#endif
+#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
+	}
+#endif
 
 	uint overlayWidth = width;
 	uint overlayHeight = height;
@@ -845,25 +870,51 @@ void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &def
 	// Disable 3D properties.
 	GL_CALL(glDisable(GL_CULL_FACE));
 	GL_CALL(glDisable(GL_DEPTH_TEST));
-	GL_CALL(glDisable(GL_LIGHTING));
-	GL_CALL(glDisable(GL_FOG));
 	GL_CALL(glDisable(GL_DITHER));
-	GL_CALL(glShadeModel(GL_FLAT));
-	GL_CALL(glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST));
+
+#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
+	if (g_context.type != kContextGLES2) {
+#endif
+#if !USE_FORCED_GLES2
+		GL_CALL(glDisable(GL_LIGHTING));
+		GL_CALL(glDisable(GL_FOG));
+		GL_CALL(glShadeModel(GL_FLAT));
+		GL_CALL(glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST));
+#endif
+#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
+	}
+#endif
 
 	// Default to black as clear color.
 	GL_CALL(glClearColor(0.0f, 0.0f, 0.0f, 0.0f));
-	GL_CALL(glColor4f(1.0f, 1.0f, 1.0f, 1.0f));
+	setColor(1.0f, 1.0f, 1.0f, 1.0f);
 
 	// Setup alpha blend (for overlay and cursor).
 	GL_CALL(glEnable(GL_BLEND));
 	GL_CALL(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
 
-	// Enable rendering with vertex and coord arrays.
-	GL_CALL(glEnableClientState(GL_VERTEX_ARRAY));
-	GL_CALL(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
+#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
+	if (g_context.type != kContextGLES2) {
+#endif
+#if !USE_FORCED_GLES2
+		// Enable rendering with vertex and coord arrays.
+		GL_CALL(glEnableClientState(GL_VERTEX_ARRAY));
+		GL_CALL(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
+
+		GL_CALL(glEnable(GL_TEXTURE_2D));
+#endif
+#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
+	} else {
+#endif
+#if !USE_FORCED_GL && !USE_FORCED_GLES
+		GL_CALL(glEnableVertexAttribArray(kPositionAttribLocation));
+		GL_CALL(glEnableVertexAttribArray(kTexCoordAttribLocation));
 
-	GL_CALL(glEnable(GL_TEXTURE_2D));
+		GL_CALL(glActiveTexture(GL_TEXTURE0));
+#endif
+#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
+	}
+#endif
 
 	// Setup scissor state accordingly.
 	if (_overlayVisible) {
@@ -883,6 +934,22 @@ void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &def
 	// Query information needed by textures.
 	Texture::queryTextureInformation();
 
+#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
+	if (g_context.type == kContextGLES2) {
+#endif
+#if !USE_FORCED_GL && !USE_FORCED_GLES
+		if (!_shader) {
+			_shader = new Shader(g_defaultVertexShader, g_defaultFragmentShader);
+		}
+
+		// TODO: What do we do on failure?
+		_shader->recreate();
+		_shader->activate(_projectionMatrix);
+#endif
+#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
+	}
+#endif
+
 	// Refresh the output screen dimensions if some are set up.
 	if (_outputScreenWidth != 0 && _outputScreenHeight != 0) {
 		setActualScreenSize(_outputScreenWidth, _outputScreenHeight);
@@ -931,6 +998,12 @@ void OpenGLGraphicsManager::notifyContextDestroy() {
 		_osd->releaseInternalTexture();
 	}
 #endif
+
+#if !USE_FORCED_GL && !USE_FORCED_GLES
+	if (_shader) {
+		_shader->destroy();
+	}
+#endif
 }
 
 void OpenGLGraphicsManager::adjustMousePosition(int16 &x, int16 &y) {
@@ -1002,6 +1075,24 @@ Texture *OpenGLGraphicsManager::createTexture(const Graphics::PixelFormat &forma
 	}
 }
 
+void OpenGLGraphicsManager::setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
+#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
+	if (g_context.type != kContextGLES2) {
+#endif
+#if !USE_FORCED_GLES2
+		GL_CALL(glColor4f(r, g, b, a));
+#endif
+#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
+	} else {
+#endif
+#if !USE_FORCED_GL && !USE_FORCED_GLES
+		GL_CALL(glVertexAttrib4f(kColorAttribLocation, r, g, b, a));
+#endif
+#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
+	}
+#endif
+}
+
 bool OpenGLGraphicsManager::getGLPixelFormat(const Graphics::PixelFormat &pixelFormat, GLenum &glIntFormat, GLenum &glFormat, GLenum &glType) const {
 #ifdef SCUMM_LITTLE_ENDIAN
 	if (pixelFormat == Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24)) { // ABGR8888
@@ -1027,7 +1118,7 @@ bool OpenGLGraphicsManager::getGLPixelFormat(const Graphics::PixelFormat &pixelF
 		glFormat = GL_RGBA;
 		glType = GL_UNSIGNED_SHORT_4_4_4_4;
 		return true;
-#if !USE_FORCED_GLES
+#if !USE_FORCED_GLES && !USE_FORCED_GLES2
 	// The formats below are not supported by every GLES implementation.
 	// Thus, we do not mark them as supported when a GLES context is setup.
 	} else if (isGLESContext()) {
@@ -1081,7 +1172,7 @@ bool OpenGLGraphicsManager::getGLPixelFormat(const Graphics::PixelFormat &pixelF
 		glFormat = GL_BGRA;
 		glType = GL_UNSIGNED_SHORT_4_4_4_4;
 		return true;
-#endif // !USE_FORCED_GLES
+#endif // !USE_FORCED_GLES && !USE_FORCED_GLES2
 	} else {
 		return false;
 	}
diff --git a/backends/graphics/opengl/opengl-graphics.h b/backends/graphics/opengl/opengl-graphics.h
index 5a2b1bb..37ab1f8 100644
--- a/backends/graphics/opengl/opengl-graphics.h
+++ b/backends/graphics/opengl/opengl-graphics.h
@@ -41,6 +41,9 @@ namespace OpenGL {
 #define USE_OSD 1
 
 class Texture;
+#if !USE_FORCED_GL && !USE_FORCED_GLES
+class Shader;
+#endif
 
 enum {
 	GFX_LINEAR = 0,
@@ -117,9 +120,9 @@ public:
 
 protected:
 	/**
-	 * Whether an GLES context is active.
+	 * Whether an GLES or GLES2 context is active.
 	 */
-	bool isGLESContext() const { return g_context.type == kContextGLES; }
+	bool isGLESContext() const { return g_context.type == kContextGLES || g_context.type == kContextGLES2; }
 
 	/**
 	 * Set up the actual screen size available for the OpenGL code to do any
@@ -300,6 +303,14 @@ private:
 	 */
 	void initializeGLContext();
 
+	/**
+	 * Set color which shall be multiplied with each pixel.
+	 *
+	 * This serves as a wrapper around glColor4f for fixed-function and our
+	 * shader pipeline.
+	 */
+	void setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
+
 protected:
 	/**
 	 * Query the address of an OpenGL function by name.
@@ -518,6 +529,22 @@ private:
 	 */
 	uint _scissorOverride;
 
+#if !USE_FORCED_GL && !USE_FORCED_GLES
+	//
+	// Shaders
+	//
+
+	/**
+	 * Active shader.
+	 */
+	Shader *_shader;
+
+	/**
+	 * Projection matrix used.
+	 */
+	GLfloat _projectionMatrix[4*4];
+#endif
+
 #ifdef USE_OSD
 	//
 	// OSD
diff --git a/backends/graphics/opengl/opengl-sys.h b/backends/graphics/opengl/opengl-sys.h
index 250357f..ad36226 100644
--- a/backends/graphics/opengl/opengl-sys.h
+++ b/backends/graphics/opengl/opengl-sys.h
@@ -35,8 +35,10 @@
 // the given selection choices:
 //  0 - Force OpenGL context
 //  1 - Force OpenGL ES context
-#define USE_FORCED_GL   (defined(USE_GLES_MODE) && USE_GLES_MODE == 0)
-#define USE_FORCED_GLES (defined(USE_GLES_MODE) && USE_GLES_MODE == 1)
+//  2 - Force OpenGL ES 2.0 context
+#define USE_FORCED_GL    (defined(USE_GLES_MODE) && USE_GLES_MODE == 0)
+#define USE_FORCED_GLES  (defined(USE_GLES_MODE) && USE_GLES_MODE == 1)
+#define USE_FORCED_GLES2 (defined(USE_GLES_MODE) && USE_GLES_MODE == 2)
 
 // On Tizen we include the toolchain's OpenGL file. This is something we
 // actually want to avoid. However, since Tizen uses eglGetProcAddress which
@@ -69,7 +71,8 @@ namespace OpenGL {
 
 enum ContextType {
 	kContextGL,
-	kContextGLES
+	kContextGLES,
+	kContextGLES2
 };
 
 /**
@@ -103,6 +106,7 @@ extern Context g_context;
 
 } // End of namespace OpenGL
 
-#define GL_CALL(x) GL_WRAP_DEBUG(g_context.x, x)
+#define GL_CALL(x)        GL_WRAP_DEBUG(g_context.x, x)
+#define GL_ASSIGN(var, x) GL_WRAP_DEBUG(var = g_context.x, x)
 
 #endif
diff --git a/backends/graphics/opengl/shader.cpp b/backends/graphics/opengl/shader.cpp
new file mode 100644
index 0000000..6e36307
--- /dev/null
+++ b/backends/graphics/opengl/shader.cpp
@@ -0,0 +1,176 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "backends/graphics/opengl/shader.h"
+
+#if !USE_FORCED_GL && !USE_FORCED_GLES
+
+#include "common/textconsole.h"
+
+namespace OpenGL {
+
+const char *const g_defaultVertexShader = 
+	"attribute vec4 position;\n"
+	"attribute vec2 texCoordIn;\n"
+	"attribute vec4 blendColorIn;\n"
+	"\n"
+	"uniform mat4 projection;\n"
+	"\n"
+	"varying vec2 texCoord;\n"
+	"varying vec4 blendColor;\n"
+	"\n"
+	"void main(void) {\n"
+	"\ttexCoord    = texCoordIn;\n"
+	"\tblendColor  = blendColorIn;\n"
+	"\tgl_Position = projection * position;\n"
+	"}\n";
+
+const char *const g_defaultFragmentShader =
+	"varying lowp vec2 texCoord;\n"
+	"varying lowp vec4 blendColor;\n"
+	"\n"
+	"uniform sampler2D texture;\n"
+	"\n"
+	"void main(void) {\n"
+	"\tgl_FragColor = blendColor * texture2D(texture, texCoord);\n"
+	"}\n";
+
+Shader::Shader(const Common::String &vertex, const Common::String &fragment)
+    : _vertex(vertex), _fragment(fragment), _program(0), _projectionLocation(-1), _textureLocation(-1) {
+}
+
+void Shader::destroy() {
+	GL_CALL(glDeleteProgram(_program));
+	_program = 0;
+}
+
+bool Shader::recreate() {
+	// Make sure any old programs are destroyed properly.
+	destroy();
+
+	GLuint vertexShader = compileShader(_vertex.c_str(), GL_VERTEX_SHADER);
+	if (!vertexShader) {
+		return false;
+	}
+
+	GLuint fragmentShader = compileShader(_fragment.c_str(), GL_FRAGMENT_SHADER);
+	if (!fragmentShader) {
+		GL_CALL(glDeleteShader(vertexShader));
+		return false;
+	}
+
+	GL_ASSIGN(_program, glCreateProgram());
+	if (!_program) {
+		GL_CALL(glDeleteShader(vertexShader));
+		GL_CALL(glDeleteShader(fragmentShader));
+		return false;
+	}
+
+	GL_CALL(glAttachShader(_program, vertexShader));
+	GL_CALL(glAttachShader(_program, fragmentShader));
+
+	GL_CALL(glBindAttribLocation(_program, kPositionAttribLocation, "position"));
+	GL_CALL(glBindAttribLocation(_program, kTexCoordAttribLocation, "texCoordIn"));
+	GL_CALL(glBindAttribLocation(_program, kColorAttribLocation,    "blendColorIn"));
+
+	GL_CALL(glLinkProgram(_program));
+
+	GL_CALL(glDetachShader(_program, fragmentShader));
+	GL_CALL(glDeleteShader(fragmentShader));
+
+	GL_CALL(glDetachShader(_program, vertexShader));
+	GL_CALL(glDeleteShader(vertexShader));
+
+	GLint result;
+	GL_CALL(glGetProgramiv(_program, GL_LINK_STATUS, &result));
+	if (result == GL_FALSE) {
+		GLint logSize;
+		GL_CALL(glGetProgramiv(_program, GL_INFO_LOG_LENGTH, &logSize));
+
+		GLchar *log = new GLchar[logSize];
+		GL_CALL(glGetProgramInfoLog(_program, logSize, nullptr, log));
+		warning("Could not link shader: \"%s\"", log);
+		delete[] log;
+
+		destroy();
+		return false;
+	}
+
+	GL_ASSIGN(_projectionLocation, glGetUniformLocation(_program, "projection"));
+	if (_projectionLocation == -1) {
+		warning("Shader misses \"projection\" uniform.");
+		destroy();
+		return false;
+	}
+
+	GL_ASSIGN(_textureLocation, glGetUniformLocation(_program, "texture"));
+	if (_textureLocation == -1) {
+		warning("Shader misses \"texture\" uniform.");
+		destroy();
+		return false;
+	}
+
+	return true;
+}
+
+void Shader::activate(const GLfloat *projectionMatrix) {
+	// Activate program.
+	GL_CALL(glUseProgram(_program));
+
+	// Set projection matrix.
+	GL_CALL(glUniformMatrix4fv(_projectionLocation, 1, GL_FALSE, projectionMatrix));
+
+	// We always use texture unit 0.
+	GL_CALL(glUniform1i(_textureLocation, 0));
+}
+
+GLuint Shader::compileShader(const char *source, GLenum shaderType) {
+	GLuint handle;
+	GL_ASSIGN(handle, glCreateShader(shaderType));
+	if (!handle) {
+		return 0;
+	}
+
+	GL_CALL(glShaderSource(handle, 1, &source, nullptr));
+	GL_CALL(glCompileShader(handle));
+
+	GLint result;
+	GL_CALL(glGetShaderiv(handle, GL_COMPILE_STATUS, &result));
+	if (result == GL_FALSE) {
+		GLint logSize;
+		GL_CALL(glGetShaderiv(handle, GL_INFO_LOG_LENGTH, &logSize));
+
+		GLchar *log = new GLchar[logSize];
+		GL_CALL(glGetShaderInfoLog(handle, logSize, nullptr, log));
+		warning("Could not compile shader \"%s\": \"%s\"", source, log);
+		delete[] log;
+
+		GL_CALL(glDeleteShader(handle));
+		return 0;
+	}
+
+	return handle;
+}
+
+} // End of namespace OpenGL
+
+#endif // !USE_FORCED_GL && !USE_FORCED_GLES
diff --git a/backends/graphics/opengl/shader.h b/backends/graphics/opengl/shader.h
new file mode 100644
index 0000000..e8535e0
--- /dev/null
+++ b/backends/graphics/opengl/shader.h
@@ -0,0 +1,110 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BACKENDS_GRAPHICS_OPENGL_SHADER_H
+#define BACKENDS_GRAPHICS_OPENGL_SHADER_H
+
+#include "backends/graphics/opengl/opengl-sys.h"
+
+#if !USE_FORCED_GL && !USE_FORCED_GLES
+
+#include "common/str.h"
+
+namespace OpenGL {
+
+enum {
+	kPositionAttribLocation = 0,
+	kTexCoordAttribLocation = 1,
+	kColorAttribLocation    = 2
+};
+
+extern const char *const g_defaultVertexShader;
+extern const char *const g_defaultFragmentShader;
+
+class Shader {
+public:
+	Shader(const Common::String &vertex, const Common::String &fragment);
+	~Shader() { destroy(); }
+
+	/**
+	 * Destroy the shader program.
+	 *
+	 * This keeps the vertex and fragment shader sources around and thus
+	 * allows for recreating the shader on context recreation.
+	 */
+	void destroy();
+
+	/**
+	 * Recreate shader program.
+	 *
+	 * @return true on success, false on failure.
+	 */
+	bool recreate();
+
+	/**
+	 * Make shader active.
+	 *
+	 * @param projectionMatrix Projection matrix to use.
+	 */
+	void activate(const GLfloat *projectionMatrix);
+private:
+	/**
+	 * Vertex shader sources.
+	 */
+	const Common::String _vertex;
+
+	/**
+	 * Fragment shader sources.
+	 */
+	const Common::String _fragment;
+
+	/**
+	 * Shader program handle.
+	 */
+	GLuint _program;
+
+	/**
+	 * Location of the matrix uniform in the shader program.
+	 */
+	GLint _projectionLocation;
+
+	/**
+	 * Location of the texture sampler location in the shader program.
+	 */
+	GLint _textureLocation;
+
+	/**
+	 * Compile a vertex or fragment shader.
+	 *
+	 * @param source     Sources to the shader.
+	 * @param shaderType Type of shader to compile (GL_FRAGMENT_SHADER or
+	 *                   GL_VERTEX_SHADER)
+	 * @return The shader object or 0 on failure.
+	 */
+	static GLuint compileShader(const char *source, GLenum shaderType);
+};
+
+} // End of namespace OpenGL
+
+#endif // !USE_FORCED_GL && !USE_FORCED_GLES
+
+#endif
diff --git a/backends/graphics/opengl/texture.cpp b/backends/graphics/opengl/texture.cpp
index fadfd99..c8c38ed 100644
--- a/backends/graphics/opengl/texture.cpp
+++ b/backends/graphics/opengl/texture.cpp
@@ -21,6 +21,7 @@
  */
 
 #include "backends/graphics/opengl/texture.h"
+#include "backends/graphics/opengl/shader.h"
 
 #include "common/rect.h"
 #include "common/textconsole.h"
@@ -185,7 +186,6 @@ void Texture::draw(GLfloat x, GLfloat y, GLfloat w, GLfloat h) {
 		0,        texHeight,
 		texWidth, texHeight
 	};
-	GL_CALL(glTexCoordPointer(2, GL_FLOAT, 0, texcoords));
 
 	// Calculate the screen rect where the texture will be drawn.
 	const GLfloat vertices[4*2] = {
@@ -194,7 +194,24 @@ void Texture::draw(GLfloat x, GLfloat y, GLfloat w, GLfloat h) {
 		x,     y + h,
 		x + w, y + h
 	};
-	GL_CALL(glVertexPointer(2, GL_FLOAT, 0, vertices));
+
+#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
+	if (g_context.type != kContextGLES2) {
+#endif
+#if !USE_FORCED_GLES2
+		GL_CALL(glTexCoordPointer(2, GL_FLOAT, 0, texcoords));
+		GL_CALL(glVertexPointer(2, GL_FLOAT, 0, vertices));
+#endif
+#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
+	} else {
+#endif
+#if !USE_FORCED_GL && !USE_FORCED_GLES
+		GL_CALL(glVertexAttribPointer(kTexCoordAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, texcoords));
+		GL_CALL(glVertexAttribPointer(kPositionAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, vertices));
+#endif
+#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
+	}
+#endif
 
 	// Draw the texture to the screen buffer.
 	GL_CALL(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
diff --git a/backends/graphics/openglsdl/openglsdl-graphics.cpp b/backends/graphics/openglsdl/openglsdl-graphics.cpp
index 94f5f7a..f2af7cc 100644
--- a/backends/graphics/openglsdl/openglsdl-graphics.cpp
+++ b/backends/graphics/openglsdl/openglsdl-graphics.cpp
@@ -57,6 +57,9 @@ OpenGLSdlGraphicsManager::OpenGLSdlGraphicsManager(uint desktopWidth, uint deskt
 #define DEFAULT_GLES_MAJOR 1
 #define DEFAULT_GLES_MINOR 1
 
+#define DEFAULT_GLES2_MAJOR 2
+#define DEFAULT_GLES2_MINOR 0
+
 #if USE_FORCED_GL
 	glContextType = OpenGL::kContextGL;
 	_glContextProfileMask = SDL_GL_CONTEXT_PROFILE_COMPATIBILITY;
@@ -67,6 +70,11 @@ OpenGLSdlGraphicsManager::OpenGLSdlGraphicsManager(uint desktopWidth, uint deskt
 	_glContextProfileMask = SDL_GL_CONTEXT_PROFILE_ES;
 	_glContextMajor = DEFAULT_GLES_MAJOR;
 	_glContextMinor = DEFAULT_GLES_MINOR;
+#elif USE_FORCED_GLES2
+	glContextType = OpenGL::kContextGLES2;
+	_glContextProfileMask = SDL_GL_CONTEXT_PROFILE_ES;
+	_glContextMajor = DEFAULT_GLES2_MAJOR;
+	_glContextMinor = DEFAULT_GLES2_MINOR;
 #else
 	bool noDefaults = false;
 
@@ -102,12 +110,10 @@ OpenGLSdlGraphicsManager::OpenGLSdlGraphicsManager(uint desktopWidth, uint deskt
 	}
 
 	if (_glContextProfileMask == SDL_GL_CONTEXT_PROFILE_ES) {
-		glContextType = OpenGL::kContextGLES;
-
-		// We do not support GLES2 contexts right now. Force a GLES1 context.
 		if (_glContextMajor >= 2) {
-			_glContextMajor = DEFAULT_GLES_MAJOR;
-			_glContextMinor = DEFAULT_GLES_MINOR;
+			glContextType = OpenGL::kContextGLES2;
+		} else {
+			glContextType = OpenGL::kContextGLES;
 		}
 	} else if (_glContextProfileMask == SDL_GL_CONTEXT_PROFILE_CORE) {
 		glContextType = OpenGL::kContextGL;
@@ -124,6 +130,8 @@ OpenGLSdlGraphicsManager::OpenGLSdlGraphicsManager(uint desktopWidth, uint deskt
 #undef DEFAULT_GL_MINOR
 #undef DEFAULT_GLES_MAJOR
 #undef DEFAULT_GLES_MINOR
+#undef DEFAULT_GLES2_MAJOR
+#undef DEFAULT_GLES2_MINOR
 #endif
 
 	setContextType(glContextType);
@@ -296,7 +304,7 @@ Common::List<Graphics::PixelFormat> OpenGLSdlGraphicsManager::getSupportedFormat
 	// RGBA4444
 	formats.push_back(Graphics::PixelFormat(2, 4, 4, 4, 4, 12, 8, 4, 0));
 
-#if !USE_FORCED_GLES
+#if !USE_FORCED_GLES && !USE_FORCED_GLES2
 #if !USE_FORCED_GL
 	if (!isGLESContext()) {
 #endif
diff --git a/backends/module.mk b/backends/module.mk
index e1c3483..e4566d0 100644
--- a/backends/module.mk
+++ b/backends/module.mk
@@ -55,6 +55,7 @@ MODULE_OBJS += \
 	graphics/opengl/context.o \
 	graphics/opengl/debug.o \
 	graphics/opengl/opengl-graphics.o \
+	graphics/opengl/shader.o \
 	graphics/opengl/texture.o
 endif
 
diff --git a/configure b/configure
index 2367466..f6cac34 100755
--- a/configure
+++ b/configure
@@ -945,6 +945,7 @@ Optional Features:
                                             any for runtime detection
                                             gl for forcing OpenGL
                                             gles for forcing OpenGL ES
+                                            gles2 for forcing OpenGL ES 2
                            WARNING: only specify this manually if you know what
                            you are doing!
 
@@ -2659,9 +2660,11 @@ if test -n "$_host"; then
 			# since SDL2 manages dispmanx/GLES2 very well internally.
 			# SDL1 is bit-rotten on this platform.
 			_sdlconfig=sdl2-config
-			# OpenGL(ES) support is mature enough as to be the best option on
+			# OpenGL ES support is mature enough as to be the best option on
 			# the Raspberry Pi, so it's enabled by default.
-			_opengl_mode=gles
+			# The Raspberry Pi always supports OpenGL ES 2.0 contexts, thus we
+			# take advantage of those.
+			_opengl_mode=gles2
 			;;
 		dreamcast)
 			append_var DEFINES "-DDISABLE_DEFAULT_SAVEFILEMANAGER"
@@ -4224,6 +4227,11 @@ case $_opengl_mode in
 		echo "yes (OpenGL ES)"
 		add_line_to_config_h "#define USE_GLES_MODE 1"
 		;;
+
+	gles2)
+		echo "yes (OpenGL ES 2)"
+		add_line_to_config_h "#define USE_GLES_MODE 2"
+		;;
 esac
 
 define_in_config_if_yes "$_opengl" "USE_OPENGL"


Commit: 1c61e017a0eec8eff4d5f6281c2bd4e906103773
    https://github.com/scummvm/scummvm/commit/1c61e017a0eec8eff4d5f6281c2bd4e906103773
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:25+01:00

Commit Message:
OPENGL: Reset full context structure.

Changed paths:
    backends/graphics/opengl/context.cpp



diff --git a/backends/graphics/opengl/context.cpp b/backends/graphics/opengl/context.cpp
index 0944e05..764cabc 100644
--- a/backends/graphics/opengl/context.cpp
+++ b/backends/graphics/opengl/context.cpp
@@ -28,13 +28,13 @@
 namespace OpenGL {
 
 void Context::reset(bool full) {
-	if (full) {
-		// GLES supports least features, thus we initialize the context type
-		// to this on full reset.
-		type = kContextGLES;
-	}
+	// GLES supports least features, thus we initialize the context type
+	// to this on full reset.
+	const ContextType savedType = full ? kContextGLES : type;
+
+	memset(this, 0, sizeof(Context));
 
-	NPOTSupported = false;
+	type = savedType;
 }
 
 Context g_context;


Commit: 19abd8ccbba339c2ea9691ef017a447b7c47701e
    https://github.com/scummvm/scummvm/commit/19abd8ccbba339c2ea9691ef017a447b7c47701e
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:25+01:00

Commit Message:
OPENGL: Reset context description on context destroy.

Changed paths:
    backends/graphics/opengl/opengl-graphics.cpp



diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index 1b20a31..7078aa8 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -1004,6 +1004,9 @@ void OpenGLGraphicsManager::notifyContextDestroy() {
 		_shader->destroy();
 	}
 #endif
+
+	// Rest our context description since the context is gone soon.
+	g_context.reset();
 }
 
 void OpenGLGraphicsManager::adjustMousePosition(int16 &x, int16 &y) {


Commit: fee1aa550203c3f46ff19afbe19a7baa4771a5cd
    https://github.com/scummvm/scummvm/commit/fee1aa550203c3f46ff19afbe19a7baa4771a5cd
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:25+01:00

Commit Message:
OPENGL: Add support for shaders with GL contexts.

Changed paths:
    backends/graphics/opengl/context.cpp
    backends/graphics/opengl/opengl-defs.h
    backends/graphics/opengl/opengl-func.h
    backends/graphics/opengl/opengl-graphics.cpp
    backends/graphics/opengl/opengl-graphics.h
    backends/graphics/opengl/opengl-sys.h
    backends/graphics/opengl/shader.cpp
    backends/graphics/opengl/shader.h
    backends/graphics/opengl/texture.cpp



diff --git a/backends/graphics/opengl/context.cpp b/backends/graphics/opengl/context.cpp
index 764cabc..618be07 100644
--- a/backends/graphics/opengl/context.cpp
+++ b/backends/graphics/opengl/context.cpp
@@ -74,14 +74,35 @@ void OpenGLGraphicsManager::initializeGLContext() {
 
 	const char *extString = (const char *)g_context.glGetString(GL_EXTENSIONS);
 
+#if !USE_FORCED_GLES && !USE_FORCED_GLES2
+	bool ARBShaderObjects = false;
+	bool ARBShadingLanguage100 = false;
+	bool ARBVertexShader = false;
+	bool ARBFragmentShader = false;
+#endif
+
 	Common::StringTokenizer tokenizer(extString, " ");
 	while (!tokenizer.empty()) {
 		Common::String token = tokenizer.nextToken();
 
 		if (token == "GL_ARB_texture_non_power_of_two") {
 			g_context.NPOTSupported = true;
+#if !USE_FORCED_GLES && !USE_FORCED_GLES2
+		} else if (token == "GL_ARB_shader_objects") {
+			ARBShaderObjects = true;
+		} else if (token == "GL_ARB_shading_language_100") {
+			ARBShadingLanguage100 = true;
+		} else if (token == "GL_ARB_vertex_shader") {
+			ARBVertexShader = true;
+		} else if (token == "GL_ARB_fragment_shader") {
+			ARBFragmentShader = true;
+#endif
 		}
 	}
+
+#if !USE_FORCED_GLES && !USE_FORCED_GLES2
+	g_context.shadersSupported = ARBShaderObjects & ARBShadingLanguage100 & ARBVertexShader & ARBFragmentShader;
+#endif
 }
 
 } // End of namespace OpenGL
diff --git a/backends/graphics/opengl/opengl-defs.h b/backends/graphics/opengl/opengl-defs.h
index fe79caa..edcf334 100644
--- a/backends/graphics/opengl/opengl-defs.h
+++ b/backends/graphics/opengl/opengl-defs.h
@@ -76,6 +76,12 @@ typedef float  GLclampf; /* single precision float in [0,1] */
 typedef double GLdouble; /* double precision float */
 typedef double GLclampd; /* double precision float in [0,1] */
 typedef char   GLchar;
+typedef GLchar GLcharARB;
+#if defined(__APPLE__) || defined(MACOSX)
+typedef void  *GLhandleARB;
+#else
+typedef uint   GLhandleARB;
+#endif
 
 /*
  * Constants
@@ -223,13 +229,20 @@ typedef char   GLchar;
 
 /* Shaders */
 #define GL_FRAGMENT_SHADER                0x8B30
+#define GL_FRAGMENT_SHADER_ARB            0x8B30
+
 #define GL_VERTEX_SHADER                  0x8B31
+#define GL_VERTEX_SHADER_ARB              0x8B31
 
 /* Programs */
 #define GL_COMPILE_STATUS                 0x8B81
 #define GL_LINK_STATUS                    0x8B82
 #define GL_INFO_LOG_LENGTH                0x8B84
 
+#define GL_OBJECT_COMPILE_STATUS_ARB      0x8B81
+#define GL_OBJECT_LINK_STATUS_ARB         0x8B82
+#define GL_OBJECT_INFO_LOG_LENGTH_ARB     0x8B84
+
 /* Textures */
 #define GL_TEXTURE0                       0x84C0
 
diff --git a/backends/graphics/opengl/opengl-func.h b/backends/graphics/opengl/opengl-func.h
index 633385a..d022d00 100644
--- a/backends/graphics/opengl/opengl-func.h
+++ b/backends/graphics/opengl/opengl-func.h
@@ -116,3 +116,24 @@ GL_FUNC_DEF(void, glGetShaderInfoLog, (GLuint shader, GLsizei bufSize, GLsizei *
 GL_FUNC_DEF(void, glEnableVertexAttribArray, (GLuint index));
 GL_FUNC_DEF(void, glActiveTexture, (GLenum texture));
 #endif
+
+#if !USE_FORCED_GLES && !USE_FORCED_GLES2
+GL_EXT_FUNC_DEF(void, glDeleteObjectARB, (GLhandleARB obj));
+GL_EXT_FUNC_DEF(GLhandleARB, glCreateProgramObjectARB, ());
+GL_EXT_FUNC_DEF(void, glAttachObjectARB, (GLhandleARB containerObj, GLhandleARB obj));
+GL_EXT_FUNC_DEF(void, glBindAttribLocationARB, (GLhandleARB programObj, GLuint index, const GLcharARB *name));
+GL_EXT_FUNC_DEF(void, glLinkProgramARB, (GLhandleARB programObj));
+GL_EXT_FUNC_DEF(void, glDetachObjectARB, (GLhandleARB containerObj, GLhandleARB attachedObj));
+GL_EXT_FUNC_DEF(void, glGetObjectParameterivARB, (GLhandleARB obj, GLenum pname, GLint *params));
+GL_EXT_FUNC_DEF(GLint, glGetUniformLocationARB, (GLhandleARB programObj, const GLcharARB *name));
+GL_EXT_FUNC_DEF(void, glGetInfoLogARB, (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog));
+GL_EXT_FUNC_DEF(void, glUseProgramObjectARB, (GLhandleARB programObj));
+GL_EXT_FUNC_DEF(void, glUniformMatrix4fvARB, (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value));
+GL_EXT_FUNC_DEF(void, glUniform1iARB, (GLint location, GLint v0));
+GL_EXT_FUNC_DEF(GLhandleARB, glCreateShaderObjectARB, (GLenum shaderType));
+GL_EXT_FUNC_DEF(void, glShaderSourceARB, (GLhandleARB shaderObj, GLsizei count, const GLcharARB **string, const GLint *length));
+GL_EXT_FUNC_DEF(void, glCompileShaderARB, (GLhandleARB shaderObj));
+GL_EXT_FUNC_DEF(void, glVertexAttribPointerARB, (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer));
+GL_EXT_FUNC_DEF(void, glVertexAttrib4fARB, (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w));
+GL_EXT_FUNC_DEF(void, glEnableVertexAttribArrayARB, (GLuint index));
+#endif
diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index 7078aa8..9203390 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -55,7 +55,7 @@ OpenGLGraphicsManager::OpenGLGraphicsManager()
 #ifdef USE_OSD
       , _osdAlpha(0), _osdFadeStartTime(0), _osd(nullptr)
 #endif
-#if !USE_FORCED_GL && !USE_FORCED_GLES
+#if !USE_FORCED_GLES
       , _shader(nullptr), _projectionMatrix()
 #endif
     {
@@ -70,7 +70,7 @@ OpenGLGraphicsManager::~OpenGLGraphicsManager() {
 #ifdef USE_OSD
 	delete _osd;
 #endif
-#if !USE_FORCED_GL && !USE_FORCED_GLES
+#if !USE_FORCED_GLES
 	delete _shader;
 #endif
 }
@@ -773,7 +773,8 @@ void OpenGLGraphicsManager::setActualScreenSize(uint width, uint height) {
 	};
 
 #if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
-	if (g_context.type != kContextGLES2) {
+	if (g_context.type == kContextGLES
+	    || (g_context.type == kContextGL && !g_context.shadersSupported)) {
 #endif
 #if !USE_FORCED_GLES2
 		GL_CALL(glMatrixMode(GL_PROJECTION));
@@ -785,7 +786,7 @@ void OpenGLGraphicsManager::setActualScreenSize(uint width, uint height) {
 #if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
 	} else {
 #endif
-#if !USE_FORCED_GL && !USE_FORCED_GLES
+#if !USE_FORCED_GLES
 		assert(sizeof(_projectionMatrix) == sizeof(orthoProjection));
 		memcpy(_projectionMatrix, orthoProjection, sizeof(_projectionMatrix));
 		if (_shader) {
@@ -894,23 +895,32 @@ void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &def
 	GL_CALL(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
 
 #if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
-	if (g_context.type != kContextGLES2) {
+	if (g_context.type == kContextGLES2) {
 #endif
-#if !USE_FORCED_GLES2
-		// Enable rendering with vertex and coord arrays.
-		GL_CALL(glEnableClientState(GL_VERTEX_ARRAY));
-		GL_CALL(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
+#if !USE_FORCED_GL && !USE_FORCED_GLES
+		GL_CALL(glEnableVertexAttribArray(kPositionAttribLocation));
+		GL_CALL(glEnableVertexAttribArray(kTexCoordAttribLocation));
 
-		GL_CALL(glEnable(GL_TEXTURE_2D));
+		GL_CALL(glActiveTexture(GL_TEXTURE0));
 #endif
 #if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
 	} else {
 #endif
-#if !USE_FORCED_GL && !USE_FORCED_GLES
-		GL_CALL(glEnableVertexAttribArray(kPositionAttribLocation));
-		GL_CALL(glEnableVertexAttribArray(kTexCoordAttribLocation));
+#if !USE_FORCED_GLES2
+#if !USE_FORCED_GLES
+		if (g_context.shadersSupported) {
+			GL_CALL(glEnableVertexAttribArrayARB(kPositionAttribLocation));
+			GL_CALL(glEnableVertexAttribArrayARB(kTexCoordAttribLocation));
+		} else {
+#endif
+			// Enable rendering with vertex and coord arrays.
+			GL_CALL(glEnableClientState(GL_VERTEX_ARRAY));
+			GL_CALL(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
+#if !USE_FORCED_GLES
+		}
+#endif
 
-		GL_CALL(glActiveTexture(GL_TEXTURE0));
+		GL_CALL(glEnable(GL_TEXTURE_2D));
 #endif
 #if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
 	}
@@ -934,19 +944,33 @@ void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &def
 	// Query information needed by textures.
 	Texture::queryTextureInformation();
 
-#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
-	if (g_context.type == kContextGLES2) {
+#if !USE_FORCED_GLES
+	if (!_shader) {
+#if !USE_FORCED_GL && !USE_FORCED_GLES2
+		if (g_context.type == kContextGLES2) {
 #endif
-#if !USE_FORCED_GL && !USE_FORCED_GLES
-		if (!_shader) {
-			_shader = new Shader(g_defaultVertexShader, g_defaultFragmentShader);
+#if !USE_FORCED_GL
+			_shader = new ShaderGLES2(g_defaultVertexShader, g_defaultFragmentShaderGLES2);
+#endif
+#if !USE_FORCED_GL && !USE_FORCED_GLES2
+		} else {
+#endif
+#if !USE_FORCED_GLES2
+			if (g_context.shadersSupported) {
+				_shader = new ShaderARB(g_defaultVertexShader, g_defaultFragmentShaderGL);
+			}
+#endif
+#if !USE_FORCED_GL && !USE_FORCED_GLES2
 		}
+#endif
+	}
+#endif
 
+#if !USE_FORCED_GLES
+	if (_shader) {
 		// TODO: What do we do on failure?
 		_shader->recreate();
 		_shader->activate(_projectionMatrix);
-#endif
-#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
 	}
 #endif
 
@@ -999,7 +1023,7 @@ void OpenGLGraphicsManager::notifyContextDestroy() {
 	}
 #endif
 
-#if !USE_FORCED_GL && !USE_FORCED_GLES
+#if !USE_FORCED_GLES
 	if (_shader) {
 		_shader->destroy();
 	}
@@ -1080,16 +1104,24 @@ Texture *OpenGLGraphicsManager::createTexture(const Graphics::PixelFormat &forma
 
 void OpenGLGraphicsManager::setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
 #if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
-	if (g_context.type != kContextGLES2) {
+	if (g_context.type == kContextGLES2) {
 #endif
-#if !USE_FORCED_GLES2
-		GL_CALL(glColor4f(r, g, b, a));
+#if !USE_FORCED_GL && !USE_FORCED_GLES
+		GL_CALL(glVertexAttrib4f(kColorAttribLocation, r, g, b, a));
 #endif
 #if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
 	} else {
 #endif
-#if !USE_FORCED_GL && !USE_FORCED_GLES
-		GL_CALL(glVertexAttrib4f(kColorAttribLocation, r, g, b, a));
+#if !USE_FORCED_GLES2
+#if !USE_FORCED_GLES
+		if (g_context.shadersSupported) {
+			GL_CALL(glVertexAttrib4fARB(kColorAttribLocation, r, g, b, a));
+		} else {
+#endif
+			GL_CALL(glColor4f(r, g, b, a));
+#if !USE_FORCED_GLES
+		}
+#endif
 #endif
 #if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
 	}
diff --git a/backends/graphics/opengl/opengl-graphics.h b/backends/graphics/opengl/opengl-graphics.h
index 37ab1f8..55e18cf 100644
--- a/backends/graphics/opengl/opengl-graphics.h
+++ b/backends/graphics/opengl/opengl-graphics.h
@@ -41,7 +41,7 @@ namespace OpenGL {
 #define USE_OSD 1
 
 class Texture;
-#if !USE_FORCED_GL && !USE_FORCED_GLES
+#if !USE_FORCED_GLES
 class Shader;
 #endif
 
@@ -529,7 +529,7 @@ private:
 	 */
 	uint _scissorOverride;
 
-#if !USE_FORCED_GL && !USE_FORCED_GLES
+#if !USE_FORCED_GLES
 	//
 	// Shaders
 	//
diff --git a/backends/graphics/opengl/opengl-sys.h b/backends/graphics/opengl/opengl-sys.h
index ad36226..f8acb93 100644
--- a/backends/graphics/opengl/opengl-sys.h
+++ b/backends/graphics/opengl/opengl-sys.h
@@ -92,6 +92,11 @@ struct Context {
 	/** Whether GL_ARB_texture_non_power_of_two is available or not. */
 	bool NPOTSupported;
 
+#if !USE_FORCED_GLES && !USE_FORCED_GLES2
+	/** Whether shader support is available or not. */
+	bool shadersSupported;
+#endif
+
 #define GL_FUNC_DEF(ret, name, param) ret (GL_CALL_CONV *name)param
 #define GL_EXT_FUNC_DEF GL_FUNC_DEF
 #include "backends/graphics/opengl/opengl-func.h"
diff --git a/backends/graphics/opengl/shader.cpp b/backends/graphics/opengl/shader.cpp
index 6e36307..c28036c 100644
--- a/backends/graphics/opengl/shader.cpp
+++ b/backends/graphics/opengl/shader.cpp
@@ -22,7 +22,7 @@
 
 #include "backends/graphics/opengl/shader.h"
 
-#if !USE_FORCED_GL && !USE_FORCED_GLES
+#if !USE_FORCED_GLES
 
 #include "common/textconsole.h"
 
@@ -44,7 +44,20 @@ const char *const g_defaultVertexShader =
 	"\tgl_Position = projection * position;\n"
 	"}\n";
 
-const char *const g_defaultFragmentShader =
+#if !USE_FORCED_GLES2
+const char *const g_defaultFragmentShaderGL =
+	"varying vec2 texCoord;\n"
+	"varying vec4 blendColor;\n"
+	"\n"
+	"uniform sampler2D texture;\n"
+	"\n"
+	"void main(void) {\n"
+	"\tgl_FragColor = blendColor * texture2D(texture, texCoord);\n"
+	"}\n";
+#endif
+
+#if !USE_FORCED_GL
+const char *const g_defaultFragmentShaderGLES2 =
 	"varying lowp vec2 texCoord;\n"
 	"varying lowp vec4 blendColor;\n"
 	"\n"
@@ -53,17 +66,146 @@ const char *const g_defaultFragmentShader =
 	"void main(void) {\n"
 	"\tgl_FragColor = blendColor * texture2D(texture, texCoord);\n"
 	"}\n";
+#endif
+
+#if !USE_FORCED_GLES2
+
+ShaderARB::ShaderARB(const Common::String &vertex, const Common::String &fragment)
+    : Shader(vertex, fragment), _program(0), _projectionLocation(-1), _textureLocation(-1) {
+}
 
-Shader::Shader(const Common::String &vertex, const Common::String &fragment)
-    : _vertex(vertex), _fragment(fragment), _program(0), _projectionLocation(-1), _textureLocation(-1) {
+void ShaderARB::destroy() {
+	// According to extension specification glDeleteObjectARB silently ignores
+	// 0. However, with nVidia drivers this can cause GL_INVALID_VALUE, thus
+	// we do not call it with 0 as parameter to avoid warnings.
+	if (_program) {
+		GL_CALL(glDeleteObjectARB(_program));
+	}
+	_program = 0;
 }
 
-void Shader::destroy() {
+bool ShaderARB::recreate() {
+	// Make sure any old programs are destroyed properly.
+	destroy();
+
+	GLhandleARB vertexShader = compileShader(_vertex.c_str(), GL_VERTEX_SHADER_ARB);
+	if (!vertexShader) {
+		return false;
+	}
+
+	GLhandleARB fragmentShader = compileShader(_fragment.c_str(), GL_FRAGMENT_SHADER_ARB);
+	if (!fragmentShader) {
+		GL_CALL(glDeleteObjectARB(vertexShader));
+		return false;
+	}
+
+	GL_ASSIGN(_program, glCreateProgramObjectARB());
+	if (!_program) {
+		GL_CALL(glDeleteObjectARB(vertexShader));
+		GL_CALL(glDeleteObjectARB(fragmentShader));
+		return false;
+	}
+
+	GL_CALL(glAttachObjectARB(_program, vertexShader));
+	GL_CALL(glAttachObjectARB(_program, fragmentShader));
+
+	GL_CALL(glBindAttribLocationARB(_program, kPositionAttribLocation, "position"));
+	GL_CALL(glBindAttribLocationARB(_program, kTexCoordAttribLocation, "texCoordIn"));
+	GL_CALL(glBindAttribLocationARB(_program, kColorAttribLocation,    "blendColorIn"));
+
+	GL_CALL(glLinkProgramARB(_program));
+
+	GL_CALL(glDetachObjectARB(_program, fragmentShader));
+	GL_CALL(glDeleteObjectARB(fragmentShader));
+
+	GL_CALL(glDetachObjectARB(_program, vertexShader));
+	GL_CALL(glDeleteObjectARB(vertexShader));
+
+	GLint result;
+	GL_CALL(glGetObjectParameterivARB(_program, GL_OBJECT_LINK_STATUS_ARB, &result));
+	if (result == GL_FALSE) {
+		GLint logSize;
+		GL_CALL(glGetObjectParameterivARB(_program, GL_OBJECT_INFO_LOG_LENGTH_ARB, &logSize));
+
+		GLchar *log = new GLchar[logSize];
+		GL_CALL(glGetInfoLogARB(_program, logSize, nullptr, log));
+		warning("Could not link shader: \"%s\"", log);
+		delete[] log;
+
+		destroy();
+		return false;
+	}
+
+	GL_ASSIGN(_projectionLocation, glGetUniformLocationARB(_program, "projection"));
+	if (_projectionLocation == -1) {
+		warning("Shader misses \"projection\" uniform.");
+		destroy();
+		return false;
+	}
+
+	GL_ASSIGN(_textureLocation, glGetUniformLocationARB(_program, "texture"));
+	if (_textureLocation == -1) {
+		warning("Shader misses \"texture\" uniform.");
+		destroy();
+		return false;
+	}
+
+	return true;
+}
+
+void ShaderARB::activate(const GLfloat *projectionMatrix) {
+	// Activate program.
+	GL_CALL(glUseProgramObjectARB(_program));
+
+	// Set projection matrix.
+	GL_CALL(glUniformMatrix4fvARB(_projectionLocation, 1, GL_FALSE, projectionMatrix));
+
+	// We always use texture unit 0.
+	GL_CALL(glUniform1iARB(_textureLocation, 0));
+}
+
+GLhandleARB ShaderARB::compileShader(const char *source, GLenum shaderType) {
+	GLuint handle;
+	GL_ASSIGN(handle, glCreateShaderObjectARB(shaderType));
+	if (!handle) {
+		return 0;
+	}
+
+	GL_CALL(glShaderSourceARB(handle, 1, &source, nullptr));
+	GL_CALL(glCompileShaderARB(handle));
+
+	GLint result;
+	GL_CALL(glGetObjectParameterivARB(handle, GL_OBJECT_COMPILE_STATUS_ARB, &result));
+	if (result == GL_FALSE) {
+		GLint logSize;
+		GL_CALL(glGetObjectParameterivARB(handle, GL_OBJECT_INFO_LOG_LENGTH_ARB, &logSize));
+
+		GLchar *log = new GLchar[logSize];
+		GL_CALL(glGetInfoLogARB(handle, logSize, nullptr, log));
+		warning("Could not compile shader \"%s\": \"%s\"", source, log);
+		delete[] log;
+
+		GL_CALL(glDeleteObjectARB(handle));
+		return 0;
+	}
+
+	return handle;
+}
+
+#endif // !USE_FORCED_GLES2
+
+#if !USE_FORCED_GL
+
+ShaderGLES2::ShaderGLES2(const Common::String &vertex, const Common::String &fragment)
+    : Shader(vertex, fragment), _program(0), _projectionLocation(-1), _textureLocation(-1) {
+}
+
+void ShaderGLES2::destroy() {
 	GL_CALL(glDeleteProgram(_program));
 	_program = 0;
 }
 
-bool Shader::recreate() {
+bool ShaderGLES2::recreate() {
 	// Make sure any old programs are destroyed properly.
 	destroy();
 
@@ -132,7 +274,7 @@ bool Shader::recreate() {
 	return true;
 }
 
-void Shader::activate(const GLfloat *projectionMatrix) {
+void ShaderGLES2::activate(const GLfloat *projectionMatrix) {
 	// Activate program.
 	GL_CALL(glUseProgram(_program));
 
@@ -143,7 +285,7 @@ void Shader::activate(const GLfloat *projectionMatrix) {
 	GL_CALL(glUniform1i(_textureLocation, 0));
 }
 
-GLuint Shader::compileShader(const char *source, GLenum shaderType) {
+GLuint ShaderGLES2::compileShader(const char *source, GLenum shaderType) {
 	GLuint handle;
 	GL_ASSIGN(handle, glCreateShader(shaderType));
 	if (!handle) {
@@ -171,6 +313,8 @@ GLuint Shader::compileShader(const char *source, GLenum shaderType) {
 	return handle;
 }
 
+#endif // !!USE_FORCED_GL
+
 } // End of namespace OpenGL
 
-#endif // !USE_FORCED_GL && !USE_FORCED_GLES
+#endif // !USE_FORCED_GLES
diff --git a/backends/graphics/opengl/shader.h b/backends/graphics/opengl/shader.h
index e8535e0..8c457f8 100644
--- a/backends/graphics/opengl/shader.h
+++ b/backends/graphics/opengl/shader.h
@@ -25,7 +25,7 @@
 
 #include "backends/graphics/opengl/opengl-sys.h"
 
-#if !USE_FORCED_GL && !USE_FORCED_GLES
+#if !USE_FORCED_GLES
 
 #include "common/str.h"
 
@@ -38,12 +38,18 @@ enum {
 };
 
 extern const char *const g_defaultVertexShader;
-extern const char *const g_defaultFragmentShader;
+#if !USE_FORCED_GLES2
+extern const char *const g_defaultFragmentShaderGL;
+#endif
+#if !USE_FORCED_GL
+extern const char *const g_defaultFragmentShaderGLES2;
+#endif
 
 class Shader {
 public:
-	Shader(const Common::String &vertex, const Common::String &fragment);
-	~Shader() { destroy(); }
+	Shader(const Common::String &vertex, const Common::String &fragment)
+	    : _vertex(vertex), _fragment(fragment) {}
+	virtual ~Shader() {}
 
 	/**
 	 * Destroy the shader program.
@@ -51,22 +57,22 @@ public:
 	 * This keeps the vertex and fragment shader sources around and thus
 	 * allows for recreating the shader on context recreation.
 	 */
-	void destroy();
+	virtual void destroy() = 0;
 
 	/**
 	 * Recreate shader program.
 	 *
 	 * @return true on success, false on failure.
 	 */
-	bool recreate();
+	virtual bool recreate() = 0;
 
 	/**
 	 * Make shader active.
 	 *
 	 * @param projectionMatrix Projection matrix to use.
 	 */
-	void activate(const GLfloat *projectionMatrix);
-private:
+	virtual void activate(const GLfloat *projectionMatrix) = 0;
+protected:
 	/**
 	 * Vertex shader sources.
 	 */
@@ -76,7 +82,59 @@ private:
 	 * Fragment shader sources.
 	 */
 	const Common::String _fragment;
+};
+
+#if !USE_FORCED_GLES2
+class ShaderARB : public Shader {
+public:
+	ShaderARB(const Common::String &vertex, const Common::String &fragment);
+	virtual ~ShaderARB() { destroy(); }
+
+	virtual void destroy();
+
+	virtual bool recreate();
 
+	virtual void activate(const GLfloat *projectionMatrix);
+private:
+	/**
+	 * Shader program handle.
+	 */
+	GLhandleARB _program;
+
+	/**
+	 * Location of the matrix uniform in the shader program.
+	 */
+	GLint _projectionLocation;
+
+	/**
+	 * Location of the texture sampler location in the shader program.
+	 */
+	GLint _textureLocation;
+
+	/**
+	 * Compile a vertex or fragment shader.
+	 *
+	 * @param source     Sources to the shader.
+	 * @param shaderType Type of shader to compile (GL_FRAGMENT_SHADER_ARB or
+	 *                   GL_VERTEX_SHADER_ARB)
+	 * @return The shader object or 0 on failure.
+	 */
+	static GLhandleARB compileShader(const char *source, GLenum shaderType);
+};
+#endif // !USE_FORCED_GLES2
+
+#if !USE_FORCED_GL
+class ShaderGLES2 : public Shader {
+public:
+	ShaderGLES2(const Common::String &vertex, const Common::String &fragment);
+	virtual ~ShaderGLES2() { destroy(); }
+
+	virtual void destroy();
+
+	virtual bool recreate();
+
+	virtual void activate(const GLfloat *projectionMatrix);
+private:
 	/**
 	 * Shader program handle.
 	 */
@@ -102,9 +160,10 @@ private:
 	 */
 	static GLuint compileShader(const char *source, GLenum shaderType);
 };
+#endif
 
 } // End of namespace OpenGL
 
-#endif // !USE_FORCED_GL && !USE_FORCED_GLES
+#endif // !USE_FORCED_GLES
 
 #endif
diff --git a/backends/graphics/opengl/texture.cpp b/backends/graphics/opengl/texture.cpp
index c8c38ed..0b01430 100644
--- a/backends/graphics/opengl/texture.cpp
+++ b/backends/graphics/opengl/texture.cpp
@@ -196,18 +196,27 @@ void Texture::draw(GLfloat x, GLfloat y, GLfloat w, GLfloat h) {
 	};
 
 #if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
-	if (g_context.type != kContextGLES2) {
+	if (g_context.type == kContextGLES2) {
 #endif
-#if !USE_FORCED_GLES2
-		GL_CALL(glTexCoordPointer(2, GL_FLOAT, 0, texcoords));
-		GL_CALL(glVertexPointer(2, GL_FLOAT, 0, vertices));
+#if !USE_FORCED_GL && !USE_FORCED_GLES
+		GL_CALL(glVertexAttribPointer(kTexCoordAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, texcoords));
+		GL_CALL(glVertexAttribPointer(kPositionAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, vertices));
 #endif
 #if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
 	} else {
 #endif
-#if !USE_FORCED_GL && !USE_FORCED_GLES
-		GL_CALL(glVertexAttribPointer(kTexCoordAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, texcoords));
-		GL_CALL(glVertexAttribPointer(kPositionAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, vertices));
+#if !USE_FORCED_GLES2
+#if !USE_FORCED_GLES
+		if (g_context.shadersSupported) {
+			GL_CALL(glVertexAttribPointerARB(kTexCoordAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, texcoords));
+			GL_CALL(glVertexAttribPointerARB(kPositionAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, vertices));
+		} else {
+#endif
+			GL_CALL(glTexCoordPointer(2, GL_FLOAT, 0, texcoords));
+			GL_CALL(glVertexPointer(2, GL_FLOAT, 0, vertices));
+#if !USE_FORCED_GLES
+		}
+#endif
 #endif
 #if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
 	}


Commit: d029f167996f3328ac278829802d9c1a32c620e2
    https://github.com/scummvm/scummvm/commit/d029f167996f3328ac278829802d9c1a32c620e2
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:25+01:00

Commit Message:
OPENGL: Handle destruction gracefully when no context is setup.

Changed paths:
    backends/graphics/opengl/opengl-sys.h
    backends/graphics/opengl/shader.cpp
    backends/graphics/opengl/shader.h
    backends/graphics/opengl/texture.cpp



diff --git a/backends/graphics/opengl/opengl-sys.h b/backends/graphics/opengl/opengl-sys.h
index f8acb93..dabd6ad 100644
--- a/backends/graphics/opengl/opengl-sys.h
+++ b/backends/graphics/opengl/opengl-sys.h
@@ -111,7 +111,13 @@ extern Context g_context;
 
 } // End of namespace OpenGL
 
-#define GL_CALL(x)        GL_WRAP_DEBUG(g_context.x, x)
-#define GL_ASSIGN(var, x) GL_WRAP_DEBUG(var = g_context.x, x)
+#define GL_CALL(x)                 GL_WRAP_DEBUG(g_context.x, x)
+#define GL_CALL_SAFE(func, params) \
+	do { \
+		if (g_context.func) { \
+			GL_CALL(func params); \
+		} \
+	} while (0)
+#define GL_ASSIGN(var, x)          GL_WRAP_DEBUG(var = g_context.x, x)
 
 #endif
diff --git a/backends/graphics/opengl/shader.cpp b/backends/graphics/opengl/shader.cpp
index c28036c..d7fc205 100644
--- a/backends/graphics/opengl/shader.cpp
+++ b/backends/graphics/opengl/shader.cpp
@@ -74,6 +74,15 @@ ShaderARB::ShaderARB(const Common::String &vertex, const Common::String &fragmen
     : Shader(vertex, fragment), _program(0), _projectionLocation(-1), _textureLocation(-1) {
 }
 
+ShaderARB::~ShaderARB() {
+	// According to extension specification glDeleteObjectARB silently ignores
+	// 0. However, with nVidia drivers this can cause GL_INVALID_VALUE, thus
+	// we do not call it with 0 as parameter to avoid warnings.
+	if (_program) {
+		GL_CALL_SAFE(glDeleteObjectARB, (_program));
+	}
+}
+
 void ShaderARB::destroy() {
 	// According to extension specification glDeleteObjectARB silently ignores
 	// 0. However, with nVidia drivers this can cause GL_INVALID_VALUE, thus
@@ -200,6 +209,10 @@ ShaderGLES2::ShaderGLES2(const Common::String &vertex, const Common::String &fra
     : Shader(vertex, fragment), _program(0), _projectionLocation(-1), _textureLocation(-1) {
 }
 
+ShaderGLES2::~ShaderGLES2() {
+	GL_CALL_SAFE(glDeleteProgram, (_program));
+}
+
 void ShaderGLES2::destroy() {
 	GL_CALL(glDeleteProgram(_program));
 	_program = 0;
diff --git a/backends/graphics/opengl/shader.h b/backends/graphics/opengl/shader.h
index 8c457f8..60a4302 100644
--- a/backends/graphics/opengl/shader.h
+++ b/backends/graphics/opengl/shader.h
@@ -88,7 +88,7 @@ protected:
 class ShaderARB : public Shader {
 public:
 	ShaderARB(const Common::String &vertex, const Common::String &fragment);
-	virtual ~ShaderARB() { destroy(); }
+	virtual ~ShaderARB();
 
 	virtual void destroy();
 
@@ -127,7 +127,7 @@ private:
 class ShaderGLES2 : public Shader {
 public:
 	ShaderGLES2(const Common::String &vertex, const Common::String &fragment);
-	virtual ~ShaderGLES2() { destroy(); }
+	virtual ~ShaderGLES2();
 
 	virtual void destroy();
 
diff --git a/backends/graphics/opengl/texture.cpp b/backends/graphics/opengl/texture.cpp
index 0b01430..e394f76 100644
--- a/backends/graphics/opengl/texture.cpp
+++ b/backends/graphics/opengl/texture.cpp
@@ -54,7 +54,7 @@ Texture::Texture(GLenum glIntFormat, GLenum glFormat, GLenum glType, const Graph
 }
 
 Texture::~Texture() {
-	releaseInternalTexture();
+	GL_CALL_SAFE(glDeleteTextures, (1, &_glTexture));
 	_textureData.free();
 }
 


Commit: b7e64c6eebd08f0f95c270a2f1f3fc78a12ce764
    https://github.com/scummvm/scummvm/commit/b7e64c6eebd08f0f95c270a2f1f3fc78a12ce764
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:25+01:00

Commit Message:
OPENGLSDL: Destroy GL context on exit with SDL2.

Changed paths:
    backends/graphics/openglsdl/openglsdl-graphics.cpp



diff --git a/backends/graphics/openglsdl/openglsdl-graphics.cpp b/backends/graphics/openglsdl/openglsdl-graphics.cpp
index f2af7cc..2171b95 100644
--- a/backends/graphics/openglsdl/openglsdl-graphics.cpp
+++ b/backends/graphics/openglsdl/openglsdl-graphics.cpp
@@ -194,6 +194,10 @@ OpenGLSdlGraphicsManager::OpenGLSdlGraphicsManager(uint desktopWidth, uint deskt
 }
 
 OpenGLSdlGraphicsManager::~OpenGLSdlGraphicsManager() {
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+	notifyContextDestroy();
+	SDL_GL_DeleteContext(_glContext);
+#endif
 }
 
 void OpenGLSdlGraphicsManager::activateManager() {


Commit: 1802c939a1a46d89df05cae5e30e2014646e30fa
    https://github.com/scummvm/scummvm/commit/1802c939a1a46d89df05cae5e30e2014646e30fa
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:25+01:00

Commit Message:
OPENGL: Slight simplifcation for opengl-func.h usage.

Changed paths:
    backends/graphics/opengl/opengl-func.h
    backends/graphics/opengl/opengl-sys.h



diff --git a/backends/graphics/opengl/opengl-func.h b/backends/graphics/opengl/opengl-func.h
index d022d00..f870214 100644
--- a/backends/graphics/opengl/opengl-func.h
+++ b/backends/graphics/opengl/opengl-func.h
@@ -63,6 +63,11 @@
  * GL_EXT_FUNC_DEF: Define an OpenGL (ES) extension function.
  */
 
+#if !defined(GL_EXT_FUNC_DEF)
+#define GL_EXT_FUNC_DEF(ret, name, param) GL_FUNC_DEF(ret, name, param)
+#define DEFINED_GL_EXT_FUNC_DEF
+#endif
+
 GL_FUNC_DEF(void, glEnable, (GLenum cap));
 GL_FUNC_DEF(void, glDisable, (GLenum cap));
 GL_FUNC_DEF(void, glClear, (GLbitfield mask));
@@ -137,3 +142,8 @@ GL_EXT_FUNC_DEF(void, glVertexAttribPointerARB, (GLuint index, GLint size, GLenu
 GL_EXT_FUNC_DEF(void, glVertexAttrib4fARB, (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w));
 GL_EXT_FUNC_DEF(void, glEnableVertexAttribArrayARB, (GLuint index));
 #endif
+
+#ifdef DEFINED_GL_EXT_FUNC_DEF
+#undef DEFINED_GL_EXT_FUNC_DEF
+#undef GL_EXT_FUNC_DEF
+#endif
diff --git a/backends/graphics/opengl/opengl-sys.h b/backends/graphics/opengl/opengl-sys.h
index dabd6ad..6da1850 100644
--- a/backends/graphics/opengl/opengl-sys.h
+++ b/backends/graphics/opengl/opengl-sys.h
@@ -98,9 +98,7 @@ struct Context {
 #endif
 
 #define GL_FUNC_DEF(ret, name, param) ret (GL_CALL_CONV *name)param
-#define GL_EXT_FUNC_DEF GL_FUNC_DEF
 #include "backends/graphics/opengl/opengl-func.h"
-#undef GL_EXT_FUNC_DEF
 #undef GL_FUNC_DEF
 };
 


Commit: 5752f125e1a0d334c3a5bfcea314c4ffceede640
    https://github.com/scummvm/scummvm/commit/5752f125e1a0d334c3a5bfcea314c4ffceede640
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:25+01:00

Commit Message:
OPENGL: Make Context::reset explicitly reset state.

Changed paths:
    backends/graphics/opengl/context.cpp
    backends/graphics/opengl/opengl-graphics.cpp
    backends/graphics/opengl/opengl-sys.h



diff --git a/backends/graphics/opengl/context.cpp b/backends/graphics/opengl/context.cpp
index 618be07..a58a5e0 100644
--- a/backends/graphics/opengl/context.cpp
+++ b/backends/graphics/opengl/context.cpp
@@ -27,14 +27,15 @@
 
 namespace OpenGL {
 
-void Context::reset(bool full) {
-	// GLES supports least features, thus we initialize the context type
-	// to this on full reset.
-	const ContextType savedType = full ? kContextGLES : type;
-
-	memset(this, 0, sizeof(Context));
+void Context::reset() {
+	NPOTSupported = false;
+#if !USE_FORCED_GLES && !USE_FORCED_GLES2
+	shadersSupported = false;
+#endif
 
-	type = savedType;
+#define GL_FUNC_DEF(ret, name, param) name = nullptr;
+#include "backends/graphics/opengl/opengl-func.h"
+#undef GL_FUNC_DEF
 }
 
 Context g_context;
diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index 9203390..624a556 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -60,7 +60,7 @@ OpenGLGraphicsManager::OpenGLGraphicsManager()
 #endif
     {
 	memset(_gamePalette, 0, sizeof(_gamePalette));
-	g_context.reset(true);
+	g_context.reset();
 }
 
 OpenGLGraphicsManager::~OpenGLGraphicsManager() {
diff --git a/backends/graphics/opengl/opengl-sys.h b/backends/graphics/opengl/opengl-sys.h
index 6da1850..239512b 100644
--- a/backends/graphics/opengl/opengl-sys.h
+++ b/backends/graphics/opengl/opengl-sys.h
@@ -85,9 +85,10 @@ struct Context {
 	/**
 	 * Reset context.
 	 *
-	 * This marks all extensions as unavailable.
+	 * This marks all extensions as unavailable and clears all function
+	 * pointers.
 	 */
-	void reset(bool full = false);
+	void reset();
 
 	/** Whether GL_ARB_texture_non_power_of_two is available or not. */
 	bool NPOTSupported;


Commit: c7c870bf7f269229d069d47c22b61c237737cdae
    https://github.com/scummvm/scummvm/commit/c7c870bf7f269229d069d47c22b61c237737cdae
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:25+01:00

Commit Message:
OPENGL: (Partly) move context specific handling to Context.

This does not include (most) shader setup, and projection matrices yet.

Changed paths:
    backends/graphics/opengl/context.cpp
    backends/graphics/opengl/opengl-graphics.cpp
    backends/graphics/opengl/opengl-graphics.h
    backends/graphics/opengl/opengl-sys.h
    backends/graphics/opengl/texture.cpp



diff --git a/backends/graphics/opengl/context.cpp b/backends/graphics/opengl/context.cpp
index a58a5e0..905532c 100644
--- a/backends/graphics/opengl/context.cpp
+++ b/backends/graphics/opengl/context.cpp
@@ -22,6 +22,7 @@
 
 #include "backends/graphics/opengl/opengl-sys.h"
 #include "backends/graphics/opengl/opengl-graphics.h"
+#include "backends/graphics/opengl/shader.h"
 
 #include "common/tokenizer.h"
 
@@ -38,6 +39,108 @@ void Context::reset() {
 #undef GL_FUNC_DEF
 }
 
+void Context::initializePipeline() {
+#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
+	if (g_context.type != kContextGLES2) {
+#endif
+#if !USE_FORCED_GLES2
+		GL_CALL(glDisable(GL_LIGHTING));
+		GL_CALL(glDisable(GL_FOG));
+		GL_CALL(glShadeModel(GL_FLAT));
+		GL_CALL(glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST));
+#endif
+#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
+	}
+#endif
+
+#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
+	if (g_context.type == kContextGLES2) {
+#endif
+#if !USE_FORCED_GL && !USE_FORCED_GLES
+		GL_CALL(glEnableVertexAttribArray(kPositionAttribLocation));
+		GL_CALL(glEnableVertexAttribArray(kTexCoordAttribLocation));
+
+		GL_CALL(glActiveTexture(GL_TEXTURE0));
+#endif
+#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
+	} else {
+#endif
+#if !USE_FORCED_GLES2
+#if !USE_FORCED_GLES
+		if (g_context.shadersSupported) {
+			GL_CALL(glEnableVertexAttribArrayARB(kPositionAttribLocation));
+			GL_CALL(glEnableVertexAttribArrayARB(kTexCoordAttribLocation));
+		} else {
+#endif
+			// Enable rendering with vertex and coord arrays.
+			GL_CALL(glEnableClientState(GL_VERTEX_ARRAY));
+			GL_CALL(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
+#if !USE_FORCED_GLES
+		}
+#endif
+
+		GL_CALL(glEnable(GL_TEXTURE_2D));
+#endif
+#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
+	}
+#endif
+}
+
+void Context::setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
+#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
+	if (g_context.type == kContextGLES2) {
+#endif
+#if !USE_FORCED_GL && !USE_FORCED_GLES
+		GL_CALL(glVertexAttrib4f(kColorAttribLocation, r, g, b, a));
+#endif
+#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
+	} else {
+#endif
+#if !USE_FORCED_GLES2
+#if !USE_FORCED_GLES
+		if (g_context.shadersSupported) {
+			GL_CALL(glVertexAttrib4fARB(kColorAttribLocation, r, g, b, a));
+		} else {
+#endif
+			GL_CALL(glColor4f(r, g, b, a));
+#if !USE_FORCED_GLES
+		}
+#endif
+#endif
+#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
+	}
+#endif
+}
+
+void Context::setDrawCoordinates(const GLfloat *vertices, const GLfloat *texCoords) {
+#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
+	if (g_context.type == kContextGLES2) {
+#endif
+#if !USE_FORCED_GL && !USE_FORCED_GLES
+		GL_CALL(glVertexAttribPointer(kTexCoordAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, texCoords));
+		GL_CALL(glVertexAttribPointer(kPositionAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, vertices));
+#endif
+#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
+	} else {
+#endif
+#if !USE_FORCED_GLES2
+#if !USE_FORCED_GLES
+		if (g_context.shadersSupported) {
+			GL_CALL(glVertexAttribPointerARB(kTexCoordAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, texCoords));
+			GL_CALL(glVertexAttribPointerARB(kPositionAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, vertices));
+		} else {
+#endif
+			GL_CALL(glTexCoordPointer(2, GL_FLOAT, 0, texCoords));
+			GL_CALL(glVertexPointer(2, GL_FLOAT, 0, vertices));
+#if !USE_FORCED_GLES
+		}
+#endif
+#endif
+#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
+	}
+#endif
+}
+
 Context g_context;
 
 void OpenGLGraphicsManager::setContextType(ContextType type) {
diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index 624a556..6d693a3 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -425,13 +425,13 @@ void OpenGLGraphicsManager::updateScreen() {
 		}
 
 		// Set the OSD transparency.
-		setColor(1.0f, 1.0f, 1.0f, _osdAlpha / 100.0f);
+		g_context.setColor(1.0f, 1.0f, 1.0f, _osdAlpha / 100.0f);
 
 		// Draw the OSD texture.
 		_osd->draw(0, 0, _outputScreenWidth, _outputScreenHeight);
 
 		// Reset color.
-		setColor(1.0f, 1.0f, 1.0f, 1.0f);
+		g_context.setColor(1.0f, 1.0f, 1.0f, 1.0f);
 	}
 #endif
 
@@ -873,58 +873,16 @@ void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &def
 	GL_CALL(glDisable(GL_DEPTH_TEST));
 	GL_CALL(glDisable(GL_DITHER));
 
-#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
-	if (g_context.type != kContextGLES2) {
-#endif
-#if !USE_FORCED_GLES2
-		GL_CALL(glDisable(GL_LIGHTING));
-		GL_CALL(glDisable(GL_FOG));
-		GL_CALL(glShadeModel(GL_FLAT));
-		GL_CALL(glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST));
-#endif
-#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
-	}
-#endif
-
 	// Default to black as clear color.
 	GL_CALL(glClearColor(0.0f, 0.0f, 0.0f, 0.0f));
-	setColor(1.0f, 1.0f, 1.0f, 1.0f);
+	g_context.setColor(1.0f, 1.0f, 1.0f, 1.0f);
 
 	// Setup alpha blend (for overlay and cursor).
 	GL_CALL(glEnable(GL_BLEND));
 	GL_CALL(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
 
-#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
-	if (g_context.type == kContextGLES2) {
-#endif
-#if !USE_FORCED_GL && !USE_FORCED_GLES
-		GL_CALL(glEnableVertexAttribArray(kPositionAttribLocation));
-		GL_CALL(glEnableVertexAttribArray(kTexCoordAttribLocation));
-
-		GL_CALL(glActiveTexture(GL_TEXTURE0));
-#endif
-#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
-	} else {
-#endif
-#if !USE_FORCED_GLES2
-#if !USE_FORCED_GLES
-		if (g_context.shadersSupported) {
-			GL_CALL(glEnableVertexAttribArrayARB(kPositionAttribLocation));
-			GL_CALL(glEnableVertexAttribArrayARB(kTexCoordAttribLocation));
-		} else {
-#endif
-			// Enable rendering with vertex and coord arrays.
-			GL_CALL(glEnableClientState(GL_VERTEX_ARRAY));
-			GL_CALL(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
-#if !USE_FORCED_GLES
-		}
-#endif
-
-		GL_CALL(glEnable(GL_TEXTURE_2D));
-#endif
-#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
-	}
-#endif
+	// Initialize the context specific state of the pipeline.
+	g_context.initializePipeline();
 
 	// Setup scissor state accordingly.
 	if (_overlayVisible) {
@@ -1102,32 +1060,6 @@ Texture *OpenGLGraphicsManager::createTexture(const Graphics::PixelFormat &forma
 	}
 }
 
-void OpenGLGraphicsManager::setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
-#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
-	if (g_context.type == kContextGLES2) {
-#endif
-#if !USE_FORCED_GL && !USE_FORCED_GLES
-		GL_CALL(glVertexAttrib4f(kColorAttribLocation, r, g, b, a));
-#endif
-#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
-	} else {
-#endif
-#if !USE_FORCED_GLES2
-#if !USE_FORCED_GLES
-		if (g_context.shadersSupported) {
-			GL_CALL(glVertexAttrib4fARB(kColorAttribLocation, r, g, b, a));
-		} else {
-#endif
-			GL_CALL(glColor4f(r, g, b, a));
-#if !USE_FORCED_GLES
-		}
-#endif
-#endif
-#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
-	}
-#endif
-}
-
 bool OpenGLGraphicsManager::getGLPixelFormat(const Graphics::PixelFormat &pixelFormat, GLenum &glIntFormat, GLenum &glFormat, GLenum &glType) const {
 #ifdef SCUMM_LITTLE_ENDIAN
 	if (pixelFormat == Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24)) { // ABGR8888
diff --git a/backends/graphics/opengl/opengl-graphics.h b/backends/graphics/opengl/opengl-graphics.h
index 55e18cf..b6e3c13 100644
--- a/backends/graphics/opengl/opengl-graphics.h
+++ b/backends/graphics/opengl/opengl-graphics.h
@@ -303,14 +303,6 @@ private:
 	 */
 	void initializeGLContext();
 
-	/**
-	 * Set color which shall be multiplied with each pixel.
-	 *
-	 * This serves as a wrapper around glColor4f for fixed-function and our
-	 * shader pipeline.
-	 */
-	void setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
-
 protected:
 	/**
 	 * Query the address of an OpenGL function by name.
diff --git a/backends/graphics/opengl/opengl-sys.h b/backends/graphics/opengl/opengl-sys.h
index 239512b..bae318f 100644
--- a/backends/graphics/opengl/opengl-sys.h
+++ b/backends/graphics/opengl/opengl-sys.h
@@ -101,6 +101,26 @@ struct Context {
 #define GL_FUNC_DEF(ret, name, param) ret (GL_CALL_CONV *name)param
 #include "backends/graphics/opengl/opengl-func.h"
 #undef GL_FUNC_DEF
+
+	//
+	// Wrapper functionality to handle fixed-function pipelines and
+	// programmable pipelines in the same fashion.
+	//
+
+	/**
+	 * Initializes the pipeline state.
+	 */
+	void initializePipeline();
+
+	/**
+	 * Set color which shall be multiplied with each pixel.
+	 */
+	void setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
+
+	/**
+	 * Set vertex and texture coordinates.
+	 */
+	void setDrawCoordinates(const GLfloat *vertices, const GLfloat *texCoords);
 };
 
 /**
diff --git a/backends/graphics/opengl/texture.cpp b/backends/graphics/opengl/texture.cpp
index e394f76..08f5e69 100644
--- a/backends/graphics/opengl/texture.cpp
+++ b/backends/graphics/opengl/texture.cpp
@@ -195,32 +195,8 @@ void Texture::draw(GLfloat x, GLfloat y, GLfloat w, GLfloat h) {
 		x + w, y + h
 	};
 
-#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
-	if (g_context.type == kContextGLES2) {
-#endif
-#if !USE_FORCED_GL && !USE_FORCED_GLES
-		GL_CALL(glVertexAttribPointer(kTexCoordAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, texcoords));
-		GL_CALL(glVertexAttribPointer(kPositionAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, vertices));
-#endif
-#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
-	} else {
-#endif
-#if !USE_FORCED_GLES2
-#if !USE_FORCED_GLES
-		if (g_context.shadersSupported) {
-			GL_CALL(glVertexAttribPointerARB(kTexCoordAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, texcoords));
-			GL_CALL(glVertexAttribPointerARB(kPositionAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, vertices));
-		} else {
-#endif
-			GL_CALL(glTexCoordPointer(2, GL_FLOAT, 0, texcoords));
-			GL_CALL(glVertexPointer(2, GL_FLOAT, 0, vertices));
-#if !USE_FORCED_GLES
-		}
-#endif
-#endif
-#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
-	}
-#endif
+	// Setup coordinates for drawing.
+	g_context.setDrawCoordinates(vertices, texcoords);
 
 	// Draw the texture to the screen buffer.
 	GL_CALL(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));


Commit: fc52f730506422ac99e44cd74f229e6a0c5c2121
    https://github.com/scummvm/scummvm/commit/fc52f730506422ac99e44cd74f229e6a0c5c2121
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:25+01:00

Commit Message:
OPENGL: Slightly cleanup programmable pipeline handling.

Changed paths:
    backends/graphics/opengl/context.cpp
    backends/graphics/opengl/opengl-func.h
    backends/graphics/opengl/shader.cpp



diff --git a/backends/graphics/opengl/context.cpp b/backends/graphics/opengl/context.cpp
index 905532c..2da4cab 100644
--- a/backends/graphics/opengl/context.cpp
+++ b/backends/graphics/opengl/context.cpp
@@ -28,6 +28,16 @@
 
 namespace OpenGL {
 
+#if USE_FORCED_GL
+#define HAS_SHADERS_CHECK shadersSupported
+#elif USE_FORCED_GLES
+#define HAS_SHADERS_CHECK false
+#elif USE_FORCED_GLES2
+#define HAS_SHADERS_CHECK true
+#else
+#define HAS_SHADERS_CHECK (type == kContextGLES2 || shadersSupported)
+#endif
+
 void Context::reset() {
 	NPOTSupported = false;
 #if !USE_FORCED_GLES && !USE_FORCED_GLES2
@@ -53,32 +63,35 @@ void Context::initializePipeline() {
 	}
 #endif
 
-#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
-	if (g_context.type == kContextGLES2) {
+	// Enable rendering with vertex and coord arrays.
+#if !USE_FORCED_GLES && !USE_FORCED_GLES2
+	if (HAS_SHADERS_CHECK) {
 #endif
-#if !USE_FORCED_GL && !USE_FORCED_GLES
+#if !USE_FORCED_GLES
 		GL_CALL(glEnableVertexAttribArray(kPositionAttribLocation));
 		GL_CALL(glEnableVertexAttribArray(kTexCoordAttribLocation));
+#endif
+#if !USE_FORCED_GLES && !USE_FORCED_GLES2
+	} else {
+#endif
+#if !USE_FORCED_GLES2
+		GL_CALL(glEnableClientState(GL_VERTEX_ARRAY));
+		GL_CALL(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
+#endif
+#if !USE_FORCED_GLES && !USE_FORCED_GLES2
+	}
+#endif
 
+#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
+	if (g_context.type == kContextGLES2) {
+#endif
+#if !USE_FORCED_GL && !USE_FORCED_GLES
 		GL_CALL(glActiveTexture(GL_TEXTURE0));
 #endif
 #if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
 	} else {
 #endif
 #if !USE_FORCED_GLES2
-#if !USE_FORCED_GLES
-		if (g_context.shadersSupported) {
-			GL_CALL(glEnableVertexAttribArrayARB(kPositionAttribLocation));
-			GL_CALL(glEnableVertexAttribArrayARB(kTexCoordAttribLocation));
-		} else {
-#endif
-			// Enable rendering with vertex and coord arrays.
-			GL_CALL(glEnableClientState(GL_VERTEX_ARRAY));
-			GL_CALL(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
-#if !USE_FORCED_GLES
-		}
-#endif
-
 		GL_CALL(glEnable(GL_TEXTURE_2D));
 #endif
 #if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
@@ -87,56 +100,39 @@ void Context::initializePipeline() {
 }
 
 void Context::setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
-#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
-	if (g_context.type == kContextGLES2) {
+#if !USE_FORCED_GLES && !USE_FORCED_GLES2
+	if (HAS_SHADERS_CHECK) {
 #endif
-#if !USE_FORCED_GL && !USE_FORCED_GLES
+#if !USE_FORCED_GLES
 		GL_CALL(glVertexAttrib4f(kColorAttribLocation, r, g, b, a));
 #endif
-#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
+#if !USE_FORCED_GLES && !USE_FORCED_GLES2
 	} else {
 #endif
 #if !USE_FORCED_GLES2
-#if !USE_FORCED_GLES
-		if (g_context.shadersSupported) {
-			GL_CALL(glVertexAttrib4fARB(kColorAttribLocation, r, g, b, a));
-		} else {
-#endif
-			GL_CALL(glColor4f(r, g, b, a));
-#if !USE_FORCED_GLES
-		}
+		GL_CALL(glColor4f(r, g, b, a));
 #endif
-#endif
-#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
+#if !USE_FORCED_GLES && !USE_FORCED_GLES2
 	}
 #endif
 }
 
 void Context::setDrawCoordinates(const GLfloat *vertices, const GLfloat *texCoords) {
-#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
-	if (g_context.type == kContextGLES2) {
+#if !USE_FORCED_GLES && !USE_FORCED_GLES2
+	if (HAS_SHADERS_CHECK) {
 #endif
-#if !USE_FORCED_GL && !USE_FORCED_GLES
+#if !USE_FORCED_GLES
 		GL_CALL(glVertexAttribPointer(kTexCoordAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, texCoords));
 		GL_CALL(glVertexAttribPointer(kPositionAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, vertices));
 #endif
-#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
+#if !USE_FORCED_GLES && !USE_FORCED_GLES2
 	} else {
 #endif
 #if !USE_FORCED_GLES2
-#if !USE_FORCED_GLES
-		if (g_context.shadersSupported) {
-			GL_CALL(glVertexAttribPointerARB(kTexCoordAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, texCoords));
-			GL_CALL(glVertexAttribPointerARB(kPositionAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, vertices));
-		} else {
-#endif
-			GL_CALL(glTexCoordPointer(2, GL_FLOAT, 0, texCoords));
-			GL_CALL(glVertexPointer(2, GL_FLOAT, 0, vertices));
-#if !USE_FORCED_GLES
-		}
+		GL_CALL(glTexCoordPointer(2, GL_FLOAT, 0, texCoords));
+		GL_CALL(glVertexPointer(2, GL_FLOAT, 0, vertices));
 #endif
-#endif
-#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
+#if !USE_FORCED_GLES && !USE_FORCED_GLES2
 	}
 #endif
 }
@@ -164,17 +160,30 @@ void OpenGLGraphicsManager::initializeGLContext() {
 	// See backends/plugins/sdl/sdl-provider.cpp for more information.
 	assert(sizeof(void (*)()) == sizeof(void *));
 	void *fn = nullptr;
-#define GL_EXT_FUNC_DEF(ret, name, param) \
-	fn = getProcAddress(#name); \
+
+#define LOAD_FUNC(name, loadName) \
+	fn = getProcAddress(#loadName); \
 	memcpy(&g_context.name, &fn, sizeof(fn))
+
+#define GL_EXT_FUNC_DEF(ret, name, param) LOAD_FUNC(name, name)
+
 #ifdef USE_BUILTIN_OPENGL
 #define GL_FUNC_DEF(ret, name, param) g_context.name = &name
+#define GL_FUNC_2_DEF GL_FUNC_DEF
 #else
 #define GL_FUNC_DEF GL_EXT_FUNC_DEF
+#define GL_FUNC_2_DEF(ret, name, extName, param) \
+	if (g_context.type == kContextGL) { \
+		LOAD_FUNC(name, extName); \
+	} else { \
+		LOAD_FUNC(name, name); \
+	}
 #endif
 #include "backends/graphics/opengl/opengl-func.h"
-#undef GL_EXT_FUNC_DEF
+#undef GL_FUNC_2_DEF
 #undef GL_FUNC_DEF
+#undef GL_EXT_FUNC_DEF
+#undef LOAD_FUNC
 
 	const char *extString = (const char *)g_context.glGetString(GL_EXTENSIONS);
 
diff --git a/backends/graphics/opengl/opengl-func.h b/backends/graphics/opengl/opengl-func.h
index f870214..c85d936 100644
--- a/backends/graphics/opengl/opengl-func.h
+++ b/backends/graphics/opengl/opengl-func.h
@@ -58,11 +58,18 @@
  * does not contain include guards because it can be required to include it
  * multiple times in a source file.
  *
- * Functions are defined by two different user supplied macros:
- * GL_FUNC_DEF: Define a (builtin) OpenGL (ES) function.
+ * Functions are defined by three different user supplied macros:
+ * GL_FUNC_DEF:     Define a (builtin) OpenGL (ES) function.
+ * GL_FUNC_2_DEF:   Define a OpenGL (ES) 2.0 function which can be provided by
+ *                  extensions in OpenGL 1.x contexts.
  * GL_EXT_FUNC_DEF: Define an OpenGL (ES) extension function.
  */
 
+#if !defined(GL_FUNC_2_DEF)
+#define GL_FUNC_2_DEF(ret, name, extName, param) GL_FUNC_DEF(ret, name, param)
+#define DEFINED_GL_FUNC_2_DEF
+#endif
+
 #if !defined(GL_EXT_FUNC_DEF)
 #define GL_EXT_FUNC_DEF(ret, name, param) GL_FUNC_DEF(ret, name, param)
 #define DEFINED_GL_EXT_FUNC_DEF
@@ -97,11 +104,15 @@ GL_FUNC_DEF(void, glTexSubImage2D, (GLenum target, GLint level, GLint xoffset, G
 GL_FUNC_DEF(const GLubyte *, glGetString, (GLenum name));
 GL_FUNC_DEF(GLenum, glGetError, ());
 
+#if !USE_FORCED_GLES
+GL_FUNC_2_DEF(void, glEnableVertexAttribArray, glEnableVertexAttribArrayARB, (GLuint index));
+GL_FUNC_2_DEF(void, glUniform1i, glUniform1iARB, (GLint location, GLint v0));
+GL_FUNC_2_DEF(void, glUniformMatrix4fv, glUniformMatrix4fvARB, (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value));
+GL_FUNC_2_DEF(void, glVertexAttrib4f, glVertexAttrib4fARB, (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w));
+GL_FUNC_2_DEF(void, glVertexAttribPointer, glVertexAttribPointerARB, (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer));
+#endif
+
 #if !USE_FORCED_GL && !USE_FORCED_GLES
-GL_FUNC_DEF(void, glVertexAttrib4f, (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w));
-GL_FUNC_DEF(void, glVertexAttribPointer, (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer));
-GL_FUNC_DEF(void, glUniformMatrix4fv, (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value));
-GL_FUNC_DEF(void, glUniform1i, (GLint location, GLint v0));
 GL_FUNC_DEF(void, glDeleteProgram, (GLuint program));
 GL_FUNC_DEF(void, glDeleteShader, (GLuint shader));
 GL_FUNC_DEF(GLuint, glCreateProgram, ());
@@ -118,7 +129,6 @@ GL_FUNC_DEF(void, glShaderSource, (GLuint shader, GLsizei count, const GLchar *c
 GL_FUNC_DEF(void, glCompileShader, (GLuint shader));
 GL_FUNC_DEF(void, glGetShaderiv, (GLuint shader, GLenum pname, GLint *params));
 GL_FUNC_DEF(void, glGetShaderInfoLog, (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog));
-GL_FUNC_DEF(void, glEnableVertexAttribArray, (GLuint index));
 GL_FUNC_DEF(void, glActiveTexture, (GLenum texture));
 #endif
 
@@ -133,17 +143,17 @@ GL_EXT_FUNC_DEF(void, glGetObjectParameterivARB, (GLhandleARB obj, GLenum pname,
 GL_EXT_FUNC_DEF(GLint, glGetUniformLocationARB, (GLhandleARB programObj, const GLcharARB *name));
 GL_EXT_FUNC_DEF(void, glGetInfoLogARB, (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog));
 GL_EXT_FUNC_DEF(void, glUseProgramObjectARB, (GLhandleARB programObj));
-GL_EXT_FUNC_DEF(void, glUniformMatrix4fvARB, (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value));
-GL_EXT_FUNC_DEF(void, glUniform1iARB, (GLint location, GLint v0));
 GL_EXT_FUNC_DEF(GLhandleARB, glCreateShaderObjectARB, (GLenum shaderType));
 GL_EXT_FUNC_DEF(void, glShaderSourceARB, (GLhandleARB shaderObj, GLsizei count, const GLcharARB **string, const GLint *length));
 GL_EXT_FUNC_DEF(void, glCompileShaderARB, (GLhandleARB shaderObj));
-GL_EXT_FUNC_DEF(void, glVertexAttribPointerARB, (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer));
-GL_EXT_FUNC_DEF(void, glVertexAttrib4fARB, (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w));
-GL_EXT_FUNC_DEF(void, glEnableVertexAttribArrayARB, (GLuint index));
 #endif
 
 #ifdef DEFINED_GL_EXT_FUNC_DEF
 #undef DEFINED_GL_EXT_FUNC_DEF
 #undef GL_EXT_FUNC_DEF
 #endif
+
+#ifdef DEFINED_GL_FUNC_2_DEF
+#undef DEFINED_GL_FUNC_2_DEF
+#undef GL_FUNC_2_DEF
+#endif
diff --git a/backends/graphics/opengl/shader.cpp b/backends/graphics/opengl/shader.cpp
index d7fc205..7fdebed 100644
--- a/backends/graphics/opengl/shader.cpp
+++ b/backends/graphics/opengl/shader.cpp
@@ -167,10 +167,10 @@ void ShaderARB::activate(const GLfloat *projectionMatrix) {
 	GL_CALL(glUseProgramObjectARB(_program));
 
 	// Set projection matrix.
-	GL_CALL(glUniformMatrix4fvARB(_projectionLocation, 1, GL_FALSE, projectionMatrix));
+	GL_CALL(glUniformMatrix4fv(_projectionLocation, 1, GL_FALSE, projectionMatrix));
 
 	// We always use texture unit 0.
-	GL_CALL(glUniform1iARB(_textureLocation, 0));
+	GL_CALL(glUniform1i(_textureLocation, 0));
 }
 
 GLhandleARB ShaderARB::compileShader(const char *source, GLenum shaderType) {


Commit: 8a3eecb73a9eb5d885e3585835db6bee738c1de5
    https://github.com/scummvm/scummvm/commit/8a3eecb73a9eb5d885e3585835db6bee738c1de5
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:25+01:00

Commit Message:
OPENGL: Unify shader implementation for GL and GLES2.

Changed paths:
    backends/graphics/opengl/opengl-defs.h
    backends/graphics/opengl/opengl-func.h
    backends/graphics/opengl/opengl-graphics.cpp
    backends/graphics/opengl/opengl-sys.h
    backends/graphics/opengl/shader.cpp
    backends/graphics/opengl/shader.h



diff --git a/backends/graphics/opengl/opengl-defs.h b/backends/graphics/opengl/opengl-defs.h
index edcf334..5e9bcab 100644
--- a/backends/graphics/opengl/opengl-defs.h
+++ b/backends/graphics/opengl/opengl-defs.h
@@ -77,12 +77,18 @@ typedef double GLdouble; /* double precision float */
 typedef double GLclampd; /* double precision float in [0,1] */
 typedef char   GLchar;
 typedef GLchar GLcharARB;
-#if defined(__APPLE__) || defined(MACOSX)
+#if defined(MACOSX)
 typedef void  *GLhandleARB;
 #else
 typedef uint   GLhandleARB;
 #endif
 
+// This is an addition from us to alias ARB shader object extensions to
+// OpenGL (ES) 2.0 style functions. It only works when GLhandleARB and GLuint
+// are type compatible.
+typedef GLhandleARB GLprogram;
+typedef GLhandleARB GLshader;
+
 /*
  * Constants
  */
diff --git a/backends/graphics/opengl/opengl-func.h b/backends/graphics/opengl/opengl-func.h
index c85d936..fb08779 100644
--- a/backends/graphics/opengl/opengl-func.h
+++ b/backends/graphics/opengl/opengl-func.h
@@ -110,44 +110,30 @@ GL_FUNC_2_DEF(void, glUniform1i, glUniform1iARB, (GLint location, GLint v0));
 GL_FUNC_2_DEF(void, glUniformMatrix4fv, glUniformMatrix4fvARB, (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value));
 GL_FUNC_2_DEF(void, glVertexAttrib4f, glVertexAttrib4fARB, (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w));
 GL_FUNC_2_DEF(void, glVertexAttribPointer, glVertexAttribPointerARB, (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer));
+
+GL_FUNC_2_DEF(GLprogram, glCreateProgram, glCreateProgramObjectARB, ());
+GL_FUNC_2_DEF(void, glDeleteProgram, glDeleteObjectARB, (GLprogram program));
+GL_FUNC_2_DEF(void, glAttachShader, glAttachObjectARB, (GLprogram program, GLshader shader));
+GL_FUNC_2_DEF(void, glDetachShader, glDetachObjectARB, (GLprogram program, GLshader shader));
+GL_FUNC_2_DEF(void, glLinkProgram, glLinkProgramARB, (GLprogram program));
+GL_FUNC_2_DEF(void, glUseProgram, glUseProgramObjectARB, (GLprogram program));
+GL_FUNC_2_DEF(void, glGetProgramiv, glGetObjectParameterivARB, (GLprogram program, GLenum pname, GLint *params));
+GL_FUNC_2_DEF(void, glGetProgramInfoLog, glGetInfoLogARB, (GLprogram program, GLsizei bufSize, GLsizei *length, GLchar *infoLog));
+GL_FUNC_2_DEF(void, glBindAttribLocation, glBindAttribLocationARB, (GLprogram program, GLuint index, const GLchar *name));
+GL_FUNC_2_DEF(GLint, glGetUniformLocation, glGetUniformLocationARB, (GLprogram program, const GLchar *name));
+
+GL_FUNC_2_DEF(GLshader, glCreateShader, glCreateShaderObjectARB, (GLenum type));
+GL_FUNC_2_DEF(void, glDeleteShader, glDeleteObjectARB, (GLshader shader));
+GL_FUNC_2_DEF(void, glGetShaderiv, glGetObjectParameterivARB, (GLshader shader, GLenum pname, GLint *params));
+GL_FUNC_2_DEF(void, glGetShaderInfoLog, glGetInfoLogARB, (GLshader shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog));
+GL_FUNC_2_DEF(void, glShaderSource, glShaderSourceARB, (GLshader shader, GLsizei count, const GLchar *const *string, const GLint *length));
+GL_FUNC_2_DEF(void, glCompileShader, glCompileShaderARB, (GLshader shader));
 #endif
 
 #if !USE_FORCED_GL && !USE_FORCED_GLES
-GL_FUNC_DEF(void, glDeleteProgram, (GLuint program));
-GL_FUNC_DEF(void, glDeleteShader, (GLuint shader));
-GL_FUNC_DEF(GLuint, glCreateProgram, ());
-GL_FUNC_DEF(void, glAttachShader, (GLuint program, GLuint shader));
-GL_FUNC_DEF(void, glBindAttribLocation, (GLuint program, GLuint index, const GLchar *name));
-GL_FUNC_DEF(void, glLinkProgram, (GLuint program));
-GL_FUNC_DEF(void, glDetachShader, (GLuint program, GLuint shader));
-GL_FUNC_DEF(void, glGetProgramiv, (GLuint program, GLenum pname, GLint *params));
-GL_FUNC_DEF(void, glGetProgramInfoLog, (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog));
-GL_FUNC_DEF(GLint, glGetUniformLocation, (GLuint program, const GLchar *name));
-GL_FUNC_DEF(void, glUseProgram, (GLuint program));
-GL_FUNC_DEF(GLuint, glCreateShader, (GLenum type));
-GL_FUNC_DEF(void, glShaderSource, (GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length));
-GL_FUNC_DEF(void, glCompileShader, (GLuint shader));
-GL_FUNC_DEF(void, glGetShaderiv, (GLuint shader, GLenum pname, GLint *params));
-GL_FUNC_DEF(void, glGetShaderInfoLog, (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog));
 GL_FUNC_DEF(void, glActiveTexture, (GLenum texture));
 #endif
 
-#if !USE_FORCED_GLES && !USE_FORCED_GLES2
-GL_EXT_FUNC_DEF(void, glDeleteObjectARB, (GLhandleARB obj));
-GL_EXT_FUNC_DEF(GLhandleARB, glCreateProgramObjectARB, ());
-GL_EXT_FUNC_DEF(void, glAttachObjectARB, (GLhandleARB containerObj, GLhandleARB obj));
-GL_EXT_FUNC_DEF(void, glBindAttribLocationARB, (GLhandleARB programObj, GLuint index, const GLcharARB *name));
-GL_EXT_FUNC_DEF(void, glLinkProgramARB, (GLhandleARB programObj));
-GL_EXT_FUNC_DEF(void, glDetachObjectARB, (GLhandleARB containerObj, GLhandleARB attachedObj));
-GL_EXT_FUNC_DEF(void, glGetObjectParameterivARB, (GLhandleARB obj, GLenum pname, GLint *params));
-GL_EXT_FUNC_DEF(GLint, glGetUniformLocationARB, (GLhandleARB programObj, const GLcharARB *name));
-GL_EXT_FUNC_DEF(void, glGetInfoLogARB, (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog));
-GL_EXT_FUNC_DEF(void, glUseProgramObjectARB, (GLhandleARB programObj));
-GL_EXT_FUNC_DEF(GLhandleARB, glCreateShaderObjectARB, (GLenum shaderType));
-GL_EXT_FUNC_DEF(void, glShaderSourceARB, (GLhandleARB shaderObj, GLsizei count, const GLcharARB **string, const GLint *length));
-GL_EXT_FUNC_DEF(void, glCompileShaderARB, (GLhandleARB shaderObj));
-#endif
-
 #ifdef DEFINED_GL_EXT_FUNC_DEF
 #undef DEFINED_GL_EXT_FUNC_DEF
 #undef GL_EXT_FUNC_DEF
diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index 6d693a3..eb9eed1 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -908,14 +908,14 @@ void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &def
 		if (g_context.type == kContextGLES2) {
 #endif
 #if !USE_FORCED_GL
-			_shader = new ShaderGLES2(g_defaultVertexShader, g_defaultFragmentShaderGLES2);
+			_shader = new Shader(g_defaultVertexShader, g_defaultFragmentShaderGLES2);
 #endif
 #if !USE_FORCED_GL && !USE_FORCED_GLES2
 		} else {
 #endif
 #if !USE_FORCED_GLES2
 			if (g_context.shadersSupported) {
-				_shader = new ShaderARB(g_defaultVertexShader, g_defaultFragmentShaderGL);
+				_shader = new Shader(g_defaultVertexShader, g_defaultFragmentShaderGL);
 			}
 #endif
 #if !USE_FORCED_GL && !USE_FORCED_GLES2
diff --git a/backends/graphics/opengl/opengl-sys.h b/backends/graphics/opengl/opengl-sys.h
index bae318f..cec1f51 100644
--- a/backends/graphics/opengl/opengl-sys.h
+++ b/backends/graphics/opengl/opengl-sys.h
@@ -30,6 +30,18 @@
 #include "backends/platform/sdl/sdl-sys.h"
 #endif
 
+// On OS X we only support GL contexts. The reason is that Apple's GL interface
+// uses "void *" for GLhandleARB which is not type compatible with GLint. This
+// kills our aliasing trick for extension functions and thus would force us to
+// supply two different Shader class implementations or introduce other
+// wrappers. OS X only supports GL contexts right now anyway (at least
+// according to SDL2 sources), thus it is not much of an issue.
+#if defined(MACOSX) && (!defined(USE_GLES_MODE) || USE_GLES_MODE != 0)
+//#warning "Only forced OpenGL mode is supported on Mac OS X. Overriding settings."
+#undef USE_GLES_MODE
+#define USE_GLES_MODE 0
+#endif
+
 // We allow to force GL or GLES modes on compile time.
 // For this the USE_GLES_MODE define is used. The following values represent
 // the given selection choices:
diff --git a/backends/graphics/opengl/shader.cpp b/backends/graphics/opengl/shader.cpp
index 7fdebed..9e106a8 100644
--- a/backends/graphics/opengl/shader.cpp
+++ b/backends/graphics/opengl/shader.cpp
@@ -68,166 +68,39 @@ const char *const g_defaultFragmentShaderGLES2 =
 	"}\n";
 #endif
 
-#if !USE_FORCED_GLES2
-
-ShaderARB::ShaderARB(const Common::String &vertex, const Common::String &fragment)
-    : Shader(vertex, fragment), _program(0), _projectionLocation(-1), _textureLocation(-1) {
+Shader::Shader(const Common::String &vertex, const Common::String &fragment)
+    : _vertex(vertex), _fragment(fragment), _program(0), _projectionLocation(-1), _textureLocation(-1) {
 }
 
-ShaderARB::~ShaderARB() {
+Shader::~Shader() {
 	// According to extension specification glDeleteObjectARB silently ignores
 	// 0. However, with nVidia drivers this can cause GL_INVALID_VALUE, thus
 	// we do not call it with 0 as parameter to avoid warnings.
 	if (_program) {
-		GL_CALL_SAFE(glDeleteObjectARB, (_program));
+		GL_CALL_SAFE(glDeleteProgram, (_program));
 	}
 }
 
-void ShaderARB::destroy() {
+void Shader::destroy() {
 	// According to extension specification glDeleteObjectARB silently ignores
 	// 0. However, with nVidia drivers this can cause GL_INVALID_VALUE, thus
 	// we do not call it with 0 as parameter to avoid warnings.
 	if (_program) {
-		GL_CALL(glDeleteObjectARB(_program));
+		GL_CALL(glDeleteProgram(_program));
+		_program = 0;
 	}
-	_program = 0;
 }
 
-bool ShaderARB::recreate() {
+bool Shader::recreate() {
 	// Make sure any old programs are destroyed properly.
 	destroy();
 
-	GLhandleARB vertexShader = compileShader(_vertex.c_str(), GL_VERTEX_SHADER_ARB);
+	GLshader vertexShader = compileShader(_vertex.c_str(), GL_VERTEX_SHADER);
 	if (!vertexShader) {
 		return false;
 	}
 
-	GLhandleARB fragmentShader = compileShader(_fragment.c_str(), GL_FRAGMENT_SHADER_ARB);
-	if (!fragmentShader) {
-		GL_CALL(glDeleteObjectARB(vertexShader));
-		return false;
-	}
-
-	GL_ASSIGN(_program, glCreateProgramObjectARB());
-	if (!_program) {
-		GL_CALL(glDeleteObjectARB(vertexShader));
-		GL_CALL(glDeleteObjectARB(fragmentShader));
-		return false;
-	}
-
-	GL_CALL(glAttachObjectARB(_program, vertexShader));
-	GL_CALL(glAttachObjectARB(_program, fragmentShader));
-
-	GL_CALL(glBindAttribLocationARB(_program, kPositionAttribLocation, "position"));
-	GL_CALL(glBindAttribLocationARB(_program, kTexCoordAttribLocation, "texCoordIn"));
-	GL_CALL(glBindAttribLocationARB(_program, kColorAttribLocation,    "blendColorIn"));
-
-	GL_CALL(glLinkProgramARB(_program));
-
-	GL_CALL(glDetachObjectARB(_program, fragmentShader));
-	GL_CALL(glDeleteObjectARB(fragmentShader));
-
-	GL_CALL(glDetachObjectARB(_program, vertexShader));
-	GL_CALL(glDeleteObjectARB(vertexShader));
-
-	GLint result;
-	GL_CALL(glGetObjectParameterivARB(_program, GL_OBJECT_LINK_STATUS_ARB, &result));
-	if (result == GL_FALSE) {
-		GLint logSize;
-		GL_CALL(glGetObjectParameterivARB(_program, GL_OBJECT_INFO_LOG_LENGTH_ARB, &logSize));
-
-		GLchar *log = new GLchar[logSize];
-		GL_CALL(glGetInfoLogARB(_program, logSize, nullptr, log));
-		warning("Could not link shader: \"%s\"", log);
-		delete[] log;
-
-		destroy();
-		return false;
-	}
-
-	GL_ASSIGN(_projectionLocation, glGetUniformLocationARB(_program, "projection"));
-	if (_projectionLocation == -1) {
-		warning("Shader misses \"projection\" uniform.");
-		destroy();
-		return false;
-	}
-
-	GL_ASSIGN(_textureLocation, glGetUniformLocationARB(_program, "texture"));
-	if (_textureLocation == -1) {
-		warning("Shader misses \"texture\" uniform.");
-		destroy();
-		return false;
-	}
-
-	return true;
-}
-
-void ShaderARB::activate(const GLfloat *projectionMatrix) {
-	// Activate program.
-	GL_CALL(glUseProgramObjectARB(_program));
-
-	// Set projection matrix.
-	GL_CALL(glUniformMatrix4fv(_projectionLocation, 1, GL_FALSE, projectionMatrix));
-
-	// We always use texture unit 0.
-	GL_CALL(glUniform1i(_textureLocation, 0));
-}
-
-GLhandleARB ShaderARB::compileShader(const char *source, GLenum shaderType) {
-	GLuint handle;
-	GL_ASSIGN(handle, glCreateShaderObjectARB(shaderType));
-	if (!handle) {
-		return 0;
-	}
-
-	GL_CALL(glShaderSourceARB(handle, 1, &source, nullptr));
-	GL_CALL(glCompileShaderARB(handle));
-
-	GLint result;
-	GL_CALL(glGetObjectParameterivARB(handle, GL_OBJECT_COMPILE_STATUS_ARB, &result));
-	if (result == GL_FALSE) {
-		GLint logSize;
-		GL_CALL(glGetObjectParameterivARB(handle, GL_OBJECT_INFO_LOG_LENGTH_ARB, &logSize));
-
-		GLchar *log = new GLchar[logSize];
-		GL_CALL(glGetInfoLogARB(handle, logSize, nullptr, log));
-		warning("Could not compile shader \"%s\": \"%s\"", source, log);
-		delete[] log;
-
-		GL_CALL(glDeleteObjectARB(handle));
-		return 0;
-	}
-
-	return handle;
-}
-
-#endif // !USE_FORCED_GLES2
-
-#if !USE_FORCED_GL
-
-ShaderGLES2::ShaderGLES2(const Common::String &vertex, const Common::String &fragment)
-    : Shader(vertex, fragment), _program(0), _projectionLocation(-1), _textureLocation(-1) {
-}
-
-ShaderGLES2::~ShaderGLES2() {
-	GL_CALL_SAFE(glDeleteProgram, (_program));
-}
-
-void ShaderGLES2::destroy() {
-	GL_CALL(glDeleteProgram(_program));
-	_program = 0;
-}
-
-bool ShaderGLES2::recreate() {
-	// Make sure any old programs are destroyed properly.
-	destroy();
-
-	GLuint vertexShader = compileShader(_vertex.c_str(), GL_VERTEX_SHADER);
-	if (!vertexShader) {
-		return false;
-	}
-
-	GLuint fragmentShader = compileShader(_fragment.c_str(), GL_FRAGMENT_SHADER);
+	GLshader fragmentShader = compileShader(_fragment.c_str(), GL_FRAGMENT_SHADER);
 	if (!fragmentShader) {
 		GL_CALL(glDeleteShader(vertexShader));
 		return false;
@@ -287,7 +160,7 @@ bool ShaderGLES2::recreate() {
 	return true;
 }
 
-void ShaderGLES2::activate(const GLfloat *projectionMatrix) {
+void Shader::activate(const GLfloat *projectionMatrix) {
 	// Activate program.
 	GL_CALL(glUseProgram(_program));
 
@@ -298,8 +171,8 @@ void ShaderGLES2::activate(const GLfloat *projectionMatrix) {
 	GL_CALL(glUniform1i(_textureLocation, 0));
 }
 
-GLuint ShaderGLES2::compileShader(const char *source, GLenum shaderType) {
-	GLuint handle;
+GLshader Shader::compileShader(const char *source, GLenum shaderType) {
+	GLshader handle;
 	GL_ASSIGN(handle, glCreateShader(shaderType));
 	if (!handle) {
 		return 0;
@@ -326,8 +199,6 @@ GLuint ShaderGLES2::compileShader(const char *source, GLenum shaderType) {
 	return handle;
 }
 
-#endif // !!USE_FORCED_GL
-
 } // End of namespace OpenGL
 
 #endif // !USE_FORCED_GLES
diff --git a/backends/graphics/opengl/shader.h b/backends/graphics/opengl/shader.h
index 60a4302..f9dcbb0 100644
--- a/backends/graphics/opengl/shader.h
+++ b/backends/graphics/opengl/shader.h
@@ -47,9 +47,8 @@ extern const char *const g_defaultFragmentShaderGLES2;
 
 class Shader {
 public:
-	Shader(const Common::String &vertex, const Common::String &fragment)
-	    : _vertex(vertex), _fragment(fragment) {}
-	virtual ~Shader() {}
+	Shader(const Common::String &vertex, const Common::String &fragment);
+	~Shader();
 
 	/**
 	 * Destroy the shader program.
@@ -57,21 +56,21 @@ public:
 	 * This keeps the vertex and fragment shader sources around and thus
 	 * allows for recreating the shader on context recreation.
 	 */
-	virtual void destroy() = 0;
+	void destroy();
 
 	/**
 	 * Recreate shader program.
 	 *
 	 * @return true on success, false on failure.
 	 */
-	virtual bool recreate() = 0;
+	bool recreate();
 
 	/**
 	 * Make shader active.
 	 *
 	 * @param projectionMatrix Projection matrix to use.
 	 */
-	virtual void activate(const GLfloat *projectionMatrix) = 0;
+	void activate(const GLfloat *projectionMatrix);
 protected:
 	/**
 	 * Vertex shader sources.
@@ -82,24 +81,11 @@ protected:
 	 * Fragment shader sources.
 	 */
 	const Common::String _fragment;
-};
-
-#if !USE_FORCED_GLES2
-class ShaderARB : public Shader {
-public:
-	ShaderARB(const Common::String &vertex, const Common::String &fragment);
-	virtual ~ShaderARB();
-
-	virtual void destroy();
 
-	virtual bool recreate();
-
-	virtual void activate(const GLfloat *projectionMatrix);
-private:
 	/**
 	 * Shader program handle.
 	 */
-	GLhandleARB _program;
+	GLprogram _program;
 
 	/**
 	 * Location of the matrix uniform in the shader program.
@@ -119,48 +105,8 @@ private:
 	 *                   GL_VERTEX_SHADER_ARB)
 	 * @return The shader object or 0 on failure.
 	 */
-	static GLhandleARB compileShader(const char *source, GLenum shaderType);
-};
-#endif // !USE_FORCED_GLES2
-
-#if !USE_FORCED_GL
-class ShaderGLES2 : public Shader {
-public:
-	ShaderGLES2(const Common::String &vertex, const Common::String &fragment);
-	virtual ~ShaderGLES2();
-
-	virtual void destroy();
-
-	virtual bool recreate();
-
-	virtual void activate(const GLfloat *projectionMatrix);
-private:
-	/**
-	 * Shader program handle.
-	 */
-	GLuint _program;
-
-	/**
-	 * Location of the matrix uniform in the shader program.
-	 */
-	GLint _projectionLocation;
-
-	/**
-	 * Location of the texture sampler location in the shader program.
-	 */
-	GLint _textureLocation;
-
-	/**
-	 * Compile a vertex or fragment shader.
-	 *
-	 * @param source     Sources to the shader.
-	 * @param shaderType Type of shader to compile (GL_FRAGMENT_SHADER or
-	 *                   GL_VERTEX_SHADER)
-	 * @return The shader object or 0 on failure.
-	 */
-	static GLuint compileShader(const char *source, GLenum shaderType);
+	static GLshader compileShader(const char *source, GLenum shaderType);
 };
-#endif
 
 } // End of namespace OpenGL
 


Commit: b8d79261eda49671e6ae63592412a80ac49cc893
    https://github.com/scummvm/scummvm/commit/b8d79261eda49671e6ae63592412a80ac49cc893
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:26+01:00

Commit Message:
OPENGLSDL: Request "standard" GL contexts.

Compatibility profiles only exist in modern OpenGL and we request an ancient
version.

Changed paths:
    backends/graphics/openglsdl/openglsdl-graphics.cpp



diff --git a/backends/graphics/openglsdl/openglsdl-graphics.cpp b/backends/graphics/openglsdl/openglsdl-graphics.cpp
index 2171b95..7ea1860 100644
--- a/backends/graphics/openglsdl/openglsdl-graphics.cpp
+++ b/backends/graphics/openglsdl/openglsdl-graphics.cpp
@@ -62,7 +62,7 @@ OpenGLSdlGraphicsManager::OpenGLSdlGraphicsManager(uint desktopWidth, uint deskt
 
 #if USE_FORCED_GL
 	glContextType = OpenGL::kContextGL;
-	_glContextProfileMask = SDL_GL_CONTEXT_PROFILE_COMPATIBILITY;
+	_glContextProfileMask = 0;
 	_glContextMajor = DEFAULT_GL_MAJOR;
 	_glContextMinor = DEFAULT_GL_MINOR;
 #elif USE_FORCED_GLES
@@ -86,7 +86,7 @@ OpenGLSdlGraphicsManager::OpenGLSdlGraphicsManager(uint desktopWidth, uint deskt
 	//
 	// In case no defaults are given we prefer OpenGL over OpenGL ES.
 	if (SDL_GL_GetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, &_glContextProfileMask) != 0) {
-		_glContextProfileMask = SDL_GL_CONTEXT_PROFILE_COMPATIBILITY;
+		_glContextProfileMask = 0;
 		noDefaults = true;
 	}
 
@@ -103,7 +103,7 @@ OpenGLSdlGraphicsManager::OpenGLSdlGraphicsManager(uint desktopWidth, uint deskt
 			_glContextMajor = DEFAULT_GLES_MAJOR;
 			_glContextMinor = DEFAULT_GLES_MINOR;
 		} else {
-			_glContextProfileMask = SDL_GL_CONTEXT_PROFILE_COMPATIBILITY;
+			_glContextProfileMask = 0;
 			_glContextMajor = DEFAULT_GL_MAJOR;
 			_glContextMinor = DEFAULT_GL_MINOR;
 		}
@@ -119,8 +119,8 @@ OpenGLSdlGraphicsManager::OpenGLSdlGraphicsManager(uint desktopWidth, uint deskt
 		glContextType = OpenGL::kContextGL;
 
 		// Core profile does not allow legacy functionality, which we use.
-		// Thus we always request a compatibility profile.
-		_glContextProfileMask = SDL_GL_CONTEXT_PROFILE_COMPATIBILITY;
+		// Thus we request a standard OpenGL context.
+		_glContextProfileMask = 0;
 		_glContextMajor = DEFAULT_GL_MAJOR;
 		_glContextMinor = DEFAULT_GL_MINOR;
 	} else {


Commit: 5eb0ac0c9e82b419d996784adddc5f94d1fa5be3
    https://github.com/scummvm/scummvm/commit/5eb0ac0c9e82b419d996784adddc5f94d1fa5be3
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:26+01:00

Commit Message:
OPENGL: Remove (some) unused GL definitions.

Changed paths:
    backends/graphics/opengl/opengl-defs.h



diff --git a/backends/graphics/opengl/opengl-defs.h b/backends/graphics/opengl/opengl-defs.h
index 5e9bcab..793955c 100644
--- a/backends/graphics/opengl/opengl-defs.h
+++ b/backends/graphics/opengl/opengl-defs.h
@@ -76,7 +76,6 @@ typedef float  GLclampf; /* single precision float in [0,1] */
 typedef double GLdouble; /* double precision float */
 typedef double GLclampd; /* double precision float in [0,1] */
 typedef char   GLchar;
-typedef GLchar GLcharARB;
 #if defined(MACOSX)
 typedef void  *GLhandleARB;
 #else
@@ -235,20 +234,14 @@ typedef GLhandleARB GLshader;
 
 /* Shaders */
 #define GL_FRAGMENT_SHADER                0x8B30
-#define GL_FRAGMENT_SHADER_ARB            0x8B30
 
 #define GL_VERTEX_SHADER                  0x8B31
-#define GL_VERTEX_SHADER_ARB              0x8B31
 
 /* Programs */
 #define GL_COMPILE_STATUS                 0x8B81
 #define GL_LINK_STATUS                    0x8B82
 #define GL_INFO_LOG_LENGTH                0x8B84
 
-#define GL_OBJECT_COMPILE_STATUS_ARB      0x8B81
-#define GL_OBJECT_LINK_STATUS_ARB         0x8B82
-#define GL_OBJECT_INFO_LOG_LENGTH_ARB     0x8B84
-
 /* Textures */
 #define GL_TEXTURE0                       0x84C0
 


Commit: b081fe63e866883b424dfefb694c9b6518efa3b4
    https://github.com/scummvm/scummvm/commit/b081fe63e866883b424dfefb694c9b6518efa3b4
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:26+01:00

Commit Message:
OPENGL: Create new abstraction for GL texture objects.

Changed paths:
    backends/graphics/opengl/texture.cpp
    backends/graphics/opengl/texture.h



diff --git a/backends/graphics/opengl/texture.cpp b/backends/graphics/opengl/texture.cpp
index 08f5e69..656de20 100644
--- a/backends/graphics/opengl/texture.cpp
+++ b/backends/graphics/opengl/texture.cpp
@@ -40,87 +40,171 @@ static GLuint nextHigher2(GLuint v) {
 	return ++v;
 }
 
-GLint Texture::_maxTextureSize = 0;
 
-void Texture::queryTextureInformation() {
-	GL_CALL(glGetIntegerv(GL_MAX_TEXTURE_SIZE, &_maxTextureSize));
-	debug(5, "OpenGL maximum texture size: %d", _maxTextureSize);
+GLTexture::GLTexture(GLenum glIntFormat, GLenum glFormat, GLenum glType)
+    : _glIntFormat(glIntFormat), _glFormat(glFormat), _glType(glType),
+      _width(0), _height(0), _texCoords(), _glFilter(GL_NEAREST),
+      _glTexture(0) {
+	create();
 }
 
-Texture::Texture(GLenum glIntFormat, GLenum glFormat, GLenum glType, const Graphics::PixelFormat &format)
-    : _glIntFormat(glIntFormat), _glFormat(glFormat), _glType(glType), _format(format), _glFilter(GL_NEAREST),
-      _glTexture(0), _textureData(), _userPixelData(), _allDirty(false) {
-	recreateInternalTexture();
+GLTexture::~GLTexture() {
+	GL_CALL_SAFE(glDeleteTextures, (1, &_glTexture));
 }
 
-Texture::~Texture() {
-	GL_CALL_SAFE(glDeleteTextures, (1, &_glTexture));
-	_textureData.free();
+void GLTexture::enableLinearFiltering(bool enable) {
+	if (enable) {
+		_glFilter = GL_LINEAR;
+	} else {
+		_glFilter = GL_NEAREST;
+	}
+
+	bind();
+
+	GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, _glFilter));
+	GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, _glFilter));
 }
 
-void Texture::releaseInternalTexture() {
+void GLTexture::destroy() {
 	GL_CALL(glDeleteTextures(1, &_glTexture));
 	_glTexture = 0;
 }
 
-void Texture::recreateInternalTexture() {
+void GLTexture::create() {
 	// Release old texture name in case it exists.
-	releaseInternalTexture();
+	destroy();
 
 	// Get a new texture name.
 	GL_CALL(glGenTextures(1, &_glTexture));
 
 	// Set up all texture parameters.
-	GL_CALL(glBindTexture(GL_TEXTURE_2D, _glTexture));
+	bind();
 	GL_CALL(glPixelStorei(GL_UNPACK_ALIGNMENT, 1));
 	GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, _glFilter));
 	GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, _glFilter));
 	GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
 	GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
 
-	// In case there is an actual texture setup we reinitialize it.
-	if (_textureData.getPixels()) {
+	// If a size is specified, allocate memory for it.
+	if (_width != 0 && _height != 0) {
 		// Allocate storage for OpenGL texture.
-		GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, _glIntFormat, _textureData.w,
-		       _textureData.h, 0, _glFormat, _glType, NULL));
-
-		// Mark dirts such that it will be completely refreshed the next time.
-		flagDirty();
+		GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, _glIntFormat, _width, _height,
+		                     0, _glFormat, _glType, NULL));
 	}
 }
 
-void Texture::enableLinearFiltering(bool enable) {
-	if (enable) {
-		_glFilter = GL_LINEAR;
+void GLTexture::bind() {
+	GL_CALL(glBindTexture(GL_TEXTURE_2D, _glTexture));
+}
+
+void GLTexture::setSize(uint width, uint height) {
+	const uint oldWidth  = _width;
+	const uint oldHeight = _height;
+
+	if (!g_context.NPOTSupported) {
+		_width  = nextHigher2(width);
+		_height = nextHigher2(height);
 	} else {
-		_glFilter = GL_NEAREST;
+		_width  = width;
+		_height = height;
 	}
 
-	GL_CALL(glBindTexture(GL_TEXTURE_2D, _glTexture));
+	// If a size is specified, allocate memory for it.
+	if (width != 0 && height != 0) {
+		const GLfloat texWidth = (GLfloat)width / _width;
+		const GLfloat texHeight = (GLfloat)height / _height;
 
-	GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, _glFilter));
-	GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, _glFilter));
+		_texCoords[0] = 0;
+		_texCoords[1] = 0;
+
+		_texCoords[2] = texWidth;
+		_texCoords[3] = 0;
+
+		_texCoords[4] = 0;
+		_texCoords[5] = texHeight;
+
+		_texCoords[6] = texWidth;
+		_texCoords[7] = texHeight;
+
+		// Allocate storage for OpenGL texture if necessary.
+		if (oldWidth != _width || oldHeight != _height) {
+			bind();
+			GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, _glIntFormat, _width,
+			                     _height, 0, _glFormat, _glType, NULL));
+		}
+	}
 }
 
-void Texture::allocate(uint width, uint height) {
-	uint texWidth = width, texHeight = height;
-	if (!g_context.NPOTSupported) {
-		texWidth  = nextHigher2(texWidth);
-		texHeight = nextHigher2(texHeight);
+void GLTexture::updateArea(const Common::Rect &area, const Graphics::Surface &src) {
+	// Set the texture on the active texture unit.
+	bind();
+
+	// Update the actual texture.
+	// Although we have the area of the texture buffer we want to update we
+	// cannot take advantage of the left/right boundries here because it is
+	// not possible to specify a pitch to glTexSubImage2D. To be precise, with
+	// plain OpenGL we could set GL_UNPACK_ROW_LENGTH to achieve this. However,
+	// OpenGL ES 1.0 does not support GL_UNPACK_ROW_LENGTH. Thus, we are left
+	// with the following options:
+	//
+	// 1) (As we do right now) Simply always update the whole texture lines of
+	//    rect changed. This is simplest to implement. In case performance is
+	//    really an issue we can think of switching to another method.
+	//
+	// 2) Copy the dirty rect to a temporary buffer and upload that by using
+	//    glTexSubImage2D. This is what the Android backend does. It is more
+	//    complicated though.
+	//
+	// 3) Use glTexSubImage2D per line changed. This is what the old OpenGL
+	//    graphics manager did but it is much slower! Thus, we do not use it.
+	GL_CALL(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, area.top, src.w, area.height(),
+	                       _glFormat, _glType, src.getBasePtr(0, area.top)));
+}
+
+GLint Texture::_maxTextureSize = 0;
+
+void Texture::queryTextureInformation() {
+	GL_CALL(glGetIntegerv(GL_MAX_TEXTURE_SIZE, &_maxTextureSize));
+	debug(5, "OpenGL maximum texture size: %d", _maxTextureSize);
+}
+
+Texture::Texture(GLenum glIntFormat, GLenum glFormat, GLenum glType, const Graphics::PixelFormat &format)
+    : _format(format), _glTexture(glIntFormat, glFormat, glType),
+      _textureData(), _userPixelData(), _allDirty(false) {
+	recreateInternalTexture();
+}
+
+Texture::~Texture() {
+	_textureData.free();
+}
+
+void Texture::releaseInternalTexture() {
+	_glTexture.destroy();
+}
+
+void Texture::recreateInternalTexture() {
+	_glTexture.create();
+
+	// In case image date exists assure it will be completely refreshed next
+	// time.
+	if (_textureData.getPixels()) {
+		flagDirty();
 	}
+}
 
-	// In case the needed texture dimension changed we will reinitialize the
-	// texture.
-	if (texWidth != _textureData.w || texHeight != _textureData.h) {
-		// Create a buffer for the texture data.
-		_textureData.create(texWidth, texHeight, _format);
+void Texture::enableLinearFiltering(bool enable) {
+	_glTexture.enableLinearFiltering(enable);
+}
 
-		// Set the texture.
-		GL_CALL(glBindTexture(GL_TEXTURE_2D, _glTexture));
+void Texture::allocate(uint width, uint height) {
+	// Assure the texture can contain our user data.
+	_glTexture.setSize(width, height);
 
-		// Allocate storage for OpenGL texture.
-		GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, _glIntFormat, _textureData.w,
-		       _textureData.h, 0, _glFormat, _glType, NULL));
+	// In case the needed texture dimension changed we will reinitialize the
+	// texture data buffer.
+	if (_glTexture.getWidth() != _textureData.w || _glTexture.getHeight() != _textureData.h) {
+		// Create a buffer for the texture data.
+		_textureData.create(_glTexture.getWidth(), _glTexture.getHeight(), _format);
 	}
 
 	// Create a sub-buffer for raw access.
@@ -175,17 +259,7 @@ void Texture::draw(GLfloat x, GLfloat y, GLfloat w, GLfloat h) {
 	updateTexture();
 
 	// Set the texture.
-	GL_CALL(glBindTexture(GL_TEXTURE_2D, _glTexture));
-
-	// Calculate the texture rect that will be drawn.
-	const GLfloat texWidth = (GLfloat)_userPixelData.w / _textureData.w;
-	const GLfloat texHeight = (GLfloat)_userPixelData.h / _textureData.h;
-	const GLfloat texcoords[4*2] = {
-		0,        0,
-		texWidth, 0,
-		0,        texHeight,
-		texWidth, texHeight
-	};
+	_glTexture.bind();
 
 	// Calculate the screen rect where the texture will be drawn.
 	const GLfloat vertices[4*2] = {
@@ -196,7 +270,7 @@ void Texture::draw(GLfloat x, GLfloat y, GLfloat w, GLfloat h) {
 	};
 
 	// Setup coordinates for drawing.
-	g_context.setDrawCoordinates(vertices, texcoords);
+	g_context.setDrawCoordinates(vertices, _glTexture.getTexCoords());
 
 	// Draw the texture to the screen buffer.
 	GL_CALL(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
@@ -211,7 +285,7 @@ void Texture::updateTexture() {
 
 	// In case we use linear filtering we might need to duplicate the last
 	// pixel row/column to avoid glitches with filtering.
-	if (_glFilter == GL_LINEAR) {
+	if (_glTexture.isLinearFilteringEnabled()) {
 		if (dirtyArea.right == _userPixelData.w && _userPixelData.w != _textureData.w) {
 			uint height = dirtyArea.height();
 
@@ -238,29 +312,7 @@ void Texture::updateTexture() {
 		}
 	}
 
-	// Set the texture.
-	GL_CALL(glBindTexture(GL_TEXTURE_2D, _glTexture));
-
-	// Update the actual texture.
-	// Although we keep track of the dirty part of the texture buffer we
-	// cannot take advantage of the left/right boundries here because it is
-	// not possible to specify a pitch to glTexSubImage2D. To be precise, with
-	// plain OpenGL we could set GL_UNPACK_ROW_LENGTH to achieve this. However,
-	// OpenGL ES 1.0 does not support GL_UNPACK_ROW_LENGTH. Thus, we are left
-	// with the following options:
-	//
-	// 1) (As we do right now) Simply always update the whole texture lines of
-	//    rect changed. This is simplest to implement. In case performance is
-	//    really an issue we can think of switching to another method.
-	//
-	// 2) Copy the dirty rect to a temporary buffer and upload that by using
-	//    glTexSubImage2D. This is what the Android backend does. It is more
-	//    complicated though.
-	//
-	// 3) Use glTexSubImage2D per line changed. This is what the old OpenGL
-	//    graphics manager did but it is much slower! Thus, we do not use it.
-	GL_CALL(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, dirtyArea.top, _textureData.w, dirtyArea.height(),
-	                       _glFormat, _glType, _textureData.getBasePtr(0, dirtyArea.top)));
+	_glTexture.updateArea(dirtyArea, _textureData);
 
 	// We should have handled everything, thus not dirty anymore.
 	clearDirty();
diff --git a/backends/graphics/opengl/texture.h b/backends/graphics/opengl/texture.h
index 4c21267..b16faab 100644
--- a/backends/graphics/opengl/texture.h
+++ b/backends/graphics/opengl/texture.h
@@ -33,6 +33,91 @@
 namespace OpenGL {
 
 /**
+ * A simple GL texture object abstraction.
+ *
+ * This is used for low-level GL texture handling.
+ */
+class GLTexture {
+public:
+	/**
+	 * Constrcut a new GL texture object.
+	 *
+	 * @param glIntFormat The internal format to use.
+	 * @param glFormat    The input format.
+	 * @param glType      The input type.
+	 */
+	GLTexture(GLenum glIntFormat, GLenum glFormat, GLenum glType);
+	~GLTexture();
+
+	/**
+	 * Enable or disable linear texture filtering.
+	 *
+	 * @param enable true to enable and false to disable.
+	 */
+	void enableLinearFiltering(bool enable);
+
+	/**
+	 * Test whether linear filtering is enabled.
+	 */
+	bool isLinearFilteringEnabled() const { return (_glFilter == GL_LINEAR); }
+
+	/**
+	 * Destroy the OpenGL texture name.
+	 */
+	void destroy();
+
+	/**
+	 * Create the OpenGL texture name.
+	 */
+	void create();
+
+	/**
+	 * Bind the texture to the active texture unit.
+	 */
+	void bind();
+
+	/**
+	 * Sets the size of the texture in pixels.
+	 *
+	 * The internal OpenGL texture might have a different size. To query the
+	 * actual size use getWidth()/getHeight().
+	 *
+	 * @param width  The desired logical width.
+	 * @param height The desired logical height.
+	 */
+	void setSize(uint width, uint height);
+
+	/**
+	 * Copy image data to the texture.
+	 *
+	 * @param area     The area to update.
+	 * @param src      Surface for the whole texture containing the pixel data
+	 *                 to upload. Only the area described by area will be
+	 *                 uploaded.
+	 */
+	void updateArea(const Common::Rect &area, const Graphics::Surface &src);
+
+	uint getWidth() const { return _width; }
+	uint getHeight() const { return _height; }
+
+	/**
+	 * Obtain texture coordinates for rectangular drawing.
+	 */
+	const GLfloat *getTexCoords() const { return _texCoords; }
+private:
+	const GLenum _glIntFormat;
+	const GLenum _glFormat;
+	const GLenum _glType;
+
+	uint _width, _height;
+	GLfloat _texCoords[4*2];
+
+	GLint _glFilter;
+
+	GLuint _glTexture;
+};
+
+/**
  * An OpenGL texture wrapper. It automatically takes care of all OpenGL
  * texture handling issues and also provides access to the texture data.
  */
@@ -125,13 +210,9 @@ protected:
 
 	Common::Rect getDirtyArea() const;
 private:
-	const GLenum _glIntFormat;
-	const GLenum _glFormat;
-	const GLenum _glType;
 	const Graphics::PixelFormat _format;
 
-	GLint _glFilter;
-	GLuint _glTexture;
+	GLTexture _glTexture;
 
 	Graphics::Surface _textureData;
 	Graphics::Surface _userPixelData;


Commit: 9844d89231de0fc2234199620390dbd057e79103
    https://github.com/scummvm/scummvm/commit/9844d89231de0fc2234199620390dbd057e79103
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:26+01:00

Commit Message:
OPENGL: Move max texture size information to Context.

Changed paths:
    backends/graphics/opengl/context.cpp
    backends/graphics/opengl/opengl-graphics.cpp
    backends/graphics/opengl/opengl-sys.h
    backends/graphics/opengl/texture.cpp
    backends/graphics/opengl/texture.h



diff --git a/backends/graphics/opengl/context.cpp b/backends/graphics/opengl/context.cpp
index 2da4cab..209c38e 100644
--- a/backends/graphics/opengl/context.cpp
+++ b/backends/graphics/opengl/context.cpp
@@ -25,6 +25,7 @@
 #include "backends/graphics/opengl/shader.h"
 
 #include "common/tokenizer.h"
+#include "common/debug.h"
 
 namespace OpenGL {
 
@@ -39,6 +40,8 @@ namespace OpenGL {
 #endif
 
 void Context::reset() {
+	_maxTextureSize = 0;
+
 	NPOTSupported = false;
 #if !USE_FORCED_GLES && !USE_FORCED_GLES2
 	shadersSupported = false;
@@ -185,6 +188,10 @@ void OpenGLGraphicsManager::initializeGLContext() {
 #undef GL_EXT_FUNC_DEF
 #undef LOAD_FUNC
 
+	// Obtain maximum texture size.
+	GL_CALL(glGetIntegerv(GL_MAX_TEXTURE_SIZE, &g_context._maxTextureSize));
+	debug(5, "OpenGL maximum texture size: %d", g_context._maxTextureSize);
+
 	const char *extString = (const char *)g_context.glGetString(GL_EXTENSIONS);
 
 #if !USE_FORCED_GLES && !USE_FORCED_GLES2
diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index eb9eed1..363fe40 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -221,8 +221,8 @@ OSystem::TransactionError OpenGLGraphicsManager::endGFXTransaction() {
 		   // a context existing before, which means we don't know the maximum
 		   // supported texture size before this. Thus, we check whether the
 		   // requested game resolution is supported over here.
-		   || (   _currentState.gameWidth  > (uint)Texture::getMaximumTextureSize()
-		       || _currentState.gameHeight > (uint)Texture::getMaximumTextureSize())) {
+		   || (   _currentState.gameWidth  > (uint)g_context._maxTextureSize
+		       || _currentState.gameHeight > (uint)g_context._maxTextureSize)) {
 			if (_transactionMode == kTransactionActive) {
 				// Try to setup the old state in case its valid and is
 				// actually different from the new one.
@@ -806,15 +806,15 @@ void OpenGLGraphicsManager::setActualScreenSize(uint width, uint height) {
 	// possible and then scale it to the physical display size. This sounds
 	// bad but actually all recent chips should support full HD resolution
 	// anyway. Thus, it should not be a real issue for modern hardware.
-	if (   overlayWidth  > (uint)Texture::getMaximumTextureSize()
-	    || overlayHeight > (uint)Texture::getMaximumTextureSize()) {
+	if (   overlayWidth  > (uint)g_context._maxTextureSize
+	    || overlayHeight > (uint)g_context._maxTextureSize) {
 		const frac_t outputAspect = intToFrac(_outputScreenWidth) / _outputScreenHeight;
 
 		if (outputAspect > (frac_t)FRAC_ONE) {
-			overlayWidth  = Texture::getMaximumTextureSize();
+			overlayWidth  = g_context._maxTextureSize;
 			overlayHeight = intToFrac(overlayWidth) / outputAspect;
 		} else {
-			overlayHeight = Texture::getMaximumTextureSize();
+			overlayHeight = g_context._maxTextureSize;
 			overlayWidth  = fracToInt(overlayHeight * outputAspect);
 		}
 	}
@@ -899,9 +899,6 @@ void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &def
 	// code and that requires the same alignment too.
 	GL_CALL(glPixelStorei(GL_PACK_ALIGNMENT, 4));
 
-	// Query information needed by textures.
-	Texture::queryTextureInformation();
-
 #if !USE_FORCED_GLES
 	if (!_shader) {
 #if !USE_FORCED_GL && !USE_FORCED_GLES2
diff --git a/backends/graphics/opengl/opengl-sys.h b/backends/graphics/opengl/opengl-sys.h
index cec1f51..4d14348 100644
--- a/backends/graphics/opengl/opengl-sys.h
+++ b/backends/graphics/opengl/opengl-sys.h
@@ -102,6 +102,9 @@ struct Context {
 	 */
 	void reset();
 
+	/** The maximum texture size supported by the context. */
+	GLint _maxTextureSize;
+
 	/** Whether GL_ARB_texture_non_power_of_two is available or not. */
 	bool NPOTSupported;
 
diff --git a/backends/graphics/opengl/texture.cpp b/backends/graphics/opengl/texture.cpp
index 656de20..da4ebeb 100644
--- a/backends/graphics/opengl/texture.cpp
+++ b/backends/graphics/opengl/texture.cpp
@@ -161,13 +161,6 @@ void GLTexture::updateArea(const Common::Rect &area, const Graphics::Surface &sr
 	                       _glFormat, _glType, src.getBasePtr(0, area.top)));
 }
 
-GLint Texture::_maxTextureSize = 0;
-
-void Texture::queryTextureInformation() {
-	GL_CALL(glGetIntegerv(GL_MAX_TEXTURE_SIZE, &_maxTextureSize));
-	debug(5, "OpenGL maximum texture size: %d", _maxTextureSize);
-}
-
 Texture::Texture(GLenum glIntFormat, GLenum glFormat, GLenum glType, const Graphics::PixelFormat &format)
     : _format(format), _glTexture(glIntFormat, glFormat, glType),
       _textureData(), _userPixelData(), _allDirty(false) {
diff --git a/backends/graphics/opengl/texture.h b/backends/graphics/opengl/texture.h
index b16faab..8357f29 100644
--- a/backends/graphics/opengl/texture.h
+++ b/backends/graphics/opengl/texture.h
@@ -194,17 +194,6 @@ public:
 
 	virtual void *getPalette() { return 0; }
 	virtual const void *getPalette() const { return 0; }
-
-	/**
-	 * Query texture related OpenGL information from the context. This only
-	 * queries the maximum texture size for now.
-	 */
-	static void queryTextureInformation();
-
-	/**
-	 * @return Return the maximum texture dimensions supported.
-	 */
-	static GLint getMaximumTextureSize() { return _maxTextureSize; }
 protected:
 	virtual void updateTexture();
 
@@ -220,8 +209,6 @@ private:
 	bool _allDirty;
 	Common::Rect _dirtyArea;
 	void clearDirty() { _allDirty = false; _dirtyArea = Common::Rect(); }
-
-	static GLint _maxTextureSize;
 };
 
 class TextureCLUT8 : public Texture {


Commit: db2917dde5e8aaf9514e19772b8f0f6646b18deb
    https://github.com/scummvm/scummvm/commit/db2917dde5e8aaf9514e19772b8f0f6646b18deb
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:26+01:00

Commit Message:
OPENGL: Fix texture format for BGR565.

Changed paths:
    backends/graphics/opengl/opengl-defs.h
    backends/graphics/opengl/opengl-graphics.cpp



diff --git a/backends/graphics/opengl/opengl-defs.h b/backends/graphics/opengl/opengl-defs.h
index 793955c..4de73d3 100644
--- a/backends/graphics/opengl/opengl-defs.h
+++ b/backends/graphics/opengl/opengl-defs.h
@@ -202,6 +202,7 @@ typedef GLhandleARB GLshader;
 #define GL_UNSIGNED_SHORT_5_6_5           0x8363
 
 #define GL_UNSIGNED_SHORT_4_4_4_4_REV     0x8365
+#define GL_UNSIGNED_SHORT_5_6_5_REV       0x8364
 #define GL_UNSIGNED_SHORT_1_5_5_5_REV     0x8366
 #define GL_UNSIGNED_INT_8_8_8_8           0x8035
 #define GL_UNSIGNED_INT_8_8_8_8_REV       0x8367
diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index 363fe40..ffc50ec 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -1118,8 +1118,8 @@ bool OpenGLGraphicsManager::getGLPixelFormat(const Graphics::PixelFormat &pixelF
 		return true;
 	} else if (pixelFormat == Graphics::PixelFormat(2, 5, 6, 5, 0, 0, 5, 11, 0)) { // BGR565
 		glIntFormat = GL_RGB;
-		glFormat = GL_BGR;
-		glType = GL_UNSIGNED_SHORT_5_6_5;
+		glFormat = GL_RGB;
+		glType = GL_UNSIGNED_SHORT_5_6_5_REV;
 		return true;
 	} else if (pixelFormat == Graphics::PixelFormat(2, 5, 5, 5, 1, 1, 6, 11, 0)) { // BGRA5551
 		glIntFormat = GL_RGBA;


Commit: 618adec7b06546e81028cb9fcce6151cb388fe98
    https://github.com/scummvm/scummvm/commit/618adec7b06546e81028cb9fcce6151cb388fe98
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:26+01:00

Commit Message:
OPENGL: Move color key handling for CLUT8 to TextureCLUT8.

Changed paths:
    backends/graphics/opengl/opengl-graphics.cpp
    backends/graphics/opengl/texture.cpp
    backends/graphics/opengl/texture.h



diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index ffc50ec..69af586 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -1208,20 +1208,7 @@ void OpenGLGraphicsManager::updateCursorPalette() {
 		_cursor->setPalette(0, 256, _gamePalette);
 	}
 
-	// We remove all alpha bits from the palette entry of the color key.
-	// This makes sure its properly handled as color key.
-	const Graphics::PixelFormat &hardwareFormat = _cursor->getHardwareFormat();
-	const uint32 aMask = (0xFF >> hardwareFormat.aLoss) << hardwareFormat.aShift;
-
-	if (hardwareFormat.bytesPerPixel == 2) {
-		uint16 *palette = (uint16 *)_cursor->getPalette() + _cursorKeyColor;
-		*palette &= ~aMask;
-	} else if (hardwareFormat.bytesPerPixel == 4) {
-		uint32 *palette = (uint32 *)_cursor->getPalette() + _cursorKeyColor;
-		*palette &= ~aMask;
-	} else {
-		warning("OpenGLGraphicsManager::updateCursorPalette: Unsupported pixel depth %d", hardwareFormat.bytesPerPixel);
-	}
+	_cursor->setColorKey(_cursorKeyColor);
 }
 
 void OpenGLGraphicsManager::recalculateCursorScaling() {
diff --git a/backends/graphics/opengl/texture.cpp b/backends/graphics/opengl/texture.cpp
index da4ebeb..a607528 100644
--- a/backends/graphics/opengl/texture.cpp
+++ b/backends/graphics/opengl/texture.cpp
@@ -346,6 +346,26 @@ Graphics::PixelFormat TextureCLUT8::getFormat() const {
 	return Graphics::PixelFormat::createFormatCLUT8();
 }
 
+void TextureCLUT8::setColorKey(uint colorKey) {
+	// We remove all alpha bits from the palette entry of the color key.
+	// This makes sure its properly handled as color key.
+	const Graphics::PixelFormat &hardwareFormat = getHardwareFormat();
+	const uint32 aMask = (0xFF >> hardwareFormat.aLoss) << hardwareFormat.aShift;
+
+	if (hardwareFormat.bytesPerPixel == 2) {
+		uint16 *palette = (uint16 *)_palette + colorKey;
+		*palette &= ~aMask;
+	} else if (hardwareFormat.bytesPerPixel == 4) {
+		uint32 *palette = (uint32 *)_palette + colorKey;
+		*palette &= ~aMask;
+	} else {
+		warning("TextureCLUT8::setColorKey: Unsupported pixel depth %d", hardwareFormat.bytesPerPixel);
+	}
+
+	// A palette changes means we need to refresh the whole surface.
+	flagDirty();
+}
+
 namespace {
 template<typename ColorType>
 inline void convertPalette(ColorType *dst, const byte *src, uint colors, const Graphics::PixelFormat &format) {
diff --git a/backends/graphics/opengl/texture.h b/backends/graphics/opengl/texture.h
index 8357f29..68af406 100644
--- a/backends/graphics/opengl/texture.h
+++ b/backends/graphics/opengl/texture.h
@@ -190,10 +190,15 @@ public:
 	 */
 	virtual bool hasPalette() const { return false; }
 
+	/**
+	 * Set color key for paletted textures.
+	 *
+	 * This needs to be called after any palette update affecting the color
+	 * key. Calling this multiple times will result in multiple color indices
+	 * to be treated as color keys.
+	 */
+	virtual void setColorKey(uint colorKey) {}
 	virtual void setPalette(uint start, uint colors, const byte *palData) {}
-
-	virtual void *getPalette() { return 0; }
-	virtual const void *getPalette() const { return 0; }
 protected:
 	virtual void updateTexture();
 
@@ -222,11 +227,9 @@ public:
 
 	virtual bool hasPalette() const { return true; }
 
+	virtual void setColorKey(uint colorKey);
 	virtual void setPalette(uint start, uint colors, const byte *palData);
 
-	virtual void *getPalette() { return _palette; }
-	virtual const void *getPalette() const { return _palette; }
-
 	virtual Graphics::Surface *getSurface() { return &_clut8Data; }
 	virtual const Graphics::Surface *getSurface() const { return &_clut8Data; }
 


Commit: 8b0cf0c5f7aa34e88a7702c4e9f54f5d8adc5ab8
    https://github.com/scummvm/scummvm/commit/8b0cf0c5f7aa34e88a7702c4e9f54f5d8adc5ab8
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:26+01:00

Commit Message:
OPENGL: Cleanup. Remove Texture::getHardwareFormat.

Changed paths:
    backends/graphics/opengl/texture.cpp
    backends/graphics/opengl/texture.h



diff --git a/backends/graphics/opengl/texture.cpp b/backends/graphics/opengl/texture.cpp
index a607528..0411df3 100644
--- a/backends/graphics/opengl/texture.cpp
+++ b/backends/graphics/opengl/texture.cpp
@@ -349,17 +349,16 @@ Graphics::PixelFormat TextureCLUT8::getFormat() const {
 void TextureCLUT8::setColorKey(uint colorKey) {
 	// We remove all alpha bits from the palette entry of the color key.
 	// This makes sure its properly handled as color key.
-	const Graphics::PixelFormat &hardwareFormat = getHardwareFormat();
-	const uint32 aMask = (0xFF >> hardwareFormat.aLoss) << hardwareFormat.aShift;
+	const uint32 aMask = (0xFF >> _format.aLoss) << _format.aShift;
 
-	if (hardwareFormat.bytesPerPixel == 2) {
+	if (_format.bytesPerPixel == 2) {
 		uint16 *palette = (uint16 *)_palette + colorKey;
 		*palette &= ~aMask;
-	} else if (hardwareFormat.bytesPerPixel == 4) {
+	} else if (_format.bytesPerPixel == 4) {
 		uint32 *palette = (uint32 *)_palette + colorKey;
 		*palette &= ~aMask;
 	} else {
-		warning("TextureCLUT8::setColorKey: Unsupported pixel depth %d", hardwareFormat.bytesPerPixel);
+		warning("TextureCLUT8::setColorKey: Unsupported pixel depth %d", _format.bytesPerPixel);
 	}
 
 	// A palette changes means we need to refresh the whole surface.
@@ -377,14 +376,12 @@ inline void convertPalette(ColorType *dst, const byte *src, uint colors, const G
 } // End of anonymous namespace
 
 void TextureCLUT8::setPalette(uint start, uint colors, const byte *palData) {
-	const Graphics::PixelFormat &hardwareFormat = getHardwareFormat();
-
-	if (hardwareFormat.bytesPerPixel == 2) {
-		convertPalette<uint16>((uint16 *)_palette + start, palData, colors, hardwareFormat);
-	} else if (hardwareFormat.bytesPerPixel == 4) {
-		convertPalette<uint32>((uint32 *)_palette + start, palData, colors, hardwareFormat);
+	if (_format.bytesPerPixel == 2) {
+		convertPalette<uint16>((uint16 *)_palette + start, palData, colors, _format);
+	} else if (_format.bytesPerPixel == 4) {
+		convertPalette<uint32>((uint32 *)_palette + start, palData, colors, _format);
 	} else {
-		warning("TextureCLUT8::setPalette: Unsupported pixel depth: %d", hardwareFormat.bytesPerPixel);
+		warning("TextureCLUT8::setPalette: Unsupported pixel depth: %d", _format.bytesPerPixel);
 	}
 
 	// A palette changes means we need to refresh the whole surface.
diff --git a/backends/graphics/opengl/texture.h b/backends/graphics/opengl/texture.h
index 68af406..acbfe40 100644
--- a/backends/graphics/opengl/texture.h
+++ b/backends/graphics/opengl/texture.h
@@ -173,11 +173,6 @@ public:
 	uint getHeight() const { return _userPixelData.h; }
 
 	/**
-	 * @return The hardware format of the texture data.
-	 */
-	const Graphics::PixelFormat &getHardwareFormat() const { return _format; }
-
-	/**
 	 * @return The logical format of the texture data.
 	 */
 	virtual Graphics::PixelFormat getFormat() const { return _format; }
@@ -200,12 +195,12 @@ public:
 	virtual void setColorKey(uint colorKey) {}
 	virtual void setPalette(uint start, uint colors, const byte *palData) {}
 protected:
+	const Graphics::PixelFormat _format;
+
 	virtual void updateTexture();
 
 	Common::Rect getDirtyArea() const;
 private:
-	const Graphics::PixelFormat _format;
-
 	GLTexture _glTexture;
 
 	Graphics::Surface _textureData;


Commit: de3846923c9a00ff6a8563e33858e12a72bfebda
    https://github.com/scummvm/scummvm/commit/de3846923c9a00ff6a8563e33858e12a72bfebda
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:26+01:00

Commit Message:
OPENGL: Introduce simple abstraction for surfaces.

This is basically an interface extracted from Texture without any knowledge
about any actual implementation, except for copyRectToTexture, fill, and
dirty rect handling. These are convenient helpers.

Changed paths:
    backends/graphics/opengl/opengl-graphics.cpp
    backends/graphics/opengl/opengl-graphics.h
    backends/graphics/opengl/texture.cpp
    backends/graphics/opengl/texture.h



diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index 69af586..6784bfe 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -273,9 +273,9 @@ OSystem::TransactionError OpenGLGraphicsManager::endGFXTransaction() {
 		_gameScreen = nullptr;
 
 #ifdef USE_RGB_COLOR
-		_gameScreen = createTexture(_currentState.gameFormat);
+		_gameScreen = createSurface(_currentState.gameFormat);
 #else
-		_gameScreen = createTexture(Graphics::PixelFormat::createFormatCLUT8());
+		_gameScreen = createSurface(Graphics::PixelFormat::createFormatCLUT8());
 #endif
 		assert(_gameScreen);
 		if (_gameScreen->hasPalette()) {
@@ -615,7 +615,7 @@ void OpenGLGraphicsManager::setMouseCursor(const void *buf, uint w, uint h, int
 		} else {
 			textureFormat = _defaultFormatAlpha;
 		}
-		_cursor = createTexture(textureFormat, true);
+		_cursor = createSurface(textureFormat, true);
 		assert(_cursor);
 		_cursor->enableLinearFiltering(_currentState.graphicsMode == GFX_LINEAR);
 	}
@@ -830,7 +830,7 @@ void OpenGLGraphicsManager::setActualScreenSize(uint width, uint height) {
 		delete _overlay;
 		_overlay = nullptr;
 
-		_overlay = createTexture(_defaultFormatAlpha);
+		_overlay = createSurface(_defaultFormatAlpha);
 		assert(_overlay);
 		// We always filter the overlay with GL_LINEAR. This assures it's
 		// readable in case it needs to be scaled and does not affect it
@@ -845,7 +845,7 @@ void OpenGLGraphicsManager::setActualScreenSize(uint width, uint height) {
 		delete _osd;
 		_osd = nullptr;
 
-		_osd = createTexture(_defaultFormatAlpha);
+		_osd = createSurface(_defaultFormatAlpha);
 		assert(_osd);
 		// We always filter the osd with GL_LINEAR. This assures it's
 		// readable in case it needs to be scaled and does not affect it
@@ -941,40 +941,40 @@ void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &def
 	_defaultFormatAlpha = defaultFormatAlpha;
 
 	if (_gameScreen) {
-		_gameScreen->recreateInternalTexture();
+		_gameScreen->recreate();
 	}
 
 	if (_overlay) {
-		_overlay->recreateInternalTexture();
+		_overlay->recreate();
 	}
 
 	if (_cursor) {
-		_cursor->recreateInternalTexture();
+		_cursor->recreate();
 	}
 
 #ifdef USE_OSD
 	if (_osd) {
-		_osd->recreateInternalTexture();
+		_osd->recreate();
 	}
 #endif
 }
 
 void OpenGLGraphicsManager::notifyContextDestroy() {
 	if (_gameScreen) {
-		_gameScreen->releaseInternalTexture();
+		_gameScreen->destroy();
 	}
 
 	if (_overlay) {
-		_overlay->releaseInternalTexture();
+		_overlay->destroy();
 	}
 
 	if (_cursor) {
-		_cursor->releaseInternalTexture();
+		_cursor->destroy();
 	}
 
 #ifdef USE_OSD
 	if (_osd) {
-		_osd->releaseInternalTexture();
+		_osd->destroy();
 	}
 #endif
 
@@ -1028,7 +1028,7 @@ void OpenGLGraphicsManager::setMousePosition(int x, int y) {
 	}
 }
 
-Texture *OpenGLGraphicsManager::createTexture(const Graphics::PixelFormat &format, bool wantAlpha) {
+Surface *OpenGLGraphicsManager::createSurface(const Graphics::PixelFormat &format, bool wantAlpha) {
 	GLenum glIntFormat, glFormat, glType;
 	if (format.bytesPerPixel == 1) {
 		const Graphics::PixelFormat &virtFormat = wantAlpha ? _defaultFormatAlpha : _defaultFormat;
diff --git a/backends/graphics/opengl/opengl-graphics.h b/backends/graphics/opengl/opengl-graphics.h
index b6e3c13..40605f0 100644
--- a/backends/graphics/opengl/opengl-graphics.h
+++ b/backends/graphics/opengl/opengl-graphics.h
@@ -40,7 +40,7 @@ namespace OpenGL {
 // SurfaceSDL backend enables it and disabling it can cause issues in sdl.cpp.
 #define USE_OSD 1
 
-class Texture;
+class Surface;
 #if !USE_FORCED_GLES
 class Shader;
 #endif
@@ -190,15 +190,15 @@ protected:
 
 private:
 	/**
-	 * Create a texture with the specified pixel format.
+	 * Create a surface with the specified pixel format.
 	 *
-	 * @param format    The pixel format the Texture object should accept as
+	 * @param format    The pixel format the Surface object should accept as
 	 *                  input.
-	 * @param wantAlpha For CLUT8 textures this marks whether an alpha
+	 * @param wantAlpha For CLUT8 surfaces this marks whether an alpha
 	 *                  channel should be used.
-	 * @return A pointer to the texture or nullptr on failure.
+	 * @return A pointer to the surface or nullptr on failure.
 	 */
-	Texture *createTexture(const Graphics::PixelFormat &format, bool wantAlpha = false);
+	Surface *createSurface(const Graphics::PixelFormat &format, bool wantAlpha = false);
 
 	//
 	// Transaction support
@@ -386,7 +386,7 @@ private:
 	/**
 	 * The virtual game screen.
 	 */
-	Texture *_gameScreen;
+	Surface *_gameScreen;
 
 	/**
 	 * The game palette if in CLUT8 mode.
@@ -405,7 +405,7 @@ private:
 	/**
 	 * The overlay screen.
 	 */
-	Texture *_overlay;
+	Surface *_overlay;
 
 	/**
 	 * Whether the overlay is visible or not.
@@ -424,7 +424,7 @@ private:
 	/**
 	 * The cursor image.
 	 */
-	Texture *_cursor;
+	Surface *_cursor;
 
 	/**
 	 * X coordinate of the cursor in phyiscal coordinates.
@@ -551,7 +551,7 @@ private:
 	/**
 	 * The OSD's contents.
 	 */
-	Texture *_osd;
+	Surface *_osd;
 
 	/**
 	 * Current opacity level of the OSD.
diff --git a/backends/graphics/opengl/texture.cpp b/backends/graphics/opengl/texture.cpp
index 0411df3..e9713ee 100644
--- a/backends/graphics/opengl/texture.cpp
+++ b/backends/graphics/opengl/texture.cpp
@@ -161,50 +161,15 @@ void GLTexture::updateArea(const Common::Rect &area, const Graphics::Surface &sr
 	                       _glFormat, _glType, src.getBasePtr(0, area.top)));
 }
 
-Texture::Texture(GLenum glIntFormat, GLenum glFormat, GLenum glType, const Graphics::PixelFormat &format)
-    : _format(format), _glTexture(glIntFormat, glFormat, glType),
-      _textureData(), _userPixelData(), _allDirty(false) {
-	recreateInternalTexture();
-}
-
-Texture::~Texture() {
-	_textureData.free();
-}
-
-void Texture::releaseInternalTexture() {
-	_glTexture.destroy();
-}
-
-void Texture::recreateInternalTexture() {
-	_glTexture.create();
+//
+// Surface
+//
 
-	// In case image date exists assure it will be completely refreshed next
-	// time.
-	if (_textureData.getPixels()) {
-		flagDirty();
-	}
+Surface::Surface()
+    : _allDirty(false), _dirtyArea() {
 }
 
-void Texture::enableLinearFiltering(bool enable) {
-	_glTexture.enableLinearFiltering(enable);
-}
-
-void Texture::allocate(uint width, uint height) {
-	// Assure the texture can contain our user data.
-	_glTexture.setSize(width, height);
-
-	// In case the needed texture dimension changed we will reinitialize the
-	// texture data buffer.
-	if (_glTexture.getWidth() != _textureData.w || _glTexture.getHeight() != _textureData.h) {
-		// Create a buffer for the texture data.
-		_textureData.create(_glTexture.getWidth(), _glTexture.getHeight(), _format);
-	}
-
-	// Create a sub-buffer for raw access.
-	_userPixelData = _textureData.getSubArea(Common::Rect(width, height));
-}
-
-void Texture::copyRectToTexture(uint x, uint y, uint w, uint h, const void *srcPtr, uint srcPitch) {
+void Surface::copyRectToTexture(uint x, uint y, uint w, uint h, const void *srcPtr, uint srcPitch) {
 	Graphics::Surface *dstSurf = getSurface();
 	assert(x + w <= dstSurf->w);
 	assert(y + h <= dstSurf->h);
@@ -235,13 +200,67 @@ void Texture::copyRectToTexture(uint x, uint y, uint w, uint h, const void *srcP
 	}
 }
 
-void Texture::fill(uint32 color) {
+void Surface::fill(uint32 color) {
 	Graphics::Surface *dst = getSurface();
 	dst->fillRect(Common::Rect(dst->w, dst->h), color);
 
 	flagDirty();
 }
 
+Common::Rect Surface::getDirtyArea() const {
+	if (_allDirty) {
+		return Common::Rect(getWidth(), getHeight());
+	} else {
+		return _dirtyArea;
+	}
+}
+
+//
+// Surface implementations
+//
+
+Texture::Texture(GLenum glIntFormat, GLenum glFormat, GLenum glType, const Graphics::PixelFormat &format)
+    : Surface(), _format(format), _glTexture(glIntFormat, glFormat, glType),
+      _textureData(), _userPixelData() {
+}
+
+Texture::~Texture() {
+	_textureData.free();
+}
+
+void Texture::destroy() {
+	_glTexture.destroy();
+}
+
+void Texture::recreate() {
+	_glTexture.create();
+
+	// In case image date exists assure it will be completely refreshed next
+	// time.
+	if (_textureData.getPixels()) {
+		flagDirty();
+	}
+}
+
+void Texture::enableLinearFiltering(bool enable) {
+	_glTexture.enableLinearFiltering(enable);
+}
+
+void Texture::allocate(uint width, uint height) {
+	// Assure the texture can contain our user data.
+	_glTexture.setSize(width, height);
+
+	// In case the needed texture dimension changed we will reinitialize the
+	// texture data buffer.
+	if (_glTexture.getWidth() != _textureData.w || _glTexture.getHeight() != _textureData.h) {
+		// Create a buffer for the texture data.
+		_textureData.create(_glTexture.getWidth(), _glTexture.getHeight(), _format);
+	}
+
+	// Create a sub-buffer for raw access.
+	_userPixelData = _textureData.getSubArea(Common::Rect(width, height));
+}
+
 void Texture::draw(GLfloat x, GLfloat y, GLfloat w, GLfloat h) {
 	// Only do any processing when the Texture is initialized.
 	if (!_textureData.getPixels()) {
@@ -311,14 +330,6 @@ void Texture::updateTexture() {
 	clearDirty();
 }
 
-Common::Rect Texture::getDirtyArea() const {
-	if (_allDirty) {
-		return Common::Rect(_userPixelData.w, _userPixelData.h);
-	} else {
-		return _dirtyArea;
-	}
-}
-
 TextureCLUT8::TextureCLUT8(GLenum glIntFormat, GLenum glFormat, GLenum glType, const Graphics::PixelFormat &format)
     : Texture(glIntFormat, glFormat, glType, format), _clut8Data(), _palette(new byte[256 * format.bytesPerPixel]) {
 	memset(_palette, 0, sizeof(byte) * format.bytesPerPixel);
diff --git a/backends/graphics/opengl/texture.h b/backends/graphics/opengl/texture.h
index acbfe40..343a32b 100644
--- a/backends/graphics/opengl/texture.h
+++ b/backends/graphics/opengl/texture.h
@@ -118,70 +118,78 @@ private:
 };
 
 /**
- * An OpenGL texture wrapper. It automatically takes care of all OpenGL
- * texture handling issues and also provides access to the texture data.
+ * Interface for OpenGL implementations of a 2D surface.
  */
-class Texture {
+class Surface {
 public:
-	/**
-	 * Create a new texture with the specific internal format.
-	 *
-	 * @param glIntFormat The internal format to use.
-	 * @param glFormat    The input format.
-	 * @param glType      The input type.
-	 * @param format      The format used for the texture input.
-	 */
-	Texture(GLenum glIntFormat, GLenum glFormat, GLenum glType, const Graphics::PixelFormat &format);
-	virtual ~Texture();
+	Surface();
+	virtual ~Surface() {}
 
 	/**
-	 * Destroy the OpenGL texture name.
+	 * Destroy OpenGL description of surface.
 	 */
-	void releaseInternalTexture();
+	virtual void destroy() = 0;
 
 	/**
-	 * Create the OpenGL texture name and flag the whole texture as dirty.
+	 * Recreate OpenGL description of surface.
 	 */
-	void recreateInternalTexture();
+	virtual void recreate() = 0;
 
 	/**
 	 * Enable or disable linear texture filtering.
 	 *
 	 * @param enable true to enable and false to disable.
 	 */
-	void enableLinearFiltering(bool enable);
+	virtual void enableLinearFiltering(bool enable) = 0;
 
 	/**
-	 * Allocate texture space for the desired dimensions. This wraps any
-	 * handling of requirements for POT textures.
+	 * Allocate storage for surface.
 	 *
 	 * @param width  The desired logical width.
 	 * @param height The desired logical height.
 	 */
-	virtual void allocate(uint width, uint height);
+	virtual void allocate(uint width, uint height) = 0;
 
+	/**
+	 * Copy image data to the surface.
+	 *
+	 * The format of the input data needs to match the format returned by
+	 * getFormat.
+	 *
+	 * @param x        X coordinate of upper left corner to copy data to.
+	 * @param y        Y coordinate of upper left corner to copy data to.
+	 * @param w        Width of the image data to copy.
+	 * @param h        Height of the image data to copy.
+	 * @param src      Pointer to image data.
+	 * @param srcPitch The number of bytes in a row of the image data.
+	 */
 	void copyRectToTexture(uint x, uint y, uint w, uint h, const void *src, uint srcPitch);
 
+	/**
+	 * Fill the surface with a fixed color.
+	 *
+	 * @param color Color value in format returned by getFormat.
+	 */
 	void fill(uint32 color);
 
-	void draw(GLfloat x, GLfloat y, GLfloat w, GLfloat h);
+	virtual void draw(GLfloat x, GLfloat y, GLfloat w, GLfloat h) = 0;
 
 	void flagDirty() { _allDirty = true; }
 	bool isDirty() const { return _allDirty || !_dirtyArea.isEmpty(); }
 
-	uint getWidth() const { return _userPixelData.w; }
-	uint getHeight() const { return _userPixelData.h; }
+	virtual uint getWidth() const = 0;
+	virtual uint getHeight() const = 0;
 
 	/**
 	 * @return The logical format of the texture data.
 	 */
-	virtual Graphics::PixelFormat getFormat() const { return _format; }
+	virtual Graphics::PixelFormat getFormat() const = 0;
 
-	virtual Graphics::Surface *getSurface() { return &_userPixelData; }
-	virtual const Graphics::Surface *getSurface() const { return &_userPixelData; }
+	virtual Graphics::Surface *getSurface() = 0;
+	virtual const Graphics::Surface *getSurface() const = 0;
 
 	/**
-	 * @return Whether the texture data is using a palette.
+	 * @return Whether the surface is having a palette.
 	 */
 	virtual bool hasPalette() const { return false; }
 
@@ -195,20 +203,62 @@ public:
 	virtual void setColorKey(uint colorKey) {}
 	virtual void setPalette(uint start, uint colors, const byte *palData) {}
 protected:
+	void clearDirty() { _allDirty = false; _dirtyArea = Common::Rect(); }
+
+	Common::Rect getDirtyArea() const;
+private:
+	bool _allDirty;
+	Common::Rect _dirtyArea;
+};
+
+/**
+ * An OpenGL texture wrapper. It automatically takes care of all OpenGL
+ * texture handling issues and also provides access to the texture data.
+ */
+class Texture : public Surface {
+public:
+	/**
+	 * Create a new texture with the specific internal format.
+	 *
+	 * @param glIntFormat The internal format to use.
+	 * @param glFormat    The input format.
+	 * @param glType      The input type.
+	 * @param format      The format used for the texture input.
+	 */
+	Texture(GLenum glIntFormat, GLenum glFormat, GLenum glType, const Graphics::PixelFormat &format);
+	virtual ~Texture();
+
+	virtual void destroy();
+
+	virtual void recreate();
+
+	virtual void enableLinearFiltering(bool enable);
+
+	virtual void allocate(uint width, uint height);
+
+	virtual void draw(GLfloat x, GLfloat y, GLfloat w, GLfloat h);
+
+	virtual uint getWidth() const { return _userPixelData.w; }
+	virtual uint getHeight() const { return _userPixelData.h; }
+
+	/**
+	 * @return The logical format of the texture data.
+	 */
+	virtual Graphics::PixelFormat getFormat() const { return _format; }
+
+	virtual Graphics::Surface *getSurface() { return &_userPixelData; }
+	virtual const Graphics::Surface *getSurface() const { return &_userPixelData; }
+
+protected:
 	const Graphics::PixelFormat _format;
 
 	virtual void updateTexture();
 
-	Common::Rect getDirtyArea() const;
 private:
 	GLTexture _glTexture;
 
 	Graphics::Surface _textureData;
 	Graphics::Surface _userPixelData;
-
-	bool _allDirty;
-	Common::Rect _dirtyArea;
-	void clearDirty() { _allDirty = false; _dirtyArea = Common::Rect(); }
 };
 
 class TextureCLUT8 : public Texture {


Commit: e66e9e44d358b0cc90d128c31e695a8ace4177fa
    https://github.com/scummvm/scummvm/commit/e66e9e44d358b0cc90d128c31e695a8ace4177fa
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:26+01:00

Commit Message:
OPENGL: Accelerate palette lookups with shaders.

This currently is limited to GL contexts.

Changed paths:
    backends/graphics/opengl/context.cpp
    backends/graphics/opengl/opengl-defs.h
    backends/graphics/opengl/opengl-func.h
    backends/graphics/opengl/opengl-graphics.cpp
    backends/graphics/opengl/opengl-sys.h
    backends/graphics/opengl/shader.cpp
    backends/graphics/opengl/shader.h
    backends/graphics/opengl/texture.cpp
    backends/graphics/opengl/texture.h



diff --git a/backends/graphics/opengl/context.cpp b/backends/graphics/opengl/context.cpp
index 209c38e..10468f3 100644
--- a/backends/graphics/opengl/context.cpp
+++ b/backends/graphics/opengl/context.cpp
@@ -45,6 +45,9 @@ void Context::reset() {
 	NPOTSupported = false;
 #if !USE_FORCED_GLES && !USE_FORCED_GLES2
 	shadersSupported = false;
+	multitextureSupported = false;
+	framebufferObjectSupported = false;
+	textureRGSupported = false;
 #endif
 
 #define GL_FUNC_DEF(ret, name, param) name = nullptr;
@@ -216,6 +219,12 @@ void OpenGLGraphicsManager::initializeGLContext() {
 			ARBVertexShader = true;
 		} else if (token == "GL_ARB_fragment_shader") {
 			ARBFragmentShader = true;
+		} else if (token == "GL_ARB_multitexture") {
+			g_context.multitextureSupported = true;
+		} else if (token == "GL_ARB_texture_rg") {
+			g_context.textureRGSupported = true;
+		} else if (token == "GL_EXT_framebuffer_object") {
+			g_context.framebufferObjectSupported = true;
 #endif
 		}
 	}
diff --git a/backends/graphics/opengl/opengl-defs.h b/backends/graphics/opengl/opengl-defs.h
index 4de73d3..733fc29 100644
--- a/backends/graphics/opengl/opengl-defs.h
+++ b/backends/graphics/opengl/opengl-defs.h
@@ -183,6 +183,9 @@ typedef GLhandleARB GLshader;
 #define GL_BGR                            0x80E0
 #define GL_BGRA                           0x80E1
 
+#define GL_RED                            0x1903
+#define GL_R8                             0x8229
+
 /* PixelStoreParameter */
 #define GL_UNPACK_ALIGNMENT               0x0CF5
 #define GL_PACK_ALIGNMENT                 0x0D05
@@ -242,8 +245,18 @@ typedef GLhandleARB GLshader;
 #define GL_COMPILE_STATUS                 0x8B81
 #define GL_LINK_STATUS                    0x8B82
 #define GL_INFO_LOG_LENGTH                0x8B84
+#define GL_CURRENT_PROGRAM                0x8B8D
 
 /* Textures */
 #define GL_TEXTURE0                       0x84C0
+#define GL_TEXTURE1                       0x84C1
+
+/* GetPName */
+#define GL_VIEWPORT                       0x0BA2
+#define GL_FRAMEBUFFER_BINDING            0x8CA6
+
+/* Framebuffer objects */
+#define GL_COLOR_ATTACHMENT0              0x8CE0
+#define GL_FRAMEBUFFER                    0x8D40
 
 #endif
diff --git a/backends/graphics/opengl/opengl-func.h b/backends/graphics/opengl/opengl-func.h
index fb08779..763d5e9 100644
--- a/backends/graphics/opengl/opengl-func.h
+++ b/backends/graphics/opengl/opengl-func.h
@@ -77,6 +77,7 @@
 
 GL_FUNC_DEF(void, glEnable, (GLenum cap));
 GL_FUNC_DEF(void, glDisable, (GLenum cap));
+GL_FUNC_DEF(GLboolean, glIsEnabled, (GLenum cap));
 GL_FUNC_DEF(void, glClear, (GLbitfield mask));
 GL_FUNC_DEF(void, glColor4f, (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha));
 GL_FUNC_DEF(void, glViewport, (GLint x, GLint y, GLsizei width, GLsizei height));
@@ -128,10 +129,16 @@ GL_FUNC_2_DEF(void, glGetShaderiv, glGetObjectParameterivARB, (GLshader shader,
 GL_FUNC_2_DEF(void, glGetShaderInfoLog, glGetInfoLogARB, (GLshader shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog));
 GL_FUNC_2_DEF(void, glShaderSource, glShaderSourceARB, (GLshader shader, GLsizei count, const GLchar *const *string, const GLint *length));
 GL_FUNC_2_DEF(void, glCompileShader, glCompileShaderARB, (GLshader shader));
+
+#if !USE_FORCED_GLES2
+GL_FUNC_2_DEF(void, glBindFramebuffer, glBindFramebufferEXT, (GLenum target, GLuint renderbuffer));
+GL_FUNC_2_DEF(void, glDeleteFramebuffers, glDeleteFramebuffersEXT, (GLsizei n, const GLuint *framebuffers));
+GL_FUNC_2_DEF(void, glGenFramebuffers, glGenFramebuffersEXT, (GLsizei n, GLuint *renderbuffers));
+GL_FUNC_2_DEF(void, glFramebufferTexture2D, glFramebufferTexture2DEXT, (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level));
+GL_FUNC_2_DEF(GLenum, glCheckFramebufferStatus, glCheckFramebufferStatusEXT, (GLenum target));
 #endif
 
-#if !USE_FORCED_GL && !USE_FORCED_GLES
-GL_FUNC_DEF(void, glActiveTexture, (GLenum texture));
+GL_FUNC_2_DEF(void, glActiveTexture, glActiveTextureARB, (GLenum texture));
 #endif
 
 #ifdef DEFINED_GL_EXT_FUNC_DEF
diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index 6784bfe..df939fb 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -1031,6 +1031,12 @@ void OpenGLGraphicsManager::setMousePosition(int x, int y) {
 Surface *OpenGLGraphicsManager::createSurface(const Graphics::PixelFormat &format, bool wantAlpha) {
 	GLenum glIntFormat, glFormat, glType;
 	if (format.bytesPerPixel == 1) {
+#if !USE_FORCED_GLES && !USE_FORCED_GLES2
+		if (TextureCLUT8GPU::isSupportedByContext()) {
+			return new TextureCLUT8GPU();
+		}
+#endif
+
 		const Graphics::PixelFormat &virtFormat = wantAlpha ? _defaultFormatAlpha : _defaultFormat;
 		const bool supported = getGLPixelFormat(virtFormat, glIntFormat, glFormat, glType);
 		if (!supported) {
diff --git a/backends/graphics/opengl/opengl-sys.h b/backends/graphics/opengl/opengl-sys.h
index 4d14348..9df5efc 100644
--- a/backends/graphics/opengl/opengl-sys.h
+++ b/backends/graphics/opengl/opengl-sys.h
@@ -111,6 +111,15 @@ struct Context {
 #if !USE_FORCED_GLES && !USE_FORCED_GLES2
 	/** Whether shader support is available or not. */
 	bool shadersSupported;
+
+	/** Whether multi texture support is available or not. */
+	bool multitextureSupported;
+
+	/** Whether (GLES2) RG texture formats are supported. */
+	bool textureRGSupported;
+
+	/** Whether FBO support is available or not. */
+	bool framebufferObjectSupported;
 #endif
 
 #define GL_FUNC_DEF(ret, name, param) ret (GL_CALL_CONV *name)param
diff --git a/backends/graphics/opengl/shader.cpp b/backends/graphics/opengl/shader.cpp
index 9e106a8..c251ec1 100644
--- a/backends/graphics/opengl/shader.cpp
+++ b/backends/graphics/opengl/shader.cpp
@@ -171,6 +171,16 @@ void Shader::activate(const GLfloat *projectionMatrix) {
 	GL_CALL(glUniform1i(_textureLocation, 0));
 }
 
+GLint Shader::getUniformLocation(const char *name) const {
+	GLint result = -1;
+	GL_ASSIGN(result, glGetUniformLocation(_program, name));
+	return result;
+}
+
+void Shader::setUniformI(GLint location, GLint value) {
+	GL_CALL(glUniform1i(location, value));
+}
+
 GLshader Shader::compileShader(const char *source, GLenum shaderType) {
 	GLshader handle;
 	GL_ASSIGN(handle, glCreateShader(shaderType));
diff --git a/backends/graphics/opengl/shader.h b/backends/graphics/opengl/shader.h
index f9dcbb0..458ecb9 100644
--- a/backends/graphics/opengl/shader.h
+++ b/backends/graphics/opengl/shader.h
@@ -71,6 +71,24 @@ public:
 	 * @param projectionMatrix Projection matrix to use.
 	 */
 	void activate(const GLfloat *projectionMatrix);
+
+	/**
+	 * Return location for uniform with given name.
+	 *
+	 * @param name Name of the uniform to look up in the shader.
+	 * @return The location or -1 if uniform was not found.
+	 */
+	GLint getUniformLocation(const char *name) const;
+
+	/**
+	 * Bind value to uniform.
+	 *
+	 * Note: this only works when the shader is actived by activate.
+	 *
+	 * @param location Location of the uniform.
+	 * @param value    The value to be set.
+	 */
+	void setUniformI(GLint location, GLint value);
 protected:
 	/**
 	 * Vertex shader sources.
diff --git a/backends/graphics/opengl/texture.cpp b/backends/graphics/opengl/texture.cpp
index e9713ee..5ae4987 100644
--- a/backends/graphics/opengl/texture.cpp
+++ b/backends/graphics/opengl/texture.cpp
@@ -504,4 +504,274 @@ void TextureRGB555::updateTexture() {
 }
 #endif // !USE_FORCED_GL
 
+#if !USE_FORCED_GLES && !USE_FORCED_GLES2
+namespace {
+const char *const g_lookUpFragmentShaderGL =
+	"varying vec2 texCoord;\n"
+	"varying vec4 blendColor;\n"
+	"\n"
+	"uniform sampler2D texture;\n"
+	"uniform sampler2D palette;\n"
+	"\n"
+	"const float adjustFactor = 255.0 / 256.0 + 1.0 / (2.0 * 256.0);"
+	"\n"
+	"void main(void) {\n"
+	"\tvec4 index = texture2D(texture, texCoord);\n"
+	"\tgl_FragColor = blendColor * texture2D(palette, vec2(index.x * adjustFactor, 0.0));\n"
+	"}\n";
+} // End of anonymous namespace
+
+TextureCLUT8GPU::TextureCLUT8GPU()
+    : _clut8Texture(GL_R8, GL_RED, GL_UNSIGNED_BYTE),
+      _paletteTexture(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE),
+      _glTexture(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE),
+      _glFBO(0), _clut8Vertices(), _projectionMatrix(),
+      _lookUpShader(nullptr), _paletteLocation(-1),
+      _clut8Data(), _userPixelData(), _palette(), _paletteDirty(false) {
+	// Allocate space for 256 colors.
+	_paletteTexture.setSize(256, 1);
+
+	_lookUpShader = new Shader(g_defaultVertexShader, g_lookUpFragmentShaderGL);
+	_lookUpShader->recreate();
+	_paletteLocation = _lookUpShader->getUniformLocation("palette");
+
+	setupFBO();
+}
+
+TextureCLUT8GPU::~TextureCLUT8GPU() {
+	delete _lookUpShader;
+	GL_CALL_SAFE(glDeleteFramebuffers, (1, &_glFBO));
+	_clut8Data.free();
+}
+
+void TextureCLUT8GPU::destroy() {
+	_clut8Texture.destroy();
+	_paletteTexture.destroy();
+	_glTexture.destroy();
+	_lookUpShader->destroy();
+
+	GL_CALL(glDeleteFramebuffers(1, &_glFBO));
+	_glFBO = 0;
+}
+
+void TextureCLUT8GPU::recreate() {
+	_clut8Texture.create();
+	_paletteTexture.create();
+	_glTexture.create();
+	_lookUpShader->recreate();
+	_paletteLocation = _lookUpShader->getUniformLocation("palette");
+	setupFBO();
+
+	// In case image date exists assure it will be completely refreshed next
+	// time.
+	if (_clut8Data.getPixels()) {
+		flagDirty();
+		_paletteDirty = true;
+	}
+}
+
+void TextureCLUT8GPU::enableLinearFiltering(bool enable) {
+	_glTexture.enableLinearFiltering(enable);
+}
+
+void TextureCLUT8GPU::allocate(uint width, uint height) {
+	// Assure the texture can contain our user data.
+	_clut8Texture.setSize(width, height);
+	_glTexture.setSize(width, height);
+
+	// In case the needed texture dimension changed we will reinitialize the
+	// texture data buffer.
+	if (_clut8Texture.getWidth() != _clut8Data.w || _clut8Texture.getHeight() != _clut8Data.h) {
+		// Create a buffer for the texture data.
+		_clut8Data.create(_clut8Texture.getWidth(), _clut8Texture.getHeight(), Graphics::PixelFormat::createFormatCLUT8());
+	}
+
+	// Create a sub-buffer for raw access.
+	_userPixelData = _clut8Data.getSubArea(Common::Rect(width, height));
+
+	// Setup structures for internal rendering to _glTexture.
+	_clut8Vertices[0] = 0;
+	_clut8Vertices[1] = 0;
+
+	_clut8Vertices[2] = width;
+	_clut8Vertices[3] = 0;
+
+	_clut8Vertices[4] = 0;
+	_clut8Vertices[5] = height;
+
+	_clut8Vertices[6] = width;
+	_clut8Vertices[7] = height;
+
+	_projectionMatrix[ 0] =  2.0f / _glTexture.getWidth();
+	_projectionMatrix[ 1] =  0.0f;
+	_projectionMatrix[ 2] =  0.0f;
+	_projectionMatrix[ 3] =  0.0f;
+
+	_projectionMatrix[ 4] =  0.0f;
+	_projectionMatrix[ 5] =  2.0f / _glTexture.getHeight();
+	_projectionMatrix[ 6] =  0.0f;
+	_projectionMatrix[ 7] =  0.0f;
+
+	_projectionMatrix[ 8] =  0.0f;
+	_projectionMatrix[ 9] =  0.0f;
+	_projectionMatrix[10] =  0.0f;
+	_projectionMatrix[11] =  0.0f;
+
+	_projectionMatrix[12] = -1.0f;
+	_projectionMatrix[13] = -1.0f;
+	_projectionMatrix[14] =  0.0f;
+	_projectionMatrix[15] =  1.0f;
+}
+
+void TextureCLUT8GPU::draw(GLfloat x, GLfloat y, GLfloat w, GLfloat h) {
+	// Only do any processing when the Texture is initialized.
+	if (!_clut8Data.getPixels()) {
+		return;
+	}
+
+	// First update any potentional changes.
+	updateTextures();
+
+	// Set the texture.
+	_glTexture.bind();
+
+	// Calculate the screen rect where the texture will be drawn.
+	const GLfloat vertices[4*2] = {
+		x,     y,
+		x + w, y,
+		x,     y + h,
+		x + w, y + h
+	};
+
+	// Setup coordinates for drawing.
+	g_context.setDrawCoordinates(vertices, _glTexture.getTexCoords());
+
+	// Draw the texture to the screen buffer.
+	GL_CALL(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
+}
+
+Graphics::PixelFormat TextureCLUT8GPU::getFormat() const {
+	return Graphics::PixelFormat::createFormatCLUT8();
+}
+
+void TextureCLUT8GPU::setColorKey(uint colorKey) {
+	_palette[colorKey * 4 + 3] = 0x00;
+
+	_paletteDirty = true;
+}
+
+void TextureCLUT8GPU::setPalette(uint start, uint colors, const byte *palData) {
+	byte *dst = _palette + start * 4;
+
+	while (colors-- > 0) {
+		memcpy(dst, palData, 3);
+		dst[3] = 0xFF;
+
+		dst += 4;
+		palData += 3;
+	}
+
+	_paletteDirty = true;
+}
+
+void TextureCLUT8GPU::updateTextures() {
+	const bool needLookUp = Surface::isDirty() || _paletteDirty;
+
+	// Update CLUT8 texture if necessary.
+	if (Surface::isDirty()) {
+		_clut8Texture.updateArea(getDirtyArea(), _clut8Data);
+		clearDirty();
+	}
+
+	// Update palette if necessary.
+	if (_paletteDirty) {
+		Graphics::Surface palSurface;
+		palSurface.init(256, 1, 256, _palette,
+#ifdef SCUMM_LITTLE_ENDIAN
+		                Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24) // ABGR8888
+#else
+		                Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0) // RGBA8888
+#endif
+		               );
+
+		_paletteTexture.updateArea(Common::Rect(256, 1), palSurface);
+		_paletteDirty = false;
+	}
+
+	// In case any data changed, do color look up and save result in _glTexture.
+	if (needLookUp) {
+		lookUpColors();
+	}
+}
+
+void TextureCLUT8GPU::lookUpColors() {
+	// Save old state.
+	GLint oldProgram = 0;
+	GL_CALL(glGetIntegerv(GL_CURRENT_PROGRAM, &oldProgram));
+
+	GLint viewport[4];
+	GL_CALL(glGetIntegerv(GL_VIEWPORT, viewport));
+
+	GLboolean scissorState;
+	GL_ASSIGN(scissorState, glIsEnabled(GL_SCISSOR_TEST));
+	GLboolean blendState;
+	GL_ASSIGN(blendState, glIsEnabled(GL_BLEND));
+
+	GLint oldFBO = 0;
+	GL_CALL(glGetIntegerv(GL_FRAMEBUFFER_BINDING, &oldFBO));
+
+	// Update state.
+	GL_CALL(glViewport(0, 0, _glTexture.getWidth(), _glTexture.getHeight()));
+	GL_CALL(glDisable(GL_SCISSOR_TEST));
+	GL_CALL(glDisable(GL_BLEND));
+
+	// Bind framebuffer.
+	GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, _glFBO));
+
+	// Set the palette texture.
+	GL_CALL(glActiveTexture(GL_TEXTURE1));
+	_paletteTexture.bind();
+
+	// Set the clut8 texture.
+	GL_CALL(glActiveTexture(GL_TEXTURE0));
+	_clut8Texture.bind();
+
+	// Do color look up.
+	_lookUpShader->activate(_projectionMatrix);
+	_lookUpShader->setUniformI(_paletteLocation, 1);
+	g_context.setDrawCoordinates(_clut8Vertices, _clut8Texture.getTexCoords());
+	GL_CALL(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
+
+	// Restore old state.
+	GL_CALL(glUseProgram(oldProgram));
+	GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, oldFBO));
+
+	if (blendState) {
+		GL_CALL(glEnable(GL_BLEND));
+	}
+	if (scissorState) {
+		GL_CALL(glEnable(GL_SCISSOR_TEST));
+	}
+	GL_CALL(glViewport(viewport[0], viewport[1], viewport[2], viewport[3]));
+}
+
+void TextureCLUT8GPU::setupFBO() {
+	// Allocate framebuffer object if necessary.
+	if (!_glFBO) {
+		GL_CALL(glGenFramebuffers(1, &_glFBO));
+	}
+
+	// Save old FBO.
+	GLint oldFBO = 0;
+	GL_CALL(glGetIntegerv(GL_FRAMEBUFFER_BINDING, &oldFBO));
+
+	// Attach destination texture to FBO.
+	GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, _glFBO));
+	GL_CALL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _glTexture.getGLTexture(), 0));
+
+	// Restore old FBO.
+	GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, oldFBO));
+}
+#endif // !USE_FORCED_GLES && !USE_FORCED_GLES2
+
 } // End of namespace OpenGL
diff --git a/backends/graphics/opengl/texture.h b/backends/graphics/opengl/texture.h
index 343a32b..06fe47a 100644
--- a/backends/graphics/opengl/texture.h
+++ b/backends/graphics/opengl/texture.h
@@ -32,6 +32,8 @@
 
 namespace OpenGL {
 
+class Shader;
+
 /**
  * A simple GL texture object abstraction.
  *
@@ -104,6 +106,14 @@ public:
 	 * Obtain texture coordinates for rectangular drawing.
 	 */
 	const GLfloat *getTexCoords() const { return _texCoords; }
+
+	/**
+	 * Obtain texture name.
+	 *
+	 * Beware that the texture name changes whenever create is used.
+	 * destroy will invalidate the texture name.
+	 */
+	GLuint getGLTexture() const { return _glTexture; }
 private:
 	const GLenum _glIntFormat;
 	const GLenum _glFormat;
@@ -175,7 +185,7 @@ public:
 	virtual void draw(GLfloat x, GLfloat y, GLfloat w, GLfloat h) = 0;
 
 	void flagDirty() { _allDirty = true; }
-	bool isDirty() const { return _allDirty || !_dirtyArea.isEmpty(); }
+	virtual bool isDirty() const { return _allDirty || !_dirtyArea.isEmpty(); }
 
 	virtual uint getWidth() const = 0;
 	virtual uint getHeight() const = 0;
@@ -307,6 +317,67 @@ private:
 };
 #endif // !USE_FORCED_GL
 
+#if !USE_FORCED_GLES && !USE_FORCED_GLES2
+class TextureCLUT8GPU : public Surface {
+public:
+	TextureCLUT8GPU();
+	virtual ~TextureCLUT8GPU();
+
+	virtual void destroy();
+
+	virtual void recreate();
+
+	virtual void enableLinearFiltering(bool enable);
+
+	virtual void allocate(uint width, uint height);
+
+	virtual void draw(GLfloat x, GLfloat y, GLfloat w, GLfloat h);
+
+	virtual bool isDirty() const { return _paletteDirty || Surface::isDirty(); }
+
+	virtual uint getWidth() const { return _userPixelData.w; }
+	virtual uint getHeight() const { return _userPixelData.h; }
+
+	virtual Graphics::PixelFormat getFormat() const;
+
+	virtual bool hasPalette() const { return true; }
+
+	virtual void setColorKey(uint colorKey);
+	virtual void setPalette(uint start, uint colors, const byte *palData);
+
+	virtual Graphics::Surface *getSurface() { return &_userPixelData; }
+	virtual const Graphics::Surface *getSurface() const { return &_userPixelData; }
+
+	static bool isSupportedByContext() {
+		return g_context.shadersSupported
+		    && g_context.multitextureSupported
+		    && g_context.textureRGSupported
+		    && g_context.framebufferObjectSupported;
+	}
+private:
+	void updateTextures();
+	void lookUpColors();
+
+	GLTexture _clut8Texture;
+	GLTexture _paletteTexture;
+	GLTexture _glTexture;
+
+	void setupFBO();
+	GLuint _glFBO;
+	GLfloat _clut8Vertices[4*2];
+	GLfloat _projectionMatrix[4*4];
+
+	Shader *_lookUpShader;
+	GLint _paletteLocation;
+
+	Graphics::Surface _clut8Data;
+	Graphics::Surface _userPixelData;
+
+	byte _palette[4 * 256];
+	bool _paletteDirty;
+};
+#endif // !USE_FORCED_GLES && !USE_FORCED_GLES2
+
 } // End of namespace OpenGL
 
 #endif


Commit: 2319fcd2289f604f2a9c00942a9cd2e88ea2acc8
    https://github.com/scummvm/scummvm/commit/2319fcd2289f604f2a9c00942a9cd2e88ea2acc8
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:26+01:00

Commit Message:
OPENGL: Handle GLES2 and GL shaders uniformly.

GLES2 requires precision qualifiers to be set and allows use of precision
qualifiers. For GLES2 we define a default precision now. Since precision
qualifiers are not supported in the GLSL version we use for GL, we
introduce compatibility #defines.

Changed paths:
    backends/graphics/opengl/opengl-graphics.cpp
    backends/graphics/opengl/shader.cpp
    backends/graphics/opengl/shader.h



diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index df939fb..7f4fcf7 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -905,14 +905,14 @@ void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &def
 		if (g_context.type == kContextGLES2) {
 #endif
 #if !USE_FORCED_GL
-			_shader = new Shader(g_defaultVertexShader, g_defaultFragmentShaderGLES2);
+			_shader = new Shader(g_defaultVertexShader, g_defaultFragmentShader);
 #endif
 #if !USE_FORCED_GL && !USE_FORCED_GLES2
 		} else {
 #endif
 #if !USE_FORCED_GLES2
 			if (g_context.shadersSupported) {
-				_shader = new Shader(g_defaultVertexShader, g_defaultFragmentShaderGL);
+				_shader = new Shader(g_defaultVertexShader, g_defaultFragmentShader);
 			}
 #endif
 #if !USE_FORCED_GL && !USE_FORCED_GLES2
diff --git a/backends/graphics/opengl/shader.cpp b/backends/graphics/opengl/shader.cpp
index c251ec1..e699262 100644
--- a/backends/graphics/opengl/shader.cpp
+++ b/backends/graphics/opengl/shader.cpp
@@ -25,6 +25,7 @@
 #if !USE_FORCED_GLES
 
 #include "common/textconsole.h"
+#include "common/util.h"
 
 namespace OpenGL {
 
@@ -44,8 +45,7 @@ const char *const g_defaultVertexShader =
 	"\tgl_Position = projection * position;\n"
 	"}\n";
 
-#if !USE_FORCED_GLES2
-const char *const g_defaultFragmentShaderGL =
+const char *const g_defaultFragmentShader =
 	"varying vec2 texCoord;\n"
 	"varying vec4 blendColor;\n"
 	"\n"
@@ -54,19 +54,24 @@ const char *const g_defaultFragmentShaderGL =
 	"void main(void) {\n"
 	"\tgl_FragColor = blendColor * texture2D(texture, texCoord);\n"
 	"}\n";
-#endif
 
-#if !USE_FORCED_GL
-const char *const g_defaultFragmentShaderGLES2 =
-	"varying lowp vec2 texCoord;\n"
-	"varying lowp vec4 blendColor;\n"
-	"\n"
-	"uniform sampler2D texture;\n"
-	"\n"
-	"void main(void) {\n"
-	"\tgl_FragColor = blendColor * texture2D(texture, texCoord);\n"
-	"}\n";
-#endif
+namespace {
+
+// Taken from: https://en.wikibooks.org/wiki/OpenGL_Programming/Modern_OpenGL_Tutorial_03#OpenGL_ES_2_portability
+const char *const g_precisionDefines =
+	"#ifdef GL_ES\n"
+	"\t#if defined(GL_FRAGMENT_PRECISION_HIGH) && GL_FRAGMENT_PRECISION_HIGH == 1\n"
+	"\t\tprecision highp float;\n"
+	"\t#else\n"
+	"\t\tprecision mediump float;\n"
+	"\t#endif\n"
+	"#else\n"
+	"\t#define highp\n"
+	"\t#define mediump\n"
+	"\t#define lowp\n"
+	"#endif\n";
+
+} // End of anonymous namespace
 
 Shader::Shader(const Common::String &vertex, const Common::String &fragment)
     : _vertex(vertex), _fragment(fragment), _program(0), _projectionLocation(-1), _textureLocation(-1) {
@@ -188,7 +193,12 @@ GLshader Shader::compileShader(const char *source, GLenum shaderType) {
 		return 0;
 	}
 
-	GL_CALL(glShaderSource(handle, 1, &source, nullptr));
+	const char *const sources[2] = {
+		g_precisionDefines,
+		source
+	};
+
+	GL_CALL(glShaderSource(handle, ARRAYSIZE(sources), sources, nullptr));
 	GL_CALL(glCompileShader(handle));
 
 	GLint result;
diff --git a/backends/graphics/opengl/shader.h b/backends/graphics/opengl/shader.h
index 458ecb9..98a2a28 100644
--- a/backends/graphics/opengl/shader.h
+++ b/backends/graphics/opengl/shader.h
@@ -38,12 +38,7 @@ enum {
 };
 
 extern const char *const g_defaultVertexShader;
-#if !USE_FORCED_GLES2
-extern const char *const g_defaultFragmentShaderGL;
-#endif
-#if !USE_FORCED_GL
-extern const char *const g_defaultFragmentShaderGLES2;
-#endif
+extern const char *const g_defaultFragmentShader;
 
 class Shader {
 public:


Commit: 397ce9b9477f9ed42e73be6c1f997e5d77fef672
    https://github.com/scummvm/scummvm/commit/397ce9b9477f9ed42e73be6c1f997e5d77fef672
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:26+01:00

Commit Message:
OPENGL: Keep feature state for all contexts and log them.

Changed paths:
    backends/graphics/opengl/context.cpp
    backends/graphics/opengl/opengl-sys.h



diff --git a/backends/graphics/opengl/context.cpp b/backends/graphics/opengl/context.cpp
index 10468f3..4dbd16f 100644
--- a/backends/graphics/opengl/context.cpp
+++ b/backends/graphics/opengl/context.cpp
@@ -43,12 +43,10 @@ void Context::reset() {
 	_maxTextureSize = 0;
 
 	NPOTSupported = false;
-#if !USE_FORCED_GLES && !USE_FORCED_GLES2
 	shadersSupported = false;
 	multitextureSupported = false;
 	framebufferObjectSupported = false;
 	textureRGSupported = false;
-#endif
 
 #define GL_FUNC_DEF(ret, name, param) name = nullptr;
 #include "backends/graphics/opengl/opengl-func.h"
@@ -197,12 +195,10 @@ void OpenGLGraphicsManager::initializeGLContext() {
 
 	const char *extString = (const char *)g_context.glGetString(GL_EXTENSIONS);
 
-#if !USE_FORCED_GLES && !USE_FORCED_GLES2
 	bool ARBShaderObjects = false;
 	bool ARBShadingLanguage100 = false;
 	bool ARBVertexShader = false;
 	bool ARBFragmentShader = false;
-#endif
 
 	Common::StringTokenizer tokenizer(extString, " ");
 	while (!tokenizer.empty()) {
@@ -210,7 +206,6 @@ void OpenGLGraphicsManager::initializeGLContext() {
 
 		if (token == "GL_ARB_texture_non_power_of_two") {
 			g_context.NPOTSupported = true;
-#if !USE_FORCED_GLES && !USE_FORCED_GLES2
 		} else if (token == "GL_ARB_shader_objects") {
 			ARBShaderObjects = true;
 		} else if (token == "GL_ARB_shading_language_100") {
@@ -225,13 +220,43 @@ void OpenGLGraphicsManager::initializeGLContext() {
 			g_context.textureRGSupported = true;
 		} else if (token == "GL_EXT_framebuffer_object") {
 			g_context.framebufferObjectSupported = true;
-#endif
 		}
 	}
 
-#if !USE_FORCED_GLES && !USE_FORCED_GLES2
-	g_context.shadersSupported = ARBShaderObjects & ARBShadingLanguage100 & ARBVertexShader & ARBFragmentShader;
-#endif
+	if (g_context.type == kContextGLES2) {
+		// GLES2 always has shader support.
+		g_context.shadersSupported = true;
+
+		// GLES2 always has multi texture support.
+		g_context.multitextureSupported = true;
+
+		// GLES2 always has FBO support.
+		g_context.framebufferObjectSupported = true;
+	} else {
+		g_context.shadersSupported = ARBShaderObjects & ARBShadingLanguage100 & ARBVertexShader & ARBFragmentShader;
+	}
+
+	// Log context type.
+	switch (g_context.type) {
+	case kContextGL:
+		debug(5, "OpenGL: GL context initialized");
+		break;
+
+	case kContextGLES:
+		debug(5, "OpenGL: GLES context initialized");
+		break;
+
+	case kContextGLES2:
+		debug(5, "OpenGL: GLES2 context initialized");
+		break;
+	}
+
+	// Log features supported by GL context.
+	debug(5, "OpenGL: NPOT texture support: %d", g_context.NPOTSupported);
+	debug(5, "OpenGL: Shader support: %d", g_context.shadersSupported);
+	debug(5, "OpenGL: Multitexture support: %d", g_context.multitextureSupported);
+	debug(5, "OpenGL: Texture RG support: %d", g_context.textureRGSupported);
+	debug(5, "OpenGL: FBO support: %d", g_context.framebufferObjectSupported);
 }
 
 } // End of namespace OpenGL
diff --git a/backends/graphics/opengl/opengl-sys.h b/backends/graphics/opengl/opengl-sys.h
index 9df5efc..9c3dfe8 100644
--- a/backends/graphics/opengl/opengl-sys.h
+++ b/backends/graphics/opengl/opengl-sys.h
@@ -108,7 +108,6 @@ struct Context {
 	/** Whether GL_ARB_texture_non_power_of_two is available or not. */
 	bool NPOTSupported;
 
-#if !USE_FORCED_GLES && !USE_FORCED_GLES2
 	/** Whether shader support is available or not. */
 	bool shadersSupported;
 
@@ -120,7 +119,6 @@ struct Context {
 
 	/** Whether FBO support is available or not. */
 	bool framebufferObjectSupported;
-#endif
 
 #define GL_FUNC_DEF(ret, name, param) ret (GL_CALL_CONV *name)param
 #include "backends/graphics/opengl/opengl-func.h"


Commit: 18306ee20602e79a2af4556658dc0f141a4ad78f
    https://github.com/scummvm/scummvm/commit/18306ee20602e79a2af4556658dc0f141a4ad78f
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:26+01:00

Commit Message:
OPENGL: Simplify shader support checks.

Changed paths:
    backends/graphics/opengl/context.cpp
    backends/graphics/opengl/opengl-graphics.cpp



diff --git a/backends/graphics/opengl/context.cpp b/backends/graphics/opengl/context.cpp
index 4dbd16f..478d98c 100644
--- a/backends/graphics/opengl/context.cpp
+++ b/backends/graphics/opengl/context.cpp
@@ -29,16 +29,6 @@
 
 namespace OpenGL {
 
-#if USE_FORCED_GL
-#define HAS_SHADERS_CHECK shadersSupported
-#elif USE_FORCED_GLES
-#define HAS_SHADERS_CHECK false
-#elif USE_FORCED_GLES2
-#define HAS_SHADERS_CHECK true
-#else
-#define HAS_SHADERS_CHECK (type == kContextGLES2 || shadersSupported)
-#endif
-
 void Context::reset() {
 	_maxTextureSize = 0;
 
@@ -69,7 +59,7 @@ void Context::initializePipeline() {
 
 	// Enable rendering with vertex and coord arrays.
 #if !USE_FORCED_GLES && !USE_FORCED_GLES2
-	if (HAS_SHADERS_CHECK) {
+	if (g_context.shadersSupported) {
 #endif
 #if !USE_FORCED_GLES
 		GL_CALL(glEnableVertexAttribArray(kPositionAttribLocation));
@@ -105,7 +95,7 @@ void Context::initializePipeline() {
 
 void Context::setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
 #if !USE_FORCED_GLES && !USE_FORCED_GLES2
-	if (HAS_SHADERS_CHECK) {
+	if (g_context.shadersSupported) {
 #endif
 #if !USE_FORCED_GLES
 		GL_CALL(glVertexAttrib4f(kColorAttribLocation, r, g, b, a));
@@ -123,7 +113,7 @@ void Context::setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
 
 void Context::setDrawCoordinates(const GLfloat *vertices, const GLfloat *texCoords) {
 #if !USE_FORCED_GLES && !USE_FORCED_GLES2
-	if (HAS_SHADERS_CHECK) {
+	if (g_context.shadersSupported) {
 #endif
 #if !USE_FORCED_GLES
 		GL_CALL(glVertexAttribPointer(kTexCoordAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, texCoords));
diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index 7f4fcf7..d9c9377 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -773,8 +773,7 @@ void OpenGLGraphicsManager::setActualScreenSize(uint width, uint height) {
 	};
 
 #if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
-	if (g_context.type == kContextGLES
-	    || (g_context.type == kContextGL && !g_context.shadersSupported)) {
+	if (!g_context.shadersSupported) {
 #endif
 #if !USE_FORCED_GLES2
 		GL_CALL(glMatrixMode(GL_PROJECTION));
@@ -901,23 +900,9 @@ void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &def
 
 #if !USE_FORCED_GLES
 	if (!_shader) {
-#if !USE_FORCED_GL && !USE_FORCED_GLES2
-		if (g_context.type == kContextGLES2) {
-#endif
-#if !USE_FORCED_GL
+		if (g_context.shadersSupported) {
 			_shader = new Shader(g_defaultVertexShader, g_defaultFragmentShader);
-#endif
-#if !USE_FORCED_GL && !USE_FORCED_GLES2
-		} else {
-#endif
-#if !USE_FORCED_GLES2
-			if (g_context.shadersSupported) {
-				_shader = new Shader(g_defaultVertexShader, g_defaultFragmentShader);
-			}
-#endif
-#if !USE_FORCED_GL && !USE_FORCED_GLES2
 		}
-#endif
 	}
 #endif
 


Commit: bf2735cd53f13d22cf4e6013a251896a3d411b97
    https://github.com/scummvm/scummvm/commit/bf2735cd53f13d22cf4e6013a251896a3d411b97
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:26+01:00

Commit Message:
OPENGL: Detect NPOT support for GLES.

For GLES1+ there exists GL_OES_texture_npot, which indicates that there is
NPOT support.

GLES2 always had (limited) NPOT support, which is all we require, thus we
always enable it.

Changed paths:
    backends/graphics/opengl/context.cpp



diff --git a/backends/graphics/opengl/context.cpp b/backends/graphics/opengl/context.cpp
index 478d98c..c149b12 100644
--- a/backends/graphics/opengl/context.cpp
+++ b/backends/graphics/opengl/context.cpp
@@ -194,7 +194,7 @@ void OpenGLGraphicsManager::initializeGLContext() {
 	while (!tokenizer.empty()) {
 		Common::String token = tokenizer.nextToken();
 
-		if (token == "GL_ARB_texture_non_power_of_two") {
+		if (token == "GL_ARB_texture_non_power_of_two" || token == "GL_OES_texture_npot") {
 			g_context.NPOTSupported = true;
 		} else if (token == "GL_ARB_shader_objects") {
 			ARBShaderObjects = true;
@@ -214,6 +214,9 @@ void OpenGLGraphicsManager::initializeGLContext() {
 	}
 
 	if (g_context.type == kContextGLES2) {
+		// GLES2 always has (limited) NPOT support.
+		g_context.NPOTSupported = true;
+
 		// GLES2 always has shader support.
 		g_context.shadersSupported = true;
 


Commit: 08553a09cfa2110d56b200bf6c69d01d5adbc6bb
    https://github.com/scummvm/scummvm/commit/08553a09cfa2110d56b200bf6c69d01d5adbc6bb
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:26+01:00

Commit Message:
OPENGL: Support GLSL based CLUT8 look up for GLES2+.

Changed paths:
    backends/graphics/opengl/context.cpp
    backends/graphics/opengl/opengl-func.h
    backends/graphics/opengl/opengl-graphics.cpp
    backends/graphics/opengl/opengl-sys.h
    backends/graphics/opengl/texture.cpp
    backends/graphics/opengl/texture.h



diff --git a/backends/graphics/opengl/context.cpp b/backends/graphics/opengl/context.cpp
index c149b12..89f0ed7 100644
--- a/backends/graphics/opengl/context.cpp
+++ b/backends/graphics/opengl/context.cpp
@@ -36,7 +36,6 @@ void Context::reset() {
 	shadersSupported = false;
 	multitextureSupported = false;
 	framebufferObjectSupported = false;
-	textureRGSupported = false;
 
 #define GL_FUNC_DEF(ret, name, param) name = nullptr;
 #include "backends/graphics/opengl/opengl-func.h"
@@ -206,8 +205,6 @@ void OpenGLGraphicsManager::initializeGLContext() {
 			ARBFragmentShader = true;
 		} else if (token == "GL_ARB_multitexture") {
 			g_context.multitextureSupported = true;
-		} else if (token == "GL_ARB_texture_rg") {
-			g_context.textureRGSupported = true;
 		} else if (token == "GL_EXT_framebuffer_object") {
 			g_context.framebufferObjectSupported = true;
 		}
@@ -248,7 +245,6 @@ void OpenGLGraphicsManager::initializeGLContext() {
 	debug(5, "OpenGL: NPOT texture support: %d", g_context.NPOTSupported);
 	debug(5, "OpenGL: Shader support: %d", g_context.shadersSupported);
 	debug(5, "OpenGL: Multitexture support: %d", g_context.multitextureSupported);
-	debug(5, "OpenGL: Texture RG support: %d", g_context.textureRGSupported);
 	debug(5, "OpenGL: FBO support: %d", g_context.framebufferObjectSupported);
 }
 
diff --git a/backends/graphics/opengl/opengl-func.h b/backends/graphics/opengl/opengl-func.h
index 763d5e9..554ac3c 100644
--- a/backends/graphics/opengl/opengl-func.h
+++ b/backends/graphics/opengl/opengl-func.h
@@ -130,13 +130,11 @@ GL_FUNC_2_DEF(void, glGetShaderInfoLog, glGetInfoLogARB, (GLshader shader, GLsiz
 GL_FUNC_2_DEF(void, glShaderSource, glShaderSourceARB, (GLshader shader, GLsizei count, const GLchar *const *string, const GLint *length));
 GL_FUNC_2_DEF(void, glCompileShader, glCompileShaderARB, (GLshader shader));
 
-#if !USE_FORCED_GLES2
 GL_FUNC_2_DEF(void, glBindFramebuffer, glBindFramebufferEXT, (GLenum target, GLuint renderbuffer));
 GL_FUNC_2_DEF(void, glDeleteFramebuffers, glDeleteFramebuffersEXT, (GLsizei n, const GLuint *framebuffers));
 GL_FUNC_2_DEF(void, glGenFramebuffers, glGenFramebuffersEXT, (GLsizei n, GLuint *renderbuffers));
 GL_FUNC_2_DEF(void, glFramebufferTexture2D, glFramebufferTexture2DEXT, (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level));
 GL_FUNC_2_DEF(GLenum, glCheckFramebufferStatus, glCheckFramebufferStatusEXT, (GLenum target));
-#endif
 
 GL_FUNC_2_DEF(void, glActiveTexture, glActiveTextureARB, (GLenum texture));
 #endif
diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index d9c9377..1ec4001 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -1016,7 +1016,7 @@ void OpenGLGraphicsManager::setMousePosition(int x, int y) {
 Surface *OpenGLGraphicsManager::createSurface(const Graphics::PixelFormat &format, bool wantAlpha) {
 	GLenum glIntFormat, glFormat, glType;
 	if (format.bytesPerPixel == 1) {
-#if !USE_FORCED_GLES && !USE_FORCED_GLES2
+#if !USE_FORCED_GLES
 		if (TextureCLUT8GPU::isSupportedByContext()) {
 			return new TextureCLUT8GPU();
 		}
diff --git a/backends/graphics/opengl/opengl-sys.h b/backends/graphics/opengl/opengl-sys.h
index 9c3dfe8..a584259 100644
--- a/backends/graphics/opengl/opengl-sys.h
+++ b/backends/graphics/opengl/opengl-sys.h
@@ -114,9 +114,6 @@ struct Context {
 	/** Whether multi texture support is available or not. */
 	bool multitextureSupported;
 
-	/** Whether (GLES2) RG texture formats are supported. */
-	bool textureRGSupported;
-
 	/** Whether FBO support is available or not. */
 	bool framebufferObjectSupported;
 
diff --git a/backends/graphics/opengl/texture.cpp b/backends/graphics/opengl/texture.cpp
index 5ae4987..f98bf8b 100644
--- a/backends/graphics/opengl/texture.cpp
+++ b/backends/graphics/opengl/texture.cpp
@@ -504,9 +504,9 @@ void TextureRGB555::updateTexture() {
 }
 #endif // !USE_FORCED_GL
 
-#if !USE_FORCED_GLES && !USE_FORCED_GLES2
+#if !USE_FORCED_GLES
 namespace {
-const char *const g_lookUpFragmentShaderGL =
+const char *const g_lookUpFragmentShader =
 	"varying vec2 texCoord;\n"
 	"varying vec4 blendColor;\n"
 	"\n"
@@ -517,12 +517,17 @@ const char *const g_lookUpFragmentShaderGL =
 	"\n"
 	"void main(void) {\n"
 	"\tvec4 index = texture2D(texture, texCoord);\n"
-	"\tgl_FragColor = blendColor * texture2D(palette, vec2(index.x * adjustFactor, 0.0));\n"
+	"\tgl_FragColor = blendColor * texture2D(palette, vec2(index.a * adjustFactor, 0.0));\n"
 	"}\n";
 } // End of anonymous namespace
 
+// _clut8Texture needs 8 bits internal precision, otherwise graphics glitches
+// can occur. GL_ALPHA does not have any internal precision requirements.
+// However, in practice (according to fuzzie) it's 8bit. If we run into
+// problems, we need to switch to GL_R8 and GL_RED, but that is only supported
+// for ARB_texture_rg and GLES3+ (EXT_rexture_rg does not support GL_R8).
 TextureCLUT8GPU::TextureCLUT8GPU()
-    : _clut8Texture(GL_R8, GL_RED, GL_UNSIGNED_BYTE),
+    : _clut8Texture(GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE),
       _paletteTexture(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE),
       _glTexture(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE),
       _glFBO(0), _clut8Vertices(), _projectionMatrix(),
@@ -531,7 +536,7 @@ TextureCLUT8GPU::TextureCLUT8GPU()
 	// Allocate space for 256 colors.
 	_paletteTexture.setSize(256, 1);
 
-	_lookUpShader = new Shader(g_defaultVertexShader, g_lookUpFragmentShaderGL);
+	_lookUpShader = new Shader(g_defaultVertexShader, g_lookUpFragmentShader);
 	_lookUpShader->recreate();
 	_paletteLocation = _lookUpShader->getUniformLocation("palette");
 
@@ -772,6 +777,6 @@ void TextureCLUT8GPU::setupFBO() {
 	// Restore old FBO.
 	GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, oldFBO));
 }
-#endif // !USE_FORCED_GLES && !USE_FORCED_GLES2
+#endif // !USE_FORCED_GLES
 
 } // End of namespace OpenGL
diff --git a/backends/graphics/opengl/texture.h b/backends/graphics/opengl/texture.h
index 06fe47a..9592815 100644
--- a/backends/graphics/opengl/texture.h
+++ b/backends/graphics/opengl/texture.h
@@ -317,7 +317,7 @@ private:
 };
 #endif // !USE_FORCED_GL
 
-#if !USE_FORCED_GLES && !USE_FORCED_GLES2
+#if !USE_FORCED_GLES
 class TextureCLUT8GPU : public Surface {
 public:
 	TextureCLUT8GPU();
@@ -351,7 +351,6 @@ public:
 	static bool isSupportedByContext() {
 		return g_context.shadersSupported
 		    && g_context.multitextureSupported
-		    && g_context.textureRGSupported
 		    && g_context.framebufferObjectSupported;
 	}
 private:
@@ -376,7 +375,7 @@ private:
 	byte _palette[4 * 256];
 	bool _paletteDirty;
 };
-#endif // !USE_FORCED_GLES && !USE_FORCED_GLES2
+#endif // !USE_FORCED_GLES
 
 } // End of namespace OpenGL
 


Commit: f5f1b6eba0d409abcda2a3c037a177d6f6e41a2e
    https://github.com/scummvm/scummvm/commit/f5f1b6eba0d409abcda2a3c037a177d6f6e41a2e
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:26+01:00

Commit Message:
OPENGL: Introduce pipeline abstraction to cleanup code.

Changed paths:
  A backends/graphics/opengl/pipeline.cpp
  A backends/graphics/opengl/pipeline.h
    backends/graphics/opengl/context.cpp
    backends/graphics/opengl/opengl-graphics.cpp
    backends/graphics/opengl/opengl-graphics.h
    backends/graphics/opengl/opengl-sys.h
    backends/graphics/opengl/texture.cpp
    backends/module.mk



diff --git a/backends/graphics/opengl/context.cpp b/backends/graphics/opengl/context.cpp
index 89f0ed7..7402e79 100644
--- a/backends/graphics/opengl/context.cpp
+++ b/backends/graphics/opengl/context.cpp
@@ -23,6 +23,7 @@
 #include "backends/graphics/opengl/opengl-sys.h"
 #include "backends/graphics/opengl/opengl-graphics.h"
 #include "backends/graphics/opengl/shader.h"
+#include "backends/graphics/opengl/pipeline.h"
 
 #include "common/tokenizer.h"
 #include "common/debug.h"
@@ -40,94 +41,19 @@ void Context::reset() {
 #define GL_FUNC_DEF(ret, name, param) name = nullptr;
 #include "backends/graphics/opengl/opengl-func.h"
 #undef GL_FUNC_DEF
-}
-
-void Context::initializePipeline() {
-#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
-	if (g_context.type != kContextGLES2) {
-#endif
-#if !USE_FORCED_GLES2
-		GL_CALL(glDisable(GL_LIGHTING));
-		GL_CALL(glDisable(GL_FOG));
-		GL_CALL(glShadeModel(GL_FLAT));
-		GL_CALL(glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST));
-#endif
-#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
-	}
-#endif
 
-	// Enable rendering with vertex and coord arrays.
-#if !USE_FORCED_GLES && !USE_FORCED_GLES2
-	if (g_context.shadersSupported) {
-#endif
-#if !USE_FORCED_GLES
-		GL_CALL(glEnableVertexAttribArray(kPositionAttribLocation));
-		GL_CALL(glEnableVertexAttribArray(kTexCoordAttribLocation));
-#endif
-#if !USE_FORCED_GLES && !USE_FORCED_GLES2
-	} else {
-#endif
-#if !USE_FORCED_GLES2
-		GL_CALL(glEnableClientState(GL_VERTEX_ARRAY));
-		GL_CALL(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
-#endif
-#if !USE_FORCED_GLES && !USE_FORCED_GLES2
-	}
-#endif
-
-#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
-	if (g_context.type == kContextGLES2) {
-#endif
-#if !USE_FORCED_GL && !USE_FORCED_GLES
-		GL_CALL(glActiveTexture(GL_TEXTURE0));
-#endif
-#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
-	} else {
-#endif
-#if !USE_FORCED_GLES2
-		GL_CALL(glEnable(GL_TEXTURE_2D));
-#endif
-#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
-	}
-#endif
+	activePipeline = nullptr;
 }
 
-void Context::setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
-#if !USE_FORCED_GLES && !USE_FORCED_GLES2
-	if (g_context.shadersSupported) {
-#endif
-#if !USE_FORCED_GLES
-		GL_CALL(glVertexAttrib4f(kColorAttribLocation, r, g, b, a));
-#endif
-#if !USE_FORCED_GLES && !USE_FORCED_GLES2
-	} else {
-#endif
-#if !USE_FORCED_GLES2
-		GL_CALL(glColor4f(r, g, b, a));
-#endif
-#if !USE_FORCED_GLES && !USE_FORCED_GLES2
-	}
-#endif
-}
+Pipeline *Context::setPipeline(Pipeline *pipeline) {
+	Pipeline *oldPipeline = activePipeline;
 
-void Context::setDrawCoordinates(const GLfloat *vertices, const GLfloat *texCoords) {
-#if !USE_FORCED_GLES && !USE_FORCED_GLES2
-	if (g_context.shadersSupported) {
-#endif
-#if !USE_FORCED_GLES
-		GL_CALL(glVertexAttribPointer(kTexCoordAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, texCoords));
-		GL_CALL(glVertexAttribPointer(kPositionAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, vertices));
-#endif
-#if !USE_FORCED_GLES && !USE_FORCED_GLES2
-	} else {
-#endif
-#if !USE_FORCED_GLES2
-		GL_CALL(glTexCoordPointer(2, GL_FLOAT, 0, texCoords));
-		GL_CALL(glVertexPointer(2, GL_FLOAT, 0, vertices));
-#endif
-#if !USE_FORCED_GLES && !USE_FORCED_GLES2
+	activePipeline = pipeline;
+	if (activePipeline) {
+		activePipeline->activate();
 	}
-#endif
+
+	return oldPipeline;
 }
 
 Context g_context;
diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index 1ec4001..0a9b040 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -23,6 +23,7 @@
 
 #include "backends/graphics/opengl/opengl-graphics.h"
 #include "backends/graphics/opengl/texture.h"
+#include "backends/graphics/opengl/pipeline.h"
 #include "backends/graphics/opengl/shader.h"
 
 #include "common/textconsole.h"
@@ -44,6 +45,7 @@ namespace OpenGL {
 
 OpenGLGraphicsManager::OpenGLGraphicsManager()
     : _currentState(), _oldState(), _transactionMode(kTransactionNone), _screenChangeID(1 << (sizeof(int) * 8 - 2)),
+      _pipeline(nullptr),
       _outputScreenWidth(0), _outputScreenHeight(0), _displayX(0), _displayY(0),
       _displayWidth(0), _displayHeight(0), _defaultFormat(), _defaultFormatAlpha(),
       _gameScreen(nullptr), _gameScreenShakeOffset(0), _overlay(nullptr),
@@ -425,13 +427,13 @@ void OpenGLGraphicsManager::updateScreen() {
 		}
 
 		// Set the OSD transparency.
-		g_context.setColor(1.0f, 1.0f, 1.0f, _osdAlpha / 100.0f);
+		g_context.activePipeline->setColor(1.0f, 1.0f, 1.0f, _osdAlpha / 100.0f);
 
 		// Draw the OSD texture.
 		_osd->draw(0, 0, _outputScreenWidth, _outputScreenHeight);
 
 		// Reset color.
-		g_context.setColor(1.0f, 1.0f, 1.0f, 1.0f);
+		g_context.activePipeline->setColor(1.0f, 1.0f, 1.0f, 1.0f);
 	}
 #endif
 
@@ -867,6 +869,24 @@ void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &def
 	// Initialize context for use.
 	initializeGLContext();
 
+	// Initialize pipeline.
+	delete _pipeline;
+	_pipeline = nullptr;
+
+#if !USE_FORCED_GLES
+	if (g_context.shadersSupported) {
+		_pipeline = new ShaderPipeline();
+	}
+#endif
+
+#if !USE_FORCED_GLES2
+	if (_pipeline == nullptr) {
+		_pipeline = new FixedPipeline();
+	}
+#endif
+
+	g_context.setPipeline(_pipeline);
+
 	// Disable 3D properties.
 	GL_CALL(glDisable(GL_CULL_FACE));
 	GL_CALL(glDisable(GL_DEPTH_TEST));
@@ -874,15 +894,12 @@ void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &def
 
 	// Default to black as clear color.
 	GL_CALL(glClearColor(0.0f, 0.0f, 0.0f, 0.0f));
-	g_context.setColor(1.0f, 1.0f, 1.0f, 1.0f);
+	g_context.activePipeline->setColor(1.0f, 1.0f, 1.0f, 1.0f);
 
 	// Setup alpha blend (for overlay and cursor).
 	GL_CALL(glEnable(GL_BLEND));
 	GL_CALL(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
 
-	// Initialize the context specific state of the pipeline.
-	g_context.initializePipeline();
-
 	// Setup scissor state accordingly.
 	if (_overlayVisible) {
 		GL_CALL(glDisable(GL_SCISSOR_TEST));
@@ -969,6 +986,11 @@ void OpenGLGraphicsManager::notifyContextDestroy() {
 	}
 #endif
 
+	// Destroy rendering pipeline.
+	g_context.setPipeline(nullptr);
+	delete _pipeline;
+	_pipeline = nullptr;
+
 	// Rest our context description since the context is gone soon.
 	g_context.reset();
 }
diff --git a/backends/graphics/opengl/opengl-graphics.h b/backends/graphics/opengl/opengl-graphics.h
index 40605f0..95ba4e7 100644
--- a/backends/graphics/opengl/opengl-graphics.h
+++ b/backends/graphics/opengl/opengl-graphics.h
@@ -41,6 +41,7 @@ namespace OpenGL {
 #define USE_OSD 1
 
 class Surface;
+class Pipeline;
 #if !USE_FORCED_GLES
 class Shader;
 #endif
@@ -303,6 +304,11 @@ private:
 	 */
 	void initializeGLContext();
 
+	/**
+	 * OpenGL pipeline used for rendering.
+	 */
+	Pipeline *_pipeline;
+
 protected:
 	/**
 	 * Query the address of an OpenGL function by name.
diff --git a/backends/graphics/opengl/opengl-sys.h b/backends/graphics/opengl/opengl-sys.h
index a584259..f68897b 100644
--- a/backends/graphics/opengl/opengl-sys.h
+++ b/backends/graphics/opengl/opengl-sys.h
@@ -87,6 +87,8 @@ enum ContextType {
 	kContextGLES2
 };
 
+class Pipeline;
+
 /**
  * Description structure of the OpenGL (ES) context.
  */
@@ -126,20 +128,18 @@ struct Context {
 	// programmable pipelines in the same fashion.
 	//
 
-	/**
-	 * Initializes the pipeline state.
-	 */
-	void initializePipeline();
-
-	/**
-	 * Set color which shall be multiplied with each pixel.
-	 */
-	void setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
+	/** Currently active rendering pipeline. */
+	Pipeline *activePipeline;
 
 	/**
-	 * Set vertex and texture coordinates.
+	 * Set new pipeline.
+	 *
+	 * Client is responsible for any memory management related to pipelines.
+	 *
+	 * @param pipeline Pipeline to activate.
+	 * @return Formerly active pipeline.
 	 */
-	void setDrawCoordinates(const GLfloat *vertices, const GLfloat *texCoords);
+	Pipeline *setPipeline(Pipeline *pipeline);
 };
 
 /**
diff --git a/backends/graphics/opengl/pipeline.cpp b/backends/graphics/opengl/pipeline.cpp
new file mode 100644
index 0000000..362f15a
--- /dev/null
+++ b/backends/graphics/opengl/pipeline.cpp
@@ -0,0 +1,76 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "backends/graphics/opengl/pipeline.h"
+#include "backends/graphics/opengl/shader.h"
+
+namespace OpenGL {
+
+#if !USE_FORCED_GLES2
+void FixedPipeline::activate() {
+	GL_CALL(glDisable(GL_LIGHTING));
+	GL_CALL(glDisable(GL_FOG));
+	GL_CALL(glShadeModel(GL_FLAT));
+	GL_CALL(glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST));
+
+	GL_CALL(glEnableClientState(GL_VERTEX_ARRAY));
+	GL_CALL(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
+
+#if !USE_FORCED_GLES
+	if (g_context.multitextureSupported) {
+		GL_CALL(glActiveTexture(GL_TEXTURE0));
+	}
+#endif
+	GL_CALL(glEnable(GL_TEXTURE_2D));
+}
+
+void FixedPipeline::setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
+	GL_CALL(glColor4f(r, g, b, a));
+}
+
+void FixedPipeline::setDrawCoordinates(const GLfloat *vertices, const GLfloat *texCoords) {
+	GL_CALL(glTexCoordPointer(2, GL_FLOAT, 0, texCoords));
+	GL_CALL(glVertexPointer(2, GL_FLOAT, 0, vertices));
+}
+#endif // !USE_FORCED_GLES2
+
+#if !USE_FORCED_GLES
+void ShaderPipeline::activate() {
+	GL_CALL(glEnableVertexAttribArray(kPositionAttribLocation));
+	GL_CALL(glEnableVertexAttribArray(kTexCoordAttribLocation));
+
+	if (g_context.multitextureSupported) {
+		GL_CALL(glActiveTexture(GL_TEXTURE0));
+	}
+}
+
+void ShaderPipeline::setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
+	GL_CALL(glVertexAttrib4f(kColorAttribLocation, r, g, b, a));
+}
+
+void ShaderPipeline::setDrawCoordinates(const GLfloat *vertices, const GLfloat *texCoords) {
+	GL_CALL(glVertexAttribPointer(kTexCoordAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, texCoords));
+	GL_CALL(glVertexAttribPointer(kPositionAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, vertices));
+}
+#endif // !USE_FORCED_GLES
+
+} // End of namespace OpenGL
diff --git a/backends/graphics/opengl/pipeline.h b/backends/graphics/opengl/pipeline.h
new file mode 100644
index 0000000..e12390b
--- /dev/null
+++ b/backends/graphics/opengl/pipeline.h
@@ -0,0 +1,92 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BACKENDS_GRAPHICS_OPENGL_PIEPLINE_H
+#define BACKENDS_GRAPHICS_OPENGL_PIEPLINE_H
+
+#include "backends/graphics/opengl/opengl-sys.h"
+
+namespace OpenGL {
+
+/**
+ * Interface for OpenGL pipeline functionality.
+ *
+ * This encapsulates differences in various rendering pipelines used for
+ * OpenGL, OpenGL ES 1, and OpenGL ES 2.
+ */
+class Pipeline {
+public:
+	virtual ~Pipeline() {}
+
+	/**
+	 * Activate the pipeline.
+	 *
+	 * This sets the OpenGL state to make use of drawing with the given
+	 * OpenGL pipeline.
+	 */
+	virtual void activate() = 0;
+
+	/**
+	 * Set modulation color.
+	 *
+	 * @param r Red component in [0,1].
+	 * @param g Green component in [0,1].
+	 * @param b Blue component in [0,1].
+	 * @param a Alpha component in [0,1].
+	 */
+	virtual void setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) = 0;
+
+	/**
+	 * Setup coordinates for drawing with glDrawArrays.
+	 *
+	 * @param vertices  The list of vertices, 2 coordinates for each vertex.
+	 * @param texCoords The list of texture coordinates, 2 coordinates for
+	 *                  each vertex.
+	 */
+	virtual void setDrawCoordinates(const GLfloat *vertices, const GLfloat *texCoords) = 0;
+};
+
+#if !USE_FORCED_GLES2
+class FixedPipeline : public Pipeline {
+public:
+	virtual void activate();
+
+	virtual void setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
+
+	virtual void setDrawCoordinates(const GLfloat *vertices, const GLfloat *texCoords);
+};
+#endif // !USE_FORCED_GLES2
+
+#if !USE_FORCED_GLES
+class ShaderPipeline : public Pipeline {
+public:
+	virtual void activate();
+
+	virtual void setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
+
+	virtual void setDrawCoordinates(const GLfloat *vertices, const GLfloat *texCoords);
+};
+#endif // !USE_FORCED_GLES
+
+} // End of namespace OpenGL
+
+#endif
diff --git a/backends/graphics/opengl/texture.cpp b/backends/graphics/opengl/texture.cpp
index f98bf8b..61e8dc3 100644
--- a/backends/graphics/opengl/texture.cpp
+++ b/backends/graphics/opengl/texture.cpp
@@ -22,6 +22,7 @@
 
 #include "backends/graphics/opengl/texture.h"
 #include "backends/graphics/opengl/shader.h"
+#include "backends/graphics/opengl/pipeline.h"
 
 #include "common/rect.h"
 #include "common/textconsole.h"
@@ -282,7 +283,7 @@ void Texture::draw(GLfloat x, GLfloat y, GLfloat w, GLfloat h) {
 	};
 
 	// Setup coordinates for drawing.
-	g_context.setDrawCoordinates(vertices, _glTexture.getTexCoords());
+	g_context.activePipeline->setDrawCoordinates(vertices, _glTexture.getTexCoords());
 
 	// Draw the texture to the screen buffer.
 	GL_CALL(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
@@ -649,7 +650,7 @@ void TextureCLUT8GPU::draw(GLfloat x, GLfloat y, GLfloat w, GLfloat h) {
 	};
 
 	// Setup coordinates for drawing.
-	g_context.setDrawCoordinates(vertices, _glTexture.getTexCoords());
+	g_context.activePipeline->setDrawCoordinates(vertices, _glTexture.getTexCoords());
 
 	// Draw the texture to the screen buffer.
 	GL_CALL(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
@@ -744,7 +745,7 @@ void TextureCLUT8GPU::lookUpColors() {
 	// Do color look up.
 	_lookUpShader->activate(_projectionMatrix);
 	_lookUpShader->setUniformI(_paletteLocation, 1);
-	g_context.setDrawCoordinates(_clut8Vertices, _clut8Texture.getTexCoords());
+	g_context.activePipeline->setDrawCoordinates(_clut8Vertices, _clut8Texture.getTexCoords());
 	GL_CALL(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
 
 	// Restore old state.
diff --git a/backends/module.mk b/backends/module.mk
index e4566d0..3059422 100644
--- a/backends/module.mk
+++ b/backends/module.mk
@@ -55,6 +55,7 @@ MODULE_OBJS += \
 	graphics/opengl/context.o \
 	graphics/opengl/debug.o \
 	graphics/opengl/opengl-graphics.o \
+	graphics/opengl/pipeline.o \
 	graphics/opengl/shader.o \
 	graphics/opengl/texture.o
 endif


Commit: 5498982a3754edccb498521587c553e0ecbe7328
    https://github.com/scummvm/scummvm/commit/5498982a3754edccb498521587c553e0ecbe7328
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:26+01:00

Commit Message:
OPENGL: Introduce ShaderManager to handle builtin shaders.

Changed paths:
    backends/graphics/opengl/opengl-graphics.cpp
    backends/graphics/opengl/opengl-graphics.h
    backends/graphics/opengl/shader.cpp
    backends/graphics/opengl/shader.h
    backends/graphics/opengl/texture.cpp
    backends/graphics/opengl/texture.h



diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index 0a9b040..a830148 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -58,7 +58,7 @@ OpenGLGraphicsManager::OpenGLGraphicsManager()
       , _osdAlpha(0), _osdFadeStartTime(0), _osd(nullptr)
 #endif
 #if !USE_FORCED_GLES
-      , _shader(nullptr), _projectionMatrix()
+      , _projectionMatrix()
 #endif
     {
 	memset(_gamePalette, 0, sizeof(_gamePalette));
@@ -73,7 +73,7 @@ OpenGLGraphicsManager::~OpenGLGraphicsManager() {
 	delete _osd;
 #endif
 #if !USE_FORCED_GLES
-	delete _shader;
+	ShaderManager::destroy();
 #endif
 }
 
@@ -790,9 +790,7 @@ void OpenGLGraphicsManager::setActualScreenSize(uint width, uint height) {
 #if !USE_FORCED_GLES
 		assert(sizeof(_projectionMatrix) == sizeof(orthoProjection));
 		memcpy(_projectionMatrix, orthoProjection, sizeof(_projectionMatrix));
-		if (_shader) {
-			_shader->activate(_projectionMatrix);
-		}
+		ShaderMan.query(ShaderManager::kDefault)->activate(_projectionMatrix);
 #endif
 #if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
 	}
@@ -916,18 +914,9 @@ void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &def
 	GL_CALL(glPixelStorei(GL_PACK_ALIGNMENT, 4));
 
 #if !USE_FORCED_GLES
-	if (!_shader) {
-		if (g_context.shadersSupported) {
-			_shader = new Shader(g_defaultVertexShader, g_defaultFragmentShader);
-		}
-	}
-#endif
-
-#if !USE_FORCED_GLES
-	if (_shader) {
-		// TODO: What do we do on failure?
-		_shader->recreate();
-		_shader->activate(_projectionMatrix);
+	if (g_context.shadersSupported) {
+		ShaderMan.notifyCreate();
+		ShaderMan.query(ShaderManager::kDefault)->activate(_projectionMatrix);
 	}
 #endif
 
@@ -981,8 +970,8 @@ void OpenGLGraphicsManager::notifyContextDestroy() {
 #endif
 
 #if !USE_FORCED_GLES
-	if (_shader) {
-		_shader->destroy();
+	if (g_context.shadersSupported) {
+		ShaderMan.notifyDestroy();
 	}
 #endif
 
diff --git a/backends/graphics/opengl/opengl-graphics.h b/backends/graphics/opengl/opengl-graphics.h
index 95ba4e7..f3cd4c4 100644
--- a/backends/graphics/opengl/opengl-graphics.h
+++ b/backends/graphics/opengl/opengl-graphics.h
@@ -533,11 +533,6 @@ private:
 	//
 
 	/**
-	 * Active shader.
-	 */
-	Shader *_shader;
-
-	/**
 	 * Projection matrix used.
 	 */
 	GLfloat _projectionMatrix[4*4];
diff --git a/backends/graphics/opengl/shader.cpp b/backends/graphics/opengl/shader.cpp
index e699262..2f2d5d8 100644
--- a/backends/graphics/opengl/shader.cpp
+++ b/backends/graphics/opengl/shader.cpp
@@ -27,8 +27,14 @@
 #include "common/textconsole.h"
 #include "common/util.h"
 
+namespace Common {
+DECLARE_SINGLETON(OpenGL::ShaderManager);
+}
+
 namespace OpenGL {
 
+namespace {
+
 const char *const g_defaultVertexShader = 
 	"attribute vec4 position;\n"
 	"attribute vec2 texCoordIn;\n"
@@ -55,7 +61,20 @@ const char *const g_defaultFragmentShader =
 	"\tgl_FragColor = blendColor * texture2D(texture, texCoord);\n"
 	"}\n";
 
-namespace {
+const char *const g_lookUpFragmentShader =
+	"varying vec2 texCoord;\n"
+	"varying vec4 blendColor;\n"
+	"\n"
+	"uniform sampler2D texture;\n"
+	"uniform sampler2D palette;\n"
+	"\n"
+	"const float adjustFactor = 255.0 / 256.0 + 1.0 / (2.0 * 256.0);"
+	"\n"
+	"void main(void) {\n"
+	"\tvec4 index = texture2D(texture, texCoord);\n"
+	"\tgl_FragColor = blendColor * texture2D(palette, vec2(index.a * adjustFactor, 0.0));\n"
+	"}\n";
+
 
 // Taken from: https://en.wikibooks.org/wiki/OpenGL_Programming/Modern_OpenGL_Tutorial_03#OpenGL_ES_2_portability
 const char *const g_precisionDefines =
@@ -219,6 +238,38 @@ GLshader Shader::compileShader(const char *source, GLenum shaderType) {
 	return handle;
 }
 
+ShaderManager::ShaderManager() {
+	_builtIn[kDefault] = new Shader(g_defaultVertexShader, g_defaultFragmentShader);
+	_builtIn[kCLUT8LookUp] = new Shader(g_defaultVertexShader, g_lookUpFragmentShader);
+}
+
+ShaderManager::~ShaderManager() {
+	for (int i = 0; i < ARRAYSIZE(_builtIn); ++i) {
+		delete _builtIn[i];
+	}
+}
+
+void ShaderManager::notifyDestroy() {
+	for (int i = 0; i < ARRAYSIZE(_builtIn); ++i) {
+		_builtIn[i]->destroy();
+	}
+}
+
+void ShaderManager::notifyCreate() {
+	for (int i = 0; i < ARRAYSIZE(_builtIn); ++i) {
+		_builtIn[i]->recreate();
+	}
+}
+
+Shader *ShaderManager::query(ShaderUsage shader) const {
+	if (shader == kMaxUsages) {
+		warning("OpenGL: ShaderManager::query used with kMaxUsages");
+		return nullptr;
+	}
+
+	return _builtIn[shader];
+}
+
 } // End of namespace OpenGL
 
 #endif // !USE_FORCED_GLES
diff --git a/backends/graphics/opengl/shader.h b/backends/graphics/opengl/shader.h
index 98a2a28..e5dbcac 100644
--- a/backends/graphics/opengl/shader.h
+++ b/backends/graphics/opengl/shader.h
@@ -28,6 +28,7 @@
 #if !USE_FORCED_GLES
 
 #include "common/str.h"
+#include "common/singleton.h"
 
 namespace OpenGL {
 
@@ -37,9 +38,6 @@ enum {
 	kColorAttribLocation    = 2
 };
 
-extern const char *const g_defaultVertexShader;
-extern const char *const g_defaultFragmentShader;
-
 class Shader {
 public:
 	Shader(const Common::String &vertex, const Common::String &fragment);
@@ -121,8 +119,47 @@ protected:
 	static GLshader compileShader(const char *source, GLenum shaderType);
 };
 
+class ShaderManager : public Common::Singleton<ShaderManager> {
+public:
+	enum ShaderUsage {
+		/** Default shader implementing the GL fixed-function pipeline. */
+		kDefault = 0,
+
+		/** CLUT8 look up shader. */
+		kCLUT8LookUp,
+
+		/** Number of built-in shaders. Should not be used for query. */
+		kMaxUsages
+	};
+
+	/**
+	 * Notify shader manager about context destruction.
+	 */
+	void notifyDestroy();
+
+	/**
+	 * Notify shader manager about context creation.
+	 */
+	void notifyCreate();
+
+	/**
+	 * Query a built-in shader.
+	 */
+	Shader *query(ShaderUsage shader) const;
+
+private:
+	friend class Common::Singleton<SingletonBaseType>;
+	ShaderManager();
+	~ShaderManager();
+
+	Shader *_builtIn[kMaxUsages];
+};
+
 } // End of namespace OpenGL
 
+/** Shortcut for accessing the font manager. */
+#define ShaderMan (OpenGL::ShaderManager::instance())
+
 #endif // !USE_FORCED_GLES
 
 #endif
diff --git a/backends/graphics/opengl/texture.cpp b/backends/graphics/opengl/texture.cpp
index 61e8dc3..828dade 100644
--- a/backends/graphics/opengl/texture.cpp
+++ b/backends/graphics/opengl/texture.cpp
@@ -506,21 +506,6 @@ void TextureRGB555::updateTexture() {
 #endif // !USE_FORCED_GL
 
 #if !USE_FORCED_GLES
-namespace {
-const char *const g_lookUpFragmentShader =
-	"varying vec2 texCoord;\n"
-	"varying vec4 blendColor;\n"
-	"\n"
-	"uniform sampler2D texture;\n"
-	"uniform sampler2D palette;\n"
-	"\n"
-	"const float adjustFactor = 255.0 / 256.0 + 1.0 / (2.0 * 256.0);"
-	"\n"
-	"void main(void) {\n"
-	"\tvec4 index = texture2D(texture, texCoord);\n"
-	"\tgl_FragColor = blendColor * texture2D(palette, vec2(index.a * adjustFactor, 0.0));\n"
-	"}\n";
-} // End of anonymous namespace
 
 // _clut8Texture needs 8 bits internal precision, otherwise graphics glitches
 // can occur. GL_ALPHA does not have any internal precision requirements.
@@ -532,20 +517,17 @@ TextureCLUT8GPU::TextureCLUT8GPU()
       _paletteTexture(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE),
       _glTexture(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE),
       _glFBO(0), _clut8Vertices(), _projectionMatrix(),
-      _lookUpShader(nullptr), _paletteLocation(-1),
+      _paletteLocation(-1),
       _clut8Data(), _userPixelData(), _palette(), _paletteDirty(false) {
 	// Allocate space for 256 colors.
 	_paletteTexture.setSize(256, 1);
 
-	_lookUpShader = new Shader(g_defaultVertexShader, g_lookUpFragmentShader);
-	_lookUpShader->recreate();
-	_paletteLocation = _lookUpShader->getUniformLocation("palette");
+	_paletteLocation = ShaderMan.query(ShaderManager::kCLUT8LookUp)->getUniformLocation("palette");
 
 	setupFBO();
 }
 
 TextureCLUT8GPU::~TextureCLUT8GPU() {
-	delete _lookUpShader;
 	GL_CALL_SAFE(glDeleteFramebuffers, (1, &_glFBO));
 	_clut8Data.free();
 }
@@ -554,7 +536,6 @@ void TextureCLUT8GPU::destroy() {
 	_clut8Texture.destroy();
 	_paletteTexture.destroy();
 	_glTexture.destroy();
-	_lookUpShader->destroy();
 
 	GL_CALL(glDeleteFramebuffers(1, &_glFBO));
 	_glFBO = 0;
@@ -564,8 +545,7 @@ void TextureCLUT8GPU::recreate() {
 	_clut8Texture.create();
 	_paletteTexture.create();
 	_glTexture.create();
-	_lookUpShader->recreate();
-	_paletteLocation = _lookUpShader->getUniformLocation("palette");
+	_paletteLocation = ShaderMan.query(ShaderManager::kCLUT8LookUp)->getUniformLocation("palette");
 	setupFBO();
 
 	// In case image date exists assure it will be completely refreshed next
@@ -743,8 +723,9 @@ void TextureCLUT8GPU::lookUpColors() {
 	_clut8Texture.bind();
 
 	// Do color look up.
-	_lookUpShader->activate(_projectionMatrix);
-	_lookUpShader->setUniformI(_paletteLocation, 1);
+	Shader *lookUpShader = ShaderMan.query(ShaderManager::kCLUT8LookUp);
+	lookUpShader->activate(_projectionMatrix);
+	lookUpShader->setUniformI(_paletteLocation, 1);
 	g_context.activePipeline->setDrawCoordinates(_clut8Vertices, _clut8Texture.getTexCoords());
 	GL_CALL(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
 
diff --git a/backends/graphics/opengl/texture.h b/backends/graphics/opengl/texture.h
index 9592815..5f586f6 100644
--- a/backends/graphics/opengl/texture.h
+++ b/backends/graphics/opengl/texture.h
@@ -366,7 +366,6 @@ private:
 	GLfloat _clut8Vertices[4*2];
 	GLfloat _projectionMatrix[4*4];
 
-	Shader *_lookUpShader;
 	GLint _paletteLocation;
 
 	Graphics::Surface _clut8Data;


Commit: c4e65732befdfb675111387c3c7edb616bf2f976
    https://github.com/scummvm/scummvm/commit/c4e65732befdfb675111387c3c7edb616bf2f976
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:26+01:00

Commit Message:
OPENGL: Introduce abstraction for framebuffer.

This allows us to use various framebuffer settings easily. Now the GPU
accelerated CLUT8 surface implementation does not need to query former
framebuffer state anymore.

Changed paths:
  A backends/graphics/opengl/framebuffer.cpp
  A backends/graphics/opengl/framebuffer.h
    backends/graphics/opengl/context.cpp
    backends/graphics/opengl/opengl-graphics.cpp
    backends/graphics/opengl/opengl-graphics.h
    backends/graphics/opengl/opengl-sys.h
    backends/graphics/opengl/texture.cpp
    backends/graphics/opengl/texture.h
    backends/module.mk



diff --git a/backends/graphics/opengl/context.cpp b/backends/graphics/opengl/context.cpp
index 7402e79..d9c4085 100644
--- a/backends/graphics/opengl/context.cpp
+++ b/backends/graphics/opengl/context.cpp
@@ -24,6 +24,7 @@
 #include "backends/graphics/opengl/opengl-graphics.h"
 #include "backends/graphics/opengl/shader.h"
 #include "backends/graphics/opengl/pipeline.h"
+#include "backends/graphics/opengl/framebuffer.h"
 
 #include "common/tokenizer.h"
 #include "common/debug.h"
@@ -42,9 +43,24 @@ void Context::reset() {
 #include "backends/graphics/opengl/opengl-func.h"
 #undef GL_FUNC_DEF
 
+	activeFramebuffer = nullptr;
 	activePipeline = nullptr;
 }
 
+Framebuffer *Context::setFramebuffer(Framebuffer *framebuffer) {
+	Framebuffer *oldFramebuffer = activeFramebuffer;
+	if (oldFramebuffer) {
+		oldFramebuffer->deactivate();
+	}
+
+	activeFramebuffer = framebuffer;
+	if (activeFramebuffer) {
+		activeFramebuffer->activate();
+	}
+
+	return oldFramebuffer;
+}
+
 Pipeline *Context::setPipeline(Pipeline *pipeline) {
 	Pipeline *oldPipeline = activePipeline;
 
diff --git a/backends/graphics/opengl/framebuffer.cpp b/backends/graphics/opengl/framebuffer.cpp
new file mode 100644
index 0000000..cca00ba
--- /dev/null
+++ b/backends/graphics/opengl/framebuffer.cpp
@@ -0,0 +1,251 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "backends/graphics/opengl/framebuffer.h"
+#include "backends/graphics/opengl/texture.h"
+
+namespace OpenGL {
+
+Framebuffer::Framebuffer()
+    : _viewport(), _projectionMatrix(), _isActive(false), _clearColor(),
+      _blendState(false), _scissorTestState(false), _scissorBox() {
+}
+
+void Framebuffer::activate() {
+	_isActive = true;
+
+	applyViewport();
+	applyClearColor();
+	applyBlendState();
+	applyScissorTestState();
+	applyScissorBox();
+}
+
+void Framebuffer::deactivate() {
+	_isActive = false;
+}
+
+void Framebuffer::setClearColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
+	_clearColor[0] = r;
+	_clearColor[1] = g;
+	_clearColor[2] = b;
+	_clearColor[3] = a;
+
+	// Directly apply changes when we are active.
+	if (isActive()) {
+		applyClearColor();
+	}
+}
+
+void Framebuffer::enableBlend(bool enable) {
+	_blendState = enable;
+
+	// Directly apply changes when we are active.
+	if (isActive()) {
+		applyBlendState();
+	}
+}
+
+void Framebuffer::enableScissorTest(bool enable) {
+	_scissorTestState = enable;
+
+	// Directly apply changes when we are active.
+	if (isActive()) {
+		applyScissorTestState();
+	}
+}
+
+void Framebuffer::setScissorBox(GLint x, GLint y, GLsizei w, GLsizei h) {
+	_scissorBox[0] = x;
+	_scissorBox[1] = y;
+	_scissorBox[2] = w;
+	_scissorBox[3] = h;
+
+	// Directly apply changes when we are active.
+	if (isActive()) {
+		applyScissorBox();
+	}
+}
+
+void Framebuffer::applyViewport() {
+	GL_CALL(glViewport(_viewport[0], _viewport[1], _viewport[2], _viewport[3]));
+}
+
+void Framebuffer::applyClearColor() {
+	GL_CALL(glClearColor(_clearColor[0], _clearColor[1], _clearColor[2], _clearColor[3]));
+}
+
+void Framebuffer::applyBlendState() {
+	if (_blendState) {
+		GL_CALL(glEnable(GL_BLEND));
+	} else {
+		GL_CALL(glDisable(GL_BLEND));
+	}
+}
+
+void Framebuffer::applyScissorTestState() {
+	if (_scissorTestState) {
+		GL_CALL(glEnable(GL_SCISSOR_TEST));
+	} else {
+		GL_CALL(glDisable(GL_SCISSOR_TEST));
+	}
+}
+
+void Framebuffer::applyScissorBox() {
+	GL_CALL(glScissor(_scissorBox[0], _scissorBox[1], _scissorBox[2], _scissorBox[3]));
+}
+
+//
+// Backbuffer implementation
+//
+
+void Backbuffer::activate() {
+	Framebuffer::activate();
+
+#if !USE_FORCED_GLES
+	if (g_context.framebufferObjectSupported) {
+		GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0));
+	}
+#endif
+}
+
+void Backbuffer::setDimensions(uint width, uint height) {
+	// Set viewport dimensions.
+	_viewport[0] = 0;
+	_viewport[1] = 0;
+	_viewport[2] = width;
+	_viewport[3] = height;
+
+	// Setup orthogonal projection matrix.
+	_projectionMatrix[ 0] =  2.0f / width;
+	_projectionMatrix[ 1] =  0.0f;
+	_projectionMatrix[ 2] =  0.0f;
+	_projectionMatrix[ 3] =  0.0f;
+
+	_projectionMatrix[ 4] =  0.0f;
+	_projectionMatrix[ 5] = -2.0f / height;
+	_projectionMatrix[ 6] =  0.0f;
+	_projectionMatrix[ 7] =  0.0f;
+
+	_projectionMatrix[ 8] =  0.0f;
+	_projectionMatrix[ 9] =  0.0f;
+	_projectionMatrix[10] =  0.0f;
+	_projectionMatrix[11] =  0.0f;
+
+	_projectionMatrix[12] = -1.0f;
+	_projectionMatrix[13] =  1.0f;
+	_projectionMatrix[14] =  0.0f;
+	_projectionMatrix[15] =  1.0f;
+
+	// Directly apply changes when we are active.
+	if (isActive()) {
+		applyViewport();
+	}
+}
+
+//
+// Render to texture target implementation
+//
+
+#if !USE_FORCED_GLES
+TextureTarget::TextureTarget()
+    : _texture(new GLTexture(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE)), _glFBO(0), _needUpdate(true) {
+}
+
+TextureTarget::~TextureTarget() {
+	delete _texture;
+	GL_CALL_SAFE(glDeleteFramebuffers, (1, &_glFBO));
+}
+
+void TextureTarget::activate() {
+	Framebuffer::activate();
+
+	// Allocate framebuffer object if necessary.
+	if (!_glFBO) {
+		GL_CALL(glGenFramebuffers(1, &_glFBO));
+		_needUpdate = true;
+	}
+
+	// Attach destination texture to FBO.
+	GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, _glFBO));
+
+	// If required attach texture to FBO.
+	if (_needUpdate) {
+		GL_CALL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _texture->getGLTexture(), 0));
+		_needUpdate = false;
+	}
+}
+
+void TextureTarget::destroy() {
+	GL_CALL(glDeleteFramebuffers(1, &_glFBO));
+	_glFBO = 0;
+
+	_texture->destroy();
+}
+
+void TextureTarget::create() {
+	_texture->create();
+
+	_needUpdate = true;
+}
+
+void TextureTarget::setSize(uint width, uint height) {
+	_texture->setSize(width, height);
+
+	const uint texWidth  = _texture->getWidth();
+	const uint texHeight = _texture->getHeight();
+
+	// Set viewport dimensions.
+	_viewport[0] = 0;
+	_viewport[1] = 0;
+	_viewport[2] = texWidth;
+	_viewport[3] = texHeight;
+
+	// Setup orthogonal projection matrix.
+	_projectionMatrix[ 0] =  2.0f / texWidth;
+	_projectionMatrix[ 1] =  0.0f;
+	_projectionMatrix[ 2] =  0.0f;
+	_projectionMatrix[ 3] =  0.0f;
+
+	_projectionMatrix[ 4] =  0.0f;
+	_projectionMatrix[ 5] =  2.0f / texHeight;
+	_projectionMatrix[ 6] =  0.0f;
+	_projectionMatrix[ 7] =  0.0f;
+
+	_projectionMatrix[ 8] =  0.0f;
+	_projectionMatrix[ 9] =  0.0f;
+	_projectionMatrix[10] =  0.0f;
+	_projectionMatrix[11] =  0.0f;
+
+	_projectionMatrix[12] = -1.0f;
+	_projectionMatrix[13] = -1.0f;
+	_projectionMatrix[14] =  0.0f;
+	_projectionMatrix[15] =  1.0f;
+
+	// Directly apply changes when we are active.
+	if (isActive()) {
+		applyViewport();
+	}
+}
+#endif // !USE_FORCED_GLES
+
+} // End of namespace OpenGL
diff --git a/backends/graphics/opengl/framebuffer.h b/backends/graphics/opengl/framebuffer.h
new file mode 100644
index 0000000..be829de
--- /dev/null
+++ b/backends/graphics/opengl/framebuffer.h
@@ -0,0 +1,157 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BACKENDS_GRAPHICS_OPENGL_FRAMEBUFFER_H
+#define BACKENDS_GRAPHICS_OPENGL_FRAMEBUFFER_H
+
+#include "backends/graphics/opengl/opengl-sys.h"
+
+namespace OpenGL {
+
+/**
+ * Object describing a framebuffer OpenGL can render to.
+ */
+class Framebuffer {
+public:
+	Framebuffer();
+	virtual ~Framebuffer() {};
+
+	/**
+	 * Activate framebuffer.
+	 *
+	 * This is supposed to set all state associated with the framebuffer.
+	 */
+	virtual void activate() = 0;
+
+	/**
+	 * Deactivate framebuffer.
+	 *
+	 * This is supposed to make any cleanup required when unbinding the
+	 * framebuffer.
+	 */
+	virtual void deactivate();
+
+	/**
+	 * Set the clear color of the framebuffer.
+	 */
+	void setClearColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
+
+	/**
+	 * Enable/disable GL_BLEND.
+	 */
+	void enableBlend(bool enable);
+
+	/**
+	 * Enable/disable GL_SCISSOR_TEST.
+	 */
+	void enableScissorTest(bool enable);
+
+	/**
+	 * Set scissor box dimensions.
+	 */
+	void setScissorBox(GLint x, GLint y, GLsizei w, GLsizei h);
+
+	/**
+	 * Obtain projection matrix of the framebuffer.
+	 */
+	const GLfloat *getProjectionMatrix() const { return _projectionMatrix; }
+protected:
+	bool isActive() const { return _isActive; }
+
+	GLint _viewport[4];
+	void applyViewport();
+
+	GLfloat _projectionMatrix[4*4];
+private:
+	bool _isActive;
+
+	GLfloat _clearColor[4];
+	void applyClearColor();
+
+	bool _blendState;
+	void applyBlendState();
+
+	bool _scissorTestState;
+	void applyScissorTestState();
+
+	GLint _scissorBox[4];
+	void applyScissorBox();
+};
+
+/**
+ * Default back buffer implementation.
+ */
+class Backbuffer : public Framebuffer {
+public:
+	virtual void activate();
+
+	/**
+	 * Set the dimensions (a.k.a. size) of the back buffer.
+	 */
+	void setDimensions(uint width, uint height);
+};
+
+#if !USE_FORCED_GLES
+class GLTexture;
+
+/**
+ * Render to texture framebuffer implementation.
+ *
+ * This target allows to render to a texture, which can then be used for
+ * further rendering.
+ */
+class TextureTarget : public Framebuffer {
+public:
+	TextureTarget();
+	virtual ~TextureTarget();
+
+	virtual void activate();
+
+	/**
+	 * Notify that the GL context is about to be destroyed.
+	 */
+	void destroy();
+
+	/**
+	 * Notify that the GL context has been created.
+	 */
+	void create();
+
+	/**
+	 * Set size of the texture target.
+	 */
+	void setSize(uint width, uint height);
+
+	/**
+	 * Query pointer to underlying GL texture.
+	 */
+	GLTexture *getTexture() const { return _texture; }
+private:
+	GLTexture *_texture;
+	GLuint _glFBO;
+	bool _needUpdate;
+};
+#endif
+
+} // End of namespace OpenGL
+
+#endif
diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index a830148..36fc7b8 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -57,9 +57,6 @@ OpenGLGraphicsManager::OpenGLGraphicsManager()
 #ifdef USE_OSD
       , _osdAlpha(0), _osdFadeStartTime(0), _osd(nullptr)
 #endif
-#if !USE_FORCED_GLES
-      , _projectionMatrix()
-#endif
     {
 	memset(_gamePalette, 0, sizeof(_gamePalette));
 	g_context.reset();
@@ -379,9 +376,9 @@ void OpenGLGraphicsManager::updateScreen() {
 		// cleared. For example, when switching from overlay visible to
 		// invisible, we need to assure that all contents are cleared to
 		// properly remove all overlay contents.
-		GL_CALL(glDisable(GL_SCISSOR_TEST));
+		_backBuffer.enableScissorTest(false);
 		GL_CALL(glClear(GL_COLOR_BUFFER_BIT));
-		GL_CALL(glEnable(GL_SCISSOR_TEST));
+		_backBuffer.enableScissorTest(true);
 
 		--_scissorOverride;
 	} else {
@@ -475,7 +472,7 @@ void OpenGLGraphicsManager::showOverlay() {
 	_forceRedraw = true;
 
 	// Allow drawing inside full screen area.
-	GL_CALL(glDisable(GL_SCISSOR_TEST));
+	_backBuffer.enableScissorTest(false);
 
 	// Update cursor position.
 	setMousePosition(_cursorX, _cursorY);
@@ -486,7 +483,7 @@ void OpenGLGraphicsManager::hideOverlay() {
 	_forceRedraw = true;
 
 	// Limit drawing to screen area.
-	GL_CALL(glEnable(GL_SCISSOR_TEST));
+	_backBuffer.enableScissorTest(true);
 	_scissorOverride = 3;
 
 	// Update cursor position.
@@ -763,23 +760,15 @@ void OpenGLGraphicsManager::setActualScreenSize(uint width, uint height) {
 	_outputScreenWidth = width;
 	_outputScreenHeight = height;
 
-	// Setup coordinate system.
-	GL_CALL(glViewport(0, 0, _outputScreenWidth, _outputScreenHeight));
-
-	// Orthogonal projection matrix in column major order.
-	const GLfloat orthoProjection[4*4] = {
-		 2.0f / _outputScreenWidth,  0.0f                      ,  0.0f, 0.0f,
-		 0.0f                     , -2.0f / _outputScreenHeight,  0.0f, 0.0f,
-		 0.0f                     ,  0.0f                      , -1.0f, 0.0f,
-		-1.0f                     ,  1.0f                      ,  0.0f, 1.0f
-	};
+	// Setup backbuffer size.
+	_backBuffer.setDimensions(width, height);
 
 #if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
 	if (!g_context.shadersSupported) {
 #endif
 #if !USE_FORCED_GLES2
 		GL_CALL(glMatrixMode(GL_PROJECTION));
-		GL_CALL(glLoadMatrixf(orthoProjection));
+		GL_CALL(glLoadMatrixf(_backBuffer.getProjectionMatrix()));
 
 		GL_CALL(glMatrixMode(GL_MODELVIEW));
 		GL_CALL(glLoadIdentity());
@@ -788,9 +777,7 @@ void OpenGLGraphicsManager::setActualScreenSize(uint width, uint height) {
 	} else {
 #endif
 #if !USE_FORCED_GLES
-		assert(sizeof(_projectionMatrix) == sizeof(orthoProjection));
-		memcpy(_projectionMatrix, orthoProjection, sizeof(_projectionMatrix));
-		ShaderMan.query(ShaderManager::kDefault)->activate(_projectionMatrix);
+		ShaderMan.query(ShaderManager::kDefault)->activate(_backBuffer.getProjectionMatrix());
 #endif
 #if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
 	}
@@ -890,20 +877,21 @@ void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &def
 	GL_CALL(glDisable(GL_DEPTH_TEST));
 	GL_CALL(glDisable(GL_DITHER));
 
-	// Default to black as clear color.
-	GL_CALL(glClearColor(0.0f, 0.0f, 0.0f, 0.0f));
 	g_context.activePipeline->setColor(1.0f, 1.0f, 1.0f, 1.0f);
 
-	// Setup alpha blend (for overlay and cursor).
-	GL_CALL(glEnable(GL_BLEND));
 	GL_CALL(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
 
+	// Setup backbuffer state.
+
+	// Default to black as clear color.
+	_backBuffer.setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+	// Setup alpha blend (for overlay and cursor).
+	_backBuffer.enableBlend(true);
 	// Setup scissor state accordingly.
-	if (_overlayVisible) {
-		GL_CALL(glDisable(GL_SCISSOR_TEST));
-	} else {
-		GL_CALL(glEnable(GL_SCISSOR_TEST));
-	}
+	_backBuffer.enableScissorTest(!_overlayVisible);
+
+	g_context.setFramebuffer(&_backBuffer);
+
 	// Clear the whole screen for the first three frames to assure any
 	// leftovers are cleared.
 	_scissorOverride = 3;
@@ -916,7 +904,7 @@ void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &def
 #if !USE_FORCED_GLES
 	if (g_context.shadersSupported) {
 		ShaderMan.notifyCreate();
-		ShaderMan.query(ShaderManager::kDefault)->activate(_projectionMatrix);
+		ShaderMan.query(ShaderManager::kDefault)->activate(_backBuffer.getProjectionMatrix());
 	}
 #endif
 
@@ -975,6 +963,9 @@ void OpenGLGraphicsManager::notifyContextDestroy() {
 	}
 #endif
 
+	// Unset back buffer.
+	g_context.setFramebuffer(nullptr);
+
 	// Destroy rendering pipeline.
 	g_context.setPipeline(nullptr);
 	delete _pipeline;
@@ -1185,10 +1176,10 @@ void OpenGLGraphicsManager::recalculateDisplayArea() {
 	// Setup drawing limitation for game graphics.
 	// This invovles some trickery because OpenGL's viewport coordinate system
 	// is upside down compared to ours.
-	GL_CALL(glScissor(_displayX,
-	                 _outputScreenHeight - _displayHeight - _displayY,
-	                 _displayWidth,
-	                 _displayHeight));
+	_backBuffer.setScissorBox(_displayX,
+	                          _outputScreenHeight - _displayHeight - _displayY,
+	                          _displayWidth,
+	                          _displayHeight);
 	// Clear the whole screen for the first three frames to remove leftovers.
 	_scissorOverride = 3;
 
diff --git a/backends/graphics/opengl/opengl-graphics.h b/backends/graphics/opengl/opengl-graphics.h
index f3cd4c4..35435c1 100644
--- a/backends/graphics/opengl/opengl-graphics.h
+++ b/backends/graphics/opengl/opengl-graphics.h
@@ -24,6 +24,7 @@
 #define BACKENDS_GRAPHICS_OPENGL_OPENGL_GRAPHICS_H
 
 #include "backends/graphics/opengl/opengl-sys.h"
+#include "backends/graphics/opengl/framebuffer.h"
 #include "backends/graphics/graphics.h"
 
 #include "common/frac.h"
@@ -305,6 +306,11 @@ private:
 	void initializeGLContext();
 
 	/**
+	 * Render back buffer.
+	 */
+	Backbuffer _backBuffer;
+
+	/**
 	 * OpenGL pipeline used for rendering.
 	 */
 	Pipeline *_pipeline;
@@ -527,17 +533,6 @@ private:
 	 */
 	uint _scissorOverride;
 
-#if !USE_FORCED_GLES
-	//
-	// Shaders
-	//
-
-	/**
-	 * Projection matrix used.
-	 */
-	GLfloat _projectionMatrix[4*4];
-#endif
-
 #ifdef USE_OSD
 	//
 	// OSD
diff --git a/backends/graphics/opengl/opengl-sys.h b/backends/graphics/opengl/opengl-sys.h
index f68897b..ffc80a2 100644
--- a/backends/graphics/opengl/opengl-sys.h
+++ b/backends/graphics/opengl/opengl-sys.h
@@ -88,6 +88,7 @@ enum ContextType {
 };
 
 class Pipeline;
+class Framebuffer;
 
 /**
  * Description structure of the OpenGL (ES) context.
@@ -123,6 +124,19 @@ struct Context {
 #include "backends/graphics/opengl/opengl-func.h"
 #undef GL_FUNC_DEF
 
+	/** Currently active framebuffer. */
+	Framebuffer *activeFramebuffer;
+
+	/**
+	 * Set new framebuffer.
+	 *
+	 * Client is responsible for any memory management related to framebuffers.
+	 *
+	 * @param framebuffer Framebuffer to activate.
+	 * @return Formerly active framebuffer.
+	 */
+	Framebuffer *setFramebuffer(Framebuffer *framebuffer);
+
 	//
 	// Wrapper functionality to handle fixed-function pipelines and
 	// programmable pipelines in the same fashion.
diff --git a/backends/graphics/opengl/texture.cpp b/backends/graphics/opengl/texture.cpp
index 828dade..02e1b2c 100644
--- a/backends/graphics/opengl/texture.cpp
+++ b/backends/graphics/opengl/texture.cpp
@@ -23,6 +23,7 @@
 #include "backends/graphics/opengl/texture.h"
 #include "backends/graphics/opengl/shader.h"
 #include "backends/graphics/opengl/pipeline.h"
+#include "backends/graphics/opengl/framebuffer.h"
 
 #include "common/rect.h"
 #include "common/textconsole.h"
@@ -515,38 +516,30 @@ void TextureRGB555::updateTexture() {
 TextureCLUT8GPU::TextureCLUT8GPU()
     : _clut8Texture(GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE),
       _paletteTexture(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE),
-      _glTexture(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE),
-      _glFBO(0), _clut8Vertices(), _projectionMatrix(),
-      _paletteLocation(-1),
+      _target(new TextureTarget()), _clut8Vertices(), _paletteLocation(-1),
       _clut8Data(), _userPixelData(), _palette(), _paletteDirty(false) {
 	// Allocate space for 256 colors.
 	_paletteTexture.setSize(256, 1);
 
 	_paletteLocation = ShaderMan.query(ShaderManager::kCLUT8LookUp)->getUniformLocation("palette");
-
-	setupFBO();
 }
 
 TextureCLUT8GPU::~TextureCLUT8GPU() {
-	GL_CALL_SAFE(glDeleteFramebuffers, (1, &_glFBO));
+	delete _target;
 	_clut8Data.free();
 }
 
 void TextureCLUT8GPU::destroy() {
 	_clut8Texture.destroy();
 	_paletteTexture.destroy();
-	_glTexture.destroy();
-
-	GL_CALL(glDeleteFramebuffers(1, &_glFBO));
-	_glFBO = 0;
+	_target->destroy();
 }
 
 void TextureCLUT8GPU::recreate() {
 	_clut8Texture.create();
 	_paletteTexture.create();
-	_glTexture.create();
 	_paletteLocation = ShaderMan.query(ShaderManager::kCLUT8LookUp)->getUniformLocation("palette");
-	setupFBO();
+	_target->create();
 
 	// In case image date exists assure it will be completely refreshed next
 	// time.
@@ -557,13 +550,13 @@ void TextureCLUT8GPU::recreate() {
 }
 
 void TextureCLUT8GPU::enableLinearFiltering(bool enable) {
-	_glTexture.enableLinearFiltering(enable);
+	_target->getTexture()->enableLinearFiltering(enable);
 }
 
 void TextureCLUT8GPU::allocate(uint width, uint height) {
 	// Assure the texture can contain our user data.
 	_clut8Texture.setSize(width, height);
-	_glTexture.setSize(width, height);
+	_target->setSize(width, height);
 
 	// In case the needed texture dimension changed we will reinitialize the
 	// texture data buffer.
@@ -587,26 +580,6 @@ void TextureCLUT8GPU::allocate(uint width, uint height) {
 
 	_clut8Vertices[6] = width;
 	_clut8Vertices[7] = height;
-
-	_projectionMatrix[ 0] =  2.0f / _glTexture.getWidth();
-	_projectionMatrix[ 1] =  0.0f;
-	_projectionMatrix[ 2] =  0.0f;
-	_projectionMatrix[ 3] =  0.0f;
-
-	_projectionMatrix[ 4] =  0.0f;
-	_projectionMatrix[ 5] =  2.0f / _glTexture.getHeight();
-	_projectionMatrix[ 6] =  0.0f;
-	_projectionMatrix[ 7] =  0.0f;
-
-	_projectionMatrix[ 8] =  0.0f;
-	_projectionMatrix[ 9] =  0.0f;
-	_projectionMatrix[10] =  0.0f;
-	_projectionMatrix[11] =  0.0f;
-
-	_projectionMatrix[12] = -1.0f;
-	_projectionMatrix[13] = -1.0f;
-	_projectionMatrix[14] =  0.0f;
-	_projectionMatrix[15] =  1.0f;
 }
 
 void TextureCLUT8GPU::draw(GLfloat x, GLfloat y, GLfloat w, GLfloat h) {
@@ -619,7 +592,7 @@ void TextureCLUT8GPU::draw(GLfloat x, GLfloat y, GLfloat w, GLfloat h) {
 	updateTextures();
 
 	// Set the texture.
-	_glTexture.bind();
+	_target->getTexture()->bind();
 
 	// Calculate the screen rect where the texture will be drawn.
 	const GLfloat vertices[4*2] = {
@@ -630,7 +603,7 @@ void TextureCLUT8GPU::draw(GLfloat x, GLfloat y, GLfloat w, GLfloat h) {
 	};
 
 	// Setup coordinates for drawing.
-	g_context.activePipeline->setDrawCoordinates(vertices, _glTexture.getTexCoords());
+	g_context.activePipeline->setDrawCoordinates(vertices, _target->getTexture()->getTexCoords());
 
 	// Draw the texture to the screen buffer.
 	GL_CALL(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
@@ -695,24 +668,7 @@ void TextureCLUT8GPU::lookUpColors() {
 	GLint oldProgram = 0;
 	GL_CALL(glGetIntegerv(GL_CURRENT_PROGRAM, &oldProgram));
 
-	GLint viewport[4];
-	GL_CALL(glGetIntegerv(GL_VIEWPORT, viewport));
-
-	GLboolean scissorState;
-	GL_ASSIGN(scissorState, glIsEnabled(GL_SCISSOR_TEST));
-	GLboolean blendState;
-	GL_ASSIGN(blendState, glIsEnabled(GL_BLEND));
-
-	GLint oldFBO = 0;
-	GL_CALL(glGetIntegerv(GL_FRAMEBUFFER_BINDING, &oldFBO));
-
-	// Update state.
-	GL_CALL(glViewport(0, 0, _glTexture.getWidth(), _glTexture.getHeight()));
-	GL_CALL(glDisable(GL_SCISSOR_TEST));
-	GL_CALL(glDisable(GL_BLEND));
-
-	// Bind framebuffer.
-	GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, _glFBO));
+	Framebuffer *oldFramebuffer = g_context.setFramebuffer(_target);
 
 	// Set the palette texture.
 	GL_CALL(glActiveTexture(GL_TEXTURE1));
@@ -724,40 +680,15 @@ void TextureCLUT8GPU::lookUpColors() {
 
 	// Do color look up.
 	Shader *lookUpShader = ShaderMan.query(ShaderManager::kCLUT8LookUp);
-	lookUpShader->activate(_projectionMatrix);
+	lookUpShader->activate(_target->getProjectionMatrix());
 	lookUpShader->setUniformI(_paletteLocation, 1);
 	g_context.activePipeline->setDrawCoordinates(_clut8Vertices, _clut8Texture.getTexCoords());
 	GL_CALL(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
 
 	// Restore old state.
-	GL_CALL(glUseProgram(oldProgram));
-	GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, oldFBO));
+	g_context.setFramebuffer(oldFramebuffer);
 
-	if (blendState) {
-		GL_CALL(glEnable(GL_BLEND));
-	}
-	if (scissorState) {
-		GL_CALL(glEnable(GL_SCISSOR_TEST));
-	}
-	GL_CALL(glViewport(viewport[0], viewport[1], viewport[2], viewport[3]));
-}
-
-void TextureCLUT8GPU::setupFBO() {
-	// Allocate framebuffer object if necessary.
-	if (!_glFBO) {
-		GL_CALL(glGenFramebuffers(1, &_glFBO));
-	}
-
-	// Save old FBO.
-	GLint oldFBO = 0;
-	GL_CALL(glGetIntegerv(GL_FRAMEBUFFER_BINDING, &oldFBO));
-
-	// Attach destination texture to FBO.
-	GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, _glFBO));
-	GL_CALL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _glTexture.getGLTexture(), 0));
-
-	// Restore old FBO.
-	GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, oldFBO));
+	GL_CALL(glUseProgram(oldProgram));
 }
 #endif // !USE_FORCED_GLES
 
diff --git a/backends/graphics/opengl/texture.h b/backends/graphics/opengl/texture.h
index 5f586f6..df9893f 100644
--- a/backends/graphics/opengl/texture.h
+++ b/backends/graphics/opengl/texture.h
@@ -318,6 +318,8 @@ private:
 #endif // !USE_FORCED_GL
 
 #if !USE_FORCED_GLES
+class TextureTarget;
+
 class TextureCLUT8GPU : public Surface {
 public:
 	TextureCLUT8GPU();
@@ -359,12 +361,10 @@ private:
 
 	GLTexture _clut8Texture;
 	GLTexture _paletteTexture;
-	GLTexture _glTexture;
 
-	void setupFBO();
-	GLuint _glFBO;
+	TextureTarget *_target;
+
 	GLfloat _clut8Vertices[4*2];
-	GLfloat _projectionMatrix[4*4];
 
 	GLint _paletteLocation;
 
diff --git a/backends/module.mk b/backends/module.mk
index 3059422..f786933 100644
--- a/backends/module.mk
+++ b/backends/module.mk
@@ -54,6 +54,7 @@ ifdef USE_OPENGL
 MODULE_OBJS += \
 	graphics/opengl/context.o \
 	graphics/opengl/debug.o \
+	graphics/opengl/framebuffer.o \
 	graphics/opengl/opengl-graphics.o \
 	graphics/opengl/pipeline.o \
 	graphics/opengl/shader.o \


Commit: 472dbc4a84997e5efe83331f6e2e1e5c079f26ca
    https://github.com/scummvm/scummvm/commit/472dbc4a84997e5efe83331f6e2e1e5c079f26ca
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:26+01:00

Commit Message:
CONFIGURE: Abort configure stage when invalid OpenGL mode is specified.

Changed paths:
    configure



diff --git a/configure b/configure
index f6cac34..d42fb3c 100755
--- a/configure
+++ b/configure
@@ -4232,6 +4232,11 @@ case $_opengl_mode in
 		echo "yes (OpenGL ES 2)"
 		add_line_to_config_h "#define USE_GLES_MODE 2"
 		;;
+
+	*)
+		echo "invalid mode specification '$_opengl_mode'. Aborting."
+		exit 1
+		;;
 esac
 
 define_in_config_if_yes "$_opengl" "USE_OPENGL"


Commit: 0b46af2f0e5eef939daa73d5b38b6b817c78c7d8
    https://github.com/scummvm/scummvm/commit/0b46af2f0e5eef939daa73d5b38b6b817c78c7d8
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:27+01:00

Commit Message:
OPENGL: Don't prefix maxTextureSize variable for consistency.

Changed paths:
    backends/graphics/opengl/context.cpp
    backends/graphics/opengl/opengl-graphics.cpp
    backends/graphics/opengl/opengl-sys.h



diff --git a/backends/graphics/opengl/context.cpp b/backends/graphics/opengl/context.cpp
index d9c4085..3678abf 100644
--- a/backends/graphics/opengl/context.cpp
+++ b/backends/graphics/opengl/context.cpp
@@ -32,7 +32,7 @@
 namespace OpenGL {
 
 void Context::reset() {
-	_maxTextureSize = 0;
+	maxTextureSize = 0;
 
 	NPOTSupported = false;
 	shadersSupported = false;
@@ -121,8 +121,8 @@ void OpenGLGraphicsManager::initializeGLContext() {
 #undef LOAD_FUNC
 
 	// Obtain maximum texture size.
-	GL_CALL(glGetIntegerv(GL_MAX_TEXTURE_SIZE, &g_context._maxTextureSize));
-	debug(5, "OpenGL maximum texture size: %d", g_context._maxTextureSize);
+	GL_CALL(glGetIntegerv(GL_MAX_TEXTURE_SIZE, &g_context.maxTextureSize));
+	debug(5, "OpenGL maximum texture size: %d", g_context.maxTextureSize);
 
 	const char *extString = (const char *)g_context.glGetString(GL_EXTENSIONS);
 
diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index 36fc7b8..8832597 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -220,8 +220,8 @@ OSystem::TransactionError OpenGLGraphicsManager::endGFXTransaction() {
 		   // a context existing before, which means we don't know the maximum
 		   // supported texture size before this. Thus, we check whether the
 		   // requested game resolution is supported over here.
-		   || (   _currentState.gameWidth  > (uint)g_context._maxTextureSize
-		       || _currentState.gameHeight > (uint)g_context._maxTextureSize)) {
+		   || (   _currentState.gameWidth  > (uint)g_context.maxTextureSize
+		       || _currentState.gameHeight > (uint)g_context.maxTextureSize)) {
 			if (_transactionMode == kTransactionActive) {
 				// Try to setup the old state in case its valid and is
 				// actually different from the new one.
@@ -792,15 +792,15 @@ void OpenGLGraphicsManager::setActualScreenSize(uint width, uint height) {
 	// possible and then scale it to the physical display size. This sounds
 	// bad but actually all recent chips should support full HD resolution
 	// anyway. Thus, it should not be a real issue for modern hardware.
-	if (   overlayWidth  > (uint)g_context._maxTextureSize
-	    || overlayHeight > (uint)g_context._maxTextureSize) {
+	if (   overlayWidth  > (uint)g_context.maxTextureSize
+	    || overlayHeight > (uint)g_context.maxTextureSize) {
 		const frac_t outputAspect = intToFrac(_outputScreenWidth) / _outputScreenHeight;
 
 		if (outputAspect > (frac_t)FRAC_ONE) {
-			overlayWidth  = g_context._maxTextureSize;
+			overlayWidth  = g_context.maxTextureSize;
 			overlayHeight = intToFrac(overlayWidth) / outputAspect;
 		} else {
-			overlayHeight = g_context._maxTextureSize;
+			overlayHeight = g_context.maxTextureSize;
 			overlayWidth  = fracToInt(overlayHeight * outputAspect);
 		}
 	}
diff --git a/backends/graphics/opengl/opengl-sys.h b/backends/graphics/opengl/opengl-sys.h
index ffc80a2..ce4f0bf 100644
--- a/backends/graphics/opengl/opengl-sys.h
+++ b/backends/graphics/opengl/opengl-sys.h
@@ -106,7 +106,7 @@ struct Context {
 	void reset();
 
 	/** The maximum texture size supported by the context. */
-	GLint _maxTextureSize;
+	GLint maxTextureSize;
 
 	/** Whether GL_ARB_texture_non_power_of_two is available or not. */
 	bool NPOTSupported;


Commit: 0fe580d10c6fb73a90eccb046c8dcbf84b062b16
    https://github.com/scummvm/scummvm/commit/0fe580d10c6fb73a90eccb046c8dcbf84b062b16
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:27+01:00

Commit Message:
OPENGL: Make shader/framebuffer part of pipeline state.

Changed paths:
    backends/graphics/opengl/context.cpp
    backends/graphics/opengl/framebuffer.cpp
    backends/graphics/opengl/framebuffer.h
    backends/graphics/opengl/opengl-graphics.cpp
    backends/graphics/opengl/opengl-sys.h
    backends/graphics/opengl/pipeline.cpp
    backends/graphics/opengl/pipeline.h
    backends/graphics/opengl/texture.cpp



diff --git a/backends/graphics/opengl/context.cpp b/backends/graphics/opengl/context.cpp
index 3678abf..09da353 100644
--- a/backends/graphics/opengl/context.cpp
+++ b/backends/graphics/opengl/context.cpp
@@ -43,24 +43,9 @@ void Context::reset() {
 #include "backends/graphics/opengl/opengl-func.h"
 #undef GL_FUNC_DEF
 
-	activeFramebuffer = nullptr;
 	activePipeline = nullptr;
 }
 
-Framebuffer *Context::setFramebuffer(Framebuffer *framebuffer) {
-	Framebuffer *oldFramebuffer = activeFramebuffer;
-	if (oldFramebuffer) {
-		oldFramebuffer->deactivate();
-	}
-
-	activeFramebuffer = framebuffer;
-	if (activeFramebuffer) {
-		activeFramebuffer->activate();
-	}
-
-	return oldFramebuffer;
-}
-
 Pipeline *Context::setPipeline(Pipeline *pipeline) {
 	Pipeline *oldPipeline = activePipeline;
 
diff --git a/backends/graphics/opengl/framebuffer.cpp b/backends/graphics/opengl/framebuffer.cpp
index cca00ba..85245b6 100644
--- a/backends/graphics/opengl/framebuffer.cpp
+++ b/backends/graphics/opengl/framebuffer.cpp
@@ -22,6 +22,7 @@
 
 #include "backends/graphics/opengl/framebuffer.h"
 #include "backends/graphics/opengl/texture.h"
+#include "backends/graphics/opengl/pipeline.h"
 
 namespace OpenGL {
 
@@ -34,6 +35,7 @@ void Framebuffer::activate() {
 	_isActive = true;
 
 	applyViewport();
+	applyProjectionMatrix();
 	applyClearColor();
 	applyBlendState();
 	applyScissorTestState();
@@ -90,6 +92,10 @@ void Framebuffer::applyViewport() {
 	GL_CALL(glViewport(_viewport[0], _viewport[1], _viewport[2], _viewport[3]));
 }
 
+void Framebuffer::applyProjectionMatrix() {
+	g_context.activePipeline->setProjectionMatrix(_projectionMatrix);
+}
+
 void Framebuffer::applyClearColor() {
 	GL_CALL(glClearColor(_clearColor[0], _clearColor[1], _clearColor[2], _clearColor[3]));
 }
@@ -159,6 +165,7 @@ void Backbuffer::setDimensions(uint width, uint height) {
 	// Directly apply changes when we are active.
 	if (isActive()) {
 		applyViewport();
+		applyProjectionMatrix();
 	}
 }
 
@@ -244,6 +251,7 @@ void TextureTarget::setSize(uint width, uint height) {
 	// Directly apply changes when we are active.
 	if (isActive()) {
 		applyViewport();
+		applyProjectionMatrix();
 	}
 }
 #endif // !USE_FORCED_GLES
diff --git a/backends/graphics/opengl/framebuffer.h b/backends/graphics/opengl/framebuffer.h
index be829de..467c00e 100644
--- a/backends/graphics/opengl/framebuffer.h
+++ b/backends/graphics/opengl/framebuffer.h
@@ -81,6 +81,7 @@ protected:
 	void applyViewport();
 
 	GLfloat _projectionMatrix[4*4];
+	void applyProjectionMatrix();
 private:
 	bool _isActive;
 
diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index 8832597..e32753e 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -763,26 +763,6 @@ void OpenGLGraphicsManager::setActualScreenSize(uint width, uint height) {
 	// Setup backbuffer size.
 	_backBuffer.setDimensions(width, height);
 
-#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
-	if (!g_context.shadersSupported) {
-#endif
-#if !USE_FORCED_GLES2
-		GL_CALL(glMatrixMode(GL_PROJECTION));
-		GL_CALL(glLoadMatrixf(_backBuffer.getProjectionMatrix()));
-
-		GL_CALL(glMatrixMode(GL_MODELVIEW));
-		GL_CALL(glLoadIdentity());
-#endif
-#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
-	} else {
-#endif
-#if !USE_FORCED_GLES
-		ShaderMan.query(ShaderManager::kDefault)->activate(_backBuffer.getProjectionMatrix());
-#endif
-#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
-	}
-#endif
-
 	uint overlayWidth = width;
 	uint overlayHeight = height;
 
@@ -872,6 +852,14 @@ void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &def
 
 	g_context.setPipeline(_pipeline);
 
+#if !USE_FORCED_GLES
+	if (g_context.shadersSupported) {
+		ShaderMan.notifyCreate();
+
+		g_context.activePipeline->setShader(ShaderMan.query(ShaderManager::kDefault));
+	}
+#endif
+
 	// Disable 3D properties.
 	GL_CALL(glDisable(GL_CULL_FACE));
 	GL_CALL(glDisable(GL_DEPTH_TEST));
@@ -890,7 +878,7 @@ void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &def
 	// Setup scissor state accordingly.
 	_backBuffer.enableScissorTest(!_overlayVisible);
 
-	g_context.setFramebuffer(&_backBuffer);
+	g_context.activePipeline->setFramebuffer(&_backBuffer);
 
 	// Clear the whole screen for the first three frames to assure any
 	// leftovers are cleared.
@@ -901,13 +889,6 @@ void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &def
 	// code and that requires the same alignment too.
 	GL_CALL(glPixelStorei(GL_PACK_ALIGNMENT, 4));
 
-#if !USE_FORCED_GLES
-	if (g_context.shadersSupported) {
-		ShaderMan.notifyCreate();
-		ShaderMan.query(ShaderManager::kDefault)->activate(_backBuffer.getProjectionMatrix());
-	}
-#endif
-
 	// Refresh the output screen dimensions if some are set up.
 	if (_outputScreenWidth != 0 && _outputScreenHeight != 0) {
 		setActualScreenSize(_outputScreenWidth, _outputScreenHeight);
@@ -963,9 +944,6 @@ void OpenGLGraphicsManager::notifyContextDestroy() {
 	}
 #endif
 
-	// Unset back buffer.
-	g_context.setFramebuffer(nullptr);
-
 	// Destroy rendering pipeline.
 	g_context.setPipeline(nullptr);
 	delete _pipeline;
diff --git a/backends/graphics/opengl/opengl-sys.h b/backends/graphics/opengl/opengl-sys.h
index ce4f0bf..723e28f 100644
--- a/backends/graphics/opengl/opengl-sys.h
+++ b/backends/graphics/opengl/opengl-sys.h
@@ -124,19 +124,6 @@ struct Context {
 #include "backends/graphics/opengl/opengl-func.h"
 #undef GL_FUNC_DEF
 
-	/** Currently active framebuffer. */
-	Framebuffer *activeFramebuffer;
-
-	/**
-	 * Set new framebuffer.
-	 *
-	 * Client is responsible for any memory management related to framebuffers.
-	 *
-	 * @param framebuffer Framebuffer to activate.
-	 * @return Formerly active framebuffer.
-	 */
-	Framebuffer *setFramebuffer(Framebuffer *framebuffer);
-
 	//
 	// Wrapper functionality to handle fixed-function pipelines and
 	// programmable pipelines in the same fashion.
diff --git a/backends/graphics/opengl/pipeline.cpp b/backends/graphics/opengl/pipeline.cpp
index 362f15a..500597c 100644
--- a/backends/graphics/opengl/pipeline.cpp
+++ b/backends/graphics/opengl/pipeline.cpp
@@ -22,9 +22,29 @@
 
 #include "backends/graphics/opengl/pipeline.h"
 #include "backends/graphics/opengl/shader.h"
+#include "backends/graphics/opengl/framebuffer.h"
 
 namespace OpenGL {
 
+Pipeline::Pipeline()
+    : _activeFramebuffer(nullptr) {
+}
+
+Framebuffer *Pipeline::setFramebuffer(Framebuffer *framebuffer) {
+	Framebuffer *oldFramebuffer = _activeFramebuffer;
+	if (oldFramebuffer) {
+		oldFramebuffer->deactivate();
+	}
+
+	_activeFramebuffer = framebuffer;
+	if (_activeFramebuffer) {
+		_activeFramebuffer->activate();
+		setProjectionMatrix(_activeFramebuffer->getProjectionMatrix());
+	}
+
+	return oldFramebuffer;
+}
+
 #if !USE_FORCED_GLES2
 void FixedPipeline::activate() {
 	GL_CALL(glDisable(GL_LIGHTING));
@@ -51,9 +71,21 @@ void FixedPipeline::setDrawCoordinates(const GLfloat *vertices, const GLfloat *t
 	GL_CALL(glTexCoordPointer(2, GL_FLOAT, 0, texCoords));
 	GL_CALL(glVertexPointer(2, GL_FLOAT, 0, vertices));
 }
+
+void FixedPipeline::setProjectionMatrix(const GLfloat *projectionMatrix) {
+	GL_CALL(glMatrixMode(GL_PROJECTION));
+	GL_CALL(glLoadMatrixf(projectionMatrix));
+
+	GL_CALL(glMatrixMode(GL_MODELVIEW));
+	GL_CALL(glLoadIdentity());
+}
 #endif // !USE_FORCED_GLES2
 
 #if !USE_FORCED_GLES
+ShaderPipeline::ShaderPipeline()
+    : _activeShader(nullptr) {
+}
+
 void ShaderPipeline::activate() {
 	GL_CALL(glEnableVertexAttribArray(kPositionAttribLocation));
 	GL_CALL(glEnableVertexAttribArray(kTexCoordAttribLocation));
@@ -63,6 +95,17 @@ void ShaderPipeline::activate() {
 	}
 }
 
+Shader *ShaderPipeline::setShader(Shader *shader) {
+	Shader *oldShader = _activeShader;
+
+	_activeShader = shader;
+	if (_activeShader && _activeFramebuffer) {
+		_activeShader->activate(_activeFramebuffer->getProjectionMatrix());
+	}
+
+	return oldShader;
+}
+
 void ShaderPipeline::setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
 	GL_CALL(glVertexAttrib4f(kColorAttribLocation, r, g, b, a));
 }
@@ -71,6 +114,12 @@ void ShaderPipeline::setDrawCoordinates(const GLfloat *vertices, const GLfloat *
 	GL_CALL(glVertexAttribPointer(kTexCoordAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, texCoords));
 	GL_CALL(glVertexAttribPointer(kPositionAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, vertices));
 }
+
+void ShaderPipeline::setProjectionMatrix(const GLfloat *projectionMatrix) {
+	if (_activeShader) {
+		_activeShader->activate(projectionMatrix);
+	}
+}
 #endif // !USE_FORCED_GLES
 
 } // End of namespace OpenGL
diff --git a/backends/graphics/opengl/pipeline.h b/backends/graphics/opengl/pipeline.h
index e12390b..d101a99 100644
--- a/backends/graphics/opengl/pipeline.h
+++ b/backends/graphics/opengl/pipeline.h
@@ -27,6 +27,11 @@
 
 namespace OpenGL {
 
+class Framebuffer;
+#if !USE_FORCED_GLES
+class Shader;
+#endif
+
 /**
  * Interface for OpenGL pipeline functionality.
  *
@@ -35,6 +40,7 @@ namespace OpenGL {
  */
 class Pipeline {
 public:
+	Pipeline();
 	virtual ~Pipeline() {}
 
 	/**
@@ -46,6 +52,31 @@ public:
 	virtual void activate() = 0;
 
 	/**
+	 * Set framebuffer to render to.
+	 *
+	 * Client is responsible for any memory management related to framebuffer.
+	 *
+	 * @param framebuffer Framebuffer to activate.
+	 * @return Formerly active framebuffer.
+	 */
+	Framebuffer *setFramebuffer(Framebuffer *framebuffer);
+
+#if !USE_FORCED_GLES
+	/**
+	 * Set shader program.
+	 *
+	 * Not all pipelines support shader programs. This is method exits at this
+	 * place for convenience only.
+	 *
+	 * Client is responsible for any memory management related to shader.
+	 *
+	 * @param shader Shader program to activate.
+	 * @return Formerly active shader program.
+	 */
+	virtual Shader *setShader(Shader *shader) { return nullptr; }
+#endif
+
+	/**
 	 * Set modulation color.
 	 *
 	 * @param r Red component in [0,1].
@@ -63,6 +94,16 @@ public:
 	 *                  each vertex.
 	 */
 	virtual void setDrawCoordinates(const GLfloat *vertices, const GLfloat *texCoords) = 0;
+
+	/**
+	 * Set the projection matrix.
+	 *
+	 * This is intended to be only ever be used by Framebuffer subclasses.
+	 */
+	virtual void setProjectionMatrix(const GLfloat *projectionMatrix) = 0;
+
+protected:
+	Framebuffer *_activeFramebuffer;
 };
 
 #if !USE_FORCED_GLES2
@@ -73,17 +114,28 @@ public:
 	virtual void setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
 
 	virtual void setDrawCoordinates(const GLfloat *vertices, const GLfloat *texCoords);
+
+	virtual void setProjectionMatrix(const GLfloat *projectionMatrix);
 };
 #endif // !USE_FORCED_GLES2
 
 #if !USE_FORCED_GLES
 class ShaderPipeline : public Pipeline {
 public:
+	ShaderPipeline();
+
 	virtual void activate();
 
+	virtual Shader *setShader(Shader *shader);
+
 	virtual void setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
 
 	virtual void setDrawCoordinates(const GLfloat *vertices, const GLfloat *texCoords);
+
+	virtual void setProjectionMatrix(const GLfloat *projectionMatrix);
+
+private:
+	Shader *_activeShader;
 };
 #endif // !USE_FORCED_GLES
 
diff --git a/backends/graphics/opengl/texture.cpp b/backends/graphics/opengl/texture.cpp
index 02e1b2c..05b7ac1 100644
--- a/backends/graphics/opengl/texture.cpp
+++ b/backends/graphics/opengl/texture.cpp
@@ -657,7 +657,7 @@ void TextureCLUT8GPU::updateTextures() {
 		_paletteDirty = false;
 	}
 
-	// In case any data changed, do color look up and save result in _glTexture.
+	// In case any data changed, do color look up and store result in _target.
 	if (needLookUp) {
 		lookUpColors();
 	}
@@ -665,10 +665,11 @@ void TextureCLUT8GPU::updateTextures() {
 
 void TextureCLUT8GPU::lookUpColors() {
 	// Save old state.
-	GLint oldProgram = 0;
-	GL_CALL(glGetIntegerv(GL_CURRENT_PROGRAM, &oldProgram));
+	Framebuffer *oldFramebuffer = g_context.activePipeline->setFramebuffer(_target);
 
-	Framebuffer *oldFramebuffer = g_context.setFramebuffer(_target);
+	Shader *lookUpShader = ShaderMan.query(ShaderManager::kCLUT8LookUp);
+	Shader *oldShader = g_context.activePipeline->setShader(lookUpShader);
+	lookUpShader->setUniformI(_paletteLocation, 1);
 
 	// Set the palette texture.
 	GL_CALL(glActiveTexture(GL_TEXTURE1));
@@ -679,16 +680,12 @@ void TextureCLUT8GPU::lookUpColors() {
 	_clut8Texture.bind();
 
 	// Do color look up.
-	Shader *lookUpShader = ShaderMan.query(ShaderManager::kCLUT8LookUp);
-	lookUpShader->activate(_target->getProjectionMatrix());
-	lookUpShader->setUniformI(_paletteLocation, 1);
 	g_context.activePipeline->setDrawCoordinates(_clut8Vertices, _clut8Texture.getTexCoords());
 	GL_CALL(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
 
 	// Restore old state.
-	g_context.setFramebuffer(oldFramebuffer);
-
-	GL_CALL(glUseProgram(oldProgram));
+	g_context.activePipeline->setShader(oldShader);
+	g_context.activePipeline->setFramebuffer(oldFramebuffer);
 }
 #endif // !USE_FORCED_GLES
 


Commit: b17c035642cc33ee614046be011bf8ad9f9db95d
    https://github.com/scummvm/scummvm/commit/b17c035642cc33ee614046be011bf8ad9f9db95d
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:27+01:00

Commit Message:
OPENGL: Implement texture drawing in Pipeline instead of Surface.

Changed paths:
    backends/graphics/opengl/opengl-graphics.cpp
    backends/graphics/opengl/pipeline.cpp
    backends/graphics/opengl/pipeline.h
    backends/graphics/opengl/texture.cpp
    backends/graphics/opengl/texture.h



diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index e32753e..a685f34 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -370,6 +370,14 @@ void OpenGLGraphicsManager::updateScreen() {
 	}
 	_forceRedraw = false;
 
+	// Update changes to textures.
+	_gameScreen->updateGLTexture();
+	if (_cursor) {
+		_cursor->updateGLTexture();
+	}
+	_overlay->updateGLTexture();
+	_osd->updateGLTexture();
+
 	// Clear the screen buffer.
 	if (_scissorOverride && !_overlayVisible) {
 		// In certain cases we need to assure that the whole screen area is
@@ -388,11 +396,11 @@ void OpenGLGraphicsManager::updateScreen() {
 	const GLfloat shakeOffset = _gameScreenShakeOffset * (GLfloat)_displayHeight / _gameScreen->getHeight();
 
 	// First step: Draw the (virtual) game screen.
-	_gameScreen->draw(_displayX, _displayY + shakeOffset, _displayWidth, _displayHeight);
+	g_context.activePipeline->drawTexture(_gameScreen->getGLTexture(), _displayX, _displayY + shakeOffset, _displayWidth, _displayHeight);
 
 	// Second step: Draw the overlay if visible.
 	if (_overlayVisible) {
-		_overlay->draw(0, 0, _outputScreenWidth, _outputScreenHeight);
+		g_context.activePipeline->drawTexture(_overlay->getGLTexture(), 0, 0, _outputScreenWidth, _outputScreenHeight);
 	}
 
 	// Third step: Draw the cursor if visible.
@@ -401,9 +409,10 @@ void OpenGLGraphicsManager::updateScreen() {
 		// visible.
 		const GLfloat cursorOffset = _overlayVisible ? 0 : shakeOffset;
 
-		_cursor->draw(_cursorDisplayX - _cursorHotspotXScaled,
-		              _cursorDisplayY - _cursorHotspotYScaled + cursorOffset,
-		              _cursorWidthScaled, _cursorHeightScaled);
+		g_context.activePipeline->drawTexture(_cursor->getGLTexture(),
+		                         _cursorDisplayX - _cursorHotspotXScaled,
+		                         _cursorDisplayY - _cursorHotspotYScaled + cursorOffset,
+		                         _cursorWidthScaled, _cursorHeightScaled);
 	}
 
 #ifdef USE_OSD
@@ -427,7 +436,7 @@ void OpenGLGraphicsManager::updateScreen() {
 		g_context.activePipeline->setColor(1.0f, 1.0f, 1.0f, _osdAlpha / 100.0f);
 
 		// Draw the OSD texture.
-		_osd->draw(0, 0, _outputScreenWidth, _outputScreenHeight);
+		g_context.activePipeline->drawTexture(_osd->getGLTexture(), 0, 0, _outputScreenWidth, _outputScreenHeight);
 
 		// Reset color.
 		g_context.activePipeline->setColor(1.0f, 1.0f, 1.0f, 1.0f);
diff --git a/backends/graphics/opengl/pipeline.cpp b/backends/graphics/opengl/pipeline.cpp
index 500597c..9ac3fe4 100644
--- a/backends/graphics/opengl/pipeline.cpp
+++ b/backends/graphics/opengl/pipeline.cpp
@@ -67,9 +67,12 @@ void FixedPipeline::setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
 	GL_CALL(glColor4f(r, g, b, a));
 }
 
-void FixedPipeline::setDrawCoordinates(const GLfloat *vertices, const GLfloat *texCoords) {
-	GL_CALL(glTexCoordPointer(2, GL_FLOAT, 0, texCoords));
-	GL_CALL(glVertexPointer(2, GL_FLOAT, 0, vertices));
+void FixedPipeline::drawTexture(const GLTexture &texture, const GLfloat *coordinates) {
+	texture.bind();
+
+	GL_CALL(glTexCoordPointer(2, GL_FLOAT, 0, texture.getTexCoords()));
+	GL_CALL(glVertexPointer(2, GL_FLOAT, 0, coordinates));
+	GL_CALL(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
 }
 
 void FixedPipeline::setProjectionMatrix(const GLfloat *projectionMatrix) {
@@ -110,9 +113,12 @@ void ShaderPipeline::setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
 	GL_CALL(glVertexAttrib4f(kColorAttribLocation, r, g, b, a));
 }
 
-void ShaderPipeline::setDrawCoordinates(const GLfloat *vertices, const GLfloat *texCoords) {
-	GL_CALL(glVertexAttribPointer(kTexCoordAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, texCoords));
-	GL_CALL(glVertexAttribPointer(kPositionAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, vertices));
+void ShaderPipeline::drawTexture(const GLTexture &texture, const GLfloat *coordinates) {
+	texture.bind();
+
+	GL_CALL(glVertexAttribPointer(kTexCoordAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, texture.getTexCoords()));
+	GL_CALL(glVertexAttribPointer(kPositionAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, coordinates));
+	GL_CALL(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
 }
 
 void ShaderPipeline::setProjectionMatrix(const GLfloat *projectionMatrix) {
diff --git a/backends/graphics/opengl/pipeline.h b/backends/graphics/opengl/pipeline.h
index d101a99..5ec52f2 100644
--- a/backends/graphics/opengl/pipeline.h
+++ b/backends/graphics/opengl/pipeline.h
@@ -24,6 +24,7 @@
 #define BACKENDS_GRAPHICS_OPENGL_PIEPLINE_H
 
 #include "backends/graphics/opengl/opengl-sys.h"
+#include "backends/graphics/opengl/texture.h"
 
 namespace OpenGL {
 
@@ -87,13 +88,22 @@ public:
 	virtual void setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) = 0;
 
 	/**
-	 * Setup coordinates for drawing with glDrawArrays.
+	 * Draw a texture rectangle to the currently active framebuffer.
 	 *
-	 * @param vertices  The list of vertices, 2 coordinates for each vertex.
-	 * @param texCoords The list of texture coordinates, 2 coordinates for
-	 *                  each vertex.
+	 * @param texture     Texture to use for drawing.
+	 * @param coordinates x1, y1, x2, y2 coordinates where to draw the texture.
 	 */
-	virtual void setDrawCoordinates(const GLfloat *vertices, const GLfloat *texCoords) = 0;
+	virtual void drawTexture(const GLTexture &texture, const GLfloat *coordinates) = 0;
+
+	void drawTexture(const GLTexture &texture, GLfloat x, GLfloat y, GLfloat w, GLfloat h) {
+		const GLfloat coordinates[4*2] = {
+			x,     y,
+			x + w, y,
+			x,     y + h,
+			x + w, y + h
+		};
+		drawTexture(texture, coordinates);
+	}
 
 	/**
 	 * Set the projection matrix.
@@ -113,7 +123,7 @@ public:
 
 	virtual void setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
 
-	virtual void setDrawCoordinates(const GLfloat *vertices, const GLfloat *texCoords);
+	virtual void drawTexture(const GLTexture &texture, const GLfloat *coordinates);
 
 	virtual void setProjectionMatrix(const GLfloat *projectionMatrix);
 };
@@ -130,7 +140,7 @@ public:
 
 	virtual void setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
 
-	virtual void setDrawCoordinates(const GLfloat *vertices, const GLfloat *texCoords);
+	virtual void drawTexture(const GLTexture &texture, const GLfloat *coordinates);
 
 	virtual void setProjectionMatrix(const GLfloat *projectionMatrix);
 
diff --git a/backends/graphics/opengl/texture.cpp b/backends/graphics/opengl/texture.cpp
index 05b7ac1..8b38f85 100644
--- a/backends/graphics/opengl/texture.cpp
+++ b/backends/graphics/opengl/texture.cpp
@@ -95,7 +95,7 @@ void GLTexture::create() {
 	}
 }
 
-void GLTexture::bind() {
+void GLTexture::bind() const {
 	GL_CALL(glBindTexture(GL_TEXTURE_2D, _glTexture));
 }
 
@@ -263,34 +263,7 @@ void Texture::allocate(uint width, uint height) {
 	_userPixelData = _textureData.getSubArea(Common::Rect(width, height));
 }
 
-void Texture::draw(GLfloat x, GLfloat y, GLfloat w, GLfloat h) {
-	// Only do any processing when the Texture is initialized.
-	if (!_textureData.getPixels()) {
-		return;
-	}
-
-	// First update any potentional changes.
-	updateTexture();
-
-	// Set the texture.
-	_glTexture.bind();
-
-	// Calculate the screen rect where the texture will be drawn.
-	const GLfloat vertices[4*2] = {
-		x,     y,
-		x + w, y,
-		x,     y + h,
-		x + w, y + h
-	};
-
-	// Setup coordinates for drawing.
-	g_context.activePipeline->setDrawCoordinates(vertices, _glTexture.getTexCoords());
-
-	// Draw the texture to the screen buffer.
-	GL_CALL(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
-}
-
-void Texture::updateTexture() {
+void Texture::updateGLTexture() {
 	if (!isDirty()) {
 		return;
 	}
@@ -418,7 +391,7 @@ inline void doPaletteLookUp(PixelType *dst, const byte *src, uint width, uint he
 }
 } // End of anonymous namespace
 
-void TextureCLUT8::updateTexture() {
+void TextureCLUT8::updateGLTexture() {
 	if (!isDirty()) {
 		return;
 	}
@@ -443,7 +416,7 @@ void TextureCLUT8::updateTexture() {
 	}
 
 	// Do generic handling of updating the texture.
-	Texture::updateTexture();
+	Texture::updateGLTexture();
 }
 
 #if !USE_FORCED_GL
@@ -502,7 +475,7 @@ void TextureRGB555::updateTexture() {
 	}
 
 	// Do generic handling of updating the texture.
-	Texture::updateTexture();
+	Texture::updateGLTexture();
 }
 #endif // !USE_FORCED_GL
 
@@ -582,33 +555,6 @@ void TextureCLUT8GPU::allocate(uint width, uint height) {
 	_clut8Vertices[7] = height;
 }
 
-void TextureCLUT8GPU::draw(GLfloat x, GLfloat y, GLfloat w, GLfloat h) {
-	// Only do any processing when the Texture is initialized.
-	if (!_clut8Data.getPixels()) {
-		return;
-	}
-
-	// First update any potentional changes.
-	updateTextures();
-
-	// Set the texture.
-	_target->getTexture()->bind();
-
-	// Calculate the screen rect where the texture will be drawn.
-	const GLfloat vertices[4*2] = {
-		x,     y,
-		x + w, y,
-		x,     y + h,
-		x + w, y + h
-	};
-
-	// Setup coordinates for drawing.
-	g_context.activePipeline->setDrawCoordinates(vertices, _target->getTexture()->getTexCoords());
-
-	// Draw the texture to the screen buffer.
-	GL_CALL(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
-}
-
 Graphics::PixelFormat TextureCLUT8GPU::getFormat() const {
 	return Graphics::PixelFormat::createFormatCLUT8();
 }
@@ -633,7 +579,11 @@ void TextureCLUT8GPU::setPalette(uint start, uint colors, const byte *palData) {
 	_paletteDirty = true;
 }
 
-void TextureCLUT8GPU::updateTextures() {
+const GLTexture &TextureCLUT8GPU::getGLTexture() const {
+	return *_target->getTexture();
+}
+
+void TextureCLUT8GPU::updateGLTexture() {
 	const bool needLookUp = Surface::isDirty() || _paletteDirty;
 
 	// Update CLUT8 texture if necessary.
@@ -674,14 +624,10 @@ void TextureCLUT8GPU::lookUpColors() {
 	// Set the palette texture.
 	GL_CALL(glActiveTexture(GL_TEXTURE1));
 	_paletteTexture.bind();
-
-	// Set the clut8 texture.
 	GL_CALL(glActiveTexture(GL_TEXTURE0));
-	_clut8Texture.bind();
 
 	// Do color look up.
-	g_context.activePipeline->setDrawCoordinates(_clut8Vertices, _clut8Texture.getTexCoords());
-	GL_CALL(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
+	g_context.activePipeline->drawTexture(_clut8Texture, _clut8Vertices);
 
 	// Restore old state.
 	g_context.activePipeline->setShader(oldShader);
diff --git a/backends/graphics/opengl/texture.h b/backends/graphics/opengl/texture.h
index df9893f..847c76d 100644
--- a/backends/graphics/opengl/texture.h
+++ b/backends/graphics/opengl/texture.h
@@ -76,7 +76,7 @@ public:
 	/**
 	 * Bind the texture to the active texture unit.
 	 */
-	void bind();
+	void bind() const;
 
 	/**
 	 * Sets the size of the texture in pixels.
@@ -182,8 +182,6 @@ public:
 	 */
 	void fill(uint32 color);
 
-	virtual void draw(GLfloat x, GLfloat y, GLfloat w, GLfloat h) = 0;
-
 	void flagDirty() { _allDirty = true; }
 	virtual bool isDirty() const { return _allDirty || !_dirtyArea.isEmpty(); }
 
@@ -212,6 +210,16 @@ public:
 	 */
 	virtual void setColorKey(uint colorKey) {}
 	virtual void setPalette(uint start, uint colors, const byte *palData) {}
+
+	/**
+	 * Update underlying OpenGL texture to reflect current state.
+	 */
+	virtual void updateGLTexture() = 0;
+
+	/**
+	 * Obtain underlying OpenGL texture.
+	 */
+	virtual const GLTexture &getGLTexture() const = 0;
 protected:
 	void clearDirty() { _allDirty = false; _dirtyArea = Common::Rect(); }
 
@@ -246,8 +254,6 @@ public:
 
 	virtual void allocate(uint width, uint height);
 
-	virtual void draw(GLfloat x, GLfloat y, GLfloat w, GLfloat h);
-
 	virtual uint getWidth() const { return _userPixelData.w; }
 	virtual uint getHeight() const { return _userPixelData.h; }
 
@@ -259,11 +265,11 @@ public:
 	virtual Graphics::Surface *getSurface() { return &_userPixelData; }
 	virtual const Graphics::Surface *getSurface() const { return &_userPixelData; }
 
+	virtual void updateGLTexture();
+	virtual const GLTexture &getGLTexture() const { return _glTexture; }
 protected:
 	const Graphics::PixelFormat _format;
 
-	virtual void updateTexture();
-
 private:
 	GLTexture _glTexture;
 
@@ -288,9 +294,7 @@ public:
 	virtual Graphics::Surface *getSurface() { return &_clut8Data; }
 	virtual const Graphics::Surface *getSurface() const { return &_clut8Data; }
 
-protected:
-	virtual void updateTexture();
-
+	virtual void updateGLTexture();
 private:
 	Graphics::Surface _clut8Data;
 	byte *_palette;
@@ -309,9 +313,7 @@ public:
 	virtual Graphics::Surface *getSurface() { return &_rgb555Data; }
 	virtual const Graphics::Surface *getSurface() const { return &_rgb555Data; }
 
-protected:
 	virtual void updateTexture();
-
 private:
 	Graphics::Surface _rgb555Data;
 };
@@ -333,8 +335,6 @@ public:
 
 	virtual void allocate(uint width, uint height);
 
-	virtual void draw(GLfloat x, GLfloat y, GLfloat w, GLfloat h);
-
 	virtual bool isDirty() const { return _paletteDirty || Surface::isDirty(); }
 
 	virtual uint getWidth() const { return _userPixelData.w; }
@@ -350,13 +350,15 @@ public:
 	virtual Graphics::Surface *getSurface() { return &_userPixelData; }
 	virtual const Graphics::Surface *getSurface() const { return &_userPixelData; }
 
+	virtual void updateGLTexture();
+	virtual const GLTexture &getGLTexture() const;
+
 	static bool isSupportedByContext() {
 		return g_context.shadersSupported
 		    && g_context.multitextureSupported
 		    && g_context.framebufferObjectSupported;
 	}
 private:
-	void updateTextures();
 	void lookUpColors();
 
 	GLTexture _clut8Texture;


Commit: ed6689d4fcfd30a36cb01392bbd9705732cfac4a
    https://github.com/scummvm/scummvm/commit/ed6689d4fcfd30a36cb01392bbd9705732cfac4a
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:27+01:00

Commit Message:
OPENGL: Do not allow direct access to Context::activePipeline.

Changed paths:
    backends/graphics/opengl/framebuffer.cpp
    backends/graphics/opengl/opengl-graphics.cpp
    backends/graphics/opengl/opengl-sys.h
    backends/graphics/opengl/texture.cpp



diff --git a/backends/graphics/opengl/framebuffer.cpp b/backends/graphics/opengl/framebuffer.cpp
index 85245b6..6775360 100644
--- a/backends/graphics/opengl/framebuffer.cpp
+++ b/backends/graphics/opengl/framebuffer.cpp
@@ -93,7 +93,7 @@ void Framebuffer::applyViewport() {
 }
 
 void Framebuffer::applyProjectionMatrix() {
-	g_context.activePipeline->setProjectionMatrix(_projectionMatrix);
+	g_context.getActivePipeline()->setProjectionMatrix(_projectionMatrix);
 }
 
 void Framebuffer::applyClearColor() {
diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index a685f34..6ede6a2 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -396,11 +396,11 @@ void OpenGLGraphicsManager::updateScreen() {
 	const GLfloat shakeOffset = _gameScreenShakeOffset * (GLfloat)_displayHeight / _gameScreen->getHeight();
 
 	// First step: Draw the (virtual) game screen.
-	g_context.activePipeline->drawTexture(_gameScreen->getGLTexture(), _displayX, _displayY + shakeOffset, _displayWidth, _displayHeight);
+	g_context.getActivePipeline()->drawTexture(_gameScreen->getGLTexture(), _displayX, _displayY + shakeOffset, _displayWidth, _displayHeight);
 
 	// Second step: Draw the overlay if visible.
 	if (_overlayVisible) {
-		g_context.activePipeline->drawTexture(_overlay->getGLTexture(), 0, 0, _outputScreenWidth, _outputScreenHeight);
+		g_context.getActivePipeline()->drawTexture(_overlay->getGLTexture(), 0, 0, _outputScreenWidth, _outputScreenHeight);
 	}
 
 	// Third step: Draw the cursor if visible.
@@ -409,7 +409,7 @@ void OpenGLGraphicsManager::updateScreen() {
 		// visible.
 		const GLfloat cursorOffset = _overlayVisible ? 0 : shakeOffset;
 
-		g_context.activePipeline->drawTexture(_cursor->getGLTexture(),
+		g_context.getActivePipeline()->drawTexture(_cursor->getGLTexture(),
 		                         _cursorDisplayX - _cursorHotspotXScaled,
 		                         _cursorDisplayY - _cursorHotspotYScaled + cursorOffset,
 		                         _cursorWidthScaled, _cursorHeightScaled);
@@ -433,13 +433,13 @@ void OpenGLGraphicsManager::updateScreen() {
 		}
 
 		// Set the OSD transparency.
-		g_context.activePipeline->setColor(1.0f, 1.0f, 1.0f, _osdAlpha / 100.0f);
+		g_context.getActivePipeline()->setColor(1.0f, 1.0f, 1.0f, _osdAlpha / 100.0f);
 
 		// Draw the OSD texture.
-		g_context.activePipeline->drawTexture(_osd->getGLTexture(), 0, 0, _outputScreenWidth, _outputScreenHeight);
+		g_context.getActivePipeline()->drawTexture(_osd->getGLTexture(), 0, 0, _outputScreenWidth, _outputScreenHeight);
 
 		// Reset color.
-		g_context.activePipeline->setColor(1.0f, 1.0f, 1.0f, 1.0f);
+		g_context.getActivePipeline()->setColor(1.0f, 1.0f, 1.0f, 1.0f);
 	}
 #endif
 
@@ -865,7 +865,7 @@ void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &def
 	if (g_context.shadersSupported) {
 		ShaderMan.notifyCreate();
 
-		g_context.activePipeline->setShader(ShaderMan.query(ShaderManager::kDefault));
+		g_context.getActivePipeline()->setShader(ShaderMan.query(ShaderManager::kDefault));
 	}
 #endif
 
@@ -874,7 +874,7 @@ void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &def
 	GL_CALL(glDisable(GL_DEPTH_TEST));
 	GL_CALL(glDisable(GL_DITHER));
 
-	g_context.activePipeline->setColor(1.0f, 1.0f, 1.0f, 1.0f);
+	g_context.getActivePipeline()->setColor(1.0f, 1.0f, 1.0f, 1.0f);
 
 	GL_CALL(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
 
@@ -887,7 +887,7 @@ void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &def
 	// Setup scissor state accordingly.
 	_backBuffer.enableScissorTest(!_overlayVisible);
 
-	g_context.activePipeline->setFramebuffer(&_backBuffer);
+	g_context.getActivePipeline()->setFramebuffer(&_backBuffer);
 
 	// Clear the whole screen for the first three frames to assure any
 	// leftovers are cleared.
diff --git a/backends/graphics/opengl/opengl-sys.h b/backends/graphics/opengl/opengl-sys.h
index 723e28f..4495128 100644
--- a/backends/graphics/opengl/opengl-sys.h
+++ b/backends/graphics/opengl/opengl-sys.h
@@ -129,9 +129,11 @@ struct Context {
 	// programmable pipelines in the same fashion.
 	//
 
+private:
 	/** Currently active rendering pipeline. */
 	Pipeline *activePipeline;
 
+public:
 	/**
 	 * Set new pipeline.
 	 *
@@ -141,6 +143,11 @@ struct Context {
 	 * @return Formerly active pipeline.
 	 */
 	Pipeline *setPipeline(Pipeline *pipeline);
+
+	/**
+	 * Query the currently active rendering pipeline.
+	 */
+	Pipeline *getActivePipeline() const { return activePipeline; }
 };
 
 /**
diff --git a/backends/graphics/opengl/texture.cpp b/backends/graphics/opengl/texture.cpp
index 8b38f85..8746527 100644
--- a/backends/graphics/opengl/texture.cpp
+++ b/backends/graphics/opengl/texture.cpp
@@ -615,10 +615,10 @@ void TextureCLUT8GPU::updateGLTexture() {
 
 void TextureCLUT8GPU::lookUpColors() {
 	// Save old state.
-	Framebuffer *oldFramebuffer = g_context.activePipeline->setFramebuffer(_target);
+	Framebuffer *oldFramebuffer = g_context.getActivePipeline()->setFramebuffer(_target);
 
 	Shader *lookUpShader = ShaderMan.query(ShaderManager::kCLUT8LookUp);
-	Shader *oldShader = g_context.activePipeline->setShader(lookUpShader);
+	Shader *oldShader = g_context.getActivePipeline()->setShader(lookUpShader);
 	lookUpShader->setUniformI(_paletteLocation, 1);
 
 	// Set the palette texture.
@@ -627,11 +627,11 @@ void TextureCLUT8GPU::lookUpColors() {
 	GL_CALL(glActiveTexture(GL_TEXTURE0));
 
 	// Do color look up.
-	g_context.activePipeline->drawTexture(_clut8Texture, _clut8Vertices);
+	g_context.getActivePipeline()->drawTexture(_clut8Texture, _clut8Vertices);
 
 	// Restore old state.
-	g_context.activePipeline->setShader(oldShader);
-	g_context.activePipeline->setFramebuffer(oldFramebuffer);
+	g_context.getActivePipeline()->setShader(oldShader);
+	g_context.getActivePipeline()->setFramebuffer(oldFramebuffer);
 }
 #endif // !USE_FORCED_GLES
 


Commit: bec2088d6c312d15e4c3377b5afbcb5a6fb0a84e
    https://github.com/scummvm/scummvm/commit/bec2088d6c312d15e4c3377b5afbcb5a6fb0a84e
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:30+01:00

Commit Message:
OPENGL: Only allow Pipeline to switch active Framebuffers.

Changed paths:
    backends/graphics/opengl/framebuffer.cpp
    backends/graphics/opengl/framebuffer.h



diff --git a/backends/graphics/opengl/framebuffer.cpp b/backends/graphics/opengl/framebuffer.cpp
index 6775360..f3332cb 100644
--- a/backends/graphics/opengl/framebuffer.cpp
+++ b/backends/graphics/opengl/framebuffer.cpp
@@ -40,10 +40,14 @@ void Framebuffer::activate() {
 	applyBlendState();
 	applyScissorTestState();
 	applyScissorBox();
+
+	activateInternal();
 }
 
 void Framebuffer::deactivate() {
 	_isActive = false;
+
+	deactivateInternal();
 }
 
 void Framebuffer::setClearColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
@@ -124,9 +128,7 @@ void Framebuffer::applyScissorBox() {
 // Backbuffer implementation
 //
 
-void Backbuffer::activate() {
-	Framebuffer::activate();
-
+void Backbuffer::activateInternal() {
 #if !USE_FORCED_GLES
 	if (g_context.framebufferObjectSupported) {
 		GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0));
@@ -183,9 +185,7 @@ TextureTarget::~TextureTarget() {
 	GL_CALL_SAFE(glDeleteFramebuffers, (1, &_glFBO));
 }
 
-void TextureTarget::activate() {
-	Framebuffer::activate();
-
+void TextureTarget::activateInternal() {
 	// Allocate framebuffer object if necessary.
 	if (!_glFBO) {
 		GL_CALL(glGenFramebuffers(1, &_glFBO));
diff --git a/backends/graphics/opengl/framebuffer.h b/backends/graphics/opengl/framebuffer.h
index 467c00e..c44c98d 100644
--- a/backends/graphics/opengl/framebuffer.h
+++ b/backends/graphics/opengl/framebuffer.h
@@ -31,25 +31,12 @@ namespace OpenGL {
  * Object describing a framebuffer OpenGL can render to.
  */
 class Framebuffer {
+	friend class Pipeline;
 public:
 	Framebuffer();
 	virtual ~Framebuffer() {};
 
-	/**
-	 * Activate framebuffer.
-	 *
-	 * This is supposed to set all state associated with the framebuffer.
-	 */
-	virtual void activate() = 0;
-
-	/**
-	 * Deactivate framebuffer.
-	 *
-	 * This is supposed to make any cleanup required when unbinding the
-	 * framebuffer.
-	 */
-	virtual void deactivate();
-
+public:
 	/**
 	 * Set the clear color of the framebuffer.
 	 */
@@ -82,6 +69,33 @@ protected:
 
 	GLfloat _projectionMatrix[4*4];
 	void applyProjectionMatrix();
+
+	/**
+	 * Activate framebuffer.
+	 *
+	 * This is supposed to set all state associated with the framebuffer.
+	 */
+	virtual void activateInternal() = 0;
+
+	/**
+	 * Deactivate framebuffer.
+	 *
+	 * This is supposed to make any cleanup required when unbinding the
+	 * framebuffer.
+	 */
+	virtual void deactivateInternal() {}
+
+private:
+	/**
+	 * Accessor to activate framebuffer for pipeline.
+	 */
+	void activate();
+
+	/**
+	 * Accessor to deactivate framebuffer from pipeline.
+	 */
+	void deactivate();
+
 private:
 	bool _isActive;
 
@@ -103,12 +117,13 @@ private:
  */
 class Backbuffer : public Framebuffer {
 public:
-	virtual void activate();
-
 	/**
 	 * Set the dimensions (a.k.a. size) of the back buffer.
 	 */
 	void setDimensions(uint width, uint height);
+
+protected:
+	virtual void activateInternal();
 };
 
 #if !USE_FORCED_GLES
@@ -125,8 +140,6 @@ public:
 	TextureTarget();
 	virtual ~TextureTarget();
 
-	virtual void activate();
-
 	/**
 	 * Notify that the GL context is about to be destroyed.
 	 */
@@ -146,6 +159,10 @@ public:
 	 * Query pointer to underlying GL texture.
 	 */
 	GLTexture *getTexture() const { return _texture; }
+
+protected:
+	virtual void activateInternal();
+
 private:
 	GLTexture *_texture;
 	GLuint _glFBO;


Commit: 8a4938f82b05b86c8f0ed010210eb6d1847c04c9
    https://github.com/scummvm/scummvm/commit/8a4938f82b05b86c8f0ed010210eb6d1847c04c9
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:30+01:00

Commit Message:
OPENGL: Move pipeline code to pipelines/.

Changed paths:
  A backends/graphics/opengl/pipelines/fixed.cpp
  A backends/graphics/opengl/pipelines/fixed.h
  A backends/graphics/opengl/pipelines/pipeline.cpp
  A backends/graphics/opengl/pipelines/pipeline.h
  A backends/graphics/opengl/pipelines/shader.cpp
  A backends/graphics/opengl/pipelines/shader.h
  R backends/graphics/opengl/pipeline.cpp
  R backends/graphics/opengl/pipeline.h
    backends/graphics/opengl/context.cpp
    backends/graphics/opengl/framebuffer.cpp
    backends/graphics/opengl/opengl-graphics.cpp
    backends/graphics/opengl/texture.cpp
    backends/module.mk



diff --git a/backends/graphics/opengl/context.cpp b/backends/graphics/opengl/context.cpp
index 09da353..d93ecdc 100644
--- a/backends/graphics/opengl/context.cpp
+++ b/backends/graphics/opengl/context.cpp
@@ -23,7 +23,7 @@
 #include "backends/graphics/opengl/opengl-sys.h"
 #include "backends/graphics/opengl/opengl-graphics.h"
 #include "backends/graphics/opengl/shader.h"
-#include "backends/graphics/opengl/pipeline.h"
+#include "backends/graphics/opengl/pipelines/pipeline.h"
 #include "backends/graphics/opengl/framebuffer.h"
 
 #include "common/tokenizer.h"
diff --git a/backends/graphics/opengl/framebuffer.cpp b/backends/graphics/opengl/framebuffer.cpp
index f3332cb..7191aab 100644
--- a/backends/graphics/opengl/framebuffer.cpp
+++ b/backends/graphics/opengl/framebuffer.cpp
@@ -22,7 +22,7 @@
 
 #include "backends/graphics/opengl/framebuffer.h"
 #include "backends/graphics/opengl/texture.h"
-#include "backends/graphics/opengl/pipeline.h"
+#include "backends/graphics/opengl/pipelines/pipeline.h"
 
 namespace OpenGL {
 
diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index 6ede6a2..3322ff5 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -23,7 +23,9 @@
 
 #include "backends/graphics/opengl/opengl-graphics.h"
 #include "backends/graphics/opengl/texture.h"
-#include "backends/graphics/opengl/pipeline.h"
+#include "backends/graphics/opengl/pipelines/pipeline.h"
+#include "backends/graphics/opengl/pipelines/fixed.h"
+#include "backends/graphics/opengl/pipelines/shader.h"
 #include "backends/graphics/opengl/shader.h"
 
 #include "common/textconsole.h"
diff --git a/backends/graphics/opengl/pipeline.cpp b/backends/graphics/opengl/pipeline.cpp
deleted file mode 100644
index 9ac3fe4..0000000
--- a/backends/graphics/opengl/pipeline.cpp
+++ /dev/null
@@ -1,131 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "backends/graphics/opengl/pipeline.h"
-#include "backends/graphics/opengl/shader.h"
-#include "backends/graphics/opengl/framebuffer.h"
-
-namespace OpenGL {
-
-Pipeline::Pipeline()
-    : _activeFramebuffer(nullptr) {
-}
-
-Framebuffer *Pipeline::setFramebuffer(Framebuffer *framebuffer) {
-	Framebuffer *oldFramebuffer = _activeFramebuffer;
-	if (oldFramebuffer) {
-		oldFramebuffer->deactivate();
-	}
-
-	_activeFramebuffer = framebuffer;
-	if (_activeFramebuffer) {
-		_activeFramebuffer->activate();
-		setProjectionMatrix(_activeFramebuffer->getProjectionMatrix());
-	}
-
-	return oldFramebuffer;
-}
-
-#if !USE_FORCED_GLES2
-void FixedPipeline::activate() {
-	GL_CALL(glDisable(GL_LIGHTING));
-	GL_CALL(glDisable(GL_FOG));
-	GL_CALL(glShadeModel(GL_FLAT));
-	GL_CALL(glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST));
-
-	GL_CALL(glEnableClientState(GL_VERTEX_ARRAY));
-	GL_CALL(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
-
-#if !USE_FORCED_GLES
-	if (g_context.multitextureSupported) {
-		GL_CALL(glActiveTexture(GL_TEXTURE0));
-	}
-#endif
-	GL_CALL(glEnable(GL_TEXTURE_2D));
-}
-
-void FixedPipeline::setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
-	GL_CALL(glColor4f(r, g, b, a));
-}
-
-void FixedPipeline::drawTexture(const GLTexture &texture, const GLfloat *coordinates) {
-	texture.bind();
-
-	GL_CALL(glTexCoordPointer(2, GL_FLOAT, 0, texture.getTexCoords()));
-	GL_CALL(glVertexPointer(2, GL_FLOAT, 0, coordinates));
-	GL_CALL(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
-}
-
-void FixedPipeline::setProjectionMatrix(const GLfloat *projectionMatrix) {
-	GL_CALL(glMatrixMode(GL_PROJECTION));
-	GL_CALL(glLoadMatrixf(projectionMatrix));
-
-	GL_CALL(glMatrixMode(GL_MODELVIEW));
-	GL_CALL(glLoadIdentity());
-}
-#endif // !USE_FORCED_GLES2
-
-#if !USE_FORCED_GLES
-ShaderPipeline::ShaderPipeline()
-    : _activeShader(nullptr) {
-}
-
-void ShaderPipeline::activate() {
-	GL_CALL(glEnableVertexAttribArray(kPositionAttribLocation));
-	GL_CALL(glEnableVertexAttribArray(kTexCoordAttribLocation));
-
-	if (g_context.multitextureSupported) {
-		GL_CALL(glActiveTexture(GL_TEXTURE0));
-	}
-}
-
-Shader *ShaderPipeline::setShader(Shader *shader) {
-	Shader *oldShader = _activeShader;
-
-	_activeShader = shader;
-	if (_activeShader && _activeFramebuffer) {
-		_activeShader->activate(_activeFramebuffer->getProjectionMatrix());
-	}
-
-	return oldShader;
-}
-
-void ShaderPipeline::setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
-	GL_CALL(glVertexAttrib4f(kColorAttribLocation, r, g, b, a));
-}
-
-void ShaderPipeline::drawTexture(const GLTexture &texture, const GLfloat *coordinates) {
-	texture.bind();
-
-	GL_CALL(glVertexAttribPointer(kTexCoordAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, texture.getTexCoords()));
-	GL_CALL(glVertexAttribPointer(kPositionAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, coordinates));
-	GL_CALL(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
-}
-
-void ShaderPipeline::setProjectionMatrix(const GLfloat *projectionMatrix) {
-	if (_activeShader) {
-		_activeShader->activate(projectionMatrix);
-	}
-}
-#endif // !USE_FORCED_GLES
-
-} // End of namespace OpenGL
diff --git a/backends/graphics/opengl/pipeline.h b/backends/graphics/opengl/pipeline.h
deleted file mode 100644
index 5ec52f2..0000000
--- a/backends/graphics/opengl/pipeline.h
+++ /dev/null
@@ -1,154 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef BACKENDS_GRAPHICS_OPENGL_PIEPLINE_H
-#define BACKENDS_GRAPHICS_OPENGL_PIEPLINE_H
-
-#include "backends/graphics/opengl/opengl-sys.h"
-#include "backends/graphics/opengl/texture.h"
-
-namespace OpenGL {
-
-class Framebuffer;
-#if !USE_FORCED_GLES
-class Shader;
-#endif
-
-/**
- * Interface for OpenGL pipeline functionality.
- *
- * This encapsulates differences in various rendering pipelines used for
- * OpenGL, OpenGL ES 1, and OpenGL ES 2.
- */
-class Pipeline {
-public:
-	Pipeline();
-	virtual ~Pipeline() {}
-
-	/**
-	 * Activate the pipeline.
-	 *
-	 * This sets the OpenGL state to make use of drawing with the given
-	 * OpenGL pipeline.
-	 */
-	virtual void activate() = 0;
-
-	/**
-	 * Set framebuffer to render to.
-	 *
-	 * Client is responsible for any memory management related to framebuffer.
-	 *
-	 * @param framebuffer Framebuffer to activate.
-	 * @return Formerly active framebuffer.
-	 */
-	Framebuffer *setFramebuffer(Framebuffer *framebuffer);
-
-#if !USE_FORCED_GLES
-	/**
-	 * Set shader program.
-	 *
-	 * Not all pipelines support shader programs. This is method exits at this
-	 * place for convenience only.
-	 *
-	 * Client is responsible for any memory management related to shader.
-	 *
-	 * @param shader Shader program to activate.
-	 * @return Formerly active shader program.
-	 */
-	virtual Shader *setShader(Shader *shader) { return nullptr; }
-#endif
-
-	/**
-	 * Set modulation color.
-	 *
-	 * @param r Red component in [0,1].
-	 * @param g Green component in [0,1].
-	 * @param b Blue component in [0,1].
-	 * @param a Alpha component in [0,1].
-	 */
-	virtual void setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) = 0;
-
-	/**
-	 * Draw a texture rectangle to the currently active framebuffer.
-	 *
-	 * @param texture     Texture to use for drawing.
-	 * @param coordinates x1, y1, x2, y2 coordinates where to draw the texture.
-	 */
-	virtual void drawTexture(const GLTexture &texture, const GLfloat *coordinates) = 0;
-
-	void drawTexture(const GLTexture &texture, GLfloat x, GLfloat y, GLfloat w, GLfloat h) {
-		const GLfloat coordinates[4*2] = {
-			x,     y,
-			x + w, y,
-			x,     y + h,
-			x + w, y + h
-		};
-		drawTexture(texture, coordinates);
-	}
-
-	/**
-	 * Set the projection matrix.
-	 *
-	 * This is intended to be only ever be used by Framebuffer subclasses.
-	 */
-	virtual void setProjectionMatrix(const GLfloat *projectionMatrix) = 0;
-
-protected:
-	Framebuffer *_activeFramebuffer;
-};
-
-#if !USE_FORCED_GLES2
-class FixedPipeline : public Pipeline {
-public:
-	virtual void activate();
-
-	virtual void setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
-
-	virtual void drawTexture(const GLTexture &texture, const GLfloat *coordinates);
-
-	virtual void setProjectionMatrix(const GLfloat *projectionMatrix);
-};
-#endif // !USE_FORCED_GLES2
-
-#if !USE_FORCED_GLES
-class ShaderPipeline : public Pipeline {
-public:
-	ShaderPipeline();
-
-	virtual void activate();
-
-	virtual Shader *setShader(Shader *shader);
-
-	virtual void setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
-
-	virtual void drawTexture(const GLTexture &texture, const GLfloat *coordinates);
-
-	virtual void setProjectionMatrix(const GLfloat *projectionMatrix);
-
-private:
-	Shader *_activeShader;
-};
-#endif // !USE_FORCED_GLES
-
-} // End of namespace OpenGL
-
-#endif
diff --git a/backends/graphics/opengl/pipelines/fixed.cpp b/backends/graphics/opengl/pipelines/fixed.cpp
new file mode 100644
index 0000000..1d671d1
--- /dev/null
+++ b/backends/graphics/opengl/pipelines/fixed.cpp
@@ -0,0 +1,66 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "backends/graphics/opengl/pipelines/fixed.h"
+
+namespace OpenGL {
+
+#if !USE_FORCED_GLES2
+void FixedPipeline::activate() {
+	GL_CALL(glDisable(GL_LIGHTING));
+	GL_CALL(glDisable(GL_FOG));
+	GL_CALL(glShadeModel(GL_FLAT));
+	GL_CALL(glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST));
+
+	GL_CALL(glEnableClientState(GL_VERTEX_ARRAY));
+	GL_CALL(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
+
+#if !USE_FORCED_GLES
+	if (g_context.multitextureSupported) {
+		GL_CALL(glActiveTexture(GL_TEXTURE0));
+	}
+#endif
+	GL_CALL(glEnable(GL_TEXTURE_2D));
+}
+
+void FixedPipeline::setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
+	GL_CALL(glColor4f(r, g, b, a));
+}
+
+void FixedPipeline::drawTexture(const GLTexture &texture, const GLfloat *coordinates) {
+	texture.bind();
+
+	GL_CALL(glTexCoordPointer(2, GL_FLOAT, 0, texture.getTexCoords()));
+	GL_CALL(glVertexPointer(2, GL_FLOAT, 0, coordinates));
+	GL_CALL(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
+}
+
+void FixedPipeline::setProjectionMatrix(const GLfloat *projectionMatrix) {
+	GL_CALL(glMatrixMode(GL_PROJECTION));
+	GL_CALL(glLoadMatrixf(projectionMatrix));
+
+	GL_CALL(glMatrixMode(GL_MODELVIEW));
+	GL_CALL(glLoadIdentity());
+}
+#endif // !USE_FORCED_GLES2
+
+} // End of namespace OpenGL
diff --git a/backends/graphics/opengl/pipelines/fixed.h b/backends/graphics/opengl/pipelines/fixed.h
new file mode 100644
index 0000000..f344ef1
--- /dev/null
+++ b/backends/graphics/opengl/pipelines/fixed.h
@@ -0,0 +1,45 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BACKENDS_GRAPHICS_OPENGL_PIPELINES_FIXED_H
+#define BACKENDS_GRAPHICS_OPENGL_PIPELINES_FIXED_H
+
+#include "backends/graphics/opengl/pipelines/pipeline.h"
+
+namespace OpenGL {
+
+#if !USE_FORCED_GLES2
+class FixedPipeline : public Pipeline {
+public:
+	virtual void activate();
+
+	virtual void setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
+
+	virtual void drawTexture(const GLTexture &texture, const GLfloat *coordinates);
+
+	virtual void setProjectionMatrix(const GLfloat *projectionMatrix);
+};
+#endif // !USE_FORCED_GLES2
+
+} // End of namespace OpenGL
+
+#endif
diff --git a/backends/graphics/opengl/pipelines/pipeline.cpp b/backends/graphics/opengl/pipelines/pipeline.cpp
new file mode 100644
index 0000000..64121d5
--- /dev/null
+++ b/backends/graphics/opengl/pipelines/pipeline.cpp
@@ -0,0 +1,47 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "backends/graphics/opengl/pipelines/pipeline.h"
+#include "backends/graphics/opengl/framebuffer.h"
+
+namespace OpenGL {
+
+Pipeline::Pipeline()
+    : _activeFramebuffer(nullptr) {
+}
+
+Framebuffer *Pipeline::setFramebuffer(Framebuffer *framebuffer) {
+	Framebuffer *oldFramebuffer = _activeFramebuffer;
+	if (oldFramebuffer) {
+		oldFramebuffer->deactivate();
+	}
+
+	_activeFramebuffer = framebuffer;
+	if (_activeFramebuffer) {
+		_activeFramebuffer->activate();
+		setProjectionMatrix(_activeFramebuffer->getProjectionMatrix());
+	}
+
+	return oldFramebuffer;
+}
+
+} // End of namespace OpenGL
diff --git a/backends/graphics/opengl/pipelines/pipeline.h b/backends/graphics/opengl/pipelines/pipeline.h
new file mode 100644
index 0000000..8509a26
--- /dev/null
+++ b/backends/graphics/opengl/pipelines/pipeline.h
@@ -0,0 +1,121 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BACKENDS_GRAPHICS_OPENGL_PIPELINES_PIPELINE_H
+#define BACKENDS_GRAPHICS_OPENGL_PIPELINES_PIPELINE_H
+
+#include "backends/graphics/opengl/opengl-sys.h"
+#include "backends/graphics/opengl/texture.h"
+
+namespace OpenGL {
+
+class Framebuffer;
+#if !USE_FORCED_GLES
+class Shader;
+#endif
+
+/**
+ * Interface for OpenGL pipeline functionality.
+ *
+ * This encapsulates differences in various rendering pipelines used for
+ * OpenGL, OpenGL ES 1, and OpenGL ES 2.
+ */
+class Pipeline {
+public:
+	Pipeline();
+	virtual ~Pipeline() {}
+
+	/**
+	 * Activate the pipeline.
+	 *
+	 * This sets the OpenGL state to make use of drawing with the given
+	 * OpenGL pipeline.
+	 */
+	virtual void activate() = 0;
+
+	/**
+	 * Set framebuffer to render to.
+	 *
+	 * Client is responsible for any memory management related to framebuffer.
+	 *
+	 * @param framebuffer Framebuffer to activate.
+	 * @return Formerly active framebuffer.
+	 */
+	Framebuffer *setFramebuffer(Framebuffer *framebuffer);
+
+#if !USE_FORCED_GLES
+	/**
+	 * Set shader program.
+	 *
+	 * Not all pipelines support shader programs. This is method exits at this
+	 * place for convenience only.
+	 *
+	 * Client is responsible for any memory management related to shader.
+	 *
+	 * @param shader Shader program to activate.
+	 * @return Formerly active shader program.
+	 */
+	virtual Shader *setShader(Shader *shader) { return nullptr; }
+#endif
+
+	/**
+	 * Set modulation color.
+	 *
+	 * @param r Red component in [0,1].
+	 * @param g Green component in [0,1].
+	 * @param b Blue component in [0,1].
+	 * @param a Alpha component in [0,1].
+	 */
+	virtual void setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) = 0;
+
+	/**
+	 * Draw a texture rectangle to the currently active framebuffer.
+	 *
+	 * @param texture     Texture to use for drawing.
+	 * @param coordinates x1, y1, x2, y2 coordinates where to draw the texture.
+	 */
+	virtual void drawTexture(const GLTexture &texture, const GLfloat *coordinates) = 0;
+
+	void drawTexture(const GLTexture &texture, GLfloat x, GLfloat y, GLfloat w, GLfloat h) {
+		const GLfloat coordinates[4*2] = {
+			x,     y,
+			x + w, y,
+			x,     y + h,
+			x + w, y + h
+		};
+		drawTexture(texture, coordinates);
+	}
+
+	/**
+	 * Set the projection matrix.
+	 *
+	 * This is intended to be only ever be used by Framebuffer subclasses.
+	 */
+	virtual void setProjectionMatrix(const GLfloat *projectionMatrix) = 0;
+
+protected:
+	Framebuffer *_activeFramebuffer;
+};
+
+} // End of namespace OpenGL
+
+#endif
diff --git a/backends/graphics/opengl/pipelines/shader.cpp b/backends/graphics/opengl/pipelines/shader.cpp
new file mode 100644
index 0000000..42f511d
--- /dev/null
+++ b/backends/graphics/opengl/pipelines/shader.cpp
@@ -0,0 +1,73 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "backends/graphics/opengl/pipelines/shader.h"
+#include "backends/graphics/opengl/shader.h"
+#include "backends/graphics/opengl/framebuffer.h"
+
+namespace OpenGL {
+
+#if !USE_FORCED_GLES
+ShaderPipeline::ShaderPipeline()
+    : _activeShader(nullptr) {
+}
+
+void ShaderPipeline::activate() {
+	GL_CALL(glEnableVertexAttribArray(kPositionAttribLocation));
+	GL_CALL(glEnableVertexAttribArray(kTexCoordAttribLocation));
+
+	if (g_context.multitextureSupported) {
+		GL_CALL(glActiveTexture(GL_TEXTURE0));
+	}
+}
+
+Shader *ShaderPipeline::setShader(Shader *shader) {
+	Shader *oldShader = _activeShader;
+
+	_activeShader = shader;
+	if (_activeShader && _activeFramebuffer) {
+		_activeShader->activate(_activeFramebuffer->getProjectionMatrix());
+	}
+
+	return oldShader;
+}
+
+void ShaderPipeline::setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
+	GL_CALL(glVertexAttrib4f(kColorAttribLocation, r, g, b, a));
+}
+
+void ShaderPipeline::drawTexture(const GLTexture &texture, const GLfloat *coordinates) {
+	texture.bind();
+
+	GL_CALL(glVertexAttribPointer(kTexCoordAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, texture.getTexCoords()));
+	GL_CALL(glVertexAttribPointer(kPositionAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, coordinates));
+	GL_CALL(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
+}
+
+void ShaderPipeline::setProjectionMatrix(const GLfloat *projectionMatrix) {
+	if (_activeShader) {
+		_activeShader->activate(projectionMatrix);
+	}
+}
+#endif // !USE_FORCED_GLES
+
+} // End of namespace OpenGL
diff --git a/backends/graphics/opengl/pipelines/shader.h b/backends/graphics/opengl/pipelines/shader.h
new file mode 100644
index 0000000..96e1580
--- /dev/null
+++ b/backends/graphics/opengl/pipelines/shader.h
@@ -0,0 +1,52 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BACKENDS_GRAPHICS_OPENGL_PIPELINES_SHADER_H
+#define BACKENDS_GRAPHICS_OPENGL_PIPELINES_SHADER_H
+
+#include "backends/graphics/opengl/pipelines/pipeline.h"
+
+namespace OpenGL {
+
+#if !USE_FORCED_GLES
+class ShaderPipeline : public Pipeline {
+public:
+	ShaderPipeline();
+
+	virtual void activate();
+
+	virtual Shader *setShader(Shader *shader);
+
+	virtual void setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
+
+	virtual void drawTexture(const GLTexture &texture, const GLfloat *coordinates);
+
+	virtual void setProjectionMatrix(const GLfloat *projectionMatrix);
+
+private:
+	Shader *_activeShader;
+};
+#endif // !USE_FORCED_GLES
+
+} // End of namespace OpenGL
+
+#endif
diff --git a/backends/graphics/opengl/texture.cpp b/backends/graphics/opengl/texture.cpp
index 8746527..b0e474d 100644
--- a/backends/graphics/opengl/texture.cpp
+++ b/backends/graphics/opengl/texture.cpp
@@ -22,7 +22,7 @@
 
 #include "backends/graphics/opengl/texture.h"
 #include "backends/graphics/opengl/shader.h"
-#include "backends/graphics/opengl/pipeline.h"
+#include "backends/graphics/opengl/pipelines/pipeline.h"
 #include "backends/graphics/opengl/framebuffer.h"
 
 #include "common/rect.h"
diff --git a/backends/module.mk b/backends/module.mk
index f786933..fd97e19 100644
--- a/backends/module.mk
+++ b/backends/module.mk
@@ -56,9 +56,11 @@ MODULE_OBJS += \
 	graphics/opengl/debug.o \
 	graphics/opengl/framebuffer.o \
 	graphics/opengl/opengl-graphics.o \
-	graphics/opengl/pipeline.o \
 	graphics/opengl/shader.o \
-	graphics/opengl/texture.o
+	graphics/opengl/texture.o \
+	graphics/opengl/pipelines/fixed.o \
+	graphics/opengl/pipelines/pipeline.o \
+	graphics/opengl/pipelines/shader.o
 endif
 
 # SDL specific source files.


Commit: 26f106497a863b84c502d122b5ba749176b2c426
    https://github.com/scummvm/scummvm/commit/26f106497a863b84c502d122b5ba749176b2c426
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:30+01:00

Commit Message:
OPENGL: Implement CLUT8 look up as Pipeline.

Changed paths:
  A backends/graphics/opengl/pipelines/clut8.cpp
  A backends/graphics/opengl/pipelines/clut8.h
    backends/graphics/opengl/opengl-graphics.cpp
    backends/graphics/opengl/pipelines/fixed.cpp
    backends/graphics/opengl/pipelines/fixed.h
    backends/graphics/opengl/pipelines/pipeline.cpp
    backends/graphics/opengl/pipelines/pipeline.h
    backends/graphics/opengl/pipelines/shader.cpp
    backends/graphics/opengl/pipelines/shader.h
    backends/graphics/opengl/texture.cpp
    backends/graphics/opengl/texture.h
    backends/module.mk



diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index 3322ff5..c5bc99e 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -866,7 +866,6 @@ void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &def
 #if !USE_FORCED_GLES
 	if (g_context.shadersSupported) {
 		ShaderMan.notifyCreate();
-
 		g_context.getActivePipeline()->setShader(ShaderMan.query(ShaderManager::kDefault));
 	}
 #endif
diff --git a/backends/graphics/opengl/pipelines/clut8.cpp b/backends/graphics/opengl/pipelines/clut8.cpp
new file mode 100644
index 0000000..69dd0a3
--- /dev/null
+++ b/backends/graphics/opengl/pipelines/clut8.cpp
@@ -0,0 +1,53 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "backends/graphics/opengl/pipelines/clut8.h"
+#include "backends/graphics/opengl/shader.h"
+#include "backends/graphics/opengl/framebuffer.h"
+
+namespace OpenGL {
+
+#if !USE_FORCED_GLES
+CLUT8LookUpPipeline::CLUT8LookUpPipeline()
+    : _paletteTexture(nullptr) {
+	ShaderPipeline::setShader(ShaderMan.query(ShaderManager::kCLUT8LookUp));
+}
+
+Shader *CLUT8LookUpPipeline::setShader(Shader *shader) {
+	return ShaderPipeline::setShader(ShaderMan.query(ShaderManager::kCLUT8LookUp));
+}
+
+void CLUT8LookUpPipeline::drawTexture(const GLTexture &texture, const GLfloat *coordinates) {
+	_activeShader->setUniformI(_activeShader->getUniformLocation("palette"), 1);
+
+	// Set the palette texture.
+	GL_CALL(glActiveTexture(GL_TEXTURE1));
+	if (_paletteTexture) {
+		_paletteTexture->bind();
+	}
+
+	GL_CALL(glActiveTexture(GL_TEXTURE0));
+	ShaderPipeline::drawTexture(texture, coordinates);
+}
+#endif // !USE_FORCED_GLES
+
+} // End of namespace OpenGL
diff --git a/backends/graphics/opengl/pipelines/clut8.h b/backends/graphics/opengl/pipelines/clut8.h
new file mode 100644
index 0000000..fed6cbf
--- /dev/null
+++ b/backends/graphics/opengl/pipelines/clut8.h
@@ -0,0 +1,48 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BACKENDS_GRAPHICS_OPENGL_PIPELINES_CLUT8_H
+#define BACKENDS_GRAPHICS_OPENGL_PIPELINES_CLUT8_H
+
+#include "backends/graphics/opengl/pipelines/shader.h"
+
+namespace OpenGL {
+
+#if !USE_FORCED_GLES
+class CLUT8LookUpPipeline : public ShaderPipeline {
+public:
+	CLUT8LookUpPipeline();
+
+	virtual Shader *setShader(Shader *shader);
+
+	void setPaletteTexture(const GLTexture *paletteTexture) { _paletteTexture = paletteTexture; }
+
+	virtual void drawTexture(const GLTexture &texture, const GLfloat *coordinates);
+
+private:
+	const GLTexture *_paletteTexture;
+};
+#endif // !USE_FORCED_GLES
+
+} // End of namespace OpenGL
+
+#endif
diff --git a/backends/graphics/opengl/pipelines/fixed.cpp b/backends/graphics/opengl/pipelines/fixed.cpp
index 1d671d1..8e3bd7e 100644
--- a/backends/graphics/opengl/pipelines/fixed.cpp
+++ b/backends/graphics/opengl/pipelines/fixed.cpp
@@ -25,7 +25,7 @@
 namespace OpenGL {
 
 #if !USE_FORCED_GLES2
-void FixedPipeline::activate() {
+void FixedPipeline::activateInternal() {
 	GL_CALL(glDisable(GL_LIGHTING));
 	GL_CALL(glDisable(GL_FOG));
 	GL_CALL(glShadeModel(GL_FLAT));
@@ -55,6 +55,10 @@ void FixedPipeline::drawTexture(const GLTexture &texture, const GLfloat *coordin
 }
 
 void FixedPipeline::setProjectionMatrix(const GLfloat *projectionMatrix) {
+	if (!isActive()) {
+		return;
+	}
+
 	GL_CALL(glMatrixMode(GL_PROJECTION));
 	GL_CALL(glLoadMatrixf(projectionMatrix));
 
diff --git a/backends/graphics/opengl/pipelines/fixed.h b/backends/graphics/opengl/pipelines/fixed.h
index f344ef1..6bfe140 100644
--- a/backends/graphics/opengl/pipelines/fixed.h
+++ b/backends/graphics/opengl/pipelines/fixed.h
@@ -30,13 +30,14 @@ namespace OpenGL {
 #if !USE_FORCED_GLES2
 class FixedPipeline : public Pipeline {
 public:
-	virtual void activate();
-
 	virtual void setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
 
 	virtual void drawTexture(const GLTexture &texture, const GLfloat *coordinates);
 
 	virtual void setProjectionMatrix(const GLfloat *projectionMatrix);
+
+protected:
+	virtual void activateInternal();
 };
 #endif // !USE_FORCED_GLES2
 
diff --git a/backends/graphics/opengl/pipelines/pipeline.cpp b/backends/graphics/opengl/pipelines/pipeline.cpp
index 64121d5..f79a923 100644
--- a/backends/graphics/opengl/pipelines/pipeline.cpp
+++ b/backends/graphics/opengl/pipelines/pipeline.cpp
@@ -26,17 +26,38 @@
 namespace OpenGL {
 
 Pipeline::Pipeline()
-    : _activeFramebuffer(nullptr) {
+    : _activeFramebuffer(nullptr), _isActive(false) {
+}
+
+void Pipeline::activate() {
+	_isActive = true;
+
+	if (_activeFramebuffer) {
+		_activeFramebuffer->activate();
+		setProjectionMatrix(_activeFramebuffer->getProjectionMatrix());
+	}
+
+	activateInternal();
+}
+
+void Pipeline::deactivate() {
+	deactivateInternal();
+
+	if (_activeFramebuffer) {
+		_activeFramebuffer->deactivate();
+	}
+
+	_isActive = false;
 }
 
 Framebuffer *Pipeline::setFramebuffer(Framebuffer *framebuffer) {
 	Framebuffer *oldFramebuffer = _activeFramebuffer;
-	if (oldFramebuffer) {
+	if (_isActive && oldFramebuffer) {
 		oldFramebuffer->deactivate();
 	}
 
 	_activeFramebuffer = framebuffer;
-	if (_activeFramebuffer) {
+	if (_isActive && _activeFramebuffer) {
 		_activeFramebuffer->activate();
 		setProjectionMatrix(_activeFramebuffer->getProjectionMatrix());
 	}
diff --git a/backends/graphics/opengl/pipelines/pipeline.h b/backends/graphics/opengl/pipelines/pipeline.h
index 8509a26..8545ef2 100644
--- a/backends/graphics/opengl/pipelines/pipeline.h
+++ b/backends/graphics/opengl/pipelines/pipeline.h
@@ -50,7 +50,12 @@ public:
 	 * This sets the OpenGL state to make use of drawing with the given
 	 * OpenGL pipeline.
 	 */
-	virtual void activate() = 0;
+	void activate();
+
+	/**
+	 * Deactivate the pipeline.
+	 */
+	void deactivate();
 
 	/**
 	 * Set framebuffer to render to.
@@ -113,7 +118,25 @@ public:
 	virtual void setProjectionMatrix(const GLfloat *projectionMatrix) = 0;
 
 protected:
+	/**
+	 * Activate the pipeline.
+	 *
+	 * This sets the OpenGL state to make use of drawing with the given
+	 * OpenGL pipeline.
+	 */
+	virtual void activateInternal() = 0;
+
+	/**
+	 * Deactivate the pipeline.
+	 */
+	virtual void deactivateInternal() {}
+
+	bool isActive() const { return _isActive; }
+
 	Framebuffer *_activeFramebuffer;
+
+private:
+	bool _isActive;
 };
 
 } // End of namespace OpenGL
diff --git a/backends/graphics/opengl/pipelines/shader.cpp b/backends/graphics/opengl/pipelines/shader.cpp
index 42f511d..f408b68 100644
--- a/backends/graphics/opengl/pipelines/shader.cpp
+++ b/backends/graphics/opengl/pipelines/shader.cpp
@@ -31,7 +31,7 @@ ShaderPipeline::ShaderPipeline()
     : _activeShader(nullptr) {
 }
 
-void ShaderPipeline::activate() {
+void ShaderPipeline::activateInternal() {
 	GL_CALL(glEnableVertexAttribArray(kPositionAttribLocation));
 	GL_CALL(glEnableVertexAttribArray(kTexCoordAttribLocation));
 
diff --git a/backends/graphics/opengl/pipelines/shader.h b/backends/graphics/opengl/pipelines/shader.h
index 96e1580..a5b94e8 100644
--- a/backends/graphics/opengl/pipelines/shader.h
+++ b/backends/graphics/opengl/pipelines/shader.h
@@ -32,8 +32,6 @@ class ShaderPipeline : public Pipeline {
 public:
 	ShaderPipeline();
 
-	virtual void activate();
-
 	virtual Shader *setShader(Shader *shader);
 
 	virtual void setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
@@ -42,7 +40,9 @@ public:
 
 	virtual void setProjectionMatrix(const GLfloat *projectionMatrix);
 
-private:
+protected:
+	virtual void activateInternal();
+
 	Shader *_activeShader;
 };
 #endif // !USE_FORCED_GLES
diff --git a/backends/graphics/opengl/texture.cpp b/backends/graphics/opengl/texture.cpp
index b0e474d..79e3acc 100644
--- a/backends/graphics/opengl/texture.cpp
+++ b/backends/graphics/opengl/texture.cpp
@@ -23,6 +23,7 @@
 #include "backends/graphics/opengl/texture.h"
 #include "backends/graphics/opengl/shader.h"
 #include "backends/graphics/opengl/pipelines/pipeline.h"
+#include "backends/graphics/opengl/pipelines/clut8.h"
 #include "backends/graphics/opengl/framebuffer.h"
 
 #include "common/rect.h"
@@ -489,15 +490,19 @@ void TextureRGB555::updateTexture() {
 TextureCLUT8GPU::TextureCLUT8GPU()
     : _clut8Texture(GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE),
       _paletteTexture(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE),
-      _target(new TextureTarget()), _clut8Vertices(), _paletteLocation(-1),
-      _clut8Data(), _userPixelData(), _palette(), _paletteDirty(false) {
+      _target(new TextureTarget()), _clut8Pipeline(new CLUT8LookUpPipeline()),
+      _clut8Vertices(), _clut8Data(), _userPixelData(), _palette(),
+      _paletteDirty(false) {
 	// Allocate space for 256 colors.
 	_paletteTexture.setSize(256, 1);
 
-	_paletteLocation = ShaderMan.query(ShaderManager::kCLUT8LookUp)->getUniformLocation("palette");
+	// Setup pipeline.
+	_clut8Pipeline->setFramebuffer(_target);
+	_clut8Pipeline->setPaletteTexture(&_paletteTexture);
 }
 
 TextureCLUT8GPU::~TextureCLUT8GPU() {
+	delete _clut8Pipeline;
 	delete _target;
 	_clut8Data.free();
 }
@@ -511,7 +516,6 @@ void TextureCLUT8GPU::destroy() {
 void TextureCLUT8GPU::recreate() {
 	_clut8Texture.create();
 	_paletteTexture.create();
-	_paletteLocation = ShaderMan.query(ShaderManager::kCLUT8LookUp)->getUniformLocation("palette");
 	_target->create();
 
 	// In case image date exists assure it will be completely refreshed next
@@ -614,24 +618,14 @@ void TextureCLUT8GPU::updateGLTexture() {
 }
 
 void TextureCLUT8GPU::lookUpColors() {
-	// Save old state.
-	Framebuffer *oldFramebuffer = g_context.getActivePipeline()->setFramebuffer(_target);
-
-	Shader *lookUpShader = ShaderMan.query(ShaderManager::kCLUT8LookUp);
-	Shader *oldShader = g_context.getActivePipeline()->setShader(lookUpShader);
-	lookUpShader->setUniformI(_paletteLocation, 1);
-
-	// Set the palette texture.
-	GL_CALL(glActiveTexture(GL_TEXTURE1));
-	_paletteTexture.bind();
-	GL_CALL(glActiveTexture(GL_TEXTURE0));
+	// Setup pipeline to do color look up.
+	Pipeline *oldPipeline = g_context.setPipeline(_clut8Pipeline);
 
 	// Do color look up.
 	g_context.getActivePipeline()->drawTexture(_clut8Texture, _clut8Vertices);
 
 	// Restore old state.
-	g_context.getActivePipeline()->setShader(oldShader);
-	g_context.getActivePipeline()->setFramebuffer(oldFramebuffer);
+	g_context.setPipeline(oldPipeline);
 }
 #endif // !USE_FORCED_GLES
 
diff --git a/backends/graphics/opengl/texture.h b/backends/graphics/opengl/texture.h
index 847c76d..97e99b4 100644
--- a/backends/graphics/opengl/texture.h
+++ b/backends/graphics/opengl/texture.h
@@ -321,6 +321,7 @@ private:
 
 #if !USE_FORCED_GLES
 class TextureTarget;
+class CLUT8LookUpPipeline;
 
 class TextureCLUT8GPU : public Surface {
 public:
@@ -365,11 +366,10 @@ private:
 	GLTexture _paletteTexture;
 
 	TextureTarget *_target;
+	CLUT8LookUpPipeline *_clut8Pipeline;
 
 	GLfloat _clut8Vertices[4*2];
 
-	GLint _paletteLocation;
-
 	Graphics::Surface _clut8Data;
 	Graphics::Surface _userPixelData;
 
diff --git a/backends/module.mk b/backends/module.mk
index fd97e19..70e3ca7 100644
--- a/backends/module.mk
+++ b/backends/module.mk
@@ -58,6 +58,7 @@ MODULE_OBJS += \
 	graphics/opengl/opengl-graphics.o \
 	graphics/opengl/shader.o \
 	graphics/opengl/texture.o \
+	graphics/opengl/pipelines/clut8.o \
 	graphics/opengl/pipelines/fixed.o \
 	graphics/opengl/pipelines/pipeline.o \
 	graphics/opengl/pipelines/shader.o


Commit: 3f9852eb202b55b93f6e3121ce473951bff033cd
    https://github.com/scummvm/scummvm/commit/3f9852eb202b55b93f6e3121ce473951bff033cd
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:31+01:00

Commit Message:
OPENGL: Make shader pipelines use fixed shaders.

Changed paths:
    backends/graphics/opengl/opengl-graphics.cpp
    backends/graphics/opengl/pipelines/clut8.cpp
    backends/graphics/opengl/pipelines/clut8.h
    backends/graphics/opengl/pipelines/pipeline.h
    backends/graphics/opengl/pipelines/shader.cpp
    backends/graphics/opengl/pipelines/shader.h



diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index c5bc99e..4d6a00a 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -851,7 +851,8 @@ void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &def
 
 #if !USE_FORCED_GLES
 	if (g_context.shadersSupported) {
-		_pipeline = new ShaderPipeline();
+		ShaderMan.notifyCreate();
+		_pipeline = new ShaderPipeline(ShaderMan.query(ShaderManager::kDefault));
 	}
 #endif
 
@@ -863,13 +864,6 @@ void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &def
 
 	g_context.setPipeline(_pipeline);
 
-#if !USE_FORCED_GLES
-	if (g_context.shadersSupported) {
-		ShaderMan.notifyCreate();
-		g_context.getActivePipeline()->setShader(ShaderMan.query(ShaderManager::kDefault));
-	}
-#endif
-
 	// Disable 3D properties.
 	GL_CALL(glDisable(GL_CULL_FACE));
 	GL_CALL(glDisable(GL_DEPTH_TEST));
diff --git a/backends/graphics/opengl/pipelines/clut8.cpp b/backends/graphics/opengl/pipelines/clut8.cpp
index 69dd0a3..9f2aa94 100644
--- a/backends/graphics/opengl/pipelines/clut8.cpp
+++ b/backends/graphics/opengl/pipelines/clut8.cpp
@@ -28,12 +28,7 @@ namespace OpenGL {
 
 #if !USE_FORCED_GLES
 CLUT8LookUpPipeline::CLUT8LookUpPipeline()
-    : _paletteTexture(nullptr) {
-	ShaderPipeline::setShader(ShaderMan.query(ShaderManager::kCLUT8LookUp));
-}
-
-Shader *CLUT8LookUpPipeline::setShader(Shader *shader) {
-	return ShaderPipeline::setShader(ShaderMan.query(ShaderManager::kCLUT8LookUp));
+    : ShaderPipeline(ShaderMan.query(ShaderManager::kCLUT8LookUp)), _paletteTexture(nullptr) {
 }
 
 void CLUT8LookUpPipeline::drawTexture(const GLTexture &texture, const GLfloat *coordinates) {
diff --git a/backends/graphics/opengl/pipelines/clut8.h b/backends/graphics/opengl/pipelines/clut8.h
index fed6cbf..16724e4 100644
--- a/backends/graphics/opengl/pipelines/clut8.h
+++ b/backends/graphics/opengl/pipelines/clut8.h
@@ -32,8 +32,6 @@ class CLUT8LookUpPipeline : public ShaderPipeline {
 public:
 	CLUT8LookUpPipeline();
 
-	virtual Shader *setShader(Shader *shader);
-
 	void setPaletteTexture(const GLTexture *paletteTexture) { _paletteTexture = paletteTexture; }
 
 	virtual void drawTexture(const GLTexture &texture, const GLfloat *coordinates);
diff --git a/backends/graphics/opengl/pipelines/pipeline.h b/backends/graphics/opengl/pipelines/pipeline.h
index 8545ef2..9f32d33 100644
--- a/backends/graphics/opengl/pipelines/pipeline.h
+++ b/backends/graphics/opengl/pipelines/pipeline.h
@@ -29,9 +29,6 @@
 namespace OpenGL {
 
 class Framebuffer;
-#if !USE_FORCED_GLES
-class Shader;
-#endif
 
 /**
  * Interface for OpenGL pipeline functionality.
@@ -67,21 +64,6 @@ public:
 	 */
 	Framebuffer *setFramebuffer(Framebuffer *framebuffer);
 
-#if !USE_FORCED_GLES
-	/**
-	 * Set shader program.
-	 *
-	 * Not all pipelines support shader programs. This is method exits at this
-	 * place for convenience only.
-	 *
-	 * Client is responsible for any memory management related to shader.
-	 *
-	 * @param shader Shader program to activate.
-	 * @return Formerly active shader program.
-	 */
-	virtual Shader *setShader(Shader *shader) { return nullptr; }
-#endif
-
 	/**
 	 * Set modulation color.
 	 *
diff --git a/backends/graphics/opengl/pipelines/shader.cpp b/backends/graphics/opengl/pipelines/shader.cpp
index f408b68..69af911 100644
--- a/backends/graphics/opengl/pipelines/shader.cpp
+++ b/backends/graphics/opengl/pipelines/shader.cpp
@@ -27,8 +27,8 @@
 namespace OpenGL {
 
 #if !USE_FORCED_GLES
-ShaderPipeline::ShaderPipeline()
-    : _activeShader(nullptr) {
+ShaderPipeline::ShaderPipeline(Shader *shader)
+    : _activeShader(shader) {
 }
 
 void ShaderPipeline::activateInternal() {
@@ -40,17 +40,6 @@ void ShaderPipeline::activateInternal() {
 	}
 }
 
-Shader *ShaderPipeline::setShader(Shader *shader) {
-	Shader *oldShader = _activeShader;
-
-	_activeShader = shader;
-	if (_activeShader && _activeFramebuffer) {
-		_activeShader->activate(_activeFramebuffer->getProjectionMatrix());
-	}
-
-	return oldShader;
-}
-
 void ShaderPipeline::setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
 	GL_CALL(glVertexAttrib4f(kColorAttribLocation, r, g, b, a));
 }
@@ -64,7 +53,7 @@ void ShaderPipeline::drawTexture(const GLTexture &texture, const GLfloat *coordi
 }
 
 void ShaderPipeline::setProjectionMatrix(const GLfloat *projectionMatrix) {
-	if (_activeShader) {
+	if (isActive() && _activeShader) {
 		_activeShader->activate(projectionMatrix);
 	}
 }
diff --git a/backends/graphics/opengl/pipelines/shader.h b/backends/graphics/opengl/pipelines/shader.h
index a5b94e8..52046f8 100644
--- a/backends/graphics/opengl/pipelines/shader.h
+++ b/backends/graphics/opengl/pipelines/shader.h
@@ -28,11 +28,11 @@
 namespace OpenGL {
 
 #if !USE_FORCED_GLES
+class Shader;
+
 class ShaderPipeline : public Pipeline {
 public:
-	ShaderPipeline();
-
-	virtual Shader *setShader(Shader *shader);
+	ShaderPipeline(Shader *shader);
 
 	virtual void setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
 
@@ -43,7 +43,7 @@ public:
 protected:
 	virtual void activateInternal();
 
-	Shader *_activeShader;
+	Shader *const _activeShader;
 };
 #endif // !USE_FORCED_GLES
 


Commit: 8b80e9d36c0705adfcd1af88c16397f2aa01afb8
    https://github.com/scummvm/scummvm/commit/8b80e9d36c0705adfcd1af88c16397f2aa01afb8
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:31+01:00

Commit Message:
OPENGL: Properly deactivate old pipeline.

Changed paths:
    backends/graphics/opengl/context.cpp



diff --git a/backends/graphics/opengl/context.cpp b/backends/graphics/opengl/context.cpp
index d93ecdc..55abdf7 100644
--- a/backends/graphics/opengl/context.cpp
+++ b/backends/graphics/opengl/context.cpp
@@ -48,6 +48,9 @@ void Context::reset() {
 
 Pipeline *Context::setPipeline(Pipeline *pipeline) {
 	Pipeline *oldPipeline = activePipeline;
+	if (oldPipeline) {
+		oldPipeline->deactivate();
+	}
 
 	activePipeline = pipeline;
 	if (activePipeline) {


Commit: 6dacc96d1f6ed804197382c59765c8cec5146c62
    https://github.com/scummvm/scummvm/commit/6dacc96d1f6ed804197382c59765c8cec5146c62
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:31+01:00

Commit Message:
OPENGL: Only set projection matrix once on pipeline activation.

Changed paths:
    backends/graphics/opengl/pipelines/pipeline.cpp



diff --git a/backends/graphics/opengl/pipelines/pipeline.cpp b/backends/graphics/opengl/pipelines/pipeline.cpp
index f79a923..6a59cd2 100644
--- a/backends/graphics/opengl/pipelines/pipeline.cpp
+++ b/backends/graphics/opengl/pipelines/pipeline.cpp
@@ -34,7 +34,6 @@ void Pipeline::activate() {
 
 	if (_activeFramebuffer) {
 		_activeFramebuffer->activate();
-		setProjectionMatrix(_activeFramebuffer->getProjectionMatrix());
 	}
 
 	activateInternal();
@@ -59,7 +58,6 @@ Framebuffer *Pipeline::setFramebuffer(Framebuffer *framebuffer) {
 	_activeFramebuffer = framebuffer;
 	if (_isActive && _activeFramebuffer) {
 		_activeFramebuffer->activate();
-		setProjectionMatrix(_activeFramebuffer->getProjectionMatrix());
 	}
 
 	return oldFramebuffer;


Commit: baca885cfce10acaa7a9892133aaa5b82c7183f7
    https://github.com/scummvm/scummvm/commit/baca885cfce10acaa7a9892133aaa5b82c7183f7
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:31+01:00

Commit Message:
OPENGL: Let Shader store the uniform state.

Changed paths:
    backends/graphics/opengl/opengl-func.h
    backends/graphics/opengl/pipelines/clut8.cpp
    backends/graphics/opengl/pipelines/shader.cpp
    backends/graphics/opengl/pipelines/shader.h
    backends/graphics/opengl/shader.cpp
    backends/graphics/opengl/shader.h



diff --git a/backends/graphics/opengl/opengl-func.h b/backends/graphics/opengl/opengl-func.h
index 554ac3c..ad7c572 100644
--- a/backends/graphics/opengl/opengl-func.h
+++ b/backends/graphics/opengl/opengl-func.h
@@ -108,6 +108,7 @@ GL_FUNC_DEF(GLenum, glGetError, ());
 #if !USE_FORCED_GLES
 GL_FUNC_2_DEF(void, glEnableVertexAttribArray, glEnableVertexAttribArrayARB, (GLuint index));
 GL_FUNC_2_DEF(void, glUniform1i, glUniform1iARB, (GLint location, GLint v0));
+GL_FUNC_2_DEF(void, glUniform1f, glUniform1fARB, (GLint location, GLfloat v0));
 GL_FUNC_2_DEF(void, glUniformMatrix4fv, glUniformMatrix4fvARB, (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value));
 GL_FUNC_2_DEF(void, glVertexAttrib4f, glVertexAttrib4fARB, (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w));
 GL_FUNC_2_DEF(void, glVertexAttribPointer, glVertexAttribPointerARB, (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer));
diff --git a/backends/graphics/opengl/pipelines/clut8.cpp b/backends/graphics/opengl/pipelines/clut8.cpp
index 9f2aa94..fca4007 100644
--- a/backends/graphics/opengl/pipelines/clut8.cpp
+++ b/backends/graphics/opengl/pipelines/clut8.cpp
@@ -32,8 +32,6 @@ CLUT8LookUpPipeline::CLUT8LookUpPipeline()
 }
 
 void CLUT8LookUpPipeline::drawTexture(const GLTexture &texture, const GLfloat *coordinates) {
-	_activeShader->setUniformI(_activeShader->getUniformLocation("palette"), 1);
-
 	// Set the palette texture.
 	GL_CALL(glActiveTexture(GL_TEXTURE1));
 	if (_paletteTexture) {
diff --git a/backends/graphics/opengl/pipelines/shader.cpp b/backends/graphics/opengl/pipelines/shader.cpp
index 69af911..46e8142 100644
--- a/backends/graphics/opengl/pipelines/shader.cpp
+++ b/backends/graphics/opengl/pipelines/shader.cpp
@@ -38,6 +38,12 @@ void ShaderPipeline::activateInternal() {
 	if (g_context.multitextureSupported) {
 		GL_CALL(glActiveTexture(GL_TEXTURE0));
 	}
+
+	_activeShader->activate();
+}
+
+void ShaderPipeline::deactivateInternal() {
+	_activeShader->deactivate();
 }
 
 void ShaderPipeline::setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
@@ -53,9 +59,7 @@ void ShaderPipeline::drawTexture(const GLTexture &texture, const GLfloat *coordi
 }
 
 void ShaderPipeline::setProjectionMatrix(const GLfloat *projectionMatrix) {
-	if (isActive() && _activeShader) {
-		_activeShader->activate(projectionMatrix);
-	}
+	_activeShader->setUniform("projection", new ShaderUniformMatrix44(projectionMatrix));
 }
 #endif // !USE_FORCED_GLES
 
diff --git a/backends/graphics/opengl/pipelines/shader.h b/backends/graphics/opengl/pipelines/shader.h
index 52046f8..8e82bd7 100644
--- a/backends/graphics/opengl/pipelines/shader.h
+++ b/backends/graphics/opengl/pipelines/shader.h
@@ -42,6 +42,7 @@ public:
 
 protected:
 	virtual void activateInternal();
+	virtual void deactivateInternal();
 
 	Shader *const _activeShader;
 };
diff --git a/backends/graphics/opengl/shader.cpp b/backends/graphics/opengl/shader.cpp
index 2f2d5d8..59749ba 100644
--- a/backends/graphics/opengl/shader.cpp
+++ b/backends/graphics/opengl/shader.cpp
@@ -35,6 +35,8 @@ namespace OpenGL {
 
 namespace {
 
+#pragma mark - Builtin Shader Sources -
+
 const char *const g_defaultVertexShader = 
 	"attribute vec4 position;\n"
 	"attribute vec2 texCoordIn;\n"
@@ -92,8 +94,25 @@ const char *const g_precisionDefines =
 
 } // End of anonymous namespace
 
+#pragma mark - Uniform Values -
+
+void ShaderUniformInteger::set(GLint location) const {
+	GL_CALL(glUniform1i(location, _value));
+}
+
+void ShaderUniformFloat::set(GLint location) const {
+	GL_CALL(glUniform1f(location, _value));
+}
+
+void ShaderUniformMatrix44::set(GLint location) const {
+	GL_CALL(glUniformMatrix4fv(location, 1, GL_FALSE, _matrix));
+}
+
+#pragma mark - Shader Implementation -
+
 Shader::Shader(const Common::String &vertex, const Common::String &fragment)
-    : _vertex(vertex), _fragment(fragment), _program(0), _projectionLocation(-1), _textureLocation(-1) {
+    : _vertex(vertex), _fragment(fragment), _isActive(false), _program(0), _uniforms() {
+	recreate();
 }
 
 Shader::~Shader() {
@@ -167,15 +186,26 @@ bool Shader::recreate() {
 		return false;
 	}
 
-	GL_ASSIGN(_projectionLocation, glGetUniformLocation(_program, "projection"));
-	if (_projectionLocation == -1) {
+	// Set program object in case shader is active during recreation.
+	if (_isActive) {
+		GL_CALL(glUseProgram(_program));
+	}
+
+	for (UniformMap::iterator i = _uniforms.begin(), end = _uniforms.end(); i != end; ++i) {
+		i->_value.location = getUniformLocation(i->_key.c_str());
+		i->_value.altered = true;
+		if (_isActive) {
+			i->_value.set();
+		}
+	}
+
+	if (getUniformLocation("projection") == -1) {
 		warning("Shader misses \"projection\" uniform.");
 		destroy();
 		return false;
 	}
 
-	GL_ASSIGN(_textureLocation, glGetUniformLocation(_program, "texture"));
-	if (_textureLocation == -1) {
+	if (!setUniform1I("texture", 0)) {
 		warning("Shader misses \"texture\" uniform.");
 		destroy();
 		return false;
@@ -184,15 +214,20 @@ bool Shader::recreate() {
 	return true;
 }
 
-void Shader::activate(const GLfloat *projectionMatrix) {
+void Shader::activate() {
 	// Activate program.
 	GL_CALL(glUseProgram(_program));
 
-	// Set projection matrix.
-	GL_CALL(glUniformMatrix4fv(_projectionLocation, 1, GL_FALSE, projectionMatrix));
+	// Reset changed uniform values.
+	for (UniformMap::iterator i = _uniforms.begin(), end = _uniforms.end(); i != end; ++i) {
+		i->_value.set();
+	}
+
+	_isActive = true;
+}
 
-	// We always use texture unit 0.
-	GL_CALL(glUniform1i(_textureLocation, 0));
+void Shader::deactivate() {
+	_isActive = false;
 }
 
 GLint Shader::getUniformLocation(const char *name) const {
@@ -201,8 +236,23 @@ GLint Shader::getUniformLocation(const char *name) const {
 	return result;
 }
 
-void Shader::setUniformI(GLint location, GLint value) {
-	GL_CALL(glUniform1i(location, value));
+bool Shader::setUniform(const Common::String &name, ShaderUniformValue *value) {
+	UniformMap::iterator uniformIter = _uniforms.find(name);
+	Uniform *uniform;
+
+	if (uniformIter == _uniforms.end()) {
+		uniform = &_uniforms[name];
+		uniform->location = getUniformLocation(name.c_str());
+	} else {
+		uniform = &uniformIter->_value;
+	}
+
+	uniform->value = Common::SharedPtr<ShaderUniformValue>(value);
+	uniform->altered = true;
+	if (_isActive) {
+		uniform->set();
+	}
+	return uniform->location != -1;
 }
 
 GLshader Shader::compileShader(const char *source, GLenum shaderType) {
@@ -238,9 +288,7 @@ GLshader Shader::compileShader(const char *source, GLenum shaderType) {
 	return handle;
 }
 
-ShaderManager::ShaderManager() {
-	_builtIn[kDefault] = new Shader(g_defaultVertexShader, g_defaultFragmentShader);
-	_builtIn[kCLUT8LookUp] = new Shader(g_defaultVertexShader, g_lookUpFragmentShader);
+ShaderManager::ShaderManager() : _initializeShaders(true) {
 }
 
 ShaderManager::~ShaderManager() {
@@ -256,8 +304,16 @@ void ShaderManager::notifyDestroy() {
 }
 
 void ShaderManager::notifyCreate() {
-	for (int i = 0; i < ARRAYSIZE(_builtIn); ++i) {
-		_builtIn[i]->recreate();
+	if (_initializeShaders) {
+		_initializeShaders = false;
+
+		_builtIn[kDefault] = new Shader(g_defaultVertexShader, g_defaultFragmentShader);
+		_builtIn[kCLUT8LookUp] = new Shader(g_defaultVertexShader, g_lookUpFragmentShader);
+		_builtIn[kCLUT8LookUp]->setUniform1I("palette", 1);
+	} else {
+		for (int i = 0; i < ARRAYSIZE(_builtIn); ++i) {
+			_builtIn[i]->recreate();
+		}
 	}
 }
 
diff --git a/backends/graphics/opengl/shader.h b/backends/graphics/opengl/shader.h
index e5dbcac..1aee8ed 100644
--- a/backends/graphics/opengl/shader.h
+++ b/backends/graphics/opengl/shader.h
@@ -27,8 +27,9 @@
 
 #if !USE_FORCED_GLES
 
-#include "common/str.h"
 #include "common/singleton.h"
+#include "common/hash-str.h"
+#include "common/ptr.h"
 
 namespace OpenGL {
 
@@ -38,6 +39,62 @@ enum {
 	kColorAttribLocation    = 2
 };
 
+/**
+ * A generic uniform value interface for a shader program.
+ */
+class ShaderUniformValue {
+public:
+	virtual ~ShaderUniformValue() {}
+
+	/**
+	 * Setup the the value to the given location.
+	 *
+	 * @param location Location of the uniform.
+	 */
+	virtual void set(GLint location) const = 0;
+};
+
+/**
+ * Integer value for a shader uniform.
+ */
+class ShaderUniformInteger : public ShaderUniformValue {
+public:
+	ShaderUniformInteger(GLint value) : _value(value) {}
+
+	virtual void set(GLint location) const override;
+
+private:
+	const GLint _value;
+};
+
+/**
+ * Float value for a shader uniform.
+ */
+class ShaderUniformFloat : public ShaderUniformValue {
+public:
+	ShaderUniformFloat(GLfloat value) : _value(value) {}
+
+	virtual void set(GLint location) const override;
+
+private:
+	const GLfloat _value;
+};
+
+/**
+ * 4x4 Matrix value for a shader uniform.
+ */
+class ShaderUniformMatrix44 : public ShaderUniformValue {
+public:
+	ShaderUniformMatrix44(const GLfloat *mat44) {
+		memcpy(_matrix, mat44, sizeof(_matrix));
+	}
+
+	virtual void set(GLint location) const override;
+
+private:
+	GLfloat _matrix[4*4];
+};
+
 class Shader {
 public:
 	Shader(const Common::String &vertex, const Common::String &fragment);
@@ -47,7 +104,8 @@ public:
 	 * Destroy the shader program.
 	 *
 	 * This keeps the vertex and fragment shader sources around and thus
-	 * allows for recreating the shader on context recreation.
+	 * allows for recreating the shader on context recreation. It also keeps
+	 * the uniform state around.
 	 */
 	void destroy();
 
@@ -60,10 +118,13 @@ public:
 
 	/**
 	 * Make shader active.
-	 *
-	 * @param projectionMatrix Projection matrix to use.
 	 */
-	void activate(const GLfloat *projectionMatrix);
+	void activate();
+
+	/**
+	 * Make shader inactive.
+	 */
+	void deactivate();
 
 	/**
 	 * Return location for uniform with given name.
@@ -76,12 +137,24 @@ public:
 	/**
 	 * Bind value to uniform.
 	 *
-	 * Note: this only works when the shader is actived by activate.
+	 * @param name  The name of the uniform to be set.
+	 * @param value The value to be set.
+	 * @return 'false' on error (i.e. uniform unknown or otherwise),
+	 *         'true' otherwise.
+	 */
+	bool setUniform(const Common::String &name, ShaderUniformValue *value);
+
+	/**
+	 * Bind integer value to uniform.
 	 *
-	 * @param location Location of the uniform.
-	 * @param value    The value to be set.
+	 * @param name  The name of the uniform to be set.
+	 * @param value The value to be set.
+	 * @return 'false' on error (i.e. uniform unknown or otherwise),
+	 *         'true' otherwise.
 	 */
-	void setUniformI(GLint location, GLint value);
+	bool setUniform1I(const Common::String &name, GLint value) {
+		return setUniform(name, new ShaderUniformInteger(value));
+	}
 protected:
 	/**
 	 * Vertex shader sources.
@@ -94,19 +167,59 @@ protected:
 	const Common::String _fragment;
 
 	/**
+	 * Whether the shader is active or not.
+	 */
+	bool _isActive;
+
+	/**
 	 * Shader program handle.
 	 */
 	GLprogram _program;
 
 	/**
-	 * Location of the matrix uniform in the shader program.
+	 * A uniform descriptor.
+	 *
+	 * This stores the state of a shader uniform. The state is made up of the
+	 * uniform location, whether the state was altered since last set, and the
+	 * value of the uniform.
 	 */
-	GLint _projectionLocation;
+	struct Uniform {
+		Uniform() : location(-1), altered(false), value() {}
+		Uniform(GLint loc, ShaderUniformValue *val)
+		    : location(loc), altered(true), value(val) {}
+
+		/**
+		 * Write uniform value into currently active shader.
+		 */
+		void set() {
+			if (altered && value) {
+				value->set(location);
+				altered = false;
+			}
+		}
+
+		/**
+		 * The location of the uniform or -1 in case it does not exist.
+		 */
+		GLint location;
+
+		/**
+		 * Whether the uniform state was aletered since last 'set'.
+		 */
+		bool altered;
+
+		/**
+		 * The value of the uniform.
+		 */
+		Common::SharedPtr<ShaderUniformValue> value;
+	};
+
+	typedef Common::HashMap<Common::String, Uniform> UniformMap;
 
 	/**
-	 * Location of the texture sampler location in the shader program.
+	 * Map from uniform name to associated uniform description.
 	 */
-	GLint _textureLocation;
+	UniformMap _uniforms;
 
 	/**
 	 * Compile a vertex or fragment shader.
@@ -152,6 +265,8 @@ private:
 	ShaderManager();
 	~ShaderManager();
 
+	bool _initializeShaders;
+
 	Shader *_builtIn[kMaxUsages];
 };
 


Commit: 39100b613272523c2e36be213cc827857a08f824
    https://github.com/scummvm/scummvm/commit/39100b613272523c2e36be213cc827857a08f824
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:31+01:00

Commit Message:
OPENGL: Do not hardcode any uniform/attribute handling in Shader.

Changed paths:
    backends/graphics/opengl/opengl-func.h
    backends/graphics/opengl/pipelines/shader.cpp
    backends/graphics/opengl/pipelines/shader.h
    backends/graphics/opengl/shader.cpp
    backends/graphics/opengl/shader.h



diff --git a/backends/graphics/opengl/opengl-func.h b/backends/graphics/opengl/opengl-func.h
index ad7c572..4e44c13 100644
--- a/backends/graphics/opengl/opengl-func.h
+++ b/backends/graphics/opengl/opengl-func.h
@@ -107,6 +107,7 @@ GL_FUNC_DEF(GLenum, glGetError, ());
 
 #if !USE_FORCED_GLES
 GL_FUNC_2_DEF(void, glEnableVertexAttribArray, glEnableVertexAttribArrayARB, (GLuint index));
+GL_FUNC_2_DEF(void, glDisableVertexAttribArray, glDisableVertexAttribArrayARB, (GLuint index));
 GL_FUNC_2_DEF(void, glUniform1i, glUniform1iARB, (GLint location, GLint v0));
 GL_FUNC_2_DEF(void, glUniform1f, glUniform1fARB, (GLint location, GLfloat v0));
 GL_FUNC_2_DEF(void, glUniformMatrix4fv, glUniformMatrix4fvARB, (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value));
@@ -122,6 +123,7 @@ GL_FUNC_2_DEF(void, glUseProgram, glUseProgramObjectARB, (GLprogram program));
 GL_FUNC_2_DEF(void, glGetProgramiv, glGetObjectParameterivARB, (GLprogram program, GLenum pname, GLint *params));
 GL_FUNC_2_DEF(void, glGetProgramInfoLog, glGetInfoLogARB, (GLprogram program, GLsizei bufSize, GLsizei *length, GLchar *infoLog));
 GL_FUNC_2_DEF(void, glBindAttribLocation, glBindAttribLocationARB, (GLprogram program, GLuint index, const GLchar *name));
+GL_FUNC_2_DEF(GLint, glGetAttribLocation, glGetAttribLocationARB, (GLprogram program, const GLchar *name));
 GL_FUNC_2_DEF(GLint, glGetUniformLocation, glGetUniformLocationARB, (GLprogram program, const GLchar *name));
 
 GL_FUNC_2_DEF(GLshader, glCreateShader, glCreateShaderObjectARB, (GLenum type));
diff --git a/backends/graphics/opengl/pipelines/shader.cpp b/backends/graphics/opengl/pipelines/shader.cpp
index 46e8142..c7befe2 100644
--- a/backends/graphics/opengl/pipelines/shader.cpp
+++ b/backends/graphics/opengl/pipelines/shader.cpp
@@ -29,11 +29,14 @@ namespace OpenGL {
 #if !USE_FORCED_GLES
 ShaderPipeline::ShaderPipeline(Shader *shader)
     : _activeShader(shader) {
+	_vertexAttribLocation = shader->getAttributeLocation("position");
+	_texCoordAttribLocation = shader->getAttributeLocation("texCoordIn");
+	_colorAttribLocation = shader->getAttributeLocation("blendColorIn");
 }
 
 void ShaderPipeline::activateInternal() {
-	GL_CALL(glEnableVertexAttribArray(kPositionAttribLocation));
-	GL_CALL(glEnableVertexAttribArray(kTexCoordAttribLocation));
+	GL_CALL(glEnableVertexAttribArray(_vertexAttribLocation));
+	GL_CALL(glEnableVertexAttribArray(_texCoordAttribLocation));
 
 	if (g_context.multitextureSupported) {
 		GL_CALL(glActiveTexture(GL_TEXTURE0));
@@ -43,18 +46,21 @@ void ShaderPipeline::activateInternal() {
 }
 
 void ShaderPipeline::deactivateInternal() {
+	GL_CALL(glDisableVertexAttribArray(_vertexAttribLocation));
+	GL_CALL(glDisableVertexAttribArray(_texCoordAttribLocation));
+
 	_activeShader->deactivate();
 }
 
 void ShaderPipeline::setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
-	GL_CALL(glVertexAttrib4f(kColorAttribLocation, r, g, b, a));
+	GL_CALL(glVertexAttrib4f(_colorAttribLocation, r, g, b, a));
 }
 
 void ShaderPipeline::drawTexture(const GLTexture &texture, const GLfloat *coordinates) {
 	texture.bind();
 
-	GL_CALL(glVertexAttribPointer(kTexCoordAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, texture.getTexCoords()));
-	GL_CALL(glVertexAttribPointer(kPositionAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, coordinates));
+	GL_CALL(glVertexAttribPointer(_texCoordAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, texture.getTexCoords()));
+	GL_CALL(glVertexAttribPointer(_vertexAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, coordinates));
 	GL_CALL(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
 }
 
diff --git a/backends/graphics/opengl/pipelines/shader.h b/backends/graphics/opengl/pipelines/shader.h
index 8e82bd7..95167ee 100644
--- a/backends/graphics/opengl/pipelines/shader.h
+++ b/backends/graphics/opengl/pipelines/shader.h
@@ -44,6 +44,10 @@ protected:
 	virtual void activateInternal();
 	virtual void deactivateInternal();
 
+	GLint _vertexAttribLocation;
+	GLint _texCoordAttribLocation;
+	GLint _colorAttribLocation;
+
 	Shader *const _activeShader;
 };
 #endif // !USE_FORCED_GLES
diff --git a/backends/graphics/opengl/shader.cpp b/backends/graphics/opengl/shader.cpp
index 59749ba..652da57 100644
--- a/backends/graphics/opengl/shader.cpp
+++ b/backends/graphics/opengl/shader.cpp
@@ -159,10 +159,6 @@ bool Shader::recreate() {
 	GL_CALL(glAttachShader(_program, vertexShader));
 	GL_CALL(glAttachShader(_program, fragmentShader));
 
-	GL_CALL(glBindAttribLocation(_program, kPositionAttribLocation, "position"));
-	GL_CALL(glBindAttribLocation(_program, kTexCoordAttribLocation, "texCoordIn"));
-	GL_CALL(glBindAttribLocation(_program, kColorAttribLocation,    "blendColorIn"));
-
 	GL_CALL(glLinkProgram(_program));
 
 	GL_CALL(glDetachShader(_program, fragmentShader));
@@ -199,18 +195,6 @@ bool Shader::recreate() {
 		}
 	}
 
-	if (getUniformLocation("projection") == -1) {
-		warning("Shader misses \"projection\" uniform.");
-		destroy();
-		return false;
-	}
-
-	if (!setUniform1I("texture", 0)) {
-		warning("Shader misses \"texture\" uniform.");
-		destroy();
-		return false;
-	}
-
 	return true;
 }
 
@@ -230,6 +214,12 @@ void Shader::deactivate() {
 	_isActive = false;
 }
 
+GLint Shader::getAttributeLocation(const char *name) const {
+	GLint result = -1;
+	GL_ASSIGN(result, glGetAttribLocation(_program, name));
+	return result;
+}
+
 GLint Shader::getUniformLocation(const char *name) const {
 	GLint result = -1;
 	GL_ASSIGN(result, glGetUniformLocation(_program, name));
@@ -310,6 +300,10 @@ void ShaderManager::notifyCreate() {
 		_builtIn[kDefault] = new Shader(g_defaultVertexShader, g_defaultFragmentShader);
 		_builtIn[kCLUT8LookUp] = new Shader(g_defaultVertexShader, g_lookUpFragmentShader);
 		_builtIn[kCLUT8LookUp]->setUniform1I("palette", 1);
+
+		for (uint i = 0; i < kMaxUsages; ++i) {
+			_builtIn[i]->setUniform1I("texture", 0);
+		}
 	} else {
 		for (int i = 0; i < ARRAYSIZE(_builtIn); ++i) {
 			_builtIn[i]->recreate();
diff --git a/backends/graphics/opengl/shader.h b/backends/graphics/opengl/shader.h
index 1aee8ed..f219861 100644
--- a/backends/graphics/opengl/shader.h
+++ b/backends/graphics/opengl/shader.h
@@ -33,12 +33,6 @@
 
 namespace OpenGL {
 
-enum {
-	kPositionAttribLocation = 0,
-	kTexCoordAttribLocation = 1,
-	kColorAttribLocation    = 2
-};
-
 /**
  * A generic uniform value interface for a shader program.
  */
@@ -127,6 +121,14 @@ public:
 	void deactivate();
 
 	/**
+	 * Return location for attribute with given name.
+	 *
+	 * @param name Name of the attribute to look up in the shader.
+	 * @return The loctaion of -1 if attribute was not found.
+	 */
+	GLint getAttributeLocation(const char *name) const;
+
+	/**
 	 * Return location for uniform with given name.
 	 *
 	 * @param name Name of the uniform to look up in the shader.


Commit: 2b3340474e6b1c7bbf12923f86c39f1d4d9b245e
    https://github.com/scummvm/scummvm/commit/2b3340474e6b1c7bbf12923f86c39f1d4d9b245e
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:31+01:00

Commit Message:
OPENGL: Introduce convenience wrappers for get*Location in Shader.

Changed paths:
    backends/graphics/opengl/shader.h



diff --git a/backends/graphics/opengl/shader.h b/backends/graphics/opengl/shader.h
index f219861..ec1e516 100644
--- a/backends/graphics/opengl/shader.h
+++ b/backends/graphics/opengl/shader.h
@@ -127,6 +127,9 @@ public:
 	 * @return The loctaion of -1 if attribute was not found.
 	 */
 	GLint getAttributeLocation(const char *name) const;
+	GLint getAttributeLocation(const Common::String &name) const {
+		return getAttributeLocation(name.c_str());
+	}
 
 	/**
 	 * Return location for uniform with given name.
@@ -135,6 +138,9 @@ public:
 	 * @return The location or -1 if uniform was not found.
 	 */
 	GLint getUniformLocation(const char *name) const;
+	GLint getUniformLocation(const Common::String &name) const {
+		return getUniformLocation(name.c_str());
+	}
 
 	/**
 	 * Bind value to uniform.


Commit: 1e1272a8c4c54d43f076d5a0153db36ee8cbeb42
    https://github.com/scummvm/scummvm/commit/1e1272a8c4c54d43f076d5a0153db36ee8cbeb42
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:31+01:00

Commit Message:
OPENGL: Store logical texture dimensions in GLTexture.

Changed paths:
    backends/graphics/opengl/texture.cpp
    backends/graphics/opengl/texture.h



diff --git a/backends/graphics/opengl/texture.cpp b/backends/graphics/opengl/texture.cpp
index 79e3acc..5252b5a 100644
--- a/backends/graphics/opengl/texture.cpp
+++ b/backends/graphics/opengl/texture.cpp
@@ -46,7 +46,8 @@ static GLuint nextHigher2(GLuint v) {
 
 GLTexture::GLTexture(GLenum glIntFormat, GLenum glFormat, GLenum glType)
     : _glIntFormat(glIntFormat), _glFormat(glFormat), _glType(glType),
-      _width(0), _height(0), _texCoords(), _glFilter(GL_NEAREST),
+      _width(0), _height(0), _logicalWidth(0), _logicalHeight(0),
+      _texCoords(), _glFilter(GL_NEAREST),
       _glTexture(0) {
 	create();
 }
@@ -112,6 +113,9 @@ void GLTexture::setSize(uint width, uint height) {
 		_height = height;
 	}
 
+	_logicalWidth  = width;
+	_logicalHeight = height;
+
 	// If a size is specified, allocate memory for it.
 	if (width != 0 && height != 0) {
 		const GLfloat texWidth = (GLfloat)width / _width;
diff --git a/backends/graphics/opengl/texture.h b/backends/graphics/opengl/texture.h
index 97e99b4..3be09cb 100644
--- a/backends/graphics/opengl/texture.h
+++ b/backends/graphics/opengl/texture.h
@@ -99,10 +99,27 @@ public:
 	 */
 	void updateArea(const Common::Rect &area, const Graphics::Surface &src);
 
+	/**
+	 * Query the GL texture's width.
+	 */
 	uint getWidth() const { return _width; }
+
+	/**
+	 * Query the GL texture's height.
+	 */
 	uint getHeight() const { return _height; }
 
 	/**
+	 * Query the logical texture's width.
+	 */
+	uint getLogicalWidth() const { return _logicalWidth; }
+
+	/**
+	 * Query the logical texture's height.
+	 */
+	uint getLogicalHeight() const { return _logicalHeight; }
+
+	/**
 	 * Obtain texture coordinates for rectangular drawing.
 	 */
 	const GLfloat *getTexCoords() const { return _texCoords; }
@@ -120,6 +137,7 @@ private:
 	const GLenum _glType;
 
 	uint _width, _height;
+	uint _logicalWidth, _logicalHeight;
 	GLfloat _texCoords[4*2];
 
 	GLint _glFilter;


Commit: 17b1124a5aa294d39cf3a3c6fc6561f835affe2d
    https://github.com/scummvm/scummvm/commit/17b1124a5aa294d39cf3a3c6fc6561f835affe2d
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:31+01:00

Commit Message:
OPENGL: Do not keep uniform state for nonexistent uniforms.

Changed paths:
    backends/graphics/opengl/shader.cpp



diff --git a/backends/graphics/opengl/shader.cpp b/backends/graphics/opengl/shader.cpp
index 652da57..27981f2 100644
--- a/backends/graphics/opengl/shader.cpp
+++ b/backends/graphics/opengl/shader.cpp
@@ -231,8 +231,14 @@ bool Shader::setUniform(const Common::String &name, ShaderUniformValue *value) {
 	Uniform *uniform;
 
 	if (uniformIter == _uniforms.end()) {
+		const GLint location = getUniformLocation(name.c_str());
+		if (location == -1) {
+			delete value;
+			return false;
+		}
+
 		uniform = &_uniforms[name];
-		uniform->location = getUniformLocation(name.c_str());
+		uniform->location = location;
 	} else {
 		uniform = &uniformIter->_value;
 	}
@@ -242,7 +248,8 @@ bool Shader::setUniform(const Common::String &name, ShaderUniformValue *value) {
 	if (_isActive) {
 		uniform->set();
 	}
-	return uniform->location != -1;
+
+	return true;
 }
 
 GLshader Shader::compileShader(const char *source, GLenum shaderType) {


Commit: b7a269947f9b5e40e4baa36d763e5c04551f584c
    https://github.com/scummvm/scummvm/commit/b7a269947f9b5e40e4baa36d763e5c04551f584c
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T20:29:31+01:00

Commit Message:
OPENGL: Flag texture dirty on allocation.

Changed paths:
    backends/graphics/opengl/texture.cpp



diff --git a/backends/graphics/opengl/texture.cpp b/backends/graphics/opengl/texture.cpp
index 5252b5a..8b94549 100644
--- a/backends/graphics/opengl/texture.cpp
+++ b/backends/graphics/opengl/texture.cpp
@@ -266,6 +266,12 @@ void Texture::allocate(uint width, uint height) {
 
 	// Create a sub-buffer for raw access.
 	_userPixelData = _textureData.getSubArea(Common::Rect(width, height));
+
+	// The whole texture is dirty after we changed the size. This fixes
+	// multiple texture size changes without any actual update in between.
+	// Without this we might try to write a too big texture into the GL
+	// texture.
+	flagDirty();
 }
 
 void Texture::updateGLTexture() {
@@ -561,6 +567,12 @@ void TextureCLUT8GPU::allocate(uint width, uint height) {
 
 	_clut8Vertices[6] = width;
 	_clut8Vertices[7] = height;
+
+	// The whole texture is dirty after we changed the size. This fixes
+	// multiple texture size changes without any actual update in between.
+	// Without this we might try to write a too big texture into the GL
+	// texture.
+	flagDirty();
 }
 
 Graphics::PixelFormat TextureCLUT8GPU::getFormat() const {


Commit: 6b2424b6353ca5712afdf80e128a912a3cf78f0c
    https://github.com/scummvm/scummvm/commit/6b2424b6353ca5712afdf80e128a912a3cf78f0c
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-16T21:03:43+01:00

Commit Message:
OPENGL: Log extensions available on debuglevel 5+.

Changed paths:
    backends/graphics/opengl/context.cpp



diff --git a/backends/graphics/opengl/context.cpp b/backends/graphics/opengl/context.cpp
index 55abdf7..a7f640d 100644
--- a/backends/graphics/opengl/context.cpp
+++ b/backends/graphics/opengl/context.cpp
@@ -113,6 +113,7 @@ void OpenGLGraphicsManager::initializeGLContext() {
 	debug(5, "OpenGL maximum texture size: %d", g_context.maxTextureSize);
 
 	const char *extString = (const char *)g_context.glGetString(GL_EXTENSIONS);
+	debug(5, "OpenGL extensions: %s", extString);
 
 	bool ARBShaderObjects = false;
 	bool ARBShadingLanguage100 = false;


Commit: 114ef5817fe661275f7cb99d490b72f1d287b30e
    https://github.com/scummvm/scummvm/commit/114ef5817fe661275f7cb99d490b72f1d287b30e
Author: Johannes Schickel (lordhoto at gmail.com)
Date: 2016-03-23T15:55:55+01:00

Commit Message:
Merge pull request #711 from lordhoto/opengl-revamp

OpenGLGraphicsManager: Revamp

Changed paths:
  A backends/graphics/opengl/context.cpp
  A backends/graphics/opengl/framebuffer.cpp
  A backends/graphics/opengl/framebuffer.h
  A backends/graphics/opengl/opengl-defs.h
  A backends/graphics/opengl/opengl-func.h
  A backends/graphics/opengl/pipelines/clut8.cpp
  A backends/graphics/opengl/pipelines/clut8.h
  A backends/graphics/opengl/pipelines/fixed.cpp
  A backends/graphics/opengl/pipelines/fixed.h
  A backends/graphics/opengl/pipelines/pipeline.cpp
  A backends/graphics/opengl/pipelines/pipeline.h
  A backends/graphics/opengl/pipelines/shader.cpp
  A backends/graphics/opengl/pipelines/shader.h
  A backends/graphics/opengl/shader.cpp
  A backends/graphics/opengl/shader.h
  R backends/graphics/opengl/extensions.cpp
  R backends/graphics/opengl/extensions.h
    backends/graphics/opengl/debug.cpp
    backends/graphics/opengl/debug.h
    backends/graphics/opengl/opengl-graphics.cpp
    backends/graphics/opengl/opengl-graphics.h
    backends/graphics/opengl/opengl-sys.h
    backends/graphics/opengl/texture.cpp
    backends/graphics/opengl/texture.h
    backends/graphics/openglsdl/openglsdl-graphics.cpp
    backends/graphics/openglsdl/openglsdl-graphics.h
    backends/module.mk
    backends/platform/tizen/graphics.cpp
    backends/platform/tizen/graphics.h
    configure
    devtools/create_project/create_project.cpp
    devtools/create_project/xcode.cpp



diff --cc configure
index 8d778db,d42fb3c..1a873b2
--- a/configure
+++ b/configure
@@@ -4162,126 -4163,85 +4163,108 @@@ case $_backend i
  		;;
  esac
  
- if test "$_opengl" = auto ; then
- 	_opengl=no
- 	if test "$_backend" = "sdl" ; then
- 		# Try different header filenames
- 		# 1) GL/gl.h         This is usually used on POSIX and Windows systems
- 		# 2) OpenGL/gl.h     This is used on Mac OS X
- 		# 3) GLES/gl.h       This is used for OpenGL ES 1.x
- 		for i in "GL/gl.h" "OpenGL/gl.h" "GLES/gl.h"; do
- 			# Test the current header for OpenGL
- 			cat > $TMPC << EOF
- #include <$i>
- #include <stdio.h>
- int main(void) { printf("ANTIVIRUS FALSE POSITIVE WORKAROUND"); return GL_VERSION_1_1; }
- EOF
- 			cc_check $DEFINES $OPENGL_CFLAGS $OPENGL_LIBS && _opengl=yes && break
+ if test "$_opengl_mode" = auto ; then
+ 	case $_backend in
+ 		sdl)
+ 			case $_sdlversion in
+ 				1.2.*)
+ 					# Stock SDL 1.2 only supports OpenGL contexts.
+ 					_opengl_mode=gl
+ 					;;
  
- 			# Test the current header for OpenGL ES
- 			cat > $TMPC << EOF
- #include <$i>
- int main(void) { return GL_OES_VERSION_1_1; }
- EOF
- 			cc_check $DEFINES $OPENGL_CFLAGS $OPENGL_LIBS && _opengl=yes && _opengles=yes && break
+ 				2.0.*)
+ 					# SDL2 supports both OpenGL + OpenGL ES contexts.
+ 					# However, Mac OS X only allows OpenGL context creation at
+ 					# this time, thus we limit us to OpenGL on that platform.
+ 					case $_host_os in
+ 						darwin*)
+ 							_opengl_mode=gl
+ 							;;
+ 
+ 						*)
+ 							_opengl_mode=any
+ 							;;
+ 					esac
+ 					;;
+ 			esac
+ 			;;
  
- 			# Test the current header for OpenGL ES on SBCs (Raspberry Pi, Cubieboard, etc)
- 			cat > $TMPC << EOF
- #include <$i>
- int main(void) { return GL_VERSION_ES_CM_1_1; }
- EOF
- 			cc_check $DEFINES $OPENGL_CFLAGS $OPENGL_LIBS && _opengl=yes && _opengles=yes && break
- 		done
- 	fi
+ 		tizen)
+ 			# Tizen always runs in GLES mode
+ 			_opengl_mode=gles
+ 			;;
+ 
+ 		*)
+ 			_opengl_mode=none
+ 			;;
+ 	esac
  fi
- if test "$_opengl" = yes ; then
- 	# Our simple test case
- 	cat > $TMPC << EOF
- int main(void) { return 0; }
- EOF
  
- 	_opengl=no
- 	# Try different library names
- 	if test "$_opengles" = "yes" ; then
- 		# 1) GLES_CM    This is usually used for OpenGL ES 1.1 (Common profile)
- 		# 2) GLESv1_CM  This is used by the Windows Mali OpenGL ES 1.1 Emulator
- 		# 3) glesv1     This is used by the Linux Mali OpenGL ES 1.1 Emulator
- 		_opengles=no
- 		for lib in "-lGLES_CM" "-lGLESv1_CM" "-lglesv1"; do
- 			if cc_check_no_clean $DEFINES $OPENGL_CFLAGS $OPENGL_LIBS $lib
- 				then
- 				_opengl=yes
- 				_opengles=yes
- 				OPENGL_LIBS="$OPENGL_LIBS $lib"
- 				break
- 			fi
- 		done
- 	else
- 		# 1) -framework OpenGL  This is used on Mac OS X
- 		# 2) GL                 This is usually used on POSIX systems
- 		# 3) opengl32           This is used on Windows
- 		#
- 		# We try "-framework OpenGL" first here to assure it will always be
- 		# picked up by the configure script on Mac OS X, even when a libGL
- 		# exists.
- 		for lib in "-framework OpenGL" "-lGL" "-lopengl32"; do
- 			if cc_check_no_clean $DEFINES $OPENGL_CFLAGS $OPENGL_LIBS $lib
- 				then
- 				_opengl=yes
- 				OPENGL_LIBS="$OPENGL_LIBS $lib"
- 				break
- 			fi
- 		done
- 	fi
- 	cc_check_clean
+ _opengl=yes
+ case $_opengl_mode in
+ 	auto)
+ 		# This case should never occur but better safe than sorry.
+ 		echo "no"
+ 		_opengl=no
+ 		;;
  
- 	if test "$_opengl" = yes ; then
- 		append_var LIBS "$OPENGL_LIBS"
- 		append_var INCLUDES "$OPENGL_CFLAGS"
- 	fi
- fi
+ 	none)
+ 		echo "no"
+ 		_opengl=no
+ 		;;
  
- case $_host_os in
- 	tizen)
- 		# components live in non-standard locations so just assume sane SDK
- 		_opengl=yes
- 		_opengles=yes
+ 	any)
+ 		echo "yes (runtime detection)"
+ 		add_line_to_config_h "#undef USE_GLES_MODE"
  		;;
- esac
  
- if test "$_opengles" = "yes" ; then
- 	echo "yes (OpenGL ES)"
- else
- 	echo "$_opengl"
- fi
+ 	gl)
+ 		echo "yes (OpenGL)"
+ 		add_line_to_config_h "#define USE_GLES_MODE 0"
+ 		;;
+ 
+ 	gles)
+ 		echo "yes (OpenGL ES)"
+ 		add_line_to_config_h "#define USE_GLES_MODE 1"
+ 		;;
+ 
+ 	gles2)
+ 		echo "yes (OpenGL ES 2)"
+ 		add_line_to_config_h "#define USE_GLES_MODE 2"
+ 		;;
+ 
+ 	*)
+ 		echo "invalid mode specification '$_opengl_mode'. Aborting."
+ 		exit 1
+ 		;;
+ esac
  
  define_in_config_if_yes "$_opengl" "USE_OPENGL"
- define_in_config_if_yes "$_opengles" "USE_GLES"
  
  #
 +# Check for Linux CD-ROM support
 +#
 +case $_host_os in
 +	*linux*)
 +		echocheck "Linux CD-ROM"
 +		linuxcd=no
 +		cat > $TMPC << EOF
 +#include <linux/cdrom.h>
 +#include <sys/types.h>
 +int main(void) {
 +	int x = CDROMREADAUDIO;
 +	dev_t dev;
 +	return major(dev) + x;
 +}
 +EOF
 +		cc_check && linuxcd=yes
 +		define_in_config_if_yes "$linuxcd" 'USE_LINUXCD'
 +		echo "$linuxcd"
 +		;;
 +esac
 +
 +
 +#
  # Check for nasm
  #
  if test "$_have_x86" = yes ; then






More information about the Scummvm-git-logs mailing list