Cocoa opens a window with OpenGL context inside

This commit is contained in:
David Partouche 2014-10-04 15:49:39 +02:00
parent fe245e2929
commit c38110cac7
3 changed files with 105 additions and 12 deletions

View file

@ -12,3 +12,9 @@ git = "https://github.com/tomaka/android-rs-glue"
[dependencies.gl_generator]
git = "https://github.com/bjz/gl-rs"
[dependencies.cocoa]
git = "https://github.com/DavidPartouche/rust-cocoa"
[dependencies.core_foundation]
git = "https://github.com/DavidPartouche/rust-core-foundation"

View file

@ -22,6 +22,11 @@
#[phase(plugin)] extern crate gl_generator;
extern crate libc;
#[cfg(target_os = "macos")]
extern crate cocoa;
#[cfg(target_os = "macos")]
extern crate core_foundation;
pub use events::*;
use std::default::Default;

View file

@ -1,13 +1,18 @@
//! Dummy implementation for OS/X to make gl-init-rs compile on this platform
use {Event, WindowBuilder};
pub struct Window;
use cocoa::base::{id, NSUInteger, nil};
use cocoa::appkit::*;
use core_foundation::base::TCFType;
use core_foundation::string::CFString;
use core_foundation::bundle::{CFBundleGetBundleWithIdentifier, CFBundleGetFunctionPointerForName};
pub struct Window {
context: id,
}
pub struct MonitorID;
compile_warning!("The OS/X platform is not implemented yet")
pub fn get_available_monitors() -> Vec<MonitorID> {
unimplemented!()
}
@ -18,7 +23,7 @@ pub fn get_primary_monitor() -> MonitorID {
impl MonitorID {
pub fn get_name(&self) -> Option<String> {
unimplemented!()
unimplemented!()
}
pub fn get_dimensions(&self) -> (uint, uint) {
@ -28,11 +33,68 @@ impl MonitorID {
impl Window {
pub fn new(_builder: WindowBuilder) -> Result<Window, String> {
unimplemented!()
let context = unsafe {
// Create the NSApplication
let app = NSApp();
app.setActivationPolicy_(NSApplicationActivationPolicyRegular);
app.finishLaunching();
// Create the window
let scr_frame = NSRect::new(NSPoint::new(0., 0.), NSSize::new(800., 600.));
let window = NSWindow::alloc(nil).initWithContentRect_styleMask_backing_defer_(
scr_frame,
NSTitledWindowMask as NSUInteger | NSClosableWindowMask as NSUInteger | NSMiniaturizableWindowMask as NSUInteger,
NSBackingStoreBuffered,
false
);
let view = NSView::alloc(nil).init();
view.setWantsBestResolutionOpenGLSurface_(true);
let title = NSString::alloc(nil).init_str("Hello World!\0");
window.setTitle_(title);
window.setContentView(view);
window.center();
// Create the context
let attributes = [
NSOpenGLPFADoubleBuffer as uint,
NSOpenGLPFAClosestPolicy as uint,
NSOpenGLPFAColorSize as uint, 24,
NSOpenGLPFAAlphaSize as uint, 8,
NSOpenGLPFADepthSize as uint, 24,
NSOpenGLPFAStencilSize as uint, 8,
0
];
let pixelformat = NSOpenGLPixelFormat::alloc(nil).initWithAttributes_(attributes);
if pixelformat == nil {
return Err(format!("Couldn't create the pixel format"));
}
let context = NSOpenGLContext::alloc(nil).initWithFormat_shareContext_(pixelformat, nil);
if context == nil {
return Err(format!("No valid OpenGL context can be created with that pixelformat"));
}
context.setView_(view);
app.activateIgnoringOtherApps_(true);
window.makeKeyAndOrderFront_(nil);
context
};
let window = Window {
context: context,
};
Ok(window)
}
pub fn is_closed(&self) -> bool {
unimplemented!()
// TODO: remove fake implementation
false
}
pub fn set_title(&self, _title: &str) {
@ -64,18 +126,38 @@ impl Window {
}
pub fn wait_events(&self) -> Vec<Event> {
unimplemented!()
loop {
unsafe {
let event = NSApp().nextEventMatchingMask_untilDate_inMode_dequeue_(
NSAnyEventMask as u64,
nil,
NSDefaultRunLoopMode,
true);
if event == nil { break; }
NSApp().sendEvent_(event);
}
}
// TODO: Remove fake implementation
Vec::new()
}
pub unsafe fn make_current(&self) {
unimplemented!()
self.context.makeCurrentContext();
}
pub fn get_proc_address(&self, _addr: &str) -> *const () {
unimplemented!()
let symbol_name: CFString = from_str(_addr).unwrap();
let framework_name: CFString = from_str("com.apple.opengl").unwrap();
let framework = unsafe {
CFBundleGetBundleWithIdentifier(framework_name.as_concrete_TypeRef())
};
let symbol = unsafe {
CFBundleGetFunctionPointerForName(framework, symbol_name.as_concrete_TypeRef())
};
symbol as *const ()
}
pub fn swap_buffers(&self) {
unimplemented!()
unsafe { self.context.flushBuffer(); }
}
}