frame buffer

main
Brett 2024-04-18 19:32:26 -04:00
parent 725b6963af
commit 42fbae4ba1
3 changed files with 141 additions and 15 deletions

View File

@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.25) cmake_minimum_required(VERSION 3.25)
set(BLT_GRAPHICS_VERSION 0.9.17) set(BLT_GRAPHICS_VERSION 0.10.1)
set(BLT_GRAPHICS_TEST_VERSION 0.0.1) set(BLT_GRAPHICS_TEST_VERSION 0.0.1)
project(BLT_WITH_GRAPHICS VERSION ${BLT_GRAPHICS_VERSION}) project(BLT_WITH_GRAPHICS VERSION ${BLT_GRAPHICS_VERSION})

View File

@ -42,6 +42,7 @@ namespace blt::gfx
GLuint rboID; GLuint rboID;
GLuint storage_type; GLuint storage_type;
blt::i32 width_, height_; blt::i32 width_, height_;
blt::i32 samples = 0;
public: public:
rbo_t(): rboID(0), storage_type(0), width_(-1), height_(-1) rbo_t(): rboID(0), storage_type(0), width_(-1), height_(-1)
{} {}
@ -52,14 +53,21 @@ namespace blt::gfx
void setStorage(GLuint storage_type, blt::i32 width, blt::i32 height); void setStorage(GLuint storage_type, blt::i32 width, blt::i32 height);
void setStorageMultiSampled(GLuint storage_type, blt::i32 width, blt::i32 height, blt::i32 samples);
void updateStorage(blt::i32 width, blt::i32 height); void updateStorage(blt::i32 width, blt::i32 height);
void updateStorageMultiSampled(blt::i32 width, blt::i32 height, blt::i32 samples); void updateStorageMultiSampled(blt::i32 width, blt::i32 height, blt::i32 samples);
void resize(blt::i32 width, blt::i32 height);
static void unbind(); static void unbind();
void destroy(); void destroy();
static rbo_t make_render_buffer(GLuint storage_type, blt::i32 width, blt::i32 height); static rbo_t make_render_buffer(GLuint storage_type, blt::i32 width, blt::i32 height);
static rbo_t make_render_buffer(GLuint storage_type, blt::i32 width, blt::i32 height, blt::i32 samples);
}; };
class fbo_t class fbo_t
@ -99,18 +107,42 @@ namespace blt::gfx
// this function takes ownership of the render buffer // this function takes ownership of the render buffer
void attachRenderBuffer(rbo_t rbo, attachment_t attachment); void attachRenderBuffer(rbo_t rbo, attachment_t attachment);
void blitTexture(const fbo_t& draw, blt::i32 srcX_off = 0, blt::i32 srcY_off = 0, blt::i32 destX_off = 0, blt::i32 destY_off = 0, GLuint filter = GL_NEAREST) const; void blitTexture(const fbo_t& draw, blt::i32 srcX_off = 0, blt::i32 srcY_off = 0, blt::i32 destX_off = 0, blt::i32 destY_off = 0,
GLuint filter = GL_NEAREST, attachment_t attachment_read = attachment_t::COLOR0,
attachment_t attachment_write = attachment_t::COLOR0) const;
void blitToScreen(blt::i32 width, blt::i32 height) const; void blitToScreen(blt::i32 width, blt::i32 height) const;
void blitDepth(const fbo_t& draw, blt::i32 srcX_off = 0, blt::i32 srcY_off = 0, blt::i32 destX_off = 0, blt::i32 destY_off = 0, GLuint filter = GL_NEAREST) const;
void blitDepth(const fbo_t& draw, blt::i32 srcX_off = 0, blt::i32 srcY_off = 0, blt::i32 destX_off = 0, blt::i32 destY_off = 0,
GLuint filter = GL_NEAREST) const;
void blitStencil(const fbo_t& draw, blt::i32 srcX_off = 0, blt::i32 srcY_off = 0, blt::i32 destX_off = 0, blt::i32 destY_off = 0,
GLuint filter = GL_NEAREST) const;
static bool validate(); static bool validate();
static void unbind(); static void unbind();
void destroy(); void destroy();
[[nodiscard]] i32 getHeight() const
{
return height_;
}
[[nodiscard]] i32 getWidth() const
{
return width_;
}
public: public:
static fbo_t make_render_texture(blt::i32 width, blt::i32 height); static fbo_t make_render_texture(blt::i32 width, blt::i32 height);
static fbo_t make_multisample_render_texture(blt::i32 width, blt::i32 height, blt::i32 samples);
static fbo_t make_render_target(blt::i32 width, blt::i32 height);
static fbo_t make_multisample_render_target(blt::i32 width, blt::i32 height, blt::i32 samples);
}; };
#undef C #undef C

View File

@ -43,13 +43,15 @@ namespace blt::gfx
{ {
width_ = width; width_ = width;
height_ = height; height_ = height;
samples = 0;
glRenderbufferStorage(GL_RENDERBUFFER, storage_type, width, height); glRenderbufferStorage(GL_RENDERBUFFER, storage_type, width, height);
} }
void rbo_t::updateStorageMultiSampled(blt::i32 width, blt::i32 height, blt::i32 samples) void rbo_t::updateStorageMultiSampled(blt::i32 width, blt::i32 height, blt::i32 s)
{ {
width_ = width; width_ = width;
height_ = height; height_ = height;
samples = s;
glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, storage_type, width, height); glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, storage_type, width, height);
} }
@ -59,6 +61,20 @@ namespace blt::gfx
updateStorage(width, height); updateStorage(width, height);
} }
void rbo_t::setStorageMultiSampled(GLuint s_type, blt::i32 width, blt::i32 height, blt::i32 s)
{
storage_type = s_type;
updateStorageMultiSampled(width, height, s);
}
void rbo_t::resize(blt::i32 width, blt::i32 height)
{
if (samples > 0)
updateStorageMultiSampled(width, height, samples);
else
updateStorage(width, height);
}
rbo_t rbo_t::make_render_buffer(GLuint storage_type, blt::i32 width, blt::i32 height) rbo_t rbo_t::make_render_buffer(GLuint storage_type, blt::i32 width, blt::i32 height)
{ {
rbo_t rbo{}; rbo_t rbo{};
@ -69,6 +85,16 @@ namespace blt::gfx
return rbo; return rbo;
} }
rbo_t rbo_t::make_render_buffer(GLuint storage_type, blt::i32 width, blt::i32 height, blt::i32 samples)
{
rbo_t rbo{};
rbo.create();
rbo.bind();
rbo.setStorageMultiSampled(storage_type, width, height, samples);
rbo_t::unbind();
return rbo;
}
void fbo_t::create(fbo_t::draw_t type) void fbo_t::create(fbo_t::draw_t type)
{ {
generic_bind_type = static_cast<GLuint>(type); generic_bind_type = static_cast<GLuint>(type);
@ -131,17 +157,20 @@ namespace blt::gfx
for (auto& rbo : render_buffers) for (auto& rbo : render_buffers)
{ {
rbo.bind(); rbo.bind();
rbo.updateStorage(width, height); rbo.resize(width, height);
} }
for (auto& texture : texture_buffers) for (auto& texture : texture_buffers)
texture->updateSize(width, height); texture->updateSize(width, height);
} }
void fbo_t::blitTexture(const fbo_t& draw, blt::i32 srcX, blt::i32 srcY, blt::i32 destX, blt::i32 destY, GLuint filter) const void fbo_t::blitTexture(const fbo_t& draw, blt::i32 srcX, blt::i32 srcY, blt::i32 destX, blt::i32 destY, GLuint filter,
attachment_t attachment_read, attachment_t attachment_write) const
{ {
glBindFramebuffer(GL_READ_FRAMEBUFFER, fboID); glBindFramebuffer(GL_READ_FRAMEBUFFER, fboID);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, draw.fboID); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, draw.fboID);
glReadBuffer(static_cast<GLuint>(attachment_read));
glDrawBuffer(static_cast<GLuint>(attachment_write));
glBlitFramebuffer(srcX, srcY, width_, height_, destX, destY, draw.width_, draw.height_, GL_COLOR_BUFFER_BIT, filter); glBlitFramebuffer(srcX, srcY, width_, height_, destX, destY, draw.width_, draw.height_, GL_COLOR_BUFFER_BIT, filter);
} }
@ -152,6 +181,22 @@ namespace blt::gfx
glBlitFramebuffer(srcX, srcY, width_, height_, destX, destY, draw.width_, draw.height_, GL_DEPTH_BUFFER_BIT, filter); glBlitFramebuffer(srcX, srcY, width_, height_, destX, destY, draw.width_, draw.height_, GL_DEPTH_BUFFER_BIT, filter);
} }
void fbo_t::blitStencil(const fbo_t& draw, blt::i32 srcX, blt::i32 srcY, blt::i32 destX, blt::i32 destY, GLuint filter) const
{
glBindFramebuffer(GL_READ_FRAMEBUFFER, fboID);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, draw.fboID);
glBlitFramebuffer(srcX, srcY, width_, height_, destX, destY, draw.width_, draw.height_, GL_STENCIL_BUFFER_BIT, filter);
}
void fbo_t::blitToScreen(blt::i32 width, blt::i32 height) const
{
glBindFramebuffer(GL_READ_FRAMEBUFFER, fboID);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
//glReadBuffer(GL_COLOR_ATTACHMENT0);
//glDrawBuffer(GL_COLOR_ATTACHMENT0);
glBlitFramebuffer(0, 0, width_, height_, 0, 0, width, height, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
}
fbo_t fbo_t::make_render_texture(blt::i32 width, blt::i32 height) fbo_t fbo_t::make_render_texture(blt::i32 width, blt::i32 height)
{ {
fbo_t fbo; fbo_t fbo;
@ -162,11 +207,7 @@ namespace blt::gfx
auto* texture = new texture_gl2D(width, height); auto* texture = new texture_gl2D(width, height);
fbo.attachTexture(texture, attachment_t::COLOR0); fbo.attachTexture(texture, attachment_t::COLOR0);
rbo_t depth_rbo; rbo_t depth_rbo = rbo_t::make_render_buffer(GL_DEPTH24_STENCIL8, width, height);
depth_rbo.create();
depth_rbo.bind();
depth_rbo.setStorage(GL_DEPTH24_STENCIL8, width, height);
fbo.attachRenderBuffer(depth_rbo, attachment_t::DEPTH_STENCIL); fbo.attachRenderBuffer(depth_rbo, attachment_t::DEPTH_STENCIL);
if (!fbo_t::validate()) if (!fbo_t::validate())
@ -176,10 +217,63 @@ namespace blt::gfx
return fbo; return fbo;
} }
void fbo_t::blitToScreen(blt::i32 width, blt::i32 height) const fbo_t fbo_t::make_multisample_render_texture(blt::i32 width, blt::i32 height, blt::i32 samples)
{ {
glBindFramebuffer(GL_READ_FRAMEBUFFER, fboID); fbo_t fbo;
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBlitFramebuffer(0, 0, width_, height_, 0, 0, width, height, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST); fbo.create();
fbo.bind();
auto* texture = new texture_gl2D_multisample(width, height, samples);
fbo.attachTexture(texture, attachment_t::COLOR0);
rbo_t depth_rbo = rbo_t::make_render_buffer(GL_DEPTH24_STENCIL8, width, height, samples);
fbo.attachRenderBuffer(depth_rbo, attachment_t::DEPTH_STENCIL);
if (!fbo_t::validate())
BLT_ERROR("Failed to create render texture framebuffer!");
fbo_t::unbind();
return fbo;
}
fbo_t fbo_t::make_multisample_render_target(blt::i32 width, blt::i32 height, blt::i32 samples)
{
fbo_t fbo;
fbo.create();
fbo.bind();
rbo_t color_rbo = rbo_t::make_render_buffer(GL_RGBA8, width, height, samples);
rbo_t depth_rbo = rbo_t::make_render_buffer(GL_DEPTH24_STENCIL8, width, height, samples);
fbo.attachRenderBuffer(color_rbo, attachment_t::COLOR0);
fbo.attachRenderBuffer(depth_rbo, attachment_t::DEPTH_STENCIL);
if (!fbo_t::validate())
BLT_ERROR("Failed to create multi-sampled render texture framebuffer!");
fbo_t::unbind();
return fbo;
}
fbo_t fbo_t::make_render_target(blt::i32 width, blt::i32 height)
{
fbo_t fbo;
fbo.create();
fbo.bind();
rbo_t color_rbo = rbo_t::make_render_buffer(GL_RGBA8, width, height);
rbo_t depth_rbo = rbo_t::make_render_buffer(GL_DEPTH24_STENCIL8, width, height);
fbo.attachRenderBuffer(color_rbo, attachment_t::COLOR0);
fbo.attachRenderBuffer(depth_rbo, attachment_t::DEPTH_STENCIL);
if (!fbo_t::validate())
BLT_ERROR("Failed to create multi-sampled render texture framebuffer!");
fbo_t::unbind();
return fbo;
} }
} }