Load meshes and setup shader data buffers
This commit is contained in:
@@ -2,5 +2,5 @@
|
||||
|
||||
bear -- clang++ -g -c -Wno-nullability-completeness -DVK_NO_PROTOTYPES -I$VULKAN_SDK/include vulkan_profiles/vulkan_profiles.cpp main.cpp
|
||||
bear -a -- clang -g -c -DVK_NO_PROTOTYPES -Ivulkan_profiles -I$VULKAN_SDK/include $VULKAN_SDK/include/volk/volk.c wapp/wapp.c
|
||||
bear -a -- clang++ -g -DVK_NO_PROTOTYPES -lSDL3 -lglm -o main *.o
|
||||
bear -a -- clang++ -g -DVK_NO_PROTOTYPES -lSDL3 -lglm -ltinyobjloader -o main *.o
|
||||
rm *.o
|
||||
|
||||
@@ -2,19 +2,23 @@
|
||||
|
||||
#include "wapp/wapp.h"
|
||||
#include "vulkan_profiles/vulkan_profiles.h"
|
||||
#include <glm/ext/vector_int2.hpp>
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
#include <SDL3/SDL.h>
|
||||
#include <SDL3/SDL_events.h>
|
||||
#include <SDL3/SDL_init.h>
|
||||
#include <SDL3/SDL_keycode.h>
|
||||
#include <SDL3/SDL_video.h>
|
||||
#include <SDL3/SDL_vulkan.h>
|
||||
#include <tiny_obj_loader.h>
|
||||
#define VMA_IMPLEMENTATION
|
||||
#include <vma/vk_mem_alloc.h>
|
||||
#include <volk/volk.h>
|
||||
#include <vulkan/vulkan.h>
|
||||
#include <vulkan/vk_enum_string_helper.h>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
enum ExitCode {
|
||||
EXIT_CODE_SUCCESS,
|
||||
@@ -32,6 +36,28 @@ enum ExitCode {
|
||||
EXIT_CODE_NO_QUEUE_FAMILIES,
|
||||
EXIT_CODE_NO_SUITABLE_QUEUE_FAMILY,
|
||||
EXIT_CODE_NO_SUITABLE_DEPTH_FORMAT,
|
||||
EXIT_CODE_MESH_LOAD_FAILED,
|
||||
};
|
||||
|
||||
struct Vertex {
|
||||
glm::vec3 pos;
|
||||
glm::vec3 normal;
|
||||
glm::vec2 uv;
|
||||
};
|
||||
|
||||
struct ShaderData {
|
||||
glm::mat4 projection;
|
||||
glm::mat4 view;
|
||||
glm::mat4 model[3];
|
||||
glm::vec4 light_pos{ 0.0f, -10.0f, 10.0f, 0.0f };
|
||||
u32 selected{ 1 };
|
||||
};
|
||||
|
||||
struct ShaderDataBuffer {
|
||||
VmaAllocation allocation;
|
||||
VmaAllocationInfo allocation_info;
|
||||
VkBuffer buffer;
|
||||
VkDeviceAddress device_address;
|
||||
};
|
||||
|
||||
typedef VkPhysicalDevice *VkPhysicalDeviceArray;
|
||||
@@ -39,37 +65,44 @@ typedef VkQueueFamilyProperties2 *VkQueueFamilyProperties2Array;
|
||||
typedef VkImage *VkImageArray;
|
||||
typedef VkImageView *VkImageViewArray;
|
||||
typedef VkFormat *VkFormatArray;
|
||||
typedef Vertex *VertexArray;
|
||||
typedef ShaderDataBuffer *ShaderDataBufferArray;
|
||||
|
||||
wapp_intern inline void check(VkResult result);
|
||||
wapp_intern inline void check_swapchain(VkResult result);
|
||||
wapp_intern inline void check(bool result, i32 code);
|
||||
|
||||
wapp_intern bool running = true;
|
||||
wapp_intern bool update_swapchain = false;
|
||||
wapp_intern f32 display_scale = 1.0f;
|
||||
wapp_intern SDL_Window *window = nullptr;
|
||||
wapp_intern VkInstance instance = VK_NULL_HANDLE;
|
||||
wapp_intern VkPhysicalDevice physical_device = VK_NULL_HANDLE;
|
||||
wapp_intern VkSurfaceKHR surface = VK_NULL_HANDLE;
|
||||
wapp_intern u32 queue_family_index = 0;
|
||||
wapp_intern VkDevice device = VK_NULL_HANDLE;
|
||||
wapp_intern VkQueue queue = VK_NULL_HANDLE;
|
||||
wapp_intern VmaAllocator allocator = VK_NULL_HANDLE;
|
||||
wapp_intern glm::ivec2 window_size = {};
|
||||
wapp_intern constexpr u32 max_frames_in_flight = 2;
|
||||
wapp_intern bool running = true;
|
||||
wapp_intern bool update_swapchain = false;
|
||||
wapp_intern f32 display_scale = 1.0f;
|
||||
wapp_intern SDL_Window *window = nullptr;
|
||||
wapp_intern VkInstance instance = VK_NULL_HANDLE;
|
||||
wapp_intern VkPhysicalDevice physical_device = VK_NULL_HANDLE;
|
||||
wapp_intern VkSurfaceKHR surface = VK_NULL_HANDLE;
|
||||
wapp_intern u32 queue_family_index = 0;
|
||||
wapp_intern VkDevice device = VK_NULL_HANDLE;
|
||||
wapp_intern VkQueue queue = VK_NULL_HANDLE;
|
||||
wapp_intern VmaAllocator allocator = VK_NULL_HANDLE;
|
||||
wapp_intern glm::ivec2 window_size = {};
|
||||
// NOTE (Abdelrahman): The following three variables are better queried from the physical device
|
||||
// to find the different supported values. For the purposes of this tutorial, we're using defaults
|
||||
// that are guaranteed by the spec to be available on any valid implementation.
|
||||
wapp_intern VkFormat image_format = VK_FORMAT_B8G8R8A8_SRGB;
|
||||
wapp_intern VkColorSpaceKHR colorspace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
|
||||
wapp_intern VkPresentModeKHR present_mode = VK_PRESENT_MODE_FIFO_KHR;
|
||||
wapp_intern VkSwapchainKHR swapchain = VK_NULL_HANDLE;
|
||||
wapp_intern u32 swapchain_image_count = 0;
|
||||
wapp_intern VkImageArray swapchain_images = nullptr;
|
||||
wapp_intern VkImageViewArray swapchain_views = nullptr;
|
||||
wapp_intern VkFormat depth_format = VK_FORMAT_UNDEFINED;
|
||||
wapp_intern VkImage depth_image = VK_NULL_HANDLE;
|
||||
wapp_intern VkImageView depth_view = VK_NULL_HANDLE;
|
||||
wapp_intern VmaAllocation depth_allocation = VK_NULL_HANDLE;
|
||||
wapp_intern VkFormat image_format = VK_FORMAT_B8G8R8A8_SRGB;
|
||||
wapp_intern VkColorSpaceKHR colorspace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
|
||||
wapp_intern VkPresentModeKHR present_mode = VK_PRESENT_MODE_FIFO_KHR;
|
||||
wapp_intern VkSwapchainKHR swapchain = VK_NULL_HANDLE;
|
||||
wapp_intern u32 swapchain_image_count = 0;
|
||||
wapp_intern VkImageArray swapchain_images = nullptr;
|
||||
wapp_intern VkImageViewArray swapchain_views = nullptr;
|
||||
wapp_intern VkFormat depth_format = VK_FORMAT_UNDEFINED;
|
||||
wapp_intern VkImage depth_image = VK_NULL_HANDLE;
|
||||
wapp_intern VkImageView depth_view = VK_NULL_HANDLE;
|
||||
wapp_intern VmaAllocation depth_allocation = VK_NULL_HANDLE;
|
||||
wapp_intern VkBuffer vert_index_buf = VK_NULL_HANDLE;
|
||||
wapp_intern VmaAllocation vert_index_buf_alloc = VK_NULL_HANDLE;
|
||||
wapp_intern ShaderData shader_data = {};
|
||||
wapp_intern ShaderDataBufferArray shader_data_bufs;
|
||||
|
||||
int main() {
|
||||
// {{{ Initialisation
|
||||
@@ -407,6 +440,104 @@ int main() {
|
||||
// }}}
|
||||
// }}}
|
||||
|
||||
wapp_mem_arena_allocator_temp_begin(&arena);
|
||||
|
||||
// {{{ Mesh Loading
|
||||
// {{{ Load Mesh Data
|
||||
tinyobj::attrib_t attrib;
|
||||
std::vector<tinyobj::shape_t> shapes;
|
||||
std::vector<tinyobj::material_t> materials;
|
||||
|
||||
check(tinyobj::LoadObj(&attrib, &shapes, &materials, nullptr, nullptr, "assets/suzanne.obj"),
|
||||
EXIT_CODE_MESH_LOAD_FAILED);
|
||||
const VkDeviceSize index_count = shapes[0].mesh.indices.size();
|
||||
|
||||
VertexArray vertices = wapp_array_alloc_capacity(Vertex, &arena, 128, ARRAY_INIT_NONE);
|
||||
U16Array indices = wapp_array_alloc_capacity(u16, &arena, 128, ARRAY_INIT_NONE);
|
||||
|
||||
for (tinyobj::index_t &index : shapes[0].mesh.indices) {
|
||||
Vertex v = {};
|
||||
v.pos = {
|
||||
attrib.vertices[index.vertex_index * 3],
|
||||
-attrib.vertices[index.vertex_index * 3 + 1],
|
||||
attrib.vertices[index.vertex_index * 3 + 2]
|
||||
};
|
||||
v.normal = {
|
||||
attrib.normals[index.normal_index * 3],
|
||||
-attrib.normals[index.normal_index * 3 + 1],
|
||||
attrib.normals[index.normal_index * 3 + 2]
|
||||
};
|
||||
v.uv = {
|
||||
attrib.texcoords[index.texcoord_index * 2],
|
||||
1.0 - attrib.texcoords[index.texcoord_index * 2 + 1]
|
||||
};
|
||||
|
||||
u16 idx = (u16)wapp_array_count(indices);
|
||||
wapp_array_append_alloc(Vertex, &arena, vertices, &v, ARRAY_INIT_NONE);
|
||||
wapp_array_append_alloc(u16, &arena, indices, &idx, ARRAY_INIT_NONE);
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ Upload to GPU
|
||||
VkDeviceSize vertex_buf_size = sizeof(Vertex) * wapp_array_count(vertices);
|
||||
VkDeviceSize index_buf_size = sizeof(u16) * wapp_array_count(vertices);
|
||||
|
||||
VkBufferCreateInfo buf_create_info = {};
|
||||
buf_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
||||
buf_create_info.size = vertex_buf_size + index_buf_size;
|
||||
buf_create_info.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
|
||||
|
||||
VmaAllocationCreateInfo buf_alloc_create_info = {};
|
||||
buf_alloc_create_info.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT |
|
||||
VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT |
|
||||
VMA_ALLOCATION_CREATE_MAPPED_BIT;
|
||||
buf_alloc_create_info.usage = VMA_MEMORY_USAGE_AUTO;
|
||||
|
||||
VmaAllocationInfo buf_alloc_info = {};
|
||||
|
||||
check(vmaCreateBuffer(allocator, &buf_create_info, &buf_alloc_create_info, &vert_index_buf,
|
||||
&vert_index_buf_alloc, &buf_alloc_info));
|
||||
memcpy(buf_alloc_info.pMappedData, vertices, vertex_buf_size);
|
||||
memcpy((void *)((u8 *)buf_alloc_info.pMappedData + vertex_buf_size), indices, index_buf_size);
|
||||
// }}}
|
||||
// }}}
|
||||
|
||||
wapp_mem_arena_allocator_temp_end(&arena);
|
||||
|
||||
// {{{ Shader Data Buffers
|
||||
shader_data_bufs = wapp_array_with_capacity(ShaderDataBuffer, 3, ARRAY_INIT_FILLED);
|
||||
for (u32 i = 0; i < max_frames_in_flight; ++i) {
|
||||
// {{{ Create Buffer
|
||||
VkBufferUsageFlags2CreateInfo data_buf_usage_flags = {};
|
||||
data_buf_usage_flags.sType = VK_STRUCTURE_TYPE_BUFFER_USAGE_FLAGS_2_CREATE_INFO;
|
||||
data_buf_usage_flags.usage = VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT;
|
||||
VkBufferCreateInfo data_buf_create_info = {};
|
||||
data_buf_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
||||
data_buf_create_info.size = sizeof(ShaderData);
|
||||
data_buf_create_info.usage = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT;
|
||||
data_buf_create_info.pNext = &data_buf_usage_flags;
|
||||
|
||||
VmaAllocationCreateInfo data_buf_alloc_create_info = {};
|
||||
data_buf_alloc_create_info.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT |
|
||||
VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT |
|
||||
VMA_ALLOCATION_CREATE_MAPPED_BIT;
|
||||
data_buf_create_info.usage = VMA_MEMORY_USAGE_AUTO;
|
||||
|
||||
check(vmaCreateBuffer(allocator, &data_buf_create_info, &data_buf_alloc_create_info,
|
||||
&shader_data_bufs[i].buffer, &shader_data_bufs[i].allocation,
|
||||
&shader_data_bufs[i].allocation_info));
|
||||
// }}}
|
||||
|
||||
// {{{ Get Buffer GPU Address
|
||||
VkBufferDeviceAddressInfo buf_dev_addr_info = {};
|
||||
buf_dev_addr_info.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO;
|
||||
buf_dev_addr_info.buffer = shader_data_bufs[i].buffer;
|
||||
|
||||
shader_data_bufs[i].device_address = vkGetBufferDeviceAddress(device, &buf_dev_addr_info);
|
||||
// }}}
|
||||
}
|
||||
// }}}
|
||||
|
||||
// {{{ Render Loop
|
||||
SDL_Event event = {};
|
||||
while (running) {
|
||||
@@ -426,6 +557,10 @@ int main() {
|
||||
// }}}
|
||||
|
||||
// {{{ Cleanup
|
||||
for (u32 i = 0; i < max_frames_in_flight; ++i) {
|
||||
vmaDestroyBuffer(allocator, shader_data_bufs[i].buffer, shader_data_bufs[i].allocation);
|
||||
}
|
||||
vmaDestroyBuffer(allocator, vert_index_buf, vert_index_buf_alloc);
|
||||
vkDestroyImageView(device, depth_view, nullptr);
|
||||
vmaDestroyImage(allocator, depth_image, depth_allocation);
|
||||
for (u32 i = 0; i < swapchain_image_count; ++i) {
|
||||
|
||||
Reference in New Issue
Block a user