diff options
Diffstat (limited to 'main.c')
-rw-r--r-- | main.c | 206 |
1 files changed, 157 insertions, 49 deletions
@@ -1,4 +1,5 @@ #define STB_IMAGE_IMPLEMENTATION +#define TINYOBJ_LOADER_C_IMPLEMENTATION #include <stdio.h> #include <vulkan/vulkan.h> @@ -26,35 +27,15 @@ struct vertex { vec2 texture_coords; }; -struct vertex vertices[] = { - {{-0.5f, -0.5f, 0.0f}, {1.0f, 0.0f, 0.0f}, {1.0f, 0.0f}}, - {{ 0.5f, -0.5f, 0.0f}, {0.0f, 1.0f, 0.0f}, {0.0f, 0.0f}}, - {{ 0.5f, 0.5f, 0.0f}, {0.0f, 0.0f, 1.0f}, {0.0f, 1.0f}}, - {{-0.5f, 0.5f, 0.0f}, {1.0f, 1.0f, 1.0f}, {1.0f, 1.0f}}, +struct { + size_t len, cap; + struct vertex data[]; +} *vertices; - {{-0.5f, -0.5f, -0.5f}, {1.0f, 0.0f, 0.0f}, {1.0f, 0.0f}}, - {{ 0.5f, -0.5f, -0.5f}, {0.0f, 1.0f, 0.0f}, {0.0f, 0.0f}}, - {{ 0.5f, 0.5f, -0.5f}, {0.0f, 0.0f, 1.0f}, {0.0f, 1.0f}}, - {{-0.5f, 0.5f, -0.5f}, {1.0f, 1.0f, 1.0f}, {1.0f, 1.0f}}, - -/* - {{ 0.0f, -0.5f}, {0.445f, 0.09f, 0.727f}}, - - {{-0.5f, -1.0f}, {0.445f, 0.09f, 0.727f}}, - {{-1.0f, -0.5f}, {0.445f, 0.09f, 0.727f}}, - - {{ 1.0f, -0.5f}, {0.445f, 0.09f, 0.727f}}, - {{ 0.5f, -1.0f}, {0.445f, 0.09f, 0.727f}}, - - {{ 0.0f, 1.0f}, {0.445f, 0.09f, 0.727f}}, -*/ -}; - -uint16_t indices[] = { - 0, 1, 2, 2, 3, 0, - 4, 5, 6, 6, 7, 4 -}; -// uint16_t indices[] = {1, 0, 2, 3, 0, 4, 2, 3, 5}; +struct { + size_t len, cap; + uint32_t data[]; +} *indices; VkVertexInputBindingDescription get_vertex_description() { return (VkVertexInputBindingDescription) { @@ -114,7 +95,7 @@ static uint32_t current_frame = 0; static VkBuffer vertex_buffer; static VkDeviceMemory vertex_buffer_memory; static VkBuffer index_buffer; -static VkDeviceMemory index_buffer_memroy; +static VkDeviceMemory index_buffer_memory; static VkImage texture_image; static VkDeviceMemory texture_image_memory; static VkImageView texture_view; @@ -251,7 +232,7 @@ void cleanup() { cleanup_swapchain(); vkDestroyBuffer(gpu, index_buffer, NULL); - vkFreeMemory(gpu, index_buffer_memroy, NULL); + vkFreeMemory(gpu, index_buffer_memory, NULL); vkDestroySampler(gpu, texture_sampler, NULL); vkDestroyImageView(gpu, texture_view, NULL); @@ -280,7 +261,7 @@ void cleanup() { SDL_DestroyWindow(window); } -static VKAPI_ATTR VkBool32 VKAPI_CALL debug_callback( VkDebugUtilsMessageSeverityFlagBitsEXT severity, +static VKAPI_ATTR VkBool32 VKAPI_CALL debug_callback(VkDebugUtilsMessageSeverityFlagBitsEXT severity, VkDebugUtilsMessageTypeFlagsEXT type, const VkDebugUtilsMessengerCallbackDataEXT *callback_data, void *data) { fprintf(stderr, "validation layer: %s\n", callback_data->pMessage); return VK_FALSE; @@ -872,18 +853,19 @@ void copy_buffer(VkBuffer src, VkBuffer dst, VkDeviceSize size) { void create_vertex_buffer() { VkBuffer tmp_buffer; VkDeviceMemory tmp_mem; - create_buffer(sizeof(vertices), VK_BUFFER_USAGE_TRANSFER_SRC_BIT, + VkDeviceSize size = vertices->len * sizeof(*vertices->data); + create_buffer(size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &tmp_buffer, &tmp_mem); void *data; - vkMapMemory(gpu, tmp_mem, 0, sizeof(vertices), 0, &data); - memcpy(data, vertices, sizeof(vertices)); + vkMapMemory(gpu, tmp_mem, 0, size, 0, &data); + memcpy(data, vertices->data, size); vkUnmapMemory(gpu, tmp_mem); - create_buffer(sizeof(vertices), VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, + create_buffer(size, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &vertex_buffer, &vertex_buffer_memory); - copy_buffer(tmp_buffer, vertex_buffer, sizeof(vertices)); + copy_buffer(tmp_buffer, vertex_buffer, size); vkDestroyBuffer(gpu, tmp_buffer, NULL); vkFreeMemory(gpu, tmp_mem, NULL); @@ -1066,12 +1048,12 @@ void record_command_buffer(VkCommandBuffer buffer, uint32_t image_index) { VkBuffer vertex_buffers[] = { vertex_buffer }; VkDeviceSize offsets[] = {0}; vkCmdBindVertexBuffers(buffer, 0, 1, vertex_buffers, offsets); - vkCmdBindIndexBuffer(buffer, index_buffer, 0, VK_INDEX_TYPE_UINT16); + vkCmdBindIndexBuffer(buffer, index_buffer, 0, VK_INDEX_TYPE_UINT32); vkCmdBindDescriptorSets(buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1, &desc_sets[current_frame], 0, NULL); - vkCmdDrawIndexed(buffer, sizeof(indices) / sizeof(*indices), 1, 0, 0, 0); + vkCmdDrawIndexed(buffer, indices->len, 1, 0, 0, 0); vkCmdEndRenderPass(buffer); @@ -1102,18 +1084,19 @@ void create_sync_objects() { void create_index_buffer() { VkBuffer tmp_buffer; VkDeviceMemory tmp_mem; - create_buffer(sizeof(indices), VK_BUFFER_USAGE_TRANSFER_SRC_BIT, + VkDeviceSize size = indices->len * sizeof(*indices->data); + create_buffer(size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &tmp_buffer, &tmp_mem); void *data; - vkMapMemory(gpu, tmp_mem, 0, sizeof(indices), 0, &data); - memcpy(data, indices, sizeof(indices)); + vkMapMemory(gpu, tmp_mem, 0, size, 0, &data); + memcpy(data, indices->data, size); vkUnmapMemory(gpu, tmp_mem); - create_buffer(sizeof(indices), VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, - VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &index_buffer, &index_buffer_memroy); + create_buffer(size, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &index_buffer, &index_buffer_memory); - copy_buffer(tmp_buffer, index_buffer, sizeof(indices)); + copy_buffer(tmp_buffer, index_buffer, size); vkDestroyBuffer(gpu, tmp_buffer, NULL); vkFreeMemory(gpu, tmp_mem, NULL); @@ -1332,9 +1315,9 @@ void transition_image_layout(VkImage image, VkFormat format, VkImageLayout old_l void create_texture_image() { int32_t width, height, channels; - stbi_uc *pixels = stbi_load("pfp.png", &width, &height, &channels, STBI_rgb_alpha); + stbi_uc *pixels = stbi_load("texture.png", &width, &height, &channels, STBI_rgb_alpha); if (!pixels) { - fputs("failed to open pfp.png", stderr); + fputs("failed to open texture", stderr); exit(-1); } @@ -1428,6 +1411,118 @@ void recreate_swapchain() { create_framebuffers(); } +void get_data(void *ctx, const char *filename, const int is_mtl, const char *obj_filename, char **data, size_t *len) { + (void) ctx; + if (!filename) { + fputs("null filename", stderr); + *data = NULL; + *len = 0; + return; + } + + FILE *fp = fopen(filename, "rb"); + fseek(fp, 0, SEEK_END); + *len = ftell(fp); + rewind(fp); + *data = calloc(*len, 1); + fread(*data, 1, *len + 1, fp); + fclose(fp); +} + +void load_model() { + vertices = calloc(1, sizeof(*vertices) + sizeof(*vertices->data) * 65535); + vertices->cap = 65535; + + indices = calloc(1, sizeof(*indices) + sizeof(*indices->data) * 65535); + indices->cap = 65535; + + FILE *fp = fopen("model.obj", "r"); + struct { + struct { + size_t len, cap; + struct vert { float x, y, z; } *data; + } verts; + struct { + size_t len, cap; + struct coord { float x, y; } *data; + } coords; + struct { + size_t len, cap; + struct face { size_t vert[3]; size_t coord[3]; } *data; + } faces; + } obj = { + .verts = { + .cap = 65535, + .data = calloc(obj.verts.cap, sizeof(*obj.verts.data)) + }, + .coords = { + .cap = 65535, + .data = calloc(obj.coords.cap, sizeof(*obj.coords.data)) + }, + .faces = { + .cap = 65535, + .data = calloc(obj.faces.cap, sizeof(*obj.faces.data)) + } + }; + + size_t len = 0; + char *line = NULL; + while (getline(&line, &len, fp) != -1) { + float x, y, z; + x = y = z = 0; + if (sscanf(line, "v %f %f %f", &x, &y, &z) == 3) { + if (obj.verts.len + 1 >= obj.verts.cap) + obj.verts.data = realloc(obj.verts.data, (obj.verts.cap *= 2) * sizeof(*obj.verts.data)); + obj.verts.data[obj.verts.len++] = (struct vert) { x, y, z }; + continue; + } + if (sscanf(line, "vt %f %f", &x, &y) == 2) { + if (obj.coords.len + 1 >= obj.coords.cap) + obj.coords.data = realloc(obj.coords.data, (obj.coords.cap *= 2) * sizeof(*obj.coords.data)); + obj.coords.data[obj.coords.len++] = (struct coord) { x, y }; + continue; + } + size_t vert[3], coords[3]; + if (sscanf(line, "f %ld/%ld/%*d %ld/%ld/%*d %ld/%ld/%*d", + &vert[0], &coords[0], &vert[1], &coords[1], &vert[2], &coords[2]) == 6) { + if (obj.faces.len + 1 >= obj.faces.cap) + obj.faces.cap *= 2, obj.faces.data = realloc(obj.faces.data, obj.faces.cap * sizeof(*obj.faces.data)); + obj.faces.data[obj.faces.len++] = (struct face) { + .vert = { vert[0] - 1, vert[1] - 1, vert[2] - 1 }, + .coord = { coords[0] - 1, coords[1] - 1, coords[2] - 1 } + }; + continue; + } + } + fclose(fp); + + for (size_t i = 0; i < obj.faces.len; i++) { + if (indices->len + 3 >= indices->cap) + indices->cap *= 2, indices = realloc(indices, sizeof(*indices) + sizeof(*indices->data) * indices->cap); + if (vertices->len + 3 >= vertices->cap) + vertices->cap *= 2, vertices = realloc(vertices, sizeof(*vertices) + sizeof(*vertices->data) * vertices->cap); + for (size_t j = 0; j < 3; j++) { + indices->data[indices->len++] = vertices->len; + vertices->data[vertices->len++] = (struct vertex) { + .pos = { + obj.verts.data[obj.faces.data[i].vert[j]].x, + obj.verts.data[obj.faces.data[i].vert[j]].y, + obj.verts.data[obj.faces.data[i].vert[j]].z + }, + .texture_coords = { + obj.coords.data[obj.faces.data[i].coord[j]].x, + 1.0f - obj.coords.data[obj.faces.data[i].coord[j]].y, + }, + .color = { 1.0f, 1.0f, 1.0f } + }; + } + } + + free(obj.verts.data); + free(obj.coords.data); + free(obj.faces.data); +} + void init() { SDL_Init(SDL_INIT_VIDEO); window = SDL_CreateWindow("vk", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 800, 800, SDL_WINDOW_VULKAN | SDL_WINDOW_RESIZABLE); @@ -1469,6 +1564,7 @@ void init() { create_texture_image(); create_texture_view(); create_texture_sampler(); + load_model(); create_vertex_buffer(); create_index_buffer(); create_uniform_buffers(); @@ -1568,10 +1664,22 @@ void draw() { int main() { init(); + bool running = true; SDL_Event e; - while (SDL_PollEvent(&e), e.type != SDL_QUIT) { - if (e.type == SDL_WINDOWEVENT && e.window.event == SDL_WINDOWEVENT_RESIZED) { - recreate_swapchain(); + while (running) { + SDL_PollEvent(&e); + switch (e.type) { + case SDL_WINDOWEVENT: + if (e.window.event == SDL_WINDOWEVENT_RESIZED) + recreate_swapchain(); + break; + case SDL_KEYDOWN: + if (e.key.keysym.sym == SDLK_q) + running = false; + break; + case SDL_QUIT: + running = false; + break; } draw(); } |