|
| 1 | +// dear imgui: standalone example application for Android + SDL3 + OpenGLES |
| 2 | +// If you are new to dear imgui, see examples/README.txt and documentation at the top of imgui.cpp. |
| 3 | +// (SDL is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.) |
| 4 | + |
| 5 | +// **THIS CODE USES MODERN OPENGL (SHADERS, VBO, VAO, etc.)** |
| 6 | +// **Prefer using the code in the example_sdl_opengl3/ folder** |
| 7 | +// See imgui_impl_sdl.cpp for details. |
| 8 | + |
| 9 | +// SDL/test/testgles.c was used as a reference guide |
| 10 | + |
| 11 | +#include <string.h> |
| 12 | +#include <stdlib.h> |
| 13 | + |
| 14 | +#include <SDL3/SDL_main.h> |
| 15 | +#include <SDL3/SDL_test_common.h> |
| 16 | + |
| 17 | +#include <EGL/egl.h> |
| 18 | +#include <GLES3/gl3.h> |
| 19 | +#include <SDL3/SDL_opengles.h> |
| 20 | + |
| 21 | +#include "imgui.h" |
| 22 | +#include "imgui_impl_opengl3.h" |
| 23 | +#include "imgui_impl_sdl3.h" |
| 24 | + |
| 25 | + |
| 26 | +// Must use conventional parameters here |
| 27 | +// or else there will be an undefined reference to SDL_main |
| 28 | +int main(int argc, char** argv) |
| 29 | +{ |
| 30 | + // Setup SDL |
| 31 | + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) != 0) |
| 32 | + { |
| 33 | + SDL_LogError(SDL_LOG_CATEGORY_ERROR, "Error: %s\n", SDL_GetError()); |
| 34 | + return EXIT_FAILURE; |
| 35 | + } |
| 36 | + |
| 37 | + SDL_LogSetAllPriority(SDL_LOG_PRIORITY_VERBOSE); |
| 38 | + |
| 39 | + // Setup window |
| 40 | + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); |
| 41 | + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); |
| 42 | + SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); |
| 43 | + SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32); |
| 44 | + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); |
| 45 | + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); |
| 46 | + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); |
| 47 | + SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); |
| 48 | + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); |
| 49 | + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); |
| 50 | + SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0); |
| 51 | + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); |
| 52 | + |
| 53 | + // Create window with graphics context |
| 54 | + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); |
| 55 | + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); |
| 56 | + SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); |
| 57 | + Uint32 window_flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN; |
| 58 | + SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL3+OpenGL3 example", 1280, 720, window_flags); |
| 59 | + if (window == 0) |
| 60 | + { |
| 61 | + SDL_LogError(SDL_LOG_CATEGORY_ERROR, "Failed to create the SDL Window: %s\n", SDL_GetError()); |
| 62 | + SDL_Quit(); |
| 63 | + return EXIT_FAILURE; |
| 64 | + } |
| 65 | + SDL_GLContext gl_context = SDL_GL_CreateContext(window); |
| 66 | + SDL_GL_SetSwapInterval(1); // Enable vsync |
| 67 | + |
| 68 | + // Query OpenGL device information |
| 69 | + const GLubyte* renderer = glGetString(GL_RENDERER); |
| 70 | + const GLubyte* vendor = glGetString(GL_VENDOR); |
| 71 | + const GLubyte* version = glGetString(GL_VERSION); |
| 72 | + const GLubyte* glslVersion = glGetString(GL_SHADING_LANGUAGE_VERSION); |
| 73 | + const char * new_line = "\n-------------------------------------------------------------\n"; |
| 74 | + SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "%s%s%s%s%s%s%s%s%s%s", |
| 75 | + new_line, |
| 76 | + "GL Vendor : ", vendor, |
| 77 | + "\nGL GLRenderer : ", renderer, |
| 78 | + "\nGL Version : ", version, |
| 79 | + "\nGLSL Version : ", glslVersion, |
| 80 | + new_line); |
| 81 | + |
| 82 | + // Setup Dear ImGui context |
| 83 | + IMGUI_CHECKVERSION(); |
| 84 | + ImGui::CreateContext(); |
| 85 | + ImGuiIO& io = ImGui::GetIO(); |
| 86 | + // Android issue: NoMouseCursorChange config prevents SDL_SetCursor call |
| 87 | + // in imgui_impl_sdl.cpp; SDL_SetCursor causes invalid operation error spam |
| 88 | + io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange | ImGuiConfigFlags_NavEnableKeyboard; |
| 89 | + io.WantSaveIniSettings = false; |
| 90 | + // Setup Platform/Renderer bindings |
| 91 | + ImGui_ImplSDL3_InitForOpenGL(window, gl_context); |
| 92 | + ImGui_ImplOpenGL3_Init(); |
| 93 | + |
| 94 | + // Setup Style |
| 95 | + ImGui::StyleColorsDark(); |
| 96 | + //ImGui::StyleColorsClassic(); |
| 97 | + |
| 98 | + bool show_demo_window = true; |
| 99 | + bool show_another_window = false; |
| 100 | + ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); |
| 101 | + |
| 102 | + // This is necessary to reposition the demo window |
| 103 | + ImGui_ImplOpenGL3_NewFrame(); |
| 104 | + ImGui_ImplSDL3_NewFrame(); |
| 105 | + ImGui::NewFrame(); |
| 106 | + ImGui::SetNextWindowSize(ImVec2(io.DisplaySize.x * 0.80, io.DisplaySize.y * 0.45), ImGuiCond_FirstUseEver); |
| 107 | + ImGui::SetNextWindowPos(ImVec2(io.DisplaySize.x * 0.05, io.DisplaySize.y * 0.30), ImGuiCond_FirstUseEver); |
| 108 | + ImGui::Begin("ImGui Demo"); |
| 109 | + ImGui::End(); |
| 110 | + ImGui::EndFrame(); |
| 111 | + |
| 112 | + // Main loop |
| 113 | + bool done = false; |
| 114 | + while (!done) |
| 115 | + { |
| 116 | + // Poll and handle events (inputs, window resize, etc.) |
| 117 | + // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. |
| 118 | + // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. |
| 119 | + // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. |
| 120 | + // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. |
| 121 | + SDL_Event event; |
| 122 | + while (SDL_PollEvent(&event)) |
| 123 | + { |
| 124 | + ImGui_ImplSDL3_ProcessEvent(&event); |
| 125 | + |
| 126 | + if (event.type == SDL_EVENT_QUIT) |
| 127 | + done = true; |
| 128 | + } |
| 129 | + |
| 130 | + // Start the Dear ImGui frame |
| 131 | + ImGui_ImplOpenGL3_NewFrame(); |
| 132 | + ImGui_ImplSDL3_NewFrame(); |
| 133 | + ImGui::NewFrame(); |
| 134 | + |
| 135 | + // 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!). |
| 136 | + if (show_demo_window) |
| 137 | + ImGui::ShowDemoWindow(&show_demo_window); |
| 138 | + |
| 139 | + // 2. Show a simple window that we create ourselves. We use a Begin/End pair to created a named window. |
| 140 | + { |
| 141 | + static float f = 0.0f; |
| 142 | + static int counter = 0; |
| 143 | + |
| 144 | + ImGui::SetNextWindowPos(ImVec2(io.DisplaySize.x * 0.05, io.DisplaySize.y * 0.05), ImGuiCond_Once); |
| 145 | + |
| 146 | + ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it. |
| 147 | + |
| 148 | + ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too) |
| 149 | + ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state |
| 150 | + ImGui::Checkbox("Another Window", &show_another_window); |
| 151 | + |
| 152 | + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f |
| 153 | + ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color |
| 154 | + |
| 155 | + if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated) |
| 156 | + counter++; |
| 157 | + ImGui::SameLine(); |
| 158 | + ImGui::Text("counter = %d", counter); |
| 159 | + |
| 160 | + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); |
| 161 | + ImGui::End(); |
| 162 | + } |
| 163 | + |
| 164 | + // 3. Show another simple window. |
| 165 | + if (show_another_window) |
| 166 | + { |
| 167 | + ImGui::SetNextWindowSize(ImVec2(200, 100), ImGuiCond_FirstUseEver); |
| 168 | + 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) |
| 169 | + ImGui::Text("Hello from another window!"); |
| 170 | + if (ImGui::Button("Close Me")) |
| 171 | + show_another_window = false; |
| 172 | + ImGui::End(); |
| 173 | + } |
| 174 | + |
| 175 | + glViewport(0, 0, (int) io.DisplaySize.x, (int) io.DisplaySize.y); |
| 176 | + glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); |
| 177 | + glClear(GL_COLOR_BUFFER_BIT); |
| 178 | + |
| 179 | + // Rendering |
| 180 | + ImGui::Render(); |
| 181 | + |
| 182 | + //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context where shaders may be bound |
| 183 | + ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); |
| 184 | + SDL_GL_SwapWindow(window); |
| 185 | + } |
| 186 | + |
| 187 | + // Cleanup |
| 188 | + ImGui_ImplOpenGL3_Shutdown(); |
| 189 | + ImGui_ImplSDL3_Shutdown(); |
| 190 | + ImGui::DestroyContext(); |
| 191 | + |
| 192 | + SDL_GL_DeleteContext(gl_context); |
| 193 | + SDL_DestroyWindow(window); |
| 194 | + SDL_Quit(); |
| 195 | + |
| 196 | + return EXIT_SUCCESS; |
| 197 | +} // main |
0 commit comments