GithubHelp home page GithubHelp logo

OpenGL Support about emscripten HOT 24 CLOSED

kripken avatar kripken commented on July 24, 2024
OpenGL Support

from emscripten.

Comments (24)

 avatar commented on July 24, 2024

I wrote a wrapper for partial OpenGL interface to OpenGL ES 2.0 in C++. I would perhaps attempt to get this into emscripten - if there is someone who can assist me.

from emscripten.

BenoitT avatar BenoitT commented on July 24, 2024

Would be great to have OpenGL header files inside the embeded files.

from emscripten.

 avatar commented on July 24, 2024

The headers are the least of your problems. Mapping WebGL to OpenGL/ES 2.0 is the real trick.
For example the question is whether you stick with:
GLuint glCreateProgram(void) which would mean you'd have to introduce a method like wglMakeCurrent(WGLContext) to map this properly to how accessing WebGL in JavaScript works (via context.createProgram()). I somehow assume the devil will be in the detail. Not to mention the OpenGL / OpenGL ES 2.0 bridge.

from emscripten.

kripken avatar kripken commented on July 24, 2024

LCID-Fire, I am happy to assist in any way I can with this. It would be awesome if we can get that into emscripten!

Even if we can get just a subset of OpenGL ES - and whatever we can map from OpenGL into that - that would be very useful for a lot of people, I think.

from emscripten.

 avatar commented on July 24, 2024

For a first glance at the changes take a look at my repo
I could not find yet any dev documentation though.

  • What C type is used to access JavaScript Objects?
  • Can I enforce the conversion of an Object adress to uint in JavaScript!?
    glCreateProgram: function() { return context.createProgram(); }
    This would be a great benefit when createProgram returns an Object while GLuint glCreateProgram() an unsigned int.
  • library_gl.js
    • Why are new textures saved to the heap in glGenTextures?

from emscripten.

 avatar commented on July 24, 2024

@kripken: Would be great if you could take a look and give some feedback.

from emscripten.

kripken avatar kripken commented on July 24, 2024

It looks good!

There are some minor changes that will be needed for this to work in Emscripten, mainly the utility functions on top there will need to be added to an object that is accessible at runtime. The issue is that library_gl.js is executed during compile time, but during run time we only have access to things that are directly used by the program. The compiler selects the right parts of library.js, library_gl.js etc. and adds them to the generated code, using dependencies and so forth. This might sound complicated but it's a very small change, I can do it if you want. For comparison, though, see library_sdl.js: $SDL is an object that will appear in the compiled code (as SDL), since it is a dependency of the SDL functions, and all the SDL utility stuff is inside it. In library_gl.js, $GL can do the same thing.

How much more work is there til this can start to compile some "hello world" type stuff? Very excited to see this in action :)

What C type is used to access JavaScript Objects?

I'm not sure what you mean. But in general, you can't return a JS object to the compiled C/C++ code, since it won't know what to do with that. Need to return types that code can understand, basically C/C++ types: integers, floats, and pointers (which are just integers).

Can I enforce the conversion of an Object adress to uint in JavaScript!?

Well, you need to do the conversion yourself. So you would do createProgram, store the object somewhere, and return an integer identifier of it.

That is sort of what glGenTextures does: The WebGL texture objects are stored in GL.textures, and we give to the C/C++ code an integer identifier, and our code manages those identifiers (with GL.textureCounter).

Why are new textures saved to the heap in glGenTextures?

glGenTextures gets a pointer to some allocated memory, and it needs to store the texture identifiers in that array in memory. So to implement that in library_gl.js, we write to that allocated memory by writing the to the HEAP array - the HEAP array represents all of the memory (both stack and heap). Pointers in the compiled code are simply integers, that represent addresses in HEAP.

