Update the debug UI
This commit is contained in:
parent
ff7c13c8fb
commit
61833168e5
|
@ -1788,8 +1788,10 @@ name = "pathfinder_gpu"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"half 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"half 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"image 0.23.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"image 0.23.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pathfinder_color 0.5.0",
|
"pathfinder_color 0.5.0",
|
||||||
"pathfinder_geometry 0.5.1",
|
"pathfinder_geometry 0.5.1",
|
||||||
"pathfinder_resources 0.5.0",
|
"pathfinder_resources 0.5.0",
|
||||||
|
@ -1837,6 +1839,7 @@ dependencies = [
|
||||||
"byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"cocoa 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cocoa 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"dispatch 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"half 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"half 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"io-surface 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"io-surface 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
|
|
@ -15,10 +15,12 @@
|
||||||
//!
|
//!
|
||||||
//! The debug font atlas was generated using: https://evanw.github.io/font-texture-generator/
|
//! The debug font atlas was generated using: https://evanw.github.io/font-texture-generator/
|
||||||
|
|
||||||
use crate::gpu::renderer::{RenderStats, RenderTime};
|
use crate::gpu::options::RendererLevel;
|
||||||
use pathfinder_geometry::vector::{Vector2I, vec2i};
|
use crate::gpu::perf::{RenderStats, RenderTime};
|
||||||
use pathfinder_geometry::rect::RectI;
|
use pathfinder_geometry::rect::RectI;
|
||||||
|
use pathfinder_geometry::vector::{Vector2I, vec2i};
|
||||||
use pathfinder_gpu::Device;
|
use pathfinder_gpu::Device;
|
||||||
|
use pathfinder_gpu::allocator::GPUMemoryAllocator;
|
||||||
use pathfinder_resources::ResourceLoader;
|
use pathfinder_resources::ResourceLoader;
|
||||||
use pathfinder_ui::{FONT_ASCENT, LINE_HEIGHT, PADDING, UIPresenter, WINDOW_COLOR};
|
use pathfinder_ui::{FONT_ASCENT, LINE_HEIGHT, PADDING, UIPresenter, WINDOW_COLOR};
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
@ -27,35 +29,39 @@ use std::time::Duration;
|
||||||
|
|
||||||
const SAMPLE_BUFFER_SIZE: usize = 60;
|
const SAMPLE_BUFFER_SIZE: usize = 60;
|
||||||
|
|
||||||
const STATS_WINDOW_WIDTH: i32 = 325;
|
const STATS_WINDOW_WIDTH: i32 = 275;
|
||||||
const STATS_WINDOW_HEIGHT: i32 = LINE_HEIGHT * 4 + PADDING + 2;
|
const STATS_WINDOW_HEIGHT: i32 = LINE_HEIGHT * 4 + PADDING + 2;
|
||||||
|
|
||||||
const PERFORMANCE_WINDOW_WIDTH: i32 = 400;
|
const PERFORMANCE_WINDOW_WIDTH: i32 = 400;
|
||||||
const PERFORMANCE_WINDOW_HEIGHT: i32 = LINE_HEIGHT * 4 + PADDING + 2;
|
const PERFORMANCE_WINDOW_HEIGHT_D3D9: i32 = LINE_HEIGHT * 8 + PADDING + 2;
|
||||||
|
const PERFORMANCE_WINDOW_HEIGHT_D3D11: i32 = LINE_HEIGHT * 10 + PADDING + 2;
|
||||||
|
|
||||||
pub struct DebugUIPresenter<D>
|
const INFO_WINDOW_WIDTH: i32 = 425;
|
||||||
where
|
const INFO_WINDOW_HEIGHT: i32 = LINE_HEIGHT * 2 + PADDING + 2;
|
||||||
D: Device,
|
|
||||||
{
|
pub struct DebugUIPresenter<D> where D: Device {
|
||||||
pub ui_presenter: UIPresenter<D>,
|
pub ui_presenter: UIPresenter<D>,
|
||||||
cpu_samples: SampleBuffer<RenderStats>,
|
cpu_samples: SampleBuffer<RenderStats>,
|
||||||
gpu_samples: SampleBuffer<RenderTime>,
|
gpu_samples: SampleBuffer<RenderTime>,
|
||||||
|
backend_name: &'static str,
|
||||||
|
device_name: String,
|
||||||
|
renderer_level: RendererLevel,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D> DebugUIPresenter<D>
|
impl<D> DebugUIPresenter<D> where D: Device {
|
||||||
where
|
pub fn new(device: &D,
|
||||||
D: Device,
|
resources: &dyn ResourceLoader,
|
||||||
{
|
framebuffer_size: Vector2I,
|
||||||
pub fn new(
|
renderer_level: RendererLevel)
|
||||||
device: &D,
|
-> DebugUIPresenter<D> {
|
||||||
resources: &dyn ResourceLoader,
|
|
||||||
framebuffer_size: Vector2I,
|
|
||||||
) -> DebugUIPresenter<D> {
|
|
||||||
let ui_presenter = UIPresenter::new(device, resources, framebuffer_size);
|
let ui_presenter = UIPresenter::new(device, resources, framebuffer_size);
|
||||||
DebugUIPresenter {
|
DebugUIPresenter {
|
||||||
ui_presenter,
|
ui_presenter,
|
||||||
cpu_samples: SampleBuffer::new(),
|
cpu_samples: SampleBuffer::new(),
|
||||||
gpu_samples: SampleBuffer::new(),
|
gpu_samples: SampleBuffer::new(),
|
||||||
|
backend_name: device.backend_name(),
|
||||||
|
device_name: device.device_name(),
|
||||||
|
renderer_level,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,84 +70,222 @@ where
|
||||||
self.gpu_samples.push(rendering_time);
|
self.gpu_samples.push(rendering_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw(&self, device: &D) {
|
pub fn draw(&self, device: &D, allocator: &mut GPUMemoryAllocator<D>) {
|
||||||
self.draw_stats_window(device);
|
self.draw_stats_window(device, allocator);
|
||||||
self.draw_performance_window(device);
|
self.draw_performance_window(device, allocator);
|
||||||
|
self.draw_info_window(device, allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_stats_window(&self, device: &D) {
|
#[inline]
|
||||||
|
pub fn set_framebuffer_size(&mut self, new_framebuffer_size: Vector2I) {
|
||||||
|
self.ui_presenter.set_framebuffer_size(new_framebuffer_size)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw_info_window(&self, device: &D, allocator: &mut GPUMemoryAllocator<D>) {
|
||||||
|
let framebuffer_size = self.ui_presenter.framebuffer_size();
|
||||||
|
let bottom = framebuffer_size.y() - PADDING;
|
||||||
|
let window_rect = RectI::new(
|
||||||
|
vec2i(framebuffer_size.x() - PADDING - INFO_WINDOW_WIDTH,
|
||||||
|
bottom - INFO_WINDOW_HEIGHT),
|
||||||
|
vec2i(INFO_WINDOW_WIDTH, INFO_WINDOW_HEIGHT),
|
||||||
|
);
|
||||||
|
|
||||||
|
self.ui_presenter.draw_solid_rounded_rect(device, allocator, window_rect, WINDOW_COLOR);
|
||||||
|
|
||||||
|
let origin = window_rect.origin() + vec2i(PADDING, PADDING + FONT_ASCENT);
|
||||||
|
let level = match self.renderer_level {
|
||||||
|
RendererLevel::D3D9 => "D3D9",
|
||||||
|
RendererLevel::D3D11 => "D3D11",
|
||||||
|
};
|
||||||
|
self.ui_presenter.draw_text(device,
|
||||||
|
allocator,
|
||||||
|
&format!("{} ({} level)", self.backend_name, level),
|
||||||
|
origin + vec2i(0, LINE_HEIGHT * 0),
|
||||||
|
false);
|
||||||
|
self.ui_presenter.draw_text(device,
|
||||||
|
allocator,
|
||||||
|
&self.device_name,
|
||||||
|
origin + vec2i(0, LINE_HEIGHT * 1),
|
||||||
|
false);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fn performance_window_size(&self) -> Vector2I {
|
||||||
|
match self.renderer_level {
|
||||||
|
RendererLevel::D3D9 => vec2i(PERFORMANCE_WINDOW_WIDTH, PERFORMANCE_WINDOW_HEIGHT_D3D9),
|
||||||
|
RendererLevel::D3D11 => {
|
||||||
|
vec2i(PERFORMANCE_WINDOW_WIDTH, PERFORMANCE_WINDOW_HEIGHT_D3D11)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw_stats_window(&self, device: &D, allocator: &mut GPUMemoryAllocator<D>) {
|
||||||
|
let performance_window_height = self.performance_window_size().y();
|
||||||
|
|
||||||
let framebuffer_size = self.ui_presenter.framebuffer_size();
|
let framebuffer_size = self.ui_presenter.framebuffer_size();
|
||||||
let bottom = framebuffer_size.y() - PADDING;
|
let bottom = framebuffer_size.y() - PADDING;
|
||||||
let window_rect = RectI::new(
|
let window_rect = RectI::new(
|
||||||
vec2i(framebuffer_size.x() - PADDING - STATS_WINDOW_WIDTH,
|
vec2i(framebuffer_size.x() - PADDING - STATS_WINDOW_WIDTH,
|
||||||
bottom - PERFORMANCE_WINDOW_HEIGHT - PADDING - STATS_WINDOW_HEIGHT),
|
bottom -
|
||||||
vec2i(STATS_WINDOW_WIDTH, STATS_WINDOW_HEIGHT),
|
PADDING -
|
||||||
);
|
INFO_WINDOW_HEIGHT -
|
||||||
|
performance_window_height -
|
||||||
|
PADDING -
|
||||||
|
STATS_WINDOW_HEIGHT),
|
||||||
|
vec2i(STATS_WINDOW_WIDTH, STATS_WINDOW_HEIGHT));
|
||||||
|
|
||||||
self.ui_presenter.draw_solid_rounded_rect(device, window_rect, WINDOW_COLOR);
|
self.ui_presenter.draw_solid_rounded_rect(device, allocator, window_rect, WINDOW_COLOR);
|
||||||
|
|
||||||
let mean_cpu_sample = self.cpu_samples.mean();
|
let mean_cpu_sample = self.cpu_samples.mean();
|
||||||
let origin = window_rect.origin() + vec2i(PADDING, PADDING + FONT_ASCENT);
|
let origin = window_rect.origin() + vec2i(PADDING, PADDING + FONT_ASCENT);
|
||||||
self.ui_presenter.draw_text(
|
self.ui_presenter.draw_text(
|
||||||
device,
|
device,
|
||||||
|
allocator,
|
||||||
&format!("Paths: {}", mean_cpu_sample.path_count),
|
&format!("Paths: {}", mean_cpu_sample.path_count),
|
||||||
origin,
|
origin,
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
self.ui_presenter.draw_text(
|
self.ui_presenter.draw_text(
|
||||||
device,
|
device,
|
||||||
&format!("Solid Tiles: {}", mean_cpu_sample.solid_tile_count),
|
allocator,
|
||||||
|
&format!("Tiles: {}", mean_cpu_sample.total_tile_count),
|
||||||
origin + vec2i(0, LINE_HEIGHT * 1),
|
origin + vec2i(0, LINE_HEIGHT * 1),
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
self.ui_presenter.draw_text(
|
self.ui_presenter.draw_text(
|
||||||
device,
|
device,
|
||||||
&format!("Alpha Tiles: {}", mean_cpu_sample.alpha_tile_count),
|
allocator,
|
||||||
|
&format!("Masks: {}", mean_cpu_sample.alpha_tile_count),
|
||||||
origin + vec2i(0, LINE_HEIGHT * 2),
|
origin + vec2i(0, LINE_HEIGHT * 2),
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
self.ui_presenter.draw_text(
|
self.ui_presenter.draw_text(
|
||||||
device,
|
device,
|
||||||
|
allocator,
|
||||||
&format!("Fills: {}", mean_cpu_sample.fill_count),
|
&format!("Fills: {}", mean_cpu_sample.fill_count),
|
||||||
origin + vec2i(0, LINE_HEIGHT * 3),
|
origin + vec2i(0, LINE_HEIGHT * 3),
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_performance_window(&self, device: &D) {
|
fn draw_performance_window(&self, device: &D, allocator: &mut GPUMemoryAllocator<D>) {
|
||||||
|
let performance_window_size = self.performance_window_size();
|
||||||
|
|
||||||
let framebuffer_size = self.ui_presenter.framebuffer_size();
|
let framebuffer_size = self.ui_presenter.framebuffer_size();
|
||||||
let bottom = framebuffer_size.y() - PADDING;
|
let bottom = framebuffer_size.y() - PADDING;
|
||||||
let window_rect = RectI::new(
|
let window_rect = RectI::new(
|
||||||
vec2i(framebuffer_size.x() - PADDING - PERFORMANCE_WINDOW_WIDTH,
|
vec2i(framebuffer_size.x() - PADDING - performance_window_size.x(),
|
||||||
bottom - PERFORMANCE_WINDOW_HEIGHT),
|
bottom - INFO_WINDOW_HEIGHT - PADDING - performance_window_size.y()),
|
||||||
vec2i(PERFORMANCE_WINDOW_WIDTH, PERFORMANCE_WINDOW_HEIGHT),
|
performance_window_size);
|
||||||
);
|
|
||||||
|
|
||||||
self.ui_presenter.draw_solid_rounded_rect(device, window_rect, WINDOW_COLOR);
|
self.ui_presenter.draw_solid_rounded_rect(device, allocator, window_rect, WINDOW_COLOR);
|
||||||
|
|
||||||
let mean_cpu_sample = self.cpu_samples.mean();
|
let mean_cpu_sample = self.cpu_samples.mean();
|
||||||
let origin = window_rect.origin() + vec2i(PADDING, PADDING + FONT_ASCENT);
|
|
||||||
self.ui_presenter.draw_text(
|
|
||||||
device,
|
|
||||||
&format!("CPU: {:.3} ms", duration_to_ms(mean_cpu_sample.cpu_build_time)),
|
|
||||||
origin,
|
|
||||||
false,
|
|
||||||
);
|
|
||||||
|
|
||||||
let mean_gpu_sample = self.gpu_samples.mean();
|
let mean_gpu_sample = self.gpu_samples.mean();
|
||||||
|
let origin = window_rect.origin() + vec2i(PADDING, PADDING + FONT_ASCENT);
|
||||||
|
|
||||||
|
let mut current_y = 0;
|
||||||
self.ui_presenter.draw_text(
|
self.ui_presenter.draw_text(
|
||||||
device,
|
device,
|
||||||
&format!("GPU: {:.3} ms", duration_to_ms(mean_gpu_sample.gpu_time)),
|
allocator,
|
||||||
origin + vec2i(0, LINE_HEIGHT * 1),
|
&format!("Drawcalls: {}", mean_cpu_sample.drawcall_count),
|
||||||
|
origin + vec2i(0, current_y),
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
|
current_y += LINE_HEIGHT;
|
||||||
let wallclock_time = f64::max(duration_to_ms(mean_gpu_sample.gpu_time),
|
|
||||||
duration_to_ms(mean_cpu_sample.cpu_build_time));
|
|
||||||
self.ui_presenter.draw_text(
|
self.ui_presenter.draw_text(
|
||||||
device,
|
device,
|
||||||
|
allocator,
|
||||||
|
&format!("VRAM Alloc.: {:.1} MB",
|
||||||
|
mean_cpu_sample.gpu_bytes_allocated as f64 / (1024.0 * 1024.0)),
|
||||||
|
origin + vec2i(0, current_y),
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
current_y += LINE_HEIGHT;
|
||||||
|
self.ui_presenter.draw_text(
|
||||||
|
device,
|
||||||
|
allocator,
|
||||||
|
&format!("VRAM Commit: {:.1} MB",
|
||||||
|
mean_cpu_sample.gpu_bytes_committed as f64 / (1024.0 * 1024.0)),
|
||||||
|
origin + vec2i(0, current_y),
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
current_y += LINE_HEIGHT;
|
||||||
|
|
||||||
|
self.ui_presenter.draw_text(
|
||||||
|
device,
|
||||||
|
allocator,
|
||||||
|
&format!("CPU: {:.3} ms", duration_to_ms(mean_cpu_sample.cpu_build_time)),
|
||||||
|
origin + vec2i(0, current_y),
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
current_y += LINE_HEIGHT;
|
||||||
|
|
||||||
|
match self.renderer_level {
|
||||||
|
RendererLevel::D3D11 => {
|
||||||
|
self.ui_presenter.draw_text(
|
||||||
|
device,
|
||||||
|
allocator,
|
||||||
|
&format!("GPU Dice: {:.3} ms", duration_to_ms(mean_gpu_sample.dice_time)),
|
||||||
|
origin + vec2i(0, current_y),
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
current_y += LINE_HEIGHT;
|
||||||
|
self.ui_presenter.draw_text(
|
||||||
|
device,
|
||||||
|
allocator,
|
||||||
|
&format!("GPU Bin: {:.3} ms", duration_to_ms(mean_gpu_sample.bin_time)),
|
||||||
|
origin + vec2i(0, current_y),
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
current_y += LINE_HEIGHT;
|
||||||
|
}
|
||||||
|
RendererLevel::D3D9 => {}
|
||||||
|
}
|
||||||
|
self.ui_presenter.draw_text(
|
||||||
|
device,
|
||||||
|
allocator,
|
||||||
|
&format!("GPU Fill: {:.3} ms", duration_to_ms(mean_gpu_sample.fill_time)),
|
||||||
|
origin + vec2i(0, current_y),
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
current_y += LINE_HEIGHT;
|
||||||
|
self.ui_presenter.draw_text(
|
||||||
|
device,
|
||||||
|
allocator,
|
||||||
|
&format!("GPU Comp.: {:.3} ms", duration_to_ms(mean_gpu_sample.composite_time)),
|
||||||
|
origin + vec2i(0, current_y),
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
current_y += LINE_HEIGHT;
|
||||||
|
self.ui_presenter.draw_text(
|
||||||
|
device,
|
||||||
|
allocator,
|
||||||
|
&format!("GPU Other: {:.3} ms", duration_to_ms(mean_gpu_sample.other_time)),
|
||||||
|
origin + vec2i(0, current_y),
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
current_y += LINE_HEIGHT;
|
||||||
|
|
||||||
|
let mut wallclock_time = match self.renderer_level {
|
||||||
|
RendererLevel::D3D11 => {
|
||||||
|
duration_to_ms(mean_cpu_sample.cpu_build_time) +
|
||||||
|
duration_to_ms(mean_gpu_sample.fill_time)
|
||||||
|
}
|
||||||
|
RendererLevel::D3D9 => {
|
||||||
|
f64::max(duration_to_ms(mean_cpu_sample.cpu_build_time),
|
||||||
|
duration_to_ms(mean_gpu_sample.fill_time))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
wallclock_time += duration_to_ms(mean_gpu_sample.composite_time) +
|
||||||
|
duration_to_ms(mean_gpu_sample.dice_time) +
|
||||||
|
duration_to_ms(mean_gpu_sample.bin_time) +
|
||||||
|
duration_to_ms(mean_gpu_sample.other_time);
|
||||||
|
self.ui_presenter.draw_text(
|
||||||
|
device,
|
||||||
|
allocator,
|
||||||
&format!("Wallclock: {:.3} ms", wallclock_time),
|
&format!("Wallclock: {:.3} ms", wallclock_time),
|
||||||
origin + vec2i(0, LINE_HEIGHT * 3),
|
origin + vec2i(0, current_y),
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,69 +7,88 @@ shaders/gl3/blit.fs.glsl
|
||||||
shaders/gl3/blit.vs.glsl
|
shaders/gl3/blit.vs.glsl
|
||||||
shaders/gl3/clear.fs.glsl
|
shaders/gl3/clear.fs.glsl
|
||||||
shaders/gl3/clear.vs.glsl
|
shaders/gl3/clear.vs.glsl
|
||||||
shaders/gl3/debug_solid.fs.glsl
|
shaders/gl3/d3d9/fill.fs.glsl
|
||||||
shaders/gl3/debug_solid.vs.glsl
|
shaders/gl3/d3d9/fill.vs.glsl
|
||||||
shaders/gl3/debug_texture.fs.glsl
|
shaders/gl3/d3d9/tile.fs.glsl
|
||||||
shaders/gl3/debug_texture.vs.glsl
|
shaders/gl3/d3d9/tile.vs.glsl
|
||||||
|
shaders/gl3/d3d9/tile_clip_combine.fs.glsl
|
||||||
|
shaders/gl3/d3d9/tile_clip_combine.vs.glsl
|
||||||
|
shaders/gl3/d3d9/tile_clip_copy.fs.glsl
|
||||||
|
shaders/gl3/d3d9/tile_clip_copy.vs.glsl
|
||||||
|
shaders/gl3/d3d9/tile_copy.fs.glsl
|
||||||
|
shaders/gl3/d3d9/tile_copy.vs.glsl
|
||||||
|
shaders/gl3/debug/solid.fs.glsl
|
||||||
|
shaders/gl3/debug/solid.vs.glsl
|
||||||
|
shaders/gl3/debug/texture.fs.glsl
|
||||||
|
shaders/gl3/debug/texture.vs.glsl
|
||||||
shaders/gl3/demo_ground.fs.glsl
|
shaders/gl3/demo_ground.fs.glsl
|
||||||
shaders/gl3/demo_ground.vs.glsl
|
shaders/gl3/demo_ground.vs.glsl
|
||||||
shaders/gl3/fill.fs.glsl
|
|
||||||
shaders/gl3/fill.vs.glsl
|
|
||||||
shaders/gl3/reproject.fs.glsl
|
shaders/gl3/reproject.fs.glsl
|
||||||
shaders/gl3/reproject.vs.glsl
|
shaders/gl3/reproject.vs.glsl
|
||||||
shaders/gl3/stencil.fs.glsl
|
shaders/gl3/stencil.fs.glsl
|
||||||
shaders/gl3/stencil.vs.glsl
|
shaders/gl3/stencil.vs.glsl
|
||||||
shaders/gl3/tile.fs.glsl
|
|
||||||
shaders/gl3/tile.vs.glsl
|
|
||||||
shaders/gl3/tile_clip.fs.glsl
|
|
||||||
shaders/gl3/tile_clip.vs.glsl
|
|
||||||
shaders/gl3/tile_copy.fs.glsl
|
|
||||||
shaders/gl3/tile_copy.vs.glsl
|
|
||||||
shaders/gl4/blit.fs.glsl
|
shaders/gl4/blit.fs.glsl
|
||||||
shaders/gl4/blit.vs.glsl
|
shaders/gl4/blit.vs.glsl
|
||||||
shaders/gl4/clear.fs.glsl
|
shaders/gl4/clear.fs.glsl
|
||||||
shaders/gl4/clear.vs.glsl
|
shaders/gl4/clear.vs.glsl
|
||||||
shaders/gl4/debug_solid.fs.glsl
|
shaders/gl4/d3d11/bin.cs.glsl
|
||||||
shaders/gl4/debug_solid.vs.glsl
|
shaders/gl4/d3d11/bound.cs.glsl
|
||||||
shaders/gl4/debug_texture.fs.glsl
|
shaders/gl4/d3d11/dice.cs.glsl
|
||||||
shaders/gl4/debug_texture.vs.glsl
|
shaders/gl4/d3d11/fill.cs.glsl
|
||||||
|
shaders/gl4/d3d11/propagate.cs.glsl
|
||||||
|
shaders/gl4/d3d11/sort.cs.glsl
|
||||||
|
shaders/gl4/d3d11/tile.cs.glsl
|
||||||
|
shaders/gl4/d3d9/fill.fs.glsl
|
||||||
|
shaders/gl4/d3d9/fill.vs.glsl
|
||||||
|
shaders/gl4/d3d9/tile.fs.glsl
|
||||||
|
shaders/gl4/d3d9/tile.vs.glsl
|
||||||
|
shaders/gl4/d3d9/tile_clip_combine.fs.glsl
|
||||||
|
shaders/gl4/d3d9/tile_clip_combine.vs.glsl
|
||||||
|
shaders/gl4/d3d9/tile_clip_copy.fs.glsl
|
||||||
|
shaders/gl4/d3d9/tile_clip_copy.vs.glsl
|
||||||
|
shaders/gl4/d3d9/tile_copy.fs.glsl
|
||||||
|
shaders/gl4/d3d9/tile_copy.vs.glsl
|
||||||
|
shaders/gl4/debug/solid.fs.glsl
|
||||||
|
shaders/gl4/debug/solid.vs.glsl
|
||||||
|
shaders/gl4/debug/texture.fs.glsl
|
||||||
|
shaders/gl4/debug/texture.vs.glsl
|
||||||
shaders/gl4/demo_ground.fs.glsl
|
shaders/gl4/demo_ground.fs.glsl
|
||||||
shaders/gl4/demo_ground.vs.glsl
|
shaders/gl4/demo_ground.vs.glsl
|
||||||
shaders/gl4/fill.fs.glsl
|
|
||||||
shaders/gl4/fill.vs.glsl
|
|
||||||
shaders/gl4/reproject.fs.glsl
|
shaders/gl4/reproject.fs.glsl
|
||||||
shaders/gl4/reproject.vs.glsl
|
shaders/gl4/reproject.vs.glsl
|
||||||
shaders/gl4/stencil.fs.glsl
|
shaders/gl4/stencil.fs.glsl
|
||||||
shaders/gl4/stencil.vs.glsl
|
shaders/gl4/stencil.vs.glsl
|
||||||
shaders/gl4/tile.fs.glsl
|
|
||||||
shaders/gl4/tile.vs.glsl
|
|
||||||
shaders/gl4/tile_clip.fs.glsl
|
|
||||||
shaders/gl4/tile_clip.vs.glsl
|
|
||||||
shaders/gl4/tile_copy.fs.glsl
|
|
||||||
shaders/gl4/tile_copy.vs.glsl
|
|
||||||
shaders/metal/blit.fs.metal
|
shaders/metal/blit.fs.metal
|
||||||
shaders/metal/blit.vs.metal
|
shaders/metal/blit.vs.metal
|
||||||
shaders/metal/clear.fs.metal
|
shaders/metal/clear.fs.metal
|
||||||
shaders/metal/clear.vs.metal
|
shaders/metal/clear.vs.metal
|
||||||
shaders/metal/debug_solid.fs.metal
|
shaders/metal/d3d11/bin.cs.metal
|
||||||
shaders/metal/debug_solid.vs.metal
|
shaders/metal/d3d11/bound.cs.metal
|
||||||
shaders/metal/debug_texture.fs.metal
|
shaders/metal/d3d11/dice.cs.metal
|
||||||
shaders/metal/debug_texture.vs.metal
|
shaders/metal/d3d11/fill.cs.metal
|
||||||
|
shaders/metal/d3d11/propagate.cs.metal
|
||||||
|
shaders/metal/d3d11/sort.cs.metal
|
||||||
|
shaders/metal/d3d11/tile.cs.metal
|
||||||
|
shaders/metal/d3d9/fill.fs.metal
|
||||||
|
shaders/metal/d3d9/fill.vs.metal
|
||||||
|
shaders/metal/d3d9/tile.fs.metal
|
||||||
|
shaders/metal/d3d9/tile.vs.metal
|
||||||
|
shaders/metal/d3d9/tile_clip_combine.fs.metal
|
||||||
|
shaders/metal/d3d9/tile_clip_combine.vs.metal
|
||||||
|
shaders/metal/d3d9/tile_clip_copy.fs.metal
|
||||||
|
shaders/metal/d3d9/tile_clip_copy.vs.metal
|
||||||
|
shaders/metal/d3d9/tile_copy.fs.metal
|
||||||
|
shaders/metal/d3d9/tile_copy.vs.metal
|
||||||
|
shaders/metal/debug/solid.fs.metal
|
||||||
|
shaders/metal/debug/solid.vs.metal
|
||||||
|
shaders/metal/debug/texture.fs.metal
|
||||||
|
shaders/metal/debug/texture.vs.metal
|
||||||
shaders/metal/demo_ground.fs.metal
|
shaders/metal/demo_ground.fs.metal
|
||||||
shaders/metal/demo_ground.vs.metal
|
shaders/metal/demo_ground.vs.metal
|
||||||
shaders/metal/fill.cs.metal
|
|
||||||
shaders/metal/fill.fs.metal
|
|
||||||
shaders/metal/fill.vs.metal
|
|
||||||
shaders/metal/reproject.fs.metal
|
shaders/metal/reproject.fs.metal
|
||||||
shaders/metal/reproject.vs.metal
|
shaders/metal/reproject.vs.metal
|
||||||
shaders/metal/stencil.fs.metal
|
shaders/metal/stencil.fs.metal
|
||||||
shaders/metal/stencil.vs.metal
|
shaders/metal/stencil.vs.metal
|
||||||
shaders/metal/tile.fs.metal
|
|
||||||
shaders/metal/tile.vs.metal
|
|
||||||
shaders/metal/tile_clip.fs.metal
|
|
||||||
shaders/metal/tile_clip.vs.metal
|
|
||||||
shaders/metal/tile_copy.fs.metal
|
|
||||||
shaders/metal/tile_copy.vs.metal
|
|
||||||
textures/area-lut.png
|
textures/area-lut.png
|
||||||
textures/debug-corner-fill.png
|
textures/debug-corner-fill.png
|
||||||
textures/debug-corner-outline.png
|
textures/debug-corner-outline.png
|
||||||
|
|
|
@ -3,36 +3,47 @@ TARGET_DIR?=../resources/shaders
|
||||||
EMPTY=
|
EMPTY=
|
||||||
|
|
||||||
SHADERS=\
|
SHADERS=\
|
||||||
|
d3d9/fill.fs.glsl \
|
||||||
|
d3d9/fill.vs.glsl \
|
||||||
|
d3d9/tile.fs.glsl \
|
||||||
|
d3d9/tile.vs.glsl \
|
||||||
|
d3d9/tile_clip_combine.fs.glsl \
|
||||||
|
d3d9/tile_clip_combine.vs.glsl \
|
||||||
|
d3d9/tile_clip_copy.fs.glsl \
|
||||||
|
d3d9/tile_clip_copy.vs.glsl \
|
||||||
|
d3d9/tile_copy.fs.glsl \
|
||||||
|
d3d9/tile_copy.vs.glsl \
|
||||||
|
debug/solid.fs.glsl \
|
||||||
|
debug/solid.vs.glsl \
|
||||||
|
debug/texture.fs.glsl \
|
||||||
|
debug/texture.vs.glsl \
|
||||||
blit.fs.glsl \
|
blit.fs.glsl \
|
||||||
blit.vs.glsl \
|
blit.vs.glsl \
|
||||||
clear.fs.glsl \
|
clear.fs.glsl \
|
||||||
clear.vs.glsl \
|
clear.vs.glsl \
|
||||||
debug_solid.fs.glsl \
|
|
||||||
debug_solid.vs.glsl \
|
|
||||||
debug_texture.fs.glsl \
|
|
||||||
debug_texture.vs.glsl \
|
|
||||||
demo_ground.fs.glsl \
|
demo_ground.fs.glsl \
|
||||||
demo_ground.vs.glsl \
|
demo_ground.vs.glsl \
|
||||||
fill.fs.glsl \
|
|
||||||
fill.vs.glsl \
|
|
||||||
reproject.fs.glsl \
|
reproject.fs.glsl \
|
||||||
reproject.vs.glsl \
|
reproject.vs.glsl \
|
||||||
stencil.fs.glsl \
|
stencil.fs.glsl \
|
||||||
stencil.vs.glsl \
|
stencil.vs.glsl \
|
||||||
tile.fs.glsl \
|
|
||||||
tile.vs.glsl \
|
|
||||||
tile_clip.fs.glsl \
|
|
||||||
tile_clip.vs.glsl \
|
|
||||||
tile_copy.fs.glsl \
|
|
||||||
tile_copy.vs.glsl \
|
|
||||||
$(EMPTY)
|
$(EMPTY)
|
||||||
|
|
||||||
COMPUTE_SHADERS=\
|
COMPUTE_SHADERS=\
|
||||||
fill.cs.glsl \
|
d3d11/bin.cs.glsl \
|
||||||
|
d3d11/bound.cs.glsl \
|
||||||
|
d3d11/dice.cs.glsl \
|
||||||
|
d3d11/fill.cs.glsl \
|
||||||
|
d3d11/propagate.cs.glsl \
|
||||||
|
d3d11/sort.cs.glsl \
|
||||||
|
d3d11/tile.cs.glsl \
|
||||||
$(EMPTY)
|
$(EMPTY)
|
||||||
|
|
||||||
INCLUDES=\
|
INCLUDES=\
|
||||||
fill.inc.glsl \
|
d3d11/fill_compute.inc.glsl \
|
||||||
|
fill_area.inc.glsl \
|
||||||
|
tile_fragment.inc.glsl \
|
||||||
|
tile_vertex.inc.glsl \
|
||||||
$(EMPTY)
|
$(EMPTY)
|
||||||
|
|
||||||
OUT=\
|
OUT=\
|
||||||
|
@ -58,6 +69,10 @@ HEADER="// Automatically generated from files in pathfinder/shaders/. Do not edi
|
||||||
|
|
||||||
GLSL_SED_ARGS=-e "s/\#version .*//" -e "s/\#line.*$$//"
|
GLSL_SED_ARGS=-e "s/\#version .*//" -e "s/\#line.*$$//"
|
||||||
|
|
||||||
|
GLSL_SHADER_TYPE.fs=frag
|
||||||
|
GLSL_SHADER_TYPE.vs=vert
|
||||||
|
GLSL_SHADER_TYPE.cs=comp
|
||||||
|
|
||||||
all: $(OUT)
|
all: $(OUT)
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
|
@ -65,29 +80,14 @@ all: $(OUT)
|
||||||
clean:
|
clean:
|
||||||
rm -f $(OUT)
|
rm -f $(OUT)
|
||||||
|
|
||||||
build/metal/%.fs.spv: %.fs.glsl $(INCLUDES)
|
build/metal/%.spv: %.glsl $(INCLUDES)
|
||||||
mkdir -p build/metal && glslangValidator $(GLSLANGFLAGS_METAL) -G$(GLSL_VERSION) -S frag -o $@ $<
|
mkdir -p $(dir $@) && glslangValidator $(GLSLANGFLAGS_METAL) -G$(GLSL_VERSION) -S $(GLSL_SHADER_TYPE$(suffix $(basename $(notdir $<)))) -o $@ $<
|
||||||
|
|
||||||
$(TARGET_DIR)/gl3/%.fs.glsl: %.fs.glsl $(INCLUDES)
|
$(TARGET_DIR)/gl3/%.glsl: %.glsl $(INCLUDES)
|
||||||
mkdir -p $(TARGET_DIR)/gl3 && echo $(GLSL_VERSION_HEADER) > $@ && echo $(HEADER) >> $@ && ( glslangValidator $(GLSLANGFLAGS) -S frag -E $< | sed $(GLSL_SED_ARGS) >> $@ ) || ( rm $@ && exit 1 )
|
mkdir -p $(dir $@) && echo $(GLSL_VERSION_HEADER) > $@ && echo $(HEADER) >> $@ && ( glslangValidator $(GLSLANGFLAGS) -S $(GLSL_SHADER_TYPE$(suffix $(basename $(notdir $<)))) -E $< | sed $(GLSL_SED_ARGS) >> $@ ) || ( rm $@ && exit 1 )
|
||||||
|
|
||||||
$(TARGET_DIR)/gl4/%.fs.glsl: %.fs.glsl $(INCLUDES)
|
$(TARGET_DIR)/gl4/%.glsl: %.glsl $(INCLUDES)
|
||||||
mkdir -p $(TARGET_DIR)/gl4 && echo $(GLSL_VERSION_HEADER) > $@ && echo $(HEADER) >> $@ && ( glslangValidator $(GLSLANGFLAGS) -S frag -E $< | sed $(GLSL_SED_ARGS) >> $@ ) || ( rm $@ && exit 1 )
|
mkdir -p $(dir $@) && echo $(GLSL_VERSION_HEADER) > $@ && echo $(HEADER) >> $@ && ( glslangValidator $(GLSLANGFLAGS) -S $(GLSL_SHADER_TYPE$(suffix $(basename $(notdir $<)))) -E $< | sed $(GLSL_SED_ARGS) >> $@ ) || ( rm $@ && exit 1 )
|
||||||
|
|
||||||
build/metal/%.vs.spv: %.vs.glsl $(INCLUDES)
|
$(TARGET_DIR)/metal/%.metal: build/metal/%.spv
|
||||||
mkdir -p build/metal && glslangValidator $(GLSLANGFLAGS_METAL) -G$(GLSL_VERSION) -S vert -o $@ $<
|
mkdir -p $(dir $@) && echo $(HEADER) > $@ && ( $(SPIRVCROSS) $(SPIRVCROSSFLAGS) $< >> $@ ) || ( rm $@ && exit 1 )
|
||||||
|
|
||||||
$(TARGET_DIR)/gl3/%.vs.glsl: %.vs.glsl $(INCLUDES)
|
|
||||||
mkdir -p $(TARGET_DIR)/gl3 && echo $(GLSL_VERSION_HEADER) > $@ && echo $(HEADER) >> $@ && ( glslangValidator $(GLSLANGFLAGS) -S vert -E $< | sed $(GLSL_SED_ARGS) >> $@ ) || ( rm $@ && exit 1 )
|
|
||||||
|
|
||||||
$(TARGET_DIR)/gl4/%.vs.glsl: %.vs.glsl $(INCLUDES)
|
|
||||||
mkdir -p $(TARGET_DIR)/gl3 && echo $(GLSL_VERSION_HEADER) > $@ && echo $(HEADER) >> $@ && ( glslangValidator $(GLSLANGFLAGS) -S vert -E $< | sed $(GLSL_SED_ARGS) >> $@ ) || ( rm $@ && exit 1 )
|
|
||||||
|
|
||||||
build/metal/%.cs.spv: %.cs.glsl $(INCLUDES)
|
|
||||||
mkdir -p build/metal && glslangValidator $(GLSLANGFLAGS_METAL) -G$(GLSL_COMPUTE_VERSION) -S comp -o $@ $<
|
|
||||||
|
|
||||||
$(TARGET_DIR)/gl4/%.cs.glsl: %.cs.glsl $(INCLUDES)
|
|
||||||
mkdir -p $(TARGET_DIR)/gl4 && echo $(GLSL_VERSION_HEADER) > $@ && echo $(HEADER) >> $@ && ( glslangValidator $(GLSLANGFLAGS) -S vert -E $< | sed $(GLSL_SED_ARGS) >> $@ ) || ( rm $@ && exit 1 )
|
|
||||||
|
|
||||||
$(TARGET_DIR)/metal/%.metal: build/metal/%.spv
|
|
||||||
mkdir -p $(TARGET_DIR)/metal && echo $(HEADER) > $@ && ( $(SPIRVCROSS) $(SPIRVCROSSFLAGS) $< >> $@ ) || ( rm $@ && exit 1 )
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#version 330
|
#version 330
|
||||||
|
|
||||||
// pathfinder/shaders/debug_solid.fs.glsl
|
// pathfinder/shaders/debug/solid.fs.glsl
|
||||||
//
|
//
|
||||||
// Copyright © 2019 The Pathfinder Project Developers.
|
// Copyright © 2019 The Pathfinder Project Developers.
|
||||||
//
|
//
|
|
@ -1,6 +1,6 @@
|
||||||
#version 330
|
#version 330
|
||||||
|
|
||||||
// pathfinder/shaders/debug_solid.vs.glsl
|
// pathfinder/shaders/debug/solid.vs.glsl
|
||||||
//
|
//
|
||||||
// Copyright © 2019 The Pathfinder Project Developers.
|
// Copyright © 2019 The Pathfinder Project Developers.
|
||||||
//
|
//
|
|
@ -1,6 +1,6 @@
|
||||||
#version 330
|
#version 330
|
||||||
|
|
||||||
// pathfinder/shaders/debug_texture.fs.glsl
|
// pathfinder/shaders/debug/texture.fs.glsl
|
||||||
//
|
//
|
||||||
// Copyright © 2019 The Pathfinder Project Developers.
|
// Copyright © 2019 The Pathfinder Project Developers.
|
||||||
//
|
//
|
|
@ -1,6 +1,6 @@
|
||||||
#version 330
|
#version 330
|
||||||
|
|
||||||
// pathfinder/shaders/debug_texture.vs.glsl
|
// pathfinder/shaders/debug/texture.vs.glsl
|
||||||
//
|
//
|
||||||
// Copyright © 2019 The Pathfinder Project Developers.
|
// Copyright © 2019 The Pathfinder Project Developers.
|
||||||
//
|
//
|
302
ui/src/lib.rs
302
ui/src/lib.rs
|
@ -20,9 +20,10 @@ use hashbrown::HashMap;
|
||||||
use pathfinder_color::ColorU;
|
use pathfinder_color::ColorU;
|
||||||
use pathfinder_geometry::rect::RectI;
|
use pathfinder_geometry::rect::RectI;
|
||||||
use pathfinder_geometry::vector::{Vector2F, Vector2I, vec2i};
|
use pathfinder_geometry::vector::{Vector2F, Vector2I, vec2i};
|
||||||
use pathfinder_gpu::{BlendFactor, BlendState, BufferData, BufferTarget, BufferUploadMode, Device};
|
use pathfinder_gpu::allocator::{BufferTag, GPUMemoryAllocator};
|
||||||
use pathfinder_gpu::{Primitive, RenderOptions, RenderState, RenderTarget, TextureFormat};
|
use pathfinder_gpu::{BlendFactor, BlendState, BufferTarget, Device, Primitive, RenderOptions};
|
||||||
use pathfinder_gpu::{UniformData, VertexAttrClass, VertexAttrDescriptor, VertexAttrType};
|
use pathfinder_gpu::{RenderState, RenderTarget, TextureFormat, UniformData, VertexAttrClass};
|
||||||
|
use pathfinder_gpu::{VertexAttrDescriptor, VertexAttrType};
|
||||||
use pathfinder_resources::ResourceLoader;
|
use pathfinder_resources::ResourceLoader;
|
||||||
use pathfinder_simd::default::F32x4;
|
use pathfinder_simd::default::F32x4;
|
||||||
use serde_json;
|
use serde_json;
|
||||||
|
@ -71,9 +72,7 @@ pub struct UIPresenter<D> where D: Device {
|
||||||
framebuffer_size: Vector2I,
|
framebuffer_size: Vector2I,
|
||||||
|
|
||||||
texture_program: DebugTextureProgram<D>,
|
texture_program: DebugTextureProgram<D>,
|
||||||
texture_vertex_array: DebugTextureVertexArray<D>,
|
|
||||||
solid_program: DebugSolidProgram<D>,
|
solid_program: DebugSolidProgram<D>,
|
||||||
solid_vertex_array: DebugSolidVertexArray<D>,
|
|
||||||
font: DebugFont,
|
font: DebugFont,
|
||||||
|
|
||||||
font_texture: D::Texture,
|
font_texture: D::Texture,
|
||||||
|
@ -85,11 +84,9 @@ impl<D> UIPresenter<D> where D: Device {
|
||||||
pub fn new(device: &D, resources: &dyn ResourceLoader, framebuffer_size: Vector2I)
|
pub fn new(device: &D, resources: &dyn ResourceLoader, framebuffer_size: Vector2I)
|
||||||
-> UIPresenter<D> {
|
-> UIPresenter<D> {
|
||||||
let texture_program = DebugTextureProgram::new(device, resources);
|
let texture_program = DebugTextureProgram::new(device, resources);
|
||||||
let texture_vertex_array = DebugTextureVertexArray::new(device, &texture_program);
|
|
||||||
let font = DebugFont::load(resources);
|
let font = DebugFont::load(resources);
|
||||||
|
|
||||||
let solid_program = DebugSolidProgram::new(device, resources);
|
let solid_program = DebugSolidProgram::new(device, resources);
|
||||||
let solid_vertex_array = DebugSolidVertexArray::new(device, &solid_program);
|
|
||||||
|
|
||||||
let font_texture = device.create_texture_from_png(resources,
|
let font_texture = device.create_texture_from_png(resources,
|
||||||
FONT_PNG_NAME,
|
FONT_PNG_NAME,
|
||||||
|
@ -108,10 +105,8 @@ impl<D> UIPresenter<D> where D: Device {
|
||||||
framebuffer_size,
|
framebuffer_size,
|
||||||
|
|
||||||
texture_program,
|
texture_program,
|
||||||
texture_vertex_array,
|
|
||||||
font,
|
font,
|
||||||
solid_program,
|
solid_program,
|
||||||
solid_vertex_array,
|
|
||||||
|
|
||||||
font_texture,
|
font_texture,
|
||||||
corner_fill_texture,
|
corner_fill_texture,
|
||||||
|
@ -128,16 +123,25 @@ impl<D> UIPresenter<D> where D: Device {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn draw_solid_rect(&self, device: &D, rect: RectI, color: ColorU) {
|
pub fn draw_solid_rect(&self,
|
||||||
self.draw_rect(device, rect, color, true);
|
device: &D,
|
||||||
|
allocator: &mut GPUMemoryAllocator<D>,
|
||||||
|
rect: RectI,
|
||||||
|
color: ColorU) {
|
||||||
|
self.draw_rect(device, allocator, rect, color, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_rect_outline(&self, device: &D, rect: RectI, color: ColorU) {
|
pub fn draw_rect_outline(&self,
|
||||||
self.draw_rect(device, rect, color, false);
|
device: &D,
|
||||||
|
allocator: &mut GPUMemoryAllocator<D>,
|
||||||
|
rect: RectI,
|
||||||
|
color: ColorU) {
|
||||||
|
self.draw_rect(device, allocator, rect, color, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_rect(&self,
|
fn draw_rect(&self,
|
||||||
device: &D,
|
device: &D,
|
||||||
|
allocator: &mut GPUMemoryAllocator<D>,
|
||||||
rect: RectI,
|
rect: RectI,
|
||||||
color: ColorU,
|
color: ColorU,
|
||||||
filled: bool) {
|
filled: bool) {
|
||||||
|
@ -150,12 +154,14 @@ impl<D> UIPresenter<D> where D: Device {
|
||||||
|
|
||||||
if filled {
|
if filled {
|
||||||
self.draw_solid_rects_with_vertex_data(device,
|
self.draw_solid_rects_with_vertex_data(device,
|
||||||
|
allocator,
|
||||||
&vertex_data,
|
&vertex_data,
|
||||||
&QUAD_INDICES,
|
&QUAD_INDICES,
|
||||||
color,
|
color,
|
||||||
true);
|
true);
|
||||||
} else {
|
} else {
|
||||||
self.draw_solid_rects_with_vertex_data(device,
|
self.draw_solid_rects_with_vertex_data(device,
|
||||||
|
allocator,
|
||||||
&vertex_data,
|
&vertex_data,
|
||||||
&RECT_LINE_INDICES,
|
&RECT_LINE_INDICES,
|
||||||
color,
|
color,
|
||||||
|
@ -165,39 +171,60 @@ impl<D> UIPresenter<D> where D: Device {
|
||||||
|
|
||||||
fn draw_solid_rects_with_vertex_data(&self,
|
fn draw_solid_rects_with_vertex_data(&self,
|
||||||
device: &D,
|
device: &D,
|
||||||
|
allocator: &mut GPUMemoryAllocator<D>,
|
||||||
vertex_data: &[DebugSolidVertex],
|
vertex_data: &[DebugSolidVertex],
|
||||||
index_data: &[u32],
|
index_data: &[u32],
|
||||||
color: ColorU,
|
color: ColorU,
|
||||||
filled: bool) {
|
filled: bool) {
|
||||||
device.allocate_buffer(&self.solid_vertex_array.vertex_buffer,
|
let vertex_buffer_id =
|
||||||
BufferData::Memory(vertex_data),
|
allocator.allocate_buffer::<DebugSolidVertex>(device,
|
||||||
BufferTarget::Vertex);
|
vertex_data.len() as u64,
|
||||||
device.allocate_buffer(&self.solid_vertex_array.index_buffer,
|
BufferTag("SolidVertexDebug"));
|
||||||
BufferData::Memory(index_data),
|
let index_buffer_id = allocator.allocate_buffer::<u32>(device,
|
||||||
BufferTarget::Index);
|
index_data.len() as u64,
|
||||||
|
BufferTag("SolidIndexDebug"));
|
||||||
|
{
|
||||||
|
let vertex_buffer = allocator.get_buffer(vertex_buffer_id);
|
||||||
|
let index_buffer = allocator.get_buffer(index_buffer_id);
|
||||||
|
device.upload_to_buffer(&vertex_buffer, 0, vertex_data, BufferTarget::Vertex);
|
||||||
|
device.upload_to_buffer(&index_buffer, 0, index_data, BufferTarget::Index);
|
||||||
|
let solid_vertex_array = DebugSolidVertexArray::new(device,
|
||||||
|
&self.solid_program,
|
||||||
|
vertex_buffer,
|
||||||
|
index_buffer);
|
||||||
|
|
||||||
let primitive = if filled { Primitive::Triangles } else { Primitive::Lines };
|
let primitive = if filled { Primitive::Triangles } else { Primitive::Lines };
|
||||||
device.draw_elements(index_data.len() as u32, &RenderState {
|
device.draw_elements(index_data.len() as u32, &RenderState {
|
||||||
target: &RenderTarget::Default,
|
target: &RenderTarget::Default,
|
||||||
program: &self.solid_program.program,
|
program: &self.solid_program.program,
|
||||||
vertex_array: &self.solid_vertex_array.vertex_array,
|
vertex_array: &solid_vertex_array.vertex_array,
|
||||||
primitive,
|
primitive,
|
||||||
uniforms: &[
|
uniforms: &[
|
||||||
(&self.solid_program.framebuffer_size_uniform,
|
(&self.solid_program.framebuffer_size_uniform,
|
||||||
UniformData::Vec2(self.framebuffer_size.0.to_f32x2())),
|
UniformData::Vec2(self.framebuffer_size.0.to_f32x2())),
|
||||||
(&self.solid_program.color_uniform, get_color_uniform(color)),
|
(&self.solid_program.color_uniform, get_color_uniform(color)),
|
||||||
],
|
],
|
||||||
textures: &[],
|
textures: &[],
|
||||||
images: &[],
|
images: &[],
|
||||||
viewport: RectI::new(Vector2I::default(), self.framebuffer_size),
|
storage_buffers: &[],
|
||||||
options: RenderOptions {
|
viewport: RectI::new(Vector2I::default(), self.framebuffer_size),
|
||||||
blend: Some(alpha_blend_state()),
|
options: RenderOptions {
|
||||||
..RenderOptions::default()
|
blend: Some(alpha_blend_state()),
|
||||||
},
|
..RenderOptions::default()
|
||||||
});
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
allocator.free_buffer(index_buffer_id);
|
||||||
|
allocator.free_buffer(vertex_buffer_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_text(&self, device: &D, string: &str, origin: Vector2I, invert: bool) {
|
pub fn draw_text(&self,
|
||||||
|
device: &D,
|
||||||
|
allocator: &mut GPUMemoryAllocator<D>,
|
||||||
|
string: &str,
|
||||||
|
origin: Vector2I,
|
||||||
|
invert: bool) {
|
||||||
let mut next = origin;
|
let mut next = origin;
|
||||||
let char_count = string.chars().count();
|
let char_count = string.chars().count();
|
||||||
let mut vertex_data = Vec::with_capacity(char_count * 4);
|
let mut vertex_data = Vec::with_capacity(char_count * 4);
|
||||||
|
@ -227,6 +254,7 @@ impl<D> UIPresenter<D> where D: Device {
|
||||||
|
|
||||||
let color = if invert { INVERTED_TEXT_COLOR } else { TEXT_COLOR };
|
let color = if invert { INVERTED_TEXT_COLOR } else { TEXT_COLOR };
|
||||||
self.draw_texture_with_vertex_data(device,
|
self.draw_texture_with_vertex_data(device,
|
||||||
|
allocator,
|
||||||
&vertex_data,
|
&vertex_data,
|
||||||
&index_data,
|
&index_data,
|
||||||
&self.font_texture,
|
&self.font_texture,
|
||||||
|
@ -235,6 +263,7 @@ impl<D> UIPresenter<D> where D: Device {
|
||||||
|
|
||||||
pub fn draw_texture(&self,
|
pub fn draw_texture(&self,
|
||||||
device: &D,
|
device: &D,
|
||||||
|
allocator: &mut GPUMemoryAllocator<D>,
|
||||||
origin: Vector2I,
|
origin: Vector2I,
|
||||||
texture: &D::Texture,
|
texture: &D::Texture,
|
||||||
color: ColorU) {
|
color: ColorU) {
|
||||||
|
@ -247,7 +276,12 @@ impl<D> UIPresenter<D> where D: Device {
|
||||||
DebugTextureVertex::new(position_rect.lower_left(), tex_coord_rect.lower_left()),
|
DebugTextureVertex::new(position_rect.lower_left(), tex_coord_rect.lower_left()),
|
||||||
];
|
];
|
||||||
|
|
||||||
self.draw_texture_with_vertex_data(device, &vertex_data, &QUAD_INDICES, texture, color);
|
self.draw_texture_with_vertex_data(device,
|
||||||
|
allocator,
|
||||||
|
&vertex_data,
|
||||||
|
&QUAD_INDICES,
|
||||||
|
texture,
|
||||||
|
color);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn measure_text(&self, string: &str) -> i32 {
|
pub fn measure_text(&self, string: &str) -> i32 {
|
||||||
|
@ -268,10 +302,14 @@ impl<D> UIPresenter<D> where D: Device {
|
||||||
SEGMENT_SIZE * segment_count as i32 + (segment_count - 1) as i32
|
SEGMENT_SIZE * segment_count as i32 + (segment_count - 1) as i32
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_solid_rounded_rect(&self, device: &D, rect: RectI, color: ColorU) {
|
pub fn draw_solid_rounded_rect(&self,
|
||||||
|
device: &D,
|
||||||
|
allocator: &mut GPUMemoryAllocator<D>,
|
||||||
|
rect: RectI,
|
||||||
|
color: ColorU) {
|
||||||
let corner_texture = self.corner_texture(true);
|
let corner_texture = self.corner_texture(true);
|
||||||
let corner_rects = CornerRects::new(device, rect, corner_texture);
|
let corner_rects = CornerRects::new(device, rect, corner_texture);
|
||||||
self.draw_rounded_rect_corners(device, color, corner_texture, &corner_rects);
|
self.draw_rounded_rect_corners(device, allocator, color, corner_texture, &corner_rects);
|
||||||
|
|
||||||
let solid_rect_mid = RectI::from_points(corner_rects.upper_left.upper_right(),
|
let solid_rect_mid = RectI::from_points(corner_rects.upper_left.upper_right(),
|
||||||
corner_rects.lower_right.lower_left());
|
corner_rects.lower_right.lower_left());
|
||||||
|
@ -302,16 +340,21 @@ impl<D> UIPresenter<D> where D: Device {
|
||||||
index_data.extend(QUAD_INDICES.iter().map(|&index| index + 8));
|
index_data.extend(QUAD_INDICES.iter().map(|&index| index + 8));
|
||||||
|
|
||||||
self.draw_solid_rects_with_vertex_data(device,
|
self.draw_solid_rects_with_vertex_data(device,
|
||||||
|
allocator,
|
||||||
&vertex_data,
|
&vertex_data,
|
||||||
&index_data[0..18],
|
&index_data[0..18],
|
||||||
color,
|
color,
|
||||||
true);
|
true);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_rounded_rect_outline(&self, device: &D, rect: RectI, color: ColorU) {
|
pub fn draw_rounded_rect_outline(&self,
|
||||||
|
device: &D,
|
||||||
|
allocator: &mut GPUMemoryAllocator<D>,
|
||||||
|
rect: RectI,
|
||||||
|
color: ColorU) {
|
||||||
let corner_texture = self.corner_texture(false);
|
let corner_texture = self.corner_texture(false);
|
||||||
let corner_rects = CornerRects::new(device, rect, corner_texture);
|
let corner_rects = CornerRects::new(device, rect, corner_texture);
|
||||||
self.draw_rounded_rect_corners(device, color, corner_texture, &corner_rects);
|
self.draw_rounded_rect_corners(device, allocator, color, corner_texture, &corner_rects);
|
||||||
|
|
||||||
let vertex_data = vec![
|
let vertex_data = vec![
|
||||||
DebugSolidVertex::new(corner_rects.upper_left.upper_right()),
|
DebugSolidVertex::new(corner_rects.upper_left.upper_right()),
|
||||||
|
@ -325,18 +368,34 @@ impl<D> UIPresenter<D> where D: Device {
|
||||||
];
|
];
|
||||||
|
|
||||||
let index_data = &OUTLINE_RECT_LINE_INDICES;
|
let index_data = &OUTLINE_RECT_LINE_INDICES;
|
||||||
self.draw_solid_rects_with_vertex_data(device, &vertex_data, index_data, color, false);
|
self.draw_solid_rects_with_vertex_data(device,
|
||||||
|
allocator,
|
||||||
|
&vertex_data,
|
||||||
|
index_data,
|
||||||
|
color,
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(pcwalton): `LineSegment2I`.
|
// TODO(pcwalton): `LineSegment2I`.
|
||||||
fn draw_line(&self, device: &D, from: Vector2I, to: Vector2I, color: ColorU) {
|
fn draw_line(&self,
|
||||||
|
device: &D,
|
||||||
|
allocator: &mut GPUMemoryAllocator<D>,
|
||||||
|
from: Vector2I,
|
||||||
|
to: Vector2I,
|
||||||
|
color: ColorU) {
|
||||||
let vertex_data = vec![DebugSolidVertex::new(from), DebugSolidVertex::new(to)];
|
let vertex_data = vec![DebugSolidVertex::new(from), DebugSolidVertex::new(to)];
|
||||||
self.draw_solid_rects_with_vertex_data(device, &vertex_data, &[0, 1], color, false);
|
self.draw_solid_rects_with_vertex_data(device,
|
||||||
|
allocator,
|
||||||
|
&vertex_data,
|
||||||
|
&[0, 1],
|
||||||
|
color,
|
||||||
|
false);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_rounded_rect_corners(&self,
|
fn draw_rounded_rect_corners(&self,
|
||||||
device: &D,
|
device: &D,
|
||||||
|
allocator: &mut GPUMemoryAllocator<D>,
|
||||||
color: ColorU,
|
color: ColorU,
|
||||||
texture: &D::Texture,
|
texture: &D::Texture,
|
||||||
corner_rects: &CornerRects) {
|
corner_rects: &CornerRects) {
|
||||||
|
@ -387,7 +446,12 @@ impl<D> UIPresenter<D> where D: Device {
|
||||||
index_data.extend(QUAD_INDICES.iter().map(|&index| index + 8));
|
index_data.extend(QUAD_INDICES.iter().map(|&index| index + 8));
|
||||||
index_data.extend(QUAD_INDICES.iter().map(|&index| index + 12));
|
index_data.extend(QUAD_INDICES.iter().map(|&index| index + 12));
|
||||||
|
|
||||||
self.draw_texture_with_vertex_data(device, &vertex_data, &index_data, texture, color);
|
self.draw_texture_with_vertex_data(device,
|
||||||
|
allocator,
|
||||||
|
&vertex_data,
|
||||||
|
&index_data,
|
||||||
|
texture,
|
||||||
|
color);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn corner_texture(&self, filled: bool) -> &D::Texture {
|
fn corner_texture(&self, filled: bool) -> &D::Texture {
|
||||||
|
@ -396,44 +460,66 @@ impl<D> UIPresenter<D> where D: Device {
|
||||||
|
|
||||||
fn draw_texture_with_vertex_data(&self,
|
fn draw_texture_with_vertex_data(&self,
|
||||||
device: &D,
|
device: &D,
|
||||||
|
allocator: &mut GPUMemoryAllocator<D>,
|
||||||
vertex_data: &[DebugTextureVertex],
|
vertex_data: &[DebugTextureVertex],
|
||||||
index_data: &[u32],
|
index_data: &[u32],
|
||||||
texture: &D::Texture,
|
texture: &D::Texture,
|
||||||
color: ColorU) {
|
color: ColorU) {
|
||||||
device.allocate_buffer(&self.texture_vertex_array.vertex_buffer,
|
let vertex_buffer_id =
|
||||||
BufferData::Memory(vertex_data),
|
allocator.allocate_buffer::<DebugTextureVertex>(device,
|
||||||
BufferTarget::Vertex);
|
vertex_data.len() as u64,
|
||||||
device.allocate_buffer(&self.texture_vertex_array.index_buffer,
|
BufferTag("TextureVertexDebug"));
|
||||||
BufferData::Memory(index_data),
|
let index_buffer_id = allocator.allocate_buffer::<u32>(device,
|
||||||
BufferTarget::Index);
|
index_data.len() as u64,
|
||||||
|
BufferTag("TextureIndexDebug"));
|
||||||
|
{
|
||||||
|
let vertex_buffer = allocator.get_buffer(vertex_buffer_id);
|
||||||
|
let index_buffer = allocator.get_buffer(index_buffer_id);
|
||||||
|
device.upload_to_buffer(&vertex_buffer, 0, vertex_data, BufferTarget::Vertex);
|
||||||
|
device.upload_to_buffer(&index_buffer, 0, index_data, BufferTarget::Index);
|
||||||
|
|
||||||
device.draw_elements(index_data.len() as u32, &RenderState {
|
let texture_vertex_array = DebugTextureVertexArray::new(device,
|
||||||
target: &RenderTarget::Default,
|
&self.texture_program,
|
||||||
program: &self.texture_program.program,
|
vertex_buffer,
|
||||||
vertex_array: &self.texture_vertex_array.vertex_array,
|
index_buffer);
|
||||||
primitive: Primitive::Triangles,
|
|
||||||
textures: &[(&self.texture_program.texture, &texture)],
|
device.draw_elements(index_data.len() as u32, &RenderState {
|
||||||
images: &[],
|
target: &RenderTarget::Default,
|
||||||
uniforms: &[
|
program: &self.texture_program.program,
|
||||||
(&self.texture_program.framebuffer_size_uniform,
|
vertex_array: &texture_vertex_array.vertex_array,
|
||||||
UniformData::Vec2(self.framebuffer_size.0.to_f32x2())),
|
primitive: Primitive::Triangles,
|
||||||
(&self.texture_program.color_uniform, get_color_uniform(color)),
|
textures: &[(&self.texture_program.texture, &texture)],
|
||||||
(&self.texture_program.texture_size_uniform,
|
images: &[],
|
||||||
UniformData::Vec2(device.texture_size(&texture).0.to_f32x2()))
|
storage_buffers: &[],
|
||||||
],
|
uniforms: &[
|
||||||
viewport: RectI::new(Vector2I::default(), self.framebuffer_size),
|
(&self.texture_program.framebuffer_size_uniform,
|
||||||
options: RenderOptions {
|
UniformData::Vec2(self.framebuffer_size.0.to_f32x2())),
|
||||||
blend: Some(alpha_blend_state()),
|
(&self.texture_program.color_uniform, get_color_uniform(color)),
|
||||||
..RenderOptions::default()
|
(&self.texture_program.texture_size_uniform,
|
||||||
},
|
UniformData::Vec2(device.texture_size(&texture).0.to_f32x2()))
|
||||||
});
|
],
|
||||||
|
viewport: RectI::new(Vector2I::default(), self.framebuffer_size),
|
||||||
|
options: RenderOptions {
|
||||||
|
blend: Some(alpha_blend_state()),
|
||||||
|
..RenderOptions::default()
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
allocator.free_buffer(index_buffer_id);
|
||||||
|
allocator.free_buffer(vertex_buffer_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_button(&mut self, device: &D, origin: Vector2I, texture: &D::Texture) -> bool {
|
pub fn draw_button(&mut self,
|
||||||
|
device: &D,
|
||||||
|
allocator: &mut GPUMemoryAllocator<D>,
|
||||||
|
origin: Vector2I,
|
||||||
|
texture: &D::Texture) -> bool {
|
||||||
let button_rect = RectI::new(origin, vec2i(BUTTON_WIDTH, BUTTON_HEIGHT));
|
let button_rect = RectI::new(origin, vec2i(BUTTON_WIDTH, BUTTON_HEIGHT));
|
||||||
self.draw_solid_rounded_rect(device, button_rect, WINDOW_COLOR);
|
self.draw_solid_rounded_rect(device, allocator, button_rect, WINDOW_COLOR);
|
||||||
self.draw_rounded_rect_outline(device, button_rect, OUTLINE_COLOR);
|
self.draw_rounded_rect_outline(device, allocator, button_rect, OUTLINE_COLOR);
|
||||||
self.draw_texture(device,
|
self.draw_texture(device,
|
||||||
|
allocator,
|
||||||
origin + vec2i(PADDING, PADDING),
|
origin + vec2i(PADDING, PADDING),
|
||||||
texture,
|
texture,
|
||||||
BUTTON_ICON_COLOR);
|
BUTTON_ICON_COLOR);
|
||||||
|
@ -442,11 +528,13 @@ impl<D> UIPresenter<D> where D: Device {
|
||||||
|
|
||||||
pub fn draw_text_switch(&mut self,
|
pub fn draw_text_switch(&mut self,
|
||||||
device: &D,
|
device: &D,
|
||||||
|
allocator: &mut GPUMemoryAllocator<D>,
|
||||||
mut origin: Vector2I,
|
mut origin: Vector2I,
|
||||||
segment_labels: &[&str],
|
segment_labels: &[&str],
|
||||||
mut value: u8)
|
mut value: u8)
|
||||||
-> u8 {
|
-> u8 {
|
||||||
if let Some(new_value) = self.draw_segmented_control(device,
|
if let Some(new_value) = self.draw_segmented_control(device,
|
||||||
|
allocator,
|
||||||
origin,
|
origin,
|
||||||
Some(value),
|
Some(value),
|
||||||
segment_labels.len() as u8) {
|
segment_labels.len() as u8) {
|
||||||
|
@ -458,6 +546,7 @@ impl<D> UIPresenter<D> where D: Device {
|
||||||
let label_width = self.measure_text(segment_label);
|
let label_width = self.measure_text(segment_label);
|
||||||
let offset = SEGMENT_SIZE / 2 - label_width / 2;
|
let offset = SEGMENT_SIZE / 2 - label_width / 2;
|
||||||
self.draw_text(device,
|
self.draw_text(device,
|
||||||
|
allocator,
|
||||||
segment_label,
|
segment_label,
|
||||||
origin + vec2i(offset, 0),
|
origin + vec2i(offset, 0),
|
||||||
segment_index as u8 == value);
|
segment_index as u8 == value);
|
||||||
|
@ -469,12 +558,14 @@ impl<D> UIPresenter<D> where D: Device {
|
||||||
|
|
||||||
pub fn draw_image_segmented_control(&mut self,
|
pub fn draw_image_segmented_control(&mut self,
|
||||||
device: &D,
|
device: &D,
|
||||||
|
allocator: &mut GPUMemoryAllocator<D>,
|
||||||
mut origin: Vector2I,
|
mut origin: Vector2I,
|
||||||
segment_textures: &[&D::Texture],
|
segment_textures: &[&D::Texture],
|
||||||
mut value: Option<u8>)
|
mut value: Option<u8>)
|
||||||
-> Option<u8> {
|
-> Option<u8> {
|
||||||
let mut clicked_segment = None;
|
let mut clicked_segment = None;
|
||||||
if let Some(segment_index) = self.draw_segmented_control(device,
|
if let Some(segment_index) = self.draw_segmented_control(device,
|
||||||
|
allocator,
|
||||||
origin,
|
origin,
|
||||||
value,
|
value,
|
||||||
segment_textures.len() as u8) {
|
segment_textures.len() as u8) {
|
||||||
|
@ -493,7 +584,7 @@ impl<D> UIPresenter<D> where D: Device {
|
||||||
TEXT_COLOR
|
TEXT_COLOR
|
||||||
};
|
};
|
||||||
|
|
||||||
self.draw_texture(device, origin + offset, segment_texture, color);
|
self.draw_texture(device, allocator, origin + offset, segment_texture, color);
|
||||||
origin += vec2i(SEGMENT_SIZE + 1, 0);
|
origin += vec2i(SEGMENT_SIZE + 1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -502,6 +593,7 @@ impl<D> UIPresenter<D> where D: Device {
|
||||||
|
|
||||||
fn draw_segmented_control(&mut self,
|
fn draw_segmented_control(&mut self,
|
||||||
device: &D,
|
device: &D,
|
||||||
|
allocator: &mut GPUMemoryAllocator<D>,
|
||||||
origin: Vector2I,
|
origin: Vector2I,
|
||||||
mut value: Option<u8>,
|
mut value: Option<u8>,
|
||||||
segment_count: u8)
|
segment_count: u8)
|
||||||
|
@ -518,13 +610,14 @@ impl<D> UIPresenter<D> where D: Device {
|
||||||
clicked_segment = Some(segment);
|
clicked_segment = Some(segment);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.draw_solid_rounded_rect(device, widget_rect, WINDOW_COLOR);
|
self.draw_solid_rounded_rect(device, allocator, widget_rect, WINDOW_COLOR);
|
||||||
self.draw_rounded_rect_outline(device, widget_rect, OUTLINE_COLOR);
|
self.draw_rounded_rect_outline(device, allocator, widget_rect, OUTLINE_COLOR);
|
||||||
|
|
||||||
if let Some(value) = value {
|
if let Some(value) = value {
|
||||||
let highlight_size = vec2i(SEGMENT_SIZE, BUTTON_HEIGHT);
|
let highlight_size = vec2i(SEGMENT_SIZE, BUTTON_HEIGHT);
|
||||||
let x_offset = value as i32 * SEGMENT_SIZE + (value as i32 - 1);
|
let x_offset = value as i32 * SEGMENT_SIZE + (value as i32 - 1);
|
||||||
self.draw_solid_rounded_rect(device,
|
self.draw_solid_rounded_rect(device,
|
||||||
|
allocator,
|
||||||
RectI::new(origin + vec2i(x_offset, 0), highlight_size),
|
RectI::new(origin + vec2i(x_offset, 0), highlight_size),
|
||||||
TEXT_COLOR);
|
TEXT_COLOR);
|
||||||
}
|
}
|
||||||
|
@ -536,6 +629,7 @@ impl<D> UIPresenter<D> where D: Device {
|
||||||
Some(value) if value == prev_segment_index || value == next_segment_index => {}
|
Some(value) if value == prev_segment_index || value == next_segment_index => {}
|
||||||
_ => {
|
_ => {
|
||||||
self.draw_line(device,
|
self.draw_line(device,
|
||||||
|
allocator,
|
||||||
segment_origin,
|
segment_origin,
|
||||||
segment_origin + vec2i(0, BUTTON_HEIGHT),
|
segment_origin + vec2i(0, BUTTON_HEIGHT),
|
||||||
TEXT_COLOR);
|
TEXT_COLOR);
|
||||||
|
@ -547,7 +641,11 @@ impl<D> UIPresenter<D> where D: Device {
|
||||||
clicked_segment
|
clicked_segment
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_tooltip(&self, device: &D, string: &str, rect: RectI) {
|
pub fn draw_tooltip(&self,
|
||||||
|
device: &D,
|
||||||
|
allocator: &mut GPUMemoryAllocator<D>,
|
||||||
|
string: &str,
|
||||||
|
rect: RectI) {
|
||||||
if !rect.to_f32().contains_point(self.mouse_position) {
|
if !rect.to_f32().contains_point(self.mouse_position) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -556,8 +654,15 @@ impl<D> UIPresenter<D> where D: Device {
|
||||||
let window_size = vec2i(text_size + PADDING * 2, TOOLTIP_HEIGHT);
|
let window_size = vec2i(text_size + PADDING * 2, TOOLTIP_HEIGHT);
|
||||||
let origin = rect.origin() - vec2i(0, window_size.y() + PADDING);
|
let origin = rect.origin() - vec2i(0, window_size.y() + PADDING);
|
||||||
|
|
||||||
self.draw_solid_rounded_rect(device, RectI::new(origin, window_size), WINDOW_COLOR);
|
self.draw_solid_rounded_rect(device,
|
||||||
self.draw_text(device, string, origin + vec2i(PADDING, PADDING + FONT_ASCENT), false);
|
allocator,
|
||||||
|
RectI::new(origin, window_size),
|
||||||
|
WINDOW_COLOR);
|
||||||
|
self.draw_text(device,
|
||||||
|
allocator,
|
||||||
|
string,
|
||||||
|
origin + vec2i(PADDING, PADDING + FONT_ASCENT),
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -571,7 +676,7 @@ struct DebugTextureProgram<D> where D: Device {
|
||||||
|
|
||||||
impl<D> DebugTextureProgram<D> where D: Device {
|
impl<D> DebugTextureProgram<D> where D: Device {
|
||||||
fn new(device: &D, resources: &dyn ResourceLoader) -> DebugTextureProgram<D> {
|
fn new(device: &D, resources: &dyn ResourceLoader) -> DebugTextureProgram<D> {
|
||||||
let program = device.create_raster_program(resources, "debug_texture");
|
let program = device.create_raster_program(resources, "debug/texture");
|
||||||
let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize");
|
let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize");
|
||||||
let texture_size_uniform = device.get_uniform(&program, "TextureSize");
|
let texture_size_uniform = device.get_uniform(&program, "TextureSize");
|
||||||
let color_uniform = device.get_uniform(&program, "Color");
|
let color_uniform = device.get_uniform(&program, "Color");
|
||||||
|
@ -588,15 +693,14 @@ impl<D> DebugTextureProgram<D> where D: Device {
|
||||||
|
|
||||||
struct DebugTextureVertexArray<D> where D: Device {
|
struct DebugTextureVertexArray<D> where D: Device {
|
||||||
vertex_array: D::VertexArray,
|
vertex_array: D::VertexArray,
|
||||||
vertex_buffer: D::Buffer,
|
|
||||||
index_buffer: D::Buffer,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D> DebugTextureVertexArray<D> where D: Device {
|
impl<D> DebugTextureVertexArray<D> where D: Device {
|
||||||
fn new(device: &D, debug_texture_program: &DebugTextureProgram<D>)
|
fn new(device: &D,
|
||||||
|
debug_texture_program: &DebugTextureProgram<D>,
|
||||||
|
vertex_buffer: &D::Buffer,
|
||||||
|
index_buffer: &D::Buffer)
|
||||||
-> DebugTextureVertexArray<D> {
|
-> DebugTextureVertexArray<D> {
|
||||||
let vertex_buffer = device.create_buffer(BufferUploadMode::Dynamic);
|
|
||||||
let index_buffer = device.create_buffer(BufferUploadMode::Dynamic);
|
|
||||||
let vertex_array = device.create_vertex_array();
|
let vertex_array = device.create_vertex_array();
|
||||||
|
|
||||||
let position_attr = device.get_vertex_attr(&debug_texture_program.program, "Position")
|
let position_attr = device.get_vertex_attr(&debug_texture_program.program, "Position")
|
||||||
|
@ -604,8 +708,8 @@ impl<D> DebugTextureVertexArray<D> where D: Device {
|
||||||
let tex_coord_attr = device.get_vertex_attr(&debug_texture_program.program, "TexCoord")
|
let tex_coord_attr = device.get_vertex_attr(&debug_texture_program.program, "TexCoord")
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
device.bind_buffer(&vertex_array, &vertex_buffer, BufferTarget::Vertex);
|
device.bind_buffer(&vertex_array, vertex_buffer, BufferTarget::Vertex);
|
||||||
device.bind_buffer(&vertex_array, &index_buffer, BufferTarget::Index);
|
device.bind_buffer(&vertex_array, index_buffer, BufferTarget::Index);
|
||||||
device.configure_vertex_attr(&vertex_array, &position_attr, &VertexAttrDescriptor {
|
device.configure_vertex_attr(&vertex_array, &position_attr, &VertexAttrDescriptor {
|
||||||
size: 2,
|
size: 2,
|
||||||
class: VertexAttrClass::Int,
|
class: VertexAttrClass::Int,
|
||||||
|
@ -625,20 +729,20 @@ impl<D> DebugTextureVertexArray<D> where D: Device {
|
||||||
buffer_index: 0,
|
buffer_index: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
DebugTextureVertexArray { vertex_array, vertex_buffer, index_buffer }
|
DebugTextureVertexArray { vertex_array }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct DebugSolidVertexArray<D> where D: Device {
|
struct DebugSolidVertexArray<D> where D: Device {
|
||||||
vertex_array: D::VertexArray,
|
vertex_array: D::VertexArray,
|
||||||
vertex_buffer: D::Buffer,
|
|
||||||
index_buffer: D::Buffer,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D> DebugSolidVertexArray<D> where D: Device {
|
impl<D> DebugSolidVertexArray<D> where D: Device {
|
||||||
fn new(device: &D, debug_solid_program: &DebugSolidProgram<D>) -> DebugSolidVertexArray<D> {
|
fn new(device: &D,
|
||||||
let vertex_buffer = device.create_buffer(BufferUploadMode::Dynamic);
|
debug_solid_program: &DebugSolidProgram<D>,
|
||||||
let index_buffer = device.create_buffer(BufferUploadMode::Dynamic);
|
vertex_buffer: &D::Buffer,
|
||||||
|
index_buffer: &D::Buffer)
|
||||||
|
-> DebugSolidVertexArray<D> {
|
||||||
let vertex_array = device.create_vertex_array();
|
let vertex_array = device.create_vertex_array();
|
||||||
|
|
||||||
let position_attr =
|
let position_attr =
|
||||||
|
@ -655,7 +759,7 @@ impl<D> DebugSolidVertexArray<D> where D: Device {
|
||||||
buffer_index: 0,
|
buffer_index: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
DebugSolidVertexArray { vertex_array, vertex_buffer, index_buffer }
|
DebugSolidVertexArray { vertex_array }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -667,7 +771,7 @@ struct DebugSolidProgram<D> where D: Device {
|
||||||
|
|
||||||
impl<D> DebugSolidProgram<D> where D: Device {
|
impl<D> DebugSolidProgram<D> where D: Device {
|
||||||
fn new(device: &D, resources: &dyn ResourceLoader) -> DebugSolidProgram<D> {
|
fn new(device: &D, resources: &dyn ResourceLoader) -> DebugSolidProgram<D> {
|
||||||
let program = device.create_raster_program(resources, "debug_solid");
|
let program = device.create_raster_program(resources, "debug/solid");
|
||||||
let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize");
|
let framebuffer_size_uniform = device.get_uniform(&program, "FramebufferSize");
|
||||||
let color_uniform = device.get_uniform(&program, "Color");
|
let color_uniform = device.get_uniform(&program, "Color");
|
||||||
DebugSolidProgram { program, framebuffer_size_uniform, color_uniform }
|
DebugSolidProgram { program, framebuffer_size_uniform, color_uniform }
|
||||||
|
|
Loading…
Reference in New Issue