model loading

This commit is contained in:
Mars 2024-10-11 20:04:28 -04:00
parent 02cd99a73a
commit 8285b60211
Signed by: pupbrained
GPG key ID: 874E22DF2F9DFCB5
11 changed files with 19622 additions and 27 deletions

2
.envrc
View file

@ -1,2 +1,2 @@
PATH_add ./src/shaders
PATH_add ./shaders
use_flake

3499
include/tiny_obj_loader.h Normal file

File diff suppressed because it is too large Load diff

16053
models/viking_room.obj Normal file

File diff suppressed because it is too large Load diff

View file

@ -5,12 +5,17 @@
#include <set>
#define GLM_FORCE_DEPTH_ZERO_TO_ONE
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/hash.hpp>
#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>
#define TINYOBJLOADER_IMPLEMENTATION
#include <tiny_obj_loader.h>
#define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 1
#define VK_ENABLE_BETA_EXTENSIONS
#define VULKAN_HPP_NO_CONSTRUCTORS
@ -26,6 +31,9 @@ VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE
constexpr i32 WIDTH = 800;
constexpr i32 HEIGHT = 600;
constexpr const char* MODEL_PATH = "models/viking_room.obj";
constexpr const char* TEXTURE_PATH = "textures/viking_room.png";
constexpr i32 MAX_FRAMES_IN_FLIGHT = 2;
constexpr std::array<const char*, 1> validationLayers = { "VK_LAYER_KHRONOS_validation" };
@ -59,25 +67,21 @@ struct Vertex {
{ 2, 0, vk::Format::eR32G32Sfloat, offsetof(Vertex, tex_coord) } }
};
}
fn operator==(const Vertex& other) const->bool {
return pos == other.pos && color == other.color && tex_coord == other.tex_coord;
}
};
constexpr std::array<Vertex, 8> vertices = {
{ { { -0.5F, -0.5F, 0.0F }, { 1.0F, 0.0F, 0.0F }, { 0.0F, 0.0F } },
{ { 0.5F, -0.5F, 0.0F }, { 0.0F, 1.0F, 0.0F }, { 1.0F, 0.0F } },
{ { 0.5F, 0.5F, 0.0F }, { 0.0F, 0.0F, 1.0F }, { 1.0F, 1.0F } },
{ { -0.5F, 0.5F, 0.0F }, { 1.0F, 1.0F, 1.0F }, { 0.0F, 1.0F } },
{ { -0.5F, -0.5F, -0.5F }, { 1.0F, 0.0F, 0.0F }, { 0.0F, 0.0F } },
{ { 0.5F, -0.5F, -0.5F }, { 0.0F, 1.0F, 0.0F }, { 1.0F, 0.0F } },
{ { 0.5F, 0.5F, -0.5F }, { 0.0F, 0.0F, 1.0F }, { 1.0F, 1.0F } },
{ { -0.5F, 0.5F, -0.5F }, { 1.0F, 1.0F, 1.0F }, { 0.0F, 1.0F } } }
namespace std {
template <>
struct hash<Vertex> {
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);
}
};
// clang-format off
constexpr std::array<u16, 12> indices = {
0, 1, 2, 2, 3, 0,
4, 5, 6, 6, 7, 4
};
// clang-format on
}
class VulkanApp {
public:
@ -125,6 +129,8 @@ class VulkanApp {
vk::UniqueImageView mTextureImageView;
vk::UniqueSampler mTextureSampler;
std::vector<Vertex> mVertices;
std::vector<u32> mIndices;
vk::UniqueBuffer mVertexBuffer;
vk::UniqueDeviceMemory mVertexBufferMemory;
vk::UniqueBuffer mIndexBuffer;
@ -217,6 +223,7 @@ class VulkanApp {
createTextureImage();
createTextureImageView();
createTextureSampler();
loadModel();
createVertexBuffer();
createIndexBuffer();
createUniformBuffers();
@ -520,8 +527,8 @@ class VulkanApp {
}
fn createGraphicsPipeline() -> void {
std::vector<char> vertShaderCode = readFile("src/shaders/vert.spv");
std::vector<char> fragShaderCode = readFile("src/shaders/frag.spv");
std::vector<char> vertShaderCode = readFile("shaders/vert.spv");
std::vector<char> fragShaderCode = readFile("shaders/frag.spv");
vk::UniqueShaderModule vertShaderModule = createShaderModule(vertShaderCode);
vk::UniqueShaderModule fragShaderModule = createShaderModule(fragShaderCode);
@ -697,7 +704,7 @@ class VulkanApp {
fn createTextureImage() -> void {
i32 texWidth = 0, texHeight = 0, texChannels = 0;
u8* pixels = stbi_load("src/textures/texture.jpg", &texWidth, &texHeight, &texChannels, STBI_rgb_alpha);
u8* pixels = stbi_load(TEXTURE_PATH, &texWidth, &texHeight, &texChannels, STBI_rgb_alpha);
vk::DeviceSize imageSize =
static_cast<vk::DeviceSize>(texWidth) * static_cast<vk::DeviceSize>(texHeight) * 4;
@ -899,8 +906,44 @@ class VulkanApp {
endSingleTimeCommands(std::move(commandBuffer));
}
fn loadModel() -> void {
tinyobj::attrib_t attrib;
std::vector<tinyobj::shape_t> shapes;
std::vector<tinyobj::material_t> materials;
std::string warn, err;
if (!tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err, MODEL_PATH))
throw std::runtime_error(warn + err);
std::unordered_map<Vertex, u32> uniqueVertices {};
for (const tinyobj::shape_t& shape : shapes) {
for (const tinyobj::index_t& index : shape.mesh.indices) {
Vertex vertex {
.pos = {
attrib.vertices[static_cast<u32>(3 * index.vertex_index + 0)],
attrib.vertices[static_cast<u32>(3 * index.vertex_index + 1)],
attrib.vertices[static_cast<u32>(3 * index.vertex_index + 2)],
},
.color = { 1.0F, 1.0F, 1.0F },
.tex_coord = {
attrib.texcoords[static_cast<u32>(2 * index.texcoord_index + 0)],
1.0F - attrib.texcoords[static_cast<u32>(2 * index.texcoord_index + 1)],
}
};
if (!uniqueVertices.contains(vertex)) {
uniqueVertices[vertex] = static_cast<u32>(mVertices.size());
mVertices.push_back(vertex);
}
mIndices.push_back(uniqueVertices[vertex]);
}
}
}
fn createVertexBuffer() -> void {
vk::DeviceSize bufferSize = sizeof(vertices[0]) * vertices.size();
vk::DeviceSize bufferSize = sizeof(mVertices[0]) * mVertices.size();
vk::UniqueBuffer stagingBuffer;
vk::UniqueDeviceMemory stagingBufferMemory;
@ -913,7 +956,7 @@ class VulkanApp {
stagingBufferMemory
);
copyData(stagingBufferMemory.get(), bufferSize, vertices.data());
copyData(stagingBufferMemory.get(), bufferSize, mVertices.data());
createBuffer(
bufferSize,
@ -930,7 +973,7 @@ class VulkanApp {
}
fn createIndexBuffer() -> void {
vk::DeviceSize bufferSize = sizeof(indices[0]) * indices.size();
vk::DeviceSize bufferSize = sizeof(mIndices[0]) * mIndices.size();
vk::UniqueBuffer stagingBuffer;
vk::UniqueDeviceMemory stagingBufferMemory;
@ -943,7 +986,7 @@ class VulkanApp {
stagingBufferMemory
);
copyData(stagingBufferMemory.get(), bufferSize, indices.data());
copyData(stagingBufferMemory.get(), bufferSize, mIndices.data());
createBuffer(
bufferSize,
@ -1170,7 +1213,7 @@ class VulkanApp {
commandBuffer.bindVertexBuffers(0, mVertexBuffer.get(), { 0 });
commandBuffer.bindIndexBuffer(mIndexBuffer.get(), 0, vk::IndexType::eUint16);
commandBuffer.bindIndexBuffer(mIndexBuffer.get(), 0, vk::IndexType::eUint32);
commandBuffer.bindDescriptorSets(
vk::PipelineBindPoint::eGraphics,
@ -1182,7 +1225,7 @@ class VulkanApp {
nullptr
);
commandBuffer.drawIndexed(static_cast<u32>(indices.size()), 1, 0, 0, 0);
commandBuffer.drawIndexed(static_cast<u32>(mIndices.size()), 1, 0, 0, 0);
commandBuffer.endRenderPass();

View file

Before

Width:  |  Height:  |  Size: 75 KiB

After

Width:  |  Height:  |  Size: 75 KiB

BIN
textures/viking_room.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 940 KiB