forked from pupbrained/vulkan-test
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
93
src/main.cpp
93
src/main.cpp
|
@ -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();
|
||||
|
||||
|
|
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