mirror of
https://github.com/ocornut/imgui.git
synced 2026-03-30 13:05:23 -05:00
Added SDL_GPU3 example.
@@ -8,6 +8,7 @@
|
||||
- [Example for DirectX9 users](#example-for-directx9-users)
|
||||
- [Example for DirectX11 users](#example-for-directx11-users)
|
||||
- [Example for DirectX12 users](#example-for-directx12-users)
|
||||
- [Example for SDL_GPU users](#example-for-sdl_gpu-users)
|
||||
- [Example for SDL_Renderer users](#example-for-sdl_renderer-users)
|
||||
- [Example for Vulkan users](#example-for-vulkan-users)
|
||||
- [Example for WebGPU users](#example-for-webgpu-users)
|
||||
@@ -583,6 +584,130 @@ ImGui::End();
|
||||
|
||||
----
|
||||
|
||||
## Example for SDL_GPU users
|
||||
|
||||
**IMPORTANT** The code below requires 1.92.2 (IMGUI_VERSION_NUM >= 19214) as the type of ImTextureID for SDL_GPU3 backend changed from 'SDL_GPUTextureSamplerBinding*' to 'SDL_GPUTexture*'.
|
||||
|
||||
We will here use [stb_image.h](https://github.com/nothings/stb/blob/master/stb_image.h) to load images from disk.
|
||||
|
||||
Add at the top of one of your source files:
|
||||
```cpp
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include "stb_image.h"
|
||||
|
||||
bool LoadTextureFromMemory(const void* data, size_t data_size, SDL_GPUDevice* device, SDL_GPUTexture** out_texture, 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_from_memory((const unsigned char*)data, (int)data_size, &image_width, &image_height, NULL, 4);
|
||||
if (image_data == NULL)
|
||||
return false;
|
||||
|
||||
// Create texture
|
||||
SDL_GPUTextureCreateInfo texture_info = {};
|
||||
texture_info.type = SDL_GPU_TEXTURETYPE_2D;
|
||||
texture_info.format = SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM;
|
||||
texture_info.usage = SDL_GPU_TEXTUREUSAGE_SAMPLER;
|
||||
texture_info.width = image_width;
|
||||
texture_info.height = image_height;
|
||||
texture_info.layer_count_or_depth = 1;
|
||||
texture_info.num_levels = 1;
|
||||
texture_info.sample_count = SDL_GPU_SAMPLECOUNT_1;
|
||||
|
||||
SDL_GPUTexture* texture = SDL_CreateGPUTexture(device, &texture_info);
|
||||
|
||||
// Create transfer buffer
|
||||
// FIXME: A real engine would likely keep one around, see what the SDL_GPU backend is doing.
|
||||
SDL_GPUTransferBufferCreateInfo transferbuffer_info = {};
|
||||
transferbuffer_info.usage = SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD;
|
||||
transferbuffer_info.size = image_width * image_height * 4;
|
||||
SDL_GPUTransferBuffer* transferbuffer = SDL_CreateGPUTransferBuffer(device, &transferbuffer_info);
|
||||
IM_ASSERT(transferbuffer != NULL);
|
||||
|
||||
// Copy to transfer buffer
|
||||
uint32_t upload_pitch = image_width * 4;
|
||||
void* texture_ptr = SDL_MapGPUTransferBuffer(device, transferbuffer, true);
|
||||
for (int y = 0; y < image_height; y++)
|
||||
memcpy((void*)((uintptr_t)texture_ptr + y * upload_pitch), image_data + y * upload_pitch, upload_pitch);
|
||||
SDL_UnmapGPUTransferBuffer(device, transferbuffer);
|
||||
|
||||
SDL_GPUTextureTransferInfo transfer_info = {};
|
||||
transfer_info.offset = 0;
|
||||
transfer_info.transfer_buffer = transferbuffer;
|
||||
|
||||
SDL_GPUTextureRegion texture_region = {};
|
||||
texture_region.texture = texture;
|
||||
texture_region.x = (Uint32)0;
|
||||
texture_region.y = (Uint32)0;
|
||||
texture_region.w = (Uint32)image_width;
|
||||
texture_region.h = (Uint32)image_height;
|
||||
texture_region.d = 1;
|
||||
|
||||
// Upload
|
||||
SDL_GPUCommandBuffer* cmd = SDL_AcquireGPUCommandBuffer(device);
|
||||
SDL_GPUCopyPass* copy_pass = SDL_BeginGPUCopyPass(cmd);
|
||||
SDL_UploadToGPUTexture(copy_pass, &transfer_info, &texture_region, false);
|
||||
SDL_EndGPUCopyPass(copy_pass);
|
||||
SDL_SubmitGPUCommandBuffer(cmd);
|
||||
|
||||
SDL_ReleaseGPUTransferBuffer(device, transferbuffer);
|
||||
|
||||
*out_texture = texture;
|
||||
*out_width = image_width;
|
||||
*out_height = image_height;
|
||||
stbi_image_free(image_data);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Open and read a file, then forward to LoadTextureFromMemory()
|
||||
bool LoadTextureFromFile(const char* file_name, SDL_GPUDevice* device, SDL_GPUTexture** out_texture, 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);
|
||||
fclose(f);
|
||||
bool ret = LoadTextureFromMemory(file_data, file_size, device, out_texture, out_width, out_height);
|
||||
IM_FREE(file_data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void DestroyTexture(SDL_GPUDevice* device, SDL_GPUTexture* texture)
|
||||
{
|
||||
SDL_ReleaseGPUTexture(device, texture);
|
||||
}
|
||||
```
|
||||
|
||||
Load our texture after initialising SDL3 and SDL_GPU:
|
||||
```cpp
|
||||
SDL_GPUTexture* my_texture;
|
||||
int my_image_width, my_image_height;
|
||||
bool ret = LoadTextureFromFile("MyImage01.jpg", gpu_device, &my_texture, &my_image_width, &my_image_height);
|
||||
IM_ASSERT(ret);
|
||||
```
|
||||
|
||||
Now that we have a SDL_GPUTexture* and its dimensions, we can display it in our main loop:
|
||||
```cpp
|
||||
ImGui::Begin("SDL_GPU Texture Test");
|
||||
ImGui::Text("pointer = %p", &my_texture);
|
||||
ImGui::Text("size = %d x %d", my_image_width, my_image_height);
|
||||
ImGui::Image((ImTextureID)(intptr_t)my_texture, ImVec2((float)my_image_width, (float)my_image_height));
|
||||
ImGui::End();
|
||||
```
|
||||
|
||||
##### [Return to Index](#index)
|
||||
|
||||
----
|
||||
|
||||
## Example for SDL_Renderer users
|
||||
|
||||
We will here use [stb_image.h](https://github.com/nothings/stb/blob/master/stb_image.h) to load images from disk.
|
||||
|
||||
Reference in New Issue
Block a user