9#ifndef _VK_MODEL_MX_H__
10#define _VK_MODEL_MX_H__
15#include <vulkan/vulkan.h>
27#include <unordered_map>
49 return std::memcmp(
this, &other,
sizeof(
VKVertex)) == 0;
68 auto hc = [&seed](
float val) {
70 seed ^= h(val) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
72 for (
int i = 0; i < 3; ++i) hc(v.
pos[i]);
73 for (
int i = 0; i < 2; ++i) hc(v.
texCoord[i]);
74 for (
int i = 0; i < 3; ++i) hc(v.
normal[i]);
104 float ka[3] = {0.2f, 0.2f, 0.2f};
105 float kd[3] = {0.8f, 0.8f, 0.8f};
106 float ks[3] = {0.0f, 0.0f, 0.0f};
139 void load(
const std::string &path,
float positionScale = 1.0f);
148 void upload(VkDevice device, VkPhysicalDevice physicalDevice,
149 VkCommandPool commandPool, VkQueue graphicsQueue);
161 void draw(VkCommandBuffer cmd)
const;
197 void drawSubMesh(VkCommandBuffer cmd,
size_t index)
const;
218 static void createBuffer(VkDevice device, VkPhysicalDevice physicalDevice,
219 VkDeviceSize size, VkBufferUsageFlags usage,
220 VkMemoryPropertyFlags properties,
221 VkBuffer &buffer, VkDeviceMemory &bufferMemory);
225 uint32_t typeFilter, VkMemoryPropertyFlags properties);
228 static void copyBuffer(VkDevice device, VkCommandPool commandPool,
229 VkQueue graphicsQueue,
230 VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size);
233 void loadOBJ(
const std::string &path,
float positionScale);
236 void loadMXMOD(
const std::string &path,
float positionScale);
239 void loadMTL(
const std::string &path);
std::string mtlLibPath_
Path to .mtl file from OBJ mtllib.
uint32_t indexCount() const
const std::vector< VKVertex > & vertices() const
static void createBuffer(VkDevice device, VkPhysicalDevice physicalDevice, VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkBuffer &buffer, VkDeviceMemory &bufferMemory)
Allocate a Vulkan buffer with the specified usage and memory flags.
void compressIndices()
Deduplicate vertices and rebuild the index list.
std::vector< uint32_t > indices_
Parsed index data.
VkBuffer vertexBuffer() const
std::vector< SubMesh > subMeshes_
Sub-mesh ranges (one per group).
VkDeviceMemory indexBufferMemory_
void loadOBJ(const std::string &path, float positionScale)
Load a Wavefront OBJ file.
std::vector< VKVertex > vertices_
Parsed vertex data.
const std::string & mtlLibPath() const
const std::vector< MXMaterial > & materials() const
uint32_t textureIndex() const
void drawSubMesh(VkCommandBuffer cmd, size_t index) const
Draw a single sub-mesh (binds vertex/index buffers and issues indexed draw).
static uint32_t findMemoryType(VkPhysicalDevice physicalDevice, uint32_t typeFilter, VkMemoryPropertyFlags properties)
Find a memory type index satisfying typeFilter and properties.
void loadMXMOD(const std::string &path, float positionScale)
Load an MXMOD format file.
void upload(VkDevice device, VkPhysicalDevice physicalDevice, VkCommandPool commandPool, VkQueue graphicsQueue)
Upload parsed geometry to device-local Vulkan buffers.
~MXModel()=default
Destructor.
const std::vector< uint32_t > & indices() const
MXModel(MXModel &&)=delete
MXModel & operator=(const MXModel &)=delete
MXModel(const MXModel &)=delete
const std::vector< SubMesh > & subMeshes() const
void draw(VkCommandBuffer cmd) const
Record a bind + indexed draw into a command buffer.
uint32_t textureIndex_
Sub-mesh texture index.
VkBuffer indexBuffer() const
MXModel()=default
Default constructor.
std::vector< MXMaterial > materials_
Parsed MTL materials.
void cleanup(VkDevice device)
Free all Vulkan buffer resources.
void load(const std::string &path, float positionScale=1.0f)
Parse a model file (.mxmod, .mxmod.z, or .obj) and populate the vertex/index vectors.
size_t subMeshCount() const
const SubMesh & subMesh(size_t i) const
VkDeviceMemory vertexBufferMemory_
MXModel & operator=(MXModel &&)=delete
void loadMTL(const std::string &path)
Parse a Wavefront .mtl file and populate materials_.
static void copyBuffer(VkDevice device, VkCommandPool commandPool, VkQueue graphicsQueue, VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size)
Copy bytes from one Vulkan buffer to another via a staging command.
Exception type used throughout libmx.
Parsed Wavefront MTL material properties.
float ks[3]
Specular colour.
int illum
Illumination model.
float ka[3]
Ambient colour.
float ns
Specular exponent.
std::string map_kd
Diffuse texture filename.
float d
Opacity (dissolve).
float kd[3]
Diffuse colour.
std::string name
Material name (newmtl).
A range of indices within the shared index buffer, with its own texture.
std::string materialName
Material name from OBJ usemtl directive.
uint32_t textureIndex
Texture slot for this sub-mesh.
uint32_t indexCount
Number of indices in this sub-mesh.
uint32_t firstIndex
Offset into the index buffer.
Hash functor for VKVertex, suitable for use in unordered_map.
std::size_t operator()(const VKVertex &v) const
Compute the hash of a VKVertex.
Per-vertex data uploaded to the Vulkan vertex buffer.
bool operator==(const VKVertex &other) const
Byte-wise equality comparison for deduplication.
float normal[3]
Surface normal vector.
float texCoord[2]
UV texture coordinates.
float pos[3]
3-D position (x, y, z).
General SDL utility helpers, file I/O, and compression utilities.