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 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> #include <set>
#define GLM_FORCE_DEPTH_ZERO_TO_ONE #define GLM_FORCE_DEPTH_ZERO_TO_ONE
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/hash.hpp>
#define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h> #include <stb_image.h>
#define TINYOBJLOADER_IMPLEMENTATION
#include <tiny_obj_loader.h>
#define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 1 #define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 1
#define VK_ENABLE_BETA_EXTENSIONS #define VK_ENABLE_BETA_EXTENSIONS
#define VULKAN_HPP_NO_CONSTRUCTORS #define VULKAN_HPP_NO_CONSTRUCTORS
@ -26,6 +31,9 @@ VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE
constexpr i32 WIDTH = 800; constexpr i32 WIDTH = 800;
constexpr i32 HEIGHT = 600; 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 i32 MAX_FRAMES_IN_FLIGHT = 2;
constexpr std::array<const char*, 1> validationLayers = { "VK_LAYER_KHRONOS_validation" }; 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) } } { 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 = { namespace std {
{ { { -0.5F, -0.5F, 0.0F }, { 1.0F, 0.0F, 0.0F }, { 0.0F, 0.0F } }, template <>
{ { 0.5F, -0.5F, 0.0F }, { 0.0F, 1.0F, 0.0F }, { 1.0F, 0.0F } }, struct hash<Vertex> {
{ { 0.5F, 0.5F, 0.0F }, { 0.0F, 0.0F, 1.0F }, { 1.0F, 1.0F } }, fn operator()(Vertex const& vertex) const->size_t {
{ { -0.5F, 0.5F, 0.0F }, { 1.0F, 1.0F, 1.0F }, { 0.0F, 1.0F } }, return ((hash<glm::vec3>()(vertex.pos) ^ (hash<glm::vec3>()(vertex.color) << 1)) >> 1) ^
{ { -0.5F, -0.5F, -0.5F }, { 1.0F, 0.0F, 0.0F }, { 0.0F, 0.0F } }, (hash<glm::vec2>()(vertex.tex_coord) << 1);
{ { 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 } } } }
};
// 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 { class VulkanApp {
public: public:
@ -125,6 +129,8 @@ class VulkanApp {
vk::UniqueImageView mTextureImageView; vk::UniqueImageView mTextureImageView;
vk::UniqueSampler mTextureSampler; vk::UniqueSampler mTextureSampler;
std::vector<Vertex> mVertices;
std::vector<u32> mIndices;
vk::UniqueBuffer mVertexBuffer; vk::UniqueBuffer mVertexBuffer;
vk::UniqueDeviceMemory mVertexBufferMemory; vk::UniqueDeviceMemory mVertexBufferMemory;
vk::UniqueBuffer mIndexBuffer; vk::UniqueBuffer mIndexBuffer;
@ -217,6 +223,7 @@ class VulkanApp {
createTextureImage(); createTextureImage();
createTextureImageView(); createTextureImageView();
createTextureSampler(); createTextureSampler();
loadModel();
createVertexBuffer(); createVertexBuffer();
createIndexBuffer(); createIndexBuffer();
createUniformBuffers(); createUniformBuffers();
@ -520,8 +527,8 @@ class VulkanApp {
} }
fn createGraphicsPipeline() -> void { fn createGraphicsPipeline() -> void {
std::vector<char> vertShaderCode = readFile("src/shaders/vert.spv"); std::vector<char> vertShaderCode = readFile("shaders/vert.spv");
std::vector<char> fragShaderCode = readFile("src/shaders/frag.spv"); std::vector<char> fragShaderCode = readFile("shaders/frag.spv");
vk::UniqueShaderModule vertShaderModule = createShaderModule(vertShaderCode); vk::UniqueShaderModule vertShaderModule = createShaderModule(vertShaderCode);
vk::UniqueShaderModule fragShaderModule = createShaderModule(fragShaderCode); vk::UniqueShaderModule fragShaderModule = createShaderModule(fragShaderCode);
@ -697,7 +704,7 @@ class VulkanApp {
fn createTextureImage() -> void { fn createTextureImage() -> void {
i32 texWidth = 0, texHeight = 0, texChannels = 0; 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 = vk::DeviceSize imageSize =
static_cast<vk::DeviceSize>(texWidth) * static_cast<vk::DeviceSize>(texHeight) * 4; static_cast<vk::DeviceSize>(texWidth) * static_cast<vk::DeviceSize>(texHeight) * 4;
@ -899,8 +906,44 @@ class VulkanApp {
endSingleTimeCommands(std::move(commandBuffer)); 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 { fn createVertexBuffer() -> void {
vk::DeviceSize bufferSize = sizeof(vertices[0]) * vertices.size(); vk::DeviceSize bufferSize = sizeof(mVertices[0]) * mVertices.size();
vk::UniqueBuffer stagingBuffer; vk::UniqueBuffer stagingBuffer;
vk::UniqueDeviceMemory stagingBufferMemory; vk::UniqueDeviceMemory stagingBufferMemory;
@ -913,7 +956,7 @@ class VulkanApp {
stagingBufferMemory stagingBufferMemory
); );
copyData(stagingBufferMemory.get(), bufferSize, vertices.data()); copyData(stagingBufferMemory.get(), bufferSize, mVertices.data());
createBuffer( createBuffer(
bufferSize, bufferSize,
@ -930,7 +973,7 @@ class VulkanApp {
} }
fn createIndexBuffer() -> void { fn createIndexBuffer() -> void {
vk::DeviceSize bufferSize = sizeof(indices[0]) * indices.size(); vk::DeviceSize bufferSize = sizeof(mIndices[0]) * mIndices.size();
vk::UniqueBuffer stagingBuffer; vk::UniqueBuffer stagingBuffer;
vk::UniqueDeviceMemory stagingBufferMemory; vk::UniqueDeviceMemory stagingBufferMemory;
@ -943,7 +986,7 @@ class VulkanApp {
stagingBufferMemory stagingBufferMemory
); );
copyData(stagingBufferMemory.get(), bufferSize, indices.data()); copyData(stagingBufferMemory.get(), bufferSize, mIndices.data());
createBuffer( createBuffer(
bufferSize, bufferSize,
@ -1170,7 +1213,7 @@ class VulkanApp {
commandBuffer.bindVertexBuffers(0, mVertexBuffer.get(), { 0 }); commandBuffer.bindVertexBuffers(0, mVertexBuffer.get(), { 0 });
commandBuffer.bindIndexBuffer(mIndexBuffer.get(), 0, vk::IndexType::eUint16); commandBuffer.bindIndexBuffer(mIndexBuffer.get(), 0, vk::IndexType::eUint32);
commandBuffer.bindDescriptorSets( commandBuffer.bindDescriptorSets(
vk::PipelineBindPoint::eGraphics, vk::PipelineBindPoint::eGraphics,
@ -1182,7 +1225,7 @@ class VulkanApp {
nullptr 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(); 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