Add multisampling for cocoa, fixes #145

This commit is contained in:
Felix Kaaman 2015-04-26 11:57:38 +02:00
parent b7f81853fb
commit f2bbb7d49c

View file

@ -328,7 +328,7 @@ impl Window {
}; };
let window = match Window::create_window(builder.dimensions.unwrap_or((800, 600)), let window = match Window::create_window(builder.dimensions.unwrap_or((800, 600)),
&*builder.title, &*builder.title,
builder.monitor) &builder.monitor)
{ {
Some(window) => window, Some(window) => window,
None => { return Err(OsError(format!("Couldn't create NSWindow"))); }, None => { return Err(OsError(format!("Couldn't create NSWindow"))); },
@ -338,7 +338,7 @@ impl Window {
None => { return Err(OsError(format!("Couldn't create NSView"))); }, None => { return Err(OsError(format!("Couldn't create NSView"))); },
}; };
let context = match Window::create_context(*view, builder.vsync, builder.gl_version) { let context = match Window::create_context(*view, &builder) {
Some(context) => context, Some(context) => context,
None => { return Err(OsError(format!("Couldn't create OpenGL context"))); }, None => { return Err(OsError(format!("Couldn't create OpenGL context"))); },
}; };
@ -384,34 +384,37 @@ impl Window {
} }
} }
fn create_window(dimensions: (u32, u32), title: &str, monitor: Option<MonitorID>) -> Option<IdRef> { fn create_window(dimensions: (u32, u32), title: &str, monitor: &Option<MonitorID>) -> Option<IdRef> {
unsafe { unsafe {
let screen = monitor.map(|monitor_id| { let screen = match *monitor {
let native_id = match monitor_id.get_native_identifier() { Some(ref monitor_id) => {
NativeMonitorId::Numeric(num) => num, let native_id = match monitor_id.get_native_identifier() {
_ => panic!("OS X monitors should always have a numeric native ID") NativeMonitorId::Numeric(num) => num,
}; _ => panic!("OS X monitors should always have a numeric native ID")
let matching_screen = { };
let screens = NSScreen::screens(nil); let matching_screen = {
let count: NSUInteger = msg_send![screens, count]; let screens = NSScreen::screens(nil);
let key = IdRef::new(NSString::alloc(nil).init_str("NSScreenNumber")); let count: NSUInteger = msg_send![screens, count];
let mut matching_screen: Option<id> = None; let key = IdRef::new(NSString::alloc(nil).init_str("NSScreenNumber"));
for i in (0..count) { let mut matching_screen: Option<id> = None;
let screen = msg_send![screens, objectAtIndex:i as NSUInteger]; for i in (0..count) {
let device_description = NSScreen::deviceDescription(screen); let screen = msg_send![screens, objectAtIndex:i as NSUInteger];
let value: id = msg_send![device_description, objectForKey:*key]; let device_description = NSScreen::deviceDescription(screen);
if value != nil { let value: id = msg_send![device_description, objectForKey:*key];
let screen_number: NSUInteger = msg_send![value, unsignedIntegerValue]; if value != nil {
if screen_number as u32 == native_id { let screen_number: NSUInteger = msg_send![value, unsignedIntegerValue];
matching_screen = Some(screen); if screen_number as u32 == native_id {
break; matching_screen = Some(screen);
break;
}
} }
} }
} matching_screen
matching_screen };
}; Some(matching_screen.unwrap_or(NSScreen::mainScreen(nil)))
matching_screen.unwrap_or(NSScreen::mainScreen(nil)) },
}); None => None
};
let frame = match screen { let frame = match screen {
Some(screen) => NSScreen::frame(screen), Some(screen) => NSScreen::frame(screen),
None => { None => {
@ -461,8 +464,8 @@ impl Window {
} }
} }
fn create_context(view: id, vsync: bool, gl_version: GlRequest) -> Option<IdRef> { fn create_context(view: id, builder: &BuilderAttribs) -> Option<IdRef> {
let profile = match gl_version { let profile = match builder.gl_version {
GlRequest::Latest => NSOpenGLProfileVersion4_1Core as u32, GlRequest::Latest => NSOpenGLProfileVersion4_1Core as u32,
GlRequest::Specific(Api::OpenGl, (1 ... 2, _)) => NSOpenGLProfileVersionLegacy as u32, GlRequest::Specific(Api::OpenGl, (1 ... 2, _)) => NSOpenGLProfileVersionLegacy as u32,
GlRequest::Specific(Api::OpenGl, (3, 0)) => NSOpenGLProfileVersionLegacy as u32, GlRequest::Specific(Api::OpenGl, (3, 0)) => NSOpenGLProfileVersionLegacy as u32,
@ -475,7 +478,7 @@ impl Window {
GlRequest::GlThenGles { .. } => NSOpenGLProfileVersion4_1Core as u32, GlRequest::GlThenGles { .. } => NSOpenGLProfileVersion4_1Core as u32,
}; };
unsafe { unsafe {
let attributes = [ let mut attributes = vec![
NSOpenGLPFADoubleBuffer as u32, NSOpenGLPFADoubleBuffer as u32,
NSOpenGLPFAClosestPolicy as u32, NSOpenGLPFAClosestPolicy as u32,
NSOpenGLPFAColorSize as u32, 24, NSOpenGLPFAColorSize as u32, 24,
@ -483,15 +486,24 @@ impl Window {
NSOpenGLPFADepthSize as u32, 24, NSOpenGLPFADepthSize as u32, 24,
NSOpenGLPFAStencilSize as u32, 8, NSOpenGLPFAStencilSize as u32, 8,
NSOpenGLPFAOpenGLProfile as u32, profile, NSOpenGLPFAOpenGLProfile as u32, profile,
0
]; ];
if let Some(samples) = builder.multisampling {
attributes = attributes + &[
NSOpenGLPFAMultisample as u32,
NSOpenGLPFASampleBuffers as u32, 1,
NSOpenGLPFASamples as u32, samples as u32,
];
}
attributes.push(0);
let pixelformat = IdRef::new(NSOpenGLPixelFormat::alloc(nil).initWithAttributes_(&attributes)); let pixelformat = IdRef::new(NSOpenGLPixelFormat::alloc(nil).initWithAttributes_(&attributes));
pixelformat.non_nil().map(|pixelformat| { pixelformat.non_nil().map(|pixelformat| {
let context = IdRef::new(NSOpenGLContext::alloc(nil).initWithFormat_shareContext_(*pixelformat, nil)); let context = IdRef::new(NSOpenGLContext::alloc(nil).initWithFormat_shareContext_(*pixelformat, nil));
context.non_nil().map(|context| { context.non_nil().map(|context| {
context.setView_(view); context.setView_(view);
if vsync { if builder.vsync {
let value = 1; let value = 1;
context.setValues_forParameter_(&value, NSOpenGLContextParameter::NSOpenGLCPSwapInterval); context.setValues_forParameter_(&value, NSOpenGLContextParameter::NSOpenGLCPSwapInterval);
} }