├── 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 | 
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 |
--------------------------------------------------------------------------------