Minor edit

master
Mark 2023-12-23 11:01:27 -08:00
parent 429c0665d1
commit 280d86c09d
Signed by: Mark
GPG Key ID: C6D63995FE72FD80
5 changed files with 207 additions and 20 deletions

View File

@ -68,10 +68,14 @@ struct Sprite {
impl Sprite { impl Sprite {
const PARALLAX_STRENGTH: Pfloat = 0.1; const PARALLAX_STRENGTH: Pfloat = 0.1;
pub fn post_parallax(parallax: Pfloat, pos: Point2<Pfloat>, camera: Camera) -> Point2<Pfloat> {
let v = camera.pos.to_vec() - pos.to_vec();
return pos + (v * parallax * Self::PARALLAX_STRENGTH);
}
/// Returns post-parallax position in game coordinates. /// Returns post-parallax position in game coordinates.
pub fn post_parallax_position(&self, camera: Camera) -> Point2<f32> { pub fn post_parallax_position(&self, camera: Camera) -> Point2<Pfloat> {
let v = camera.pos.to_vec() - self.pos.to_vec(); return Self::post_parallax(self.parallax, self.pos, camera);
return self.pos + (v * self.parallax * Self::PARALLAX_STRENGTH);
} }
} }

View File

@ -1,5 +1,6 @@
mod bufferdata; mod bufferdata;
mod gpustate; mod gpustate;
mod pipeline;
mod rawtexture; mod rawtexture;
mod texturearray; mod texturearray;
mod util; mod util;
@ -7,7 +8,7 @@ mod util;
pub use gpustate::GPUState; pub use gpustate::GPUState;
pub use texturearray::Texture; pub use texturearray::Texture;
use self::bufferdata::Vertex; use self::bufferdata::{PlainVertex, TexturedVertex};
use cgmath::Matrix4; use cgmath::Matrix4;
/// API correction matrix. /// API correction matrix.
@ -21,6 +22,10 @@ const OPENGL_TO_WGPU_MATRIX: Matrix4<f32> = Matrix4::new(
0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0,
); );
const STARFIELD_VERTICES: &[PlainVertex] = &[PlainVertex {
position: [0.0, 0.0, 0.0],
}];
// The surface we draw sprites on. // The surface we draw sprites on.
// Every sprite is an instance of this. // Every sprite is an instance of this.
// //
@ -32,23 +37,23 @@ const OPENGL_TO_WGPU_MATRIX: Matrix4<f32> = Matrix4::new(
// Screen coordinates range from -1 to 1, with the origin at the center. // Screen coordinates range from -1 to 1, with the origin at the center.
// Texture coordinates range from 0 to 1, with the origin at the top-left // Texture coordinates range from 0 to 1, with the origin at the top-left
// and (1,1) at the bottom-right. // and (1,1) at the bottom-right.
const SPRITE_MESH_VERTICES: &[Vertex] = &[ const SPRITE_VERTICES: &[TexturedVertex] = &[
Vertex { TexturedVertex {
position: [-1.0, 1.0, 0.0], position: [-1.0, 1.0, 0.0],
texture_coords: [0.0, 0.0], texture_coords: [0.0, 0.0],
}, },
Vertex { TexturedVertex {
position: [1.0, 1.0, 0.0], position: [1.0, 1.0, 0.0],
texture_coords: [1.0, 0.0], texture_coords: [1.0, 0.0],
}, },
Vertex { TexturedVertex {
position: [1.0, -1.0, 0.0], position: [1.0, -1.0, 0.0],
texture_coords: [1.0, 1.0], texture_coords: [1.0, 1.0],
}, },
Vertex { TexturedVertex {
position: [-1.0, -1.0, 0.0], position: [-1.0, -1.0, 0.0],
texture_coords: [0.0, 1.0], texture_coords: [0.0, 1.0],
}, },
]; ];
const SPRITE_MESH_INDICES: &[u16] = &[0, 3, 2, 0, 2, 1]; const SPRITE_INDICES: &[u16] = &[0, 3, 2, 0, 2, 1];

140
src/render/pipeline.rs Normal file
View File

@ -0,0 +1,140 @@
use wgpu;
pub struct PipelineBuilder<'a> {
// These are provided with new()
label: &'a str,
device: &'a wgpu::Device,
// These have empty defaults
triangle: bool,
vertex_buffers: &'a [wgpu::VertexBufferLayout<'a>],
bind_group_layouts: &'a [&'a wgpu::BindGroupLayout],
// These must be provided
shader: Option<&'a str>,
format: Option<wgpu::TextureFormat>,
}
impl<'a> PipelineBuilder<'a> {
const VERTEX_MAIN: &'static str = "vertex_shader_main";
const FRAGMENT_MAIN: &'static str = "fragment_shader_main";
pub fn new(label: &'a str, device: &'a wgpu::Device) -> Self {
Self {
label,
device,
triangle: true,
vertex_buffers: &[],
bind_group_layouts: &[],
shader: None,
format: None,
}
}
pub fn set_shader(mut self, shader: &'a str) -> Self {
self.shader = Some(shader);
self
}
pub fn set_format(mut self, format: wgpu::TextureFormat) -> Self {
self.format = Some(format);
self
}
pub fn set_triangle(mut self, triangle: bool) -> Self {
self.triangle = triangle;
self
}
pub fn set_vertex_buffers(
mut self,
vertex_buffers: &'a [wgpu::VertexBufferLayout<'a>],
) -> Self {
self.vertex_buffers = vertex_buffers;
self
}
pub fn set_bind_group_layouts(
mut self,
bind_group_layouts: &'a [&'a wgpu::BindGroupLayout],
) -> Self {
self.bind_group_layouts = bind_group_layouts;
self
}
pub fn build(self) -> wgpu::RenderPipeline {
// All fields should be set.
// Nones are not checked, they will panic.
let shader = self
.device
.create_shader_module(wgpu::ShaderModuleDescriptor {
label: Some(&format!("pipeline [{}] shader", self.label)),
source: wgpu::ShaderSource::Wgsl(self.shader.unwrap().into()),
});
let pipeline_layout = self
.device
.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
label: Some(&format!("pipeline [{}] layout", self.label)),
bind_group_layouts: self.bind_group_layouts,
push_constant_ranges: &[],
});
let pipeline = self
.device
.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
label: Some(&format!("pipeline [{}]", self.label)),
layout: Some(&pipeline_layout),
depth_stencil: None,
multiview: None,
multisample: wgpu::MultisampleState {
count: 1,
mask: !0,
alpha_to_coverage_enabled: false,
},
vertex: wgpu::VertexState {
module: &shader,
entry_point: Self::VERTEX_MAIN,
buffers: self.vertex_buffers,
},
fragment: Some(wgpu::FragmentState {
module: &shader,
entry_point: Self::FRAGMENT_MAIN,
targets: &[Some(wgpu::ColorTargetState {
format: self.format.unwrap(),
blend: Some(wgpu::BlendState::ALPHA_BLENDING),
write_mask: wgpu::ColorWrites::ALL,
})],
}),
primitive: if self.triangle {
wgpu::PrimitiveState {
topology: wgpu::PrimitiveTopology::TriangleList,
strip_index_format: None,
front_face: wgpu::FrontFace::Ccw,
cull_mode: Some(wgpu::Face::Back),
polygon_mode: wgpu::PolygonMode::Fill,
unclipped_depth: false,
conservative: false,
}
} else {
wgpu::PrimitiveState {
topology: wgpu::PrimitiveTopology::PointList,
strip_index_format: None,
front_face: wgpu::FrontFace::Ccw,
cull_mode: None,
polygon_mode: wgpu::PolygonMode::Fill,
unclipped_depth: false,
conservative: false,
}
},
});
return pipeline;
}
}

