post processing works on emscripten now
parent
2c85c0f93c
commit
a6853e6ff7
|
@ -1,6 +1,6 @@
|
||||||
cmake_minimum_required(VERSION 3.25)
|
cmake_minimum_required(VERSION 3.25)
|
||||||
|
|
||||||
set(BLT_GRAPHICS_VERSION 0.13.10)
|
set(BLT_GRAPHICS_VERSION 0.13.11)
|
||||||
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})
|
||||||
|
|
|
@ -216,7 +216,7 @@ namespace blt::gfx
|
||||||
std::make_unique<pp_blur_step_inplace_t>(state, frame_buffer_t::attachment_t::COLOR1),
|
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,
|
std::make_unique<pp_expansion_step_inplace_t>(frame_buffer_t::attachment_t::COLOR1,
|
||||||
vec4{4, 4, 4, 1}),
|
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_overlay_blur_step_t>(frame_buffer_t::attachment_t::COLOR1, 2, 2),
|
||||||
std::make_unique<pp_outline_step_t>(state)
|
std::make_unique<pp_outline_step_t>(state)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <blt/std/assert.h>
|
#include <blt/std/assert.h>
|
||||||
|
#include <blt/parse/templating.h>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
namespace blt::gfx
|
namespace blt::gfx
|
||||||
{
|
{
|
||||||
|
@ -171,6 +173,27 @@ namespace blt::gfx
|
||||||
i32 y_blur;
|
i32 y_blur;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class pp_overlay_blur_step_t : public pp_in_place_t
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
pp_overlay_blur_step_t(frame_buffer_t::attachment_t from, i32 x_blur = 2, i32 y_blur = 2):
|
||||||
|
pp_in_place_t(from), x_blur(x_blur), y_blur(y_blur)
|
||||||
|
{}
|
||||||
|
|
||||||
|
pp_overlay_blur_step_t(frame_buffer_t::attachment_t from, frame_buffer_t::attachment_t to, i32 x_blur = 2,
|
||||||
|
i32 y_blur = 2):
|
||||||
|
pp_in_place_t(from, to), x_blur(x_blur), y_blur(y_blur)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void create() override;
|
||||||
|
|
||||||
|
void draw(frame_buffer_t& previous);
|
||||||
|
|
||||||
|
private:
|
||||||
|
i32 x_blur;
|
||||||
|
i32 y_blur;
|
||||||
|
};
|
||||||
|
|
||||||
class pp_expansion_step_inplace_t : public pp_in_place_t
|
class pp_expansion_step_inplace_t : public pp_in_place_t
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -207,7 +230,7 @@ namespace blt::gfx
|
||||||
steps.emplace_back(std::move(step));
|
steps.emplace_back(std::move(step));
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::unique_ptr<shader_t> createShader(std::string_view fragment);
|
static std::unique_ptr<shader_t> createShader(std::string_view fragment, std::optional<std::reference_wrapper<template_engine_t>> engine = {});
|
||||||
|
|
||||||
static std::unique_ptr<pp_engine_t> make_basic_pp()
|
static std::unique_ptr<pp_engine_t> make_basic_pp()
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#include <string>
|
||||||
|
const std::string shader_overlay_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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vec4 blur_val = result / vec4((float(size.z) * 2.0) * (float(size.w) * 2.0));
|
||||||
|
vec4 tex_val = texture(tex, uv);
|
||||||
|
if (tex_val != vec4(0.0,0.0,0.0,0.0))
|
||||||
|
FragColor = tex_val;
|
||||||
|
else
|
||||||
|
FragColor = blur_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
")";
|
||||||
|
#endif
|
|
@ -23,6 +23,9 @@
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <blt/math/math.h>
|
#include <blt/math/math.h>
|
||||||
|
#include <blt/parse/templating.h>
|
||||||
|
#include <optional>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace blt::gfx
|
namespace blt::gfx
|
||||||
{
|
{
|
||||||
|
@ -59,21 +62,24 @@ namespace blt::gfx
|
||||||
|
|
||||||
~uniform_buffer();
|
~uniform_buffer();
|
||||||
|
|
||||||
[[nodiscard]] inline size_t size() const { return size_; }
|
[[nodiscard]] inline size_t size() const
|
||||||
|
{ return size_; }
|
||||||
|
|
||||||
[[nodiscard]] inline GLuint location() const { return location_; }
|
[[nodiscard]] inline GLuint location() const
|
||||||
|
{ return location_; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class shader_base_t
|
class shader_base_t
|
||||||
{
|
{
|
||||||
friend uniform_buffer;
|
friend uniform_buffer;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
struct IntDefaultedToMinusOne
|
struct IntDefaultedToMinusOne
|
||||||
{
|
{
|
||||||
GLint i = -1;
|
GLint i = -1;
|
||||||
|
|
||||||
inline explicit operator bool() const { return i != -1; }
|
inline explicit operator bool() const
|
||||||
|
{ return i != -1; }
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unordered_map<std::string, IntDefaultedToMinusOne> uniformVars;
|
std::unordered_map<std::string, IntDefaultedToMinusOne> uniformVars;
|
||||||
|
@ -116,6 +122,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& 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);
|
||||||
|
@ -155,18 +162,58 @@ namespace blt::gfx
|
||||||
|
|
||||||
static std::string loadShader(std::string_view file);
|
static std::string loadShader(std::string_view file);
|
||||||
|
|
||||||
|
shader_t(std::string_view vertex, std::string_view fragment);
|
||||||
|
|
||||||
|
static std::pair<std::string, std::string> process_templates(template_engine_t& engine, std::string_view vertex,
|
||||||
|
std::string_view fragment);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Creates a shader
|
* Creates a shader from source file
|
||||||
* @param vertex vertex shader source or file
|
* @param vertex vertex shader source
|
||||||
* @param fragment fragment shader source or file
|
* @param fragment fragment shader source
|
||||||
* @param geometry geometry shader source or file (optional)
|
|
||||||
* @param load_as_string load the shader as a string (true) or use the string to load the shader as a file (false)
|
|
||||||
*/
|
*/
|
||||||
shader_t(const std::string& vertex, const std::string& fragment, bool load_as_string = true);
|
static shader_t* make(std::optional<std::reference_wrapper<template_engine_t>> engine, std::string_view vertex,
|
||||||
|
std::string_view fragment);
|
||||||
|
|
||||||
|
static shader_t* make(std::string_view vertex, std::string_view fragment)
|
||||||
|
{
|
||||||
|
return make({}, vertex, fragment);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::unique_ptr<shader_t> make_unique(std::optional<std::reference_wrapper<template_engine_t>> engine,
|
||||||
|
std::string_view vertex, std::string_view fragment);
|
||||||
|
|
||||||
|
static std::unique_ptr<shader_t> make_unique(std::string_view vertex, std::string_view fragment)
|
||||||
|
{
|
||||||
|
return make_unique({}, vertex, fragment);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a shader by loading lines of source from the file.
|
||||||
|
* @param vertex vertex shader file path
|
||||||
|
* @param fragment fragment shader file path
|
||||||
|
*/
|
||||||
|
static shader_t* load(std::optional<std::reference_wrapper<template_engine_t>> engine, std::string_view vertex,
|
||||||
|
std::string_view fragment);
|
||||||
|
|
||||||
|
static shader_t* load(std::string_view vertex, std::string_view fragment)
|
||||||
|
{
|
||||||
|
return load({}, vertex, fragment);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::unique_ptr<shader_t> load_unique(std::optional<std::reference_wrapper<template_engine_t>> engine,
|
||||||
|
std::string_view vertex, std::string_view fragment);
|
||||||
|
|
||||||
|
static std::unique_ptr<shader_t> load_unique(std::string_view vertex, std::string_view fragment)
|
||||||
|
{
|
||||||
|
return load_unique({}, vertex, fragment);
|
||||||
|
}
|
||||||
|
|
||||||
shader_t(shader_t&& move) noexcept;
|
shader_t(shader_t&& move) noexcept;
|
||||||
|
|
||||||
|
shader_t(const shader_t& copy) = delete;
|
||||||
|
|
||||||
// used to set the location of VAOs to the in variables in opengl shaders.
|
// used to set the location of VAOs to the in variables in opengl shaders.
|
||||||
void bindAttribute(int attribute, const std::string& name) const;
|
void bindAttribute(int attribute, const std::string& name) const;
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit fa5083b637a96af5b430c9f0015ee11d5638d201
|
Subproject commit f228cfbbe31538731a2ef1bd990d41c99562c4d3
|
|
@ -1 +1 @@
|
||||||
Subproject commit a1b06823fe2d964a62fda99385499b218cf5cea5
|
Subproject commit 231cbee0fc4f59dbe5b8b853a11b08dc84e57c65
|
|
@ -1 +1 @@
|
||||||
Subproject commit 6675317107257c2cc16c947b359d557821d85bf2
|
Subproject commit 111397c71a5f1c2c88e05da9c84edfdba2e472a4
|
|
@ -81,11 +81,11 @@ namespace blt::gfx
|
||||||
line_vao->bindElement(indices_vbo);
|
line_vao->bindElement(indices_vbo);
|
||||||
}
|
}
|
||||||
|
|
||||||
square_shader = new shader_t(shader_2d_textured_vert, shader_2d_textured_frag);
|
square_shader = shader_t::make(shader_2d_textured_vert, shader_2d_textured_frag);
|
||||||
square_shader->bindAttribute(0, "vertex");
|
square_shader->bindAttribute(0, "vertex");
|
||||||
square_shader->bindAttribute(1, "uv_in");
|
square_shader->bindAttribute(1, "uv_in");
|
||||||
|
|
||||||
point_shader = new shader_t(shader_2d_textured_vert, shader_2d_textured_cirlce_frag);
|
point_shader = shader_t::make(shader_2d_textured_vert, shader_2d_textured_cirlce_frag);
|
||||||
point_shader->bindAttribute(0, "vertex");
|
point_shader->bindAttribute(0, "vertex");
|
||||||
point_shader->bindAttribute(1, "uv_in");
|
point_shader->bindAttribute(1, "uv_in");
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#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_gaussian_blur.frag>
|
||||||
|
#include <blt/gfx/renderer/shaders/pp_overlay_blur.frag>
|
||||||
#include <blt/gfx/renderer/shaders/pp_multiplier.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>
|
#include <blt/math/log_util.h>
|
||||||
|
@ -117,9 +118,18 @@ namespace blt::gfx
|
||||||
steps.clear();
|
steps.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<shader_t> pp_engine_t::createShader(std::string_view fragment)
|
std::unique_ptr<shader_t> pp_engine_t::createShader(std::string_view fragment, std::optional<std::reference_wrapper<template_engine_t>> engine)
|
||||||
{
|
{
|
||||||
auto shader = std::make_unique<shader_t>(shader_postprocess_vert, std::string(fragment));
|
std::unique_ptr<shader_t> shader;
|
||||||
|
if (engine)
|
||||||
|
{
|
||||||
|
shader = shader_t::make_unique(engine, shader_postprocess_vert, std::string(fragment));
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
template_engine_t templateEngine;
|
||||||
|
templateEngine.set("LAYOUT_STRING", "");
|
||||||
|
shader = shader_t::make_unique(templateEngine, shader_postprocess_vert, std::string(fragment));
|
||||||
|
}
|
||||||
shader->bindAttribute(0, "vertex");
|
shader->bindAttribute(0, "vertex");
|
||||||
shader->bindAttribute(1, "uv_in");
|
shader->bindAttribute(1, "uv_in");
|
||||||
return shader;
|
return shader;
|
||||||
|
@ -139,7 +149,10 @@ namespace blt::gfx
|
||||||
|
|
||||||
void pp_in_place_t::create()
|
void pp_in_place_t::create()
|
||||||
{
|
{
|
||||||
shader_pass = pp_engine_t::createShader(shader_pp_screen_frag);
|
template_engine_t engine;
|
||||||
|
engine.set("LAYOUT_STRING", "layout (location = ${IF(LAYOUT_LOCATION) { LAYOUT_LOCATION } ELSE { ~DISCARD }}) ");
|
||||||
|
engine.set("LAYOUT_LOCATION", std::to_string(static_cast<int>(to) - static_cast<int>(frame_buffer_t::attachment_t::COLOR0)));
|
||||||
|
shader_pass = pp_engine_t::createShader(shader_pp_screen_frag, engine);
|
||||||
draw_buffer = frame_buffer_t::make_render_texture(getWindowWidth(), getWindowHeight());
|
draw_buffer = frame_buffer_t::make_render_texture(getWindowWidth(), getWindowHeight());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,4 +287,18 @@ namespace blt::gfx
|
||||||
shader->bind();
|
shader->bind();
|
||||||
shader->setVec4("multiplier", multiplier);
|
shader->setVec4("multiplier", multiplier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pp_overlay_blur_step_t::create()
|
||||||
|
{
|
||||||
|
pp_in_place_t::create();
|
||||||
|
shader = pp_engine_t::createShader(shader_overlay_blur_frag);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pp_overlay_blur_step_t::draw(frame_buffer_t& previous)
|
||||||
|
{
|
||||||
|
pp_in_place_t::draw(previous);
|
||||||
|
shader->bind();
|
||||||
|
auto v = vec2(getWindowWidth(), getWindowHeight());
|
||||||
|
shader->setVec4i("size", {static_cast<i32>(v.x()), static_cast<i32>(v.y()), x_blur, y_blur});
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -70,13 +70,13 @@ namespace blt::gfx
|
||||||
glDeleteBuffers(1, &uboID);
|
glDeleteBuffers(1, &uboID);
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string removeEmptyFirstLines(const std::string& string)
|
static std::string removeEmptyFirstLines(std::string_view string)
|
||||||
{
|
{
|
||||||
auto lines = blt::string::split(string, "\n");
|
auto lines = blt::string::split_sv(string, "\n");
|
||||||
std::string new_source_string;
|
std::string new_source_string;
|
||||||
for (const auto& line : lines)
|
for (const auto& line : lines)
|
||||||
{
|
{
|
||||||
if (!line.empty() && !blt::string::contains(line, "\""))
|
if (!blt::string::trim(line).empty() && !blt::string::starts_with(line, "\""))
|
||||||
{
|
{
|
||||||
new_source_string += line;
|
new_source_string += line;
|
||||||
new_source_string += "\n";
|
new_source_string += "\n";
|
||||||
|
@ -122,21 +122,11 @@ namespace blt::gfx
|
||||||
return shaderID;
|
return shaderID;
|
||||||
}
|
}
|
||||||
|
|
||||||
shader_t::shader_t(const std::string& vertex, const std::string& fragment, bool load_as_string)
|
shader_t::shader_t(std::string_view vertex, std::string_view fragment)
|
||||||
{
|
{
|
||||||
// load shader sources
|
// load shader sources
|
||||||
std::string vertex_source = vertex;
|
std::string vertex_source = removeEmptyFirstLines(vertex);
|
||||||
std::string fragment_source = fragment;
|
std::string fragment_source = removeEmptyFirstLines(fragment);
|
||||||
if (!load_as_string)
|
|
||||||
{
|
|
||||||
// BLT provides a recursive file loader for glsl shaders. It's pretty much just a recursive function looking for include statements.
|
|
||||||
vertex_source = loadShader(vertex);
|
|
||||||
fragment_source = loadShader(fragment);
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
vertex_source = removeEmptyFirstLines(vertex_source);
|
|
||||||
fragment_source = removeEmptyFirstLines(fragment_source);
|
|
||||||
}
|
|
||||||
|
|
||||||
// create the shaders
|
// create the shaders
|
||||||
vertexShaderID = createShader(vertex_source, GL_VERTEX_SHADER);
|
vertexShaderID = createShader(vertex_source, GL_VERTEX_SHADER);
|
||||||
|
@ -232,6 +222,64 @@ namespace blt::gfx
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shader_t* shader_t::make(std::optional<std::reference_wrapper<template_engine_t>> engine, std::string_view vertex,
|
||||||
|
std::string_view fragment)
|
||||||
|
{
|
||||||
|
std::string vertex_source;
|
||||||
|
std::string fragment_source;
|
||||||
|
if (engine)
|
||||||
|
{
|
||||||
|
auto s_pair = process_templates(engine->get(), vertex, fragment);
|
||||||
|
vertex_source = std::move(s_pair.first);
|
||||||
|
fragment_source = std::move(s_pair.second);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
vertex_source = vertex;
|
||||||
|
fragment_source = fragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new shader_t(vertex_source, fragment_source);
|
||||||
|
}
|
||||||
|
|
||||||
|
shader_t* shader_t::load(std::optional<std::reference_wrapper<template_engine_t>> engine, std::string_view vertex,
|
||||||
|
std::string_view fragment)
|
||||||
|
{
|
||||||
|
auto vertex_source = loadShader(vertex);
|
||||||
|
auto fragment_source = loadShader((fragment));
|
||||||
|
return make(engine, vertex_source, fragment_source);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<std::string, std::string> shader_t::process_templates(template_engine_t& engine, std::string_view vertex, std::string_view fragment)
|
||||||
|
{
|
||||||
|
auto vertex_e = engine.evaluate(vertex);
|
||||||
|
auto fragment_e = engine.evaluate(fragment);
|
||||||
|
if (!vertex_e)
|
||||||
|
{
|
||||||
|
BLT_ERROR("Error vertex function returned: %d", static_cast<int>(vertex_e.error()));
|
||||||
|
throw std::runtime_error("Unable to substitute vertex source");
|
||||||
|
}
|
||||||
|
if (!fragment_e)
|
||||||
|
{
|
||||||
|
BLT_ERROR("Error fragment function returned: %d", static_cast<int>(vertex_e.error()));
|
||||||
|
throw std::runtime_error("Unable to substitute fragment source");
|
||||||
|
}
|
||||||
|
return {vertex_e.value(), fragment_e.value()};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<shader_t> shader_t::make_unique(std::optional<std::reference_wrapper<template_engine_t>> engine, std::string_view vertex,
|
||||||
|
std::string_view fragment)
|
||||||
|
{
|
||||||
|
return std::unique_ptr<shader_t>(shader_t::make(engine, vertex, fragment));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<shader_t> shader_t::load_unique(std::optional<std::reference_wrapper<template_engine_t>> engine, std::string_view vertex,
|
||||||
|
std::string_view fragment)
|
||||||
|
{
|
||||||
|
auto vertex_source = loadShader(vertex);
|
||||||
|
auto fragment_source = loadShader((fragment));
|
||||||
|
return make_unique(engine, vertex_source, fragment_source);
|
||||||
|
}
|
||||||
|
|
||||||
shader_base_t& shader_base_t::setBool(const std::string& name, bool value)
|
shader_base_t& shader_base_t::setBool(const std::string& name, bool value)
|
||||||
{
|
{
|
||||||
if (auto i = getUniformLocation(name))
|
if (auto i = getUniformLocation(name))
|
||||||
|
|
|
@ -252,8 +252,10 @@ namespace blt::gfx
|
||||||
gladLoadGL(glfwGetProcAddress);
|
gladLoadGL(glfwGetProcAddress);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef __EMSCRIPTEN__
|
||||||
glEnable(GL_DEBUG_OUTPUT);
|
glEnable(GL_DEBUG_OUTPUT);
|
||||||
glDebugMessageCallback(gl_error_callback, nullptr);
|
glDebugMessageCallback(gl_error_callback, nullptr);
|
||||||
|
#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();
|
||||||
|
|
Loading…
Reference in New Issue