post processing
parent
eb761557f0
commit
7c61323a05
|
@ -1,6 +1,6 @@
|
||||||
cmake_minimum_required(VERSION 3.25)
|
cmake_minimum_required(VERSION 3.25)
|
||||||
|
|
||||||
set(BLT_GRAPHICS_VERSION 0.13.5)
|
set(BLT_GRAPHICS_VERSION 0.13.6)
|
||||||
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})
|
||||||
|
|
|
@ -174,6 +174,7 @@ namespace blt::gfx
|
||||||
shader_t* square_shader = nullptr;
|
shader_t* square_shader = nullptr;
|
||||||
shader_t* point_shader = nullptr;
|
shader_t* point_shader = nullptr;
|
||||||
resource_manager& resources;
|
resource_manager& resources;
|
||||||
|
matrix_state_manager& state;
|
||||||
// texture name -> draw info
|
// texture name -> draw info
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
|
@ -209,10 +210,15 @@ namespace blt::gfx
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit batch_renderer_2d(resource_manager& resources, matrix_state_manager& state): resources(resources)
|
explicit batch_renderer_2d(resource_manager& resources, matrix_state_manager& state): resources(resources), state(state)
|
||||||
{
|
{
|
||||||
engine = pp_engine_t::make_multi_pp(std::make_unique<pp_outline_target>(),
|
engine = pp_engine_t::make_multi_pp(std::make_unique<pp_outline_target_t>(),
|
||||||
std::make_unique<pp_outline_step_t>(state));
|
std::make_unique<pp_blur_step_inplace_t>(state, frame_buffer_t::attachment_t::COLOR1),
|
||||||
|
std::make_unique<pp_expansion_step_inplace_t>(frame_buffer_t::attachment_t::COLOR1,
|
||||||
|
vec4{4, 4, 4, 1}),
|
||||||
|
std::make_unique<pp_blur_step_inplace_t>(state, frame_buffer_t::attachment_t::COLOR1, 2, 2),
|
||||||
|
std::make_unique<pp_outline_step_t>(state)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void create();
|
void create();
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include <blt/gfx/state.h>
|
#include <blt/gfx/state.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <blt/std/assert.h>
|
||||||
|
|
||||||
namespace blt::gfx
|
namespace blt::gfx
|
||||||
{
|
{
|
||||||
|
@ -33,6 +34,12 @@ namespace blt::gfx
|
||||||
|
|
||||||
class pp_step_t;
|
class pp_step_t;
|
||||||
|
|
||||||
|
enum class pp_request_t : u64
|
||||||
|
{
|
||||||
|
BIND_BUFFER = 0x1,
|
||||||
|
CLEAR_BUFFER = 0x2
|
||||||
|
};
|
||||||
|
|
||||||
class pp_step_t
|
class pp_step_t
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -40,13 +47,17 @@ namespace blt::gfx
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// only called on render()
|
// only called on render()
|
||||||
virtual void draw(pp_step_t&)
|
virtual void draw(frame_buffer_t&)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// only called on bind()
|
// only called on bind()
|
||||||
virtual void draw()
|
virtual void draw()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
// called after rendering, provides previous framebuffer
|
||||||
|
virtual void post_draw(frame_buffer_t&)
|
||||||
|
{}
|
||||||
|
|
||||||
auto& getBuffer()
|
auto& getBuffer()
|
||||||
{
|
{
|
||||||
return draw_buffer;
|
return draw_buffer;
|
||||||
|
@ -62,6 +73,11 @@ namespace blt::gfx
|
||||||
return shader != nullptr;
|
return shader != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual bool requests(pp_request_t)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
virtual ~pp_step_t() = default;
|
virtual ~pp_step_t() = default;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -69,6 +85,25 @@ namespace blt::gfx
|
||||||
std::unique_ptr<shader_t> shader;
|
std::unique_ptr<shader_t> shader;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class pp_in_place_t : public pp_step_t
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
pp_in_place_t(frame_buffer_t::attachment_t from): from(from), to(from)
|
||||||
|
{}
|
||||||
|
|
||||||
|
pp_in_place_t(frame_buffer_t::attachment_t from, frame_buffer_t::attachment_t to): from(from), to(to)
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool requests(blt::gfx::pp_request_t request) override
|
||||||
|
{
|
||||||
|
return static_cast<u64>(request) & ~(static_cast<u64>(pp_request_t::BIND_BUFFER) | static_cast<u64>(pp_request_t::CLEAR_BUFFER));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
frame_buffer_t::attachment_t from;
|
||||||
|
frame_buffer_t::attachment_t to;
|
||||||
|
};
|
||||||
|
|
||||||
class pp_render_target_t : public pp_step_t
|
class pp_render_target_t : public pp_step_t
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -82,10 +117,10 @@ namespace blt::gfx
|
||||||
public:
|
public:
|
||||||
void create() override;
|
void create() override;
|
||||||
|
|
||||||
void draw(pp_step_t& previous) override;
|
void draw(frame_buffer_t& previous) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class pp_outline_target : public pp_step_t
|
class pp_outline_target_t : public pp_step_t
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void create() override;
|
void create() override;
|
||||||
|
@ -101,12 +136,93 @@ namespace blt::gfx
|
||||||
|
|
||||||
void create() override;
|
void create() override;
|
||||||
|
|
||||||
void draw(pp_step_t& previous) override;
|
void draw(frame_buffer_t& previous) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
matrix_state_manager& manager;
|
matrix_state_manager& manager;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class pp_blur_step_base_t : public pp_step_t
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
pp_blur_step_base_t(frame_buffer_t::attachment_t from, i32 x_blur = 2, i32 y_blur = 2):
|
||||||
|
from(from), to(from), x_blur(x_blur), y_blur(y_blur)
|
||||||
|
{}
|
||||||
|
|
||||||
|
pp_blur_step_base_t(frame_buffer_t::attachment_t from, frame_buffer_t::attachment_t to, i32 x_blur = 2, i32 y_blur = 2):
|
||||||
|
from(from), to(to), x_blur(x_blur), y_blur(y_blur)
|
||||||
|
{}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
frame_buffer_t::attachment_t from;
|
||||||
|
frame_buffer_t::attachment_t to;
|
||||||
|
i32 x_blur;
|
||||||
|
i32 y_blur;
|
||||||
|
};
|
||||||
|
|
||||||
|
class pp_blur_step_t : public pp_blur_step_base_t
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
pp_blur_step_t(frame_buffer_t::attachment_t from, i32 x_blur = 2, i32 y_blur = 2): pp_blur_step_base_t(from, x_blur, y_blur)
|
||||||
|
{}
|
||||||
|
|
||||||
|
pp_blur_step_t(frame_buffer_t::attachment_t from, frame_buffer_t::attachment_t to, i32 x_blur = 2, i32 y_blur = 2):
|
||||||
|
pp_blur_step_base_t(from, to, x_blur, y_blur)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void create() override;
|
||||||
|
|
||||||
|
void draw(frame_buffer_t& previous);
|
||||||
|
};
|
||||||
|
|
||||||
|
class pp_blur_step_inplace_t : public pp_blur_step_base_t
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
pp_blur_step_inplace_t(matrix_state_manager& manager, frame_buffer_t::attachment_t from, i32 x_blur = 2, i32 y_blur = 2):
|
||||||
|
pp_blur_step_base_t(from, x_blur, y_blur), manager(manager)
|
||||||
|
{}
|
||||||
|
|
||||||
|
pp_blur_step_inplace_t(matrix_state_manager& manager, frame_buffer_t::attachment_t from, frame_buffer_t::attachment_t to, i32 x_blur = 2,
|
||||||
|
i32 y_blur = 2):
|
||||||
|
pp_blur_step_base_t(from, to, x_blur, y_blur), manager(manager)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void create() override;
|
||||||
|
|
||||||
|
void draw(frame_buffer_t& previous);
|
||||||
|
|
||||||
|
void post_draw(frame_buffer_t& previous) override;
|
||||||
|
|
||||||
|
bool requests(blt::gfx::pp_request_t request) override
|
||||||
|
{
|
||||||
|
return static_cast<u64>(request) & ~(static_cast<u64>(pp_request_t::BIND_BUFFER) | static_cast<u64>(pp_request_t::CLEAR_BUFFER));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<shader_t> shader_pass;
|
||||||
|
matrix_state_manager& manager;
|
||||||
|
};
|
||||||
|
|
||||||
|
class pp_expansion_step_inplace_t : public pp_in_place_t
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
pp_expansion_step_inplace_t(frame_buffer_t::attachment_t from, const vec4& multiplier = vec4{2,2,2,2}):
|
||||||
|
pp_in_place_t(from), multiplier(multiplier)
|
||||||
|
{}
|
||||||
|
|
||||||
|
pp_expansion_step_inplace_t(frame_buffer_t::attachment_t from, frame_buffer_t::attachment_t to,
|
||||||
|
const vec4& multiplier = vec4{2,2,2,2}):
|
||||||
|
pp_in_place_t(from, to), multiplier(multiplier)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void create() override;
|
||||||
|
|
||||||
|
void draw(frame_buffer_t& previous);
|
||||||
|
|
||||||
|
private:
|
||||||
|
vec4 multiplier;
|
||||||
|
};
|
||||||
|
|
||||||
class pp_engine_t
|
class pp_engine_t
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -144,10 +260,14 @@ namespace blt::gfx
|
||||||
(engine->addStep(std::move(steps)), ...);
|
(engine->addStep(std::move(steps)), ...);
|
||||||
return std::unique_ptr<pp_engine_t>(engine);
|
return std::unique_ptr<pp_engine_t>(engine);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void render_quad();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
pp_engine_t() = default;
|
pp_engine_t() = default;
|
||||||
|
|
||||||
|
pp_step_t& find_last_frame_buffer(size_t index);
|
||||||
|
|
||||||
std::vector<std::unique_ptr<pp_step_t>> steps;
|
std::vector<std::unique_ptr<pp_step_t>> steps;
|
||||||
std::unique_ptr<vertex_array_t> screen_vao;
|
std::unique_ptr<vertex_array_t> screen_vao;
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#include <string>
|
||||||
|
const std::string shader_gaussian_blur_frag = R"("
|
||||||
|
#version 300 es
|
||||||
|
precision mediump float;
|
||||||
|
|
||||||
|
out vec4 FragColor;
|
||||||
|
in vec2 uv;
|
||||||
|
in vec2 pos;
|
||||||
|
|
||||||
|
uniform sampler2D tex;
|
||||||
|
uniform ivec4 size;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec2 texelSize = 1.0 / vec2(float(size.x), float(size.y));
|
||||||
|
vec4 result = vec4(0.0, 0.0, 0.0, 0.0);
|
||||||
|
for (int x = -size.z; x <= size.z; ++x) {
|
||||||
|
for (int y = -size.w; y <= size.w; ++y) {
|
||||||
|
vec2 offset = (vec2(float(x), float(y)) * texelSize);
|
||||||
|
result += texture(tex, uv + offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//FragColor = result;
|
||||||
|
FragColor = result / vec4((float(size.z) * 2.0 + 1.0) * (float(size.w) * 2.0 + 1.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
")";
|
||||||
|
#endif
|
|
@ -0,0 +1,19 @@
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#include <string>
|
||||||
|
const std::string shader_multiplier_frag = R"("
|
||||||
|
#version 300 es
|
||||||
|
precision mediump float;
|
||||||
|
|
||||||
|
out vec4 FragColor;
|
||||||
|
in vec2 uv;
|
||||||
|
in vec2 pos;
|
||||||
|
|
||||||
|
uniform sampler2D tex;
|
||||||
|
uniform vec4 multiplier;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
FragColor = normalize(texture(tex, uv) * multiplier);
|
||||||
|
}
|
||||||
|
|
||||||
|
")";
|
||||||
|
#endif
|
|
@ -19,38 +19,41 @@ float longest(vec3 v){
|
||||||
return max(v.r, max(v.b, v.g));
|
return max(v.r, max(v.b, v.g));
|
||||||
}
|
}
|
||||||
|
|
||||||
#define LINE_WEIGHT 3.0
|
#define LINE_WEIGHT 1.0
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
float dx = (1.0 / viewportSize.x) * LINE_WEIGHT;
|
// float dx = (1.0 / viewportSize.x) * LINE_WEIGHT;
|
||||||
float dy = (1.0 / viewportSize.y) * LINE_WEIGHT;
|
// float dy = (1.0 / viewportSize.y) * LINE_WEIGHT;
|
||||||
|
//
|
||||||
vec2 uvCenter = uv;
|
// vec2 uvCenter = uv;
|
||||||
vec2 uvRight = vec2(uvCenter.x + dx, uvCenter.y);
|
// vec2 uvRight = vec2(uvCenter.x + dx, uvCenter.y);
|
||||||
vec2 uvTop = vec2(uvCenter.x, uvCenter.y - dx);
|
// vec2 uvTop = vec2(uvCenter.x, uvCenter.y - dy);
|
||||||
vec2 uvTopRight = vec2(uvCenter.x + dx, uvCenter.y - dx);
|
// vec2 uvTopRight = vec2(uvCenter.x + dx, uvCenter.y - dy);
|
||||||
|
//
|
||||||
float mCenter = longest(texture(mask, uvCenter).rgb);
|
// float mCenter = longest(texture(mask, uvCenter).rgb);
|
||||||
float mTop = longest(texture(mask, uvTop).rgb);
|
// float mTop = longest(texture(mask, uvTop).rgb);
|
||||||
float mRight = longest(texture(mask, uvRight).rgb);
|
// float mRight = longest(texture(mask, uvRight).rgb);
|
||||||
float mTopRight = longest(texture(mask, uvTopRight).rgb);
|
// float mTopRight = longest(texture(mask, uvTopRight).rgb);
|
||||||
|
//
|
||||||
float dT = abs(mCenter - mTop);
|
// float dT = abs(mCenter - mTop);
|
||||||
float dR = abs(mCenter - mRight);
|
// float dR = abs(mCenter - mRight);
|
||||||
float dTR = abs(mCenter - mTopRight);
|
// float dTR = abs(mCenter - mTopRight);
|
||||||
|
//
|
||||||
float delta = 0.0f;
|
// float delta = 0.0f;
|
||||||
delta = max(delta, dT);
|
// delta = max(delta, dT);
|
||||||
delta = max(delta, dR);
|
// delta = max(delta, dR);
|
||||||
delta = max(delta, dTR);
|
// delta = max(delta, dTR);
|
||||||
|
//
|
||||||
vec4 outline = vec4(delta, delta, delta, 1.0);
|
// vec4 outline = vec4(delta, delta, delta, 1.0);
|
||||||
vec4 albedo = texture(albedo, uv);
|
// vec4 albedo = texture(albedo, uv);
|
||||||
|
//
|
||||||
if (delta <= 0.001)
|
// if (delta <= 0.0)
|
||||||
FragColor = albedo;
|
// FragColor = albedo;
|
||||||
else
|
// else
|
||||||
FragColor = outline_color;
|
// FragColor = outline_color;
|
||||||
|
FragColor = texture(albedo, uv);
|
||||||
|
if (FragColor.a == 0.0)
|
||||||
|
FragColor = texture(mask, uv);
|
||||||
}
|
}
|
||||||
|
|
||||||
")";
|
")";
|
||||||
|
|
|
@ -116,6 +116,7 @@ namespace blt::gfx
|
||||||
shader_base_t& setVec3(const std::string& name, const blt::vec3& vec);
|
shader_base_t& setVec3(const std::string& name, const blt::vec3& vec);
|
||||||
|
|
||||||
shader_base_t& setVec4(const std::string& name, const blt::vec4& vec);
|
shader_base_t& setVec4(const std::string& name, const blt::vec4& vec);
|
||||||
|
shader_base_t& setVec4i(const std::string& name, const blt::vec4i& vec);
|
||||||
|
|
||||||
shader_base_t& setVec2(const std::string& name, float x, float y);
|
shader_base_t& setVec2(const std::string& name, float x, float y);
|
||||||
|
|
||||||
|
|
|
@ -135,7 +135,7 @@ namespace blt::gfx
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void setDefaults(GLint type) const;
|
void setDefaults(GLint type, GLint wrap = GL_REPEAT) const;
|
||||||
|
|
||||||
inline void generateMipmaps() const
|
inline void generateMipmaps() const
|
||||||
{
|
{
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 9b86278a2982d80fbac6f87045a182088e07afbe
|
Subproject commit 943fb842117cd698f75ffd7d13815622e4a6e128
|
|
@ -175,10 +175,9 @@ namespace blt::gfx
|
||||||
{
|
{
|
||||||
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));
|
glReadBuffer(static_cast<GLenum>(attachment_read));
|
||||||
#ifdef glDrawBuffer
|
GLenum buffers[] {static_cast<GLenum>(attachment_write)};
|
||||||
glDrawBuffer(static_cast<GLuint>(attachment_write));
|
glDrawBuffers(1, buffers);
|
||||||
#endif
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,6 +185,9 @@ namespace blt::gfx
|
||||||
{
|
{
|
||||||
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<GLenum>(attachment_t::DEPTH));
|
||||||
|
GLenum buffers[] {static_cast<GLenum>(attachment_t::DEPTH)};
|
||||||
|
glDrawBuffers(1, buffers);
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,6 +195,9 @@ namespace blt::gfx
|
||||||
{
|
{
|
||||||
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<GLenum>(attachment_t::STENCIL));
|
||||||
|
GLenum buffers[] {static_cast<GLenum>(attachment_t::STENCIL)};
|
||||||
|
glDrawBuffers(1, buffers);
|
||||||
glBlitFramebuffer(srcX, srcY, width_, height_, destX, destY, draw.width_, draw.height_, GL_STENCIL_BUFFER_BIT, filter);
|
glBlitFramebuffer(srcX, srcY, width_, height_, destX, destY, draw.width_, draw.height_, GL_STENCIL_BUFFER_BIT, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,6 +207,9 @@ namespace blt::gfx
|
||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||||
//glReadBuffer(GL_COLOR_ATTACHMENT0);
|
//glReadBuffer(GL_COLOR_ATTACHMENT0);
|
||||||
//glDrawBuffer(GL_COLOR_ATTACHMENT0);
|
//glDrawBuffer(GL_COLOR_ATTACHMENT0);
|
||||||
|
glReadBuffer(static_cast<GLenum>(attachment_t::COLOR0));
|
||||||
|
GLenum buffers[] {static_cast<GLenum>(attachment_t::COLOR0)};
|
||||||
|
glDrawBuffers(1, buffers);
|
||||||
glBlitFramebuffer(0, 0, width_, height_, 0, 0, width, height, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
|
glBlitFramebuffer(0, 0, width_, height_, 0, 0, width, height, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -184,8 +184,6 @@ namespace blt::gfx
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
|
||||||
engine->bind();
|
engine->bind();
|
||||||
const GLenum buffers[]{GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};
|
|
||||||
glDrawBuffers(2, buffers);
|
|
||||||
draw_objects();
|
draw_objects();
|
||||||
|
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
@ -295,7 +293,7 @@ namespace blt::gfx
|
||||||
|
|
||||||
mat4x4 model;
|
mat4x4 model;
|
||||||
model.translate(point.pos.x(), point.pos.y(), 0.0f);
|
model.translate(point.pos.x(), point.pos.y(), 0.0f);
|
||||||
model.scale(point.scale, point.scale, 1);
|
model.scale(point.scale, point.scale, 1.0);
|
||||||
|
|
||||||
point_shader->setVec4("color", render_info.color);
|
point_shader->setVec4("color", render_info.color);
|
||||||
point_shader->setVec4("use_texture", render_info.blend);
|
point_shader->setVec4("use_texture", render_info.blend);
|
||||||
|
|
|
@ -20,7 +20,10 @@
|
||||||
#include <blt/gfx/renderer/shaders/postprocess.vert>
|
#include <blt/gfx/renderer/shaders/postprocess.vert>
|
||||||
#include <blt/gfx/renderer/shaders/pp_screen.frag>
|
#include <blt/gfx/renderer/shaders/pp_screen.frag>
|
||||||
#include <blt/gfx/renderer/shaders/pp_outline_step.frag>
|
#include <blt/gfx/renderer/shaders/pp_outline_step.frag>
|
||||||
|
#include <blt/gfx/renderer/shaders/pp_gaussian_blur.frag>
|
||||||
|
#include <blt/gfx/renderer/shaders/pp_multiplier.frag>
|
||||||
#include <blt/std/ranges.h>
|
#include <blt/std/ranges.h>
|
||||||
|
#include <blt/math/log_util.h>
|
||||||
|
|
||||||
#define __EMSCRIPTEN__
|
#define __EMSCRIPTEN__
|
||||||
|
|
||||||
|
@ -68,6 +71,17 @@ namespace blt::gfx
|
||||||
step->create();
|
step->create();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pp_step_t& pp_engine_t::find_last_frame_buffer(size_t index)
|
||||||
|
{
|
||||||
|
for (i64 i = static_cast<i64>(index); i >= 0; i--)
|
||||||
|
{
|
||||||
|
if (steps[i]->requests(pp_request_t::BIND_BUFFER))
|
||||||
|
return *steps[i];
|
||||||
|
}
|
||||||
|
BLT_FATAL("We reached the end trying to find a previous frame buffer, unable to do so! Please ensure this in-place step has a framebuffer!");
|
||||||
|
std::exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
void pp_engine_t::render()
|
void pp_engine_t::render()
|
||||||
{
|
{
|
||||||
screen_vao->bind();
|
screen_vao->bind();
|
||||||
|
@ -75,13 +89,18 @@ namespace blt::gfx
|
||||||
{
|
{
|
||||||
if (index == 0)
|
if (index == 0)
|
||||||
continue;
|
continue;
|
||||||
auto& previous = steps[index - 1];
|
auto& previous = find_last_frame_buffer(index - 1);
|
||||||
step->getBuffer().bind(frame_buffer_t::draw_t::BOTH);
|
if (step->requests(pp_request_t::BIND_BUFFER))
|
||||||
step->draw(*previous);
|
step->getBuffer().bind();
|
||||||
|
else
|
||||||
|
previous.getBuffer().bind();
|
||||||
|
if (step->requests(pp_request_t::CLEAR_BUFFER))
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||||
|
step->draw(previous.getBuffer());
|
||||||
if (step->hasShader())
|
if (step->hasShader())
|
||||||
step->getShader().bind();
|
step->getShader().bind();
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
render_quad();
|
||||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
|
step->post_draw(previous.getBuffer());
|
||||||
}
|
}
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
frame_buffer_t::unbind();
|
frame_buffer_t::unbind();
|
||||||
|
@ -108,20 +127,27 @@ namespace blt::gfx
|
||||||
|
|
||||||
void pp_engine_t::bind()
|
void pp_engine_t::bind()
|
||||||
{
|
{
|
||||||
steps.front()->draw();
|
|
||||||
steps.front()->getBuffer().bind();
|
steps.front()->getBuffer().bind();
|
||||||
|
steps.front()->draw();
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pp_engine_t::render_quad()
|
||||||
|
{
|
||||||
|
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
|
||||||
|
}
|
||||||
|
|
||||||
void pp_to_screen_step_t::create()
|
void pp_to_screen_step_t::create()
|
||||||
{
|
{
|
||||||
shader = pp_engine_t::createShader(shader_pp_screen_frag);
|
shader = pp_engine_t::createShader(shader_pp_screen_frag);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pp_to_screen_step_t::draw(pp_step_t& previous)
|
void pp_to_screen_step_t::draw(frame_buffer_t& previous)
|
||||||
{
|
{
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
previous.getBuffer().getTexture(frame_buffer_t::attachment_t::COLOR0).bind();
|
previous.getTexture(frame_buffer_t::attachment_t::COLOR0).bind();
|
||||||
|
GLenum buf[]{static_cast<GLenum>(frame_buffer_t::attachment_t::COLOR0)};
|
||||||
|
glDrawBuffers(1, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pp_render_target_t::create()
|
void pp_render_target_t::create()
|
||||||
|
@ -132,9 +158,11 @@ namespace blt::gfx
|
||||||
void pp_render_target_t::draw()
|
void pp_render_target_t::draw()
|
||||||
{
|
{
|
||||||
draw_buffer.updateBuffersStorage(getWindowWidth(), getWindowHeight());
|
draw_buffer.updateBuffersStorage(getWindowWidth(), getWindowHeight());
|
||||||
|
GLenum buf[]{static_cast<GLenum>(frame_buffer_t::attachment_t::COLOR0)};
|
||||||
|
glDrawBuffers(1, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pp_outline_target::create()
|
void pp_outline_target_t::create()
|
||||||
{
|
{
|
||||||
draw_buffer.create();
|
draw_buffer.create();
|
||||||
draw_buffer.bind();
|
draw_buffer.bind();
|
||||||
|
@ -153,9 +181,11 @@ namespace blt::gfx
|
||||||
frame_buffer_t::unbind();
|
frame_buffer_t::unbind();
|
||||||
}
|
}
|
||||||
|
|
||||||
void pp_outline_target::draw()
|
void pp_outline_target_t::draw()
|
||||||
{
|
{
|
||||||
draw_buffer.updateBuffersStorage(getWindowWidth(), getWindowHeight());
|
draw_buffer.updateBuffersStorage(getWindowWidth(), getWindowHeight());
|
||||||
|
const GLenum buffers[]{static_cast<GLenum>(frame_buffer_t::attachment_t::COLOR0), static_cast<GLenum>(frame_buffer_t::attachment_t::COLOR1)};
|
||||||
|
glDrawBuffers(2, buffers);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pp_outline_step_t::create()
|
void pp_outline_step_t::create()
|
||||||
|
@ -166,15 +196,86 @@ namespace blt::gfx
|
||||||
shader->setInt("mask", 1);
|
shader->setInt("mask", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pp_outline_step_t::draw(pp_step_t& previous)
|
void pp_outline_step_t::draw(frame_buffer_t& previous)
|
||||||
{
|
{
|
||||||
draw_buffer.updateBuffersStorage(getWindowWidth(), getWindowHeight());
|
draw_buffer.updateBuffersStorage(getWindowWidth(), getWindowHeight());
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
previous.getBuffer().getTexture(frame_buffer_t::attachment_t::COLOR0).bind();
|
previous.getTexture(frame_buffer_t::attachment_t::COLOR0).bind();
|
||||||
glActiveTexture(GL_TEXTURE1);
|
glActiveTexture(GL_TEXTURE1);
|
||||||
previous.getBuffer().getTexture(frame_buffer_t::attachment_t::COLOR1).bind();
|
previous.getTexture(frame_buffer_t::attachment_t::COLOR1).bind();
|
||||||
shader->bind();
|
shader->bind();
|
||||||
auto v = manager.getScale2D();
|
auto v = vec2(getWindowWidth(), getWindowHeight()) * (1.0 / blt::make_vec2(manager.getScale2D()));
|
||||||
shader->setVec2("viewportSize", static_cast<f32>(getWindowWidth()) * (1.0f/v.x()), static_cast<f32>(getWindowHeight()) * (1.0f / v.y()));
|
//BLT_TRACE_STREAM << v << '\n';
|
||||||
|
//shader->setVec2("viewportSize", static_cast<f32>(v.x()), static_cast<f32>(v.y()));
|
||||||
|
GLenum buf[]{static_cast<GLenum>(frame_buffer_t::attachment_t::COLOR0)};
|
||||||
|
glDrawBuffers(1, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pp_blur_step_t::create()
|
||||||
|
{
|
||||||
|
draw_buffer = frame_buffer_t::make_render_texture(getWindowWidth(), getWindowHeight());
|
||||||
|
shader = pp_engine_t::createShader(shader_gaussian_blur_frag);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pp_blur_step_t::draw(frame_buffer_t& previous)
|
||||||
|
{
|
||||||
|
draw_buffer.updateBuffersStorage(getWindowWidth(), getWindowHeight());
|
||||||
|
shader->bind();
|
||||||
|
shader->setVec4i("size", {getWindowWidth(), getWindowHeight(), x_blur, y_blur});
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
previous.getTexture(from).bind();
|
||||||
|
GLenum buf[]{static_cast<GLenum>(to)};
|
||||||
|
glDrawBuffers(1, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pp_blur_step_inplace_t::create()
|
||||||
|
{
|
||||||
|
draw_buffer = frame_buffer_t::make_render_texture(getWindowWidth(), getWindowHeight());
|
||||||
|
shader = pp_engine_t::createShader(shader_gaussian_blur_frag);
|
||||||
|
shader_pass = pp_engine_t::createShader(shader_pp_screen_frag);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pp_blur_step_inplace_t::draw(frame_buffer_t& previous)
|
||||||
|
{
|
||||||
|
draw_buffer.updateBuffersStorage(getWindowWidth(), getWindowHeight());
|
||||||
|
shader->bind();
|
||||||
|
//auto v = vec2(getWindowWidth(), getWindowHeight()) * (1.0 / blt::make_vec2(manager.getScale2D()));
|
||||||
|
auto v = vec2(getWindowWidth(), getWindowHeight());
|
||||||
|
shader->setVec4i("size", {static_cast<i32>(v.x()), static_cast<i32>(v.y()), x_blur, y_blur});
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
previous.getTexture(from).bind();
|
||||||
|
//GLenum buf[]{static_cast<GLenum>(to)};
|
||||||
|
GLenum buf[]{static_cast<GLenum>(frame_buffer_t::attachment_t::COLOR0)};
|
||||||
|
glDrawBuffers(1, buf);
|
||||||
|
draw_buffer.bind();
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pp_blur_step_inplace_t::post_draw(frame_buffer_t& previous)
|
||||||
|
{
|
||||||
|
//draw_buffer.blitTexture(previous, 0, 0, 0, 0, GL_NEAREST, from, to);
|
||||||
|
previous.bind();
|
||||||
|
GLenum buf[]{static_cast<GLenum>(to)};
|
||||||
|
glDrawBuffers(1, buf);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
shader_pass->bind();
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
draw_buffer.getTexture(frame_buffer_t::attachment_t::COLOR0).bind();
|
||||||
|
pp_engine_t::render_quad();
|
||||||
|
}
|
||||||
|
|
||||||
|
void pp_expansion_step_inplace_t::create()
|
||||||
|
{
|
||||||
|
shader = pp_engine_t::createShader(shader_multiplier_frag);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pp_expansion_step_inplace_t::draw(frame_buffer_t& previous)
|
||||||
|
{
|
||||||
|
shader->bind();
|
||||||
|
shader->setVec4("multiplier", multiplier);
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
previous.getTexture(from).bind();
|
||||||
|
GLenum buf[]{static_cast<u32>(to)};
|
||||||
|
glDrawBuffers(1, buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -322,6 +322,15 @@ namespace blt::gfx
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shader_base_t& shader_base_t::setVec4i(const std::string& name, const vec4i& vec)
|
||||||
|
{
|
||||||
|
if (auto i = getUniformLocation(name))
|
||||||
|
glUniform4i(i.i, vec.x(), vec.y(), vec.z(), vec.w());
|
||||||
|
else
|
||||||
|
BLT_WARN("Unable to find vec4i uniform variable %s", name.c_str());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
shader_base_t::IntDefaultedToMinusOne shader_base_t::getUniformLocation(const std::string& name)
|
shader_base_t::IntDefaultedToMinusOne shader_base_t::getUniformLocation(const std::string& name)
|
||||||
{
|
{
|
||||||
if (uniformVars[name])
|
if (uniformVars[name])
|
||||||
|
|
|
@ -152,10 +152,10 @@ blt::gfx::texture_file& blt::gfx::texture_file::resize(int target_width, int tar
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void blt::gfx::texture_gl::setDefaults(GLint type) const
|
void blt::gfx::texture_gl::setDefaults(GLint type, GLint wrap_type) const
|
||||||
{
|
{
|
||||||
glTexParameteri(textureBindType, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
glTexParameteri(textureBindType, GL_TEXTURE_WRAP_S, wrap_type);
|
||||||
glTexParameteri(textureBindType, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
glTexParameteri(textureBindType, GL_TEXTURE_WRAP_T, wrap_type);
|
||||||
// nearest preserves the pixely look
|
// nearest preserves the pixely look
|
||||||
#ifdef __EMSCRIPTEN__
|
#ifdef __EMSCRIPTEN__
|
||||||
glTexParameteri(textureBindType, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
glTexParameteri(textureBindType, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
@ -215,7 +215,7 @@ void blt::gfx::texture_gl2D::resize(int width, int height)
|
||||||
blt::gfx::texture_gl2D::texture_gl2D(int width, int height, GLint colorMode): texture_gl(width, height, GL_TEXTURE_2D, colorMode)
|
blt::gfx::texture_gl2D::texture_gl2D(int width, int height, GLint colorMode): texture_gl(width, height, GL_TEXTURE_2D, colorMode)
|
||||||
{
|
{
|
||||||
bind();
|
bind();
|
||||||
setDefaults(GL_LINEAR);
|
setDefaults(GL_LINEAR, GL_CLAMP_TO_EDGE);
|
||||||
resize(width, height);
|
resize(width, height);
|
||||||
//glTexStorage2D(textureBindType, 4, colorMode, width, height);
|
//glTexStorage2D(textureBindType, 4, colorMode, width, height);
|
||||||
}
|
}
|
||||||
|
@ -249,13 +249,17 @@ blt::gfx::texture_gl2D_multisample::texture_gl2D_multisample(int width, int heig
|
||||||
texture_gl(width, height, GL_TEXTURE_2D_MULTISAMPLE, colorMode), samples(samples)
|
texture_gl(width, height, GL_TEXTURE_2D_MULTISAMPLE, colorMode), samples(samples)
|
||||||
{
|
{
|
||||||
bind();
|
bind();
|
||||||
setDefaults(GL_LINEAR);
|
setDefaults(GL_LINEAR, GL_CLAMP_TO_EDGE);
|
||||||
//glTexImage2DMultisample(textureBindType, samples, colorMode, width, height, GL_TRUE);
|
//glTexImage2DMultisample(textureBindType, samples, colorMode, width, height, GL_TRUE);
|
||||||
glTexStorage2DMultisample(textureBindType, samples, colorMode, width, height, GL_TRUE);
|
glTexStorage2DMultisample(textureBindType, samples, colorMode, width, height, GL_TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void blt::gfx::texture_gl2D_multisample::resize(int width, int height)
|
void blt::gfx::texture_gl2D_multisample::resize(int width, int height)
|
||||||
{
|
{
|
||||||
|
if (m_width == width && m_height == height)
|
||||||
|
return;
|
||||||
|
m_width = width;
|
||||||
|
m_height = height;
|
||||||
bind();
|
bind();
|
||||||
//glTexImage2DMultisample(textureBindType, samples, textureColorMode, width, height, GL_TRUE);
|
//glTexImage2DMultisample(textureBindType, samples, textureColorMode, width, height, GL_TRUE);
|
||||||
glTexStorage2DMultisample(textureBindType, samples, textureColorMode, width, height, GL_TRUE);
|
glTexStorage2DMultisample(textureBindType, samples, textureColorMode, width, height, GL_TRUE);
|
||||||
|
|
Loading…
Reference in New Issue