2d renderer code cleanup
parent
3588dcbd49
commit
e25dad380c
|
@ -1,6 +1,6 @@
|
||||||
cmake_minimum_required(VERSION 3.25)
|
cmake_minimum_required(VERSION 3.25)
|
||||||
|
|
||||||
set(BLT_GRAPHICS_VERSION 0.12.5)
|
set(BLT_GRAPHICS_VERSION 0.13.0)
|
||||||
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})
|
||||||
|
|
|
@ -27,79 +27,121 @@
|
||||||
#include <blt/math/vectors.h>
|
#include <blt/math/vectors.h>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
|
||||||
#include <map>
|
|
||||||
#include <variant>
|
|
||||||
|
|
||||||
namespace blt::gfx
|
namespace blt::gfx
|
||||||
{
|
{
|
||||||
struct rectangle2d_t
|
struct rectangle2d_t
|
||||||
{
|
{
|
||||||
blt::vec2f pos, size;
|
vec2f pos, size;
|
||||||
blt::f32 rotation = 0;
|
f32 rotation = 0;
|
||||||
|
|
||||||
rectangle2d_t(blt::f32 x, blt::f32 y, blt::f32 width, blt::f32 height, blt::f32 rotation): pos(x, y), size(width, height), rotation(rotation)
|
rectangle2d_t(const f32 x, const f32 y, const f32 width, const f32 height, const f32 rotation): pos(x, y), size(width, height),
|
||||||
|
rotation(rotation)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
rectangle2d_t(blt::f32 x, blt::f32 y, blt::f32 width, blt::f32 height): pos(x, y), size(width, height)
|
rectangle2d_t(const f32 x, const f32 y, const f32 width, const f32 height): pos(x, y), size(width, height)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
rectangle2d_t(blt::vec2f pos, blt::vec2f size, blt::f32 rotation): pos(pos), size(size), rotation(rotation)
|
rectangle2d_t(const vec2f pos, const vec2f size, const f32 rotation): pos(pos), size(size), rotation(rotation)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
rectangle2d_t(blt::vec2f pos, blt::vec2f size): pos(pos), size(size)
|
rectangle2d_t(const vec2f pos, const vec2f size): pos(pos), size(size)
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct line2d_t
|
struct line2d_t
|
||||||
{
|
{
|
||||||
blt::vec2f p1;
|
vec2f p1;
|
||||||
blt::vec2f p2;
|
vec2f p2;
|
||||||
blt::f32 thickness = 1;
|
f32 thickness = 1;
|
||||||
|
|
||||||
line2d_t(blt::f32 px1, blt::f32 py1, blt::f32 px2, blt::f32 py2): p1(px1, py1), p2(px2, py2)
|
line2d_t(const f32 px1, const f32 py1, const f32 px2, const f32 py2): p1(px1, py1), p2(px2, py2)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
line2d_t(blt::vec2f p1, blt::vec2f p2): p1(p1), p2(p2)
|
line2d_t(const vec2f p1, const vec2f p2): p1(p1), p2(p2)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
line2d_t(blt::f32 px1, blt::f32 py1, blt::f32 px2, blt::f32 py2, blt::f32 thickness): p1(px1, py1), p2(px2, py2), thickness(thickness)
|
line2d_t(const f32 px1, const f32 py1, const f32 px2, const f32 py2, const f32 thickness): p1(px1, py1), p2(px2, py2), thickness(thickness)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
line2d_t(blt::vec2f p1, blt::vec2f p2, blt::f32 thickness): p1(p1), p2(p2), thickness(thickness)
|
line2d_t(const vec2f p1, const vec2f p2, const f32 thickness): p1(p1), p2(p2), thickness(thickness)
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct point2d_t
|
struct point2d_t
|
||||||
{
|
{
|
||||||
blt::vec2f pos;
|
vec2f pos;
|
||||||
float scale = 1;
|
float scale = 1;
|
||||||
|
|
||||||
point2d_t(float x, float y, float scale): pos(x, y), scale(scale)
|
point2d_t(const float x, const float y, const float scale): pos(x, y), scale(scale)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
point2d_t(float x, float y): pos(x, y)
|
point2d_t(const float x, const float y): pos(x, y)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
point2d_t(vec2f pos, float scale): pos(pos), scale(scale)
|
point2d_t(const vec2f pos, const float scale): pos(pos), scale(scale)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
explicit point2d_t(vec2f pos): pos(pos)
|
explicit point2d_t(const vec2f pos): pos(pos)
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct draw_state
|
struct render_info_t
|
||||||
{
|
{
|
||||||
// texture to use
|
private:
|
||||||
std::string texture_name;
|
constexpr static color4 disabled = color4(0, 0, 0, 0);
|
||||||
// color to use
|
constexpr static vec4 empty{0, 0, 0, 1};
|
||||||
blt::color4 color;
|
constexpr static vec4 full{1, 1, 1, 1};
|
||||||
// how much to blend the texture into the color? note blending is always additive!
|
|
||||||
blt::color4 blend;
|
render_info_t(const std::string_view texture, color4 color, color4 blend): texture_name(texture), color(color), blend(blend)
|
||||||
// should we outline this object?
|
{}
|
||||||
bool outline;
|
|
||||||
// what color should we outline with?
|
public:
|
||||||
blt::color4 outline_color;
|
// texture to use
|
||||||
|
std::string texture_name;
|
||||||
|
// color to use
|
||||||
|
color4 color;
|
||||||
|
// how much to blend the texture into the color? note blending is always additive!
|
||||||
|
color4 blend;
|
||||||
|
// should we outline this object?
|
||||||
|
bool outline = false;
|
||||||
|
// what color should we outline with?
|
||||||
|
color4 outline_color;
|
||||||
|
|
||||||
|
render_info_t() = default;
|
||||||
|
|
||||||
|
static render_info_t make_info(const std::string_view texture, const color4 outline = disabled)
|
||||||
|
{
|
||||||
|
render_info_t info{texture, empty, full};
|
||||||
|
if (outline != disabled)
|
||||||
|
{
|
||||||
|
info.outline = true;
|
||||||
|
info.outline_color = outline;
|
||||||
|
}
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
static render_info_t make_info(const color4 color, const color4 outline = disabled)
|
||||||
|
{
|
||||||
|
render_info_t info{"", color, empty};
|
||||||
|
if (outline != disabled)
|
||||||
|
{
|
||||||
|
info.outline = true;
|
||||||
|
info.outline_color = outline;
|
||||||
|
}
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
static render_info_t make_info(const std::string_view texture, const color4 color, const color4 blend, const color4 outline = disabled)
|
||||||
|
{
|
||||||
|
render_info_t info{texture, color, blend};
|
||||||
|
if (outline != disabled)
|
||||||
|
{
|
||||||
|
info.outline = true;
|
||||||
|
info.outline_color = outline;
|
||||||
|
}
|
||||||
|
return info;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class batch_renderer_2d
|
class batch_renderer_2d
|
||||||
|
@ -107,143 +149,125 @@ namespace blt::gfx
|
||||||
private:
|
private:
|
||||||
struct vec_hash
|
struct vec_hash
|
||||||
{
|
{
|
||||||
std::size_t operator()(const blt::vec4& key) const
|
std::size_t operator()(const vec4& key) const
|
||||||
{
|
{
|
||||||
using namespace blt::mem;
|
using namespace blt::mem;
|
||||||
return type_cast<blt::i32>(key.x()) ^ type_cast<blt::i32>(key.y()) ^ type_cast<blt::i32>(key.y()) ^ type_cast<blt::i32>(key.z());
|
return type_cast<i32>(key.x()) ^ type_cast<i32>(key.y()) ^ type_cast<i32>(key.y()) ^ type_cast<i32>(key.z());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct render_object_t
|
struct render_object_t
|
||||||
{
|
{
|
||||||
blt::f32 z_index;
|
f32 z_index;
|
||||||
T obj;
|
T obj;
|
||||||
|
|
||||||
render_object_t(float z_index, T obj): z_index(z_index), obj(obj)
|
render_object_t(const float z_index, const T obj): z_index(z_index), obj(obj)
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
using rectangle2d_obj_t = render_object_t<rectangle2d_t>;
|
using rectangle2d_obj_t = render_object_t<rectangle2d_t>;
|
||||||
using point2d_obj_t = render_object_t<point2d_t>;
|
using point2d_obj_t = render_object_t<point2d_t>;
|
||||||
using line2d_obj_t = render_object_t<line2d_t>;
|
using line2d_obj_t = render_object_t<line2d_t>;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
using object_container = hashmap_t<std::string, std::vector<std::pair<render_info_t, T>>>;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
vertex_array* square_vao = nullptr;
|
vertex_array* square_vao = nullptr;
|
||||||
vertex_array* line_vao = nullptr;
|
vertex_array* line_vao = nullptr;
|
||||||
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;
|
||||||
// texture -> color -> blend factor -> list of rectangles
|
// texture name -> draw info
|
||||||
blt::hashmap_t<std::string, blt::hashmap_t<blt::vec4, blt::hashmap_t<blt::vec4, std::vector<rectangle2d_obj_t>, vec_hash>, vec_hash>> complex_rectangles;
|
struct
|
||||||
blt::hashmap_t<std::string, blt::hashmap_t<blt::vec4, blt::hashmap_t<blt::vec4, std::vector<point2d_obj_t>, vec_hash>, vec_hash>> complex_points;
|
{
|
||||||
blt::hashmap_t<std::string, blt::hashmap_t<blt::vec4, blt::hashmap_t<blt::vec4, std::vector<line2d_obj_t>, vec_hash>, vec_hash>> complex_lines;
|
object_container<rectangle2d_obj_t> complex_rectangles;
|
||||||
size_t draw_count_ = 0;
|
object_container<point2d_obj_t> complex_points;
|
||||||
|
object_container<line2d_obj_t> complex_lines;
|
||||||
|
size_t draw_count = 0;
|
||||||
|
f32 z_min = std::numeric_limits<f32>::max();
|
||||||
|
f32 z_max = std::numeric_limits<f32>::min();
|
||||||
|
} draw;
|
||||||
|
|
||||||
|
template<typename E>
|
||||||
|
static void insert_obj(object_container<E>& map, const render_info_t& info, const E& obj)
|
||||||
|
{
|
||||||
|
map[info.texture_name].emplace_back(info, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
// called at the end of the render function
|
||||||
|
void render_reset();
|
||||||
|
|
||||||
|
// called before invocation of draw_objects
|
||||||
|
void pre_reset();
|
||||||
|
|
||||||
|
// called after draw_objects()
|
||||||
|
void post_reset();
|
||||||
|
|
||||||
|
void draw_objects();
|
||||||
|
|
||||||
|
inline void update_z_index(f32 z_index)
|
||||||
|
{
|
||||||
|
draw.z_min = std::min(draw.z_min, -z_index);
|
||||||
|
draw.z_max = std::max(draw.z_max, -z_index);
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit batch_renderer_2d(resource_manager& resources): resources(resources)
|
explicit batch_renderer_2d(resource_manager& resources): resources(resources)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void create();
|
void create();
|
||||||
|
|
||||||
inline void drawRectangleInternal(std::string_view texture, const rectangle2d_t& rectangle, blt::f32 z_index = 0)
|
void drawRectangleInternal(std::string_view texture, const rectangle2d_t& rectangle, f32 z_index = 0);
|
||||||
{
|
|
||||||
const static blt::vec4 empty{0, 0, 0, 1};
|
|
||||||
const static blt::vec4 full{1, 1, 1, 1};
|
|
||||||
complex_rectangles[texture][empty][full].emplace_back(-z_index, rectangle);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void drawRectangleInternal(const blt::vec4& color, const rectangle2d_t& rectangle, blt::f32 z_index = 0)
|
void drawRectangleInternal(const vec4& color, const rectangle2d_t& rectangle, f32 z_index = 0);
|
||||||
{
|
|
||||||
const static blt::vec4 empty{0, 0, 0, 0};
|
|
||||||
complex_rectangles[""][color][empty].emplace_back(-z_index, rectangle);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void drawRectangleInternal(const draw_state& draw_info, const rectangle2d_t& rectangle, blt::f32 z_index = 0)
|
void drawRectangleInternal(const render_info_t& draw_info, const rectangle2d_t& rectangle, f32 z_index = 0);
|
||||||
{
|
|
||||||
complex_rectangles[draw_info.texture_name][draw_info.color][draw_info.blend].emplace_back(-z_index, rectangle);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void drawLineInternal(std::string_view texture, const line2d_t& line, blt::f32 z_index = 0)
|
void drawLineInternal(std::string_view texture, const line2d_t& line, f32 z_index = 0);
|
||||||
{
|
|
||||||
const static blt::vec4 empty{0, 0, 0, 1};
|
|
||||||
const static blt::vec4 full{1, 1, 1, 1};
|
|
||||||
complex_lines[texture][empty][full].emplace_back(-z_index, line);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void drawLineInternal(const blt::vec4& color, const line2d_t& line, blt::f32 z_index = 0)
|
void drawLineInternal(const vec4& color, const line2d_t& line, f32 z_index = 0);
|
||||||
{
|
|
||||||
const static blt::vec4 empty{0, 0, 0, 0};
|
|
||||||
complex_lines[""][color][empty].emplace_back(-z_index, line);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void drawLineInternal(const draw_state& draw_info, const line2d_t& line, blt::f32 z_index = 0)
|
void drawLineInternal(const render_info_t& draw_info, const line2d_t& line, f32 z_index = 0);
|
||||||
{
|
|
||||||
complex_lines[draw_info.texture_name][draw_info.color][draw_info.blend].emplace_back(-z_index, line);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void drawPointInternal(std::string_view texture, const point2d_t& point, blt::f32 z_index = 0)
|
void drawPointInternal(std::string_view texture, const point2d_t& point, f32 z_index = 0);
|
||||||
{
|
|
||||||
const static blt::vec4 empty{0, 0, 0, 1};
|
|
||||||
const static blt::vec4 full{1, 1, 1, 1};
|
|
||||||
complex_points[texture][empty][full].emplace_back(-z_index, point);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void drawPointInternal(const blt::vec4& color, const point2d_t& point, blt::f32 z_index = 0)
|
void drawPointInternal(const vec4& color, const point2d_t& point, f32 z_index = 0);
|
||||||
{
|
|
||||||
const static blt::vec4 empty{0, 0, 0, 0};
|
|
||||||
complex_points[""][color][empty].emplace_back(-z_index, point);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void drawPointInternal(const draw_state& draw_info, const point2d_t& point, blt::f32 z_index = 0)
|
void drawPointInternal(const render_info_t& draw_info, const point2d_t& point, f32 z_index = 0);
|
||||||
{
|
|
||||||
complex_points[draw_info.texture_name][draw_info.color][draw_info.blend].emplace_back(-z_index, point);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T, typename... P>
|
template<typename T, typename... P>
|
||||||
inline void drawRectangle(const T& render_info, P... p)
|
void drawRectangle(const T& render_info, P... p)
|
||||||
{
|
{ drawRectangleInternal(render_info, {p...}); }
|
||||||
drawRectangleInternal(render_info, {p...});
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T, typename... P>
|
template<typename T, typename... P>
|
||||||
inline void drawPoint(const T& render_info, P... p)
|
void drawPoint(const T& render_info, P... p)
|
||||||
{
|
{ drawPointInternal(render_info, {p...}); }
|
||||||
drawPointInternal(render_info, {p...});
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T, typename... P>
|
template<typename T, typename... P>
|
||||||
inline void drawLine(const T& render_info, P... p)
|
void drawLine(const T& render_info, P... p)
|
||||||
{
|
{ drawLineInternal(render_info, {p...}); }
|
||||||
drawLineInternal(render_info, {p...});
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T, typename... P>
|
template<typename T, typename... P>
|
||||||
inline void drawRectangle(const T& render_info, blt::f32 z_index, P... p)
|
void drawRectangle(const T& render_info, f32 z_index, P... p)
|
||||||
{
|
{ drawRectangleInternal(render_info, {p...}, z_index); }
|
||||||
drawRectangleInternal(render_info, {p...}, z_index);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T, typename... P>
|
template<typename T, typename... P>
|
||||||
inline void drawPoint(const T& render_info, blt::f32 z_index, P... p)
|
void drawPoint(const T& render_info, f32 z_index, P... p)
|
||||||
{
|
{ drawPointInternal(render_info, {p...}, z_index); }
|
||||||
drawPointInternal(render_info, {p...}, z_index);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T, typename... P>
|
template<typename T, typename... P>
|
||||||
inline void drawLine(const T& render_info, blt::f32 z_index, P... p)
|
void drawLine(const T& render_info, f32 z_index, P... p)
|
||||||
{
|
{ drawLineInternal(render_info, {p...}, z_index); }
|
||||||
drawLineInternal(render_info, {p...}, z_index);
|
|
||||||
}
|
|
||||||
|
|
||||||
void render(bool transparency = true);
|
void render(bool transparency = true);
|
||||||
|
|
||||||
void cleanup();
|
void cleanup();
|
||||||
|
|
||||||
[[nodiscard]] inline size_t draw_count() const
|
[[nodiscard]] size_t draw_count() const
|
||||||
{
|
{ return draw.draw_count; }
|
||||||
return draw_count_;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //BLT_WITH_GRAPHICS_BATCH_2D_RENDERER_H
|
#endif //BLT_WITH_GRAPHICS_BATCH_2D_RENDERER_H
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
#define BLT_WITH_GRAPHICS_SHADER_H
|
#define BLT_WITH_GRAPHICS_SHADER_H
|
||||||
|
|
||||||
#include <blt/gfx/gl_includes.h>
|
#include <blt/gfx/gl_includes.h>
|
||||||
#include <vector>
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <blt/math/math.h>
|
#include <blt/math/math.h>
|
||||||
|
@ -33,98 +32,98 @@ namespace blt::gfx
|
||||||
GLuint uboID = 0;
|
GLuint uboID = 0;
|
||||||
size_t size_;
|
size_t size_;
|
||||||
GLuint location_;
|
GLuint location_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit uniform_buffer(size_t size, GLuint location = 0);
|
explicit uniform_buffer(size_t size, GLuint location = 0);
|
||||||
|
|
||||||
uniform_buffer(void* data, size_t size, GLuint location = 0);
|
uniform_buffer(void* data, size_t size, GLuint location = 0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resizes the internal UBO
|
* Resizes the internal UBO
|
||||||
* @param newSize new size for the UBO
|
* @param newSize new size for the UBO
|
||||||
*/
|
*/
|
||||||
uniform_buffer& resize(size_t newSize);
|
uniform_buffer& resize(size_t newSize);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Uploads data to the UBO. This can be an arbitrary locations and does not need to be the whole UBO.
|
* Uploads data to the UBO. This can be an arbitrary locations and does not need to be the whole UBO.
|
||||||
*/
|
*/
|
||||||
uniform_buffer& upload(void* data, size_t size, size_t offset = 0);
|
uniform_buffer& upload(void* data, size_t size, size_t offset = 0);
|
||||||
|
|
||||||
uniform_buffer& bind();
|
uniform_buffer& bind();
|
||||||
|
|
||||||
inline uniform_buffer& unbind()
|
inline uniform_buffer& unbind()
|
||||||
{
|
{
|
||||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
~uniform_buffer();
|
~uniform_buffer();
|
||||||
|
|
||||||
[[nodiscard]] inline size_t size() const
|
[[nodiscard]] inline size_t size() const { return size_; }
|
||||||
{
|
|
||||||
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
|
inline explicit operator bool() const { return i != -1; }
|
||||||
{
|
|
||||||
return i != -1;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unordered_map<std::string, IntDefaultedToMinusOne> uniformVars;
|
std::unordered_map<std::string, IntDefaultedToMinusOne> uniformVars;
|
||||||
GLuint programID = 0;
|
GLuint programID = 0;
|
||||||
|
|
||||||
IntDefaultedToMinusOne getUniformLocation(const std::string& name);
|
IntDefaultedToMinusOne getUniformLocation(const std::string& name);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
inline const shader_base_t& bind() const
|
const shader_base_t& bind() const
|
||||||
{
|
{
|
||||||
glUseProgram(programID);
|
glUseProgram(programID);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline shader_base_t& unbind()
|
shader_base_t& bind()
|
||||||
|
{
|
||||||
|
glUseProgram(programID);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
shader_base_t& unbind()
|
||||||
{
|
{
|
||||||
glUseProgram(0);
|
glUseProgram(0);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
shader_base_t& setBool(const std::string& name, bool value);
|
shader_base_t& setBool(const std::string& name, bool value);
|
||||||
|
|
||||||
shader_base_t& setInt(const std::string& name, int value);
|
shader_base_t& setInt(const std::string& name, int value);
|
||||||
|
|
||||||
shader_base_t& setFloat(const std::string& name, float value);
|
shader_base_t& setFloat(const std::string& name, float value);
|
||||||
|
|
||||||
shader_base_t& setMatrix(const std::string& name, blt::mat4x4& matrix);
|
shader_base_t& setMatrix(const std::string& name, blt::mat4x4& matrix);
|
||||||
|
|
||||||
// poor solution: TODO
|
// poor solution: TODO
|
||||||
shader_base_t& setMatrix(const std::string& name, blt::mat4x4&& matrix);
|
shader_base_t& setMatrix(const std::string& name, blt::mat4x4&& matrix);
|
||||||
|
|
||||||
shader_base_t& setVec2(const std::string& name, const blt::vec2& vec);
|
shader_base_t& setVec2(const std::string& name, const blt::vec2& vec);
|
||||||
|
|
||||||
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& setVec2(const std::string& name, float x, float y);
|
shader_base_t& setVec2(const std::string& name, float x, float y);
|
||||||
|
|
||||||
shader_base_t& setVec3(const std::string& name, float x, float y, float z);
|
shader_base_t& setVec3(const std::string& name, float x, float y, float z);
|
||||||
|
|
||||||
shader_base_t& setVec4(const std::string& name, float x, float y, float z, float w);
|
shader_base_t& setVec4(const std::string& name, float x, float y, float z, float w);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* a basic computer shader class, contains the functions and resources required to use compute shaders!
|
* a basic computer shader class, contains the functions and resources required to use compute shaders!
|
||||||
*/
|
*/
|
||||||
|
@ -132,27 +131,29 @@ namespace blt::gfx
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
GLuint shaderID = 0;
|
GLuint shaderID = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit compute_shader_t(const std::string& shader_source, bool loadAsString = true);
|
explicit compute_shader_t(const std::string& shader_source, bool loadAsString = true);
|
||||||
|
|
||||||
inline void execute(int x, int y, int z) const
|
void execute(const int x, const int y, const int z) const
|
||||||
{
|
{
|
||||||
bind();
|
bind();
|
||||||
glDispatchCompute(x, y, z);
|
glDispatchCompute(x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
~compute_shader_t();
|
~compute_shader_t();
|
||||||
};
|
};
|
||||||
|
|
||||||
class shader_t : public shader_base_t
|
class shader_t : public shader_base_t
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
GLuint vertexShaderID = 0;
|
GLuint vertexShaderID = 0;
|
||||||
GLuint fragmentShaderID = 0;
|
GLuint fragmentShaderID = 0;
|
||||||
|
|
||||||
static unsigned int createShader(const std::string& source, int type);
|
static unsigned int createShader(const std::string& source, int type);
|
||||||
|
|
||||||
static std::string loadShader(std::string_view file);
|
static std::string loadShader(std::string_view file);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Creates a shader
|
* Creates a shader
|
||||||
|
@ -162,15 +163,15 @@ namespace blt::gfx
|
||||||
* @param load_as_string load the shader as a string (true) or use the string to load the shader as a file (false)
|
* @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);
|
shader_t(const std::string& vertex, const std::string& fragment, bool load_as_string = true);
|
||||||
|
|
||||||
shader_t(shader_t&& move) noexcept;
|
shader_t(shader_t&& move) noexcept;
|
||||||
|
|
||||||
// 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;
|
||||||
|
|
||||||
// used to set location of shared UBOs like the perspective and view matrix
|
// used to set location of shared UBOs like the perspective and view matrix
|
||||||
void setUniformBlockLocation(const std::string& name, int location) const;
|
void setUniformBlockLocation(const std::string& name, int location) const;
|
||||||
|
|
||||||
~shader_t();
|
~shader_t();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 3f0ea887cd2923cb2cf390a4929ffce452301670
|
Subproject commit 9b86278a2982d80fbac6f87045a182088e07afbe
|
|
@ -16,31 +16,29 @@
|
||||||
* 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/batch_2d_renderer.h>
|
#include <blt/gfx/renderer/batch_2d_renderer.h>
|
||||||
#include <blt/gfx/renderer/2d_textured.vert>
|
#include <blt/gfx/renderer/shaders/2d_textured.vert>
|
||||||
#include <blt/gfx/renderer/2d_line.vert>
|
#include <blt/gfx/renderer/shaders/2d_textured.frag>
|
||||||
#include <blt/gfx/renderer/2d_textured.frag>
|
#include <blt/gfx/renderer/shaders/2d_textured_circle.frag>
|
||||||
#include <blt/gfx/renderer/2d_textured_circle.frag>
|
|
||||||
#include <blt/gfx/renderer/2d_line.frag>
|
|
||||||
// https://stackoverflow.com/questions/60440682/drawing-a-line-in-modern-opengl
|
// https://stackoverflow.com/questions/60440682/drawing-a-line-in-modern-opengl
|
||||||
|
|
||||||
float square_vertices[20] = {
|
float square_vertices[20] = {
|
||||||
// positions // texture coords
|
// positions // texture coords
|
||||||
0.5f, 0.5f, 0.0f, 1.0f, 1.0f, // top right
|
0.5f, 0.5f, 0.0f, 1.0f, 1.0f, // top right
|
||||||
0.5f, -0.5f, 0.0f, 1.0f, 0.0f, // bottom right
|
0.5f, -0.5f, 0.0f, 1.0f, 0.0f, // bottom right
|
||||||
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, // bottom left
|
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, // bottom left
|
||||||
-0.5f, 0.5f, 0.0f, 0.0f, 1.0f // top left
|
-0.5f, 0.5f, 0.0f, 0.0f, 1.0f // top left
|
||||||
};
|
};
|
||||||
const unsigned int square_indices[6] = {
|
const unsigned int square_indices[6] = {
|
||||||
0, 1, 3, // first triangle
|
0, 1, 3, // first triangle
|
||||||
1, 2, 3 // second triangle
|
1, 2, 3 // second triangle
|
||||||
};
|
};
|
||||||
|
|
||||||
float line_vertices[20] = {
|
float line_vertices[20] = {
|
||||||
// positions // texture coords
|
// positions // texture coords
|
||||||
0.5f, 0.5f, 0.0f, 1.0f, 1.0f, // top right
|
0.5f, 0.5f, 0.0f, 1.0f, 1.0f, // top right
|
||||||
0.5f, -0.5f, 0.0f, 1.0f, 0.0f, // bottom right
|
0.5f, -0.5f, 0.0f, 1.0f, 0.0f, // bottom right
|
||||||
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, // bottom left
|
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, // bottom left
|
||||||
-0.5f, 0.5f, 0.0f, 0.0f, 1.0f // top left
|
-0.5f, 0.5f, 0.0f, 0.0f, 1.0f // top left
|
||||||
};
|
};
|
||||||
|
|
||||||
// 0, 1 (top right)
|
// 0, 1 (top right)
|
||||||
|
@ -50,7 +48,6 @@ float line_vertices[20] = {
|
||||||
|
|
||||||
namespace blt::gfx
|
namespace blt::gfx
|
||||||
{
|
{
|
||||||
|
|
||||||
void batch_renderer_2d::create()
|
void batch_renderer_2d::create()
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
|
@ -64,7 +61,7 @@ namespace blt::gfx
|
||||||
indices_vbo.allocate(sizeof(square_indices), square_indices);
|
indices_vbo.allocate(sizeof(square_indices), square_indices);
|
||||||
|
|
||||||
square_vao = new vertex_array();
|
square_vao = new vertex_array();
|
||||||
auto tb = square_vao->bindVBO(vertices_vbo, 0, 3, GL_FLOAT, 5 * sizeof(float), 0);
|
const auto tb = square_vao->bindVBO(vertices_vbo, 0, 3, GL_FLOAT, 5 * sizeof(float), 0);
|
||||||
square_vao->bindVBO(tb, 1, 2, GL_FLOAT, 5 * sizeof(float), 3 * sizeof(float));
|
square_vao->bindVBO(tb, 1, 2, GL_FLOAT, 5 * sizeof(float), 3 * sizeof(float));
|
||||||
square_vao->bindElement(indices_vbo);
|
square_vao->bindElement(indices_vbo);
|
||||||
}
|
}
|
||||||
|
@ -93,6 +90,60 @@ namespace blt::gfx
|
||||||
point_shader->bindAttribute(1, "uv_in");
|
point_shader->bindAttribute(1, "uv_in");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void batch_renderer_2d::drawRectangleInternal(const std::string_view texture, const rectangle2d_t& rectangle, const f32 z_index)
|
||||||
|
{
|
||||||
|
update_z_index(z_index);
|
||||||
|
insert_obj(draw.complex_rectangles, render_info_t::make_info(texture), {-z_index, rectangle});
|
||||||
|
}
|
||||||
|
|
||||||
|
void batch_renderer_2d::drawRectangleInternal(const vec4& color, const rectangle2d_t& rectangle, const f32 z_index)
|
||||||
|
{
|
||||||
|
update_z_index(z_index);
|
||||||
|
insert_obj(draw.complex_rectangles, render_info_t::make_info(color), {-z_index, rectangle});
|
||||||
|
}
|
||||||
|
|
||||||
|
void batch_renderer_2d::drawRectangleInternal(const render_info_t& draw_info, const rectangle2d_t& rectangle, const f32 z_index)
|
||||||
|
{
|
||||||
|
update_z_index(z_index);
|
||||||
|
insert_obj(draw.complex_rectangles, draw_info, {-z_index, rectangle});
|
||||||
|
}
|
||||||
|
|
||||||
|
void batch_renderer_2d::drawLineInternal(const std::string_view texture, const line2d_t& line, const f32 z_index)
|
||||||
|
{
|
||||||
|
update_z_index(z_index);
|
||||||
|
insert_obj(draw.complex_lines, render_info_t::make_info(texture), {-z_index, line});
|
||||||
|
}
|
||||||
|
|
||||||
|
void batch_renderer_2d::drawLineInternal(const vec4& color, const line2d_t& line, const f32 z_index)
|
||||||
|
{
|
||||||
|
update_z_index(z_index);
|
||||||
|
insert_obj(draw.complex_lines, render_info_t::make_info(color), {-z_index, line});
|
||||||
|
}
|
||||||
|
|
||||||
|
void batch_renderer_2d::drawLineInternal(const render_info_t& draw_info, const line2d_t& line, const f32 z_index)
|
||||||
|
{
|
||||||
|
update_z_index(z_index);
|
||||||
|
insert_obj(draw.complex_lines, draw_info, {-z_index, line});
|
||||||
|
}
|
||||||
|
|
||||||
|
void batch_renderer_2d::drawPointInternal(const std::string_view texture, const point2d_t& point, const f32 z_index)
|
||||||
|
{
|
||||||
|
update_z_index(z_index);
|
||||||
|
insert_obj(draw.complex_points, render_info_t::make_info(texture), {-z_index, point});
|
||||||
|
}
|
||||||
|
|
||||||
|
void batch_renderer_2d::drawPointInternal(const vec4& color, const point2d_t& point, f32 z_index)
|
||||||
|
{
|
||||||
|
update_z_index(z_index);
|
||||||
|
insert_obj(draw.complex_points, render_info_t::make_info(color), {-z_index, point});
|
||||||
|
}
|
||||||
|
|
||||||
|
void batch_renderer_2d::drawPointInternal(const render_info_t& draw_info, const point2d_t& point, f32 z_index)
|
||||||
|
{
|
||||||
|
update_z_index(z_index);
|
||||||
|
insert_obj(draw.complex_points, draw_info, {-z_index, point});
|
||||||
|
}
|
||||||
|
|
||||||
void batch_renderer_2d::cleanup()
|
void batch_renderer_2d::cleanup()
|
||||||
{
|
{
|
||||||
delete square_vao;
|
delete square_vao;
|
||||||
|
@ -101,7 +152,7 @@ namespace blt::gfx
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void find_min_and_max(T& container, blt::f32& min, blt::f32& max)
|
void find_min_and_max(T& container, f32& min, f32& max)
|
||||||
{
|
{
|
||||||
for (auto& textures : container)
|
for (auto& textures : container)
|
||||||
{
|
{
|
||||||
|
@ -119,7 +170,7 @@ namespace blt::gfx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void batch_renderer_2d::render(bool transparency)
|
void batch_renderer_2d::render(const bool transparency)
|
||||||
{
|
{
|
||||||
if (transparency)
|
if (transparency)
|
||||||
{
|
{
|
||||||
|
@ -127,142 +178,143 @@ namespace blt::gfx
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
}
|
}
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
draw_count_ = 0;
|
|
||||||
square_shader->bind();
|
|
||||||
square_vao->bind();
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
|
||||||
// annoying
|
draw_objects();
|
||||||
blt::f32 min = std::numeric_limits<blt::f32>::max();
|
|
||||||
blt::f32 max = std::numeric_limits<blt::f32>::min();
|
|
||||||
|
|
||||||
find_min_and_max(complex_rectangles, min, max);
|
|
||||||
find_min_and_max(complex_points, min, max);
|
|
||||||
find_min_and_max(complex_lines, min, max);
|
|
||||||
|
|
||||||
blt::f32 denominator = 1.0f / (max - min);
|
|
||||||
|
|
||||||
for (auto& textures : complex_rectangles)
|
|
||||||
{
|
|
||||||
// resource manager handles the check for empty string
|
|
||||||
if (auto val = resources.get(textures.first))
|
|
||||||
val.value()->bind();
|
|
||||||
for (auto& colors : textures.second)
|
|
||||||
{
|
|
||||||
square_shader->setVec4("color", colors.first);
|
|
||||||
for (auto& blend_factors : colors.second)
|
|
||||||
{
|
|
||||||
square_shader->setVec4("use_texture", blend_factors.first);
|
|
||||||
for (auto& rect_obj : blend_factors.second)
|
|
||||||
{
|
|
||||||
auto& rect = rect_obj.obj;
|
|
||||||
blt::mat4x4 model;
|
|
||||||
model.translate(rect.pos.x(), rect.pos.y(), 0.0f);
|
|
||||||
model.scale(rect.size.x(), rect.size.y(), 1);
|
|
||||||
if (rect.rotation != 0)
|
|
||||||
model.rotateZ(blt::toRadians(rect.rotation));
|
|
||||||
square_shader->setMatrix("model", model);
|
|
||||||
square_shader->setFloat("z_index", (rect_obj.z_index - min) * denominator);
|
|
||||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
|
|
||||||
draw_count_++;
|
|
||||||
}
|
|
||||||
blend_factors.second.clear();
|
|
||||||
}
|
|
||||||
colors.second.clear();
|
|
||||||
}
|
|
||||||
textures.second.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
point_shader->bind();
|
|
||||||
for (auto& textures : complex_points)
|
|
||||||
{
|
|
||||||
// resource manager handles the check for empty string
|
|
||||||
if (auto val = resources.get(textures.first))
|
|
||||||
val.value()->bind();
|
|
||||||
for (auto& colors : textures.second)
|
|
||||||
{
|
|
||||||
point_shader->setVec4("color", colors.first);
|
|
||||||
for (auto& blend_factors : colors.second)
|
|
||||||
{
|
|
||||||
point_shader->setVec4("use_texture", blend_factors.first);
|
|
||||||
for (auto& point_obj : blend_factors.second)
|
|
||||||
{
|
|
||||||
auto& point = point_obj.obj;
|
|
||||||
blt::mat4x4 model;
|
|
||||||
model.translate(point.pos.x(), point.pos.y(), 0.0f);
|
|
||||||
model.scale(point.scale, point.scale, 1);
|
|
||||||
point_shader->setMatrix("model", model);
|
|
||||||
point_shader->setFloat("z_index", (point_obj.z_index - min) * denominator);
|
|
||||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
|
|
||||||
draw_count_++;
|
|
||||||
}
|
|
||||||
blend_factors.second.clear();
|
|
||||||
}
|
|
||||||
colors.second.clear();
|
|
||||||
}
|
|
||||||
textures.second.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
blt::mat4x4 model;
|
|
||||||
square_shader->bind();
|
|
||||||
square_shader->setMatrix("model", model);
|
|
||||||
line_vao->bind();
|
|
||||||
auto& buf = line_vao->getBuffer(0);
|
|
||||||
buf.bind();
|
|
||||||
for (auto& textures : complex_lines)
|
|
||||||
{
|
|
||||||
// resource manager handles the check for empty string
|
|
||||||
if (auto val = resources.get(textures.first))
|
|
||||||
val.value()->bind();
|
|
||||||
for (auto& colors : textures.second)
|
|
||||||
{
|
|
||||||
square_shader->setVec4("color", colors.first);
|
|
||||||
for (auto& blend_factors : colors.second)
|
|
||||||
{
|
|
||||||
square_shader->setVec4("use_texture", blend_factors.first);
|
|
||||||
for (auto& line_obj : blend_factors.second)
|
|
||||||
{
|
|
||||||
auto& line = line_obj.obj;
|
|
||||||
// 0, 1 (top right)
|
|
||||||
// 5, 6 (bottom right)
|
|
||||||
// 10, 11 (bottom left)
|
|
||||||
// 15, 16 (top left)
|
|
||||||
blt::vec2 dir = (line.p1 - line.p2).normalize();
|
|
||||||
blt::vec2 right = {dir.y(), -dir.x()};
|
|
||||||
blt::vec2 left = {-dir.y(), dir.x()};
|
|
||||||
|
|
||||||
auto bottom_left = line.p1 + left * line.thickness;
|
|
||||||
auto bottom_right = line.p1 + right * line.thickness;
|
|
||||||
|
|
||||||
auto top_left = line.p2 + left * line.thickness;
|
|
||||||
auto top_right = line.p2 + right * line.thickness;
|
|
||||||
|
|
||||||
line_vertices[0] = top_right.x();
|
|
||||||
line_vertices[1] = top_right.y();
|
|
||||||
|
|
||||||
line_vertices[5] = bottom_right.x();
|
|
||||||
line_vertices[6] = bottom_right.y();
|
|
||||||
|
|
||||||
line_vertices[10] = bottom_left.x();
|
|
||||||
line_vertices[11] = bottom_left.y();
|
|
||||||
|
|
||||||
line_vertices[15] = top_left.x();
|
|
||||||
line_vertices[16] = top_left.y();
|
|
||||||
|
|
||||||
buf.update(sizeof(line_vertices), line_vertices);
|
|
||||||
|
|
||||||
square_shader->setFloat("z_index", (line_obj.z_index - min) * denominator);
|
|
||||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
|
|
||||||
draw_count_++;
|
|
||||||
}
|
|
||||||
blend_factors.second.clear();
|
|
||||||
}
|
|
||||||
colors.second.clear();
|
|
||||||
}
|
|
||||||
textures.second.clear();
|
|
||||||
}
|
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
if (transparency)
|
if (transparency)
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
|
|
||||||
|
render_reset();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
void batch_renderer_2d::draw_objects()
|
||||||
|
{
|
||||||
|
pre_reset();
|
||||||
|
const f32 denominator = 1.0f / (draw.z_max - draw.z_min);
|
||||||
|
|
||||||
|
square_shader->bind();
|
||||||
|
square_vao->bind();
|
||||||
|
for (auto& [texture, objects] : draw.complex_rectangles)
|
||||||
|
{
|
||||||
|
// resource manager handles the check for empty string
|
||||||
|
if (auto val = resources.get(texture))
|
||||||
|
val.value()->bind();
|
||||||
|
for (auto& [render_info, object] : objects)
|
||||||
|
{
|
||||||
|
auto& [z_index, rect] = object;
|
||||||
|
|
||||||
|
mat4x4 model;
|
||||||
|
model.translate(rect.pos.x(), rect.pos.y(), 0.0f);
|
||||||
|
model.scale(rect.size.x(), rect.size.y(), 1);
|
||||||
|
if (rect.rotation != 0)
|
||||||
|
model.rotateZ(toRadians(rect.rotation));
|
||||||
|
|
||||||
|
square_shader->setVec4("color", render_info.color);
|
||||||
|
square_shader->setVec4("use_texture", render_info.blend);
|
||||||
|
square_shader->setFloat("z_index", (z_index - draw.z_min) * denominator);
|
||||||
|
square_shader->setMatrix("model", model);
|
||||||
|
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
|
||||||
|
draw.draw_count++;
|
||||||
|
}
|
||||||
|
objects.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4x4 empty_model;
|
||||||
|
square_shader->setMatrix("model", empty_model);
|
||||||
|
line_vao->bind();
|
||||||
|
auto& buf = line_vao->getBuffer(0);
|
||||||
|
buf.bind();
|
||||||
|
for (auto& [texture, objects] : draw.complex_lines)
|
||||||
|
{
|
||||||
|
// resource manager handles the check for empty string
|
||||||
|
if (auto val = resources.get(texture))
|
||||||
|
val.value()->bind();
|
||||||
|
for (auto& [render_info, object] : objects)
|
||||||
|
{
|
||||||
|
auto& [z_index, line] = object;
|
||||||
|
|
||||||
|
square_shader->setVec4("color", render_info.color);
|
||||||
|
square_shader->setVec4("use_texture", render_info.blend);
|
||||||
|
square_shader->setFloat("z_index", (z_index - draw.z_min) * denominator);
|
||||||
|
|
||||||
|
// 0, 1 (top right)
|
||||||
|
// 5, 6 (bottom right)
|
||||||
|
// 10, 11 (bottom left)
|
||||||
|
// 15, 16 (top left)
|
||||||
|
vec2 dir = (line.p1 - line.p2).normalize();
|
||||||
|
vec2 right = {dir.y(), -dir.x()};
|
||||||
|
vec2 left = {-dir.y(), dir.x()};
|
||||||
|
|
||||||
|
auto bottom_left = line.p1 + left * line.thickness;
|
||||||
|
auto bottom_right = line.p1 + right * line.thickness;
|
||||||
|
|
||||||
|
auto top_left = line.p2 + left * line.thickness;
|
||||||
|
auto top_right = line.p2 + right * line.thickness;
|
||||||
|
|
||||||
|
line_vertices[0] = top_right.x();
|
||||||
|
line_vertices[1] = top_right.y();
|
||||||
|
|
||||||
|
line_vertices[5] = bottom_right.x();
|
||||||
|
line_vertices[6] = bottom_right.y();
|
||||||
|
|
||||||
|
line_vertices[10] = bottom_left.x();
|
||||||
|
line_vertices[11] = bottom_left.y();
|
||||||
|
|
||||||
|
line_vertices[15] = top_left.x();
|
||||||
|
line_vertices[16] = top_left.y();
|
||||||
|
|
||||||
|
buf.update(sizeof(line_vertices), line_vertices);
|
||||||
|
|
||||||
|
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
|
||||||
|
draw.draw_count++;
|
||||||
|
}
|
||||||
|
objects.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
point_shader->bind();
|
||||||
|
square_vao->bind();
|
||||||
|
for (auto& [texture, objects] : draw.complex_points)
|
||||||
|
{
|
||||||
|
// resource manager handles the check for empty string
|
||||||
|
if (auto val = resources.get(texture))
|
||||||
|
val.value()->bind();
|
||||||
|
for (auto& [render_info, object] : objects)
|
||||||
|
{
|
||||||
|
auto& [z_index, point] = object;
|
||||||
|
|
||||||
|
mat4x4 model;
|
||||||
|
model.translate(point.pos.x(), point.pos.y(), 0.0f);
|
||||||
|
model.scale(point.scale, point.scale, 1);
|
||||||
|
|
||||||
|
point_shader->setVec4("color", render_info.color);
|
||||||
|
point_shader->setVec4("use_texture", render_info.blend);
|
||||||
|
point_shader->setFloat("z_index", (z_index - draw.z_min) * denominator);
|
||||||
|
point_shader->setMatrix("model", model);
|
||||||
|
|
||||||
|
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
|
||||||
|
draw.draw_count++;
|
||||||
|
}
|
||||||
|
objects.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
post_reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void batch_renderer_2d::render_reset()
|
||||||
|
{
|
||||||
|
draw.z_min = std::numeric_limits<f32>::max();
|
||||||
|
draw.z_max = std::numeric_limits<f32>::min();
|
||||||
|
}
|
||||||
|
|
||||||
|
void batch_renderer_2d::pre_reset()
|
||||||
|
{
|
||||||
|
draw.draw_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void batch_renderer_2d::post_reset()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -29,7 +29,6 @@ void error_callback(int error, const char* description)
|
||||||
|
|
||||||
namespace blt::gfx
|
namespace blt::gfx
|
||||||
{
|
{
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
/* GLFW Window Object */
|
/* GLFW Window Object */
|
||||||
|
@ -47,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 */
|
||||||
|
@ -69,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)
|
||||||
|
@ -87,56 +86,54 @@ 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) {
|
glfwSetScrollCallback(window_state.window, [](GLFWwindow*, double, double s) { window_state.inputManager.updateScroll(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;
|
||||||
config.GlyphMinAdvanceX = 13.0f; // Use if you want to make the icon monospaced
|
config.GlyphMinAdvanceX = 13.0f; // Use if you want to make the icon monospaced
|
||||||
static const ImWchar icon_ranges[] = {ICON_MIN_FA, ICON_MAX_FA, 0};
|
static constexpr ImWchar icon_ranges[] = {ICON_MIN_FA, ICON_MAX_FA, 0};
|
||||||
io.Fonts->AddFontFromMemoryCompressedBase85TTF(fontAwesomeRegular_compressed_data_base85, 13.0f, &config, icon_ranges);
|
io.Fonts->AddFontFromMemoryCompressedBase85TTF(fontAwesomeRegular_compressed_data_base85, 13.0f, &config, icon_ranges);
|
||||||
io.Fonts->AddFontFromMemoryCompressedTTF(fontAwesomeSolid_compressed_data, static_cast<int>(fontAwesomeSolid_compressed_size), 13.0, &config,
|
io.Fonts->AddFontFromMemoryCompressedTTF(fontAwesomeSolid_compressed_data, static_cast<int>(fontAwesomeSolid_compressed_size), 13.0, &config,
|
||||||
icon_ranges);
|
icon_ranges);
|
||||||
io.Fonts
|
io.Fonts->AddFontFromMemoryCompressedTTF(fontAwesomeBrands_compressed_data, static_cast<int>(fontAwesomeBrands_compressed_size), 13.0,
|
||||||
->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__
|
||||||
|
@ -148,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);
|
||||||
|
@ -158,27 +155,27 @@ namespace blt::gfx
|
||||||
data.width = window_state.width;
|
data.width = window_state.width;
|
||||||
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);
|
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 -- */
|
||||||
auto current_time = blt::system::nanoTime();
|
const auto current_time = system::nanoTime();
|
||||||
window_state.deltaTime = current_time - window_state.lastTime;
|
window_state.deltaTime = current_time - window_state.lastTime;
|
||||||
window_state.lastTime = current_time;
|
window_state.lastTime = current_time;
|
||||||
window_state.nanoDelta = static_cast<double>(window_state.deltaTime) / 1e9f;
|
window_state.nanoDelta = static_cast<double>(window_state.deltaTime) / 1e9f;
|
||||||
|
@ -186,27 +183,27 @@ 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;
|
||||||
int height = event->documentBodyClientHeight;
|
int height = event->documentBodyClientHeight;
|
||||||
|
|
||||||
glfwSetWindowSize(window_state.window, width, height);
|
glfwSetWindowSize(window_state.window, width, height);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
EM_JS(int, get_screen_width, (), {
|
EM_JS(int, get_screen_width, (), {
|
||||||
return document.body.clientWidth;
|
return document.body.clientWidth;
|
||||||
});
|
});
|
||||||
|
|
||||||
EM_JS(int, get_screen_height, (), {
|
EM_JS(int, get_screen_height, (), {
|
||||||
return document.body.clientHeight;
|
return document.body.clientHeight;
|
||||||
});
|
});
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void init(window_data data)
|
void init(window_data data)
|
||||||
{
|
{
|
||||||
#ifdef __EMSCRIPTEN__
|
#ifdef __EMSCRIPTEN__
|
||||||
|
@ -220,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();
|
||||||
|
|
||||||
|
@ -249,7 +246,7 @@ namespace blt::gfx
|
||||||
if (data.context.SAMPLES > 0)
|
if (data.context.SAMPLES > 0)
|
||||||
glEnable(GL_MULTISAMPLE);
|
glEnable(GL_MULTISAMPLE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* -- Call User Provided post-window-init function -- */
|
/* -- Call User Provided post-window-init function -- */
|
||||||
data.call_init();
|
data.call_init();
|
||||||
|
|
||||||
|
@ -267,52 +264,31 @@ 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()
|
double getMouseX() { return window_state.inputManager.mouseX; }
|
||||||
{
|
|
||||||
return window_state.inputManager.mouseX;
|
double getMouseY() { return window_state.inputManager.mouseY; }
|
||||||
}
|
|
||||||
|
double getMouseDX() { return window_state.inputManager.deltaX; }
|
||||||
double getMouseY()
|
|
||||||
{
|
double getMouseDY() { return window_state.inputManager.deltaY; }
|
||||||
return window_state.inputManager.mouseY;
|
|
||||||
}
|
void lockCursor() { glfwSetInputMode(window_state.window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); }
|
||||||
|
|
||||||
double getMouseDX()
|
void unlockCursor() { glfwSetInputMode(window_state.window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); }
|
||||||
{
|
|
||||||
return window_state.inputManager.deltaX;
|
bool isCursorLocked() { return glfwGetInputMode(window_state.window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED; }
|
||||||
}
|
|
||||||
|
|
||||||
double getMouseDY()
|
|
||||||
{
|
|
||||||
return window_state.inputManager.deltaY;
|
|
||||||
}
|
|
||||||
|
|
||||||
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__
|
||||||
|
@ -322,7 +298,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__
|
||||||
|
@ -332,7 +308,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__
|
||||||
|
@ -341,57 +317,27 @@ 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)
|
void setClipboard(const std::string& str) { glfwSetClipboardString(window_state.window, str.c_str()); }
|
||||||
{
|
|
||||||
glfwSetClipboardString(window_state.window, str.c_str());
|
std::string getClipboard() { return glfwGetClipboardString(window_state.window); }
|
||||||
}
|
|
||||||
|
bool isMousePressed(int button) { return window_state.inputManager.isMousePressed(button); }
|
||||||
std::string getClipboard()
|
|
||||||
{
|
bool isKeyPressed(int key) { return window_state.inputManager.isKeyPressed(key); }
|
||||||
return glfwGetClipboardString(window_state.window);
|
|
||||||
}
|
double getFrameDeltaSeconds() { return window_state.nanoDelta; }
|
||||||
|
|
||||||
bool isMousePressed(int button)
|
double getFrameDeltaMilliseconds() { return window_state.millisDelta; }
|
||||||
{
|
|
||||||
return window_state.inputManager.isMousePressed(button);
|
std::int64_t getFrameDelta() { return window_state.deltaTime; }
|
||||||
}
|
|
||||||
|
bool mouseMovedLastFrame() { return window_state.inputManager.mouse_moved; }
|
||||||
bool isKeyPressed(int key)
|
|
||||||
{
|
bool mousePressedLastFrame() { return window_state.inputManager.mouse_pressed; }
|
||||||
return window_state.inputManager.isKeyPressed(key);
|
|
||||||
}
|
bool keyPressedLastFrame() { return window_state.inputManager.key_pressed; }
|
||||||
|
|
||||||
double getFrameDeltaSeconds()
|
|
||||||
{
|
|
||||||
return window_state.nanoDelta;
|
|
||||||
}
|
|
||||||
|
|
||||||
double getFrameDeltaMilliseconds()
|
|
||||||
{
|
|
||||||
return window_state.millisDelta;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::int64_t 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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