mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-01 07:41:12 +00:00
Merge pull request #801 from rtfeldman/editor_refactor
editor: refactoring orthographic projection
This commit is contained in:
commit
44e91bbfda
2 changed files with 130 additions and 91 deletions
|
@ -11,12 +11,10 @@
|
||||||
use crate::buffer::create_rect_buffers;
|
use crate::buffer::create_rect_buffers;
|
||||||
use crate::text::{build_glyph_brush, Text};
|
use crate::text::{build_glyph_brush, Text};
|
||||||
use crate::vertex::Vertex;
|
use crate::vertex::Vertex;
|
||||||
use cgmath::Ortho;
|
use ortho::{init_ortho, update_ortho_buffer, OrthoResources};
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use wgpu::util::DeviceExt;
|
|
||||||
use wgpu::{BindGroup, BindGroupLayoutDescriptor, BindGroupLayoutEntry, Buffer, ShaderStage};
|
|
||||||
use winit::event;
|
use winit::event;
|
||||||
use winit::event::{Event, ModifiersState};
|
use winit::event::{Event, ModifiersState};
|
||||||
use winit::event_loop::ControlFlow;
|
use winit::event_loop::ControlFlow;
|
||||||
|
@ -25,6 +23,7 @@ pub mod ast;
|
||||||
mod buffer;
|
mod buffer;
|
||||||
pub mod file;
|
pub mod file;
|
||||||
mod keyboard_input;
|
mod keyboard_input;
|
||||||
|
mod ortho;
|
||||||
pub mod pool;
|
pub mod pool;
|
||||||
mod rect;
|
mod rect;
|
||||||
pub mod text;
|
pub mod text;
|
||||||
|
@ -41,31 +40,6 @@ pub fn launch(_filepaths: &[&Path]) -> io::Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
#[derive(Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
|
|
||||||
struct Uniforms {
|
|
||||||
// We can't use cgmath with bytemuck directly so we'll have
|
|
||||||
// to convert the Matrix4 into a 4x4 f32 array
|
|
||||||
ortho: [[f32; 4]; 4],
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Uniforms {
|
|
||||||
fn new(w: u32, h: u32) -> Self {
|
|
||||||
let ortho: cgmath::Matrix4<f32> = Ortho::<f32> {
|
|
||||||
left: 0.0,
|
|
||||||
right: w as f32,
|
|
||||||
bottom: h as f32,
|
|
||||||
top: 0.0,
|
|
||||||
near: -1.0,
|
|
||||||
far: 1.0,
|
|
||||||
}
|
|
||||||
.into();
|
|
||||||
Self {
|
|
||||||
ortho: ortho.into(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn run_event_loop() -> Result<(), Box<dyn Error>> {
|
fn run_event_loop() -> Result<(), Box<dyn Error>> {
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
|
|
||||||
|
@ -123,8 +97,7 @@ fn run_event_loop() -> Result<(), Box<dyn Error>> {
|
||||||
|
|
||||||
let mut swap_chain = gpu_device.create_swap_chain(&surface, &swap_chain_descr);
|
let mut swap_chain = gpu_device.create_swap_chain(&surface, &swap_chain_descr);
|
||||||
|
|
||||||
let (rect_pipeline, ortho_bind_group, ortho_buffer) =
|
let (rect_pipeline, ortho) = make_rect_pipeline(&gpu_device, &swap_chain_descr);
|
||||||
make_rect_pipeline(&gpu_device, &swap_chain_descr);
|
|
||||||
|
|
||||||
let mut glyph_brush = build_glyph_brush(&gpu_device, render_format)?;
|
let mut glyph_brush = build_glyph_brush(&gpu_device, render_format)?;
|
||||||
|
|
||||||
|
@ -169,33 +142,13 @@ fn run_event_loop() -> Result<(), Box<dyn Error>> {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
// update orthographic buffer according to new window size
|
update_ortho_buffer(
|
||||||
let new_uniforms = Uniforms::new(size.width, size.height);
|
size.width,
|
||||||
|
size.height,
|
||||||
let new_ortho_buffer =
|
&gpu_device,
|
||||||
gpu_device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
&ortho.buffer,
|
||||||
label: Some("Ortho uniform buffer"),
|
&cmd_queue,
|
||||||
contents: bytemuck::cast_slice(&[new_uniforms]),
|
|
||||||
usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_SRC,
|
|
||||||
});
|
|
||||||
|
|
||||||
// get a command encoder for the current frame
|
|
||||||
let mut encoder =
|
|
||||||
gpu_device.create_command_encoder(&wgpu::CommandEncoderDescriptor {
|
|
||||||
label: Some("Resize"),
|
|
||||||
});
|
|
||||||
|
|
||||||
// overwrite the new buffer over the old one
|
|
||||||
encoder.copy_buffer_to_buffer(
|
|
||||||
&new_ortho_buffer,
|
|
||||||
0,
|
|
||||||
&ortho_buffer,
|
|
||||||
0,
|
|
||||||
(std::mem::size_of::<Uniforms>() * vec![new_uniforms].as_slice().len())
|
|
||||||
as wgpu::BufferAddress,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
cmd_queue.submit(Some(encoder.finish()));
|
|
||||||
}
|
}
|
||||||
//Received Character
|
//Received Character
|
||||||
Event::WindowEvent {
|
Event::WindowEvent {
|
||||||
|
@ -250,7 +203,7 @@ fn run_event_loop() -> Result<(), Box<dyn Error>> {
|
||||||
|
|
||||||
if rect_buffers.num_rects > 0 {
|
if rect_buffers.num_rects > 0 {
|
||||||
render_pass.set_pipeline(&rect_pipeline);
|
render_pass.set_pipeline(&rect_pipeline);
|
||||||
render_pass.set_bind_group(0, &ortho_bind_group, &[]);
|
render_pass.set_bind_group(0, &ortho.bind_group, &[]);
|
||||||
render_pass.set_vertex_buffer(0, rect_buffers.vertex_buffer.slice(..));
|
render_pass.set_vertex_buffer(0, rect_buffers.vertex_buffer.slice(..));
|
||||||
render_pass.set_index_buffer(rect_buffers.index_buffer.slice(..));
|
render_pass.set_index_buffer(rect_buffers.index_buffer.slice(..));
|
||||||
render_pass.draw_indexed(0..rect_buffers.num_rects, 0, 0..1);
|
render_pass.draw_indexed(0..rect_buffers.num_rects, 0, 0..1);
|
||||||
|
@ -290,41 +243,11 @@ fn run_event_loop() -> Result<(), Box<dyn Error>> {
|
||||||
fn make_rect_pipeline(
|
fn make_rect_pipeline(
|
||||||
gpu_device: &wgpu::Device,
|
gpu_device: &wgpu::Device,
|
||||||
swap_chain_descr: &wgpu::SwapChainDescriptor,
|
swap_chain_descr: &wgpu::SwapChainDescriptor,
|
||||||
) -> (wgpu::RenderPipeline, BindGroup, Buffer) {
|
) -> (wgpu::RenderPipeline, OrthoResources) {
|
||||||
let uniforms = Uniforms::new(swap_chain_descr.width, swap_chain_descr.height);
|
let ortho = init_ortho(swap_chain_descr.width, swap_chain_descr.height, gpu_device);
|
||||||
|
|
||||||
// orthographic projection is used to transfrom pixel coords to the coordinate system used by wgpu
|
|
||||||
let ortho_buffer = gpu_device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
|
||||||
label: Some("Ortho uniform buffer"),
|
|
||||||
contents: bytemuck::cast_slice(&[uniforms]),
|
|
||||||
usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST,
|
|
||||||
});
|
|
||||||
|
|
||||||
// bind groups consist of extra resources that are provided to the shaders
|
|
||||||
let ortho_bind_group_layout = gpu_device.create_bind_group_layout(&BindGroupLayoutDescriptor {
|
|
||||||
entries: &[BindGroupLayoutEntry {
|
|
||||||
binding: 0,
|
|
||||||
visibility: ShaderStage::VERTEX,
|
|
||||||
ty: wgpu::BindingType::UniformBuffer {
|
|
||||||
dynamic: false,
|
|
||||||
min_binding_size: None,
|
|
||||||
},
|
|
||||||
count: None,
|
|
||||||
}],
|
|
||||||
label: Some("Ortho bind group layout"),
|
|
||||||
});
|
|
||||||
|
|
||||||
let ortho_bind_group = gpu_device.create_bind_group(&wgpu::BindGroupDescriptor {
|
|
||||||
layout: &ortho_bind_group_layout,
|
|
||||||
entries: &[wgpu::BindGroupEntry {
|
|
||||||
binding: 0,
|
|
||||||
resource: wgpu::BindingResource::Buffer(ortho_buffer.slice(..)),
|
|
||||||
}],
|
|
||||||
label: Some("Ortho bind group"),
|
|
||||||
});
|
|
||||||
|
|
||||||
let pipeline_layout = gpu_device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
let pipeline_layout = gpu_device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||||
bind_group_layouts: &[&ortho_bind_group_layout],
|
bind_group_layouts: &[&ortho.bind_group_layout],
|
||||||
push_constant_ranges: &[],
|
push_constant_ranges: &[],
|
||||||
label: Some("Rectangle pipeline layout"),
|
label: Some("Rectangle pipeline layout"),
|
||||||
});
|
});
|
||||||
|
@ -337,7 +260,7 @@ fn make_rect_pipeline(
|
||||||
wgpu::include_spirv!("shaders/rect.frag.spv"),
|
wgpu::include_spirv!("shaders/rect.frag.spv"),
|
||||||
);
|
);
|
||||||
|
|
||||||
(pipeline, ortho_bind_group, ortho_buffer)
|
(pipeline, ortho)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_render_pipeline(
|
fn create_render_pipeline(
|
||||||
|
|
116
editor/src/ortho.rs
Normal file
116
editor/src/ortho.rs
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
use cgmath::{Matrix4, Ortho};
|
||||||
|
use wgpu::util::DeviceExt;
|
||||||
|
use wgpu::{
|
||||||
|
BindGroup, BindGroupLayout, BindGroupLayoutDescriptor, BindGroupLayoutEntry, Buffer,
|
||||||
|
ShaderStage,
|
||||||
|
};
|
||||||
|
|
||||||
|
// orthographic projection is used to transfrom pixel coords to the coordinate system used by wgpu
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
|
||||||
|
struct Uniforms {
|
||||||
|
// We can't use cgmath with bytemuck directly so we'll have
|
||||||
|
// to convert the Matrix4 into a 4x4 f32 array
|
||||||
|
ortho: [[f32; 4]; 4],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Uniforms {
|
||||||
|
fn new(w: u32, h: u32) -> Self {
|
||||||
|
let ortho: Matrix4<f32> = Ortho::<f32> {
|
||||||
|
left: 0.0,
|
||||||
|
right: w as f32,
|
||||||
|
bottom: h as f32,
|
||||||
|
top: 0.0,
|
||||||
|
near: -1.0,
|
||||||
|
far: 1.0,
|
||||||
|
}
|
||||||
|
.into();
|
||||||
|
Self {
|
||||||
|
ortho: ortho.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// update orthographic buffer according to new window size
|
||||||
|
pub fn update_ortho_buffer(
|
||||||
|
inner_width: u32,
|
||||||
|
inner_height: u32,
|
||||||
|
gpu_device: &wgpu::Device,
|
||||||
|
ortho_buffer: &Buffer,
|
||||||
|
cmd_queue: &wgpu::Queue,
|
||||||
|
) {
|
||||||
|
let new_uniforms = Uniforms::new(inner_width, inner_height);
|
||||||
|
|
||||||
|
let new_ortho_buffer = gpu_device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||||
|
label: Some("Ortho uniform buffer"),
|
||||||
|
contents: bytemuck::cast_slice(&[new_uniforms]),
|
||||||
|
usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_SRC,
|
||||||
|
});
|
||||||
|
|
||||||
|
// get a command encoder for the current frame
|
||||||
|
let mut encoder = gpu_device.create_command_encoder(&wgpu::CommandEncoderDescriptor {
|
||||||
|
label: Some("Resize"),
|
||||||
|
});
|
||||||
|
|
||||||
|
// overwrite the new buffer over the old one
|
||||||
|
encoder.copy_buffer_to_buffer(
|
||||||
|
&new_ortho_buffer,
|
||||||
|
0,
|
||||||
|
ortho_buffer,
|
||||||
|
0,
|
||||||
|
(std::mem::size_of::<Uniforms>() * vec![new_uniforms].as_slice().len())
|
||||||
|
as wgpu::BufferAddress,
|
||||||
|
);
|
||||||
|
|
||||||
|
cmd_queue.submit(Some(encoder.finish()));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct OrthoResources {
|
||||||
|
pub buffer: Buffer,
|
||||||
|
pub bind_group_layout: BindGroupLayout,
|
||||||
|
pub bind_group: BindGroup,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn init_ortho(
|
||||||
|
inner_width: u32,
|
||||||
|
inner_height: u32,
|
||||||
|
gpu_device: &wgpu::Device,
|
||||||
|
) -> OrthoResources {
|
||||||
|
let uniforms = Uniforms::new(inner_width, inner_height);
|
||||||
|
|
||||||
|
let ortho_buffer = gpu_device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||||
|
label: Some("Ortho uniform buffer"),
|
||||||
|
contents: bytemuck::cast_slice(&[uniforms]),
|
||||||
|
usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST,
|
||||||
|
});
|
||||||
|
|
||||||
|
// bind groups consist of extra resources that are provided to the shaders
|
||||||
|
let ortho_bind_group_layout = gpu_device.create_bind_group_layout(&BindGroupLayoutDescriptor {
|
||||||
|
entries: &[BindGroupLayoutEntry {
|
||||||
|
binding: 0,
|
||||||
|
visibility: ShaderStage::VERTEX,
|
||||||
|
ty: wgpu::BindingType::UniformBuffer {
|
||||||
|
dynamic: false,
|
||||||
|
min_binding_size: None,
|
||||||
|
},
|
||||||
|
count: None,
|
||||||
|
}],
|
||||||
|
label: Some("Ortho bind group layout"),
|
||||||
|
});
|
||||||
|
|
||||||
|
let ortho_bind_group = gpu_device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||||
|
layout: &ortho_bind_group_layout,
|
||||||
|
entries: &[wgpu::BindGroupEntry {
|
||||||
|
binding: 0,
|
||||||
|
resource: wgpu::BindingResource::Buffer(ortho_buffer.slice(..)),
|
||||||
|
}],
|
||||||
|
label: Some("Ortho bind group"),
|
||||||
|
});
|
||||||
|
|
||||||
|
OrthoResources {
|
||||||
|
buffer: ortho_buffer,
|
||||||
|
bind_group_layout: ortho_bind_group_layout,
|
||||||
|
bind_group: ortho_bind_group,
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue