diff --git a/Cargo.lock b/Cargo.lock index cf63a5aff5..3adb754c3b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -230,6 +230,12 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" +[[package]] +name = "bytemuck" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41aa2ec95ca3b5c54cf73c91acf06d24f4495d5f1b1c12506ae3483d646177ac" + [[package]] name = "byteorder" version = "1.3.4" @@ -2397,6 +2403,7 @@ version = "0.1.0" dependencies = [ "anyhow", "bumpalo", + "bytemuck", "env_logger 0.7.1", "fs_extra", "futures", diff --git a/editor/Cargo.toml b/editor/Cargo.toml index ffa38a2b2c..0aaac2bd91 100644 --- a/editor/Cargo.toml +++ b/editor/Cargo.toml @@ -56,6 +56,7 @@ zerocopy = "0.3" env_logger = "0.7" futures = "0.3" wgpu_glyph = "0.10" +bytemuck = "1.4" [dev-dependencies] pretty_assertions = "0.5.1" diff --git a/editor/src/lib.rs b/editor/src/lib.rs index 3fdf1fd3c8..efe491f200 100644 --- a/editor/src/lib.rs +++ b/editor/src/lib.rs @@ -11,15 +11,18 @@ // re-enable this when working on performance optimizations than have it block PRs. #![allow(clippy::large_enum_variant)] +use crate::vertex::Vertex; use std::error::Error; use std::io; use std::path::Path; +use wgpu::util::DeviceExt; use wgpu_glyph::{ab_glyph, GlyphBrushBuilder, Section, Text}; use winit::event::{ElementState, ModifiersState, VirtualKeyCode}; use winit::event_loop::ControlFlow; pub mod ast; pub mod text_state; +mod vertex; /// The editor is actually launched from the CLI if you pass it zero arguments, /// or if you provide it 1 or more files or directories to open on launch. @@ -117,7 +120,7 @@ fn run_event_loop() -> Result<(), Box> { depth_stencil_state: None, vertex_state: wgpu::VertexStateDescriptor { index_format: wgpu::IndexFormat::Uint16, - vertex_buffers: &[], + vertex_buffers: &[Vertex::buffer_descriptor()], }, sample_count: 1, sample_mask: !0, @@ -216,6 +219,13 @@ fn run_event_loop() -> Result<(), Box> { .expect("Failed to acquire next swap chain texture") .output; + // Vertex Buffer for drawing rectangles + let vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("Vertex Buffer"), + contents: bytemuck::cast_slice(&vertex::test()), + usage: wgpu::BufferUsage::VERTEX, + }); + // Clear frame { let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { @@ -236,7 +246,15 @@ fn run_event_loop() -> Result<(), Box> { }); render_pass.set_pipeline(&triangle_pipeline); - render_pass.draw(0..3, 0..1); + + render_pass.set_vertex_buffer( + 0, // The buffer slot to use for this vertex buffer. + vertex_buffer.slice(..), // Use the entire buffer. + ); + render_pass.draw( + 0..((&vertex::test()).len() as u32), // Draw all of the vertices from our test data. + 0..1, // Instances + ); } glyph_brush.queue(Section { diff --git a/editor/src/shaders/rect.frag b/editor/src/shaders/rect.frag index 74e14f410e..5671b40913 100644 --- a/editor/src/shaders/rect.frag +++ b/editor/src/shaders/rect.frag @@ -1,7 +1,11 @@ #version 450 -layout(location = 0) out vec4 outColor; +// The fragment shader's "in" values come from the "out" values of the vertex shader. +layout(location=0) in vec3 color; + +// The actual color that is rendered to the screen based on the vertex. +layout(location=0) out vec4 f_color; void main() { - outColor = vec4(1.0, 0.0, 0.0, 1.0); + f_color = vec4(color, 1.0); } diff --git a/editor/src/shaders/rect.vert b/editor/src/shaders/rect.vert index 2b9399e710..6236935f91 100644 --- a/editor/src/shaders/rect.vert +++ b/editor/src/shaders/rect.vert @@ -1,10 +1,14 @@ #version 450 -out gl_PerVertex { - vec4 gl_Position; -}; +// Layout value labelled "in" acquire data from the vertex buffer, +// as defined in the buffer descriptor for this shader. +layout(location=0) in vec3 position; +layout(location=1) in vec3 color; + +// Layout values labelled "out" send their data to the fragment shader. +layout(location=0) out vec3 v_color; void main() { - vec2 position = vec2(gl_VertexIndex, (gl_VertexIndex & 1) * 2) - 1; - gl_Position = vec4(position, 0.0, 1.0); + v_color = color; + gl_Position = vec4(position, 1.0); } diff --git a/editor/src/vertex.rs b/editor/src/vertex.rs new file mode 100644 index 0000000000..36ba53a31c --- /dev/null +++ b/editor/src/vertex.rs @@ -0,0 +1,50 @@ +#[repr(C)] +#[derive(Copy, Clone, Debug)] +pub struct Vertex { + position: [f32; 3], + color: [f32; 3], +} + +unsafe impl bytemuck::Pod for Vertex {} +unsafe impl bytemuck::Zeroable for Vertex {} + +impl Vertex { + // Defines how the shader will use this data structure. + pub fn buffer_descriptor<'a>() -> wgpu::VertexBufferDescriptor<'a> { + wgpu::VertexBufferDescriptor { + stride: std::mem::size_of::() as wgpu::BufferAddress, + step_mode: wgpu::InputStepMode::Vertex, + attributes: &[ + // position + wgpu::VertexAttributeDescriptor { + offset: 0, + shader_location: 0, + format: wgpu::VertexFormat::Float3, + }, + // color + wgpu::VertexAttributeDescriptor { + offset: std::mem::size_of::<[f32; 3]>() as wgpu::BufferAddress, + shader_location: 1, + format: wgpu::VertexFormat::Float3, + }, + ], + } + } +} + +pub fn test() -> [Vertex; 3] { + [ + Vertex { + position: [0.0, 0.5, 0.0], + color: [1.0, 0.0, 0.0], + }, + Vertex { + position: [-0.5, -0.5, 0.0], + color: [0.0, 1.0, 0.0], + }, + Vertex { + position: [0.5, -0.5, 0.0], + color: [0.0, 0.0, 1.0], + }, + ] +}