From 324375d6a4199cd16e5aa7d75efba5074bc9eebc Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 30 Jul 2024 14:36:26 +0200 Subject: [PATCH] Added LoadTextureFromMemory() for DX11 and DX12 examples. --- Image-Loading-and-Displaying-Examples.md | 53 ++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/Image-Loading-and-Displaying-Examples.md b/Image-Loading-and-Displaying-Examples.md index d45187f..77c0306 100644 --- a/Image-Loading-and-Displaying-Examples.md +++ b/Image-Loading-and-Displaying-Examples.md @@ -234,16 +234,17 @@ ImGui::End(); Add at the top of one of your source file: ```cpp +#define _CRT_SECURE_NO_WARNINGS #define STB_IMAGE_IMPLEMENTATION #include "stb_image.h" // Simple helper function to load an image into a DX11 texture with common settings -bool LoadTextureFromFile(const char* filename, ID3D11ShaderResourceView** out_srv, int* out_width, int* out_height) +bool LoadTextureFromMemory(const void* data, size_t data_size, ID3D11ShaderResourceView** out_srv, int* out_width, int* out_height) { // Load from disk into a raw RGBA buffer int image_width = 0; int image_height = 0; - unsigned char* image_data = stbi_load(filename, &image_width, &image_height, NULL, 4); + unsigned char* image_data = stbi_load_from_memory((const unsigned char*)data, (int)data_size, &image_width, &image_height, NULL, 4); if (image_data == NULL) return false; @@ -283,6 +284,24 @@ bool LoadTextureFromFile(const char* filename, ID3D11ShaderResourceView** out_sr return true; } + +// Open and read a file, then forward to LoadTextureFromMemory() +bool LoadTextureFromFile(const char* file_name, ID3D11ShaderResourceView** out_srv, int* out_width, int* out_height) +{ + FILE* f = fopen(file_name, "rb"); + if (f == NULL) + return false; + fseek(f, 0, SEEK_END); + size_t file_size = (size_t)ftell(f); + if (file_size == -1) + return false; + fseek(f, 0, SEEK_SET); + void* file_data = IM_ALLOC(file_size); + fread(file_data, 1, file_size, f); + bool ret = LoadTextureFromMemory(file_data, file_size, out_srv, out_width, out_height); + IM_FREE(file_data); + return ret; +} ``` At initialization time, load our texture: @@ -328,17 +347,18 @@ If you want to use this code to load more than one texture (and don't have your The actual implementation itself is as follows - firstly, at the top of one of your source files add: ```cpp +#define _CRT_SECURE_NO_WARNINGS #define STB_IMAGE_IMPLEMENTATION #include "stb_image.h" // Simple helper function to load an image into a DX12 texture with common settings // Returns true on success, with the SRV CPU handle having an SRV for the newly-created texture placed in it (srv_cpu_handle must be a handle in a valid descriptor heap) -bool LoadTextureFromFile(const char* filename, ID3D12Device* d3d_device, D3D12_CPU_DESCRIPTOR_HANDLE srv_cpu_handle, ID3D12Resource** out_tex_resource, int* out_width, int* out_height) +bool LoadTextureFromMemory(const void* data, size_t data_size, ID3D12Device* d3d_device, D3D12_CPU_DESCRIPTOR_HANDLE srv_cpu_handle, ID3D12Resource** out_tex_resource, int* out_width, int* out_height) { // Load from disk into a raw RGBA buffer int image_width = 0; int image_height = 0; - unsigned char* image_data = stbi_load(filename, &image_width, &image_height, NULL, 4); + unsigned char* image_data = stbi_load_from_memory((const unsigned char*)data, (int)data_size, &image_width, &image_height, NULL, 4); if (image_data == NULL) return false; @@ -489,6 +509,30 @@ bool LoadTextureFromFile(const char* filename, ID3D12Device* d3d_device, D3D12_C return true; } + +// Open and read a file, then forward to LoadTextureFromMemory() +bool LoadTextureFromFile(const char* file_name, ID3D12Device* d3d_device, D3D12_CPU_DESCRIPTOR_HANDLE srv_cpu_handle, ID3D12Resource** out_tex_resource, int* out_width, int* out_height) +{ + FILE* f = fopen(file_name, "rb"); + if (f == NULL) + return false; + fseek(f, 0, SEEK_END); + size_t file_size = (size_t)ftell(f); + if (file_size == -1) + return false; + fseek(f, 0, SEEK_SET); + void* file_data = IM_ALLOC(file_size); + fread(file_data, 1, file_size, f); + bool ret = LoadTextureFromMemory(file_data, file_size, d3d_device, srv_cpu_handle, out_tex_resource, out_width, out_height); + IM_FREE(file_data); + return ret; +} + +void DestroyTexture(ID3D12Resource** tex_resources) +{ + (*tex_resources)->Release(); + *tex_resources = NULL; +} ``` Then at initialization time, load our texture: @@ -882,6 +926,7 @@ RemoveTexture(&my_texture); If instead of loading from a file you would like to load from memory, you can call `stbi_load_from_memory()` instead of `stbi_load()`. All `LoadTextureFromFile()` function could be reworked to call `LoadTextureFromMemory()` which contains most of the code. +See our implementation of `LoadTextureFromFile()` for DX11 and DX12 examples. ##### [Return to Index](#index)