Update the demo for the D3D11 backend
This commit is contained in:
parent
72cdef2c2a
commit
423a91ea1a
|
@ -34,9 +34,10 @@ use pathfinder_geometry::transform2d::Transform2F;
|
||||||
use pathfinder_geometry::transform3d::Transform4F;
|
use pathfinder_geometry::transform3d::Transform4F;
|
||||||
use pathfinder_geometry::vector::{Vector2F, Vector2I, Vector4F, vec2f, vec2i};
|
use pathfinder_geometry::vector::{Vector2F, Vector2I, Vector4F, vec2f, vec2i};
|
||||||
use pathfinder_gpu::Device;
|
use pathfinder_gpu::Device;
|
||||||
use pathfinder_renderer::concurrent::scene_proxy::{RenderCommandStream, SceneProxy};
|
use pathfinder_renderer::concurrent::scene_proxy::SceneProxy;
|
||||||
use pathfinder_renderer::gpu::options::{DestFramebuffer, RendererOptions};
|
use pathfinder_renderer::gpu::options::{DestFramebuffer, RendererLevel};
|
||||||
use pathfinder_renderer::gpu::renderer::{RenderStats, RenderTime, Renderer};
|
use pathfinder_renderer::gpu::options::{RendererMode, RendererOptions};
|
||||||
|
use pathfinder_renderer::gpu::renderer::{DebugUIPresenterInfo, Renderer};
|
||||||
use pathfinder_renderer::options::{BuildOptions, RenderTransform};
|
use pathfinder_renderer::options::{BuildOptions, RenderTransform};
|
||||||
use pathfinder_renderer::paint::Paint;
|
use pathfinder_renderer::paint::Paint;
|
||||||
use pathfinder_renderer::scene::{DrawPath, RenderTarget, Scene};
|
use pathfinder_renderer::scene::{DrawPath, RenderTarget, Scene};
|
||||||
|
@ -90,7 +91,6 @@ pub struct DemoApp<W> where W: Window {
|
||||||
svg_tree: Tree,
|
svg_tree: Tree,
|
||||||
scene_metadata: SceneMetadata,
|
scene_metadata: SceneMetadata,
|
||||||
render_transform: Option<RenderTransform>,
|
render_transform: Option<RenderTransform>,
|
||||||
render_command_stream: Option<RenderCommandStream>,
|
|
||||||
|
|
||||||
camera: Camera,
|
camera: Camera,
|
||||||
frame_counter: u32,
|
frame_counter: u32,
|
||||||
|
@ -135,14 +135,25 @@ impl<W> DemoApp<W> where W: Window {
|
||||||
let executor = DemoExecutor::new(options.jobs);
|
let executor = DemoExecutor::new(options.jobs);
|
||||||
|
|
||||||
let mut ui_model = DemoUIModel::new(&options);
|
let mut ui_model = DemoUIModel::new(&options);
|
||||||
|
|
||||||
|
let level = match options.renderer_level {
|
||||||
|
Some(level) => level,
|
||||||
|
None => RendererLevel::default_for_device(&device),
|
||||||
|
};
|
||||||
|
let viewport = window.viewport(options.mode.view(0));
|
||||||
|
let dest_framebuffer = DestFramebuffer::Default {
|
||||||
|
viewport,
|
||||||
|
window_size: window_size.device_size(),
|
||||||
|
};
|
||||||
|
let render_mode = RendererMode { level };
|
||||||
let render_options = RendererOptions {
|
let render_options = RendererOptions {
|
||||||
|
dest: dest_framebuffer,
|
||||||
background_color: None,
|
background_color: None,
|
||||||
no_compute: options.no_compute,
|
show_debug_ui: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
let filter = build_filter(&ui_model);
|
let filter = build_filter(&ui_model);
|
||||||
|
|
||||||
let viewport = window.viewport(options.mode.view(0));
|
|
||||||
let (mut built_svg, svg_tree) = load_scene(resources,
|
let (mut built_svg, svg_tree) = load_scene(resources,
|
||||||
&options.input_path,
|
&options.input_path,
|
||||||
viewport.size(),
|
viewport.size(),
|
||||||
|
@ -150,21 +161,16 @@ impl<W> DemoApp<W> where W: Window {
|
||||||
|
|
||||||
let message = get_svg_building_message(&built_svg);
|
let message = get_svg_building_message(&built_svg);
|
||||||
|
|
||||||
let dest_framebuffer = DestFramebuffer::Default {
|
let renderer = Renderer::new(device, resources, render_mode, render_options);
|
||||||
viewport,
|
|
||||||
window_size: window_size.device_size(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let renderer = Renderer::new(device, resources, dest_framebuffer, render_options);
|
|
||||||
|
|
||||||
let scene_metadata = SceneMetadata::new_clipping_view_box(&mut built_svg.scene,
|
let scene_metadata = SceneMetadata::new_clipping_view_box(&mut built_svg.scene,
|
||||||
viewport.size());
|
viewport.size());
|
||||||
let camera = Camera::new(options.mode, scene_metadata.view_box, viewport.size());
|
let camera = Camera::new(options.mode, scene_metadata.view_box, viewport.size());
|
||||||
|
|
||||||
let scene_proxy = SceneProxy::from_scene(built_svg.scene, executor);
|
let scene_proxy = SceneProxy::from_scene(built_svg.scene, level, executor);
|
||||||
|
|
||||||
let ground_program = GroundProgram::new(&renderer.device, resources);
|
let ground_program = GroundProgram::new(renderer.device(), resources);
|
||||||
let ground_vertex_array = GroundVertexArray::new(&renderer.device,
|
let ground_vertex_array = GroundVertexArray::new(renderer.device(),
|
||||||
&ground_program,
|
&ground_program,
|
||||||
&renderer.quad_vertex_positions_buffer(),
|
&renderer.quad_vertex_positions_buffer(),
|
||||||
&renderer.quad_vertex_indices_buffer());
|
&renderer.quad_vertex_indices_buffer());
|
||||||
|
@ -177,7 +183,7 @@ impl<W> DemoApp<W> where W: Window {
|
||||||
message,
|
message,
|
||||||
);
|
);
|
||||||
|
|
||||||
let ui_presenter = DemoUIPresenter::new(&renderer.device, resources);
|
let ui_presenter = DemoUIPresenter::new(renderer.device(), resources);
|
||||||
|
|
||||||
DemoApp {
|
DemoApp {
|
||||||
window,
|
window,
|
||||||
|
@ -189,7 +195,6 @@ impl<W> DemoApp<W> where W: Window {
|
||||||
svg_tree,
|
svg_tree,
|
||||||
scene_metadata,
|
scene_metadata,
|
||||||
render_transform: None,
|
render_transform: None,
|
||||||
render_command_stream: None,
|
|
||||||
|
|
||||||
camera,
|
camera,
|
||||||
frame_counter: 0,
|
frame_counter: 0,
|
||||||
|
@ -265,7 +270,11 @@ impl<W> DemoApp<W> where W: Window {
|
||||||
subpixel_aa_enabled: self.ui_model.subpixel_aa_effect_enabled,
|
subpixel_aa_enabled: self.ui_model.subpixel_aa_effect_enabled,
|
||||||
};
|
};
|
||||||
|
|
||||||
self.render_command_stream = Some(self.scene_proxy.build_with_stream(build_options));
|
self.scene_proxy.build(build_options);
|
||||||
|
/*
|
||||||
|
self.render_command_stream =
|
||||||
|
Some(self.scene_proxy.build_with_stream(build_options, self.renderer.gpu_features()));
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_events(&mut self, events: Vec<Event>) -> Vec<UIEvent> {
|
fn handle_events(&mut self, events: Vec<Event>) -> Vec<UIEvent> {
|
||||||
|
@ -469,57 +478,41 @@ impl<W> DemoApp<W> where W: Window {
|
||||||
|
|
||||||
pub fn finish_drawing_frame(&mut self) {
|
pub fn finish_drawing_frame(&mut self) {
|
||||||
self.maybe_take_screenshot();
|
self.maybe_take_screenshot();
|
||||||
self.update_stats();
|
|
||||||
self.draw_debug_ui();
|
|
||||||
|
|
||||||
let frame = self.current_frame.take().unwrap();
|
let frame = self.current_frame.take().unwrap();
|
||||||
for ui_event in &frame.ui_events {
|
for ui_event in &frame.ui_events {
|
||||||
self.dirty = true;
|
self.dirty = true;
|
||||||
self.renderer.debug_ui_presenter.ui_presenter.event_queue.push(*ui_event);
|
self.renderer
|
||||||
|
.debug_ui_presenter_mut()
|
||||||
|
.debug_ui_presenter
|
||||||
|
.ui_presenter
|
||||||
|
.event_queue
|
||||||
|
.push(*ui_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.renderer.debug_ui_presenter.ui_presenter.mouse_position =
|
self.renderer.debug_ui_presenter_mut().debug_ui_presenter.ui_presenter.mouse_position =
|
||||||
self.last_mouse_position.to_f32() * self.window_size.backing_scale_factor;
|
self.last_mouse_position.to_f32() * self.window_size.backing_scale_factor;
|
||||||
|
|
||||||
let mut ui_action = UIAction::None;
|
let mut ui_action = UIAction::None;
|
||||||
if self.options.ui == UIVisibility::All {
|
if self.options.ui == UIVisibility::All {
|
||||||
self.ui_presenter.update(
|
let DebugUIPresenterInfo { device, allocator, debug_ui_presenter } =
|
||||||
&self.renderer.device,
|
self.renderer.debug_ui_presenter_mut();
|
||||||
|
self.ui_presenter.update(device,
|
||||||
|
allocator,
|
||||||
&mut self.window,
|
&mut self.window,
|
||||||
&mut self.renderer.debug_ui_presenter,
|
debug_ui_presenter,
|
||||||
&mut ui_action,
|
&mut ui_action,
|
||||||
&mut self.ui_model,
|
&mut self.ui_model);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.handle_ui_events(frame, &mut ui_action);
|
self.handle_ui_events(frame, &mut ui_action);
|
||||||
|
|
||||||
self.renderer.device.end_commands();
|
self.renderer.device().end_commands();
|
||||||
|
|
||||||
self.window.present(&mut self.renderer.device);
|
self.window.present(self.renderer.device_mut());
|
||||||
self.frame_counter += 1;
|
self.frame_counter += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_stats(&mut self) {
|
|
||||||
let frame = self.current_frame.as_mut().unwrap();
|
|
||||||
if let Some(rendering_time) = self.renderer.shift_rendering_time() {
|
|
||||||
frame.scene_rendering_times.push(rendering_time);
|
|
||||||
}
|
|
||||||
|
|
||||||
if frame.scene_stats.is_empty() && frame.scene_rendering_times.is_empty() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let zero = RenderStats::default();
|
|
||||||
let aggregate_stats = frame.scene_stats.iter().fold(zero, |sum, item| sum + *item);
|
|
||||||
if !frame.scene_rendering_times.is_empty() {
|
|
||||||
let total_rendering_time = frame.scene_rendering_times
|
|
||||||
.iter()
|
|
||||||
.fold(RenderTime::default(), |sum, item| sum + *item);
|
|
||||||
self.renderer.debug_ui_presenter.add_sample(aggregate_stats, total_rendering_time);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn maybe_take_screenshot(&mut self) {
|
fn maybe_take_screenshot(&mut self) {
|
||||||
match self.pending_screenshot_info.take() {
|
match self.pending_screenshot_info.take() {
|
||||||
None => {}
|
None => {}
|
||||||
|
@ -535,7 +528,12 @@ impl<W> DemoApp<W> where W: Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_ui_events(&mut self, mut frame: Frame, ui_action: &mut UIAction) {
|
fn handle_ui_events(&mut self, mut frame: Frame, ui_action: &mut UIAction) {
|
||||||
frame.ui_events = self.renderer.debug_ui_presenter.ui_presenter.event_queue.drain();
|
frame.ui_events = self.renderer
|
||||||
|
.debug_ui_presenter_mut()
|
||||||
|
.debug_ui_presenter
|
||||||
|
.ui_presenter
|
||||||
|
.event_queue
|
||||||
|
.drain();
|
||||||
|
|
||||||
self.handle_ui_action(ui_action);
|
self.handle_ui_action(ui_action);
|
||||||
|
|
||||||
|
@ -625,7 +623,7 @@ pub struct Options {
|
||||||
pub ui: UIVisibility,
|
pub ui: UIVisibility,
|
||||||
pub background_color: BackgroundColor,
|
pub background_color: BackgroundColor,
|
||||||
pub high_performance_gpu: bool,
|
pub high_performance_gpu: bool,
|
||||||
pub no_compute: bool,
|
pub renderer_level: Option<RendererLevel>,
|
||||||
hidden_field_for_future_proofing: (),
|
hidden_field_for_future_proofing: (),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -638,7 +636,7 @@ impl Default for Options {
|
||||||
ui: UIVisibility::All,
|
ui: UIVisibility::All,
|
||||||
background_color: BackgroundColor::Light,
|
background_color: BackgroundColor::Light,
|
||||||
high_performance_gpu: false,
|
high_performance_gpu: false,
|
||||||
no_compute: false,
|
renderer_level: None,
|
||||||
hidden_field_for_future_proofing: (),
|
hidden_field_for_future_proofing: (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -646,7 +644,7 @@ impl Default for Options {
|
||||||
|
|
||||||
impl Options {
|
impl Options {
|
||||||
pub fn command_line_overrides(&mut self) {
|
pub fn command_line_overrides(&mut self) {
|
||||||
let matches = App::new("tile-svg")
|
let matches = App::new("demo")
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("jobs")
|
Arg::with_name("jobs")
|
||||||
.short("j")
|
.short("j")
|
||||||
|
@ -692,10 +690,12 @@ impl Options {
|
||||||
.help("Use the high-performance (discrete) GPU, if available")
|
.help("Use the high-performance (discrete) GPU, if available")
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("no-compute")
|
Arg::with_name("level")
|
||||||
.short("c")
|
.long("level")
|
||||||
.long("no-compute")
|
.short("l")
|
||||||
.help("Never use compute shaders")
|
.help("Set the renderer feature level as a Direct3D version equivalent")
|
||||||
|
.takes_value(true)
|
||||||
|
.possible_values(&["9", "11"])
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("INPUT")
|
Arg::with_name("INPUT")
|
||||||
|
@ -734,13 +734,17 @@ impl Options {
|
||||||
self.high_performance_gpu = true;
|
self.high_performance_gpu = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if matches.is_present("no-compute") {
|
if let Some(renderer_level) = matches.value_of("level") {
|
||||||
self.no_compute = true;
|
if renderer_level == "11" {
|
||||||
|
self.renderer_level = Some(RendererLevel::D3D11);
|
||||||
|
} else if renderer_level == "9" {
|
||||||
|
self.renderer_level = Some(RendererLevel::D3D9);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(path) = matches.value_of("INPUT") {
|
if let Some(path) = matches.value_of("INPUT") {
|
||||||
self.input_path = SVGPath::Path(PathBuf::from(path));
|
self.input_path = SVGPath::Path(PathBuf::from(path));
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -798,7 +802,7 @@ fn build_svg_tree(tree: &Tree, viewport_size: Vector2I, filter: Option<PatternFi
|
||||||
let path = DrawPath::new(outline, paint_id);
|
let path = DrawPath::new(outline, paint_id);
|
||||||
|
|
||||||
built_svg.scene.pop_render_target();
|
built_svg.scene.pop_render_target();
|
||||||
built_svg.scene.push_path(path);
|
built_svg.scene.push_draw_path(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
return built_svg;
|
return built_svg;
|
||||||
|
@ -848,18 +852,11 @@ fn emit_message<W>(
|
||||||
struct Frame {
|
struct Frame {
|
||||||
transform: RenderTransform,
|
transform: RenderTransform,
|
||||||
ui_events: Vec<UIEvent>,
|
ui_events: Vec<UIEvent>,
|
||||||
scene_rendering_times: Vec<RenderTime>,
|
|
||||||
scene_stats: Vec<RenderStats>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Frame {
|
impl Frame {
|
||||||
fn new(transform: RenderTransform, ui_events: Vec<UIEvent>) -> Frame {
|
fn new(transform: RenderTransform, ui_events: Vec<UIEvent>) -> Frame {
|
||||||
Frame {
|
Frame { transform, ui_events }
|
||||||
transform,
|
|
||||||
ui_events,
|
|
||||||
scene_rendering_times: vec![],
|
|
||||||
scene_stats: vec![],
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ use pathfinder_geometry::transform3d::Transform4F;
|
||||||
use pathfinder_geometry::vector::{Vector2I, Vector4F};
|
use pathfinder_geometry::vector::{Vector2I, Vector4F};
|
||||||
use pathfinder_renderer::gpu::options::{DestFramebuffer, RendererOptions};
|
use pathfinder_renderer::gpu::options::{DestFramebuffer, RendererOptions};
|
||||||
use pathfinder_renderer::options::RenderTransform;
|
use pathfinder_renderer::options::RenderTransform;
|
||||||
|
use std::mem;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
const GROUND_SOLID_COLOR: ColorU = ColorU {
|
const GROUND_SOLID_COLOR: ColorU = ColorU {
|
||||||
|
@ -46,59 +47,58 @@ impl<W> DemoApp<W> where W: Window {
|
||||||
let view = self.ui_model.mode.view(0);
|
let view = self.ui_model.mode.view(0);
|
||||||
self.window.make_current(view);
|
self.window.make_current(view);
|
||||||
|
|
||||||
// Set up framebuffers.
|
|
||||||
let window_size = self.window_size.device_size();
|
|
||||||
let mode = self.camera.mode();
|
|
||||||
let scene_count = match mode {
|
|
||||||
Mode::VR => {
|
|
||||||
let viewport = self.window.viewport(View::Stereo(0));
|
|
||||||
if self.scene_framebuffer.is_none()
|
|
||||||
|| self.renderer.device.texture_size(
|
|
||||||
&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());
|
|
||||||
self.scene_framebuffer =
|
|
||||||
Some(self.renderer.device.create_framebuffer(scene_texture));
|
|
||||||
}
|
|
||||||
self.renderer
|
|
||||||
.replace_dest_framebuffer(DestFramebuffer::Other(
|
|
||||||
self.scene_framebuffer.take().unwrap(),
|
|
||||||
));
|
|
||||||
2
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
self.renderer
|
|
||||||
.replace_dest_framebuffer(DestFramebuffer::Default {
|
|
||||||
viewport: self.window.viewport(View::Mono),
|
|
||||||
window_size,
|
|
||||||
});
|
|
||||||
1
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Clear to the appropriate color.
|
// Clear to the appropriate color.
|
||||||
|
let mode = self.camera.mode();
|
||||||
let clear_color = match mode {
|
let clear_color = match mode {
|
||||||
Mode::TwoD => Some(self.ui_model.background_color().to_f32()),
|
Mode::TwoD => Some(self.ui_model.background_color().to_f32()),
|
||||||
Mode::ThreeD => None,
|
Mode::ThreeD => None,
|
||||||
Mode::VR => Some(ColorF::transparent_black()),
|
Mode::VR => Some(ColorF::transparent_black()),
|
||||||
};
|
};
|
||||||
self.renderer.set_options(RendererOptions {
|
|
||||||
|
// Set up framebuffers.
|
||||||
|
let window_size = self.window_size.device_size();
|
||||||
|
let scene_count = match mode {
|
||||||
|
Mode::VR => {
|
||||||
|
let viewport = self.window.viewport(View::Stereo(0));
|
||||||
|
if self.scene_framebuffer.is_none()
|
||||||
|
|| self.renderer.device().texture_size(
|
||||||
|
&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());
|
||||||
|
self.scene_framebuffer =
|
||||||
|
Some(self.renderer.device().create_framebuffer(scene_texture));
|
||||||
|
}
|
||||||
|
*self.renderer.options_mut() = RendererOptions {
|
||||||
|
dest: DestFramebuffer::Other(self.scene_framebuffer.take().unwrap()),
|
||||||
background_color: clear_color,
|
background_color: clear_color,
|
||||||
no_compute: self.options.no_compute,
|
show_debug_ui: self.options.ui != UIVisibility::None,
|
||||||
});
|
};
|
||||||
|
2
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
*self.renderer.options_mut() = RendererOptions {
|
||||||
|
dest: DestFramebuffer::Default {
|
||||||
|
viewport: self.window.viewport(View::Mono),
|
||||||
|
window_size,
|
||||||
|
},
|
||||||
|
background_color: clear_color,
|
||||||
|
show_debug_ui: self.options.ui != UIVisibility::None,
|
||||||
|
};
|
||||||
|
1
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
scene_count
|
scene_count
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_scene(&mut self) {
|
pub fn draw_scene(&mut self) {
|
||||||
self.renderer.device.begin_commands();
|
self.renderer.device().begin_commands();
|
||||||
|
|
||||||
let view = self.ui_model.mode.view(0);
|
let view = self.ui_model.mode.view(0);
|
||||||
self.window.make_current(view);
|
self.window.make_current(view);
|
||||||
|
@ -107,26 +107,29 @@ impl<W> DemoApp<W> where W: Window {
|
||||||
self.draw_environment(0);
|
self.draw_environment(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.renderer.device.end_commands();
|
self.renderer.device().end_commands();
|
||||||
|
|
||||||
self.render_vector_scene();
|
self.render_vector_scene();
|
||||||
|
|
||||||
// Reattach default framebuffer.
|
// Reattach default framebuffer.
|
||||||
if self.camera.mode() == Mode::VR {
|
if self.camera.mode() == Mode::VR {
|
||||||
if let DestFramebuffer::Other(scene_framebuffer) =
|
let new_options = RendererOptions {
|
||||||
self.renderer
|
dest: DestFramebuffer::Default {
|
||||||
.replace_dest_framebuffer(DestFramebuffer::Default {
|
|
||||||
viewport: self.window.viewport(View::Mono),
|
viewport: self.window.viewport(View::Mono),
|
||||||
window_size: self.window_size.device_size(),
|
window_size: self.window_size.device_size(),
|
||||||
})
|
},
|
||||||
{
|
..*self.renderer.options()
|
||||||
|
};
|
||||||
|
if let DestFramebuffer::Other(scene_framebuffer) = mem::replace(self.renderer
|
||||||
|
.options_mut(),
|
||||||
|
new_options).dest {
|
||||||
self.scene_framebuffer = Some(scene_framebuffer);
|
self.scene_framebuffer = Some(scene_framebuffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn begin_compositing(&mut self) {
|
pub fn begin_compositing(&mut self) {
|
||||||
self.renderer.device.begin_commands();
|
self.renderer.device().begin_commands();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn composite_scene(&mut self, render_scene_index: u32) {
|
pub fn composite_scene(&mut self, render_scene_index: u32) {
|
||||||
|
@ -153,15 +156,15 @@ impl<W> DemoApp<W> where W: Window {
|
||||||
let viewport = self.window.viewport(View::Stereo(render_scene_index));
|
let viewport = self.window.viewport(View::Stereo(render_scene_index));
|
||||||
self.window.make_current(View::Stereo(render_scene_index));
|
self.window.make_current(View::Stereo(render_scene_index));
|
||||||
|
|
||||||
self.renderer.replace_dest_framebuffer(DestFramebuffer::Default {
|
self.renderer.options_mut().dest = DestFramebuffer::Default {
|
||||||
viewport,
|
viewport,
|
||||||
window_size: self.window_size.device_size(),
|
window_size: self.window_size.device_size(),
|
||||||
});
|
};
|
||||||
|
|
||||||
self.draw_environment(render_scene_index);
|
self.draw_environment(render_scene_index);
|
||||||
|
|
||||||
let scene_framebuffer = self.scene_framebuffer.as_ref().unwrap();
|
let scene_framebuffer = self.scene_framebuffer.as_ref().unwrap();
|
||||||
let scene_texture = self.renderer.device.framebuffer_texture(scene_framebuffer);
|
let scene_texture = self.renderer.device().framebuffer_texture(scene_framebuffer);
|
||||||
|
|
||||||
let mut quad_scale = self.scene_metadata.view_box.size().to_4d();
|
let mut quad_scale = self.scene_metadata.view_box.size().to_4d();
|
||||||
quad_scale.set_z(1.0);
|
quad_scale.set_z(1.0);
|
||||||
|
@ -226,13 +229,14 @@ impl<W> DemoApp<W> where W: Window {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
self.renderer.device.draw_elements(6, &RenderState {
|
self.renderer.device().draw_elements(6, &RenderState {
|
||||||
target: &self.renderer.draw_render_target(),
|
target: &self.renderer.draw_render_target(),
|
||||||
program: &self.ground_program.program,
|
program: &self.ground_program.program,
|
||||||
vertex_array: &self.ground_vertex_array.vertex_array,
|
vertex_array: &self.ground_vertex_array.vertex_array,
|
||||||
primitive: Primitive::Triangles,
|
primitive: Primitive::Triangles,
|
||||||
textures: &[],
|
textures: &[],
|
||||||
images: &[],
|
images: &[],
|
||||||
|
storage_buffers: &[],
|
||||||
uniforms: &[
|
uniforms: &[
|
||||||
(&self.ground_program.transform_uniform,
|
(&self.ground_program.transform_uniform,
|
||||||
UniformData::from_transform_3d(&transform)),
|
UniformData::from_transform_3d(&transform)),
|
||||||
|
@ -258,27 +262,16 @@ impl<W> DemoApp<W> where W: Window {
|
||||||
self.renderer.enable_depth();
|
self.renderer.enable_depth();
|
||||||
}
|
}
|
||||||
|
|
||||||
self.renderer.begin_scene();
|
|
||||||
|
|
||||||
// Issue render commands!
|
// Issue render commands!
|
||||||
for command in self.render_command_stream.as_mut().unwrap() {
|
self.scene_proxy.render(&mut self.renderer);
|
||||||
self.renderer.render_command(&command);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.current_frame
|
|
||||||
.as_mut()
|
|
||||||
.unwrap()
|
|
||||||
.scene_stats
|
|
||||||
.push(self.renderer.stats);
|
|
||||||
self.renderer.end_scene();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn take_raster_screenshot(&mut self, path: PathBuf) {
|
pub fn take_raster_screenshot(&mut self, path: PathBuf) {
|
||||||
let drawable_size = self.window_size.device_size();
|
let drawable_size = self.window_size.device_size();
|
||||||
let viewport = RectI::new(Vector2I::default(), drawable_size);
|
let viewport = RectI::new(Vector2I::default(), drawable_size);
|
||||||
let texture_data_receiver =
|
let texture_data_receiver =
|
||||||
self.renderer.device.read_pixels(&RenderTarget::Default, viewport);
|
self.renderer.device().read_pixels(&RenderTarget::Default, viewport);
|
||||||
let pixels = match self.renderer.device.recv_texture_data(&texture_data_receiver) {
|
let pixels = match self.renderer.device().recv_texture_data(&texture_data_receiver) {
|
||||||
TextureData::U8(pixels) => pixels,
|
TextureData::U8(pixels) => pixels,
|
||||||
_ => panic!("Unexpected pixel format for default framebuffer!"),
|
_ => panic!("Unexpected pixel format for default framebuffer!"),
|
||||||
};
|
};
|
||||||
|
@ -291,19 +284,4 @@ impl<W> DemoApp<W> where W: Window {
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_debug_ui(&mut self) {
|
|
||||||
if self.options.ui == UIVisibility::None {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let viewport = self.window.viewport(View::Mono);
|
|
||||||
self.window.make_current(View::Mono);
|
|
||||||
self.renderer.replace_dest_framebuffer(DestFramebuffer::Default {
|
|
||||||
viewport,
|
|
||||||
window_size: self.window_size.device_size(),
|
|
||||||
});
|
|
||||||
|
|
||||||
self.renderer.draw_debug_ui();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ use crate::{BackgroundColor, Options};
|
||||||
use pathfinder_color::ColorU;
|
use pathfinder_color::ColorU;
|
||||||
use pathfinder_geometry::rect::RectI;
|
use pathfinder_geometry::rect::RectI;
|
||||||
use pathfinder_geometry::vector::{Vector2I, vec2i};
|
use pathfinder_geometry::vector::{Vector2I, vec2i};
|
||||||
|
use pathfinder_gpu::allocator::GPUMemoryAllocator;
|
||||||
use pathfinder_gpu::{Device, TextureFormat};
|
use pathfinder_gpu::{Device, TextureFormat};
|
||||||
use pathfinder_renderer::gpu::debug::DebugUIPresenter;
|
use pathfinder_renderer::gpu::debug::DebugUIPresenter;
|
||||||
use pathfinder_resources::ResourceLoader;
|
use pathfinder_resources::ResourceLoader;
|
||||||
|
@ -97,10 +98,7 @@ impl DemoUIModel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DemoUIPresenter<D>
|
pub struct DemoUIPresenter<D> where D: Device {
|
||||||
where
|
|
||||||
D: Device,
|
|
||||||
{
|
|
||||||
effects_texture: D::Texture,
|
effects_texture: D::Texture,
|
||||||
open_texture: D::Texture,
|
open_texture: D::Texture,
|
||||||
rotate_texture: D::Texture,
|
rotate_texture: D::Texture,
|
||||||
|
@ -116,11 +114,10 @@ where
|
||||||
rotate_panel_visible: bool,
|
rotate_panel_visible: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D> DemoUIPresenter<D>
|
impl<D> DemoUIPresenter<D> where D: Device {
|
||||||
where
|
|
||||||
D: Device,
|
|
||||||
{
|
|
||||||
pub fn new(device: &D, resources: &dyn ResourceLoader) -> DemoUIPresenter<D> {
|
pub fn new(device: &D, resources: &dyn ResourceLoader) -> DemoUIPresenter<D> {
|
||||||
|
device.begin_commands();
|
||||||
|
|
||||||
let effects_texture = device.create_texture_from_png(resources,
|
let effects_texture = device.create_texture_from_png(resources,
|
||||||
EFFECTS_PNG_NAME,
|
EFFECTS_PNG_NAME,
|
||||||
TextureFormat::R8);
|
TextureFormat::R8);
|
||||||
|
@ -146,6 +143,8 @@ where
|
||||||
SCREENSHOT_PNG_NAME,
|
SCREENSHOT_PNG_NAME,
|
||||||
TextureFormat::R8);
|
TextureFormat::R8);
|
||||||
|
|
||||||
|
device.end_commands();
|
||||||
|
|
||||||
DemoUIPresenter {
|
DemoUIPresenter {
|
||||||
effects_texture,
|
effects_texture,
|
||||||
open_texture,
|
open_texture,
|
||||||
|
@ -163,19 +162,17 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update<W>(
|
pub fn update<W>(&mut self,
|
||||||
&mut self,
|
|
||||||
device: &D,
|
device: &D,
|
||||||
|
allocator: &mut GPUMemoryAllocator<D>,
|
||||||
window: &mut W,
|
window: &mut W,
|
||||||
debug_ui_presenter: &mut DebugUIPresenter<D>,
|
debug_ui_presenter: &mut DebugUIPresenter<D>,
|
||||||
action: &mut UIAction,
|
action: &mut UIAction,
|
||||||
model: &mut DemoUIModel
|
model: &mut DemoUIModel)
|
||||||
) where
|
where W: Window {
|
||||||
W: Window,
|
|
||||||
{
|
|
||||||
// Draw message text.
|
// Draw message text.
|
||||||
|
|
||||||
self.draw_message_text(device, debug_ui_presenter, model);
|
self.draw_message_text(device, allocator, debug_ui_presenter, model);
|
||||||
|
|
||||||
// Draw button strip.
|
// Draw button strip.
|
||||||
|
|
||||||
|
@ -185,50 +182,57 @@ where
|
||||||
let button_size = vec2i(BUTTON_WIDTH, BUTTON_HEIGHT);
|
let button_size = vec2i(BUTTON_WIDTH, BUTTON_HEIGHT);
|
||||||
|
|
||||||
// Draw effects button.
|
// Draw effects button.
|
||||||
if debug_ui_presenter.ui_presenter.draw_button(device, position, &self.effects_texture) {
|
if debug_ui_presenter.ui_presenter
|
||||||
|
.draw_button(device, allocator, position, &self.effects_texture) {
|
||||||
self.effects_panel_visible = !self.effects_panel_visible;
|
self.effects_panel_visible = !self.effects_panel_visible;
|
||||||
}
|
}
|
||||||
if !self.effects_panel_visible {
|
if !self.effects_panel_visible {
|
||||||
debug_ui_presenter.ui_presenter.draw_tooltip(
|
debug_ui_presenter.ui_presenter.draw_tooltip(device,
|
||||||
device,
|
allocator,
|
||||||
"Effects",
|
"Effects",
|
||||||
RectI::new(position, button_size),
|
RectI::new(position, button_size));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
position += vec2i(button_size.x() + PADDING, 0);
|
position += vec2i(button_size.x() + PADDING, 0);
|
||||||
|
|
||||||
// Draw open button.
|
// Draw open button.
|
||||||
if debug_ui_presenter.ui_presenter.draw_button(device, position, &self.open_texture) {
|
if debug_ui_presenter.ui_presenter
|
||||||
|
.draw_button(device, allocator, position, &self.open_texture) {
|
||||||
// FIXME(pcwalton): This is not sufficient for Android, where we will need to take in
|
// FIXME(pcwalton): This is not sufficient for Android, where we will need to take in
|
||||||
// the contents of the file.
|
// the contents of the file.
|
||||||
window.present_open_svg_dialog();
|
window.present_open_svg_dialog();
|
||||||
}
|
}
|
||||||
debug_ui_presenter.ui_presenter.draw_tooltip(device,
|
debug_ui_presenter.ui_presenter.draw_tooltip(device,
|
||||||
|
allocator,
|
||||||
"Open SVG",
|
"Open SVG",
|
||||||
RectI::new(position, button_size));
|
RectI::new(position, button_size));
|
||||||
position += vec2i(BUTTON_WIDTH + PADDING, 0);
|
position += vec2i(BUTTON_WIDTH + PADDING, 0);
|
||||||
|
|
||||||
// Draw screenshot button.
|
// Draw screenshot button.
|
||||||
if debug_ui_presenter.ui_presenter.draw_button(device,
|
if debug_ui_presenter.ui_presenter
|
||||||
position,
|
.draw_button(device, allocator, position, &self.screenshot_texture) {
|
||||||
&self.screenshot_texture) {
|
|
||||||
self.screenshot_panel_visible = !self.screenshot_panel_visible;
|
self.screenshot_panel_visible = !self.screenshot_panel_visible;
|
||||||
}
|
}
|
||||||
if !self.screenshot_panel_visible {
|
if !self.screenshot_panel_visible {
|
||||||
debug_ui_presenter.ui_presenter.draw_tooltip(
|
debug_ui_presenter.ui_presenter.draw_tooltip(
|
||||||
device,
|
device,
|
||||||
|
allocator,
|
||||||
"Take Screenshot",
|
"Take Screenshot",
|
||||||
RectI::new(position, button_size),
|
RectI::new(position, button_size),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw screenshot panel, if necessary.
|
// Draw screenshot panel, if necessary.
|
||||||
self.draw_screenshot_panel(device, window, debug_ui_presenter, position.x(), action);
|
self.draw_screenshot_panel(device,
|
||||||
|
allocator,
|
||||||
|
window,
|
||||||
|
debug_ui_presenter,
|
||||||
|
position.x(),
|
||||||
|
action);
|
||||||
position += vec2i(button_size.x() + PADDING, 0);
|
position += vec2i(button_size.x() + PADDING, 0);
|
||||||
|
|
||||||
// Draw mode switch.
|
// Draw mode switch.
|
||||||
let new_mode = debug_ui_presenter.ui_presenter.draw_text_switch(
|
let new_mode = debug_ui_presenter.ui_presenter.draw_text_switch(device,
|
||||||
device,
|
allocator,
|
||||||
position,
|
position,
|
||||||
&["2D", "3D", "VR"],
|
&["2D", "3D", "VR"],
|
||||||
model.mode as u8);
|
model.mode as u8);
|
||||||
|
@ -245,6 +249,7 @@ where
|
||||||
let mode_switch_size = vec2i(mode_switch_width, BUTTON_HEIGHT);
|
let mode_switch_size = vec2i(mode_switch_width, BUTTON_HEIGHT);
|
||||||
debug_ui_presenter.ui_presenter.draw_tooltip(
|
debug_ui_presenter.ui_presenter.draw_tooltip(
|
||||||
device,
|
device,
|
||||||
|
allocator,
|
||||||
"2D/3D/VR Mode",
|
"2D/3D/VR Mode",
|
||||||
RectI::new(position, mode_switch_size),
|
RectI::new(position, mode_switch_size),
|
||||||
);
|
);
|
||||||
|
@ -252,6 +257,7 @@ where
|
||||||
|
|
||||||
// Draw background switch.
|
// Draw background switch.
|
||||||
if debug_ui_presenter.ui_presenter.draw_button(device,
|
if debug_ui_presenter.ui_presenter.draw_button(device,
|
||||||
|
allocator,
|
||||||
position,
|
position,
|
||||||
&self.background_texture) {
|
&self.background_texture) {
|
||||||
self.background_panel_visible = !self.background_panel_visible;
|
self.background_panel_visible = !self.background_panel_visible;
|
||||||
|
@ -259,50 +265,60 @@ where
|
||||||
if !self.background_panel_visible {
|
if !self.background_panel_visible {
|
||||||
debug_ui_presenter.ui_presenter.draw_tooltip(
|
debug_ui_presenter.ui_presenter.draw_tooltip(
|
||||||
device,
|
device,
|
||||||
|
allocator,
|
||||||
"Background Color",
|
"Background Color",
|
||||||
RectI::new(position, button_size),
|
RectI::new(position, button_size),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw background panel, if necessary.
|
// Draw background panel, if necessary.
|
||||||
self.draw_background_panel(device, debug_ui_presenter, position.x(), action, model);
|
self.draw_background_panel(device,
|
||||||
|
allocator,
|
||||||
|
debug_ui_presenter,
|
||||||
|
position.x(),
|
||||||
|
action,
|
||||||
|
model);
|
||||||
position += vec2i(button_size.x() + PADDING, 0);
|
position += vec2i(button_size.x() + PADDING, 0);
|
||||||
|
|
||||||
// Draw effects panel, if necessary.
|
// Draw effects panel, if necessary.
|
||||||
self.draw_effects_panel(device, debug_ui_presenter, model, action);
|
self.draw_effects_panel(device, allocator, debug_ui_presenter, model, action);
|
||||||
|
|
||||||
// Draw rotate and zoom buttons, if applicable.
|
// Draw rotate and zoom buttons, if applicable.
|
||||||
if model.mode != Mode::TwoD {
|
if model.mode != Mode::TwoD {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if debug_ui_presenter.ui_presenter.draw_button(device, position, &self.rotate_texture) {
|
if debug_ui_presenter.ui_presenter.draw_button(device,
|
||||||
|
allocator,
|
||||||
|
position,
|
||||||
|
&self.rotate_texture) {
|
||||||
self.rotate_panel_visible = !self.rotate_panel_visible;
|
self.rotate_panel_visible = !self.rotate_panel_visible;
|
||||||
}
|
}
|
||||||
if !self.rotate_panel_visible {
|
if !self.rotate_panel_visible {
|
||||||
debug_ui_presenter.ui_presenter.draw_tooltip(device,
|
debug_ui_presenter.ui_presenter.draw_tooltip(device,
|
||||||
|
allocator,
|
||||||
"Rotate",
|
"Rotate",
|
||||||
RectI::new(position, button_size));
|
RectI::new(position, button_size));
|
||||||
}
|
}
|
||||||
self.draw_rotate_panel(device, debug_ui_presenter, position.x(), action, model);
|
self.draw_rotate_panel(device, allocator, debug_ui_presenter, position.x(), action, model);
|
||||||
position += vec2i(BUTTON_WIDTH + PADDING, 0);
|
position += vec2i(BUTTON_WIDTH + PADDING, 0);
|
||||||
|
|
||||||
// Draw zoom control.
|
// Draw zoom control.
|
||||||
self.draw_zoom_control(device, debug_ui_presenter, position, action);
|
self.draw_zoom_control(device, allocator, debug_ui_presenter, position, action);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_zoom_control(
|
fn draw_zoom_control(&mut self,
|
||||||
&mut self,
|
|
||||||
device: &D,
|
device: &D,
|
||||||
|
allocator: &mut GPUMemoryAllocator<D>,
|
||||||
debug_ui_presenter: &mut DebugUIPresenter<D>,
|
debug_ui_presenter: &mut DebugUIPresenter<D>,
|
||||||
position: Vector2I,
|
position: Vector2I,
|
||||||
action: &mut UIAction,
|
action: &mut UIAction) {
|
||||||
) {
|
|
||||||
let zoom_segmented_control_width =
|
let zoom_segmented_control_width =
|
||||||
debug_ui_presenter.ui_presenter.measure_segmented_control(3);
|
debug_ui_presenter.ui_presenter.measure_segmented_control(3);
|
||||||
let zoom_segmented_control_rect =
|
let zoom_segmented_control_rect =
|
||||||
RectI::new(position, vec2i(zoom_segmented_control_width, BUTTON_HEIGHT));
|
RectI::new(position, vec2i(zoom_segmented_control_width, BUTTON_HEIGHT));
|
||||||
debug_ui_presenter.ui_presenter.draw_tooltip(device, "Zoom", zoom_segmented_control_rect);
|
debug_ui_presenter.ui_presenter
|
||||||
|
.draw_tooltip(device, allocator, "Zoom", zoom_segmented_control_rect);
|
||||||
|
|
||||||
let zoom_textures = &[
|
let zoom_textures = &[
|
||||||
&self.zoom_in_texture,
|
&self.zoom_in_texture,
|
||||||
|
@ -311,6 +327,7 @@ where
|
||||||
];
|
];
|
||||||
|
|
||||||
match debug_ui_presenter.ui_presenter.draw_image_segmented_control(device,
|
match debug_ui_presenter.ui_presenter.draw_image_segmented_control(device,
|
||||||
|
allocator,
|
||||||
position,
|
position,
|
||||||
zoom_textures,
|
zoom_textures,
|
||||||
None) {
|
None) {
|
||||||
|
@ -323,6 +340,7 @@ where
|
||||||
|
|
||||||
fn draw_message_text(&mut self,
|
fn draw_message_text(&mut self,
|
||||||
device: &D,
|
device: &D,
|
||||||
|
allocator: &mut GPUMemoryAllocator<D>,
|
||||||
debug_ui_presenter: &mut DebugUIPresenter<D>,
|
debug_ui_presenter: &mut DebugUIPresenter<D>,
|
||||||
model: &mut DemoUIModel) {
|
model: &mut DemoUIModel) {
|
||||||
if model.message.is_empty() {
|
if model.message.is_empty() {
|
||||||
|
@ -334,11 +352,13 @@ where
|
||||||
let window_size = vec2i(PADDING * 2 + message_size, TOOLTIP_HEIGHT);
|
let window_size = vec2i(PADDING * 2 + message_size, TOOLTIP_HEIGHT);
|
||||||
debug_ui_presenter.ui_presenter.draw_solid_rounded_rect(
|
debug_ui_presenter.ui_presenter.draw_solid_rounded_rect(
|
||||||
device,
|
device,
|
||||||
|
allocator,
|
||||||
RectI::new(window_origin, window_size),
|
RectI::new(window_origin, window_size),
|
||||||
WINDOW_COLOR,
|
WINDOW_COLOR,
|
||||||
);
|
);
|
||||||
debug_ui_presenter.ui_presenter.draw_text(
|
debug_ui_presenter.ui_presenter.draw_text(
|
||||||
device,
|
device,
|
||||||
|
allocator,
|
||||||
&model.message,
|
&model.message,
|
||||||
window_origin + vec2i(PADDING, PADDING + FONT_ASCENT),
|
window_origin + vec2i(PADDING, PADDING + FONT_ASCENT),
|
||||||
false,
|
false,
|
||||||
|
@ -347,6 +367,7 @@ where
|
||||||
|
|
||||||
fn draw_effects_panel(&mut self,
|
fn draw_effects_panel(&mut self,
|
||||||
device: &D,
|
device: &D,
|
||||||
|
allocator: &mut GPUMemoryAllocator<D>,
|
||||||
debug_ui_presenter: &mut DebugUIPresenter<D>,
|
debug_ui_presenter: &mut DebugUIPresenter<D>,
|
||||||
model: &mut DemoUIModel,
|
model: &mut DemoUIModel,
|
||||||
action: &mut UIAction) {
|
action: &mut UIAction) {
|
||||||
|
@ -358,29 +379,29 @@ where
|
||||||
let effects_panel_y = bottom - (BUTTON_HEIGHT + PADDING + EFFECTS_PANEL_HEIGHT);
|
let effects_panel_y = bottom - (BUTTON_HEIGHT + PADDING + EFFECTS_PANEL_HEIGHT);
|
||||||
debug_ui_presenter.ui_presenter.draw_solid_rounded_rect(
|
debug_ui_presenter.ui_presenter.draw_solid_rounded_rect(
|
||||||
device,
|
device,
|
||||||
|
allocator,
|
||||||
RectI::new(vec2i(PADDING, effects_panel_y),
|
RectI::new(vec2i(PADDING, effects_panel_y),
|
||||||
vec2i(EFFECTS_PANEL_WIDTH, EFFECTS_PANEL_HEIGHT)),
|
vec2i(EFFECTS_PANEL_WIDTH, EFFECTS_PANEL_HEIGHT)),
|
||||||
WINDOW_COLOR,
|
WINDOW_COLOR);
|
||||||
);
|
|
||||||
|
|
||||||
self.draw_effects_switch(
|
self.draw_effects_switch(device,
|
||||||
device,
|
allocator,
|
||||||
action,
|
action,
|
||||||
debug_ui_presenter,
|
debug_ui_presenter,
|
||||||
"Gamma Correction",
|
"Gamma Correction",
|
||||||
0,
|
0,
|
||||||
effects_panel_y,
|
effects_panel_y,
|
||||||
&mut model.gamma_correction_effect_enabled);
|
&mut model.gamma_correction_effect_enabled);
|
||||||
self.draw_effects_switch(
|
self.draw_effects_switch(device,
|
||||||
device,
|
allocator,
|
||||||
action,
|
action,
|
||||||
debug_ui_presenter,
|
debug_ui_presenter,
|
||||||
"Stem Darkening",
|
"Stem Darkening",
|
||||||
1,
|
1,
|
||||||
effects_panel_y,
|
effects_panel_y,
|
||||||
&mut model.stem_darkening_effect_enabled);
|
&mut model.stem_darkening_effect_enabled);
|
||||||
self.draw_effects_switch(
|
self.draw_effects_switch(device,
|
||||||
device,
|
allocator,
|
||||||
action,
|
action,
|
||||||
debug_ui_presenter,
|
debug_ui_presenter,
|
||||||
"Subpixel AA",
|
"Subpixel AA",
|
||||||
|
@ -389,14 +410,14 @@ where
|
||||||
&mut model.subpixel_aa_effect_enabled);
|
&mut model.subpixel_aa_effect_enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_screenshot_panel<W>(
|
fn draw_screenshot_panel<W>(&mut self,
|
||||||
&mut self,
|
|
||||||
device: &D,
|
device: &D,
|
||||||
|
allocator: &mut GPUMemoryAllocator<D>,
|
||||||
window: &mut W,
|
window: &mut W,
|
||||||
debug_ui_presenter: &mut DebugUIPresenter<D>,
|
debug_ui_presenter: &mut DebugUIPresenter<D>,
|
||||||
panel_x: i32,
|
panel_x: i32,
|
||||||
action: &mut UIAction,
|
action: &mut UIAction)
|
||||||
) where W: Window {
|
where W: Window {
|
||||||
if !self.screenshot_panel_visible {
|
if !self.screenshot_panel_visible {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -406,36 +427,34 @@ where
|
||||||
let panel_position = vec2i(panel_x, panel_y);
|
let panel_position = vec2i(panel_x, panel_y);
|
||||||
debug_ui_presenter.ui_presenter.draw_solid_rounded_rect(
|
debug_ui_presenter.ui_presenter.draw_solid_rounded_rect(
|
||||||
device,
|
device,
|
||||||
|
allocator,
|
||||||
RectI::new(panel_position, vec2i(SCREENSHOT_PANEL_WIDTH, SCREENSHOT_PANEL_HEIGHT)),
|
RectI::new(panel_position, vec2i(SCREENSHOT_PANEL_WIDTH, SCREENSHOT_PANEL_HEIGHT)),
|
||||||
WINDOW_COLOR,
|
WINDOW_COLOR,
|
||||||
);
|
);
|
||||||
|
|
||||||
self.draw_screenshot_menu_item(
|
self.draw_screenshot_menu_item(device,
|
||||||
device,
|
allocator,
|
||||||
window,
|
window,
|
||||||
debug_ui_presenter,
|
debug_ui_presenter,
|
||||||
ScreenshotType::PNG,
|
ScreenshotType::PNG,
|
||||||
panel_position,
|
panel_position,
|
||||||
action,
|
action);
|
||||||
);
|
self.draw_screenshot_menu_item(device,
|
||||||
self.draw_screenshot_menu_item(
|
allocator,
|
||||||
device,
|
|
||||||
window,
|
window,
|
||||||
debug_ui_presenter,
|
debug_ui_presenter,
|
||||||
ScreenshotType::SVG,
|
ScreenshotType::SVG,
|
||||||
panel_position,
|
panel_position,
|
||||||
action,
|
action);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_background_panel(
|
fn draw_background_panel(&mut self,
|
||||||
&mut self,
|
|
||||||
device: &D,
|
device: &D,
|
||||||
|
allocator: &mut GPUMemoryAllocator<D>,
|
||||||
debug_ui_presenter: &mut DebugUIPresenter<D>,
|
debug_ui_presenter: &mut DebugUIPresenter<D>,
|
||||||
panel_x: i32,
|
panel_x: i32,
|
||||||
action: &mut UIAction,
|
action: &mut UIAction,
|
||||||
model: &mut DemoUIModel,
|
model: &mut DemoUIModel) {
|
||||||
) {
|
|
||||||
if !self.background_panel_visible {
|
if !self.background_panel_visible {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -445,44 +464,41 @@ where
|
||||||
let panel_position = vec2i(panel_x, panel_y);
|
let panel_position = vec2i(panel_x, panel_y);
|
||||||
debug_ui_presenter.ui_presenter.draw_solid_rounded_rect(
|
debug_ui_presenter.ui_presenter.draw_solid_rounded_rect(
|
||||||
device,
|
device,
|
||||||
|
allocator,
|
||||||
RectI::new(panel_position, vec2i(BACKGROUND_PANEL_WIDTH, BACKGROUND_PANEL_HEIGHT)),
|
RectI::new(panel_position, vec2i(BACKGROUND_PANEL_WIDTH, BACKGROUND_PANEL_HEIGHT)),
|
||||||
WINDOW_COLOR,
|
WINDOW_COLOR,
|
||||||
);
|
);
|
||||||
|
|
||||||
self.draw_background_menu_item(
|
self.draw_background_menu_item(device,
|
||||||
device,
|
allocator,
|
||||||
debug_ui_presenter,
|
debug_ui_presenter,
|
||||||
BackgroundColor::Light,
|
BackgroundColor::Light,
|
||||||
panel_position,
|
panel_position,
|
||||||
action,
|
action,
|
||||||
model,
|
model);
|
||||||
);
|
self.draw_background_menu_item(device,
|
||||||
self.draw_background_menu_item(
|
allocator,
|
||||||
device,
|
|
||||||
debug_ui_presenter,
|
debug_ui_presenter,
|
||||||
BackgroundColor::Dark,
|
BackgroundColor::Dark,
|
||||||
panel_position,
|
panel_position,
|
||||||
action,
|
action,
|
||||||
model,
|
model);
|
||||||
);
|
self.draw_background_menu_item(device,
|
||||||
self.draw_background_menu_item(
|
allocator,
|
||||||
device,
|
|
||||||
debug_ui_presenter,
|
debug_ui_presenter,
|
||||||
BackgroundColor::Transparent,
|
BackgroundColor::Transparent,
|
||||||
panel_position,
|
panel_position,
|
||||||
action,
|
action,
|
||||||
model,
|
model);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_rotate_panel(
|
fn draw_rotate_panel(&mut self,
|
||||||
&mut self,
|
|
||||||
device: &D,
|
device: &D,
|
||||||
|
allocator: &mut GPUMemoryAllocator<D>,
|
||||||
debug_ui_presenter: &mut DebugUIPresenter<D>,
|
debug_ui_presenter: &mut DebugUIPresenter<D>,
|
||||||
rotate_panel_x: i32,
|
rotate_panel_x: i32,
|
||||||
action: &mut UIAction,
|
action: &mut UIAction,
|
||||||
model: &mut DemoUIModel
|
model: &mut DemoUIModel) {
|
||||||
) {
|
|
||||||
if !self.rotate_panel_visible {
|
if !self.rotate_panel_visible {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -493,9 +509,9 @@ where
|
||||||
let rotate_panel_size = vec2i(ROTATE_PANEL_WIDTH, ROTATE_PANEL_HEIGHT);
|
let rotate_panel_size = vec2i(ROTATE_PANEL_WIDTH, ROTATE_PANEL_HEIGHT);
|
||||||
debug_ui_presenter.ui_presenter.draw_solid_rounded_rect(
|
debug_ui_presenter.ui_presenter.draw_solid_rounded_rect(
|
||||||
device,
|
device,
|
||||||
|
allocator,
|
||||||
RectI::new(rotate_panel_origin, rotate_panel_size),
|
RectI::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_x, widget_y) = (rotate_panel_x + PADDING, rotate_panel_y + PADDING);
|
||||||
let widget_rect = RectI::new(vec2i(widget_x, widget_y),
|
let widget_rect = RectI::new(vec2i(widget_x, widget_y),
|
||||||
|
@ -503,8 +519,7 @@ where
|
||||||
if let Some(position) = debug_ui_presenter
|
if let Some(position) = debug_ui_presenter
|
||||||
.ui_presenter
|
.ui_presenter
|
||||||
.event_queue
|
.event_queue
|
||||||
.handle_mouse_down_or_dragged_in_rect(widget_rect)
|
.handle_mouse_down_or_dragged_in_rect(widget_rect) {
|
||||||
{
|
|
||||||
model.rotation = position.x();
|
model.rotation = position.x();
|
||||||
*action = UIAction::Rotate(model.rotation());
|
*action = UIAction::Rotate(model.rotation());
|
||||||
}
|
}
|
||||||
|
@ -513,23 +528,25 @@ where
|
||||||
rotate_panel_y + PADDING + SLIDER_KNOB_HEIGHT / 2 - SLIDER_TRACK_HEIGHT / 2;
|
rotate_panel_y + PADDING + SLIDER_KNOB_HEIGHT / 2 - SLIDER_TRACK_HEIGHT / 2;
|
||||||
let slider_track_rect = RectI::new(vec2i(widget_x, slider_track_y),
|
let slider_track_rect = RectI::new(vec2i(widget_x, slider_track_y),
|
||||||
vec2i(SLIDER_WIDTH, SLIDER_TRACK_HEIGHT));
|
vec2i(SLIDER_WIDTH, SLIDER_TRACK_HEIGHT));
|
||||||
debug_ui_presenter.ui_presenter.draw_rect_outline(device, slider_track_rect, TEXT_COLOR);
|
debug_ui_presenter.ui_presenter
|
||||||
|
.draw_rect_outline(device, allocator, slider_track_rect, TEXT_COLOR);
|
||||||
|
|
||||||
let slider_knob_x = widget_x + model.rotation - SLIDER_KNOB_WIDTH / 2;
|
let slider_knob_x = widget_x + model.rotation - SLIDER_KNOB_WIDTH / 2;
|
||||||
let slider_knob_rect = RectI::new(vec2i(slider_knob_x, widget_y),
|
let slider_knob_rect = RectI::new(vec2i(slider_knob_x, widget_y),
|
||||||
vec2i(SLIDER_KNOB_WIDTH, SLIDER_KNOB_HEIGHT));
|
vec2i(SLIDER_KNOB_WIDTH, SLIDER_KNOB_HEIGHT));
|
||||||
debug_ui_presenter.ui_presenter.draw_solid_rect(device, slider_knob_rect, TEXT_COLOR);
|
debug_ui_presenter.ui_presenter
|
||||||
|
.draw_solid_rect(device, allocator, slider_knob_rect, TEXT_COLOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_screenshot_menu_item<W>(
|
fn draw_screenshot_menu_item<W>(&mut self,
|
||||||
&mut self,
|
|
||||||
device: &D,
|
device: &D,
|
||||||
|
allocator: &mut GPUMemoryAllocator<D>,
|
||||||
window: &mut W,
|
window: &mut W,
|
||||||
debug_ui_presenter: &mut DebugUIPresenter<D>,
|
debug_ui_presenter: &mut DebugUIPresenter<D>,
|
||||||
screenshot_type: ScreenshotType,
|
screenshot_type: ScreenshotType,
|
||||||
panel_position: Vector2I,
|
panel_position: Vector2I,
|
||||||
action: &mut UIAction,
|
action: &mut UIAction)
|
||||||
) where W: Window {
|
where W: Window {
|
||||||
let index = screenshot_type as i32;
|
let index = screenshot_type as i32;
|
||||||
let text = format!("Save as {}...", screenshot_type.as_str());
|
let text = format!("Save as {}...", screenshot_type.as_str());
|
||||||
|
|
||||||
|
@ -538,6 +555,7 @@ where
|
||||||
let widget_rect = RectI::new(widget_origin, widget_size);
|
let widget_rect = RectI::new(widget_origin, widget_size);
|
||||||
|
|
||||||
if self.draw_menu_item(device,
|
if self.draw_menu_item(device,
|
||||||
|
allocator,
|
||||||
debug_ui_presenter,
|
debug_ui_presenter,
|
||||||
&text,
|
&text,
|
||||||
widget_rect,
|
widget_rect,
|
||||||
|
@ -551,15 +569,14 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_background_menu_item(
|
fn draw_background_menu_item(&mut self,
|
||||||
&mut self,
|
|
||||||
device: &D,
|
device: &D,
|
||||||
|
allocator: &mut GPUMemoryAllocator<D>,
|
||||||
debug_ui_presenter: &mut DebugUIPresenter<D>,
|
debug_ui_presenter: &mut DebugUIPresenter<D>,
|
||||||
color: BackgroundColor,
|
color: BackgroundColor,
|
||||||
panel_position: Vector2I,
|
panel_position: Vector2I,
|
||||||
action: &mut UIAction,
|
action: &mut UIAction,
|
||||||
model: &mut DemoUIModel,
|
model: &mut DemoUIModel) {
|
||||||
) {
|
|
||||||
let (text, index) = (color.as_str(), color as i32);
|
let (text, index) = (color.as_str(), color as i32);
|
||||||
|
|
||||||
let widget_size = vec2i(BACKGROUND_PANEL_WIDTH, BUTTON_HEIGHT);
|
let widget_size = vec2i(BACKGROUND_PANEL_WIDTH, BUTTON_HEIGHT);
|
||||||
|
@ -568,6 +585,7 @@ where
|
||||||
|
|
||||||
let selected = color == model.background_color;
|
let selected = color == model.background_color;
|
||||||
if self.draw_menu_item(device,
|
if self.draw_menu_item(device,
|
||||||
|
allocator,
|
||||||
debug_ui_presenter,
|
debug_ui_presenter,
|
||||||
text,
|
text,
|
||||||
widget_rect,
|
widget_rect,
|
||||||
|
@ -579,20 +597,21 @@ where
|
||||||
|
|
||||||
fn draw_menu_item(&self,
|
fn draw_menu_item(&self,
|
||||||
device: &D,
|
device: &D,
|
||||||
|
allocator: &mut GPUMemoryAllocator<D>,
|
||||||
debug_ui_presenter: &mut DebugUIPresenter<D>,
|
debug_ui_presenter: &mut DebugUIPresenter<D>,
|
||||||
text: &str,
|
text: &str,
|
||||||
widget_rect: RectI,
|
widget_rect: RectI,
|
||||||
selected: bool)
|
selected: bool)
|
||||||
-> bool {
|
-> bool {
|
||||||
if selected {
|
if selected {
|
||||||
debug_ui_presenter.ui_presenter.draw_solid_rounded_rect(device,
|
debug_ui_presenter.ui_presenter
|
||||||
widget_rect,
|
.draw_solid_rounded_rect(device, allocator, widget_rect, TEXT_COLOR);
|
||||||
TEXT_COLOR);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let (text_x, text_y) = (PADDING * 2, BUTTON_TEXT_OFFSET);
|
let (text_x, text_y) = (PADDING * 2, BUTTON_TEXT_OFFSET);
|
||||||
let text_position = widget_rect.origin() + vec2i(text_x, text_y);
|
let text_position = widget_rect.origin() + vec2i(text_x, text_y);
|
||||||
debug_ui_presenter.ui_presenter.draw_text(device, text, text_position, selected);
|
debug_ui_presenter.ui_presenter
|
||||||
|
.draw_text(device, allocator, text, text_position, selected);
|
||||||
|
|
||||||
debug_ui_presenter.ui_presenter
|
debug_ui_presenter.ui_presenter
|
||||||
.event_queue
|
.event_queue
|
||||||
|
@ -600,9 +619,9 @@ where
|
||||||
.is_some()
|
.is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_effects_switch(
|
fn draw_effects_switch(&self,
|
||||||
&self,
|
|
||||||
device: &D,
|
device: &D,
|
||||||
|
allocator: &mut GPUMemoryAllocator<D>,
|
||||||
action: &mut UIAction,
|
action: &mut UIAction,
|
||||||
debug_ui_presenter: &mut DebugUIPresenter<D>,
|
debug_ui_presenter: &mut DebugUIPresenter<D>,
|
||||||
text: &str,
|
text: &str,
|
||||||
|
@ -611,17 +630,20 @@ where
|
||||||
value: &mut bool) {
|
value: &mut bool) {
|
||||||
let text_x = PADDING * 2;
|
let text_x = PADDING * 2;
|
||||||
let text_y = window_y + PADDING + BUTTON_TEXT_OFFSET + (BUTTON_HEIGHT + PADDING) * index;
|
let text_y = window_y + PADDING + BUTTON_TEXT_OFFSET + (BUTTON_HEIGHT + PADDING) * index;
|
||||||
debug_ui_presenter.ui_presenter.draw_text(device, text, vec2i(text_x, text_y), false);
|
debug_ui_presenter.ui_presenter
|
||||||
|
.draw_text(device, allocator, text, vec2i(text_x, text_y), false);
|
||||||
|
|
||||||
let switch_width = debug_ui_presenter.ui_presenter.measure_segmented_control(2);
|
let switch_width = debug_ui_presenter.ui_presenter.measure_segmented_control(2);
|
||||||
let switch_x = PADDING + EFFECTS_PANEL_WIDTH - (switch_width + PADDING);
|
let switch_x = PADDING + EFFECTS_PANEL_WIDTH - (switch_width + PADDING);
|
||||||
let switch_y = window_y + PADDING + (BUTTON_HEIGHT + PADDING) * index;
|
let switch_y = window_y + PADDING + (BUTTON_HEIGHT + PADDING) * index;
|
||||||
let switch_position = vec2i(switch_x, switch_y);
|
let switch_position = vec2i(switch_x, switch_y);
|
||||||
|
|
||||||
let new_value =
|
let new_value = debug_ui_presenter.ui_presenter
|
||||||
debug_ui_presenter
|
.draw_text_switch(device,
|
||||||
.ui_presenter
|
allocator,
|
||||||
.draw_text_switch(device, switch_position, &["Off", "On"], *value as u8) != 0;
|
switch_position,
|
||||||
|
&["Off", "On"],
|
||||||
|
*value as u8) != 0;
|
||||||
|
|
||||||
if new_value != *value {
|
if new_value != *value {
|
||||||
*action = UIAction::EffectsChanged;
|
*action = UIAction::EffectsChanged;
|
||||||
|
|
Loading…
Reference in New Issue