Skip to content

Commit

Permalink
[Framebuffer] Migrated.
Browse files Browse the repository at this point in the history
  • Loading branch information
Unarelith committed Oct 29, 2023
1 parent 12474af commit c64d75f
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 138 deletions.
199 changes: 69 additions & 130 deletions source/client/graphics/Framebuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,61 +25,11 @@
* =====================================================================================
*/
#include <gk/core/Exception.hpp>
#include <gk/gl/GLCheck.hpp>

#include "Framebuffer.hpp"
#include "GameConfig.hpp"

Framebuffer::Framebuffer(u16 width, u16 height) {
init(width, height);
}

Framebuffer::~Framebuffer() {
clear();
}

void Framebuffer::init(u16 width, u16 height) {
#ifdef OM_NOT_IMPLEMENTED_GL_FRAMEBUFFER
if (m_id)
clear();

// Create and bind our framebuffer
glCheck(glGenFramebuffers(1, &m_id));
bind(this);

// Create a texture to store the colors
glCheck(glGenTextures(1, &m_colorTexID));
glCheck(glBindTexture(GL_TEXTURE_2D, m_colorTexID));
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_colorTexID, 0));

// Create a renderbuffer
// 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));

// Create a texture to store depth data
glCheck(glGenTextures(1, &m_depthTexID));
glCheck(glBindTexture(GL_TEXTURE_2D, m_depthTexID));
glCheck(glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, width, height, 0, GL_DEPTH_COMPONENT, 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_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_depthTexID, 0));

if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
throw EXCEPTION("Framebuffer is not complete");

bind(nullptr);

Framebuffer::Framebuffer() {
float quad[24] = {
-1.0f, 1.0f, 0.0f, 1.0f,
-1.0f, -1.0f, 0.0f, 0.0f,
Expand All @@ -90,104 +40,93 @@ void Framebuffer::init(u16 width, u16 height) {
1.0f, 1.0f, 1.0f, 1.0f
};

VertexBuffer::bind(&m_vbo);
m_vbo.setData(sizeof(quad), &quad, GL_STATIC_DRAW);
VertexBuffer::bind(nullptr);
#endif // OM_NOT_IMPLEMENTED_GL_FRAMEBUFFER
}
m_vbo.layout().begin()
.add(bgfx::Attrib::Position, 2, bgfx::AttribType::Float)
.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float)
.end();

void Framebuffer::clear() {
#ifdef OM_NOT_IMPLEMENTED_GL_FRAMEBUFFER
if (m_id) {
glCheck(glDeleteFramebuffers(1, &m_id));
m_id = 0;
}

if (m_colorTexID) {
glCheck(glDeleteTextures(1, &m_colorTexID));
m_colorTexID = 0;
}

if (m_depthTexID) {
glCheck(glDeleteTextures(1, &m_depthTexID));
m_depthTexID = 0;
}

if (m_rbo) {
glCheck(glDeleteRenderbuffers(1, &m_rbo));
m_rbo = 0;
}
#endif // OM_NOT_IMPLEMENTED_GL_FRAMEBUFFER
}
m_vbo.init(quad, sizeof(quad));

void Framebuffer::loadShader(const std::string &name) {
#ifdef OM_NOT_IMPLEMENTED_GL_FRAMEBUFFER
m_shader.createProgram();
m_shader.addShader(GL_VERTEX_SHADER, "resources/shaders/" + name + ".v.glsl");
m_shader.addShader(GL_FRAGMENT_SHADER, "resources/shaders/" + name + ".f.glsl");
m_shader.linkProgram();

m_shader.setUniform("screenTexture", 0);
m_shader.setUniform("depthTexture", 1);
#endif // OM_NOT_IMPLEMENTED_GL_FRAMEBUFFER
m_colorTextureSampler = bgfx::createUniform("s_colorTexture", bgfx::UniformType::Sampler);
m_depthTextureSampler = bgfx::createUniform("s_depthTexture", bgfx::UniformType::Sampler);

m_effectTypeUniform = bgfx::createUniform("u_effectType", bgfx::UniformType::Vec4);
m_depthFogColorUniform = bgfx::createUniform("u_depthFogColor", bgfx::UniformType::Vec4);
}

