summaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
authorAnna (navi) Figueiredo Gomes <navi@vlhl.dev>2024-01-04 17:44:00 +0100
committerAnna (navi) Figueiredo Gomes <navi@vlhl.dev>2024-01-05 00:40:06 +0100
commit81be424535d5c3671f42d8347b1a50e9205af3e2 (patch)
tree12d3ef386be54c346124d1cc3c1b02c2d5648676 /main.c
parentb0adc3b8710bab4e67a28a001836b9d3d51cb3cc (diff)
dynamic vertex loading
Signed-off-by: Anna (navi) Figueiredo Gomes <navi@vlhl.dev>
Diffstat (limited to 'main.c')
-rw-r--r--main.c206
1 files changed, 157 insertions, 49 deletions
diff --git a/main.c b/main.c
index b3648cb..d606747 100644
--- a/main.c
+++ b/main.c
@@ -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();
}