model loading
This commit is contained in:
parent
02cd99a73a
commit
8285b60211
3499
include/tiny_obj_loader.h
Normal file
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
16053
models/viking_room.obj
Normal file
File diff suppressed because it is too large
Load diff
95
src/main.cpp
95
src/main.cpp
|
@ -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();
|
||||||
|
|
||||||
|
|
Before Width: | Height: | Size: 75 KiB After Width: | Height: | Size: 75 KiB |
BIN
textures/viking_room.png
Normal file
BIN
textures/viking_room.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 940 KiB |
Loading…
Reference in a new issue