add curve rendering
parent
f60ce3dc0b
commit
ad6ef34300
|
@ -1,7 +1,7 @@
|
||||||
cmake_minimum_required(VERSION 3.25)
|
cmake_minimum_required(VERSION 3.25)
|
||||||
include(FetchContent)
|
include(FetchContent)
|
||||||
|
|
||||||
set(BLT_GRAPHICS_VERSION 1.1.8)
|
set(BLT_GRAPHICS_VERSION 1.1.9)
|
||||||
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})
|
||||||
|
|
|
@ -70,24 +70,75 @@ namespace blt::gfx
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct curve2d_mesh_data_t
|
||||||
|
{
|
||||||
|
struct line_vertex_t
|
||||||
|
{
|
||||||
|
vec3 pos;
|
||||||
|
vec2 uv;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct draw_t
|
||||||
|
{
|
||||||
|
std::unique_ptr<vertex_array_t> vao;
|
||||||
|
i32 count;
|
||||||
|
};
|
||||||
|
|
||||||
|
[[nodiscard]] draw_t to_vertex_array() const;
|
||||||
|
size_t populate_vertex_array(vertex_array_t& va) const;
|
||||||
|
|
||||||
|
[[nodiscard]] std::vector<line_vertex_t> calculate_vertices() const;
|
||||||
|
|
||||||
|
curve2d_mesh_data_t& with(const curve2d_mesh_data_t& mesh)
|
||||||
|
{
|
||||||
|
lines.insert(lines.end(), mesh.lines.begin(), mesh.lines.end());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
curve2d_mesh_data_t& set_thickness(const f32 thickness)
|
||||||
|
{
|
||||||
|
for (auto& line : lines)
|
||||||
|
line.thickness = thickness;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<line2d_t> lines;
|
||||||
|
};
|
||||||
|
|
||||||
|
class curve2d_t
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
curve2d_t(vec2 p0, vec2 p1, vec2 p2);
|
||||||
|
curve2d_t(vec2 p0, vec2 p1, vec2 p2, vec2 p3);
|
||||||
|
|
||||||
|
[[nodiscard]] vec2 get_point(f32 t) const;
|
||||||
|
|
||||||
|
[[nodiscard]] std::vector<line2d_t> to_lines(i32 segments, f32 thickness = 1.0) const;
|
||||||
|
|
||||||
|
[[nodiscard]] curve2d_mesh_data_t to_mesh(i32 segments, f32 thickness = 1.0) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
vec2 m_p0, m_p1, m_p2, m_p3;
|
||||||
|
};
|
||||||
|
|
||||||
struct point2d_t
|
struct point2d_t
|
||||||
{
|
{
|
||||||
vec2f pos;
|
vec2f pos;
|
||||||
float scale = 1;
|
f32 scale = 1;
|
||||||
|
|
||||||
point2d_t(const float x, const float y, const float scale): pos(x, y), scale(scale)
|
point2d_t(const f32 x, const f32 y, const f32 scale): pos(x, y), scale(scale)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
point2d_t(const float x, const float y): pos(x, y)
|
point2d_t(const f32 x, const f32 y): pos(x, y)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
point2d_t(const vec2f pos, const float scale): pos(pos), scale(scale)
|
point2d_t(const vec2f pos, const f32 scale): pos(pos), scale(scale)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
explicit point2d_t(const vec2f pos): pos(pos)
|
explicit point2d_t(const vec2f pos): pos(pos)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
point2d_t apply_scale(float s) const
|
[[nodiscard]] point2d_t apply_scale(const f32 s) const
|
||||||
{
|
{
|
||||||
return {pos, scale * s};
|
return {pos, scale * s};
|
||||||
}
|
}
|
||||||
|
@ -143,13 +194,14 @@ namespace blt::gfx
|
||||||
f32 z_index;
|
f32 z_index;
|
||||||
T obj;
|
T obj;
|
||||||
|
|
||||||
render_object_t(const float z_index, const T obj): z_index(z_index), obj(obj)
|
render_object_t(const f32 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>;
|
||||||
|
using curve2d_obj_t = render_object_t<curve2d_mesh_data_t>;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
using object_container = hashmap_t<std::string, std::vector<std::pair<render_info_t, T>>>;
|
using object_container = hashmap_t<std::string, std::vector<std::pair<render_info_t, T>>>;
|
||||||
|
@ -157,6 +209,7 @@ namespace blt::gfx
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<vertex_array_t> square_vao;
|
std::unique_ptr<vertex_array_t> square_vao;
|
||||||
std::unique_ptr<vertex_array_t> line_vao;
|
std::unique_ptr<vertex_array_t> line_vao;
|
||||||
|
std::unique_ptr<vertex_array_t> curve_vao;
|
||||||
std::unique_ptr<shader_t> square_shader;
|
std::unique_ptr<shader_t> square_shader;
|
||||||
std::unique_ptr<shader_t> point_shader;
|
std::unique_ptr<shader_t> point_shader;
|
||||||
resource_manager& resources;
|
resource_manager& resources;
|
||||||
|
@ -168,6 +221,7 @@ namespace blt::gfx
|
||||||
object_container<rectangle2d_obj_t> complex_rectangles;
|
object_container<rectangle2d_obj_t> complex_rectangles;
|
||||||
object_container<point2d_obj_t> complex_points;
|
object_container<point2d_obj_t> complex_points;
|
||||||
object_container<line2d_obj_t> complex_lines;
|
object_container<line2d_obj_t> complex_lines;
|
||||||
|
object_container<curve2d_obj_t> complex_curves;
|
||||||
size_t draw_count = 0;
|
size_t draw_count = 0;
|
||||||
f32 z_min = std::numeric_limits<f32>::max();
|
f32 z_min = std::numeric_limits<f32>::max();
|
||||||
f32 z_max = std::numeric_limits<f32>::min();
|
f32 z_max = std::numeric_limits<f32>::min();
|
||||||
|
@ -188,15 +242,17 @@ namespace blt::gfx
|
||||||
// called after draw_objects()
|
// called after draw_objects()
|
||||||
void post_reset();
|
void post_reset();
|
||||||
|
|
||||||
void draw_points(const f32 denominator);
|
void draw_points(f32 denominator);
|
||||||
|
|
||||||
void draw_lines(const f32 denominator);
|
void draw_lines(f32 denominator);
|
||||||
|
|
||||||
void draw_rectangles(const f32 denominator);
|
void draw_rectangles(f32 denominator);
|
||||||
|
|
||||||
|
void draw_curves(f32 denominator);
|
||||||
|
|
||||||
void draw_objects();
|
void draw_objects();
|
||||||
|
|
||||||
inline void update_z_index(f32 z_index)
|
void update_z_index(const f32 z_index)
|
||||||
{
|
{
|
||||||
draw.z_min = std::min(draw.z_min, -z_index);
|
draw.z_min = std::min(draw.z_min, -z_index);
|
||||||
draw.z_max = std::max(draw.z_max, -z_index);
|
draw.z_max = std::max(draw.z_max, -z_index);
|
||||||
|
@ -214,61 +270,31 @@ namespace blt::gfx
|
||||||
|
|
||||||
void create();
|
void create();
|
||||||
|
|
||||||
void drawRectangleInternal(std::string_view texture, const rectangle2d_t& rectangle, f32 z_index = 0);
|
void drawRectangle(const rectangle2d_t& rectangle, std::string_view texture, f32 z_index = 0);
|
||||||
|
|
||||||
void drawRectangleInternal(const vec4& color, const rectangle2d_t& rectangle, f32 z_index = 0);
|
void drawRectangle(const rectangle2d_t& rectangle, const vec4& color, f32 z_index = 0);
|
||||||
|
|
||||||
void drawRectangleInternal(const render_info_t& draw_info, const rectangle2d_t& rectangle, f32 z_index = 0);
|
void drawRectangle(const rectangle2d_t& rectangle, const render_info_t& draw_info, f32 z_index = 0);
|
||||||
|
|
||||||
void drawLineInternal(std::string_view texture, const line2d_t& line, f32 z_index = 0);
|
void drawLine(const line2d_t& line, std::string_view texture, f32 z_index = 0);
|
||||||
|
|
||||||
void drawLineInternal(const vec4& color, const line2d_t& line, f32 z_index = 0);
|
void drawLine(const line2d_t& line, const vec4& color, f32 z_index = 0);
|
||||||
|
|
||||||
void drawLineInternal(const render_info_t& draw_info, const line2d_t& line, f32 z_index = 0);
|
void drawLine(const line2d_t& line, const render_info_t& draw_info, f32 z_index = 0);
|
||||||
|
|
||||||
void drawPointInternal(std::string_view texture, const point2d_t& point, f32 z_index = 0);
|
void drawPoint(const point2d_t& point, std::string_view texture, f32 z_index = 0);
|
||||||
|
|
||||||
void drawPointInternal(const vec4& color, const point2d_t& point, f32 z_index = 0);
|
void drawPoint(const point2d_t& point, const vec4& color, f32 z_index = 0);
|
||||||
|
|
||||||
void drawPointInternal(const render_info_t& draw_info, const point2d_t& point, f32 z_index = 0);
|
void drawPoint(const point2d_t& point, const render_info_t& draw_info, f32 z_index = 0);
|
||||||
|
|
||||||
template <typename T, typename... P>
|
void drawCurve(const curve2d_mesh_data_t& curve, std::string_view texture, f32 z_index = 0);
|
||||||
void drawRectangle(const T& render_info, P... p)
|
|
||||||
{
|
|
||||||
drawRectangleInternal(render_info, {p...});
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, typename... P>
|
void drawCurve(const curve2d_mesh_data_t& curve, const vec4& color, f32 z_index = 0);
|
||||||
void drawPoint(const T& render_info, P... p)
|
|
||||||
{
|
|
||||||
drawPointInternal(render_info, {p...});
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, typename... P>
|
void drawCurve(const curve2d_mesh_data_t& curve, const render_info_t& draw_info, f32 z_index = 0);
|
||||||
void drawLine(const T& render_info, P... p)
|
|
||||||
{
|
|
||||||
drawLineInternal(render_info, {p...});
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, typename... P>
|
void render(i32 width, i32 height, bool transparency = true, bool postprocessing = false);
|
||||||
void drawRectangle(const T& render_info, f32 z_index, P... p)
|
|
||||||
{
|
|
||||||
drawRectangleInternal(render_info, {p...}, z_index);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, typename... P>
|
|
||||||
void drawPoint(const T& render_info, f32 z_index, P... p)
|
|
||||||
{
|
|
||||||
drawPointInternal(render_info, {p...}, z_index);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, typename... P>
|
|
||||||
void drawLine(const T& render_info, f32 z_index, P... p)
|
|
||||||
{
|
|
||||||
drawLineInternal(render_info, {p...}, z_index);
|
|
||||||
}
|
|
||||||
|
|
||||||
void render(i32 width, i32 height, bool transparency = true);
|
|
||||||
|
|
||||||
void cleanup();
|
void cleanup();
|
||||||
|
|
||||||
|
|
|
@ -22,23 +22,23 @@
|
||||||
// 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)
|
||||||
|
@ -48,322 +48,448 @@ float line_vertices[20] = {
|
||||||
|
|
||||||
namespace blt::gfx
|
namespace blt::gfx
|
||||||
{
|
{
|
||||||
void batch_renderer_2d::create()
|
curve2d_mesh_data_t::draw_t curve2d_mesh_data_t::to_vertex_array() const
|
||||||
{
|
{
|
||||||
{
|
const auto vertices = calculate_vertices();
|
||||||
vertex_buffer_t vertices_vbo;
|
auto vao = std::make_unique<vertex_array_t>();
|
||||||
element_buffer_t indices_vbo;
|
|
||||||
|
|
||||||
vertices_vbo.create();
|
|
||||||
indices_vbo.create();
|
|
||||||
|
|
||||||
vertices_vbo.allocate(sizeof(square_vertices), square_vertices);
|
|
||||||
indices_vbo.allocate(sizeof(square_indices), square_indices);
|
|
||||||
|
|
||||||
square_vao = std::make_unique<vertex_array_t>();
|
|
||||||
auto vb = vertex_array_t::make_vbo(vertices_vbo);
|
|
||||||
square_vao->bindVBO(vb, 0, 3, GL_FLOAT, 5 * sizeof(float), 0);
|
|
||||||
square_vao->bindVBO(vb, 1, 2, GL_FLOAT, 5 * sizeof(float), 3 * sizeof(float));
|
|
||||||
square_vao->bindElement(indices_vbo);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
vertex_buffer_t vertices_vbo;
|
|
||||||
element_buffer_t indices_vbo;
|
|
||||||
|
|
||||||
vertices_vbo.create();
|
|
||||||
indices_vbo.create();
|
|
||||||
|
|
||||||
vertices_vbo.allocate(sizeof(line_vertices), line_vertices, GL_DYNAMIC_DRAW);
|
|
||||||
indices_vbo.allocate(sizeof(square_indices), square_indices, GL_DYNAMIC_DRAW);
|
|
||||||
|
|
||||||
line_vao = std::make_unique<vertex_array_t>();
|
|
||||||
auto vb = vertex_array_t::make_vbo(vertices_vbo);
|
|
||||||
line_vao->bindVBO(vb, 0, 3, GL_FLOAT, 5 * sizeof(float), 0);
|
|
||||||
line_vao->bindVBO(vb, 1, 2, GL_FLOAT, 5 * sizeof(float), 3 * sizeof(float));
|
|
||||||
line_vao->bindElement(indices_vbo);
|
|
||||||
}
|
|
||||||
|
|
||||||
square_shader = shader_t::make_unique(shader_2d_textured_vert, shader_2d_textured_frag);
|
|
||||||
square_shader->bindAttribute(0, "vertex");
|
|
||||||
square_shader->bindAttribute(1, "uv_in");
|
|
||||||
|
|
||||||
point_shader = shader_t::make_unique(shader_2d_textured_vert, shader_2d_textured_cirlce_frag);
|
|
||||||
point_shader->bindAttribute(0, "vertex");
|
|
||||||
point_shader->bindAttribute(1, "uv_in");
|
|
||||||
|
|
||||||
engine->create();
|
|
||||||
}
|
|
||||||
|
|
||||||
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()
|
|
||||||
{
|
|
||||||
engine->cleanup();
|
|
||||||
engine = nullptr;
|
|
||||||
square_vao = nullptr;
|
|
||||||
line_vao = nullptr;
|
|
||||||
square_shader = nullptr;
|
|
||||||
point_shader = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void batch_renderer_2d::render(i32, i32, const bool transparency)
|
|
||||||
{
|
|
||||||
//draw_buffer.bind();
|
|
||||||
//draw_buffer.updateBuffersStorage(width, height);
|
|
||||||
//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
||||||
if (transparency)
|
|
||||||
{
|
|
||||||
glEnable(GL_BLEND);
|
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
||||||
}
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
|
|
||||||
engine->bind();
|
|
||||||
draw_objects();
|
|
||||||
|
|
||||||
glDisable(GL_DEPTH_TEST);
|
|
||||||
if (transparency)
|
|
||||||
glDisable(GL_BLEND);
|
|
||||||
|
|
||||||
engine->render();
|
|
||||||
render_reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
// void batch_renderer_2d::draw_objects()
|
vertex_buffer_t vertex_buffer;
|
||||||
// {
|
vertex_buffer.create();
|
||||||
// pre_reset();
|
vertex_buffer.allocate(static_cast<long>(vertices.size() * sizeof(line_vertex_t)), vertices.data());
|
||||||
// const f32 denominator = 1.0f / (draw.z_max - draw.z_min);
|
|
||||||
//
|
const auto vb = vertex_array_t::make_vbo(vertex_buffer);
|
||||||
// glEnable(GL_STENCIL_TEST);
|
vao->bindVBO(vb, 0, 3, GL_FLOAT, sizeof(line_vertex_t), 0);
|
||||||
// glClear(GL_STENCIL_BUFFER_BIT);
|
vao->bindVBO(vb, 1, 2, GL_FLOAT, sizeof(line_vertex_t), sizeof(vec3));
|
||||||
// glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
|
||||||
// glStencilMask(0xFF);
|
return {std::move(vao), static_cast<i32>(vertices.size())};
|
||||||
//
|
}
|
||||||
// glStencilFunc(GL_ALWAYS, 1, 0xFF);
|
|
||||||
// draw_points(true, false, denominator);
|
size_t curve2d_mesh_data_t::populate_vertex_array(vertex_array_t& va) const
|
||||||
//
|
{
|
||||||
// glDisable(GL_DEPTH_TEST);
|
const auto vertices = calculate_vertices();
|
||||||
// glStencilFunc(GL_EQUAL, 1, 0xFF);
|
va.getBuffer(0).update(static_cast<long>(vertices.size() * sizeof(line_vertex_t)), vertices.data());
|
||||||
// draw_points(false, true, denominator);
|
return vertices.size();
|
||||||
// glEnable(GL_DEPTH_TEST);
|
}
|
||||||
//
|
|
||||||
// glStencilFunc(GL_ALWAYS, 2, 0xFF);
|
std::vector<curve2d_mesh_data_t::line_vertex_t> curve2d_mesh_data_t::calculate_vertices() const
|
||||||
// draw_rectangles(true, false, denominator);
|
{
|
||||||
//
|
std::vector<line_vertex_t> vertices;
|
||||||
// glDisable(GL_DEPTH_TEST);
|
|
||||||
// glStencilFunc(GL_EQUAL, 2, 0xFF);
|
for (const auto [i, line] : enumerate(lines))
|
||||||
// draw_rectangles(false, true, denominator);
|
{
|
||||||
// glEnable(GL_DEPTH_TEST);
|
const float thickness = line.thickness;
|
||||||
//
|
const vec2 dir = (line.p1 - line.p2).normalize();
|
||||||
// glStencilFunc(GL_ALWAYS, 4, 0xFF);
|
const vec2 right = {dir.y(), -dir.x()};
|
||||||
// draw_lines(true, false, denominator);
|
const vec2 left = {-dir.y(), dir.x()};
|
||||||
//
|
|
||||||
// glDisable(GL_DEPTH_TEST);
|
auto bottom_left = line.p1 + left * thickness;
|
||||||
// glStencilFunc(GL_EQUAL, 4, 0xFF);
|
auto bottom_right = line.p1 + right * thickness;
|
||||||
// draw_lines(false, true, denominator);
|
|
||||||
// glEnable(GL_DEPTH_TEST);
|
auto top_left = line.p2 + left * thickness;
|
||||||
//
|
auto top_right = line.p2 + right * thickness;
|
||||||
// glStencilMask(0x00);
|
|
||||||
// glDisable(GL_STENCIL_TEST);
|
vertices.push_back({make_vec3(bottom_right), vec2{1, 0}});
|
||||||
// post_reset();
|
vertices.push_back({make_vec3(bottom_left), vec2{0, 0}});
|
||||||
// }
|
|
||||||
void batch_renderer_2d::draw_objects()
|
if (i == lines.size() - 1)
|
||||||
{
|
{
|
||||||
pre_reset();
|
vertices.push_back({make_vec3(top_right), vec2{1, 1}});
|
||||||
const f32 denominator = 1.0f / (draw.z_max - draw.z_min);
|
vertices.push_back({make_vec3(top_left), vec2{0, 1}});
|
||||||
|
} else
|
||||||
glClear(GL_STENCIL_BUFFER_BIT);
|
{
|
||||||
draw_points(denominator);
|
auto& next = lines[i + 1];
|
||||||
draw_rectangles(denominator);
|
vec2 next_dir = (next.p1 - next.p2).normalize();
|
||||||
draw_lines(denominator);
|
vec2 next_right = {next_dir.y(), -next_dir.x()};
|
||||||
post_reset();
|
vec2 next_left = {-next_dir.y(), next_dir.x()};
|
||||||
}
|
|
||||||
|
auto next_bottom_left = next.p1 + next_left * next.thickness;
|
||||||
void batch_renderer_2d::render_reset()
|
auto next_bottom_right = next.p1 + next_right * next.thickness;
|
||||||
{
|
|
||||||
draw.z_min = std::numeric_limits<f32>::max();
|
auto avg_top_left = (next_bottom_left + top_left) / 2.0f;
|
||||||
draw.z_max = std::numeric_limits<f32>::min();
|
auto avg_top_right = (next_bottom_right + top_right) / 2.0f;
|
||||||
}
|
|
||||||
|
vertices.push_back({make_vec3(avg_top_right), vec2{1, 1}});
|
||||||
void batch_renderer_2d::pre_reset()
|
vertices.push_back({make_vec3(avg_top_left), vec2{0, 1}});
|
||||||
{
|
}
|
||||||
draw.draw_count = 0;
|
}
|
||||||
}
|
|
||||||
|
return vertices;
|
||||||
void batch_renderer_2d::post_reset()
|
}
|
||||||
{
|
|
||||||
|
curve2d_t::curve2d_t(const vec2 p0, const vec2 p1, const vec2 p2): m_p0(p0), m_p1(p1), m_p2(p1), m_p3(p2)
|
||||||
}
|
{}
|
||||||
|
|
||||||
void batch_renderer_2d::draw_points(const f32 denominator)
|
curve2d_t::curve2d_t(const vec2 p0, const vec2 p1, const vec2 p2, const vec2 p3): m_p0(p0), m_p1(p1), m_p2(p2), m_p3(p3)
|
||||||
{
|
{}
|
||||||
point_shader->bind();
|
|
||||||
square_vao->bind();
|
vec2 curve2d_t::get_point(const float t) const
|
||||||
for (auto& [texture, objects] : draw.complex_points)
|
{
|
||||||
{
|
const auto t_inv = 1.0f - t;
|
||||||
// resource manager handles the check for empty string
|
const auto t_inv_sq = t_inv * t_inv;
|
||||||
if (auto val = resources.get(texture))
|
const auto t_inv_cub = t_inv_sq * t_inv;
|
||||||
val.value()->bind();
|
const auto t_sq = t * t;
|
||||||
for (auto& [render_info, object] : objects)
|
const auto t_cub = t_sq * t;
|
||||||
{
|
return t_inv_cub * m_p0 + 3 * t_inv_sq * t * m_p1 + 3 * t_inv * t_sq * m_p2 + t_cub * m_p3;
|
||||||
auto& [z_index, point] = object;
|
}
|
||||||
|
|
||||||
mat4x4 model;
|
std::vector<line2d_t> curve2d_t::to_lines(const i32 segments, const float thickness) const
|
||||||
model.translate(point.pos.x(), point.pos.y(), 0.0f);
|
{
|
||||||
model.scale(point.scale, point.scale, 1.0);
|
std::vector<line2d_t> lines;
|
||||||
point_shader->setVec4("color", render_info.color);
|
float t = 0;
|
||||||
point_shader->setVec4("use_texture", render_info.blend);
|
const float diff = 1.0f / static_cast<float>(segments);
|
||||||
|
|
||||||
//point_shader->setVec4("outline_color", render_info.outline_color);
|
for (i32 i = 0; i < segments; ++i)
|
||||||
point_shader->setFloat("z_index", (z_index - draw.z_min) * denominator);
|
{
|
||||||
point_shader->setMatrix("model", model);
|
auto begin = get_point(t);
|
||||||
|
t += diff;
|
||||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
|
auto end = get_point(t);
|
||||||
draw.draw_count++;
|
|
||||||
}
|
lines.emplace_back(begin, end, thickness);
|
||||||
objects.clear();
|
}
|
||||||
}
|
|
||||||
}
|
return lines;
|
||||||
|
}
|
||||||
void batch_renderer_2d::draw_lines(const f32 denominator)
|
|
||||||
{
|
curve2d_mesh_data_t curve2d_t::to_mesh(const i32 segments, const float thickness) const
|
||||||
mat4x4 empty_model;
|
{
|
||||||
square_shader->setMatrix("model", empty_model);
|
curve2d_mesh_data_t mesh_data;
|
||||||
line_vao->bind();
|
mesh_data.lines = to_lines(segments, thickness);
|
||||||
auto& buf = line_vao->getBuffer(0);
|
return mesh_data;
|
||||||
buf.bind();
|
}
|
||||||
for (auto& [texture, objects] : draw.complex_lines)
|
|
||||||
{
|
void batch_renderer_2d::create()
|
||||||
// resource manager handles the check for empty string
|
{
|
||||||
if (auto val = resources.get(texture))
|
{
|
||||||
val.value()->bind();
|
vertex_buffer_t vertices_vbo;
|
||||||
for (auto& [render_info, object] : objects)
|
element_buffer_t indices_vbo;
|
||||||
{
|
|
||||||
auto& [z_index, line] = object;
|
vertices_vbo.create();
|
||||||
|
indices_vbo.create();
|
||||||
float thickness = line.thickness;
|
|
||||||
square_shader->setVec4("color", render_info.color);
|
vertices_vbo.allocate(sizeof(square_vertices), square_vertices);
|
||||||
square_shader->setVec4("use_texture", render_info.blend);
|
indices_vbo.allocate(sizeof(square_indices), square_indices);
|
||||||
|
|
||||||
//square_shader->setVec4("outline_color", render_info.outline_color);
|
square_vao = std::make_unique<vertex_array_t>();
|
||||||
square_shader->setFloat("z_index", (z_index - draw.z_min) * denominator);
|
auto vb = vertex_array_t::make_vbo(vertices_vbo);
|
||||||
|
square_vao->bindVBO(vb, 0, 3, GL_FLOAT, 5 * sizeof(float), 0);
|
||||||
// 0, 1 (top right)
|
square_vao->bindVBO(vb, 1, 2, GL_FLOAT, 5 * sizeof(float), 3 * sizeof(float));
|
||||||
// 5, 6 (bottom right)
|
square_vao->bindElement(indices_vbo);
|
||||||
// 10, 11 (bottom left)
|
}
|
||||||
// 15, 16 (top left)
|
{
|
||||||
vec2 dir = (line.p1 - line.p2).normalize();
|
vertex_buffer_t vertices_vbo;
|
||||||
vec2 right = {dir.y(), -dir.x()};
|
element_buffer_t indices_vbo;
|
||||||
vec2 left = {-dir.y(), dir.x()};
|
|
||||||
|
vertices_vbo.create();
|
||||||
auto bottom_left = line.p1 + left * thickness;
|
indices_vbo.create();
|
||||||
auto bottom_right = line.p1 + right * thickness;
|
|
||||||
|
vertices_vbo.allocate(sizeof(line_vertices), line_vertices, GL_DYNAMIC_DRAW);
|
||||||
auto top_left = line.p2 + left * thickness;
|
indices_vbo.allocate(sizeof(square_indices), square_indices, GL_DYNAMIC_DRAW);
|
||||||
auto top_right = line.p2 + right * thickness;
|
|
||||||
|
line_vao = std::make_unique<vertex_array_t>();
|
||||||
line_vertices[0] = top_right.x();
|
const auto vb = vertex_array_t::make_vbo(vertices_vbo);
|
||||||
line_vertices[1] = top_right.y();
|
line_vao->bindVBO(vb, 0, 3, GL_FLOAT, 5 * sizeof(float), 0);
|
||||||
|
line_vao->bindVBO(vb, 1, 2, GL_FLOAT, 5 * sizeof(float), 3 * sizeof(float));
|
||||||
line_vertices[5] = bottom_right.x();
|
line_vao->bindElement(indices_vbo);
|
||||||
line_vertices[6] = bottom_right.y();
|
}
|
||||||
|
{
|
||||||
line_vertices[10] = bottom_left.x();
|
curve_vao = std::make_unique<vertex_array_t>();
|
||||||
line_vertices[11] = bottom_left.y();
|
|
||||||
|
vertex_buffer_t vertex_buffer;
|
||||||
line_vertices[15] = top_left.x();
|
vertex_buffer.create();
|
||||||
line_vertices[16] = top_left.y();
|
vertex_buffer.allocate(0, GL_DYNAMIC_DRAW);
|
||||||
|
|
||||||
buf.update(sizeof(line_vertices), line_vertices);
|
const auto vb = vertex_array_t::make_vbo(vertex_buffer);
|
||||||
|
curve_vao->bindVBO(vb, 0, 3, GL_FLOAT, sizeof(curve2d_mesh_data_t::line_vertex_t), 0);
|
||||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
|
curve_vao->bindVBO(vb, 1, 2, GL_FLOAT, sizeof(curve2d_mesh_data_t::line_vertex_t), sizeof(vec3));
|
||||||
draw.draw_count++;
|
}
|
||||||
}
|
|
||||||
objects.clear();
|
square_shader = shader_t::make_unique(shader_2d_textured_vert, shader_2d_textured_frag);
|
||||||
}
|
square_shader->bindAttribute(0, "vertex");
|
||||||
}
|
square_shader->bindAttribute(1, "uv_in");
|
||||||
|
|
||||||
void batch_renderer_2d::draw_rectangles(const f32 denominator)
|
point_shader = shader_t::make_unique(shader_2d_textured_vert, shader_2d_textured_cirlce_frag);
|
||||||
{
|
point_shader->bindAttribute(0, "vertex");
|
||||||
square_shader->bind();
|
point_shader->bindAttribute(1, "uv_in");
|
||||||
square_vao->bind();
|
|
||||||
for (auto& [texture, objects] : draw.complex_rectangles)
|
engine->create();
|
||||||
{
|
}
|
||||||
// resource manager handles the check for empty string
|
|
||||||
if (auto val = resources.get(texture))
|
void batch_renderer_2d::drawRectangle(const rectangle2d_t& rectangle, const std::string_view texture, const f32 z_index)
|
||||||
val.value()->bind();
|
{
|
||||||
for (auto& [render_info, object] : objects)
|
update_z_index(z_index);
|
||||||
{
|
insert_obj(draw.complex_rectangles, render_info_t::make_info(texture), {-z_index, rectangle});
|
||||||
auto& [z_index, rect] = object;
|
}
|
||||||
|
|
||||||
mat4x4 model;
|
void batch_renderer_2d::drawRectangle(const rectangle2d_t& rectangle, const vec4& color, const f32 z_index)
|
||||||
model.translate(rect.pos);
|
{
|
||||||
model.scale(rect.size);
|
update_z_index(z_index);
|
||||||
square_shader->setVec4("color", render_info.color);
|
insert_obj(draw.complex_rectangles, render_info_t::make_info(color), {-z_index, rectangle});
|
||||||
square_shader->setVec4("use_texture", render_info.blend);
|
}
|
||||||
if (rect.rotation != 0)
|
|
||||||
model.rotateZ(toRadians(rect.rotation));
|
void batch_renderer_2d::drawRectangle(const rectangle2d_t& rectangle, const render_info_t& draw_info, const f32 z_index)
|
||||||
|
{
|
||||||
//square_shader->setVec4("outline_color", render_info.outline_color);
|
update_z_index(z_index);
|
||||||
square_shader->setFloat("z_index", (z_index - draw.z_min) * denominator);
|
insert_obj(draw.complex_rectangles, draw_info, {-z_index, rectangle});
|
||||||
square_shader->setMatrix("model", model);
|
}
|
||||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
|
|
||||||
draw.draw_count++;
|
void batch_renderer_2d::drawLine(const line2d_t& line, const std::string_view texture, const f32 z_index)
|
||||||
}
|
{
|
||||||
objects.clear();
|
update_z_index(z_index);
|
||||||
}
|
insert_obj(draw.complex_lines, render_info_t::make_info(texture), {-z_index, line});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void batch_renderer_2d::drawLine(const line2d_t& line, const vec4& color, 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::drawLine(const line2d_t& line, const render_info_t& draw_info, const f32 z_index)
|
||||||
|
{
|
||||||
|
update_z_index(z_index);
|
||||||
|
insert_obj(draw.complex_lines, draw_info, {-z_index, line});
|
||||||
|
}
|
||||||
|
|
||||||
|
void batch_renderer_2d::drawPoint(const point2d_t& point, const std::string_view texture, 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::drawPoint(const point2d_t& point, const vec4& color, 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::drawPoint(const point2d_t& point, const render_info_t& draw_info, f32 z_index)
|
||||||
|
{
|
||||||
|
update_z_index(z_index);
|
||||||
|
insert_obj(draw.complex_points, draw_info, {-z_index, point});
|
||||||
|
}
|
||||||
|
|
||||||
|
void batch_renderer_2d::drawCurve(const curve2d_mesh_data_t& curve, std::string_view texture, f32 z_index)
|
||||||
|
{
|
||||||
|
update_z_index(z_index);
|
||||||
|
insert_obj(draw.complex_curves, render_info_t::make_info(texture), {-z_index, curve});
|
||||||
|
}
|
||||||
|
|
||||||
|
void batch_renderer_2d::drawCurve(const curve2d_mesh_data_t& curve, const vec4& color, f32 z_index)
|
||||||
|
{
|
||||||
|
update_z_index(z_index);
|
||||||
|
insert_obj(draw.complex_curves, render_info_t::make_info(color), {-z_index, curve});
|
||||||
|
}
|
||||||
|
|
||||||
|
void batch_renderer_2d::drawCurve(const curve2d_mesh_data_t& curve, const render_info_t& draw_info, f32 z_index)
|
||||||
|
{
|
||||||
|
update_z_index(z_index);
|
||||||
|
insert_obj(draw.complex_curves, draw_info, {-z_index, curve});
|
||||||
|
}
|
||||||
|
|
||||||
|
void batch_renderer_2d::cleanup()
|
||||||
|
{
|
||||||
|
engine->cleanup();
|
||||||
|
engine = nullptr;
|
||||||
|
square_vao = nullptr;
|
||||||
|
line_vao = nullptr;
|
||||||
|
curve_vao = nullptr;
|
||||||
|
square_shader = nullptr;
|
||||||
|
point_shader = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void batch_renderer_2d::render(i32, i32, const bool transparency, const bool postprocessing)
|
||||||
|
{
|
||||||
|
//draw_buffer.bind();
|
||||||
|
//draw_buffer.updateBuffersStorage(width, height);
|
||||||
|
//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
if (transparency)
|
||||||
|
{
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
}
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
|
||||||
|
if (engine && postprocessing)
|
||||||
|
engine->bind();
|
||||||
|
draw_objects();
|
||||||
|
|
||||||
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
if (transparency)
|
||||||
|
glDisable(GL_BLEND);
|
||||||
|
|
||||||
|
if (engine && postprocessing)
|
||||||
|
engine->render();
|
||||||
|
render_reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void batch_renderer_2d::draw_objects()
|
||||||
|
{
|
||||||
|
pre_reset();
|
||||||
|
const f32 denominator = 1.0f / (draw.z_max - draw.z_min);
|
||||||
|
|
||||||
|
glClear(GL_STENCIL_BUFFER_BIT);
|
||||||
|
draw_points(denominator);
|
||||||
|
draw_rectangles(denominator);
|
||||||
|
draw_lines(denominator);
|
||||||
|
draw_curves(denominator);
|
||||||
|
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()
|
||||||
|
{}
|
||||||
|
|
||||||
|
void batch_renderer_2d::draw_points(const f32 denominator)
|
||||||
|
{
|
||||||
|
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.0);
|
||||||
|
point_shader->setVec4("color", render_info.color);
|
||||||
|
point_shader->setVec4("use_texture", render_info.blend);
|
||||||
|
|
||||||
|
//point_shader->setVec4("outline_color", render_info.outline_color);
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void batch_renderer_2d::draw_lines(const f32 denominator)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
float thickness = line.thickness;
|
||||||
|
square_shader->setVec4("color", render_info.color);
|
||||||
|
square_shader->setVec4("use_texture", render_info.blend);
|
||||||
|
|
||||||
|
//square_shader->setVec4("outline_color", render_info.outline_color);
|
||||||
|
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 * thickness;
|
||||||
|
auto bottom_right = line.p1 + right * thickness;
|
||||||
|
|
||||||
|
auto top_left = line.p2 + left * thickness;
|
||||||
|
auto top_right = line.p2 + right * 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void batch_renderer_2d::draw_curves(const f32 denominator)
|
||||||
|
{
|
||||||
|
curve_vao->bind();
|
||||||
|
mat4x4 empty_model;
|
||||||
|
square_shader->setMatrix("model", empty_model);
|
||||||
|
for (auto& [texture, objects] : draw.complex_curves)
|
||||||
|
{
|
||||||
|
if (auto val = resources.get(texture))
|
||||||
|
val.value()->bind();
|
||||||
|
for (auto& [render_info, object] : objects)
|
||||||
|
{
|
||||||
|
auto& [z_index, curve] = 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);
|
||||||
|
|
||||||
|
const auto count = curve.populate_vertex_array(*curve_vao);
|
||||||
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, static_cast<i32>(count));
|
||||||
|
|
||||||
|
draw.draw_count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void batch_renderer_2d::draw_rectangles(const f32 denominator)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
model.scale(rect.size);
|
||||||
|
square_shader->setVec4("color", render_info.color);
|
||||||
|
square_shader->setVec4("use_texture", render_info.blend);
|
||||||
|
if (rect.rotation != 0)
|
||||||
|
model.rotateZ(toRadians(rect.rotation));
|
||||||
|
|
||||||
|
//square_shader->setVec4("outline_color", render_info.outline_color);
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,11 +35,11 @@ void gl_error_callback(GLenum source, GLenum type, GLuint id, GLenum severity, G
|
||||||
return;
|
return;
|
||||||
if (type == GL_DEBUG_TYPE_ERROR)
|
if (type == GL_DEBUG_TYPE_ERROR)
|
||||||
{
|
{
|
||||||
BLT_ERROR("[OpenGL Error] message = '%s', type = 0x%x, severity = 0x%x, source = 0x%x, id = %d",
|
BLT_ERROR("[OpenGL Error] message = '{}', type = 0x{:x}, severity = 0x{:x}, source = 0x{:x}, id = {}",
|
||||||
message, type, severity, source, id);
|
message, type, severity, source, id);
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
BLT_WARN("[OpenGL Error] message = '%s', type = 0x%x, severity = 0x%x, source = 0x%x, id = %d",
|
BLT_WARN("[OpenGL Error] message = '{}', type = 0x{:x}, severity = 0x{:x}, source = 0x{:x}, id = {}",
|
||||||
message, type, severity, source, id);
|
message, type, severity, source, id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue