반응형

SDL에서 ImGui를 이용해 간단한 그래픽 유저 인터페이스를 구현해 보자.

 

비주얼 스튜디오에서 C++ 프로젝트를 만들고 소스파일(Source.cpp)을 추가한다.

SDL을 사용하기 위한 Include, Library 디렉토리 설정 등을 진행하고 ..\imgui-1.90.1\backends 에서 imgui_impl_sdl2.*, imgui_impl_sdlrenderer2.* 파일들을 복사한다. 나머지 파일들은 ..\imgui-1.90.1 에서 복사한다.

 

필터(ImGui)를 추가하고 복사한 파일들을 프로젝트에 추가한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include <iostream>
#include "SDL.h"
#include "imgui.h"
#include "imgui_impl_sdl2.h"
#include "imgui_impl_sdlrenderer2.h"
 
int main(int argc, char* argv[]) {
    SDL_Init(SDL_INIT_VIDEO);
    SDL_Window* window = SDL_CreateWindow("SDL Test", SDL_WINDOWPOS_UNDEFINED,
        SDL_WINDOWPOS_UNDEFINED, 640480, SDL_WINDOW_RESIZABLE);
    SDL_Renderer* renderer = SDL_CreateRenderer(window, -10);
 
    // Setup Dear ImGui context
    IMGUI_CHECKVERSION();
    ImGui::CreateContext();
    ImGuiIO& io = ImGui::GetIO();
    io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
    //io.Fonts->AddFontFromFileTTF("newfont.ttf", 20);
    // If no fonts are loaded, dear imgui will use the default font.
 
    // Setup Dear ImGui style    
    ImGui::StyleColorsLight();
    //ImGui::StyleColorsDark();
 
    // Setup Platform/Renderer backends
    ImGui_ImplSDL2_InitForSDLRenderer(window, renderer);
    ImGui_ImplSDLRenderer2_Init(renderer);
 
    // Our state
    bool show_demo_window = true;
    bool show_another_window = false;
    ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
 
    SDL_Event event;
    bool quit = false;
 
    // Poll and handle events (inputs, window resize, etc.)
    // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to
    // use your inputs.
    // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or
    // clear/overwrite your copy of the mouse data.
    // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application,
    // or clear/overwrite your copy of the keyboard data.
    // Generally you may always pass all inputs to dear imgui, and hide them from your application based on
    // those two flags.
    while (!quit) {
        while (SDL_PollEvent(&event)) {
            ImGui_ImplSDL2_ProcessEvent(&event);
            switch (event.type) {
            case SDL_QUIT:
                quit = true;
                break;
            case SDL_KEYDOWN:
                printf("Key pressed: %s\n", SDL_GetKeyName(event.key.keysym.sym));
                if (event.key.keysym.sym == SDLK_ESCAPE)
                    quit = true;
                break;
            default:
                break;
            }
        }
 
        // Start the Dear ImGui frame
        ImGui_ImplSDLRenderer2_NewFrame();
        ImGui_ImplSDL2_NewFrame();
        ImGui::NewFrame();
 
        // Show a simple window that we create ourselves. We use a Begin/End pair to create a named window.
        {
            static float f = 0.0f;
            static int counter = 0;
 
            ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it.
 
            ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too)
            ImGui::Checkbox("Demo Window"&show_demo_window); // Edit bools storing our window open/close state
            ImGui::Checkbox("Another Window"&show_another_window);
 
            ImGui::SliderFloat("float"&f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f
            ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color
 
            if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated)
                counter++;
            ImGui::SameLine();
            ImGui::Text("counter = %d", counter);
 
            ImGui::Text("Application average %.3f ms/frame (%.1f FPS)"1000.0f / io.Framerate, io.Framerate);
            ImGui::End();
        }
 
        // Show another simple window.
        if (show_another_window)
        {
            ImGui::Begin("Another Window"&show_another_window);
            // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked)
            ImGui::Text("Hello from another window!");
            if (ImGui::Button("Close Me"))
                show_another_window = false;
            ImGui::End();
        }
 
        // Show only a button at (0, 0).
        {
            ImGui::SetNextWindowPos(ImVec2(00), ImGuiCond_Always);
            ImGui::Begin("No Name"NULL, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoDecoration
                | ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoSavedSettings);
            if (ImGui::Button("MyButton", ImVec2(200100))) {
                std::cout << "Clicked" << std::endl;
            }
            ImGui::End();
        }
 
        // Rendering
        ImGui::Render();
        SDL_SetRenderDrawColor(renderer, 255255255, SDL_ALPHA_OPAQUE);
        SDL_RenderClear(renderer);
        ImGui_ImplSDLRenderer2_RenderDrawData(ImGui::GetDrawData());
        SDL_RenderPresent(renderer);
    }
 
    // Cleanup
    ImGui_ImplSDLRenderer2_Shutdown();
    ImGui_ImplSDL2_Shutdown();
    ImGui::DestroyContext();
 
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();
 
    return 0;
}
 

 

코드를 입력하고 빌드한다.

 

실행하면 윈도우에 GUI가 출력된다.

 

ImGui의 스타일(테마)은 아래와 같이 개별적으로도 지정할 수 있다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// Setup Dear ImGui style
//ImGui::StyleColorsLight();
//ImGui::StyleColorsDark();
ImGuiStyle& style = ImGui::GetStyle();
 
style.Colors[ImGuiCol_Text] = ImVec4(0.86f, 0.93f, 0.89f, 0.78f);
style.Colors[ImGuiCol_TextDisabled] = ImVec4(0.86f, 0.93f, 0.89f, 0.28f);
style.Colors[ImGuiCol_WindowBg] = ImVec4(0.13f, 0.14f, 0.17f, 1.00f);
style.Colors[ImGuiCol_Border] = ImVec4(0.31f, 0.31f, 1.00f, 0.00f);
style.Colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
style.Colors[ImGuiCol_FrameBg] = ImVec4(0.20f, 0.22f, 0.27f, 1.00f);
style.Colors[ImGuiCol_FrameBgHovered] = ImVec4(0.92f, 0.18f, 0.29f, 0.78f);
style.Colors[ImGuiCol_FrameBgActive] = ImVec4(0.92f, 0.18f, 0.29f, 1.00f);
style.Colors[ImGuiCol_TitleBg] = ImVec4(0.20f, 0.22f, 0.27f, 1.00f);
style.Colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.20f, 0.22f, 0.27f, 0.75f);
style.Colors[ImGuiCol_TitleBgActive] = ImVec4(0.92f, 0.18f, 0.29f, 1.00f);
style.Colors[ImGuiCol_MenuBarBg] = ImVec4(0.20f, 0.22f, 0.27f, 0.47f);
style.Colors[ImGuiCol_ScrollbarBg] = ImVec4(0.20f, 0.22f, 0.27f, 1.00f);
style.Colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.09f, 0.15f, 0.16f, 1.00f);
style.Colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.92f, 0.18f, 0.29f, 0.78f);
style.Colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.92f, 0.18f, 0.29f, 1.00f);
style.Colors[ImGuiCol_CheckMark] = ImVec4(0.71f, 0.22f, 0.27f, 1.00f);
style.Colors[ImGuiCol_SliderGrab] = ImVec4(0.47f, 0.77f, 0.83f, 0.14f);
style.Colors[ImGuiCol_SliderGrabActive] = ImVec4(0.92f, 0.18f, 0.29f, 1.00f);
style.Colors[ImGuiCol_Button] = ImVec4(0.92f, 0.18f, 0.29f, 0.70f);
style.Colors[ImGuiCol_ButtonHovered] = ImVec4(0.92f, 0.18f, 0.29f, 0.86f);
style.Colors[ImGuiCol_ButtonActive] = ImVec4(0.92f, 0.18f, 0.29f, 1.00f);
style.Colors[ImGuiCol_Header] = ImVec4(0.92f, 0.18f, 0.29f, 0.76f);
style.Colors[ImGuiCol_HeaderHovered] = ImVec4(0.92f, 0.18f, 0.29f, 0.86f);
style.Colors[ImGuiCol_HeaderActive] = ImVec4(0.92f, 0.18f, 0.29f, 1.00f);
style.Colors[ImGuiCol_Separator] = ImVec4(0.14f, 0.16f, 0.19f, 1.00f);
style.Colors[ImGuiCol_SeparatorHovered] = ImVec4(0.92f, 0.18f, 0.29f, 0.78f);
style.Colors[ImGuiCol_SeparatorActive] = ImVec4(0.92f, 0.18f, 0.29f, 1.00f);
style.Colors[ImGuiCol_ResizeGrip] = ImVec4(0.47f, 0.77f, 0.83f, 0.04f);
style.Colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.92f, 0.18f, 0.29f, 0.78f);
style.Colors[ImGuiCol_ResizeGripActive] = ImVec4(0.92f, 0.18f, 0.29f, 1.00f);
style.Colors[ImGuiCol_PlotLines] = ImVec4(0.86f, 0.93f, 0.89f, 0.63f);
style.Colors[ImGuiCol_PlotLinesHovered] = ImVec4(0.92f, 0.18f, 0.29f, 1.00f);
style.Colors[ImGuiCol_PlotHistogram] = ImVec4(0.86f, 0.93f, 0.89f, 0.63f);
style.Colors[ImGuiCol_PlotHistogramHovered] = ImVec4(0.92f, 0.18f, 0.29f, 1.00f);
style.Colors[ImGuiCol_TextSelectedBg] = ImVec4(0.92f, 0.18f, 0.29f, 0.43f);
style.Colors[ImGuiCol_PopupBg] = ImVec4(0.20f, 0.22f, 0.27f, 0.9f);
style.Colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.20f, 0.22f, 0.27f, 0.73f);
 

 

 

