Merge pull request #409 from kvark/core

GL core profile flag
This commit is contained in:
tomaka 2015-05-01 14:07:10 +02:00
commit 4882a94080
7 changed files with 82 additions and 18 deletions

View file

@ -1,6 +1,6 @@
[package] [package]
name = "glutin" name = "glutin"
version = "0.0.27" version = "0.0.28"
authors = ["tomaka <pierre.krieger1708@gmail.com>"] authors = ["tomaka <pierre.krieger1708@gmail.com>"]
description = "Cross-plaform OpenGL context provider." description = "Cross-plaform OpenGL context provider."
keywords = ["windowing", "opengl"] keywords = ["windowing", "opengl"]

View file

@ -52,6 +52,7 @@ fn main() {
khronos_api::GLX_XML, khronos_api::GLX_XML,
vec![ vec![
"GLX_ARB_create_context".to_string(), "GLX_ARB_create_context".to_string(),
"GLX_ARB_create_context_profile".to_string(),
"GLX_ARB_framebuffer_sRGB".to_string(), "GLX_ARB_framebuffer_sRGB".to_string(),
"GLX_EXT_framebuffer_sRGB".to_string(), "GLX_EXT_framebuffer_sRGB".to_string(),
"GLX_EXT_swap_control".to_string(), "GLX_EXT_swap_control".to_string(),

View file

@ -9,7 +9,9 @@ use libc;
use Api; use Api;
use BuilderAttribs; use BuilderAttribs;
use CreationError;
use GlContext; use GlContext;
use GlProfile;
use GlRequest; use GlRequest;
use PixelFormat; use PixelFormat;
use native_monitor::NativeMonitorId; use native_monitor::NativeMonitorId;
@ -334,7 +336,6 @@ impl Window {
Some(window) => window, Some(window) => window,
None => { return Err(OsError(format!("Couldn't create NSWindow"))); }, None => { return Err(OsError(format!("Couldn't create NSWindow"))); },
}; };
let view = match Window::create_view(*window) { let view = match Window::create_view(*window) {
Some(view) => view, Some(view) => view,
None => { return Err(OsError(format!("Couldn't create NSView"))); }, None => { return Err(OsError(format!("Couldn't create NSView"))); },
@ -469,18 +470,17 @@ impl Window {
} }
} }
fn create_context(view: id, builder: &BuilderAttribs) -> (Option<IdRef>, Option<PixelFormat>) { fn create_context(view: id, builder: &BuilderAttribs) -> Result<(Option<IdRef>, Option<PixelFormat>), CreationError> {
let profile = match builder.gl_version { let profile = match (builder.gl_version, builder.gl_version.to_gl_version(), builder.gl_profile) {
GlRequest::Latest => NSOpenGLProfileVersion4_1Core as u32, (GlRequest::Latest, _, Some(GlProfile::Compatibility)) => NSOpenGLProfileVersionLegacy as u32,
GlRequest::Specific(Api::OpenGl, (1 ... 2, _)) => NSOpenGLProfileVersionLegacy as u32, (GlRequest::Latest, _, _) => NSOpenGLProfileVersion4_1Core as u32,
GlRequest::Specific(Api::OpenGl, (3, 0)) => NSOpenGLProfileVersionLegacy as u32, (_, Some(1 ... 2, _), Some(GlProfile::Core)) |
GlRequest::Specific(Api::OpenGl, (3, 1 ... 2)) => NSOpenGLProfileVersion3_2Core as u32, (_, Some(3 ... 4, _), Some(GlProfile::Compatibility)) =>
GlRequest::Specific(Api::OpenGl, _) => NSOpenGLProfileVersion4_1Core as u32, return Err(CreationError::NotSupported),
GlRequest::Specific(_, _) => panic!("Only the OpenGL API is supported"), // FIXME: return Result (_, Some(1 ... 2, _), _) => NSOpenGLProfileVersionLegacy as u32,
GlRequest::GlThenGles { opengl_version: (1 ... 2, _), .. } => NSOpenGLProfileVersionLegacy as u32, (_, Some(3, 0 ... 2), _) => NSOpenGLProfileVersion3_2Core as u32,
GlRequest::GlThenGles { opengl_version: (3, 0), .. } => NSOpenGLProfileVersionLegacy as u32, (_, Some(3 ... 4, _), _) => NSOpenGLProfileVersion4_1Core as u32,
GlRequest::GlThenGles { opengl_version: (3, 1 ... 2), .. } => NSOpenGLProfileVersion3_2Core as u32, _ => return Err(CreationError::NotSupported),
GlRequest::GlThenGles { .. } => NSOpenGLProfileVersion4_1Core as u32,
}; };
// NOTE: OS X no longer has the concept of setting individual // NOTE: OS X no longer has the concept of setting individual
@ -517,7 +517,7 @@ impl Window {
// attribute list must be null terminated. // attribute list must be null terminated.
attributes.push(0); attributes.push(0);
unsafe { Ok(unsafe {
let pixelformat = IdRef::new(NSOpenGLPixelFormat::alloc(nil).initWithAttributes_(&attributes)); let pixelformat = IdRef::new(NSOpenGLPixelFormat::alloc(nil).initWithAttributes_(&attributes));
if let Some(pixelformat) = pixelformat.non_nil() { if let Some(pixelformat) = pixelformat.non_nil() {
@ -575,7 +575,7 @@ impl Window {
} else { } else {
(None, None) (None, None)
} }
} })
} }
pub fn is_closed(&self) -> bool { pub fn is_closed(&self) -> bool {

View file

@ -3,6 +3,7 @@
use BuilderAttribs; use BuilderAttribs;
use CreationError; use CreationError;
use GlContext; use GlContext;
use GlProfile;
use GlRequest; use GlRequest;
use Api; use Api;
use PixelFormat; use PixelFormat;
@ -52,6 +53,17 @@ impl Context {
}, },
} }
if let Some(profile) = builder.gl_profile {
let flag = match profile {
GlProfile::Compatibility =>
ffi::glx_extra::CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
GlProfile::Core =>
ffi::glx_extra::CONTEXT_CORE_PROFILE_BIT_ARB,
};
attributes.push(ffi::glx_extra::CONTEXT_PROFILE_MASK_ARB as libc::c_int);
attributes.push(flag as libc::c_int);
}
if builder.gl_debug { if builder.gl_debug {
attributes.push(ffi::glx_extra::CONTEXT_FLAGS_ARB as libc::c_int); attributes.push(ffi::glx_extra::CONTEXT_FLAGS_ARB as libc::c_int);
attributes.push(ffi::glx_extra::CONTEXT_DEBUG_BIT_ARB as libc::c_int); attributes.push(ffi::glx_extra::CONTEXT_DEBUG_BIT_ARB as libc::c_int);
@ -184,8 +196,6 @@ unsafe impl Sync for Context {}
impl Drop for Context { impl Drop for Context {
fn drop(&mut self) { fn drop(&mut self) {
use std::ptr;
unsafe { unsafe {
// we don't call MakeCurrent(0, 0) because we are not sure that the context // we don't call MakeCurrent(0, 0) because we are not sure that the context
// is still the current one // is still the current one

View file

@ -17,6 +17,7 @@ use BuilderAttribs;
use CreationError; use CreationError;
use CreationError::OsError; use CreationError::OsError;
use CursorState; use CursorState;
use GlProfile;
use GlRequest; use GlRequest;
use PixelFormat; use PixelFormat;
@ -374,6 +375,23 @@ unsafe fn create_context(extra: Option<(&gl::wgl_extra::Wgl, &BuilderAttribs<'st
}, },
} }
if let Some(profile) = builder.gl_profile {
if is_extension_supported(extra_functions, hdc,
"WGL_ARB_create_context_profile")
{
let flag = match profile {
GlProfile::Compatibility =>
gl::wgl_extra::CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
GlProfile::Core =>
gl::wgl_extra::CONTEXT_CORE_PROFILE_BIT_ARB,
};
attributes.push(gl::wgl_extra::CONTEXT_PROFILE_MASK_ARB as libc::c_int);
attributes.push(flag as libc::c_int);
} else {
return Err(CreationError::NotSupported);
}
}
if builder.gl_debug { if builder.gl_debug {
attributes.push(gl::wgl_extra::CONTEXT_FLAGS_ARB as libc::c_int); attributes.push(gl::wgl_extra::CONTEXT_FLAGS_ARB as libc::c_int);
attributes.push(gl::wgl_extra::CONTEXT_DEBUG_BIT_ARB as libc::c_int); attributes.push(gl::wgl_extra::CONTEXT_DEBUG_BIT_ARB as libc::c_int);

View file

@ -137,6 +137,15 @@ pub enum Api {
WebGl, WebGl,
} }
/// Describes the requested OpenGL context profiles.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum GlProfile {
/// Include all the immediate more functions and definitions.
Compatibility,
/// Include all the future-compatible functions and definitions.
Core,
}
/// Describes the OpenGL API and version that are being requested when a context is created. /// Describes the OpenGL API and version that are being requested when a context is created.
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub enum GlRequest { pub enum GlRequest {
@ -161,6 +170,22 @@ pub enum GlRequest {
}, },
} }
impl GlRequest {
/// Extract the desktop GL version, if any.
pub fn to_gl_version(&self) -> Option<(u8, u8)> {
match self {
&GlRequest::Specific(Api::OpenGl, version) => Some(version),
&GlRequest::GlThenGles { opengl_version: version, .. } => Some(version),
_ => None,
}
}
}
/// The minimum core profile GL context. Useful for getting the minimum
/// required GL version while still running on OSX, which often forbids
/// the compatibility profile features.
pub static GL_CORE: GlRequest = GlRequest::Specific(Api::OpenGl, (3, 2));
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub enum MouseCursor { pub enum MouseCursor {
/// The platform-dependent default cursor. /// The platform-dependent default cursor.
@ -261,6 +286,7 @@ pub struct BuilderAttribs<'a> {
title: String, title: String,
monitor: Option<platform::MonitorID>, monitor: Option<platform::MonitorID>,
gl_version: GlRequest, gl_version: GlRequest,
gl_profile: Option<GlProfile>,
gl_debug: bool, gl_debug: bool,
vsync: bool, vsync: bool,
visible: bool, visible: bool,
@ -283,6 +309,7 @@ impl BuilderAttribs<'static> {
title: "glutin window".to_string(), title: "glutin window".to_string(),
monitor: None, monitor: None,
gl_version: GlRequest::Latest, gl_version: GlRequest::Latest,
gl_profile: None,
gl_debug: cfg!(debug_assertions), gl_debug: cfg!(debug_assertions),
vsync: false, vsync: false,
visible: true, visible: true,
@ -309,6 +336,7 @@ impl<'a> BuilderAttribs<'a> {
title: self.title, title: self.title,
monitor: self.monitor, monitor: self.monitor,
gl_version: self.gl_version, gl_version: self.gl_version,
gl_profile: self.gl_profile,
gl_debug: self.gl_debug, gl_debug: self.gl_debug,
vsync: self.vsync, vsync: self.vsync,
visible: self.visible, visible: self.visible,

View file

@ -7,6 +7,7 @@ use CreationError;
use CursorState; use CursorState;
use Event; use Event;
use GlContext; use GlContext;
use GlProfile;
use GlRequest; use GlRequest;
use MouseCursor; use MouseCursor;
use PixelFormat; use PixelFormat;
@ -67,6 +68,12 @@ impl<'a> WindowBuilder<'a> {
self self
} }
/// Sets the desired OpenGL context profile.
pub fn with_gl_profile(mut self, profile: GlProfile) -> WindowBuilder<'a> {
self.attribs.gl_profile = Some(profile);
self
}
/// Sets the *debug* flag for the OpenGL context. /// Sets the *debug* flag for the OpenGL context.
/// ///
/// The default value for this flag is `cfg!(debug_assertions)`, which means that it's enabled /// The default value for this flag is `cfg!(debug_assertions)`, which means that it's enabled