diff --git a/source/client/graphics/Framebuffer.cpp b/source/client/graphics/Framebuffer.cpp index 842d59c8..e77e6d5a 100644 --- a/source/client/graphics/Framebuffer.cpp +++ b/source/client/graphics/Framebuffer.cpp @@ -25,61 +25,11 @@ * ===================================================================================== */ #include -#include #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, @@ -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()); +} diff --git a/source/client/graphics/Framebuffer.hpp b/source/client/graphics/Framebuffer.hpp index 6fcbeccb..99cc76a9 100644 --- a/source/client/graphics/Framebuffer.hpp +++ b/source/client/graphics/Framebuffer.hpp @@ -28,10 +28,12 @@ #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(); @@ -39,24 +41,25 @@ class Framebuffer : public gk::NonCopyable { 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;