[Scummvm-git-logs] scummvm master -> 1d2d08169066947f61f7abf97ca01835296f4caf

sev- noreply at scummvm.org
Sun Sep 29 15:04:09 UTC 2024


This automated email contains information about 7 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
2eebb5db02 BACKENDS: SDL: Add SDL2 Renderer support for ImGui
27c7a64683 COMMON: Add ImGui API to create images
f04f248f20 BACKENDS: SDL: Implement ImGui API to load images
930390450f DIRECTOR: Use Common API to create ImGui images
af8ce0e254 QDENGINE: Use Common API to create ImGui images
2813582f6b BACKENDS: SDL: Remove superfluous version checks
1d2d081690 CREATE_PROJECT: Enable ImGui SDL Renderer support


Commit: 2eebb5db02f0fc3dba9b08a62106192a07b62171
    https://github.com/scummvm/scummvm/commit/2eebb5db02f0fc3dba9b08a62106192a07b62171
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2024-09-29T17:04:03+02:00

Commit Message:
BACKENDS: SDL: Add SDL2 Renderer support for ImGui

Some adaptations will be needed for the the engines.

Changed paths:
  A backends/imgui/backends/imgui_impl_sdlrenderer2.cpp
  A backends/imgui/backends/imgui_impl_sdlrenderer2.h
    backends/graphics/openglsdl/openglsdl-graphics.cpp
    backends/graphics/sdl/sdl-graphics.cpp
    backends/graphics/sdl/sdl-graphics.h
    backends/graphics/surfacesdl/surfacesdl-graphics.cpp
    backends/graphics3d/openglsdl/openglsdl-graphics3d.cpp
    backends/module.mk
    configure


