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

Unable to create a OpenGL 2.1 context on macOS #1672

Open
dgavedissian opened this issue Mar 30, 2024 · 0 comments
Open

Unable to create a OpenGL 2.1 context on macOS #1672

dgavedissian opened this issue Mar 30, 2024 · 0 comments
Labels

Comments

@dgavedissian
Copy link

dgavedissian commented Mar 30, 2024

Hello! I had an application which was previously using some SDL2 Rust bindings and was later rewritten to use winit + glutin, which happens to use a legacy OpenGL 2.1 context on macOS. The code that creates the context looks roughly like this:

let gl_display = gl_config.display();

let context_attributes = ContextAttributesBuilder::new()
    .with_context_api(ContextApi::OpenGl(Some(Version::new(
        self.gl_version_major,
        self.gl_version_minor,
    ))))
    .with_profile(GlProfile::Compatibility) // <--- I'm requesting a compatibility context
    .build(raw_window_handle);

let gl_context = unsafe {
    gl_display
        .create_context(&gl_config, &context_attributes)
        .expect("failed to create context")
};

However, I end up with an OpenGL 4.1 core context, with all legacy OpenGL features disabled.

I had a look through the cgl module and found this piece of code, which seems to indicate that we will always try to create an OpenGL context with the latest version of OpenGL regardless of the profile specified in the ContextAttributesBuilder:

// Automatically pick the latest profile.
let raw = [
NSOpenGLProfileVersion4_1Core,
NSOpenGLProfileVersion3_2Core,
NSOpenGLProfileVersionLegacy,
]
.into_iter()
.find_map(|profile| {
attrs[profile_attr_pos] = profile;
// initWithAttributes returns None if the attributes were invalid
unsafe { NSOpenGLPixelFormat::newWithAttributes(&attrs) }
})
.ok_or(ErrorKind::BadConfig)?;

If I change that array locally so that NSOpenGLProfileVersionLegacy is the first element, then the NSOpenGLPixelFormat object gets created with the legacy OpenGL context correctly as expected, and my application works properly.

It seems that we don't have the ContextAttributes object yet when calling Display::find_configs. SDL2's behaviour is to use NSOpenGLProfileVersionLegacy by default unless a core profile is specified, then favour NSOpenGLProfileVersion3_2Core.

I'm not very familiar with glutin's internals, so not sure what the cleanest approach would be here, but I had some potential ideas:

  • Maybe we could fix this by creating two NSOpenGLPixelFormat objects and storing both in cgl's ConfigInner type, one for the "compatibility" profile with NSOpenGLProfileVersionLegacy, and one for the "core" profile using either NSOpenGLProfileVersion4_1Core and NSOpenGLProfileVersion3_2Core (similar to the existing logic)?
  • Maybe a cleaner option would be to defer the creation of the NSOpenGLPixelFormat by instead storing the Vec<NSOpenGLPixelFormatAttribute> directly in cgl's ConfigInner type, then setting NSOpenGLPFAOpenGLProfile correctly and create the NSOpenGLPixelFormat object later when we have access to the ContextAttributes object: https://github.com/rust-windowing/glutin/blob/master/glutin/src/api/cgl/context.rs#L49

Thanks for your time! I'm happy to contribute a PR if any of the above approaches sound reasonable.

@kchibisov kchibisov added the CGL label May 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

2 participants