※ 참고

Dear ImGui는 API Reference가 없다. Python 래퍼 pyimgui 를 참고하자.

pyimgui

 

반응형
Posted by J-sean
:
반응형

SDL 에는 GUI 기능이 없어 다른 라이브러리를 사용해야 한다. 많은 GUI 라이브러리가 있는데 ImGui 를 확인해 보자.

아래 링크에서 ImGui를 다운로드 한다.

Dear ImGui

 

압축을 풀고 examples - imgui_examples.sln 파일을 실행한다.

 

비주얼 스튜디오 버전이 다르면 프로젝트를 업그레이드 한다.

 

sdlrenderer2를 startup 프로젝트로 설정한다.

 

main.cpp 파일을 확인하자.

 

 

SDL 관련 명령에서 에러가 발생한다.

 

Project Property Pages - Additional Include Directories 에 정확한 SDL Include 디렉토리를 지정한다.

 

Project Property Pages - Additional Library Directories 에 정확한 SDL Library 디렉토리를 지정한다.

 

프로젝트를 빌드한다.

 

실행하면 윈도우에 GUI가 출력된다. (SDL2.dll 파일이 없다는 에러가 발생하면 복사해 넣어준다)

 

 

이번엔 내가 직접 만든 프로젝트에서 ImGui 예제를 실행해 보자.

 

ImGui 라이브러리 디렉토리는 위 그림과 같이 구성 되어 있다.

 

비주얼 스튜디오 프로젝트를 만들고 소스 파일 하나만 추가한다.

 

SDL2.dll 파일을 찾을 수 있도록 환경을 설정한다.

 

SDL과 ImGui에서 사용하는 Include 디렉토리를 설정한다.

 

 

SDL에서 사용하는 Library 디렉토리를 설정한다.

 

SDL에서 사용하는 라이브러리 파일을 설정한다.

 

ImGui, ImGui-Backend 필터를 만들고 ImGui SDL 예제에서 사용하는 파일을 추가한다.

 

처음에 만들어둔 소스 파일에 예제 소스파일(..\imgui-1.90.1\examples\example_sdl2_sdlrenderer2\main.cpp) 내용을 복사하고 빌드한다.

 

 

실행하면 운도우에 GUI가 출력된다.

 

※ 참고

Getting Started

 

반응형
Posted by J-sean
: