Created
December 18, 2021 15:18
-
-
Save samloeschen/2c667a1fe5eafdd0d8b877f2d5fe9693 to your computer and use it in GitHub Desktop.
wgpu-hello-triangle
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::borrow::Cow; | |
use winit::{ | |
event::*, | |
event_loop::{ControlFlow, EventLoop}, | |
window::Window, | |
}; | |
struct AppState { | |
surface: wgpu::Surface, | |
device: wgpu::Device, | |
queue: wgpu::Queue, | |
surface_config: wgpu::SurfaceConfiguration, | |
size: winit::dpi::PhysicalSize<u32>, | |
} | |
impl AppState { | |
async fn new(window: &Window) -> Self { | |
let size = window.inner_size(); | |
let instance = wgpu::Instance::new(wgpu::Backends::all()); | |
let surface = unsafe { instance.create_surface(window) }; | |
let adapter = instance.request_adapter(&wgpu::RequestAdapterOptions { | |
power_preference: wgpu::PowerPreference::default(), | |
compatible_surface: Some(&surface), | |
force_fallback_adapter: false, | |
}) | |
.await | |
.unwrap(); | |
let device_desc = wgpu::DeviceDescriptor { | |
label: None, | |
features: wgpu::Features::empty(), | |
limits: wgpu::Limits::default(), | |
}; | |
let (device, queue) = adapter.request_device(&device_desc, None) | |
.await | |
.unwrap(); | |
let surface_config = wgpu::SurfaceConfiguration { | |
usage: wgpu::TextureUsages::RENDER_ATTACHMENT, | |
format: surface.get_preferred_format(&adapter).unwrap(), | |
width: size.width, | |
height: size.height, | |
present_mode: wgpu::PresentMode::Fifo | |
}; | |
surface.configure(&device, &surface_config); | |
Self { | |
surface, | |
device, | |
queue, | |
surface_config, | |
size | |
} | |
} | |
fn resize(&mut self, new_size: winit::dpi::PhysicalSize<u32>) { | |
if new_size.width > 0 && new_size.height > 0 { | |
self.size = new_size; | |
self.surface_config.width = new_size.width; | |
self.surface_config.height = new_size.height; | |
self.surface.configure(&self.device, &self.surface_config); | |
} | |
} | |
} | |
fn render(state: &mut AppState) -> Result<(), wgpu::SurfaceError> { | |
let frame = state.surface.get_current_texture()?; | |
let view = frame.texture.create_view(&wgpu::TextureViewDescriptor::default()); | |
let shader_module = state.device.create_shader_module(&wgpu::ShaderModuleDescriptor { | |
label: None, | |
source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("shader.wgsl"))) | |
}); | |
let pipeline_layout = state.device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { | |
label: None, | |
bind_group_layouts: &[], | |
push_constant_ranges: &[], | |
}); | |
let pipeline = state.device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { | |
label: None, | |
layout: Some(&pipeline_layout), | |
vertex: wgpu::VertexState { | |
module: &shader_module, | |
entry_point: "vs_main", | |
buffers: &[], | |
}, | |
fragment: Some(wgpu::FragmentState { | |
module: &shader_module, | |
entry_point: "fs_main", | |
targets: &[wgpu::ColorTargetState { | |
format: state.surface_config.format, | |
blend: None, | |
write_mask: wgpu::ColorWrites::all() | |
}], | |
}), | |
primitive: wgpu::PrimitiveState::default(), | |
depth_stencil: None, | |
multisample: wgpu::MultisampleState::default(), | |
}); | |
let mut encoder = state.device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: Some ("Render Encoder")}); | |
{ | |
let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { | |
label: None, | |
color_attachments: &[wgpu::RenderPassColorAttachment { | |
view: &view, | |
resolve_target: None, | |
ops: wgpu::Operations { | |
load: wgpu::LoadOp::Clear(wgpu::Color::BLACK), | |
store: true, | |
}, | |
}], | |
depth_stencil_attachment: None, | |
}); | |
render_pass.set_pipeline(&pipeline); | |
render_pass.draw(0..3, 0..1); | |
} | |
state.queue.submit(Some(encoder.finish())); | |
frame.present(); | |
Ok(()) | |
} | |
fn handle_input(event: &WindowEvent) -> bool { | |
return false; | |
} | |
fn main() { | |
env_logger::init(); | |
let event_loop = EventLoop::new(); | |
let window = winit::window::WindowBuilder::new().build(&event_loop).unwrap(); | |
let mut state = pollster::block_on(AppState::new(&window)); | |
event_loop.run(move | event, _, control_flow| { | |
match event { | |
Event::WindowEvent { | |
ref event, | |
window_id, | |
} if window_id == window.id() => { | |
if !handle_input(event) { | |
match event { | |
WindowEvent::CloseRequested | | |
WindowEvent::KeyboardInput { | |
input: KeyboardInput { | |
state: ElementState::Pressed, | |
virtual_keycode: Some(VirtualKeyCode::Escape), | |
.. | |
}, | |
.. | |
} => *control_flow = ControlFlow::Exit, | |
WindowEvent::Resized(new_size) => { | |
state.resize(*new_size); | |
} | |
WindowEvent::ScaleFactorChanged {new_inner_size, ..} => { | |
state.resize(**new_inner_size); | |
} | |
_ => {} | |
} | |
} | |
} | |
Event::RedrawRequested(_) => { | |
match render(&mut state) { | |
Ok(_) => {} | |
Err(wgpu::SurfaceError::Lost) => state.resize(state.size), // Reconfigure the surface if lost | |
Err(wgpu::SurfaceError::OutOfMemory) => *control_flow = ControlFlow::Exit, // The system is out of memory, we should probably quit | |
Err(e) => eprintln!("{:?}", e), // The system is out of memory, we should probably quit | |
} | |
} | |
Event::MainEventsCleared => { | |
window.request_redraw(); | |
} | |
_ => {} | |
} | |
}); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[[stage(vertex)]] | |
fn vs_main([[builtin(vertex_index)]] in_vertex_index: u32) -> [[builtin(position)]] vec4<f32> { | |
let x = f32(i32(in_vertex_index) - 1); | |
let y = f32(i32(in_vertex_index & 1u) * 2 - 1); | |
return vec4<f32>(x, y, 0.0, 1.0); | |
} | |
[[stage(fragment)]] | |
fn fs_main() -> [[location(0)]] vec4<f32> { | |
return vec4<f32>(1.0, 0.0, 0.0, 1.0); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment