glow icon indicating copy to clipboard operation
glow copied to clipboard

glow design rationale

Open notdanilo opened this issue 5 years ago • 6 comments

glow is supposed to provide GL on Whatever. But what is the strategy to achieve it? Being clear about the design rationale would increase trust in the project.

As suggested in the comment bellow, glow only exposes a subset of the functions which are present in OpenGL, OpenGLES3 and WebGL2.

[...] generally if there's a function which exists in all of {OpenGL, OpenGL ES 3, WebGL2} and it's not exposed in glow then it's just unimplemented at the moment.

https://github.com/grovesNL/glow/issues/75#issuecomment-576056903

It makes sense for the project purpose, but what if we want to use platform-specific functionalities?

For instance: It's totally possible to keep track of the platform specific context, but it doesn't seem to be possible to use an OpenGL object created with glow in the original context because the object ID isn't exposed.

notdanilo avatar Jan 20 '20 14:01 notdanilo

But what is the strategy to achieve it?

Basically the goal is to make it easy as possible to use the portable subset between OpenGL, OpenGL ES, and WebGL. We want to avoid users having to write #[cfg(target_arch = "wasm32")] in order to switch between these APIs.

Some of the original rationale was described in https://github.com/gfx-rs/gfx/pull/2554 but the glow README definitely needs some more detail about this :)

It makes sense for the project purpose, but what if we want to use platform-specific functionalities?

I think it's reasonable to expose parts of the API outside that subset as platform-specific extensions as long as the user is aware that it's not portable. For example, we already started exposing some WebGL-specific functionality that doesn't exist on OpenGL or OpenGL ES.

winit also has a nice approach to handle platform-specific functionality -- we might be able to apply a similar approach to glow.

grovesNL avatar Jan 20 '20 15:01 grovesNL

As it pertains to the design of this lib, I'm curious about https://github.com/grovesNL/glow/commit/ed1ca4323cb2b976170a56daed53427099eed0b2. Was the driving force behind removing the more complex type system just to keep this crate as simple as possible? Creating a more 'Rusty' type representation fell outside of it's scope?

TannerRogalsky avatar Feb 03 '20 21:02 TannerRogalsky

@TannerRogalsky Great question :) It's difficult to say whether removing typed enums/newtypes/bitflags is the best move, but the biggest issues I noticed were:

  • We basically had to invent names for these new groups of values, and it wasn't clear which values should be grouped together (we'd have to create enums specific to functions if we want to provide meaningful restrictions). For example, which would we prefer:
    • enum TextureTarget with all possible texture targets
    • separate function-specific like enum GenerateMipmapTextureTarget (the list at https://www.khronos.org/registry/OpenGL-Refpages/es3.0/html/glGenerateMipmap.xhtml), enum TexImage2dTextureTarget (the list at https://www.khronos.org/registry/OpenGL-Refpages/es3.0/html/glTexImage2D.xhtml), and enum BindTextureTarget (the list at https://www.khronos.org/registry/OpenGL-Refpages/es3.1/html/glBindTexture.xhtml) in order to help users choose valid texture targets (some variants like Texture2d would be common to all of these)
  • For enums/bitflags, it required more user effort to port existing GL code. For example, following along with an OpenGL tutorial or switching a crate from gl_generator to glow required extra work (especially if the enum name isn't obvious which could be tricky due to the first point). It's also common to have GL code like GL_COLOR_ATTACHMENT0 + i to select an attachment which is more difficult when these are enum variants.

There are probably some places where enums/bitflags are obvious improvements, but at least for now I thought it would be easier if we just kept using constants.

grovesNL avatar Feb 05 '20 04:02 grovesNL

I'd say the biggest loss was actually the newtypes. I recently ran into a (stupid) error which could have been caught by the compiler telling me I was trying to use a BufferID where a BufferTarget was needed. I think these newtypes don't remove much porting ease, since one hardly ever (never?) manipulates some of these identifiers.

rspencer01 avatar Jul 02 '21 08:07 rspencer01

@rspencer01 interesting, maybe we could improve that by using newtypes inside of the associated types at https://github.com/grovesNL/glow/blob/c5a7ec768f57379d5435b9d6fa764967c62e2d29/src/native.rs#L84-L95

e.g. type Shader = NativeShader; with NativeShader defined as struct NativeShader(native_gl::GLuint)

The web backend already does something similar.

grovesNL avatar Jul 02 '21 17:07 grovesNL

It introduces a bit of boilerplate and destructuring code throughout, but I would personally think it is worth it (and, as you say, no worse than the web code).

rspencer01 avatar Jul 02 '21 20:07 rspencer01