(If glGenTextures were a function that just created a single texture and returned it as its return value, then we wouldn't need to store anything to HEAP, we would just return the integer identifier.)

from emscripten.

 avatar commented on July 24, 2024

Thanks, okay some further questions:

  • I feared that I cannot really access JavaScript from CXX (which on the the other side keeps the interop simple). The thing that bugs me is, can I map C++ classes onto JavaScript classes? All I've seen so far is using C functions - which is not the nicest way to do things.
  • I saw that there are different heaps in use. IHEAP, FHEAP, HEAPI32, etc. What is the correct way to access these?
  • How are the types like uint8_t mapped to JavaScript? I guess that handing them to JavaScript is pretty easy but what about the other way around?

from emscripten.

kripken avatar kripken commented on July 24, 2024
  • You can call emscripten_run_script in C++, passing it a string, and that string will be eval-ed. This is useful sometimes, but slow - however we can make some convenience functions around that and optimized versions if necessary. As for the other direction, accessing C++ from JS, the bindings generator lets you do that fairly well (you can access C++ objects in JS as if they were JS objects, the best documentation for this is the README in ammo.js). If we need the opposite direction we can probably write that. Can you describe the use case?
  • For HEAP stuff, you should basically do {{{ makeSetValue(..) }}} and {{{ makeGetValue }}} (plenty of examples of those in library.js). Writing that means that the compiler will generate the optimal code for accessing memory there (which can be very different depending on what optimizations are being used in compilation).
  • All integers and floats in C/C++ become JavaScript numbers (which are technically doubles, but JS engines optimize so they can also be 32-bit ints that overflow into doubles). So the communication in both directions for those values is very simple, you just pass them. Returning an int of any size in C/C++ becomes a simple return of the value, and so forth, and in the opposite direction, just pass a JS number as a parameter to a compiled C/C++ function.

from emscripten.

 avatar commented on July 24, 2024
  • For setting up the GL context I replaced EGL with a kind of similar WGL. WGL uses a HTMLCanvas handle to initialize the context. For this we need some means of getting the handle. From what I know I would currently opt to allow access to the document.
    Is this possible by making the document object accessible (which would mean mapping a JavaScript prototype to a C++ class) or should we just allow access via static function calls like document_getElementById?
  • Okay, I'll rewrite the code.
  • The way from C -> JS is clear/easy. But JS -> C isn't. What would e.g. happen if one returns 50000 in JS but the function prototype in C has a return type of int8_t?

from emscripten.

kripken avatar kripken commented on July 24, 2024
  • I am not sure I follow the first point. Do you want to access the DOM from C/C++?
  • Regarding the last point, if you send 50,000 from JS to C, and the C function assumes it is getting an int8, then a problem will likely occur. The assumption is that we send valid data from JS to C/C++. We can add automatic correction code, if there is a good use case for it.

from emscripten.

 avatar commented on July 24, 2024
  • I want the interface for OpenGL ES 2.0 to work similar to the standard one. Which means having some way of specifying/setting up your drawing context. Therefor I am writing WGL, which is designed like EGL. Now, to specify, which context should be used for drawing we have a few options:
    1. Provide access to the HTMLCanvas element in C*, which would be pretty similar to EGL (and yes, would allow access to the whole DOM).
    2. Just provide the id of the HTMLCanvas and keep the interface plainer/simpler.
    3. Don't deal with the context in C*, but require the coder to write the hookup in JavaScript.
  • Could you test this case? In theory I would say we should handle it similar to an overflow.

from emscripten.

kripken avatar kripken commented on July 24, 2024
  • If the issue is the setup of the canvas, context, and so forth, I think the best way to do that is with the SDL API. We already support the SDL API for writing pixel data to a canvas, and we can extend that so you use SDL to work with OpenGL on the canvas.
  • If the code is compiled with overflow correction, then data sent from JS will be corrected when it is used inside the compiled C/C++ code. I don't think we should add any additional correction code, because in general it adds overhead that isn't needed.

from emscripten.

 avatar commented on July 24, 2024

Since I assume the majority of code for Emscripten to be previous code and since the interface is for OpenGL ES 2.0 I think all of the code will include setup of the graphics context via EGL.
So having to rewrite the setup code to use SDL is quite a leap. WGL would probably be pretty straightforward since it is kind of a subset of EGL. And WGL is quite slim compared to the bloat that SDL incorporates (not to mention the often occurring define conflicts).
I think it would be better to move all the context/surface code to WGL since SDL is normally just a wrapper around other libs anyhow. You are right though, that one piece of code should handle all the graphics stuff on the JS side.

All that said I am thinking about whether we should provide a EGL emulation, since this would be easiest for the programmers (but we would have to fake quite a few objects).

from emscripten.

kripken avatar kripken commented on July 24, 2024

I agree, we should support all interfaces if possible. My only concern is trying to do too much. But if it's feasible to support both SDL and EGL/WGL, that would be great.

I don't know enough about EGL/WGL though to understand how that stuff would work, however (but I know a little SDL, that's why I supported that so far with canvas etc.).

from emscripten.

daoshengmu avatar daoshengmu commented on July 24, 2024

Hi, I have some questions want to ask. I have finished my OpenGL|ES version 3D engine, and I want to know how to create window and context to support Emscripten.

  1. I have seen the hello_world_gles.cpp sample, it uses glutCreateWindow and glutInit, but I used eglCreateWindowSurface and eglCreateContext in my engine. Could I use these OpenGL|ES initial functions like before?
  2. When I use WebGL Inspector to capture hello_world_gles.js, it will show "Uncaught GLUT mainloop called, simulating infinite loop by throwing so we get right into the JS event loop" on console window. Is it normal?

from emscripten.

kripken avatar kripken commented on July 24, 2024
  1. We have some egl support (src/library_egl.js) but it is very minimal. SDL or glut are much better supported.
  2. glut mainloop is a function that does not return, so the code after it is not run. The closest we can do is to throw an exception there.

from emscripten.

 avatar commented on July 24, 2024
  1. I am currently completing egl support in my project, but it's not yet at a level, that I want to commit it.
  2. I'd redefine glut mainloop to generate a compile error. But that's just me.

from emscripten.

kripken avatar kripken commented on July 24, 2024

The original goal of this issue was achieved, we have full WebGL subset support, and also a lot of additional GL/GLES support as well. So closing this issue. Let's file followups for specific missing stuff that we find.

from emscripten.

 avatar commented on July 24, 2024

@kripken Hey, sorry for the idiot question, but how can I use this WebGL subset in my project? I.e., how do I include it and where's the API?

from emscripten.

 avatar commented on July 24, 2024

I'm new to this :(

from emscripten.

 avatar commented on July 24, 2024

@kripken I think I've found the API, but I don't how to include the WebGL subset :/

from emscripten.

kripken avatar kripken commented on July 24, 2024

An overview is here:

http://kripken.github.io/emscripten-site/docs/porting/multimedia_and_graphics/OpenGL-support.html

You can find GL tests in the test suite which are working examples, can be helpful to read.

from emscripten.

 avatar commented on July 24, 2024

@kripken I've checked it. I just didn't note the tests. Thank u for ur time

from emscripten.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.