35 m_vertexCount =
static_cast<uint32_t
>(vertices.size());
36 assert(m_vertexCount >= 3 &&
"Vertex count must be at least 3");
37 const VkDeviceSize bufferSize =
sizeof(vertices[0]) * m_vertexCount;
38 uint32_t vertexSize =
sizeof(vertices[0]);
40 Buffer stagingBuffer{m_device, vertexSize, m_vertexCount, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT};
43 stagingBuffer.writeToBuffer(vertices.data());
45 m_vertexBuffer = std::make_unique<Buffer>(m_device, vertexSize, m_vertexCount, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
47 m_device.copyBuffer(stagingBuffer.getBuffer(), m_vertexBuffer->getBuffer(), bufferSize);
52 m_indexCount =
static_cast<uint32_t
>(indices.size());
53 m_hasIndexBuffer = m_indexCount > 0;
55 if (!m_hasIndexBuffer) {
59 const VkDeviceSize bufferSize =
sizeof(indices[0]) * m_indexCount;
60 uint32_t indexSize =
sizeof(indices[0]);
62 Buffer stagingBuffer{m_device, indexSize, m_indexCount, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT};
65 stagingBuffer.writeToBuffer(indices.data());
67 m_indexBuffer = std::make_unique<Buffer>(m_device, indexSize, m_indexCount, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
69 m_device.copyBuffer(stagingBuffer.getBuffer(), m_indexBuffer->getBuffer(), bufferSize);
74 if (m_hasIndexBuffer) {
75 vkCmdDrawIndexed(commandBuffer, m_indexCount, 1, 0, 0, 0);
77 vkCmdDraw(commandBuffer, m_vertexCount, 1, 0, 0);
83 const VkBuffer buffers[] = {m_vertexBuffer->getBuffer()};
84 constexpr VkDeviceSize offsets[] = {0};
85 vkCmdBindVertexBuffers(commandBuffer, 0, 1, buffers, offsets);
87 if (m_hasIndexBuffer) {
88 vkCmdBindIndexBuffer(commandBuffer, m_indexBuffer->getBuffer(), 0, VK_INDEX_TYPE_UINT32);
110 std::vector<VkVertexInputAttributeDescription> attributeDescriptions{};
112 attributeDescriptions.push_back({0, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(
Vertex, position)});
113 attributeDescriptions.push_back({1, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(
Vertex, color)});
114 attributeDescriptions.push_back({2, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(
Vertex, normal)});
115 attributeDescriptions.push_back({3, 0, VK_FORMAT_R32G32_SFLOAT, offsetof(
Vertex, uv)});
117 return attributeDescriptions;
122 tinyobj::attrib_t attrib;
123 std::vector<tinyobj::shape_t> shapes;
124 std::vector<tinyobj::material_t> materials;
128 if (!LoadObj(&attrib, &shapes, &materials, &warn, &err, filename.c_str()))
130 throw std::runtime_error(warn + err);
136 std::unordered_map<Vertex, uint32_t> uniqueVertices{};
137 for (
const auto &shape : shapes) {
138 for (
const auto &index : shape.mesh.indices) {
140 if (index.vertex_index >= 0) {
142 attrib.vertices[3 *
static_cast<size_t>(index.vertex_index) + 0],
143 attrib.vertices[3 *
static_cast<size_t>(index.vertex_index) + 1],
144 attrib.vertices[3 *
static_cast<size_t>(index.vertex_index) + 2]
148 attrib.colors[3 *
static_cast<size_t>(index.vertex_index) + 0],
149 attrib.colors[3 *
static_cast<size_t>(index.vertex_index) + 1],
150 attrib.colors[3 *
static_cast<size_t>(index.vertex_index) + 2]
154 if (index.normal_index >= 0) {
156 attrib.normals[3 *
static_cast<size_t>(index.normal_index) + 0],
157 attrib.normals[3 *
static_cast<size_t>(index.normal_index) + 1],
158 attrib.normals[3 *
static_cast<size_t>(index.normal_index) + 2]
162 if (index.texcoord_index >= 0) {
164 attrib.texcoords[2 *
static_cast<size_t>(index.texcoord_index) + 0],
165 attrib.texcoords[2 *
static_cast<size_t>(index.texcoord_index) + 1]
169 if (!uniqueVertices.contains(vertex)) {
170 uniqueVertices[vertex] =
static_cast<uint32_t
>(vertices.size());
171 vertices.push_back(vertex);
173 indices.push_back(uniqueVertices[vertex]);