[Framebuffer] Added. [GameState] Now using a framebuffer to render the scene and apply effects.

This commit is contained in:
Quentin Bazin 2020-06-29 23:18:24 +02:00
parent abbf55fd21
commit 608b53730e
7 changed files with 202 additions and 2 deletions

2
external/gamekit vendored

@ -1 +1 @@
Subproject commit 4e4317882c53b0b67ed4918f4cf5f11335b4fb69
Subproject commit 29f76f71e938234c110794008854eea23582bef2

View File

@ -0,0 +1,12 @@
#version 120
varying vec2 v_texCoord;
varying vec2 v_coord2d;
uniform sampler2D screenTexture;
void main() {
gl_FragColor = texture2D(screenTexture, v_texCoord);
/* gl_FragColor = vec4(vec3(1.0 - texture2D(screenTexture, v_texCoord)), 1.0); */
}

View File

@ -0,0 +1,15 @@
#version 120
attribute vec2 coord2d;
attribute vec2 texCoord;
varying vec2 v_texCoord;
varying vec2 v_coord2d;
void main() {
v_texCoord = texCoord;
v_coord2d = coord2d;
gl_Position = vec4(coord2d.x, coord2d.y, 0.0, 1.0);
}

View File

@ -0,0 +1,75 @@
/*
* =====================================================================================
*
* OpenMiner
*
* Copyright (C) 2018-2020 Unarelith, Quentin Bazin <openminer@unarelith.net>
* Copyright (C) 2019-2020 the OpenMiner contributors (see CONTRIBUTORS.md)
*
* This file is part of OpenMiner.
*
* OpenMiner is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* OpenMiner 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with OpenMiner; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* =====================================================================================
*/
#include <gk/core/Exception.hpp>
#include <gk/gl/GLCheck.hpp>
#include "Framebuffer.hpp"
Framebuffer::Framebuffer(u16 width, u16 height) {
glCheck(glGenFramebuffers(1, &m_id));
bind(this);
glCheck(glGenTextures(1, &m_texid));
glCheck(glBindTexture(GL_TEXTURE_2D, m_texid));
glCheck(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr));
glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
glCheck(glBindTexture(GL_TEXTURE_2D, 0));
glCheck(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texid, 0));
glCheck(glGenRenderbuffers(1, &m_rbo));
glCheck(glBindRenderbuffer(GL_RENDERBUFFER, m_rbo));
glCheck(glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height));
glCheck(glBindRenderbuffer(GL_RENDERBUFFER, 0));
glCheck(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_rbo));
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
throw EXCEPTION("Framebuffer is not complete");
bind(nullptr);
}
Framebuffer::~Framebuffer() {
if (m_id)
glCheck(glDeleteFramebuffers(1, &m_id));
if (m_texid)
glCheck(glDeleteTextures(1, &m_texid));
if (m_rbo)
glCheck(glDeleteRenderbuffers(1, &m_rbo));
}
void Framebuffer::bind(const Framebuffer *framebuffer) {
if (framebuffer)
glCheck(glBindFramebuffer(GL_FRAMEBUFFER, framebuffer->m_id));
else
glCheck(glBindFramebuffer(GL_FRAMEBUFFER, 0));
}

View File

@ -0,0 +1,49 @@
/*
* =====================================================================================
*
* OpenMiner
*
* Copyright (C) 2018-2020 Unarelith, Quentin Bazin <openminer@unarelith.net>
* Copyright (C) 2019-2020 the OpenMiner contributors (see CONTRIBUTORS.md)
*
* This file is part of OpenMiner.
*
* OpenMiner is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* OpenMiner 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with OpenMiner; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* =====================================================================================
*/
#ifndef FRAMEBUFFER_HPP_
#define FRAMEBUFFER_HPP_
#include <gk/core/IntTypes.hpp>
#include <gk/gl/OpenGL.hpp>
class Framebuffer {
public:
Framebuffer(u16 width, u16 height);
~Framebuffer();
GLuint texid() const { return m_texid; }
static void bind(const Framebuffer *framebuffer);
private:
GLuint m_id = 0;
GLuint m_texid = 0;
GLuint m_rbo = 0;
};
#endif // FRAMEBUFFER_HPP_

View File

@ -182,6 +182,24 @@ void GameState::initShaders() {
m_shader.addShader(GL_FRAGMENT_SHADER, "resources/shaders/game.f.glsl");
m_shader.linkProgram();
m_screenShader.createProgram();
m_screenShader.addShader(GL_VERTEX_SHADER, "resources/shaders/screen.v.glsl");
m_screenShader.addShader(GL_FRAGMENT_SHADER, "resources/shaders/screen.f.glsl");
m_screenShader.linkProgram();
float quad[24] = {
-1.0f, 1.0f, 0.0f, 1.0f,
-1.0f, -1.0f, 0.0f, 0.0f,
1.0f, -1.0f, 1.0f, 0.0f,
-1.0f, 1.0f, 0.0f, 1.0f,
1.0f, -1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 1.0f, 1.0f
};
gk::VertexBuffer::bind(&m_screenQuadVBO);
m_screenQuadVBO.setData(sizeof(quad), &quad, GL_STATIC_DRAW);
gk::VertexBuffer::bind(nullptr);
}
void GameState::onGuiScaleChanged(const GuiScaleChangedEvent &event) {
@ -194,8 +212,12 @@ void GameState::draw(gk::RenderTarget &target, gk::RenderStates states) const {
// m_shader.setUniform("u_time", gk::GameClock::getInstance().getTicks());
// gk::Shader::bind(nullptr);
states.shader = &m_shader;
Framebuffer::bind(&m_fbo);
// glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
states.shader = &m_shader;
target.setView(m_camera);
target.draw(m_world, states);
@ -203,6 +225,28 @@ void GameState::draw(gk::RenderTarget &target, gk::RenderStates states) const {
if (it.second.dimension() == m_player.dimension())
target.draw(it.second, states);
Framebuffer::bind(nullptr);
// glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
glBindTexture(GL_TEXTURE_2D, m_fbo.texid());
gk::Shader::bind(&m_screenShader);
gk::VertexBuffer::bind(&m_screenQuadVBO);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
m_screenQuadVBO.setAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(0 * sizeof(float)));
m_screenQuadVBO.setAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float)));
glDrawArrays(GL_TRIANGLES, 0, 6);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(0);
gk::VertexBuffer::bind(nullptr);
gk::Shader::bind(nullptr);
states.shader = &m_shader;
glEnable(GL_DEPTH_TEST);
target.draw(m_hud, states);
}

View File

@ -38,6 +38,7 @@
#include "ClientPlayer.hpp"
#include "ClientWorld.hpp"
#include "Config.hpp"
#include "Framebuffer.hpp"
#include "HUD.hpp"
#include "KeyboardHandler.hpp"
#include "PlayerBox.hpp"
@ -78,6 +79,10 @@ class GameState : public gk::ApplicationState {
gk::Shader m_shader;
gk::Shader m_screenShader;
Framebuffer m_fbo{Config::screenWidth, Config::screenHeight};
gk::VertexBuffer m_screenQuadVBO;
gk::Camera m_camera{70.0f, DIST_NEAR, DIST_FAR};
ClientPlayer m_player{m_camera};