Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Web platform #28

Closed
gen2brain opened this issue Dec 8, 2017 · 5 comments
Closed

Web platform #28

gen2brain opened this issue Dec 8, 2017 · 5 comments

Comments

@gen2brain
Copy link
Owner

gen2brain commented Dec 8, 2017

Support for web platform is partially implemented. There are still problems with _emscripten_set_main_loop().

go generate -tags js github.com/gen2brain/raylib-go/raylib will generate raylib.js file in github.com/gen2brain/raylib-go/raylib (emcc from emscripten must be in PATH).

GopherJS bindings to raylib.js are here https://github.com/gen2brain/raylib-go/blob/master/raylib/raylib_js.go .

gopherjs build is then used to build project example or game to js. After that, https://github.com/gen2brain/raylib-go/blob/master/raylib/external/web/index.html should be edited to include that js file.

If I open that index.html in browser, I can see that InitWindow() works, OpenGL ES is active, etc. but per emscripten docs https://kripken.github.io/emscripten-site/docs/api_reference/emscripten.h.html#c.emscripten_set_main_loop, I need to set update()/mainloop() function there and use that in app, raylib also does that, but in C code (and includes emscripten.h).

https://github.com/gen2brain/raylib-go/blob/master/raylib/external/web/mainloop.js is added at the end of raylib.js (with --post-js option), and then SetMainLoop() https://github.com/gen2brain/raylib-go/blob/master/raylib/platform_web.go#L22 should be called in app.

Currently this gives error:

Invalid function pointer called with signature 'v'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)
printErr @ index.html:179
nullFunc_v @ raylib.js:11789
b23 @ raylib.js:102220
dynCall_v @ raylib.js:101673
browserIterationFunc @ raylib.js:1960
runIter @ raylib.js:2077
Browser_mainLoop_runner @ raylib.js:2015
requestAnimationFrame (async)
requestAnimationFrame @ raylib.js:2398
Browser_mainLoop_scheduler_rAF @ raylib.js:1915
_emscripten_set_main_loop @ raylib.js:2035
_emscripten_set_main_loop_go @ raylib.js:105111
SetMainLoop @ platform_web.go:24
main @ main.go:10
$init @ basic_window.js:28354
$goroutine @ basic_window.js:1471
$runScheduled @ basic_window.js:1511
$schedule @ basic_window.js:1527
$go @ basic_window.js:1503
(anonymous) @ basic_window.js:28365
(anonymous) @ basic_window.js:28368

Edit: demo is here http://81.4.106.254/raylib-go/ , .js files are not optimized/compressed/obfuscated .

@gen2brain
Copy link
Owner Author

Now there is a different problem, _emscripten_set_main_loop issue is solved with this https://github.com/gen2brain/raylib-go/blob/master/raylib/external/scripts/emcc-generate-js.sh#L15 .

Function that is set with SetMainLoop(somefunc, 0, true) is running in loop as it should, but doesn't render anything on screen, first frame is visible and then just gray background.

http://81.4.106.254/raylib-go/

@gen2brain
Copy link
Owner Author

gen2brain commented Dec 10, 2017

I have a clue now what is wrong. The only working functions in raylib_js.go for now are the one that doesn't return or accept structs, like InitWindow() for example, the others should be called like this, via ccall http://kripken.github.io/emscripten-site/docs/porting/connecting_cpp_and_javascript/Interacting-with-code.html#interacting-with-code-call-javascript-from-native and http://kripken.github.io/emscripten-site/docs/api_reference/preamble.js.html#ccall.

Something like this in GopherJS:

// LoadWaveEx is used, not _LoadWaveEx name that is exported
js.Global.Get("Module").Call("ccall", "LoadWaveEx", "array",
		[]string{"array", "number", "number", "number", "number"},
		[]interface{}{data, sampleCount, sampleRate, sampleSize, channels})

But then, there is again problem for all functions that work with structs passed by value. Structs can be converted to []byte with unsafe or encodings/binary, so GopherJS pass it as TypedArray, argument type from emscripten side is then array, but return type can not be array, only number or string, emscripten complains then, because it can not know size.

I will look more what can be done with http://kripken.github.io/emscripten-site/docs/porting/connecting_cpp_and_javascript/WebIDL-Binder.html#webidl-binder and http://kripken.github.io/emscripten-site/docs/porting/connecting_cpp_and_javascript/embind.html#embind , results can be complete bindings to raylib in javascript, example is box2d here https://github.com/kripken/box2d.js , that can than be easily used from GopherJS .

Edit: embind example here emscripten-core/emscripten#3083 (comment)

@gen2brain
Copy link
Owner Author

Closing for now, don't have time for this, I tried to use embind but it is not so easy.

@avelican
Copy link

Hi, I saw a video by someone using raylib-go and it got me wondering about the web export. That aspect seems to be abandoned for 5 years?

I recently did a game jam in Odin with Raylib. I used Caedo's template: https://github.com/Caedo/raylib_wasm_odin

It works by having a C/Emscripten raylib game, which calls out to external code (i.e. the actual game code) in the Odin wasm module. Perhaps something similar could be done for raylib-go?

@gen2brain
Copy link
Owner Author

@avelican Well no, it is not possible in Go to compile WASM obj (.o) like in your example. Odin relies on LLVM like many other newer languages while Go is using pure Go. What is possible in theory is to compile raylib with emscripten, not for the web, but as a standalone WASI, then use wazero (the web assembly runtime that is completely cgo-free) to call raylib functions (wazero also has an extension for emscripten).

I may try just to see how it works (and if it works) when I find the time, with some basic example, but it would require new bindings, and that would be a third binding beside cgo and purego bindings, so it would be hard to maintain.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants