nsys-gl-utils 0.11.9

OpenGL and graphics utilities
Documentation
//! Glium initialization functions

use std;

use glium::{self, glutin};
use winit;

/// Creates a `winit::event_loop::EventLoop`, `winit::window::Window`, and
/// associated `glium::Display` with an OpenGL 3.3 core profile
pub fn glium_init_gl33core (window_title : &str) -> (
  winit::event_loop::EventLoop <()>,
  winit::window::Window,
  glutin::config::Config,
  glium::Display <glutin::surface::WindowSurface>
) {
  let (event_loop, window, gl_config) = glutin_window (window_title);
  let display = glium_display_gl33core (&window, &gl_config);
  (event_loop, window, gl_config, display)
}

/// Creates a `winit::event_loop::EventLoop`, `winit::window::Window`, and a
/// `glutin::config::Config` that can be moved or shared to another thread and
/// used to create a `glium::Display` with `glium_display`
pub fn glutin_window (window_title : &str) -> (
  winit::event_loop::EventLoop <()>,
  winit::window::Window,
  glutin::config::Config
) {
  let event_loop = winit::event_loop::EventLoop::builder()
    .build().unwrap();
  let window_attributes = winit::window::Window::default_attributes()
    .with_title      (window_title)
    .with_inner_size (winit::dpi::PhysicalSize::new (320, 240));
  let config_template_builder = glutin::config::ConfigTemplateBuilder::new()
    .with_api (glutin::config::Api::OPENGL);
  let (window, gl_config) = glutin_winit::DisplayBuilder::new()
    .with_window_attributes (Some (window_attributes))
    .build (&event_loop, config_template_builder, |mut configs| configs.next().unwrap())
    .unwrap();
  (event_loop, window.unwrap(), gl_config)
}

/// Create glium Display from given window and OpenGL configuration
pub fn glium_display (
  window     : &winit::window::Window,
  gl_config  : &glutin::config::Config,
  gl_version : glutin::context::Version,
  gl_profile : glutin::context::GlProfile
) -> glium::Display <glutin::surface::WindowSurface> {
  use glutin::context::NotCurrentGlContext;
  use glutin::display::{GetGlDisplay, GlDisplay};
  use glutin::surface::GlSurface;
  let (width, height) = window.inner_size().into();
  #[cfg(target_os = "windows")]
  let raw_window_handle = unsafe {
    use winit::platform::windows::WindowExtWindows;
    window.window_handle_any_thread()
  }.unwrap().into();
  #[cfg(not(target_os = "windows"))]
  let raw_window_handle = {
    use winit::raw_window_handle::HasWindowHandle;
    window.window_handle().unwrap().into()
  };
  let surface_attrs = glutin::surface::SurfaceAttributesBuilder::<
    glutin::surface::WindowSurface
  >::new().build (
    raw_window_handle,
    std::num::NonZeroU32::new (width).unwrap(),
    std::num::NonZeroU32::new (height).unwrap(),
  );
  let surface = unsafe {
    gl_config.display().create_window_surface (gl_config, &surface_attrs)
      .unwrap()
  };
  let context_attributes = glutin::context::ContextAttributesBuilder::new()
    .with_context_api (glutin::context::ContextApi::OpenGl (Some (gl_version)))
    .with_profile (gl_profile)
    .build (Some (raw_window_handle));
  let not_current_context = unsafe {
    gl_config.display().create_context (gl_config, &context_attributes)
      .expect("failed to create context")
  };
  let possibly_current_context = not_current_context.make_current (&surface)
    .unwrap();
  // set vsync
  surface.set_swap_interval (
    &possibly_current_context,
    glutin::surface::SwapInterval::Wait (std::num::NonZeroU32::new (1).unwrap())
  ).unwrap();
  glium::Display::from_context_surface (possibly_current_context, surface)
    .unwrap()
}

/// Create glium Display from given window and OpenGL configuration
pub fn glium_display_gl33core (
  window     : &winit::window::Window,
  gl_config  : &glutin::config::Config
) -> glium::Display <glutin::surface::WindowSurface> {
  glium_display (
    window, gl_config, glutin::context::Version { major: 3, minor: 3 },
    glutin::context::GlProfile::Core
  )
}