z indexing on 2d objects

main
Brett 2024-04-14 17:34:56 -04:00
parent 8b6686fa3f
commit 8943558109
8 changed files with 90 additions and 44 deletions

View File

@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.25) cmake_minimum_required(VERSION 3.25)
set(BLT_GRAPHICS_VERSION 0.9.7) set(BLT_GRAPHICS_VERSION 0.9.8)
set(BLT_GRAPHICS_TEST_VERSION 0.0.1) set(BLT_GRAPHICS_TEST_VERSION 0.0.1)
project(BLT_WITH_GRAPHICS VERSION ${BLT_GRAPHICS_VERSION}) project(BLT_WITH_GRAPHICS VERSION ${BLT_GRAPHICS_VERSION})

View File

@ -20,9 +20,10 @@ layout (std140) uniform GlobalMatrices
}; };
uniform mat4 model; uniform mat4 model;
uniform float z_index;
void main() { void main() {
gl_Position = ortho * model * vec4(vertex, 1.0); gl_Position = ortho * model * vec4(vertex.xy, z_index, 1.0);
pos = vertex.xy; pos = vertex.xy;
uv = uv_in; uv = uv_in;
} }

View File

@ -36,15 +36,15 @@ namespace blt::gfx
struct rectangle2d_t struct rectangle2d_t
{ {
blt::vec2f pos, size; blt::vec2f pos, size;
float rotation = 0; blt::f32 rotation = 0;
rectangle2d_t(float x, float y, float width, float height, float rotation): pos(x, y), size(width, height), rotation(rotation) 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(float x, float y, float width, float height): pos(x, y), size(width, height) rectangle2d_t(blt::f32 x, blt::f32 y, blt::f32 width, blt::f32 height): pos(x, y), size(width, height)
{} {}
rectangle2d_t(blt::vec2f pos, blt::vec2f size, float rotation): pos(pos), size(size), rotation(rotation) rectangle2d_t(blt::vec2f pos, blt::vec2f size, blt::f32 rotation): pos(pos), size(size), rotation(rotation)
{} {}
rectangle2d_t(blt::vec2f pos, blt::vec2f size): pos(pos), size(size) rectangle2d_t(blt::vec2f pos, blt::vec2f size): pos(pos), size(size)
@ -55,18 +55,18 @@ namespace blt::gfx
{ {
blt::vec2f p1; blt::vec2f p1;
blt::vec2f p2; blt::vec2f p2;
float thickness = 1; blt::f32 thickness = 1;
line2d_t(float px1, float py1, float px2, float py2): p1(px1, py1), p2(px2, py2) line2d_t(blt::f32 px1, blt::f32 py1, blt::f32 px2, blt::f32 py2): p1(px1, py1), p2(px2, py2)
{} {}
line2d_t(blt::vec2f p1, blt::vec2f p2): p1(p1), p2(p2) line2d_t(blt::vec2f p1, blt::vec2f p2): p1(p1), p2(p2)
{} {}
line2d_t(float px1, float py1, float px2, float py2, float thickness): p1(px1, py1), p2(px2, py2), thickness(thickness) 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(blt::vec2f p1, blt::vec2f p2, float thickness): p1(p1), p2(p2), thickness(thickness) line2d_t(blt::vec2f p1, blt::vec2f p2, blt::f32 thickness): p1(p1), p2(p2), thickness(thickness)
{} {}
}; };
@ -110,22 +110,29 @@ namespace blt::gfx
} }
}; };
template<typename T>
struct render_object_t struct render_object_t
{ {
std::string texture; blt::f32 z_index;
blt::vec4 color; T obj;
blt::vec4 texture_blend_factor;
std::variant<rectangle2d_t, point2d_t, line2d_t> t; render_object_t(float z_index, T obj): z_index(z_index), obj(obj)
{}
}; };
using rectangle2d_obj_t = render_object_t<rectangle2d_t>;
using point2d_obj_t = render_object_t<point2d_t>;
using line2d_obj_t = render_object_t<line2d_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;
// z-index -> draw object // texture -> color -> blend factor -> list of rectangles
std::map<blt::i32, std::vector<render_object_t>> draw_objects; 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;
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;
size_t draw_count_ = 0; size_t draw_count_ = 0;
public: public:
explicit batch_renderer_2d(resource_manager& resources): resources(resources) explicit batch_renderer_2d(resource_manager& resources): resources(resources)
@ -133,58 +140,58 @@ namespace blt::gfx
void create(); void create();
inline void drawRectangle(std::string_view texture, const rectangle2d_t& rectangle, blt::i32 z_index = 0) inline void drawRectangle(std::string_view texture, const rectangle2d_t& rectangle, blt::f32 z_index = 0)
{ {
const static blt::vec4 empty{0, 0, 0, 1}; const static blt::vec4 empty{0, 0, 0, 1};
const static blt::vec4 full{1, 1, 1, 1}; const static blt::vec4 full{1, 1, 1, 1};
draw_objects[z_index].push_back(render_object_t{std::string(texture), empty, full, rectangle}); complex_rectangles[texture][empty][full].emplace_back(z_index, rectangle);
} }
inline void drawRectangle(const blt::vec4& color, const rectangle2d_t& rectangle, blt::i32 z_index = 0) inline void drawRectangle(const blt::vec4& color, const rectangle2d_t& rectangle, blt::f32 z_index = 0)
{ {
const static blt::vec4 empty{0, 0, 0, 0}; const static blt::vec4 empty{0, 0, 0, 0};
draw_objects[z_index].push_back(render_object_t{"", color, empty, rectangle}); complex_rectangles[""][color][empty].emplace_back(z_index, rectangle);
} }
inline void drawRectangle(const draw_state& draw_info, const rectangle2d_t& rectangle, blt::i32 z_index = 0) inline void drawRectangle(const draw_state& draw_info, const rectangle2d_t& rectangle, blt::f32 z_index = 0)
{ {
draw_objects[z_index].push_back(render_object_t{draw_info.texture_name, draw_info.color, draw_info.blend, rectangle}); complex_rectangles[draw_info.texture_name][draw_info.color][draw_info.blend].emplace_back(z_index, rectangle);
} }
inline void drawLine(std::string_view texture, const line2d_t& line, blt::i32 z_index = 0) inline void drawLine(std::string_view texture, const line2d_t& line, blt::f32 z_index = 0)
{ {
const static blt::vec4 empty{0, 0, 0, 1}; const static blt::vec4 empty{0, 0, 0, 1};
const static blt::vec4 full{1, 1, 1, 1}; const static blt::vec4 full{1, 1, 1, 1};
draw_objects[z_index].push_back(render_object_t{std::string(texture), empty, full, line}); complex_lines[texture][empty][full].emplace_back(z_index, line);
} }
inline void drawLine(const blt::vec4& color, const line2d_t& line, blt::i32 z_index = 0) inline void drawLine(const blt::vec4& color, const line2d_t& line, blt::f32 z_index = 0)
{ {
const static blt::vec4 empty{0, 0, 0, 0}; const static blt::vec4 empty{0, 0, 0, 0};
draw_objects[z_index].push_back(render_object_t{"", color, empty, line}); complex_lines[""][color][empty].emplace_back(z_index, line);
} }
inline void drawLine(const draw_state& draw_info, const line2d_t& line, blt::i32 z_index = 0) inline void drawLine(const draw_state& draw_info, const line2d_t& line, blt::f32 z_index = 0)
{ {
draw_objects[z_index].push_back(render_object_t{draw_info.texture_name, draw_info.color, draw_info.blend, line}); complex_lines[draw_info.texture_name][draw_info.color][draw_info.blend].emplace_back(z_index, line);
} }
inline void drawPoint(std::string_view texture, const point2d_t& point, blt::i32 z_index = 0) inline void drawPoint(std::string_view texture, const point2d_t& point, blt::f32 z_index = 0)
{ {
const static blt::vec4 empty{0, 0, 0, 1}; const static blt::vec4 empty{0, 0, 0, 1};
const static blt::vec4 full{1, 1, 1, 1}; const static blt::vec4 full{1, 1, 1, 1};
draw_objects[z_index].push_back(render_object_t{std::string(texture), empty, full, point}); complex_points[texture][empty][full].emplace_back(z_index, point);
} }
inline void drawPoint(const blt::vec4& color, const point2d_t& point, blt::i32 z_index = 0) inline void drawPoint(const blt::vec4& color, const point2d_t& point, blt::f32 z_index = 0)
{ {
const static blt::vec4 empty{0, 0, 0, 0}; const static blt::vec4 empty{0, 0, 0, 0};
draw_objects[z_index].push_back(render_object_t{"", color, empty, point}); complex_points[""][color][empty].emplace_back(z_index, point);
} }
inline void drawPoint(const draw_state& draw_info, const point2d_t& point, blt::i32 z_index = 0) inline void drawPoint(const draw_state& draw_info, const point2d_t& point, blt::f32 z_index = 0)
{ {
draw_objects[z_index].push_back(render_object_t{draw_info.texture_name, draw_info.color, draw_info.blend, point}); 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>
@ -206,19 +213,19 @@ namespace blt::gfx
} }
template<typename T, typename... P> template<typename T, typename... P>
inline void drawRectangle(const T& render_info, blt::i32 z_index, P... p) inline void drawRectangle(const T& render_info, blt::f32 z_index, P... p)
{ {
drawRectangle(render_info, {p...}, z_index); drawRectangle(render_info, {p...}, z_index);
} }
template<typename T, typename... P> template<typename T, typename... P>
inline void drawPoint(const T& render_info, blt::i32 z_index, P... p) inline void drawPoint(const T& render_info, blt::f32 z_index, P... p)
{ {
drawPoint(render_info, {p...}, z_index); drawPoint(render_info, {p...}, z_index);
} }
template<typename T, typename... P> template<typename T, typename... P>
inline void drawLine(const T& render_info, blt::i32 z_index, P... p) inline void drawLine(const T& render_info, blt::f32 z_index, P... p)
{ {
drawLine(render_info, {p...}, z_index); drawLine(render_info, {p...}, z_index);
} }

View File

@ -85,7 +85,7 @@ namespace blt::gfx
} }
void update_perspectives(std::int32_t width, std::int32_t height, float fov = 90, float near = 0.1f, float far = 500.0f, void update_perspectives(std::int32_t width, std::int32_t height, float fov = 90, float near = 0.1f, float far = 500.0f,
float ortho_near = -1, float ortho_far = 1); float ortho_near = 0, float ortho_far = 1.1);
void update(); void update();
}; };

@ -1 +1 @@
Subproject commit 9db3f120489ff27aa560e488d82b5ae0d64019df Subproject commit 325508e807f376fb7d287dbb9d80899eddb4e8ff

@ -1 +1 @@
Subproject commit 231cbee0fc4f59dbe5b8b853a11b08dc84e57c65 Subproject commit a1b06823fe2d964a62fda99385499b218cf5cea5

@ -1 +1 @@
Subproject commit 111397c71a5f1c2c88e05da9c84edfdba2e472a4 Subproject commit 6675317107257c2cc16c947b359d557821d85bf2

View File

@ -100,6 +100,25 @@ namespace blt::gfx
delete point_shader; delete point_shader;
} }
template<typename T>
void find_min_and_max(T& container, blt::f32& min, blt::f32& max)
{
for (auto& textures : container)
{
for (auto& colors : textures.second)
{
for (auto& blend_factors : colors.second)
{
for (auto& obj : blend_factors.second)
{
min = std::min(min, obj.z_index);
max = std::max(max, obj.z_index);
}
}
}
}
}
void batch_renderer_2d::render(bool transparency) void batch_renderer_2d::render(bool transparency)
{ {
if (transparency) if (transparency)
@ -107,10 +126,22 @@ namespace blt::gfx
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
} }
glEnable(GL_DEPTH_TEST);
draw_count_ = 0; draw_count_ = 0;
square_shader->bind(); square_shader->bind();
square_vao->bind(); square_vao->bind();
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
// annoying
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) for (auto& textures : complex_rectangles)
{ {
// resource manager handles the check for empty string // resource manager handles the check for empty string
@ -122,14 +153,16 @@ namespace blt::gfx
for (auto& blend_factors : colors.second) for (auto& blend_factors : colors.second)
{ {
square_shader->setVec4("use_texture", blend_factors.first); square_shader->setVec4("use_texture", blend_factors.first);
for (auto& rect : blend_factors.second) for (auto& rect_obj : blend_factors.second)
{ {
auto& rect = rect_obj.obj;
blt::mat4x4 model; blt::mat4x4 model;
model.translate(rect.pos.x(), rect.pos.y(), 0.0f); model.translate(rect.pos.x(), rect.pos.y(), 0.0f);
model.scale(rect.size.x(), rect.size.y(), 1); model.scale(rect.size.x(), rect.size.y(), 1);
if (rect.rotation != 0) if (rect.rotation != 0)
model.rotateZ(blt::toRadians(rect.rotation)); model.rotateZ(blt::toRadians(rect.rotation));
square_shader->setMatrix("model", model); square_shader->setMatrix("model", model);
square_shader->setFloat("z_index", (rect_obj.z_index - min) * denominator);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
draw_count_++; draw_count_++;
} }
@ -152,12 +185,14 @@ namespace blt::gfx
for (auto& blend_factors : colors.second) for (auto& blend_factors : colors.second)
{ {
point_shader->setVec4("use_texture", blend_factors.first); point_shader->setVec4("use_texture", blend_factors.first);
for (auto& point : blend_factors.second) for (auto& point_obj : blend_factors.second)
{ {
auto& point = point_obj.obj;
blt::mat4x4 model; blt::mat4x4 model;
model.translate(point.pos.x(), point.pos.y(), 0.0f); model.translate(point.pos.x(), point.pos.y(), 0.0f);
model.scale(point.scale, point.scale, 1); model.scale(point.scale, point.scale, 1);
point_shader->setMatrix("model", model); point_shader->setMatrix("model", model);
point_shader->setFloat("z_index", (point_obj.z_index - min) * denominator);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
draw_count_++; draw_count_++;
} }
@ -185,8 +220,9 @@ namespace blt::gfx
for (auto& blend_factors : colors.second) for (auto& blend_factors : colors.second)
{ {
square_shader->setVec4("use_texture", blend_factors.first); square_shader->setVec4("use_texture", blend_factors.first);
for (auto& line : blend_factors.second) for (auto& line_obj : blend_factors.second)
{ {
auto& line = line_obj.obj;
// 0, 1 (top right) // 0, 1 (top right)
// 5, 6 (bottom right) // 5, 6 (bottom right)
// 10, 11 (bottom left) // 10, 11 (bottom left)
@ -215,6 +251,7 @@ namespace blt::gfx
buf.update(sizeof(line_vertices), line_vertices); 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); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
draw_count_++; draw_count_++;
} }
@ -224,6 +261,7 @@ namespace blt::gfx
} }
textures.second.clear(); textures.second.clear();
} }
glDisable(GL_DEPTH_TEST);
if (transparency) if (transparency)
glDisable(GL_BLEND); glDisable(GL_BLEND);
} }