frame buffer
parent
725b6963af
commit
42fbae4ba1
|
@ -1,6 +1,6 @@
|
|||
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)
|
||||
|
||||
project(BLT_WITH_GRAPHICS VERSION ${BLT_GRAPHICS_VERSION})
|
||||
|
|
|
@ -42,6 +42,7 @@ namespace blt::gfx
|
|||
GLuint rboID;
|
||||
GLuint storage_type;
|
||||
blt::i32 width_, height_;
|
||||
blt::i32 samples = 0;
|
||||
public:
|
||||
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 setStorageMultiSampled(GLuint storage_type, blt::i32 width, blt::i32 height, blt::i32 samples);
|
||||
|
||||
void updateStorage(blt::i32 width, blt::i32 height);
|
||||
|
||||
void updateStorageMultiSampled(blt::i32 width, blt::i32 height, blt::i32 samples);
|
||||
|
||||
void resize(blt::i32 width, blt::i32 height);
|
||||
|
||||
static void unbind();
|
||||
|
||||
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, blt::i32 samples);
|
||||
};
|
||||
|
||||
class fbo_t
|
||||
|
@ -99,18 +107,42 @@ namespace blt::gfx
|
|||
// this function takes ownership of the render buffer
|
||||
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 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 void unbind();
|
||||
|
||||
void destroy();
|
||||
|
||||
[[nodiscard]] i32 getHeight() const
|
||||
{
|
||||
return height_;
|
||||
}
|
||||
|
||||
[[nodiscard]] i32 getWidth() const
|
||||
{
|
||||
return width_;
|
||||
}
|
||||
|
||||
public:
|
||||
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
|
||||
|
|
|
@ -43,13 +43,15 @@ namespace blt::gfx
|
|||
{
|
||||
width_ = width;
|
||||
height_ = height;
|
||||
samples = 0;
|
||||
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;
|
||||
height_ = height;
|
||||
samples = s;
|
||||
glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, storage_type, width, height);
|
||||
}
|
||||
|
||||
|
@ -59,6 +61,20 @@ namespace blt::gfx
|
|||
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{};
|
||||
|
@ -69,6 +85,16 @@ namespace blt::gfx
|
|||
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)
|
||||
{
|
||||
generic_bind_type = static_cast<GLuint>(type);
|
||||
|
@ -131,17 +157,20 @@ namespace blt::gfx
|
|||
for (auto& rbo : render_buffers)
|
||||
{
|
||||
rbo.bind();
|
||||
rbo.updateStorage(width, height);
|
||||
rbo.resize(width, height);
|
||||
}
|
||||
|
||||
for (auto& texture : texture_buffers)
|
||||
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_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);
|
||||
}
|
||||
|
||||
|
@ -152,6 +181,22 @@ namespace blt::gfx
|
|||
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;
|
||||
|
@ -162,11 +207,7 @@ namespace blt::gfx
|
|||
auto* texture = new texture_gl2D(width, height);
|
||||
fbo.attachTexture(texture, attachment_t::COLOR0);
|
||||
|
||||
rbo_t depth_rbo;
|
||||
depth_rbo.create();
|
||||
depth_rbo.bind();
|
||||
depth_rbo.setStorage(GL_DEPTH24_STENCIL8, width, height);
|
||||
|
||||
rbo_t depth_rbo = rbo_t::make_render_buffer(GL_DEPTH24_STENCIL8, width, height);
|
||||
fbo.attachRenderBuffer(depth_rbo, attachment_t::DEPTH_STENCIL);
|
||||
|
||||
if (!fbo_t::validate())
|
||||
|
@ -176,10 +217,63 @@ namespace blt::gfx
|
|||
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);
|
||||
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_t fbo;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue