Fix cocoa headless

This commit is contained in:
Fredrik Noren 2016-01-08 00:03:54 -05:00
parent 88e64a87a9
commit c6c4dfdd1e
4 changed files with 52 additions and 51 deletions

View file

@ -180,8 +180,8 @@ fn main() {
let mut file = File::create(&dest.join("test_gl_bindings.rs")).unwrap(); let mut file = File::create(&dest.join("test_gl_bindings.rs")).unwrap();
gl_generator::generate_bindings(gl_generator::StructGenerator, gl_generator::generate_bindings(gl_generator::StructGenerator,
gl_generator::registry::Ns::Gles2, gl_generator::registry::Ns::Gl,
gl_generator::Fallbacks::All, gl_generator::Fallbacks::All,
khronos_api::GL_XML, vec![], khronos_api::GL_XML, vec![],
"3.0", "core", &mut file).unwrap(); "3.3", "core", &mut file).unwrap();
} }

View file

@ -4,7 +4,6 @@ use std::ptr;
use glutin; use glutin;
mod gl { mod gl {
pub use self::Gles2 as Gl;
include!(concat!(env!("OUT_DIR"), "/test_gl_bindings.rs")); include!(concat!(env!("OUT_DIR"), "/test_gl_bindings.rs"));
} }

View file

