vulkan-test/src/util/vertex.hpp
2024-11-17 18:49:23 -05:00

124 lines
5 KiB
C++

/**
* @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 <glm/glm.hpp>
#include <glm/gtx/hash.hpp>
#define VULKAN_HPP_NO_CONSTRUCTORS
#include <vulkan/vulkan.hpp>
#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<vk::VertexInputAttributeDescription, 4> 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<vk::VertexInputAttributeDescription, 4> {
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<Vertex> {
/**
* @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<glm::vec3>()(vertex.pos) ^ (hash<glm::vec3>()(vertex.color) << 1)) >> 1) ^
(hash<glm::vec2>()(vertex.tex_coord) << 1) ^ (hash<glm::vec3>()(vertex.normal) << 2);
}
};
}