Adjust renderer for new system

master
Mark 2024-01-23 15:53:17 -08:00
parent 46049467a8
commit 55bb25b6d0
Signed by: Mark
GPG Key ID: C6D63995FE72FD80
5 changed files with 86 additions and 184 deletions

View File

@ -20,7 +20,6 @@ pub struct GPUState {
object_pipeline: wgpu::RenderPipeline, object_pipeline: wgpu::RenderPipeline,
starfield_pipeline: wgpu::RenderPipeline, starfield_pipeline: wgpu::RenderPipeline,
//particle_pipeline: wgpu::RenderPipeline,
ui_pipeline: wgpu::RenderPipeline, ui_pipeline: wgpu::RenderPipeline,
radialbar_pipeline: wgpu::RenderPipeline, radialbar_pipeline: wgpu::RenderPipeline,

View File

@ -168,23 +168,6 @@ impl GPUState {
.set_bind_group_layouts(bind_group_layouts) .set_bind_group_layouts(bind_group_layouts)
.build(); .build();
/*
let particle_pipeline = PipelineBuilder::new("particle", &device)
.set_shader(&preprocess_shader(
&include_str!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/shaders/",
"particle.wgsl"
)),
&global_uniform,
1,
))
.set_format(config.format)
.set_triangle(true)
.set_vertex_buffer(vertex_buffers.get_particle())
.set_bind_group_layouts(bind_group_layouts)
.build();*/
let radialbar_pipeline = PipelineBuilder::new("radialbar", &device) let radialbar_pipeline = PipelineBuilder::new("radialbar", &device)
.set_shader(&preprocess_shader( .set_shader(&preprocess_shader(
&include_str!(concat!( &include_str!(concat!(
@ -230,7 +213,6 @@ impl GPUState {
object_pipeline, object_pipeline,
starfield_pipeline, starfield_pipeline,
ui_pipeline, ui_pipeline,
//particle_pipeline,
radialbar_pipeline, radialbar_pipeline,
state, state,

View File

@ -10,37 +10,35 @@ use crate::{
}; };
impl GPUState { impl GPUState {
pub(super) fn phys_push_ship( pub(super) fn phys_push_ships(
&mut self, &mut self,
input: &RenderInput, input: &RenderInput,
// NE and SW corners of screen // NE and SW corners of screen
screen_clip: (Point2<f32>, Point2<f32>), screen_clip: (Point2<f32>, Point2<f32>),
) { ) {
for ship in input.systemsim.iter_ships() { for s in input.phys_img.iter_ships() {
// TODO: move collapse sequence here?
let ship_pos; let ship_pos;
let ship_ang; let ship_ang;
let ship_cnt; let ship_cnt;
match ship.get_data().get_state() { match s.ship.get_data().get_state() {
ShipState::Dead | ShipState::Landed { .. } => continue, ShipState::Dead | ShipState::Landed { .. } => continue,
ShipState::Collapsing { .. } | ShipState::Flying { .. } => { ShipState::Collapsing { .. } | ShipState::Flying { .. } => {
let r = input.systemsim.get_rigid_body(ship.rigid_body).unwrap(); let r = &s.rigidbody;
let pos = *r.translation(); let pos = *r.translation();
ship_pos = Point3::new(pos.x, pos.y, 1.0); ship_pos = Point3::new(pos.x, pos.y, 1.0);
let ship_rot = r.rotation(); let ship_rot = r.rotation();
ship_ang = ship_rot.angle(); ship_ang = ship_rot.angle();
ship_cnt = input.ct.get_ship(ship.get_data().get_content()); ship_cnt = input.ct.get_ship(s.ship.get_data().get_content());
} }
ShipState::UnLanding { current_z, .. } | ShipState::Landing { current_z, .. } => { ShipState::UnLanding { current_z, .. } | ShipState::Landing { current_z, .. } => {
let r = input.systemsim.get_rigid_body(ship.rigid_body).unwrap(); let r = &s.rigidbody;
let pos = *r.translation(); let pos = *r.translation();
ship_pos = Point3::new(pos.x, pos.y, *current_z); ship_pos = Point3::new(pos.x, pos.y, *current_z);
let ship_rot = r.rotation(); let ship_rot = r.rotation();
ship_ang = ship_rot.angle(); ship_ang = ship_rot.angle();
ship_cnt = input.ct.get_ship(ship.get_data().get_content()); ship_cnt = input.ct.get_ship(s.ship.get_data().get_content());
} }
} }
@ -85,7 +83,7 @@ impl GPUState {
); );
// Push this object's instance // Push this object's instance
let anim_state = ship.get_anim_state(); let anim_state = s.ship.get_anim_state();
self.state.push_object_buffer(ObjectInstance { self.state.push_object_buffer(ObjectInstance {
texture_index: anim_state.texture_index(), texture_index: anim_state.texture_index(),
texture_fade: anim_state.fade, texture_fade: anim_state.fade,
@ -93,7 +91,7 @@ impl GPUState {
}); });
if { if {
let is_flying = match ship.get_data().get_state() { let is_flying = match s.ship.get_data().get_state() {
ShipState::Flying { .. } ShipState::Flying { .. }
| ShipState::UnLanding { .. } | ShipState::UnLanding { .. }
| ShipState::Landing { .. } => true, | ShipState::Landing { .. } => true,
@ -101,7 +99,7 @@ impl GPUState {
}; };
is_flying is_flying
} { } {
for (engine_point, anim) in ship.iter_engine_anim() { for (engine_point, anim) in s.ship.iter_engine_anim() {
self.state.queue.write_buffer( self.state.queue.write_buffer(
&self.state.global_uniform.object_buffer, &self.state.global_uniform.object_buffer,
ObjectData::SIZE * self.state.get_object_counter() as u64, ObjectData::SIZE * self.state.get_object_counter() as u64,
@ -135,18 +133,18 @@ impl GPUState {
} }
} }
pub(super) fn phys_push_projectile( pub(super) fn phys_push_projectiles(
&mut self, &mut self,
input: &RenderInput, input: &RenderInput,
// NE and SW corners of screen // NE and SW corners of screen
screen_clip: (Point2<f32>, Point2<f32>), screen_clip: (Point2<f32>, Point2<f32>),
) { ) {
for p in input.systemsim.iter_projectiles() { for p in input.phys_img.iter_projectiles() {
let r = input.systemsim.get_rigid_body(p.rigid_body).unwrap(); let r = &p.rigidbody;
let proj_pos = *r.translation(); let proj_pos = *r.translation();
let proj_rot = r.rotation(); let proj_rot = r.rotation();
let proj_ang = proj_rot.angle(); let proj_ang = proj_rot.angle();
let proj_cnt = &p.content; // TODO: don't clone this? let proj_cnt = &p.projectile.content; // TODO: don't clone this?
// Position adjusted for parallax // Position adjusted for parallax
// TODO: adjust parallax for zoom? // TODO: adjust parallax for zoom?
@ -179,14 +177,14 @@ impl GPUState {
ypos: proj_pos.y, ypos: proj_pos.y,
zpos: 1.0, zpos: 1.0,
angle: proj_ang, angle: proj_ang,
size: 0f32.max(proj_cnt.size + p.size_rng), size: 0f32.max(proj_cnt.size + p.projectile.size_rng),
parent: 0, parent: 0,
is_child: 0, is_child: 0,
_padding: Default::default(), _padding: Default::default(),
}]), }]),
); );
let anim_state = p.get_anim_state(); let anim_state = p.projectile.get_anim_state();
self.state.push_object_buffer(ObjectInstance { self.state.push_object_buffer(ObjectInstance {
texture_index: anim_state.texture_index(), texture_index: anim_state.texture_index(),
texture_fade: anim_state.fade, texture_fade: anim_state.fade,
@ -251,4 +249,68 @@ impl GPUState {
}); });
} }
} }
pub(super) fn phys_push_effects(
&mut self,
input: &RenderInput,
// NE and SW corners of screen
screen_clip: (Point2<f32>, Point2<f32>),
) {
for p in input.phys_img.iter_effects() {
let r = &p.rigidbody;
let pos = *r.translation();
let rot = r.rotation();
let ang = rot.angle();
// Position adjusted for parallax
// TODO: adjust parallax for zoom?
// 1.0 is z-coordinate, which is constant for projectiles
let adjusted_pos = (pos - input.camera_pos) / 1.0;
// Game dimensions of this sprite post-scale.
// Post-scale width or height, whichever is larger.
// This is in game units.
//
// We take the maximum to account for rotated sprites.
let m = (p.effect.size / 1.0)
* input
.ct
.get_sprite(p.effect.anim.get_sprite())
.aspect
.max(1.0);
// Don't draw sprites that are off the screen
if adjusted_pos.x < screen_clip.0.x - m
|| adjusted_pos.y > screen_clip.0.y + m
|| adjusted_pos.x > screen_clip.1.x + m
|| adjusted_pos.y < screen_clip.1.y - m
{
continue;
}
let idx = self.state.get_object_counter();
// Write this object's location data
self.state.queue.write_buffer(
&self.state.global_uniform.object_buffer,
ObjectData::SIZE * idx as u64,
bytemuck::cast_slice(&[ObjectData {
xpos: pos.x,
ypos: pos.y,
zpos: 1.0,
angle: ang,
size: p.effect.size,
parent: 0,
is_child: 0,
_padding: Default::default(),
}]),
);
let anim_state = p.effect.anim.get_texture_idx();
self.state.push_object_buffer(ObjectInstance {
texture_index: anim_state.texture_index(),
texture_fade: anim_state.fade,
object_index: idx as u32,
});
}
}
} }

View File

@ -1,17 +1,12 @@
use anyhow::Result; use anyhow::Result;
use bytemuck; use bytemuck;
use galactica_system::{data::ShipState, phys::PhysSimShipHandle}; use galactica_system::{data::ShipState, phys::PhysSimShipHandle};
use galactica_util::constants::PARTICLE_SPRITE_INSTANCE_LIMIT;
use glyphon::Resolution; use glyphon::Resolution;
use nalgebra::Point2; use nalgebra::Point2;
use std::iter; use std::iter;
use wgpu; use wgpu;
use crate::{ use crate::{globaluniform::GlobalDataContent, vertexbuffer::consts::SPRITE_INDICES, RenderInput};
globaluniform::GlobalDataContent,
vertexbuffer::{consts::SPRITE_INDICES, types::ParticleInstance},
RenderInput,
};
impl<'a> super::GPUState { impl<'a> super::GPUState {
/// Render routines while player is flying /// Render routines while player is flying
@ -46,25 +41,6 @@ impl<'a> super::GPUState {
timestamp_writes: None, timestamp_writes: None,
}); });
// Write all new particles to GPU buffer
for i in input.particles.iter() {
let sprite = input.ct.get_sprite(i.sprite);
let texture_a = sprite.get_first_frame(); // ANIMATE
self.state.push_particle_buffer(ParticleInstance {
position: [i.pos.x, i.pos.y],
velocity: i.velocity.into(),
angle: i.angle,
angvel: i.angvel,
size: i.size,
texture_index: [texture_a, texture_a],
texture_fade: 1.0,
created: input.current_time,
expires: input.current_time + i.lifetime,
fade: i.fade,
});
}
// Create sprite instances // Create sprite instances
// Game coordinates (relative to camera) of ne and sw corners of screen. // Game coordinates (relative to camera) of ne and sw corners of screen.
@ -76,8 +52,9 @@ impl<'a> super::GPUState {
// The order inside ships and projectiles doesn't matter, // The order inside ships and projectiles doesn't matter,
// but ships should always be under projectiles. // but ships should always be under projectiles.
self.phys_push_system(&input, (clip_ne, clip_sw)); self.phys_push_system(&input, (clip_ne, clip_sw));
self.phys_push_ship(&input, (clip_ne, clip_sw)); self.phys_push_ships(&input, (clip_ne, clip_sw));
self.phys_push_projectile(&input, (clip_ne, clip_sw)); self.phys_push_projectiles(&input, (clip_ne, clip_sw));
self.phys_push_effects(&input, (clip_ne, clip_sw));
self.ui.draw(&input, &mut self.state); self.ui.draw(&input, &mut self.state);
// These should match the indices in each shader, // These should match the indices in each shader,
@ -109,19 +86,6 @@ impl<'a> super::GPUState {
0..self.state.get_object_counter(), 0..self.state.get_object_counter(),
); );
/*
// Particle pipeline
self.state
.vertex_buffers
.get_particle()
.set_in_pass(&mut render_pass);
render_pass.set_pipeline(&self.particle_pipeline);
render_pass.draw_indexed(
0..SPRITE_INDICES.len() as u32,
0,
0..PARTICLE_SPRITE_INSTANCE_LIMIT as _,
); */
// Ui pipeline // Ui pipeline
self.state self.state
.vertex_buffers .vertex_buffers
@ -319,9 +283,10 @@ impl<'a> super::GPUState {
self.state.frame_reset(); self.state.frame_reset();
match input match input
.systemsim .phys_img
.get_ship(&PhysSimShipHandle(input.player.ship.unwrap())) .get_ship(&PhysSimShipHandle(input.player.ship.unwrap()))
.unwrap() .unwrap()
.ship
.get_data() .get_data()
.get_state() .get_state()
{ {

View File

@ -224,112 +224,6 @@ impl BufferObject for UiInstance {
} }
} }
#[repr(C)]
#[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
pub struct ParticleInstance {
/// World position of this particle
pub position: [f32; 2],
/// Velocity of this particle, in world coordinates
pub velocity: [f32; 2],
/// Angle of this particle, in radians
pub angle: f32,
/// Angular velocity of this particle, rad/sec
pub angvel: f32,
/// The height of this particle, in world units
pub size: f32,
/// The time, in seconds, at which this particle was created.
/// Time is kept by a variable in the global uniform.
pub created: f32,
/// The time, in seconds, at which this particle expires.
/// Time is kept by a variable in the global uniform.
pub expires: f32,
/// Fade this particle out over this many seconds as it expires
pub fade: f32,
/// What texture to use for this particle
pub texture_index: [u32; 2],
/// Fade parameter for texture index
pub texture_fade: f32,
}
impl BufferObject for ParticleInstance {
fn layout() -> wgpu::VertexBufferLayout<'static> {
wgpu::VertexBufferLayout {
array_stride: Self::SIZE,
step_mode: wgpu::VertexStepMode::Instance,
attributes: &[
// Position
wgpu::VertexAttribute {
offset: 0,
shader_location: 2,
format: wgpu::VertexFormat::Float32x2,
},
// Velocity
wgpu::VertexAttribute {
offset: mem::size_of::<[f32; 2]>() as wgpu::BufferAddress,
shader_location: 3,
format: wgpu::VertexFormat::Float32x2,
},
// Angle
wgpu::VertexAttribute {
offset: mem::size_of::<[f32; 4]>() as wgpu::BufferAddress,
shader_location: 4,
format: wgpu::VertexFormat::Float32,
},
// Angvel
wgpu::VertexAttribute {
offset: mem::size_of::<[f32; 5]>() as wgpu::BufferAddress,
shader_location: 5,
format: wgpu::VertexFormat::Float32,
},
// Size
wgpu::VertexAttribute {
offset: mem::size_of::<[f32; 6]>() as wgpu::BufferAddress,
shader_location: 6,
format: wgpu::VertexFormat::Float32,
},
// Created
wgpu::VertexAttribute {
offset: mem::size_of::<[f32; 7]>() as wgpu::BufferAddress,
shader_location: 7,
format: wgpu::VertexFormat::Float32,
},
// Expires
wgpu::VertexAttribute {
offset: mem::size_of::<[f32; 8]>() as wgpu::BufferAddress,
shader_location: 8,
format: wgpu::VertexFormat::Float32,
},
// Fade
wgpu::VertexAttribute {
offset: mem::size_of::<[f32; 9]>() as wgpu::BufferAddress,
shader_location: 9,
format: wgpu::VertexFormat::Float32,
},
// Texture
wgpu::VertexAttribute {
offset: mem::size_of::<[f32; 10]>() as wgpu::BufferAddress,
shader_location: 10,
format: wgpu::VertexFormat::Uint32x2,
},
// Texture fade
wgpu::VertexAttribute {
offset: mem::size_of::<[f32; 12]>() as wgpu::BufferAddress,
shader_location: 11,
format: wgpu::VertexFormat::Float32,
},
],
}
}
}
#[repr(C)] #[repr(C)]
#[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)] #[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
pub struct RadialBarInstance { pub struct RadialBarInstance {