206 lines
5.8 KiB
Rust
206 lines
5.8 KiB
Rust
//! GPUState routines for drawing the world
|
|
|
|
use bytemuck;
|
|
use cgmath::{EuclideanSpace, InnerSpace, Point2, Vector2};
|
|
use galactica_world::{
|
|
objects::{ProjectileWorldObject, ShipWorldObject},
|
|
util,
|
|
};
|
|
|
|
use crate::{
|
|
globaluniform::ObjectData,
|
|
vertexbuffer::{types::ObjectInstance, BufferObject},
|
|
GPUState, RenderState,
|
|
};
|
|
|
|
impl GPUState {
|
|
pub(super) fn world_push_ship(
|
|
&mut self,
|
|
state: &RenderState,
|
|
// NE and SW corners of screen
|
|
screen_clip: (Point2<f32>, Point2<f32>),
|
|
s: &ShipWorldObject,
|
|
) {
|
|
let r = state.world.get_rigid_body(s.rigid_body).unwrap();
|
|
let ship = state.data.get_ship(s.data_handle);
|
|
let ship_pos = util::rigidbody_position(&r);
|
|
let ship_rot = util::rigidbody_rotation(r);
|
|
let ship_ang = -ship_rot.angle(Vector2 { x: 0.0, y: 1.0 }); // TODO: inconsistent angles. Fix!
|
|
let ship_cnt = state.content.get_ship(s.data_handle.content_handle());
|
|
|
|
// Position adjusted for parallax
|
|
// TODO: adjust parallax for zoom?
|
|
// 1.0 is z-coordinate, which is constant for ships
|
|
let pos: Point2<f32> = (ship_pos - state.camera_pos.to_vec()) / 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 = (ship_cnt.size / 1.0) * ship_cnt.sprite.aspect.max(1.0);
|
|
|
|
// Don't draw sprites that are off the screen
|
|
if pos.x < screen_clip.0.x - m
|
|
|| pos.y > screen_clip.0.y + m
|
|
|| pos.x > screen_clip.1.x + m
|
|
|| pos.y < screen_clip.1.y - m
|
|
{
|
|
return;
|
|
}
|
|
|
|
let idx = self.vertex_buffers.object_counter;
|
|
// Write this object's location data
|
|
self.queue.write_buffer(
|
|
&self.global_uniform.object_buffer,
|
|
ObjectData::SIZE * idx as u64,
|
|
bytemuck::cast_slice(&[ObjectData {
|
|
xpos: ship_pos.x,
|
|
ypos: ship_pos.y,
|
|
zpos: 1.0,
|
|
angle: ship_ang.0,
|
|
size: ship_cnt.size,
|
|
parent: 0,
|
|
is_child: 0,
|
|
_padding: Default::default(),
|
|
}]),
|
|
);
|
|
|
|
// Enforce buffer limit
|
|
if self.vertex_buffers.object_counter as u64
|
|
> galactica_constants::OBJECT_SPRITE_INSTANCE_LIMIT
|
|
{
|
|
// TODO: no panic, handle this better.
|
|
panic!("Sprite limit exceeded!")
|
|
}
|
|
|
|
// Push this object's instance
|
|
self.queue.write_buffer(
|
|
&self.vertex_buffers.object.instances,
|
|
ObjectInstance::SIZE * self.vertex_buffers.object_counter,
|
|
bytemuck::cast_slice(&[ObjectInstance {
|
|
sprite_index: ship_cnt.sprite.get_index(),
|
|
object_index: idx as u32,
|
|
}]),
|
|
);
|
|
self.vertex_buffers.object_counter += 1;
|
|
|
|
/*
|
|
// Draw engine flares if necessary
|
|
//if s.controls.thrust && !s.ship.is_dead() {
|
|
if s.controls.thrust {
|
|
for f in s.ship.outfits.iter_enginepoints() {
|
|
let flare = match s.ship.outfits.get_flare_sprite() {
|
|
None => continue,
|
|
Some(s) => s,
|
|
};
|
|
|
|
self.queue.write_buffer(
|
|
&self.global_uniform.object_buffer,
|
|
ObjectData::SIZE * self.vertex_buffers.object_counter as u64,
|
|
bytemuck::cast_slice(&[ObjectData {
|
|
xpos: f.pos.x,
|
|
ypos: f.pos.y - f.size / 2.0,
|
|
zpos: 1.0,
|
|
angle: 0.0,
|
|
size: f.size,
|
|
parent: idx as u32,
|
|
is_child: 1,
|
|
_padding: Default::default(),
|
|
}]),
|
|
);
|
|
|
|
// Enforce buffer limit
|
|
if self.vertex_buffers.object_counter as u64
|
|
> galactica_constants::OBJECT_SPRITE_INSTANCE_LIMIT
|
|
{
|
|
// TODO: no panic, handle this better.
|
|
panic!("Sprite limit exceeded!")
|
|
}
|
|
|
|
self.queue.write_buffer(
|
|
&self.vertex_buffers.object.instances,
|
|
ObjectInstance::SIZE * self.vertex_buffers.object_counter,
|
|
bytemuck::cast_slice(&[ObjectInstance {
|
|
sprite_index: flare.get_index(),
|
|
object_index: self.vertex_buffers.object_counter as u32,
|
|
}]),
|
|
);
|
|
self.vertex_buffers.object_counter += 1;
|
|
}
|
|
}
|
|
*/
|
|
}
|
|
|
|
pub(super) fn world_push_projectile(
|
|
&mut self,
|
|
state: &RenderState,
|
|
// NE and SW corners of screen
|
|
screen_clip: (Point2<f32>, Point2<f32>),
|
|
p: &ProjectileWorldObject,
|
|
) {
|
|
let r = state.world.get_rigid_body(p.rigid_body).unwrap();
|
|
let proj_pos = util::rigidbody_position(&r);
|
|
let proj_rot = util::rigidbody_rotation(r);
|
|
let proj_ang = -proj_rot.angle(Vector2 { x: 1.0, y: 0.0 });
|
|
let proj_cnt = &p.content; // TODO: don't clone this?
|
|
|
|
// Position adjusted for parallax
|
|
// TODO: adjust parallax for zoom?
|
|
// 1.0 is z-coordinate, which is constant for ships
|
|
let pos: Point2<f32> = (proj_pos - state.camera_pos.to_vec()) / 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 = (proj_cnt.size / 1.0) * proj_cnt.sprite.aspect.max(1.0);
|
|
|
|
// Don't draw sprites that are off the screen
|
|
if pos.x < screen_clip.0.x - m
|
|
|| pos.y > screen_clip.0.y + m
|
|
|| pos.x > screen_clip.1.x + m
|
|
|| pos.y < screen_clip.1.y - m
|
|
{
|
|
return;
|
|
}
|
|
|
|
let idx = self.vertex_buffers.object_counter;
|
|
// Write this object's location data
|
|
self.queue.write_buffer(
|
|
&self.global_uniform.object_buffer,
|
|
ObjectData::SIZE * idx as u64,
|
|
bytemuck::cast_slice(&[ObjectData {
|
|
xpos: proj_pos.x,
|
|
ypos: proj_pos.y,
|
|
zpos: 1.0,
|
|
angle: proj_ang.0,
|
|
size: 0f32.max(proj_cnt.size + p.size_rng),
|
|
parent: 0,
|
|
is_child: 0,
|
|
_padding: Default::default(),
|
|
}]),
|
|
);
|
|
|
|
// Enforce buffer limit
|
|
if self.vertex_buffers.object_counter as u64
|
|
> galactica_constants::OBJECT_SPRITE_INSTANCE_LIMIT
|
|
{
|
|
// TODO: no panic, handle this better.
|
|
panic!("Sprite limit exceeded!")
|
|
}
|
|
|
|
// Push this object's instance
|
|
self.queue.write_buffer(
|
|
&self.vertex_buffers.object.instances,
|
|
ObjectInstance::SIZE * self.vertex_buffers.object_counter,
|
|
bytemuck::cast_slice(&[ObjectInstance {
|
|
sprite_index: proj_cnt.sprite.get_index(),
|
|
object_index: idx as u32,
|
|
}]),
|
|
);
|
|
self.vertex_buffers.object_counter += 1;
|
|
}
|
|
}
|