Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Imgui on Android question #1200

Closed
stawrocek opened this issue Jun 25, 2017 · 12 comments
Closed

Imgui on Android question #1200

stawrocek opened this issue Jun 25, 2017 · 12 comments
Labels

Comments

@stawrocek
Copy link

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?

@sfalexrog
Copy link

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.

@stawrocek
Copy link
Author

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?

@sfalexrog
Copy link

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

@stawrocek
Copy link
Author

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";

@sfalexrog
Copy link

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.

@sfalexrog
Copy link

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().

@stawrocek
Copy link
Author

Hahahaha! Thanks!
It works now!
imgui_android3

Fixed code:
imgui_android.zip

Thanks a lot!

@ocornut
Copy link
Owner

ocornut commented Jun 25, 2017 via email

@sfalexrog
Copy link

@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.

@yoyz
Copy link

yoyz commented Jun 26, 2017

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.

@ocornut
Copy link
Owner

ocornut commented Aug 6, 2017

@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?)

@ocornut
Copy link
Owner

ocornut commented Mar 4, 2021

Closing this,
FYI

  • We have native backend + example in WIP: Native Android backend + example #3446
  • The SDL based example in Android + OpenGL ES 3 Example #421 which back in its 2015 iteration was a little of a mess has been revamped and it now rather clean and I expect/hope we can transition it into support files for the existing e.g. example_sdl_opengl3/ example, as generally we would recommend using SDL rather than Android native API.

@ocornut ocornut closed this as completed Mar 4, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants