Add specific rendering methods for each eye
This commit is contained in:
parent
e212a839b4
commit
5db7edad0b
|
@ -13,7 +13,9 @@ public class PathfinderDemoRenderer extends Object implements GLSurfaceView.Rend
|
|||
private static native void init(PathfinderDemoResourceLoader resourceLoader,
|
||||
int width,
|
||||
int height);
|
||||
private static native void runOnce();
|
||||
private static native int prepareFrame();
|
||||
private static native void drawScene(int sceneIndex);
|
||||
private static native void finishDrawingFrame();
|
||||
|
||||
public static native void pushWindowResizedEvent(int width, int height);
|
||||
public static native void pushMouseDownEvent(int x, int y);
|
||||
|
@ -48,6 +50,9 @@ public class PathfinderDemoRenderer extends Object implements GLSurfaceView.Rend
|
|||
|
||||
@Override
|
||||
public void onDrawFrame(GL10 gl) {
|
||||
runOnce();
|
||||
int sceneCount = prepareFrame();
|
||||
for (int sceneIndex = 0; sceneIndex < sceneCount; sceneIndex++)
|
||||
drawScene(sceneIndex);
|
||||
finishDrawingFrame();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,14 +57,43 @@ pub unsafe extern "system" fn
|
|||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "system" fn
|
||||
Java_graphics_pathfinder_pathfinderdemo_PathfinderDemoRenderer_runOnce(env: JNIEnv,
|
||||
class: JClass) {
|
||||
Java_graphics_pathfinder_pathfinderdemo_PathfinderDemoRenderer_prepareFrame(env: JNIEnv,
|
||||
class: JClass)
|
||||
-> i32 {
|
||||
DEMO_APP.with(|demo_app| {
|
||||
let mut event_queue = EVENT_QUEUE.lock().unwrap();
|
||||
if let Some(ref mut demo_app) = *demo_app.borrow_mut() {
|
||||
demo_app.run_once(mem::replace(&mut *event_queue, vec![]));
|
||||
match *demo_app.borrow_mut() {
|
||||
Some(ref mut demo_app) => {
|
||||
demo_app.prepare_frame(mem::replace(&mut *event_queue, vec![])) as i32
|
||||
}
|
||||
});
|
||||
None => 0,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "system" fn
|
||||
Java_graphics_pathfinder_pathfinderdemo_PathfinderDemoRenderer_drawScene(
|
||||
env: JNIEnv,
|
||||
class: JClass,
|
||||
scene_index: i32) {
|
||||
DEMO_APP.with(|demo_app| {
|
||||
if let Some(ref mut demo_app) = *demo_app.borrow_mut() {
|
||||
demo_app.draw_scene(scene_index as u32)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "system" fn
|
||||
Java_graphics_pathfinder_pathfinderdemo_PathfinderDemoRenderer_finishDrawingFrame(
|
||||
env: JNIEnv,
|
||||
class: JClass) {
|
||||
DEMO_APP.with(|demo_app| {
|
||||
if let Some(ref mut demo_app) = *demo_app.borrow_mut() {
|
||||
demo_app.finish_drawing_frame()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
|
|
@ -35,13 +35,11 @@ use pathfinder_svg::BuiltSVG;
|
|||
use pathfinder_ui::{MousePosition, UIEvent};
|
||||
use rayon::ThreadPoolBuilder;
|
||||
use std::f32::consts::FRAC_PI_4;
|
||||
use std::ffi::CString;
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
use std::iter;
|
||||
use std::mem;
|
||||
use std::panic;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::path::PathBuf;
|
||||
use std::process;
|
||||
use std::sync::mpsc::{self, Receiver, Sender};
|
||||
use std::thread;
|
||||
|
@ -98,6 +96,8 @@ pub struct DemoApp<W> where W: Window {
|
|||
message_epoch: u32,
|
||||
last_mouse_position: Point2DI32,
|
||||
|
||||
current_frame: Option<Frame>,
|
||||
|
||||
ui: DemoUI<GLDevice>,
|
||||
scene_thread_proxy: SceneThreadProxy,
|
||||
renderer: Renderer<GLDevice>,
|
||||
|
@ -113,7 +113,7 @@ impl<W> DemoApp<W> where W: Window {
|
|||
|
||||
let device = GLDevice::new(window.gl_version());
|
||||
let resources = window.resource_loader();
|
||||
let options = Options::get(resources);
|
||||
let options = Options::get();
|
||||
|
||||
let view_box_size = view_box_size(options.mode, &window_size);
|
||||
|
||||
|
@ -165,6 +165,8 @@ impl<W> DemoApp<W> where W: Window {
|
|||
message_epoch,
|
||||
last_mouse_position: Point2DI32::default(),
|
||||
|
||||
current_frame: None,
|
||||
|
||||
ui,
|
||||
scene_thread_proxy,
|
||||
renderer,
|
||||
|
@ -175,16 +177,24 @@ impl<W> DemoApp<W> where W: Window {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn run_once(&mut self, events: Vec<Event>) {
|
||||
pub fn prepare_frame(&mut self, events: Vec<Event>) -> u32 {
|
||||
// Update the scene.
|
||||
self.build_scene();
|
||||
|
||||
// Handle events.
|
||||
let ui_events = self.handle_events(events);
|
||||
|
||||
// Draw the scene.
|
||||
// Get the render message, and determine how many scenes it contains.
|
||||
let render_msg = self.scene_thread_proxy.receiver.recv().unwrap();
|
||||
self.draw_scene(render_msg, ui_events);
|
||||
let render_scene_count = render_msg.render_scenes.len() as u32;
|
||||
|
||||
// Save the frame.
|
||||
self.current_frame = Some(Frame::new(render_msg, ui_events));
|
||||
|
||||
// Begin drawing the scene.
|
||||
self.renderer.device.clear(Some(self.background_color().to_f32().0), Some(1.0), Some(0));
|
||||
|
||||
render_scene_count
|
||||
}
|
||||
|
||||
fn build_scene(&mut self) {
|
||||
|
@ -338,19 +348,15 @@ impl<W> DemoApp<W> where W: Window {
|
|||
MousePosition { absolute, relative }
|
||||
}
|
||||
|
||||
fn draw_scene(&mut self, render_msg: SceneToMainMsg, mut ui_events: Vec<UIEvent>) {
|
||||
self.renderer.device.clear(Some(self.background_color().to_f32().0), Some(1.0), Some(0));
|
||||
pub fn draw_scene(&mut self, render_scene_index: u32) {
|
||||
self.draw_environment(render_scene_index);
|
||||
self.render_vector_scene(render_scene_index);
|
||||
|
||||
let SceneToMainMsg::Render { render_scenes, tile_time } = render_msg;
|
||||
let mut render_stats = None;
|
||||
|
||||
for (viewport_index, render_scene) in render_scenes.iter().enumerate() {
|
||||
self.draw_environment(viewport_index, &render_scene.transform);
|
||||
self.render_vector_scene(viewport_index, &render_scene.built_scene);
|
||||
|
||||
match render_stats {
|
||||
let frame = self.current_frame.as_mut().unwrap();
|
||||
let render_scene = &frame.render_msg.render_scenes[render_scene_index as usize];
|
||||
match frame.render_stats {
|
||||
None => {
|
||||
render_stats = Some(RenderStats {
|
||||
frame.render_stats = Some(RenderStats {
|
||||
rendering_time: self.renderer.shift_timer_query(),
|
||||
stats: render_scene.built_scene.stats(),
|
||||
})
|
||||
|
@ -361,6 +367,9 @@ impl<W> DemoApp<W> where W: Window {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn finish_drawing_frame(&mut self) {
|
||||
let mut frame = self.current_frame.take().unwrap();
|
||||
|
||||
let drawable_size = self.window_size.device_size();
|
||||
self.renderer.set_viewport(RectI32::new(Point2DI32::default(), drawable_size));
|
||||
|
||||
|
@ -368,14 +377,14 @@ impl<W> DemoApp<W> where W: Window {
|
|||
self.take_screenshot();
|
||||
}
|
||||
|
||||
if let Some(render_stats) = render_stats {
|
||||
if let Some(render_stats) = frame.render_stats.take() {
|
||||
self.renderer.debug_ui.add_sample(render_stats.stats,
|
||||
tile_time,
|
||||
frame.render_msg.tile_time,
|
||||
render_stats.rendering_time);
|
||||
self.renderer.draw_debug_ui();
|
||||
}
|
||||
|
||||
for ui_event in &ui_events {
|
||||
for ui_event in &frame.ui_events {
|
||||
self.dirty = true;
|
||||
self.renderer.debug_ui.ui.event_queue.push(*ui_event);
|
||||
}
|
||||
|
@ -390,7 +399,7 @@ impl<W> DemoApp<W> where W: Window {
|
|||
&mut self.renderer.debug_ui,
|
||||
&mut ui_action);
|
||||
|
||||
ui_events = self.renderer.debug_ui.ui.event_queue.drain();
|
||||
frame.ui_events = self.renderer.debug_ui.ui.event_queue.drain();
|
||||
self.handle_ui_action(&mut ui_action);
|
||||
|
||||
// Switch camera mode (2D/3D) if requested.
|
||||
|
@ -407,7 +416,7 @@ impl<W> DemoApp<W> where W: Window {
|
|||
_ => {}
|
||||
}
|
||||
|
||||
for ui_event in ui_events {
|
||||
for ui_event in frame.ui_events {
|
||||
match ui_event {
|
||||
UIEvent::MouseDown(_) if self.camera.is_3d() => {
|
||||
// If nothing handled the mouse-down event, toggle mouselook.
|
||||
|
@ -426,7 +435,10 @@ impl<W> DemoApp<W> where W: Window {
|
|||
self.frame_counter += 1;
|
||||
}
|
||||
|
||||
fn draw_environment(&self, viewport_index: usize, render_transform: &RenderTransform) {
|
||||
fn draw_environment(&self, viewport_index: u32) {
|
||||
let render_msg = &self.current_frame.as_ref().unwrap().render_msg;
|
||||
let render_transform = &render_msg.render_scenes[viewport_index as usize].transform;
|
||||
|
||||
let perspective = match *render_transform {
|
||||
RenderTransform::Transform2D(..) => return,
|
||||
RenderTransform::Perspective(perspective) => perspective,
|
||||
|
@ -493,7 +505,10 @@ 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: u32) {
|
||||
let render_msg = &self.current_frame.as_ref().unwrap().render_msg;
|
||||
let built_scene = &render_msg.render_scenes[viewport_index as usize].built_scene;
|
||||
|
||||
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 = RectI32::new(Point2DI32::new(viewport_origin_x, 0), view_box_size);
|
||||
|
@ -654,7 +669,7 @@ impl SceneThread {
|
|||
RenderScene { built_scene, transform: (*render_transform).clone() }
|
||||
}).collect();
|
||||
let tile_time = Instant::now() - start_time;
|
||||
self.sender.send(SceneToMainMsg::Render { render_scenes, tile_time }).unwrap();
|
||||
self.sender.send(SceneToMainMsg { render_scenes, tile_time }).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -672,8 +687,9 @@ struct BuildOptions {
|
|||
stem_darkening_font_size: Option<f32>,
|
||||
}
|
||||
|
||||
enum SceneToMainMsg {
|
||||
Render { render_scenes: Vec<RenderScene>, tile_time: Duration }
|
||||
struct SceneToMainMsg {
|
||||
render_scenes: Vec<RenderScene>,
|
||||
tile_time: Duration,
|
||||
}
|
||||
|
||||
pub struct RenderScene {
|
||||
|
@ -689,7 +705,7 @@ pub struct Options {
|
|||
}
|
||||
|
||||
impl Options {
|
||||
fn get(resources: &dyn ResourceLoader) -> Options {
|
||||
fn get() -> Options {
|
||||
let matches = App::new("tile-svg")
|
||||
.arg(
|
||||
Arg::with_name("jobs")
|
||||
|
@ -755,7 +771,7 @@ fn load_scene(resource_loader: &dyn ResourceLoader, input_path: &Option<PathBuf>
|
|||
data = vec![];
|
||||
let mut file = match File::open(input_path) {
|
||||
Ok(file) => file,
|
||||
Err(err) => panic!(),
|
||||
Err(_) => panic!(),
|
||||
};
|
||||
file.read_to_end(&mut data).unwrap();
|
||||
}
|
||||
|
@ -932,3 +948,15 @@ fn view_box_size(mode: Mode, window_size: &WindowSize) -> Point2DI32 {
|
|||
Mode::VR => Point2DI32::new(window_drawable_size.x() / 2, window_drawable_size.y()),
|
||||
}
|
||||
}
|
||||
|
||||
struct Frame {
|
||||
render_msg: SceneToMainMsg,
|
||||
ui_events: Vec<UIEvent>,
|
||||
render_stats: Option<RenderStats>,
|
||||
}
|
||||
|
||||
impl Frame {
|
||||
fn new(render_msg: SceneToMainMsg, ui_events: Vec<UIEvent>) -> Frame {
|
||||
Frame { render_msg, ui_events, render_stats: None }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,7 +37,12 @@ fn main() {
|
|||
while let Some(event) = app.window.try_get_event() {
|
||||
events.push(event);
|
||||
}
|
||||
app.run_once(events);
|
||||
|
||||
let scene_count = app.prepare_frame(events);
|
||||
for scene_index in 0..scene_count {
|
||||
app.draw_scene(scene_index);
|
||||
}
|
||||
app.finish_drawing_frame();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue