This commit is contained in:
Tsuki 2024-11-15 20:52:43 +08:00
parent e541933ae1
commit 4caf348587
3 changed files with 121 additions and 29 deletions

View File

@ -1,4 +1,6 @@
use crate::elements::{ElementAttach, Elements}; use std::collections::HashMap;
use crate::elements::{ElementAttach, Elements, ElementsRef};
use crate::elementvec::ElementVec; use crate::elementvec::ElementVec;
use wgpu::{Backends, Instance}; use wgpu::{Backends, Instance};
@ -14,6 +16,8 @@ pub struct App {
_texture: wgpu::Texture, _texture: wgpu::Texture,
texture_view: wgpu::TextureView, texture_view: wgpu::TextureView,
pipelines: Option<ElementVec>, pipelines: Option<ElementVec>,
buffer_pool: DataBufferPool,
} }
impl App { impl App {
@ -63,6 +67,9 @@ impl App {
// Create a texture view from the texture. This texture view will be used as the output texture for the render pass. // Create a texture view from the texture. This texture view will be used as the output texture for the render pass.
let texture_view = texture.create_view(&wgpu::TextureViewDescriptor::default()); let texture_view = texture.create_view(&wgpu::TextureViewDescriptor::default());
// Buffer pool
let buffer_pool = DataBufferPool::new();
Self { Self {
device, device,
queue, queue,
@ -70,6 +77,7 @@ impl App {
pipelines: None, pipelines: None,
_texture: texture, _texture: texture,
texture_view, texture_view,
buffer_pool,
} }
} }
@ -165,16 +173,16 @@ impl<'a> Ctx<'a> {
} }
} }
pub struct DrawList<'a> { pub struct DrawList<'b, 'a: 'b> {
pub elements: Vec<(&'a ElementAttach, &'a Elements)>, // 修复字段访问权限 pub elements: Vec<(&'b ElementAttach, ElementsRef<'a>)>, // 修复字段访问权限
} }
impl<'a> DrawList<'a> { impl<'b, 'a: 'b> DrawList<'b, 'a> {
pub fn new() -> Self { pub fn new() -> Self {
Self { elements: vec![] } Self { elements: vec![] }
} }
pub fn push<Ele: Into<&'a Elements>>(&mut self, element: Ele, attach: &'a ElementAttach) { pub fn push<Ele: Into<ElementsRef<'a>>>(&mut self, element: Ele, attach: &'a ElementAttach) {
self.elements.push((attach, element.into())); self.elements.push((attach, element.into()));
} }
} }
@ -239,7 +247,25 @@ impl CommonUtils {
} }
} }
pub struct Elementi {} pub struct DataBufferPool {
buffers: HashMap<BufferKey, wgpu::Buffer>,
}
impl DataBufferPool {
pub fn new() -> Self {
Self {
buffers: HashMap::new(),
}
}
pub fn get_or_create_buffer(&mut self) {}
}
#[derive(Debug, PartialEq, Eq, Hash)]
pub struct BufferKey {
pub size: u64,
pub from: String,
}
mod test { mod test {
use mp_core::{PluginManager, RadarGridData}; use mp_core::{PluginManager, RadarGridData};
@ -257,29 +283,35 @@ mod test {
pollster::block_on(async { pollster::block_on(async {
let mut app = App::instant().await; let mut app = App::instant().await;
app.init().await;
let pipelines = app.pipelines();
let ctx = app.ctx();
let ppi = pipelines.ppi();
if let Ok(data) = data { if let Ok(data) = data {
let first_block = data.first().unwrap(); let first_block = data.first().unwrap();
if let Ok(data) = <&mp_core::Data as TryInto<&RadarGridData>>::try_into(first_block) // Convert the first block into a PPI struct.
{ if let Ok(data) = first_block.try_into() {
let buffer_pool = &mut app.buffer_pool;
// Reused buffer is None, so a new attachment is created.
let attachment = ppi.new_attachment(&ctx, buffer_pool);
// Load the data into the attachment.
ppi.load_data(&ctx, data, &attachment);
// Create a new draw list and push the attachment into it.
let mut draw_list = DrawList::new();
draw_list.push(ppi, &attachment);
// Draw the elements in the draw list.
app.draw(draw_list);
} }
} else {
panic!("Failed to load data");
} }
// app.init().await;
// let pipelines = app.pipelines();
// let ppi = pipelines.ppi();
// let ctx = app.ctx();
// let attachment = ppi.new_attachment(&ctx);
// ppi.bake()
// attachment.update_data(&ctx, data);
// let mut draw_list = DrawList::new();
// draw_list.push(pipelines.ppi());
}) })
} }
} }

View File

