/** * @file vertex.hpp * @brief Defines the vertex structure and its associated utilities for 3D rendering. * * This file contains the Vertex structure used for 3D model representation in the Vulkan * graphics pipeline. It includes position, color, texture coordinate, and normal data, along with * Vulkan-specific descriptors for vertex input handling. */ #define GLM_FORCE_DEPTH_ZERO_TO_ONE #define GLM_ENABLE_EXPERIMENTAL #include #include #define VULKAN_HPP_NO_CONSTRUCTORS #include #include "types.hpp" /** * @brief Represents a vertex in 3D space with color, texture, and normal information. * * This structure defines a vertex with all its attributes required for rendering, * including position in 3D space, RGB color, texture coordinates, and normal vector. It also * provides methods for Vulkan vertex input configuration. */ struct Vertex { glm::vec3 pos; ///< Position of the vertex in 3D space (x, y, z) glm::vec3 color; ///< RGB color values, each component in range [0, 1] glm::vec2 tex_coord; ///< Texture coordinates (u, v) for texture mapping glm::vec3 normal; ///< Normal vector of the vertex /** * @brief Provides the vertex binding description for Vulkan. * * @return vk::VertexInputBindingDescription Describes how to bind vertex data to GPU memory. * * The binding description specifies: * - Binding index (0) * - Stride (size of one vertex) * - Input rate (per-vertex data) */ static fn getBindingDescription() -> vk::VertexInputBindingDescription { return vk::VertexInputBindingDescription { .binding = 0, .stride = sizeof(Vertex), .inputRate = vk::VertexInputRate::eVertex, }; } /** * @brief Provides attribute descriptions for vertex data interpretation. * * @return std::array Array of descriptions for position, color, * texture coordinates, and normal. * * The attribute descriptions specify: * - Location indices (0 for position, 1 for color, 2 for texture coordinates, 3 for normal) * - Binding point (0) * - Data format (R32G32B32 for vec3, R32G32 for vec2) * - Offset of each attribute in the vertex structure */ static fn getAttributeDescriptions() -> std::array { return { vk::VertexInputAttributeDescription { .location = 0, .binding = 0, .format = vk::Format::eR32G32B32Sfloat, .offset = offsetof(Vertex, pos), }, vk::VertexInputAttributeDescription { .location = 1, .binding = 0, .format = vk::Format::eR32G32B32Sfloat, .offset = offsetof(Vertex, color), }, vk::VertexInputAttributeDescription { .location = 2, .binding = 0, .format = vk::Format::eR32G32Sfloat, .offset = offsetof(Vertex, tex_coord), }, vk::VertexInputAttributeDescription { .location = 3, .binding = 0, .format = vk::Format::eR32G32B32Sfloat, .offset = offsetof(Vertex, normal), }, }; } /** * @brief Compares two vertices for equality. * * @param other The vertex to compare with. * @return bool True if vertices are identical in position, color, texture coordinates, and normal. */ fn operator==(const Vertex& other) const->bool { return pos == other.pos && color == other.color && tex_coord == other.tex_coord && normal == other.normal; } }; namespace std { /** * @brief Hash function specialization for Vertex type. * * This specialization allows Vertex objects to be used as keys in unordered containers. * The hash combines position, color, texture coordinate, and normal data using bit operations * to create a unique hash value. */ template <> struct hash { /** * @brief Computes hash value for a vertex. * * @param vertex The vertex to hash. * @return size_t Hash value combining all vertex attributes. */ fn operator()(Vertex const& vertex) const->size_t { return ((hash()(vertex.pos) ^ (hash()(vertex.color) << 1)) >> 1) ^ (hash()(vertex.tex_coord) << 1) ^ (hash()(vertex.normal) << 2); } }; }