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