From 7a292860536d439bc7a8508fc6010c2c0dffef3a Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Wed, 2 Jan 2019 21:25:01 +0000 Subject: [PATCH] Started adding voxygen and windowing code --- Cargo.toml | 1 + voxygen/.gitignore | 3 ++ voxygen/Cargo.toml | 14 +++++++ voxygen/src/main.rs | 50 ++++++++++++++++++++++ voxygen/src/menu/mod.rs | 1 + voxygen/src/menu/title.rs | 30 ++++++++++++++ voxygen/src/window.rs | 87 +++++++++++++++++++++++++++++++++++++++ 7 files changed, 186 insertions(+) create mode 100644 voxygen/.gitignore create mode 100644 voxygen/Cargo.toml create mode 100644 voxygen/src/main.rs create mode 100644 voxygen/src/menu/mod.rs create mode 100644 voxygen/src/menu/title.rs create mode 100644 voxygen/src/window.rs diff --git a/Cargo.toml b/Cargo.toml index ddf12b4e37..70930e72e1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,6 +3,7 @@ members = [ "common", "client", "server", + "voxygen", ] [profile.dev] diff --git a/voxygen/.gitignore b/voxygen/.gitignore new file mode 100644 index 0000000000..693699042b --- /dev/null +++ b/voxygen/.gitignore @@ -0,0 +1,3 @@ +/target +**/*.rs.bk +Cargo.lock diff --git a/voxygen/Cargo.toml b/voxygen/Cargo.toml new file mode 100644 index 0000000000..feb943fe65 --- /dev/null +++ b/voxygen/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "voxygen" +version = "0.1.0" +authors = ["Joshua Barretto "] +edition = "2018" + +[dependencies] +common = { path = "../common" } + +# Graphics +gfx = "0.17.1" +gfx_device_gl = "0.15.0" +gfx_window_glutin = "0.25.0" +glutin = "0.17.0" diff --git a/voxygen/src/main.rs b/voxygen/src/main.rs new file mode 100644 index 0000000000..eca06ce4d1 --- /dev/null +++ b/voxygen/src/main.rs @@ -0,0 +1,50 @@ +mod menu; +mod window; + +// Standard +use std::mem; + +// Crate +use crate::{ + menu::title::TitleState, + window::Window, +}; + +// A type used to store state that is shared between all play states +pub struct GlobalState { + window: Window, +} + +// States can either close (and revert to a previous state), push a new state on top of themselves, +// or switch to a totally different state +pub enum StateResult { + Close, + Push(Box), + Switch(Box), +} + +pub trait PlayState { + fn play(&mut self, global_state: &mut GlobalState) -> StateResult; +} + +fn main() { + let mut states: Vec> = vec![Box::new(TitleState::new())]; + + let mut global_state = GlobalState { + window: Window::new(), + }; + + loop { + // Implement state transfer logic + match states.last_mut().map(|last| last.play(&mut global_state)) { + Some(StateResult::Close) => { states.pop(); }, + Some(StateResult::Push(new_state)) => { states.push(new_state); }, + Some(StateResult::Switch(mut new_state)) => if let Some(old_state) = states.last_mut() { + mem::swap(old_state, &mut new_state); + } else { + break; + }, + None => break, + } + } +} diff --git a/voxygen/src/menu/mod.rs b/voxygen/src/menu/mod.rs new file mode 100644 index 0000000000..5cec26ea76 --- /dev/null +++ b/voxygen/src/menu/mod.rs @@ -0,0 +1 @@ +pub mod title; diff --git a/voxygen/src/menu/title.rs b/voxygen/src/menu/title.rs new file mode 100644 index 0000000000..ccb2354ec1 --- /dev/null +++ b/voxygen/src/menu/title.rs @@ -0,0 +1,30 @@ +// Crate +use crate::{ + PlayState, + StateResult, + GlobalState, + window::Event, +}; + +pub struct TitleState; + +impl TitleState { + pub fn new() -> Self { + Self + } +} + +impl PlayState for TitleState { + fn play(&mut self, global_state: &mut GlobalState) -> StateResult { + let mut running = true; + while running { + global_state.window.poll_events(|event| match event { + Event::Close => running = false, + }); + + global_state.window.swap_buffers(); + } + + StateResult::Close + } +} diff --git a/voxygen/src/window.rs b/voxygen/src/window.rs new file mode 100644 index 0000000000..17ba361bb7 --- /dev/null +++ b/voxygen/src/window.rs @@ -0,0 +1,87 @@ +// External +use gfx::handle::{RenderTargetView, DepthStencilView}; +use gfx_device_gl::{Device, Resources, Factory}; +use gfx_window_glutin; +use glutin::{ + self, + Api::OpenGl, + dpi::LogicalSize, + ContextBuilder, + EventsLoop, + GlContext, + GlRequest, + GlWindow, + WindowBuilder, +}; + +type TgtColorView = RenderTargetView; +type TgtDepthView = DepthStencilView; + +pub struct RenderCtx { + device: Device, + factory: Factory, + tgt_color_view: TgtColorView, + tgt_depth_view: TgtDepthView, +} + +pub struct Window { + events_loop: EventsLoop, + gl_window: GlWindow, + render_ctx: RenderCtx, +} + + +impl Window { + pub fn new() -> Window { + let events_loop = EventsLoop::new(); + + let ( + gl_window, + device, + factory, + tgt_color_view, + tgt_depth_view, + ) = gfx_window_glutin::init( + WindowBuilder::new() + .with_title("Veloren (Voxygen)") + .with_dimensions(LogicalSize::new(800.0, 500.0)) + .with_maximized(false), + ContextBuilder::new() + .with_gl(GlRequest::Specific(OpenGl, (3, 2))) + .with_multisampling(2) + .with_vsync(true), + &events_loop, + ); + + Self { + events_loop, + gl_window, + render_ctx: RenderCtx { + device, + factory, + tgt_color_view, + tgt_depth_view, + }, + } + } + + pub fn poll_events(&mut self, mut f: F) { + self.events_loop.poll_events(|event| match event { + glutin::Event::WindowEvent { event, .. } => match event { + glutin::WindowEvent::CloseRequested => f(Event::Close), + _ => {}, + }, + _ => {}, + }); + } + + pub fn swap_buffers(&self) { + self.gl_window + .swap_buffers() + .expect("Failed to swap window buffers"); + } +} + +pub enum Event { + Close, +}