post processing
parent
622b706618
commit
ecae5287cc
|
@ -1,6 +1,6 @@
|
||||||
cmake_minimum_required(VERSION 3.25)
|
cmake_minimum_required(VERSION 3.25)
|
||||||
|
|
||||||
set(BLT_GRAPHICS_VERSION 0.13.2)
|
set(BLT_GRAPHICS_VERSION 0.13.3)
|
||||||
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})
|
||||||
|
|
|
@ -123,6 +123,8 @@ namespace blt::gfx
|
||||||
|
|
||||||
static void unbind();
|
static void unbind();
|
||||||
|
|
||||||
|
static void bindScreen(draw_t type);
|
||||||
|
|
||||||
void destroy();
|
void destroy();
|
||||||
|
|
||||||
[[nodiscard]] i32 getHeight() const
|
[[nodiscard]] i32 getHeight() const
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "blt/gfx/shader.h"
|
#include "blt/gfx/shader.h"
|
||||||
#include "blt/gfx/framebuffer.h"
|
#include "blt/gfx/framebuffer.h"
|
||||||
#include "blt/gfx/renderer/resource_manager.h"
|
#include "blt/gfx/renderer/resource_manager.h"
|
||||||
|
#include "blt/gfx/renderer/postprocess.h"
|
||||||
#include <blt/std/hashmap.h>
|
#include <blt/std/hashmap.h>
|
||||||
#include <blt/std/memory_util.h>
|
#include <blt/std/memory_util.h>
|
||||||
#include <blt/math/vectors.h>
|
#include <blt/math/vectors.h>
|
||||||
|
@ -148,7 +149,7 @@ namespace blt::gfx
|
||||||
class batch_renderer_2d
|
class batch_renderer_2d
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
frame_buffer_t draw_buffer;
|
pp_engine_t engine;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct render_object_t
|
struct render_object_t
|
||||||
|
|
|
@ -28,56 +28,74 @@
|
||||||
|
|
||||||
namespace blt::gfx
|
namespace blt::gfx
|
||||||
{
|
{
|
||||||
namespace detail
|
class pp_engine_t;
|
||||||
{
|
|
||||||
class pp_link;
|
|
||||||
|
|
||||||
class pp_iterator;
|
|
||||||
|
|
||||||
class pp_link
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
class pp_iterator
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
class pp_step
|
class pp_step_t;
|
||||||
|
|
||||||
|
class pp_step_t
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual void create(i32 width, i32 height) = 0;
|
virtual void create() = 0;
|
||||||
|
|
||||||
virtual void draw(i32 width, i32 height) = 0;
|
virtual void draw() = 0;
|
||||||
|
|
||||||
frame_buffer_t& getBuffer()
|
frame_buffer_t& getBuffer()
|
||||||
{
|
{
|
||||||
return draw_buffer;
|
return draw_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shader_t& getShader()
|
||||||
|
{
|
||||||
|
return *shader;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~pp_step_t() = default;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
frame_buffer_t draw_buffer;
|
frame_buffer_t draw_buffer;
|
||||||
|
std::unique_ptr<shader_t> shader;
|
||||||
};
|
};
|
||||||
|
|
||||||
class pp_engine
|
class pp_render_target_t : public pp_step_t
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void create() override;
|
||||||
|
|
||||||
|
void draw() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class pp_to_screen_step_t : public pp_step_t
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void create() override;
|
||||||
|
|
||||||
|
void draw() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class pp_engine_t
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void create();
|
void create();
|
||||||
|
|
||||||
void render(i32 width, i32 height);
|
void bind();
|
||||||
|
|
||||||
|
void render();
|
||||||
|
|
||||||
|
void cleanup();
|
||||||
|
|
||||||
|
void addStep(std::unique_ptr<pp_step_t> step)
|
||||||
|
{
|
||||||
|
steps.emplace_back(std::move(step));
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::unique_ptr<shader_t> createShader(std::string_view fragment);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<std::unique_ptr<pp_step>> steps;
|
std::vector<std::unique_ptr<pp_step_t>> steps;
|
||||||
shader_t screen_shader;
|
std::unique_ptr<vertex_array_t> screen_vao;
|
||||||
|
#ifdef __EMSCRIPTEN__
|
||||||
|
std::unique_ptr<pp_to_screen_step_t> to_screen;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#include <string>
|
||||||
|
const std::string shader_postprocess_vert = R"("
|
||||||
|
#version 300 es
|
||||||
|
precision mediump float;
|
||||||
|
|
||||||
|
layout (location = 0) in vec3 vertex;
|
||||||
|
layout (location = 1) in vec2 uv_in;
|
||||||
|
|
||||||
|
out vec2 pos;
|
||||||
|
out vec2 uv;
|
||||||
|
|
||||||
|
layout (std140) uniform GlobalMatrices
|
||||||
|
{
|
||||||
|
mat4 projection;
|
||||||
|
mat4 ortho;
|
||||||
|
mat4 view;
|
||||||
|
mat4 pvm;
|
||||||
|
mat4 ovm;
|
||||||
|
};
|
||||||
|
|
||||||
|
uniform mat4 model;
|
||||||
|
uniform float z_index;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_Position = ovm * model * vec4(vertex.xy, z_index, 1.0);
|
||||||
|
pos = vertex.xy;
|
||||||
|
uv = uv_in;
|
||||||
|
}
|
||||||
|
|
||||||
|
")";
|
||||||
|
#endif
|
|
@ -0,0 +1,22 @@
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#include <string>
|
||||||
|
const std::string shader_pp_to_screen_frag = R"("
|
||||||
|
#version 300 es
|
||||||
|
precision mediump float;
|
||||||
|
|
||||||
|
out vec4 FragColor;
|
||||||
|
in vec2 uv;
|
||||||
|
in vec2 pos;
|
||||||
|
|
||||||
|
uniform sampler2D tex;
|
||||||
|
|
||||||
|
vec4 linear_iter(vec4 i, vec4 p, float factor){
|
||||||
|
return (i + p) * factor;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
FragColor = texture(tex, uv);
|
||||||
|
}
|
||||||
|
|
||||||
|
")";
|
||||||
|
#endif
|
|
@ -9,6 +9,7 @@
|
||||||
#define BLT_WITH_GRAPHICS_TEMPLATE_WINDOW_H
|
#define BLT_WITH_GRAPHICS_TEMPLATE_WINDOW_H
|
||||||
|
|
||||||
#include <blt/gfx/gl_includes.h>
|
#include <blt/gfx/gl_includes.h>
|
||||||
|
#include <blt/std/types.h>
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
@ -19,11 +20,11 @@ namespace blt::gfx
|
||||||
{
|
{
|
||||||
struct window_context
|
struct window_context
|
||||||
{
|
{
|
||||||
std::int32_t GL_MAJOR = 4;
|
i32 GL_MAJOR = 4;
|
||||||
std::int32_t GL_MINOR = 6;
|
i32 GL_MINOR = 6;
|
||||||
std::int32_t DOUBLE_BUFFER = GLFW_TRUE;
|
i32 DOUBLE_BUFFER = GLFW_TRUE;
|
||||||
std::int32_t GL_PROFILE = GLFW_OPENGL_CORE_PROFILE;
|
i32 GL_PROFILE = GLFW_OPENGL_CORE_PROFILE;
|
||||||
std::int32_t SAMPLES = 8;
|
i32 SAMPLES = 8;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct window_data
|
struct window_data
|
||||||
|
@ -39,9 +40,9 @@ namespace blt::gfx
|
||||||
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(const window_data&)> init, std::function<void(const window_data&)> update,
|
window_data(std::string_view title, std::function<void(const window_data&)> init, std::function<void(const window_data&)> update,
|
||||||
std::int32_t width = 640, std::int32_t height = 480): init(std::move(init)), update(std::move(update)),
|
i32 width = 640, i32 height = 480): init(std::move(init)), update(std::move(update)),
|
||||||
title(std::move(title)), width(width), height(height)
|
title(title), width(width), height(height)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
inline void call_init() const
|
inline void call_init() const
|
||||||
|
@ -128,7 +129,11 @@ namespace blt::gfx
|
||||||
|
|
||||||
double getFrameDeltaMilliseconds();
|
double getFrameDeltaMilliseconds();
|
||||||
|
|
||||||
std::int64_t getFrameDelta();
|
i64 getFrameDelta();
|
||||||
|
|
||||||
|
i32 getWindowWidth();
|
||||||
|
|
||||||
|
i32 getWindowHeight();
|
||||||
|
|
||||||
void cleanup();
|
void cleanup();
|
||||||
|
|
||||||
|
|
|
@ -279,9 +279,14 @@ namespace blt::gfx
|
||||||
fbo.attachRenderBuffer(depth_rbo, attachment_t::DEPTH_STENCIL);
|
fbo.attachRenderBuffer(depth_rbo, attachment_t::DEPTH_STENCIL);
|
||||||
|
|
||||||
if (!frame_buffer_t::validate())
|
if (!frame_buffer_t::validate())
|
||||||
BLT_ERROR("Failed to create multi-sampled render texture framebuffer!");
|
BLT_ERROR("Failed to create render texture framebuffer!");
|
||||||
frame_buffer_t::unbind();
|
frame_buffer_t::unbind();
|
||||||
|
|
||||||
return fbo;
|
return fbo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void frame_buffer_t::bindScreen(frame_buffer_t::draw_t type)
|
||||||
|
{
|
||||||
|
glBindFramebuffer(static_cast<i32>(type), 0);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -89,20 +89,23 @@ namespace blt::gfx
|
||||||
point_shader->bindAttribute(0, "vertex");
|
point_shader->bindAttribute(0, "vertex");
|
||||||
point_shader->bindAttribute(1, "uv_in");
|
point_shader->bindAttribute(1, "uv_in");
|
||||||
|
|
||||||
draw_buffer.create();
|
engine.addStep(std::make_unique<pp_render_target_t>());
|
||||||
draw_buffer.bind();
|
engine.create();
|
||||||
|
|
||||||
auto* texture = new texture_gl2D(1440, 720);
|
// draw_buffer.create();
|
||||||
draw_buffer.attachTexture(texture, frame_buffer_t::attachment_t::COLOR0);
|
// draw_buffer.bind();
|
||||||
auto* mask = new texture_gl2D(1440, 720);
|
//
|
||||||
draw_buffer.attachTexture(mask, frame_buffer_t::attachment_t::COLOR1);
|
// auto* texture = new texture_gl2D(1440, 720);
|
||||||
|
// draw_buffer.attachTexture(texture, frame_buffer_t::attachment_t::COLOR0);
|
||||||
render_buffer_t depth_rbo = render_buffer_t::make_render_buffer(GL_DEPTH24_STENCIL8, 1440, 720);
|
// auto* mask = new texture_gl2D(1440, 720);
|
||||||
draw_buffer.attachRenderBuffer(depth_rbo, frame_buffer_t::attachment_t::DEPTH_STENCIL);
|
// draw_buffer.attachTexture(mask, frame_buffer_t::attachment_t::COLOR1);
|
||||||
|
//
|
||||||
if (!frame_buffer_t::validate())
|
// render_buffer_t depth_rbo = render_buffer_t::make_render_buffer(GL_DEPTH24_STENCIL8, 1440, 720);
|
||||||
BLT_ERROR("Failed to create render framebuffer!");
|
// draw_buffer.attachRenderBuffer(depth_rbo, frame_buffer_t::attachment_t::DEPTH_STENCIL);
|
||||||
frame_buffer_t::unbind();
|
//
|
||||||
|
// if (!frame_buffer_t::validate())
|
||||||
|
// BLT_ERROR("Failed to create render framebuffer!");
|
||||||
|
// frame_buffer_t::unbind();
|
||||||
}
|
}
|
||||||
|
|
||||||
void batch_renderer_2d::drawRectangleInternal(const std::string_view texture, const rectangle2d_t& rectangle, const f32 z_index)
|
void batch_renderer_2d::drawRectangleInternal(const std::string_view texture, const rectangle2d_t& rectangle, const f32 z_index)
|
||||||
|
@ -161,6 +164,7 @@ namespace blt::gfx
|
||||||
|
|
||||||
void batch_renderer_2d::cleanup()
|
void batch_renderer_2d::cleanup()
|
||||||
{
|
{
|
||||||
|
engine.cleanup();
|
||||||
delete square_vao;
|
delete square_vao;
|
||||||
delete square_shader;
|
delete square_shader;
|
||||||
delete point_shader;
|
delete point_shader;
|
||||||
|
@ -168,8 +172,8 @@ namespace blt::gfx
|
||||||
|
|
||||||
void batch_renderer_2d::render(i32 width, i32 height, const bool transparency)
|
void batch_renderer_2d::render(i32 width, i32 height, const bool transparency)
|
||||||
{
|
{
|
||||||
draw_buffer.bind();
|
//draw_buffer.bind();
|
||||||
draw_buffer.updateBuffersStorage(width, height);
|
//draw_buffer.updateBuffersStorage(width, height);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
if (transparency)
|
if (transparency)
|
||||||
{
|
{
|
||||||
|
@ -179,6 +183,7 @@ namespace blt::gfx
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
|
||||||
|
engine.bind();
|
||||||
draw_objects();
|
draw_objects();
|
||||||
|
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
@ -186,8 +191,9 @@ namespace blt::gfx
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
|
|
||||||
render_reset();
|
render_reset();
|
||||||
draw_buffer.blitToScreen(width, height);
|
|
||||||
frame_buffer_t::unbind();
|
frame_buffer_t::unbind();
|
||||||
|
|
||||||
|
engine.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
void batch_renderer_2d::draw_objects()
|
void batch_renderer_2d::draw_objects()
|
||||||
|
|
|
@ -15,17 +15,115 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#include <blt/gfx/renderer/post_process.h>
|
#include <blt/gfx/window.h>
|
||||||
|
#include <blt/gfx/renderer/postprocess.h>
|
||||||
|
#include <blt/gfx/renderer/shaders/postprocess.vert>
|
||||||
|
#include <blt/gfx/renderer/shaders/pp_to_screen.frag>
|
||||||
|
#include <blt/std/ranges.h>
|
||||||
|
|
||||||
|
|
||||||
|
float full_screen_vertices[20] = {
|
||||||
|
1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
|
||||||
|
1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
|
||||||
|
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
|
||||||
|
-1.0f, 1.0f, 0.0f, 0.0f, 1.0f
|
||||||
|
};
|
||||||
|
const unsigned int full_screen_indices[6] = {
|
||||||
|
0, 1, 3,
|
||||||
|
1, 2, 3
|
||||||
|
};
|
||||||
|
|
||||||
namespace blt::gfx
|
namespace blt::gfx
|
||||||
{
|
{
|
||||||
void pp_engine::create()
|
void pp_engine_t::create()
|
||||||
{
|
{
|
||||||
|
{
|
||||||
|
vertex_buffer_t vertices_vbo;
|
||||||
|
element_buffer_t indices_vbo;
|
||||||
|
|
||||||
|
vertices_vbo.create();
|
||||||
|
indices_vbo.create();
|
||||||
|
|
||||||
|
vertices_vbo.allocate(sizeof(full_screen_vertices), full_screen_vertices);
|
||||||
|
indices_vbo.allocate(sizeof(full_screen_indices), full_screen_indices);
|
||||||
|
|
||||||
|
screen_vao = std::make_unique<vertex_array_t>();
|
||||||
|
const auto tb = screen_vao->bindVBO(vertices_vbo, 0, 3, GL_FLOAT, 5 * sizeof(float), 0);
|
||||||
|
screen_vao->bindVBO(tb, 1, 2, GL_FLOAT, 5 * sizeof(float), 3 * sizeof(float));
|
||||||
|
screen_vao->bindElement(indices_vbo);
|
||||||
|
}
|
||||||
|
#ifdef __EMSCRIPTEN__
|
||||||
|
to_screen = std::make_unique<pp_to_screen_step_t>();
|
||||||
|
#endif
|
||||||
|
for (auto& step : steps)
|
||||||
|
step->create();
|
||||||
}
|
}
|
||||||
|
|
||||||
void pp_engine::render(i32 width, i32 height)
|
void pp_engine_t::render()
|
||||||
{
|
{
|
||||||
|
screen_vao->bind();
|
||||||
|
for (const auto& [index, step] : blt::enumerate(steps))
|
||||||
|
{
|
||||||
|
if (index == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
} else
|
||||||
|
steps[index - 1]->getBuffer().bind(frame_buffer_t::draw_t::READ);
|
||||||
|
step->draw();
|
||||||
|
step->getBuffer().bind(frame_buffer_t::draw_t::DRAW);
|
||||||
|
step->getShader().bind();
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||||
|
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
|
||||||
|
}
|
||||||
|
frame_buffer_t::unbind();
|
||||||
|
#ifdef __EMSCRIPTEN__
|
||||||
|
to_screen->getShader().bind();
|
||||||
|
steps.back()->getBuffer().bind(frame_buffer_t::draw_t::READ);
|
||||||
|
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
|
||||||
|
#else
|
||||||
|
steps.back()->getBuffer().blitToScreen(getWindowWidth(), getWindowHeight());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void pp_engine_t::cleanup()
|
||||||
|
{
|
||||||
|
screen_vao = nullptr;
|
||||||
|
for (auto& v : steps)
|
||||||
|
v = nullptr;
|
||||||
|
steps.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<shader_t> pp_engine_t::createShader(std::string_view fragment)
|
||||||
|
{
|
||||||
|
auto shader = std::make_unique<shader_t>(shader_postprocess_vert, std::string(fragment));
|
||||||
|
shader->bindAttribute(0, "vertex");
|
||||||
|
shader->bindAttribute(1, "uv_in");
|
||||||
|
return shader;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pp_engine_t::bind()
|
||||||
|
{
|
||||||
|
steps.front()->draw();
|
||||||
|
steps.front()->getBuffer().bind(frame_buffer_t::draw_t::DRAW);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pp_to_screen_step_t::create()
|
||||||
|
{
|
||||||
|
shader = pp_engine_t::createShader(shader_pp_to_screen_frag);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pp_to_screen_step_t::draw()
|
||||||
|
{}
|
||||||
|
|
||||||
|
void pp_render_target_t::create()
|
||||||
|
{
|
||||||
|
shader = pp_engine_t::createShader(shader_pp_to_screen_frag);
|
||||||
|
draw_buffer = frame_buffer_t::make_render_target(getWindowWidth(), getWindowHeight());
|
||||||
|
}
|
||||||
|
|
||||||
|
void pp_render_target_t::draw()
|
||||||
|
{
|
||||||
|
draw_buffer.updateBuffersStorage(getWindowWidth(), getWindowHeight());
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -46,7 +46,7 @@ namespace blt::gfx
|
||||||
double nanoDelta = 0;
|
double nanoDelta = 0;
|
||||||
double millisDelta = 0;
|
double millisDelta = 0;
|
||||||
} window_state;
|
} window_state;
|
||||||
|
|
||||||
void create_callbacks()
|
void create_callbacks()
|
||||||
{
|
{
|
||||||
/* Setup keyboard callback */
|
/* Setup keyboard callback */
|
||||||
|
@ -68,7 +68,7 @@ namespace blt::gfx
|
||||||
window_state.inputManager.key(key) = state;
|
window_state.inputManager.key(key) = state;
|
||||||
window_state.inputManager.key_pressed = true;
|
window_state.inputManager.key_pressed = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
/* Setup mouse button callback */
|
/* Setup mouse button callback */
|
||||||
glfwSetMouseButtonCallback(window_state.window, [](GLFWwindow*, int button, int action, int) {
|
glfwSetMouseButtonCallback(window_state.window, [](GLFWwindow*, int button, int action, int) {
|
||||||
if (button < 0)
|
if (button < 0)
|
||||||
|
@ -86,40 +86,40 @@ namespace blt::gfx
|
||||||
window_state.inputManager.mouse(button) = state;
|
window_state.inputManager.mouse(button) = state;
|
||||||
window_state.inputManager.mouse_pressed = true;
|
window_state.inputManager.mouse_pressed = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
/* Setup mouse cursor callback */
|
/* Setup mouse cursor callback */
|
||||||
glfwSetCursorPosCallback(window_state.window, [](GLFWwindow*, double x, double y) {
|
glfwSetCursorPosCallback(window_state.window, [](GLFWwindow*, double x, double y) {
|
||||||
window_state.inputManager.updateMousePos(x, y);
|
window_state.inputManager.updateMousePos(x, y);
|
||||||
window_state.inputManager.mouse_moved = true;
|
window_state.inputManager.mouse_moved = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
/* Setup mouse scroll callback */
|
/* Setup mouse scroll callback */
|
||||||
glfwSetScrollCallback(window_state.window, [](GLFWwindow*, double, double s) { window_state.inputManager.updateScroll(s); });
|
glfwSetScrollCallback(window_state.window, [](GLFWwindow*, double, double s) { window_state.inputManager.updateScroll(s); });
|
||||||
|
|
||||||
/* Setup drop input callback */
|
/* Setup drop input callback */
|
||||||
glfwSetDropCallback(window_state.window, [](GLFWwindow*, int count, const char** paths) {
|
glfwSetDropCallback(window_state.window, [](GLFWwindow*, int count, const char** paths) {
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
window_state.pendingPaths.emplace(paths[i]);
|
window_state.pendingPaths.emplace(paths[i]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup_ImGUI()
|
void setup_ImGUI()
|
||||||
{
|
{
|
||||||
const char* glsl_version = "#version 100";
|
const char* glsl_version = "#version 100";
|
||||||
|
|
||||||
// Setup Dear ImGui context
|
// Setup Dear ImGui context
|
||||||
IMGUI_CHECKVERSION();
|
IMGUI_CHECKVERSION();
|
||||||
ImGui::CreateContext();
|
ImGui::CreateContext();
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||||
|
|
||||||
// Setup Dear ImGui style
|
// Setup Dear ImGui style
|
||||||
ImGui::StyleColorsDark();
|
ImGui::StyleColorsDark();
|
||||||
//ImGui::Spectrum::StyleColorsSpectrum();
|
//ImGui::Spectrum::StyleColorsSpectrum();
|
||||||
ImGui::Spectrum::LoadFont();
|
ImGui::Spectrum::LoadFont();
|
||||||
ImGui::SetupImGuiStyle(true, 1.0);
|
ImGui::SetupImGuiStyle(true, 1.0);
|
||||||
|
|
||||||
// Setup FA
|
// Setup FA
|
||||||
ImFontConfig config;
|
ImFontConfig config;
|
||||||
config.MergeMode = true;
|
config.MergeMode = true;
|
||||||
|
@ -131,9 +131,9 @@ namespace blt::gfx
|
||||||
io.Fonts->AddFontFromMemoryCompressedTTF(fontAwesomeBrands_compressed_data, static_cast<int>(fontAwesomeBrands_compressed_size), 13.0,
|
io.Fonts->AddFontFromMemoryCompressedTTF(fontAwesomeBrands_compressed_data, static_cast<int>(fontAwesomeBrands_compressed_size), 13.0,
|
||||||
&config,
|
&config,
|
||||||
icon_ranges);
|
icon_ranges);
|
||||||
|
|
||||||
//ImGui::StyleColorsLight();
|
//ImGui::StyleColorsLight();
|
||||||
|
|
||||||
// Setup Platform/Renderer backends
|
// Setup Platform/Renderer backends
|
||||||
ImGui_ImplGlfw_InitForOpenGL(window_state.window, true);
|
ImGui_ImplGlfw_InitForOpenGL(window_state.window, true);
|
||||||
#ifdef __EMSCRIPTEN__
|
#ifdef __EMSCRIPTEN__
|
||||||
|
@ -145,7 +145,7 @@ namespace blt::gfx
|
||||||
io.IniFilename = nullptr;
|
io.IniFilename = nullptr;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop(void* arg)
|
void loop(void* arg)
|
||||||
{
|
{
|
||||||
auto& data = *((window_data*) arg);
|
auto& data = *((window_data*) arg);
|
||||||
|
@ -156,24 +156,24 @@ namespace blt::gfx
|
||||||
data.height = window_state.height;
|
data.height = window_state.height;
|
||||||
// TODO: user option for this
|
// TODO: user option for this
|
||||||
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);
|
||||||
|
|
||||||
/* -- Begin the next ImGUI frame -- */
|
/* -- Begin the next ImGUI frame -- */
|
||||||
ImGui_ImplOpenGL3_NewFrame();
|
ImGui_ImplOpenGL3_NewFrame();
|
||||||
ImGui_ImplGlfw_NewFrame();
|
ImGui_ImplGlfw_NewFrame();
|
||||||
ImGui::NewFrame();
|
ImGui::NewFrame();
|
||||||
|
|
||||||
/* -- Call user update function -- */
|
/* -- Call user update function -- */
|
||||||
data.call_update();
|
data.call_update();
|
||||||
|
|
||||||
/* -- Render the ImGUI frame -- */
|
/* -- Render the ImGUI frame -- */
|
||||||
ImGui::Render();
|
ImGui::Render();
|
||||||
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
||||||
|
|
||||||
/* -- Update GLFW state -- */
|
/* -- Update GLFW state -- */
|
||||||
window_state.inputManager.clear();
|
window_state.inputManager.clear();
|
||||||
glfwSwapBuffers(window_state.window);
|
glfwSwapBuffers(window_state.window);
|
||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
|
|
||||||
/* -- Update Frame Timing Information -- */
|
/* -- Update Frame Timing Information -- */
|
||||||
const auto current_time = system::nanoTime();
|
const auto current_time = system::nanoTime();
|
||||||
window_state.deltaTime = current_time - window_state.lastTime;
|
window_state.deltaTime = current_time - window_state.lastTime;
|
||||||
|
@ -183,7 +183,7 @@ namespace blt::gfx
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __EMSCRIPTEN__
|
#ifdef __EMSCRIPTEN__
|
||||||
|
|
||||||
EM_BOOL emscripten_resize_callback(int, const EmscriptenUiEvent* event, void* data)
|
EM_BOOL emscripten_resize_callback(int, const EmscriptenUiEvent* event, void* data)
|
||||||
{
|
{
|
||||||
int width = event->documentBodyClientWidth;
|
int width = event->documentBodyClientWidth;
|
||||||
|
@ -203,7 +203,7 @@ namespace blt::gfx
|
||||||
});
|
});
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void init(window_data data)
|
void init(window_data data)
|
||||||
{
|
{
|
||||||
#ifdef __EMSCRIPTEN__
|
#ifdef __EMSCRIPTEN__
|
||||||
|
@ -217,28 +217,28 @@ namespace blt::gfx
|
||||||
/* -- Set up Error Callback -- */
|
/* -- Set up Error Callback -- */
|
||||||
glfwSetErrorCallback(error_callback);
|
glfwSetErrorCallback(error_callback);
|
||||||
BLT_ASSERT(glfwInit() && "Unable to init GLFW. Aborting.");
|
BLT_ASSERT(glfwInit() && "Unable to init GLFW. Aborting.");
|
||||||
|
|
||||||
/* -- Set up Window Context -- */
|
/* -- Set up Window Context -- */
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, data.context.GL_MAJOR);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, data.context.GL_MAJOR);
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, data.context.GL_MINOR);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, data.context.GL_MINOR);
|
||||||
glfwWindowHint(GLFW_DOUBLEBUFFER, data.context.DOUBLE_BUFFER);
|
glfwWindowHint(GLFW_DOUBLEBUFFER, data.context.DOUBLE_BUFFER);
|
||||||
glfwWindowHint(GLFW_OPENGL_PROFILE, data.context.GL_PROFILE);
|
glfwWindowHint(GLFW_OPENGL_PROFILE, data.context.GL_PROFILE);
|
||||||
glfwWindowHint(GLFW_SAMPLES, data.context.SAMPLES);
|
glfwWindowHint(GLFW_SAMPLES, data.context.SAMPLES);
|
||||||
|
|
||||||
/* -- Create the Window -- */
|
/* -- Create the Window -- */
|
||||||
window_state.window = glfwCreateWindow(data.width, data.height, data.title.c_str(), nullptr, nullptr);
|
window_state.window = glfwCreateWindow(data.width, data.height, data.title.c_str(), nullptr, nullptr);
|
||||||
BLT_ASSERT(window_state.window && "Unable to create GLFW window.");
|
BLT_ASSERT(window_state.window && "Unable to create GLFW window.");
|
||||||
|
|
||||||
/* -- Set Window Specifics + OpenGL -- */
|
/* -- Set Window Specifics + OpenGL -- */
|
||||||
glfwMakeContextCurrent(window_state.window);
|
glfwMakeContextCurrent(window_state.window);
|
||||||
#ifndef __EMSCRIPTEN__
|
#ifndef __EMSCRIPTEN__
|
||||||
glfwSwapInterval(data.sync_interval);
|
glfwSwapInterval(data.sync_interval);
|
||||||
gladLoadGL(glfwGetProcAddress);
|
gladLoadGL(glfwGetProcAddress);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* -- Set up our local callbacks, ImGUI will then call these -- */
|
/* -- Set up our local callbacks, ImGUI will then call these -- */
|
||||||
create_callbacks();
|
create_callbacks();
|
||||||
|
|
||||||
/* -- Set up ImGUI -- */
|
/* -- Set up ImGUI -- */
|
||||||
setup_ImGUI();
|
setup_ImGUI();
|
||||||
|
|
||||||
|
@ -246,7 +246,10 @@ namespace blt::gfx
|
||||||
if (data.context.SAMPLES > 0)
|
if (data.context.SAMPLES > 0)
|
||||||
glEnable(GL_MULTISAMPLE);
|
glEnable(GL_MULTISAMPLE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
window_state.width = data.width;
|
||||||
|
window_state.height = data.height;
|
||||||
|
|
||||||
/* -- Call User Provided post-window-init function -- */
|
/* -- Call User Provided post-window-init function -- */
|
||||||
data.call_init();
|
data.call_init();
|
||||||
|
|
||||||
|
@ -264,31 +267,38 @@ namespace blt::gfx
|
||||||
loop((void*) &data);
|
loop((void*) &data);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void cleanup()
|
void cleanup()
|
||||||
{
|
{
|
||||||
ImGui_ImplOpenGL3_Shutdown();
|
ImGui_ImplOpenGL3_Shutdown();
|
||||||
ImGui_ImplGlfw_Shutdown();
|
ImGui_ImplGlfw_Shutdown();
|
||||||
ImGui::DestroyContext();
|
ImGui::DestroyContext();
|
||||||
|
|
||||||
glfwDestroyWindow(window_state.window);
|
glfwDestroyWindow(window_state.window);
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
}
|
}
|
||||||
|
|
||||||
double getMouseX() { return window_state.inputManager.mouseX; }
|
double getMouseX()
|
||||||
|
{ return window_state.inputManager.mouseX; }
|
||||||
double getMouseY() { return window_state.inputManager.mouseY; }
|
|
||||||
|
double getMouseY()
|
||||||
double getMouseDX() { return window_state.inputManager.deltaX; }
|
{ return window_state.inputManager.mouseY; }
|
||||||
|
|
||||||
double getMouseDY() { return window_state.inputManager.deltaY; }
|
double getMouseDX()
|
||||||
|
{ return window_state.inputManager.deltaX; }
|
||||||
void lockCursor() { glfwSetInputMode(window_state.window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); }
|
|
||||||
|
double getMouseDY()
|
||||||
void unlockCursor() { glfwSetInputMode(window_state.window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); }
|
{ return window_state.inputManager.deltaY; }
|
||||||
|
|
||||||
bool isCursorLocked() { return glfwGetInputMode(window_state.window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED; }
|
void lockCursor()
|
||||||
|
{ glfwSetInputMode(window_state.window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); }
|
||||||
|
|
||||||
|
void unlockCursor()
|
||||||
|
{ glfwSetInputMode(window_state.window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); }
|
||||||
|
|
||||||
|
bool isCursorLocked()
|
||||||
|
{ return glfwGetInputMode(window_state.window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED; }
|
||||||
|
|
||||||
bool isCursorInWindow()
|
bool isCursorInWindow()
|
||||||
{
|
{
|
||||||
#ifdef __EMSCRIPTEN__
|
#ifdef __EMSCRIPTEN__
|
||||||
|
@ -298,7 +308,7 @@ namespace blt::gfx
|
||||||
return glfwGetWindowAttrib(window_state.window, GLFW_HOVERED);
|
return glfwGetWindowAttrib(window_state.window, GLFW_HOVERED);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void setRawInput(bool state)
|
void setRawInput(bool state)
|
||||||
{
|
{
|
||||||
#ifdef __EMSCRIPTEN__
|
#ifdef __EMSCRIPTEN__
|
||||||
|
@ -308,7 +318,7 @@ namespace blt::gfx
|
||||||
glfwSetInputMode(window_state.window, GLFW_RAW_MOUSE_MOTION, state ? GLFW_TRUE : GLFW_FALSE);
|
glfwSetInputMode(window_state.window, GLFW_RAW_MOUSE_MOTION, state ? GLFW_TRUE : GLFW_FALSE);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isRawInput()
|
bool isRawInput()
|
||||||
{
|
{
|
||||||
#ifdef __EMSCRIPTEN__
|
#ifdef __EMSCRIPTEN__
|
||||||
|
@ -317,27 +327,43 @@ namespace blt::gfx
|
||||||
return glfwGetInputMode(window_state.window, GLFW_RAW_MOUSE_MOTION);
|
return glfwGetInputMode(window_state.window, GLFW_RAW_MOUSE_MOTION);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void setClipboard(const std::string& str) { glfwSetClipboardString(window_state.window, str.c_str()); }
|
void setClipboard(const std::string& str)
|
||||||
|
{ glfwSetClipboardString(window_state.window, str.c_str()); }
|
||||||
std::string getClipboard() { return glfwGetClipboardString(window_state.window); }
|
|
||||||
|
std::string getClipboard()
|
||||||
bool isMousePressed(int button) { return window_state.inputManager.isMousePressed(button); }
|
{ return glfwGetClipboardString(window_state.window); }
|
||||||
|
|
||||||
bool isKeyPressed(int key) { return window_state.inputManager.isKeyPressed(key); }
|
bool isMousePressed(int button)
|
||||||
|
{ return window_state.inputManager.isMousePressed(button); }
|
||||||
double getFrameDeltaSeconds() { return window_state.nanoDelta; }
|
|
||||||
|
bool isKeyPressed(int key)
|
||||||
double getFrameDeltaMilliseconds() { return window_state.millisDelta; }
|
{ return window_state.inputManager.isKeyPressed(key); }
|
||||||
|
|
||||||
std::int64_t getFrameDelta() { return window_state.deltaTime; }
|
double getFrameDeltaSeconds()
|
||||||
|
{ return window_state.nanoDelta; }
|
||||||
bool mouseMovedLastFrame() { return window_state.inputManager.mouse_moved; }
|
|
||||||
|
double getFrameDeltaMilliseconds()
|
||||||
bool mousePressedLastFrame() { return window_state.inputManager.mouse_pressed; }
|
{ return window_state.millisDelta; }
|
||||||
|
|
||||||
bool keyPressedLastFrame() { return window_state.inputManager.key_pressed; }
|
i64 getFrameDelta()
|
||||||
|
{ return window_state.deltaTime; }
|
||||||
|
|
||||||
|
bool mouseMovedLastFrame()
|
||||||
|
{ return window_state.inputManager.mouse_moved; }
|
||||||
|
|
||||||
|
bool mousePressedLastFrame()
|
||||||
|
{ return window_state.inputManager.mouse_pressed; }
|
||||||
|
|
||||||
|
bool keyPressedLastFrame()
|
||||||
|
{ return window_state.inputManager.key_pressed; }
|
||||||
|
|
||||||
|
i32 getWindowHeight()
|
||||||
|
{ return window_state.height; }
|
||||||
|
|
||||||
|
i32 getWindowWidth()
|
||||||
|
{ return window_state.width; }
|
||||||
|
|
||||||
window_data& window_data::setWindowSize(int32_t new_width, int32_t new_height)
|
window_data& window_data::setWindowSize(int32_t new_width, int32_t new_height)
|
||||||
{
|
{
|
||||||
width = new_width;
|
width = new_width;
|
||||||
|
|
Loading…
Reference in New Issue