flyover / imgui-js

JavaScript bindings for Dear ImGui using Emscripten and TypeScript
https://flyover.github.io/imgui-js/example/
MIT License
962 stars 103 forks source link

imgui_impl.umd.js's ImGui_Impl.Init crashes with null exception #25

Open yaustar opened 4 years ago

yaustar commented 4 years ago

I'm trying to use imgui-js within the PlayCanvas engine with the dist/umd version https://github.com/flyover/imgui-js/tree/master/dist

I'm hitting an error when I call ImGui_Impl.Init as bind is undefined. Looking at the file itself, I can't see where it is assigned a value as well.

Comparing it to example/imgui_impl.js, also notice some logic differences .

In the example/imgui_impl.js, the Init function looks like this:

    function Init(value) {
        const io = ImGui.GetIO();

Whereas, the UMD looks like this:

    function Init(value) {
        const io = GetIO();

Where GetIO is

    function GetIO() { return new ImGuiIO(bind.GetIO()); }

Am I doing something wrong in the setup or should I not use the dist/umd versions of the library?

flyover commented 4 years ago

Before calling any ImGui functions, you need to initialize the WebAssembly module by calling ImGui.default() and wait for the promise to resolve.

yaustar commented 4 years ago

Thanks @flyover,

This is what I had from last night:

ImGui.default().then(function() {
        ImGui.CreateContext();
        var io = ImGui.GetIO();
        ImGui.StyleColorsDark();
        io.Fonts.AddFontDefault();

        // bind is undefined in this function
        ImGui_Impl.Init(self.app.graphicsDevice.canvas);

        self._ready = true;
    });

Unfortunately, I still couldn't get past ImGui_Impl.Init call and was wondering if I had to something similar with getting the module ready?

flyover commented 4 years ago

Ah, I see. ImGui_Impl is packaged with it's own copy of ImGui, which hasn't been initialized. I will need to see if I can change the rollup config to use an external ImGui module; or, have ImGui_Impl initialize the internal ImGui module.

yaustar commented 4 years ago

Ah, that explains a few things! I thought it was a bit strange that ImGui_Impl has duplicates of functions from ImGui. Might have a go a compiling it myself tonight 😬

mtmckenna commented 4 years ago

Not sure if it's helpful, but in the short term for my own app, I got around this but re-exporting ImGui_Impl's version of ImGui by adding export { ImGui }; to the bottom of imgui_impl.ts.

After re-building with yarn dist, I imported both ImGui_Impl and ImGui from imgui_impl.umd.js with something like:

import * as ImGui_Impl from "./imgui-js/imgui_impl.umd";
const { ImGui } = ImGui_Impl;

Not sure if that solves more problems than it creates, but I figured I'd share that.

Thanks for your work on this!

yaustar commented 4 years ago

@mtmckenna it's good to know someone has got it working! Does your solution end up putting all the code in a single JS file?

mtmckenna commented 4 years ago

It does. Everything ends up in the ‘imgui_impl.umd.js‘ file. In some ways, I can see that as being convenient since it’s just one file to import. I’m just getting into ‘Imgui’ though so I don’t know if maybe keeping the files separate is preferred?

yaustar commented 4 years ago

One of our forum members on PlayCanvas has integrated it quite nicely :)

https://forum.playcanvas.com/t/playcanvas-dear-imgui/13469/4?u=yaustar Dear ImGUI with PlayCanvas

vojty commented 4 years ago

Is it possible to make ES modules build as well? I am unable to figure out how to use this with webpack... EDIT: actually that hack @mtmckenna mentioned works but...

vojty commented 4 years ago

So I have finally managed to produce a build which uses esm and have successfully used it with webpack. However I am still little bit confused, what exactly imgui_impl.ts is... is it something that should be included in the ouput?

This is what I did:

And then used it in my project like this:

import * as ImGui from "imgui-js";
import * as ImGui_Impl from "imgui-js/es/example/imgui_impl";

...

Is this something we could add to this repository and eventually publish it to NPM? I could prepare PR... cc @flyover

LeXXik commented 4 years ago

Imgui core library is agnostic of where it is going to be rendered. It relies on the implementation files, each targeting their own renderer. This imgui_impl makes it so that the Imgui can be rendered in WebGL context. It prepares the canvas, framebuffers, etc. You want to include it, if you want to render gui in a browser.

vojty commented 4 years ago

so it's basically something like CanvasRenderer or BrowserRenderer

LeXXik commented 4 years ago

Right, so there is a core library and there is a so called "backend". That backend is basically the renderer. There are many available in the original repo for vulkan, opengl, etc. If the naming convention is followed, then it should probably be something like imgui_impl_webgl: https://github.com/ocornut/imgui/tree/master/examples