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

Enable to use multiple canvas #2271

Closed
jihoonbyun opened this issue Apr 3, 2014 · 15 comments
Closed

Enable to use multiple canvas #2271

jihoonbyun opened this issue Apr 3, 2014 · 15 comments
Assignees

Comments

@jihoonbyun
Copy link

In some c/c++ opengl projects, can see multiple windows. And
"glutSetWindows" function sets current window, and "glutGetWindows" return current window id.

Thus, for porting the glutSetWindow and glutGetWindow functions to JS, the emscripten should support multiple canvas at least.
But, after few look , I think the whole architecture is based on single canvas.
this is glutCreateWindow (library_glut.js)

  glutCreateWindow: function(name) {
    var contextAttributes = {
      antialias: ((GLUT.initDisplayMode & 0x0080 /*GLUT_MULTISAMPLE*/) != 0),
      depth: ((GLUT.initDisplayMode & 0x0010 /*GLUT_DEPTH*/) != 0),
      stencil: ((GLUT.initDisplayMode & 0x0020 /*GLUT_STENCIL*/) != 0)
    };  
    Module.ctx = Browser.createContext(Module['canvas'], true, true, contextAttributes);
    return Module.ctx ? 1 /* a new GLUT window ID for the created context */ : 0 /* failure */;
  }

Module.ctx is just one canvas tag. It's not Array. and There's no use of parameter 'name'. ( I think the parameter should be the window 'id'. so maybe it's suitable for canvas classname or id).

for using multiple canvas, the 'Module.ctx must be changed in some parts. But is it OK? and where's Module.ctx and how to implement into html?

Do you have any good solutions?

@kripken
Copy link
Member

kripken commented Apr 3, 2014

There is currently no support for multiple windows, the Module object is a
singleton and Module.ctx/Module.canvas represent a single window that we
render to.

@kripken
Copy link
Member

kripken commented Apr 4, 2014

What do you mean by 'tag'?

@jihoonbyun
Copy link
Author

I mean what function generate canvas HTML tag? I'm gonna try make it more than one

@juj
Copy link
Collaborator

juj commented Apr 7, 2014

Currently we don't create the HTML element in code at all, it's created by the shell.html file. For implementing support for multiple simultaneous WebGL contexts, I'm thinking it could work that we would store in the current Module.ctx and GLctx variables the currently active thread context, and context activation functions like eglMakeCurrent would then set that variable to the currently active one. There's probably a good amount of extra dev work that needs to be done, but conceptually that sounds like a plausible approach - all the glXXX functions need to have a known spot where they read the current canvas context from.

If you want to try multiple canvases, you could start by creating a custom shell file that has multiple elements, and then modify the initialization functions to get the gl contexts from both objects, and so on.

@juj
Copy link
Collaborator

juj commented Jul 25, 2014

The pull request #2583 will add support for multiple simultaneous contexts, however it will be a separate work to enable all companion APIs like GLUT and EGL to support those as well.

@juj juj added GL labels Jul 27, 2014
@juj juj self-assigned this Jul 28, 2014
@zivsha
Copy link

zivsha commented Nov 19, 2018

@kripken, @juj has this changed in the last 4 years? Is it possible to bind multiple canvases to different windows (OpenGL contexts)? I couldn't find a way or example for doing that. Currently only by creating an iframe and assigning it with a different script (that creates a window and renders with OpenGL) I am able to display multiple canvases.
I saw the test in #2583 which creates multiple contexts and uses EM_ASM to indicate which canvas it is currently using but how can I use this when paralleling OpenGL rendering (where each window runs on a different thread)

@juj
Copy link
Collaborator

juj commented Nov 19, 2018

With the Emscripten HTML5 API (emscripten/html5.h), it is possible to create multiple GL contexts that each target their own canvas. Though nobody has contributed support for Emscripten's GLUT implementation to take advantage of this, so GLUT still remains hardcoded to using a single context. (If someone would like to work on that, PRs are welcome)

Related, WebGL specification requires that each canvas must use it's own context, so it is not possible to use one WebGL context to render to multiple canvases. Upcoming OffscreenCanvas web specification might change this, but the spec is still in flux.

@zivsha
Copy link

zivsha commented Nov 19, 2018

Could you point me to which function(s) I should use to target a specific GL context to a specific canvas?
Is it emscripten_webgl_create_context?

@stale
Copy link

stale bot commented Nov 19, 2019

This issue has been automatically marked as stale because there has been no activity in the past year. It will be closed automatically if no further activity occurs in the next 7 days. Feel free to re-open at any time if this issue is still relevant.

@stale stale bot added the wontfix label Nov 19, 2019
@juj
Copy link
Collaborator

juj commented Nov 21, 2019

Apologies, somehow missed the followup question. I suppose you did figure it out as there were no further pings. :)

To summarize, the function emscripten_webgl_create_context can be used to create a context against a specific canvas on the page, and the function emscripten_webgl_make_context_current can then be used to switch between the active context.

@stale stale bot removed the wontfix label Nov 21, 2019
@juj juj closed this as completed Nov 21, 2019
@zivsha
Copy link

zivsha commented Nov 21, 2019

Hi @juj , this was a long time ago so I don'r remember if I was able to complete my little experiment. Thanks anyways

@damien-monni
Copy link

damien-monni commented May 20, 2020

Hi @juj, it seems that I am able to create new contexts with emscripten_webgl_create_context and emscripten_webgl_make_context_current but it does not behave as I expected with the SDL port :

EmscriptenWebGLContextAttributes contextAttr;
emscripten_webgl_init_context_attributes(&contextAttr);
EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context = emscripten_webgl_create_context("#canvas2", &contextAttr);

emscripten_webgl_make_context_current(context);

SDL_Init(SDL_INIT_VIDEO);
window = SDL_CreateWindow("SDL Test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 500, 500, SDL_WINDOW_SHOWN);

I thought it would switch the SDL context but the window is created on the first canvas instead of my canvas with the id #canvas2. Am I doing something wrong?

@juj
Copy link
Collaborator

juj commented May 20, 2020

I think SDL_CreateWindow or will on its own create a WebGL context, so the emscripten_webgl_* functions are ignored/"overwritten". I don't recall off the top of my head if there is a way to let SDL 2 specify which canvas to target.

The SDL 1.4 support code in Emscripten repository is old and hardcoded to looking at Module.canvas as the target canvas - to choose the target canvas one should set a different canvas DOM element there.

@clo-yunhee
Copy link

AFAIK the canvas id that is used as the window surface is hardcoded as #canvas in SDL2

@damien-monni
Copy link

AFAIK the canvas id that is used as the window surface is hardcoded as #canvas in SDL2

Yes, I just opened a issue about this: emscripten-ports/SDL2#130

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

No branches or pull requests

6 participants