diff options
author | Johannes Schickel | 2016-01-04 07:07:37 +0100 |
---|---|---|
committer | Johannes Schickel | 2016-03-16 20:29:26 +0100 |
commit | 5498982a3754edccb498521587c553e0ecbe7328 (patch) | |
tree | 956bfaacf060f28b83af030d3a0063abb2fd72ef | |
parent | f5f1b6eba0d409abcda2a3c037a177d6f6e41a2e (diff) | |
download | scummvm-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.cpp | 27 | ||||
-rw-r--r-- | backends/graphics/opengl/opengl-graphics.h | 5 | ||||
-rw-r--r-- | backends/graphics/opengl/shader.cpp | 53 | ||||
-rw-r--r-- | backends/graphics/opengl/shader.h | 43 | ||||
-rw-r--r-- | backends/graphics/opengl/texture.cpp | 31 | ||||
-rw-r--r-- | backends/graphics/opengl/texture.h | 1 |
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; |