mirror of
https://github.com/bevyengine/bevy
synced 2024-11-24 21:53:07 +00:00
fix asset loading. no more temp!
This commit is contained in:
parent
a96f3cfda5
commit
3922c76efe
14 changed files with 121 additions and 80 deletions
|
@ -1,9 +1,40 @@
|
|||
use bevy::{Application};
|
||||
use legion::prelude::*;
|
||||
use bevy::*;
|
||||
use bevy::{render::*, asset::{Asset, AssetStorage}, math};
|
||||
|
||||
fn main() {
|
||||
// Create a world to store our entities
|
||||
let universe = Universe::new();
|
||||
let mut world = universe.create_world();
|
||||
// Create a query which finds all `Position` and `Velocity` components
|
||||
// let mut query = Read::<Transform>::query();
|
||||
let cube = Mesh::load(MeshType::Cube);
|
||||
let plane = Mesh::load(MeshType::Plane{ size: 10 });
|
||||
let mut mesh_storage = AssetStorage::<Mesh, MeshType>::new();
|
||||
|
||||
// this currently breaks because Arcs cant be modified after they are cloned :(
|
||||
let mesh_handle = mesh_storage.add(cube);
|
||||
let plane_handle = mesh_storage.add(plane);
|
||||
world.resources.insert(mesh_storage);
|
||||
|
||||
world.insert((), vec![
|
||||
(
|
||||
Material { color: math::vec4(0.1, 0.6, 0.1, 1.0), bind_group: None, uniform_buf: None },
|
||||
plane_handle.clone(),
|
||||
LocalToWorld(math::translation(&math::vec3(0.0, 0.0, 0.0))),
|
||||
Translation::new(0.0, 0.0, 0.0)
|
||||
),
|
||||
(
|
||||
Material { color: math::vec4(0.1, 0.1, 0.6, 1.0), bind_group: None, uniform_buf: None },
|
||||
mesh_handle.clone(),
|
||||
LocalToWorld(math::translation(&math::vec3(3.0, 0.0, 0.0))),
|
||||
Translation::new(0.0, 0.0, 0.0)
|
||||
),
|
||||
(
|
||||
Material { color: math::vec4(0.6, 0.1, 0.1, 1.0), bind_group: None, uniform_buf: None },
|
||||
mesh_handle,
|
||||
LocalToWorld::identity(),
|
||||
Translation::new(0.0, 0.0, 0.0)
|
||||
),
|
||||
]);
|
||||
|
||||
Application::run(universe, world);
|
||||
}
|
|
@ -10,7 +10,7 @@ use legion::prelude::*;
|
|||
use std::sync::Arc;
|
||||
use std::mem;
|
||||
|
||||
use crate::{temp::*, vertex::*, render::*, math, LocalToWorld, Translation, ApplicationStage};
|
||||
use crate::{vertex::*, render::*, math, LocalToWorld, ApplicationStage};
|
||||
|
||||
pub struct Application
|
||||
{
|
||||
|
@ -45,9 +45,9 @@ impl Application {
|
|||
});
|
||||
|
||||
|
||||
let mut entities = <Write<CubeEnt>>::query();
|
||||
let mut entities = <Write<Material>>::query();
|
||||
for mut entity in entities.iter(&mut world) {
|
||||
let entity_uniform_size = mem::size_of::<EntityUniforms>() as wgpu::BufferAddress;
|
||||
let entity_uniform_size = mem::size_of::<MaterialUniforms>() as wgpu::BufferAddress;
|
||||
let uniform_buf = device.create_buffer(&wgpu::BufferDescriptor {
|
||||
size: entity_uniform_size,
|
||||
usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST,
|
||||
|
@ -204,9 +204,9 @@ impl Application {
|
|||
device.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 });
|
||||
|
||||
{
|
||||
let mut entities = <(Read<CubeEnt>, Read<LocalToWorld>)>::query();
|
||||
let mut entities = <(Read<Material>, Read<LocalToWorld>)>::query();
|
||||
let entities_count = entities.iter(&mut self.world).count();
|
||||
let size = mem::size_of::<EntityUniforms>();
|
||||
let size = mem::size_of::<MaterialUniforms>();
|
||||
let temp_buf_data = device
|
||||
.create_buffer_mapped(entities_count * size, wgpu::BufferUsage::COPY_SRC);
|
||||
|
||||
|
@ -214,7 +214,7 @@ impl Application {
|
|||
.zip(temp_buf_data.data.chunks_exact_mut(size))
|
||||
{
|
||||
slot.copy_from_slice(
|
||||
EntityUniforms {
|
||||
MaterialUniforms {
|
||||
model: transform.0.into(),
|
||||
color: [
|
||||
entity.color.x as f32,
|
||||
|
|
|
@ -1,10 +1,20 @@
|
|||
use std::{sync::Arc, marker::PhantomData, ops::Drop};
|
||||
use std::{sync::{Arc, RwLock}, marker::PhantomData, ops::Drop};
|
||||
|
||||
pub struct Handle<T>
|
||||
{
|
||||
pub id: Arc<usize>,
|
||||
pub id: Arc<RwLock<usize>>,
|
||||
marker: PhantomData<T>,
|
||||
free_indices: Arc<Vec<usize>>
|
||||
free_indices: Arc<RwLock<Vec<usize>>>
|
||||
}
|
||||
|
||||
impl<T> Clone for Handle<T> {
|
||||
fn clone(&self) -> Self {
|
||||
Handle {
|
||||
id: self.id.clone(),
|
||||
free_indices: self.free_indices.clone(),
|
||||
marker: PhantomData
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Drop for Handle<T> {
|
||||
|
@ -12,7 +22,8 @@ impl<T> Drop for Handle<T> {
|
|||
// TODO: Maybe this should be 1
|
||||
// TODO: Is this even necessary?
|
||||
if Arc::strong_count(&self.id) == 0 {
|
||||
Arc::get_mut(&mut self.free_indices).unwrap().push(*self.id);
|
||||
let id = *self.id.read().unwrap();
|
||||
self.free_indices.write().unwrap().push(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +34,7 @@ pub trait Asset<D> {
|
|||
|
||||
pub struct AssetStorage<T, D> where T: Asset<D> {
|
||||
assets: Vec<Option<T>>,
|
||||
free_indices: Arc<Vec<usize>>,
|
||||
free_indices: Arc<RwLock<Vec<usize>>>,
|
||||
marker: PhantomData<D>,
|
||||
}
|
||||
|
||||
|
@ -31,17 +42,17 @@ impl<T, D> AssetStorage<T, D> where T: Asset<D> {
|
|||
pub fn new() -> AssetStorage<T, D> {
|
||||
AssetStorage {
|
||||
assets: Vec::new(),
|
||||
free_indices: Arc::new(Vec::new()),
|
||||
free_indices: Arc::new(RwLock::new(Vec::new())),
|
||||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add(&mut self, asset: T) -> Handle<T> {
|
||||
match Arc::get_mut(&mut self.free_indices).unwrap().pop() {
|
||||
match self.free_indices.write().unwrap().pop() {
|
||||
Some(id) => {
|
||||
self.assets[id as usize] = Some(asset);
|
||||
Handle {
|
||||
id: Arc::new(id),
|
||||
id: Arc::new(RwLock::new(id)),
|
||||
marker: PhantomData,
|
||||
free_indices: self.free_indices.clone()
|
||||
}
|
||||
|
@ -49,7 +60,7 @@ impl<T, D> AssetStorage<T, D> where T: Asset<D> {
|
|||
None => {
|
||||
self.assets.push(Some(asset));
|
||||
Handle {
|
||||
id: Arc::new(self.assets.len() - 1),
|
||||
id: Arc::new(RwLock::new(self.assets.len() - 1)),
|
||||
marker: PhantomData,
|
||||
free_indices: self.free_indices.clone()
|
||||
}
|
||||
|
|
|
@ -218,6 +218,7 @@ pub fn build(_: &mut World) -> Box<dyn Schedulable> {
|
|||
});
|
||||
|
||||
// Just to issue warnings: Scale + NonUniformScale
|
||||
#[allow(unused_unsafe)]
|
||||
unsafe {
|
||||
l.iter_entities_immutable(world).for_each(
|
||||
|(entity, (mut _ltw, _scale, _non_uniform_scale))| {
|
||||
|
|
|
@ -2,7 +2,6 @@ pub mod render;
|
|||
pub mod asset;
|
||||
mod application;
|
||||
mod vertex;
|
||||
pub mod temp;
|
||||
mod core;
|
||||
|
||||
pub use application::Application;
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
use crate::math;
|
||||
|
||||
pub struct Camera {
|
||||
projection: math::Mat4,
|
||||
}
|
||||
|
||||
pub fn get_projection_view_matrix(eye: &math::Vec3, fov: f32, aspect_ratio: f32, near: f32, far: f32) -> math::Mat4 {
|
||||
let projection = math::perspective(aspect_ratio, fov, near, far);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{render::*, temp::*, asset::*, render::mesh::*};
|
||||
use crate::{render::*, asset::*, render::mesh::*};
|
||||
use legion::prelude::*;
|
||||
use std::{mem, sync::Arc};
|
||||
use zerocopy::{AsBytes, FromBytes};
|
||||
|
@ -21,7 +21,7 @@ pub struct ForwardPass {
|
|||
|
||||
impl Pass for ForwardPass {
|
||||
fn render(&mut self, device: &Device, frame: &SwapChainOutput, encoder: &mut CommandEncoder, world: &mut World) {
|
||||
let mut mesh_query = <(Read<CubeEnt>, Read<Handle<Mesh>>)>::query();
|
||||
let mut mesh_query = <(Read<Material>, Read<Handle<Mesh>>)>::query();
|
||||
let mut pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||
color_attachments: &[wgpu::RenderPassColorAttachmentDescriptor {
|
||||
attachment: &frame.view,
|
||||
|
@ -50,7 +50,7 @@ impl Pass for ForwardPass {
|
|||
|
||||
let mut mesh_storage = world.resources.get_mut::<AssetStorage<Mesh, MeshType>>().unwrap();
|
||||
for (entity, mesh) in mesh_query.iter_immutable(world) {
|
||||
if let Some(mesh_asset) = mesh_storage.get(*mesh.id) {
|
||||
if let Some(mesh_asset) = mesh_storage.get(*mesh.id.read().unwrap()) {
|
||||
mesh_asset.setup_buffers(device);
|
||||
pass.set_bind_group(1, entity.bind_group.as_ref().unwrap(), &[]);
|
||||
pass.set_index_buffer(mesh_asset.index_buffer.as_ref().unwrap(), 0);
|
||||
|
|
21
src/render/material.rs
Normal file
21
src/render/material.rs
Normal file
|
@ -0,0 +1,21 @@
|
|||
use zerocopy::{AsBytes, FromBytes};
|
||||
use crate::math;
|
||||
|
||||
pub struct Material {
|
||||
pub color: math::Vec4,
|
||||
pub bind_group: Option<wgpu::BindGroup>,
|
||||
pub uniform_buf: Option<wgpu::Buffer>,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, AsBytes, FromBytes)]
|
||||
pub struct RenderedUniforms {
|
||||
pub transform: [[f32; 4]; 4],
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, AsBytes, FromBytes)]
|
||||
pub struct MaterialUniforms {
|
||||
pub model: [[f32; 4]; 4],
|
||||
pub color: [f32; 4],
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{vertex::Vertex, asset::Asset};
|
||||
use wgpu::{Buffer, Device};
|
||||
use zerocopy::{AsBytes, FromBytes};
|
||||
use zerocopy::AsBytes;
|
||||
|
||||
pub enum MeshType {
|
||||
Cube,
|
||||
|
|
|
@ -5,20 +5,17 @@ mod forward;
|
|||
mod shadow;
|
||||
mod light;
|
||||
mod pass;
|
||||
mod material;
|
||||
|
||||
pub use forward::{ForwardPass, ForwardUniforms};
|
||||
pub use shadow::ShadowPass;
|
||||
pub use light::*;
|
||||
pub use shader::*;
|
||||
pub use pass::*;
|
||||
|
||||
use wgpu::BindGroup;
|
||||
pub use material::*;
|
||||
pub use mesh::*;
|
||||
|
||||
pub struct UniformBuffer {
|
||||
pub buffer: wgpu::Buffer,
|
||||
pub size: u64,
|
||||
}
|
||||
|
||||
pub struct Rendered {
|
||||
pub bind_group: Option<BindGroup>,
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{render::*, temp::*, asset::*, render::mesh::*};
|
||||
use crate::{render::*, asset::*};
|
||||
use wgpu::{BindGroupLayout, CommandEncoder, Device, VertexBufferDescriptor, SwapChainOutput};
|
||||
use legion::prelude::*;
|
||||
use zerocopy::AsBytes;
|
||||
|
@ -23,7 +23,7 @@ pub struct ShadowUniforms {
|
|||
impl Pass for ShadowPass {
|
||||
fn render(&mut self, device: &Device, _: &SwapChainOutput, encoder: &mut CommandEncoder, world: &mut World) {
|
||||
let mut light_query = <Read<Light>>::query();
|
||||
let mut mesh_query = <(Read<CubeEnt>, Read<Handle<Mesh>>)>::query();
|
||||
let mut mesh_query = <(Read<Material>, Read<Handle<Mesh>>)>::query();
|
||||
let light_count = light_query.iter(world).count();
|
||||
|
||||
if self.lights_are_dirty {
|
||||
|
@ -75,7 +75,7 @@ impl Pass for ShadowPass {
|
|||
|
||||
let mut mesh_storage = world.resources.get_mut::<AssetStorage<Mesh, MeshType>>().unwrap();
|
||||
for (entity, mesh) in mesh_query.iter_immutable(world) {
|
||||
if let Some(mut mesh_asset) = mesh_storage.get(*mesh.id) {
|
||||
if let Some(mesh_asset) = mesh_storage.get(*mesh.id.read().unwrap()) {
|
||||
mesh_asset.setup_buffers(device);
|
||||
|
||||
pass.set_bind_group(1, entity.bind_group.as_ref().unwrap(), &[]);
|
||||
|
|
40
src/temp.rs
40
src/temp.rs
|
@ -1,40 +0,0 @@
|
|||
use std::{sync::Arc};
|
||||
use zerocopy::{AsBytes, FromBytes};
|
||||
use crate::math;
|
||||
|
||||
pub struct CubeEnt {
|
||||
pub color: math::Vec4,
|
||||
pub bind_group: Option<wgpu::BindGroup>,
|
||||
pub uniform_buf: Option<wgpu::Buffer>,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, AsBytes, FromBytes)]
|
||||
pub struct EntityUniforms {
|
||||
pub model: [[f32; 4]; 4],
|
||||
pub color: [f32; 4],
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn create_texels(size: usize) -> Vec<u8> {
|
||||
use std::iter;
|
||||
|
||||
(0 .. size * size)
|
||||
.flat_map(|id| {
|
||||
// get high five for recognizing this ;)
|
||||
let cx = 3.0 * (id % size) as f32 / (size - 1) as f32 - 2.0;
|
||||
let cy = 2.0 * (id / size) as f32 / (size - 1) as f32 - 1.0;
|
||||
let (mut x, mut y, mut count) = (cx, cy, 0);
|
||||
while count < 0xFF && x * x + y * y < 4.0 {
|
||||
let old_x = x;
|
||||
x = x * x - y * y + cx;
|
||||
y = 2.0 * old_x * y + cy;
|
||||
count += 1;
|
||||
}
|
||||
iter::once(0xFF - (count * 5) as u8)
|
||||
.chain(iter::once(0xFF - (count * 15) as u8))
|
||||
.chain(iter::once(0xFF - (count * 50) as u8))
|
||||
.chain(iter::once(1))
|
||||
})
|
||||
.collect()
|
||||
}
|
|
@ -1,6 +1,9 @@
|
|||
|
||||
|
||||
```bash
|
||||
# run using this command
|
||||
# run using one of these commands
|
||||
# lld linker makes compiles faster
|
||||
# rust backtrace gives you a nice backtrace on panics
|
||||
env RUSTFLAGS="-C link-arg=-fuse-ld=lld" cargo run --release
|
||||
env RUSTFLAGS="-C link-arg=-fuse-ld=lld" RUST_BACKTRACE=1 cargo run --release
|
||||
```
|
|
@ -1,5 +1,6 @@
|
|||
use bevy::*;
|
||||
use bevy::{render::mesh::{Mesh, MeshType}, asset::{Asset, AssetStorage}, temp::*, math};
|
||||
use std::clone::Clone;
|
||||
|
||||
fn main() {
|
||||
let universe = Universe::new();
|
||||
|
@ -7,12 +8,33 @@ fn main() {
|
|||
// Create a query which finds all `Position` and `Velocity` components
|
||||
// let mut query = Read::<Transform>::query();
|
||||
let cube = Mesh::load(MeshType::Cube);
|
||||
let plane = Mesh::load(MeshType::Plane{ size: 10 });
|
||||
let mut mesh_storage = AssetStorage::<Mesh, MeshType>::new();
|
||||
let handle = mesh_storage.add(cube);
|
||||
|
||||
// this currently breaks because Arcs cant be modified after they are cloned :(
|
||||
let mesh_handle = mesh_storage.add(cube);
|
||||
let plane_handle = mesh_storage.add(plane);
|
||||
world.resources.insert(mesh_storage);
|
||||
|
||||
world.insert((), vec![
|
||||
(CubeEnt { color: math::Vec4::identity(), bind_group: None, uniform_buf: None }, handle, LocalToWorld::identity(), Translation::new(0.0, 0.0, 0.0))
|
||||
(
|
||||
Material { color: math::vec4(0.0, 1.0, 0.0, 1.0), bind_group: None, uniform_buf: None },
|
||||
plane_handle.clone(),
|
||||
LocalToWorld(math::translation(&math::vec3(0.0, 0.0, 0.0))),
|
||||
Translation::new(0.0, 0.0, 0.0)
|
||||
),
|
||||
(
|
||||
Material { color: math::vec4(0.0, 1.0, 0.0, 1.0), bind_group: None, uniform_buf: None },
|
||||
mesh_handle.clone(),
|
||||
LocalToWorld(math::translation(&math::vec3(3.0, 0.0, 0.0))),
|
||||
Translation::new(0.0, 0.0, 0.0)
|
||||
),
|
||||
(
|
||||
Material { color: math::vec4(1.0, 0.0, 0.0, 1.0), bind_group: None, uniform_buf: None },
|
||||
mesh_handle,
|
||||
LocalToWorld::identity(),
|
||||
Translation::new(0.0, 0.0, 0.0)
|
||||
),
|
||||
]);
|
||||
|
||||
Application::run(universe, world);
|
||||
|
|
Loading…
Reference in a new issue