Files

173 lines
5.3 KiB
C++
Raw Permalink Normal View History

2022-07-27 11:25:25 -04:00
#include "imgui.hpp"
2025-04-03 00:12:22 -06:00
#include <cstddef>
#include <string>
#include <vector>
#include <webgpu/webgpu_cpp.h>
2025-04-04 22:01:52 -06:00
#include <SDL3/SDL_render.h>
2025-04-03 00:12:22 -06:00
2022-07-27 11:25:25 -04:00
#include "internal.hpp"
2025-04-03 00:12:22 -06:00
#include "webgpu/gpu.hpp"
2022-07-27 11:25:25 -04:00
#include "window.hpp"
2025-04-03 00:12:22 -06:00
#define IMGUI_IMPL_WEBGPU_BACKEND_DAWN
2025-04-04 22:01:52 -06:00
#include "backends/imgui_impl_sdl3.h"
#include "backends/imgui_impl_sdlrenderer3.h"
#include "backends/imgui_impl_wgpu.h"
2022-07-27 11:25:25 -04:00
namespace aurora::imgui {
static float g_scale;
static std::string g_imguiSettings{};
static std::string g_imguiLog{};
static bool g_useSdlRenderer = false;
static std::vector<SDL_Texture*> g_sdlTextures;
static std::vector<wgpu::Texture> g_wgpuTextures;
2022-07-27 11:25:25 -04:00
void create_context() noexcept {
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
g_imguiSettings = std::string{g_config.configPath} + "/imgui.ini";
g_imguiLog = std::string{g_config.configPath} + "/imgui.log";
io.IniFilename = g_imguiSettings.c_str();
io.LogFilename = g_imguiLog.c_str();
}
void initialize() noexcept {
SDL_Renderer* renderer = window::get_sdl_renderer();
2025-04-04 22:01:52 -06:00
ImGui_ImplSDL3_InitForSDLRenderer(window::get_sdl_window(), renderer);
2022-07-27 11:25:25 -04:00
g_useSdlRenderer = renderer != nullptr;
if (g_useSdlRenderer) {
2025-04-02 19:57:16 -06:00
ImGui_ImplSDLRenderer3_Init(renderer);
2022-07-27 11:25:25 -04:00
} else {
2025-04-03 00:12:22 -06:00
ImGui_ImplWGPU_InitInfo info;
info.Device = webgpu::g_device.Get();
info.RenderTargetFormat = static_cast<WGPUTextureFormat>(webgpu::g_graphicsConfig.surfaceConfiguration.format);
ImGui_ImplWGPU_Init(&info);
2022-07-27 11:25:25 -04:00
}
}
void shutdown() noexcept {
if (g_useSdlRenderer) {
2025-04-02 19:57:16 -06:00
ImGui_ImplSDLRenderer3_Shutdown();
2022-07-27 11:25:25 -04:00
} else {
ImGui_ImplWGPU_Shutdown();
}
2025-04-02 19:57:16 -06:00
ImGui_ImplSDL3_Shutdown();
2022-07-27 11:25:25 -04:00
ImGui::DestroyContext();
for (const auto& texture : g_sdlTextures) {
SDL_DestroyTexture(texture);
}
g_sdlTextures.clear();
g_wgpuTextures.clear();
}
void process_event(const SDL_Event& event) noexcept {
2025-04-03 00:12:22 -06:00
if (event.type == SDL_EVENT_MOUSE_MOTION) {
SDL_Event scaledEvent = event;
const auto density = SDL_GetWindowPixelDensity(window::get_sdl_window());
scaledEvent.motion.x *= density;
scaledEvent.motion.y *= density;
scaledEvent.motion.xrel *= density;
scaledEvent.motion.yrel *= density;
2025-04-03 00:12:22 -06:00
ImGui_ImplSDL3_ProcessEvent(&scaledEvent);
2022-07-27 11:25:25 -04:00
return;
}
2025-04-02 19:57:16 -06:00
ImGui_ImplSDL3_ProcessEvent(&event);
2022-07-27 11:25:25 -04:00
}
void new_frame(const AuroraWindowSize& size) noexcept {
if (g_useSdlRenderer) {
2025-04-02 19:57:16 -06:00
ImGui_ImplSDLRenderer3_NewFrame();
2023-05-27 11:44:36 -04:00
g_scale = size.scale;
2022-07-27 11:25:25 -04:00
} else {
if (g_scale != size.scale) {
if (g_scale > 0.f) {
ImGui_ImplWGPU_CreateDeviceObjects();
}
g_scale = size.scale;
}
ImGui_ImplWGPU_NewFrame();
}
2025-04-02 19:57:16 -06:00
ImGui_ImplSDL3_NewFrame();
2022-07-27 11:25:25 -04:00
// Render at full DPI
ImGui::GetIO().DisplaySize = {
static_cast<float>(size.fb_width),
static_cast<float>(size.fb_height),
};
ImGui::NewFrame();
}
void render(const wgpu::RenderPassEncoder& pass) noexcept {
2022-07-27 11:25:25 -04:00
ImGui::Render();
auto* data = ImGui::GetDrawData();
// io.DisplayFramebufferScale is informational; we're rendering at full DPI
data->FramebufferScale = {1.f, 1.f};
if (g_useSdlRenderer) {
2025-04-04 22:01:52 -06:00
SDL_Renderer* renderer = window::get_sdl_renderer();
2022-07-27 11:25:25 -04:00
SDL_RenderClear(renderer);
2025-04-02 19:57:16 -06:00
ImGui_ImplSDLRenderer3_RenderDrawData(data, renderer);
2022-07-27 11:25:25 -04:00
SDL_RenderPresent(renderer);
} else {
ImGui_ImplWGPU_RenderDrawData(data, pass.Get());
2022-07-27 11:25:25 -04:00
}
}
ImTextureID add_texture(uint32_t width, uint32_t height, const uint8_t* data) noexcept {
if (g_useSdlRenderer) {
2025-04-04 22:01:52 -06:00
SDL_Renderer* renderer = window::get_sdl_renderer();
2022-07-27 11:25:25 -04:00
SDL_Texture* texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_STATIC, width, height);
SDL_UpdateTexture(texture, nullptr, data, width * 4);
2025-04-02 19:57:16 -06:00
SDL_SetTextureScaleMode(texture, SDL_SCALEMODE_LINEAR);
2022-07-27 11:25:25 -04:00
g_sdlTextures.push_back(texture);
2025-04-02 19:57:16 -06:00
return reinterpret_cast<ImTextureID>(texture);
2022-07-27 11:25:25 -04:00
}
const wgpu::Extent3D size{
2022-07-27 11:25:25 -04:00
.width = width,
.height = height,
.depthOrArrayLayers = 1,
};
const wgpu::TextureDescriptor textureDescriptor{
2022-07-27 11:25:25 -04:00
.label = "imgui texture",
.usage = wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::CopyDst,
.dimension = wgpu::TextureDimension::e2D,
2022-07-27 11:25:25 -04:00
.size = size,
.format = wgpu::TextureFormat::RGBA8Unorm,
2022-07-27 11:25:25 -04:00
.mipLevelCount = 1,
.sampleCount = 1,
};
const wgpu::TextureViewDescriptor textureViewDescriptor{
2022-07-27 11:25:25 -04:00
.label = "imgui texture view",
.format = wgpu::TextureFormat::RGBA8Unorm,
.dimension = wgpu::TextureViewDimension::e2D,
2022-07-27 11:25:25 -04:00
.mipLevelCount = WGPU_MIP_LEVEL_COUNT_UNDEFINED,
.arrayLayerCount = WGPU_ARRAY_LAYER_COUNT_UNDEFINED,
};
auto texture = webgpu::g_device.CreateTexture(&textureDescriptor);
auto textureView = texture.CreateView(&textureViewDescriptor);
2022-07-27 11:25:25 -04:00
{
2025-04-03 00:12:22 -06:00
const wgpu::TexelCopyTextureInfo dstView{
2022-07-27 11:25:25 -04:00
.texture = texture,
};
2025-04-03 00:12:22 -06:00
const wgpu::TexelCopyBufferLayout dataLayout{
2022-07-27 11:25:25 -04:00
.bytesPerRow = 4 * width,
.rowsPerImage = height,
};
webgpu::g_queue.WriteTexture(&dstView, data, width * height * 4, &dataLayout, &size);
2022-07-27 11:25:25 -04:00
}
g_wgpuTextures.push_back(texture);
2025-04-03 00:12:22 -06:00
return reinterpret_cast<ImTextureID>(textureView.MoveToCHandle());
2022-07-27 11:25:25 -04:00
}
} // namespace aurora::imgui
// C bindings
extern "C" {
ImTextureID aurora_imgui_add_texture(uint32_t width, uint32_t height, const void* rgba8) {
return aurora::imgui::add_texture(width, height, static_cast<const uint8_t*>(rgba8));
}
}