framebuffers
parent
321379fb12
commit
e9e3622963
|
@ -1,6 +1,6 @@
|
||||||
cmake_minimum_required(VERSION 3.25)
|
cmake_minimum_required(VERSION 3.25)
|
||||||
|
|
||||||
set(BLT_GRAPHICS_VERSION 0.9.13)
|
set(BLT_GRAPHICS_VERSION 0.9.14)
|
||||||
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})
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
# BLT-With-Graphics-Template
|
# BLT-With-Graphics-Template
|
||||||
|
|
||||||
BLT + Graphics + Emscripten
|
BLT + Graphics + Emscripten
|
||||||
|
|
||||||
|
TODO: some of the API is inconsistent.
|
||||||
|
|
||||||
|
Textures bind themselves but FBOs do not.
|
||||||
|
|
||||||
|
make more use of factory functions
|
|
@ -25,7 +25,7 @@ blt::gfx::resource_manager resources;
|
||||||
blt::gfx::batch_renderer_2d renderer_2d(resources);
|
blt::gfx::batch_renderer_2d renderer_2d(resources);
|
||||||
blt::gfx::first_person_camera camera;
|
blt::gfx::first_person_camera camera;
|
||||||
|
|
||||||
void init(blt::gfx::window_context& context)
|
void init(const blt::gfx::window_context& context)
|
||||||
{
|
{
|
||||||
using namespace blt::gfx;
|
using namespace blt::gfx;
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ void init(blt::gfx::window_context& context)
|
||||||
renderer_2d.create();
|
renderer_2d.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
void update(blt::gfx::window_context& context, std::int32_t width, std::int32_t height)
|
void update(const blt::gfx::window_context& context, std::int32_t width, std::int32_t height)
|
||||||
{
|
{
|
||||||
global_matrices.update_perspectives(width, height, 90, 0.1, 2000);
|
global_matrices.update_perspectives(width, height, 90, 0.1, 2000);
|
||||||
|
|
||||||
|
|
|
@ -20,31 +20,94 @@
|
||||||
#define BLT_WITH_GRAPHICS_FRAMEBUFFER_H
|
#define BLT_WITH_GRAPHICS_FRAMEBUFFER_H
|
||||||
|
|
||||||
#include "blt/gfx/gl_includes.h"
|
#include "blt/gfx/gl_includes.h"
|
||||||
|
#include <blt/gfx/texture.h>
|
||||||
|
#include <vector>
|
||||||
|
#include "blt/std/types.h"
|
||||||
|
|
||||||
namespace blt::gfx
|
namespace blt::gfx
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#define C(num) COLOR##num = GL_COLOR_ATTACHMENT##num,
|
||||||
|
|
||||||
|
#define COLOR_LIST \
|
||||||
|
C(0) C(1) C(2) C(3) C(4) C(5) C(6) C(7) C(8) C(9) C(10) C(11) C(12) C(13) C(14) C(15) C(16) \
|
||||||
|
C(17) C(18) C(19) C(20) C(21) C(22) C(23) C(24) C(25) C(26) C(27) C(28) C(29) C(30) C(31)
|
||||||
|
|
||||||
|
class fbo_t;
|
||||||
|
|
||||||
|
class rbo_t
|
||||||
|
{
|
||||||
|
friend fbo_t;
|
||||||
|
private:
|
||||||
|
GLuint rboID;
|
||||||
|
GLuint storage_type;
|
||||||
|
public:
|
||||||
|
rbo_t(): rboID(0), storage_type(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void create();
|
||||||
|
|
||||||
|
void bind() const;
|
||||||
|
|
||||||
|
void setStorage(GLuint storage_type, blt::i32 width, blt::i32 height);
|
||||||
|
|
||||||
|
void updateStorage(blt::i32 width, blt::i32 height) const;
|
||||||
|
|
||||||
|
static void unbind();
|
||||||
|
|
||||||
|
void destroy();
|
||||||
|
|
||||||
|
static rbo_t make_render_buffer(GLuint storage_type, blt::i32 width, blt::i32 height);
|
||||||
|
};
|
||||||
|
|
||||||
class fbo_t
|
class fbo_t
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum class fbo_draw_t : GLuint
|
enum class draw_t : GLuint
|
||||||
{
|
{
|
||||||
DRAW = GL_DRAW_FRAMEBUFFER,
|
DRAW = GL_DRAW_FRAMEBUFFER,
|
||||||
READ = GL_READ_FRAMEBUFFER,
|
READ = GL_READ_FRAMEBUFFER,
|
||||||
BOTH = GL_FRAMEBUFFER
|
BOTH = GL_FRAMEBUFFER
|
||||||
};
|
};
|
||||||
|
enum class attachment_t : GLuint
|
||||||
|
{
|
||||||
|
COLOR_LIST
|
||||||
|
DEPTH_STENCIL = GL_DEPTH_STENCIL_ATTACHMENT,
|
||||||
|
DEPTH = GL_DEPTH_ATTACHMENT,
|
||||||
|
STENCIL = GL_STENCIL_ATTACHMENT
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GLuint fboID;
|
GLuint fboID = 0;
|
||||||
|
GLuint generic_bind_type = GL_FRAMEBUFFER;
|
||||||
|
std::vector<blt::gfx::texture_gl*> texture_buffers;
|
||||||
|
std::vector<rbo_t> render_buffers;
|
||||||
public:
|
public:
|
||||||
void create();
|
// default used for fbo binding
|
||||||
|
void create(draw_t bind_type = draw_t::BOTH);
|
||||||
|
|
||||||
void bind(fbo_draw_t type = fbo_draw_t::BOTH) const;
|
void bind(draw_t type = draw_t::BOTH) const;
|
||||||
|
|
||||||
bool validate();
|
// this function takes ownership of the pointer.
|
||||||
|
void attachTexture(blt::gfx::texture_gl* texture, attachment_t attachment, int level = 0);
|
||||||
|
|
||||||
|
void updateBuffersStorage(blt::i32 width, blt::i32 height);
|
||||||
|
|
||||||
|
// this function takes ownership of the render buffer
|
||||||
|
void attachRenderBuffer(rbo_t rbo, attachment_t attachment);
|
||||||
|
|
||||||
|
static bool validate();
|
||||||
|
|
||||||
static void unbind();
|
static void unbind();
|
||||||
|
|
||||||
void destroy();
|
void destroy();
|
||||||
|
|
||||||
|
public:
|
||||||
|
static fbo_t make_render_texture(blt::i32 width, blt::i32 height);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#undef C
|
||||||
|
#undef COLOR_LIST
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //BLT_WITH_GRAPHICS_FRAMEBUFFER_H
|
#endif //BLT_WITH_GRAPHICS_FRAMEBUFFER_H
|
||||||
|
|
|
@ -227,7 +227,7 @@ namespace blt::gfx
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline std::shared_ptr<vbo_t_owner> createSharedVBO(const vbo_t& vbo)
|
static inline static_dynamic_array::vbo_type createSharedVBO(const vbo_t& vbo)
|
||||||
{
|
{
|
||||||
return std::make_shared<vbo_t_owner>(vbo);
|
return std::make_shared<vbo_t_owner>(vbo);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include "blt/std/types.h"
|
||||||
|
|
||||||
namespace blt::gfx
|
namespace blt::gfx
|
||||||
{
|
{
|
||||||
|
@ -157,6 +158,14 @@ namespace blt::gfx
|
||||||
return textureID;
|
return textureID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] inline GLint getBindType() const
|
||||||
|
{
|
||||||
|
return textureBindType;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void updateSize(blt::i32, blt::i32)
|
||||||
|
{}
|
||||||
|
|
||||||
virtual ~texture_gl()
|
virtual ~texture_gl()
|
||||||
{
|
{
|
||||||
glDeleteTextures(1, &textureID);
|
glDeleteTextures(1, &textureID);
|
||||||
|
@ -177,10 +186,15 @@ namespace blt::gfx
|
||||||
|
|
||||||
void upload(const texture_data& file_data) const;
|
void upload(const texture_data& file_data) const;
|
||||||
|
|
||||||
|
inline void updateSize(blt::i32 width, blt::i32 height) final
|
||||||
|
{
|
||||||
|
resize(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resizes the internal memory for the texture but does NOT resize the texture image stored
|
* Resizes the internal memory for the texture but does NOT resize the texture image stored
|
||||||
*/
|
*/
|
||||||
inline void resize(int width, int height);
|
void resize(int width, int height);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct gl_texture2D_array : public texture_gl
|
struct gl_texture2D_array : public texture_gl
|
||||||
|
|
|
@ -31,14 +31,14 @@ namespace blt::gfx
|
||||||
std::string title;
|
std::string title;
|
||||||
std::int32_t width;
|
std::int32_t width;
|
||||||
std::int32_t height;
|
std::int32_t height;
|
||||||
std::function<void(window_context&)> init;
|
std::function<void(const window_context&)> init;
|
||||||
std::function<void(window_context&, std::int32_t, std::int32_t)> update;
|
std::function<void(const window_context&, std::int32_t, std::int32_t)> update;
|
||||||
|
|
||||||
window_context context{};
|
window_context context{};
|
||||||
std::int32_t sync_interval = 0;
|
std::int32_t sync_interval = 0;
|
||||||
|
|
||||||
window_data(std::string title, std::function<void(window_context&)> init,
|
window_data(std::string title, std::function<void(const window_context&)> init,
|
||||||
std::function<void(window_context&, std::int32_t, std::int32_t)> update, std::int32_t width = 640,
|
std::function<void(const window_context&, std::int32_t, std::int32_t)> update, std::int32_t width = 640,
|
||||||
std::int32_t height = 480):
|
std::int32_t height = 480):
|
||||||
title(std::move(title)), width(width), height(height), init(std::move(init)), update(std::move(update))
|
title(std::move(title)), width(width), height(height), init(std::move(init)), update(std::move(update))
|
||||||
{}
|
{}
|
||||||
|
|
|
@ -18,13 +18,54 @@
|
||||||
|
|
||||||
namespace blt::gfx
|
namespace blt::gfx
|
||||||
{
|
{
|
||||||
|
void rbo_t::create()
|
||||||
void fbo_t::create()
|
|
||||||
{
|
{
|
||||||
|
glGenRenderbuffers(1, &rboID);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rbo_t::bind() const
|
||||||
|
{
|
||||||
|
glBindRenderbuffer(GL_RENDERBUFFER, rboID);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rbo_t::unbind()
|
||||||
|
{
|
||||||
|
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rbo_t::destroy()
|
||||||
|
{
|
||||||
|
glDeleteRenderbuffers(1, &rboID);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rbo_t::updateStorage(blt::i32 width, blt::i32 height) const
|
||||||
|
{
|
||||||
|
glRenderbufferStorage(GL_RENDERBUFFER, storage_type, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rbo_t::setStorage(GLuint s_type, blt::i32 width, blt::i32 height)
|
||||||
|
{
|
||||||
|
storage_type = s_type;
|
||||||
|
updateStorage(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
rbo_t rbo_t::make_render_buffer(GLuint storage_type, blt::i32 width, blt::i32 height)
|
||||||
|
{
|
||||||
|
rbo_t rbo{};
|
||||||
|
rbo.create();
|
||||||
|
rbo.bind();
|
||||||
|
rbo.setStorage(storage_type, width, height);
|
||||||
|
rbo_t::unbind();
|
||||||
|
return rbo;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fbo_t::create(fbo_t::draw_t type)
|
||||||
|
{
|
||||||
|
generic_bind_type = static_cast<GLuint>(type);
|
||||||
glGenFramebuffers(1, &fboID);
|
glGenFramebuffers(1, &fboID);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fbo_t::bind(fbo_draw_t type) const
|
void fbo_t::bind(draw_t type) const
|
||||||
{
|
{
|
||||||
glBindFramebuffer(static_cast<GLuint>(type), fboID);
|
glBindFramebuffer(static_cast<GLuint>(type), fboID);
|
||||||
}
|
}
|
||||||
|
@ -36,11 +77,64 @@ namespace blt::gfx
|
||||||
|
|
||||||
void fbo_t::destroy()
|
void fbo_t::destroy()
|
||||||
{
|
{
|
||||||
|
glDeleteFramebuffers(1, &fboID);
|
||||||
|
for (auto& v : render_buffers)
|
||||||
|
v.destroy();
|
||||||
|
for (auto* texture : texture_buffers)
|
||||||
|
delete texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool fbo_t::validate()
|
bool fbo_t::validate()
|
||||||
{
|
{
|
||||||
return glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE;
|
return glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void fbo_t::attachTexture(blt::gfx::texture_gl* texture, attachment_t attachment, int level)
|
||||||
|
{
|
||||||
|
texture_buffers.push_back(texture);
|
||||||
|
glFramebufferTexture2D(generic_bind_type, static_cast<GLuint>(attachment), texture->getBindType(), texture->getTextureID(), level);
|
||||||
|
}
|
||||||
|
|
||||||
|
void fbo_t::attachRenderBuffer(rbo_t rbo, fbo_t::attachment_t attachment)
|
||||||
|
{
|
||||||
|
rbo.bind();
|
||||||
|
glFramebufferRenderbuffer(generic_bind_type, static_cast<GLuint>(attachment), GL_RENDERBUFFER, rbo.rboID);
|
||||||
|
render_buffers.push_back(rbo);
|
||||||
|
}
|
||||||
|
|
||||||
|
void fbo_t::updateBuffersStorage(blt::i32 width, blt::i32 height)
|
||||||
|
{
|
||||||
|
for (auto& rbo : render_buffers)
|
||||||
|
{
|
||||||
|
rbo.bind();
|
||||||
|
rbo.updateStorage(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& texture : texture_buffers)
|
||||||
|
texture->updateSize(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
fbo_t fbo_t::make_render_texture(blt::i32 width, blt::i32 height)
|
||||||
|
{
|
||||||
|
fbo_t fbo;
|
||||||
|
|
||||||
|
fbo.create();
|
||||||
|
fbo.bind();
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -43,8 +43,7 @@ namespace blt::gfx
|
||||||
size_ = next_size;
|
size_ = next_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static_dynamic_array::static_dynamic_array()
|
static_dynamic_array::static_dynamic_array() = default;
|
||||||
{}
|
|
||||||
|
|
||||||
static_dynamic_array::vbo_type& static_dynamic_array::operator[](size_t index)
|
static_dynamic_array::vbo_type& static_dynamic_array::operator[](size_t index)
|
||||||
{
|
{
|
||||||
|
|
|
@ -143,7 +143,7 @@ namespace blt::gfx
|
||||||
|
|
||||||
void loop(void* arg)
|
void loop(void* arg)
|
||||||
{
|
{
|
||||||
const auto& data = *((const window_data*) arg);
|
const auto& data = *((window_data*) arg);
|
||||||
/* -- Get the current framebuffer size, update the global width/height state, along with OpenGL viewport -- */
|
/* -- Get the current framebuffer size, update the global width/height state, along with OpenGL viewport -- */
|
||||||
glfwGetFramebufferSize(window_state.window, &window_state.width, &window_state.height);
|
glfwGetFramebufferSize(window_state.window, &window_state.width, &window_state.height);
|
||||||
glViewport(0, 0, window_state.width, window_state.height);
|
glViewport(0, 0, window_state.width, window_state.height);
|
||||||
|
@ -156,7 +156,7 @@ namespace blt::gfx
|
||||||
ImGui::NewFrame();
|
ImGui::NewFrame();
|
||||||
|
|
||||||
/* -- Call user update function -- */
|
/* -- Call user update function -- */
|
||||||
data.update(window_state.width, window_state.height);
|
data.update(data.context, window_state.width, window_state.height);
|
||||||
|
|
||||||
/* -- Render the ImGUI frame -- */
|
/* -- Render the ImGUI frame -- */
|
||||||
ImGui::Render();
|
ImGui::Render();
|
||||||
|
@ -209,7 +209,7 @@ namespace blt::gfx
|
||||||
glEnable(GL_MULTISAMPLE);
|
glEnable(GL_MULTISAMPLE);
|
||||||
|
|
||||||
/* -- Call User Provided post-window-init function -- */
|
/* -- Call User Provided post-window-init function -- */
|
||||||
data.init();
|
data.init(data.context);
|
||||||
|
|
||||||
#ifdef __EMSCRIPTEN__
|
#ifdef __EMSCRIPTEN__
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue