Comments (2)
io.AddMousePosEvent((mouseX - viewportX) / scale, (mouseY - viewportY) / scale);
Adding a Mouse Pos Event may conflicts with the one added by the backend.
Ideally you would parse the event list g.InputEventsQueue[]
, by reading old Size, calling ImGui_ImplSDL2_ProcessEvent()+ImGui_ImplSDL2_NewFrame(), reading new Size, and modifying the events.
It has been a recurrent topic that we should eventually allow backend to "transform" inputs and also work within a subsection of the main host window. Some forms of DPI scaling (for Mac) may be facilitated by it. And also see stuff like #6942, #6714, #6064, #3972 (yours!), #3814, this is why those issues are kept open.
In addition it is possible that the ideal solution for #2176 will be that we offset all viewports and our coordinate system to ensure everything use positive coordinates.
from imgui.
Okay, I worked it out.... had to very slightly modify the backend
example-2024-05-16_16.49.55.mp4
Backend
Modify static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_width, int fb_height, GLuint vertex_array_object)
:
//GL_CALL(glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height)); // <------ Commented out by me
Modify void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data, ImVec2 offset)
:
(note added ImVec2 'offset' argument passed from example)
// Apply scissor/clipping rectangle (Y is inverted in OpenGL)
GL_CALL(glScissor((int)clip_min.x+offset.x, (int)((float)fb_height - clip_max.y+offset.y), (int)(clip_max.x - clip_min.x), (int)(clip_max.y - clip_min.y)));
Example
#include "imgui.h"
#include "imgui_impl_sdl2.h"
#include "imgui_impl_opengl3.h"
#include <stdio.h>
#include <SDL.h>
#include <SDL_opengl.h>
int main(int, char**)
{
// Setup SDL
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0)
{
printf("Error: %s\n", SDL_GetError());
return -1;
}
// Decide GL+GLSL versions
#if defined(IMGUI_IMPL_OPENGL_ES2)
// GL ES 2.0 + GLSL 100
const char* glsl_version = "#version 100";
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
#elif defined(__APPLE__)
// GL 3.2 Core + GLSL 150
const char* glsl_version = "#version 150";
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG); // Always required on Mac
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
#else
// GL 3.0 + GLSL 130
const char* glsl_version = "#version 130";
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
#endif
// Create window with graphics context
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+OpenGL3 example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1920, 1080, window_flags);
if (window == nullptr)
{
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
return -1;
}
SDL_GLContext gl_context = SDL_GL_CreateContext(window);
SDL_GL_MakeCurrent(window, gl_context);
SDL_GL_SetSwapInterval(1); // Enable vsync
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io;
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
ImGui::StyleColorsDark();
ImGui_ImplSDL2_InitForOpenGL(window, gl_context);
ImGui_ImplOpenGL3_Init(glsl_version);
bool show_demo_window = false;
ImVec4 clear_color = ImVec4(0.0f, 0.0f, 0.0f, 1.0f);
// Main loop
bool done = false;
while (!done)
{
SDL_Event event;
while (SDL_PollEvent(&event))
{
ImGui_ImplSDL2_ProcessEvent(&event);
if (event.type == SDL_QUIT || (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE && event.window.windowID == SDL_GetWindowID(window)))
done = true;
}
// --- Start new backend frame
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplSDL2_NewFrame();
// Calculations to fit logical display into the current window
// while maintaining aspect ratio and centering the display
constexpr float logicalDisplayX = 1920.0f;
constexpr float logicalDisplayY = 1080.0f;
int windowWidth, windowHeight;
SDL_GetWindowSize(window, &windowWidth, &windowHeight);
float scaleX = windowWidth / logicalDisplayX;
float scaleY = windowHeight / logicalDisplayY;
float scale = scaleX < scaleY ? scaleX : scaleY;
int viewportWidth = (int)(logicalDisplayX * scale);
int viewportHeight = (int)(logicalDisplayY * scale);
int viewportX = (windowWidth - viewportWidth) / 2;
int viewportY = (windowHeight - viewportHeight) / 2;
io.DisplaySize = ImVec2(logicalDisplayX, logicalDisplayY);
io.DisplayFramebufferScale = ImVec2(scale, scale);
// scale the mouse position
int mouseX, mouseY;
SDL_GetMouseState(&mouseX, &mouseY);
io.AddMousePosEvent((mouseX - viewportX) / scale, (mouseY - viewportY) / scale);
// ---- Start the Dear ImGui frame
ImGui::NewFrame();
// make a window that represents the "desktop" space, must always be at the back
ImGui::SetNextWindowPos(ImVec2(0, 0));
ImGui::SetNextWindowSize(ImVec2(logicalDisplayX, logicalDisplayY));
ImGui::PushStyleColor(ImGuiCol_WindowBg, IM_COL32(115, 140, 153, 255));
ImGui::Begin("Desktop Space", nullptr, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoBringToFrontOnFocus);
ImGui::End();
ImGui::PopStyleColor();
ImVec2 center = ImGui::GetMainViewport()->GetCenter();
ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
ImGui::Begin("Window Scaling Debug",nullptr,ImGuiWindowFlags_AlwaysAutoResize);
ImGui::Text("io.DisplaySize: %d x %d", (int)io.DisplaySize.x, (int)io.DisplaySize.y);
ImGui::Text("Window size: %d x %d", windowWidth, windowHeight);
ImGui::Text("Viewport size: %d x %d", viewportWidth, viewportHeight);
ImGui::Text("Viewport position: %d x %d", viewportX, viewportY);
ImGui::Text("Scale: %.2f", scale);
ImGui::Text("Mouse: %d x %d", (int)io.MousePos.x, (int)io.MousePos.y);
ImGui::Text("SDL Mouse: %d x %d", mouseX, mouseY);
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / io.Framerate, io.Framerate);
ImGui::Checkbox("Demo Window", &show_demo_window);
ImGui::End();
// make a window in each corner, marking out the 1920x1080 display space
for (int i = 0; i < 4; i++)
{
ImGui::SetNextWindowPos(ImVec2(i % 2 ? 0 : logicalDisplayX - 320, i / 2 ? 0 : logicalDisplayY - 240));
ImGui::SetNextWindowSize(ImVec2(320, 240));
char windowName[32];
sprintf(windowName, "Window %d", i);
ImGui::Begin(windowName, nullptr, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse);
ImGui::Text("Corner Window %d", i);
ImGui::End();
}
if (show_demo_window) { ImGui::ShowDemoWindow(&show_demo_window); }
ImGui::Render();
glViewport(viewportX, viewportY, viewportWidth, viewportHeight);
glClearColor(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w);
glClear(GL_COLOR_BUFFER_BIT);
// modified back end to accept the view port offsets
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData(), ImVec2(viewportX, viewportY));
SDL_GL_SwapWindow(window);
}
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplSDL2_Shutdown();
ImGui::DestroyContext();
SDL_GL_DeleteContext(gl_context);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
from imgui.
Related Issues (20)
- imgui_widgets.cpp gives 200+ errors HOT 1
- How can I size a table correctly for a given number of rows when using ImGuiTableFlags_ScrollX? HOT 4
- Image Loading Not Working
- Item-tooltip for group will disappear for a short time if the widget inside is clicked HOT 1
- Multi-viewport: window constrained to main viewport moves if it goes outside of viewport HOT 2
- Add a flag to disable Ctrl+Tab navigation HOT 1
- Renderer backend for the new SDL3 GPU API HOT 6
- Advice on implementing a visual tour for a user interface HOT 5
- Merging icon font doesn't work HOT 7
- Not all expected cells are selected when drag-selecting in an x-scrolling table
- Late availability of monitor information HOT 2
- IMGUI_DISABLE_OBSOLETE_FUNCTIONS does more than hiding obsoleted functions HOT 6
- Translating between backend keycode and ImGuiKey HOT 1
- Lack of separate ImGuiDockNodeFlags_NoDockingSplitMe flag in 1.91 HOT 2
- Question - D3D12 Texture
- Scrollbar behavior change HOT 8
- IsItemDeactivatedAfterEdit and InputTextMultiline HOT 3
- Displaying a slice of a 3D texture HOT 1
- SDL2 backend does not build on UWP HOT 4
- Latest Dawn source code breaks WGPU Backend. HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from imgui.