summaryrefslogtreecommitdiffstats
path: root/src/render.c
diff options
context:
space:
mode:
authorgramanas <anastasis.gramm2@gmail.com>2024-05-31 22:44:35 +0300
committergramanas <anastasis.gramm2@gmail.com>2024-05-31 22:44:35 +0300
commit9acc6b19c6efefb75ee5bc409df3e9346bd07d73 (patch)
tree113831fe97b39a0d2fa2d2cd8c825a8d2e13c657 /src/render.c
parenta5a82709028c475d0ff6cd54f6d07f16375e156e (diff)
downloadcgame-9acc6b19c6efefb75ee5bc409df3e9346bd07d73.tar.gz
cgame-9acc6b19c6efefb75ee5bc409df3e9346bd07d73.tar.bz2
cgame-9acc6b19c6efefb75ee5bc409df3e9346bd07d73.zip
Load glTF
Diffstat (limited to 'src/render.c')
-rw-r--r--src/render.c260
1 files changed, 98 insertions, 162 deletions
diff --git a/src/render.c b/src/render.c
index db3c168..275752c 100644
--- a/src/render.c
+++ b/src/render.c
@@ -39,7 +39,7 @@
#define TEXTURE_PATH "assets/viking_room.png"
void load_model_obj();
-
+void load_model_gltf();
// embedded clgm library
uint32_t currentFrame = 0;
state_t s;
@@ -962,7 +962,7 @@ vulkan_create_graphics_pipeline(VkPolygonMode polygon_mode)
attributeDescriptions[1].binding = 0;
attributeDescriptions[1].location = 1;
attributeDescriptions[1].format = VK_FORMAT_R32G32B32_SFLOAT;
- attributeDescriptions[1].offset = offsetof(Vertex, color);
+ attributeDescriptions[1].offset = offsetof(Vertex, normal);
attributeDescriptions[2].binding = 0;
attributeDescriptions[2].location = 2;
@@ -1494,6 +1494,8 @@ int polygon_mode_n = 3;
VkPolygonMode polygon_modes[3] = {VK_POLYGON_MODE_FILL, VK_POLYGON_MODE_LINE,
VK_POLYGON_MODE_POINT};
+int toggle = 0;
+
void
handle_input(bool * quit)
{
@@ -1548,13 +1550,21 @@ handle_input(bool * quit)
vkDeviceWaitIdle(s.vk_device);
free(s.vertices);
free(s.indices);
- if (!strcmp(s.model_path, "assets/human.obj"))
- strcpy(s.model_path, "assets/viking_room.obj");
- else if (!strcmp(s.model_path, "assets/viking_room.obj"))
- strcpy(s.model_path, "assets/test.obj");
- else
- strcpy(s.model_path, "assets/human.obj");
- load_model_obj();
+ /* if (!strcmp(s.model_path, "assets/human.obj")) */
+ /* strcpy(s.model_path, "assets/viking_room.obj"); */
+ /* else if (!strcmp(s.model_path, "assets/viking_room.obj")) */
+ /* strcpy(s.model_path, "assets/monkey.obj"); */
+ /* else */
+ /* strcpy(s.model_path, "assets/human.obj"); */
+
+ if (toggle) {
+ strcpy(s.model_path, "assets/monkey.obj");
+ load_model_obj();
+ toggle = 0;
+ } else {
+ toggle = 1;
+ load_model_gltf();
+ }
vkDestroyBuffer(s.vk_device, s.vk_vertex_buffer, NULL);
vkFreeMemory(s.vk_device, s.vk_vertex_buffer_memory, NULL);
@@ -1825,6 +1835,7 @@ load_model_obj()
indexed draw call.
*/
+ s.vertices = (Vertex *)malloc(s.indices_count * sizeof(Vertex));
/* Count indexs and vertices */
size_t c = 0;
for (size_t ii = 0; ii < m->group_count; ii++) {
@@ -1833,6 +1844,7 @@ load_model_obj()
unsigned int fv = m->face_vertices[grp->face_offset + jj];
for (unsigned int kk = 0; kk < fv; kk++) {
/* position index */
+ fastObjIndex mi = m->indices[grp->index_offset + c];
uint32_t mip = m->indices[grp->index_offset + c].p - 1; /* make index start from zero */
/* flag if we've seen the index*/
@@ -1844,51 +1856,8 @@ load_model_obj()
}
}
s.indices[c] = mip;
+
if (!index_seen) {
- /* If not seen, incremet vertices */
- s.vertices_count++;
- }
- c++;
- }
- }
- }
-
- printf("vertex count %ld!!!!!!!!!!!!!!!!!!\n", s.vertices_count);
- s.vertices = (Vertex *)malloc(s.vertices_count * sizeof(Vertex));
-
- /* for (size_t i = 0; i < s.indices_count; i++) { */
- /* uint32_t mip = s.indices[i]; */
- /* int index_seen = 0; */
- /* for (size_t j = 0; j < i; j++) { */
- /* if (mip == s.indices[j]) { */
- /* index_seen = 1; */
- /* break; */
- /* } */
- /* } */
- /* if (!index_seen) { */
- /* s.vertices[mip].pos.x = m->positions[3 * (mip + 1) + 0]; */
- /* s.vertices[mip].pos.y = m->positions[3 * (mip + 1) + 1]; */
- /* s.vertices[mip].pos.z = m->positions[3 * (mip + 1) + 2]; */
- /* } */
- /* } */
-
- for (size_t ii = 0; ii < m->group_count; ii++) {
- const fastObjGroup *grp = &m->groups[ii];
- size_t idx = 0;
- for (unsigned int jj = 0; jj < grp->face_count; jj++) {
- unsigned int fv = m->face_vertices[grp->face_offset + jj];
- for (unsigned int kk = 0; kk < fv; kk++) {
- fastObjIndex mi = m->indices[grp->index_offset + idx];
-
- int flag = 0;
- for (size_t i = 0; i < idx; i++) {
- /* if it exists */
- if (mi.p - 1 == s.indices[i]) {
- flag = 1;
- break;
- }
- }
- if (!flag) {
int index = mi.p - 1; /* zero indexed */
if (mi.p) {
s.vertices[index].pos.x = m->positions[3 * mi.p + 0];
@@ -1900,130 +1869,97 @@ load_model_obj()
s.vertices[index].texCoord.y = 1.0f - m->texcoords[2 * mi.t + 1];
}
if (mi.n) {
- s.vertices[index].color.x = m->normals[3 * mi.n + 0];
- s.vertices[index].color.y = m->normals[3 * mi.n + 1];
- s.vertices[index].color.z = m->normals[3 * mi.n + 2];
+ s.vertices[index].normal.x = m->normals[3 * mi.n + 0];
+ s.vertices[index].normal.y = m->normals[3 * mi.n + 1];
+ s.vertices[index].normal.z = m->normals[3 * mi.n + 2];
}
+
+ /* If not seen, incremet vertices */
+ s.vertices_count++;
}
- idx++;
+ c++;
}
}
}
-
+
+ vk_log(VK_INFO, "[obj] %s: Loaded %ld vertices %ld indices\n", s.model_path, s.vertices_count, s.indices_count);
+
+
fast_obj_destroy(m);
}
void load_model_gltf() {
// TODO maybe copy the raylib implemenetation
- /*
- RESTRICTIONS:
- - Only triangle meshes supported
- - Vertex attribute types and formats supported:
- > Vertices (position): vec3: float
- > Normals: vec3: float
- > Texcoords: vec2: float
- > Colors: vec4: u8, u16, f32 (normalized)
- > Indices: u16, u32 (truncated to u16)
- - Node hierarchies or transforms not supported
- */
- /* cgltf_options options; */
- /* memset(&options, 0, sizeof(cgltf_options)); */
- /* cgltf_data* data = NULL; */
- /* cgltf_result result = cgltf_parse_file(&options, MODEL_PATH, &data); */
+ char * path = "assets/monkey.glb";
+ cgltf_options options;
+ memset(&options, 0, sizeof(cgltf_options));
+ cgltf_data* data = NULL;
+ cgltf_result result = cgltf_parse_file(&options, path, &data);
- /* if (result == cgltf_result_success) */
- /* result = cgltf_load_buffers(&options, data, MODEL_PATH); */
+ if (result == cgltf_result_success)
+ result = cgltf_load_buffers(&options, data, path);
+ else {
+ vk_log(VK_ERROR, "Can't load %s\n", path);
+ }
- /* if (result == cgltf_result_success) */
- /* result = cgltf_validate(data); */
+ if (result == cgltf_result_success)
+ result = cgltf_validate(data);
- /* if (data->meshes_count < 1) { */
- /* cgltf_free(data); */
- /* return; */
- /* } */
+ if (data->meshes_count < 1) {
+ cgltf_free(data);
+ return;
+ }
- /* int idx = 0; */
- /* int meshIndex = 0; */
- /* for (unsigned int i = 0, meshIndex = 0; i < data->meshes_count; i++) { */
- /* for (unsigned int p = 0; p < data->meshes[i].primitives_count; p++) { */
- /* // NOTE: We only support primitives defined by triangles */
- /* // Other alternatives: points, lines, line_strip, triangle_strip */
- /* if (data->meshes[i].primitives[p].type != cgltf_primitive_type_triangles) continue; */
-
- /* // NOTE: Attributes data could be provided in several data formats (8, 8u, 16u, 32...), */
- /* // Only some formats for each attribute type are supported, read info at the top of this function! */
-
- /* for (unsigned int j = 0; j < data->meshes[i].primitives[p].attributes_count; j++) { */
- /* // Check the different attributes for every primitive */
- /* if (data->meshes[i].primitives[p].attributes[j].type == cgltf_attribute_type_position) { // POSITION, vec3, float */
- /* cgltf_accessor *attribute = data->meshes[i].primitives[p].attributes[j].data; */
-
- /* // WARNING: SPECS: POSITION accessor MUST have its min and max properties defined */
-
- /* if ((attribute->type == cgltf_type_vec3) && (attribute->component_type == cgltf_component_type_r_32f)) { */
- /* // Init raylib mesh vertices to copy glTF attribute data */
- /* s.vertices_count = attribute->count / 3; */
- /* s.vertices = calloc(attribute->count, attribute->count*sizeof(Vertex)); */
-
- /* size_t float_count = cgltf_accessor_unpack_floats(attribute, NULL, 0); */
- /* printf("This many floats: %ld\n", float_count); */
- /* float floats[float_count] = {}; */
- /* cgltf_accessor_unpack_floats(attribute, floats, float_count); */
-
- /* for (unsigned int k = 0; k < attribute->count + 3; k+=3) { */
- /* s.vertices[idx].pos.x = floats[k + 0]; */
- /* s.vertices[idx].pos.y = floats[k + 1]; */
- /* s.vertices[idx].pos.z = floats[k + 2]; */
- /* //s.indices[idx] = idx; */
- /* idx++; */
- /* } */
- /* // Load 3 components of float data type into mesh.vertices */
- /* } */
- /* } */
- /* } */
- /* if (data->meshes[i].primitives[p].indices != NULL) { */
- /* printf("THERE ARE INDIXCES!!!\n"); */
- /* cgltf_accessor *attribute = data->meshes[i].primitives[p].indices; */
-
- /* s.indices_count = attribute->count / 3; */
- /* s.indices = calloc(attribute->count, attribute->count*sizeof(uint32_t)); */
-
- /* if (attribute->component_type == cgltf_component_type_r_16u) { */
- /* size_t float_count = cgltf_accessor_unpack_indices(attribute, NULL, 0, 0); */
- /* printf("This many floats: %ld\n", float_count); */
- /* uint16_t floats[float_count] = {}; */
- /* cgltf_accessor_unpack_indices(attribute, floats, float_count, */
- /* float_count); */
-
- /* for (int x = 0; x < float_count; x++) { */
- /* printf("%d \n", floats[x]); */
- /* } */
-
- /* } */
- /* else if (attribute->component_type == cgltf_component_type_r_32u) { */
- /* printf("ASDASDASDAS2222222!\n"); */
- /* // Init raylib mesh indices to copy glTF attribute data */
- /* /\* model.meshes[meshIndex].indices = RL_MALLOC(attribute->count*sizeof(unsigned short)); *\/ */
-
- /* /\* // Load data into a temp buffer to be converted to raylib data type *\/ */
- /* /\* unsigned int *temp = malloc(attribute->count*sizeof(unsigned int)); *\/ */
- /* /\* LOAD_ATTRIBUTE(attribute, 1, unsigned int, temp); *\/ */
-
- /* /\* // Convert data to raylib indices data type (unsigned short) *\/ */
- /* /\* for (unsigned int d = 0; d < attribute->count; d++) model.meshes[meshIndex].indices[d] = (unsigned short)temp[d]; *\/ */
-
- /* //free(temp); */
- /* } */
- /* } */
- /* } */
- /* } */
+ for (cgltf_size i = 0; i < data->meshes_count; ++i) {
+ cgltf_mesh *mesh = &data->meshes[i];
+ for (cgltf_size j = 0; j < mesh->primitives_count; ++j) {
+ cgltf_primitive* primitive = &mesh->primitives[j];
- /* for (int i = 0; i < s.vertices_count; i++) { */
- /* printf("%d: %f %f %f\n",i, s.vertices[i].pos.x, s.vertices[i].pos.y, s.vertices[i].pos.z); */
- /* } */
+ cgltf_accessor* index_accessor = primitive->indices;
+
+ if (index_accessor) {
+ s.indices_count = index_accessor->count;
+ s.indices = (uint32_t *)malloc(s.indices_count * sizeof(uint32_t));
+ // Read indices
+ for (cgltf_size k = 0; k < index_accessor->count; ++k) {
+ s.indices[k] = cgltf_accessor_read_index(index_accessor, k);
+ }
+ }
+
+ // Find the position attribute accessor
+ for (cgltf_size k = 0; k < primitive->attributes_count; ++k) {
+ if (primitive->attributes[k].type == cgltf_attribute_type_position) {
+ cgltf_accessor* position_accessor = primitive->attributes[k].data;
+ s.vertices_count = position_accessor->count;
+ s.vertices = (Vertex *)malloc(s.vertices_count * sizeof(Vertex));
+ // Read vertex positions
+ for (cgltf_size k = 0; k < position_accessor->count; ++k) {
+ float vertex[3];
+ cgltf_accessor_read_float(position_accessor, k, (cgltf_float *)(&s.vertices[k].pos), 3);
+ }
+ }
+ if (primitive->attributes[k].type == cgltf_attribute_type_texcoord) {
+ cgltf_accessor* texcoord_accessor = primitive->attributes[k].data;
+ // Read texture coordinates
+ for (cgltf_size k = 0; k < texcoord_accessor->count; ++k) {
+ cgltf_accessor_read_float(texcoord_accessor, k, (cgltf_float *)(&s.vertices[k].texCoord), 2);
+ }
+ }
+ if (primitive->attributes[k].type == cgltf_attribute_type_normal) {
+ cgltf_accessor* color_accessor = primitive->attributes[k].data;
+ // Read texture coordinates
+ for (cgltf_size k = 0; k < color_accessor->count; ++k) {
+ cgltf_accessor_read_float(color_accessor, k, (cgltf_float *)(&s.vertices[k].normal), 3);
+ }
+ }
+ }
+ }
+ }
+
+ vk_log(VK_INFO, "[glTF] %s: Loaded %ld vertices %ld indices\n", path, s.vertices_count, s.indices_count);
- /* cgltf_free(data); */
+ cgltf_free(data);
}
void
@@ -2050,8 +1986,8 @@ init_vulkan()
vulkan_create_texture_image();
vulkan_create_texture_image_view();
vulkan_create_texture_sampler();
- load_model_obj();
- //load_model_gltf();
+ //load_model_obj();
+ load_model_gltf();
vulkan_create_vertex_buffer();
vulkan_create_index_buffer();
vulkan_create_uniform_buffers();