Run `rustfmt` on the demos
This commit is contained in:
parent
0da11ffe01
commit
60b951409c
|
@ -11,11 +11,11 @@
|
|||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
|
||||
use jni::{JNIEnv, JavaVM};
|
||||
use jni::objects::{GlobalRef, JByteBuffer, JClass, JObject, JString, JValue};
|
||||
use jni::{JNIEnv, JavaVM};
|
||||
use pathfinder_demo::window::{Event, SVGPath, View, Window, WindowSize};
|
||||
use pathfinder_demo::DemoApp;
|
||||
use pathfinder_demo::Options;
|
||||
use pathfinder_demo::window::{Event, SVGPath, View, Window, WindowSize};
|
||||
use pathfinder_geometry::basic::point::Point2DI32;
|
||||
use pathfinder_geometry::basic::rect::RectI32;
|
||||
use pathfinder_gl::GLVersion;
|
||||
|
@ -40,15 +40,19 @@ thread_local! {
|
|||
static RESOURCE_LOADER: AndroidResourceLoader = AndroidResourceLoader;
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "system" fn
|
||||
Java_graphics_pathfinder_pathfinderdemo_PathfinderDemoRenderer_init(env: JNIEnv,
|
||||
pub unsafe extern "system" fn Java_graphics_pathfinder_pathfinderdemo_PathfinderDemoRenderer_init(
|
||||
env: JNIEnv,
|
||||
class: JClass,
|
||||
activity: JObject,
|
||||
loader: JObject,
|
||||
width: i32,
|
||||
height: i32) {
|
||||
height: i32,
|
||||
) {
|
||||
let logical_size = Point2DI32::new(width, height);
|
||||
let window_size = WindowSize { logical_size, backing_scale_factor: 1.0 };
|
||||
let window_size = WindowSize {
|
||||
logical_size,
|
||||
backing_scale_factor: 1.0,
|
||||
};
|
||||
let window = WindowImpl { size: logical_size };
|
||||
let options = Options::default();
|
||||
|
||||
|
@ -65,10 +69,10 @@ pub unsafe extern "system" fn
|
|||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "system" fn
|
||||
Java_graphics_pathfinder_pathfinderdemo_PathfinderDemoRenderer_prepareFrame(env: JNIEnv,
|
||||
class: JClass)
|
||||
-> i32 {
|
||||
pub unsafe extern "system" fn Java_graphics_pathfinder_pathfinderdemo_PathfinderDemoRenderer_prepareFrame(
|
||||
env: JNIEnv,
|
||||
class: JClass,
|
||||
) -> i32 {
|
||||
DEMO_APP.with(|demo_app| {
|
||||
let mut event_queue = EVENT_QUEUE.lock().unwrap();
|
||||
match *demo_app.borrow_mut() {
|
||||
|
@ -81,10 +85,10 @@ pub unsafe extern "system" fn
|
|||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "system" fn
|
||||
Java_graphics_pathfinder_pathfinderdemo_PathfinderDemoRenderer_drawScene(
|
||||
pub unsafe extern "system" fn Java_graphics_pathfinder_pathfinderdemo_PathfinderDemoRenderer_drawScene(
|
||||
env: JNIEnv,
|
||||
class: JClass) {
|
||||
class: JClass,
|
||||
) {
|
||||
DEMO_APP.with(|demo_app| {
|
||||
if let Some(ref mut demo_app) = *demo_app.borrow_mut() {
|
||||
demo_app.draw_scene()
|
||||
|
@ -93,10 +97,10 @@ pub unsafe extern "system" fn
|
|||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "system" fn
|
||||
Java_graphics_pathfinder_pathfinderdemo_PathfinderDemoRenderer_finishDrawingFrame(
|
||||
pub unsafe extern "system" fn Java_graphics_pathfinder_pathfinderdemo_PathfinderDemoRenderer_finishDrawingFrame(
|
||||
env: JNIEnv,
|
||||
class: JClass) {
|
||||
class: JClass,
|
||||
) {
|
||||
DEMO_APP.with(|demo_app| {
|
||||
if let Some(ref mut demo_app) = *demo_app.borrow_mut() {
|
||||
demo_app.finish_drawing_frame()
|
||||
|
@ -105,67 +109,82 @@ pub unsafe extern "system" fn
|
|||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "system" fn
|
||||
Java_graphics_pathfinder_pathfinderdemo_PathfinderDemoRenderer_pushWindowResizedEvent(
|
||||
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 {
|
||||
height: i32,
|
||||
) {
|
||||
EVENT_QUEUE
|
||||
.lock()
|
||||
.unwrap()
|
||||
.push(Event::WindowResized(WindowSize {
|
||||
logical_size: Point2DI32::new(width, height),
|
||||
backing_scale_factor: 1.0,
|
||||
}))
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "system" fn
|
||||
Java_graphics_pathfinder_pathfinderdemo_PathfinderDemoRenderer_pushMouseDownEvent(
|
||||
pub unsafe extern "system" fn Java_graphics_pathfinder_pathfinderdemo_PathfinderDemoRenderer_pushMouseDownEvent(
|
||||
_: JNIEnv,
|
||||
_: JClass,
|
||||
x: i32,
|
||||
y: i32) {
|
||||
EVENT_QUEUE.lock().unwrap().push(Event::MouseDown(Point2DI32::new(x, y)))
|
||||
y: i32,
|
||||
) {
|
||||
EVENT_QUEUE
|
||||
.lock()
|
||||
.unwrap()
|
||||
.push(Event::MouseDown(Point2DI32::new(x, y)))
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "system" fn
|
||||
Java_graphics_pathfinder_pathfinderdemo_PathfinderDemoRenderer_pushMouseDraggedEvent(
|
||||
pub unsafe extern "system" fn Java_graphics_pathfinder_pathfinderdemo_PathfinderDemoRenderer_pushMouseDraggedEvent(
|
||||
_: JNIEnv,
|
||||
_: JClass,
|
||||
x: i32,
|
||||
y: i32) {
|
||||
EVENT_QUEUE.lock().unwrap().push(Event::MouseDragged(Point2DI32::new(x, y)))
|
||||
y: i32,
|
||||
) {
|
||||
EVENT_QUEUE
|
||||
.lock()
|
||||
.unwrap()
|
||||
.push(Event::MouseDragged(Point2DI32::new(x, y)))
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "system" fn
|
||||
Java_graphics_pathfinder_pathfinderdemo_PathfinderDemoRenderer_pushZoomEvent(
|
||||
pub unsafe extern "system" fn Java_graphics_pathfinder_pathfinderdemo_PathfinderDemoRenderer_pushZoomEvent(
|
||||
_: JNIEnv,
|
||||
_: JClass,
|
||||
factor: f32,
|
||||
center_x: i32,
|
||||
center_y: i32) {
|
||||
EVENT_QUEUE.lock().unwrap().push(Event::Zoom(factor, Point2DI32::new(center_x, center_y)))
|
||||
center_y: i32,
|
||||
) {
|
||||
EVENT_QUEUE
|
||||
.lock()
|
||||
.unwrap()
|
||||
.push(Event::Zoom(factor, Point2DI32::new(center_x, center_y)))
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "system" fn
|
||||
Java_graphics_pathfinder_pathfinderdemo_PathfinderDemoRenderer_pushLookEvent(
|
||||
pub unsafe extern "system" fn Java_graphics_pathfinder_pathfinderdemo_PathfinderDemoRenderer_pushLookEvent(
|
||||
_: JNIEnv,
|
||||
_: JClass,
|
||||
pitch: f32,
|
||||
yaw: f32) {
|
||||
yaw: f32,
|
||||
) {
|
||||
EVENT_QUEUE.lock().unwrap().push(Event::Look { pitch, yaw })
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "system" fn
|
||||
Java_graphics_pathfinder_pathfinderdemo_PathfinderDemoRenderer_pushOpenSVGEvent(
|
||||
pub unsafe extern "system" fn Java_graphics_pathfinder_pathfinderdemo_PathfinderDemoRenderer_pushOpenSVGEvent(
|
||||
env: JNIEnv,
|
||||
_: JClass,
|
||||
string: JObject) {
|
||||
string: JObject,
|
||||
) {
|
||||
let string: String = env.get_string(JString::from(string)).unwrap().into();
|
||||
EVENT_QUEUE.lock().unwrap().push(Event::OpenSVG(SVGPath::Resource(string)))
|
||||
EVENT_QUEUE
|
||||
.lock()
|
||||
.unwrap()
|
||||
.push(Event::OpenSVG(SVGPath::Resource(string)))
|
||||
}
|
||||
|
||||
struct WindowImpl {
|
||||
|
@ -202,18 +221,20 @@ impl Window for WindowImpl {
|
|||
0
|
||||
}
|
||||
|
||||
fn push_user_event(message_type: u32, message_data: u32) {
|
||||
}
|
||||
fn push_user_event(message_type: u32, message_data: u32) {}
|
||||
|
||||
fn present_open_svg_dialog(&mut self) {
|
||||
JAVA_ACTIVITY.with(|java_activity| {
|
||||
let mut java_activity = java_activity.borrow_mut();
|
||||
let java_activity = java_activity.as_mut().unwrap();
|
||||
let env = java_activity.vm.get_env().unwrap();
|
||||
env.call_method(java_activity.activity.as_obj(),
|
||||
env.call_method(
|
||||
java_activity.activity.as_obj(),
|
||||
"presentOpenSVGDialog",
|
||||
"()V",
|
||||
&[]).unwrap();
|
||||
&[],
|
||||
)
|
||||
.unwrap();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -232,13 +253,20 @@ impl ResourceLoader for AndroidResourceLoader {
|
|||
let java_resource_loader = java_resource_loader.as_ref().unwrap();
|
||||
let loader = java_resource_loader.loader.as_obj();
|
||||
let env = java_resource_loader.vm.get_env().unwrap();
|
||||
match env.call_method(loader,
|
||||
match env
|
||||
.call_method(
|
||||
loader,
|
||||
"slurp",
|
||||
"(Ljava/lang/String;)Ljava/nio/ByteBuffer;",
|
||||
&[JValue::Object(*env.new_string(path).unwrap())]).unwrap() {
|
||||
&[JValue::Object(*env.new_string(path).unwrap())],
|
||||
)
|
||||
.unwrap()
|
||||
{
|
||||
JValue::Object(object) => {
|
||||
let byte_buffer = JByteBuffer::from(object);
|
||||
Ok(Vec::from(env.get_direct_buffer_address(byte_buffer).unwrap()))
|
||||
Ok(Vec::from(
|
||||
env.get_direct_buffer_address(byte_buffer).unwrap(),
|
||||
))
|
||||
}
|
||||
_ => panic!("Unexpected return value!"),
|
||||
}
|
||||
|
|
|
@ -14,30 +14,47 @@ use crate::GRIDLINE_COUNT;
|
|||
use pathfinder_gpu::resources::ResourceLoader;
|
||||
use pathfinder_gpu::{BufferData, BufferTarget, BufferUploadMode, Device, VertexAttrType};
|
||||
|
||||
pub struct GroundProgram<D> where D: Device {
|
||||
pub struct GroundProgram<D>
|
||||
where
|
||||
D: Device,
|
||||
{
|
||||
pub program: D::Program,
|
||||
pub transform_uniform: D::Uniform,
|
||||
pub color_uniform: D::Uniform,
|
||||
}
|
||||
|
||||
impl<D> GroundProgram<D> where D: Device {
|
||||
impl<D> GroundProgram<D>
|
||||
where
|
||||
D: Device,
|
||||
{
|
||||
pub fn new(device: &D, resources: &dyn ResourceLoader) -> GroundProgram<D> {
|
||||
let program = device.create_program(resources, "demo_ground");
|
||||
let transform_uniform = device.get_uniform(&program, "Transform");
|
||||
let color_uniform = device.get_uniform(&program, "Color");
|
||||
GroundProgram { program, transform_uniform, color_uniform }
|
||||
GroundProgram {
|
||||
program,
|
||||
transform_uniform,
|
||||
color_uniform,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct GroundSolidVertexArray<D> where D: Device {
|
||||
pub struct GroundSolidVertexArray<D>
|
||||
where
|
||||
D: Device,
|
||||
{
|
||||
pub vertex_array: D::VertexArray,
|
||||
}
|
||||
|
||||
impl<D> GroundSolidVertexArray<D> where D: Device {
|
||||
pub fn new(device: &D,
|
||||
impl<D> GroundSolidVertexArray<D>
|
||||
where
|
||||
D: Device,
|
||||
{
|
||||
pub fn new(
|
||||
device: &D,
|
||||
ground_program: &GroundProgram<D>,
|
||||
quad_vertex_positions_buffer: &D::Buffer)
|
||||
-> GroundSolidVertexArray<D> {
|
||||
quad_vertex_positions_buffer: &D::Buffer,
|
||||
) -> GroundSolidVertexArray<D> {
|
||||
let vertex_array = device.create_vertex_array();
|
||||
|
||||
let position_attr = device.get_vertex_attr(&ground_program.program, "Position");
|
||||
|
@ -51,19 +68,27 @@ impl<D> GroundSolidVertexArray<D> where D: Device {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct GroundLineVertexArray<D> where D: Device {
|
||||
pub struct GroundLineVertexArray<D>
|
||||
where
|
||||
D: Device,
|
||||
{
|
||||
pub vertex_array: D::VertexArray,
|
||||
#[allow(dead_code)]
|
||||
grid_vertex_positions_buffer: D::Buffer,
|
||||
}
|
||||
|
||||
impl<D> GroundLineVertexArray<D> where D: Device {
|
||||
impl<D> GroundLineVertexArray<D>
|
||||
where
|
||||
D: Device,
|
||||
{
|
||||
pub fn new(device: &D, ground_program: &GroundProgram<D>) -> GroundLineVertexArray<D> {
|
||||
let grid_vertex_positions_buffer = device.create_buffer();
|
||||
device.allocate_buffer(&grid_vertex_positions_buffer,
|
||||
device.allocate_buffer(
|
||||
&grid_vertex_positions_buffer,
|
||||
BufferData::Memory(&create_grid_vertex_positions()),
|
||||
BufferTarget::Vertex,
|
||||
BufferUploadMode::Static);
|
||||
BufferUploadMode::Static,
|
||||
);
|
||||
|
||||
let vertex_array = device.create_vertex_array();
|
||||
|
||||
|
@ -74,7 +99,10 @@ impl<D> GroundLineVertexArray<D> where D: Device {
|
|||
device.bind_buffer(&grid_vertex_positions_buffer, BufferTarget::Vertex);
|
||||
device.configure_float_vertex_attr(&position_attr, 2, VertexAttrType::U8, false, 0, 0, 0);
|
||||
|
||||
GroundLineVertexArray { vertex_array, grid_vertex_positions_buffer }
|
||||
GroundLineVertexArray {
|
||||
vertex_array,
|
||||
grid_vertex_positions_buffer,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -82,8 +110,10 @@ fn create_grid_vertex_positions() -> Vec<(u8, u8)> {
|
|||
let mut positions = vec![];
|
||||
for index in 0..(GRIDLINE_COUNT + 1) {
|
||||
positions.extend_from_slice(&[
|
||||
(0, index), (GRIDLINE_COUNT, index),
|
||||
(index, 0), (index, GRIDLINE_COUNT),
|
||||
(0, index),
|
||||
(GRIDLINE_COUNT, index),
|
||||
(index, 0),
|
||||
(index, GRIDLINE_COUNT),
|
||||
]);
|
||||
}
|
||||
positions
|
||||
|
|
|
@ -60,12 +60,37 @@ const CAMERA_ZOOM_AMOUNT_2D: f32 = 0.1;
|
|||
const NEAR_CLIP_PLANE: f32 = 0.01;
|
||||
const FAR_CLIP_PLANE: f32 = 10.0;
|
||||
|
||||
const LIGHT_BG_COLOR: ColorU = ColorU { r: 248, g: 248, b: 248, a: 255 };
|
||||
const DARK_BG_COLOR: ColorU = ColorU { r: 32, g: 32, b: 32, a: 255 };
|
||||
const TRANSPARENT_BG_COLOR: ColorU = ColorU { r: 0, g: 0, b: 0, a: 0 };
|
||||
const LIGHT_BG_COLOR: ColorU = ColorU {
|
||||
r: 248,
|
||||
g: 248,
|
||||
b: 248,
|
||||
a: 255,
|
||||
};
|
||||
const DARK_BG_COLOR: ColorU = ColorU {
|
||||
r: 32,
|
||||
g: 32,
|
||||
b: 32,
|
||||
a: 255,
|
||||
};
|
||||
const TRANSPARENT_BG_COLOR: ColorU = ColorU {
|
||||
r: 0,
|
||||
g: 0,
|
||||
b: 0,
|
||||
a: 0,
|
||||
};
|
||||
|
||||
const GROUND_SOLID_COLOR: ColorU = ColorU { r: 80, g: 80, b: 80, a: 255 };
|
||||
const GROUND_LINE_COLOR: ColorU = ColorU { r: 127, g: 127, b: 127, a: 255 };
|
||||
const GROUND_SOLID_COLOR: ColorU = ColorU {
|
||||
r: 80,
|
||||
g: 80,
|
||||
b: 80,
|
||||
a: 255,
|
||||
};
|
||||
const GROUND_LINE_COLOR: ColorU = ColorU {
|
||||
r: 127,
|
||||
g: 127,
|
||||
b: 127,
|
||||
a: 255,
|
||||
};
|
||||
|
||||
const APPROX_FONT_SIZE: f32 = 16.0;
|
||||
|
||||
|
@ -83,7 +108,10 @@ pub mod window;
|
|||
mod device;
|
||||
mod ui;
|
||||
|
||||
pub struct DemoApp<W> where W: Window {
|
||||
pub struct DemoApp<W>
|
||||
where
|
||||
W: Window,
|
||||
{
|
||||
pub window: W,
|
||||
pub should_exit: bool,
|
||||
pub options: Options,
|
||||
|
@ -115,7 +143,10 @@ pub struct DemoApp<W> where W: Window {
|
|||
ground_line_vertex_array: GroundLineVertexArray<GLDevice>,
|
||||
}
|
||||
|
||||
impl<W> DemoApp<W> where W: Window {
|
||||
impl<W> DemoApp<W>
|
||||
where
|
||||
W: Window,
|
||||
{
|
||||
pub fn new(window: W, window_size: WindowSize, mut options: Options) -> DemoApp<W> {
|
||||
let expire_message_event_id = window.create_user_event_id();
|
||||
|
||||
|
@ -148,16 +179,22 @@ impl<W> DemoApp<W> where W: Window {
|
|||
let camera = Camera::new(options.mode, scene_view_box, viewport.size());
|
||||
|
||||
let ground_program = GroundProgram::new(&renderer.device, resources);
|
||||
let ground_solid_vertex_array =
|
||||
GroundSolidVertexArray::new(&renderer.device,
|
||||
let ground_solid_vertex_array = GroundSolidVertexArray::new(
|
||||
&renderer.device,
|
||||
&ground_program,
|
||||
&renderer.quad_vertex_positions_buffer());
|
||||
let ground_line_vertex_array = GroundLineVertexArray::new(&renderer.device,
|
||||
&ground_program);
|
||||
&renderer.quad_vertex_positions_buffer(),
|
||||
);
|
||||
let ground_line_vertex_array =
|
||||
GroundLineVertexArray::new(&renderer.device, &ground_program);
|
||||
|
||||
let mut ui = DemoUI::new(&renderer.device, resources, options.clone());
|
||||
let mut message_epoch = 0;
|
||||
emit_message::<W>(&mut ui, &mut message_epoch, expire_message_event_id, message);
|
||||
emit_message::<W>(
|
||||
&mut ui,
|
||||
&mut message_epoch,
|
||||
expire_message_event_id,
|
||||
message,
|
||||
);
|
||||
|
||||
DemoApp {
|
||||
window,
|
||||
|
@ -218,28 +255,30 @@ impl<W> DemoApp<W> where W: Window {
|
|||
let scene_count = match self.camera.mode() {
|
||||
Mode::VR => {
|
||||
let viewport = self.window.viewport(View::Stereo(0));
|
||||
if self.scene_framebuffer.is_none() ||
|
||||
self.renderer
|
||||
if self.scene_framebuffer.is_none()
|
||||
|| self.renderer.device.texture_size(
|
||||
&self
|
||||
.renderer
|
||||
.device
|
||||
.texture_size(&self.renderer
|
||||
.framebuffer_texture(self.scene_framebuffer.as_ref().unwrap()),
|
||||
) != viewport.size()
|
||||
{
|
||||
let scene_texture = self
|
||||
.renderer
|
||||
.device
|
||||
.framebuffer_texture(self.scene_framebuffer
|
||||
.as_ref()
|
||||
.unwrap())) !=
|
||||
viewport.size() {
|
||||
let scene_texture = self.renderer.device.create_texture(TextureFormat::RGBA8,
|
||||
viewport.size());
|
||||
.create_texture(TextureFormat::RGBA8, viewport.size());
|
||||
self.scene_framebuffer =
|
||||
Some(self.renderer.device.create_framebuffer(scene_texture));
|
||||
}
|
||||
self.renderer
|
||||
.replace_dest_framebuffer(DestFramebuffer::Other(self.scene_framebuffer
|
||||
.take()
|
||||
.unwrap()));
|
||||
.replace_dest_framebuffer(DestFramebuffer::Other(
|
||||
self.scene_framebuffer.take().unwrap(),
|
||||
));
|
||||
2
|
||||
}
|
||||
_ => {
|
||||
self.renderer.replace_dest_framebuffer(DestFramebuffer::Default {
|
||||
self.renderer
|
||||
.replace_dest_framebuffer(DestFramebuffer::Default {
|
||||
viewport: self.window.viewport(View::Mono),
|
||||
window_size,
|
||||
});
|
||||
|
@ -277,7 +316,8 @@ impl<W> DemoApp<W> where W: Window {
|
|||
if modelview_transform.offset(*velocity) {
|
||||
self.dirty = true;
|
||||
}
|
||||
let perspective = scene_transform.perspective
|
||||
let perspective = scene_transform
|
||||
.perspective
|
||||
.post_mul(&scene_transform.modelview_to_eye)
|
||||
.post_mul(&modelview_transform.to_transform());
|
||||
RenderTransform::Perspective(perspective)
|
||||
|
@ -285,7 +325,9 @@ impl<W> DemoApp<W> where W: Window {
|
|||
Camera::TwoD(transform) => RenderTransform::Transform2D(transform),
|
||||
};
|
||||
|
||||
self.scene_thread_proxy.sender.send(MainToSceneMsg::Build(BuildOptions {
|
||||
self.scene_thread_proxy
|
||||
.sender
|
||||
.send(MainToSceneMsg::Build(BuildOptions {
|
||||
render_transform,
|
||||
stem_darkening_font_size: if self.ui.stem_darkening_effect_enabled {
|
||||
Some(APPROX_FONT_SIZE * self.window_size.backing_scale_factor)
|
||||
|
@ -293,7 +335,8 @@ impl<W> DemoApp<W> where W: Window {
|
|||
None
|
||||
},
|
||||
subpixel_aa_enabled: self.ui.subpixel_aa_effect_enabled,
|
||||
})).unwrap();
|
||||
}))
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
fn handle_events(&mut self, events: Vec<Event>) -> Vec<UIEvent> {
|
||||
|
@ -302,8 +345,7 @@ impl<W> DemoApp<W> where W: Window {
|
|||
|
||||
for event in events {
|
||||
match event {
|
||||
Event::Quit { .. } |
|
||||
Event::KeyDown(Keycode::Escape) => {
|
||||
Event::Quit { .. } | Event::KeyDown(Keycode::Escape) => {
|
||||
self.should_exit = true;
|
||||
self.dirty = true;
|
||||
}
|
||||
|
@ -311,7 +353,8 @@ impl<W> DemoApp<W> where W: Window {
|
|||
self.window_size = new_size;
|
||||
let viewport = self.window.viewport(self.ui.mode.view(0));
|
||||
self.scene_thread_proxy.set_drawable_size(viewport.size());
|
||||
self.renderer.set_main_framebuffer_size(self.window_size.device_size());
|
||||
self.renderer
|
||||
.set_main_framebuffer_size(self.window_size.device_size());
|
||||
self.dirty = true;
|
||||
}
|
||||
Event::MouseDown(new_position) => {
|
||||
|
@ -320,8 +363,13 @@ impl<W> DemoApp<W> where W: Window {
|
|||
}
|
||||
Event::MouseMoved(new_position) if self.mouselook_enabled => {
|
||||
let mouse_position = self.process_mouse_position(new_position);
|
||||
if let Camera::ThreeD { ref mut modelview_transform, .. } = self.camera {
|
||||
let rotation = mouse_position.relative
|
||||
if let Camera::ThreeD {
|
||||
ref mut modelview_transform,
|
||||
..
|
||||
} = self.camera
|
||||
{
|
||||
let rotation = mouse_position
|
||||
.relative
|
||||
.to_f32()
|
||||
.scale(MOUSELOOK_ROTATION_SPEED);
|
||||
modelview_transform.yaw += rotation.x();
|
||||
|
@ -345,54 +393,80 @@ impl<W> DemoApp<W> where W: Window {
|
|||
}
|
||||
}
|
||||
Event::Look { pitch, yaw } => {
|
||||
if let Camera::ThreeD { ref mut modelview_transform, .. } = self.camera {
|
||||
if let Camera::ThreeD {
|
||||
ref mut modelview_transform,
|
||||
..
|
||||
} = self.camera
|
||||
{
|
||||
modelview_transform.pitch += pitch;
|
||||
modelview_transform.yaw += yaw;
|
||||
}
|
||||
}
|
||||
Event::SetEyeTransforms(new_eye_transforms) => {
|
||||
if let Camera::ThreeD { ref mut eye_transforms, .. } = self.camera {
|
||||
if let Camera::ThreeD {
|
||||
ref mut eye_transforms,
|
||||
..
|
||||
} = self.camera
|
||||
{
|
||||
*eye_transforms = new_eye_transforms;
|
||||
}
|
||||
}
|
||||
Event::KeyDown(Keycode::Alphanumeric(b'w')) => {
|
||||
if let Camera::ThreeD { ref mut velocity, .. } = self.camera {
|
||||
if let Camera::ThreeD {
|
||||
ref mut velocity, ..
|
||||
} = self.camera
|
||||
{
|
||||
let scale_factor = scale_factor_for_view_box(self.scene_view_box);
|
||||
velocity.set_z(-CAMERA_VELOCITY / scale_factor);
|
||||
self.dirty = true;
|
||||
}
|
||||
}
|
||||
Event::KeyDown(Keycode::Alphanumeric(b's')) => {
|
||||
if let Camera::ThreeD { ref mut velocity, .. } = self.camera {
|
||||
if let Camera::ThreeD {
|
||||
ref mut velocity, ..
|
||||
} = self.camera
|
||||
{
|
||||
let scale_factor = scale_factor_for_view_box(self.scene_view_box);
|
||||
velocity.set_z(CAMERA_VELOCITY / scale_factor);
|
||||
self.dirty = true;
|
||||
}
|
||||
}
|
||||
Event::KeyDown(Keycode::Alphanumeric(b'a')) => {
|
||||
if let Camera::ThreeD { ref mut velocity, .. } = self.camera {
|
||||
if let Camera::ThreeD {
|
||||
ref mut velocity, ..
|
||||
} = self.camera
|
||||
{
|
||||
let scale_factor = scale_factor_for_view_box(self.scene_view_box);
|
||||
velocity.set_x(-CAMERA_VELOCITY / scale_factor);
|
||||
self.dirty = true;
|
||||
}
|
||||
}
|
||||
Event::KeyDown(Keycode::Alphanumeric(b'd')) => {
|
||||
if let Camera::ThreeD { ref mut velocity, .. } = self.camera {
|
||||
if let Camera::ThreeD {
|
||||
ref mut velocity, ..
|
||||
} = self.camera
|
||||
{
|
||||
let scale_factor = scale_factor_for_view_box(self.scene_view_box);
|
||||
velocity.set_x(CAMERA_VELOCITY / scale_factor);
|
||||
self.dirty = true;
|
||||
}
|
||||
}
|
||||
Event::KeyUp(Keycode::Alphanumeric(b'w')) |
|
||||
Event::KeyUp(Keycode::Alphanumeric(b's')) => {
|
||||
if let Camera::ThreeD { ref mut velocity, .. } = self.camera {
|
||||
Event::KeyUp(Keycode::Alphanumeric(b'w'))
|
||||
| Event::KeyUp(Keycode::Alphanumeric(b's')) => {
|
||||
if let Camera::ThreeD {
|
||||
ref mut velocity, ..
|
||||
} = self.camera
|
||||
{
|
||||
velocity.set_z(0.0);
|
||||
self.dirty = true;
|
||||
}
|
||||
}
|
||||
Event::KeyUp(Keycode::Alphanumeric(b'a')) |
|
||||
Event::KeyUp(Keycode::Alphanumeric(b'd')) => {
|
||||
if let Camera::ThreeD { ref mut velocity, .. } = self.camera {
|
||||
Event::KeyUp(Keycode::Alphanumeric(b'a'))
|
||||
| Event::KeyUp(Keycode::Alphanumeric(b'd')) => {
|
||||
if let Camera::ThreeD {
|
||||
ref mut velocity, ..
|
||||
} = self.camera
|
||||
{
|
||||
velocity.set_x(0.0);
|
||||
self.dirty = true;
|
||||
}
|
||||
|
@ -412,12 +486,16 @@ impl<W> DemoApp<W> where W: Window {
|
|||
self.scene_view_box = built_svg.scene.view_box;
|
||||
self.monochrome_scene_color = built_svg.scene.monochrome_color();
|
||||
self.camera = Camera::new(self.ui.mode, self.scene_view_box, viewport_size);
|
||||
self.scene_thread_proxy.load_scene(built_svg.scene, viewport_size);
|
||||
self.scene_thread_proxy
|
||||
.load_scene(built_svg.scene, viewport_size);
|
||||
self.dirty = true;
|
||||
}
|
||||
Event::User { message_type: event_id, message_data: expected_epoch } if
|
||||
event_id == self.expire_message_event_id &&
|
||||
expected_epoch as u32 == self.message_epoch => {
|
||||
Event::User {
|
||||
message_type: event_id,
|
||||
message_data: expected_epoch,
|
||||
} if event_id == self.expire_message_event_id
|
||||
&& expected_epoch as u32 == self.message_epoch =>
|
||||
{
|
||||
self.ui.message = String::new();
|
||||
self.dirty = true;
|
||||
}
|
||||
|
@ -451,10 +529,12 @@ impl<W> DemoApp<W> where W: Window {
|
|||
}
|
||||
|
||||
if let DestFramebuffer::Other(scene_framebuffer) =
|
||||
self.renderer.replace_dest_framebuffer(DestFramebuffer::Default {
|
||||
self.renderer
|
||||
.replace_dest_framebuffer(DestFramebuffer::Default {
|
||||
viewport: self.window.viewport(View::Mono),
|
||||
window_size: self.window_size.device_size(),
|
||||
}) {
|
||||
})
|
||||
{
|
||||
self.scene_framebuffer = Some(scene_framebuffer);
|
||||
}
|
||||
}
|
||||
|
@ -466,18 +546,23 @@ impl<W> DemoApp<W> where W: Window {
|
|||
ref scene_transform,
|
||||
ref modelview_transform,
|
||||
..
|
||||
} if eye_transforms.len() > 1 => {
|
||||
(eye_transforms, scene_transform, modelview_transform)
|
||||
}
|
||||
} if eye_transforms.len() > 1 => (eye_transforms, scene_transform, modelview_transform),
|
||||
_ => return,
|
||||
};
|
||||
|
||||
debug!("scene_transform.perspective={:?}", scene_transform.perspective);
|
||||
debug!("scene_transform.modelview_to_eye={:?}", scene_transform.modelview_to_eye);
|
||||
debug!(
|
||||
"scene_transform.perspective={:?}",
|
||||
scene_transform.perspective
|
||||
);
|
||||
debug!(
|
||||
"scene_transform.modelview_to_eye={:?}",
|
||||
scene_transform.modelview_to_eye
|
||||
);
|
||||
debug!("modelview transform={:?}", modelview_transform);
|
||||
|
||||
let viewport = self.window.viewport(View::Stereo(render_scene_index));
|
||||
self.renderer.replace_dest_framebuffer(DestFramebuffer::Default {
|
||||
self.renderer
|
||||
.replace_dest_framebuffer(DestFramebuffer::Default {
|
||||
viewport,
|
||||
window_size: self.window_size.device_size(),
|
||||
});
|
||||
|
@ -495,35 +580,49 @@ impl<W> DemoApp<W> where W: Window {
|
|||
let scene_framebuffer = self.scene_framebuffer.as_ref().unwrap();
|
||||
let scene_texture = self.renderer.device.framebuffer_texture(scene_framebuffer);
|
||||
|
||||
let quad_scale_transform = Transform3DF32::from_scale(self.scene_view_box.size().x(),
|
||||
let quad_scale_transform = Transform3DF32::from_scale(
|
||||
self.scene_view_box.size().x(),
|
||||
self.scene_view_box.size().y(),
|
||||
1.0);
|
||||
1.0,
|
||||
);
|
||||
|
||||
let scene_transform_matrix = scene_transform.perspective
|
||||
let scene_transform_matrix = scene_transform
|
||||
.perspective
|
||||
.post_mul(&scene_transform.modelview_to_eye)
|
||||
.post_mul(&modelview_transform.to_transform())
|
||||
.post_mul(&quad_scale_transform);
|
||||
|
||||
let eye_transform = &eye_transforms[render_scene_index as usize];
|
||||
let eye_transform_matrix = eye_transform.perspective
|
||||
let eye_transform_matrix = eye_transform
|
||||
.perspective
|
||||
.post_mul(&eye_transform.modelview_to_eye)
|
||||
.post_mul(&modelview_transform.to_transform())
|
||||
.post_mul(&quad_scale_transform);
|
||||
|
||||
debug!("eye transform({}).modelview_to_eye={:?}",
|
||||
render_scene_index,
|
||||
eye_transform.modelview_to_eye);
|
||||
debug!("eye transform_matrix({})={:?}", render_scene_index, eye_transform_matrix);
|
||||
debug!(
|
||||
"eye transform({}).modelview_to_eye={:?}",
|
||||
render_scene_index, eye_transform.modelview_to_eye
|
||||
);
|
||||
debug!(
|
||||
"eye transform_matrix({})={:?}",
|
||||
render_scene_index, eye_transform_matrix
|
||||
);
|
||||
debug!("---");
|
||||
|
||||
self.renderer.reproject_texture(scene_texture,
|
||||
self.renderer.reproject_texture(
|
||||
scene_texture,
|
||||
&scene_transform_matrix.transform,
|
||||
&eye_transform_matrix.transform);
|
||||
&eye_transform_matrix.transform,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn finish_drawing_frame(&mut self) {
|
||||
if let Some(rendering_time) = self.renderer.shift_timer_query() {
|
||||
self.current_frame.as_mut().unwrap().scene_rendering_times.push(rendering_time);
|
||||
self.current_frame
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.scene_rendering_times
|
||||
.push(rendering_time);
|
||||
}
|
||||
|
||||
let tile_time = match self.scene_thread_proxy.receiver.recv().unwrap() {
|
||||
|
@ -544,15 +643,23 @@ impl<W> DemoApp<W> where W: Window {
|
|||
None
|
||||
} else {
|
||||
let zero = Duration::new(0, 0);
|
||||
Some(frame.scene_rendering_times.iter().fold(zero, |sum, item| sum + *item))
|
||||
Some(
|
||||
frame
|
||||
.scene_rendering_times
|
||||
.iter()
|
||||
.fold(zero, |sum, item| sum + *item),
|
||||
)
|
||||
};
|
||||
self.renderer.debug_ui.add_sample(aggregate_stats, tile_time, total_rendering_time);
|
||||
self.renderer
|
||||
.debug_ui
|
||||
.add_sample(aggregate_stats, tile_time, total_rendering_time);
|
||||
}
|
||||
|
||||
if self.options.ui != UIVisibility::None {
|
||||
let viewport = self.window.viewport(View::Mono);
|
||||
self.window.make_current(View::Mono);
|
||||
self.renderer.replace_dest_framebuffer(DestFramebuffer::Default {
|
||||
self.renderer
|
||||
.replace_dest_framebuffer(DestFramebuffer::Default {
|
||||
viewport,
|
||||
window_size: self.window_size.device_size(),
|
||||
});
|
||||
|
@ -564,16 +671,20 @@ impl<W> DemoApp<W> where W: Window {
|
|||
self.renderer.debug_ui.ui.event_queue.push(*ui_event);
|
||||
}
|
||||
|
||||
self.renderer.debug_ui.ui.mouse_position =
|
||||
self.last_mouse_position.to_f32().scale(self.window_size.backing_scale_factor);
|
||||
self.renderer.debug_ui.ui.mouse_position = self
|
||||
.last_mouse_position
|
||||
.to_f32()
|
||||
.scale(self.window_size.backing_scale_factor);
|
||||
self.ui.show_text_effects = self.monochrome_scene_color.is_some();
|
||||
|
||||
let mut ui_action = UIAction::None;
|
||||
if self.options.ui == UIVisibility::All {
|
||||
self.ui.update(&self.renderer.device,
|
||||
self.ui.update(
|
||||
&self.renderer.device,
|
||||
&mut self.window,
|
||||
&mut self.renderer.debug_ui,
|
||||
&mut ui_action);
|
||||
&mut ui_action,
|
||||
);
|
||||
}
|
||||
frame.ui_events = self.renderer.debug_ui.ui.event_queue.drain();
|
||||
self.handle_ui_action(&mut ui_action);
|
||||
|
@ -625,26 +736,36 @@ impl<W> DemoApp<W> where W: Window {
|
|||
base_transform = base_transform.post_mul(&Transform3DF32::from_translation(
|
||||
-0.5 * self.scene_view_box.max_x(),
|
||||
self.scene_view_box.max_y(),
|
||||
-0.5 * ground_scale));
|
||||
-0.5 * ground_scale,
|
||||
));
|
||||
|
||||
// Draw gridlines. Use the stencil buffer to avoid Z-fighting.
|
||||
let mut transform = base_transform;
|
||||
let gridline_scale = ground_scale / GRIDLINE_COUNT as f32;
|
||||
transform =
|
||||
transform.post_mul(&Transform3DF32::from_scale(gridline_scale, 1.0, gridline_scale));
|
||||
transform = transform.post_mul(&Transform3DF32::from_scale(
|
||||
gridline_scale,
|
||||
1.0,
|
||||
gridline_scale,
|
||||
));
|
||||
let device = &self.renderer.device;
|
||||
device.bind_vertex_array(&self.ground_line_vertex_array.vertex_array);
|
||||
device.use_program(&self.ground_program.program);
|
||||
device.set_uniform(&self.ground_program.transform_uniform, UniformData::Mat4([
|
||||
transform.c0,
|
||||
transform.c1,
|
||||
transform.c2,
|
||||
transform.c3,
|
||||
]));
|
||||
device.set_uniform(&self.ground_program.color_uniform,
|
||||
UniformData::Vec4(GROUND_LINE_COLOR.to_f32().0));
|
||||
device.draw_arrays(Primitive::Lines, (GRIDLINE_COUNT as u32 + 1) * 4, &RenderState {
|
||||
depth: Some(DepthState { func: DepthFunc::Always, write: true }),
|
||||
device.set_uniform(
|
||||
&self.ground_program.transform_uniform,
|
||||
UniformData::Mat4([transform.c0, transform.c1, transform.c2, transform.c3]),
|
||||
);
|
||||
device.set_uniform(
|
||||
&self.ground_program.color_uniform,
|
||||
UniformData::Vec4(GROUND_LINE_COLOR.to_f32().0),
|
||||
);
|
||||
device.draw_arrays(
|
||||
Primitive::Lines,
|
||||
(GRIDLINE_COUNT as u32 + 1) * 4,
|
||||
&RenderState {
|
||||
depth: Some(DepthState {
|
||||
func: DepthFunc::Always,
|
||||
write: true,
|
||||
}),
|
||||
stencil: Some(StencilState {
|
||||
func: StencilFunc::Always,
|
||||
reference: 2,
|
||||
|
@ -652,7 +773,8 @@ impl<W> DemoApp<W> where W: Window {
|
|||
write: true,
|
||||
}),
|
||||
..RenderState::default()
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
// Fill ground.
|
||||
let mut transform = base_transform;
|
||||
|
@ -660,12 +782,22 @@ impl<W> DemoApp<W> where W: Window {
|
|||
transform.post_mul(&Transform3DF32::from_scale(ground_scale, 1.0, ground_scale));
|
||||
device.bind_vertex_array(&self.ground_solid_vertex_array.vertex_array);
|
||||
device.use_program(&self.ground_program.program);
|
||||
device.set_uniform(&self.ground_program.transform_uniform,
|
||||
UniformData::from_transform_3d(&transform));
|
||||
device.set_uniform(&self.ground_program.color_uniform,
|
||||
UniformData::Vec4(GROUND_SOLID_COLOR.to_f32().0));
|
||||
device.draw_arrays(Primitive::TriangleFan, 4, &RenderState {
|
||||
depth: Some(DepthState { func: DepthFunc::Less, write: true }),
|
||||
device.set_uniform(
|
||||
&self.ground_program.transform_uniform,
|
||||
UniformData::from_transform_3d(&transform),
|
||||
);
|
||||
device.set_uniform(
|
||||
&self.ground_program.color_uniform,
|
||||
UniformData::Vec4(GROUND_SOLID_COLOR.to_f32().0),
|
||||
);
|
||||
device.draw_arrays(
|
||||
Primitive::TriangleFan,
|
||||
4,
|
||||
&RenderState {
|
||||
depth: Some(DepthState {
|
||||
func: DepthFunc::Less,
|
||||
write: true,
|
||||
}),
|
||||
stencil: Some(StencilState {
|
||||
func: StencilFunc::NotEqual,
|
||||
reference: 2,
|
||||
|
@ -673,7 +805,8 @@ impl<W> DemoApp<W> where W: Window {
|
|||
write: false,
|
||||
}),
|
||||
..RenderState::default()
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
fn render_vector_scene(&mut self) {
|
||||
|
@ -694,7 +827,7 @@ impl<W> DemoApp<W> where W: Window {
|
|||
Some(DEFRINGING_KERNEL_CORE_GRAPHICS)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -715,7 +848,11 @@ impl<W> DemoApp<W> where W: Window {
|
|||
}
|
||||
}
|
||||
|
||||
self.current_frame.as_mut().unwrap().scene_stats.push(self.renderer.stats);
|
||||
self.current_frame
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.scene_stats
|
||||
.push(self.renderer.stats);
|
||||
self.renderer.end_scene();
|
||||
}
|
||||
|
||||
|
@ -731,7 +868,8 @@ impl<W> DemoApp<W> where W: Window {
|
|||
if let Camera::TwoD(ref mut transform) = self.camera {
|
||||
let scale = Point2DF32::splat(1.0 + CAMERA_ZOOM_AMOUNT_2D);
|
||||
let center = center_of_window(&self.window_size);
|
||||
*transform = transform.post_translate(-center)
|
||||
*transform = transform
|
||||
.post_translate(-center)
|
||||
.post_scale(scale)
|
||||
.post_translate(center);
|
||||
self.dirty = true;
|
||||
|
@ -741,7 +879,8 @@ impl<W> DemoApp<W> where W: Window {
|
|||
if let Camera::TwoD(ref mut transform) = self.camera {
|
||||
let scale = Point2DF32::splat(1.0 - CAMERA_ZOOM_AMOUNT_2D);
|
||||
let center = center_of_window(&self.window_size);
|
||||
*transform = transform.post_translate(-center)
|
||||
*transform = transform
|
||||
.post_translate(-center)
|
||||
.post_scale(scale)
|
||||
.post_translate(center);
|
||||
self.dirty = true;
|
||||
|
@ -751,7 +890,8 @@ impl<W> DemoApp<W> where W: Window {
|
|||
if let Camera::TwoD(ref mut transform) = self.camera {
|
||||
let old_rotation = transform.rotation();
|
||||
let center = center_of_window(&self.window_size);
|
||||
*transform = transform.post_translate(-center)
|
||||
*transform = transform
|
||||
.post_translate(-center)
|
||||
.post_rotate(*theta - old_rotation)
|
||||
.post_translate(center);
|
||||
}
|
||||
|
@ -762,12 +902,18 @@ impl<W> DemoApp<W> where W: Window {
|
|||
fn take_screenshot(&mut self) {
|
||||
let screenshot_path = self.pending_screenshot_path.take().unwrap();
|
||||
let drawable_size = self.window_size.device_size();
|
||||
let pixels = self.renderer.device.read_pixels_from_default_framebuffer(drawable_size);
|
||||
image::save_buffer(screenshot_path,
|
||||
let pixels = self
|
||||
.renderer
|
||||
.device
|
||||
.read_pixels_from_default_framebuffer(drawable_size);
|
||||
image::save_buffer(
|
||||
screenshot_path,
|
||||
&pixels,
|
||||
drawable_size.x() as u32,
|
||||
drawable_size.y() as u32,
|
||||
ColorType::RGBA(8)).unwrap();
|
||||
ColorType::RGBA(8),
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
fn background_color(&self) -> ColorU {
|
||||
|
@ -790,15 +936,25 @@ impl SceneThreadProxy {
|
|||
let (scene_to_main_sender, scene_to_main_receiver) =
|
||||
mpsc::sync_channel(MAX_MESSAGES_IN_FLIGHT);
|
||||
SceneThread::new(scene, scene_to_main_sender, main_to_scene_receiver, options);
|
||||
SceneThreadProxy { sender: main_to_scene_sender, receiver: scene_to_main_receiver }
|
||||
SceneThreadProxy {
|
||||
sender: main_to_scene_sender,
|
||||
receiver: scene_to_main_receiver,
|
||||
}
|
||||
}
|
||||
|
||||
fn load_scene(&self, scene: Scene, view_box_size: Point2DI32) {
|
||||
self.sender.send(MainToSceneMsg::LoadScene { scene, view_box_size }).unwrap();
|
||||
self.sender
|
||||
.send(MainToSceneMsg::LoadScene {
|
||||
scene,
|
||||
view_box_size,
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
fn set_drawable_size(&self, drawable_size: Point2DI32) {
|
||||
self.sender.send(MainToSceneMsg::SetDrawableSize(drawable_size)).unwrap();
|
||||
self.sender
|
||||
.send(MainToSceneMsg::SetDrawableSize(drawable_size))
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -810,32 +966,54 @@ struct SceneThread {
|
|||
}
|
||||
|
||||
impl SceneThread {
|
||||
fn new(scene: Scene,
|
||||
fn new(
|
||||
scene: Scene,
|
||||
sender: SyncSender<SceneToMainMsg>,
|
||||
receiver: Receiver<MainToSceneMsg>,
|
||||
options: Options) {
|
||||
thread::spawn(move || (SceneThread { scene, sender, receiver, options }).run());
|
||||
options: Options,
|
||||
) {
|
||||
thread::spawn(move || {
|
||||
(SceneThread {
|
||||
scene,
|
||||
sender,
|
||||
receiver,
|
||||
options,
|
||||
})
|
||||
.run()
|
||||
});
|
||||
}
|
||||
|
||||
fn run(mut self) {
|
||||
while let Ok(msg) = self.receiver.recv() {
|
||||
match msg {
|
||||
MainToSceneMsg::LoadScene { scene, view_box_size } => {
|
||||
MainToSceneMsg::LoadScene {
|
||||
scene,
|
||||
view_box_size,
|
||||
} => {
|
||||
self.scene = scene;
|
||||
self.scene.view_box = RectF32::new(Point2DF32::default(),
|
||||
view_box_size.to_f32());
|
||||
self.scene.view_box =
|
||||
RectF32::new(Point2DF32::default(), view_box_size.to_f32());
|
||||
}
|
||||
MainToSceneMsg::SetDrawableSize(size) => {
|
||||
self.scene.view_box = RectF32::new(Point2DF32::default(), size.to_f32());
|
||||
}
|
||||
MainToSceneMsg::Build(build_options) => {
|
||||
self.sender.send(SceneToMainMsg::BeginFrame {
|
||||
self.sender
|
||||
.send(SceneToMainMsg::BeginFrame {
|
||||
transform: build_options.render_transform.clone(),
|
||||
}).unwrap();
|
||||
})
|
||||
.unwrap();
|
||||
let start_time = Instant::now();
|
||||
build_scene(&self.scene, &build_options, self.options.jobs, &mut self.sender);
|
||||
build_scene(
|
||||
&self.scene,
|
||||
&build_options,
|
||||
self.options.jobs,
|
||||
&mut self.sender,
|
||||
);
|
||||
let tile_time = Instant::now() - start_time;
|
||||
self.sender.send(SceneToMainMsg::EndFrame { tile_time }).unwrap();
|
||||
self.sender
|
||||
.send(SceneToMainMsg::EndFrame { tile_time })
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -844,7 +1022,10 @@ impl SceneThread {
|
|||
|
||||
#[derive(Clone)]
|
||||
enum MainToSceneMsg {
|
||||
LoadScene { scene: Scene, view_box_size: Point2DI32 },
|
||||
LoadScene {
|
||||
scene: Scene,
|
||||
view_box_size: Point2DI32,
|
||||
},
|
||||
SetDrawableSize(Point2DI32),
|
||||
Build(BuildOptions),
|
||||
}
|
||||
|
@ -877,10 +1058,12 @@ impl Debug for SceneToMainMsg {
|
|||
}
|
||||
}
|
||||
|
||||
fn build_scene(scene: &Scene,
|
||||
fn build_scene(
|
||||
scene: &Scene,
|
||||
build_options: &BuildOptions,
|
||||
jobs: Option<usize>,
|
||||
sink: &mut SyncSender<SceneToMainMsg>) {
|
||||
sink: &mut SyncSender<SceneToMainMsg>,
|
||||
) {
|
||||
let render_options = RenderOptions {
|
||||
transform: build_options.render_transform.clone(),
|
||||
dilation: match build_options.stem_darkening_font_size {
|
||||
|
@ -894,14 +1077,16 @@ fn build_scene(scene: &Scene,
|
|||
};
|
||||
|
||||
let built_options = render_options.prepare(scene.bounds);
|
||||
sink.send(SceneToMainMsg::BeginRenderScene(scene.build_descriptor(&built_options))).unwrap();
|
||||
sink.send(SceneToMainMsg::BeginRenderScene(
|
||||
scene.build_descriptor(&built_options),
|
||||
))
|
||||
.unwrap();
|
||||
|
||||
let inner_sink = AssertUnwindSafe(sink.clone());
|
||||
let result = panic::catch_unwind(move || {
|
||||
let sink = (*inner_sink).clone();
|
||||
let listener = Box::new(move |command| {
|
||||
sink.send(SceneToMainMsg::Execute(command)).unwrap()
|
||||
});
|
||||
let listener =
|
||||
Box::new(move |command| sink.send(SceneToMainMsg::Execute(command)).unwrap());
|
||||
|
||||
let mut scene_builder = SceneBuilder::new(scene, &built_options, listener);
|
||||
match jobs {
|
||||
|
@ -953,8 +1138,20 @@ impl Options {
|
|||
.takes_value(true)
|
||||
.help("Number of threads to use"),
|
||||
)
|
||||
.arg(Arg::with_name("3d").short("3").long("3d").help("Run in 3D").conflicts_with("vr"))
|
||||
.arg(Arg::with_name("vr").short("V").long("vr").help("Run in VR").conflicts_with("3d"))
|
||||
.arg(
|
||||
Arg::with_name("3d")
|
||||
.short("3")
|
||||
.long("3d")
|
||||
.help("Run in 3D")
|
||||
.conflicts_with("vr"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("vr")
|
||||
.short("V")
|
||||
.long("vr")
|
||||
.help("Run in VR")
|
||||
.conflicts_with("3d"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("ui")
|
||||
.short("u")
|
||||
|
@ -971,7 +1168,11 @@ impl Options {
|
|||
.possible_values(&["light", "dark", "transparent"])
|
||||
.help("The background color to use"),
|
||||
)
|
||||
.arg(Arg::with_name("INPUT").help("Path to the SVG file to render").index(1))
|
||||
.arg(
|
||||
Arg::with_name("INPUT")
|
||||
.help("Path to the SVG file to render")
|
||||
.index(1),
|
||||
)
|
||||
.get_matches();
|
||||
|
||||
if let Some(jobs) = matches.value_of("jobs") {
|
||||
|
@ -1005,8 +1206,10 @@ impl Options {
|
|||
};
|
||||
}
|
||||
|
||||
fn adjust_thread_pool_settings(&self, mut thread_pool_builder: ThreadPoolBuilder)
|
||||
-> ThreadPoolBuilder {
|
||||
fn adjust_thread_pool_settings(
|
||||
&self,
|
||||
mut thread_pool_builder: ThreadPoolBuilder,
|
||||
) -> ThreadPoolBuilder {
|
||||
if let Some(jobs) = self.jobs {
|
||||
thread_pool_builder = thread_pool_builder.num_threads(jobs);
|
||||
}
|
||||
|
@ -1023,11 +1226,17 @@ pub enum Mode {
|
|||
|
||||
impl Mode {
|
||||
pub fn viewport_count(self) -> usize {
|
||||
match self { Mode::TwoD | Mode::ThreeD => 1, Mode::VR => 2 }
|
||||
match self {
|
||||
Mode::TwoD | Mode::ThreeD => 1,
|
||||
Mode::VR => 2,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn view(self, viewport: u32) -> View {
|
||||
match self { Mode::TwoD | Mode::ThreeD => View::Mono, Mode::VR => View::Stereo(viewport) }
|
||||
match self {
|
||||
Mode::TwoD | Mode::ThreeD => View::Mono,
|
||||
Mode::VR => View::Stereo(viewport),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1083,8 +1292,8 @@ impl Camera {
|
|||
}
|
||||
|
||||
fn new_2d(view_box: RectF32, viewport_size: Point2DI32) -> Camera {
|
||||
let scale = i32::min(viewport_size.x(), viewport_size.y()) as f32 *
|
||||
scale_factor_for_view_box(view_box);
|
||||
let scale = i32::min(viewport_size.x(), viewport_size.y()) as f32
|
||||
* scale_factor_for_view_box(view_box);
|
||||
let origin = viewport_size.to_f32().scale(0.5) - view_box.size().scale(scale * 0.5);
|
||||
Camera::TwoD(Transform2DF32::from_scale(&Point2DF32::splat(scale)).post_translate(origin))
|
||||
}
|
||||
|
@ -1094,10 +1303,8 @@ impl Camera {
|
|||
|
||||
let fov_y = FRAC_PI_4;
|
||||
let aspect = viewport_size.x() as f32 / viewport_size.y() as f32;
|
||||
let projection = Transform3DF32::from_perspective(fov_y,
|
||||
aspect,
|
||||
NEAR_CLIP_PLANE,
|
||||
FAR_CLIP_PLANE);
|
||||
let projection =
|
||||
Transform3DF32::from_perspective(fov_y, aspect, NEAR_CLIP_PLANE, FAR_CLIP_PLANE);
|
||||
let perspective = Perspective::new(&projection, viewport_size);
|
||||
|
||||
// Create a scene transform by moving the camera back from the center of the eyes so that
|
||||
|
@ -1110,13 +1317,19 @@ impl Camera {
|
|||
|
||||
// For now, initialize the eye transforms as copies of the scene transform.
|
||||
let eye_offset = DEFAULT_EYE_OFFSET;
|
||||
let eye_transforms = (0..viewport_count).map(|viewport_index| {
|
||||
let this_eye_offset = if viewport_index == 0 { eye_offset } else { -eye_offset };
|
||||
let eye_transforms = (0..viewport_count)
|
||||
.map(|viewport_index| {
|
||||
let this_eye_offset = if viewport_index == 0 {
|
||||
eye_offset
|
||||
} else {
|
||||
-eye_offset
|
||||
};
|
||||
OcularTransform {
|
||||
perspective,
|
||||
modelview_to_eye: Transform3DF32::from_translation(this_eye_offset, 0.0, 0.0),
|
||||
}
|
||||
}).collect();
|
||||
})
|
||||
.collect();
|
||||
|
||||
Camera::ThreeD {
|
||||
scene_transform,
|
||||
|
@ -1127,12 +1340,17 @@ impl Camera {
|
|||
}
|
||||
|
||||
fn is_3d(&self) -> bool {
|
||||
match *self { Camera::ThreeD { .. } => true, Camera::TwoD { .. } => false }
|
||||
match *self {
|
||||
Camera::ThreeD { .. } => true,
|
||||
Camera::TwoD { .. } => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn mode(&self) -> Mode {
|
||||
match *self {
|
||||
Camera::ThreeD { ref eye_transforms, .. } if eye_transforms.len() >= 2 => Mode::VR,
|
||||
Camera::ThreeD {
|
||||
ref eye_transforms, ..
|
||||
} if eye_transforms.len() >= 2 => Mode::VR,
|
||||
Camera::ThreeD { .. } => Mode::ThreeD,
|
||||
Camera::TwoD { .. } => Mode::TwoD,
|
||||
}
|
||||
|
@ -1151,10 +1369,12 @@ impl CameraTransform3D {
|
|||
fn new(view_box: RectF32) -> CameraTransform3D {
|
||||
let scale = scale_factor_for_view_box(view_box);
|
||||
CameraTransform3D {
|
||||
position: Point3DF32::new(0.5 * view_box.max_x(),
|
||||
position: Point3DF32::new(
|
||||
0.5 * view_box.max_x(),
|
||||
-0.5 * view_box.max_y(),
|
||||
1.5 / scale,
|
||||
1.0),
|
||||
1.0,
|
||||
),
|
||||
yaw: 0.0,
|
||||
pitch: 0.0,
|
||||
scale,
|
||||
|
@ -1173,9 +1393,11 @@ impl CameraTransform3D {
|
|||
fn to_transform(&self) -> Transform3DF32 {
|
||||
let mut transform = Transform3DF32::from_rotation(self.yaw, self.pitch, 0.0);
|
||||
transform = transform.post_mul(&Transform3DF32::from_uniform_scale(2.0 * self.scale));
|
||||
transform = transform.post_mul(&Transform3DF32::from_translation(-self.position.x(),
|
||||
transform = transform.post_mul(&Transform3DF32::from_translation(
|
||||
-self.position.x(),
|
||||
-self.position.y(),
|
||||
-self.position.z()));
|
||||
-self.position.z(),
|
||||
));
|
||||
|
||||
// Flip Y.
|
||||
transform = transform.post_mul(&Transform3DF32::from_scale(1.0, -1.0, 1.0));
|
||||
|
@ -1192,14 +1414,20 @@ fn get_svg_building_message(built_svg: &BuiltSVG) -> String {
|
|||
if built_svg.result_flags.is_empty() {
|
||||
return String::new();
|
||||
}
|
||||
format!("Warning: These features in the SVG are unsupported: {}.", built_svg.result_flags)
|
||||
format!(
|
||||
"Warning: These features in the SVG are unsupported: {}.",
|
||||
built_svg.result_flags
|
||||
)
|
||||
}
|
||||
|
||||
fn emit_message<W>(ui: &mut DemoUI<GLDevice>,
|
||||
fn emit_message<W>(
|
||||
ui: &mut DemoUI<GLDevice>,
|
||||
message_epoch: &mut u32,
|
||||
expire_message_event_id: u32,
|
||||
message: String)
|
||||
where W: Window {
|
||||
message: String,
|
||||
) where
|
||||
W: Window,
|
||||
{
|
||||
if message.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
@ -1222,7 +1450,12 @@ struct Frame {
|
|||
|
||||
impl Frame {
|
||||
fn new(transform: RenderTransform, ui_events: Vec<UIEvent>) -> Frame {
|
||||
Frame { transform, ui_events, scene_rendering_times: vec![], scene_stats: vec![] }
|
||||
Frame {
|
||||
transform,
|
||||
ui_events,
|
||||
scene_rendering_times: vec![],
|
||||
scene_stats: vec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,12 +8,12 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use crate::{BackgroundColor, Mode, Options};
|
||||
use crate::window::Window;
|
||||
use crate::{BackgroundColor, Mode, Options};
|
||||
use pathfinder_geometry::basic::point::Point2DI32;
|
||||
use pathfinder_geometry::basic::rect::RectI32;
|
||||
use pathfinder_gpu::Device;
|
||||
use pathfinder_gpu::resources::ResourceLoader;
|
||||
use pathfinder_gpu::Device;
|
||||
use pathfinder_renderer::gpu::debug::DebugUI;
|
||||
use pathfinder_ui::{BUTTON_HEIGHT, BUTTON_TEXT_OFFSET, BUTTON_WIDTH, FONT_ASCENT, PADDING};
|
||||
use pathfinder_ui::{TEXT_COLOR, TOOLTIP_HEIGHT, WINDOW_COLOR};
|
||||
|
@ -43,7 +43,10 @@ static ZOOM_OUT_PNG_NAME: &'static str = "demo-zoom-out";
|
|||
static BACKGROUND_PNG_NAME: &'static str = "demo-background";
|
||||
static SCREENSHOT_PNG_NAME: &'static str = "demo-screenshot";
|
||||
|
||||
pub struct DemoUI<D> where D: Device {
|
||||
pub struct DemoUI<D>
|
||||
where
|
||||
D: Device,
|
||||
{
|
||||
effects_texture: D::Texture,
|
||||
open_texture: D::Texture,
|
||||
rotate_texture: D::Texture,
|
||||
|
@ -57,7 +60,6 @@ pub struct DemoUI<D> where D: Device {
|
|||
rotate_panel_visible: bool,
|
||||
|
||||
// FIXME(pcwalton): Factor the below out into a model class.
|
||||
|
||||
pub mode: Mode,
|
||||
pub background_color: BackgroundColor,
|
||||
pub gamma_correction_effect_enabled: bool,
|
||||
|
@ -68,7 +70,10 @@ pub struct DemoUI<D> where D: Device {
|
|||
pub show_text_effects: bool,
|
||||
}
|
||||
|
||||
impl<D> DemoUI<D> where D: Device {
|
||||
impl<D> DemoUI<D>
|
||||
where
|
||||
D: Device,
|
||||
{
|
||||
pub fn new(device: &D, resources: &dyn ResourceLoader, options: Options) -> DemoUI<D> {
|
||||
let effects_texture = device.create_texture_from_png(resources, EFFECTS_PNG_NAME);
|
||||
let open_texture = device.create_texture_from_png(resources, OPEN_PNG_NAME);
|
||||
|
@ -106,12 +111,15 @@ impl<D> DemoUI<D> where D: Device {
|
|||
(self.rotation as f32 / SLIDER_WIDTH as f32 * 2.0 - 1.0) * PI
|
||||
}
|
||||
|
||||
pub fn update<W>(&mut self,
|
||||
pub fn update<W>(
|
||||
&mut self,
|
||||
device: &D,
|
||||
window: &mut W,
|
||||
debug_ui: &mut DebugUI<D>,
|
||||
action: &mut UIAction)
|
||||
where W: Window {
|
||||
action: &mut UIAction,
|
||||
) where
|
||||
W: Window,
|
||||
{
|
||||
// Draw message text.
|
||||
|
||||
self.draw_message_text(device, debug_ui);
|
||||
|
@ -125,42 +133,59 @@ impl<D> DemoUI<D> where D: Device {
|
|||
|
||||
// Draw text effects button.
|
||||
if self.show_text_effects {
|
||||
if debug_ui.ui.draw_button(device, position, &self.effects_texture) {
|
||||
if debug_ui
|
||||
.ui
|
||||
.draw_button(device, position, &self.effects_texture)
|
||||
{
|
||||
self.effects_panel_visible = !self.effects_panel_visible;
|
||||
}
|
||||
if !self.effects_panel_visible {
|
||||
debug_ui.ui.draw_tooltip(device,
|
||||
debug_ui.ui.draw_tooltip(
|
||||
device,
|
||||
"Text Effects",
|
||||
RectI32::new(position, button_size));
|
||||
RectI32::new(position, button_size),
|
||||
);
|
||||
}
|
||||
position += Point2DI32::new(button_size.x() + PADDING, 0);
|
||||
}
|
||||
|
||||
// Draw open button.
|
||||
if debug_ui.ui.draw_button(device, position, &self.open_texture) {
|
||||
if debug_ui
|
||||
.ui
|
||||
.draw_button(device, position, &self.open_texture)
|
||||
{
|
||||
// FIXME(pcwalton): This is not sufficient for Android, where we will need to take in
|
||||
// the contents of the file.
|
||||
window.present_open_svg_dialog();
|
||||
}
|
||||
debug_ui.ui.draw_tooltip(device, "Open SVG", RectI32::new(position, button_size));
|
||||
debug_ui
|
||||
.ui
|
||||
.draw_tooltip(device, "Open SVG", RectI32::new(position, button_size));
|
||||
position += Point2DI32::new(BUTTON_WIDTH + PADDING, 0);
|
||||
|
||||
// Draw screenshot button.
|
||||
if debug_ui.ui.draw_button(device, position, &self.screenshot_texture) {
|
||||
if debug_ui
|
||||
.ui
|
||||
.draw_button(device, position, &self.screenshot_texture)
|
||||
{
|
||||
// FIXME(pcwalton): This is not sufficient for Android, where we will need to take in
|
||||
// the contents of the file.
|
||||
if let Ok(file) = window.run_save_dialog("png") {
|
||||
*action = UIAction::TakeScreenshot(file);
|
||||
}
|
||||
}
|
||||
debug_ui.ui.draw_tooltip(device, "Take Screenshot", RectI32::new(position, button_size));
|
||||
debug_ui.ui.draw_tooltip(
|
||||
device,
|
||||
"Take Screenshot",
|
||||
RectI32::new(position, button_size),
|
||||
);
|
||||
position += Point2DI32::new(BUTTON_WIDTH + PADDING, 0);
|
||||
|
||||
// Draw mode switch.
|
||||
let new_mode = debug_ui.ui.draw_text_switch(device,
|
||||
position,
|
||||
&["2D", "3D", "VR"],
|
||||
self.mode as u8);
|
||||
let new_mode =
|
||||
debug_ui
|
||||
.ui
|
||||
.draw_text_switch(device, position, &["2D", "3D", "VR"], self.mode as u8);
|
||||
if new_mode != self.mode as u8 {
|
||||
self.mode = match new_mode {
|
||||
0 => Mode::TwoD,
|
||||
|
@ -172,19 +197,26 @@ impl<D> DemoUI<D> where D: Device {
|
|||
|
||||
let mode_switch_width = debug_ui.ui.measure_switch(3);
|
||||
let mode_switch_size = Point2DI32::new(mode_switch_width, BUTTON_HEIGHT);
|
||||
debug_ui.ui.draw_tooltip(device,
|
||||
debug_ui.ui.draw_tooltip(
|
||||
device,
|
||||
"2D/3D/VR Mode",
|
||||
RectI32::new(position, mode_switch_size));
|
||||
RectI32::new(position, mode_switch_size),
|
||||
);
|
||||
position += Point2DI32::new(mode_switch_width + PADDING, 0);
|
||||
|
||||
// Draw background switch.
|
||||
if debug_ui.ui.draw_button(device, position, &self.background_texture) {
|
||||
if debug_ui
|
||||
.ui
|
||||
.draw_button(device, position, &self.background_texture)
|
||||
{
|
||||
self.background_panel_visible = !self.background_panel_visible;
|
||||
}
|
||||
if !self.background_panel_visible {
|
||||
debug_ui.ui.draw_tooltip(device,
|
||||
debug_ui.ui.draw_tooltip(
|
||||
device,
|
||||
"Background Color",
|
||||
RectI32::new(position, button_size));
|
||||
RectI32::new(position, button_size),
|
||||
);
|
||||
}
|
||||
|
||||
// Draw background panel, if necessary.
|
||||
|
@ -199,25 +231,40 @@ impl<D> DemoUI<D> where D: Device {
|
|||
return;
|
||||
}
|
||||
|
||||
if debug_ui.ui.draw_button(device, position, &self.rotate_texture) {
|
||||
if debug_ui
|
||||
.ui
|
||||
.draw_button(device, position, &self.rotate_texture)
|
||||
{
|
||||
self.rotate_panel_visible = !self.rotate_panel_visible;
|
||||
}
|
||||
if !self.rotate_panel_visible {
|
||||
debug_ui.ui.draw_tooltip(device, "Rotate", RectI32::new(position, button_size));
|
||||
debug_ui
|
||||
.ui
|
||||
.draw_tooltip(device, "Rotate", RectI32::new(position, button_size));
|
||||
}
|
||||
self.draw_rotate_panel(device, debug_ui, position.x(), action);
|
||||
position += Point2DI32::new(BUTTON_WIDTH + PADDING, 0);
|
||||
|
||||
if debug_ui.ui.draw_button(device, position, &self.zoom_in_texture) {
|
||||
if debug_ui
|
||||
.ui
|
||||
.draw_button(device, position, &self.zoom_in_texture)
|
||||
{
|
||||
*action = UIAction::ZoomIn;
|
||||
}
|
||||
debug_ui.ui.draw_tooltip(device, "Zoom In", RectI32::new(position, button_size));
|
||||
debug_ui
|
||||
.ui
|
||||
.draw_tooltip(device, "Zoom In", RectI32::new(position, button_size));
|
||||
position += Point2DI32::new(BUTTON_WIDTH + PADDING, 0);
|
||||
|
||||
if debug_ui.ui.draw_button(device, position, &self.zoom_out_texture) {
|
||||
if debug_ui
|
||||
.ui
|
||||
.draw_button(device, position, &self.zoom_out_texture)
|
||||
{
|
||||
*action = UIAction::ZoomOut;
|
||||
}
|
||||
debug_ui.ui.draw_tooltip(device, "Zoom Out", RectI32::new(position, button_size));
|
||||
debug_ui
|
||||
.ui
|
||||
.draw_tooltip(device, "Zoom Out", RectI32::new(position, button_size));
|
||||
position += Point2DI32::new(BUTTON_WIDTH + PADDING, 0);
|
||||
}
|
||||
|
||||
|
@ -229,13 +276,17 @@ impl<D> DemoUI<D> where D: Device {
|
|||
let message_size = debug_ui.ui.measure_text(&self.message);
|
||||
let window_origin = Point2DI32::new(PADDING, PADDING);
|
||||
let window_size = Point2DI32::new(PADDING * 2 + message_size, TOOLTIP_HEIGHT);
|
||||
debug_ui.ui.draw_solid_rounded_rect(device,
|
||||
debug_ui.ui.draw_solid_rounded_rect(
|
||||
device,
|
||||
RectI32::new(window_origin, window_size),
|
||||
WINDOW_COLOR);
|
||||
debug_ui.ui.draw_text(device,
|
||||
WINDOW_COLOR,
|
||||
);
|
||||
debug_ui.ui.draw_text(
|
||||
device,
|
||||
&self.message,
|
||||
window_origin + Point2DI32::new(PADDING, PADDING + FONT_ASCENT),
|
||||
false);
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
fn draw_effects_panel(&mut self, device: &D, debug_ui: &mut DebugUI<D>) {
|
||||
|
@ -245,40 +296,48 @@ impl<D> DemoUI<D> where D: Device {
|
|||
|
||||
let bottom = debug_ui.ui.framebuffer_size().y() - PADDING;
|
||||
let effects_panel_y = bottom - (BUTTON_HEIGHT + PADDING + EFFECTS_PANEL_HEIGHT);
|
||||
debug_ui.ui.draw_solid_rounded_rect(device,
|
||||
RectI32::new(Point2DI32::new(PADDING, effects_panel_y),
|
||||
Point2DI32::new(EFFECTS_PANEL_WIDTH,
|
||||
EFFECTS_PANEL_HEIGHT)),
|
||||
WINDOW_COLOR);
|
||||
debug_ui.ui.draw_solid_rounded_rect(
|
||||
device,
|
||||
RectI32::new(
|
||||
Point2DI32::new(PADDING, effects_panel_y),
|
||||
Point2DI32::new(EFFECTS_PANEL_WIDTH, EFFECTS_PANEL_HEIGHT),
|
||||
),
|
||||
WINDOW_COLOR,
|
||||
);
|
||||
|
||||
self.gamma_correction_effect_enabled =
|
||||
self.draw_effects_switch(device,
|
||||
self.gamma_correction_effect_enabled = self.draw_effects_switch(
|
||||
device,
|
||||
debug_ui,
|
||||
"Gamma Correction",
|
||||
0,
|
||||
effects_panel_y,
|
||||
self.gamma_correction_effect_enabled);
|
||||
self.stem_darkening_effect_enabled =
|
||||
self.draw_effects_switch(device,
|
||||
self.gamma_correction_effect_enabled,
|
||||
);
|
||||
self.stem_darkening_effect_enabled = self.draw_effects_switch(
|
||||
device,
|
||||
debug_ui,
|
||||
"Stem Darkening",
|
||||
1,
|
||||
effects_panel_y,
|
||||
self.stem_darkening_effect_enabled);
|
||||
self.subpixel_aa_effect_enabled =
|
||||
self.draw_effects_switch(device,
|
||||
self.stem_darkening_effect_enabled,
|
||||
);
|
||||
self.subpixel_aa_effect_enabled = self.draw_effects_switch(
|
||||
device,
|
||||
debug_ui,
|
||||
"Subpixel AA",
|
||||
2,
|
||||
effects_panel_y,
|
||||
self.subpixel_aa_effect_enabled);
|
||||
self.subpixel_aa_effect_enabled,
|
||||
);
|
||||
}
|
||||
|
||||
fn draw_background_panel(&mut self,
|
||||
fn draw_background_panel(
|
||||
&mut self,
|
||||
device: &D,
|
||||
debug_ui: &mut DebugUI<D>,
|
||||
panel_x: i32,
|
||||
action: &mut UIAction) {
|
||||
action: &mut UIAction,
|
||||
) {
|
||||
if !self.background_panel_visible {
|
||||
return;
|
||||
}
|
||||
|
@ -286,34 +345,45 @@ impl<D> DemoUI<D> where D: Device {
|
|||
let bottom = debug_ui.ui.framebuffer_size().y() - PADDING;
|
||||
let panel_y = bottom - (BUTTON_HEIGHT + PADDING + BACKGROUND_PANEL_HEIGHT);
|
||||
let panel_position = Point2DI32::new(panel_x, panel_y);
|
||||
debug_ui.ui.draw_solid_rounded_rect(device,
|
||||
RectI32::new(panel_position,
|
||||
Point2DI32::new(BACKGROUND_PANEL_WIDTH,
|
||||
BACKGROUND_PANEL_HEIGHT)),
|
||||
WINDOW_COLOR);
|
||||
debug_ui.ui.draw_solid_rounded_rect(
|
||||
device,
|
||||
RectI32::new(
|
||||
panel_position,
|
||||
Point2DI32::new(BACKGROUND_PANEL_WIDTH, BACKGROUND_PANEL_HEIGHT),
|
||||
),
|
||||
WINDOW_COLOR,
|
||||
);
|
||||
|
||||
self.draw_background_menu_item(device,
|
||||
self.draw_background_menu_item(
|
||||
device,
|
||||
debug_ui,
|
||||
BackgroundColor::Light,
|
||||
panel_position,
|
||||
action);
|
||||
self.draw_background_menu_item(device,
|
||||
action,
|
||||
);
|
||||
self.draw_background_menu_item(
|
||||
device,
|
||||
debug_ui,
|
||||
BackgroundColor::Dark,
|
||||
panel_position,
|
||||
action);
|
||||
self.draw_background_menu_item(device,
|
||||
action,
|
||||
);
|
||||
self.draw_background_menu_item(
|
||||
device,
|
||||
debug_ui,
|
||||
BackgroundColor::Transparent,
|
||||
panel_position,
|
||||
action);
|
||||
action,
|
||||
);
|
||||
}
|
||||
|
||||
fn draw_rotate_panel(&mut self,
|
||||
fn draw_rotate_panel(
|
||||
&mut self,
|
||||
device: &D,
|
||||
debug_ui: &mut DebugUI<D>,
|
||||
rotate_panel_x: i32,
|
||||
action: &mut UIAction) {
|
||||
action: &mut UIAction,
|
||||
) {
|
||||
if !self.rotate_panel_visible {
|
||||
return;
|
||||
}
|
||||
|
@ -322,40 +392,54 @@ impl<D> DemoUI<D> where D: Device {
|
|||
let rotate_panel_y = bottom - (BUTTON_HEIGHT + PADDING + ROTATE_PANEL_HEIGHT);
|
||||
let rotate_panel_origin = Point2DI32::new(rotate_panel_x, rotate_panel_y);
|
||||
let rotate_panel_size = Point2DI32::new(ROTATE_PANEL_WIDTH, ROTATE_PANEL_HEIGHT);
|
||||
debug_ui.ui.draw_solid_rounded_rect(device,
|
||||
debug_ui.ui.draw_solid_rounded_rect(
|
||||
device,
|
||||
RectI32::new(rotate_panel_origin, rotate_panel_size),
|
||||
WINDOW_COLOR);
|
||||
WINDOW_COLOR,
|
||||
);
|
||||
|
||||
let (widget_x, widget_y) = (rotate_panel_x + PADDING, rotate_panel_y + PADDING);
|
||||
let widget_rect = RectI32::new(Point2DI32::new(widget_x, widget_y),
|
||||
Point2DI32::new(SLIDER_WIDTH, SLIDER_KNOB_HEIGHT));
|
||||
if let Some(position) = debug_ui.ui
|
||||
let widget_rect = RectI32::new(
|
||||
Point2DI32::new(widget_x, widget_y),
|
||||
Point2DI32::new(SLIDER_WIDTH, SLIDER_KNOB_HEIGHT),
|
||||
);
|
||||
if let Some(position) = debug_ui
|
||||
.ui
|
||||
.event_queue
|
||||
.handle_mouse_down_or_dragged_in_rect(widget_rect) {
|
||||
.handle_mouse_down_or_dragged_in_rect(widget_rect)
|
||||
{
|
||||
self.rotation = position.x();
|
||||
*action = UIAction::Rotate(self.rotation());
|
||||
}
|
||||
|
||||
let slider_track_y = rotate_panel_y + PADDING + SLIDER_KNOB_HEIGHT / 2 -
|
||||
SLIDER_TRACK_HEIGHT / 2;
|
||||
let slider_track_rect =
|
||||
RectI32::new(Point2DI32::new(widget_x, slider_track_y),
|
||||
Point2DI32::new(SLIDER_WIDTH, SLIDER_TRACK_HEIGHT));
|
||||
debug_ui.ui.draw_rect_outline(device, slider_track_rect, TEXT_COLOR);
|
||||
let slider_track_y =
|
||||
rotate_panel_y + PADDING + SLIDER_KNOB_HEIGHT / 2 - SLIDER_TRACK_HEIGHT / 2;
|
||||
let slider_track_rect = RectI32::new(
|
||||
Point2DI32::new(widget_x, slider_track_y),
|
||||
Point2DI32::new(SLIDER_WIDTH, SLIDER_TRACK_HEIGHT),
|
||||
);
|
||||
debug_ui
|
||||
.ui
|
||||
.draw_rect_outline(device, slider_track_rect, TEXT_COLOR);
|
||||
|
||||
let slider_knob_x = widget_x + self.rotation - SLIDER_KNOB_WIDTH / 2;
|
||||
let slider_knob_rect =
|
||||
RectI32::new(Point2DI32::new(slider_knob_x, widget_y),
|
||||
Point2DI32::new(SLIDER_KNOB_WIDTH, SLIDER_KNOB_HEIGHT));
|
||||
debug_ui.ui.draw_solid_rect(device, slider_knob_rect, TEXT_COLOR);
|
||||
let slider_knob_rect = RectI32::new(
|
||||
Point2DI32::new(slider_knob_x, widget_y),
|
||||
Point2DI32::new(SLIDER_KNOB_WIDTH, SLIDER_KNOB_HEIGHT),
|
||||
);
|
||||
debug_ui
|
||||
.ui
|
||||
.draw_solid_rect(device, slider_knob_rect, TEXT_COLOR);
|
||||
}
|
||||
|
||||
fn draw_background_menu_item(&mut self,
|
||||
fn draw_background_menu_item(
|
||||
&mut self,
|
||||
device: &D,
|
||||
debug_ui: &mut DebugUI<D>,
|
||||
color: BackgroundColor,
|
||||
panel_position: Point2DI32,
|
||||
action: &mut UIAction) {
|
||||
action: &mut UIAction,
|
||||
) {
|
||||
let (text, index) = (color.as_str(), color as i32);
|
||||
|
||||
let widget_size = Point2DI32::new(BACKGROUND_PANEL_WIDTH, BUTTON_HEIGHT);
|
||||
|
@ -363,36 +447,50 @@ impl<D> DemoUI<D> where D: Device {
|
|||
let widget_rect = RectI32::new(widget_origin, widget_size);
|
||||
|
||||
if color == self.background_color {
|
||||
debug_ui.ui.draw_solid_rounded_rect(device, widget_rect, TEXT_COLOR);
|
||||
debug_ui
|
||||
.ui
|
||||
.draw_solid_rounded_rect(device, widget_rect, TEXT_COLOR);
|
||||
}
|
||||
|
||||
let (text_x, text_y) = (PADDING * 2, BUTTON_TEXT_OFFSET);
|
||||
let text_position = widget_origin + Point2DI32::new(text_x, text_y);
|
||||
debug_ui.ui.draw_text(device, text, text_position, color == self.background_color);
|
||||
debug_ui
|
||||
.ui
|
||||
.draw_text(device, text, text_position, color == self.background_color);
|
||||
|
||||
if let Some(_) = debug_ui.ui.event_queue.handle_mouse_down_in_rect(widget_rect) {
|
||||
if let Some(_) = debug_ui
|
||||
.ui
|
||||
.event_queue
|
||||
.handle_mouse_down_in_rect(widget_rect)
|
||||
{
|
||||
self.background_color = color;
|
||||
*action = UIAction::ModelChanged;
|
||||
}
|
||||
}
|
||||
|
||||
fn draw_effects_switch(&self,
|
||||
fn draw_effects_switch(
|
||||
&self,
|
||||
device: &D,
|
||||
debug_ui: &mut DebugUI<D>,
|
||||
text: &str,
|
||||
index: i32,
|
||||
window_y: i32,
|
||||
value: bool)
|
||||
-> bool {
|
||||
value: bool,
|
||||
) -> bool {
|
||||
let text_x = PADDING * 2;
|
||||
let text_y = window_y + PADDING + BUTTON_TEXT_OFFSET + (BUTTON_HEIGHT + PADDING) * index;
|
||||
debug_ui.ui.draw_text(device, text, Point2DI32::new(text_x, text_y), false);
|
||||
debug_ui
|
||||
.ui
|
||||
.draw_text(device, text, Point2DI32::new(text_x, text_y), false);
|
||||
|
||||
let switch_width = debug_ui.ui.measure_switch(2);
|
||||
let switch_x = PADDING + EFFECTS_PANEL_WIDTH - (switch_width + PADDING);
|
||||
let switch_y = window_y + PADDING + (BUTTON_HEIGHT + PADDING) * index;
|
||||
let switch_position = Point2DI32::new(switch_x, switch_y);
|
||||
debug_ui.ui.draw_text_switch(device, switch_position, &["Off", "On"], value as u8) != 0
|
||||
debug_ui
|
||||
.ui
|
||||
.draw_text_switch(device, switch_position, &["Off", "On"], value as u8)
|
||||
!= 0
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,9 @@ use std::path::PathBuf;
|
|||
|
||||
pub trait Window {
|
||||
fn gl_version(&self) -> GLVersion;
|
||||
fn gl_default_framebuffer(&self) -> GLuint { 0 }
|
||||
fn gl_default_framebuffer(&self) -> GLuint {
|
||||
0
|
||||
}
|
||||
fn viewport(&self, view: View) -> RectI32;
|
||||
fn make_current(&mut self, view: View);
|
||||
fn present(&mut self);
|
||||
|
@ -31,7 +33,10 @@ pub trait Window {
|
|||
fn present_open_svg_dialog(&mut self);
|
||||
fn run_save_dialog(&self, extension: &str) -> Result<PathBuf, ()>;
|
||||
|
||||
fn adjust_thread_pool_settings(&self, thread_pool_builder: ThreadPoolBuilder) -> ThreadPoolBuilder {
|
||||
fn adjust_thread_pool_settings(
|
||||
&self,
|
||||
thread_pool_builder: ThreadPoolBuilder,
|
||||
) -> ThreadPoolBuilder {
|
||||
thread_pool_builder
|
||||
}
|
||||
}
|
||||
|
@ -45,10 +50,16 @@ pub enum Event {
|
|||
MouseMoved(Point2DI32),
|
||||
MouseDragged(Point2DI32),
|
||||
Zoom(f32, Point2DI32),
|
||||
Look { pitch: f32, yaw: f32 },
|
||||
Look {
|
||||
pitch: f32,
|
||||
yaw: f32,
|
||||
},
|
||||
SetEyeTransforms(Vec<OcularTransform>),
|
||||
OpenSVG(SVGPath),
|
||||
User { message_type: u32, message_data: u32 },
|
||||
User {
|
||||
message_type: u32,
|
||||
message_data: u32,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
|
@ -67,7 +78,10 @@ pub struct WindowSize {
|
|||
impl WindowSize {
|
||||
#[inline]
|
||||
pub fn device_size(&self) -> Point2DI32 {
|
||||
self.logical_size.to_f32().scale(self.backing_scale_factor).to_i32()
|
||||
self.logical_size
|
||||
.to_f32()
|
||||
.scale(self.backing_scale_factor)
|
||||
.to_i32()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,17 +12,17 @@
|
|||
|
||||
use jemallocator;
|
||||
use nfd::Response;
|
||||
use pathfinder_demo::window::{Event, Keycode, SVGPath, View, Window, WindowSize};
|
||||
use pathfinder_demo::DemoApp;
|
||||
use pathfinder_demo::Options;
|
||||
use pathfinder_demo::window::{Event, Keycode, SVGPath, View, Window, WindowSize};
|
||||
use pathfinder_geometry::basic::point::Point2DI32;
|
||||
use pathfinder_geometry::basic::rect::RectI32;
|
||||
use pathfinder_gl::GLVersion;
|
||||
use pathfinder_gpu::resources::{FilesystemResourceLoader, ResourceLoader};
|
||||
use sdl2::{EventPump, EventSubsystem, Sdl, VideoSubsystem};
|
||||
use sdl2::event::{Event as SDLEvent, WindowEvent};
|
||||
use sdl2::keyboard::Keycode as SDLKeycode;
|
||||
use sdl2::video::{GLContext, GLProfile, Window as SDLWindow};
|
||||
use sdl2::{EventPump, EventSubsystem, Sdl, VideoSubsystem};
|
||||
use sdl2_sys::{SDL_Event, SDL_UserEvent};
|
||||
use std::path::PathBuf;
|
||||
use std::ptr;
|
||||
|
@ -150,9 +150,12 @@ impl WindowImpl {
|
|||
gl_attributes.set_depth_size(24);
|
||||
gl_attributes.set_stencil_size(8);
|
||||
|
||||
window = sdl_video.window("Pathfinder Demo",
|
||||
window = sdl_video
|
||||
.window(
|
||||
"Pathfinder Demo",
|
||||
DEFAULT_WINDOW_WIDTH,
|
||||
DEFAULT_WINDOW_HEIGHT)
|
||||
DEFAULT_WINDOW_HEIGHT,
|
||||
)
|
||||
.opengl()
|
||||
.resizable()
|
||||
.allow_highdpi()
|
||||
|
@ -166,9 +169,7 @@ impl WindowImpl {
|
|||
|
||||
let resource_loader = FilesystemResourceLoader::locate();
|
||||
|
||||
let open_svg_message_type = unsafe {
|
||||
sdl_event.register_event().unwrap()
|
||||
};
|
||||
let open_svg_message_type = unsafe { sdl_event.register_event().unwrap() };
|
||||
|
||||
WindowImpl {
|
||||
window,
|
||||
|
@ -211,16 +212,17 @@ impl WindowImpl {
|
|||
|
||||
fn convert_sdl_event(&self, sdl_event: SDLEvent) -> Option<Event> {
|
||||
match sdl_event {
|
||||
SDLEvent::User { type_, .. } if type_ == self.open_svg_message_type => {
|
||||
Some(Event::OpenSVG(SVGPath::Path(self.selected_file.clone().unwrap())))
|
||||
}
|
||||
SDLEvent::User { type_, code, .. } => {
|
||||
Some(Event::User { message_type: type_, message_data: code as u32 })
|
||||
}
|
||||
SDLEvent::MouseButtonDown { x, y, .. } => {
|
||||
Some(Event::MouseDown(Point2DI32::new(x, y)))
|
||||
}
|
||||
SDLEvent::MouseMotion { x, y, mousestate, .. } => {
|
||||
SDLEvent::User { type_, .. } if type_ == self.open_svg_message_type => Some(
|
||||
Event::OpenSVG(SVGPath::Path(self.selected_file.clone().unwrap())),
|
||||
),
|
||||
SDLEvent::User { type_, code, .. } => Some(Event::User {
|
||||
message_type: type_,
|
||||
message_data: code as u32,
|
||||
}),
|
||||
SDLEvent::MouseButtonDown { x, y, .. } => Some(Event::MouseDown(Point2DI32::new(x, y))),
|
||||
SDLEvent::MouseMotion {
|
||||
x, y, mousestate, ..
|
||||
} => {
|
||||
let position = Point2DI32::new(x, y);
|
||||
if mousestate.left() {
|
||||
Some(Event::MouseDragged(position))
|
||||
|
@ -229,15 +231,18 @@ impl WindowImpl {
|
|||
}
|
||||
}
|
||||
SDLEvent::Quit { .. } => Some(Event::Quit),
|
||||
SDLEvent::Window { win_event: WindowEvent::SizeChanged(..), .. } => {
|
||||
Some(Event::WindowResized(self.size()))
|
||||
}
|
||||
SDLEvent::KeyDown { keycode: Some(sdl_keycode), .. } => {
|
||||
self.convert_sdl_keycode(sdl_keycode).map(Event::KeyDown)
|
||||
}
|
||||
SDLEvent::KeyUp { keycode: Some(sdl_keycode), .. } => {
|
||||
self.convert_sdl_keycode(sdl_keycode).map(Event::KeyUp)
|
||||
}
|
||||
SDLEvent::Window {
|
||||
win_event: WindowEvent::SizeChanged(..),
|
||||
..
|
||||
} => Some(Event::WindowResized(self.size())),
|
||||
SDLEvent::KeyDown {
|
||||
keycode: Some(sdl_keycode),
|
||||
..
|
||||
} => self.convert_sdl_keycode(sdl_keycode).map(Event::KeyDown),
|
||||
SDLEvent::KeyUp {
|
||||
keycode: Some(sdl_keycode),
|
||||
..
|
||||
} => self.convert_sdl_keycode(sdl_keycode).map(Event::KeyUp),
|
||||
SDLEvent::MultiGesture { d_dist, .. } => {
|
||||
let mouse_state = self.event_pump.mouse_state();
|
||||
let center = Point2DI32::new(mouse_state.x(), mouse_state.y());
|
||||
|
@ -251,8 +256,10 @@ impl WindowImpl {
|
|||
match sdl_keycode {
|
||||
SDLKeycode::Escape => Some(Keycode::Escape),
|
||||
SDLKeycode::Tab => Some(Keycode::Tab),
|
||||
sdl_keycode if sdl_keycode as i32 >= SDLKeycode::A as i32 &&
|
||||
sdl_keycode as i32 <= SDLKeycode::Z as i32 => {
|
||||
sdl_keycode
|
||||
if sdl_keycode as i32 >= SDLKeycode::A as i32
|
||||
&& sdl_keycode as i32 <= SDLKeycode::Z as i32 =>
|
||||
{
|
||||
let offset = (sdl_keycode as i32 - SDLKeycode::A as i32) as u8;
|
||||
Some(Keycode::Alphanumeric(offset + b'a'))
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue