Imgui: Imgui on Android question

Created on 25 Jun 2017  路  11Comments  路  Source: ocornut/imgui

Hi!
I am currently trying to run imgui on android via ndk/jni.
So I found this
But I don't want to use SDL2, I want to just use Android's GLSurfaceView and GLSurfaceView.Renderer and then pass native methods for opengl rendering (I have to admit that I've downloaded this imgui+sdl2+android demo from google store and it works great on my device).
So I've built my own demo using GLSurfaceView and it works only if I don't mix it with my own opengl ;/

I added a .zip with all the demo. You can build it with:
ndk-build
ant-debug
adb install -r bin/ImguiExample-debug.apk
This is my rendering loop callback:

```
void renderFrame() {
glClearColor(grey, grey, grey, 1.0f);
glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
ImGui_ImplAndroidGLES2_NewFrame(screenWidth, screenHeight, currentTimeInMilliseconds()-startTime);
{
static float f = 0.0f;
ImGui::SetNextWindowSize(ImVec2(200, 200), ImGuiSetCond_FirstUseEver);
ImGui::Text("Hello, world!");
ImGui::SliderFloat("float", &f, 0.0f, 1.0f);
ImGui::ColorEdit3("clear color", (float *) &imClearColor);
if (ImGui::Button("Test Window")) showTestWindow = !showTestWindow;
if (ImGui::Button("Another Window")) showAnotherWindow = !showAnotherWindow;
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)",
1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
}
// 2. Show another simple window, this time using an explicit Begin/End pair
if (showAnotherWindow)
{
ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver);
ImGui::Begin("Another Window", &showAnotherWindow);
ImGui::Text("Hello");
ImGui::End();
}
// 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow()
if (showTestWindow)
{
ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiSetCond_FirstUseEver);
ImGui::ShowTestWindow(&showTestWindow);
}
ImGui::Render();
glUseProgram(gProgram);
checkGlError("glUseProgram");
glBindBuffer(GL_ARRAY_BUFFER, vbo);

 //THIS IS IMPORTANT
//After commentig glVertexAttribArray call imgui start working without glitches
glVertexAttribPointer(gvPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0);

glEnableVertexAttribArray(gvPositionHandle);
glDrawArrays(GL_TRIANGLES, 0, 3);
checkGlError("glDrawArrays");
glBindBuffer(GL_ARRAY_BUFFER, 0);

}
```

I use imgui implementation provided with android example I've linked, with slight changes (I dont use SDL2 and I commented out all events related code for now).

This happens when I try to render both imgui and my own opengl triangle

For me it looks like opengl state wasn't handled properly (glVertexAttribPointer call is messing it somehow). Do you have any idea what may be the problem?

backenbinding

Most helpful comment

Hahahaha! Thanks!
It works now!
imgui_android3

Fixed code:
imgui_android.zip

Thanks a lot!

All 11 comments

You're drawing over your ImGui windows. Try moving your ImGui::Render() call after you're done rendering your graphics.

Not sure if that's related, but in your vertex shader you're expecting a vec4, but you actually try to pass vec2s.

I have changed it to this:

void renderFrame() {
    ImGui_ImplAndroidGLES2_NewFrame(screenWidth, screenHeight, currentTimeInMilliseconds()-startTime);
    {
        static float f = 0.0f;
        ImGui::SetNextWindowSize(ImVec2(200, 200), ImGuiSetCond_FirstUseEver);
        ImGui::Text("Hello, world!");
        ImGui::SliderFloat("float", &f, 0.0f, 1.0f);
        ImGui::ColorEdit3("clear color", (float *) &imClearColor);
        if (ImGui::Button("Test Window")) showTestWindow = !showTestWindow;
        if (ImGui::Button("Another Window")) showAnotherWindow = !showAnotherWindow;
        ImGui::Text("Application average %.3f ms/frame (%.1f FPS)",
                    1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
    }

    // 2. Show another simple window, this time using an explicit Begin/End pair
    if (showAnotherWindow)
    {
        ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver);
        ImGui::Begin("Another Window", &showAnotherWindow);
        ImGui::Text("Hello");
        ImGui::End();
    }

    // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow()
    if (showTestWindow)
    {
        ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiSetCond_FirstUseEver);
        ImGui::ShowTestWindow(&showTestWindow);
    }

    static float grey;
    grey += 0.01f;
    if (grey > 1.0f) {
        grey = 0.0f;
    }
    glClearColor(grey, grey, grey, 1.0f);
    checkGlError("glClearColor");
    glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
    checkGlError("glClear");




    glUseProgram(gProgram);
    checkGlError("glUseProgram");

    glBindBuffer(GL_ARRAY_BUFFER, vbo);

    //After commentig glVertexAttribArray rendering imgui works fine
    glVertexAttribPointer(gvPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0);
    glEnableVertexAttribArray(gvPositionHandle);

    glDrawArrays(GL_TRIANGLES, 0, 3);
    checkGlError("glDrawArrays");
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    ImGui::Render();
}

It results in following screenshot:
this

If i comment glVertexAttribPointer the imgui renders perfectly well.
By the way: where can I find description of ImGui::Render and other crucial functions of imgui?

Have you tried changing your vPosition to vec2 in your shader? I'm not sure what the official spec says about matching the number of components in the shader to the size parameter of your glVertexAttribPointer calls, but even if it's allowed to provide less data than the shader expects, it's probably an edge case, and android gles implementations are not known for handling edge cases well.

Most of the docs are in the source and header files themselves, here's a short programming guide: https://github.com/ocornut/imgui/blob/master/imgui.cpp#L79

Yeah, I've changed vertex shader, just forgot to write about it in previous comment
It looks like this now:

auto gVertexShader =
    "attribute vec2 vPosition;\n"
    "void main() {\n"
    "  gl_Position = vec4(vPosition.x, vPosition.y, 0, 0);\n"
    "}\n";

Shouldn't it read

"   gl_Position = vec4(vPosition.x, vPosition.y, 0.0, 1.0);\n"

? You probably don't want your w coord set to 0, and I believe you're not allowed to use integral literals where floats are expected in es2.

Upon closer inspection, it seems like imgui_impl_android is adapted from opengl3 example, with any mention of VAOs removed (as they are not part of es2 spec). This probably means you want to move all of the glEnableVertexAttribArray and glVertexAttribPointer calls from ImGui_ImplAndroidGLES2_CreateDeviceObjects() to ImGui_ImplAndroidGLES2_RenderDrawLists().

Hahahaha! Thanks!
It works now!
imgui_android3

Fixed code:
imgui_android.zip

Thanks a lot!

It would be good if the android example had an official maintainer to make them nice and simple and synched to the other examples!

@ocornut I'd say an OpenGL ES2 implementation (preferably with SDL2, since it seems to be the most cross-platform solution) should be sufficient. Creating a full Android Studio project isn't hard, but it seems like everyone and their cat has their own unique workflow, with build systems ranging from shell scripts and makefiles to cmake + standalone toolchains to "official" gradle support. I've converted a project from ant+ndk-build to gradle+invoking ndk-build through a cmd to gradle-experimental to gradle+cmake over a span of two years, and while I now have some cutting-edge technology like a resource-hungry IDE with C++ syntax highlighting and almost working debugging, I'm not sure google won't think of moving to yet another build system next week.

It could help someone if you want to build a simple project with SDL2, ndk-build and ant :
https://github.com/yoyz/android/
and this directory :
https://github.com/yoyz/android/tree/master/androidimguisdl

I've been able to build it and put it on my zenfone2 this afternoon without issue.

@sfalexrog I'd take the Android example solution that is the most standard while not taking too much disk space on Git if possible (avoid unnecessary large files such as large icons). I don't have an Android device and would be happy if an official, simple, example was made available (with support for things like text input using the io.WantTextInput flag to spawn on-screen keyboard, etc.). Or somebody to guide me to keep the PR #421 to up to date, perhaps fix it if needed, and then we merge it.
Thanks!
(ping @proppy who once expressed interested in helping making such example?)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

SlNPacifist picture SlNPacifist  路  3Comments

dowit picture dowit  路  3Comments

bizehao picture bizehao  路  3Comments

ILoveImgui picture ILoveImgui  路  3Comments

mnemode2 picture mnemode2  路  3Comments