Galactica/crates/render/src/renderstate.rs

199 lines
5.2 KiB
Rust
Raw Normal View History

2024-01-17 10:17:18 -08:00
use galactica_content::Content;
2024-02-02 22:32:03 -08:00
use galactica_util::constants::{OBJECT_SPRITE_INSTANCE_LIMIT, UI_SPRITE_INSTANCE_LIMIT};
2024-01-17 10:17:18 -08:00
use glyphon::{FontSystem, SwashCache, TextAtlas, TextRenderer};
use std::rc::Rc;
use wgpu::BufferAddress;
use winit::window::Window;
use crate::{
globaluniform::GlobalUniform,
vertexbuffer::{
consts::{SPRITE_INDICES, SPRITE_VERTICES},
2024-01-23 15:53:50 -08:00
types::{ObjectInstance, RadialBarInstance, StarfieldInstance, TexturedVertex, UiInstance},
2024-01-17 10:17:18 -08:00
BufferObject, VertexBuffer,
},
};
/// Vertex buffers
pub(crate) struct VertexBuffers {
// Keeps track of length of each buffer
// Most of these are reset on each frame.
object_counter: BufferAddress,
ui_counter: BufferAddress,
radialbar_counter: BufferAddress,
starfield_counter: BufferAddress,
starfield_limit: BufferAddress,
object: Rc<VertexBuffer>,
starfield: Rc<VertexBuffer>,
ui: Rc<VertexBuffer>,
radialbar: Rc<VertexBuffer>,
}
impl<'a> VertexBuffers {
pub fn new(device: &wgpu::Device, ct: &Content) -> Self {
Self {
object_counter: 0,
ui_counter: 0,
radialbar_counter: 0,
starfield_counter: 0,
starfield_limit: ct.get_config().starfield_instance_limit,
object: Rc::new(VertexBuffer::new::<TexturedVertex, ObjectInstance>(
"object",
&device,
Some(SPRITE_VERTICES),
Some(SPRITE_INDICES),
OBJECT_SPRITE_INSTANCE_LIMIT,
)),
starfield: Rc::new(VertexBuffer::new::<TexturedVertex, StarfieldInstance>(
"starfield",
&device,
Some(SPRITE_VERTICES),
Some(SPRITE_INDICES),
ct.get_config().starfield_instance_limit,
)),
ui: Rc::new(VertexBuffer::new::<TexturedVertex, UiInstance>(
"ui",
&device,
Some(SPRITE_VERTICES),
Some(SPRITE_INDICES),
UI_SPRITE_INSTANCE_LIMIT,
)),
radialbar: Rc::new(VertexBuffer::new::<TexturedVertex, RadialBarInstance>(
"radial bar",
&device,
Some(SPRITE_VERTICES),
Some(SPRITE_INDICES),
10,
)),
}
}
pub fn get_ui(&'a self) -> &'a Rc<VertexBuffer> {
&self.ui
}
pub fn get_object(&'a self) -> &'a Rc<VertexBuffer> {
&self.object
}
pub fn get_radialbar(&'a self) -> &'a Rc<VertexBuffer> {
&self.radialbar
}
pub fn get_starfield(&'a self) -> &'a Rc<VertexBuffer> {
&self.starfield
}
}
/// Renderer state. A reference to this struct is often passed to helper functions.
pub(crate) struct RenderState {
pub window: Window,
pub window_size: winit::dpi::PhysicalSize<u32>,
pub window_aspect: f32,
pub queue: wgpu::Queue,
pub global_uniform: GlobalUniform,
pub vertex_buffers: VertexBuffers,
pub text_font_system: FontSystem,
pub text_cache: SwashCache,
pub text_atlas: TextAtlas,
pub text_renderer: TextRenderer,
}
impl RenderState {
/// Prepare this state for a new frame
pub fn frame_reset(&mut self) {
self.vertex_buffers.object_counter = 0;
self.vertex_buffers.ui_counter = 0;
self.vertex_buffers.radialbar_counter = 0
}
pub fn push_ui_buffer(&mut self, instance: UiInstance) {
// Enforce buffer limit
if self.vertex_buffers.ui_counter as u64 > UI_SPRITE_INSTANCE_LIMIT {
// TODO: no panic, handle this better.
panic!("UI limit exceeded!")
}
self.queue.write_buffer(
&self.vertex_buffers.ui.instances,
UiInstance::SIZE * self.vertex_buffers.ui_counter,
bytemuck::cast_slice(&[instance]),
);
self.vertex_buffers.ui_counter += 1;
}
pub fn get_ui_counter(&self) -> u32 {
self.vertex_buffers.ui_counter as u32
}
pub fn push_object_buffer(&mut self, instance: ObjectInstance) {
// Enforce buffer limit
if self.vertex_buffers.object_counter as u64 > OBJECT_SPRITE_INSTANCE_LIMIT {
// TODO: no panic, handle this better.
panic!("Object limit exceeded!")
}
self.queue.write_buffer(
&self.vertex_buffers.object.instances,
ObjectInstance::SIZE * self.vertex_buffers.object_counter,
bytemuck::cast_slice(&[instance]),
);
self.vertex_buffers.object_counter += 1;
}
pub fn get_object_counter(&self) -> u32 {
self.vertex_buffers.object_counter as u32
}
2024-02-02 22:32:03 -08:00
/*
2024-01-17 10:17:18 -08:00
pub fn push_radialbar_buffer(&mut self, instance: RadialBarInstance) {
// Enforce buffer limit
if self.vertex_buffers.radialbar_counter as u64 > RADIALBAR_SPRITE_INSTANCE_LIMIT {
// TODO: no panic, handle this better.
panic!("Radialbar sprite limit exceeded!")
}
self.queue.write_buffer(
&self.vertex_buffers.radialbar.instances,
RadialBarInstance::SIZE * self.vertex_buffers.radialbar_counter,
bytemuck::cast_slice(&[instance]),
);
self.vertex_buffers.radialbar_counter += 1;
}
2024-02-02 22:32:03 -08:00
*/
2024-01-17 10:17:18 -08:00
pub fn get_radialbar_counter(&self) -> u32 {
self.vertex_buffers.radialbar_counter as u32
}
pub fn reset_starfield_counter(&mut self) {
self.vertex_buffers.starfield_counter = 0;
}
pub fn push_starfield_buffer(&mut self, instance: StarfieldInstance) {
// Enforce buffer limit
// This should never happen, since starfield generator checks array size
if self.vertex_buffers.starfield_counter as u64 > self.vertex_buffers.starfield_limit {
panic!("Starfield sprite limit exceeded!")
}
self.queue.write_buffer(
&self.vertex_buffers.starfield.instances,
StarfieldInstance::SIZE * self.vertex_buffers.starfield_counter,
bytemuck::cast_slice(&[instance]),
);
self.vertex_buffers.starfield_counter += 1;
}
pub fn get_starfield_counter(&self) -> u32 {
self.vertex_buffers.starfield_counter as u32
}
}