@ -14,13 +14,6 @@ use cocoa::base::{id, nil};
use cocoa::appkit::*; use cocoa::appkit::*;
use PixelFormat; use PixelFormat;
mod gl {
include!(concat!(env!("OUT_DIR"), "/gl_bindings.rs"));
}
static mut framebuffer: u32 = 0;
static mut texture: u32 = 0;
pub struct HeadlessContext { pub struct HeadlessContext {
width: u32, width: u32,
height: u32, height: u32,
@ -33,9 +26,14 @@ impl HeadlessContext {
{ {
let context = unsafe { let context = unsafe {
let attributes = [ let attributes = [
NSOpenGLPFAAccelerated as u32,
NSOpenGLPFAAllowOfflineRenderers as u32,
NSOpenGLPFADoubleBuffer as u32, NSOpenGLPFADoubleBuffer as u32,
NSOpenGLPFAClosestPolicy as u32,
NSOpenGLPFAColorSize as u32, 24,
NSOpenGLPFAAlphaSize as u32, 8,
NSOpenGLPFADepthSize as u32, 24,
NSOpenGLPFAStencilSize as u32, 8,
NSOpenGLPFAOpenGLProfile as u32, NSOpenGLProfileVersion3_2Core as u32,
0 0
]; ];
@ -56,9 +54,6 @@ impl HeadlessContext {
context: context, context: context,
}; };
// Load the function pointers as we need them to create the FBO
gl::load_with(|s| headless.get_proc_address(s) as *const c_void);
Ok(headless) Ok(headless)
} }
} }
@ -66,28 +61,12 @@ impl HeadlessContext {
impl GlContext for HeadlessContext { impl GlContext for HeadlessContext {
unsafe fn make_current(&self) -> Result<(), ContextError> { unsafe fn make_current(&self) -> Result<(), ContextError> {
self.context.makeCurrentContext(); self.context.makeCurrentContext();
gl::GenFramebuffersEXT(1, &mut framebuffer);
gl::BindFramebufferEXT(gl::FRAMEBUFFER_EXT, framebuffer);
gl::GenTextures(1, &mut texture);
gl::BindTexture(gl::TEXTURE_2D, texture);
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::LINEAR as i32);
gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::LINEAR as i32);
gl::TexImage2D(gl::TEXTURE_2D, 0, gl::RGBA8 as i32, self.width as i32, self.height as i32,
0, gl::RGBA, gl::UNSIGNED_BYTE, ptr::null());
gl::FramebufferTexture2DEXT(gl::FRAMEBUFFER_EXT, gl::COLOR_ATTACHMENT0_EXT,
gl::TEXTURE_2D, texture, 0);
let status = gl::CheckFramebufferStatusEXT(gl::FRAMEBUFFER_EXT);
if status != gl::FRAMEBUFFER_COMPLETE_EXT {
panic!("Error while creating the framebuffer");
}
Ok(()) Ok(())
} }
#[inline] #[inline]
fn is_current(&self) -> bool { fn is_current(&self) -> bool {
unimplemented!() true
} }
#[inline] #[inline]
@ -105,6 +84,7 @@ impl GlContext for HeadlessContext {
#[inline] #[inline]
fn swap_buffers(&self) -> Result<(), ContextError> { fn swap_buffers(&self) -> Result<(), ContextError> {
unsafe { self.context.flushBuffer(); }
Ok(()) Ok(())
} }
@ -121,13 +101,3 @@ impl GlContext for HeadlessContext {
unsafe impl Send for HeadlessContext {} unsafe impl Send for HeadlessContext {}
unsafe impl Sync for HeadlessContext {} unsafe impl Sync for HeadlessContext {}
impl Drop for HeadlessContext {
#[inline]
fn drop(&mut self) {
unsafe {
gl::DeleteTextures(1, &texture);
gl::DeleteFramebuffersEXT(1, &framebuffer);
}
}
}

View file

@ -1,28 +1,60 @@
extern crate glutin; extern crate glutin;
extern crate libc; extern crate libc;
use glutin::*;
use std::ptr;
mod gl { mod gl {
include!(concat!(env!("OUT_DIR"), "/test_gl_bindings.rs")); include!(concat!(env!("OUT_DIR"), "/test_gl_bindings.rs"));
} }
use gl::types::*;
#[cfg(feature = "headless")]
#[test] #[test]
fn main() { fn main() {
let window = glutin::HeadlessRendererBuilder::new(1024, 768).build().unwrap(); let width: i32 = 2;
let height: i32 = 1;
let window = glutin::HeadlessRendererBuilder::new(width as u32, height as u32).build().unwrap();
unsafe { window.make_current() }; unsafe { window.make_current() };
let gl = gl::Gl::load_with(|symbol| window.get_proc_address(symbol)); let gl = gl::Gl::load_with(|symbol| window.get_proc_address(symbol) as *const _);
unsafe { unsafe {
let mut framebuffer = 0;
let mut texture = 0;
gl.GenFramebuffers(1, &mut framebuffer);
gl.BindFramebuffer(gl::FRAMEBUFFER, framebuffer);
gl.GenTextures(1, &mut texture);
gl.BindTexture(gl::TEXTURE_2D, texture);
gl.TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::LINEAR as i32);
gl.TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::LINEAR as i32);
gl.TexImage2D(gl::TEXTURE_2D, 0, gl::RGBA as i32, width, height,
0, gl::RGBA, gl::UNSIGNED_BYTE, ptr::null());
gl.FramebufferTexture(gl::FRAMEBUFFER, gl::COLOR_ATTACHMENT0, texture, 0);
let status = gl.CheckFramebufferStatus(gl::FRAMEBUFFER);
if status != gl::FRAMEBUFFER_COMPLETE {
panic!("Error while creating the framebuffer");
}
gl.ClearColor(0.0, 1.0, 0.0, 1.0); gl.ClearColor(0.0, 1.0, 0.0, 1.0);
gl.Clear(gl::COLOR_BUFFER_BIT); gl.Clear(gl::COLOR_BUFFER_BIT);
gl.Enable(gl::SCISSOR_TEST);
gl.Scissor(1, 0, 1, 1);
gl.ClearColor(1.0, 0.0, 0.0, 1.0);
gl.Clear(gl::COLOR_BUFFER_BIT);
let mut value: (u8, u8, u8, u8) = std::mem::uninitialized(); let mut values: Vec<u8> = vec![0;(width*height*4) as usize];
gl.ReadPixels(0, 0, 1, 1, gl::RGBA, gl::UNSIGNED_BYTE, std::mem::transmute(&mut value)); gl.ReadPixels(0, 0, width, height, gl::RGBA, gl::UNSIGNED_BYTE, values.as_mut_ptr() as *mut GLvoid);
assert!(value == (0, 255, 0, 255) || value == (0, 64, 0, 255) || println!("{:?}", values);
value == (0, 64, 0, 255) || value == (0, 64, 0, 0),
"value is: {:?}", value); assert_eq!(values[0], 0);
assert_eq!(values[1], 255);
assert_eq!(values[2], 0);
assert_eq!(values[3], 255);
assert_eq!(values[4], 255);
assert_eq!(values[5], 0);
assert_eq!(values[6], 0);
assert_eq!(values[7], 255);
} }
} }