From 9f72e50fc2936ed777b131bb72f9c0b97791aad9 Mon Sep 17 00:00:00 2001 From: zmertens Date: Wed, 17 Jan 2024 17:42:46 -0700 Subject: [PATCH] Add setup.sh script to build android from SDL3 repo Add README --- .../DearImGuiDemo.cpp | 197 ++++++++++++++++++ .../example_android_sdl3_opengl3/README.md | 9 + examples/example_android_sdl3_opengl3/SDL | 1 + .../example_android_sdl3_opengl3/setup.sh | 17 ++ 4 files changed, 224 insertions(+) create mode 100644 examples/example_android_sdl3_opengl3/DearImGuiDemo.cpp create mode 100644 examples/example_android_sdl3_opengl3/README.md create mode 160000 examples/example_android_sdl3_opengl3/SDL create mode 100644 examples/example_android_sdl3_opengl3/setup.sh diff --git a/examples/example_android_sdl3_opengl3/DearImGuiDemo.cpp b/examples/example_android_sdl3_opengl3/DearImGuiDemo.cpp new file mode 100644 index 0000000000000..4559fc18b03ea --- /dev/null +++ b/examples/example_android_sdl3_opengl3/DearImGuiDemo.cpp @@ -0,0 +1,197 @@ +// dear imgui: standalone example application for Android + SDL3 + OpenGLES +// If you are new to dear imgui, see examples/README.txt and documentation at the top of imgui.cpp. +// (SDL is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.) + +// **THIS CODE USES MODERN OPENGL (SHADERS, VBO, VAO, etc.)** +// **Prefer using the code in the example_sdl_opengl3/ folder** +// See imgui_impl_sdl.cpp for details. + +// SDL/test/testgles.c was used as a reference guide + +#include +#include + +#include +#include + +#include +#include +#include + +#include "imgui.h" +#include "imgui_impl_opengl3.h" +#include "imgui_impl_sdl3.h" + + +// Must use conventional parameters here +// or else there will be an undefined reference to SDL_main +int main(int argc, char** argv) +{ + // Setup SDL + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) != 0) + { + SDL_LogError(SDL_LOG_CATEGORY_ERROR, "Error: %s\n", SDL_GetError()); + return EXIT_FAILURE; + } + + SDL_LogSetAllPriority(SDL_LOG_PRIORITY_VERBOSE); + + // Setup window + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); + SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32); + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); + + // 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); + Uint32 window_flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN; + SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL3+OpenGL3 example", 1280, 720, window_flags); + if (window == 0) + { + SDL_LogError(SDL_LOG_CATEGORY_ERROR, "Failed to create the SDL Window: %s\n", SDL_GetError()); + SDL_Quit(); + return EXIT_FAILURE; + } + SDL_GLContext gl_context = SDL_GL_CreateContext(window); + SDL_GL_SetSwapInterval(1); // Enable vsync + + // Query OpenGL device information + const GLubyte* renderer = glGetString(GL_RENDERER); + const GLubyte* vendor = glGetString(GL_VENDOR); + const GLubyte* version = glGetString(GL_VERSION); + const GLubyte* glslVersion = glGetString(GL_SHADING_LANGUAGE_VERSION); + const char * new_line = "\n-------------------------------------------------------------\n"; + SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "%s%s%s%s%s%s%s%s%s%s", + new_line, + "GL Vendor : ", vendor, + "\nGL GLRenderer : ", renderer, + "\nGL Version : ", version, + "\nGLSL Version : ", glslVersion, + new_line); + + // Setup Dear ImGui context + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); + // Android issue: NoMouseCursorChange config prevents SDL_SetCursor call + // in imgui_impl_sdl.cpp; SDL_SetCursor causes invalid operation error spam + io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange | ImGuiConfigFlags_NavEnableKeyboard; + io.WantSaveIniSettings = false; + // Setup Platform/Renderer bindings + ImGui_ImplSDL3_InitForOpenGL(window, gl_context); + ImGui_ImplOpenGL3_Init(); + + // Setup Style + ImGui::StyleColorsDark(); + //ImGui::StyleColorsClassic(); + + bool show_demo_window = true; + bool show_another_window = false; + ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); + + // This is necessary to reposition the demo window + ImGui_ImplOpenGL3_NewFrame(); + ImGui_ImplSDL3_NewFrame(); + ImGui::NewFrame(); + ImGui::SetNextWindowSize(ImVec2(io.DisplaySize.x * 0.80, io.DisplaySize.y * 0.45), ImGuiCond_FirstUseEver); + ImGui::SetNextWindowPos(ImVec2(io.DisplaySize.x * 0.05, io.DisplaySize.y * 0.30), ImGuiCond_FirstUseEver); + ImGui::Begin("ImGui Demo"); + ImGui::End(); + ImGui::EndFrame(); + + // Main loop + bool done = false; + while (!done) + { + // 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. + // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. + // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. + SDL_Event event; + while (SDL_PollEvent(&event)) + { + ImGui_ImplSDL3_ProcessEvent(&event); + + if (event.type == SDL_EVENT_QUIT) + done = true; + } + + // Start the Dear ImGui frame + ImGui_ImplOpenGL3_NewFrame(); + ImGui_ImplSDL3_NewFrame(); + ImGui::NewFrame(); + + // 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!). + if (show_demo_window) + ImGui::ShowDemoWindow(&show_demo_window); + + // 2. Show a simple window that we create ourselves. We use a Begin/End pair to created a named window. + { + static float f = 0.0f; + static int counter = 0; + + ImGui::SetNextWindowPos(ImVec2(io.DisplaySize.x * 0.05, io.DisplaySize.y * 0.05), ImGuiCond_Once); + + 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 / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + ImGui::End(); + } + + // 3. Show another simple window. + if (show_another_window) + { + ImGui::SetNextWindowSize(ImVec2(200, 100), ImGuiCond_FirstUseEver); + 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(); + } + + glViewport(0, 0, (int) io.DisplaySize.x, (int) io.DisplaySize.y); + glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + glClear(GL_COLOR_BUFFER_BIT); + + // Rendering + ImGui::Render(); + + //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context where shaders may be bound + ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); + SDL_GL_SwapWindow(window); + } + + // Cleanup + ImGui_ImplOpenGL3_Shutdown(); + ImGui_ImplSDL3_Shutdown(); + ImGui::DestroyContext(); + + SDL_GL_DeleteContext(gl_context); + SDL_DestroyWindow(window); + SDL_Quit(); + + return EXIT_SUCCESS; +} // main diff --git a/examples/example_android_sdl3_opengl3/README.md b/examples/example_android_sdl3_opengl3/README.md new file mode 100644 index 0000000000000..6a913f4d5d249 --- /dev/null +++ b/examples/example_android_sdl3_opengl3/README.md @@ -0,0 +1,9 @@ +# Dear ImGui Android Example + +This example runs the Dear ImGui demo app on modern Android (targeting API 33+). The `setup.sh` looks for a SDL3 submodule and then tries to run an `androidbuild.sh` script from within the SDL3 submodule. + +Set JAVA_HOME, ANDROID_HOME, and ANDROID_NDK_HOME environment variables in order to run `setup.sh`. + +After running `setup.sh` there is a generated Android Activity and Gradle files in the SDL3 submodule under the `SDL/build/` directory. + +Example Gradle build: `ANDROID_HOME=MY_SDK_PATH ANDROID_NDK_HOME=MY_NDK_PATH ./gradlew installDebug`. This should install the demo app on a connected emulator or physical device. \ No newline at end of file diff --git a/examples/example_android_sdl3_opengl3/SDL b/examples/example_android_sdl3_opengl3/SDL new file mode 160000 index 0000000000000..0d7df16812c75 --- /dev/null +++ b/examples/example_android_sdl3_opengl3/SDL @@ -0,0 +1 @@ +Subproject commit 0d7df16812c75c4a587d7d2673e3d1a5f2c2879b diff --git a/examples/example_android_sdl3_opengl3/setup.sh b/examples/example_android_sdl3_opengl3/setup.sh new file mode 100644 index 0000000000000..949422c5ee598 --- /dev/null +++ b/examples/example_android_sdl3_opengl3/setup.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +JAVA_PKG_NAME="com.example.imgui" + +SDL_DIR="SDL" +SDL_BUILD_SCRIPTS_DIR="${SDL_DIR}/build-scripts" + +if [ ! -d "${SDL_DIR}" ]; then + echo "Cloning submodules..." + git submodule update --init --recursive +fi + +ANDROID_JNI_PATH="${SDL_DIR}/build/${JAVA_PKG_NAME}/app/jni/src" + +if [ ! -d "${ANDROID_JNI_PATH}" ]; then + bash ${SDL_BUILD_SCRIPTS_DIR}/androidbuild.sh $JAVA_PKG_NAME < ../../imgui.cpp ../../imgui.h ../../imconfig.h ../../imstb_rectpack.h ../../imstb_textedit.h ../../imstb_truetype.h ../../imgui_internal.h imconfig.h ../../imgui_widgets.cpp ../../imgui_tables.cpp ../../imgui_draw.cpp ../../imgui_demo.cpp ../../backends/imgui_impl_opengl3.cpp ../../backends/imgui_impl_opengl3.h ../../backends/imgui_impl_sdl3.cpp ../../backends/imgui_impl_sdl3.h DearImGuiDemo.cpp +fi