realh / gwebgl

Provides a GObject Introspectable wrapper library for OpenGL ES that uses an API compatible with WebGL
2 stars 1 forks source link

Use gwebgl to port browser game engines to GJS #1

Open JumpLink opened 2 years ago

JumpLink commented 2 years ago

I find this project very interesting. If I understood your motivation behind this project correctly, you want to achieve browser based games developed in JavaScript without the overhead of the browser to run with GJS. Is that correct?

I would like to do something similar. I would like to get Excalibur.js and/or Phaser running under GJS. So your project could be just right for that. Do you plan to continue working on the project and can I possibly help somewhere? I'm not a good C programmer but Vala would be an option for me and of course JavaScript / Typescript.

realh commented 2 years ago

That's right, I wanted to make it possible to use gjs for games with an API compatible with web standards. I figured gjs might run better on Raspberry Pi than a full blown browser. It seemed to be working at first and was able to run a 2D game up to a point (see below), which showed that the calls for creating and uploading textures, compiling shaders, and rendering were all good. However, after a few seconds the game would hang. IIRC there were no alternatives to glib_idle_add and glib_timeout_add such as compatible implementations of setTimeOut and/or requestAnimationFrame in globalThis.

So I don't think it's possible to run a real-time game in gjs and I gave up on it. There are some GI projects for node.js; node-gtk seems the most popular. It might be worth seeing if gwebgl will work with node, but in my case I just moved on and wrote my game in C++ with SDL instead, and I haven't really got enough time to devote to gwebgl now. Most of the C should be the same for node, but you might have to change the JS wrappers because node-gtk has a different API for signals, and probably for registering classes and properties etc too.

JumpLink commented 2 years ago

There are now official implementations of setTimeout and setInterval in Gjs which internally uses GLib.timeout_source_new for this, have you tried that?

For Node.js there are already similar projects like node-webgl and headless-gl, but I would like to use Gjs for it.

By the way, for Vala there are already several different bindings for OpenGL and OpenGL ES which might also be helpful. Thanks to valabind it's very easy to use this bindings in other laguages which have gir bindings (examples).

realh commented 2 years ago

setTimeout hasn't made it into a release version yet. I tried making an equivalent for idle_add, but I wasn't able to include the PromiseNative part because import.meta.importSync doesn't seem to be available either. This didn't fix the problem. So Either the call to PromiseNative.drainTaskQueue() is crucial, or setting up the source manually instead of simply using GLib.idle_add is not the answer to this problem. I don't know which. I might try installing gjs from git a bit later, but I doubt it'll help.

I wouldn't recommend continuing with your projects unless you can be sure you won't run into this problem. Otherwise, you're welcome to what help I can give with gwebgl. It would probably be a good idea if I give you full access to the repo.

JumpLink commented 2 years ago

So far I haven't implemented anything concrete, because I want to improve ts-for-gir first (because I want to implement the whole thing in typescript). But it would be nice if you could check if the problem with the git version still exists and if you could add a small demo which demonstrates your current problem.

Feel free to give me access but I'm currently working on other parts (and be warned, as you probably know me by now, I like to restructure everything)

realh commented 2 years ago

I've tried using setTimeout from gjs git, and that doesn't help. I also updated the demo and then added some largish array allocations to the render callback to try to trigger GC, but I wasn't able to reproduce it. However, I then found gjs#327, so it looks like it is a gjs bug, not just me.

Speaking of ts-for-gjs, I did notice the recent major changes, but due to this issue and being busy with something else, I haven't tried to merge my fork. I guess I should have raised a PR long ago. My changes aren't very extensive, but to make it easier to share code with and without the inheritance option I think I changed something like the order in which it outputs symbols even with the option off, so it fails all the existing tests. The bindings it generated with inheritance worked pretty well for me though in various experimental projects.

JumpLink commented 2 years ago

I have added an example with a working workaround to gjs#327. When I tried your demo I had another error which I could fix with #2 otherwise it runs smoothly for me, this is very cool by the way.

Regarding ts-for-gjs, that sounds great and I plan to adopt it but due to my recent changes the codebase has changed massively, my goal was to make the codebase more readable and maintainable. I am currently working on another PR https://github.com/sammydre/ts-for-gir/pull/59 to improve the types in general by implementing a more comprehensive example in parallel. After that I would like to have a closer look at inheritance again.

Regarding the tests in ts-for-gir, I want to rework them anyway and they are currently deactivated because they don't work anymore with my last major changes. I think the tests should be written in such a way that the order does not matter, it should be enough that the expected types are present regardless of their order, besides the tests were also difficult to read.