use crate::graphics::{DisplayMode, OpenGLWindowContract, WindowSettings};
use cgmath::*;
use log::info;
use wasm_bindgen::JsCast;
use winit::dpi::LogicalSize;
use winit::event_loop::EventLoop;
use winit::platform::web::WindowExtWebSys;
use winit::window::{Fullscreen, Window, WindowBuilder};
pub struct OpenGLWindow {
inner: Window,
}
impl OpenGLWindowContract for OpenGLWindow {
fn new(desc: &WindowSettings, event_loop: &EventLoop<()>) -> (OpenGLWindow, glow::Context) {
let mut builder = WindowBuilder::new().with_title(&desc.title);
builder = match desc.display_mode {
DisplayMode::Windowed {
width,
height,
..
} => builder.with_inner_size(LogicalSize::new(width, height)),
DisplayMode::WindowedFullscreen | DisplayMode::Fullscreen => {
builder.with_fullscreen(Some(Fullscreen::Borderless(None)))
}
};
let winit_window = builder.build(event_loop).expect("Window build");
let canvas = winit_window.canvas();
let webgl2_context = canvas
.get_context("webgl2") .expect("Get webgl2 context A") .expect("Get webgl2 context B") .dyn_into::<web_sys::WebGl2RenderingContext>() .expect("Get webgl2 context C"); let gl = glow::Context::from_webgl2_context(webgl2_context);
let window = web_sys::window().unwrap();
let document = window.document().unwrap();
let body = document.body().unwrap();
body.append_child(&canvas).expect("Append canvas to HTML body");
let window = OpenGLWindow {
inner: winit_window,
};
window.set_title(&desc.title);
window.set_display_mode(desc.display_mode);
info!("Created canvas.");
(window, gl)
}
fn scale_factor(&self) -> f32 {
self.inner.scale_factor() as f32
}
fn logical_size(&self) -> Vector2<f32> {
let size = self.inner.inner_size();
let scale_factor = self.inner.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.inner_size();
Vector2::new(size.width as f32, size.height as f32)
}
fn set_cursor_grab(&self, grab: bool) {
let _ = self.inner.set_cursor_grab(grab);
}
fn set_cursor_visible(&self, visible: bool) {
let _ = self.inner.set_cursor_visible(visible);
}
fn swap_buffers(&self) {
}
fn set_title(&self, title: &str) {
web_sys::window() .unwrap() .document() .unwrap() .set_title(title);
}
fn set_display_mode(&self, display_mode: DisplayMode) {
match display_mode {
DisplayMode::Windowed {
width,
height,
..
} => {
if let Some(_) = self.inner.fullscreen() {
self.inner.set_fullscreen(None);
}
self.inner.set_inner_size(LogicalSize::new(width, height));
}
DisplayMode::WindowedFullscreen | DisplayMode::Fullscreen => {
self.inner.set_fullscreen(Some(Fullscreen::Borderless(None)));
}
}
}
}