diff --git a/backends/graphics/openglsdl/openglsdl-graphics.cpp b/backends/graphics/openglsdl/openglsdl-graphics.cpp
index 528886e2fb2..546785b15c1 100644
--- a/backends/graphics/openglsdl/openglsdl-graphics.cpp
+++ b/backends/graphics/openglsdl/openglsdl-graphics.cpp
@@ -621,7 +621,7 @@ bool OpenGLSdlGraphicsManager::setupMode(uint width, uint height) {
 
 #ifdef USE_IMGUI
 	// Setup Dear ImGui
-	initImGui(_glContext);
+	initImGui(nullptr, _glContext);
 #endif
 
 	if (SDL_GL_SetSwapInterval(_vsync ? 1 : 0)) {
diff --git a/backends/graphics/sdl/sdl-graphics.cpp b/backends/graphics/sdl/sdl-graphics.cpp
index 516c421c63d..0e5554bdbf8 100644
--- a/backends/graphics/sdl/sdl-graphics.cpp
+++ b/backends/graphics/sdl/sdl-graphics.cpp
@@ -40,8 +40,13 @@
 
 #if defined(USE_IMGUI) && SDL_VERSION_ATLEAST(2, 0, 0)
 #include "backends/imgui/backends/imgui_impl_sdl2.h"
+#ifdef USE_OPENGL
 #include "backends/imgui/backends/imgui_impl_opengl3.h"
 #endif
+#ifdef USE_IMGUI_SDLRENDERER2
+#include "backends/imgui/backends/imgui_impl_sdlrenderer2.h"
+#endif
+#endif
 
 SdlGraphicsManager::SdlGraphicsManager(SdlEventSource *source, SdlWindow *window)
 	: _eventSource(source), _window(window), _hwScreen(nullptr)
@@ -543,7 +548,7 @@ Common::Keymap *SdlGraphicsManager::getKeymap() {
 }
 
 #if defined(USE_IMGUI) && SDL_VERSION_ATLEAST(2, 0, 0)
-void SdlGraphicsManager::initImGui(void *glContext) {
+void SdlGraphicsManager::initImGui(SDL_Renderer *renderer, void *glContext) {
 	assert(!_imGuiReady);
 	_imGuiInited = false;
 
@@ -553,26 +558,55 @@ void SdlGraphicsManager::initImGui(void *glContext) {
 	}
 	ImGuiIO &io = ImGui::GetIO();
 	io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;         // Enable Docking
-	io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;       // Enable Multi-Viewport / Platform Windows
 	ImGui::StyleColorsDark();
 	// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
 	ImGuiStyle& style = ImGui::GetStyle();
 	style.WindowRounding = 0.0f;
 	style.Colors[ImGuiCol_WindowBg].w = 1.0f;
 	io.IniFilename = nullptr;
-	if (!ImGui_ImplSDL2_InitForOpenGL(_window->getSDLWindow(), glContext)) {
-		ImGui::DestroyContext();
-		return;
+
+	_imGuiSDLRenderer = nullptr;
+#ifdef USE_OPENGL
+	if (!_imGuiReady && glContext) {
+		io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;       // Enable Multi-Viewport / Platform Windows
+
+		if (!ImGui_ImplSDL2_InitForOpenGL(_window->getSDLWindow(), glContext)) {
+			ImGui::DestroyContext();
+			return;
+		}
+
+		if (!ImGui_ImplOpenGL3_Init("#version 110")) {
+			ImGui_ImplSDL2_Shutdown();
+			ImGui::DestroyContext();
+			return;
+		}
+
+		_imGuiReady = true;
 	}
+#endif
+#ifdef USE_IMGUI_SDLRENDERER2
+	if (!_imGuiReady && renderer) {
+		if (!ImGui_ImplSDL2_InitForSDLRenderer(_window->getSDLWindow(), renderer)) {
+			ImGui::DestroyContext();
+			return;
+		}
+
+		if (!ImGui_ImplSDLRenderer2_Init(renderer)) {
+			ImGui_ImplSDL2_Shutdown();
+			ImGui::DestroyContext();
+			return;
+		}
 
-	if (!ImGui_ImplOpenGL3_Init("#version 110")) {
-		ImGui_ImplSDL2_Shutdown();
+		_imGuiReady = true;
+		_imGuiSDLRenderer = renderer;
+	}
+#endif
+	if (!_imGuiReady) {
+		warning("No ImGui renderer has been found");
 		ImGui::DestroyContext();
 		return;
 	}
 
-	_imGuiReady = true;
-
 	if (_imGuiCallbacks.init) {
 		_imGuiCallbacks.init();
 		_imGuiInited = true;
@@ -591,19 +625,39 @@ void SdlGraphicsManager::renderImGui() {
 		_imGuiInited = true;
 	}
 
-	ImGui_ImplOpenGL3_NewFrame();
+#ifdef USE_IMGUI_SDLRENDERER2
+	if (_imGuiSDLRenderer) {
+		ImGui_ImplSDLRenderer2_NewFrame();
+	} else {
+#endif
+#ifdef USE_OPENGL
+		ImGui_ImplOpenGL3_NewFrame();
+#endif
+#ifdef USE_IMGUI_SDLRENDERER2
+	}
+#endif
 	ImGui_ImplSDL2_NewFrame();
 
 	ImGui::NewFrame();
 	_imGuiCallbacks.render();
 	ImGui::Render();
-	ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
-
-	SDL_Window* backup_current_window = SDL_GL_GetCurrentWindow();
-	SDL_GLContext backup_current_context = SDL_GL_GetCurrentContext();
-	ImGui::UpdatePlatformWindows();
-	ImGui::RenderPlatformWindowsDefault();
-	SDL_GL_MakeCurrent(backup_current_window, backup_current_context);
+#ifdef USE_IMGUI_SDLRENDERER2
+	if (_imGuiSDLRenderer) {
+		ImGui_ImplSDLRenderer2_RenderDrawData(ImGui::GetDrawData(), _imGuiSDLRenderer);
+	} else {
+#endif
+#ifdef USE_OPENGL
+		ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
+
+		SDL_Window* backup_current_window = SDL_GL_GetCurrentWindow();
+		SDL_GLContext backup_current_context = SDL_GL_GetCurrentContext();
+		ImGui::UpdatePlatformWindows();
+		ImGui::RenderPlatformWindowsDefault();
+		SDL_GL_MakeCurrent(backup_current_window, backup_current_context);
+#endif
+#ifdef USE_IMGUI_SDLRENDERER2
+	}
+#endif
 }
 
 void SdlGraphicsManager::destroyImGui() {
@@ -618,7 +672,17 @@ void SdlGraphicsManager::destroyImGui() {
 	_imGuiInited = false;
 	_imGuiReady = false;
 
-	ImGui_ImplOpenGL3_Shutdown();
+#ifdef USE_IMGUI_SDLRENDERER2
+	if (_imGuiSDLRenderer) {
+		ImGui_ImplSDLRenderer2_Shutdown();
+	} else {
+#endif
+#ifdef USE_OPENGL
+		ImGui_ImplOpenGL3_Shutdown();
+#endif
+#ifdef USE_IMGUI_SDLRENDERER2
+	}
+#endif
 	ImGui_ImplSDL2_Shutdown();
 	ImGui::DestroyContext();
 }
diff --git a/backends/graphics/sdl/sdl-graphics.h b/backends/graphics/sdl/sdl-graphics.h
index 6c978a9e129..17a3bfde115 100644
--- a/backends/graphics/sdl/sdl-graphics.h
+++ b/backends/graphics/sdl/sdl-graphics.h
@@ -216,8 +216,9 @@ protected:
 	ImGuiCallbacks _imGuiCallbacks;
 	bool _imGuiReady = false;
 	bool _imGuiInited = false;
+	SDL_Renderer *_imGuiSDLRenderer = nullptr;
 
-	void initImGui(void *glContext);
+	void initImGui(SDL_Renderer *renderer, void *glContext);
 	void renderImGui();
 	void destroyImGui();
 #endif
diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
index 840fee5a82e..836c20aadea 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
@@ -927,11 +927,6 @@ void SurfaceSdlGraphicsManager::initGraphicsSurface() {
 	_isDoubleBuf = flags & SDL_DOUBLEBUF;
 	_isHwPalette = flags & SDL_HWPALETTE;
 #endif
-
-#if defined(USE_IMGUI) && SDL_VERSION_ATLEAST(2, 0, 0)
-	// Setup Dear ImGui
-	initImGui(nullptr);
-#endif
 }
 
 bool SurfaceSdlGraphicsManager::loadGFXMode() {
@@ -1323,6 +1318,12 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
 	if (_isDoubleBuf && _numDirtyRects)
 		_forceRedraw = true;
 
+#if defined(USE_IMGUI) && defined(USE_IMGUI_SDLRENDERER2)
+	if (_imGuiCallbacks.render) {
+		_forceRedraw = true;
+	}
+#endif
+
 	bool doRedraw = _forceRedraw || (_prevForceRedraw && _isDoubleBuf);
 	int actualDirtyRects = _numDirtyRects;
 	if (_isDoubleBuf && _numPrevDirtyRects > 0) {
@@ -1347,6 +1348,7 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
 	}
 
 	// Only draw anything if necessary
+	bool doPresent = false;
 	if (actualDirtyRects > 0 || _cursorNeedsRedraw) {
 		SDL_Rect *r;
 		SDL_Rect dst;
@@ -1525,6 +1527,7 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
 		// Finally, blit all our changes to the screen
 		if (!_displayDisabled) {
 			updateScreen(_dirtyRectList, actualDirtyRects);
+			doPresent = true;
 		}
 	}
 
@@ -1536,11 +1539,16 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
 	_forceRedraw = false;
 	_cursorNeedsRedraw = false;
 
-#if defined(USE_IMGUI) && SDL_VERSION_ATLEAST(2, 0, 0)
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+
+#if defined(USE_IMGUI) && defined(USE_IMGUI_SDLRENDERER2)
 	renderImGui();
 #endif
 
-#if !SDL_VERSION_ATLEAST(2, 0, 0)
+	if (doPresent) {
+		SDL_RenderPresent(_renderer);
+	}
+#else
 	if (_isDoubleBuf)
 		SDL_Flip(_hwScreen);
 #endif
@@ -2815,7 +2823,7 @@ void SurfaceSdlGraphicsManager::notifyResize(const int width, const int height)
 
 #if SDL_VERSION_ATLEAST(2, 0, 0)
 void SurfaceSdlGraphicsManager::deinitializeRenderer() {
-#ifdef USE_IMGUI
+#if defined(USE_IMGUI) && defined(USE_IMGUI_SDLRENDERER2)
 	destroyImGui();
 #endif
 
@@ -2899,9 +2907,14 @@ SDL_Surface *SurfaceSdlGraphicsManager::SDL_SetVideoMode(int width, int height,
 	if (!screen) {
 		deinitializeRenderer();
 		return nullptr;
-	} else {
-		return screen;
 	}
+
+#if defined(USE_IMGUI) && defined(USE_IMGUI_SDLRENDERER2)
+	// Setup Dear ImGui
+	initImGui(_renderer, nullptr);
+#endif
+
+	return screen;
 }
 
 void SurfaceSdlGraphicsManager::SDL_UpdateRects(SDL_Surface *screen, int numrects, SDL_Rect *rects) {
@@ -2929,11 +2942,9 @@ void SurfaceSdlGraphicsManager::SDL_UpdateRects(SDL_Surface *screen, int numrect
 #if SDL_VERSION_ATLEAST(2, 0, 0)
 	if (rotangle != 0)
 		SDL_RenderCopyEx(_renderer, _screenTexture, nullptr, &viewport, rotangle, nullptr, SDL_FLIP_NONE);
-	else 
+	else
 #endif
 		SDL_RenderCopy(_renderer, _screenTexture, nullptr, &viewport);
-
-	SDL_RenderPresent(_renderer);
 }
 
 int SurfaceSdlGraphicsManager::SDL_SetColors(SDL_Surface *surface, SDL_Color *colors, int firstcolor, int ncolors) {
diff --git a/backends/graphics3d/openglsdl/openglsdl-graphics3d.cpp b/backends/graphics3d/openglsdl/openglsdl-graphics3d.cpp
index 284ab28d06b..69630e92dbf 100644
--- a/backends/graphics3d/openglsdl/openglsdl-graphics3d.cpp
+++ b/backends/graphics3d/openglsdl/openglsdl-graphics3d.cpp
@@ -554,7 +554,7 @@ bool OpenGLSdlGraphics3dManager::createOrUpdateGLContext(uint gameWidth, uint ga
 
 #ifdef USE_IMGUI
 					// Setup Dear ImGui
-					initImGui(_glContext);
+					initImGui(nullptr, _glContext);
 #endif
 				}
 			}
diff --git a/backends/imgui/backends/imgui_impl_sdlrenderer2.cpp b/backends/imgui/backends/imgui_impl_sdlrenderer2.cpp
new file mode 100644
index 00000000000..c385a0dabef
--- /dev/null
+++ b/backends/imgui/backends/imgui_impl_sdlrenderer2.cpp
@@ -0,0 +1,266 @@
+// dear imgui: Renderer Backend for SDL_Renderer for SDL2
+// (Requires: SDL 2.0.17+)
+
+// Note how SDL_Renderer is an _optional_ component of SDL2.
+// For a multi-platform app consider using e.g. SDL+DirectX on Windows and SDL+OpenGL on Linux/OSX.
+// If your application will want to render any non trivial amount of graphics other than UI,
+// please be aware that SDL_Renderer currently offers a limited graphic API to the end-user and
+// it might be difficult to step out of those boundaries.
+
+// Implemented features:
+//  [X] Renderer: User texture binding. Use 'SDL_Texture*' as ImTextureID. Read the FAQ about ImTextureID!
+//  [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
+// Missing features:
+//  [ ] Renderer: Multi-viewport support (multiple windows).
+
+// You can copy and use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
+// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
+// Learn about Dear ImGui:
+// - FAQ                  https://dearimgui.com/faq
+// - Getting Started      https://dearimgui.com/getting-started
+// - Documentation        https://dearimgui.com/docs (same as your local docs/ folder).
+// - Introduction, links and more at the top of imgui.cpp
+
+// CHANGELOG
+//  2024-05-14: *BREAKING CHANGE* ImGui_ImplSDLRenderer3_RenderDrawData() requires SDL_Renderer* passed as parameter.
+//  2023-05-30: Renamed imgui_impl_sdlrenderer.h/.cpp to imgui_impl_sdlrenderer2.h/.cpp to accommodate for upcoming SDL3.
+//  2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
+//  2021-12-21: Update SDL_RenderGeometryRaw() format to work with SDL 2.0.19.
+//  2021-12-03: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag.
+//  2021-10-06: Backup and restore modified ClipRect/Viewport.
+//  2021-09-21: Initial version.
+
+#include "backends/imgui/imgui.h"
+#ifndef IMGUI_DISABLE
+#include "imgui_impl_sdlrenderer2.h"
+#include <stdint.h>     // intptr_t
+
+// Clang warnings with -Weverything
+#if defined(__clang__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wsign-conversion"    // warning: implicit conversion changes signedness
+#endif
+
+// SDL
+#include <SDL.h>
+#if !SDL_VERSION_ATLEAST(2,0,17)
+#error This backend requires SDL 2.0.17+ because of SDL_RenderGeometry() function
+#endif
+
+// SDL_Renderer data
+struct ImGui_ImplSDLRenderer2_Data
+{
+    SDL_Renderer*   Renderer;       // Main viewport's renderer
+    SDL_Texture*    FontTexture;
+    ImGui_ImplSDLRenderer2_Data()   { memset((void*)this, 0, sizeof(*this)); }
+};
+
+// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts
+// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts.
+static ImGui_ImplSDLRenderer2_Data* ImGui_ImplSDLRenderer2_GetBackendData()
+{
+    return ImGui::GetCurrentContext() ? (ImGui_ImplSDLRenderer2_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
+}
+
+// Functions
+bool ImGui_ImplSDLRenderer2_Init(SDL_Renderer* renderer)
+{
+    ImGuiIO& io = ImGui::GetIO();
+    IMGUI_CHECKVERSION();
+    IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
+    IM_ASSERT(renderer != nullptr && "SDL_Renderer not initialized!");
+
+    // Setup backend capabilities flags
+    ImGui_ImplSDLRenderer2_Data* bd = IM_NEW(ImGui_ImplSDLRenderer2_Data)();
+    io.BackendRendererUserData = (void*)bd;
+    io.BackendRendererName = "imgui_impl_sdlrenderer2";
+    io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset;  // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
+
+    bd->Renderer = renderer;
+
+    return true;
+}
+
+void ImGui_ImplSDLRenderer2_Shutdown()
+{
+    ImGui_ImplSDLRenderer2_Data* bd = ImGui_ImplSDLRenderer2_GetBackendData();
+    IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
+    ImGuiIO& io = ImGui::GetIO();
+
+    ImGui_ImplSDLRenderer2_DestroyDeviceObjects();
+
+    io.BackendRendererName = nullptr;
+    io.BackendRendererUserData = nullptr;
+    io.BackendFlags &= ~ImGuiBackendFlags_RendererHasVtxOffset;
+    IM_DELETE(bd);
+}
+
+static void ImGui_ImplSDLRenderer2_SetupRenderState(SDL_Renderer* renderer)
+{
+	// Clear out any viewports and cliprect set by the user
+    // FIXME: Technically speaking there are lots of other things we could backup/setup/restore during our render process.
+	SDL_RenderSetViewport(renderer, nullptr);
+	SDL_RenderSetClipRect(renderer, nullptr);
+}
+
+void ImGui_ImplSDLRenderer2_NewFrame()
+{
+    ImGui_ImplSDLRenderer2_Data* bd = ImGui_ImplSDLRenderer2_GetBackendData();
+    IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplSDLRenderer2_Init()?");
+
+    if (!bd->FontTexture)
+        ImGui_ImplSDLRenderer2_CreateDeviceObjects();
+}
+
+void ImGui_ImplSDLRenderer2_RenderDrawData(ImDrawData* draw_data, SDL_Renderer* renderer)
+{
+	// If there's a scale factor set by the user, use that instead
+    // If the user has specified a scale factor to SDL_Renderer already via SDL_RenderSetScale(), SDL will scale whatever we pass
+    // to SDL_RenderGeometryRaw() by that scale factor. In that case we don't want to be also scaling it ourselves here.
+    float rsx = 1.0f;
+	float rsy = 1.0f;
+	SDL_RenderGetScale(renderer, &rsx, &rsy);
+    ImVec2 render_scale;
+	render_scale.x = (rsx == 1.0f) ? draw_data->FramebufferScale.x : 1.0f;
+	render_scale.y = (rsy == 1.0f) ? draw_data->FramebufferScale.y : 1.0f;
+
+	// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
+	int fb_width = (int)(draw_data->DisplaySize.x * render_scale.x);
+	int fb_height = (int)(draw_data->DisplaySize.y * render_scale.y);
+	if (fb_width == 0 || fb_height == 0)
+		return;
+
+    // Backup SDL_Renderer state that will be modified to restore it afterwards
+    struct BackupSDLRendererState
+    {
+        SDL_Rect    Viewport;
+        bool        ClipEnabled;
+        SDL_Rect    ClipRect;
+    };
+    BackupSDLRendererState old = {};
+    old.ClipEnabled = SDL_RenderIsClipEnabled(renderer) == SDL_TRUE;
+    SDL_RenderGetViewport(renderer, &old.Viewport);
+    SDL_RenderGetClipRect(renderer, &old.ClipRect);
+
+	// Will project scissor/clipping rectangles into framebuffer space
+	ImVec2 clip_off = draw_data->DisplayPos;         // (0,0) unless using multi-viewports
+	ImVec2 clip_scale = render_scale;
+
+    // Render command lists
+    ImGui_ImplSDLRenderer2_SetupRenderState(renderer);
+    for (int n = 0; n < draw_data->CmdListsCount; n++)
+    {
+        const ImDrawList* cmd_list = draw_data->CmdLists[n];
+        const ImDrawVert* vtx_buffer = cmd_list->VtxBuffer.Data;
+        const ImDrawIdx* idx_buffer = cmd_list->IdxBuffer.Data;
+
+        for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
+        {
+            const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
+            if (pcmd->UserCallback)
+            {
+                // User callback, registered via ImDrawList::AddCallback()
+                // (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
+                if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
+                    ImGui_ImplSDLRenderer2_SetupRenderState(renderer);
+                else
+                    pcmd->UserCallback(cmd_list, pcmd);
+            }
+            else
+            {
+                // Project scissor/clipping rectangles into framebuffer space
+                ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y);
+                ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y);
+                if (clip_min.x < 0.0f) { clip_min.x = 0.0f; }
+                if (clip_min.y < 0.0f) { clip_min.y = 0.0f; }
+                if (clip_max.x > (float)fb_width) { clip_max.x = (float)fb_width; }
+                if (clip_max.y > (float)fb_height) { clip_max.y = (float)fb_height; }
+                if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
+                    continue;
+
+                SDL_Rect r = { (int)(clip_min.x), (int)(clip_min.y), (int)(clip_max.x - clip_min.x), (int)(clip_max.y - clip_min.y) };
+                SDL_RenderSetClipRect(renderer, &r);
+
+                const float* xy = (const float*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + offsetof(ImDrawVert, pos));
+                const float* uv = (const float*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + offsetof(ImDrawVert, uv));
+#if SDL_VERSION_ATLEAST(2,0,19)
+                const SDL_Color* color = (const SDL_Color*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + offsetof(ImDrawVert, col)); // SDL 2.0.19+
+#else
+                const int* color = (const int*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + offsetof(ImDrawVert, col)); // SDL 2.0.17 and 2.0.18
+#endif
+
+                // Bind texture, Draw
+				SDL_Texture* tex = (SDL_Texture*)pcmd->GetTexID();
+                SDL_RenderGeometryRaw(renderer, tex,
+                    xy, (int)sizeof(ImDrawVert),
+                    color, (int)sizeof(ImDrawVert),
+                    uv, (int)sizeof(ImDrawVert),
+                    cmd_list->VtxBuffer.Size - pcmd->VtxOffset,
+                    idx_buffer + pcmd->IdxOffset, pcmd->ElemCount, sizeof(ImDrawIdx));
+            }
+        }
+    }
+
+    // Restore modified SDL_Renderer state
+    SDL_RenderSetViewport(renderer, &old.Viewport);
+    SDL_RenderSetClipRect(renderer, old.ClipEnabled ? &old.ClipRect : nullptr);
+}
+
+// Called by Init/NewFrame/Shutdown
+bool ImGui_ImplSDLRenderer2_CreateFontsTexture()
+{
+    ImGuiIO& io = ImGui::GetIO();
+    ImGui_ImplSDLRenderer2_Data* bd = ImGui_ImplSDLRenderer2_GetBackendData();
+
+    // Build texture atlas
+    unsigned char* pixels;
+    int width, height;
+    io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);   // Load as RGBA 32-bit (75% of the memory is wasted, but default font is so small) because it is more likely to be compatible with user's existing shaders. If your ImTextureId represent a higher-level concept than just a GL texture id, consider calling GetTexDataAsAlpha8() instead to save on GPU memory.
+
+    // Upload texture to graphics system
+    // (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
+    bd->FontTexture = SDL_CreateTexture(bd->Renderer, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STATIC, width, height);
+    if (bd->FontTexture == nullptr)
+    {
+        SDL_Log("error creating texture");
+        return false;
+    }
+    SDL_UpdateTexture(bd->FontTexture, nullptr, pixels, 4 * width);
+    SDL_SetTextureBlendMode(bd->FontTexture, SDL_BLENDMODE_BLEND);
+    SDL_SetTextureScaleMode(bd->FontTexture, SDL_ScaleModeLinear);
+
+    // Store our identifier
+    io.Fonts->SetTexID((ImTextureID)(intptr_t)bd->FontTexture);
+
+    return true;
+}
+
+void ImGui_ImplSDLRenderer2_DestroyFontsTexture()
+{
+    ImGuiIO& io = ImGui::GetIO();
+    ImGui_ImplSDLRenderer2_Data* bd = ImGui_ImplSDLRenderer2_GetBackendData();
+    if (bd->FontTexture)
+    {
+        io.Fonts->SetTexID(0);
+        SDL_DestroyTexture(bd->FontTexture);
+        bd->FontTexture = nullptr;
+    }
+}
+
+bool ImGui_ImplSDLRenderer2_CreateDeviceObjects()
+{
+    return ImGui_ImplSDLRenderer2_CreateFontsTexture();
+}
+
+void ImGui_ImplSDLRenderer2_DestroyDeviceObjects()
+{
+    ImGui_ImplSDLRenderer2_DestroyFontsTexture();
+}
+
+//-----------------------------------------------------------------------------
+
+#if defined(__clang__)
+#pragma clang diagnostic pop
+#endif
+
+#endif // #ifndef IMGUI_DISABLE
diff --git a/backends/imgui/backends/imgui_impl_sdlrenderer2.h b/backends/imgui/backends/imgui_impl_sdlrenderer2.h
new file mode 100644
index 00000000000..6b7ff09ade1
--- /dev/null
+++ b/backends/imgui/backends/imgui_impl_sdlrenderer2.h
@@ -0,0 +1,41 @@
+// dear imgui: Renderer Backend for SDL_Renderer for SDL2
+// (Requires: SDL 2.0.17+)
+
+// Note how SDL_Renderer is an _optional_ component of SDL2.
+// For a multi-platform app consider using e.g. SDL+DirectX on Windows and SDL+OpenGL on Linux/OSX.
+// If your application will want to render any non trivial amount of graphics other than UI,
+// please be aware that SDL_Renderer currently offers a limited graphic API to the end-user and
+// it might be difficult to step out of those boundaries.
+
+// Implemented features:
+//  [X] Renderer: User texture binding. Use 'SDL_Texture*' as ImTextureID. Read the FAQ about ImTextureID!
+//  [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
+// Missing features:
+//  [ ] Renderer: Multi-viewport support (multiple windows).
+
+// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
+// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
+// Learn about Dear ImGui:
+// - FAQ                  https://dearimgui.com/faq
+// - Getting Started      https://dearimgui.com/getting-started
+// - Documentation        https://dearimgui.com/docs (same as your local docs/ folder).
+// - Introduction, links and more at the top of imgui.cpp
+
+#pragma once
+#include "backends/imgui/imgui.h"      // IMGUI_IMPL_API
+#ifndef IMGUI_DISABLE
+
+struct SDL_Renderer;
+
+IMGUI_IMPL_API bool     ImGui_ImplSDLRenderer2_Init(SDL_Renderer* renderer);
+IMGUI_IMPL_API void     ImGui_ImplSDLRenderer2_Shutdown();
+IMGUI_IMPL_API void     ImGui_ImplSDLRenderer2_NewFrame();
+IMGUI_IMPL_API void     ImGui_ImplSDLRenderer2_RenderDrawData(ImDrawData* draw_data, SDL_Renderer* renderer);
+
+// Called by Init/NewFrame/Shutdown
+IMGUI_IMPL_API bool     ImGui_ImplSDLRenderer2_CreateFontsTexture();
+IMGUI_IMPL_API void     ImGui_ImplSDLRenderer2_DestroyFontsTexture();
+IMGUI_IMPL_API bool     ImGui_ImplSDLRenderer2_CreateDeviceObjects();
+IMGUI_IMPL_API void     ImGui_ImplSDLRenderer2_DestroyDeviceObjects();
+
+#endif // #ifndef IMGUI_DISABLE
diff --git a/backends/module.mk b/backends/module.mk
index 086f2fb6a34..7314e4d4c26 100644
--- a/backends/module.mk
+++ b/backends/module.mk
@@ -509,8 +509,15 @@ endif
 
 ifdef USE_SDL2
 ifdef USE_IMGUI
+ifdef USE_OPENGL
+MODULE_OBJS += \
+	imgui/backends/imgui_impl_opengl3.o
+endif
+ifdef USE_IMGUI_SDLRENDERER2
+MODULE_OBJS += \
+	imgui/backends/imgui_impl_sdlrenderer2.o
+endif
 MODULE_OBJS += \
-	imgui/backends/imgui_impl_opengl3.o \
 	imgui/backends/imgui_impl_sdl2.o
 endif
 endif
diff --git a/configure b/configure
index 06d5d3dfcea..ab53209f3b7 100755
--- a/configure
+++ b/configure
@@ -6726,31 +6726,42 @@ echo "$_discord"
 echocheck "ImGui"
 
 if test "$_imgui" != no ; then
-	if test "$_opengl" = yes ; then
-		if test "$_freetype2" = yes ; then
-			case $_backend in
-				sdl)
-					if test "$_sdlMajorVersionNumber" -ge 2 ; then
+	if test "$_freetype2" = yes ; then
+		case $_backend in
+			sdl)
+				if test "$_sdlMajorVersionNumber" -ge 2 ; then
+					cat > $TMPC << EOF
+#include "SDL.h"
+#if !SDL_VERSION_ATLEAST(2,0,18)
+#error Missing SDL_RenderGeometryRaw() function
+#endif
+int main(int argc, char *argv[]) { return 0; }
+EOF
+					if cc_check $LIBS $SDL_LIBS $INCLUDES $SDL_CFLAGS; then
+						define_in_config_if_yes yes 'USE_IMGUI_SDLRENDERER2'
+						_imgui=yes
+						echo "yes"
+					elif test "$_opengl" = yes; then
 						_imgui=yes
 						echo "yes"
 					else
 						_imgui=no
-						echo "no (backend unsupported)"
+						echo "no (requires OpenGL or recent SDL)"
 					fi
-					;;
-				*)
-					# For now, only SDL supports ImGui
+				else
 					_imgui=no
 					echo "no (backend unsupported)"
-					;;
-			esac
-		else
-			_imgui=no
-			echo "no (requires FreeType2)"
-		fi
+				fi
+				;;
+			*)
+				# For now, only SDL supports ImGui
+				_imgui=no
+				echo "no (backend unsupported)"
+				;;
+		esac
 	else
 		_imgui=no
-		echo "no (requires OpenGL)"
+		echo "no (requires FreeType2)"
 	fi
 else
 	echo "$_imgui"


Commit: 27c7a64683748dfbd8b1672847ce809c8bbd29ae
    https://github.com/scummvm/scummvm/commit/27c7a64683748dfbd8b1672847ce809c8bbd29ae
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2024-09-29T17:04:03+02:00

Commit Message:
COMMON: Add ImGui API to create images

Changed paths:
    backends/graphics/graphics.h
    backends/modular-backend.cpp
    backends/modular-backend.h
    common/system.h


diff --git a/backends/graphics/graphics.h b/backends/graphics/graphics.h
index b4a200cd8a5..be04b2d6a72 100644
--- a/backends/graphics/graphics.h
+++ b/backends/graphics/graphics.h
@@ -51,6 +51,8 @@ public:
 	virtual int getGraphicsMode() const { return 0; }
 #if defined(USE_IMGUI)
 	virtual void setImGuiCallbacks(const ImGuiCallbacks &callbacks) { }
+	virtual void *getImGuiTexture(const Graphics::Surface &image, const byte *palette, int palCount) { return nullptr; }
+	virtual void freeImGuiTexture(void *texture) { }
 #endif
 	virtual bool setShader(const Common::Path &fileName) { return false; }
 	virtual const OSystem::GraphicsMode *getSupportedStretchModes() const {
diff --git a/backends/modular-backend.cpp b/backends/modular-backend.cpp
index e8f27b60024..47955f1b29f 100644
--- a/backends/modular-backend.cpp
+++ b/backends/modular-backend.cpp
@@ -77,6 +77,12 @@ int ModularGraphicsBackend::getGraphicsMode() const {
 void ModularGraphicsBackend::setImGuiCallbacks(const ImGuiCallbacks &callbacks) {
 	_graphicsManager->setImGuiCallbacks(callbacks);
 }
+void *ModularGraphicsBackend::getImGuiTexture(const Graphics::Surface &image, const byte *palette, int palCount) {
+	return _graphicsManager->getImGuiTexture(image, palette, palCount);
+}
+void ModularGraphicsBackend::freeImGuiTexture(void *texture) {
+	_graphicsManager->freeImGuiTexture(texture);
+}
 #endif
 
 bool ModularGraphicsBackend::setShader(const Common::Path &fileName) {
diff --git a/backends/modular-backend.h b/backends/modular-backend.h
index 13ddb88f1c8..c8af74e836a 100644
--- a/backends/modular-backend.h
+++ b/backends/modular-backend.h
@@ -69,6 +69,8 @@ public:
 	int getGraphicsMode() const override;
 #if defined(USE_IMGUI)
 	void setImGuiCallbacks(const ImGuiCallbacks &callbacks) override final;
+	void *getImGuiTexture(const Graphics::Surface &image, const byte *palette, int palCount) override final;
+	void freeImGuiTexture(void *texture) override final;
 #endif
 	bool setShader(const Common::Path &name) override final;
 	const GraphicsMode *getSupportedStretchModes() const override final;
diff --git a/common/system.h b/common/system.h
index 0c3949cd43b..8b6735faf27 100644
--- a/common/system.h
+++ b/common/system.h
@@ -915,6 +915,22 @@ public:
 	 * @param callbacks Structure containing init/render/cleanup callbacks called on screen initialization, rendering and when deinitialized.
 	 */
 	virtual void setImGuiCallbacks(const ImGuiCallbacks &callbacks) {}
+	/**
+	 * Creates a new ImGui texture from a Graphics::Surface.
+	 *
+	 * @param image The Surface to convert.
+	 * @param palette The palette to use if image is a paletized surface.
+	 * @param palCount The number of entries in the palette.
+	 *
+	 * @return An ImGui texture identifier casted to void *.
+	 */
+	virtual void *getImGuiTexture(const Graphics::Surface &image, const byte *palette = nullptr, int palCount = 0) { return nullptr; }
+	/**
+	 * Frees an ImGui texture previously obtained by getImGuiTexture.
+	 *
+	 * @param texture The texture to free.
+	 */
+	virtual void freeImGuiTexture(void *texture) {}
 #endif
 
 	/**


Commit: f04f248f20572644f74e4d131e212f71e0348ba1
    https://github.com/scummvm/scummvm/commit/f04f248f20572644f74e4d131e212f71e0348ba1
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2024-09-29T17:04:03+02:00

Commit Message:
BACKENDS: SDL: Implement ImGui API to load images

Changed paths:
    backends/graphics/openglsdl/openglsdl-graphics.cpp
    backends/graphics/openglsdl/openglsdl-graphics.h
    backends/graphics/surfacesdl/surfacesdl-graphics.cpp
    backends/graphics/surfacesdl/surfacesdl-graphics.h
    backends/graphics3d/openglsdl/openglsdl-graphics3d.cpp
    backends/graphics3d/openglsdl/openglsdl-graphics3d.h


diff --git a/backends/graphics/openglsdl/openglsdl-graphics.cpp b/backends/graphics/openglsdl/openglsdl-graphics.cpp
index 546785b15c1..ed320391956 100644
--- a/backends/graphics/openglsdl/openglsdl-graphics.cpp
+++ b/backends/graphics/openglsdl/openglsdl-graphics.cpp
@@ -915,3 +915,32 @@ bool OpenGLSdlGraphicsManager::notifyEvent(const Common::Event &event) {
 		return SdlGraphicsManager::notifyEvent(event);
 	}
 }
+
+#if defined(USE_IMGUI) && SDL_VERSION_ATLEAST(2, 0, 0)
+void *OpenGLSdlGraphicsManager::getImGuiTexture(const Graphics::Surface &image, const byte *palette, int palCount) {
+	// Create a OpenGL texture identifier
+	GLuint image_texture;
+	glGenTextures(1, &image_texture);
+	glBindTexture(GL_TEXTURE_2D, image_texture);
+
+	// Setup filtering parameters for display
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); // This is required on WebGL for non power-of-two textures
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // Same
+
+	// Upload pixels into texture
+	Graphics::Surface *s = image.convertTo(Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 8, 16, 0), palette, palCount);
+	glPixelStorei(GL_UNPACK_ALIGNMENT, s->format.bytesPerPixel);
+
+	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, s->w, s->h, 0, GL_RGB, GL_UNSIGNED_BYTE, s->getPixels());
+	s->free();
+	delete s;
+	return (void *)(intptr_t)image_texture;
+}
+
+void OpenGLSdlGraphicsManager::freeImGuiTexture(void *texture) {
+	GLuint textureID = (intptr_t)texture;
+	glDeleteTextures(1, &textureID);
+}
+#endif
diff --git a/backends/graphics/openglsdl/openglsdl-graphics.h b/backends/graphics/openglsdl/openglsdl-graphics.h
index 076d574ec4c..de676764fbe 100644
--- a/backends/graphics/openglsdl/openglsdl-graphics.h
+++ b/backends/graphics/openglsdl/openglsdl-graphics.h
@@ -50,6 +50,11 @@ public:
 	void notifyVideoExpose() override;
 	void notifyResize(const int width, const int height) override;
 
+#if defined(USE_IMGUI) && SDL_VERSION_ATLEAST(2, 0, 0)
+	void *getImGuiTexture(const Graphics::Surface &image, const byte *palette, int palCount) override;
+	void freeImGuiTexture(void *texture) override;
+#endif
+
 protected:
 	bool loadVideoMode(uint requestedWidth, uint requestedHeight, const Graphics::PixelFormat &format) override;
 
diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
index 836c20aadea..6290a848545 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
@@ -2977,6 +2977,32 @@ int SurfaceSdlGraphicsManager::SDL_SetColorKey(SDL_Surface *surface, Uint32 flag
 	return ::SDL_SetColorKey(surface, flag ? SDL_TRUE : SDL_FALSE, key) ? -1 : 0;
 }
 
+#if defined(USE_IMGUI) && defined(USE_IMGUI_SDLRENDERER2)
+void *SurfaceSdlGraphicsManager::getImGuiTexture(const Graphics::Surface &image, const byte *palette, int palCount) {
+
+	// Upload pixels into texture
+	SDL_Texture *texture = SDL_CreateTexture(_renderer, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STATIC, image.w, image.h);
+	if (texture == nullptr) {
+		error("getImGuiTexture: errror creating tetxure: %s", SDL_GetError());
+		return nullptr;
+	}
+
+	Graphics::Surface *s = image.convertTo(Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0), palette, palCount);
+	SDL_UpdateTexture(texture, nullptr, s->getPixels(), s->pitch);
+	SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
+	SDL_SetTextureScaleMode(texture, SDL_ScaleModeLinear);
+
+	s->free();
+	delete s;
+
+	return (void *)texture;
+}
+
+void SurfaceSdlGraphicsManager::freeImGuiTexture(void *texture) {
+	SDL_DestroyTexture((SDL_Texture *) texture);
+}
+#endif // defined(USE_IMGUI) && defined(USE_IMGUI_SDLRENDERER2)
+
 #endif // SDL_VERSION_ATLEAST(2, 0, 0)
 
 #endif
diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.h b/backends/graphics/surfacesdl/surfacesdl-graphics.h
index 58cc9fda99a..87abc4f7603 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.h
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.h
@@ -129,6 +129,11 @@ public:
 	void notifyVideoExpose() override;
 	void notifyResize(const int width, const int height) override;
 
+#if defined(USE_IMGUI) && defined(USE_IMGUI_SDLRENDERER2)
+	void *getImGuiTexture(const Graphics::Surface &image, const byte *palette, int palCount) override;
+	void freeImGuiTexture(void *texture) override;
+#endif
+
 protected:
 #ifdef USE_OSD
 	/** Surface containing the OSD message */
diff --git a/backends/graphics3d/openglsdl/openglsdl-graphics3d.cpp b/backends/graphics3d/openglsdl/openglsdl-graphics3d.cpp
index 69630e92dbf..eb3364c8f12 100644
--- a/backends/graphics3d/openglsdl/openglsdl-graphics3d.cpp
+++ b/backends/graphics3d/openglsdl/openglsdl-graphics3d.cpp
@@ -867,4 +867,33 @@ bool OpenGLSdlGraphics3dManager::saveScreenshot(const Common::Path &filename) co
 #endif
 }
 
+#if defined(USE_IMGUI) && SDL_VERSION_ATLEAST(2, 0, 0)
+void *OpenGLSdlGraphics3dManager::getImGuiTexture(const Graphics::Surface &image, const byte *palette, int palCount) {
+	// Create a OpenGL texture identifier
+	GLuint image_texture;
+	glGenTextures(1, &image_texture);
+	glBindTexture(GL_TEXTURE_2D, image_texture);
+
+	// Setup filtering parameters for display
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); // This is required on WebGL for non power-of-two textures
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // Same
+
+	// Upload pixels into texture
+	Graphics::Surface *s = image.convertTo(Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 8, 16, 0));
+	glPixelStorei(GL_UNPACK_ALIGNMENT, s->format.bytesPerPixel);
+
+	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, s->w, s->h, 0, GL_RGB, GL_UNSIGNED_BYTE, s->getPixels());
+	s->free();
+	delete s;
+	return (void *)(intptr_t)image_texture;
+}
+
+void OpenGLSdlGraphics3dManager::freeImGuiTexture(void *texture) {
+	GLuint textureID = (intptr_t)texture;
+	glDeleteTextures(1, &textureID);
+}
+#endif
+
 #endif
diff --git a/backends/graphics3d/openglsdl/openglsdl-graphics3d.h b/backends/graphics3d/openglsdl/openglsdl-graphics3d.h
index 7c633fbef75..d71df8b39ac 100644
--- a/backends/graphics3d/openglsdl/openglsdl-graphics3d.h
+++ b/backends/graphics3d/openglsdl/openglsdl-graphics3d.h
@@ -115,6 +115,11 @@ public:
 
 	void showSystemMouseCursor(bool visible) override;
 
+#if defined(USE_IMGUI) && SDL_VERSION_ATLEAST(2, 0, 0)
+	void *getImGuiTexture(const Graphics::Surface &image, const byte *palette, int palCount) override;
+	void freeImGuiTexture(void *texture) override;
+#endif
+
 protected:
 #if SDL_VERSION_ATLEAST(2, 0, 0)
 	int _glContextProfileMask, _glContextMajor, _glContextMinor;


Commit: 930390450fec005d3ff6df3c8e5b0fe272721fc2
    https://github.com/scummvm/scummvm/commit/930390450fec005d3ff6df3c8e5b0fe272721fc2
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2024-09-29T17:04:03+02:00

Commit Message:
DIRECTOR: Use Common API to create ImGui images

Changed paths:
    engines/director/debugger/debugtools.cpp


diff --git a/engines/director/debugger/debugtools.cpp b/engines/director/debugger/debugtools.cpp
index 3834562b89b..7d0843663ed 100644
--- a/engines/director/debugger/debugtools.cpp
+++ b/engines/director/debugger/debugtools.cpp
@@ -132,29 +132,6 @@ Director::Breakpoint *getBreakpoint(const Common::String &handlerName, uint16 sc
 	return nullptr;
 }
 
-static GLuint loadTextureFromSurface(Graphics::Surface *surface, const byte *palette, int palCount) {
-
-	// Create a OpenGL texture identifier
-	GLuint image_texture;
-	glGenTextures(1, &image_texture);
-	glBindTexture(GL_TEXTURE_2D, image_texture);
-
-	// Setup filtering parameters for display
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); // This is required on WebGL for non power-of-two textures
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // Same
-
-	// Upload pixels into texture
-	Graphics::Surface *s = surface->convertTo(Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 8, 16, 0), palette, palCount);
-	glPixelStorei(GL_UNPACK_ALIGNMENT, s->format.bytesPerPixel);
-
-	GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, s->w, s->h, 0, GL_RGB, GL_UNSIGNED_BYTE, s->getPixels()));
-	s->free();
-	delete s;
-	return image_texture;
-}
-
 ImGuiImage getImageID(CastMember *castMember) {
 	if (castMember->_type != CastType::kCastBitmap)
 		return {};
@@ -172,7 +149,7 @@ ImGuiImage getImageID(CastMember *castMember) {
 	if (!pic)
 		return {};
 
-	ImTextureID textureID = (ImTextureID)(intptr_t)loadTextureFromSurface(&pic->_surface, pic->_palette, pic->_paletteColors);
+	ImTextureID textureID = g_system->getImGuiTexture(pic->_surface, pic->_palette, pic->_paletteColors);
 	_state->_cast._textures[bmp] = {textureID, pic->_surface.w, pic->_surface.h};
 	return _state->_cast._textures[bmp];
 }


Commit: af8ce0e254be9f351e3a5f70a53ef3a54b3c2a43
    https://github.com/scummvm/scummvm/commit/af8ce0e254be9f351e3a5f70a53ef3a54b3c2a43
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2024-09-29T17:04:03+02:00

Commit Message:
QDENGINE: Use Common API to create ImGui images

Changed paths:
    engines/qdengine/debugger/debugtools.cpp


diff --git a/engines/qdengine/debugger/debugtools.cpp b/engines/qdengine/debugger/debugtools.cpp
index 1b239958397..818689b76af 100644
--- a/engines/qdengine/debugger/debugtools.cpp
+++ b/engines/qdengine/debugger/debugtools.cpp
@@ -50,28 +50,6 @@ const int TILES_ID = -1337;
 
 ImGuiState *_state = nullptr;
 
-static GLuint loadTextureFromSurface(Graphics::Surface *surface) {
-	// Create a OpenGL texture identifier
-	GLuint image_texture;
-	glGenTextures(1, &image_texture);
-	glBindTexture(GL_TEXTURE_2D, image_texture);
-
-	// Setup filtering parameters for display
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); // This is required on WebGL for non power-of-two textures
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // Same
-
-	// Upload pixels into texture
-	Graphics::Surface *s = surface->convertTo(Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 8, 16, 0));
-	glPixelStorei(GL_UNPACK_ALIGNMENT, s->format.bytesPerPixel);
-
-	GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, s->w, s->h, 0, GL_RGB, GL_UNSIGNED_BYTE, s->getPixels()));
-	s->free();
-	delete s;
-	return image_texture;
-}
-
 ImGuiImage getImageID(Common::Path filename, int frameNum) {
 	Common::String key = Common::String::format("%s:%d", filename.toString().c_str(), frameNum);
 
@@ -144,7 +122,7 @@ ImGuiImage getImageID(Common::Path filename, int frameNum) {
 	}
 
 	if (surface)
-		_state->_frames[key] = { (ImTextureID)(intptr_t)loadTextureFromSurface(surface->surfacePtr()), sx, sy };
+		_state->_frames[key] = { (ImTextureID)g_system->getImGuiTexture(*surface->surfacePtr()), sx, sy };
 
 	delete surface;
 


Commit: 2813582f6b4d7cdef62ebe89508f4a09199684ed
    https://github.com/scummvm/scummvm/commit/2813582f6b4d7cdef62ebe89508f4a09199684ed
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2024-09-29T17:04:03+02:00

Commit Message:
BACKENDS: SDL: Remove superfluous version checks

The code is already guarded by outer checks.

Changed paths:
    backends/graphics/surfacesdl/surfacesdl-graphics.cpp


diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
index 6290a848545..49d0f1b5e85 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
@@ -2925,7 +2925,7 @@ void SurfaceSdlGraphicsManager::SDL_UpdateRects(SDL_Surface *screen, int numrect
 	Common::Rect &drawRect = (_overlayVisible) ? _overlayDrawRect : _gameDrawRect;
 	viewport.x = drawRect.left;
 	viewport.y = drawRect.top;
-#if SDL_VERSION_ATLEAST(2, 0, 0)
+
 	int rotation = getRotationMode();
 	int rotangle = 0;
 	if (rotation == Common::kRotation90 || rotation == Common::kRotation270) {
@@ -2934,16 +2934,15 @@ void SurfaceSdlGraphicsManager::SDL_UpdateRects(SDL_Surface *screen, int numrect
 		viewport.y = drawRect.left + delta;
 	}
 	rotangle = rotation;
-#endif
+
 	viewport.w = drawRect.width();
 	viewport.h = drawRect.height();
 
 	SDL_RenderClear(_renderer);
-#if SDL_VERSION_ATLEAST(2, 0, 0)
+
 	if (rotangle != 0)
 		SDL_RenderCopyEx(_renderer, _screenTexture, nullptr, &viewport, rotangle, nullptr, SDL_FLIP_NONE);
 	else
-#endif
 		SDL_RenderCopy(_renderer, _screenTexture, nullptr, &viewport);
 }
 


Commit: 1d2d08169066947f61f7abf97ca01835296f4caf
    https://github.com/scummvm/scummvm/commit/1d2d08169066947f61f7abf97ca01835296f4caf
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2024-09-29T17:04:03+02:00

Commit Message:
CREATE_PROJECT: Enable ImGui SDL Renderer support

Changed paths:
    devtools/create_project/create_project.cpp


diff --git a/devtools/create_project/create_project.cpp b/devtools/create_project/create_project.cpp
index 0e064b6016a..63447239404 100644
--- a/devtools/create_project/create_project.cpp
+++ b/devtools/create_project/create_project.cpp
@@ -475,6 +475,12 @@ int main(int argc, char *argv[]) {
 		setup.defines.push_back("USE_GLAD");
 	}
 
+	// HACK: Add IMGUI SDL Renderer support
+	// This needs SDL 2.0.18+
+	if (getFeatureBuildState("imgui", setup.features)) {
+		setup.defines.push_back("USE_IMGUI_SDLRENDERER2");
+	}
+
 	// List of global warnings and map of project-specific warnings
 	// FIXME: As shown below these two structures have different behavior for
 	// Code::Blocks and MSVC. In Code::Blocks this is used to enable *and*




More information about the Scummvm-git-logs mailing list