post processing

main
Brett 2024-05-05 17:03:50 -04:00
parent eb761557f0
commit 7c61323a05
14 changed files with 364 additions and 67 deletions

View File

@ -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})

View File

@ -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();

View File

@ -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:
@ -145,9 +261,13 @@ namespace blt::gfx
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;
}; };

View File

@ -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

View File

@ -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

View File

@ -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);
} }
")"; ")";

View File

@ -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);

View File

@ -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

View File

@ -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);
} }

View File

@ -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);

View File

@ -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);
} }
} }

View File

@ -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])

View File

@ -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);