@ -1,5 +1,5 @@
pub mod ppi; pub mod ppi;
use crate::app::Ctx; use crate::app::{Ctx, DataBufferPool};
pub use ppi::PPI; pub use ppi::PPI;
use std::any::Any; use std::any::Any;
use wgpu::util::DeviceExt; use wgpu::util::DeviceExt;
@ -10,12 +10,22 @@ macro_rules! elements {
$($element_name($element),)+ $($element_name($element),)+
} }
pub enum ElementsRef<'a> {
$($element_name(&'a $element),)+
}
$( $(
impl From<$element> for Elements { impl From<$element> for Elements {
fn from(element: $element) -> Self { fn from(element: $element) -> Self {
Elements::$element_name(element) Elements::$element_name(element)
} }
} }
impl<'a> From<&'a $element> for ElementsRef<'a> {
fn from(element: &'a $element) -> Self {
ElementsRef::$element_name(element)
}
}
)+ )+
impl Elements { impl Elements {
@ -32,6 +42,20 @@ macro_rules! elements {
} }
} }
impl<'a> ElementsRef<'a> {
pub fn pipeline(&'a self) -> &wgpu::RenderPipeline {
match self {
$(ElementsRef::$element_name(element) => element.pipeline(),)+
}
}
pub fn draw(&'a self, attach: &ElementAttach, render_pass: &mut wgpu::RenderPass) {
match self {
$(ElementsRef::$element_name(element) => element.draw(attach, render_pass),)+
}
}
}
}; };
} }
@ -42,7 +66,7 @@ pub trait Element {
fn new(ctx: &Ctx) -> Self; fn new(ctx: &Ctx) -> Self;
fn new_attachment(&self, ctx: &Ctx) -> ElementAttach; fn new_attachment<'a>(&self, ctx: &Ctx, buffer_pool: &'a mut DataBufferPool) -> ElementAttach;
// Bake the data into vertices and indices // Bake the data into vertices and indices
fn bake(&self, data: &Self::Data) -> (Vec<Self::Vertex>, Option<Vec<u32>>); fn bake(&self, data: &Self::Data) -> (Vec<Self::Vertex>, Option<Vec<u32>>);
@ -54,6 +78,8 @@ pub trait Element {
fn pipeline(&self) -> &wgpu::RenderPipeline; fn pipeline(&self) -> &wgpu::RenderPipeline;
fn draw(&self, attach: &ElementAttach, render_pass: &mut wgpu::RenderPass); fn draw(&self, attach: &ElementAttach, render_pass: &mut wgpu::RenderPass);
fn load_data(&self, ctx: &Ctx, data: &Self::Data, attach: &ElementAttach);
} }
pub struct ElementAttach { pub struct ElementAttach {

View File

@ -1,6 +1,9 @@
use std::ops::Sub; use std::{ops::Sub, result};
use crate::{app::Ctx, utils::merge_shader}; use crate::{
app::{Ctx, DataBufferPool},
utils::merge_shader,
};
use bytemuck; use bytemuck;
use glam::Vec3; use glam::Vec3;
use mp_core::{data::CoordType, RadarGridData}; use mp_core::{data::CoordType, RadarGridData};
@ -152,11 +155,18 @@ impl Element for PPI {
} }
} }
fn new_attachment(&self, ctx: &Ctx) -> ElementAttach { fn new_attachment<'a>(&self, ctx: &Ctx, buffer_pool: &'a mut DataBufferPool) -> ElementAttach {
let device = ctx.device; let device = ctx.device;
// Buffers // Buffers
let data_buffer = Self::create_data_buffer(device);
let data_buffer = buffer_pool.get_or_create_buffer();
// let data_buffer = if let Some(reused) = reused_buffer {
// reused[0]
// } else {
// &Self::create_data_buffer(device)
// };
let uniform_buffer = Self::create_uniform_buffer(device); let uniform_buffer = Self::create_uniform_buffer(device);
// Bind Group // Bind Group
@ -229,6 +239,30 @@ impl Element for PPI {
fn draw(&self, attach: &ElementAttach, render_pass: &mut wgpu::RenderPass) { fn draw(&self, attach: &ElementAttach, render_pass: &mut wgpu::RenderPass) {
render_pass.draw_indexed(0..attach.num_indices, 0, 0..1); render_pass.draw_indexed(0..attach.num_indices, 0, 0..1);
} }
fn load_data(&self, ctx: &Ctx, data: &Self::Data, attach: &ElementAttach) {
let (vertex, index) = self.bake(data);
let queue = ctx.queue;
// Update Vertex Buffer
let vertex_buffer = &attach.vertex_buffer;
queue.write_buffer(vertex_buffer, 0, bytemuck::cast_slice(&vertex));
// Update Index Buffer
if let Some(indices) = index {
let index_buffer = attach.index_buffer.as_ref().unwrap();
queue.write_buffer(index_buffer, 0, bytemuck::cast_slice(&indices));
}
// Load Data
let data_array = data.get_data();
let data_array_f32 = data_array.cast_to::<f32>();
queue.write_buffer(
data_buffer,
0,
bytemuck::cast_slice(data_array_f32.as_slice().unwrap()),
);
}
} }
impl PPI { impl PPI {