Load texture from glb
Add loading image from glb file.
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 3.0 MiB |
@@ -21,6 +21,7 @@
|
|||||||
#include "utilities/errors_common.h"
|
#include "utilities/errors_common.h"
|
||||||
#include "utilities/file_utils.h"
|
#include "utilities/file_utils.h"
|
||||||
#include "vulkan_buffers.h"
|
#include "vulkan_buffers.h"
|
||||||
|
#include "vulkan_image.h"
|
||||||
|
|
||||||
rse_err_t mesh_create(struct graphics_context_t* context,
|
rse_err_t mesh_create(struct graphics_context_t* context,
|
||||||
struct vertex_t* vertices,
|
struct vertex_t* vertices,
|
||||||
@@ -49,7 +50,7 @@ rse_err_t mesh_create(struct graphics_context_t* context,
|
|||||||
return status;
|
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;
|
struct vertex_t* vertices = NULL;
|
||||||
uint16_t* indices = 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* position_data_offset = NULL;
|
||||||
size_t* color_data_offset = NULL;
|
size_t* color_data_offset = NULL;
|
||||||
size_t* texture_coord_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_count = 0U;
|
||||||
size_t data_index = 0U;
|
size_t data_index = 0U;
|
||||||
size_t tmp_offset = 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));
|
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) {
|
for (attribute_index = 0; attribute_index < primitive->attributes_count; ++attribute_index) {
|
||||||
attribute = &primitive->attributes[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));
|
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));
|
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(color_data_offset);
|
||||||
rse_free(texture_coord_data_offset);
|
rse_free(texture_coord_data_offset);
|
||||||
rse_free(indices_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(vertices);
|
||||||
rse_free(indices);
|
rse_free(indices);
|
||||||
cgltf_free(data);
|
cgltf_free(data);
|
||||||
|
|||||||
@@ -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,
|
rse_err_t mesh_create_instance(struct graphics_context_t* context, entity_t entity,
|
||||||
struct instance_data_t instance_data);
|
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
|
* @brief Get the vertex count for mesh with mesh_id ID
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ rse_err_t shader_create_module(struct graphics_context_t* context,
|
|||||||
const char* shader_path,
|
const char* shader_path,
|
||||||
const VkShaderStageFlagBits shader_stage)
|
const VkShaderStageFlagBits shader_stage)
|
||||||
{
|
{
|
||||||
char* buffer;
|
unsigned char* buffer;
|
||||||
size_t buffer_size;
|
size_t buffer_size;
|
||||||
VkShaderModuleCreateInfo create_info = {0};
|
VkShaderModuleCreateInfo create_info = {0};
|
||||||
|
|
||||||
|
|||||||
@@ -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.jpg", &textures[0]));
|
||||||
STATUS_CHECK(texture_load_from_file(context, "../../test_image_2.jpg", &textures[1]));
|
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_init());
|
||||||
// STATUS_CHECK(fonts_load_from_file(context, "../../NotoSansMono-Regular.ttf", &font_id));
|
// 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);
|
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 !=
|
if (RSE_ERROR_NO_ERROR !=
|
||||||
mesh_create_instance(
|
mesh_create_instance(
|
||||||
context,
|
context,
|
||||||
|
|||||||
@@ -16,6 +16,9 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
|
#include "stb/stb_image.h"
|
||||||
|
|
||||||
#define IMAGE_TAKEN 1U
|
#define IMAGE_TAKEN 1U
|
||||||
#define IMAGE_FREE 0U
|
#define IMAGE_FREE 0U
|
||||||
|
|
||||||
@@ -515,20 +518,19 @@ rse_err_t load_texture_from_bitmat(struct graphics_context_t* context,
|
|||||||
return status;
|
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 width = 0;
|
||||||
int height = 0;
|
int height = 0;
|
||||||
size_t buffer_size = 0U;
|
int channels = 0;
|
||||||
unsigned char* pixel_buffer = NULL;
|
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));
|
pixel_buffer = stbi_load_from_memory(data_buffer, (int)buffer_size, &width, &height, &channels, STBI_rgb_alpha);
|
||||||
rse_malloc(pixel_buffer, buffer_size);
|
if (pixel_buffer == NULL) {
|
||||||
if (file_load_pixels(file_path, pixel_buffer, &buffer_size, &width, &height) != RSE_ERROR_NO_ERROR) {
|
SDL_LogCritical(SDL_LOG_CATEGORY_GPU, "Failed to load image");
|
||||||
status = RSE_ERROR_INTERNAL_ERROR;
|
|
||||||
|
|
||||||
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) {
|
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:
|
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;
|
return status;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
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);
|
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
|
* @brief Loads image from file, for later to be used as a texture
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -15,12 +15,10 @@
|
|||||||
* @param bytes_count Returned bytes count
|
* @param bytes_count Returned bytes count
|
||||||
* @param buffer Returned filled buffer
|
* @param buffer Returned filled buffer
|
||||||
*/
|
*/
|
||||||
rse_err_t file_read_bytes(const char* file_path, size_t* bytes_count, char* buffer);
|
rse_err_t file_read_bytes(const char* file_path, size_t* bytes_count, unsigned char* buffer);
|
||||||
|
|
||||||
rse_err_t file_write(const char* file_name, size_t bytes_count, char* buffer);
|
rse_err_t file_write(const char* file_name, size_t bytes_count, char* buffer);
|
||||||
|
|
||||||
rse_err_t file_load_pixels(const char* file_name, unsigned char* buffer, size_t* buffer_size, int* width, int* height);
|
|
||||||
|
|
||||||
rse_err_t file_append_full_path(char* file_path, size_t max_buffer_size);
|
rse_err_t file_append_full_path(char* file_path, size_t max_buffer_size);
|
||||||
|
|
||||||
rse_err_t file_load_gltf(const char* file_name, cgltf_data** data);
|
rse_err_t file_load_gltf(const char* file_name, cgltf_data** data);
|
||||||
|
|||||||
@@ -14,9 +14,6 @@
|
|||||||
#include "commons.h"
|
#include "commons.h"
|
||||||
#include "errors_common.h"
|
#include "errors_common.h"
|
||||||
|
|
||||||
#define STB_IMAGE_IMPLEMENTATION
|
|
||||||
#include "stb/stb_image.h"
|
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -119,70 +116,7 @@ rse_err_t file_append_full_path(char* file_path, size_t max_buffer_size)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
rse_err_t file_load_pixels(const char* file_name, unsigned char* buffer, size_t* buffer_size, int* width, int* height)
|
rse_err_t file_read_bytes(const char* file_name, size_t* bytes_count, unsigned char* buffer)
|
||||||
{
|
|
||||||
int channels = 0;
|
|
||||||
stbi_uc* pixel_buffer = NULL;
|
|
||||||
size_t image_buffer_size = 0U;
|
|
||||||
rse_err_t ret = RSE_ERROR_NO_ERROR;
|
|
||||||
char real_path[MAX_PATH_LENGTH] = {0};
|
|
||||||
|
|
||||||
if (buffer_size == NULL) {
|
|
||||||
SDL_LogCritical(SDL_LOG_CATEGORY_APPLICATION, "Provided NULL buffer_size");
|
|
||||||
|
|
||||||
return RSE_ERROR_INVALID_PARAM;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (width == NULL) {
|
|
||||||
SDL_LogCritical(SDL_LOG_CATEGORY_APPLICATION, "Provided NULL width");
|
|
||||||
|
|
||||||
return RSE_ERROR_INVALID_PARAM;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (height == NULL) {
|
|
||||||
SDL_LogCritical(SDL_LOG_CATEGORY_APPLICATION, "Provided NULL height");
|
|
||||||
|
|
||||||
return RSE_ERROR_INVALID_PARAM;
|
|
||||||
}
|
|
||||||
|
|
||||||
strncpy(real_path, file_name, MAX_PATH_LENGTH);
|
|
||||||
if ((ret = file_append_full_path(real_path, MAX_PATH_LENGTH)) != RSE_ERROR_NO_ERROR) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
pixel_buffer = stbi_load(real_path, width, height, &channels, STBI_rgb_alpha);
|
|
||||||
|
|
||||||
if (pixel_buffer == NULL) {
|
|
||||||
SDL_LogCritical(SDL_LOG_CATEGORY_GPU, "Failed to load texture from file: %s", file_name);
|
|
||||||
return RSE_ERROR_INTERNAL_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
image_buffer_size = *width * *height * 4; // TODO: "4" is very hardcoded value. Change this
|
|
||||||
|
|
||||||
if ((buffer != NULL) && (image_buffer_size > *buffer_size)) {
|
|
||||||
SDL_LogCritical(SDL_LOG_CATEGORY_APPLICATION,
|
|
||||||
"Provided buffer is to small to hold pixel data. %ld vs %ld",
|
|
||||||
*buffer_size,
|
|
||||||
image_buffer_size);
|
|
||||||
ret = RSE_ERROR_INTERNAL_ERROR;
|
|
||||||
|
|
||||||
goto image_free;
|
|
||||||
}
|
|
||||||
|
|
||||||
*buffer_size = image_buffer_size;
|
|
||||||
|
|
||||||
if (buffer != NULL) {
|
|
||||||
memset(buffer, 0, *buffer_size);
|
|
||||||
memcpy(buffer, pixel_buffer, *buffer_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
image_free:
|
|
||||||
stbi_image_free(pixel_buffer);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
rse_err_t file_read_bytes(const char* file_name, size_t* bytes_count, char* buffer)
|
|
||||||
{
|
{
|
||||||
rse_err_t ret = RSE_ERROR_NO_ERROR;
|
rse_err_t ret = RSE_ERROR_NO_ERROR;
|
||||||
FILE* file = NULL;
|
FILE* file = NULL;
|
||||||
|
|||||||
Reference in New Issue
Block a user