Merge pull request #775 from rtfeldman/editor_color_fix

refactoring, fixed color shader bug
This commit is contained in:
Richard Feldman 2020-12-05 16:49:23 -05:00 committed by GitHub
commit 1b6d03d0ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 316 additions and 250 deletions

View File

@ -78,6 +78,71 @@ impl QuadBufferBuilder {
}
}
pub struct RectBuffers {
pub vertex_buffer: wgpu::Buffer,
pub index_buffer: wgpu::Buffer,
pub num_rects: u32,
}
pub fn create_rect_buffers(
gpu_device: &wgpu::Device,
encoder: &mut wgpu::CommandEncoder,
) -> RectBuffers {
// Test Rectangles
let test_rect_1 = Rect {
top_left_coords: (-0.2, 0.6).into(),
width: 0.1,
height: 0.5,
color: [0.0, 0.0, 1.0],
};
let test_rect_2 = Rect {
top_left_coords: (-0.5, 0.0).into(),
width: 0.5,
height: 0.5,
color: [0.0, 1.0, 0.0],
};
let test_rect_3 = Rect {
top_left_coords: (0.3, 0.3).into(),
width: 0.6,
height: 0.1,
color: [1.0, 0.0, 0.0],
};
let vertex_buffer = gpu_device.create_buffer(&wgpu::BufferDescriptor {
label: None,
size: Vertex::SIZE * 4 * 3,
usage: wgpu::BufferUsage::VERTEX | wgpu::BufferUsage::COPY_DST,
mapped_at_creation: false,
});
let u32_size = std::mem::size_of::<u32>() as wgpu::BufferAddress;
let index_buffer = gpu_device.create_buffer(&wgpu::BufferDescriptor {
label: None,
size: u32_size * 6 * 3,
usage: wgpu::BufferUsage::INDEX | wgpu::BufferUsage::COPY_DST,
mapped_at_creation: false,
});
let num_rects = {
let (stg_vertex, stg_index, num_indices) = QuadBufferBuilder::new()
.push_rect(&test_rect_1)
.push_rect(&test_rect_2)
.push_rect(&test_rect_3)
.build(&gpu_device);
stg_vertex.copy_to_buffer(encoder, &vertex_buffer);
stg_index.copy_to_buffer(encoder, &index_buffer);
num_indices
};
RectBuffers {
vertex_buffer,
index_buffer,
num_rects,
}
}
pub struct StagingBuffer {
buffer: wgpu::Buffer,
size: wgpu::BufferAddress,

View File

@ -0,0 +1,153 @@
use winit::event::{ElementState, ModifiersState, VirtualKeyCode};
pub fn handle_keydown(
elem_state: ElementState,
virtual_keycode: VirtualKeyCode,
_modifiers: ModifiersState,
) {
use winit::event::VirtualKeyCode::*;
if let ElementState::Released = elem_state {
return;
}
match virtual_keycode {
Copy => {
todo!("copy");
}
Paste => {
todo!("paste");
}
Cut => {
todo!("cut");
}
_ => {}
}
}
// pub fn handle_text_input(
// text_state: &mut String,
// elem_state: ElementState,
// virtual_keycode: VirtualKeyCode,
// _modifiers: ModifiersState,
// ) {
// use winit::event::VirtualKeyCode::*;
// if let ElementState::Released = elem_state {
// return;
// }
// match virtual_keycode {
// Key1 | Numpad1 => text_state.push('1'),
// Key2 | Numpad2 => text_state.push('2'),
// Key3 | Numpad3 => text_state.push('3'),
// Key4 | Numpad4 => text_state.push('4'),
// Key5 | Numpad5 => text_state.push('5'),
// Key6 | Numpad6 => text_state.push('6'),
// Key7 | Numpad7 => text_state.push('7'),
// Key8 | Numpad8 => text_state.push('8'),
// Key9 | Numpad9 => text_state.push('9'),
// Key0 | Numpad0 => text_state.push('0'),
// A => text_state.push('a'),
// B => text_state.push('b'),
// C => text_state.push('c'),
// D => text_state.push('d'),
// E => text_state.push('e'),
// F => text_state.push('f'),
// G => text_state.push('g'),
// H => text_state.push('h'),
// I => text_state.push('i'),
// J => text_state.push('j'),
// K => text_state.push('k'),
// L => text_state.push('l'),
// M => text_state.push('m'),
// N => text_state.push('n'),
// O => text_state.push('o'),
// P => text_state.push('p'),
// Q => text_state.push('q'),
// R => text_state.push('r'),
// S => text_state.push('s'),
// T => text_state.push('t'),
// U => text_state.push('u'),
// V => text_state.push('v'),
// W => text_state.push('w'),
// X => text_state.push('x'),
// Y => text_state.push('y'),
// Z => text_state.push('z'),
// Escape | F1 | F2 | F3 | F4 | F5 | F6 | F7 | F8 | F9 | F10 | F11 | F12 | F13 | F14 | F15
// | F16 | F17 | F18 | F19 | F20 | F21 | F22 | F23 | F24 | Snapshot | Scroll | Pause
// | Insert | Home | Delete | End | PageDown | PageUp | Left | Up | Right | Down | Compose
// | Caret | Numlock | AbntC1 | AbntC2 | Ax | Calculator | Capital | Convert | Kana
// | Kanji | LAlt | LBracket | LControl | LShift | LWin | Mail | MediaSelect | PlayPause
// | Power | PrevTrack | MediaStop | Mute | MyComputer | NavigateForward
// | NavigateBackward | NextTrack | NoConvert | OEM102 | RAlt | Sysrq | RBracket
// | RControl | RShift | RWin | Sleep | Stop | Unlabeled | VolumeDown | VolumeUp | Wake
// | WebBack | WebFavorites | WebForward | WebHome | WebRefresh | WebSearch | Apps | Tab
// | WebStop => {
// // TODO handle
// }
// Back => {
// text_state.pop();
// }
// Return | NumpadEnter => {
// text_state.push('\n');
// }
// Space => {
// text_state.push(' ');
// }
// Comma | NumpadComma => {
// text_state.push(',');
// }
// Add => {
// text_state.push('+');
// }
// Apostrophe => {
// text_state.push('\'');
// }
// At => {
// text_state.push('@');
// }
// Backslash => {
// text_state.push('\\');
// }
// Colon => {
// text_state.push(':');
// }
// Period | Decimal => {
// text_state.push('.');
// }
// Equals | NumpadEquals => {
// text_state.push('=');
// }
// Grave => {
// text_state.push('`');
// }
// Minus | Subtract => {
// text_state.push('-');
// }
// Multiply => {
// text_state.push('*');
// }
// Semicolon => {
// text_state.push(';');
// }
// Slash | Divide => {
// text_state.push('/');
// }
// Underline => {
// text_state.push('_');
// }
// Yen => {
// text_state.push('¥');
// }
// Copy => {
// todo!("copy");
// }
// Paste => {
// todo!("paste");
// }
// Cut => {
// todo!("cut");
// }
// }
// }

View File

@ -16,22 +16,22 @@
// See this link to learn wgpu: https://sotrh.github.io/learn-wgpu/
use crate::buffer::QuadBufferBuilder;
use crate::rect::Rect;
use crate::buffer::create_rect_buffers;
use crate::text::{build_glyph_brush, Text};
use crate::vertex::Vertex;
use std::error::Error;
use std::io;
use std::path::Path;
use wgpu_glyph::{ab_glyph, GlyphBrushBuilder, Section, Text};
use winit::event;
use winit::event::{ElementState, Event, ModifiersState, VirtualKeyCode};
use winit::event::{Event, ModifiersState};
use winit::event_loop::ControlFlow;
pub mod ast;
mod buffer;
pub mod file;
mod keyboard_input;
mod rect;
pub mod text_state;
pub mod text;
mod util;
mod vertex;
@ -104,12 +104,7 @@ fn run_event_loop() -> Result<(), Box<dyn Error>> {
let rect_pipeline = make_rect_pipeline(&gpu_device, &swap_chain_descr);
// Prepare glyph_brush
let inconsolata =
ab_glyph::FontArc::try_from_slice(include_bytes!("../Inconsolata-Regular.ttf"))?;
let mut glyph_brush =
GlyphBrushBuilder::using_font(inconsolata).build(&gpu_device, render_format);
let mut glyph_brush = build_glyph_brush(&gpu_device, render_format)?;
let is_animating = true;
let mut text_state = String::new();
@ -161,7 +156,11 @@ fn run_event_loop() -> Result<(), Box<dyn Error>> {
..
} => {
if let Some(virtual_keycode) = input.virtual_keycode {
handle_keydown(input.state, virtual_keycode, keyboard_modifiers);
keyboard_input::handle_keydown(
input.state,
virtual_keycode,
keyboard_modifiers,
);
}
}
Event::WindowEvent {
@ -203,7 +202,7 @@ fn run_event_loop() -> Result<(), Box<dyn Error>> {
drop(render_pass);
draw_text(
draw_all_text(
&gpu_device,
&mut staging_belt,
&mut encoder,
@ -294,72 +293,7 @@ fn create_render_pipeline(
})
}
struct RectBuffers {
vertex_buffer: wgpu::Buffer,
index_buffer: wgpu::Buffer,
num_rects: u32,
}
fn create_rect_buffers(
gpu_device: &wgpu::Device,
encoder: &mut wgpu::CommandEncoder,
) -> RectBuffers {
// Test Rectangles
let test_rect_1 = Rect {
top_left_coords: (-0.2, 0.6).into(),
width: 0.1,
height: 0.5,
color: [0.0, 0.0, 1.0],
};
let test_rect_2 = Rect {
top_left_coords: (-0.5, 0.0).into(),
width: 0.5,
height: 0.5,
color: [0.0, 1.0, 0.0],
};
let test_rect_3 = Rect {
top_left_coords: (0.3, 0.3).into(),
width: 0.6,
height: 0.1,
color: [0.0, 0.0, 1.0],
};
let vertex_buffer = gpu_device.create_buffer(&wgpu::BufferDescriptor {
label: None,
size: Vertex::SIZE * 4 * 3,
usage: wgpu::BufferUsage::VERTEX | wgpu::BufferUsage::COPY_DST,
mapped_at_creation: false,
});
let u32_size = std::mem::size_of::<u32>() as wgpu::BufferAddress;
let index_buffer = gpu_device.create_buffer(&wgpu::BufferDescriptor {
label: None,
size: u32_size * 6 * 3,
usage: wgpu::BufferUsage::INDEX | wgpu::BufferUsage::COPY_DST,
mapped_at_creation: false,
});
let num_rects = {
let (stg_vertex, stg_index, num_indices) = QuadBufferBuilder::new()
.push_rect(&test_rect_1)
.push_rect(&test_rect_2)
.push_rect(&test_rect_3)
.build(&gpu_device);
stg_vertex.copy_to_buffer(encoder, &vertex_buffer);
stg_index.copy_to_buffer(encoder, &index_buffer);
num_indices
};
RectBuffers {
vertex_buffer,
index_buffer,
num_rects,
}
}
fn draw_text(
fn draw_all_text(
gpu_device: &wgpu::Device,
staging_belt: &mut wgpu::util::StagingBelt,
encoder: &mut wgpu::CommandEncoder,
@ -368,25 +302,30 @@ fn draw_text(
text_state: &str,
glyph_brush: &mut wgpu_glyph::GlyphBrush<()>,
) {
glyph_brush.queue(Section {
screen_position: (30.0, 30.0),
bounds: (size.width as f32, size.height as f32),
text: vec![Text::new("Enter some text:")
.with_color([0.4666, 0.2, 1.0, 1.0])
.with_scale(40.0)],
..Section::default()
});
let bounds = (size.width as f32, size.height as f32).into();
glyph_brush.queue(Section {
screen_position: (30.0, 90.0),
bounds: (size.width as f32, size.height as f32),
text: vec![Text::new(format!("{}|", text_state).as_str())
.with_color([1.0, 1.0, 1.0, 1.0])
.with_scale(40.0)],
..Section::default()
});
let main_label = Text {
position: (30.0, 30.0).into(),
bounds,
color: (0.4666, 0.2, 1.0, 1.0).into(),
text: String::from("Enter some text:"),
size: 40.0,
..Default::default()
};
let code_text = Text {
position: (30.0, 90.0).into(),
bounds,
color: (1.0, 1.0, 1.0, 1.0).into(),
text: String::from(format!("{}|", text_state).as_str()),
size: 40.0,
..Default::default()
};
text::queue_text_draw(&main_label, glyph_brush);
text::queue_text_draw(&code_text, glyph_brush);
// Draw the text!
glyph_brush
.draw_queued(
gpu_device,
@ -415,28 +354,3 @@ fn update_text_state(text_state: &mut String, received_char: &char) {
}
}
}
fn handle_keydown(
elem_state: ElementState,
virtual_keycode: VirtualKeyCode,
_modifiers: ModifiersState,
) {
use winit::event::VirtualKeyCode::*;
if let ElementState::Released = elem_state {
return;
}
match virtual_keycode {
Copy => {
todo!("copy");
}
Paste => {
todo!("paste");
}
Cut => {
todo!("cut");
}
_ => {}
}
}

62
editor/src/text.rs Normal file
View File

@ -0,0 +1,62 @@
// Adapted from https://github.com/sotrh/learn-wgpu
// by Benjamin Hansen, licensed under the MIT license
use ab_glyph::{FontArc, InvalidFont};
use cgmath::{Vector2, Vector4};
use wgpu_glyph::{ab_glyph, GlyphBrush, GlyphBrushBuilder, Section};
#[derive(Debug)]
pub struct Text {
pub position: Vector2<f32>,
pub bounds: Vector2<f32>,
pub color: Vector4<f32>,
pub text: String,
pub size: f32,
pub visible: bool,
pub centered: bool,
}
impl Default for Text {
fn default() -> Self {
Self {
position: (0.0, 0.0).into(),
bounds: (std::f32::INFINITY, std::f32::INFINITY).into(),
color: (1.0, 1.0, 1.0, 1.0).into(),
text: String::new(),
size: 16.0,
visible: true,
centered: false,
}
}
}
pub fn queue_text_draw(text: &Text, glyph_brush: &mut GlyphBrush<()>) {
let layout = wgpu_glyph::Layout::default().h_align(if text.centered {
wgpu_glyph::HorizontalAlign::Center
} else {
wgpu_glyph::HorizontalAlign::Left
});
let section = Section {
screen_position: text.position.into(),
bounds: text.bounds.into(),
layout,
..Section::default()
}
.add_text(
wgpu_glyph::Text::new(&text.text)
.with_color(text.color)
.with_scale(text.size),
);
glyph_brush.queue(section);
}
pub fn build_glyph_brush(
gpu_device: &wgpu::Device,
render_format: wgpu::TextureFormat,
) -> Result<GlyphBrush<()>, InvalidFont> {
let inconsolata = FontArc::try_from_slice(include_bytes!("../Inconsolata-Regular.ttf"))?;
Ok(GlyphBrushBuilder::using_font(inconsolata).build(&gpu_device, render_format))
}

View File

@ -1,128 +0,0 @@
use winit::event::{ElementState, ModifiersState, VirtualKeyCode};
pub fn handle_text_input(
text_state: &mut String,
elem_state: ElementState,
virtual_keycode: VirtualKeyCode,
_modifiers: ModifiersState,
) {
use winit::event::VirtualKeyCode::*;
if let ElementState::Released = elem_state {
return;
}
match virtual_keycode {
Key1 | Numpad1 => text_state.push('1'),
Key2 | Numpad2 => text_state.push('2'),
Key3 | Numpad3 => text_state.push('3'),
Key4 | Numpad4 => text_state.push('4'),
Key5 | Numpad5 => text_state.push('5'),
Key6 | Numpad6 => text_state.push('6'),
Key7 | Numpad7 => text_state.push('7'),
Key8 | Numpad8 => text_state.push('8'),
Key9 | Numpad9 => text_state.push('9'),
Key0 | Numpad0 => text_state.push('0'),
A => text_state.push('a'),
B => text_state.push('b'),
C => text_state.push('c'),
D => text_state.push('d'),
E => text_state.push('e'),
F => text_state.push('f'),
G => text_state.push('g'),
H => text_state.push('h'),
I => text_state.push('i'),
J => text_state.push('j'),
K => text_state.push('k'),
L => text_state.push('l'),
M => text_state.push('m'),
N => text_state.push('n'),
O => text_state.push('o'),
P => text_state.push('p'),
Q => text_state.push('q'),
R => text_state.push('r'),
S => text_state.push('s'),
T => text_state.push('t'),
U => text_state.push('u'),
V => text_state.push('v'),
W => text_state.push('w'),
X => text_state.push('x'),
Y => text_state.push('y'),
Z => text_state.push('z'),
Escape | F1 | F2 | F3 | F4 | F5 | F6 | F7 | F8 | F9 | F10 | F11 | F12 | F13 | F14 | F15
| F16 | F17 | F18 | F19 | F20 | F21 | F22 | F23 | F24 | Snapshot | Scroll | Pause
| Insert | Home | Delete | End | PageDown | PageUp | Left | Up | Right | Down | Compose
| Caret | Numlock | AbntC1 | AbntC2 | Ax | Calculator | Capital | Convert | Kana
| Kanji | LAlt | LBracket | LControl | LShift | LWin | Mail | MediaSelect | PlayPause
| Power | PrevTrack | MediaStop | Mute | MyComputer | NavigateForward
| NavigateBackward | NextTrack | NoConvert | OEM102 | RAlt | Sysrq | RBracket
| RControl | RShift | RWin | Sleep | Stop | Unlabeled | VolumeDown | VolumeUp | Wake
| WebBack | WebFavorites | WebForward | WebHome | WebRefresh | WebSearch | Apps | Tab
| WebStop => {
// TODO handle
}
Back => {
text_state.pop();
}
Return | NumpadEnter => {
text_state.push('\n');
}
Space => {
text_state.push(' ');
}
Comma | NumpadComma => {
text_state.push(',');
}
Add => {
text_state.push('+');
}
Apostrophe => {
text_state.push('\'');
}
At => {
text_state.push('@');
}
Backslash => {
text_state.push('\\');
}
Colon => {
text_state.push(':');
}
Period | Decimal => {
text_state.push('.');
}
Equals | NumpadEquals => {
text_state.push('=');
}
Grave => {
text_state.push('`');
}
Minus | Subtract => {
text_state.push('-');
}
Multiply => {
text_state.push('*');
}
Semicolon => {
text_state.push(';');
}
Slash | Divide => {
text_state.push('/');
}
Underline => {
text_state.push('_');
}
Yen => {
text_state.push('¥');
}
Copy => {
todo!("copy");
}
Paste => {
todo!("paste");
}
Cut => {
todo!("cut");
}
}
}

View File

@ -26,7 +26,7 @@ impl Vertex {
},
// color
wgpu::VertexAttributeDescriptor {
offset: std::mem::size_of::<[f32; 3]>() as wgpu::BufferAddress,
offset: std::mem::size_of::<[f32; 2]>() as wgpu::BufferAddress,
shader_location: 1,
format: wgpu::VertexFormat::Float3,
},