storm 0.11.0

A personal 2D game engine designed for performance
Documentation
use crate::graphics::{DisplayMode, OpenGLWindowContract, Vsync, WindowSettings};
use cgmath::*;
use glutin::ContextBuilder;
use log::info;
use winit::dpi::LogicalSize;
use winit::event_loop::EventLoop;
use winit::window::{Fullscreen, Window, WindowBuilder};

pub struct OpenGLWindow {
    inner: glutin::ContextWrapper<glutin::PossiblyCurrent, Window>,
}

impl OpenGLWindowContract for OpenGLWindow {
    fn new(desc: &WindowSettings, event_loop: &EventLoop<()>) -> (OpenGLWindow, glow::Context) {
        let mut window_builder = WindowBuilder::new().with_title(&desc.title);
        match desc.display_mode {
            DisplayMode::Windowed {
                width,
                height,
                resizable,
            } => {
                window_builder =
                    window_builder.with_resizable(resizable).with_inner_size(LogicalSize::new(width, height))
            }
            DisplayMode::WindowedFullscreen | DisplayMode::Fullscreen => {
                let fullscreen = Fullscreen::Borderless(event_loop.primary_monitor());
                window_builder = window_builder.with_fullscreen(Some(fullscreen));
            }
        }
        let mut context_builder = ContextBuilder::new();
        match desc.vsync {
            Vsync::Disabled => {
                context_builder = context_builder.with_vsync(false);
            }
            Vsync::Enabled => {
                context_builder = context_builder.with_vsync(true);
            }
        }
        let window_context = context_builder.build_windowed(window_builder, &event_loop).unwrap();
        let window_context = unsafe { window_context.make_current() }.unwrap();
        let gl = unsafe {
            glow::Context::from_loader_function(|s| window_context.get_proc_address(s) as *const _)
        };
        info!("Created window.");
        (
            OpenGLWindow {
                inner: window_context,
            },
            gl,
        )
    }

    fn scale_factor(&self) -> f32 {
        self.inner.window().scale_factor() as f32
    }

    fn logical_size(&self) -> Vector2<f32> {
        let size = self.inner.window().inner_size();
        let scale_factor = self.inner.window().scale_factor() as f32;
        let size = Vector2::new(size.width as f32, size.height as f32);
        size / scale_factor
    }

    fn physical_size(&self) -> Vector2<f32> {
        let size = self.inner.window().inner_size();
        Vector2::new(size.width as f32, size.height as f32)
    }

    fn set_cursor_grab(&self, grab: bool) {
        let _ = self.inner.window().set_cursor_grab(grab);
    }

    fn set_cursor_visible(&self, visible: bool) {
        let _ = self.inner.window().set_cursor_visible(visible);
    }

    fn swap_buffers(&self) {
        self.inner.swap_buffers().unwrap();
    }

    fn set_title(&self, title: &str) {
        self.inner.window().set_title(title);
    }

    fn set_display_mode(&self, display_mode: DisplayMode) {
        match display_mode {
            DisplayMode::Windowed {
                width,
                height,
                resizable,
            } => {
                self.inner.window().set_inner_size(LogicalSize::new(width, height));
                self.inner.window().set_resizable(resizable);
                self.inner.window().set_fullscreen(None);
            }
            DisplayMode::WindowedFullscreen | DisplayMode::Fullscreen => {
                let fullscreen = Fullscreen::Borderless(self.inner.window().current_monitor());
                self.inner.window().set_fullscreen(Some(fullscreen));
            }
        }
    }
}