Get device orientation changes partially working

This commit is contained in:
Patrick Walton 2019-03-14 19:13:27 -07:00
parent f02e75edaf
commit e212a839b4
6 changed files with 136 additions and 104 deletions

View File

@ -7,11 +7,15 @@ import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10; import javax.microedition.khronos.opengles.GL10;
public class PathfinderDemoRenderer extends Object implements GLSurfaceView.Renderer { public class PathfinderDemoRenderer extends Object implements GLSurfaceView.Renderer {
private AssetManager m_assetManager; private AssetManager mAssetManager;
private boolean mInitialized;
private static native void init(PathfinderDemoResourceLoader resourceLoader); private static native void init(PathfinderDemoResourceLoader resourceLoader,
int width,
int height);
private static native void runOnce(); private static native void runOnce();
public static native void pushWindowResizedEvent(int width, int height);
public static native void pushMouseDownEvent(int x, int y); public static native void pushMouseDownEvent(int x, int y);
public static native void pushMouseDraggedEvent(int x, int y); public static native void pushMouseDraggedEvent(int x, int y);
public static native void pushLookEvent(float pitch, float yaw); public static native void pushLookEvent(float pitch, float yaw);
@ -24,17 +28,22 @@ public class PathfinderDemoRenderer extends Object implements GLSurfaceView.Rend
PathfinderDemoRenderer(AssetManager assetManager) { PathfinderDemoRenderer(AssetManager assetManager) {
super(); super();
m_assetManager = assetManager; mAssetManager = assetManager;
mInitialized = false;
} }
@Override @Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) { public void onSurfaceCreated(GL10 gl, EGLConfig config) {
init(new PathfinderDemoResourceLoader(m_assetManager));
} }
@Override @Override
public void onSurfaceChanged(GL10 gl, int width, int height) { public void onSurfaceChanged(GL10 gl, int width, int height) {
if (!mInitialized) {
init(new PathfinderDemoResourceLoader(mAssetManager), width, height);
mInitialized = true;
} else {
pushWindowResizedEvent(width, height);
}
} }
@Override @Override

View File

@ -14,7 +14,7 @@ extern crate lazy_static;
use jni::{JNIEnv, JavaVM}; use jni::{JNIEnv, JavaVM};
use jni::objects::{GlobalRef, JByteBuffer, JClass, JObject, JValue}; use jni::objects::{GlobalRef, JByteBuffer, JClass, JObject, JValue};
use pathfinder_demo::DemoApp; use pathfinder_demo::DemoApp;
use pathfinder_demo::window::{Event, Keycode, Window}; use pathfinder_demo::window::{Event, Window, WindowSize};
use pathfinder_geometry::basic::point::Point2DI32; use pathfinder_geometry::basic::point::Point2DI32;
use pathfinder_gl::GLVersion; use pathfinder_gl::GLVersion;
use pathfinder_gpu::resources::ResourceLoader; use pathfinder_gpu::resources::ResourceLoader;
@ -40,11 +40,19 @@ static RESOURCE_LOADER: AndroidResourceLoader = AndroidResourceLoader;
pub unsafe extern "system" fn pub unsafe extern "system" fn
Java_graphics_pathfinder_pathfinderdemo_PathfinderDemoRenderer_init(env: JNIEnv, Java_graphics_pathfinder_pathfinderdemo_PathfinderDemoRenderer_init(env: JNIEnv,
class: JClass, class: JClass,
loader: JObject) { loader: JObject,
width: i32,
height: i32) {
let logical_size = Point2DI32::new(width, height);
let window_size = WindowSize { logical_size, backing_scale_factor: 1.0 };
JAVA_RESOURCE_LOADER.with(|java_resource_loader| { JAVA_RESOURCE_LOADER.with(|java_resource_loader| {
*java_resource_loader.borrow_mut() = Some(JavaResourceLoader::new(env, loader)) *java_resource_loader.borrow_mut() = Some(JavaResourceLoader::new(env, loader));
});
DEMO_APP.with(|demo_app| {
gl::load_with(|name| egl::get_proc_address(name) as *const c_void);
*demo_app.borrow_mut() = Some(DemoApp::new(WindowImpl, window_size));
}); });
DEMO_APP.with(|demo_app| *demo_app.borrow_mut() = Some(DemoApp::<WindowImpl>::new()));
} }
#[no_mangle] #[no_mangle]
@ -59,6 +67,19 @@ pub unsafe extern "system" fn
}); });
} }
#[no_mangle]
pub unsafe extern "system" fn
Java_graphics_pathfinder_pathfinderdemo_PathfinderDemoRenderer_pushWindowResizedEvent(
env: JNIEnv,
class: JClass,
width: i32,
height: i32) {
EVENT_QUEUE.lock().unwrap().push(Event::WindowResized(WindowSize {
logical_size: Point2DI32::new(width, height),
backing_scale_factor: 1.0,
}))
}
#[no_mangle] #[no_mangle]
pub unsafe extern "system" fn pub unsafe extern "system" fn
Java_graphics_pathfinder_pathfinderdemo_PathfinderDemoRenderer_pushMouseDownEvent( Java_graphics_pathfinder_pathfinderdemo_PathfinderDemoRenderer_pushMouseDownEvent(
@ -92,23 +113,10 @@ pub unsafe extern "system" fn
struct WindowImpl; struct WindowImpl;
impl Window for WindowImpl { impl Window for WindowImpl {
fn new(default_framebuffer_size: Point2DI32) -> WindowImpl {
gl::load_with(|name| egl::get_proc_address(name) as *const c_void);
WindowImpl
}
fn gl_version(&self) -> GLVersion { fn gl_version(&self) -> GLVersion {
GLVersion::GLES3 GLVersion::GLES3
} }
fn size(&self) -> Point2DI32 {
Point2DI32::new(1920, 1080)
}
fn drawable_size(&self) -> Point2DI32 {
Point2DI32::new(1920, 1080)
}
fn mouse_position(&self) -> Point2DI32 { fn mouse_position(&self) -> Point2DI32 {
Point2DI32::new(0, 0) Point2DI32::new(0, 0)
} }

View File

@ -12,7 +12,7 @@
use crate::device::{GroundLineVertexArray, GroundProgram, GroundSolidVertexArray}; use crate::device::{GroundLineVertexArray, GroundProgram, GroundSolidVertexArray};
use crate::ui::{DemoUI, UIAction}; use crate::ui::{DemoUI, UIAction};
use crate::window::{Event, Keycode, Window}; use crate::window::{Event, Keycode, Window, WindowSize};
use clap::{App, Arg}; use clap::{App, Arg};
use image::ColorType; use image::ColorType;
use jemallocator; use jemallocator;
@ -53,9 +53,6 @@ static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;
static DEFAULT_SVG_VIRTUAL_PATH: &'static str = "svg/Ghostscript_Tiger.svg"; static DEFAULT_SVG_VIRTUAL_PATH: &'static str = "svg/Ghostscript_Tiger.svg";
const MAIN_FRAMEBUFFER_WIDTH: u32 = 1067;
const MAIN_FRAMEBUFFER_HEIGHT: u32 = 800;
const MOUSELOOK_ROTATION_SPEED: f32 = 0.007; const MOUSELOOK_ROTATION_SPEED: f32 = 0.007;
const CAMERA_VELOCITY: f32 = 0.02; const CAMERA_VELOCITY: f32 = 0.02;
@ -87,7 +84,7 @@ pub struct DemoApp<W> where W: Window {
pub window: W, pub window: W,
pub should_exit: bool, pub should_exit: bool,
scale_factor: f32, window_size: WindowSize,
scene_view_box: RectF32, scene_view_box: RectF32,
scene_is_monochrome: bool, scene_is_monochrome: bool,
@ -111,18 +108,14 @@ pub struct DemoApp<W> where W: Window {
} }
impl<W> DemoApp<W> where W: Window { impl<W> DemoApp<W> where W: Window {
pub fn new() -> DemoApp<W> { pub fn new(window: W, window_size: WindowSize) -> DemoApp<W> {
let default_framebuffer_size = Point2DI32::new(MAIN_FRAMEBUFFER_WIDTH as i32,
MAIN_FRAMEBUFFER_HEIGHT as i32);
let window = W::new(default_framebuffer_size);
let expire_message_event_id = window.create_user_event_id(); let expire_message_event_id = window.create_user_event_id();
let device = GLDevice::new(window.gl_version()); let device = GLDevice::new(window.gl_version());
let resources = window.resource_loader(); let resources = window.resource_loader();
let options = Options::get(resources); let options = Options::get(resources);
let (window_size, drawable_size) = (window.size(), window.drawable_size()); let view_box_size = view_box_size(options.mode, &window_size);
let view_box_size = view_box_size(options.mode, &window);
let built_svg = load_scene(resources, &options.input_path); let built_svg = load_scene(resources, &options.input_path);
let message = get_svg_building_message(&built_svg); let message = get_svg_building_message(&built_svg);
@ -132,7 +125,7 @@ impl<W> DemoApp<W> where W: Window {
let renderer = Renderer::new(device, let renderer = Renderer::new(device,
resources, resources,
RectI32::new(Point2DI32::default(), view_box_size), RectI32::new(Point2DI32::default(), view_box_size),
drawable_size); window_size.device_size());
let scene_thread_proxy = SceneThreadProxy::new(built_svg.scene, options.clone()); let scene_thread_proxy = SceneThreadProxy::new(built_svg.scene, options.clone());
scene_thread_proxy.set_drawable_size(view_box_size); scene_thread_proxy.set_drawable_size(view_box_size);
@ -158,7 +151,7 @@ impl<W> DemoApp<W> where W: Window {
window, window,
should_exit: false, should_exit: false,
scale_factor: drawable_size.x() as f32 / window_size.x() as f32, window_size,
scene_view_box, scene_view_box,
scene_is_monochrome, scene_is_monochrome,
@ -195,7 +188,7 @@ impl<W> DemoApp<W> where W: Window {
} }
fn build_scene(&mut self) { fn build_scene(&mut self) {
let view_box_size = view_box_size(self.ui.mode, &self.window); let view_box_size = view_box_size(self.ui.mode, &self.window_size);
let render_transform = match self.camera { let render_transform = match self.camera {
Camera::ThreeD { ref mut transform, ref mut velocity } => { Camera::ThreeD { ref mut transform, ref mut velocity } => {
@ -217,7 +210,7 @@ impl<W> DemoApp<W> where W: Window {
self.scene_thread_proxy.sender.send(MainToSceneMsg::Build(BuildOptions { self.scene_thread_proxy.sender.send(MainToSceneMsg::Build(BuildOptions {
render_transforms, render_transforms,
stem_darkening_font_size: if self.ui.stem_darkening_effect_enabled { stem_darkening_font_size: if self.ui.stem_darkening_effect_enabled {
Some(APPROX_FONT_SIZE * self.scale_factor) Some(APPROX_FONT_SIZE * self.window_size.backing_scale_factor)
} else { } else {
None None
}, },
@ -240,10 +233,11 @@ impl<W> DemoApp<W> where W: Window {
self.should_exit = true; self.should_exit = true;
self.dirty = true; self.dirty = true;
} }
Event::WindowResized => { Event::WindowResized(new_size) => {
let view_box_size = view_box_size(self.ui.mode, &self.window); self.window_size = new_size;
let view_box_size = view_box_size(self.ui.mode, &self.window_size);
self.scene_thread_proxy.set_drawable_size(view_box_size); self.scene_thread_proxy.set_drawable_size(view_box_size);
self.renderer.set_main_framebuffer_size(self.window.drawable_size()); self.renderer.set_main_framebuffer_size(self.window_size.device_size());
self.dirty = true; self.dirty = true;
} }
Event::MouseDown(new_position) => { Event::MouseDown(new_position) => {
@ -268,7 +262,8 @@ impl<W> DemoApp<W> where W: Window {
} }
Event::Zoom(d_dist) => { Event::Zoom(d_dist) => {
if let Camera::TwoD(ref mut transform) = self.camera { if let Camera::TwoD(ref mut transform) = self.camera {
let position = get_mouse_position(&self.window, self.scale_factor); let position = get_mouse_position(&self.window,
self.window_size.backing_scale_factor);
*transform = transform.post_translate(-position); *transform = transform.post_translate(-position);
let scale_delta = 1.0 + d_dist * CAMERA_SCALE_SPEED_2D; let scale_delta = 1.0 + d_dist * CAMERA_SCALE_SPEED_2D;
*transform = transform.post_scale(Point2DF32::splat(scale_delta)); *transform = transform.post_scale(Point2DF32::splat(scale_delta));
@ -337,7 +332,7 @@ impl<W> DemoApp<W> where W: Window {
} }
fn process_mouse_position(&mut self, new_position: Point2DI32) -> MousePosition { fn process_mouse_position(&mut self, new_position: Point2DI32) -> MousePosition {
let absolute = new_position.scale(self.scale_factor as i32); let absolute = new_position.scale(self.window_size.backing_scale_factor as i32);
let relative = absolute - self.last_mouse_position; let relative = absolute - self.last_mouse_position;
self.last_mouse_position = absolute; self.last_mouse_position = absolute;
MousePosition { absolute, relative } MousePosition { absolute, relative }
@ -366,7 +361,7 @@ impl<W> DemoApp<W> where W: Window {
} }
} }
let drawable_size = self.window.drawable_size(); let drawable_size = self.window_size.device_size();
self.renderer.set_viewport(RectI32::new(Point2DI32::default(), drawable_size)); self.renderer.set_viewport(RectI32::new(Point2DI32::default(), drawable_size));
if self.pending_screenshot_path.is_some() { if self.pending_screenshot_path.is_some() {
@ -385,8 +380,8 @@ impl<W> DemoApp<W> where W: Window {
self.renderer.debug_ui.ui.event_queue.push(*ui_event); self.renderer.debug_ui.ui.event_queue.push(*ui_event);
} }
self.renderer.debug_ui.ui.mouse_position = get_mouse_position(&self.window, self.renderer.debug_ui.ui.mouse_position =
self.scale_factor); get_mouse_position(&self.window, self.window_size.backing_scale_factor);
self.ui.show_text_effects = self.scene_is_monochrome; self.ui.show_text_effects = self.scene_is_monochrome;
let mut ui_action = UIAction::None; let mut ui_action = UIAction::None;
@ -406,7 +401,7 @@ impl<W> DemoApp<W> where W: Window {
self.camera = Camera::new_3d(self.scene_view_box); self.camera = Camera::new_3d(self.scene_view_box);
} }
(&Camera::ThreeD { .. }, Mode::TwoD) => { (&Camera::ThreeD { .. }, Mode::TwoD) => {
let drawable_size = self.window.drawable_size(); let drawable_size = self.window_size.device_size();
self.camera = Camera::new_2d(self.scene_view_box, drawable_size); self.camera = Camera::new_2d(self.scene_view_box, drawable_size);
} }
_ => {} _ => {}
@ -499,7 +494,7 @@ impl<W> DemoApp<W> where W: Window {
} }
fn render_vector_scene(&mut self, viewport_index: usize, built_scene: &BuiltScene) { fn render_vector_scene(&mut self, viewport_index: usize, built_scene: &BuiltScene) {
let view_box_size = view_box_size(self.ui.mode, &self.window); let view_box_size = view_box_size(self.ui.mode, &self.window_size);
let viewport_origin_x = viewport_index as i32 * view_box_size.x(); let viewport_origin_x = viewport_index as i32 * view_box_size.x();
let viewport = RectI32::new(Point2DI32::new(viewport_origin_x, 0), view_box_size); let viewport = RectI32::new(Point2DI32::new(viewport_origin_x, 0), view_box_size);
self.renderer.set_viewport(viewport); self.renderer.set_viewport(viewport);
@ -536,8 +531,8 @@ impl<W> DemoApp<W> where W: Window {
self.scene_view_box = built_svg.scene.view_box; self.scene_view_box = built_svg.scene.view_box;
self.scene_is_monochrome = built_svg.scene.is_monochrome(); self.scene_is_monochrome = built_svg.scene.is_monochrome();
self.scene_thread_proxy.set_drawable_size(self.window.drawable_size()); let drawable_size = self.window_size.device_size();
let drawable_size = self.window.drawable_size(); self.scene_thread_proxy.set_drawable_size(drawable_size);
self.camera = if self.ui.mode == Mode::TwoD { self.camera = if self.ui.mode == Mode::TwoD {
Camera::new_2d(built_svg.scene.view_box, drawable_size) Camera::new_2d(built_svg.scene.view_box, drawable_size)
@ -557,7 +552,7 @@ impl<W> DemoApp<W> where W: Window {
UIAction::ZoomIn => { UIAction::ZoomIn => {
if let Camera::TwoD(ref mut transform) = self.camera { if let Camera::TwoD(ref mut transform) = self.camera {
let scale = Point2DF32::splat(1.0 + CAMERA_ZOOM_AMOUNT_2D); let scale = Point2DF32::splat(1.0 + CAMERA_ZOOM_AMOUNT_2D);
let center = center_of_window(&self.window); let center = center_of_window(&self.window_size);
*transform = transform.post_translate(-center) *transform = transform.post_translate(-center)
.post_scale(scale) .post_scale(scale)
.post_translate(center); .post_translate(center);
@ -567,7 +562,7 @@ impl<W> DemoApp<W> where W: Window {
UIAction::ZoomOut => { UIAction::ZoomOut => {
if let Camera::TwoD(ref mut transform) = self.camera { if let Camera::TwoD(ref mut transform) = self.camera {
let scale = Point2DF32::splat(1.0 - CAMERA_ZOOM_AMOUNT_2D); let scale = Point2DF32::splat(1.0 - CAMERA_ZOOM_AMOUNT_2D);
let center = center_of_window(&self.window); let center = center_of_window(&self.window_size);
*transform = transform.post_translate(-center) *transform = transform.post_translate(-center)
.post_scale(scale) .post_scale(scale)
.post_translate(center); .post_translate(center);
@ -577,7 +572,7 @@ impl<W> DemoApp<W> where W: Window {
UIAction::Rotate(theta) => { UIAction::Rotate(theta) => {
if let Camera::TwoD(ref mut transform) = self.camera { if let Camera::TwoD(ref mut transform) = self.camera {
let old_rotation = transform.rotation(); let old_rotation = transform.rotation();
let center = center_of_window(&self.window); let center = center_of_window(&self.window_size);
*transform = transform.post_translate(-center) *transform = transform.post_translate(-center)
.post_rotate(*theta - old_rotation) .post_rotate(*theta - old_rotation)
.post_translate(center); .post_translate(center);
@ -588,7 +583,7 @@ impl<W> DemoApp<W> where W: Window {
fn take_screenshot(&mut self) { fn take_screenshot(&mut self) {
let screenshot_path = self.pending_screenshot_path.take().unwrap(); let screenshot_path = self.pending_screenshot_path.take().unwrap();
let drawable_size = self.window.drawable_size(); let drawable_size = self.window_size.device_size();
let pixels = self.renderer.device.read_pixels_from_default_framebuffer(drawable_size); let pixels = self.renderer.device.read_pixels_from_default_framebuffer(drawable_size);
image::save_buffer(screenshot_path, image::save_buffer(screenshot_path,
&pixels, &pixels,
@ -819,8 +814,8 @@ fn build_scene(scene: &Scene,
built_scene built_scene
} }
fn center_of_window<W>(window: &W) -> Point2DF32 where W: Window { fn center_of_window(window_size: &WindowSize) -> Point2DF32 {
window.drawable_size().to_f32().scale(0.5) window_size.device_size().to_f32().scale(0.5)
} }
enum Camera { enum Camera {
@ -930,8 +925,8 @@ fn emit_message<W>(ui: &mut DemoUI<GLDevice>,
}); });
} }
fn view_box_size<W>(mode: Mode, window: &W) -> Point2DI32 where W: Window { fn view_box_size(mode: Mode, window_size: &WindowSize) -> Point2DI32 {
let window_drawable_size = window.drawable_size(); let window_drawable_size = window_size.device_size();
match mode { match mode {
Mode::TwoD | Mode::ThreeD => window_drawable_size, Mode::TwoD | Mode::ThreeD => window_drawable_size,
Mode::VR => Point2DI32::new(window_drawable_size.x() / 2, window_drawable_size.y()), Mode::VR => Point2DI32::new(window_drawable_size.x() / 2, window_drawable_size.y()),

View File

@ -17,10 +17,7 @@ use std::io::Error;
use std::path::PathBuf; use std::path::PathBuf;
pub trait Window { pub trait Window {
fn new(initial_size: Point2DI32) -> Self;
fn gl_version(&self) -> GLVersion; fn gl_version(&self) -> GLVersion;
fn size(&self) -> Point2DI32;
fn drawable_size(&self) -> Point2DI32;
fn mouse_position(&self) -> Point2DI32; fn mouse_position(&self) -> Point2DI32;
fn present(&self); fn present(&self);
fn resource_loader(&self) -> &dyn ResourceLoader; fn resource_loader(&self) -> &dyn ResourceLoader;
@ -32,7 +29,7 @@ pub trait Window {
pub enum Event { pub enum Event {
Quit, Quit,
WindowResized, WindowResized(WindowSize),
KeyDown(Keycode), KeyDown(Keycode),
KeyUp(Keycode), KeyUp(Keycode),
MouseDown(Point2DI32), MouseDown(Point2DI32),
@ -48,3 +45,16 @@ pub enum Keycode {
Alphanumeric(u8), Alphanumeric(u8),
Escape, Escape,
} }
#[derive(Clone, Copy, Debug)]
pub struct WindowSize {
pub logical_size: Point2DI32,
pub backing_scale_factor: f32,
}
impl WindowSize {
#[inline]
pub fn device_size(&self) -> Point2DI32 {
self.logical_size.to_f32().scale(self.backing_scale_factor).to_i32()
}
}

View File

@ -12,7 +12,7 @@
use nfd::Response; use nfd::Response;
use pathfinder_demo::DemoApp; use pathfinder_demo::DemoApp;
use pathfinder_demo::window::{Event, Keycode, Window}; use pathfinder_demo::window::{Event, Keycode, Window, WindowSize};
use pathfinder_geometry::basic::point::Point2DI32; use pathfinder_geometry::basic::point::Point2DI32;
use pathfinder_gl::GLVersion; use pathfinder_gl::GLVersion;
use pathfinder_gpu::resources::{FilesystemResourceLoader, ResourceLoader}; use pathfinder_gpu::resources::{FilesystemResourceLoader, ResourceLoader};
@ -24,8 +24,14 @@ use sdl2_sys::{SDL_Event, SDL_UserEvent};
use std::path::PathBuf; use std::path::PathBuf;
use std::ptr; use std::ptr;
const DEFAULT_WINDOW_WIDTH: u32 = 1067;
const DEFAULT_WINDOW_HEIGHT: u32 = 800;
fn main() { fn main() {
let mut app = DemoApp::<WindowImpl>::new(); let window = WindowImpl::new();
let window_size = window.size();
let mut app = DemoApp::new(window, window_size);
while !app.should_exit { while !app.should_exit {
let mut events = vec![app.window.get_event()]; let mut events = vec![app.window.get_event()];
while let Some(event) = app.window.try_get_event() { while let Some(event) = app.window.try_get_event() {
@ -50,50 +56,10 @@ struct WindowImpl {
} }
impl Window for WindowImpl { impl Window for WindowImpl {
fn new(default_framebuffer_size: Point2DI32) -> WindowImpl {
SDL_VIDEO.with(|sdl_video| {
let (window, gl_context, event_pump);
let gl_attributes = sdl_video.gl_attr();
gl_attributes.set_context_profile(GLProfile::Core);
gl_attributes.set_context_version(3, 3);
gl_attributes.set_depth_size(24);
gl_attributes.set_stencil_size(8);
window = sdl_video.window("Pathfinder Demo",
default_framebuffer_size.x() as u32,
default_framebuffer_size.y() as u32)
.opengl()
.resizable()
.allow_highdpi()
.build()
.unwrap();
gl_context = window.gl_create_context().unwrap();
gl::load_with(|name| sdl_video.gl_get_proc_address(name) as *const _);
event_pump = SDL_CONTEXT.with(|sdl_context| sdl_context.event_pump().unwrap());
let resource_loader = FilesystemResourceLoader::locate();
WindowImpl { window, event_pump, gl_context, resource_loader }
})
}
fn gl_version(&self) -> GLVersion { fn gl_version(&self) -> GLVersion {
GLVersion::GL3 GLVersion::GL3
} }
fn size(&self) -> Point2DI32 {
let (width, height) = self.window.size();
Point2DI32::new(width as i32, height as i32)
}
fn drawable_size(&self) -> Point2DI32 {
let (width, height) = self.window.drawable_size();
Point2DI32::new(width as i32, height as i32)
}
fn mouse_position(&self) -> Point2DI32 { fn mouse_position(&self) -> Point2DI32 {
let mouse_state = self.event_pump.mouse_state(); let mouse_state = self.event_pump.mouse_state();
Point2DI32::new(mouse_state.x(), mouse_state.y()) Point2DI32::new(mouse_state.x(), mouse_state.y())
@ -141,6 +107,45 @@ impl Window for WindowImpl {
} }
impl WindowImpl { impl WindowImpl {
fn new() -> WindowImpl {
SDL_VIDEO.with(|sdl_video| {
let (window, gl_context, event_pump);
let gl_attributes = sdl_video.gl_attr();
gl_attributes.set_context_profile(GLProfile::Core);
gl_attributes.set_context_version(3, 3);
gl_attributes.set_depth_size(24);
gl_attributes.set_stencil_size(8);
window = sdl_video.window("Pathfinder Demo",
DEFAULT_WINDOW_WIDTH,
DEFAULT_WINDOW_HEIGHT)
.opengl()
.resizable()
.allow_highdpi()
.build()
.unwrap();
gl_context = window.gl_create_context().unwrap();
gl::load_with(|name| sdl_video.gl_get_proc_address(name) as *const _);
event_pump = SDL_CONTEXT.with(|sdl_context| sdl_context.event_pump().unwrap());
let resource_loader = FilesystemResourceLoader::locate();
WindowImpl { window, event_pump, gl_context, resource_loader }
})
}
fn size(&self) -> WindowSize {
let (logical_width, logical_height) = self.window.size();
let (drawable_width, _) = self.window.drawable_size();
WindowSize {
logical_size: Point2DI32::new(logical_width as i32, logical_height as i32),
backing_scale_factor: drawable_width as f32 / logical_width as f32,
}
}
fn get_event(&mut self) -> Event { fn get_event(&mut self) -> Event {
loop { loop {
let sdl_event = self.event_pump.wait_event(); let sdl_event = self.event_pump.wait_event();
@ -177,7 +182,7 @@ impl WindowImpl {
} }
SDLEvent::Quit { .. } => Some(Event::Quit), SDLEvent::Quit { .. } => Some(Event::Quit),
SDLEvent::Window { win_event: WindowEvent::SizeChanged(..), .. } => { SDLEvent::Window { win_event: WindowEvent::SizeChanged(..), .. } => {
Some(Event::WindowResized) Some(Event::WindowResized(self.size()))
} }
SDLEvent::KeyDown { keycode: Some(sdl_keycode), .. } => { SDLEvent::KeyDown { keycode: Some(sdl_keycode), .. } => {
self.convert_sdl_keycode(sdl_keycode).map(Event::KeyDown) self.convert_sdl_keycode(sdl_keycode).map(Event::KeyDown)

View File

@ -133,6 +133,11 @@ impl Point2DF32 {
pub fn lerp(&self, other: Point2DF32, t: f32) -> Point2DF32 { pub fn lerp(&self, other: Point2DF32, t: f32) -> Point2DF32 {
*self + (other - *self).scale(t) *self + (other - *self).scale(t)
} }
#[inline]
pub fn to_i32(&self) -> Point2DI32 {
Point2DI32(self.0.to_i32x4())
}
} }
impl PartialEq for Point2DF32 { impl PartialEq for Point2DF32 {