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

question - c ffi like api #189

Closed
dobkeratops opened this issue Oct 24, 2021 · 9 comments
Closed

question - c ffi like api #189

dobkeratops opened this issue Oct 24, 2021 · 9 comments
Labels
question Further information is requested

Comments

@dobkeratops
Copy link

dobkeratops commented Oct 24, 2021

here is my predicament:
ive written a game im rust using raw C FFI unsafe opengl functions (“glBindBuffer” “glDrawElements” etc) - because i alternate between c++ and rust, i like the coherence with samoke code and my own c++ projects;; ive been abke to develop in one (I still get things working in c++ more easily sometimes) and “rework it in rust” ; i can put both side by side and theyre broadly similar. I want to keeo the option of going back the other way, extracting libraries that could be used in both etc.

Now I have a need to port to the web; c “raw gl bindings” work in emscrioten just fine, but support for this seems to be deprecated (i had an early engine test working that way years ago)

one option I have is to use glow but wrap it in a C like API (“extern fn “C” glDrawElements()” etc etc).
I wonder if glow has something like this under the hood , and this plan would be a wrapper on a wrapper on a wrapper :/ , although it should inline sway.

Q1 would you be interested in integrsting unssfe() raw gl bindings for this kind of use case
Q2 if so would it be any easier to do it in a more integrated way

one sticking point was the newtypes wrapping the object handles. I agree this is a great idea but i am where I am with legacy code and a continued need to interact with the c++ world; most people cannot afford the risk of switching languages. ive replaced “type GlTexture = …” in my code a bit but it would still be hard to switch.. ill greally need to convert between the raw handles and the tyoechecked abstractions.

any ideas?

@grovesNL
Copy link
Owner

Hi @dobkeratops! 👋 This use case definitely makes sense but I'm not sure of the best approach.

glow doesn't really have this kind of thing under the hood. There is currently a small layer that maps handles to WebGL objects in the web backend, but I'm thinking about removing it to handle #187 (e.g. it causes problems when working with externally-managed resources).

I'd like to keep glow as lightweight as possible so I think having an unsafe API on top of it would be better implemented as a separate crate (built on top of glow). I think it might be possible to wrap glow in a raw GL API, but it could be a little tricky:

  • WebGL handles are typed while OpenGL handles are generally just integers, so something would need to convert between raw handles and the type checked abstractions. You could do something like glow currently does internally if you know the lifetime of all the handles (e.g. no resources are created externally).
  • It's a bit difficult managing raw pointers when doing certain things like buffer mapping (e.g. temporarily allocate memory and make pointers to that, then after the mapping completes it can be freed).

@grovesNL grovesNL added the question Further information is requested label Oct 25, 2021
@dobkeratops
Copy link
Author

dobkeratops commented Oct 26, 2021

thanks for the reply

ok so currentky I managed to get my code compiling with wasm32-unknown-emscrioten, which has the raw gl bindings i needed.
however there is some doubt about other asoects of emscrioten (eg how it handles networking and files).. so its still possible i will be looking for another solution like.this later (for the moment what i have is enough to get the gl side of things goimg)

i guess a seperate crate built ontop of this is easier to manage and it should just optimise out

i wlll comment again when ive got a bit further

@TannerRogalsky
Copy link
Contributor

@dobkeratops You might be interested in reading this issue (rust-windowing/glutin#1167). There's potentially some prior work in there that you could build off of.

@dobkeratops
Copy link
Author

:

  • WebGL handles are typed while OpenGL handles are generally just integers, so something would need to convert between raw handles and the type checked abstractions. You could do something like glow currently does internally if you know the lifetime of all the handles (e.g. no resources are created externally).

are they still managed lik desktop gl handles, or do gl bindings for webgl have to do extra bookkeeping in the middle.. to turn them into untyped ints would we have to keep an array of webgl handles to translate to?

  • It's a bit difficult managing raw pointers when doing certain things like buffer mapping (e.g. temporarily allocate memory and make pointers to that, then after the mapping completes it can be freed).

just to clarify : i have not used the buffer mapping APIs.. i figured theyd be less likely to be supported.

i have some coarification on “doubts about emscrioten”: it seems it runs fast enoigh for the graphics calls (i have my program running easily fast enough ), but thungs like networking are imolemented with a lot of JS overhead; so my collaborators are still keen to get onto uninown-unkown. so i still have the sticking point of needing c like. calls (or a messy rework).

at this point i would almost want to “rewrite (my used subset of)emscripten in rust”, using glow for gl.

@grovesNL
Copy link
Owner

grovesNL commented Nov 8, 2021

are they still managed lik desktop gl handles, or do gl bindings for webgl have to do extra bookkeeping in the middle.. to turn them into untyped ints would we have to keep an array of webgl handles to translate to?

They're reference counted (not Copy) and typed by resource, so they're a bit different than desktop GL handles. glow has this kind of map internally.

at this point i would almost want to “rewrite (my used subset of)emscripten in rust”, using glow for gl.

Makes sense! I think rewriting a subset on your side would be easier than trying to apply it to the full glow API

@dobkeratops
Copy link
Author

thanks for the info..
perhaps we could add a “unsafe fn handle_to_int(&self)”, “unsafe fn handle_from_int()->Self” in glow to enable writing the wrapper?” (it would need those for each resouce type?)

now im gueassing you might need those resources in seperate arrays internally.. i dont think it would break my code if they did overlap between types , because i always track them in ways that it always knows they are textures, buffer objects, etc itself (i used my own type GlBuffer=GLint” etc.. but this stops short of being a full strongly typed port)

i know “real” gl has calls “glIsBuffer” etc to query handle types at runtime ..i dont rely on them.
i wouldnt want to anyway - ive seen that any calls getting data back from webgl are cripplingly slow (my original port ran about half the speed until i remived all glGetError, glGetIntegeriv calls from the rednderloop..

@grovesNL
Copy link
Owner

grovesNL commented Nov 8, 2021

The handle map is meant to be an internal implementation detail that might change in the future, so I'm not sure about exposing those conversion functions right now. Would it be possible to you to keep a map in your wrapper instead?

e.g. anytime a resource is created, store the resource and return an integer representing it instead so you can use it in your wrapper. All the resources could be combined into one map if you'd like, with values like enum Resource { Buffer(Buffer), /* etc. ...*/ }

@dobkeratops
Copy link
Author

dobkeratops commented Nov 8, 2021

right that could certanly be done (and the enum idea wouod allow glIsBuffer etc to work as a bonus;
you could also expose it with a heavy warning that the API is subject to change. in the use case i would be happy to comfer and id assume most people wont touch it
you could also make the raw handle a type (that just happens to be the same as glint) incase you need flexibility (“get_internal_raw_handle(&self)->glow::RawHandle /// warning this is unstable,subject to future change… type RawHandle=i32 ; /// warning this is unstable” perhaps).

but right.. no problem if you dont want to expose this, the wrapper could do it. but id rather avoid the extra lookup and accept the potential for a breaking change

bors bot added a commit that referenced this issue Dec 7, 2021
195: support wasm32-unknown-emscripten r=grovesNL a=caiiiycuk

Related to #189
To support `wasm32-unknown-emscripten` no need to do anything special like c api. It just works as is, because emscripten emulates OpenGL ES 3.0, so just disabling web path for it works fine (tested on vange-rs project)

Co-authored-by: Alexander Guryanov <[email protected]>
@grovesNL
Copy link
Owner

Generally this isn't planned right now but #189 can probably help with this for now

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

No branches or pull requests

3 participants