mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Added camera panning and cursor trapping
This commit is contained in:
parent
45d5a0a396
commit
979f47420d
@ -21,12 +21,14 @@ use crate::{
|
||||
window::Window,
|
||||
};
|
||||
|
||||
// A type used to store state that is shared between all play states
|
||||
/// A type used to store state that is shared between all play states
|
||||
pub struct GlobalState {
|
||||
window: Window,
|
||||
}
|
||||
|
||||
impl GlobalState {
|
||||
/// Called after a change in play state has occured (usually used to reverse any temporary
|
||||
/// effects a state may have made).
|
||||
pub fn on_play_state_changed(&mut self) {
|
||||
self.window.untrap_cursor();
|
||||
}
|
||||
|
@ -31,14 +31,23 @@ use gfx_device_gl as gfx_backend;
|
||||
// Library
|
||||
use gfx;
|
||||
|
||||
/// Used to represent one of many possible errors that may be omitted by the rendering code
|
||||
/// Used to represent one of many possible errors that may be omitted by the rendering subsystem
|
||||
#[derive(Debug)]
|
||||
pub enum RenderError {
|
||||
PipelineError(gfx::PipelineStateError<String>),
|
||||
UpdateError(gfx::UpdateError<usize>),
|
||||
}
|
||||
|
||||
/// Used to represent a specific rendering configuration
|
||||
/// Used to represent a specific rendering configuration.
|
||||
///
|
||||
/// Note that pipelines are tied to the
|
||||
/// rendering backend, and as such it is necessary to modify the rendering subsystem when adding
|
||||
/// new pipelines - custom pipelines are not currently an objective of the rendering subsystem.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// - `SkyboxPipeline`
|
||||
/// - `CharacterPipeline`
|
||||
pub trait Pipeline {
|
||||
type Vertex:
|
||||
Clone +
|
||||
|
@ -66,10 +66,10 @@ pub fn create_mesh() -> Mesh<SkyboxPipeline> {
|
||||
// +x
|
||||
#[rustfmt::skip]
|
||||
mesh.push_quad(Quad::new(
|
||||
Vertex { pos: [ 1.0, -1.0, -1.0] },
|
||||
Vertex { pos: [ 1.0, -1.0, 1.0] },
|
||||
Vertex { pos: [ 1.0, 1.0, 1.0] },
|
||||
Vertex { pos: [ 1.0, 1.0, -1.0] },
|
||||
Vertex { pos: [ 1.0, -1.0, 1.0] },
|
||||
Vertex { pos: [ 1.0, -1.0, -1.0] },
|
||||
));
|
||||
// -y
|
||||
#[rustfmt::skip]
|
||||
@ -82,10 +82,10 @@ pub fn create_mesh() -> Mesh<SkyboxPipeline> {
|
||||
// +y
|
||||
#[rustfmt::skip]
|
||||
mesh.push_quad(Quad::new(
|
||||
Vertex { pos: [ 1.0, 1.0, -1.0] },
|
||||
Vertex { pos: [ 1.0, 1.0, 1.0] },
|
||||
Vertex { pos: [-1.0, 1.0, 1.0] },
|
||||
Vertex { pos: [-1.0, 1.0, -1.0] },
|
||||
Vertex { pos: [ 1.0, 1.0, 1.0] },
|
||||
Vertex { pos: [ 1.0, 1.0, -1.0] },
|
||||
));
|
||||
// -z
|
||||
#[rustfmt::skip]
|
||||
@ -98,10 +98,10 @@ pub fn create_mesh() -> Mesh<SkyboxPipeline> {
|
||||
// +z
|
||||
#[rustfmt::skip]
|
||||
mesh.push_quad(Quad::new(
|
||||
Vertex { pos: [-1.0, -1.0, 1.0] },
|
||||
Vertex { pos: [-1.0, 1.0, 1.0] },
|
||||
Vertex { pos: [ 1.0, 1.0, 1.0] },
|
||||
Vertex { pos: [ 1.0, -1.0, 1.0] },
|
||||
Vertex { pos: [-1.0, 1.0, 1.0] },
|
||||
Vertex { pos: [-1.0, -1.0, 1.0] },
|
||||
));
|
||||
|
||||
mesh
|
||||
|
@ -32,7 +32,7 @@ pub type TgtDepthView = gfx::handle::DepthStencilView<gfx_backend::Resources, Tg
|
||||
|
||||
/// A type that encapsulates rendering state. `Renderer` is central to Voxygen's rendering
|
||||
/// subsystem and contains any state necessary to interact with the GPU, along with pipeline state
|
||||
/// objects (PSOs) needed to renderer different kinds of model to the screen.
|
||||
/// objects (PSOs) needed to renderer different kinds of models to the screen.
|
||||
pub struct Renderer {
|
||||
device: gfx_backend::Device,
|
||||
encoder: gfx::Encoder<gfx_backend::Resources, gfx_backend::CommandBuffer>,
|
||||
@ -127,7 +127,7 @@ impl Renderer {
|
||||
))
|
||||
}
|
||||
|
||||
/// Queue the rendering of the provided skybox model in the upcoming frame
|
||||
/// Queue the rendering of the provided skybox model in the upcoming frame.
|
||||
pub fn render_skybox(
|
||||
&mut self,
|
||||
model: &Model<skybox::SkyboxPipeline>,
|
||||
@ -152,7 +152,7 @@ struct GfxPipeline<P: gfx::pso::PipelineInit> {
|
||||
pso: gfx::pso::PipelineState<gfx_backend::Resources, P::Meta>,
|
||||
}
|
||||
|
||||
/// Create a new pipeline from the provided vertex shader and fragment shader
|
||||
/// Create a new pipeline from the provided vertex shader and fragment shader.
|
||||
fn create_pipeline<'a, P: gfx::pso::PipelineInit>(
|
||||
factory: &mut gfx_backend::Factory,
|
||||
pipe: P,
|
||||
|
@ -50,6 +50,15 @@ impl Camera {
|
||||
(view_mat, proj_mat, cam_pos)
|
||||
}
|
||||
|
||||
/// Rotate the camera about its focus by the given delta, limiting the input accordingly.
|
||||
pub fn rotate_by(&mut self, delta: Vec3<f32>) {
|
||||
self.ori += delta;
|
||||
// Clamp camera pitch to the vertical limits
|
||||
self.ori.y = self.ori.y
|
||||
.min(PI / 2.0)
|
||||
.max(-PI / 2.0);
|
||||
}
|
||||
|
||||
/// Get the focus position of the camera.
|
||||
pub fn get_focus_pos(&self) -> Vec3<f32> { self.focus }
|
||||
/// Set the focus position of the camera.
|
||||
|
@ -1,14 +1,20 @@
|
||||
pub mod camera;
|
||||
|
||||
// Library
|
||||
use vek::*;
|
||||
|
||||
// Crate
|
||||
use crate::render::{
|
||||
Consts,
|
||||
Globals,
|
||||
Model,
|
||||
Renderer,
|
||||
SkyboxPipeline,
|
||||
SkyboxLocals,
|
||||
create_skybox_mesh,
|
||||
use crate::{
|
||||
render::{
|
||||
Consts,
|
||||
Globals,
|
||||
Model,
|
||||
Renderer,
|
||||
SkyboxPipeline,
|
||||
SkyboxLocals,
|
||||
create_skybox_mesh,
|
||||
},
|
||||
window::Event,
|
||||
};
|
||||
|
||||
// Local
|
||||
@ -19,6 +25,9 @@ struct Skybox {
|
||||
locals: Consts<SkyboxLocals>,
|
||||
}
|
||||
|
||||
// TODO: Don't hard-code this
|
||||
const CURSOR_PAN_SCALE: f32 = 0.005;
|
||||
|
||||
pub struct Scene {
|
||||
camera: Camera,
|
||||
globals: Consts<Globals>,
|
||||
@ -44,6 +53,20 @@ impl Scene {
|
||||
}
|
||||
}
|
||||
|
||||
/// Handle an incoming user input event (i.e: cursor moved, key pressed, window closed, etc.).
|
||||
pub fn handle_input_event(&mut self, event: Event) -> bool {
|
||||
match event {
|
||||
// Panning the cursor makes the camera rotate
|
||||
Event::CursorPan(delta) => {
|
||||
self.camera.rotate_by(Vec3::from(delta) * CURSOR_PAN_SCALE);
|
||||
true
|
||||
},
|
||||
// All other events are unhandled
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Maintain and update GPU data such as constant buffers, models, etc.
|
||||
pub fn maintain_gpu_data(&mut self, renderer: &mut Renderer) {
|
||||
// Compute camera matrices
|
||||
let (view_mat, proj_mat, cam_pos) = self.camera.compute_dependents();
|
||||
|
@ -38,13 +38,14 @@ impl PlayState for SessionState {
|
||||
loop {
|
||||
// Handle window events
|
||||
for event in global_state.window.fetch_events() {
|
||||
match event {
|
||||
let _handled = match event {
|
||||
Event::Close => return PlayStateResult::Shutdown,
|
||||
// When 'q' is pressed, exit the session
|
||||
Event::Char('q') => return PlayStateResult::Pop,
|
||||
// Ignore all other events
|
||||
_ => {},
|
||||
}
|
||||
// Pass all other events to the scene
|
||||
event => self.scene.handle_input_event(event),
|
||||
};
|
||||
// TODO: Do something if the event wasn't handled?
|
||||
}
|
||||
|
||||
// Maintain scene GPU data
|
||||
|
@ -69,6 +69,11 @@ impl Window {
|
||||
glutin::WindowEvent::ReceivedCharacter(c) => events.push(Event::Char(c)),
|
||||
_ => {},
|
||||
},
|
||||
glutin::Event::DeviceEvent { event, .. } => match event {
|
||||
glutin::DeviceEvent::MouseMotion { delta: (dx, dy), .. } =>
|
||||
events.push(Event::CursorPan(Vec2::new(dx as f32, dy as f32))),
|
||||
_ => {},
|
||||
},
|
||||
_ => {},
|
||||
});
|
||||
events
|
||||
|
Loading…
Reference in New Issue
Block a user