From 0fa6423cfaa139c13284309e86d28578d96b61ad Mon Sep 17 00:00:00 2001 From: ravi688 Date: Sun, 24 Nov 2024 03:36:28 +0530 Subject: [PATCH] [SGE] Added texture_load_pixels() variant to create texture object from pixel data directly --- include/sge-cpp/Texture.hpp | 1 + include/sge-cpp/sge.hpp | 1 + include/sge/texture.h | 32 ++++++++++++++++++++++++ source/sge-cpp/Texture.cpp | 5 ++++ source/sge/texture.c | 49 +++++++++++++++++++++++++++++++++++++ 5 files changed, 88 insertions(+) diff --git a/include/sge-cpp/Texture.hpp b/include/sge-cpp/Texture.hpp index 9df815fa..73bd44fc 100644 --- a/include/sge-cpp/Texture.hpp +++ b/include/sge-cpp/Texture.hpp @@ -18,6 +18,7 @@ namespace SGE public: Texture(Driver& driver, texture_type_t type, std::string_view str) noexcept; Texture(Driver& driver, texture_type_t type, const std::span data) noexcept; + Texture(Driver& driver, texture_type_t type, const u8* pixelData, u32 width, u32 height, u32 channels) noexcept; void getAttributes(texture_attributes_t& attributes) noexcept; void destroy() noexcept { diff --git a/include/sge-cpp/sge.hpp b/include/sge-cpp/sge.hpp index b974fae0..ef9f5d17 100644 --- a/include/sge-cpp/sge.hpp +++ b/include/sge-cpp/sge.hpp @@ -89,6 +89,7 @@ namespace SGE Mesh createMesh() noexcept { return Mesh(*this); } Texture loadTexture(texture_type_t type, std::string_view str) noexcept { return Texture(*this, type, str); } Texture loadTexture(texture_type_t type, const std::span data) noexcept { return Texture(*this, type, data); } + Texture loadTexture(texture_type_t type, const u8* pixelData, u32 width, u32 height, u32 channels) noexcept { return Texture(*this, type, pixelData, width, height, channels); } RenderWindow getRenderWindow() const noexcept { return RenderWindow(renderer_get_window(m_handle)); } }; diff --git a/include/sge/texture.h b/include/sge/texture.h index 17a703ee..3bed1a6d 100644 --- a/include/sge/texture.h +++ b/include/sge/texture.h @@ -138,6 +138,38 @@ SGE_API texture_t* texture_load(renderer_t* renderer, texture_type_t type, ...); */ SGE_API texture_t* texture_load_mem(renderer_t* renderer, texture_type_t type, ...); +typedef struct immutable_texture_pixel_data_t +{ + const u8* pixels; + const u32 width; + const u32 height; + const u32 num_channels; +} immutable_texture_pixel_data_t; + +/* + description: + creates a texture of a type 'type' from in-memory buffer(s) of pixel data + params: + renderer: pointer to the renderer object + type: type of the texture, must be a valid texture_type_t + variable arguements: pointers immutable_texture_pixel_data_t object + returns: + pointer to the newly created texture object + */ +SGE_API texture_t* texture_load_pixels(renderer_t* renderer, texture_type_t type, ...); + +/* + description: + creates a texture of a type 'type' from in-memory buffer(s) of pixel data + params: + renderer: pointer to the renderer object + type: type of the texture, must be a valid texture_type_t + va_list: pointers immutable_texture_pixel_data_t object + returns: + pointer to the newly created texture object + */ +SGE_API texture_t* texture_load_pixelsv(renderer_t* renderer, texture_type_t type, va_list pixelDatas); + /* description: creates a texture of a type 'type' diff --git a/source/sge-cpp/Texture.cpp b/source/sge-cpp/Texture.cpp index c68e1bbc..d002d3a2 100644 --- a/source/sge-cpp/Texture.cpp +++ b/source/sge-cpp/Texture.cpp @@ -13,6 +13,11 @@ namespace SGE { m_handle = texture_load_mem(driver.getHandle(), type, com_immutable_data_t { data.data(), static_cast(data.size()) }); } + Texture::Texture(Driver& driver, texture_type_t type, const u8* pixelData, u32 width, u32 height, u32 channels) noexcept + { + immutable_texture_pixel_data_t data = { pixelData, width, height, channels }; + m_handle = texture_load_pixels(driver.getHandle(), type, &data); + } void Texture::getAttributes(texture_attributes_t& attributes) noexcept { const texture_attributes_t* pAttributes = texture_get_attributes(m_handle); diff --git a/source/sge/texture.c b/source/sge/texture.c index c44c0bda..e87bda45 100644 --- a/source/sge/texture.c +++ b/source/sge/texture.c @@ -132,6 +132,55 @@ static texture_t* _texture_create(renderer_t* renderer, texture_type_t type, vul return texture; } +static u32 get_texture_count_from_texture_type(texture_type_t type) +{ + u32 texture_count; + switch(type) + { + case TEXTURE_TYPE_ALBEDO: + case TEXTURE_TYPE_NORMAL: + case TEXTURE_TYPE_CUBE_COMBINED: + texture_count = 1; + break; + case TEXTURE_TYPE_CUBE_SEPARATED: + texture_count = 6; + break; + default: + LOG_FETAL_ERR("Unrecognized texture_type\n"); + }; + return texture_count; +} + +SGE_API texture_t* texture_load_pixels(renderer_t* renderer, texture_type_t type, ...) +{ + va_list datas; + va_start(datas, type); + texture_t* texture = texture_load_pixelsv(renderer, type, datas); + va_end(datas); + return texture; +} + +SGE_API texture_t* texture_load_pixelsv(renderer_t* renderer, texture_type_t type, va_list pixelDatas) +{ + AUTO texture_count = get_texture_count_from_texture_type(type); + // load all the textures from disk to memory + vulkan_texture_data_t data[texture_count]; + for(u32 i = 0; i < texture_count; i++) + { + AUTO pixel_data = va_arg(pixelDatas, const immutable_texture_pixel_data_t*); + data[i].data = CAST_TO(void*, pixel_data->pixels); + data[i].width = pixel_data->width; + data[i].height = pixel_data->height; + data[i].depth = 1; + data[i].channel_count = 4; + com_assert(COM_DESCRIPTION(pixel_data->num_channels == 4), "For now number of channels in a texture must be 4, we will add support for variable number of channels later"); + } + + texture_t* texture = _texture_create(renderer, type, data, texture_count); + + return texture; +} + SGE_API texture_t* texture_loadv(renderer_t* renderer, texture_type_t type, va_list file_paths) { u32 file_path_count;