-
Notifications
You must be signed in to change notification settings - Fork 3
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
WebGL device #40
Comments
FWIW, I'm starting to realize that might be the way to go. It's only the desktop where it's feasible to take full control and do a busy loop to do what you want with full control. On a platform like the web, you have to play by its rules, because it's a more complicated ecosystem, and the browser can probably do a better job of telling you what to do, than you figuring it out. Consider situations where the tab is inactive, or your viewport is offscreen, etc. It might make more sense to have the browser ask you to render frames when appropriate, rather than you trying to render them and figure out when to sleep longer, etc. Just some thoughts. |
You can do it on desktop, mobile, and the web. The difference is that we won't be busy waiting (I despise busy-waiting API's honestly, and I think given Go's nature is a horrible thing to do).
Your comment actually got me very curious how we could implement it on the web. So I've taken the time to look into if my plans here would work with the web well, and I think it will (see below link).
Absolutely. This is similar to how GLFW's swap buffers command pauses for a vertical refresh, but a bit different: Instead of the command stalling (which goes against Javascript, somewhat excessive, use of callbacks) you pass in a function to be invoked at the next frame via window.requestAnimationFrame. The basic plan is:
I've made a dumb-go-version of that RequestAnimationFrame function in Go which simply pauses for a second and then calls it's function argument, I tested it on the Gopherjs playground and it works well: https://gist.github.com/slimsag/0b7c40e8fb6b566e491f What do you think? |
I think that's pretty fantastic! But I'll have to play with it later, when I have more time. |
For those on-looking this in the future, I've outlined the benefits of this approach of managing the main thread/loop in this blog post: http://slimsag.blogspot.com/2014/11/go-solves-busy-waiting.html |
Playing with this right now. :D (With the specific goal that I want to be able to run Hover on desktop and in browser on my iPad). I have two code paths (implemented via 2 packages or a single package with 2 build tags), one for desktop/OpenGL/gc and another for browser/WebGL/GopherJS. I've realized it makes things a lot easier to reason about if I think of the browser path as originating from backend Go that hosts the frontend. The desktop path (for now) simply opens a glfw window and proceeds from there. The browser path sets up a server that hosts the index.html and compiled (via GopherJS) script.go file, and opens a browser window that navigates to the hosted index.html page. That way I could actually implement a wrapper for var document = dom.GetWindow().Document().(dom.HTMLDocument)
canvas := document.CreateElement("canvas").(*dom.HTMLCanvasElement) Having control over both the backend (serving resources, generating index page html) and frontend (GopherJS code that runs in the browser) seems to be a great idea so far. Now, I'm getting closer to trying out your idea of using channels so that the main package can retain |
Nice! I think for
I've done a lot more research over the past two weeks into an OpenGL ES and WebGL device -- Since WebGL 1/2 was based on OpenGL ES 2/3 I believe we can expose just two simply device packages: WebGL 2 and OpenGL ES 3 are both just functionally extensions on top of the existing WebGL 1 / OpenGL ES 2 API's, so we could have the devices start out by trying the latest (2/3) and then falling back to the standard (1/2) versions. |
I've tried that and I got it to work using
As far as I understand, using Edit: More precisely, I couldn't get |
AFAIK the problem lies in the fact that JS cannot call back into Go functions if they are blocking. For this reason you'd have to have whatever function I updated the gist to have |
I forgot about, thanks! I should add a wiki page that outlines all of the JS gotchas on one page. |
Callbacks from JavaScript cannot be blocking. Thanks @slimsag for the hint in azul3d-legacy/gfx#40 (comment)!
Sorry if this is a little off topic, but I was able to get the main loop of the desktop path and browser path to be essentially identical! And it really works. IMO this is incredibly cool. ;D (I've now implemented Here it is running as a desktop app: And inside the browser: |
That sounds like a great idea. 👍
I think it's pretty on-topic (and cool!), actually. It's a strong indicator that this pattern will work well in lieu of an actual implementation for us here (thus far). |
Done at https://github.com/gopherjs/gopherjs/wiki/JavaScript-Gotchas. It can be removed if deemed unhelpful (because the information is available elsewhere); just trying it out to have a single page that lists bullet points with links to more info. |
Made some progress on the demo above. Instead of rendering a single triangle, it now renders a million. See here for more info. It's pretty impressive that it runs at roughly 30~ FPS on an iPad mini with Retina, and this is just the first cut. I'm sure there's still quite some room for optimization. |
We've done some pretty cool things above. :) It's interesting that I take Hover and eX0-go running in desktop/browser via same codebase for granted now, but this thread shows the progression and how it took collaboration, hard work, and multiple breakthroughs to make today's reality possible. Thanks again for help @slimsag! And @neelance for making it possible in the first place. ;) |
😄 👍 |
For WebGL to be supported by the graphics package we need to:
gfx/window
package.Moved here from azul3d-legacy/issues#29
The text was updated successfully, but these errors were encountered: