aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Schickel2016-01-04 07:07:37 +0100
committerJohannes Schickel2016-03-16 20:29:26 +0100
commit5498982a3754edccb498521587c553e0ecbe7328 (patch)
tree956bfaacf060f28b83af030d3a0063abb2fd72ef
parentf5f1b6eba0d409abcda2a3c037a177d6f6e41a2e (diff)
downloadscummvm-rg350-5498982a3754edccb498521587c553e0ecbe7328.tar.gz
scummvm-rg350-5498982a3754edccb498521587c553e0ecbe7328.tar.bz2
scummvm-rg350-5498982a3754edccb498521587c553e0ecbe7328.zip
OPENGL: Introduce ShaderManager to handle builtin shaders.
-rw-r--r--backends/graphics/opengl/opengl-graphics.cpp27
-rw-r--r--backends/graphics/opengl/opengl-graphics.h5
-rw-r--r--backends/graphics/opengl/shader.cpp53
-rw-r--r--backends/graphics/opengl/shader.h43
-rw-r--r--backends/graphics/opengl/texture.cpp31
-rw-r--r--backends/graphics/opengl/texture.h1
6 files changed, 106 insertions, 54 deletions
diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index 0a9b040f83..a8301482d3 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 95ba4e7377..f3cd4c437f 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 e699262b8d..2f2d5d82eb 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 98a2a2859b..e5dbcacfad 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 61e8dc37b3..828dade0be 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 959281539f..5f586f6a2f 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;