diff options
Diffstat (limited to 'backends/graphics/opengl')
-rw-r--r-- | backends/graphics/opengl/context.cpp | 15 | ||||
-rw-r--r-- | backends/graphics/opengl/framebuffer.cpp | 8 | ||||
-rw-r--r-- | backends/graphics/opengl/framebuffer.h | 1 | ||||
-rw-r--r-- | backends/graphics/opengl/opengl-graphics.cpp | 40 | ||||
-rw-r--r-- | backends/graphics/opengl/opengl-sys.h | 13 | ||||
-rw-r--r-- | backends/graphics/opengl/pipeline.cpp | 49 | ||||
-rw-r--r-- | backends/graphics/opengl/pipeline.h | 52 | ||||
-rw-r--r-- | backends/graphics/opengl/texture.cpp | 17 |
8 files changed, 126 insertions, 69 deletions
diff --git a/backends/graphics/opengl/context.cpp b/backends/graphics/opengl/context.cpp index 3678abfd09..09da353918 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 cca00bab03..85245b683c 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 be829de3d2..467c00e5da 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 8832597f33..e32753ee3e 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 ce4f0bfa40..723e28fa17 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 362f15a36b..500597cc3d 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 e12390bcce..d101a99d9b 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 02e1b2c325..05b7ac1896 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 |