From cbf7d23623b5bb2d2092cb6c86bc965138b4ea75 Mon Sep 17 00:00:00 2001 From: vimene Date: Tue, 3 Feb 2026 20:26:01 +0100 Subject: added mipmaps for the hw renderer, improvements This commit add mipmaps, but for now, mipmaps are generated on the gpu at runtime. We should generate them in advance. - added mipmaps for the hardware renderer - renamed stb_image.c to stb_image.cpp - add compiler flag to stb_image.cpp to prevent warning - added pipe notation for various objects to have all clipping functions be left to right. We need this for the time being because dot notation would considerably complicate the current implementation - small improvements --- src/o3d/mesh.cpp | 10 ++++---- src/o3d/mesh.hpp | 4 ++-- src/o3d/polygon.hpp | 69 +++++++++++++++++++++++++++++++++++++---------------- 3 files changed, 56 insertions(+), 27 deletions(-) (limited to 'src/o3d') diff --git a/src/o3d/mesh.cpp b/src/o3d/mesh.cpp index fc5ff78..c3314b4 100644 --- a/src/o3d/mesh.cpp +++ b/src/o3d/mesh.cpp @@ -21,7 +21,7 @@ struct VertexIndicesHasher { } }; -Mesh Mesh::plane(float width, float height) { +Mesh Mesh::plane(float width, float height) noexcept { const float w2 = width / 2, h2 = height / 2; return { @@ -50,18 +50,18 @@ Mesh Mesh::plane(float width, float height) { }; } -std::tuple, std::vector> Mesh::linearize_indices() const & { +std::tuple, std::vector> Mesh::linearize_indices() const & noexcept { std::unordered_map, size_t, VertexIndicesHasher<3>> unique_vertices; std::vector linearized_vertices; std::vector linearized_indices; - for (const auto& triangle_indices : this->indices) { + for (const auto& triangle_indices : indices) { for (const auto& vertex_indices : triangle_indices) { auto it = unique_vertices.find(vertex_indices); if (it == unique_vertices.end()) { - linearized_vertices.emplace_back(this->vertices[vertex_indices[0]], this->normals[vertex_indices[1]], this->uvs[vertex_indices[2]]); + linearized_vertices.emplace_back(vertices[vertex_indices[0]], normals[vertex_indices[1]], uvs[vertex_indices[2]]); size_t idx = linearized_vertices.size() - 1; - unique_vertices.emplace(vertex_indices, idx); + unique_vertices[vertex_indices] = idx; linearized_indices.emplace_back(idx); } else { linearized_indices.emplace_back((*it).second); diff --git a/src/o3d/mesh.hpp b/src/o3d/mesh.hpp index d1d3f1c..cac0f62 100644 --- a/src/o3d/mesh.hpp +++ b/src/o3d/mesh.hpp @@ -13,7 +13,7 @@ namespace engine::o3d { struct Mesh { - static Mesh plane(float width, float height); + static Mesh plane(float width, float height) noexcept; std::vector vertices; std::vector normals; @@ -22,7 +22,7 @@ struct Mesh { // TODO: find a better way to do this. This workaround is due to the fact that vulkan only // accepts a single index, not an index for each attributes - std::tuple, std::vector> linearize_indices() const &; + std::tuple, std::vector> linearize_indices() const & noexcept; }; } diff --git a/src/o3d/polygon.hpp b/src/o3d/polygon.hpp index 5ede910..47ecafe 100644 --- a/src/o3d/polygon.hpp +++ b/src/o3d/polygon.hpp @@ -17,11 +17,39 @@ concept PolygonVectorTypeConcept = engine::math::VectorTypeConcept && (std::i template struct Polygon; +class ToPolygon { + public: + constexpr ToPolygon() {} +}; + template -constexpr Polygon from_triangle_derived(const engine::o3d::TriangleDerived& triangle_derived); +constexpr Polygon operator|(const engine::o3d::TriangleDerived& triangle_derived, ToPolygon); template -constexpr Polygon clip_aligned(float boundary, const Polygon& polygon); +class ClipAligned { + public: + constexpr ClipAligned(float boundary) : m_boundary { boundary } {} + + constexpr float boundary() const & { + return m_boundary; + } + private: + float m_boundary; +}; + +template +constexpr Polygon operator|(const Polygon& polygon, + ClipAligned clip_aligned); + +class DivByW { + public: + constexpr DivByW() {} +}; + +class SignedAreaXY { + public: + constexpr SignedAreaXY() {} +}; template struct Polygon { @@ -33,19 +61,19 @@ struct Polygon { : points_count { points_count }, points { points } {} constexpr Polygon clip_z(float z1, float z2) const & { - return - clip_aligned(z2, - clip_aligned(z1, - *this)); + return *this + | ClipAligned(z1) + | ClipAligned(z2) + ; } constexpr Polygon clip_xy(float x1, float y1, float x2, float y2) const & { - return - clip_aligned(y2, - clip_aligned(x2, - clip_aligned(y1, - clip_aligned(x1, - *this)))); + return *this + | ClipAligned(x1) + | ClipAligned(y1) + | ClipAligned(x2) + | ClipAligned(y2) + ; } constexpr Polygon map_xy( @@ -89,12 +117,13 @@ struct Polygon { }; template -constexpr Polygon from_triangle_derived(const engine::o3d::TriangleDerived& triangle_derived) { +constexpr Polygon operator|(const engine::o3d::TriangleDerived& triangle_derived, ToPolygon) { return { 3, { triangle_derived.derived_vertex1, triangle_derived.derived_vertex2, triangle_derived.derived_vertex3 } }; } template -constexpr Polygon clip_aligned(float boundary, const Polygon& polygon) +constexpr Polygon operator|(const Polygon& polygon, + ClipAligned clip_aligned) { using transposition = engine::math::vector_coords::transpose; constexpr auto y_coord_id = transposition::template id(); @@ -107,10 +136,10 @@ constexpr Polygon clip_aligned(float boundary, for (size_t i = 0; i < polygon.points_count; i++) { const auto& prev = polygon.points[(i + polygon.points_count - 1) % polygon.points_count]; const auto& cur = polygon.points[i]; - if (is_in(prev, boundary) != is_in(cur, boundary)) { - float fac = (boundary - prev.vertex.template v()) / (cur.vertex.template v() - prev.vertex.template v()); + if (is_in(prev, clip_aligned.boundary()) != is_in(cur, clip_aligned.boundary())) { + float fac = (clip_aligned.boundary() - prev.vertex.template v()) / (cur.vertex.template v() - prev.vertex.template v()); auto& new_point = new_polygon.points[new_polygon.points_count++]; - new_point.vertex.template v() = boundary; + new_point.vertex.template v() = clip_aligned.boundary(); new_point.vertex.template v() = engine::math::utils::lerp(prev.vertex.template v(), cur.vertex.template v(), fac); if constexpr (std::is_same_v) { // called new_w because it represents w, but because we only need x, y and w, we use @@ -127,14 +156,14 @@ constexpr Polygon clip_aligned(float boundary, new_point.b1 = engine::math::utils::lerp(prev.b1, cur.b1, fac); } } - if (is_in(cur, boundary)) + if (is_in(cur, clip_aligned.boundary())) new_polygon.points[new_polygon.points_count++] = cur; } return new_polygon; } template -constexpr Polygon div_by_w(const Polygon& polygon) { +constexpr Polygon operator|(const Polygon& polygon, DivByW) { Polygon new_polygon; new_polygon.points_count = polygon.points_count; for (std::size_t i = 0; i < polygon.points_count; i++) @@ -143,7 +172,7 @@ constexpr Polygon div_by_w(const Polygo } template -constexpr float signed_area_xy(const Polygon& polygon) { +constexpr float operator|(const Polygon& polygon, SignedAreaXY) { float res = 0.f; if (polygon.points_count > 0) { for (std::size_t i = 0; i < polygon.points_count - 1; i++) -- cgit v1.2.3