Add basic loader for gltf
Added loading of avocado. Something is still wrong though, becaus I cannot see the seed. But basic functionality is there.
This commit is contained in:
@@ -10,13 +10,16 @@
|
||||
*/
|
||||
#include <SDL3/SDL_log.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "src/graphics_context.h"
|
||||
#include "src/vulkan_commons.h"
|
||||
#include "utilities/cgltf.h"
|
||||
#include "utilities/commons.h"
|
||||
#include "utilities/entity.h"
|
||||
#include "utilities/errors_common.h"
|
||||
#include "utilities/file_utils.h"
|
||||
#include "vulkan_buffers.h"
|
||||
|
||||
rse_err_t mesh_create(struct graphics_context_t* context,
|
||||
@@ -46,6 +49,132 @@ rse_err_t mesh_create(struct graphics_context_t* context,
|
||||
return status;
|
||||
}
|
||||
|
||||
rse_err_t mesh_create_from_file(struct graphics_context_t* context, const char* file_name, rse_id_t* mesh_id)
|
||||
{
|
||||
struct vertex_t* vertices = NULL;
|
||||
uint16_t* indices = NULL;
|
||||
size_t indices_count = 0U;
|
||||
size_t mesh_index = 0U;
|
||||
size_t primitive_index = 0U;
|
||||
size_t attribute_index = 0U;
|
||||
cgltf_mesh* mesh = NULL;
|
||||
cgltf_primitive* primitive = NULL;
|
||||
cgltf_attribute* attribute = NULL;
|
||||
size_t* position_data_offset = NULL;
|
||||
size_t* color_data_offset = NULL;
|
||||
size_t* texture_coord_data_offset = NULL;
|
||||
size_t* indices_data_offset = 0U;
|
||||
size_t data_count = 0U;
|
||||
size_t data_index = 0U;
|
||||
size_t tmp_offset = 0U;
|
||||
uint8_t* bin = NULL;
|
||||
|
||||
(void)context;
|
||||
(void)mesh_id;
|
||||
|
||||
cgltf_data* data = NULL;
|
||||
rse_err_t status = RSE_ERROR_NO_ERROR;
|
||||
|
||||
STATUS_CHECK(file_load_gltf(file_name, &data));
|
||||
|
||||
SDL_LogInfo(SDL_LOG_CATEGORY_GPU, "Attribute name: %s", data->meshes->primitives[0].attributes[3].name);
|
||||
SDL_LogInfo(SDL_LOG_CATEGORY_GPU, "Accessor: %ld", data->meshes->primitives[0].attributes[3].data->count);
|
||||
|
||||
for (mesh_index = 0U; mesh_index < data->meshes_count; ++mesh_index) {
|
||||
mesh = &data->meshes[mesh_index];
|
||||
|
||||
for (primitive_index = 0U; primitive_index < mesh->primitives_count; ++primitive_index) {
|
||||
primitive = &mesh->primitives[primitive_index];
|
||||
|
||||
for (attribute_index = 0; attribute_index < primitive->attributes_count; ++attribute_index) {
|
||||
attribute = &primitive->attributes[attribute_index];
|
||||
|
||||
if (primitive->indices == NULL) {
|
||||
SDL_LogCritical(SDL_LOG_CATEGORY_GPU,
|
||||
"No indices for mesh found. Currently only indexed drawing is supported");
|
||||
return RSE_ERROR_INVALID_PARAM;
|
||||
} else {
|
||||
rse_malloc(indices_data_offset, sizeof(size_t));
|
||||
*indices_data_offset = primitive->indices->buffer_view->offset;
|
||||
indices_count = primitive->indices->count;
|
||||
rse_malloc(indices, (sizeof(uint16_t) * indices_count));
|
||||
}
|
||||
|
||||
tmp_offset = attribute->data->buffer_view->offset;
|
||||
|
||||
switch (attribute->type) {
|
||||
case cgltf_attribute_type_position:
|
||||
rse_malloc(position_data_offset, sizeof(size_t));
|
||||
*position_data_offset = tmp_offset;
|
||||
data_count = attribute->data->count;
|
||||
break;
|
||||
case cgltf_attribute_type_color:
|
||||
rse_malloc(color_data_offset, sizeof(size_t));
|
||||
*color_data_offset = tmp_offset;
|
||||
break;
|
||||
case cgltf_attribute_type_texcoord:
|
||||
rse_malloc(texture_coord_data_offset, sizeof(size_t));
|
||||
*texture_coord_data_offset = tmp_offset;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (position_data_offset == NULL) {
|
||||
SDL_LogCritical(SDL_LOG_CATEGORY_GPU, "Failed to retrieve position data for mesh %s", file_name);
|
||||
status = RSE_ERROR_INVALID_PARAM;
|
||||
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (data_count == 0) {
|
||||
SDL_LogCritical(SDL_LOG_CATEGORY_GPU, "Failure: data count for mesh is 0");
|
||||
status = RSE_ERROR_INVALID_PARAM;
|
||||
|
||||
goto exit;
|
||||
}
|
||||
|
||||
rse_malloc(vertices, sizeof(struct vertex_t) * data_count);
|
||||
bin = (uint8_t*)data->bin;
|
||||
|
||||
for (data_index = 0U; data_index < data_count; ++data_index) {
|
||||
rse_memcpy(vertices[data_index].pos,
|
||||
(bin + *position_data_offset + (sizeof(vec3) * data_index)),
|
||||
sizeof(vec3));
|
||||
if (color_data_offset != NULL) {
|
||||
rse_memcpy(vertices[data_index].color,
|
||||
(bin + *color_data_offset + (sizeof(vec3) * data_index)),
|
||||
sizeof(vec3));
|
||||
} else {
|
||||
vertices[data_index].color[0] = 1.0;
|
||||
vertices[data_index].color[1] = 1.0;
|
||||
vertices[data_index].color[2] = 1.0;
|
||||
}
|
||||
|
||||
if (texture_coord_data_offset != NULL) {
|
||||
rse_memcpy(vertices[data_index].tex_coords,
|
||||
(bin + *texture_coord_data_offset + (sizeof(vec2) * data_index)),
|
||||
sizeof(vec2));
|
||||
}
|
||||
}
|
||||
|
||||
rse_memcpy(indices, (bin + *indices_data_offset), (sizeof(uint16_t) * indices_count));
|
||||
|
||||
STATUS_CHECK(mesh_create(context, vertices, indices, data_count, indices_count, mesh_id));
|
||||
}
|
||||
|
||||
exit:
|
||||
rse_free(position_data_offset);
|
||||
rse_free(color_data_offset);
|
||||
rse_free(texture_coord_data_offset);
|
||||
rse_free(vertices);
|
||||
cgltf_free(data);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
rse_err_t mesh_create_instance(struct graphics_context_t* context,
|
||||
entity_t entity,
|
||||
struct instance_data_t instance_data)
|
||||
|
||||
Reference in New Issue
Block a user