Playing with cgltf(not much success though)

main
noah metz 2024-01-10 23:55:11 -07:00
parent 26b5af16b3
commit 36f4947c6c
3 changed files with 7128 additions and 7 deletions

@ -1,4 +1,5 @@
CFLAGS = -fsanitize=address -I/usr/local/include -O0 -g -Wall -Wextra
ROOT_DIR:=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
CFLAGS = -fsanitize=address -I $(ROOT_DIR)/include -I/usr/local/include -O0 -g -Wall -Wextra
LDFLAGS = -L/usr/local/lib -lglfw -lvulkan -ldl -Xlinker -rpath -Xlinker /usr/local/lib
CC = clang
GDB = lldb

File diff suppressed because it is too large Load Diff

@ -16,6 +16,9 @@
#include <stdio.h>
#include <string.h>
#define CGLTF_IMPLEMENTATION
#include <cgltf.h>
typedef struct QueueIndicesStruct {
uint32_t graphics_family;
uint32_t graphics_index;
@ -1611,7 +1614,7 @@ VkPipeline create_graphics_pipeline(
raster_info.rasterizerDiscardEnable = VK_FALSE;
raster_info.polygonMode = VK_POLYGON_MODE_FILL;
raster_info.lineWidth = 1.0f;
raster_info.cullMode = VK_CULL_MODE_BACK_BIT;
raster_info.cullMode = VK_CULL_MODE_NONE;
raster_info.frontFace = VK_FRONT_FACE_CLOCKWISE;
raster_info.depthBiasEnable = VK_FALSE;
raster_info.depthBiasConstantFactor = 0.0f;
@ -2071,6 +2074,123 @@ Object create_renderable(Mesh* mesh, Material* material, uint32_t descriptor_set
return object;
}
struct VertexMesh {
struct Vertex* vertex;
uint32_t vertex_count;
uint16_t* index;
uint32_t index_count;
};
struct VertexMesh* load_vertex_gltf(char* filename) {
cgltf_options options = {0};
cgltf_data* data = NULL;
cgltf_result result = cgltf_parse_file(&options, filename, &data);
if(result != cgltf_result_success) {
fprintf(stderr, "failed to load %s\n", filename);
return 0;
}
result = cgltf_load_buffers(&options, data, filename);
if(result != cgltf_result_success) {
fprintf(stderr, "failed to load buffers from %s\n", filename);
goto free_cgltf;
}
if(data->meshes_count != 1) {
fprintf(stderr, "cannot load more than 1 mesh from gltf\n");
goto free_cgltf;
}
cgltf_mesh mesh = data->meshes[0];
if(mesh.primitives_count != 1) {
fprintf(stderr, "cannot load more than 1 primitive from gltf\n");
goto free_cgltf;
}
cgltf_primitive prim = mesh.primitives[0];
if(prim.type != cgltf_primitive_type_triangles) {
fprintf(stderr, "cannot load non-triangles from gltf\n");
goto free_cgltf;
}
cgltf_attribute* color = NULL;
cgltf_attribute* position = NULL;
for(uint32_t i = 0; i < prim.attributes_count; i++) {
cgltf_attribute attribute = prim.attributes[i];
switch(attribute.type) {
case cgltf_attribute_type_color:
color = &prim.attributes[i];
break;
case cgltf_attribute_type_position:
position = &prim.attributes[i];
break;
default:
break;
}
}
if(color == NULL || position == NULL) {
fprintf(stderr, "could not find color or position attributes in gltf\n");
goto free_cgltf;
}
uint32_t vertex_count = position->data->count;
struct Vertex* vertices = malloc(sizeof(struct Vertex)*vertex_count);
if(vertices == 0) {
fprintf(stderr, "failed to callocate vertex buffer of size %d\n", vertex_count);
goto free_cgltf;
}
cgltf_float* pos = malloc(sizeof(cgltf_float)*vertex_count*3);
cgltf_accessor_unpack_floats(position->data, pos, vertex_count*3);
const uint8_t* color_vec = cgltf_buffer_view_data(color->data->buffer_view);
struct Vertex* vertex_data = malloc(sizeof(struct Vertex)*vertex_count);
if(vertex_data == 0) {
fprintf(stderr, "failed to allocate vertex data buffer\n");
goto free_cgltf;
}
for(cgltf_size i = 0; i < vertex_count; i++) {
uint16_t* colors = (uint16*)(&color_vec[2*4*i]);
struct Vertex v = {
.pos = {
pos[3*i + 0],
pos[3*i + 0],
pos[3*i + 0],
},
.color = {
((float)colors[0])/(float)UINT16_MAX,
((float)colors[1])/(float)UINT16_MAX,
((float)colors[2])/(float)UINT16_MAX,
},
};
vertex_data[i] = v;
}
uint32_t index_count = prim.indices->count;
uint16_t* indices = malloc(sizeof(uint16_t)*index_count);
if(indices == 0) {
fprintf(stderr, "failed to allocate index data buffer\n");
goto free_vertex;
}
cgltf_accessor_unpack_indices(prim.indices, indices, 2, prim.indices->count);
struct VertexMesh* ret = malloc(sizeof(struct VertexMesh));
ret->vertex_count = vertex_count;
ret->vertex = vertex_data;
ret->index_count = index_count;
ret->index = indices;
return ret;
free_vertex:
free(vertex_data);
free_cgltf:
cgltf_free(data);
return 0;
}
Mesh* load_simple_mesh(VkPhysicalDeviceMemoryProperties memories, VkDevice device, struct Vertex* vertices, uint32_t vertex_count, uint16_t* indices, uint32_t index_count, VkCommandPool transfer_pool, VkQueue transfer_queue) {
AllocatedBuffer vertex_buffer = create_populated_buffer(memories, device, (void*)vertices, sizeof(struct Vertex) * vertex_count, transfer_pool, transfer_queue, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
if(vertex_buffer.memory == VK_NULL_HANDLE) {
@ -3085,7 +3205,7 @@ VkResult draw_frame(VulkanContext* context, SceneContext* scene, uint32_t materi
Object create_simple_mesh_object(Material* simple_mesh_material, VkPhysicalDeviceMemoryProperties memories, VkDevice device, VkCommandPool transfer_pool, VkQueue transfer_queue, uint32_t max_frames_in_flight, VkDescriptorPool pool) {
Object zero = {};
Mesh* mesh = load_simple_mesh(memories, device, (struct Vertex*)vertices, 4, (uint16_t*)indices, 6, transfer_pool, transfer_queue);
Mesh* mesh = load_simple_mesh(memories, device, vertices, 4, indices, 6, transfer_pool, transfer_queue);
if(mesh == 0) {
return zero;
}
@ -3126,12 +3246,12 @@ Object create_simple_mesh_object(Material* simple_mesh_material, VkPhysicalDevic
return zero;
}
glm_quat_identity(position->rotation);
position->scale[0] = 1.f;
position->scale[1] = 1.f;
position->scale[2] = 1.f;
position->scale[0] = 10.f;
position->scale[1] = 10.f;
position->scale[2] = 10.f;
position->position[0] = 0.0f;
position->position[1] = 0.0f;
position->position[2] = 0.0f;
position->position[2] = 1.1f;
bool map_result = map_add(&object.attributes, ATTRIBUTE_ID_POSITION, position);
if(map_result == 0) {
return zero;
@ -3457,6 +3577,12 @@ void cleanup(GLFWwindow* window, VulkanContext* context) {
}
int main() {
struct VertexMesh* loaded_gltf = load_vertex_gltf("spaceship.glb");
if(loaded_gltf == 0) {
fprintf(stderr, "failed to load gltf %s\n", "spaceship.glb");
return -1;
}
GLFWwindow* window = init_window(800, 600);
if(window == 0) {
fprintf(stderr, "failed to initialize glfw window\n");