#[deny(missing_docs)]
extern crate gfx_core as core;
extern crate gfx_device_gl as device_gl;
extern crate glutin;
#[cfg(feature = "headless")]
pub use headless::{init_headless, init_headless_raw};
use core::{format, handle, texture};
use core::memory::Typed;
use device_gl::Resources as R;
use glutin::{NotCurrent, PossiblyCurrent, CreationError};
#[cfg(feature = "headless")]
mod headless;
pub fn init<Cf, Df>(window: glutin::WindowBuilder,
context: glutin::ContextBuilder<NotCurrent>,
events_loop: &glutin::EventsLoop) ->
Result<(glutin::WindowedContext<PossiblyCurrent>, device_gl::Device, device_gl::Factory,
handle::RenderTargetView<R, Cf>, handle::DepthStencilView<R, Df>), CreationError>
where
Cf: format::RenderFormat,
Df: format::DepthFormat,
{
let (window, device, factory, color_view, ds_view) = init_raw(
window,
context,
events_loop,
Cf::get_format(),
Df::get_format())?;
Ok((window, device, factory, Typed::new(color_view), Typed::new(ds_view)))
}
pub fn init_existing<Cf, Df>(window: glutin::WindowedContext<NotCurrent>) ->
(glutin::WindowedContext<PossiblyCurrent>, device_gl::Device, device_gl::Factory,
handle::RenderTargetView<R, Cf>, handle::DepthStencilView<R, Df>)
where
Cf: format::RenderFormat,
Df: format::DepthFormat,
{
let (window, device, factory, color_view, ds_view) = init_existing_raw(window, Cf::get_format(), Df::get_format());
(window, device, factory, Typed::new(color_view), Typed::new(ds_view))
}
fn get_window_dimensions(ctx: &glutin::WindowedContext<PossiblyCurrent>) -> texture::Dimensions {
let window = ctx.window();
let (width, height) = {
let size = window.get_inner_size().unwrap().to_physical(window.get_hidpi_factor());
(size.width as _, size.height as _)
};
let aa = ctx
.get_pixel_format().multisampling
.unwrap_or(0) as texture::NumSamples;
(width, height, 1, aa.into())
}
pub fn init_raw(window: glutin::WindowBuilder,
context: glutin::ContextBuilder<NotCurrent>,
events_loop: &glutin::EventsLoop,
color_format: format::Format,
ds_format: format::Format) ->
Result<(glutin::WindowedContext<PossiblyCurrent>, device_gl::Device, device_gl::Factory,
handle::RawRenderTargetView<R>, handle::RawDepthStencilView<R>), CreationError>
{
let window = {
let color_total_bits = color_format.0.get_total_bits();
let alpha_bits = color_format.0.get_alpha_stencil_bits();
let depth_total_bits = ds_format.0.get_total_bits();
let stencil_bits = ds_format.0.get_alpha_stencil_bits();
context
.with_depth_buffer(depth_total_bits - stencil_bits)
.with_stencil_buffer(stencil_bits)
.with_pixel_format(color_total_bits - alpha_bits, alpha_bits)
.with_srgb(color_format.1 == format::ChannelType::Srgb)
.build_windowed(window, events_loop)?
};
let (window, device, factory, color_view, ds_view) =
init_existing_raw(window, color_format, ds_format);
Ok((window, device, factory, color_view, ds_view))
}
pub fn init_existing_raw(
window: glutin::WindowedContext<NotCurrent>,
color_format: format::Format, ds_format: format::Format,
) -> (
glutin::WindowedContext<PossiblyCurrent>,
device_gl::Device,
device_gl::Factory,
handle::RawRenderTargetView<R>,
handle::RawDepthStencilView<R>,
)
{
let window = unsafe { window.make_current().unwrap() };
let (device, factory) = device_gl::create(|s|
window.get_proc_address(s) as *const std::os::raw::c_void);
let dim = get_window_dimensions(&window);
let (color_view, ds_view) = device_gl::create_main_targets_raw(dim, color_format.0, ds_format.0);
(window, device, factory, color_view, ds_view)
}
pub fn update_views<Cf, Df>(window: &glutin::WindowedContext<PossiblyCurrent>, color_view: &mut handle::RenderTargetView<R, Cf>,
ds_view: &mut handle::DepthStencilView<R, Df>)
where
Cf: format::RenderFormat,
Df: format::DepthFormat,
{
let dim = color_view.get_dimensions();
assert_eq!(dim, ds_view.get_dimensions());
if let Some((cv, dv)) = update_views_raw(window, dim, Cf::get_format(), Df::get_format()) {
*color_view = Typed::new(cv);
*ds_view = Typed::new(dv);
}
}
pub fn update_views_raw(window: &glutin::WindowedContext<PossiblyCurrent>, old_dimensions: texture::Dimensions,
color_format: format::Format, ds_format: format::Format)
-> Option<(handle::RawRenderTargetView<R>, handle::RawDepthStencilView<R>)>
{
let dim = get_window_dimensions(window);
if dim != old_dimensions {
Some(device_gl::create_main_targets_raw(dim, color_format.0, ds_format.0))
}else {
None
}
}
pub fn new_views<Cf, Df>(window: &glutin::WindowedContext<PossiblyCurrent>)
-> (handle::RenderTargetView<R, Cf>, handle::DepthStencilView<R, Df>) where
Cf: format::RenderFormat,
Df: format::DepthFormat,
{
let dim = get_window_dimensions(window);
let (color_view_raw, depth_view_raw) =
device_gl::create_main_targets_raw(dim, Cf::get_format().0, Df::get_format().0);
(Typed::new(color_view_raw), Typed::new(depth_view_raw))
}