|
|
@ -16,6 +16,9 @@
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define CGLTF_IMPLEMENTATION
|
|
|
|
|
|
|
|
#include <cgltf.h>
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct QueueIndicesStruct {
|
|
|
|
typedef struct QueueIndicesStruct {
|
|
|
|
uint32_t graphics_family;
|
|
|
|
uint32_t graphics_family;
|
|
|
|
uint32_t graphics_index;
|
|
|
|
uint32_t graphics_index;
|
|
|
@ -1611,7 +1614,7 @@ VkPipeline create_graphics_pipeline(
|
|
|
|
raster_info.rasterizerDiscardEnable = VK_FALSE;
|
|
|
|
raster_info.rasterizerDiscardEnable = VK_FALSE;
|
|
|
|
raster_info.polygonMode = VK_POLYGON_MODE_FILL;
|
|
|
|
raster_info.polygonMode = VK_POLYGON_MODE_FILL;
|
|
|
|
raster_info.lineWidth = 1.0f;
|
|
|
|
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.frontFace = VK_FRONT_FACE_CLOCKWISE;
|
|
|
|
raster_info.depthBiasEnable = VK_FALSE;
|
|
|
|
raster_info.depthBiasEnable = VK_FALSE;
|
|
|
|
raster_info.depthBiasConstantFactor = 0.0f;
|
|
|
|
raster_info.depthBiasConstantFactor = 0.0f;
|
|
|
@ -2071,6 +2074,123 @@ Object create_renderable(Mesh* mesh, Material* material, uint32_t descriptor_set
|
|
|
|
return object;
|
|
|
|
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) {
|
|
|
|
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);
|
|
|
|
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) {
|
|
|
|
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 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 = {};
|
|
|
|
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) {
|
|
|
|
if(mesh == 0) {
|
|
|
|
return zero;
|
|
|
|
return zero;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -3126,12 +3246,12 @@ Object create_simple_mesh_object(Material* simple_mesh_material, VkPhysicalDevic
|
|
|
|
return zero;
|
|
|
|
return zero;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
glm_quat_identity(position->rotation);
|
|
|
|
glm_quat_identity(position->rotation);
|
|
|
|
position->scale[0] = 1.f;
|
|
|
|
position->scale[0] = 10.f;
|
|
|
|
position->scale[1] = 1.f;
|
|
|
|
position->scale[1] = 10.f;
|
|
|
|
position->scale[2] = 1.f;
|
|
|
|
position->scale[2] = 10.f;
|
|
|
|
position->position[0] = 0.0f;
|
|
|
|
position->position[0] = 0.0f;
|
|
|
|
position->position[1] = 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);
|
|
|
|
bool map_result = map_add(&object.attributes, ATTRIBUTE_ID_POSITION, position);
|
|
|
|
if(map_result == 0) {
|
|
|
|
if(map_result == 0) {
|
|
|
|
return zero;
|
|
|
|
return zero;
|
|
|
@ -3457,6 +3577,12 @@ void cleanup(GLFWwindow* window, VulkanContext* context) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int main() {
|
|
|
|
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);
|
|
|
|
GLFWwindow* window = init_window(800, 600);
|
|
|
|
if(window == 0) {
|
|
|
|
if(window == 0) {
|
|
|
|
fprintf(stderr, "failed to initialize glfw window\n");
|
|
|
|
fprintf(stderr, "failed to initialize glfw window\n");
|
|
|
|