diff --git a/meshes/cube.rs b/meshes/cube.rs deleted file mode 100644 index f51e766..0000000 --- a/meshes/cube.rs +++ /dev/null @@ -1,53 +0,0 @@ -mod meshes { - use std::mem::size_of; - - const CUBE_VERTEX_SIZE: usize = size_of::() * 10; - const CUBE_VERTEX_COUNT: usize = 36; - const CUBE_VERTEX_POS_OFFSET: usize = 0; - const CUBE_VERTEX_COLOR_OFFSET: usize = size_of::() * 4; - const CUBE_VERTEX_UV_OFFSET: usize = size_of::() * 8; - const CUBE_VERTICES: [f32; 24] = [ - // float4 position, float4 color, float2 uv - 1, -1, 1, 1, 1, 0, 1, 1, 0, 1, - -1, -1, 1, 1, 0, 0, 1, 1, 1, 1, - -1, -1, -1, 1, 0, 0, 0, 1, 1, 0, - 1, -1, -1, 1, 1, 0, 0, 1, 0, 0, - 1, -1, 1, 1, 1, 0, 1, 1, 0, 1, - -1, -1, -1, 1, 0, 0, 0, 1, 1, 0, - - 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, - 1, -1, 1, 1, 1, 0, 1, 1, 1, 1, - 1, -1, -1, 1, 1, 0, 0, 1, 1, 0, - 1, 1, -1, 1, 1, 1, 0, 1, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, - 1, -1, -1, 1, 1, 0, 0, 1, 1, 0, - - -1, 1, 1, 1, 0, 1, 1, 1, 0, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, -1, 1, 1, 1, 0, 1, 1, 0, - -1, 1, -1, 1, 0, 1, 0, 1, 0, 0, - -1, 1, 1, 1, 0, 1, 1, 1, 0, 1, - 1, 1, -1, 1, 1, 1, 0, 1, 1, 0, - - -1, -1, 1, 1, 0, 0, 1, 1, 0, 1, - -1, 1, 1, 1, 0, 1, 1, 1, 1, 1, - -1, 1, -1, 1, 0, 1, 0, 1, 1, 0, - -1, -1, -1, 1, 0, 0, 0, 1, 0, 0, - -1, -1, 1, 1, 0, 0, 1, 1, 0, 1, - -1, 1, -1, 1, 0, 1, 0, 1, 1, 0, - - 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, - -1, 1, 1, 1, 0, 1, 1, 1, 1, 1, - -1, -1, 1, 1, 0, 0, 1, 1, 1, 0, - -1, -1, 1, 1, 0, 0, 1, 1, 1, 0, - 1, -1, 1, 1, 1, 0, 1, 1, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, - - 1, -1, -1, 1, 1, 0, 0, 1, 0, 1, - -1, -1, -1, 1, 0, 0, 0, 1, 1, 1, - -1, 1, -1, 1, 0, 1, 0, 1, 1, 0, - 1, 1, -1, 1, 1, 1, 0, 1, 0, 0, - 1, -1, -1, 1, 1, 0, 0, 1, 0, 1, - -1, 1, -1, 1, 0, 1, 0, 1, 1, 0, - ]; -} \ No newline at end of file diff --git a/shaders/cube.wgsl b/shaders/cube.wgsl new file mode 100644 index 0000000..fd69f15 --- /dev/null +++ b/shaders/cube.wgsl @@ -0,0 +1,27 @@ +struct VertexOutput { + @location(0) color: vec3, + @builtin(position) position: vec4 +}; + +struct Locals { + transform: mat4x4 +}; + +@group(0) @binding(0) +var r_locals: Locals; + +@vertex +fn vs_main( + @location(0) position: vec4, + @location(1) color: vec3, +) -> VertexOutput { + var out: VertexOutput; + out.color = color; + out.position = r_locals.transform * position; + return out; +} + +@fragment +fn fs_main(in: VertexOutput) -> @location(0) vec4 { + return vec4(in.color.r, in.color.g, in.color.b, 1.0); +} \ No newline at end of file diff --git a/shaders/shader.wgsl b/shaders/shader.wgsl index 859ffa4..acb8f41 100644 --- a/shaders/shader.wgsl +++ b/shaders/shader.wgsl @@ -1,11 +1,26 @@ + + @vertex fn vs_main(@builtin(vertex_index) in_vertex_index: u32) -> @builtin(position) vec4 { let x = f32(i32(in_vertex_index) - 1); let y = f32(i32(in_vertex_index & 1u) * 2 - 1); return vec4(x, y, 0.0, 1.0); + + // param 0 + // x = -1 + // y = -1 + + // param 1 + // x = 0 + // y = 1 + + // param 2 + // x = 1 + // y = -1 + } @fragment fn fs_main() -> @location(0) vec4 { - return vec4(1.0, 0.0, 0.0, 1.0); + return vec4(0.0, 0.0, 1.0, 1.0); } \ No newline at end of file diff --git a/src/cube.rs b/src/cube.rs new file mode 100644 index 0000000..bb7475c --- /dev/null +++ b/src/cube.rs @@ -0,0 +1,114 @@ +#[derive(Copy, Clone)] +pub struct Vertex { + position: [f32; 4], + color: [f32; 3] +} + +fn vertex(pos: [i8; 3], color: [i8; 3]) -> Vertex { + Vertex { + position: [pos[0] as f32, pos[1] as f32, pos[2] as f32, 1.0], + color: [color[0] as f32, color[1] as f32, color[2] as f32] + } +} + +pub fn create_vertices() -> (Vec, Vec) { + let vertex_data = [ + // top (0, 0, 1) + vertex([-1, -1, 1], [1, 0, 0]), + vertex([1, -1, 1], [1, 0, 0]), + vertex([1, 1, 1], [1, 0, 0]), + vertex([-1, 1, 1], [1, 0, 0]), + // bottom (0, 0, -1) + vertex([-1, 1, -1], [0, 1, 0]), + vertex([1, 1, -1], [0, 1, 0]), + vertex([1, -1, -1], [0, 1, 0]), + vertex([-1, -1, -1],[0, 1, 0]), + // right (1, 0, 0) + vertex([1, -1, -1], [0, 0, 1]), + vertex([1, 1, -1], [0, 0, 1]), + vertex([1, 1, 1], [0, 0, 1]), + vertex([1, -1, 1], [0, 0, 1]), + // left (-1, 0, 0) + vertex([-1, -1, 1], [1, 1, 1]), + vertex([-1, 1, 1], [1, 1, 1]), + vertex([-1, 1, -1], [1, 1, 1]), + vertex([-1, -1, -1], [1, 1, 1]), + // front (0, 1, 0) + vertex([1, 1, -1], [1, 1, 0]), + vertex([-1, 1, -1], [1, 1, 0]), + vertex([-1, 1, 1], [1, 1, 0]), + vertex([1, 1, 1], [1, 1, 0]), + // back (0, -1, 0) + vertex([1, -1, 1], [0, 0, 0]), + vertex([-1, -1, 1], [0, 0, 0]), + vertex([-1, -1, -1], [0, 0, 0]), + vertex([1, -1, -1], [0, 0, 0]), + ]; + + let index_data: &[u16] = &[ + 0, 1, 2, 2, 3, 0, // top + 4, 5, 6, 6, 7, 4, // bottom + 8, 9, 10, 10, 11, 8, // right + 12, 13, 14, 14, 15, 12, // left + 16, 17, 18, 18, 19, 16, // front + 20, 21, 22, 22, 23, 20, // back + ]; + + (vertex_data.to_vec(), index_data.to_vec()) +} + + +// OLD +/* +use std::mem::size_of; + +const CUBE_VERTEX_SIZE: usize = size_of::() * 10; +const CUBE_VERTEX_COUNT: usize = 36; +const CUBE_VERTEX_POS_OFFSET: usize = 0; +const CUBE_VERTEX_COLOR_OFFSET: usize = size_of::() * 4; +const CUBE_VERTEX_UV_OFFSET: usize = size_of::() * 8; +const CUBE_VERTICES: [f32; 24] = [ + // float4 position, float4 color, float2 uv + 1, -1, 1, 1, 1, 0, 1, 1, 0, 1, + -1, -1, 1, 1, 0, 0, 1, 1, 1, 1, + -1, -1, -1, 1, 0, 0, 0, 1, 1, 0, + 1, -1, -1, 1, 1, 0, 0, 1, 0, 0, + 1, -1, 1, 1, 1, 0, 1, 1, 0, 1, + -1, -1, -1, 1, 0, 0, 0, 1, 1, 0, + + 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, + 1, -1, 1, 1, 1, 0, 1, 1, 1, 1, + 1, -1, -1, 1, 1, 0, 0, 1, 1, 0, + 1, 1, -1, 1, 1, 1, 0, 1, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, + 1, -1, -1, 1, 1, 0, 0, 1, 1, 0, + + -1, 1, 1, 1, 0, 1, 1, 1, 0, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, -1, 1, 1, 1, 0, 1, 1, 0, + -1, 1, -1, 1, 0, 1, 0, 1, 0, 0, + -1, 1, 1, 1, 0, 1, 1, 1, 0, 1, + 1, 1, -1, 1, 1, 1, 0, 1, 1, 0, + + -1, -1, 1, 1, 0, 0, 1, 1, 0, 1, + -1, 1, 1, 1, 0, 1, 1, 1, 1, 1, + -1, 1, -1, 1, 0, 1, 0, 1, 1, 0, + -1, -1, -1, 1, 0, 0, 0, 1, 0, 0, + -1, -1, 1, 1, 0, 0, 1, 1, 0, 1, + -1, 1, -1, 1, 0, 1, 0, 1, 1, 0, + + 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, + -1, 1, 1, 1, 0, 1, 1, 1, 1, 1, + -1, -1, 1, 1, 0, 0, 1, 1, 1, 0, + -1, -1, 1, 1, 0, 0, 1, 1, 1, 0, + 1, -1, 1, 1, 1, 0, 1, 1, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, + + 1, -1, -1, 1, 1, 0, 0, 1, 0, 1, + -1, -1, -1, 1, 0, 0, 0, 1, 1, 1, + -1, 1, -1, 1, 0, 1, 0, 1, 1, 0, + 1, 1, -1, 1, 1, 1, 0, 1, 0, 0, + 1, -1, -1, 1, 1, 0, 0, 1, 0, 1, + -1, 1, -1, 1, 0, 1, 0, 1, 1, 0, +]; +*/ \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 33f6ec3..5cffc8d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,11 +1,14 @@ mod voxel; +mod cube; use std::borrow::Cow; +use wgpu::util::DeviceExt; use winit::{ event::{Event, WindowEvent}, event_loop::{ControlFlow, EventLoop}, window::Window, }; +use std::mem; async fn run(event_loop: EventLoop<()>, window: Window) { let size = window.inner_size(); @@ -38,18 +41,78 @@ async fn run(event_loop: EventLoop<()>, window: Window) { .await .expect("Failed to create device"); - // Load the shaders from disk - let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor { + let (vertex_data, index_data) = cube::create_vertices(); + + let vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("Vertex Buffer"), + contents: bytemuck::cast_slice(&vertex_data), + usage: wgpu::BufferUsages::VERTEX, + }); + + let index_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("Index Buffer"), + contents: bytemuck::cast_slice(&index_data), + usage: wgpu::BufferUsages::INDEX, + }); + + let vertex_size = mem::size_of::(); + let vertex_buffer = wgpu::VertexBufferLayout { + array_stride: vertex_size as wgpu::BufferAddress, + step_mode: wgpu::VertexStepMode::Vertex, + attributes: &[ + wgpu::VertexAttribute { + format: wgpu::VertexFormat::Float32x4, + offset: 0, + shader_location: 0, + }, + wgpu::VertexAttribute { + format: wgpu::VertexFormat::Float32x3, + offset: mem::size_of::() as u64 * 4, + shader_location: 1, + }, + ], + }; + + let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { label: None, - source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("../shaders/shader.wgsl"))), + entries: &[ + wgpu::BindGroupLayoutEntry { + binding: 0, + visibility: wgpu::ShaderStages::VERTEX, + ty: wgpu::BindingType::Buffer { + ty: wgpu::BufferBindingType::Uniform, + has_dynamic_offset: false, + min_binding_size: wgpu::BufferSize::new(64), + }, + count: None, + } + ], }); let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: None, - bind_group_layouts: &[], + bind_group_layouts: &[&bind_group_layout], push_constant_ranges: &[], }); + // Create bind group + let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { + layout: &bind_group_layout, + entries: &[ + wgpu::BindGroupEntry { + binding: 0, + resource: uniform_buffer.as_entire_binding(), + } + ], + label: None, + }); + + // Load the shaders from disk + let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor { + label: None, + source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("../shaders/cube.wgsl"))), + }); + let swapchain_capabilities = surface.get_capabilities(&adapter); let swapchain_format = swapchain_capabilities.formats[0]; @@ -59,14 +122,17 @@ async fn run(event_loop: EventLoop<()>, window: Window) { vertex: wgpu::VertexState { module: &shader, entry_point: "vs_main", - buffers: &[], + buffers: &[vertex_buffer], }, fragment: Some(wgpu::FragmentState { module: &shader, entry_point: "fs_main", targets: &[Some(swapchain_format.into())], }), - primitive: wgpu::PrimitiveState::default(), + primitive: wgpu::PrimitiveState { + cull_mode: Some(wgpu::Face::Back), + ..Default::default() + }, depth_stencil: None, multisample: wgpu::MultisampleState::default(), multiview: None, @@ -126,7 +192,10 @@ async fn run(event_loop: EventLoop<()>, window: Window) { depth_stencil_attachment: None, }); rpass.set_pipeline(&render_pipeline); - rpass.draw(0..3, 0..1); + rpass.set_bind_group(0, &bind_group, &[]); + rpass.set_index_buffer(index_buffer.slice(..), wgpu::IndexFormat::Uint16); + rpass.set_vertex_buffer(0, vertex_buffer.slice(..)); + rpass.draw_indexed(0..index_data.len() as u32, 0, 0..1); } queue.submit(Some(encoder.finish())); diff --git a/src/voxel.rs b/src/voxel.rs index cc0df82..e4b036d 100644 --- a/src/voxel.rs +++ b/src/voxel.rs @@ -3,7 +3,7 @@ struct Voxel { r: u8, g: u8, b: u8 } -const AIR_VOXEL: Voxel = Voxel { r: 0, g: 0, b: 0 }; +const AIR_VOXEL: Voxel = Voxel { r: 0, g: 0, b: 0}; struct VoxelMap { data: Vec,