void Framebuffer::begin() const {
#ifdef OM_NOT_IMPLEMENTED_GL_FRAMEBUFFER
bind(this);
glCheck(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
glCheck(glEnable(GL_DEPTH_TEST));
#endif // OM_NOT_IMPLEMENTED_GL_FRAMEBUFFER
Framebuffer::Framebuffer(u16 width, u16 height) : Framebuffer() {
init(width, height);
}

void Framebuffer::end() const {
#ifdef OM_NOT_IMPLEMENTED_GL_FRAMEBUFFER
bind(nullptr);
glClear(GL_COLOR_BUFFER_BIT);
Framebuffer::~Framebuffer() {
free();
}

glDisable(GL_DEPTH_TEST);
void Framebuffer::init(u16 width, u16 height) {
const uint64_t colorTextureFlags = BGFX_TEXTURE_RT | BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP;
const uint64_t depthTextureFlags = BGFX_TEXTURE_RT;

if (m_colorTexID != 0) {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, m_colorTexID);
}
m_textures[0] = bgfx::createTexture2D(width, height, false, 1, bgfx::TextureFormat::BGRA8, colorTextureFlags);
m_textures[1] = bgfx::createTexture2D(width, height, false, 1, bgfx::TextureFormat::D24S8, depthTextureFlags);

if (m_depthTexID != 0) {
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, m_depthTexID);
}
if (!bgfx::isValid(m_textures[0]))
throw EXCEPTION("Framebuffer error: Unable to create color texture with format BGRA8");
if (!bgfx::isValid(m_textures[1]))
throw EXCEPTION("Framebuffer error: Unable to create depth texture with format D24S8");

m_shader.setUniform("u_effectType", GameConfig::currentScreenEffect);
m_shader.setUniform("u_fogDepth", GameConfig::fogDepth);
m_shader.setUniform("u_fogColor", GameConfig::fogColor);
m_handle = bgfx::createFrameBuffer(2, m_textures, true);

VertexBuffer::bind(&m_vbo);
if (!bgfx::isValid(m_handle))
throw EXCEPTION("Failed to create framebuffer");

glCheck(glEnableVertexAttribArray(0));
glCheck(glEnableVertexAttribArray(1));
bgfx::setViewRect(view, 0, 0, width, height);
bgfx::setViewClear(view, BGFX_CLEAR_COLOR);
}

glCheck(glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(0 * sizeof(float))));
glCheck(glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float))));
void Framebuffer::free() {
if (bgfx::isValid(m_handle))
bgfx::destroy(m_handle);

glCheck(glDrawArrays(GL_TRIANGLES, 0, 6));
if (bgfx::isValid(m_depthFogColorUniform))
bgfx::destroy(m_depthFogColorUniform);

glCheck(glDisableVertexAttribArray(1));
glCheck(glDisableVertexAttribArray(0));
if (bgfx::isValid(m_effectTypeUniform))
bgfx::destroy(m_effectTypeUniform);

VertexBuffer::bind(nullptr);
if (bgfx::isValid(m_depthTextureSampler))
bgfx::destroy(m_depthTextureSampler);

glCheck(glActiveTexture(GL_TEXTURE0));
if (bgfx::isValid(m_colorTextureSampler))
bgfx::destroy(m_colorTextureSampler);
}

glCheck(glEnable(GL_DEPTH_TEST));
#endif // OM_NOT_IMPLEMENTED_GL_FRAMEBUFFER
void Framebuffer::loadShader(const std::string &name) {
m_shader.loadFromFile(name);
}

void Framebuffer::bind(const Framebuffer *framebuffer) {
#ifdef OM_NOT_IMPLEMENTED_GL_FRAMEBUFFER
if (framebuffer)
glCheck(glBindFramebuffer(GL_FRAMEBUFFER, framebuffer->m_id));
else
glCheck(glBindFramebuffer(GL_FRAMEBUFFER, 0));
#endif // OM_NOT_IMPLEMENTED_GL_FRAMEBUFFER
void Framebuffer::begin() const {
bgfx::setViewFrameBuffer(0, m_handle);
bgfx::setViewFrameBuffer(1, m_handle);
}

void Framebuffer::end() const {
bgfx::setTexture(0, m_colorTextureSampler, m_textures[0]);
bgfx::setTexture(1, m_depthTextureSampler, m_textures[1]);

float effectType[4] = {(float)GameConfig::currentScreenEffect, GameConfig::fogDepth, 0.f, 0.f};
bgfx::setUniform(m_effectTypeUniform, effectType);

float fogColor[4] = {
GameConfig::fogColor.r,
GameConfig::fogColor.g,
GameConfig::fogColor.b,
GameConfig::fogColor.a,
};
bgfx::setUniform(m_depthFogColorUniform, fogColor);

m_vbo.enable();

bgfx::setState(BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A);

bgfx::submit(view, m_shader.program());
}
19 changes: 11 additions & 8 deletions source/client/graphics/Framebuffer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,35 +28,38 @@
#define FRAMEBUFFER_HPP_

#include "Shader.hpp"
#include "Texture.hpp"
#include "VertexBuffer.hpp"

class Framebuffer : public gk::NonCopyable {
public:
Framebuffer();
Framebuffer(u16 width, u16 height);
Framebuffer(Framebuffer &&) = default;
~Framebuffer();

Framebuffer &operator=(Framebuffer &&) = default;

void init(u16 width, u16 height);
void clear();
void free();

void loadShader(const std::string &name);

void begin() const;
void end() const;

static void bind(const Framebuffer *framebuffer);
static const u32 view = 2;

private:
#ifdef OM_NOT_IMPLEMENTED_GL_FRAMEBUFFER
GLuint m_id = 0;
bgfx::UniformHandle m_colorTextureSampler = BGFX_INVALID_HANDLE;
bgfx::UniformHandle m_depthTextureSampler = BGFX_INVALID_HANDLE;

GLuint m_colorTexID = 0;
GLuint m_depthTexID = 0;
bgfx::UniformHandle m_effectTypeUniform = BGFX_INVALID_HANDLE;
bgfx::UniformHandle m_depthFogColorUniform = BGFX_INVALID_HANDLE;

GLuint m_rbo = 0;
#endif // OM_NOT_IMPLEMENTED_GL_FRAMEBUFFER
bgfx::TextureHandle m_textures[2] = {BGFX_INVALID_HANDLE, BGFX_STATE_BLEND_INV_SRC_ALPHA};

bgfx::FrameBufferHandle m_handle = BGFX_INVALID_HANDLE;

Shader m_shader;
VertexBuffer m_vbo;
Expand Down

0 comments on commit c64d75f

Please sign in to comment.