Giter Site home page Giter Site logo

Comments (2)

hippyau avatar hippyau commented on June 2, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.