ECS + mesh instances
This commit is contained in:
parent
314e842dc1
commit
a9c80760ab
|
@ -4,5 +4,7 @@ version = "0.1.0"
|
|||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
glam = "0.20"
|
||||
legion = "0.4.0"
|
||||
rayon = "1"
|
||||
strum = { version = "0.24", features = ["derive"] }
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
|
||||
pub struct MeshHandle {
|
||||
pub group_id: usize,
|
||||
pub sub_id: usize,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
|
||||
pub struct TextureHandle {
|
||||
pub id: usize,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
|
||||
pub struct MaterialHandle {
|
||||
pub id: usize,
|
||||
}
|
|
@ -5,8 +5,10 @@ use rayon::prelude::*;
|
|||
use std::sync::{Arc, RwLock};
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
pub mod handle;
|
||||
pub mod pass;
|
||||
pub mod phase;
|
||||
pub mod scene;
|
||||
|
||||
use pass::*;
|
||||
use phase::*;
|
||||
|
|
33
src/main.rs
33
src/main.rs
|
@ -1,9 +1,32 @@
|
|||
use cyborg::{pass, Renderer};
|
||||
use cyborg::{pass, scene, Renderer};
|
||||
use legion::{IntoSoa, World};
|
||||
use std::sync::{Arc, RwLock};
|
||||
|
||||
fn main() {
|
||||
let mut renderer = Renderer::default();
|
||||
let mesh_pass = pass::mesh::MeshPass::new();
|
||||
renderer.add_pass(mesh_pass);
|
||||
let world = Arc::new(RwLock::new(World::default()));
|
||||
|
||||
renderer.render();
|
||||
world.write().unwrap().extend(
|
||||
(
|
||||
vec![scene::MeshComponent {}; 1000],
|
||||
vec![
|
||||
scene::TransformComponent {
|
||||
transform: glam::Mat4::IDENTITY,
|
||||
};
|
||||
1000
|
||||
],
|
||||
)
|
||||
.into_soa(),
|
||||
);
|
||||
|
||||
let mut renderer = Renderer::default();
|
||||
let mesh_pass = pass::mesh::MeshPass::new(world);
|
||||
renderer.add_pass_arc(mesh_pass);
|
||||
|
||||
let start = std::time::Instant::now();
|
||||
for n in 0..1000 {
|
||||
println!("Frame #{}:", n);
|
||||
renderer.render();
|
||||
}
|
||||
|
||||
println!("Time elapsed: {:?}", start.elapsed());
|
||||
}
|
||||
|
|
|
@ -1,12 +1,32 @@
|
|||
use super::*;
|
||||
use crate::scene;
|
||||
use legion::{Query, World};
|
||||
use std::sync::{Arc, Mutex, RwLock};
|
||||
|
||||
pub struct FrameData {}
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct MeshInstance {
|
||||
// TODO put useful data in here
|
||||
mesh: scene::MeshComponent,
|
||||
transform: scene::TransformComponent,
|
||||
}
|
||||
|
||||
pub struct MeshPass {}
|
||||
#[derive(Debug, Default)]
|
||||
pub struct FrameData {
|
||||
meshes: Vec<MeshInstance>,
|
||||
}
|
||||
|
||||
pub struct MeshPass {
|
||||
world: Arc<RwLock<World>>,
|
||||
mesh_query: Query<(
|
||||
&'static scene::MeshComponent,
|
||||
&'static scene::TransformComponent,
|
||||
)>,
|
||||
}
|
||||
|
||||
impl MeshPass {
|
||||
pub fn new() -> Self {
|
||||
Self {}
|
||||
pub fn new(world: Arc<RwLock<World>>) -> Arc<RwLock<Self>> {
|
||||
let mesh_query = Query::new();
|
||||
Arc::new(RwLock::new(Self { world, mesh_query }))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,17 +34,31 @@ impl RenderPass for MeshPass {
|
|||
type FrameData = FrameData;
|
||||
|
||||
fn create_frame_data(&mut self) -> FrameData {
|
||||
FrameData {}
|
||||
FrameData::default()
|
||||
}
|
||||
|
||||
fn begin_frame(&mut self, data: &mut FrameData, phases: &mut PhaseList) {
|
||||
println!("MeshPass::begin_frame()");
|
||||
|
||||
phases.insert_pre(PrePhase::VertexSkinning);
|
||||
|
||||
phases.insert_viewport(ViewportPhase::Depth);
|
||||
phases.insert_viewport(ViewportPhase::Opaque);
|
||||
phases.insert_viewport(ViewportPhase::Transparent);
|
||||
|
||||
let world = self.world.read().unwrap();
|
||||
let meshes = Mutex::new(Vec::new());
|
||||
self.mesh_query.par_for_each_chunk(&*world, |chunk| {
|
||||
let chunk_meshes: Vec<MeshInstance> = chunk
|
||||
.into_iter()
|
||||
.map(|(mesh, transform)| MeshInstance {
|
||||
mesh: mesh.to_owned(),
|
||||
transform: transform.to_owned(),
|
||||
})
|
||||
.collect();
|
||||
meshes.lock().unwrap().extend_from_slice(&chunk_meshes);
|
||||
});
|
||||
|
||||
data.meshes = meshes.into_inner().unwrap();
|
||||
}
|
||||
|
||||
fn render_pre(&self, phase: PrePhase, data: &FrameData, cmds: &mut gpu::RenderBundleEncoder) {
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
use crate::handle;
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub struct MeshComponent {
|
||||
// TODO resource pools
|
||||
// pub mesh_handle: handle::MeshHandle,
|
||||
// pub material_handle: handle::MaterialHandle,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub struct PointLightComponent {
|
||||
pub intensity: glam::Vec3A,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub struct PositionComponent {
|
||||
pub position: glam::Vec3A,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub struct OrientationComponent {
|
||||
pub orientation: glam::Quat,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub struct TransformComponent {
|
||||
pub transform: glam::Mat4,
|
||||
}
|
Loading…
Reference in New Issue