aboutsummaryrefslogtreecommitdiff
path: root/backends/graphics/opengl
diff options
context:
space:
mode:
authorJohannes Schickel2016-01-04 06:41:10 +0100
committerJohannes Schickel2016-03-16 20:29:26 +0100
commitf5f1b6eba0d409abcda2a3c037a177d6f6e41a2e (patch)
tree7185022bb128795f3035de8925d04d98784a1afa /backends/graphics/opengl
parent08553a09cfa2110d56b200bf6c69d01d5adbc6bb (diff)
downloadscummvm-rg350-f5f1b6eba0d409abcda2a3c037a177d6f6e41a2e.tar.gz
scummvm-rg350-f5f1b6eba0d409abcda2a3c037a177d6f6e41a2e.tar.bz2
scummvm-rg350-f5f1b6eba0d409abcda2a3c037a177d6f6e41a2e.zip
OPENGL: Introduce pipeline abstraction to cleanup code.
Diffstat (limited to 'backends/graphics/opengl')
-rw-r--r--backends/graphics/opengl/context.cpp92
-rw-r--r--backends/graphics/opengl/opengl-graphics.cpp34
-rw-r--r--backends/graphics/opengl/opengl-graphics.h6
-rw-r--r--backends/graphics/opengl/opengl-sys.h22
-rw-r--r--backends/graphics/opengl/pipeline.cpp76
-rw-r--r--backends/graphics/opengl/pipeline.h92
-rw-r--r--backends/graphics/opengl/texture.cpp7
7 files changed, 226 insertions, 103 deletions
diff --git a/backends/graphics/opengl/context.cpp b/backends/graphics/opengl/context.cpp
index 89f0ed7910..7402e79ea5 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 1ec40015af..0a9b040f83 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 40605f0259..95ba4e7377 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 a584259abe..f68897ba58 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 0000000000..362f15a36b
--- /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 0000000000..e12390bcce
--- /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 f98bf8be06..61e8dc37b3 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.