Quick Links: Download Gideros Studio | Gideros Documentation | Gideros Development Center | Gideros community chat | DONATE
imGui bindings - Page 3 — Gideros Forum

imGui bindings

1356715

Comments

  • rrraptorrrraptor Member
    edited August 2020
    antix said:

    @rrraptor That's a great idea but personally I don't think it's worthwhile. I say that because I don't see Gideros ever being able to make apps that need a user interfaces as complex as that since Gideros is really a gaming platform, not a utility platform.

    You dont have to create apps. What if I want to create a city building simulator or something like Factorio or maybe a strategy game? In all cases, the UI will be pretty complex.
    Check this out.
    antix said:

    Also.. your little GUI framework is very good and more than Gideros needs I'd say ;)

    No, it is missing a lot of stuff, like drop downs, popups, text input dialogs (single line and nultiline) and e.t.c.

    As I said, I can try to create a binding, but I dont know where to start. It sounds not that hard:
    Integrating Dear ImGui within your custom engine is a matter of
    1) wiring mouse/keyboard/gamepad inputs
    2) uploading one texture to your GPU/render engine
    3) providing a render function that can bind textures and render textured triangles.
    But the only thing that I can do by my self is mouse and keyboard inputs, but not the drawing stuff.
  • hgy29hgy29 Maintainer
    I can help with the drawing stuff, luckily gideros has internal apis usable by plugins for that.
  • hgy29 said:

    I can help with the drawing stuff, luckily gideros has internal apis usable by plugins for that.

    It look like this, right?
    static Application* application;
    static lua_State *L;
     
    class ImGuiSprite {
    public:
    	ImGuiSprite(LuaApplication* application, lua_State *L);
    	virtual ~ImGuiSprite();
    	SpriteProxy *proxy_;
    	void doDraw(const CurrentTransform&, float sx, float sy, float ex, float ey);
    private:
    	void drawMesh();
    	LuaApplication* application_;
     
    	// declare vertex and color arrays to be able to draw triangles?
    };
     
    static void b2PSS_Draw(void *c, const CurrentTransform&t, float sx, float sy,
    		float ex, float ey) {
    	((ImGuiSprite *) c)->doDraw(t, sx, sy, ex, ey);
    }
     
    static void b2PSS_Destroy(void *c) {
    	delete ((ImGuiSprite *) c);
    }
     
    ImGuiSprite::ImGuiSprite(LuaApplication* application, lua_State *L)
    {
    	application_ = application;	
    	proxy_ = gtexture_get_spritefactory()->createProxy(application->getApplication(), this, b2PSS_Draw, b2PSS_Destroy);
    }
     
    ImGuiSprite::~ImGuiSprite() {
    	delete proxy_;
    	// gevent_RemoveEventsWithGid(gid);
    }
     
    int createSpineSprite(lua_State *L) {
    	LuaApplication* application = static_cast<LuaApplication*>(luaL_getdata(L));
    	::application = application->getApplication();
    	Binder binder(L);
    	ImGuiSprite *ps = new ImGuiSprite(application, L);
     
    	binder.pushInstance("SpineSprite", ps->proxy_);
     
    	luaL_rawgetptr(L, LUA_REGISTRYINDEX, &keyWeak);
    	lua_pushvalue(L, -2);
    	luaL_rawsetptr(L, -2, ps);
    	lua_pop(L, 1);
     
    	return 1;
    }


    I tried to compile this, but got an error... I dont realy remember what kind of error, but it was related to "binder.pushInstance".
  • hgy29hgy29 Maintainer
    Yes, something like that. It is more complex than for other plugins as you need full Gideros source tree, but you are on the right track.
  • hgy29hgy29 Maintainer
    I think the issue was that 'binder' class isn't actually visible from plugins, so you have to compile it inside the plugin by including "luabinding/binder.cpp" inside your plugin

    Likes: rrraptor

    +1 -1 (+1 / -0 )Share on Facebook
  • Thanks @rrraptor for working on this, it will be an awesome addition.

    Likes: MoKaLux, rrraptor

    +1 -1 (+2 / -0 )Share on Facebook
  • rrraptorrrraptor Member
    edited August 2020
    hgy29 said:

    I think the issue was that 'binder' class isn't actually visible from plugins, so you have to compile it inside the plugin by including "luabinding/binder.cpp" inside your plugin

    Ty, that worked :)

    Btw, can I setup qt so it will put the dll to "plugins" folder ? :D
    Solved
    DESTDIR = ../../../plugins/
  • Finally I figured out how to get ImGui to work :D It successfully generated a default font and seems like mouse inputs also works.

    Imgui.png
    959 x 442 - 25K

    Likes: keszegh, hgy29, MoKaLux

    +1 -1 (+3 / -0 )Share on Facebook
  • Wonderful rrraptor, with this addition gideros will be number 1 :)
    my growING GIDEROS github repositories: https://github.com/mokalux?tab=repositories
  • rrraptorrrraptor Member
    edited August 2020
    @hgy29 how can I redefine a ImGui assertion macro to get error messages ?

    It says that you need to change macro in imgui.h:
    //---- Define assertion handler. Defaults to calling assert().
    // If your macro uses multiple statements, make sure is enclosed in a 'do { .. } while (0)' block so it can be used as a single statement.
    //#define IM_ASSERT(_EXPR)  MyAssert(_EXPR)
    //#define IM_ASSERT(_EXPR)  ((void)(_EXPR))     // Disable asserts
    But in order to use lua_error(lua_State *L) I need a lua_State. But idk how to get/use it in macro.

    Example use of IM_ASSERT:
     IM_ASSERT(g.Initialized);
    IM_ASSERT((g.IO.DeltaTime > 0.0f || g.FrameCount == 0)              && "Need a positive DeltaTime!");
    ...
    IM_ASSERT(text != NULL);
  • hgy29hgy29 Maintainer
    Something like:
    #include "glog.h" //From gideros SDK
    #define IM_ASSERT( exp ) \
        ( (exp) ? (void)0 : glog_v("Failed assertion at %s:%d %s\n",  __FILE__,__LINE__, #exp))
    Log will be sent to the debugger. If you are on windows, you can use DebugView to see them without a debugger.
  • rrraptorrrraptor Member
    edited August 2020
    @hgy29 I'll try. I made simpliest version, and seems like it works. Now its time to create drawing stuff?

    Plugin source is attached. There is a "MyImGuiRenderFunction" function that handles the drawing stuff. ImGui initialization in "initImGui" function.

    Demo code:
    require "ImGui"
     
    local imgui = ImGui.new()
    stage:addChild(imgui)
     
    function enterFrame(e)
    	imgui:NewFrame(e)
     
    	imgui:Begin("My window")
    	imgui:Text("Hello world")
    	imgui:End()
     
    	imgui:EndFrame()
    	imgui:Render()
    end
     
    stage:addEventListener("mouseDown", function(e) imgui:onMouseDown(e) end)
    stage:addEventListener("mouseUp", function(e) imgui:onMouseUp(e) end)
    stage:addEventListener("mouseHover", function(e) imgui:onMouseHover(e) end)
    stage:addEventListener("enterFrame", enterFrame)
    Result shoud be something like this:


    P.S. I forgot about screen resolution :disappointed: Its 200x200 by default :)

    upload_2017-11-25_18-29-2.png
    163 x 124 - 30K
    zip
    zip
    ImGui.zip
    1M
    222.png
    507 x 166 - 8K
    +1 -1 (+2 / -0 )Share on Facebook
  • i see imGui is not following the sprite hierarchy philosophy, instead the 'redraw on each frame' philosophy. that's a bit inconvenient, in gideros code it will look strange, but i guess we can live with it.
  • rrraptorrrraptor Member
    edited August 2020
    keszegh said:

    i see imGui is not following the sprite hierarchy philosophy, instead the 'redraw on each frame' philosophy. that's a bit inconvenient, in gideros code it will look strange, but i guess we can live with it.

    It is called "Immediate" mode.

    http://forum.giderosmobile.com/discussion/comment/63638/#Comment_63638

    Anyways, I think it is easier to create a binding of existing GUI library rather than trying to create you own solution from scratch. Also, I will coninue working on my "retained" lib :)

    Likes: keszegh, MoKaLux

    +1 -1 (+2 / -0 )Share on Facebook
  • hgy29hgy29 Maintainer
    @rraptor, here is your main.cpp modified for rendering.
    New init code from lua: wpre lang="lua">
    local imgui = ImGui.new(application:getContentWidth(),application:getContentHeight())

    Result:

    zip
    zip
    main.zip
    4K
    GID-imgui.png
    560 x 451 - 9K
    +1 -1 (+2 / -0 )Share on Facebook
  • rrraptorrrraptor Member
    edited August 2020
    Something went wrong :smile: Light theme does not work corectly (is just me, nevermind :D). Clipping does not work corectly.


    P.S. Fixed mouse.
    image.png
    1282 x 772 - 47K
    zip
    zip
    main_mouse_fixed.zip
    4K

    Likes: MoKaLux

    +1 -1 (+1 / -0 )Share on Facebook
  • hgy29hgy29 Maintainer
    rrraptor said:

    Clipping does not work corectly.

    Now you say that, I didn't pay much attention to clipping values, and assumed they were x,y,w,h while they seem to be x1,y1,x2,y2 instead.
    Try to change
    engine->pushClip((int)(pcmd->ClipRect.x - pos.x), (int)(pcmd->ClipRect.y - pos.y), (int)(pcmd->ClipRect.z - pos.x), (int)(pcmd->ClipRect.w - pos.y));
    into
    engine->pushClip((int)(pcmd->ClipRect.x - pos.x), (int)(pcmd->ClipRect.y - pos.y), (int)(1+pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(1+pcmd->ClipRect.w - pcmd->ClipRect.y));
    (I am not sure about the '1+')
  • hgy29 said:

    rrraptor said:

    Clipping does not work corectly.

    Now you say that, I didn't pay much attention to clipping values, and assumed they were x,y,w,h while they seem to be x1,y1,x2,y2 instead.
    Try to change
    engine->pushClip((int)(pcmd->ClipRect.x - pos.x), (int)(pcmd->ClipRect.y - pos.y), (int)(pcmd->ClipRect.z - pos.x), (int)(pcmd->ClipRect.w - pos.y));
    into
    engine->pushClip((int)(pcmd->ClipRect.x - pos.x), (int)(pcmd->ClipRect.y - pos.y), (int)(1+pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(1+pcmd->ClipRect.w - pcmd->ClipRect.y));
    (I am not sure about the '1+')
    Ok, that works, ty.



    1 more question. Lines are sharp, but in original they are smooth.
    xxx.png
    939 x 599 - 27K
    xxx.png 26.7K
  • hgy29hgy29 Maintainer
    rrraptor said:


    1 more question. Lines are sharp, but in original they are smooth.

    I don't know for that one

  • rrraptorrrraptor Member
    edited August 2020
    hgy29 said:

    rrraptor said:


    1 more question. Lines are sharp, but in original they are smooth.

    I don't know for that one

    Premultiplied alpha maybe?
  • hgy29hgy29 Maintainer
    Yes, it looks better when premultiplying with alpha.
    I changed render code for colors with
               uint32_t c=vtx_buffer[i].col;
               uint32_t a=(c&0xFF000000)>>24;
               uint32_t b=(c&0xFF0000)>>16;
               uint32_t g=(c&0xFF00)>>8;
               uint32_t r=(c&0xFF)>>0;
               colors[i].b=(b*a)>>8;
               colors[i].g=(g*a)>>8;
               colors[i].r=(r*a)>>8;
               colors[i].a=a;
    instead of just
    colors[i]=vtx_buffer[i].col;
    and changed the definitions of the colors buffer too:
        struct _Color {
            uint8_t r,g,b,a;
        };
        VertexBuffer<_Color> colors;

    Likes: rrraptor

    +1 -1 (+1 / -0 )Share on Facebook
  • Wow! :)

    Likes: MoKaLux

    Coder, video game industry veteran (since the '80s, ❤'s assembler), arrested - never convicted hacker (in the '90s), dad of five, he/him (if that even matters!).
    https://deluxepixel.com
    +1 -1 (+1 / -0 )Share on Facebook
  • keszeghkeszegh Member
    edited August 2020
    @SinisterSoft, i knew that adding this cannot be that hard, finally we are lucky to have @rrraptor around to do the dirty job with the help of @hgy29. thanks for you all.
    +1 -1 (+2 / -0 )Share on Facebook
  • btw guys, how does this 'immediate' mode affect performance? there is a lot of lua code that needs to be run at each enterframe.
  • rrraptorrrraptor Member
    edited August 2020
    keszegh said:

    btw guys, how does this 'immediate' mode affect performance? there is a lot of lua code that needs to be run at each enterframe.

    I cant tell you right now, because the entire lua code looks like that:
    require "ImGui"
     
    local imgui = ImGui.new()
    stage:addChild(imgui)
     
    function enterFrame(e)
    	imgui:NewFrame(e)
     
    	imgui:ShowDemoWindow()
     
    	imgui:EndFrame()
    	imgui:Render()
    end
     
    stage:addEventListener("mouseDown", function(e) imgui:onMouseDown(e) end)
    stage:addEventListener("mouseUp", function(e) imgui:onMouseUp(e) end)
    stage:addEventListener("mouseHover", function(e) imgui:onMouseHover(e) end)
    stage:addEventListener("mouseMove", function(e) imgui:onMouseMove(e) end)
    stage:addEventListener("enterFrame", enterFrame)
    "ShowDemoWindow" uses built-in function.

    But I just looked at CPU usage in windows task manager and its about 2-4%
  • rrraptorrrraptor Member
    edited August 2020
    @hgy29 how can I get keyboard modifiers? I dont see any method in "LuaApplication" or "Application" that can help me. Also, can I add callback to detect if window is resized/lose focus without using lua?
  • rrraptorrrraptor Member
    edited August 2020
    Is it problem from my side or renderer side? Texture is streched on the edges.


    Code:
    void* getTexture(lua_State *L, int idx = 1)
    {
        Binder binder(L);
     
        if (binder.isInstanceOf("TextureBase", idx))
        {
            TextureBase* textureBase = static_cast<TextureBase*>(binder.getInstance("TextureBase", idx));
            return (void *)textureBase->data->gid;
        }
        else if (binder.isInstanceOf("TextureRegion", idx))
        {
            BitmapData* bitmapData = static_cast<BitmapData*>(binder.getInstance("TextureRegion", idx));
            return (void *)bitmapData->texture()->data->gid;
        }
        else
        {
            lua_pushstring(L, "Type mismatch. 'TextureBase' or 'TextureRegion' expected.");
            lua_error(L);
        }
    }
    int ImGui_impl_Image(lua_State *L)
    {
        void *tex = getTexture(L, 2);
        float w = luaL_checknumber(L, 3);
        float h = luaL_checknumber(L, 4);
        const ImVec2& size = ImVec2(w, h);
        ImGui::Image(tex, size);
        return 0;
    }
    _image.png
    895 x 367 - 36K
  • hgy29hgy29 Maintainer
    I think this is a NPOT texture size issue. Gideros makes textures power of two, expending your 320 to 512 internally, but of course that changes the uv mappings and Imgui won’t know.
Sign In or Register to comment.