View File

@ -1,23 +1,22 @@
struct InstanceInput { struct InstanceInput {
@location(5) transform_matrix_0: vec4<f32>, @location(2) transform_matrix_0: vec4<f32>,
@location(6) transform_matrix_1: vec4<f32>, @location(3) transform_matrix_1: vec4<f32>,
@location(7) transform_matrix_2: vec4<f32>, @location(4) transform_matrix_2: vec4<f32>,
@location(8) transform_matrix_3: vec4<f32>, @location(5) transform_matrix_3: vec4<f32>,
@location(9) texture_idx: u32, @location(6) texture_idx: u32,
}; };
// Vertex shader // Vertex shader
struct VertexInput { struct VertexInput {
@location(0) position: vec3<f32>, @location(0) position: vec3<f32>,
@location(1) tex_coords: vec2<f32>, @location(1) texture_coords: vec2<f32>,
} }
struct VertexOutput { struct VertexOutput {
@builtin(position) clip_position: vec4<f32>, @builtin(position) clip_position: vec4<f32>,
@location(0) tex_coords: vec2<f32>, @location(0) texture_coords: vec2<f32>,
@location(1) index: u32, @location(1) index: u32,
} }
@ -34,7 +33,7 @@ fn vertex_shader_main(
); );
var out: VertexOutput; var out: VertexOutput;
out.tex_coords = model.tex_coords; out.texture_coords = model.texture_coords;
out.clip_position = transform_matrix * vec4<f32>(model.position, 1.0); out.clip_position = transform_matrix * vec4<f32>(model.position, 1.0);
out.index = instance.texture_idx; out.index = instance.texture_idx;
return out; return out;
@ -54,7 +53,7 @@ fn fragment_shader_main(in: VertexOutput) -> @location(0) vec4<f32> {
return textureSampleLevel( return textureSampleLevel(
texture_array[in.index], texture_array[in.index],
sampler_array[in.index], sampler_array[in.index],
in.tex_coords, in.texture_coords,
0.0 0.0
).rgba; ).rgba;
} }

View File

@ -0,0 +1,39 @@
struct InstanceInput {
@location(2) transform_matrix_0: vec4<f32>,
@location(3) transform_matrix_1: vec4<f32>,
@location(4) transform_matrix_2: vec4<f32>,
@location(5) transform_matrix_3: vec4<f32>,
};
// Vertex shader
struct VertexInput {
@location(0) position: vec3<f32>,
}
struct VertexOutput {
@builtin(position) clip_position: vec4<f32>,
}
@vertex
fn vertex_shader_main(
model: VertexInput,
instance: InstanceInput,
) -> VertexOutput {
let transform_matrix = mat4x4<f32>(
instance.transform_matrix_0,
instance.transform_matrix_1,
instance.transform_matrix_2,
instance.transform_matrix_3,
);
var out: VertexOutput;
out.clip_position = transform_matrix * vec4<f32>(model.position, 1.0);
return out;
}
@fragment
fn fragment_shader_main(in: VertexOutput) -> @location(0) vec4<f32> {
return vec4<f32>(1.0, 1.0, 1.0, 1.0);
}