openFrameworks
openFrameworks copied to clipboard
Automatically add emscripten examples to OF website ( curation help needed )
We now have a custom Github Action which builds examples listed and uploads them to the website. at: https://openframeworks.cc/examples/
I have a few listed for now at: https://github.com/openframeworks/openFrameworks/blob/master/scripts/ci/emscripten/examples_to_build.sh#L5-L21
But it would be great to add examples that work well on the web to the list. cc: @Jonathhhan @artificiel @NickHardeman @dimitre
Feel free to PR to the script or just list examples in the format below.
eg:
"examples/gl/shadowsExample"
"examples/gl/materialPBR"
"examples/gl/materialPBRAdvanced"
"examples/gl/vboMeshDrawInstancedExample"
Next step will be to generate a nice index page.
Thinking to try and make something like this for the examples page:
with all the examples actually running emscripten instances?
(probably not haha)
the only thing that came to me thinking about this showcase is having a form of navigation to quickly try things (so that once you are "in" an example you do not have to "browser back" or click a "back to gallery" link to go back a menu page).
(maybe a little like the listing of suggestions at the right side of YouTube?). so you can roll along.
with all the examples actually running emscripten instances?
Ha - that is def more than my html skills allow and yes, it would probably totally hammer any machine trying to view it :) I'll try and get something simple working ( as web is not my strong suit ) and then happily take PRs for additional functionality. 😁
Made some progress here: https://openframeworks.cc/examples/
need to add a default thumbnail graphic for examples without screenshots, but also helpful to see what ones are missing thumbnail images.
There are images for some of the examples that are not showing ( though they are outdated). Ie. materialPBR https://github.com/openframeworks/openFrameworks/tree/master/examples/gl/materialPBR
The image names are different than their containing folder, maybe that's the issue?
ahh yeah. @NickHardeman I think the script could handle it but right now it's just looking for files that match the folder name.
More progress added the src/ files to the bottom of each example page:
@Jonathhhan - did you have a list somewhere of examples that worked with emscipten? would love to get this: https://openframeworks.cc/examples/ to be a complete representation of the examples that work online.
@ofTheo here is a list of examples that do not work from https://github.com/openframeworks/openFrameworks/discussions/7168 (need to check it again maybe. And some of the communication examples can work too, I guess): https://pads.ccc.de/Lu6s668Ruk The GLInfoExample can be fixed with this PR: https://github.com/openframeworks/openFrameworks/pull/7211 The USE_PTHREADS=1 flag (and the CORS script: https://github.com/openframeworks/openFrameworks/pull/7727#issuecomment-1787353264 or .htaccess settings) is needed for the threading examples.
There was a script from @themancalledjakob. With that it was possible to compile all examples with Emscripten at once, somehow I do not find it anymore. Something like that could be quite handy.
how far are we from that code to be editable / compilable in-browser??
before that happens, I find the README could also be integrated (perhaps omitting the image when it is embedded?) for sure it's a bit of html/css work but having the various files in tabs, starting with the README, would be great.
also I just noticed the console is write-enabled, but obviously typing in there does nothing... perhaps there is a way to make the widget read-only?
also wonder about key events? In the example above it say "space to delete" but here (Safari/MacOS14) space gets consumed by the browser which scrolls down a page, even after clicking the OF render and keeping the mouse in the area.
(FYI the Csound wasm gallery looks like this, and here is an instance of a project in the IDE — Csound is a compiled interpreter/engine with it's own sort of "opcode" language so getting live coding to work is simpler than actual C++, but it might give ideas)
There was a script from @themancalledjakob. With that it was possible to compile all examples with Emscripten at once, somehow I do not find it anymore. Something like that could be quite handy.
weirdly enough i cannot find the topic on github either, but indeed i once wrote a script to compile all examples, generate an overview gallery and upload it on a server. when an example didn't work it would grab the error messages.
an example of this generated overview is here: https://dev.pointer.click/of/ it's not up to date anymore, but now i am itching to update it :)
as soon as i'm back at my computer, i'll check for the script. hope it can be useful.
@ofTheo I had a look at your script, very cool! I love the added source files with syntax highlighting. I didn't find my former script back yet, but it seems as this script is also quite far already.
If you don't mind I would love to hack a little bit into it :) The folders-array of the examples could perhaps be collected semi-automatically, which could make it easier to run on every commit and get notified on regressions.
Filtering examples which don't compile is easy. Filtering example which compile - but don't work - would have to be done manually or with something like selenium. This is obviously not the most important thing, but I couldn't hold myself trying something out. I don't have a lot of experience, but was able to get something rudimentary running to parse the output of console.log.
Just to keep track of it, here the script I tried (would have to be tinkered with of course):
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import time
options = webdriver.ChromeOptions()
options.headless = True
driver = webdriver.Chrome(options=options)
driver.get("https://openframeworks.cc/examples/3d/pointCloudExample/") # replace with url as parameter, or even better loop through an array
time.sleep(120) # ideally wait until page loading finished instead of hardcoded 2 minutes
print(driver.get_log('browser'))
driver.quit()
you may run the script like this:
$ python -m venv venv
$ source ./venv/bin/activate
(venv) $ pip install selenium
(venv) $ python script.py
[{'level': 'SEVERE', 'message': 'https://openframeworks.cc/examples/3d/pointCloudExample/ 0:4120 "wasm streaming compile failed: TypeError: Failed to execute \'compile\' on \'WebAssembly\': Incorrect response MIME type. Expected \'application/wasm\'."', 'source': 'console-api', 'timestamp': 1702047779871}, {'level': 'SEVERE', 'message': 'https://openframeworks.cc/examples/3d/pointCloudExample/ 0:4120 "falling back to ArrayBuffer instantiation"', 'source': 'console-api', 'timestamp': 1702047779871}, {'level': 'WARNING', 'message': 'https://openframeworks.cc/examples/3d/pointCloudExample/index.js 0 The AudioContext was not allowed to start. It must be resumed (or created) after a user gesture on the page. https://goo.gl/7K7WLu', 'source': 'other', 'timestamp': 1702047785020}]
However, we often get console errors even though everything appears to be working (like the pointCloudExample). To get this reliable may be too much work. I'll leave this here as a possible note to the future, but probably there are more urgent things to focus on.
In any case it would be great to have the option to compile all examples on demand (e.g. with a --force-compile-all, or -f parameter) and collect all errors in a table.
I might have some more ideas and will try to find some time to play with this in the next days.
Thanks for all the comments @artificiel @Jonathhhan @themancalledjakob
@artificiel - in terms of code editable in the browser, I think a long way off. Reloadable shaders might be a lot easier and we could potentially do something like a shaderToyExample where you could switch out shaders and edit them, but recompiling c++ and the security side of thing there might be too tricky for now.
@themancalledjakob - thanks for posting the link, your gallery was definitely the inspiration behind this push. Please feel free to jump in on this effort! It would be good to be able to detect examples with changes so we don't have to build every example each time.
@Jonathhhan - will use that list as a starting place. I know a lot of examples that didn't work before work now and @NickHardeman is also working on some that almost work.
One other thought @NickHardeman and I were talking about - what about some sort of #define or config.make define that indicates whether an example works in emscripten?
eg in config.make:
#options are 0 = no, 1 = yes, 2 ( default ) = yes and good for web demo gallery
EMSCRIPTEN_COMPATIBLITY = 1 #works, but don't include in web gallery
That way we don't have to maintain a separate list, but could just go through the examples folder and only build the ones that are marked compatible?
@ofTheo or just some excludes in a emscriptenBuildAllExamples script (but I am also fine with your suggestion)?
I get an error with the guiExample, which was working before:
/mnt/c/Users/Jonat/Desktop/of_v20231120_vs_release/examples/gui/guiExample/src/ofApp.cpp:56:2: error: no matching function for call to 'ofSetColor'
56 | ofSetColor(color);
| ^~~~~~~~~~
/mnt/c/Users/Jonat/Desktop/of_v20231120_vs_release/libs/openFrameworks/graphics/ofGraphics.h:56:6: note: candidate function not viable: no known conversion from 'ofxColorSlider' (aka 'ofxColorSlider_<unsigned char>') to 'int' for 1st argument
@Jonathhhan I believe that is fixed in the pending #7788