use glow::HasContext;
use wasm_bindgen::JsCast;
use winit::{application::ApplicationHandler, dpi::LogicalSize, event::WindowEvent, event_loop::ActiveEventLoop, platform::web::{WindowAttributesExtWebSys, WindowExtWebSys}, raw_window_handle::HasWindowHandle, window::{Window, WindowAttributes}};
pub mod init;
#[derive(Default)]
pub struct App {
window: Option<Window>,
program: glow::Program,
vertex_array: glow::VertexArray,
vertex_buffer: glow::Buffer,
gl: Option<glow::Context>,
}
const VERTICES: [f32; 6] = [
0.0, 1.0,
-1.0, -1.0,
1.0, -1.0,
];
impl ApplicationHandler for App {
fn resumed(&mut self, event_loop: &ActiveEventLoop) {
#[cfg(target_arch = "wasm32")]
let attributes = {
let document = web_sys::window().unwrap().document().unwrap();
let canvas = document.get_element_by_id("canvas").unwrap();
let canvas = canvas.dyn_into::<web_sys::HtmlCanvasElement>()
.map_err(|_| ()).unwrap();
Window::default_attributes()
.with_title("StarKingdoms.TK")
.with_canvas(Some(canvas))
};
#[cfg(not(target_arch = "wasm32"))]
let attributes = {
Window::default_attributes().with_title("StarKingdoms.TK");
};
self.window = Some(event_loop.create_window(attributes).unwrap());
let window = self.window.as_ref().unwrap();
#[cfg(target_arch = "wasm32")]
let context = window.canvas().unwrap().get_context("webgl2")
.unwrap().unwrap()
.dyn_into::<web_sys::WebGl2RenderingContext>()
.unwrap();
#[cfg(not(target_arch = "wasm32"))]
unsafe {
}
let (gl, shader_version) = (glow::Context::from_webgl2_context(context), "#version 300 es");
unsafe {
let vertex_shader = gl.create_shader(glow::VERTEX_SHADER).expect("Failed to create vertex shader");
let fragment_shader = gl.create_shader(glow::FRAGMENT_SHADER).expect("Failed to create fragment shader");
let vertex_source = include_str!("../shaders/vertex.glsl");
let fragment_source = include_str!("../shaders/fragment.glsl");
gl.shader_source(vertex_shader, &format!("{}\n{}", shader_version, vertex_source));
gl.compile_shader(vertex_shader);
if !gl.get_shader_compile_status(vertex_shader) {
tracing::error!("error in vertex shader: {}", gl.get_shader_info_log(vertex_shader));
}
gl.shader_source(fragment_shader, &format!("{}\n{}", shader_version, fragment_source));
gl.compile_shader(fragment_shader);
if !gl.get_shader_compile_status(fragment_shader) {
tracing::error!("error in fragment shader: {}", gl.get_shader_info_log(fragment_shader));
}
let program = gl.create_program().expect("Failed to create program");
gl.attach_shader(program, vertex_shader);
gl.attach_shader(program, fragment_shader);
gl.link_program(program);
gl.delete_shader(vertex_shader);
gl.delete_shader(fragment_shader);
gl.use_program(Some(program));
let vertex_array = gl.create_vertex_array().expect("Failed to create vertex array");
gl.bind_vertex_array(Some(vertex_array));
let vertex_buffer = gl.create_buffer().expect("Failed to create vertex buffer");
gl.bind_buffer(glow::ARRAY_BUFFER, Some(vertex_buffer));
gl.buffer_data_u8_slice(glow::ARRAY_BUFFER,
std::slice::from_raw_parts(VERTICES.as_ptr() as *const u8, 6*4),
glow::STATIC_DRAW);
gl.vertex_attrib_pointer_f32(0, 2, glow::FLOAT, false, 2*std::mem::size_of::<f32>() as i32, 0);
gl.enable_vertex_attrib_array(0);
gl.clear_color(1.0, 1.0, 1.0, 1.0);
self.program = program;
self.vertex_array = vertex_array;
self.vertex_buffer = vertex_buffer;
}
self.gl = Some(gl);
}
fn window_event(
&mut self,
event_loop: &ActiveEventLoop,
window_id: winit::window::WindowId,
event: winit::event::WindowEvent,
) {
match event {
WindowEvent::Resized(size) => {
}
WindowEvent::RedrawRequested => {
let window = self.window.as_ref().unwrap();
let gl = self.gl.as_ref().unwrap();
unsafe {
gl.clear(glow::COLOR_BUFFER_BIT);
gl.draw_arrays(glow::TRIANGLES, 0, 3);
}
window.request_redraw();
}
_ => {}
}
}
}