OPENGL: Introduce abstraction for framebuffer.
This allows us to use various framebuffer settings easily. Now the GPU accelerated CLUT8 surface implementation does not need to query former framebuffer state anymore.
This commit is contained in:
parent
5498982a37
commit
c4e65732be
9 changed files with 488 additions and 132 deletions
251
backends/graphics/opengl/framebuffer.cpp
Normal file
251
backends/graphics/opengl/framebuffer.cpp
Normal file
|
@ -0,0 +1,251 @@
|
|||
/* 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/framebuffer.h"
|
||||
#include "backends/graphics/opengl/texture.h"
|
||||
|
||||
namespace OpenGL {
|
||||
|
||||
Framebuffer::Framebuffer()
|
||||
: _viewport(), _projectionMatrix(), _isActive(false), _clearColor(),
|
||||
_blendState(false), _scissorTestState(false), _scissorBox() {
|
||||
}
|
||||
|
||||
void Framebuffer::activate() {
|
||||
_isActive = true;
|
||||
|
||||
applyViewport();
|
||||
applyClearColor();
|
||||
applyBlendState();
|
||||
applyScissorTestState();
|
||||
applyScissorBox();
|
||||
}
|
||||
|
||||
void Framebuffer::deactivate() {
|
||||
_isActive = false;
|
||||
}
|
||||
|
||||
void Framebuffer::setClearColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
|
||||
_clearColor[0] = r;
|
||||
_clearColor[1] = g;
|
||||
_clearColor[2] = b;
|
||||
_clearColor[3] = a;
|
||||
|
||||
// Directly apply changes when we are active.
|
||||
if (isActive()) {
|
||||
applyClearColor();
|
||||
}
|
||||
}
|
||||
|
||||
void Framebuffer::enableBlend(bool enable) {
|
||||
_blendState = enable;
|
||||
|
||||
// Directly apply changes when we are active.
|
||||
if (isActive()) {
|
||||
applyBlendState();
|
||||
}
|
||||
}
|
||||
|
||||
void Framebuffer::enableScissorTest(bool enable) {
|
||||
_scissorTestState = enable;
|
||||
|
||||
// Directly apply changes when we are active.
|
||||
if (isActive()) {
|
||||
applyScissorTestState();
|
||||
}
|
||||
}
|
||||
|
||||
void Framebuffer::setScissorBox(GLint x, GLint y, GLsizei w, GLsizei h) {
|
||||
_scissorBox[0] = x;
|
||||
_scissorBox[1] = y;
|
||||
_scissorBox[2] = w;
|
||||
_scissorBox[3] = h;
|
||||
|
||||
// Directly apply changes when we are active.
|
||||
if (isActive()) {
|
||||
applyScissorBox();
|
||||
}
|
||||
}
|
||||
|
||||
void Framebuffer::applyViewport() {
|
||||
GL_CALL(glViewport(_viewport[0], _viewport[1], _viewport[2], _viewport[3]));
|
||||
}
|
||||
|
||||
void Framebuffer::applyClearColor() {
|
||||
GL_CALL(glClearColor(_clearColor[0], _clearColor[1], _clearColor[2], _clearColor[3]));
|
||||
}
|
||||
|
||||
void Framebuffer::applyBlendState() {
|
||||
if (_blendState) {
|
||||
GL_CALL(glEnable(GL_BLEND));
|
||||
} else {
|
||||
GL_CALL(glDisable(GL_BLEND));
|
||||
}
|
||||
}
|
||||
|
||||
void Framebuffer::applyScissorTestState() {
|
||||
if (_scissorTestState) {
|
||||
GL_CALL(glEnable(GL_SCISSOR_TEST));
|
||||
} else {
|
||||
GL_CALL(glDisable(GL_SCISSOR_TEST));
|
||||
}
|
||||
}
|
||||
|
||||
void Framebuffer::applyScissorBox() {
|
||||
GL_CALL(glScissor(_scissorBox[0], _scissorBox[1], _scissorBox[2], _scissorBox[3]));
|
||||
}
|
||||
|
||||
//
|
||||
// Backbuffer implementation
|
||||
//
|
||||
|
||||
void Backbuffer::activate() {
|
||||
Framebuffer::activate();
|
||||
|
||||
#if !USE_FORCED_GLES
|
||||
if (g_context.framebufferObjectSupported) {
|
||||
GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void Backbuffer::setDimensions(uint width, uint height) {
|
||||
// Set viewport dimensions.
|
||||
_viewport[0] = 0;
|
||||
_viewport[1] = 0;
|
||||
_viewport[2] = width;
|
||||
_viewport[3] = height;
|
||||
|
||||
// Setup orthogonal projection matrix.
|
||||
_projectionMatrix[ 0] = 2.0f / width;
|
||||
_projectionMatrix[ 1] = 0.0f;
|
||||
_projectionMatrix[ 2] = 0.0f;
|
||||
_projectionMatrix[ 3] = 0.0f;
|
||||
|
||||
_projectionMatrix[ 4] = 0.0f;
|
||||
_projectionMatrix[ 5] = -2.0f / height;
|
||||
_projectionMatrix[ 6] = 0.0f;
|
||||
_projectionMatrix[ 7] = 0.0f;
|
||||
|
||||
_projectionMatrix[ 8] = 0.0f;
|
||||
_projectionMatrix[ 9] = 0.0f;
|
||||
_projectionMatrix[10] = 0.0f;
|
||||
_projectionMatrix[11] = 0.0f;
|
||||
|
||||
_projectionMatrix[12] = -1.0f;
|
||||
_projectionMatrix[13] = 1.0f;
|
||||
_projectionMatrix[14] = 0.0f;
|
||||
_projectionMatrix[15] = 1.0f;
|
||||
|
||||
// Directly apply changes when we are active.
|
||||
if (isActive()) {
|
||||
applyViewport();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Render to texture target implementation
|
||||
//
|
||||
|
||||
#if !USE_FORCED_GLES
|
||||
TextureTarget::TextureTarget()
|
||||
: _texture(new GLTexture(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE)), _glFBO(0), _needUpdate(true) {
|
||||
}
|
||||
|
||||
TextureTarget::~TextureTarget() {
|
||||
delete _texture;
|
||||
GL_CALL_SAFE(glDeleteFramebuffers, (1, &_glFBO));
|
||||
}
|
||||
|
||||
void TextureTarget::activate() {
|
||||
Framebuffer::activate();
|
||||
|
||||
// Allocate framebuffer object if necessary.
|
||||
if (!_glFBO) {
|
||||
GL_CALL(glGenFramebuffers(1, &_glFBO));
|
||||
_needUpdate = true;
|
||||
}
|
||||
|
||||
// Attach destination texture to FBO.
|
||||
GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, _glFBO));
|
||||
|
||||
// If required attach texture to FBO.
|
||||
if (_needUpdate) {
|
||||
GL_CALL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _texture->getGLTexture(), 0));
|
||||
_needUpdate = false;
|
||||
}
|
||||
}
|
||||
|
||||
void TextureTarget::destroy() {
|
||||
GL_CALL(glDeleteFramebuffers(1, &_glFBO));
|
||||
_glFBO = 0;
|
||||
|
||||
_texture->destroy();
|
||||
}
|
||||
|
||||
void TextureTarget::create() {
|
||||
_texture->create();
|
||||
|
||||
_needUpdate = true;
|
||||
}
|
||||
|
||||
void TextureTarget::setSize(uint width, uint height) {
|
||||
_texture->setSize(width, height);
|
||||
|
||||
const uint texWidth = _texture->getWidth();
|
||||
const uint texHeight = _texture->getHeight();
|
||||
|
||||
// Set viewport dimensions.
|
||||
_viewport[0] = 0;
|
||||
_viewport[1] = 0;
|
||||
_viewport[2] = texWidth;
|
||||
_viewport[3] = texHeight;
|
||||
|
||||
// Setup orthogonal projection matrix.
|
||||
_projectionMatrix[ 0] = 2.0f / texWidth;
|
||||
_projectionMatrix[ 1] = 0.0f;
|
||||
_projectionMatrix[ 2] = 0.0f;
|
||||
_projectionMatrix[ 3] = 0.0f;
|
||||
|
||||
_projectionMatrix[ 4] = 0.0f;
|
||||
_projectionMatrix[ 5] = 2.0f / texHeight;
|
||||
_projectionMatrix[ 6] = 0.0f;
|
||||
_projectionMatrix[ 7] = 0.0f;
|
||||
|
||||
_projectionMatrix[ 8] = 0.0f;
|
||||
_projectionMatrix[ 9] = 0.0f;
|
||||
_projectionMatrix[10] = 0.0f;
|
||||
_projectionMatrix[11] = 0.0f;
|
||||
|
||||
_projectionMatrix[12] = -1.0f;
|
||||
_projectionMatrix[13] = -1.0f;
|
||||
_projectionMatrix[14] = 0.0f;
|
||||
_projectionMatrix[15] = 1.0f;
|
||||
|
||||
// Directly apply changes when we are active.
|
||||
if (isActive()) {
|
||||
applyViewport();
|
||||
}
|
||||
}
|
||||
#endif // !USE_FORCED_GLES
|
||||
|
||||
} // End of namespace OpenGL
|
Loading…
Add table
Add a link
Reference in a new issue