// Copyright (C) Oscar Shrimpton 2019
// This program is free software: you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
// You should have received a copy of the GNU General Public License along
// with this program. If not, see .
//! Renders ./example.bsp
extern crate stockton_types;
extern crate stockton_levels;
extern crate stockton_render;
extern crate winit;
extern crate simple_logger;
extern crate image;
use image::load_from_memory;
use std::time::SystemTime;
use stockton_levels::prelude::*;
use stockton_levels::q3::Q3BSPFile;
use stockton_types::{World, Vector3};
use stockton_render::Renderer;
use winit::{
event::{Event, WindowEvent, ElementState},
event_loop::{ControlFlow, EventLoop},
window::WindowBuilder
};
const SPEED: f32 = 100.0;
#[derive(Debug)]
struct KeyState {
pub up: bool,
pub left: bool,
pub right: bool,
pub down: bool,
pub inwards: bool,
pub out: bool
}
impl KeyState {
pub fn new() -> KeyState {
KeyState {
up: false,
left: false,
right: false,
down: false,
inwards: false,
out: false,
}
}
pub fn as_vector(&self) -> Vector3 {
let mut vec = Vector3::new(0.0, 0.0, 0.0);
if self.up {
vec.y = 1.0;
} else if self.down {
vec.y = -1.0;
}
if self.right {
vec.x = 1.0;
} else if self.left {
vec.x = -1.0;
}
if self.inwards {
vec.z = 1.0;
} else if self.out {
vec.z = -1.0;
}
vec
}
}
fn main() {
simple_logger::init().unwrap();
// Load the world and renderer
let event_loop = EventLoop::new();
let window = WindowBuilder::new().build(&event_loop).unwrap();
let data = include_bytes!("../data/test.bsp").to_vec().into_boxed_slice();
let bsp: Result, stockton_levels::types::ParseError> = Q3BSPFile::parse_file(&data);
let bsp: Q3BSPFile = bsp.unwrap();
let bsp: Q3BSPFile = bsp.swizzle_to();
let world = World::new(bsp);
let mut renderer = Renderer::new(world, &window).unwrap();
{
renderer.context.add_texture(
load_from_memory(include_bytes!("../../render-quad/data/test1.png"))
.expect("Couldn't load test texture 1")
.into_rgba()).unwrap();
renderer.context.add_texture(
load_from_memory(include_bytes!("../../render-quad/data/test2.png"))
.expect("Couldn't load test texture 2")
.into_rgba()).unwrap();
}
let mut last_update = SystemTime::now();
let mut key_state = KeyState::new();
// Keep rendering the world
event_loop.run(move |event, _, flow| {
*flow = ControlFlow::Poll;
match event {
Event::WindowEvent {
event,
..
} => match event {
WindowEvent::CloseRequested => {
*flow = ControlFlow::Exit
},
WindowEvent::KeyboardInput {input, ..} => match input.scancode {
// Left
105 => key_state.left = input.state == ElementState::Pressed,
// Right
106 => key_state.right = input.state == ElementState::Pressed,
// Up (in)
103 => key_state.inwards = input.state == ElementState::Pressed,
// Down (out)
108 => key_state.out = input.state == ElementState::Pressed,
// Space (up)
57 => key_state.up = input.state == ElementState::Pressed,
// Ctrl (down)
29 => key_state.down = input.state == ElementState::Pressed,
_ => ()
}
_ => ()
},
Event::MainEventsCleared => {
window.request_redraw()
},
Event::RedrawRequested(_) => {
let delta = last_update.elapsed().unwrap().as_secs_f32();
last_update = SystemTime::now();
let delta_pos = key_state.as_vector() * delta * SPEED;
if delta_pos.x != 0.0 || delta_pos.y != 0.0 || delta_pos.z != 0.0 {
renderer.context.move_camera(delta_pos);
println!("camera is at {:?}", renderer.context.camera_pos());
}
renderer.render_frame().unwrap()
}
_ => ()
}
});
}