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)
set(BLT_GRAPHICS_VERSION 0.9.7)
set(BLT_GRAPHICS_VERSION 0.9.8)
set(BLT_GRAPHICS_TEST_VERSION 0.0.1)
project(BLT_WITH_GRAPHICS VERSION ${BLT_GRAPHICS_VERSION})

View File

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

View File

@ -36,15 +36,15 @@ namespace blt::gfx
struct rectangle2d_t
{
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)
@ -55,18 +55,18 @@ namespace blt::gfx
{
blt::vec2f p1;
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(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
{
std::string texture;
blt::vec4 color;
blt::vec4 texture_blend_factor;
std::variant<rectangle2d_t, point2d_t, line2d_t> t;
blt::f32 z_index;
T obj;
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:
vertex_array* square_vao = nullptr;
vertex_array* line_vao = nullptr;
shader_t* square_shader = nullptr;
shader_t* point_shader = nullptr;
resource_manager& resources;
// z-index -> draw object
std::map<blt::i32, std::vector<render_object_t>> draw_objects;
// texture -> color -> blend factor -> list of rectangles
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;
public:
explicit batch_renderer_2d(resource_manager& resources): resources(resources)
@ -133,58 +140,58 @@ namespace blt::gfx
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 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};
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 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};
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 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};
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>
@ -206,19 +213,19 @@ namespace blt::gfx
}
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);
}
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);
}
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);
}

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,
float ortho_near = -1, float ortho_far = 1);
float ortho_near = 0, float ortho_far = 1.1);
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;
}
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)
{
if (transparency)
@ -107,10 +126,22 @@ namespace blt::gfx
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
glEnable(GL_DEPTH_TEST);
draw_count_ = 0;
square_shader->bind();
square_vao->bind();
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)
{
// resource manager handles the check for empty string
@ -122,14 +153,16 @@ namespace blt::gfx
for (auto& blend_factors : colors.second)
{
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;
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_++;
}
@ -152,12 +185,14 @@ namespace blt::gfx
for (auto& blend_factors : colors.second)
{
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;
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_++;
}
@ -185,8 +220,9 @@ namespace blt::gfx
for (auto& blend_factors : colors.second)
{
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)
// 5, 6 (bottom right)
// 10, 11 (bottom left)
@ -215,6 +251,7 @@ namespace blt::gfx
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_++;
}
@ -224,6 +261,7 @@ namespace blt::gfx
}
textures.second.clear();
}
glDisable(GL_DEPTH_TEST);
if (transparency)
glDisable(GL_BLEND);
}