Having fun

This commit is contained in:
Piotrek
2021-04-12 11:58:40 +02:00
commit 93c535626a
12 changed files with 2157 additions and 0 deletions
Binary file not shown.
Binary file not shown.
+154
View File
@@ -0,0 +1,154 @@
use winit::{window::Window, dpi::PhysicalSize, event::WindowEvent};
pub struct App {
surface: wgpu::Surface,
device: wgpu::Device,
queue: wgpu::Queue,
swapchain_desc: wgpu::SwapChainDescriptor,
swapchain: wgpu::SwapChain,
pipeline: wgpu::RenderPipeline
}
impl App {
pub async fn new(window: &Window) -> Self {
// Select backend
let backend = wgpu::BackendBit::DX12;
println!("Backend: {:?}", backend);
// Create surface and pick adapter (physical gpu)
let instance = wgpu::Instance::new(backend);
let surface = unsafe { instance.create_surface(window) };
let adapter = instance.request_adapter(
&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::default(),
compatible_surface: Some(&surface),
},
).await.unwrap();
println!("Adapter: {}", adapter.get_info().name);
// Pick device (logical gpu) from adapter
let (device, queue) = adapter.request_device(
&wgpu::DeviceDescriptor {
features: wgpu::Features::empty(),
limits: wgpu::Limits::default(),
label: None,
},
None, // Trace path
).await.unwrap();
// Build descriptor and create swap chain
let size = window.inner_size();
let swapchain_desc = wgpu::SwapChainDescriptor {
usage: wgpu::TextureUsage::RENDER_ATTACHMENT, // render to screen
format: adapter.get_swap_chain_preferred_format(&surface),
width: size.width,
height: size.height,
present_mode: wgpu::PresentMode::Fifo,
};
let swapchain = device.create_swap_chain(&surface, &swapchain_desc);
// Create pipeline
let vert_module = device.create_shader_module(&wgpu::include_spirv!(".bin\\shader.vert.spv"));
let frag_module = device.create_shader_module(&wgpu::include_spirv!(".bin\\shader.frag.spv"));
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
label: Some("Render Pipeline Layout"),
bind_group_layouts: &[],
push_constant_ranges: &[],
});
let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
label: Some("Render Pipeline"),
layout: Some(&pipeline_layout),
// Vertex shader
vertex: wgpu::VertexState {
module: &vert_module,
entry_point: "main",
buffers: &[],
},
// Fragment shader
fragment: Some(wgpu::FragmentState {
module: &frag_module,
entry_point: "main",
targets: &[wgpu::ColorTargetState {
format: swapchain_desc.format,
alpha_blend: wgpu::BlendState::REPLACE,
color_blend: wgpu::BlendState::REPLACE,
write_mask: wgpu::ColorWrite::ALL,
}],
}),
// Other
primitive: wgpu::PrimitiveState {
topology: wgpu::PrimitiveTopology::TriangleList,
strip_index_format: None,
front_face: wgpu::FrontFace::Ccw,
cull_mode: wgpu::CullMode::Back,
polygon_mode: wgpu::PolygonMode::Fill,
},
depth_stencil: None,
multisample: wgpu::MultisampleState {
count: 1,
mask: !0,
alpha_to_coverage_enabled: false,
},
});
// Save values in app
Self { surface, device, queue, swapchain_desc, swapchain, pipeline }
}
pub fn resize(&mut self, new_size: Option<PhysicalSize<u32>>) {
if let Some(size) = new_size {
// Minimized or manually resized to 0
if size.width == 0 || size.height == 0 { return }
// Recreate swapchain
self.swapchain_desc.width = size.width;
self.swapchain_desc.height = size.height;
}
// Recreate swapchain
self.swapchain = self.device.create_swap_chain(&self.surface, &self.swapchain_desc);
}
pub fn input(&mut self, _event: &WindowEvent) -> bool {
false
}
pub fn update(&mut self) {
// Nothing right now
}
pub fn render(&mut self) -> Result<(), wgpu::SwapChainError> {
// Get next frame to render to
let frame = self.swapchain.get_current_frame()?.output;
// Create encoder that will build command buffer for us
let mut encoder = self.device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: Some("Render Encoder"),});
// Create render pass
{
let ops = wgpu::Operations {
// Clear command
load: wgpu::LoadOp::Clear(wgpu::Color {r: 0.1, g: 0.2, b: 0.3, a: 1.0,}),
// Store command
store: true,
};
let _render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { label: Some("Render Pass"),
color_attachments: &[
wgpu::RenderPassColorAttachmentDescriptor {
attachment: &frame.view,
resolve_target: None,
ops: ops
}
],
depth_stencil_attachment: None,
});
}
// Submit encoder (command buffer)
self.queue.submit(std::iter::once(encoder.finish()));
// Return ok
Ok(())
}
}
Binary file not shown.
Binary file not shown.
+78
View File
@@ -0,0 +1,78 @@
use winit::{
event::{Event, WindowEvent, KeyboardInput, ElementState, VirtualKeyCode},
event_loop::{ControlFlow, EventLoop},
window::WindowBuilder,
dpi::LogicalSize
};
mod app;
use app::App;
fn main() {
// Create event loop
let events = EventLoop::new();
// Spawn window
let window = WindowBuilder::new()
.with_title("Test")
.with_inner_size(LogicalSize::new(1280.0, 720.0))
.build(&events)
.expect("Failed to create window");
// Create app
let mut app = futures::executor::block_on(App::new(&window));
// Run event loop
events.run(move |e, _, c| {
match e {
// Window event
Event::WindowEvent { ref event, .. } => if !app.input(event) {
match event {
// Window closed
WindowEvent::CloseRequested => {
*c = ControlFlow::Exit;
}
// Keyboard input
WindowEvent::KeyboardInput { input, .. } => {
match input {
// Escape key pressed
KeyboardInput { state: ElementState::Pressed, virtual_keycode: Some(VirtualKeyCode::Escape), .. } => {
*c = ControlFlow::Exit;
}
// Other keys
_ => ()
}
}
// Window resized
WindowEvent::Resized(physical_size) => {
app.resize(Some(*physical_size));
}
WindowEvent::ScaleFactorChanged { new_inner_size, .. } => {
app.resize(Some(**new_inner_size));
}
// Other window events
_ => ()
}
}
// Request draw
Event::MainEventsCleared => {
window.request_redraw();
}
// Draw
Event::RedrawRequested(_) => {
app.update();
match app.render() {
Ok(_) => {}
// Recreate the swap_chain if lost
Err(wgpu::SwapChainError::Lost) => app.resize(None),
// The system is out of memory, we should probably quit
Err(wgpu::SwapChainError::OutOfMemory) => *c = ControlFlow::Exit,
// All other errors (Outdated, Timeout) should be resolved by the next frame
Err(e) => eprintln!("{:?}", e),
}
}
// Other events
_ => ()
}
});
}
+9
View File
@@ -0,0 +1,9 @@
// shader.frag
#version 450
layout(location=0) out vec4 f_color;
void main()
{
f_color = vec4(0.3, 0.2, 0.1, 1.0);
}
+17
View File
@@ -0,0 +1,17 @@
// shader.vert
#version 450
const vec2 positions[3] = vec2[3](
vec2(0.0, 0.5),
vec2(-0.5, -0.5),
vec2(0.5, -0.5)
);
void main()
{
gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0);
}