diff options
Diffstat (limited to 'src/lib.rs')
-rw-r--r-- | src/lib.rs | 130 |
1 files changed, 101 insertions, 29 deletions
@@ -70,12 +70,14 @@ pub struct MonitorID(winimpl::MonitorID); #[deriving(Clone, Show, PartialEq, Eq)] pub enum CreationError { OsError(String), + NotSupported, } impl std::error::Error for CreationError { fn description(&self) -> &str { match self { &CreationError::OsError(ref text) => text.as_slice(), + &CreationError::NotSupported => "Some of the requested attributes are not supported", } } } @@ -92,7 +94,14 @@ pub enum Api { /// Object that allows you to build windows. #[cfg(feature = "window")] pub struct WindowBuilder<'a> { - sharing: Option<&'a Window>, + attribs: BuilderAttribs<'a> +} + +/// Attributes +struct BuilderAttribs<'a> { + headless: bool, + strict: bool, + sharing: Option<&'a winimpl::Window>, dimensions: Option<(uint, uint)>, title: String, monitor: Option<winimpl::MonitorID>, @@ -101,13 +110,18 @@ pub struct WindowBuilder<'a> { vsync: bool, visible: bool, multisampling: Option<u16>, + depth_bits: Option<u8>, + stencil_bits: Option<u8>, + color_bits: Option<u8>, + alpha_bits: Option<u8>, + stereoscopy: bool, } -#[cfg(feature = "window")] -impl<'a> WindowBuilder<'a> { - /// Initializes a new `WindowBuilder` with default values. - pub fn new() -> WindowBuilder<'a> { - WindowBuilder { +impl BuilderAttribs<'static> { + fn new() -> BuilderAttribs<'static> { + BuilderAttribs { + headless: false, + strict: false, sharing: None, dimensions: None, title: "glutin window".to_string(), @@ -117,6 +131,21 @@ impl<'a> WindowBuilder<'a> { vsync: false, visible: true, multisampling: None, + depth_bits: None, + stencil_bits: None, + color_bits: None, + alpha_bits: None, + stereoscopy: false, + } + } +} + +#[cfg(feature = "window")] +impl<'a> WindowBuilder<'a> { + /// Initializes a new `WindowBuilder` with default values. + pub fn new() -> WindowBuilder<'a> { + WindowBuilder { + attribs: BuilderAttribs::new(), } } @@ -124,13 +153,13 @@ impl<'a> WindowBuilder<'a> { /// /// Width and height are in pixels. pub fn with_dimensions(mut self, width: uint, height: uint) -> WindowBuilder<'a> { - self.dimensions = Some((width, height)); + self.attribs.dimensions = Some((width, height)); self } /// Requests a specific title for the window. pub fn with_title(mut self, title: String) -> WindowBuilder<'a> { - self.title = title; + self.attribs.title = title; self } @@ -139,7 +168,7 @@ impl<'a> WindowBuilder<'a> { /// If you don't specify dimensions for the window, it will match the monitor's. pub fn with_fullscreen(mut self, monitor: MonitorID) -> WindowBuilder<'a> { let MonitorID(monitor) = monitor; - self.monitor = Some(monitor); + self.attribs.monitor = Some(monitor); self } @@ -147,7 +176,7 @@ impl<'a> WindowBuilder<'a> { /// /// There are some exceptions, like FBOs or VAOs. See the OpenGL documentation. pub fn with_shared_lists(mut self, other: &'a Window) -> WindowBuilder<'a> { - self.sharing = Some(other); + self.attribs.sharing = Some(&other.window); self } @@ -156,7 +185,7 @@ impl<'a> WindowBuilder<'a> { /// Version is a (major, minor) pair. For example to request OpenGL 3.3 /// you would pass `(3, 3)`. pub fn with_gl_version(mut self, version: (uint, uint)) -> WindowBuilder<'a> { - self.gl_version = Some(version); + self.attribs.gl_version = Some(version); self } @@ -165,19 +194,19 @@ impl<'a> WindowBuilder<'a> { /// The default value for this flag is `cfg!(ndebug)`, which means that it's enabled /// when you run `cargo build` and disabled when you run `cargo build --release`. pub fn with_gl_debug_flag(mut self, flag: bool) -> WindowBuilder<'a> { - self.gl_debug = flag; + self.attribs.gl_debug = flag; self } /// Requests that the window has vsync enabled. pub fn with_vsync(mut self) -> WindowBuilder<'a> { - self.vsync = true; + self.attribs.vsync = true; self } /// Sets whether the window will be initially hidden or visible. pub fn with_visibility(mut self, visible: bool) -> WindowBuilder<'a> { - self.visible = visible; + self.attribs.visible = visible; self } @@ -189,7 +218,32 @@ impl<'a> WindowBuilder<'a> { pub fn with_multisampling(mut self, samples: u16) -> WindowBuilder<'a> { use std::num::UnsignedInt; assert!(samples.is_power_of_two()); - self.multisampling = Some(samples); + self.attribs.multisampling = Some(samples); + self + } + + /// Sets the number of bits in the depth buffer. + pub fn with_depth_buffer(mut self, bits: u8) -> WindowBuilder<'a> { + self.attribs.depth_bits = Some(bits); + self + } + + /// Sets the number of bits in the stencil buffer. + pub fn with_stencil_buffer(mut self, bits: u8) -> WindowBuilder<'a> { + self.attribs.stencil_bits = Some(bits); + self + } + + /// Sets the number of bits in the color buffer. + pub fn with_pixel_format(mut self, color_bits: u8, alpha_bits: u8) -> WindowBuilder<'a> { + self.attribs.color_bits = Some(color_bits); + self.attribs.alpha_bits = Some(alpha_bits); + self + } + + /// Request the backend to be stereoscopic. + pub fn with_stereoscopy(mut self) -> WindowBuilder<'a> { + self.attribs.stereoscopy = true; self } @@ -199,26 +253,33 @@ impl<'a> WindowBuilder<'a> { /// out of memory, etc. pub fn build(mut self) -> Result<Window, CreationError> { // resizing the window to the dimensions of the monitor when fullscreen - if self.dimensions.is_none() && self.monitor.is_some() { - self.dimensions = Some(self.monitor.as_ref().unwrap().get_dimensions()) + if self.attribs.dimensions.is_none() && self.attribs.monitor.is_some() { + self.attribs.dimensions = Some(self.attribs.monitor.as_ref().unwrap().get_dimensions()) } // default dimensions - if self.dimensions.is_none() { - self.dimensions = Some((1024, 768)); + if self.attribs.dimensions.is_none() { + self.attribs.dimensions = Some((1024, 768)); } // building - winimpl::Window::new(self).map(|w| Window { window: w }) + winimpl::Window::new(self.attribs).map(|w| Window { window: w }) + } + + /// Builds the window. + /// + /// The context is build in a *strict* way. That means that if the backend couldn't give + /// you what you requested, an `Err` will be returned. + pub fn build_strict(mut self) -> Result<Window, CreationError> { + self.attribs.strict = true; + self.build() } } /// Object that allows you to build headless contexts. #[cfg(feature = "headless")] pub struct HeadlessRendererBuilder { - dimensions: (uint, uint), - gl_version: Option<(uint, uint)>, - gl_debug: bool, + attribs: BuilderAttribs<'static>, } #[cfg(feature = "headless")] @@ -226,9 +287,11 @@ impl HeadlessRendererBuilder { /// Initializes a new `HeadlessRendererBuilder` with default values. pub fn new(width: uint, height: uint) -> HeadlessRendererBuilder { HeadlessRendererBuilder { - dimensions: (width, height), - gl_version: None, - gl_debug: cfg!(ndebug), + attribs: BuilderAttribs { + headless: true, + dimensions: Some((width, height)), + .. BuilderAttribs::new() + }, } } @@ -237,7 +300,7 @@ impl HeadlessRendererBuilder { /// Version is a (major, minor) pair. For example to request OpenGL 3.3 /// you would pass `(3, 3)`. pub fn with_gl_version(mut self, version: (uint, uint)) -> HeadlessRendererBuilder { - self.gl_version = Some(version); + self.attribs.gl_version = Some(version); self } @@ -246,7 +309,7 @@ impl HeadlessRendererBuilder { /// The default value for this flag is `cfg!(ndebug)`, which means that it's enabled /// when you run `cargo build` and disabled when you run `cargo build --release`. pub fn with_gl_debug_flag(mut self, flag: bool) -> HeadlessRendererBuilder { - self.gl_debug = flag; + self.attribs.gl_debug = flag; self } @@ -255,7 +318,16 @@ impl HeadlessRendererBuilder { /// Error should be very rare and only occur in case of permission denied, incompatible system, /// out of memory, etc. pub fn build(self) -> Result<HeadlessContext, CreationError> { - winimpl::HeadlessContext::new(self).map(|w| HeadlessContext { context: w }) + winimpl::HeadlessContext::new(self.attribs).map(|w| HeadlessContext { context: w }) + } + + /// Builds the headless context. + /// + /// The context is build in a *strict* way. That means that if the backend couldn't give + /// you what you requested, an `Err` will be returned. + pub fn build_strict(mut self) -> Result<HeadlessContext, CreationError> { + self.attribs.strict = true; + self.build() } } |