|  |  |  | @ -17,9 +17,6 @@ | 
		
	
		
			
				|  |  |  |  | #include <stdlib.h> | 
		
	
		
			
				|  |  |  |  | #include <string.h> | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | #define CGLTF_IMPLEMENTATION | 
		
	
		
			
				|  |  |  |  | #include <cgltf.h> | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | #include <ply.h> | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | typedef struct QueueIndicesStruct { | 
		
	
	
		
			
				
					|  |  |  | @ -2077,123 +2074,6 @@ 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) { | 
		
	
	
		
			
				
					|  |  |  | 
 |