Best way to integrate Electron-based Editor UI with C++ 3D Engine


#1

I’m working on a C++ 3D engine that uses GLFW for cross-platform compatibility.
I now need to build some sort of editor UI to drive the engine. I was thinking of using Electron. But I’m not sure how to go about the integration or whether I’m even thinking about it in a sensical way.

In normal operation, my engine itself is responsible for creating a GL window to render to (via GLFW) and then rendering to the GLFWwindow’s buffer.

What I’d like to do is create an Electron-based app that has all UI elements of the “engine editor” (i.e. buttons, sliders, etc) but also a couple GL windows ‘inside’ the main Electron app window, where the engine renders as usual in response to the user’s interaction thru the Electron app.

I believe this will require that I write a Node.JS wrapper for the engine, which I know how to do. But I’m not sure how to ‘embed’ the GL windows that take rendering commands from the engine. Does that make sense?

In other words, assume the UI in the image included:

How would I embed those GL views inside the main window? Can those be native, aka not WebGL?
Should they be WebGL? If so how can my engine render into those via the native GL API as opposed to WebGL?


#2

It might be easiest if it was WebGL, but let’s take a look …

Electron has a BrowserWindow.getNativeWindowHandle() function that, I assume, could be used to draw to. (I haven’t done any cross-platform GUI stuff outside of browsers, so I’m just going off the assumption that all three platforms work in approximately the same fashion rendering-wise.) You would probably have to establish some sort of clipping region or regions within that window that are handled by the GLFW stack. If you made the contents of that area transparent as far as Electron is concerned, it wouldn’t matter if you accidentally got the z-order wrong.

I’ve never tried anything like this though … so ¯\_(ツ)_/¯


#3

So what you are saying would be something along the lines of:

  1. from node, get native window handle with the method you linked to.
  2. pass that handle to the engine (marshaling from JS to C++, via the native plugin).
  3. in the engine, somehow get the gl context for that window handle.
  4. draw a viewport in some area of that context.

Right?

Thing is it seems GLFW is not capable of creating a GLFWwindow (it’s platform-neutral window/context wrapper) from a pointer to an existing window.

If then I were to bypass GLFW I would have to instead write a bunch of platform specific code depending on what type of native window handle I get from Node. Maybe this could work, but I would also lose GLFW’s platform-neutral input handling which I am also relying on.


#4

Then I would probably abandon the concept of having it all in one window. I’d have the GLFWwindow for the GL stuff and let Electron handle the extra stuff as separate window tool palettes or something.


#5

@saldavonschwartz It would be interesting to see how far you got with this. I want to achieve something similar, so that you have an area where the DirectX can render to and a nice UI written in HTML/CSS/*


#6

I didn’t pursuit it any further for now; I asked a friend who works at Github in the Atom team and she said she wasn’t sure it was currently possible either.
What might be possible though is to switch the problem around: have the engine (in my case C++) both create a window where it can render and embed webkit or something.

Another thing I just found is https://sourceforge.net/projects/wke/ though I haven’t even tried it yet.

But like I said, for now I bumped this down in priority and am instead working on the engine itself and doing a UI in Cocoa (since I’m working on Mac anyway). I’ll revisit this when the time comes to try and do the platform agnostic UI.


#7

Any progress? Same question……


#8

I had a similar issue. A neat way to do this might be to have your Electron shell/window as master and C++ window as a slave. Of course they’ll be two different processes as far as operating system is concerned, but you can hook both of them up using some sort of protocol to communicate, in my case I used websockets.

Implement all your rendering logic inside C++ window. Sliding a slider inside electron window will dispatch those values to C++ window and will render the scene.


#9

So yourself already try this solution?:heart_eyes:


#10

That defeats the purpose in my case. I wanted a unified UI and using electron to avoid creating my own UI framework in c++, not two separate windows and processes.


#11

Glad you asked! And I have a good news and a bad news.
Good news is that YOU CAN have them “look” as one window. Explained later…

Bad news is that you’ll have to sacrifice minimize/maximize animations on one of them, since they are two different sandboxed windows and processes at the end of the day. So you’ll have to call win.hide() when your C++ win dispatches the minimize event or else they both will have their own animations running at the same time when minimized.

With that being said, make your BrowserWindow frameless and shadowless. Make an empty container in your C++ app. Whenever the C++ window is moved or dragged, it’ll dispatch some event to Electron shell and latter will call win.setPosition(x, y[, animate]) so that both appear to be clamped with each other, and there you have it. Two windows that look as one.

Although to be honest, you’ll be much better off using a webview instead of electron as far as I understand your case. In my case I didn’t have the option to use webview.


#12

@NeekSandhu Did you end up doing this in a “portable” way, or Windows only?


#13

Do you have an example code for your proposal? because i have the same problem and would like to try the two windows method.


#14

Trust me…You don’t wanna do this. It’s a very fragile and very hacky way, too fragile.

If the your situation is similar to OP, or even 3D, web technologies have come a verrryyy long way. There’s a very good chance that you can pull of what you’re trying to do with pure web technologies.

You should be able to get near native experience now that we have web workers, WebGL and stuff.

And also quickly picking up is WebAssembly/WASM/Emscripten, allowing you to run C++ in damn browser.


#15

I am trying to display directX in a desktop app using electron and I can not find a way to do so, so i thought your method might be helpful.