z indexing on 2d objects
parent
8b6686fa3f
commit
8943558109
|
@ -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})
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue