aboutsummaryrefslogtreecommitdiff
path: root/backends/graphics
diff options
context:
space:
mode:
authorJohannes Schickel2016-01-04 11:38:21 +0100
committerJohannes Schickel2016-03-16 20:29:27 +0100
commit0fe580d10c6fb73a90eccb046c8dcbf84b062b16 (patch)
tree374a7e245e5b39caa120de0ae9c4e3d19dba60ee /backends/graphics
parent0b46af2f0e5eef939daa73d5b38b6b817c78c7d8 (diff)
downloadscummvm-rg350-0fe580d10c6fb73a90eccb046c8dcbf84b062b16.tar.gz
scummvm-rg350-0fe580d10c6fb73a90eccb046c8dcbf84b062b16.tar.bz2
scummvm-rg350-0fe580d10c6fb73a90eccb046c8dcbf84b062b16.zip
OPENGL: Make shader/framebuffer part of pipeline state.
Diffstat (limited to 'backends/graphics')
-rw-r--r--backends/graphics/opengl/context.cpp15
-rw-r--r--backends/graphics/opengl/framebuffer.cpp8
-rw-r--r--backends/graphics/opengl/framebuffer.h1
-rw-r--r--backends/graphics/opengl/opengl-graphics.cpp40
-rw-r--r--backends/graphics/opengl/opengl-sys.h13
-rw-r--r--backends/graphics/opengl/pipeline.cpp49
-rw-r--r--backends/graphics/opengl/pipeline.h52
-rw-r--r--backends/graphics/opengl/texture.cpp17
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