ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

opengls.cpp

Go to the documentation of this file.
00001 /* ResidualVM - A 3D game interpreter
00002  *
00003  * ResidualVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the AUTHORS
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #include "engines/stark/gfx/opengls.h"
00024 
00025 #include "common/system.h"
00026 
00027 #include "math/matrix4.h"
00028 
00029 #if defined(USE_GLES2) || defined(USE_OPENGL_SHADERS)
00030 
00031 #include "engines/stark/gfx/openglsactor.h"
00032 #include "engines/stark/gfx/openglsprop.h"
00033 #include "engines/stark/gfx/openglssurface.h"
00034 #include "engines/stark/gfx/openglsfade.h"
00035 #include "engines/stark/gfx/opengltexture.h"
00036 
00037 #include "graphics/pixelbuffer.h"
00038 #include "graphics/surface.h"
00039 #include "graphics/opengl/shader.h"
00040 
00041 namespace Stark {
00042 namespace Gfx {
00043 
00044 static const GLfloat surfaceVertices[] = {
00045     // XS   YT
00046     0.0f, 0.0f,
00047     1.0f, 0.0f,
00048     0.0f, 1.0f,
00049     1.0f, 1.0f,
00050 };
00051 
00052 static const GLfloat fadeVertices[] = {
00053     // XS   YT
00054     -1.0f,  1.0f,
00055      1.0f,  1.0f,
00056     -1.0f, -1.0f,
00057      1.0f, -1.0f,
00058 };
00059 
00060 OpenGLSDriver::OpenGLSDriver() :
00061     _surfaceShader(nullptr),
00062     _actorShader(nullptr),
00063     _fadeShader(nullptr),
00064     _shadowShader(nullptr),
00065     _surfaceVBO(0),
00066     _fadeVBO(0) {
00067 }
00068 
00069 OpenGLSDriver::~OpenGLSDriver() {
00070     OpenGL::Shader::freeBuffer(_surfaceVBO);
00071     OpenGL::Shader::freeBuffer(_fadeVBO);
00072     delete _surfaceShader;
00073     delete _actorShader;
00074     delete _fadeShader;
00075     delete _shadowShader;
00076 }
00077 
00078 void OpenGLSDriver::init() {
00079     computeScreenViewport();
00080 
00081     static const char* attributes[] = { "position", "texcoord", nullptr };
00082     _surfaceShader = OpenGL::Shader::fromFiles("stark_surface", attributes);
00083     _surfaceVBO = OpenGL::Shader::createBuffer(GL_ARRAY_BUFFER, sizeof(surfaceVertices), surfaceVertices);
00084     _surfaceShader->enableVertexAttribute("position", _surfaceVBO, 2, GL_FLOAT, GL_TRUE, 2 * sizeof(float), 0);
00085     _surfaceShader->enableVertexAttribute("texcoord", _surfaceVBO, 2, GL_FLOAT, GL_TRUE, 2 * sizeof(float), 0);
00086 
00087     static const char* actorAttributes[] = { "position1", "position2", "bone1", "bone2", "boneWeight", "normal", "texcoord", nullptr };
00088     _actorShader = OpenGL::Shader::fromFiles("stark_actor", actorAttributes);
00089 
00090     static const char* shadowAttributes[] = { "position1", "position2", "bone1", "bone2", "boneWeight", nullptr };
00091     _shadowShader = OpenGL::Shader::fromFiles("stark_shadow", shadowAttributes);
00092 
00093     static const char* fadeAttributes[] = { "position", nullptr };
00094     _fadeShader = OpenGL::Shader::fromFiles("stark_fade", fadeAttributes);
00095     _fadeVBO = OpenGL::Shader::createBuffer(GL_ARRAY_BUFFER, sizeof(fadeVertices), fadeVertices);
00096     _fadeShader->enableVertexAttribute("position", _fadeVBO, 2, GL_FLOAT, GL_TRUE, 2 * sizeof(float), 0);
00097 }
00098 
00099 void OpenGLSDriver::setScreenViewport(bool noScaling) {
00100     if (noScaling) {
00101         _viewport = Common::Rect(g_system->getWidth(), g_system->getHeight());
00102         _unscaledViewport = _viewport;
00103     } else {
00104         _viewport = _screenViewport;
00105         _unscaledViewport = Common::Rect(kOriginalWidth, kOriginalHeight);
00106     }
00107 
00108     glViewport(_viewport.left, _viewport.top, _viewport.width(), _viewport.height());
00109 }
00110 
00111 void OpenGLSDriver::setViewport(const Common::Rect &rect) {
00112     _viewport = Common::Rect(
00113             _screenViewport.width() * rect.width() / kOriginalWidth,
00114             _screenViewport.height() * rect.height() / kOriginalHeight
00115             );
00116 
00117     _viewport.translate(
00118             _screenViewport.left + _screenViewport.width() * rect.left / kOriginalWidth,
00119             _screenViewport.top + _screenViewport.height() * rect.top / kOriginalHeight
00120             );
00121 
00122     _unscaledViewport = rect;
00123 
00124     glViewport(_viewport.left, g_system->getHeight() - _viewport.bottom, _viewport.width(), _viewport.height());
00125 }
00126 
00127 void OpenGLSDriver::clearScreen() {
00128     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
00129 }
00130 
00131 void OpenGLSDriver::flipBuffer() {
00132     g_system->updateScreen();
00133 }
00134 
00135 Texture *OpenGLSDriver::createTexture(const Graphics::Surface *surface, const byte *palette) {
00136     OpenGlTexture *texture = new OpenGlTexture();
00137 
00138     if (surface) {
00139         texture->update(surface, palette);
00140     }
00141 
00142     return texture;
00143 }
00144 
00145 VisualActor *OpenGLSDriver::createActorRenderer() {
00146     return new OpenGLSActorRenderer(this);
00147 }
00148 
00149 VisualProp *OpenGLSDriver::createPropRenderer() {
00150     return new OpenGLSPropRenderer(this);
00151 }
00152 
00153 SurfaceRenderer *OpenGLSDriver::createSurfaceRenderer() {
00154     return new OpenGLSSurfaceRenderer(this);
00155 }
00156 
00157 FadeRenderer *OpenGLSDriver::createFadeRenderer() {
00158     return new OpenGLSFadeRenderer(this);
00159 }
00160 
00161 void OpenGLSDriver::start2DMode() {
00162     // Enable alpha blending
00163     glEnable(GL_BLEND);
00164     //glBlendEquation(GL_FUNC_ADD); // It's the default
00165 
00166     // This blend mode prevents color fringes due to filtering.
00167     // It requires the textures to have their color values pre-multiplied
00168     // with their alpha value. This is the "Premultiplied Alpha" technique.
00169     glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
00170 
00171     glDisable(GL_DEPTH_TEST);
00172     glDepthMask(GL_FALSE);
00173 }
00174 
00175 void OpenGLSDriver::end2DMode() {
00176     // Disable alpha blending
00177     glDisable(GL_BLEND);
00178 
00179     glEnable(GL_DEPTH_TEST);
00180     glDepthMask(GL_TRUE);
00181 }
00182 
00183 void OpenGLSDriver::set3DMode() {
00184     glEnable(GL_DEPTH_TEST);
00185     glDepthFunc(GL_LESS);
00186 
00187     // Blending and stencil test are only used in rendering shadows
00188     // They are manually enabled and disabled there
00189     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00190     glStencilFunc(GL_EQUAL, 0, 0xFF);
00191     glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
00192 }
00193 
00194 Common::Rect OpenGLSDriver::getViewport() const {
00195     return _viewport;
00196 }
00197 
00198 Common::Rect OpenGLSDriver::getUnscaledViewport() const {
00199     return _unscaledViewport;
00200 }
00201 
00202 OpenGL::Shader *OpenGLSDriver::createActorShaderInstance() {
00203     return _actorShader->clone();
00204 }
00205 
00206 OpenGL::Shader *OpenGLSDriver::createSurfaceShaderInstance() {
00207     return _surfaceShader->clone();
00208 }
00209 
00210 OpenGL::Shader *OpenGLSDriver::createFadeShaderInstance() {
00211     return _fadeShader->clone();
00212 }
00213 
00214 OpenGL::Shader *OpenGLSDriver::createShadowShaderInstance() {
00215     return _shadowShader->clone();
00216 }
00217 
00218 Graphics::Surface *OpenGLSDriver::getViewportScreenshot() const {
00219     Graphics::Surface *s = new Graphics::Surface();
00220     s->create(_viewport.width(), _viewport.height(), getRGBAPixelFormat());
00221 
00222     glReadPixels(_viewport.left, g_system->getHeight() - _viewport.bottom, _viewport.width(), _viewport.height(),
00223                  GL_RGBA, GL_UNSIGNED_BYTE, s->getPixels());
00224 
00225     flipVertical(s);
00226 
00227     return s;
00228 }
00229 
00230 } // End of namespace Gfx
00231 } // End of namespace Stark
00232 
00233 #endif // defined(USE_GLES2) || defined(USE_OPENGL_SHADERS)


Generated on Sat Apr 20 2019 05:03:21 for ResidualVM by doxygen 1.7.1
curved edge   curved edge