Load texture from glb

Add loading image from glb file.
This commit is contained in:
Piotr Krygier
2026-03-20 14:22:17 +01:00
parent 4c706982f1
commit ceb9e365de
9 changed files with 59 additions and 85 deletions
+24 -2
View File
@@ -21,6 +21,7 @@
#include "utilities/errors_common.h"
#include "utilities/file_utils.h"
#include "vulkan_buffers.h"
#include "vulkan_image.h"
rse_err_t mesh_create(struct graphics_context_t* context,
struct vertex_t* vertices,
@@ -49,7 +50,7 @@ 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)
rse_err_t mesh_create_from_file(struct graphics_context_t* context, const char* file_name, rse_id_t* mesh_id, rse_id_t* texture_id)
{
struct vertex_t* vertices = NULL;
uint16_t* indices = NULL;
@@ -63,7 +64,10 @@ rse_err_t mesh_create_from_file(struct graphics_context_t* context, const char*
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* indices_data_offset = NULL;
size_t* texture_data_offset = NULL;
int* texture_data_size = NULL;
unsigned char *texture_pixel_buffer = NULL;
size_t data_count = 0U;
size_t data_index = 0U;
size_t tmp_offset = 0U;
@@ -94,6 +98,15 @@ rse_err_t mesh_create_from_file(struct graphics_context_t* context, const char*
rse_malloc(indices, (sizeof(uint16_t) * indices_count));
}
if (primitive->material != NULL) {
if (primitive->material->has_pbr_metallic_roughness) {
rse_malloc(texture_data_offset, sizeof(size_t));
rse_malloc(texture_data_size, sizeof(int));
*texture_data_offset = primitive->material->pbr_metallic_roughness.base_color_texture.texture->image->buffer_view->offset;
*texture_data_size = primitive->material->pbr_metallic_roughness.base_color_texture.texture->image->buffer_view->size;
}
}
for (attribute_index = 0; attribute_index < primitive->attributes_count; ++attribute_index) {
attribute = &primitive->attributes[attribute_index];
@@ -157,6 +170,12 @@ rse_err_t mesh_create_from_file(struct graphics_context_t* context, const char*
}
}
if (texture_data_offset != NULL) {
rse_malloc(texture_pixel_buffer, *texture_data_size);
rse_memcpy(texture_pixel_buffer, (bin + *texture_data_offset), *texture_data_size);
STATUS_CHECK(texture_load_from_buffer(context, texture_pixel_buffer, *texture_data_size, texture_id));
}
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));
@@ -167,6 +186,9 @@ exit:
rse_free(color_data_offset);
rse_free(texture_coord_data_offset);
rse_free(indices_data_offset);
rse_free(texture_data_size);
rse_free(texture_data_offset);
rse_free(texture_pixel_buffer);
rse_free(vertices);
rse_free(indices);
cgltf_free(data);
+1 -1
View File
@@ -41,7 +41,7 @@ rse_err_t mesh_create(struct graphics_context_t* context, struct vertex_t* verti
rse_err_t mesh_create_instance(struct graphics_context_t* context, entity_t entity,
struct instance_data_t instance_data);
rse_err_t mesh_create_from_file(struct graphics_context_t* context, const char* file_name, rse_id_t* mesh_id);
rse_err_t mesh_create_from_file(struct graphics_context_t* context, const char* file_name, rse_id_t* mesh_id, rse_id_t* texture_id);
/**
* @brief Get the vertex count for mesh with mesh_id ID
*
+1 -1
View File
@@ -29,7 +29,7 @@ rse_err_t shader_create_module(struct graphics_context_t* context,
const char* shader_path,
const VkShaderStageFlagBits shader_stage)
{
char* buffer;
unsigned char* buffer;
size_t buffer_size;
VkShaderModuleCreateInfo create_info = {0};
+1 -2
View File
@@ -134,7 +134,6 @@ rse_err_t rse_graphics_test_function(struct graphics_context_t* context)
STATUS_CHECK(texture_load_from_file(context, "../../test_image.jpg", &textures[0]));
STATUS_CHECK(texture_load_from_file(context, "../../test_image_2.jpg", &textures[1]));
STATUS_CHECK(texture_load_from_file(context, "../../Avocado_baseColor.png", &textures[2]));
// STATUS_CHECK(fonts_init());
// STATUS_CHECK(fonts_load_from_file(context, "../../NotoSansMono-Regular.ttf", &font_id));
@@ -183,7 +182,7 @@ rse_err_t rse_graphics_test_function(struct graphics_context_t* context)
exit(1);
}
mesh_create_from_file(context, "../../Avocado.glb", &avocado_id);
mesh_create_from_file(context, "../../Avocado.glb", &avocado_id, &textures[2]);
if (RSE_ERROR_NO_ERROR !=
mesh_create_instance(
context,
+29 -9
View File
@@ -16,6 +16,9 @@
#include <stdlib.h>
#include <string.h>
#define STB_IMAGE_IMPLEMENTATION
#include "stb/stb_image.h"
#define IMAGE_TAKEN 1U
#define IMAGE_FREE 0U
@@ -515,20 +518,19 @@ rse_err_t load_texture_from_bitmat(struct graphics_context_t* context,
return status;
}
rse_err_t texture_load_from_file(struct graphics_context_t* context, const char* file_path, rse_id_t* texture_id)
rse_err_t texture_load_from_buffer(struct graphics_context_t* context, const unsigned char* data_buffer, size_t buffer_size, rse_id_t* texture_id)
{
rse_err_t status = RSE_ERROR_NO_ERROR;
int width = 0;
int height = 0;
size_t buffer_size = 0U;
int channels = 0;
unsigned char* pixel_buffer = NULL;
rse_err_t status = RSE_ERROR_NO_ERROR;
STATUS_CHECK(file_load_pixels(file_path, NULL, &buffer_size, &width, &height));
rse_malloc(pixel_buffer, buffer_size);
if (file_load_pixels(file_path, pixel_buffer, &buffer_size, &width, &height) != RSE_ERROR_NO_ERROR) {
status = RSE_ERROR_INTERNAL_ERROR;
pixel_buffer = stbi_load_from_memory(data_buffer, (int)buffer_size, &width, &height, &channels, STBI_rgb_alpha);
if (pixel_buffer == NULL) {
SDL_LogCritical(SDL_LOG_CATEGORY_GPU, "Failed to load image");
goto mem_free;
return RSE_ERROR_INTERNAL_ERROR;
}
if (load_texture_from_bitmat(context, pixel_buffer, width, height, texture_id, VK_FORMAT_R8G8B8A8_SRGB) != RSE_ERROR_NO_ERROR) {
@@ -538,8 +540,26 @@ rse_err_t texture_load_from_file(struct graphics_context_t* context, const char*
}
mem_free:
stbi_image_free(pixel_buffer);
rse_free(pixel_buffer);
return status;
}
rse_err_t texture_load_from_file(struct graphics_context_t* context, const char* file_path, rse_id_t* texture_id)
{
size_t buffer_size = 0U;
unsigned char* data_buffer = NULL;
rse_err_t status = RSE_ERROR_NO_ERROR;
STATUS_CHECK(file_read_bytes(file_path, &buffer_size, NULL));
rse_malloc(data_buffer, buffer_size);
STATUS_CHECK(file_read_bytes(file_path, &buffer_size, data_buffer));
if (texture_load_from_buffer(context, data_buffer, buffer_size, texture_id) != RSE_ERROR_NO_ERROR) {
status = RSE_ERROR_INTERNAL_ERROR;
}
rse_free(data_buffer);
return status;
}
+1
View File
@@ -42,6 +42,7 @@ rse_err_t image_get_extent(struct graphics_context_t* context, VkExtent2D* exten
rse_err_t load_texture_from_bitmat(struct graphics_context_t* context, const unsigned char* pixel_buffer, int width,
int height, rse_id_t* texture_id, VkFormat color_format);
rse_err_t texture_load_from_buffer(struct graphics_context_t* context, const unsigned char* data_buffer, size_t buffer_size, rse_id_t* texture_id);
/**
* @brief Loads image from file, for later to be used as a texture
*