├── settings.gradle ├── screenshot └── screenshot.png ├── ImguiDemoSdl ├── src │ ├── main │ │ ├── res │ │ │ ├── values │ │ │ │ ├── strings.xml │ │ │ │ ├── colors.xml │ │ │ │ └── styles.xml │ │ │ ├── mipmap-hdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-mdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ └── mipmap-xxxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ ├── cpp │ │ │ ├── data │ │ │ │ ├── bump.jpg │ │ │ │ ├── skybox-negx.jpg │ │ │ │ ├── skybox-negy.jpg │ │ │ │ ├── skybox-negz.jpg │ │ │ │ ├── skybox-posx.jpg │ │ │ │ ├── skybox-posy.jpg │ │ │ │ ├── skybox-posz.jpg │ │ │ │ ├── Roboto-Medium.ttf │ │ │ │ └── imgui.ini │ │ │ ├── src │ │ │ │ ├── teapotjs │ │ │ │ │ ├── bump.jpg │ │ │ │ │ ├── skybox-negx.jpg │ │ │ │ │ ├── skybox-negy.jpg │ │ │ │ │ ├── skybox-negz.jpg │ │ │ │ │ ├── skybox-posx.jpg │ │ │ │ │ ├── skybox-posy.jpg │ │ │ │ │ ├── skybox-posz.jpg │ │ │ │ │ └── demo.js │ │ │ │ ├── imgui_impl │ │ │ │ │ ├── imgui_impl_sdl_gl3.h │ │ │ │ │ ├── imgui_impl_sdl_es3.h │ │ │ │ │ ├── imgui_impl_sdl_es2.h │ │ │ │ │ ├── imgui_impl_sdl_gl3.cpp │ │ │ │ │ ├── imgui_impl_sdl_es2.cpp │ │ │ │ │ └── imgui_impl_sdl_es3.cpp │ │ │ │ ├── teapot.h │ │ │ │ ├── logger.h │ │ │ │ ├── main.cpp │ │ │ │ └── teapot.cpp │ │ │ ├── CMakeLists.txt │ │ │ └── cmake │ │ │ │ └── FindSDL2.cmake │ │ ├── AndroidManifest.xml │ │ └── java │ │ │ └── me │ │ │ └── sfalexrog │ │ │ └── imguidemo │ │ │ └── DemoActivity.java │ ├── test │ │ └── java │ │ │ └── me │ │ │ └── sfalexrog │ │ │ └── imguidemo │ │ │ └── ExampleUnitTest.java │ └── androidTest │ │ └── java │ │ └── me │ │ └── sfalexrog │ │ └── imguidemo │ │ └── ExampleInstrumentedTest.java ├── proguard-rules.pro └── build.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .gitignore ├── .gitmodules ├── gradle.properties ├── gradlew.bat ├── README.md └── gradlew /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':ImguiDemoSdl' 2 | -------------------------------------------------------------------------------- /screenshot/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sfalexrog/Imgui_Android/HEAD/screenshot/screenshot.png -------------------------------------------------------------------------------- /ImguiDemoSdl/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | ImguiDemo 3 | 4 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sfalexrog/Imgui_Android/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /ImguiDemoSdl/src/main/cpp/data/bump.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sfalexrog/Imgui_Android/HEAD/ImguiDemoSdl/src/main/cpp/data/bump.jpg -------------------------------------------------------------------------------- /ImguiDemoSdl/src/main/cpp/data/skybox-negx.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sfalexrog/Imgui_Android/HEAD/ImguiDemoSdl/src/main/cpp/data/skybox-negx.jpg -------------------------------------------------------------------------------- /ImguiDemoSdl/src/main/cpp/data/skybox-negy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sfalexrog/Imgui_Android/HEAD/ImguiDemoSdl/src/main/cpp/data/skybox-negy.jpg -------------------------------------------------------------------------------- /ImguiDemoSdl/src/main/cpp/data/skybox-negz.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sfalexrog/Imgui_Android/HEAD/ImguiDemoSdl/src/main/cpp/data/skybox-negz.jpg -------------------------------------------------------------------------------- /ImguiDemoSdl/src/main/cpp/data/skybox-posx.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sfalexrog/Imgui_Android/HEAD/ImguiDemoSdl/src/main/cpp/data/skybox-posx.jpg -------------------------------------------------------------------------------- /ImguiDemoSdl/src/main/cpp/data/skybox-posy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sfalexrog/Imgui_Android/HEAD/ImguiDemoSdl/src/main/cpp/data/skybox-posy.jpg -------------------------------------------------------------------------------- /ImguiDemoSdl/src/main/cpp/data/skybox-posz.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sfalexrog/Imgui_Android/HEAD/ImguiDemoSdl/src/main/cpp/data/skybox-posz.jpg -------------------------------------------------------------------------------- /ImguiDemoSdl/src/main/cpp/src/teapotjs/bump.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sfalexrog/Imgui_Android/HEAD/ImguiDemoSdl/src/main/cpp/src/teapotjs/bump.jpg -------------------------------------------------------------------------------- /ImguiDemoSdl/src/main/cpp/data/Roboto-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sfalexrog/Imgui_Android/HEAD/ImguiDemoSdl/src/main/cpp/data/Roboto-Medium.ttf -------------------------------------------------------------------------------- /ImguiDemoSdl/src/main/cpp/src/teapotjs/skybox-negx.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sfalexrog/Imgui_Android/HEAD/ImguiDemoSdl/src/main/cpp/src/teapotjs/skybox-negx.jpg -------------------------------------------------------------------------------- /ImguiDemoSdl/src/main/cpp/src/teapotjs/skybox-negy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sfalexrog/Imgui_Android/HEAD/ImguiDemoSdl/src/main/cpp/src/teapotjs/skybox-negy.jpg -------------------------------------------------------------------------------- /ImguiDemoSdl/src/main/cpp/src/teapotjs/skybox-negz.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sfalexrog/Imgui_Android/HEAD/ImguiDemoSdl/src/main/cpp/src/teapotjs/skybox-negz.jpg -------------------------------------------------------------------------------- /ImguiDemoSdl/src/main/cpp/src/teapotjs/skybox-posx.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sfalexrog/Imgui_Android/HEAD/ImguiDemoSdl/src/main/cpp/src/teapotjs/skybox-posx.jpg -------------------------------------------------------------------------------- /ImguiDemoSdl/src/main/cpp/src/teapotjs/skybox-posy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sfalexrog/Imgui_Android/HEAD/ImguiDemoSdl/src/main/cpp/src/teapotjs/skybox-posy.jpg -------------------------------------------------------------------------------- /ImguiDemoSdl/src/main/cpp/src/teapotjs/skybox-posz.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sfalexrog/Imgui_Android/HEAD/ImguiDemoSdl/src/main/cpp/src/teapotjs/skybox-posz.jpg -------------------------------------------------------------------------------- /ImguiDemoSdl/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sfalexrog/Imgui_Android/HEAD/ImguiDemoSdl/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /ImguiDemoSdl/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sfalexrog/Imgui_Android/HEAD/ImguiDemoSdl/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /ImguiDemoSdl/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sfalexrog/Imgui_Android/HEAD/ImguiDemoSdl/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /ImguiDemoSdl/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sfalexrog/Imgui_Android/HEAD/ImguiDemoSdl/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /ImguiDemoSdl/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sfalexrog/Imgui_Android/HEAD/ImguiDemoSdl/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .externalNativeBuild 10 | -------------------------------------------------------------------------------- /ImguiDemoSdl/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sfalexrog/Imgui_Android/HEAD/ImguiDemoSdl/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /ImguiDemoSdl/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sfalexrog/Imgui_Android/HEAD/ImguiDemoSdl/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /ImguiDemoSdl/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sfalexrog/Imgui_Android/HEAD/ImguiDemoSdl/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /ImguiDemoSdl/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sfalexrog/Imgui_Android/HEAD/ImguiDemoSdl/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /ImguiDemoSdl/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sfalexrog/Imgui_Android/HEAD/ImguiDemoSdl/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /ImguiDemoSdl/src/main/cpp/data/imgui.ini: -------------------------------------------------------------------------------- 1 | [Debug] 2 | Pos=60,60 3 | Size=400,400 4 | Collapsed=0 5 | 6 | [ImGui Demo] 7 | Pos=705,35 8 | Size=550,680 9 | Collapsed=0 10 | 11 | [Teapot controls] 12 | Pos=68,487 13 | Size=459,262 14 | Collapsed=0 15 | 16 | -------------------------------------------------------------------------------- /ImguiDemoSdl/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3F51B5 4 | #303F9F 5 | #FF4081 6 | 7 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon Aug 07 14:54:43 MSK 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip 7 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "ImguiDemoSdl/src/main/cpp/deps/imgui"] 2 | path = ImguiDemoSdl/src/main/cpp/deps/imgui 3 | url = https://github.com/ocornut/imgui 4 | [submodule "ImguiDemoSdl/src/main/cpp/deps/glm"] 5 | path = ImguiDemoSdl/src/main/cpp/deps/glm 6 | url = https://github.com/g-truc/glm 7 | [submodule "ImguiDemoSdl/src/main/cpp/deps/SDL"] 8 | path = ImguiDemoSdl/src/main/cpp/deps/SDL 9 | url = https://github.com/sfalexrog/SDL 10 | branch = cmake_fixes 11 | -------------------------------------------------------------------------------- /ImguiDemoSdl/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /ImguiDemoSdl/src/test/java/me/sfalexrog/imguidemo/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package me.sfalexrog.imguidemo; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() throws Exception { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /ImguiDemoSdl/src/androidTest/java/me/sfalexrog/imguidemo/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package me.sfalexrog.imguidemo; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumentation test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("me.sfalexrog.imguidemo", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ImguiDemoSdl/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 14 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /ImguiDemoSdl/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /opt/android/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | org.gradle.jvmargs=-Xmx1536m 13 | 14 | # When configured, Gradle will run in incubating parallel mode. 15 | # This option should only be used with decoupled projects. More details, visit 16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 17 | # org.gradle.parallel=true 18 | # AndroidX package structure to make it clearer which packages are bundled with the 19 | # Android operating system, and which are packaged with your app's APK 20 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 21 | android.useAndroidX=true 22 | # Automatically convert third-party libraries to use AndroidX 23 | android.enableJetifier=true 24 | -------------------------------------------------------------------------------- /ImguiDemoSdl/src/main/cpp/src/imgui_impl/imgui_impl_sdl_gl3.h: -------------------------------------------------------------------------------- 1 | // ImGui SDL2 binding with OpenGL3 2 | // In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. 3 | 4 | // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. 5 | // If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). 6 | // If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. 7 | // https://github.com/ocornut/imgui 8 | 9 | #ifdef GL_PROFILE_GL3 10 | 11 | #ifndef IMGUI_IMPL_SDL_GL3 12 | #define IMGUI_IMPL_SDL_GL3 13 | 14 | struct SDL_Window; 15 | typedef union SDL_Event SDL_Event; 16 | 17 | IMGUI_API bool ImGui_ImplSdlGL3_Init(SDL_Window* window); 18 | IMGUI_API void ImGui_ImplSdlGL3_Shutdown(); 19 | IMGUI_API void ImGui_ImplSdlGL3_NewFrame(SDL_Window* window); 20 | IMGUI_API bool ImGui_ImplSdlGL3_ProcessEvent(SDL_Event* event); 21 | 22 | // Use if you want to reset your rendering device without losing ImGui state. 23 | IMGUI_API void ImGui_ImplSdlGL3_InvalidateDeviceObjects(); 24 | IMGUI_API bool ImGui_ImplSdlGL3_CreateDeviceObjects(); 25 | 26 | #endif // IMGUI_IMPL_SDL_GL3 27 | 28 | #endif // GL_PROFILE_GL3 29 | -------------------------------------------------------------------------------- /ImguiDemoSdl/src/main/cpp/src/imgui_impl/imgui_impl_sdl_es3.h: -------------------------------------------------------------------------------- 1 | // ImGui SDL2 binding with OpenGL3 2 | // In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. 3 | 4 | // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. 5 | // If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). 6 | // If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. 7 | // https://github.com/ocornut/imgui 8 | 9 | #ifdef GL_PROFILE_GLES3 10 | 11 | #ifndef IMGUI_IMPL_SDL_ES3 12 | #define IMGUI_IMPL_SDL_ES3 13 | 14 | struct SDL_Window; 15 | typedef union SDL_Event SDL_Event; 16 | 17 | IMGUI_API bool ImGui_ImplSdlGLES3_Init(SDL_Window* window); 18 | IMGUI_API void ImGui_ImplSdlGLES3_Shutdown(); 19 | IMGUI_API void ImGui_ImplSdlGLES3_NewFrame(SDL_Window* window); 20 | IMGUI_API bool ImGui_ImplSdlGLES3_ProcessEvent(SDL_Event* event); 21 | 22 | // Use if you want to reset your rendering device without losing ImGui state. 23 | IMGUI_API void ImGui_ImplSdlGLES3_InvalidateDeviceObjects(); 24 | IMGUI_API bool ImGui_ImplSdlGLES3_CreateDeviceObjects(); 25 | 26 | #endif // IMGUI_IMPL_SDL_ES3 27 | #endif // GL_PROFILE_GLES3 -------------------------------------------------------------------------------- /ImguiDemoSdl/src/main/cpp/src/imgui_impl/imgui_impl_sdl_es2.h: -------------------------------------------------------------------------------- 1 | // ImGui SDL2 binding with OpenGL3 2 | // In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. 3 | 4 | // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. 5 | // If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). 6 | // If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. 7 | // https://github.com/ocornut/imgui 8 | 9 | #ifdef GL_PROFILE_GLES2 10 | 11 | #ifndef IMGUI_IMPL_SDL_ES2 12 | #define IMGUI_IMPL_SDL_ES2 13 | 14 | struct SDL_Window; 15 | typedef union SDL_Event SDL_Event; 16 | 17 | IMGUI_API bool ImGui_ImplSdlGLES2_Init(SDL_Window* window); 18 | IMGUI_API void ImGui_ImplSdlGLES2_Shutdown(); 19 | IMGUI_API void ImGui_ImplSdlGLES2_NewFrame(SDL_Window* window); 20 | IMGUI_API bool ImGui_ImplSdlGLES2_ProcessEvent(SDL_Event* event); 21 | 22 | // Use if you want to reset your rendering device without losing ImGui state. 23 | IMGUI_API void ImGui_ImplSdlGLES2_InvalidateDeviceObjects(); 24 | IMGUI_API bool ImGui_ImplSdlGLES2_CreateDeviceObjects(); 25 | 26 | #endif // IMGUI_IMPL_SDL_ES2 27 | 28 | #endif // GL_PROFILE_GLES2 -------------------------------------------------------------------------------- /ImguiDemoSdl/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 29 5 | buildToolsVersion "29.0.2" 6 | defaultConfig { 7 | applicationId "me.sfalexrog.imguidemo" 8 | minSdkVersion 18 9 | targetSdkVersion 29 10 | versionCode 1 11 | versionName "1.0" 12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 13 | externalNativeBuild { 14 | cmake { 15 | cppFlags "" 16 | } 17 | } 18 | } 19 | buildTypes { 20 | release { 21 | minifyEnabled false 22 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 23 | } 24 | } 25 | externalNativeBuild { 26 | cmake { 27 | path "src/main/cpp/CMakeLists.txt" 28 | } 29 | } 30 | 31 | sourceSets { 32 | main { 33 | // We're using SDLActivity from SDL sources, not copying that to our source tree 34 | java.srcDirs += ['src/main/cpp/deps/SDL/android-project/app/src/main/java'] 35 | // Instead of copying data files from the native project, we just add its data 36 | // as another asset directory 37 | assets.srcDirs += ['src/main/cpp/data'] 38 | } 39 | } 40 | } 41 | 42 | dependencies { 43 | implementation fileTree(dir: 'libs', include: ['*.jar']) 44 | implementation 'androidx.appcompat:appcompat:1.0.2' 45 | testImplementation 'junit:junit:4.12' 46 | androidTestImplementation 'androidx.test:runner:1.1.1' 47 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' 48 | } 49 | -------------------------------------------------------------------------------- /ImguiDemoSdl/src/main/cpp/src/teapot.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by sf on 8/9/17. 3 | // 4 | 5 | #ifndef IMGUI_DEMO_TEAPOT_H 6 | #define IMGUI_DEMO_TEAPOT_H 7 | 8 | #ifdef GL_PROFILE_GL3 9 | #include "gl_glcore_3_3.h" 10 | #else 11 | #include 12 | #endif 13 | 14 | #include 15 | #include 16 | 17 | class Teapot { 18 | public: 19 | Teapot(); 20 | ~Teapot(); 21 | bool init(); 22 | void draw(); 23 | void rotateBy(float angleX, float angleY); 24 | void rotateTo(float angleX); 25 | void rotateCameraBy(float angleX, float angleY); 26 | void rotateCameraTo(float angleX); 27 | void zoomBy(float zoomFactor); 28 | float zoomValue(); 29 | 30 | private: 31 | struct vtxData { 32 | glm::vec3 pos; 33 | glm::vec3 norm; 34 | glm::vec3 tangent; 35 | glm::vec3 binorm; 36 | glm::vec3 texcoord; 37 | }; 38 | 39 | struct uniformData { 40 | glm::mat4 world; 41 | glm::mat4 worldInverseTranspose; 42 | glm::mat4 worldViewProj; 43 | glm::mat4 viewInverse; 44 | } unfData; 45 | 46 | #ifdef GL_PROFILE_GL3 47 | static GLuint g_vao; 48 | #endif 49 | int num_vertices; 50 | int num_indices; 51 | GLuint ibo; 52 | GLuint vbo; 53 | GLuint tex_skybox; 54 | GLuint tex_bump; 55 | 56 | struct { 57 | GLint g_Position; 58 | GLint g_TexCoord0; 59 | GLint g_Tangent; 60 | GLint g_Binormal; 61 | GLint g_Normal; 62 | } attribs; 63 | 64 | struct { 65 | GLint world; 66 | GLint worldInverseTranspose; 67 | GLint worldViewProj; 68 | GLint viewInverse; 69 | GLint normalSampler; 70 | GLint envSampler; 71 | } uniforms; 72 | GLuint program; 73 | 74 | GLfloat rotX, rotY, zoom; 75 | GLfloat camRX, camRY; 76 | GLfloat addRotX, addRotY, addZoom; 77 | GLfloat addCamRX, addCamRY; 78 | 79 | bool compileShaders(); 80 | 81 | }; 82 | 83 | #endif //IMGUI_DEMO_TEAPOT_H 84 | -------------------------------------------------------------------------------- /ImguiDemoSdl/src/main/cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Cmake file for a sample cross-platform project with dear imgui. 2 | # The aim here is to have most of the stuff (including cmake files) 3 | # be the same throughout platforms. 4 | 5 | cmake_minimum_required(VERSION 3.1) 6 | 7 | project(imgui_demo) 8 | 9 | set(CMAKE_CXX_STANDARD 11) 10 | set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) 11 | 12 | find_package(SDL2 REQUIRED) 13 | 14 | # This is an adaptation of the ImGui demo, with some geometry (a teapot) 15 | # rendered in order to check the ImGui implementation. Teapot is taken 16 | # from Google NDK samples. 17 | 18 | set(IMGUI_PATH deps/imgui) 19 | set(IMGUI_IMPL_PATH src/imgui_impl) 20 | 21 | # Since we're drawing something that's not just a triangle, we're gonna 22 | # want a library that deals with vectors and matrices. glm is the obvious 23 | # choice. 24 | 25 | add_subdirectory(deps/glm) 26 | 27 | # Use GLES2/GLES3 implementations for Android, GL3 for everything else 28 | 29 | if (ANDROID) 30 | set(GL_PROFILES "GL_PROFILE_GLES2" "GL_PROFILE_GLES3") 31 | else() 32 | set(GL_PROFILES "GL_PROFILE_GL3") 33 | endif() 34 | 35 | file(GLOB IMGUI_FILES 36 | ${IMGUI_PATH}/*.cpp 37 | ${IMGUI_IMPL_PATH}/*.cpp 38 | ) 39 | 40 | file(GLOB DEMO_FILES 41 | src/*.cpp 42 | ) 43 | 44 | if (NOT ANDROID) 45 | set(GLLOAD_PATH src/glload) 46 | file(GLOB GLLOAD_FILES 47 | ${GLLOAD_PATH}/*.c) 48 | endif() 49 | 50 | 51 | set(DEMO_SOURCES ${IMGUI_FILES} ${DEMO_FILES} ${GLLOAD_FILES}) 52 | 53 | # Build as a library for Android, as an executable otherwise 54 | 55 | if (ANDROID) 56 | add_library(demo SHARED 57 | ${DEMO_SOURCES} 58 | ) 59 | else() 60 | add_executable(demo 61 | ${DEMO_SOURCES} 62 | ) 63 | endif() 64 | 65 | target_link_libraries(demo ${SDL2_LIBRARY} glm GLESv2) 66 | target_include_directories(demo PRIVATE ${SDL2_INCLUDE_DIR}) 67 | target_include_directories(demo PRIVATE ${IMGUI_PATH}) 68 | target_include_directories(demo PRIVATE ${IMGUI_IMPL_PATH}) 69 | target_include_directories(demo PRIVATE ${GLLOAD_PATH}) 70 | target_compile_definitions(demo PRIVATE ${GL_PROFILES}) -------------------------------------------------------------------------------- /ImguiDemoSdl/src/main/java/me/sfalexrog/imguidemo/DemoActivity.java: -------------------------------------------------------------------------------- 1 | package me.sfalexrog.imguidemo; 2 | 3 | import android.content.res.AssetManager; 4 | import android.os.Bundle; 5 | import android.util.Log; 6 | 7 | import org.libsdl.app.SDLActivity; 8 | 9 | import java.io.BufferedOutputStream; 10 | import java.io.FileOutputStream; 11 | import java.io.IOException; 12 | import java.io.InputStream; 13 | 14 | /** 15 | * Created by sf on 8/7/17. 16 | */ 17 | 18 | public class DemoActivity extends SDLActivity { 19 | 20 | /* A fancy way of getting the class name */ 21 | private static final String TAG = DemoActivity.class.getSimpleName(); 22 | 23 | /* A list of assets to copy to internal directory */ 24 | private static final String[] ASSET_NAMES = new String[]{"bump.jpg", 25 | "skybox-negx.jpg", 26 | "skybox-negy.jpg", 27 | "skybox-negz.jpg", 28 | "skybox-posx.jpg", 29 | "skybox-posy.jpg", 30 | "skybox-posz.jpg", 31 | "Roboto-Medium.ttf" 32 | }; 33 | 34 | @Override 35 | protected String[] getLibraries() { 36 | return new String[]{"hidapi", "SDL2", "demo"}; 37 | } 38 | 39 | @Override 40 | protected String[] getArguments() { 41 | return new String[]{getFilesDir().getAbsolutePath()}; 42 | } 43 | 44 | @Override 45 | protected void onCreate(Bundle savedInstanceState) { 46 | 47 | super.onCreate(savedInstanceState); 48 | /* We're going to unpack our assets to a location that's accessible 49 | * via the usual stdio means. This is to avoid using AAssetManager 50 | * in our native code. */ 51 | Log.v(TAG, "Copying assets to accessible locations"); 52 | AssetManager assetManager = this.getAssets(); 53 | for (String assetName: ASSET_NAMES) { 54 | try { 55 | Log.v(TAG, "Copying " + assetName); 56 | InputStream ais = assetManager.open(assetName); 57 | FileOutputStream fos = openFileOutput(assetName, MODE_PRIVATE); 58 | final int BUFSZ = 8192; 59 | byte[] buffer = new byte[BUFSZ]; 60 | int readlen = 0; 61 | do { 62 | readlen = ais.read(buffer, 0, BUFSZ); 63 | if (readlen < 0) { 64 | break; 65 | } 66 | fos.write(buffer, 0, readlen); 67 | } while (readlen > 0); 68 | fos.close(); 69 | ais.close(); 70 | } catch(IOException e){ 71 | Log.e(TAG, "Could not open " + assetName + " from assets, that should not happen", e); 72 | } 73 | } 74 | 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /ImguiDemoSdl/src/main/cpp/src/logger.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by sf on 6/28/17. 3 | // 4 | 5 | #ifndef XPLATDEV_LOGGER_H 6 | #define XPLATDEV_LOGGER_H 7 | 8 | #ifdef __ANDROID__ 9 | #include 10 | #define LOG_TAG "NativeApp" 11 | #else 12 | #include 13 | #endif 14 | #include 15 | 16 | namespace _Logger { 17 | enum Severity { 18 | LOG_DEBUG = 0, 19 | LOG_INFO, 20 | LOG_WARN, 21 | LOG_ERROR, 22 | LOG_FATAL 23 | }; 24 | 25 | class Logger { 26 | private: 27 | std::stringstream logbuf; 28 | Severity severity; 29 | 30 | std::string sevStr() 31 | { 32 | switch(severity){ 33 | case LOG_DEBUG: 34 | return "[DEBUG] "; 35 | case LOG_INFO: 36 | return "[INFO] "; 37 | case LOG_WARN: 38 | return "[WARN] "; 39 | case LOG_ERROR: 40 | return "[ERROR] "; 41 | case LOG_FATAL: 42 | return "[FATAL] "; 43 | } 44 | } 45 | 46 | #ifdef __ANDROID__ 47 | int getPrio() 48 | { 49 | switch(severity) 50 | { 51 | case LOG_DEBUG: 52 | return ANDROID_LOG_DEBUG; 53 | case LOG_INFO: 54 | return ANDROID_LOG_INFO; 55 | case LOG_WARN: 56 | return ANDROID_LOG_WARN; 57 | case LOG_ERROR: 58 | return ANDROID_LOG_ERROR; 59 | case LOG_FATAL: 60 | return ANDROID_LOG_FATAL; 61 | default: 62 | return ANDROID_LOG_DEFAULT; 63 | } 64 | } 65 | #else 66 | static std::ostream& getStream(Severity s) 67 | { 68 | if (s < LOG_ERROR) 69 | { 70 | return std::cout; 71 | } 72 | else 73 | { 74 | return std::cerr; 75 | } 76 | } 77 | #endif 78 | 79 | public: 80 | static Severity& minSeverity() 81 | { 82 | static Severity minSeverity = LOG_DEBUG; 83 | return minSeverity; 84 | } 85 | 86 | Logger(Severity s) : severity(s) 87 | { 88 | 89 | } 90 | ~Logger() 91 | { 92 | #ifdef __ANDROID__ 93 | __android_log_print(getPrio(), LOG_TAG, "%s", logbuf.str().c_str()); 94 | #else 95 | getStream(severity) << sevStr() << logbuf.str() << std::endl; 96 | #endif 97 | } 98 | std::stringstream& log() 99 | { 100 | return logbuf; 101 | } 102 | 103 | }; 104 | }; 105 | 106 | #define Log(LOGLEVEL) _Logger::Logger(_Logger::LOGLEVEL).log() 107 | 108 | #endif //XPLATDEV_LOGGER_H 109 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Imgui_Android 2 | A demo of dear imgui running on Android 3 | ![screenshot](https://raw.githubusercontent.com/sfalexrog/Imgui_Android/master/screenshot/screenshot.png) 4 | 5 | ## What? 6 | 7 | This is a port of [dear imgui](https://github.com/ocornut/imgui) SDL2 example to Android. In order to check my implementation, 8 | I've decided to render a teapot from [WebGL repository](https://github.com/KhronosGroup/WebGL) (the 9 | [shiny teapot demo](https://github.com/KhronosGroup/WebGL/tree/master/sdk/demos/google/shiny-teapot) by Google). Since ImGui 10 | windows and the teapot itself are rendered properly, I assume my ES2 code is correct (since rendering a teapot perturbs GL state 11 | that ImGui implementations might depend on). 12 | 13 | As an added bonus, you can compile and run this demo on a desktop! (Tested only on Linux so far) 14 | 15 | ## How? 16 | 17 | This demo, apart from dear imgui, uses [SDL2](http://libsdl.org/), [glm](https://glm.g-truc.net/0.9.8/index.html), and 18 | [stb_image](https://github.com/nothings/stb). It includes SDL and glm as submodules. You don't need SDL2 sources if you're 19 | building on a desktop, though, but you'll need SDL2 installed. 20 | 21 | I ran into some issues while working on this demo. First, Android's virtual keyboard sends events in a weird way, making 22 | backspace, for instance, not working or working unreliably. This doesn't concern actual physical keyboards, but since the 23 | vast majority of Android users don't have a hardware keyboard, I've made a hack that discards the keyUp event for Backspace 24 | until the rendering starts. This may or may not work with your setup, and may or may not work with hardware keyboards. 25 | 26 | Second, since I'm buiding the native part with CMake, I've decided to try and use SDL's CMakeLists.txt directly. I had to make 27 | some modifications to it in order for it to work, but it seems to build just fine. In order to keep instances of `if(ANDROID)` 28 | in my own CMakeLists.txt, I've decided to hack a FindSDL2.cmake module I've found. So now `find_package(SDL2)` will build 29 | SDL2 if you're building for Android and will try to find SDL2 libraries on a desktop. Not sure if that's a good idea (please 30 | tell me why if it isn't!), but it seems to work. 31 | 32 | ## Build 33 | 34 | ### Android 35 | 36 | You'll need OpenJDK 1.8, Android SDK, NDK, and Android-specific cmake in order to build this demo. Good thing is, you only really need the 37 | SDK and NDK parts, gradle will install everything else for you if you accept the licenses. In order to accept the licenses, run 38 | 39 | ${ANDROID_SDK_ROOT}/tools/bin/sdkmanager --licenses 40 | 41 | and accept the licenses. If you don't have an NDK, run 42 | 43 | ${ANDROID_SDK_ROOT}/tools/bin/sdkmanager ndk-bundle 44 | 45 | This will download the latest NDK and put it into `${ANDROID_SDK_ROOT}/ndk-bundle`. 46 | 47 | Then, download the project and its submodules: 48 | 49 | $ git clone --recursive https://github.com/sfalexrog/Imgui_Android 50 | 51 | (or do `git submodule update --init --recursive` after cloning if your Git client does not support the `--recursive` option) 52 | 53 | Finally, run 54 | 55 | $ ./gradlew assembleDebug 56 | 57 | in the project folder. Gradle wrapper will download the required gradle version, and gradle plugin will download everything 58 | that's required. Your apk will be in `ImguiDemoSdl/build/outputs/apk`. 59 | 60 | Of course, you can simply run Android Studio and open this project. Android Studio will prompt you to install all missing 61 | components. 62 | 63 | ### Desktop (Linux, really) 64 | 65 | You won't need all submodules, glm and imgui will be enough. Unfortunately I'm not using system glm. You'll have to clone the 66 | project without submodules, and then only initialize glm and imgui: 67 | 68 | $ git clone https://github.com/sfalexrog/Imgui_Android 69 | $ cd Imgui_Android 70 | $ git submodule update --init --recursive ImguiDemoSdl/src/main/cpp/deps/glm 71 | $ git submodule update --init --recursive ImguiDemoSdl/src/main/cpp/deps/imgui 72 | 73 | Then, create a build directory somewhere out-of-source, and run 74 | 75 | $ cmake ${PATH_TO_IMGUI_ANDROID}/ImguiDemoSdl/src/main/cpp 76 | $ make demo 77 | $ ./demo ${PATH_TO_IMGUI_ANDROID}/ImguiDemoSdl/src/main/cpp/data 78 | 79 | That's basically it. You should have a demo on your screen. 80 | 81 | ## Why? 82 | 83 | I've done this project mostly to create a correct ES2 implementation for ImGui, but also to try and write cross-platform 84 | C++/OpenGL code that will use the same set of build files on Android and desktop. Oh, and for the fun of it! 85 | 86 | ## Next? 87 | 88 | Since this is more of a proof-of-concept (well, maybe several concepts), there are a lot of things that are worth doing: 89 | 90 | - Rendering an environment-mapped teapot without any "environment" (skybox) seems odd. Adding it shouldn't be too difficult. 91 | 92 | - There are lots of parameters you'd probably want to monitor and/or control, but right now I'm only displaying a zoom value 93 | and teapot rotation. Changing shader parameters on the fly seems like just the right thing to do with ImGui. 94 | 95 | - Speaking of zoom, controls are very wrong. Seems like using a virtual "trackball" is the way to go to rotate camera 96 | in 3D space. 97 | 98 | - Since this is a working implementation of ImGui for OpenGL ES2, and a working project with SDL2, you can try adding your 99 | own game/app here and have a nice overlay! 100 | 101 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # Attempt to set APP_HOME 46 | # Resolve links: $0 may be a link 47 | PRG="$0" 48 | # Need this for relative symlinks. 49 | while [ -h "$PRG" ] ; do 50 | ls=`ls -ld "$PRG"` 51 | link=`expr "$ls" : '.*-> \(.*\)$'` 52 | if expr "$link" : '/.*' > /dev/null; then 53 | PRG="$link" 54 | else 55 | PRG=`dirname "$PRG"`"/$link" 56 | fi 57 | done 58 | SAVED="`pwd`" 59 | cd "`dirname \"$PRG\"`/" >/dev/null 60 | APP_HOME="`pwd -P`" 61 | cd "$SAVED" >/dev/null 62 | 63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 64 | 65 | # Determine the Java command to use to start the JVM. 66 | if [ -n "$JAVA_HOME" ] ; then 67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 68 | # IBM's JDK on AIX uses strange locations for the executables 69 | JAVACMD="$JAVA_HOME/jre/sh/java" 70 | else 71 | JAVACMD="$JAVA_HOME/bin/java" 72 | fi 73 | if [ ! -x "$JAVACMD" ] ; then 74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 75 | 76 | Please set the JAVA_HOME variable in your environment to match the 77 | location of your Java installation." 78 | fi 79 | else 80 | JAVACMD="java" 81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 82 | 83 | Please set the JAVA_HOME variable in your environment to match the 84 | location of your Java installation." 85 | fi 86 | 87 | # Increase the maximum file descriptors if we can. 88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 89 | MAX_FD_LIMIT=`ulimit -H -n` 90 | if [ $? -eq 0 ] ; then 91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 92 | MAX_FD="$MAX_FD_LIMIT" 93 | fi 94 | ulimit -n $MAX_FD 95 | if [ $? -ne 0 ] ; then 96 | warn "Could not set maximum file descriptor limit: $MAX_FD" 97 | fi 98 | else 99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 100 | fi 101 | fi 102 | 103 | # For Darwin, add options to specify how the application appears in the dock 104 | if $darwin; then 105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 106 | fi 107 | 108 | # For Cygwin, switch paths to Windows format before running java 109 | if $cygwin ; then 110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 112 | JAVACMD=`cygpath --unix "$JAVACMD"` 113 | 114 | # We build the pattern for arguments to be converted via cygpath 115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 116 | SEP="" 117 | for dir in $ROOTDIRSRAW ; do 118 | ROOTDIRS="$ROOTDIRS$SEP$dir" 119 | SEP="|" 120 | done 121 | OURCYGPATTERN="(^($ROOTDIRS))" 122 | # Add a user-defined pattern to the cygpath arguments 123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 125 | fi 126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 127 | i=0 128 | for arg in "$@" ; do 129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 131 | 132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 134 | else 135 | eval `echo args$i`="\"$arg\"" 136 | fi 137 | i=$((i+1)) 138 | done 139 | case $i in 140 | (0) set -- ;; 141 | (1) set -- "$args0" ;; 142 | (2) set -- "$args0" "$args1" ;; 143 | (3) set -- "$args0" "$args1" "$args2" ;; 144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 150 | esac 151 | fi 152 | 153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 154 | function splitJvmOpts() { 155 | JVM_OPTS=("$@") 156 | } 157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 159 | 160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 161 | -------------------------------------------------------------------------------- /ImguiDemoSdl/src/main/cpp/cmake/FindSDL2.cmake: -------------------------------------------------------------------------------- 1 | # Locate SDL2 library 2 | # This module defines 3 | # SDL2_LIBRARY, the name of the library to link against 4 | # SDL2_FOUND, if false, do not try to link to SDL2 5 | # SDL2_INCLUDE_DIR, where to find SDL.h 6 | # 7 | # This module responds to the the flag: 8 | # SDL2_BUILDING_LIBRARY 9 | # If this is defined, then no SDL2main will be linked in because 10 | # only applications need main(). 11 | # Otherwise, it is assumed you are building an application and this 12 | # module will attempt to locate and set the the proper link flags 13 | # as part of the returned SDL2_LIBRARY variable. 14 | # 15 | # Don't forget to include SDLmain.h and SDLmain.m your project for the 16 | # OS X framework based version. (Other versions link to -lSDL2main which 17 | # this module will try to find on your behalf.) Also for OS X, this 18 | # module will automatically add the -framework Cocoa on your behalf. 19 | # 20 | # 21 | # Additional Note: If you see an empty SDL2_LIBRARY_TEMP in your configuration 22 | # and no SDL2_LIBRARY, it means CMake did not find your SDL2 library 23 | # (SDL2.dll, libsdl2.so, SDL2.framework, etc). 24 | # Set SDL2_LIBRARY_TEMP to point to your SDL2 library, and configure again. 25 | # Similarly, if you see an empty SDL2MAIN_LIBRARY, you should set this value 26 | # as appropriate. These values are used to generate the final SDL2_LIBRARY 27 | # variable, but when these values are unset, SDL2_LIBRARY does not get created. 28 | # 29 | # 30 | # $SDL2DIR is an environment variable that would 31 | # correspond to the ./configure --prefix=$SDL2DIR 32 | # used in building SDL2. 33 | # l.e.galup 9-20-02 34 | # 35 | # Modified by Eric Wing. 36 | # Added code to assist with automated building by using environmental variables 37 | # and providing a more controlled/consistent search behavior. 38 | # Added new modifications to recognize OS X frameworks and 39 | # additional Unix paths (FreeBSD, etc). 40 | # Also corrected the header search path to follow "proper" SDL guidelines. 41 | # Added a search for SDL2main which is needed by some platforms. 42 | # Added a search for threads which is needed by some platforms. 43 | # Added needed compile switches for MinGW. 44 | # 45 | # On OSX, this will prefer the Framework version (if found) over others. 46 | # People will have to manually change the cache values of 47 | # SDL2_LIBRARY to override this selection or set the CMake environment 48 | # CMAKE_INCLUDE_PATH to modify the search paths. 49 | # 50 | # Note that the header path has changed from SDL2/SDL.h to just SDL.h 51 | # This needed to change because "proper" SDL convention 52 | # is #include "SDL.h", not . This is done for portability 53 | # reasons because not all systems place things in SDL2/ (see FreeBSD). 54 | 55 | #============================================================================= 56 | # Copyright 2003-2009 Kitware, Inc. 57 | # 58 | # Distributed under the OSI-approved BSD License (the "License"); 59 | # see accompanying file Copyright.txt for details. 60 | # 61 | # This software is distributed WITHOUT ANY WARRANTY; without even the 62 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 63 | # See the License for more information. 64 | #============================================================================= 65 | # (To distribute this file outside of CMake, substitute the full 66 | # License text for the above reference.) 67 | 68 | # Modified by sfalexrog to accomodate Android builds. SDL2_LIBRARY 69 | # will be a target which you'll want to link against. It will be built 70 | # statically, mostly because that would save you from needing to 71 | # also add SDL2MAIN_LIBRARY to your target, and will not require you to 72 | # add SDL_android_main.c to your source sets. 73 | # You can override this behavior by changing this file, but as far as 74 | # I know having multiple shared libraries don't really give you any 75 | # benefit on Android. 76 | 77 | if (ANDROID) 78 | set(_SDL_SOURCE_SEARCH_PATHS 79 | SDL 80 | deps/SDL 81 | external/SDL 82 | libs/SDL 83 | ) 84 | 85 | # This is a hack to allow find_path to actually search for headers and sources 86 | set(_SDL_CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ${CMAKE_FIND_ROOT_PATH_MODE_INCLUDE}) 87 | set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE "NEVER") 88 | 89 | find_path(_SDL2_SOURCE_DIR SDL.c 90 | HINTS 91 | ${_SDL_SOURCE_SEARCH_PATHS} 92 | PATH_SUFFIXES src 93 | PATHS ${_SDL_SOURCE_SEARCH_PATHS} 94 | ) 95 | 96 | set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ${_SDL_CMAKE_FIND_ROOT_PATH_MODE_INCLUDE}) 97 | 98 | if (${_SDL2_SOURCE_DIR} STREQUAL "SDL2_SOURCE_DIR-NOTFOUND") 99 | message(FATAL_ERROR "Could not find SDL2 source directory, cannot continue") 100 | endif() 101 | 102 | get_filename_component(_SDL2_PROJECT_DIR ${_SDL2_SOURCE_DIR} DIRECTORY) 103 | add_subdirectory(${_SDL2_PROJECT_DIR}) 104 | 105 | # You can't directly specify a target in target_link_libraries 106 | # in ${}, but you can't specify a variable name without ${}, 107 | # so here's a little hack to make ${target_name} behave like 108 | # it should. 109 | set(SDL2_LIBRARY SDL2 SDL2main) 110 | set(SDL2_INCLUDE_DIR ${_SDL2_PROJECT_DIR}/include) 111 | 112 | else() 113 | 114 | SET(SDL2_SEARCH_PATHS 115 | ~/Library/Frameworks 116 | /Library/Frameworks 117 | /usr/local 118 | /usr 119 | /sw # Fink 120 | /opt/local # DarwinPorts 121 | /opt/csw # Blastwave 122 | /opt 123 | ) 124 | 125 | FIND_PATH(SDL2_INCLUDE_DIR SDL.h 126 | HINTS 127 | $ENV{SDL2DIR} 128 | PATH_SUFFIXES include/SDL2 include 129 | PATHS ${SDL2_SEARCH_PATHS} 130 | ) 131 | 132 | FIND_LIBRARY(SDL2_LIBRARY_TEMP 133 | NAMES SDL2 134 | HINTS 135 | $ENV{SDL2DIR} 136 | PATH_SUFFIXES lib64 lib 137 | PATHS ${SDL2_SEARCH_PATHS} 138 | ) 139 | 140 | IF(NOT SDL2_BUILDING_LIBRARY) 141 | IF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework") 142 | # Non-OS X framework versions expect you to also dynamically link to 143 | # SDL2main. This is mainly for Windows and OS X. Other (Unix) platforms 144 | # seem to provide SDL2main for compatibility even though they don't 145 | # necessarily need it. 146 | FIND_LIBRARY(SDL2MAIN_LIBRARY 147 | NAMES SDL2main 148 | HINTS 149 | $ENV{SDL2DIR} 150 | PATH_SUFFIXES lib64 lib 151 | PATHS ${SDL2_SEARCH_PATHS} 152 | ) 153 | ENDIF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework") 154 | ENDIF(NOT SDL2_BUILDING_LIBRARY) 155 | 156 | # SDL2 may require threads on your system. 157 | # The Apple build may not need an explicit flag because one of the 158 | # frameworks may already provide it. 159 | # But for non-OSX systems, I will use the CMake Threads package. 160 | IF(NOT APPLE) 161 | FIND_PACKAGE(Threads) 162 | ENDIF(NOT APPLE) 163 | 164 | # MinGW needs an additional library, mwindows 165 | # It's total link flags should look like -lmingw32 -lSDL2main -lSDL2 -lmwindows 166 | # (Actually on second look, I think it only needs one of the m* libraries.) 167 | IF(MINGW) 168 | SET(MINGW32_LIBRARY mingw32 CACHE STRING "mwindows for MinGW") 169 | ENDIF(MINGW) 170 | 171 | IF(SDL2_LIBRARY_TEMP) 172 | # For SDL2main 173 | IF(NOT SDL2_BUILDING_LIBRARY) 174 | IF(SDL2MAIN_LIBRARY) 175 | SET(SDL2_LIBRARY_TEMP ${SDL2MAIN_LIBRARY} ${SDL2_LIBRARY_TEMP}) 176 | ENDIF(SDL2MAIN_LIBRARY) 177 | ENDIF(NOT SDL2_BUILDING_LIBRARY) 178 | 179 | # For OS X, SDL2 uses Cocoa as a backend so it must link to Cocoa. 180 | # CMake doesn't display the -framework Cocoa string in the UI even 181 | # though it actually is there if I modify a pre-used variable. 182 | # I think it has something to do with the CACHE STRING. 183 | # So I use a temporary variable until the end so I can set the 184 | # "real" variable in one-shot. 185 | IF(APPLE) 186 | SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} "-framework Cocoa") 187 | ENDIF(APPLE) 188 | 189 | # For threads, as mentioned Apple doesn't need this. 190 | # In fact, there seems to be a problem if I used the Threads package 191 | # and try using this line, so I'm just skipping it entirely for OS X. 192 | IF(NOT APPLE) 193 | SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} ${CMAKE_THREAD_LIBS_INIT}) 194 | ENDIF(NOT APPLE) 195 | 196 | # For MinGW library 197 | IF(MINGW) 198 | SET(SDL2_LIBRARY_TEMP ${MINGW32_LIBRARY} ${SDL2_LIBRARY_TEMP}) 199 | ENDIF(MINGW) 200 | 201 | # Set the final string here so the GUI reflects the final state. 202 | SET(SDL2_LIBRARY ${SDL2_LIBRARY_TEMP} CACHE STRING "Where the SDL2 Library can be found") 203 | # Set the temp variable to INTERNAL so it is not seen in the CMake GUI 204 | SET(SDL2_LIBRARY_TEMP "${SDL2_LIBRARY_TEMP}" CACHE INTERNAL "") 205 | ENDIF(SDL2_LIBRARY_TEMP) 206 | 207 | INCLUDE(FindPackageHandleStandardArgs) 208 | 209 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2 REQUIRED_VARS SDL2_LIBRARY SDL2_INCLUDE_DIR) 210 | endif() 211 | -------------------------------------------------------------------------------- /ImguiDemoSdl/src/main/cpp/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "imgui.h" 3 | 4 | #include "logger.h" 5 | 6 | #ifdef __ANDROID__ 7 | #include 8 | #include "imgui_impl_sdl_es2.h" 9 | #include "imgui_impl_sdl_es3.h" 10 | #else 11 | #include "gl_glcore_3_3.h" 12 | #include "imgui_impl_sdl_gl3.h" 13 | #endif 14 | #include "teapot.h" 15 | 16 | #include 17 | #include 18 | 19 | /** 20 | * A convenience function to create a context for the specified window 21 | * @param w Pointer to SDL_Window 22 | * @return An SDL_Context value 23 | */ 24 | 25 | typedef bool(initImgui_t)(SDL_Window*); 26 | typedef bool(processEvent_t)(SDL_Event*); 27 | typedef void(newFrame_t)(SDL_Window*); 28 | typedef void(shutdown_t)(); 29 | 30 | static initImgui_t *initImgui; 31 | static processEvent_t *processEvent; 32 | static newFrame_t *newFrame; 33 | static shutdown_t *shutdown; 34 | 35 | static SDL_GLContext createCtx(SDL_Window *w) 36 | { 37 | // Prepare and create context 38 | #ifdef __ANDROID__ 39 | SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); 40 | SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); 41 | SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); 42 | #else 43 | SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); 44 | SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); 45 | SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); 46 | #endif 47 | SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); 48 | SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 6); 49 | SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5); 50 | SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0); 51 | 52 | SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); 53 | SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); 54 | 55 | SDL_GLContext ctx = SDL_GL_CreateContext(w); 56 | 57 | if (!ctx) 58 | { 59 | Log(LOG_ERROR) << "Could not create context! SDL reports error: " << SDL_GetError(); 60 | return ctx; 61 | } 62 | 63 | int major, minor, mask; 64 | int r, g, b, a, depth; 65 | SDL_GL_GetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, &mask); 66 | SDL_GL_GetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, &major); 67 | SDL_GL_GetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, &minor); 68 | 69 | SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &r); 70 | SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &g); 71 | SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &b); 72 | SDL_GL_GetAttribute(SDL_GL_ALPHA_SIZE, &a); 73 | 74 | SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &depth); 75 | 76 | const char* mask_desc; 77 | 78 | if (mask & SDL_GL_CONTEXT_PROFILE_CORE) { 79 | mask_desc = "core"; 80 | } else if (mask & SDL_GL_CONTEXT_PROFILE_COMPATIBILITY) { 81 | mask_desc = "compatibility"; 82 | } else if (mask & SDL_GL_CONTEXT_PROFILE_ES) { 83 | mask_desc = "es"; 84 | } else { 85 | mask_desc = "?"; 86 | } 87 | 88 | Log(LOG_INFO) << "Got context: " << major << "." << minor << mask_desc 89 | << ", R" << r << "G" << g << "B" << b << "A" << a << ", depth bits: " << depth; 90 | 91 | SDL_GL_MakeCurrent(w, ctx); 92 | #ifdef __ANDROID__ 93 | if (major == 3) 94 | { 95 | Log(LOG_INFO) << "Initializing ImGui for GLES3"; 96 | initImgui = ImGui_ImplSdlGLES3_Init; 97 | Log(LOG_INFO) << "Setting processEvent and newFrame functions appropriately"; 98 | processEvent = ImGui_ImplSdlGLES3_ProcessEvent; 99 | newFrame = ImGui_ImplSdlGLES3_NewFrame; 100 | shutdown = ImGui_ImplSdlGLES3_Shutdown; 101 | } 102 | else 103 | { 104 | Log(LOG_INFO) << "Initializing ImGui for GLES2"; 105 | initImgui = ImGui_ImplSdlGLES2_Init; 106 | Log(LOG_INFO) << "Setting processEvent and newFrame functions appropriately"; 107 | processEvent = ImGui_ImplSdlGLES2_ProcessEvent; 108 | newFrame = ImGui_ImplSdlGLES2_NewFrame; 109 | shutdown = ImGui_ImplSdlGLES2_Shutdown; 110 | } 111 | #else 112 | initImgui = ImGui_ImplSdlGL3_Init; 113 | processEvent = ImGui_ImplSdlGL3_ProcessEvent; 114 | newFrame = ImGui_ImplSdlGL3_NewFrame; 115 | shutdown = ImGui_ImplSdlGL3_Shutdown; 116 | #endif 117 | Log(LOG_INFO) << "Finished initialization"; 118 | return ctx; 119 | } 120 | 121 | 122 | int main(int argc, char** argv) 123 | { 124 | SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER); 125 | 126 | if (argc < 2) 127 | { 128 | Log(LOG_FATAL) << "Not enough arguments! Usage: " << argv[0] << " path_to_data_dir"; 129 | SDL_Quit(); 130 | return 1; 131 | } 132 | if (chdir(argv[1])) { 133 | Log(LOG_ERROR) << "Could not change directory properly!"; 134 | } else { 135 | dirent **namelist; 136 | int numdirs = scandir(".", &namelist, NULL, alphasort); 137 | if (numdirs < 0) { 138 | Log(LOG_ERROR) << "Could not list directory"; 139 | } else { 140 | for (int dirid = 0; dirid < numdirs; ++dirid) { 141 | Log(LOG_INFO) << "Got file: " << namelist[dirid]->d_name; 142 | } 143 | free(namelist); 144 | } 145 | } 146 | 147 | // Create window 148 | Log(LOG_INFO) << "Creating SDL_Window"; 149 | SDL_Window *window = SDL_CreateWindow("Demo App", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1280, 800, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE); 150 | SDL_GLContext ctx = createCtx(window); 151 | initImgui(window); 152 | 153 | // Load Fonts 154 | // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) 155 | ImGuiIO& io = ImGui::GetIO(); 156 | //io.Fonts->AddFontDefault(); 157 | //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); 158 | //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); 159 | io.Fonts->AddFontFromFileTTF("Roboto-Medium.ttf", 32.0f); 160 | 161 | bool show_test_window = true; 162 | bool show_another_window = false; 163 | ImVec4 clear_color = ImColor(114, 144, 154); 164 | 165 | Log(LOG_INFO) << "Entering main loop"; 166 | { 167 | 168 | bool done = false; 169 | float teapotRotation = 0; 170 | bool rotateSync = false; 171 | 172 | Teapot teapot; 173 | teapot.init(); 174 | 175 | int deltaX = 0, deltaY = 0; 176 | int prevX , prevY; 177 | SDL_GetMouseState(&prevX, &prevY); 178 | 179 | while (!done) { 180 | SDL_Event e; 181 | 182 | deltaX = 0; 183 | deltaY = 0; 184 | 185 | float deltaZoom = 0.0f; 186 | 187 | while (SDL_PollEvent(&e)) { 188 | bool handledByImGui = processEvent(&e); 189 | { 190 | switch (e.type) { 191 | case SDL_QUIT: 192 | done = true; 193 | break; 194 | case SDL_MOUSEBUTTONDOWN: 195 | prevX = e.button.x; 196 | prevY = e.button.y; 197 | break; 198 | case SDL_MOUSEMOTION: 199 | if (e.motion.state & SDL_BUTTON_LMASK) { 200 | deltaX += prevX - e.motion.x; 201 | deltaY += prevY - e.motion.y; 202 | prevX = e.motion.x; 203 | prevY = e.motion.y; 204 | } 205 | break; 206 | case SDL_MULTIGESTURE: 207 | if (e.mgesture.numFingers > 1) { 208 | deltaZoom += e.mgesture.dDist * 10.0f; 209 | } 210 | break; 211 | case SDL_MOUSEWHEEL: 212 | deltaZoom += e.wheel.y / 100.0f; 213 | break; 214 | default: 215 | break; 216 | } 217 | } 218 | } 219 | if (io.WantTextInput) { 220 | SDL_StartTextInput(); 221 | } else { 222 | SDL_StopTextInput(); 223 | } 224 | newFrame(window); 225 | // 1. Show a simple window 226 | // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug" 227 | { 228 | static float f = 0.0f; 229 | ImGui::Text("Hello, world!"); 230 | ImGui::SliderFloat("float", &f, 0.0f, 1.0f); 231 | ImGui::ColorEdit3("clear color", (float *) &clear_color); 232 | if (ImGui::Button("Test Window")) show_test_window ^= 1; 233 | if (ImGui::Button("Another Window")) show_another_window ^= 1; 234 | ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, 235 | ImGui::GetIO().Framerate); 236 | } 237 | 238 | // 2. Show another simple window, this time using an explicit Begin/End pair 239 | if (show_another_window) { 240 | ImGui::SetNextWindowSize(ImVec2(200, 100), ImGuiSetCond_FirstUseEver); 241 | ImGui::Begin("Another Window", &show_another_window); 242 | ImGui::Text("Hello"); 243 | ImGui::End(); 244 | } 245 | 246 | // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow() 247 | if (show_test_window) { 248 | ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); 249 | ImGui::ShowTestWindow(&show_test_window); 250 | } 251 | 252 | // 4. Show some controls for the teapot 253 | { 254 | ImGui::Begin("Teapot controls"); 255 | ImGui::SliderFloat("Teapot rotation", &teapotRotation, 0, 2 * M_PI); 256 | ImGui::Checkbox("Rotate synchronously", &rotateSync); 257 | ImGui::Text("Zoom value: %f", teapot.zoomValue()); 258 | ImGui::End(); 259 | } 260 | 261 | 262 | // Rendering 263 | glViewport(0, 0, (int) ImGui::GetIO().DisplaySize.x, (int) ImGui::GetIO().DisplaySize.y); 264 | glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); 265 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 266 | 267 | teapot.rotateTo(teapotRotation); 268 | if (rotateSync) 269 | teapot.rotateCameraTo(teapotRotation); 270 | 271 | if (!ImGui::IsMouseHoveringAnyWindow()) 272 | { 273 | if (std::abs(deltaZoom) > 0.001f) 274 | teapot.zoomBy(deltaZoom); 275 | if ((deltaX != 0) || (deltaY != 0)) 276 | teapot.rotateCameraBy(deltaX * 0.005f, deltaY * 0.005f); 277 | } 278 | teapot.draw(); 279 | ImGui::Render(); 280 | SDL_GL_SwapWindow(window); 281 | } 282 | } 283 | shutdown(); 284 | SDL_GL_DeleteContext(ctx); 285 | SDL_Quit(); 286 | return 0; 287 | } -------------------------------------------------------------------------------- /ImguiDemoSdl/src/main/cpp/src/teapotjs/demo.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009 The Chromium Authors. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are 6 | * met: 7 | * 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above 11 | * copyright notice, this list of conditions and the following disclaimer 12 | * in the documentation and/or other materials provided with the 13 | * distribution. 14 | * * Neither the name of Google Inc. nor the names of its 15 | * contributors may be used to endorse or promote products derived from 16 | * this software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | var gl = null; 32 | var g_width = 0; 33 | var g_height = 0; 34 | var g_bumpTexture = null; 35 | var g_envTexture = null; 36 | var g_programObject = null; 37 | var g_vbo = null; 38 | var g_elementVbo = null; 39 | var g_normalsOffset = 0; 40 | var g_tangentsOffset = 0; 41 | var g_binormalsOffset = 0; 42 | var g_texCoordsOffset = 0; 43 | var g_numElements = 0; 44 | 45 | // Uniform variables 46 | var g_worldLoc = 0; 47 | var g_worldInverseTransposeLoc = 0; 48 | var g_worldViewProjLoc = 0; 49 | var g_viewInverseLoc = 0; 50 | var g_normalSamplerLoc = 0; 51 | var g_envSamplerLoc = 0; 52 | 53 | var g_pendingTextureLoads = 0; 54 | 55 | // The "model" matrix is the "world" matrix in Standard Annotations 56 | // and Semantics 57 | var model = new Matrix4x4(); 58 | var view = new Matrix4x4(); 59 | var projection = new Matrix4x4(); 60 | 61 | var controller = null; 62 | 63 | function main() { 64 | var c = document.getElementById("c"); 65 | 66 | //c = WebGLDebugUtils.makeLostContextSimulatingCanvas(c); 67 | // tell the simulator when to lose context. 68 | //c.loseContextInNCalls(15); 69 | 70 | c.addEventListener('webglcontextlost', handleContextLost, false); 71 | c.addEventListener('webglcontextrestored', handleContextRestored, false); 72 | 73 | var ratio = window.devicePixelRatio ? window.devicePixelRatio : 1; 74 | c.width = 800 * ratio; 75 | c.height = 600 * ratio; 76 | gl = WebGLUtils.setupWebGL(c); 77 | if (!gl) 78 | return; 79 | g_width = c.width; 80 | g_height = c.height; 81 | controller = new CameraController(c); 82 | // Try the following (and uncomment the "pointer-events: none;" in 83 | // the index.html) to try the more precise hit detection 84 | // controller = new CameraController(document.getElementById("body"), c, gl); 85 | controller.onchange = function(xRot, yRot) { 86 | draw(); 87 | }; 88 | init(); 89 | } 90 | 91 | function log(msg) { 92 | if (window.console && window.console.log) { 93 | console.log(msg); 94 | } 95 | } 96 | 97 | function handleContextLost(e) { 98 | log("handle context lost"); 99 | e.preventDefault(); 100 | clearLoadingImages(); 101 | } 102 | 103 | function handleContextRestored() { 104 | log("handle context restored"); 105 | init(); 106 | } 107 | 108 | 109 | function output(str) { 110 | document.body.appendChild(document.createTextNode(str)); 111 | document.body.appendChild(document.createElement("br")); 112 | } 113 | 114 | function checkGLError() { 115 | var error = gl.getError(); 116 | if (error != gl.NO_ERROR && error != gl.CONTEXT_LOST_WEBGL) { 117 | var str = "GL Error: " + error; 118 | output(str); 119 | throw str; 120 | } 121 | } 122 | 123 | function init() { 124 | gl.enable(gl.DEPTH_TEST); 125 | // Can use this to make the background opaque 126 | // gl.clearColor(0.3, 0.2, 0.2, 1.); 127 | gl.clearColor(0.0, 0.0, 0.0, 0.0); 128 | initTeapot(); 129 | initShaders(); 130 | g_bumpTexture = loadTexture("bump.jpg"); 131 | g_envTexture = loadCubeMap("skybox", "jpg"); 132 | draw(); 133 | } 134 | 135 | function initTeapot() { 136 | g_vbo = gl.createBuffer(); 137 | gl.bindBuffer(gl.ARRAY_BUFFER, g_vbo); 138 | gl.bufferData(gl.ARRAY_BUFFER, 139 | teapotPositions.byteLength + 140 | teapotNormals.byteLength + 141 | teapotTangents.byteLength + 142 | teapotBinormals.byteLength + 143 | teapotTexCoords.byteLength, 144 | gl.STATIC_DRAW); 145 | g_normalsOffset = teapotPositions.byteLength; 146 | g_tangentsOffset = g_normalsOffset + teapotNormals.byteLength; 147 | g_binormalsOffset = g_tangentsOffset + teapotTangents.byteLength; 148 | g_texCoordsOffset = g_binormalsOffset + teapotBinormals.byteLength; 149 | gl.bufferSubData(gl.ARRAY_BUFFER, 0, teapotPositions); 150 | gl.bufferSubData(gl.ARRAY_BUFFER, g_normalsOffset, teapotNormals); 151 | gl.bufferSubData(gl.ARRAY_BUFFER, g_tangentsOffset, teapotTangents); 152 | gl.bufferSubData(gl.ARRAY_BUFFER, g_binormalsOffset, teapotBinormals); 153 | gl.bufferSubData(gl.ARRAY_BUFFER, g_texCoordsOffset, teapotTexCoords); 154 | 155 | g_elementVbo = gl.createBuffer(); 156 | gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, g_elementVbo); 157 | gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, teapotIndices, gl.STATIC_DRAW); 158 | g_numElements = teapotIndices.length; 159 | } 160 | 161 | var bumpReflectVertexSource = [ 162 | "attribute vec3 g_Position;", 163 | "attribute vec3 g_TexCoord0;", 164 | "attribute vec3 g_Tangent;", 165 | "attribute vec3 g_Binormal;", 166 | "attribute vec3 g_Normal;", 167 | "", 168 | "uniform mat4 world;", 169 | "uniform mat4 worldInverseTranspose;", 170 | "uniform mat4 worldViewProj;", 171 | "uniform mat4 viewInverse;", 172 | "", 173 | "varying vec2 texCoord;", 174 | "varying vec3 worldEyeVec;", 175 | "varying vec3 worldNormal;", 176 | "varying vec3 worldTangent;", 177 | "varying vec3 worldBinorm;", 178 | "", 179 | "void main() {", 180 | " gl_Position = worldViewProj * vec4(g_Position.xyz, 1.);", 181 | " texCoord.xy = g_TexCoord0.xy;", 182 | " worldNormal = (worldInverseTranspose * vec4(g_Normal, 1.)).xyz;", 183 | " worldTangent = (worldInverseTranspose * vec4(g_Tangent, 1.)).xyz;", 184 | " worldBinorm = (worldInverseTranspose * vec4(g_Binormal, 1.)).xyz;", 185 | " vec3 worldPos = (world * vec4(g_Position, 1.)).xyz;", 186 | " worldEyeVec = normalize(worldPos - viewInverse[3].xyz);", 187 | "}" 188 | ].join("\n"); 189 | 190 | var bumpReflectFragmentSource = [ 191 | "precision mediump float;\n", 192 | "const float bumpHeight = 0.2;", 193 | "", 194 | "uniform sampler2D normalSampler;", 195 | "uniform samplerCube envSampler;", 196 | "", 197 | "varying vec2 texCoord;", 198 | "varying vec3 worldEyeVec;", 199 | "varying vec3 worldNormal;", 200 | "varying vec3 worldTangent;", 201 | "varying vec3 worldBinorm;", 202 | "", 203 | "void main() {", 204 | " vec2 bump = (texture2D(normalSampler, texCoord.xy).xy * 2.0 - 1.0) * bumpHeight;", 205 | " vec3 normal = normalize(worldNormal);", 206 | " vec3 tangent = normalize(worldTangent);", 207 | " vec3 binormal = normalize(worldBinorm);", 208 | " vec3 nb = normal + bump.x * tangent + bump.y * binormal;", 209 | " nb = normalize(nb);", 210 | " vec3 worldEye = normalize(worldEyeVec);", 211 | " vec3 lookup = reflect(worldEye, nb);", 212 | " vec4 color = textureCube(envSampler, lookup);", 213 | " gl_FragColor = color;", 214 | "}" 215 | ].join("\n"); 216 | 217 | function loadShader(type, shaderSrc) { 218 | var shader = gl.createShader(type); 219 | // Load the shader source 220 | gl.shaderSource(shader, shaderSrc); 221 | // Compile the shader 222 | gl.compileShader(shader); 223 | // Check the compile status 224 | if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS) && 225 | !gl.isContextLost()) { 226 | var infoLog = gl.getShaderInfoLog(shader); 227 | output("Error compiling shader:\n" + infoLog); 228 | gl.deleteShader(shader); 229 | return null; 230 | } 231 | return shader; 232 | } 233 | 234 | function initShaders() { 235 | var vertexShader = loadShader(gl.VERTEX_SHADER, bumpReflectVertexSource); 236 | var fragmentShader = loadShader(gl.FRAGMENT_SHADER, bumpReflectFragmentSource); 237 | // Create the program object 238 | var programObject = gl.createProgram(); 239 | gl.attachShader(programObject, vertexShader); 240 | gl.attachShader(programObject, fragmentShader); 241 | // Bind attributes 242 | gl.bindAttribLocation(programObject, 0, "g_Position"); 243 | gl.bindAttribLocation(programObject, 1, "g_TexCoord0"); 244 | gl.bindAttribLocation(programObject, 2, "g_Tangent"); 245 | gl.bindAttribLocation(programObject, 3, "g_Binormal"); 246 | gl.bindAttribLocation(programObject, 4, "g_Normal"); 247 | // Link the program 248 | gl.linkProgram(programObject); 249 | // Check the link status 250 | var linked = gl.getProgramParameter(programObject, gl.LINK_STATUS); 251 | if (!linked && !gl.isContextLost()) { 252 | var infoLog = gl.getProgramInfoLog(programObject); 253 | output("Error linking program:\n" + infoLog); 254 | gl.deleteProgram(programObject); 255 | return; 256 | } 257 | g_programObject = programObject; 258 | // Look up uniform locations 259 | g_worldLoc = gl.getUniformLocation(g_programObject, "world"); 260 | g_worldInverseTransposeLoc = gl.getUniformLocation(g_programObject, "worldInverseTranspose"); 261 | g_worldViewProjLoc = gl.getUniformLocation(g_programObject, "worldViewProj"); 262 | g_viewInverseLoc = gl.getUniformLocation(g_programObject, "viewInverse"); 263 | g_normalSamplerLoc = gl.getUniformLocation(g_programObject, "normalSampler"); 264 | g_envSamplerLoc = gl.getUniformLocation(g_programObject, "envSampler"); 265 | checkGLError(); 266 | } 267 | 268 | function draw() { 269 | // Note: the viewport is automatically set up to cover the entire Canvas. 270 | gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 271 | checkGLError(); 272 | 273 | // For now, don't render if we have incomplete textures, just to 274 | // avoid accidentally incurring OpenGL errors -- although we should 275 | // be fully able to load textures in in the background 276 | if (g_pendingTextureLoads > 0) { 277 | return; 278 | } 279 | 280 | // Set up the model, view and projection matrices 281 | projection.loadIdentity(); 282 | projection.perspective(45, g_width / g_height, 10, 500); 283 | view.loadIdentity(); 284 | view.translate(0, -10, -100.0); 285 | 286 | // Add in camera controller's rotation 287 | model.loadIdentity(); 288 | model.rotate(controller.xRot, 1, 0, 0); 289 | model.rotate(controller.yRot, 0, 1, 0); 290 | 291 | // Correct for initial placement and orientation of model 292 | model.translate(0, -10, 0); 293 | model.rotate(90, 1, 0, 0); 294 | 295 | gl.useProgram(g_programObject); 296 | 297 | // Compute necessary matrices 298 | var mvp = new Matrix4x4(); 299 | mvp.multiply(model); 300 | mvp.multiply(view); 301 | mvp.multiply(projection); 302 | var worldInverseTranspose = model.inverse(); 303 | worldInverseTranspose.transpose(); 304 | var viewInverse = view.inverse(); 305 | 306 | // Set up uniforms 307 | gl.uniformMatrix4fv(g_worldLoc, gl.FALSE, new Float32Array(model.elements)); 308 | gl.uniformMatrix4fv(g_worldInverseTransposeLoc, gl.FALSE, new Float32Array(worldInverseTranspose.elements)); 309 | gl.uniformMatrix4fv(g_worldViewProjLoc, gl.FALSE, new Float32Array(mvp.elements)); 310 | gl.uniformMatrix4fv(g_viewInverseLoc, gl.FALSE, new Float32Array(viewInverse.elements)); 311 | gl.activeTexture(gl.TEXTURE0); 312 | gl.bindTexture(gl.TEXTURE_2D, g_bumpTexture); 313 | gl.uniform1i(g_normalSamplerLoc, 0); 314 | gl.activeTexture(gl.TEXTURE1); 315 | gl.bindTexture(gl.TEXTURE_CUBE_MAP, g_envTexture); 316 | gl.uniform1i(g_envSamplerLoc, 1); 317 | checkGLError(); 318 | 319 | // Bind and set up vertex streams 320 | gl.bindBuffer(gl.ARRAY_BUFFER, g_vbo); 321 | gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0); 322 | gl.enableVertexAttribArray(0); 323 | gl.vertexAttribPointer(1, 3, gl.FLOAT, false, 0, g_texCoordsOffset); 324 | gl.enableVertexAttribArray(1); 325 | gl.vertexAttribPointer(2, 3, gl.FLOAT, false, 0, g_tangentsOffset); 326 | gl.enableVertexAttribArray(2); 327 | gl.vertexAttribPointer(3, 3, gl.FLOAT, false, 0, g_binormalsOffset); 328 | gl.enableVertexAttribArray(3); 329 | gl.vertexAttribPointer(4, 3, gl.FLOAT, false, 0, g_normalsOffset); 330 | gl.enableVertexAttribArray(4); 331 | gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, g_elementVbo); 332 | checkGLError(); 333 | gl.drawElements(gl.TRIANGLES, g_numElements, gl.UNSIGNED_SHORT, 0); 334 | } 335 | 336 | // Array of images curently loading 337 | var g_loadingImages = []; 338 | 339 | // Clears all the images currently loading. 340 | // This is used to handle context lost events. 341 | function clearLoadingImages() { 342 | for (var ii = 0; ii < g_loadingImages.length; ++ii) { 343 | g_loadingImages[ii].onload = undefined; 344 | } 345 | g_loadingImages = []; 346 | } 347 | 348 | function loadTexture(src) { 349 | var texture = gl.createTexture(); 350 | gl.bindTexture(gl.TEXTURE_2D, texture); 351 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); 352 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); 353 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT); 354 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT); 355 | ++g_pendingTextureLoads; 356 | var image = new Image(); 357 | g_loadingImages.push(image); 358 | image.onload = function() { 359 | g_loadingImages.splice(g_loadingImages.indexOf(image), 1); 360 | --g_pendingTextureLoads; 361 | gl.bindTexture(gl.TEXTURE_2D, texture); 362 | gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); 363 | gl.texImage2D( 364 | gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image); 365 | checkGLError(); 366 | draw(); 367 | }; 368 | image.src = src; 369 | return texture; 370 | } 371 | 372 | function loadCubeMap(base, suffix) { 373 | var texture = gl.createTexture(); 374 | gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture); 375 | checkGLError(); 376 | gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); 377 | checkGLError(); 378 | gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); 379 | checkGLError(); 380 | // FIXME: TEXTURE_WRAP_R doesn't exist in OpenGL ES?! 381 | // gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_R, gl.CLAMP_TO_EDGE); 382 | // checkGLError(); 383 | gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR); 384 | checkGLError(); 385 | gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR); 386 | checkGLError(); 387 | var faces = [["posx", gl.TEXTURE_CUBE_MAP_POSITIVE_X], 388 | ["negx", gl.TEXTURE_CUBE_MAP_NEGATIVE_X], 389 | ["posy", gl.TEXTURE_CUBE_MAP_POSITIVE_Y], 390 | ["negy", gl.TEXTURE_CUBE_MAP_NEGATIVE_Y], 391 | ["posz", gl.TEXTURE_CUBE_MAP_POSITIVE_Z], 392 | ["negz", gl.TEXTURE_CUBE_MAP_NEGATIVE_Z]]; 393 | for (var i = 0; i < faces.length; i++) { 394 | var url = base + "-" + faces[i][0] + "." + suffix; 395 | var face = faces[i][1]; 396 | ++g_pendingTextureLoads; 397 | var image = new Image(); 398 | g_loadingImages.push(image); 399 | // Javascript has function, not block, scope. 400 | // See "JavaScript: The Good Parts", Chapter 4, "Functions", 401 | // section "Scope". 402 | image.onload = function(texture, face, image, url) { 403 | return function() { 404 | g_loadingImages.splice(g_loadingImages.indexOf(image), 1); 405 | --g_pendingTextureLoads; 406 | gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture); 407 | gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false); 408 | gl.texImage2D( 409 | face, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image); 410 | checkGLError(); 411 | draw(); 412 | } 413 | }(texture, face, image, url); 414 | image.src = url; 415 | } 416 | return texture; 417 | } 418 | -------------------------------------------------------------------------------- /ImguiDemoSdl/src/main/cpp/src/teapot.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by sf on 8/9/17. 3 | // 4 | 5 | #include "teapot.h" 6 | 7 | #define STB_IMAGE_IMPLEMENTATION 8 | #include "stb_image.h" 9 | 10 | #include "teapot.inl" 11 | #include 12 | #include 13 | //#include 14 | #include "logger.h" 15 | 16 | #ifdef GL_PROFILE_GL3 17 | GLuint Teapot::g_vao = 0; 18 | #endif 19 | 20 | static const std::vector> faces { 21 | {"skybox-negx.jpg", GL_TEXTURE_CUBE_MAP_NEGATIVE_X}, 22 | {"skybox-negy.jpg", GL_TEXTURE_CUBE_MAP_NEGATIVE_Y}, 23 | {"skybox-negz.jpg", GL_TEXTURE_CUBE_MAP_NEGATIVE_Z}, 24 | {"skybox-posx.jpg", GL_TEXTURE_CUBE_MAP_POSITIVE_X}, 25 | {"skybox-posy.jpg", GL_TEXTURE_CUBE_MAP_POSITIVE_Y}, 26 | {"skybox-posz.jpg", GL_TEXTURE_CUBE_MAP_POSITIVE_Z} 27 | }; 28 | 29 | const char* vtxShader = 30 | #ifdef GL_PROFILE_GL3 31 | "#version 120\n" 32 | #else 33 | "#version 100\n" 34 | #endif 35 | "attribute vec3 g_Position;\n" 36 | "attribute vec3 g_TexCoord0;\n" 37 | "attribute vec3 g_Tangent;\n" 38 | "attribute vec3 g_Binormal;\n" 39 | "attribute vec3 g_Normal;\n" 40 | "\n" 41 | "uniform mat4 world;\n" 42 | "uniform mat4 worldInverseTranspose;\n" 43 | "uniform mat4 worldViewProj;\n" 44 | "uniform mat4 viewInverse;\n" 45 | "\n" 46 | "varying vec2 texCoord;\n" 47 | "varying vec3 worldEyeVec;\n" 48 | "varying vec3 worldNormal;\n" 49 | "varying vec3 worldTangent;\n" 50 | "varying vec3 worldBinorm;\n" 51 | "\n" 52 | "void main() {\n" 53 | " gl_Position = worldViewProj * vec4(g_Position, 1.0);\n" 54 | " texCoord.x = g_TexCoord0.x;\n" 55 | " texCoord.y = 1.0-g_TexCoord0.y;\n" 56 | " worldNormal = (worldInverseTranspose * vec4(g_Normal, 1.0)).xyz;\n" 57 | " worldTangent = (worldInverseTranspose * vec4(g_Tangent, 1.0)).xyz;\n" 58 | " worldBinorm = (worldInverseTranspose * vec4(g_Binormal, 1.0)).xyz;\n" 59 | " vec3 worldPos = (world * vec4(g_Position, 1.0)).xyz;\n" 60 | " worldEyeVec = normalize(worldPos - viewInverse[3].xyz);\n" 61 | "}"; 62 | 63 | const char* fragShader = 64 | #ifdef GL_PROFILE_GL3 65 | "#version 120\n" 66 | #else 67 | "#version 100\n" 68 | "precision mediump float;\n" 69 | #endif 70 | "const float bumpHeight = 0.5;\n" 71 | "uniform sampler2D normalSampler;\n" 72 | "uniform samplerCube envSampler;\n" 73 | "\n" 74 | "varying vec2 texCoord;\n" 75 | "varying vec3 worldEyeVec;\n" 76 | "varying vec3 worldNormal;\n" 77 | "varying vec3 worldTangent;\n" 78 | "varying vec3 worldBinorm;\n" 79 | "\n" 80 | "void main() {\n" 81 | " vec2 bump = (texture2D(normalSampler, texCoord.xy).xy * 2.0 - 1.0) * bumpHeight;\n" 82 | " vec3 normal = normalize(worldNormal);\n" 83 | " vec3 tangent = normalize(worldTangent);\n" 84 | " vec3 binormal = normalize(worldBinorm);\n" 85 | " vec3 nb = normal + bump.x * tangent + bump.y * binormal;\n" 86 | " nb = normalize(nb);\n" 87 | " vec3 worldEye = normalize(worldEyeVec);\n" 88 | " vec3 lookup = reflect(worldEye, nb);\n" 89 | " vec4 color = textureCube(envSampler, lookup);\n" 90 | " gl_FragColor = color;\n" 91 | "}"; 92 | 93 | Teapot::Teapot() : num_vertices(0), num_indices(0), ibo(0), vbo(0), tex_skybox(0), 94 | tex_bump(0), program(0), rotX(0.0f), rotY(0.0f), zoom(1.0f), 95 | camRX(0.0f), camRY(0.0f), 96 | addRotX(0.0f), addRotY(0.0f), addZoom(0.0f), addCamRX(0.0f), addCamRY(0.0f){ } 97 | 98 | Teapot::~Teapot() 99 | { 100 | if (program) 101 | { 102 | glDeleteProgram(program); 103 | } 104 | if (ibo) 105 | { 106 | glDeleteBuffers(1, &ibo); 107 | } 108 | if (vbo) 109 | { 110 | glDeleteBuffers(1, &vbo); 111 | } 112 | if (tex_skybox) 113 | { 114 | glDeleteTextures(1, &tex_skybox); 115 | } 116 | if (tex_bump) 117 | { 118 | glDeleteTextures(1, &tex_bump); 119 | } 120 | } 121 | 122 | #define glCheckError() {GLenum error = glGetError(); if (error != GL_NO_ERROR) {Log(LOG_ERROR) << "GL error at " << __FILE__ << "@" << __LINE__ << ": " << error << " (" << errorToStr(error) << ")";}} 123 | 124 | static const char* errorToStr(GLenum error) 125 | { 126 | switch(error) 127 | { 128 | case GL_INVALID_ENUM: 129 | return "GL_INVALID_ENUM"; 130 | case GL_INVALID_OPERATION: 131 | return "GL_INVALID_OPERATION"; 132 | case GL_INVALID_VALUE: 133 | return "GL_INVALID_VALUE"; 134 | #ifdef GL_INVALID_INDEX 135 | case GL_INVALID_INDEX: 136 | return "GL_INVALID_INDEX"; 137 | #endif // GL_INVALID_INDEX 138 | default: 139 | return "Unknown error"; 140 | } 141 | } 142 | 143 | bool Teapot::init() 144 | { 145 | #ifdef GL_PROFILE_GL3 146 | if (g_vao == 0) 147 | { 148 | glGenVertexArrays(1, &g_vao); 149 | glBindVertexArray(g_vao); 150 | } 151 | #endif 152 | num_indices = sizeof(teapotIndices) / sizeof(teapotIndices[0]); 153 | num_vertices = (sizeof(teapotPositions) / sizeof(teapotPositions[0])) / 3; 154 | 155 | std::vector bufferData(num_vertices); 156 | for (int i = 0; i < num_vertices; ++i) 157 | { 158 | bufferData[i].pos = glm::vec3{teapotPositions[3*i], teapotPositions[3*i+1], teapotPositions[3*i+2]}; 159 | bufferData[i].norm = glm::vec3{teapotNormals[3*i], teapotNormals[3*i+1], teapotNormals[3*i+2]}; 160 | bufferData[i].tangent = glm::vec3{teapotTangents[3*i], teapotTangents[3*i+1], teapotTangents[3*i+2]}; 161 | bufferData[i].binorm = glm::vec3{teapotBinormals[3*i], teapotBinormals[3*i+1], teapotBinormals[3*i+2]}; 162 | bufferData[i].texcoord = glm::vec3{teapotTexCoords[3*i], teapotTexCoords[3*i+1], teapotTexCoords[3*i+2]}; 163 | } 164 | 165 | glGenBuffers(1, &vbo); 166 | glBindBuffer(GL_ARRAY_BUFFER, vbo); 167 | glBufferData(GL_ARRAY_BUFFER, num_vertices * sizeof(vtxData), bufferData.data(), GL_STATIC_DRAW); 168 | 169 | glCheckError(); 170 | 171 | glGenBuffers(1, &ibo); 172 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); 173 | glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(teapotIndices), teapotIndices, GL_STATIC_DRAW); 174 | 175 | glCheckError(); 176 | 177 | glGenTextures(1, &tex_skybox); 178 | glBindTexture(GL_TEXTURE_CUBE_MAP, tex_skybox); 179 | glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 180 | glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 181 | glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 182 | glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 183 | for(const auto& face: faces) 184 | { 185 | int x, y, channels; 186 | auto data = stbi_load(face.first, &x, &y, &channels, 0); 187 | if (data == NULL) 188 | { 189 | Log(LOG_ERROR) << "Could not load " << face.first; 190 | } 191 | glTexImage2D(face.second, 0, GL_RGB, x, y, 0, GL_RGB, GL_UNSIGNED_BYTE, data); 192 | stbi_image_free(data); 193 | } 194 | 195 | glCheckError(); 196 | 197 | glGenTextures(1, &tex_bump); 198 | glBindTexture(GL_TEXTURE_2D, tex_bump); 199 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 200 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 201 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 202 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 203 | { 204 | int x, y, channels; 205 | auto data = stbi_load("bump.jpg", &x, &y, &channels, 0); 206 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, x, y, 0, GL_RGB, GL_UNSIGNED_BYTE, data); 207 | stbi_image_free(data); 208 | } 209 | glCheckError(); 210 | 211 | if (!compileShaders()) 212 | { 213 | Log(LOG_ERROR) << "Initialization failed"; 214 | return false; 215 | } 216 | glCheckError(); 217 | 218 | GLint viewport[4]; 219 | glGetIntegerv(GL_VIEWPORT, viewport); 220 | GLfloat aspect = (GLfloat)viewport[2] / (GLfloat)viewport[3]; 221 | 222 | glm::mat4 projection = glm::perspective(45.0f, aspect, 10.0f, 500.0f); 223 | glm::mat4 view = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, -10.0f, -100.0f)); 224 | glm::mat4 model = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, -10.0f, 0.0f)); 225 | model = glm::rotate(model, (float)M_PI_2, glm::vec3(1.0f, 0.0f, 0.0f)); 226 | 227 | glm::mat4 mvp = projection * view * model; 228 | glm::mat4 worldInverseTranspose = glm::inverse(model); 229 | worldInverseTranspose = glm::transpose(worldInverseTranspose); 230 | glm::mat4 viewInverse = glm::inverse(view); 231 | 232 | unfData.world = model; 233 | unfData.worldInverseTranspose = worldInverseTranspose; 234 | unfData.viewInverse = viewInverse; 235 | unfData.worldViewProj = mvp; 236 | 237 | return true; 238 | } 239 | 240 | float Teapot::zoomValue() {return zoom;} 241 | 242 | void Teapot::draw() 243 | { 244 | // Apply rotations and zoom, recalculate matrices 245 | rotX += addRotX; 246 | rotY += addRotY; 247 | zoom += addZoom; 248 | 249 | if (zoom > 3.0f) 250 | { 251 | zoom = 3.0f; 252 | } 253 | if (zoom < 0.5f) 254 | { 255 | zoom = 0.5f; 256 | } 257 | 258 | camRX += addCamRX; 259 | camRY += addCamRY; 260 | 261 | const GLfloat clampEps = 0.00001f; 262 | 263 | if (camRX > M_PI * 2) 264 | { 265 | camRX -= M_PI * 2; 266 | } 267 | if (camRX < - M_PI * 2) 268 | { 269 | camRX += M_PI * 2; 270 | } 271 | if (camRY > (M_PI_2 - clampEps)) 272 | { 273 | camRY = M_PI_2 - clampEps; 274 | } 275 | if (camRY < - (M_PI_2 - clampEps)) 276 | { 277 | camRY = - (M_PI_2 - clampEps); 278 | } 279 | 280 | addRotX = 0; 281 | addRotY = 0; 282 | addZoom = 0; 283 | 284 | addCamRX = 0; 285 | addCamRY = 0; 286 | 287 | GLint viewport[4]; 288 | glGetIntegerv(GL_VIEWPORT, viewport); 289 | GLfloat aspect = (GLfloat) viewport[2] / (GLfloat) viewport[3]; 290 | 291 | const GLfloat camDistance = 100.0f; 292 | 293 | glm::vec3 cameraPos = glm::vec3(camDistance * cos(camRX) * cos(camRY), camDistance * sin(camRY), camDistance * sin(camRX) * cos(camRY)); 294 | 295 | //cameraPos = (glm::rotate(glm::mat4(1.0f), rotX, glm::vec3(0.0f, 1.0f, 0.0f)) * glm::rotate(glm::mat4(1.0f), rotY, glm::vec3(0.0f, 0.0f, 1.0f)) * glm::vec4(cameraPos, 1.0f)); 296 | 297 | glm::mat4 projection = glm::perspective(glm::radians(45.0f / zoom), aspect, 10.0f, 500.0f); 298 | glm::mat4 view = glm::lookAt(cameraPos, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f)); 299 | /*glm::mat4 model = glm::rotate(glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, -10.0f, 0.0f)), 300 | -(GLfloat)M_PI_2, 301 | glm::vec3(1.0f, 0.0f, 0.0f)); */ 302 | glm::mat4 model = glm::mat4(1.0f); 303 | model = glm::translate(model, glm::vec3(0.0f, -20.0f, 0.0f)); 304 | model = glm::rotate(model, rotY, glm::vec3(0.0f, 0.0f, 1.0f)); 305 | model = glm::rotate(model, -rotX, glm::vec3(0.0f, 1.0f, 0.0f)); 306 | model = glm::rotate(model, -(GLfloat)M_PI_2, glm::vec3(1.0f, 0.0f, 0.0f)); 307 | 308 | glm::mat4 mvp = projection * view * model; 309 | glm::mat4 worldInverseTranspose = glm::transpose(glm::inverse(model)); 310 | glm::mat4 viewInverse = glm::inverse(view); 311 | 312 | unfData.world = model; 313 | unfData.worldInverseTranspose = worldInverseTranspose; 314 | unfData.viewInverse = viewInverse; 315 | unfData.worldViewProj = mvp; 316 | 317 | glUseProgram(program); 318 | #ifdef GL_PROFILE_GL3 319 | glBindVertexArray(g_vao); 320 | #endif 321 | 322 | glEnable(GL_DEPTH_TEST); 323 | 324 | glCheckError(); 325 | glBindBuffer(GL_ARRAY_BUFFER, vbo); 326 | glCheckError(); 327 | glVertexAttribPointer(attribs.g_Position, 3, GL_FLOAT, GL_FALSE, sizeof(vtxData), (void*)offsetof(vtxData, pos)); 328 | glEnableVertexAttribArray(attribs.g_Position); 329 | glCheckError(); 330 | 331 | glVertexAttribPointer(attribs.g_Normal, 3, GL_FLOAT, GL_FALSE, sizeof(vtxData), (void*)offsetof(vtxData, norm)); 332 | glEnableVertexAttribArray(attribs.g_Normal); 333 | glCheckError(); 334 | 335 | glVertexAttribPointer(attribs.g_TexCoord0, 3, GL_FLOAT, GL_FALSE, sizeof(vtxData), (void*)offsetof(vtxData, texcoord)); 336 | glEnableVertexAttribArray(attribs.g_TexCoord0); 337 | glCheckError(); 338 | 339 | glVertexAttribPointer(attribs.g_Tangent, 3, GL_FLOAT, GL_FALSE, sizeof(vtxData), (void*)offsetof(vtxData, tangent)); 340 | glEnableVertexAttribArray(attribs.g_Tangent); 341 | glCheckError(); 342 | 343 | glVertexAttribPointer(attribs.g_Binormal, 3, GL_FLOAT, GL_FALSE, sizeof(vtxData), (void*)offsetof(vtxData, binorm)); 344 | glEnableVertexAttribArray(attribs.g_Binormal); 345 | glCheckError(); 346 | 347 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); 348 | 349 | glCheckError(); 350 | 351 | glUniformMatrix4fv(uniforms.world, 1, GL_FALSE, &unfData.world[0][0]); 352 | glUniformMatrix4fv(uniforms.worldViewProj, 1, GL_FALSE, &unfData.worldViewProj[0][0]); 353 | glUniformMatrix4fv(uniforms.worldInverseTranspose, 1, GL_FALSE, &unfData.worldInverseTranspose[0][0]); 354 | glUniformMatrix4fv(uniforms.viewInverse, 1, GL_FALSE, &unfData.viewInverse[0][0]); 355 | 356 | glCheckError(); 357 | 358 | glActiveTexture(GL_TEXTURE0); 359 | glBindTexture(GL_TEXTURE_2D, tex_bump); 360 | glUniform1i(uniforms.normalSampler, 0); 361 | glActiveTexture(GL_TEXTURE1); 362 | glBindTexture(GL_TEXTURE_CUBE_MAP, tex_skybox); 363 | glUniform1i(uniforms.envSampler, 1); 364 | 365 | glDrawElements(GL_TRIANGLES, num_indices, GL_UNSIGNED_SHORT, 0); 366 | } 367 | 368 | void Teapot::rotateBy(float angleX, float angleY) 369 | { 370 | addRotX += angleX; 371 | addRotY += angleY; 372 | } 373 | 374 | void Teapot::rotateTo(float angleX) 375 | { 376 | rotX = angleX; 377 | } 378 | 379 | void Teapot::rotateCameraTo(float angleX) 380 | { 381 | camRX = angleX; 382 | } 383 | 384 | void Teapot::rotateCameraBy(float angleX, float angleY) 385 | { 386 | addCamRX -= angleX; 387 | addCamRY -= angleY; 388 | } 389 | 390 | void Teapot::zoomBy(float zoomFactor) 391 | { 392 | addRotX = 0; 393 | addRotY = 0; 394 | addCamRX = 0; 395 | addCamRY = 0; 396 | addZoom += zoomFactor; 397 | } 398 | 399 | static GLint compileShader(GLenum shaderType, const char* shaderSrc) 400 | { 401 | GLuint shader = glCreateShader(shaderType); 402 | glShaderSource(shader, 1, &shaderSrc, NULL); 403 | glCompileShader(shader); 404 | int status; 405 | glGetShaderiv(shader, GL_COMPILE_STATUS, &status); 406 | if (status != GL_TRUE) 407 | { 408 | // Assume we only care about vertex and fragment shaders 409 | Log(LOG_ERROR) << "Could not compile shader! Shader type: " << ((shaderType == GL_VERTEX_SHADER) ? "vertex" : "fragment"); 410 | GLint logLength; 411 | glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength); 412 | std::vector infoLog(logLength + 1); 413 | glGetShaderInfoLog(shader, infoLog.size(), &logLength, infoLog.data()); 414 | Log(LOG_ERROR) << "Error log: " << infoLog.data(); 415 | Log(LOG_ERROR) << "Shader source: " << shaderSrc; 416 | glDeleteShader(shader); 417 | return -1; 418 | } 419 | return shader; 420 | } 421 | 422 | bool Teapot::compileShaders() { 423 | GLint vertexShader = compileShader(GL_VERTEX_SHADER, vtxShader); 424 | GLint fragmentShader = compileShader(GL_FRAGMENT_SHADER, fragShader); 425 | if (vertexShader < 0 || fragmentShader < 0) 426 | { 427 | // Delete any shaders that were actually compiled 428 | if (vertexShader >= 0) {glDeleteShader(vertexShader);} 429 | if (fragmentShader >= 0) {glDeleteShader(fragmentShader);} 430 | return false; 431 | } 432 | 433 | program = glCreateProgram(); 434 | glAttachShader(program, vertexShader); 435 | glAttachShader(program, fragmentShader); 436 | glLinkProgram(program); 437 | GLint status; 438 | glGetProgramiv(program, GL_LINK_STATUS, &status); 439 | if (status != GL_TRUE) 440 | { 441 | Log(LOG_ERROR) << "Could not link shaders; interface mismatch?"; 442 | GLint logLength; 443 | glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength); 444 | std::vector infoLog(logLength + 1); 445 | glGetProgramInfoLog(program, infoLog.size(), &logLength, infoLog.data()); 446 | Log(LOG_ERROR) << "Error log: " << infoLog.data(); 447 | glDeleteShader(vertexShader); 448 | glDeleteShader(fragmentShader); 449 | glDeleteProgram(program); 450 | return false; 451 | } 452 | 453 | // Get all attribute/uniform locations 454 | 455 | attribs.g_Position = glGetAttribLocation(program, "g_Position"); 456 | attribs.g_TexCoord0 = glGetAttribLocation(program, "g_TexCoord0"); 457 | attribs.g_Tangent = glGetAttribLocation(program, "g_Tangent"); 458 | attribs.g_Binormal = glGetAttribLocation(program, "g_Binormal"); 459 | attribs.g_Normal = glGetAttribLocation(program, "g_Normal"); 460 | 461 | uniforms.world = glGetUniformLocation(program, "world"); 462 | uniforms.worldInverseTranspose = glGetUniformLocation(program, "worldInverseTranspose"); 463 | uniforms.worldViewProj = glGetUniformLocation(program, "worldViewProj"); 464 | uniforms.viewInverse = glGetUniformLocation(program, "viewInverse"); 465 | uniforms.normalSampler = glGetUniformLocation(program, "normalSampler"); 466 | uniforms.envSampler = glGetUniformLocation(program, "envSampler"); 467 | 468 | return true; 469 | } 470 | -------------------------------------------------------------------------------- /ImguiDemoSdl/src/main/cpp/src/imgui_impl/imgui_impl_sdl_gl3.cpp: -------------------------------------------------------------------------------- 1 | // ImGui SDL2 binding with OpenGL3 2 | // In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. 3 | 4 | // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. 5 | // If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). 6 | // If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. 7 | // https://github.com/ocornut/imgui 8 | #ifdef GL_PROFILE_GL3 9 | 10 | #include "imgui.h" 11 | #include "imgui_impl_sdl_gl3.h" 12 | 13 | // SDL,GL3W 14 | #include 15 | #include 16 | //#include // This example is using gl3w to access OpenGL functions (because it is small). You may use glew/glad/glLoadGen/etc. whatever already works for you. 17 | #include "gl_glcore_3_3.h" 18 | 19 | // Data 20 | static double g_Time = 0.0f; 21 | static bool g_MousePressed[3] = { false, false, false }; 22 | static float g_MouseWheel = 0.0f; 23 | static GLuint g_FontTexture = 0; 24 | static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; 25 | static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; 26 | static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; 27 | static unsigned int g_VboHandle = 0, g_VaoHandle = 0, g_ElementsHandle = 0; 28 | 29 | // This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) 30 | // If text or lines are blurry when integrating ImGui in your engine: 31 | // - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) 32 | void ImGui_ImplSdlGL3_RenderDrawLists(ImDrawData* draw_data) 33 | { 34 | // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) 35 | ImGuiIO& io = ImGui::GetIO(); 36 | int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); 37 | int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); 38 | if (fb_width == 0 || fb_height == 0) 39 | return; 40 | draw_data->ScaleClipRects(io.DisplayFramebufferScale); 41 | 42 | // Backup GL state 43 | GLint last_active_texture; glGetIntegerv(GL_ACTIVE_TEXTURE, &last_active_texture); 44 | glActiveTexture(GL_TEXTURE0); 45 | GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); 46 | GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); 47 | GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); 48 | GLint last_element_array_buffer; glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_element_array_buffer); 49 | GLint last_vertex_array; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); 50 | GLint last_blend_src_rgb; glGetIntegerv(GL_BLEND_SRC_RGB, &last_blend_src_rgb); 51 | GLint last_blend_dst_rgb; glGetIntegerv(GL_BLEND_DST_RGB, &last_blend_dst_rgb); 52 | GLint last_blend_src_alpha; glGetIntegerv(GL_BLEND_SRC_ALPHA, &last_blend_src_alpha); 53 | GLint last_blend_dst_alpha; glGetIntegerv(GL_BLEND_DST_ALPHA, &last_blend_dst_alpha); 54 | GLint last_blend_equation_rgb; glGetIntegerv(GL_BLEND_EQUATION_RGB, &last_blend_equation_rgb); 55 | GLint last_blend_equation_alpha; glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &last_blend_equation_alpha); 56 | GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); 57 | GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box); 58 | GLboolean last_enable_blend = glIsEnabled(GL_BLEND); 59 | GLboolean last_enable_cull_face = glIsEnabled(GL_CULL_FACE); 60 | GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST); 61 | GLboolean last_enable_scissor_test = glIsEnabled(GL_SCISSOR_TEST); 62 | 63 | // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled 64 | glEnable(GL_BLEND); 65 | glBlendEquation(GL_FUNC_ADD); 66 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 67 | glDisable(GL_CULL_FACE); 68 | glDisable(GL_DEPTH_TEST); 69 | glEnable(GL_SCISSOR_TEST); 70 | 71 | // Setup viewport, orthographic projection matrix 72 | glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); 73 | const float ortho_projection[4][4] = 74 | { 75 | { 2.0f/io.DisplaySize.x, 0.0f, 0.0f, 0.0f }, 76 | { 0.0f, 2.0f/-io.DisplaySize.y, 0.0f, 0.0f }, 77 | { 0.0f, 0.0f, -1.0f, 0.0f }, 78 | {-1.0f, 1.0f, 0.0f, 1.0f }, 79 | }; 80 | glUseProgram(g_ShaderHandle); 81 | glUniform1i(g_AttribLocationTex, 0); 82 | glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); 83 | glBindVertexArray(g_VaoHandle); 84 | 85 | for (int n = 0; n < draw_data->CmdListsCount; n++) 86 | { 87 | const ImDrawList* cmd_list = draw_data->CmdLists[n]; 88 | const ImDrawIdx* idx_buffer_offset = 0; 89 | 90 | glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); 91 | glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)cmd_list->VtxBuffer.Size * sizeof(ImDrawVert), (const GLvoid*)cmd_list->VtxBuffer.Data, GL_STREAM_DRAW); 92 | 93 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_ElementsHandle); 94 | glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx), (const GLvoid*)cmd_list->IdxBuffer.Data, GL_STREAM_DRAW); 95 | 96 | for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) 97 | { 98 | const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; 99 | if (pcmd->UserCallback) 100 | { 101 | pcmd->UserCallback(cmd_list, pcmd); 102 | } 103 | else 104 | { 105 | glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); 106 | glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); 107 | glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer_offset); 108 | } 109 | idx_buffer_offset += pcmd->ElemCount; 110 | } 111 | } 112 | 113 | // Restore modified GL state 114 | glUseProgram(last_program); 115 | glBindTexture(GL_TEXTURE_2D, last_texture); 116 | glActiveTexture(last_active_texture); 117 | glBindVertexArray(last_vertex_array); 118 | glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); 119 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, last_element_array_buffer); 120 | glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha); 121 | glBlendFuncSeparate(last_blend_src_rgb, last_blend_dst_rgb, last_blend_src_alpha, last_blend_dst_alpha); 122 | if (last_enable_blend) glEnable(GL_BLEND); else glDisable(GL_BLEND); 123 | if (last_enable_cull_face) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE); 124 | if (last_enable_depth_test) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST); 125 | if (last_enable_scissor_test) glEnable(GL_SCISSOR_TEST); else glDisable(GL_SCISSOR_TEST); 126 | glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); 127 | glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]); 128 | } 129 | 130 | static const char* ImGui_ImplSdlGL3_GetClipboardText(void*) 131 | { 132 | return SDL_GetClipboardText(); 133 | } 134 | 135 | static void ImGui_ImplSdlGL3_SetClipboardText(void*, const char* text) 136 | { 137 | SDL_SetClipboardText(text); 138 | } 139 | 140 | bool ImGui_ImplSdlGL3_ProcessEvent(SDL_Event* event) 141 | { 142 | ImGuiIO& io = ImGui::GetIO(); 143 | switch (event->type) 144 | { 145 | case SDL_MOUSEWHEEL: 146 | { 147 | if (event->wheel.y > 0) 148 | g_MouseWheel = 1; 149 | if (event->wheel.y < 0) 150 | g_MouseWheel = -1; 151 | return true; 152 | } 153 | case SDL_MOUSEBUTTONDOWN: 154 | { 155 | if (event->button.button == SDL_BUTTON_LEFT) g_MousePressed[0] = true; 156 | if (event->button.button == SDL_BUTTON_RIGHT) g_MousePressed[1] = true; 157 | if (event->button.button == SDL_BUTTON_MIDDLE) g_MousePressed[2] = true; 158 | return true; 159 | } 160 | case SDL_TEXTINPUT: 161 | { 162 | io.AddInputCharactersUTF8(event->text.text); 163 | return true; 164 | } 165 | case SDL_KEYDOWN: 166 | case SDL_KEYUP: 167 | { 168 | int key = event->key.keysym.sym & ~SDLK_SCANCODE_MASK; 169 | io.KeysDown[key] = (event->type == SDL_KEYDOWN); 170 | io.KeyShift = ((SDL_GetModState() & KMOD_SHIFT) != 0); 171 | io.KeyCtrl = ((SDL_GetModState() & KMOD_CTRL) != 0); 172 | io.KeyAlt = ((SDL_GetModState() & KMOD_ALT) != 0); 173 | io.KeySuper = ((SDL_GetModState() & KMOD_GUI) != 0); 174 | return true; 175 | } 176 | } 177 | return false; 178 | } 179 | 180 | void ImGui_ImplSdlGL3_CreateFontsTexture() 181 | { 182 | // Build texture atlas 183 | ImGuiIO& io = ImGui::GetIO(); 184 | unsigned char* pixels; 185 | int width, height; 186 | io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader. 187 | 188 | // Upload texture to graphics system 189 | GLint last_texture; 190 | glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); 191 | glGenTextures(1, &g_FontTexture); 192 | glBindTexture(GL_TEXTURE_2D, g_FontTexture); 193 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 194 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 195 | glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); 196 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); 197 | 198 | // Store our identifier 199 | io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; 200 | 201 | // Restore state 202 | glBindTexture(GL_TEXTURE_2D, last_texture); 203 | } 204 | 205 | bool ImGui_ImplSdlGL3_CreateDeviceObjects() 206 | { 207 | // Backup GL state 208 | GLint last_texture, last_array_buffer, last_vertex_array; 209 | glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); 210 | glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); 211 | glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); 212 | 213 | const GLchar *vertex_shader = 214 | "#version 330\n" 215 | "uniform mat4 ProjMtx;\n" 216 | "in vec2 Position;\n" 217 | "in vec2 UV;\n" 218 | "in vec4 Color;\n" 219 | "out vec2 Frag_UV;\n" 220 | "out vec4 Frag_Color;\n" 221 | "void main()\n" 222 | "{\n" 223 | " Frag_UV = UV;\n" 224 | " Frag_Color = Color;\n" 225 | " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" 226 | "}\n"; 227 | 228 | const GLchar* fragment_shader = 229 | "#version 330\n" 230 | "uniform sampler2D Texture;\n" 231 | "in vec2 Frag_UV;\n" 232 | "in vec4 Frag_Color;\n" 233 | "out vec4 Out_Color;\n" 234 | "void main()\n" 235 | "{\n" 236 | " Out_Color = Frag_Color * texture( Texture, Frag_UV.st);\n" 237 | "}\n"; 238 | 239 | g_ShaderHandle = glCreateProgram(); 240 | g_VertHandle = glCreateShader(GL_VERTEX_SHADER); 241 | g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); 242 | glShaderSource(g_VertHandle, 1, &vertex_shader, 0); 243 | glShaderSource(g_FragHandle, 1, &fragment_shader, 0); 244 | glCompileShader(g_VertHandle); 245 | glCompileShader(g_FragHandle); 246 | glAttachShader(g_ShaderHandle, g_VertHandle); 247 | glAttachShader(g_ShaderHandle, g_FragHandle); 248 | glLinkProgram(g_ShaderHandle); 249 | 250 | g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); 251 | g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); 252 | g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position"); 253 | g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV"); 254 | g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color"); 255 | 256 | glGenBuffers(1, &g_VboHandle); 257 | glGenBuffers(1, &g_ElementsHandle); 258 | 259 | glGenVertexArrays(1, &g_VaoHandle); 260 | glBindVertexArray(g_VaoHandle); 261 | glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); 262 | glEnableVertexAttribArray(g_AttribLocationPosition); 263 | glEnableVertexAttribArray(g_AttribLocationUV); 264 | glEnableVertexAttribArray(g_AttribLocationColor); 265 | 266 | #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) 267 | glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); 268 | glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); 269 | glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); 270 | #undef OFFSETOF 271 | 272 | ImGui_ImplSdlGL3_CreateFontsTexture(); 273 | 274 | // Restore modified GL state 275 | glBindTexture(GL_TEXTURE_2D, last_texture); 276 | glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); 277 | glBindVertexArray(last_vertex_array); 278 | 279 | return true; 280 | } 281 | 282 | void ImGui_ImplSdlGL3_InvalidateDeviceObjects() 283 | { 284 | if (g_VaoHandle) glDeleteVertexArrays(1, &g_VaoHandle); 285 | if (g_VboHandle) glDeleteBuffers(1, &g_VboHandle); 286 | if (g_ElementsHandle) glDeleteBuffers(1, &g_ElementsHandle); 287 | g_VaoHandle = g_VboHandle = g_ElementsHandle = 0; 288 | 289 | if (g_ShaderHandle && g_VertHandle) glDetachShader(g_ShaderHandle, g_VertHandle); 290 | if (g_VertHandle) glDeleteShader(g_VertHandle); 291 | g_VertHandle = 0; 292 | 293 | if (g_ShaderHandle && g_FragHandle) glDetachShader(g_ShaderHandle, g_FragHandle); 294 | if (g_FragHandle) glDeleteShader(g_FragHandle); 295 | g_FragHandle = 0; 296 | 297 | if (g_ShaderHandle) glDeleteProgram(g_ShaderHandle); 298 | g_ShaderHandle = 0; 299 | 300 | if (g_FontTexture) 301 | { 302 | glDeleteTextures(1, &g_FontTexture); 303 | ImGui::GetIO().Fonts->TexID = 0; 304 | g_FontTexture = 0; 305 | } 306 | } 307 | 308 | bool ImGui_ImplSdlGL3_Init(SDL_Window* window) 309 | { 310 | ImGuiIO& io = ImGui::GetIO(); 311 | io.KeyMap[ImGuiKey_Tab] = SDLK_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array. 312 | io.KeyMap[ImGuiKey_LeftArrow] = SDL_SCANCODE_LEFT; 313 | io.KeyMap[ImGuiKey_RightArrow] = SDL_SCANCODE_RIGHT; 314 | io.KeyMap[ImGuiKey_UpArrow] = SDL_SCANCODE_UP; 315 | io.KeyMap[ImGuiKey_DownArrow] = SDL_SCANCODE_DOWN; 316 | io.KeyMap[ImGuiKey_PageUp] = SDL_SCANCODE_PAGEUP; 317 | io.KeyMap[ImGuiKey_PageDown] = SDL_SCANCODE_PAGEDOWN; 318 | io.KeyMap[ImGuiKey_Home] = SDL_SCANCODE_HOME; 319 | io.KeyMap[ImGuiKey_End] = SDL_SCANCODE_END; 320 | io.KeyMap[ImGuiKey_Delete] = SDLK_DELETE; 321 | io.KeyMap[ImGuiKey_Backspace] = SDLK_BACKSPACE; 322 | io.KeyMap[ImGuiKey_Enter] = SDLK_RETURN; 323 | io.KeyMap[ImGuiKey_Escape] = SDLK_ESCAPE; 324 | io.KeyMap[ImGuiKey_A] = SDLK_a; 325 | io.KeyMap[ImGuiKey_C] = SDLK_c; 326 | io.KeyMap[ImGuiKey_V] = SDLK_v; 327 | io.KeyMap[ImGuiKey_X] = SDLK_x; 328 | io.KeyMap[ImGuiKey_Y] = SDLK_y; 329 | io.KeyMap[ImGuiKey_Z] = SDLK_z; 330 | 331 | io.RenderDrawListsFn = ImGui_ImplSdlGL3_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. 332 | io.SetClipboardTextFn = ImGui_ImplSdlGL3_SetClipboardText; 333 | io.GetClipboardTextFn = ImGui_ImplSdlGL3_GetClipboardText; 334 | io.ClipboardUserData = NULL; 335 | 336 | #ifdef _WIN32 337 | SDL_SysWMinfo wmInfo; 338 | SDL_VERSION(&wmInfo.version); 339 | SDL_GetWindowWMInfo(window, &wmInfo); 340 | io.ImeWindowHandle = wmInfo.info.win.window; 341 | #else 342 | (void)window; 343 | #endif 344 | 345 | return true; 346 | } 347 | 348 | void ImGui_ImplSdlGL3_Shutdown() 349 | { 350 | ImGui_ImplSdlGL3_InvalidateDeviceObjects(); 351 | ImGui::Shutdown(); 352 | } 353 | 354 | void ImGui_ImplSdlGL3_NewFrame(SDL_Window* window) 355 | { 356 | if (!g_FontTexture) 357 | ImGui_ImplSdlGL3_CreateDeviceObjects(); 358 | 359 | ImGuiIO& io = ImGui::GetIO(); 360 | 361 | // Setup display size (every frame to accommodate for window resizing) 362 | int w, h; 363 | int display_w, display_h; 364 | SDL_GetWindowSize(window, &w, &h); 365 | SDL_GL_GetDrawableSize(window, &display_w, &display_h); 366 | io.DisplaySize = ImVec2((float)w, (float)h); 367 | io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); 368 | 369 | // Setup time step 370 | Uint32 time = SDL_GetTicks(); 371 | double current_time = time / 1000.0; 372 | io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f / 60.0f); 373 | g_Time = current_time; 374 | 375 | // Setup inputs 376 | // (we already got mouse wheel, keyboard keys & characters from SDL_PollEvent()) 377 | int mx, my; 378 | Uint32 mouseMask = SDL_GetMouseState(&mx, &my); 379 | if (SDL_GetWindowFlags(window) & SDL_WINDOW_MOUSE_FOCUS) 380 | io.MousePos = ImVec2((float)mx, (float)my); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.) 381 | else 382 | io.MousePos = ImVec2(-1, -1); 383 | 384 | io.MouseDown[0] = g_MousePressed[0] || (mouseMask & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. 385 | io.MouseDown[1] = g_MousePressed[1] || (mouseMask & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0; 386 | io.MouseDown[2] = g_MousePressed[2] || (mouseMask & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0; 387 | g_MousePressed[0] = g_MousePressed[1] = g_MousePressed[2] = false; 388 | 389 | io.MouseWheel = g_MouseWheel; 390 | g_MouseWheel = 0.0f; 391 | 392 | // Hide OS mouse cursor if ImGui is drawing it 393 | SDL_ShowCursor(io.MouseDrawCursor ? 0 : 1); 394 | 395 | // Start the frame 396 | ImGui::NewFrame(); 397 | } 398 | 399 | #endif -------------------------------------------------------------------------------- /ImguiDemoSdl/src/main/cpp/src/imgui_impl/imgui_impl_sdl_es2.cpp: -------------------------------------------------------------------------------- 1 | // ImGui SDL2 binding with OpenGL ES2 (based on SDL+GL3 example) 2 | // In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. 3 | 4 | // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. 5 | // If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). 6 | // If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. 7 | // https://github.com/ocornut/imgui 8 | #ifdef GL_PROFILE_GLES2 9 | #include "imgui.h" 10 | #include "imgui_impl_sdl_es2.h" 11 | 12 | // SDL,GL3W 13 | #include 14 | #include 15 | #include // No need to use a loader, since we're linking against libGLES2.so 16 | 17 | // Data 18 | static double g_Time = 0.0f; 19 | static bool g_MousePressed[3] = { false, false, false }; 20 | static float g_MouseWheel = 0.0f; 21 | static GLuint g_FontTexture = 0; 22 | static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; 23 | static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; 24 | static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; 25 | static unsigned int g_VboHandle = 0, /*g_VaoHandle = 0,*/ g_ElementsHandle = 0; 26 | 27 | // This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) 28 | // If text or lines are blurry when integrating ImGui in your engine: 29 | // - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) 30 | void ImGui_ImplSdlGLES2_RenderDrawLists(ImDrawData* draw_data) 31 | { 32 | // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) 33 | ImGuiIO& io = ImGui::GetIO(); 34 | // Because of some weird handling of Android's virtual keyboard, we have to check if the Backspace button is pressed 35 | const Uint8* kbState = SDL_GetKeyboardState(NULL); 36 | if (!kbState[SDL_SCANCODE_BACKSPACE]) 37 | { 38 | io.KeysDown[SDLK_BACKSPACE] = 0; 39 | } 40 | int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); 41 | int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); 42 | if (fb_width == 0 || fb_height == 0) 43 | return; 44 | draw_data->ScaleClipRects(io.DisplayFramebufferScale); 45 | 46 | // Backup GL state 47 | GLint last_active_texture; glGetIntegerv(GL_ACTIVE_TEXTURE, &last_active_texture); 48 | glActiveTexture(GL_TEXTURE0); 49 | GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); 50 | GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); 51 | GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); 52 | GLint last_element_array_buffer; glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_element_array_buffer); 53 | // Note that your vertex buffer state is NOT saved, since es2 has no vertex array objects 54 | //GLint last_vertex_array; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); 55 | GLint last_blend_src_rgb; glGetIntegerv(GL_BLEND_SRC_RGB, &last_blend_src_rgb); 56 | GLint last_blend_dst_rgb; glGetIntegerv(GL_BLEND_DST_RGB, &last_blend_dst_rgb); 57 | GLint last_blend_src_alpha; glGetIntegerv(GL_BLEND_SRC_ALPHA, &last_blend_src_alpha); 58 | GLint last_blend_dst_alpha; glGetIntegerv(GL_BLEND_DST_ALPHA, &last_blend_dst_alpha); 59 | GLint last_blend_equation_rgb; glGetIntegerv(GL_BLEND_EQUATION_RGB, &last_blend_equation_rgb); 60 | GLint last_blend_equation_alpha; glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &last_blend_equation_alpha); 61 | GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); 62 | GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box); 63 | GLboolean last_enable_blend = glIsEnabled(GL_BLEND); 64 | GLboolean last_enable_cull_face = glIsEnabled(GL_CULL_FACE); 65 | GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST); 66 | GLboolean last_enable_scissor_test = glIsEnabled(GL_SCISSOR_TEST); 67 | 68 | // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled 69 | glEnable(GL_BLEND); 70 | glBlendEquation(GL_FUNC_ADD); 71 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 72 | glDisable(GL_CULL_FACE); 73 | glDisable(GL_DEPTH_TEST); 74 | glEnable(GL_SCISSOR_TEST); 75 | 76 | // Setup viewport, orthographic projection matrix 77 | glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); 78 | const float ortho_projection[4][4] = 79 | { 80 | { 2.0f/io.DisplaySize.x, 0.0f, 0.0f, 0.0f }, 81 | { 0.0f, 2.0f/-io.DisplaySize.y, 0.0f, 0.0f }, 82 | { 0.0f, 0.0f, -1.0f, 0.0f }, 83 | {-1.0f, 1.0f, 0.0f, 1.0f }, 84 | }; 85 | glUseProgram(g_ShaderHandle); 86 | glUniform1i(g_AttribLocationTex, 0); 87 | glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); 88 | //glBindVertexArray(g_VaoHandle); 89 | 90 | glEnableVertexAttribArray(g_AttribLocationPosition); 91 | glEnableVertexAttribArray(g_AttribLocationUV); 92 | glEnableVertexAttribArray(g_AttribLocationColor); 93 | 94 | glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); 95 | #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) 96 | glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); 97 | glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); 98 | glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); 99 | #undef OFFSETOF 100 | 101 | for (int n = 0; n < draw_data->CmdListsCount; n++) 102 | { 103 | const ImDrawList* cmd_list = draw_data->CmdLists[n]; 104 | const ImDrawIdx* idx_buffer_offset = 0; 105 | 106 | glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); 107 | glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)cmd_list->VtxBuffer.Size * sizeof(ImDrawVert), (const GLvoid*)cmd_list->VtxBuffer.Data, GL_STREAM_DRAW); 108 | 109 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_ElementsHandle); 110 | glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx), (const GLvoid*)cmd_list->IdxBuffer.Data, GL_STREAM_DRAW); 111 | 112 | 113 | 114 | for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) 115 | { 116 | const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; 117 | if (pcmd->UserCallback) 118 | { 119 | pcmd->UserCallback(cmd_list, pcmd); 120 | } 121 | else 122 | { 123 | glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); 124 | glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); 125 | glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer_offset); 126 | } 127 | idx_buffer_offset += pcmd->ElemCount; 128 | } 129 | } 130 | 131 | // Restore modified GL state 132 | glUseProgram(last_program); 133 | glBindTexture(GL_TEXTURE_2D, last_texture); 134 | glActiveTexture(last_active_texture); 135 | //glBindVertexArray(last_vertex_array); 136 | glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); 137 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, last_element_array_buffer); 138 | glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha); 139 | glBlendFuncSeparate(last_blend_src_rgb, last_blend_dst_rgb, last_blend_src_alpha, last_blend_dst_alpha); 140 | if (last_enable_blend) glEnable(GL_BLEND); else glDisable(GL_BLEND); 141 | if (last_enable_cull_face) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE); 142 | if (last_enable_depth_test) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST); 143 | if (last_enable_scissor_test) glEnable(GL_SCISSOR_TEST); else glDisable(GL_SCISSOR_TEST); 144 | glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); 145 | glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]); 146 | } 147 | 148 | static const char* ImGui_ImplSdlGLES2_GetClipboardText(void*) 149 | { 150 | return SDL_GetClipboardText(); 151 | } 152 | 153 | static void ImGui_ImplSdlGLES2_SetClipboardText(void*, const char* text) 154 | { 155 | SDL_SetClipboardText(text); 156 | } 157 | 158 | bool ImGui_ImplSdlGLES2_ProcessEvent(SDL_Event* event) 159 | { 160 | ImGuiIO& io = ImGui::GetIO(); 161 | switch (event->type) 162 | { 163 | case SDL_MOUSEWHEEL: 164 | { 165 | if (event->wheel.y > 0) 166 | g_MouseWheel = 1; 167 | if (event->wheel.y < 0) 168 | g_MouseWheel = -1; 169 | return true; 170 | } 171 | case SDL_MOUSEBUTTONDOWN: 172 | { 173 | if (event->button.button == SDL_BUTTON_LEFT) g_MousePressed[0] = true; 174 | if (event->button.button == SDL_BUTTON_RIGHT) g_MousePressed[1] = true; 175 | if (event->button.button == SDL_BUTTON_MIDDLE) g_MousePressed[2] = true; 176 | return true; 177 | } 178 | case SDL_TEXTINPUT: 179 | { 180 | io.AddInputCharactersUTF8(event->text.text); 181 | return true; 182 | } 183 | case SDL_KEYDOWN: 184 | case SDL_KEYUP: 185 | { 186 | // We have to handle the Backspace key as a special case here 187 | int key = event->key.keysym.sym & ~SDLK_SCANCODE_MASK; 188 | if (key == SDLK_BACKSPACE) { 189 | io.KeysDown[key] = 1; 190 | } else { 191 | io.KeysDown[key] = (event->type == SDL_KEYDOWN); 192 | } 193 | io.KeyShift = ((SDL_GetModState() & KMOD_SHIFT) != 0); 194 | io.KeyCtrl = ((SDL_GetModState() & KMOD_CTRL) != 0); 195 | io.KeyAlt = ((SDL_GetModState() & KMOD_ALT) != 0); 196 | io.KeySuper = ((SDL_GetModState() & KMOD_GUI) != 0); 197 | return true; 198 | } 199 | } 200 | return false; 201 | } 202 | 203 | void ImGui_ImplSdlGLES2_CreateFontsTexture() 204 | { 205 | // Build texture atlas 206 | ImGuiIO& io = ImGui::GetIO(); 207 | unsigned char* pixels; 208 | int width, height; 209 | io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader. 210 | 211 | // Upload texture to graphics system 212 | GLint last_texture; 213 | glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); 214 | glGenTextures(1, &g_FontTexture); 215 | glBindTexture(GL_TEXTURE_2D, g_FontTexture); 216 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 217 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 218 | // gles2 does not support changing UNPACK_ROW_LENGTH, assume it's always 0? 219 | //glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); 220 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); 221 | 222 | // Store our identifier 223 | io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; 224 | 225 | // Restore state 226 | glBindTexture(GL_TEXTURE_2D, last_texture); 227 | } 228 | 229 | bool ImGui_ImplSdlGLES2_CreateDeviceObjects() 230 | { 231 | // Backup GL state 232 | GLint last_texture, last_array_buffer, last_vertex_array; 233 | glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); 234 | glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); 235 | //glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); 236 | 237 | // Set version to 100 for gles2 shading language 238 | const GLchar *vertex_shader = 239 | "#version 100\n" 240 | "uniform mat4 ProjMtx;\n" 241 | "attribute vec2 Position;\n" 242 | "attribute vec2 UV;\n" 243 | "attribute vec4 Color;\n" 244 | "varying vec2 Frag_UV;\n" 245 | "varying vec4 Frag_Color;\n" 246 | "void main()\n" 247 | "{\n" 248 | " Frag_UV = UV;\n" 249 | " Frag_Color = Color;\n" 250 | " gl_Position = ProjMtx * vec4(Position.xy,0.0,1.0);\n" 251 | "}\n"; 252 | 253 | // You need to specify your precision in FS, according to ES2 shading language 254 | const GLchar* fragment_shader = 255 | "#version 100\n" 256 | "precision mediump float;" 257 | "uniform sampler2D Texture;\n" 258 | "varying vec2 Frag_UV;\n" 259 | "varying vec4 Frag_Color;\n" 260 | "void main()\n" 261 | "{\n" 262 | " gl_FragColor = Frag_Color * texture2D( Texture, Frag_UV.st);\n" 263 | "}\n"; 264 | 265 | g_ShaderHandle = glCreateProgram(); 266 | g_VertHandle = glCreateShader(GL_VERTEX_SHADER); 267 | g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); 268 | glShaderSource(g_VertHandle, 1, &vertex_shader, 0); 269 | glShaderSource(g_FragHandle, 1, &fragment_shader, 0); 270 | glCompileShader(g_VertHandle); 271 | glCompileShader(g_FragHandle); 272 | glAttachShader(g_ShaderHandle, g_VertHandle); 273 | glAttachShader(g_ShaderHandle, g_FragHandle); 274 | glLinkProgram(g_ShaderHandle); 275 | 276 | g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); 277 | g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); 278 | g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position"); 279 | g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV"); 280 | g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color"); 281 | 282 | glGenBuffers(1, &g_VboHandle); 283 | glGenBuffers(1, &g_ElementsHandle); 284 | 285 | //glGenVertexArrays(1, &g_VaoHandle); 286 | //glBindVertexArray(g_VaoHandle); 287 | glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); 288 | glEnableVertexAttribArray(g_AttribLocationPosition); 289 | glEnableVertexAttribArray(g_AttribLocationUV); 290 | glEnableVertexAttribArray(g_AttribLocationColor); 291 | 292 | #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) 293 | glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); 294 | glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); 295 | glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); 296 | #undef OFFSETOF 297 | 298 | ImGui_ImplSdlGLES2_CreateFontsTexture(); 299 | 300 | // Restore modified GL state 301 | glBindTexture(GL_TEXTURE_2D, last_texture); 302 | glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); 303 | //glBindVertexArray(last_vertex_array); 304 | 305 | return true; 306 | } 307 | 308 | void ImGui_ImplSdlGLES2_InvalidateDeviceObjects() 309 | { 310 | //if (g_VaoHandle) glDeleteVertexArrays(1, &g_VaoHandle); 311 | if (g_VboHandle) glDeleteBuffers(1, &g_VboHandle); 312 | if (g_ElementsHandle) glDeleteBuffers(1, &g_ElementsHandle); 313 | /*g_VaoHandle = */g_VboHandle = g_ElementsHandle = 0; 314 | 315 | if (g_ShaderHandle && g_VertHandle) glDetachShader(g_ShaderHandle, g_VertHandle); 316 | if (g_VertHandle) glDeleteShader(g_VertHandle); 317 | g_VertHandle = 0; 318 | 319 | if (g_ShaderHandle && g_FragHandle) glDetachShader(g_ShaderHandle, g_FragHandle); 320 | if (g_FragHandle) glDeleteShader(g_FragHandle); 321 | g_FragHandle = 0; 322 | 323 | if (g_ShaderHandle) glDeleteProgram(g_ShaderHandle); 324 | g_ShaderHandle = 0; 325 | 326 | if (g_FontTexture) 327 | { 328 | glDeleteTextures(1, &g_FontTexture); 329 | ImGui::GetIO().Fonts->TexID = 0; 330 | g_FontTexture = 0; 331 | } 332 | } 333 | 334 | bool ImGui_ImplSdlGLES2_Init(SDL_Window* window) 335 | { 336 | ImGuiIO& io = ImGui::GetIO(); 337 | io.KeyMap[ImGuiKey_Tab] = SDLK_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array. 338 | io.KeyMap[ImGuiKey_LeftArrow] = SDL_SCANCODE_LEFT; 339 | io.KeyMap[ImGuiKey_RightArrow] = SDL_SCANCODE_RIGHT; 340 | io.KeyMap[ImGuiKey_UpArrow] = SDL_SCANCODE_UP; 341 | io.KeyMap[ImGuiKey_DownArrow] = SDL_SCANCODE_DOWN; 342 | io.KeyMap[ImGuiKey_PageUp] = SDL_SCANCODE_PAGEUP; 343 | io.KeyMap[ImGuiKey_PageDown] = SDL_SCANCODE_PAGEDOWN; 344 | io.KeyMap[ImGuiKey_Home] = SDL_SCANCODE_HOME; 345 | io.KeyMap[ImGuiKey_End] = SDL_SCANCODE_END; 346 | io.KeyMap[ImGuiKey_Delete] = SDLK_DELETE; 347 | io.KeyMap[ImGuiKey_Backspace] = SDLK_BACKSPACE; 348 | io.KeyMap[ImGuiKey_Enter] = SDLK_RETURN; 349 | io.KeyMap[ImGuiKey_Escape] = SDLK_ESCAPE; 350 | io.KeyMap[ImGuiKey_A] = SDLK_a; 351 | io.KeyMap[ImGuiKey_C] = SDLK_c; 352 | io.KeyMap[ImGuiKey_V] = SDLK_v; 353 | io.KeyMap[ImGuiKey_X] = SDLK_x; 354 | io.KeyMap[ImGuiKey_Y] = SDLK_y; 355 | io.KeyMap[ImGuiKey_Z] = SDLK_z; 356 | 357 | io.RenderDrawListsFn = ImGui_ImplSdlGLES2_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. 358 | io.SetClipboardTextFn = ImGui_ImplSdlGLES2_SetClipboardText; 359 | io.GetClipboardTextFn = ImGui_ImplSdlGLES2_GetClipboardText; 360 | io.ClipboardUserData = NULL; 361 | 362 | #ifdef _WIN32 363 | SDL_SysWMinfo wmInfo; 364 | SDL_VERSION(&wmInfo.version); 365 | SDL_GetWindowWMInfo(window, &wmInfo); 366 | io.ImeWindowHandle = wmInfo.info.win.window; 367 | #else 368 | (void)window; 369 | #endif 370 | 371 | return true; 372 | } 373 | 374 | void ImGui_ImplSdlGLES2_Shutdown() 375 | { 376 | ImGui_ImplSdlGLES2_InvalidateDeviceObjects(); 377 | ImGui::Shutdown(); 378 | } 379 | 380 | void ImGui_ImplSdlGLES2_NewFrame(SDL_Window* window) 381 | { 382 | if (!g_FontTexture) 383 | ImGui_ImplSdlGLES2_CreateDeviceObjects(); 384 | 385 | ImGuiIO& io = ImGui::GetIO(); 386 | 387 | // Setup display size (every frame to accommodate for window resizing) 388 | int w, h; 389 | int display_w, display_h; 390 | SDL_GetWindowSize(window, &w, &h); 391 | SDL_GL_GetDrawableSize(window, &display_w, &display_h); 392 | io.DisplaySize = ImVec2((float)w, (float)h); 393 | io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); 394 | 395 | // Setup time step 396 | Uint32 time = SDL_GetTicks(); 397 | double current_time = time / 1000.0; 398 | io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f / 60.0f); 399 | g_Time = current_time; 400 | 401 | // Setup inputs 402 | // (we already got mouse wheel, keyboard keys & characters from SDL_PollEvent()) 403 | int mx, my; 404 | Uint32 mouseMask = SDL_GetMouseState(&mx, &my); 405 | if (SDL_GetWindowFlags(window) & SDL_WINDOW_MOUSE_FOCUS) 406 | io.MousePos = ImVec2((float)mx, (float)my); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.) 407 | else 408 | io.MousePos = ImVec2(-1, -1); 409 | 410 | io.MouseDown[0] = g_MousePressed[0] || (mouseMask & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. 411 | io.MouseDown[1] = g_MousePressed[1] || (mouseMask & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0; 412 | io.MouseDown[2] = g_MousePressed[2] || (mouseMask & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0; 413 | g_MousePressed[0] = g_MousePressed[1] = g_MousePressed[2] = false; 414 | 415 | io.MouseWheel = g_MouseWheel; 416 | g_MouseWheel = 0.0f; 417 | 418 | // Hide OS mouse cursor if ImGui is drawing it 419 | SDL_ShowCursor(io.MouseDrawCursor ? 0 : 1); 420 | 421 | // Start the frame 422 | ImGui::NewFrame(); 423 | } 424 | #endif // GL_PROFILE_GLES2 -------------------------------------------------------------------------------- /ImguiDemoSdl/src/main/cpp/src/imgui_impl/imgui_impl_sdl_es3.cpp: -------------------------------------------------------------------------------- 1 | // ImGui SDL2 binding with OpenGL3 2 | // In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. 3 | 4 | // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. 5 | // If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). 6 | // If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. 7 | // https://github.com/ocornut/imgui 8 | 9 | #ifdef GL_PROFILE_GLES3 10 | 11 | #include "imgui.h" 12 | #include "imgui_impl_sdl_gl3.h" 13 | 14 | // SDL,GL3W 15 | #include 16 | #include 17 | // We could have linked with libGLES3, but that would have limited us to ES3-only devices; 18 | // Instead we're going to load all ES3 functions at runtime. 19 | #define GL_GLES_PROTOTYPES 0 20 | #include 21 | #undef GL_GLES_PROTOTYPES 22 | 23 | 24 | // These are all of the used functions. They will be loaded during the Init() phase. 25 | static PFNGLGETINTEGERVPROC glGetIntegerv; 26 | static PFNGLACTIVETEXTUREPROC glActiveTexture; 27 | static PFNGLISENABLEDPROC glIsEnabled; 28 | static PFNGLENABLEPROC glEnable; 29 | static PFNGLBLENDEQUATIONPROC glBlendEquation; 30 | static PFNGLBLENDFUNCPROC glBlendFunc; 31 | static PFNGLDISABLEPROC glDisable; 32 | static PFNGLVIEWPORTPROC glViewport; 33 | static PFNGLUSEPROGRAMPROC glUseProgram; 34 | static PFNGLUNIFORM1IPROC glUniform1i; 35 | static PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv; 36 | static PFNGLBINDVERTEXARRAYPROC glBindVertexArray; 37 | static PFNGLBINDBUFFERPROC glBindBuffer; 38 | static PFNGLBUFFERDATAPROC glBufferData; 39 | static PFNGLBINDTEXTUREPROC glBindTexture; 40 | static PFNGLDRAWELEMENTSPROC glDrawElements; 41 | static PFNGLSCISSORPROC glScissor; 42 | static PFNGLBLENDEQUATIONSEPARATEPROC glBlendEquationSeparate; 43 | static PFNGLBLENDFUNCSEPARATEPROC glBlendFuncSeparate; 44 | static PFNGLGENTEXTURESPROC glGenTextures; 45 | static PFNGLTEXPARAMETERIPROC glTexParameteri; 46 | static PFNGLPIXELSTOREIPROC glPixelStorei; 47 | static PFNGLTEXIMAGE2DPROC glTexImage2D; 48 | static PFNGLCREATEPROGRAMPROC glCreateProgram; 49 | static PFNGLCREATESHADERPROC glCreateShader; 50 | static PFNGLSHADERSOURCEPROC glShaderSource; 51 | static PFNGLCOMPILESHADERPROC glCompileShader; 52 | static PFNGLATTACHSHADERPROC glAttachShader; 53 | static PFNGLLINKPROGRAMPROC glLinkProgram; 54 | static PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation; 55 | static PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation; 56 | static PFNGLGENBUFFERSPROC glGenBuffers; 57 | static PFNGLGENVERTEXARRAYSPROC glGenVertexArrays; 58 | static PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray; 59 | static PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer; 60 | static PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays; 61 | static PFNGLDELETEBUFFERSPROC glDeleteBuffers; 62 | static PFNGLDETACHSHADERPROC glDetachShader; 63 | static PFNGLDELETETEXTURESPROC glDeleteTextures; 64 | static PFNGLDELETESHADERPROC glDeleteShader; 65 | static PFNGLDELETEPROGRAMPROC glDeleteProgram; 66 | 67 | // Data 68 | static double g_Time = 0.0f; 69 | static bool g_MousePressed[3] = { false, false, false }; 70 | static float g_MouseWheel = 0.0f; 71 | static GLuint g_FontTexture = 0; 72 | static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; 73 | static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; 74 | static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; 75 | static unsigned int g_VboHandle = 0, g_VaoHandle = 0, g_ElementsHandle = 0; 76 | 77 | // This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) 78 | // If text or lines are blurry when integrating ImGui in your engine: 79 | // - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) 80 | void ImGui_ImplSdlGLES3_RenderDrawLists(ImDrawData* draw_data) 81 | { 82 | // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) 83 | ImGuiIO& io = ImGui::GetIO(); 84 | int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); 85 | int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); 86 | if (fb_width == 0 || fb_height == 0) 87 | return; 88 | draw_data->ScaleClipRects(io.DisplayFramebufferScale); 89 | 90 | // Backup GL state 91 | GLint last_active_texture; glGetIntegerv(GL_ACTIVE_TEXTURE, &last_active_texture); 92 | glActiveTexture(GL_TEXTURE0); 93 | GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); 94 | GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); 95 | GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); 96 | GLint last_element_array_buffer; glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_element_array_buffer); 97 | GLint last_vertex_array; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); 98 | GLint last_blend_src_rgb; glGetIntegerv(GL_BLEND_SRC_RGB, &last_blend_src_rgb); 99 | GLint last_blend_dst_rgb; glGetIntegerv(GL_BLEND_DST_RGB, &last_blend_dst_rgb); 100 | GLint last_blend_src_alpha; glGetIntegerv(GL_BLEND_SRC_ALPHA, &last_blend_src_alpha); 101 | GLint last_blend_dst_alpha; glGetIntegerv(GL_BLEND_DST_ALPHA, &last_blend_dst_alpha); 102 | GLint last_blend_equation_rgb; glGetIntegerv(GL_BLEND_EQUATION_RGB, &last_blend_equation_rgb); 103 | GLint last_blend_equation_alpha; glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &last_blend_equation_alpha); 104 | GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); 105 | GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box); 106 | GLboolean last_enable_blend = glIsEnabled(GL_BLEND); 107 | GLboolean last_enable_cull_face = glIsEnabled(GL_CULL_FACE); 108 | GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST); 109 | GLboolean last_enable_scissor_test = glIsEnabled(GL_SCISSOR_TEST); 110 | 111 | // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled 112 | glEnable(GL_BLEND); 113 | glBlendEquation(GL_FUNC_ADD); 114 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 115 | glDisable(GL_CULL_FACE); 116 | glDisable(GL_DEPTH_TEST); 117 | glEnable(GL_SCISSOR_TEST); 118 | 119 | // Setup viewport, orthographic projection matrix 120 | glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); 121 | const float ortho_projection[4][4] = 122 | { 123 | { 2.0f/io.DisplaySize.x, 0.0f, 0.0f, 0.0f }, 124 | { 0.0f, 2.0f/-io.DisplaySize.y, 0.0f, 0.0f }, 125 | { 0.0f, 0.0f, -1.0f, 0.0f }, 126 | {-1.0f, 1.0f, 0.0f, 1.0f }, 127 | }; 128 | glUseProgram(g_ShaderHandle); 129 | glUniform1i(g_AttribLocationTex, 0); 130 | glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); 131 | glBindVertexArray(g_VaoHandle); 132 | 133 | for (int n = 0; n < draw_data->CmdListsCount; n++) 134 | { 135 | const ImDrawList* cmd_list = draw_data->CmdLists[n]; 136 | const ImDrawIdx* idx_buffer_offset = 0; 137 | 138 | glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); 139 | glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)cmd_list->VtxBuffer.Size * sizeof(ImDrawVert), (const GLvoid*)cmd_list->VtxBuffer.Data, GL_STREAM_DRAW); 140 | 141 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_ElementsHandle); 142 | glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx), (const GLvoid*)cmd_list->IdxBuffer.Data, GL_STREAM_DRAW); 143 | 144 | for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) 145 | { 146 | const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; 147 | if (pcmd->UserCallback) 148 | { 149 | pcmd->UserCallback(cmd_list, pcmd); 150 | } 151 | else 152 | { 153 | glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); 154 | glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); 155 | glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer_offset); 156 | } 157 | idx_buffer_offset += pcmd->ElemCount; 158 | } 159 | } 160 | 161 | // Restore modified GL state 162 | glUseProgram(last_program); 163 | glBindTexture(GL_TEXTURE_2D, last_texture); 164 | glActiveTexture(last_active_texture); 165 | glBindVertexArray(last_vertex_array); 166 | glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); 167 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, last_element_array_buffer); 168 | glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha); 169 | glBlendFuncSeparate(last_blend_src_rgb, last_blend_dst_rgb, last_blend_src_alpha, last_blend_dst_alpha); 170 | if (last_enable_blend) glEnable(GL_BLEND); else glDisable(GL_BLEND); 171 | if (last_enable_cull_face) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE); 172 | if (last_enable_depth_test) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST); 173 | if (last_enable_scissor_test) glEnable(GL_SCISSOR_TEST); else glDisable(GL_SCISSOR_TEST); 174 | glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); 175 | glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]); 176 | } 177 | 178 | static const char* ImGui_ImplSdlGLES3_GetClipboardText(void*) 179 | { 180 | return SDL_GetClipboardText(); 181 | } 182 | 183 | static void ImGui_ImplSdlGLES3_SetClipboardText(void*, const char* text) 184 | { 185 | SDL_SetClipboardText(text); 186 | } 187 | 188 | bool ImGui_ImplSdlGLES3_ProcessEvent(SDL_Event* event) 189 | { 190 | ImGuiIO& io = ImGui::GetIO(); 191 | switch (event->type) 192 | { 193 | case SDL_MOUSEWHEEL: 194 | { 195 | if (event->wheel.y > 0) 196 | g_MouseWheel = 1; 197 | if (event->wheel.y < 0) 198 | g_MouseWheel = -1; 199 | return true; 200 | } 201 | case SDL_MOUSEBUTTONDOWN: 202 | { 203 | if (event->button.button == SDL_BUTTON_LEFT) g_MousePressed[0] = true; 204 | if (event->button.button == SDL_BUTTON_RIGHT) g_MousePressed[1] = true; 205 | if (event->button.button == SDL_BUTTON_MIDDLE) g_MousePressed[2] = true; 206 | return true; 207 | } 208 | case SDL_TEXTINPUT: 209 | { 210 | io.AddInputCharactersUTF8(event->text.text); 211 | return true; 212 | } 213 | case SDL_KEYDOWN: 214 | case SDL_KEYUP: 215 | { 216 | int key = event->key.keysym.sym & ~SDLK_SCANCODE_MASK; 217 | io.KeysDown[key] = (event->type == SDL_KEYDOWN); 218 | io.KeyShift = ((SDL_GetModState() & KMOD_SHIFT) != 0); 219 | io.KeyCtrl = ((SDL_GetModState() & KMOD_CTRL) != 0); 220 | io.KeyAlt = ((SDL_GetModState() & KMOD_ALT) != 0); 221 | io.KeySuper = ((SDL_GetModState() & KMOD_GUI) != 0); 222 | return true; 223 | } 224 | } 225 | return false; 226 | } 227 | 228 | void ImGui_ImplSdlGLES3_CreateFontsTexture() 229 | { 230 | // Build texture atlas 231 | ImGuiIO& io = ImGui::GetIO(); 232 | unsigned char* pixels; 233 | int width, height; 234 | io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader. 235 | 236 | // Upload texture to graphics system 237 | GLint last_texture; 238 | glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); 239 | glGenTextures(1, &g_FontTexture); 240 | glBindTexture(GL_TEXTURE_2D, g_FontTexture); 241 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 242 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 243 | glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); 244 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); 245 | 246 | // Store our identifier 247 | io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; 248 | 249 | // Restore state 250 | glBindTexture(GL_TEXTURE_2D, last_texture); 251 | } 252 | 253 | bool ImGui_ImplSdlGLES3_CreateDeviceObjects() 254 | { 255 | // Backup GL state 256 | GLint last_texture, last_array_buffer, last_vertex_array; 257 | glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); 258 | glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); 259 | glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); 260 | 261 | const GLchar *vertex_shader = 262 | "#version 300 es\n" 263 | "uniform mat4 ProjMtx;\n" 264 | "in vec2 Position;\n" 265 | "in vec2 UV;\n" 266 | "in vec4 Color;\n" 267 | "out vec2 Frag_UV;\n" 268 | "out vec4 Frag_Color;\n" 269 | "void main()\n" 270 | "{\n" 271 | " Frag_UV = UV;\n" 272 | " Frag_Color = Color;\n" 273 | " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" 274 | "}\n"; 275 | 276 | const GLchar* fragment_shader = 277 | "#version 300 es\n" 278 | "precision mediump float;" 279 | "uniform sampler2D Texture;\n" 280 | "in vec2 Frag_UV;\n" 281 | "in vec4 Frag_Color;\n" 282 | "out vec4 Out_Color;\n" 283 | "void main()\n" 284 | "{\n" 285 | " Out_Color = Frag_Color * texture( Texture, Frag_UV.st);\n" 286 | "}\n"; 287 | 288 | g_ShaderHandle = glCreateProgram(); 289 | g_VertHandle = glCreateShader(GL_VERTEX_SHADER); 290 | g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); 291 | glShaderSource(g_VertHandle, 1, &vertex_shader, 0); 292 | glShaderSource(g_FragHandle, 1, &fragment_shader, 0); 293 | glCompileShader(g_VertHandle); 294 | glCompileShader(g_FragHandle); 295 | glAttachShader(g_ShaderHandle, g_VertHandle); 296 | glAttachShader(g_ShaderHandle, g_FragHandle); 297 | glLinkProgram(g_ShaderHandle); 298 | 299 | g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); 300 | g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); 301 | g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position"); 302 | g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV"); 303 | g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color"); 304 | 305 | glGenBuffers(1, &g_VboHandle); 306 | glGenBuffers(1, &g_ElementsHandle); 307 | 308 | glGenVertexArrays(1, &g_VaoHandle); 309 | glBindVertexArray(g_VaoHandle); 310 | glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); 311 | glEnableVertexAttribArray(g_AttribLocationPosition); 312 | glEnableVertexAttribArray(g_AttribLocationUV); 313 | glEnableVertexAttribArray(g_AttribLocationColor); 314 | 315 | #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) 316 | glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); 317 | glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); 318 | glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); 319 | #undef OFFSETOF 320 | 321 | ImGui_ImplSdlGLES3_CreateFontsTexture(); 322 | 323 | // Restore modified GL state 324 | glBindTexture(GL_TEXTURE_2D, last_texture); 325 | glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); 326 | glBindVertexArray(last_vertex_array); 327 | 328 | return true; 329 | } 330 | 331 | void ImGui_ImplSdlGLES3_InvalidateDeviceObjects() 332 | { 333 | if (g_VaoHandle) glDeleteVertexArrays(1, &g_VaoHandle); 334 | if (g_VboHandle) glDeleteBuffers(1, &g_VboHandle); 335 | if (g_ElementsHandle) glDeleteBuffers(1, &g_ElementsHandle); 336 | g_VaoHandle = g_VboHandle = g_ElementsHandle = 0; 337 | 338 | if (g_ShaderHandle && g_VertHandle) glDetachShader(g_ShaderHandle, g_VertHandle); 339 | if (g_VertHandle) glDeleteShader(g_VertHandle); 340 | g_VertHandle = 0; 341 | 342 | if (g_ShaderHandle && g_FragHandle) glDetachShader(g_ShaderHandle, g_FragHandle); 343 | if (g_FragHandle) glDeleteShader(g_FragHandle); 344 | g_FragHandle = 0; 345 | 346 | if (g_ShaderHandle) glDeleteProgram(g_ShaderHandle); 347 | g_ShaderHandle = 0; 348 | 349 | if (g_FontTexture) 350 | { 351 | glDeleteTextures(1, &g_FontTexture); 352 | ImGui::GetIO().Fonts->TexID = 0; 353 | g_FontTexture = 0; 354 | } 355 | } 356 | 357 | bool ImGui_ImplSdlGLES3_Init(SDL_Window* window) 358 | { 359 | ImGuiIO& io = ImGui::GetIO(); 360 | io.KeyMap[ImGuiKey_Tab] = SDLK_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array. 361 | io.KeyMap[ImGuiKey_LeftArrow] = SDL_SCANCODE_LEFT; 362 | io.KeyMap[ImGuiKey_RightArrow] = SDL_SCANCODE_RIGHT; 363 | io.KeyMap[ImGuiKey_UpArrow] = SDL_SCANCODE_UP; 364 | io.KeyMap[ImGuiKey_DownArrow] = SDL_SCANCODE_DOWN; 365 | io.KeyMap[ImGuiKey_PageUp] = SDL_SCANCODE_PAGEUP; 366 | io.KeyMap[ImGuiKey_PageDown] = SDL_SCANCODE_PAGEDOWN; 367 | io.KeyMap[ImGuiKey_Home] = SDL_SCANCODE_HOME; 368 | io.KeyMap[ImGuiKey_End] = SDL_SCANCODE_END; 369 | io.KeyMap[ImGuiKey_Delete] = SDLK_DELETE; 370 | io.KeyMap[ImGuiKey_Backspace] = SDLK_BACKSPACE; 371 | io.KeyMap[ImGuiKey_Enter] = SDLK_RETURN; 372 | io.KeyMap[ImGuiKey_Escape] = SDLK_ESCAPE; 373 | io.KeyMap[ImGuiKey_A] = SDLK_a; 374 | io.KeyMap[ImGuiKey_C] = SDLK_c; 375 | io.KeyMap[ImGuiKey_V] = SDLK_v; 376 | io.KeyMap[ImGuiKey_X] = SDLK_x; 377 | io.KeyMap[ImGuiKey_Y] = SDLK_y; 378 | io.KeyMap[ImGuiKey_Z] = SDLK_z; 379 | 380 | io.RenderDrawListsFn = ImGui_ImplSdlGLES3_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. 381 | io.SetClipboardTextFn = ImGui_ImplSdlGLES3_SetClipboardText; 382 | io.GetClipboardTextFn = ImGui_ImplSdlGLES3_GetClipboardText; 383 | io.ClipboardUserData = NULL; 384 | 385 | #ifdef _WIN32 386 | SDL_SysWMinfo wmInfo; 387 | SDL_VERSION(&wmInfo.version); 388 | SDL_GetWindowWMInfo(window, &wmInfo); 389 | io.ImeWindowHandle = wmInfo.info.win.window; 390 | #else 391 | (void)window; 392 | #endif 393 | // Assume we already have the context 394 | 395 | glGetIntegerv = reinterpret_cast(SDL_GL_GetProcAddress("glGetIntegerv")); 396 | glActiveTexture = reinterpret_cast(SDL_GL_GetProcAddress("glActiveTexture")); 397 | glIsEnabled = reinterpret_cast(SDL_GL_GetProcAddress("glIsEnabled")); 398 | glEnable = reinterpret_cast(SDL_GL_GetProcAddress("glEnable")); 399 | glBlendEquation = reinterpret_cast(SDL_GL_GetProcAddress("glBlendEquation")); 400 | glBlendFunc = reinterpret_cast(SDL_GL_GetProcAddress("glBlendFunc")); 401 | glDisable = reinterpret_cast(SDL_GL_GetProcAddress("glDisable")); 402 | glViewport = reinterpret_cast(SDL_GL_GetProcAddress("glViewport")); 403 | glUseProgram = reinterpret_cast(SDL_GL_GetProcAddress("glUseProgram")); 404 | glUniform1i = reinterpret_cast(SDL_GL_GetProcAddress("glUniform1i")); 405 | glUniformMatrix4fv = reinterpret_cast(SDL_GL_GetProcAddress("glUniformMatrix4fv")); 406 | glBindVertexArray = reinterpret_cast(SDL_GL_GetProcAddress("glBindVertexArray")); 407 | glBindBuffer = reinterpret_cast(SDL_GL_GetProcAddress("glBindBuffer")); 408 | glBufferData = reinterpret_cast(SDL_GL_GetProcAddress("glBufferData")); 409 | glBindTexture = reinterpret_cast(SDL_GL_GetProcAddress("glBindTexture")); 410 | glDrawElements = reinterpret_cast(SDL_GL_GetProcAddress("glDrawElements")); 411 | glScissor = reinterpret_cast(SDL_GL_GetProcAddress("glScissor")); 412 | glBlendEquationSeparate = reinterpret_cast(SDL_GL_GetProcAddress("glBlendEquationSeparate")); 413 | glBlendFuncSeparate = reinterpret_cast(SDL_GL_GetProcAddress("glBlendFuncSeparate")); 414 | glGenTextures = reinterpret_cast(SDL_GL_GetProcAddress("glGenTextures")); 415 | glTexParameteri = reinterpret_cast(SDL_GL_GetProcAddress("glTexParameteri")); 416 | glPixelStorei = reinterpret_cast(SDL_GL_GetProcAddress("glPixelStorei")); 417 | glTexImage2D = reinterpret_cast(SDL_GL_GetProcAddress("glTexImage2D")); 418 | glCreateProgram = reinterpret_cast(SDL_GL_GetProcAddress("glCreateProgram")); 419 | glCreateShader = reinterpret_cast(SDL_GL_GetProcAddress("glCreateShader")); 420 | glShaderSource = reinterpret_cast(SDL_GL_GetProcAddress("glShaderSource")); 421 | glCompileShader = reinterpret_cast(SDL_GL_GetProcAddress("glCompileShader")); 422 | glAttachShader = reinterpret_cast(SDL_GL_GetProcAddress("glAttachShader")); 423 | glLinkProgram = reinterpret_cast(SDL_GL_GetProcAddress("glLinkProgram")); 424 | glGetUniformLocation = reinterpret_cast(SDL_GL_GetProcAddress("glGetUniformLocation")); 425 | glGetAttribLocation = reinterpret_cast(SDL_GL_GetProcAddress("glGetAttribLocation")); 426 | glGenBuffers = reinterpret_cast(SDL_GL_GetProcAddress("glGenBuffers")); 427 | glGenVertexArrays = reinterpret_cast(SDL_GL_GetProcAddress("glGenVertexArrays")); 428 | glEnableVertexAttribArray = reinterpret_cast(SDL_GL_GetProcAddress("glEnableVertexAttribArray")); 429 | glVertexAttribPointer = reinterpret_cast(SDL_GL_GetProcAddress("glVertexAttribPointer")); 430 | glDeleteVertexArrays = reinterpret_cast(SDL_GL_GetProcAddress("glDeleteVertexArrays")); 431 | glDeleteBuffers = reinterpret_cast(SDL_GL_GetProcAddress("glDeleteBuffers")); 432 | glDetachShader = reinterpret_cast(SDL_GL_GetProcAddress("glDetachShader")); 433 | glDeleteTextures = reinterpret_cast(SDL_GL_GetProcAddress("glDeleteTextures")); 434 | glDeleteShader = reinterpret_cast(SDL_GL_GetProcAddress("glDeleteShader")); 435 | glDeleteProgram = reinterpret_cast(SDL_GL_GetProcAddress("glDeleteProgram")); 436 | 437 | return true; 438 | } 439 | 440 | void ImGui_ImplSdlGLES3_Shutdown() 441 | { 442 | ImGui_ImplSdlGLES3_InvalidateDeviceObjects(); 443 | ImGui::Shutdown(); 444 | } 445 | 446 | void ImGui_ImplSdlGLES3_NewFrame(SDL_Window* window) 447 | { 448 | if (!g_FontTexture) 449 | ImGui_ImplSdlGLES3_CreateDeviceObjects(); 450 | 451 | ImGuiIO& io = ImGui::GetIO(); 452 | 453 | // Setup display size (every frame to accommodate for window resizing) 454 | int w, h; 455 | int display_w, display_h; 456 | SDL_GetWindowSize(window, &w, &h); 457 | SDL_GL_GetDrawableSize(window, &display_w, &display_h); 458 | io.DisplaySize = ImVec2((float)w, (float)h); 459 | io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); 460 | 461 | // Setup time step 462 | Uint32 time = SDL_GetTicks(); 463 | double current_time = time / 1000.0; 464 | io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f / 60.0f); 465 | g_Time = current_time; 466 | 467 | // Setup inputs 468 | // (we already got mouse wheel, keyboard keys & characters from SDL_PollEvent()) 469 | int mx, my; 470 | Uint32 mouseMask = SDL_GetMouseState(&mx, &my); 471 | if (SDL_GetWindowFlags(window) & SDL_WINDOW_MOUSE_FOCUS) 472 | io.MousePos = ImVec2((float)mx, (float)my); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.) 473 | else 474 | io.MousePos = ImVec2(-1, -1); 475 | 476 | io.MouseDown[0] = g_MousePressed[0] || (mouseMask & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. 477 | io.MouseDown[1] = g_MousePressed[1] || (mouseMask & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0; 478 | io.MouseDown[2] = g_MousePressed[2] || (mouseMask & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0; 479 | g_MousePressed[0] = g_MousePressed[1] = g_MousePressed[2] = false; 480 | 481 | io.MouseWheel = g_MouseWheel; 482 | g_MouseWheel = 0.0f; 483 | 484 | // Hide OS mouse cursor if ImGui is drawing it 485 | SDL_ShowCursor(io.MouseDrawCursor ? 0 : 1); 486 | 487 | // Start the frame 488 | ImGui::NewFrame(); 489 | } 490 | 491 | 492 | #endif // GL_PROFILE_GLES3 493 | --------------------------------------------------------------------------------