summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMicha White <botahamec@outlook.com>2022-09-18 14:49:16 -0400
committerMicha White <botahamec@outlook.com>2022-09-18 14:49:16 -0400
commitffee09ada476b3a350f331718d60fa806b564bad (patch)
treed2998f5bc6deea7e8cd746ce08c94b78764c58b7 /src
parentb92e827eb623a8d93872c6f95aceeb882b867a29 (diff)
Made a square
Diffstat (limited to 'src')
-rw-r--r--src/config.rs8
-rw-r--r--src/renderer.rs98
2 files changed, 83 insertions, 23 deletions
diff --git a/src/config.rs b/src/config.rs
index 1e8c43e..f321a9b 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -5,7 +5,7 @@ use winit::dpi::{LogicalPosition, LogicalSize};
use winit::window::{Fullscreen, WindowBuilder};
/// Describes how a window may be resized
-#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
+#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
pub struct Resizable {
/// The minimum width of the window, or None if unconstrained
pub min_width: Option<NonZeroU32>,
@@ -18,7 +18,7 @@ pub struct Resizable {
}
/// Information about a window, that is not fullscreened
-#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct WindowInfo {
pub default_x: i32,
pub default_y: i32,
@@ -37,7 +37,7 @@ impl Default for WindowInfo {
}
}
-#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum WindowMode {
Windowed(WindowInfo),
// TODO support choosing a monitor
@@ -50,7 +50,7 @@ impl Default for WindowMode {
}
}
-#[derive(Clone, Debug, PartialEq, Eq)]
+#[derive(Clone, Debug, PartialEq, Eq, Hash)]
// TODO window icon
pub struct RenderWindowConfig<'a> {
/// The width of the window, once initialized
diff --git a/src/renderer.rs b/src/renderer.rs
index bf7226d..2264ab5 100644
--- a/src/renderer.rs
+++ b/src/renderer.rs
@@ -1,6 +1,7 @@
use crate::config::RenderWindowConfig;
use pollster::FutureExt;
use thiserror::Error;
+use wgpu::include_wgsl;
use winit::{
dpi::PhysicalSize,
error::OsError,
@@ -10,7 +11,7 @@ use winit::{
};
/// No device could be found which supports the given surface
-#[derive(Clone, Copy, Debug, PartialEq, Eq, Error)]
+#[derive(Clone, Copy, Debug, Error)]
#[error("No GPU could be found on this machine")]
pub struct NoGpuError {
/// Prevents this type from being constructed
@@ -32,11 +33,13 @@ pub enum NewRendererError {
WindowInitError(#[from] OsError),
}
+#[derive(Debug)]
pub struct Renderer {
surface: wgpu::Surface,
device: wgpu::Device,
queue: wgpu::Queue,
- config: wgpu::SurfaceConfiguration,
+ surface_config: wgpu::SurfaceConfiguration,
+ render_pipeline: wgpu::RenderPipeline,
window: Window,
}
@@ -100,18 +103,65 @@ impl Renderer {
.unwrap();
// configuration for the surface
- let config = config.to_surface_configuration(
+ let surface_config = config.to_surface_configuration(
&surface.get_supported_modes(&adapter),
surface.get_supported_formats(&adapter)[0],
);
- surface.configure(&device, &config);
+ surface.configure(&device, &surface_config);
+
+ // set up a pipeline for sprite rendering
+ let shader = device.create_shader_module(include_wgsl!("../shaders/sprite.wgsl"));
+ let render_pipeline_layout =
+ device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
+ label: Some("Render Pipeline Layout"),
+ ..Default::default()
+ });
+ let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
+ label: Some("Render Pipeline"),
+ layout: Some(&render_pipeline_layout),
+ // information about the vertex shader
+ vertex: wgpu::VertexState {
+ module: &shader,
+ entry_point: "vs_main",
+ buffers: &[],
+ },
+ // information about the fragment shader
+ fragment: Some(wgpu::FragmentState {
+ module: &shader,
+ entry_point: "fs_main",
+ targets: &[Some(wgpu::ColorTargetState {
+ format: surface_config.format,
+ blend: Some(wgpu::BlendState::REPLACE),
+ write_mask: wgpu::ColorWrites::ALL,
+ })],
+ }),
+ primitive: wgpu::PrimitiveState {
+ // save some memory
+ topology: wgpu::PrimitiveTopology::TriangleStrip,
+ strip_index_format: None,
+ front_face: wgpu::FrontFace::Ccw,
+ // don't render the back of a sprite
+ cull_mode: Some(wgpu::Face::Back),
+ polygon_mode: wgpu::PolygonMode::Fill,
+ unclipped_depth: false,
+ conservative: false,
+ },
+ depth_stencil: None,
+ multisample: wgpu::MultisampleState {
+ count: 1,
+ mask: !0,
+ alpha_to_coverage_enabled: false,
+ },
+ multiview: None,
+ });
Ok(Self {
surface,
device,
queue,
- config,
+ surface_config,
+ render_pipeline,
window,
})
}
@@ -123,9 +173,9 @@ impl Renderer {
return;
}
- self.config.height = size.height;
- self.config.width = size.width;
- self.surface.configure(&self.device, &self.config);
+ self.surface_config.height = size.height;
+ self.surface_config.width = size.width;
+ self.surface.configure(&self.device, &self.surface_config);
}
/// Renders a new frame to the window
@@ -150,7 +200,7 @@ impl Renderer {
});
{
- let _render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
+ let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
label: Some("Render Pass"),
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
view: &view,
@@ -162,6 +212,9 @@ impl Renderer {
})],
depth_stencil_attachment: None,
});
+
+ render_pass.set_pipeline(&self.render_pipeline);
+ render_pass.draw(0..4, 0..1);
}
// the encoder can't finish building the command buffer until the
// render pass is dropped
@@ -185,19 +238,26 @@ impl Renderer {
}
}
}
- Event::MainEventsCleared => {
- match self.render() {
- Ok(_) => {}
- // reconfigure the surface if it's been lost
- Err(wgpu::SurfaceError::Lost) => self.resize_renderer(self.window.inner_size()),
- // if we ran out of memory, then we'll die
- Err(wgpu::SurfaceError::OutOfMemory) => {
- *control_flow = ControlFlow::ExitWithCode(1);
+ Event::RedrawRequested(window_id) => {
+ if window_id == self.window.id() {
+ match self.render() {
+ Ok(_) => {}
+ // reconfigure the surface if it's been lost
+ Err(wgpu::SurfaceError::Lost) => {
+ self.resize_renderer(self.window.inner_size());
+ }
+ // if we ran out of memory, then we'll die
+ Err(wgpu::SurfaceError::OutOfMemory) => {
+ *control_flow = ControlFlow::ExitWithCode(1);
+ }
+ // otherwise, we'll just log the error
+ Err(e) => log::error!("{}", e),
}
- // otherwise, we'll just log the error
- Err(e) => log::error!("{}", e),
}
}
+ Event::MainEventsCleared => {
+ self.window.request_redraw();
+ }
_ => {}
})
}