kotlin-graphics/imgui

JME3: Init

Closed this issue · 14 comments

So I finally managed to get the dependencies working proerply in combination with jme3 :)

	@Override
	protected void initialize(Application app) {
		this.rendererapp = app;
		ImGui.INSTANCE.initialize();
		fontTexture = IO.INSTANCE.getFonts().getTexDataAsRGBA32();
                //TODO pack into jme texture and upload after this
	}

I try to roughly follow the generic lwjgl3 binding already provided, but bring it into a jme appstate.
Am I missing some other required call in before?

I get some kind of assertion from the depth of the font system, sadly I do not really understand the reason for this:

fontAtlas.class@461
    fun addCustomRectRegular(id: Int, width: Int, height: Int): Int {
        assert(id >= 0x10000 && width in 0..0xFFFF && height in 0..0xFFFF)
        val r = CustomRect()
        r.id = id
        r.width = width
        r.height = height
        customRects.add(r)
        return customRects.lastIndex
    }

width is 181, height is 27, but id is -2147483648.
The call comes from here:

    fun buildRegisterDefaultCustomRects() {
        if (customRectIds[0] < 0)
            customRectIds[0] = addCustomRectRegular(DefaultTexData.id, DefaultTexData.wHalf * 2 + 1, DefaultTexData.h)
    }

Sadly I'm missing kotlin knowledge & ide support support a bit, and cannot figure out why the id has that value (or where it actually comes from)

Hi dear,

glad to read that

Before we go on, let me first sync with this commit, because it'll affect the way things get initialized and destroyed (basically no more static Context)

I'll be back :p

Ok, so:

instantiate a Context and init imgui like this:

    ctx = new Context()
    JoglGL3.init(window, true)

Then at each display():

  • newFrame()
  • gui logic
  •     imgui.render()
        joglGl3.renderDrawData(imgui.getDrawData())
    

And at dispose():

    joglGL3.shutdown(gl)
    ctx.destroy()

Where imgui = ImGuI.INSTANCE and joglGl3 = JoglGL3.INSTANCE

Let me know :)

Hm new old issue:
I got a bit further, however with assertions enabled, the fonts.kt seems to throw an error. In my opinion this might actually be an issue with the imgui code.

In font.kt@902 DefaultTexData id is populated with val id = 0x80000000.i, in th jvm (due to signed integers) this evaluates to -2147483648 (as it overflows silently)
In font.kt@420 addCustomRectRegular the values of this id is checked with an assertion:
assert(id >= 0x10000 && width in 0..0xFFFF && height in 0..0xFFFF)
obviously the -2147483648 does not fulfill this criteria.

Please advice

Oh shit, I didn't have -ea on my test configuration...

Anyway, fixed that, I then caught another assert.. I'll check that with calm, but in the meanwhile I commented it so imgui can work

Ok, thanks I managed to get further, actually it seems that i have the loop running, however I do not yet see anything.

void onRenderingFrame(){
   imgui.newFrame()
   imgui.text("Testtest")
   imgui.render()
  lwjglGL3.renderDrawData(imgui.getDrawData())
}

Sadly I'm missing abit imgui knowledge, as I never used the c version.
Should this already display the text on the screen? Or is something more required to see anything?
(Eg. I'm trying to determine, if I miss something, or if that method is executed at the wrong point in the engines renderloop (e.g before a framebuffer clear or similar)

Can you show me some additional code? Do you have a repo?

I guess we shall create some sort of jogl implementation for JM3

I can provide coder in the evening when I'm back at home.
Actually that way my plan (this is basically a first step), to provide a similar class, that directly uses the engines interfaces instead of lwjgl or jogl specific binds. That way it could be used with each renderer implementation in the engine.

The first part (getting the font texture to engine native objects works without issues (even using the alpha8 one already), and I'm currently figuring out how to render the drawlist.

The idea here is, that once I have the simple implementation (using the lwjglgl3) outputting valid drawlists, I could validate my results with a side to side comparison. (Eg when I need to implement a shader for clipping)

This would be the current (very ugly) test code I use. Question is (if the render call is at the right point in time, and not before a clear or similar) if some ui should be visible.

package com.jme3.imgui;

import glm_.vec2.Vec2;
import glm_.vec2.Vec2i;
import imgui.Context;
import imgui.DrawData;
import imgui.DrawList;
import imgui.FontAtlas;
import imgui.IO;
import imgui.ImGui;
import imgui.impl.LwjglGL3;
import uno.glfw.GlfwWindow;

public class ImGuiState extends BaseAppState {
	private Application	rendererapp;
	private Context		ctx;
	private IO			io;
	private Texture2D	font;
	private float		time;
	private float		tpf;

	public ImGuiState() {
	}

	@Override
	protected void initialize(Application app) {
		this.rendererapp = app;
		LwjglWindow context = (LwjglWindow) app.getContext();

		ctx = new Context();
		io = ctx.getIo();
		GlfwWindow window = new GlfwWindow(context.getWindowHandle());
		LwjglGL3.INSTANCE.init(window, false);
		ImGui.INSTANCE.styleColorsDark(null);
		// Triple<ByteBuffer, Vec2i, Integer> font =
		// ctx.getIo().getFonts().getTexDataAsAlpha8();
		// ByteBuffer rawData = font.component1();
		// Vec2i resolution = font.component2();
		// Integer bytesPixel = font.component3();
		// assert bytesPixel == 1;
		//
		// Image img = new Image(Format.Alpha8, resolution.x, resolution.y,
		// rawData, ColorSpace.Linear);
		// this.font = new Texture2D(img);
	}

	@Override
	protected void cleanup(Application app) {
		ctx.shutdown();
		// TODO Auto-generated method stub

	}

	@Override
	public void render(RenderManager rm) {
		LwjglGL3.INSTANCE.newFrame();
		ImGui.INSTANCE.showDemoWindow(new boolean[] {true});
 
		ImGui.INSTANCE.text("Hello, world!");
		float[] f = {0f};
		ImGui.INSTANCE.sliderFloat("float", f, 0f, 1f, "%.3f", 1f);       // Edit 1 float using a slider from 0.0f to 1.0f
		ImGui.INSTANCE.colorEdit3("clear color", new float[]{1,0,0}, 0);               // Edit 3 floats representing a color

		 boolean[] showDemo = {true};
		
		ImGui.INSTANCE.checkbox("Demo Window", showDemo);                 // Edit bools storing our windows open/close state
		
		ImGui.INSTANCE.render();

		DrawData drawData = ImGui.INSTANCE.getDrawData();
		System.out.println(drawData.getValid());
		LwjglGL3.INSTANCE.renderDrawData(drawData);
	}

	@Override
	public void update(float tpf) {
		this.tpf = tpf;
		super.update(tpf);
	}

}

One question, are you using lwjgl or jogl backend?

I use the lwjgl3 renderer in jme3.

Try adding a glViewport() before

ImGui.INSTANCE.render();

and also check against gl errors

Hm this does not seem to do the trick.
I meanwhile checked the drawdata, and it seems to contain valid data, so it is some engine related issue.
I asked in the engine forum, and was directed towards a integration of another ui library, that basically renders similar. I will report back after testing the approach used by them.

Here?

Anyway, we may try to debug it by starting rendering a very simple triangle and then go on from that, but only if you want

Thanks for the feedback, tough!

Hi! Friendly reminder that there has been no activity here for over a month and this appears to be fixed. If you wish to keep this open, please respond with what still is an issue, or this will be closed in a week. Thanks!