mirror of
https://github.com/bevyengine/bevy
synced 2024-11-10 07:04:33 +00:00
New Mesh implementation (adapts to arbitrary vertex descriptors). Initial gltf model loading.
This commit is contained in:
parent
2aaf23b9fd
commit
649ffebb7f
41 changed files with 487 additions and 249 deletions
3
.vscode/launch.json
vendored
3
.vscode/launch.json
vendored
|
@ -9,6 +9,7 @@
|
|||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"name": "Debug unit tests in library 'bevy'",
|
||||
"sourceLanguages": ["rust"],
|
||||
"cargo": {
|
||||
"args": [
|
||||
"test",
|
||||
|
@ -28,6 +29,7 @@
|
|||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"name": "Build and launch example",
|
||||
"sourceLanguages": ["rust"],
|
||||
"cargo": {
|
||||
"args": [
|
||||
"build",
|
||||
|
@ -46,6 +48,7 @@
|
|||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"name": "Launch example",
|
||||
"sourceLanguages": ["rust"],
|
||||
"cargo": {
|
||||
"args": [
|
||||
"run",
|
||||
|
|
|
@ -6,11 +6,12 @@ edition = "2018"
|
|||
|
||||
[features]
|
||||
default = ["headless", "wgpu", "winit"]
|
||||
headless = ["asset", "core", "derive", "diagnostic", "input", "render", "serialization", "transform", "ui", "window"]
|
||||
headless = ["asset", "core", "derive", "diagnostic", "gltf", "input", "render", "serialization", "transform", "ui", "window"]
|
||||
asset = ["bevy_asset"]
|
||||
core = ["bevy_core"]
|
||||
derive = ["bevy_derive"]
|
||||
diagnostic = ["bevy_diagnostic"]
|
||||
gltf = ["bevy_gltf"]
|
||||
input = ["bevy_input"]
|
||||
render = ["bevy_render"]
|
||||
serialization = ["bevy_serialization"]
|
||||
|
@ -27,6 +28,7 @@ bevy_asset = { path = "bevy_asset", optional = true }
|
|||
bevy_core = { path = "bevy_core", optional = true }
|
||||
bevy_derive = { path = "bevy_derive", optional = true }
|
||||
bevy_diagnostic = { path = "bevy_diagnostic", optional = true }
|
||||
bevy_gltf = { path = "bevy_gltf", optional = true }
|
||||
bevy_input = { path = "bevy_input", optional = true }
|
||||
bevy_render = { path = "bevy_render", optional = true }
|
||||
bevy_serialization = { path = "bevy_serialization", optional = true }
|
||||
|
|
|
@ -5,5 +5,4 @@ authors = ["Carter Anderson <mcanders1@gmail.com>"]
|
|||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
bevy_core = { path = "../bevy_core" }
|
||||
gltf = "0.14.0"
|
||||
bevy_core = { path = "../bevy_core" }
|
|
@ -1,15 +0,0 @@
|
|||
use std::{boxed::Box, error::Error, fs, io};
|
||||
|
||||
// use crate::render::Mesh;
|
||||
|
||||
pub fn load_gltf(path: &str) -> Result<(), Box<dyn Error>> {
|
||||
println!("{}", path);
|
||||
let file = fs::File::open(&path)?;
|
||||
let reader = io::BufReader::new(file);
|
||||
let gltf = gltf::Gltf::from_reader(reader)?;
|
||||
for scene in gltf.scenes() {
|
||||
for _mesh in scene.nodes() {}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -1,6 +1,3 @@
|
|||
mod gltf;
|
||||
|
||||
pub use self::gltf::load_gltf;
|
||||
use bevy_core::bytes::GetBytes;
|
||||
use std::{
|
||||
fmt::Debug,
|
||||
|
|
|
@ -387,7 +387,7 @@ pub fn derive_uniforms(input: TokenStream) -> TokenStream {
|
|||
format!("{}", name)
|
||||
};
|
||||
let descriptor = VertexAttributeDescriptor {
|
||||
name: formatted_name,
|
||||
name: formatted_name.into(),
|
||||
offset,
|
||||
format: *format,
|
||||
shader_location,
|
||||
|
@ -400,7 +400,7 @@ pub fn derive_uniforms(input: TokenStream) -> TokenStream {
|
|||
|
||||
#bevy_render_path::pipeline::VertexBufferDescriptor {
|
||||
attributes: vertex_attribute_descriptors,
|
||||
name: #struct_name_string.to_string(),
|
||||
name: #struct_name_string.into(),
|
||||
step_mode: #bevy_render_path::pipeline::InputStepMode::Instance,
|
||||
stride: offset,
|
||||
}
|
||||
|
|
12
bevy_gltf/Cargo.toml
Normal file
12
bevy_gltf/Cargo.toml
Normal file
|
@ -0,0 +1,12 @@
|
|||
[package]
|
||||
name = "bevy_gltf"
|
||||
version = "0.1.0"
|
||||
authors = ["Carter Anderson <mcanders1@gmail.com>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
bevy_asset = { path = "../bevy_asset" }
|
||||
bevy_render = { path = "../bevy_render" }
|
||||
|
||||
gltf = "0.15.2"
|
||||
thiserror = "1.0"
|
91
bevy_gltf/src/lib.rs
Normal file
91
bevy_gltf/src/lib.rs
Normal file
|
@ -0,0 +1,91 @@
|
|||
use bevy_render::{
|
||||
mesh::{Mesh, VertexAttribute, VertexAttributeValues},
|
||||
pipeline::state_descriptors::PrimitiveTopology,
|
||||
};
|
||||
use gltf::{buffer::Source, iter, mesh::Mode};
|
||||
use std::{fs, io, path::Path};
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum GltfError {
|
||||
#[error("Unsupported primitive mode.")]
|
||||
UnsupportedPrimitive { mode: Mode },
|
||||
#[error("Invalid GLTF file.")]
|
||||
Gltf(#[from] gltf::Error),
|
||||
#[error("Failed to load file.")]
|
||||
Io(#[from] io::Error),
|
||||
#[error("Binary buffers not supported yet.")]
|
||||
BinaryBuffersUnsupported,
|
||||
}
|
||||
|
||||
fn get_primitive_topology(mode: Mode) -> Result<PrimitiveTopology, GltfError> {
|
||||
match mode {
|
||||
Mode::Points => Ok(PrimitiveTopology::PointList),
|
||||
Mode::Lines => Ok(PrimitiveTopology::LineList),
|
||||
Mode::LineStrip => Ok(PrimitiveTopology::LineStrip),
|
||||
Mode::Triangles => Ok(PrimitiveTopology::TriangleList),
|
||||
Mode::TriangleStrip => Ok(PrimitiveTopology::TriangleStrip),
|
||||
mode @ _ => Err(GltfError::UnsupportedPrimitive { mode }),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load_gltf(path: &str) -> Result<Option<Mesh>, GltfError> {
|
||||
let path: &Path = path.as_ref();
|
||||
let file = fs::File::open(&path)?;
|
||||
let reader = io::BufReader::new(file);
|
||||
let gltf = gltf::Gltf::from_reader(reader)?;
|
||||
let buffer_data = load_buffers(gltf.buffers(), path)?;
|
||||
for scene in gltf.scenes() {
|
||||
for node in scene.nodes() {
|
||||
return Ok(Some(load_node(&buffer_data, &node, 1)?));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn load_node(buffer_data: &[Vec<u8>], node: &gltf::Node, depth: i32) -> Result<Mesh, GltfError> {
|
||||
if let Some(mesh) = node.mesh() {
|
||||
for primitive in mesh.primitives() {
|
||||
let reader = primitive.reader(|buffer| Some(&buffer_data[buffer.index()]));
|
||||
let primitive_topology = get_primitive_topology(primitive.mode())?;
|
||||
let mut mesh = Mesh::new(primitive_topology);
|
||||
reader
|
||||
.read_positions()
|
||||
.map(|v| VertexAttribute {
|
||||
name: "position".into(),
|
||||
values: VertexAttributeValues::Float3(v.collect()),
|
||||
})
|
||||
.map(|vertex_attribute| mesh.attributes.push(vertex_attribute));
|
||||
|
||||
// let indices = reader.read_indices().unwrap();
|
||||
return Ok(mesh);
|
||||
}
|
||||
}
|
||||
println!();
|
||||
|
||||
for child in node.children() {
|
||||
return Ok(load_node(buffer_data, &child, depth + 1)?);
|
||||
}
|
||||
|
||||
panic!("failed to find mesh")
|
||||
}
|
||||
|
||||
fn load_buffers(buffers: iter::Buffers, path: &Path) -> Result<Vec<Vec<u8>>, GltfError> {
|
||||
let mut buffer_data = Vec::new();
|
||||
for buffer in buffers {
|
||||
match buffer.source() {
|
||||
Source::Uri(uri) => {
|
||||
if uri.starts_with("data:") {
|
||||
} else {
|
||||
let buffer_path = path.parent().unwrap().join(uri);
|
||||
let buffer_bytes = fs::read(buffer_path)?;
|
||||
buffer_data.push(buffer_bytes);
|
||||
}
|
||||
}
|
||||
Source::Bin => return Err(GltfError::BinaryBuffersUnsupported),
|
||||
}
|
||||
}
|
||||
|
||||
Ok(buffer_data)
|
||||
}
|
|
@ -28,4 +28,5 @@ zerocopy = "0.3"
|
|||
bitflags = "1.0"
|
||||
# TODO: replace once_cell with std equivalent if/when this lands: https://github.com/rust-lang/rfcs/pull/2788
|
||||
once_cell = "1.3.1"
|
||||
downcast-rs = "1.1.1"
|
||||
downcast-rs = "1.1.1"
|
||||
thiserror = "1.0"
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{
|
||||
draw_target::DrawTarget,
|
||||
mesh::{Mesh, MeshType},
|
||||
mesh::{shape::Quad, Mesh},
|
||||
pass::RenderPass,
|
||||
pipeline::PipelineDescriptor,
|
||||
render_resource::{
|
||||
|
@ -83,24 +83,36 @@ impl DrawTarget for UiDrawTarget {
|
|||
return;
|
||||
}
|
||||
|
||||
let quad = Mesh::load(MeshType::Quad {
|
||||
let quad = Mesh::from(Quad {
|
||||
size: glam::vec2(1.0, 1.0),
|
||||
});
|
||||
let vertex_buffer_bytes = quad.get_vertex_buffer_bytes(
|
||||
pipeline_descriptor
|
||||
.get_layout()
|
||||
.unwrap()
|
||||
.vertex_buffer_descriptors
|
||||
.first()
|
||||
.as_ref()
|
||||
.unwrap(),
|
||||
).unwrap();
|
||||
self.mesh_vertex_buffer = Some(render_context.resources_mut().create_buffer_with_data(
|
||||
BufferInfo {
|
||||
buffer_usage: BufferUsage::VERTEX,
|
||||
..Default::default()
|
||||
},
|
||||
quad.vertices.as_bytes(),
|
||||
&vertex_buffer_bytes,
|
||||
));
|
||||
|
||||
let index_buffer_bytes = quad.get_index_buffer_bytes(pipeline_descriptor.index_format).unwrap();
|
||||
self.mesh_index_buffer = Some(render_context.resources_mut().create_buffer_with_data(
|
||||
BufferInfo {
|
||||
buffer_usage: BufferUsage::INDEX,
|
||||
..Default::default()
|
||||
},
|
||||
quad.indices.as_bytes(),
|
||||
&index_buffer_bytes,
|
||||
));
|
||||
self.mesh_index_length = quad.indices.len();
|
||||
|
||||
self.mesh_index_length = quad.indices.as_ref().unwrap().len();
|
||||
|
||||
let global_render_resource_assignments =
|
||||
resources.get::<RenderResourceAssignments>().unwrap();
|
||||
|
|
|
@ -6,10 +6,10 @@ pub mod render_graph;
|
|||
pub mod render_graph_2;
|
||||
pub mod renderer_2;
|
||||
pub mod shader;
|
||||
pub mod vertex;
|
||||
|
||||
mod color;
|
||||
mod light;
|
||||
mod vertex;
|
||||
|
||||
pub use camera::*;
|
||||
pub use color::*;
|
||||
|
|
|
@ -1,126 +1,310 @@
|
|||
use crate::{render_resource::AssetBatchers, Renderable, Vertex};
|
||||
use crate::{
|
||||
pipeline::{
|
||||
state_descriptors::{IndexFormat, PrimitiveTopology},
|
||||
VertexBufferDescriptor, VertexFormat,
|
||||
},
|
||||
render_resource::AssetBatchers,
|
||||
Renderable, Vertex,
|
||||
};
|
||||
use bevy_asset::{Asset, Handle};
|
||||
use glam::*;
|
||||
use legion::prelude::*;
|
||||
use std::borrow::Cow;
|
||||
use thiserror::Error;
|
||||
use zerocopy::AsBytes;
|
||||
|
||||
pub const VERTEX_BUFFER_ASSET_INDEX: usize = 0;
|
||||
pub const INDEX_BUFFER_ASSET_INDEX: usize = 1;
|
||||
|
||||
pub enum MeshType {
|
||||
Cube,
|
||||
Plane { size: f32 },
|
||||
Quad { size: Vec2 },
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum VertexAttributeValues {
|
||||
Float(Vec<f32>),
|
||||
Float2(Vec<[f32; 2]>),
|
||||
Float3(Vec<[f32; 3]>),
|
||||
Float4(Vec<[f32; 4]>),
|
||||
}
|
||||
|
||||
pub struct Mesh {
|
||||
pub vertices: Vec<Vertex>,
|
||||
pub indices: Vec<u16>,
|
||||
}
|
||||
impl VertexAttributeValues {
|
||||
pub fn len(&self) -> usize {
|
||||
match *self {
|
||||
VertexAttributeValues::Float(ref values) => values.len(),
|
||||
VertexAttributeValues::Float2(ref values) => values.len(),
|
||||
VertexAttributeValues::Float3(ref values) => values.len(),
|
||||
VertexAttributeValues::Float4(ref values) => values.len(),
|
||||
}
|
||||
}
|
||||
|
||||
impl Asset<MeshType> for Mesh {
|
||||
fn load(descriptor: MeshType) -> Self {
|
||||
let (vertices, indices) = match descriptor {
|
||||
MeshType::Cube => create_cube(),
|
||||
MeshType::Plane { size } => create_plane(size),
|
||||
MeshType::Quad { size } => create_quad(size),
|
||||
};
|
||||
|
||||
Mesh { vertices, indices }
|
||||
// TODO: add vertex format as parameter here and perform type conversions
|
||||
pub fn get_bytes(&self) -> &[u8] {
|
||||
match *self {
|
||||
VertexAttributeValues::Float(ref values) => values.as_bytes(),
|
||||
VertexAttributeValues::Float2(ref values) => values.as_bytes(),
|
||||
VertexAttributeValues::Float3(ref values) => values.as_bytes(),
|
||||
VertexAttributeValues::Float4(ref values) => values.as_bytes(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_quad_from_vertices(
|
||||
north_west: Vec2,
|
||||
north_east: Vec2,
|
||||
south_west: Vec2,
|
||||
south_east: Vec2,
|
||||
) -> (Vec<Vertex>, Vec<u16>) {
|
||||
let vertex_data = [
|
||||
Vertex::from((
|
||||
[south_west.x(), south_west.y(), 0.0],
|
||||
[0.0, 0.0, 1.0],
|
||||
[0.0, 1.0],
|
||||
)),
|
||||
Vertex::from((
|
||||
[north_west.x(), north_west.y(), 0.0],
|
||||
[0.0, 0.0, 1.0],
|
||||
[0.0, 0.0],
|
||||
)),
|
||||
Vertex::from((
|
||||
[north_east.x(), north_east.y(), 0.0],
|
||||
[0.0, 0.0, 1.0],
|
||||
[1.0, 0.0],
|
||||
)),
|
||||
Vertex::from((
|
||||
[south_east.x(), south_east.y(), 0.0],
|
||||
[0.0, 0.0, 1.0],
|
||||
[1.0, 1.0],
|
||||
)),
|
||||
];
|
||||
|
||||
let index_data: &[u16] = &[0, 2, 1, 0, 3, 2];
|
||||
return (vertex_data.to_vec(), index_data.to_vec());
|
||||
impl From<&VertexAttributeValues> for VertexFormat {
|
||||
fn from(values: &VertexAttributeValues) -> Self {
|
||||
match values {
|
||||
VertexAttributeValues::Float(_) => VertexFormat::Float,
|
||||
VertexAttributeValues::Float2(_) => VertexFormat::Float2,
|
||||
VertexAttributeValues::Float3(_) => VertexFormat::Float3,
|
||||
VertexAttributeValues::Float4(_) => VertexFormat::Float4,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_quad(dimensions: Vec2) -> (Vec<Vertex>, Vec<u16>) {
|
||||
let extent_x = dimensions.x() / 2.0;
|
||||
let extent_y = dimensions.y() / 2.0;
|
||||
create_quad_from_vertices(
|
||||
vec2(-extent_x, extent_y),
|
||||
vec2(extent_x, extent_y),
|
||||
vec2(-extent_x, -extent_y),
|
||||
vec2(extent_x, -extent_y),
|
||||
)
|
||||
#[derive(Debug)]
|
||||
pub struct VertexAttribute {
|
||||
pub name: Cow<'static, str>,
|
||||
pub values: VertexAttributeValues,
|
||||
}
|
||||
|
||||
pub fn create_cube() -> (Vec<Vertex>, Vec<u16>) {
|
||||
let vertex_data = [
|
||||
// top (0, 0, 1)
|
||||
Vertex::from(([-1, -1, 1], [0, 0, 1], [0, 0])),
|
||||
Vertex::from(([1, -1, 1], [0, 0, 1], [1, 0])),
|
||||
Vertex::from(([1, 1, 1], [0, 0, 1], [1, 1])),
|
||||
Vertex::from(([-1, 1, 1], [0, 0, 1], [0, 1])),
|
||||
// bottom (0, 0, -1)
|
||||
Vertex::from(([-1, 1, -1], [0, 0, -1], [1, 0])),
|
||||
Vertex::from(([1, 1, -1], [0, 0, -1], [0, 0])),
|
||||
Vertex::from(([1, -1, -1], [0, 0, -1], [0, 1])),
|
||||
Vertex::from(([-1, -1, -1], [0, 0, -1], [1, 1])),
|
||||
// right (1, 0, 0)
|
||||
Vertex::from(([1, -1, -1], [1, 0, 0], [0, 0])),
|
||||
Vertex::from(([1, 1, -1], [1, 0, 0], [1, 0])),
|
||||
Vertex::from(([1, 1, 1], [1, 0, 0], [1, 1])),
|
||||
Vertex::from(([1, -1, 1], [1, 0, 0], [0, 1])),
|
||||
// left (-1, 0, 0)
|
||||
Vertex::from(([-1, -1, 1], [-1, 0, 0], [1, 0])),
|
||||
Vertex::from(([-1, 1, 1], [-1, 0, 0], [0, 0])),
|
||||
Vertex::from(([-1, 1, -1], [-1, 0, 0], [0, 1])),
|
||||
Vertex::from(([-1, -1, -1], [-1, 0, 0], [1, 1])),
|
||||
// front (0, 1, 0)
|
||||
Vertex::from(([1, 1, -1], [0, 1, 0], [1, 0])),
|
||||
Vertex::from(([-1, 1, -1], [0, 1, 0], [0, 0])),
|
||||
Vertex::from(([-1, 1, 1], [0, 1, 0], [0, 1])),
|
||||
Vertex::from(([1, 1, 1], [0, 1, 0], [1, 1])),
|
||||
// back (0, -1, 0)
|
||||
Vertex::from(([1, -1, 1], [0, -1, 0], [0, 0])),
|
||||
Vertex::from(([-1, -1, 1], [0, -1, 0], [1, 0])),
|
||||
Vertex::from(([-1, -1, -1], [0, -1, 0], [1, 1])),
|
||||
Vertex::from(([1, -1, -1], [0, -1, 0], [0, 1])),
|
||||
];
|
||||
impl VertexAttribute {
|
||||
pub const POSITION: &'static str = "position";
|
||||
pub const NORMAL: &'static str = "normal";
|
||||
pub const UV: &'static str = "uv";
|
||||
|
||||
let index_data: &[u16] = &[
|
||||
0, 1, 2, 2, 3, 0, // top
|
||||
4, 5, 6, 6, 7, 4, // bottom
|
||||
8, 9, 10, 10, 11, 8, // right
|
||||
12, 13, 14, 14, 15, 12, // left
|
||||
16, 17, 18, 18, 19, 16, // front
|
||||
20, 21, 22, 22, 23, 20, // back
|
||||
];
|
||||
pub fn position(positions: Vec<[f32; 3]>) -> Self {
|
||||
VertexAttribute {
|
||||
name: Self::POSITION.into(),
|
||||
values: VertexAttributeValues::Float3(positions),
|
||||
}
|
||||
}
|
||||
|
||||
(vertex_data.to_vec(), index_data.to_vec())
|
||||
pub fn normal(normals: Vec<[f32; 3]>) -> Self {
|
||||
VertexAttribute {
|
||||
name: Self::NORMAL.into(),
|
||||
values: VertexAttributeValues::Float3(normals),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn uv(uvs: Vec<[f32; 2]>) -> Self {
|
||||
VertexAttribute {
|
||||
name: Self::UV.into(),
|
||||
values: VertexAttributeValues::Float2(uvs),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_plane(size: f32) -> (Vec<Vertex>, Vec<u16>) {
|
||||
create_quad(vec2(size, size))
|
||||
#[derive(Error, Debug)]
|
||||
pub enum MeshToVertexBufferError {
|
||||
#[error("VertexBufferDescriptor requires a VertexBufferAttribute this Mesh does not contain.")]
|
||||
MissingVertexAttribute { attribute_name: Cow<'static, str> },
|
||||
#[error("Mesh VertexAttribute VertexFormat is incompatible with VertexBufferDescriptor VertexAttribute VertexFormat.")]
|
||||
IncompatibleVertexAttributeFormat {
|
||||
attribute_name: Cow<'static, str>,
|
||||
descriptor_format: VertexFormat,
|
||||
mesh_format: VertexFormat,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Mesh {
|
||||
pub primitive_topology: PrimitiveTopology,
|
||||
pub attributes: Vec<VertexAttribute>,
|
||||
pub indices: Option<Vec<u32>>,
|
||||
}
|
||||
|
||||
impl Mesh {
|
||||
pub fn new(primitive_topology: PrimitiveTopology) -> Self {
|
||||
Mesh {
|
||||
primitive_topology,
|
||||
attributes: Vec::new(),
|
||||
indices: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_vertex_buffer_bytes(
|
||||
&self,
|
||||
vertex_buffer_descriptor: &VertexBufferDescriptor,
|
||||
) -> Result<Vec<u8>, MeshToVertexBufferError> {
|
||||
let length = self.attributes.first().map(|a| a.values.len()).unwrap_or(0);
|
||||
let mut bytes = vec![0; vertex_buffer_descriptor.stride as usize * length];
|
||||
|
||||
for vertex_attribute in vertex_buffer_descriptor.attributes.iter() {
|
||||
match self
|
||||
.attributes
|
||||
.iter()
|
||||
.find(|a| VertexFormat::from(&a.values) == vertex_attribute.format)
|
||||
{
|
||||
Some(mesh_attribute) => {
|
||||
let attribute_bytes = mesh_attribute.values.get_bytes();
|
||||
let attribute_size = vertex_attribute.format.get_size() as usize;
|
||||
for (i, vertex_slice) in attribute_bytes.chunks(attribute_size).enumerate() {
|
||||
let vertex_offset = vertex_buffer_descriptor.stride as usize * i;
|
||||
let attribute_offset = vertex_offset + vertex_attribute.offset as usize;
|
||||
bytes[attribute_offset..attribute_offset + attribute_size]
|
||||
.copy_from_slice(vertex_slice);
|
||||
}
|
||||
}
|
||||
None => {
|
||||
return Err(MeshToVertexBufferError::MissingVertexAttribute {
|
||||
attribute_name: vertex_attribute.name.clone(),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(bytes)
|
||||
}
|
||||
|
||||
pub fn get_index_buffer_bytes(&self, index_format: IndexFormat) -> Option<Vec<u8>> {
|
||||
self.indices.as_ref().map(|indices| match index_format {
|
||||
IndexFormat::Uint16 => indices
|
||||
.iter()
|
||||
.map(|i| *i as u16)
|
||||
.collect::<Vec<u16>>()
|
||||
.as_bytes()
|
||||
.to_vec(),
|
||||
IndexFormat::Uint32 => indices.as_bytes().to_vec(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub mod shape {
|
||||
use super::{Mesh, VertexAttribute};
|
||||
use crate::pipeline::state_descriptors::PrimitiveTopology;
|
||||
use glam::*;
|
||||
|
||||
pub struct Cube;
|
||||
|
||||
impl From<Cube> for Mesh {
|
||||
fn from(_: Cube) -> Self {
|
||||
let vertices = &[
|
||||
// top (0., 0., 1.)
|
||||
([-1., -1., 1.], [0., 0., 1.], [0., 0.]),
|
||||
([1., -1., 1.], [0., 0., 1.], [1., 0.]),
|
||||
([1., 1., 1.], [0., 0., 1.], [1., 1.]),
|
||||
([-1., 1., 1.], [0., 0., 1.], [0., 1.]),
|
||||
// bottom (0., 0., -1.)
|
||||
([-1., 1., -1.], [0., 0., -1.], [1., 0.]),
|
||||
([1., 1., -1.], [0., 0., -1.], [0., 0.]),
|
||||
([1., -1., -1.], [0., 0., -1.], [0., 1.]),
|
||||
([-1., -1., -1.], [0., 0., -1.], [1., 1.]),
|
||||
// right (1., 0., 0.)
|
||||
([1., -1., -1.], [1., 0., 0.], [0., 0.]),
|
||||
([1., 1., -1.], [1., 0., 0.], [1., 0.]),
|
||||
([1., 1., 1.], [1., 0., 0.], [1., 1.]),
|
||||
([1., -1., 1.], [1., 0., 0.], [0., 1.]),
|
||||
// left (-1., 0., 0.)
|
||||
([-1., -1., 1.], [-1., 0., 0.], [1., 0.]),
|
||||
([-1., 1., 1.], [-1., 0., 0.], [0., 0.]),
|
||||
([-1., 1., -1.], [-1., 0., 0.], [0., 1.]),
|
||||
([-1., -1., -1.], [-1., 0., 0.], [1., 1.]),
|
||||
// front (0., 1., 0.)
|
||||
([1., 1., -1.], [0., 1., 0.], [1., 0.]),
|
||||
([-1., 1., -1.], [0., 1., 0.], [0., 0.]),
|
||||
([-1., 1., 1.], [0., 1., 0.], [0., 1.]),
|
||||
([1., 1., 1.], [0., 1., 0.], [1., 1.]),
|
||||
// back (0., -1., 0.)
|
||||
([1., -1., 1.], [0., -1., 0.], [0., 0.]),
|
||||
([-1., -1., 1.], [0., -1., 0.], [1., 0.]),
|
||||
([-1., -1., -1.], [0., -1., 0.], [1., 1.]),
|
||||
([1., -1., -1.], [0., -1., 0.], [0., 1.]),
|
||||
];
|
||||
|
||||
let mut positions = Vec::new();
|
||||
let mut normals = Vec::new();
|
||||
let mut uvs = Vec::new();
|
||||
for (position, normal, uv) in vertices.iter() {
|
||||
positions.push(position.clone());
|
||||
normals.push(normal.clone());
|
||||
uvs.push(uv.clone());
|
||||
}
|
||||
|
||||
let indices = vec![
|
||||
0, 1, 2, 2, 3, 0, // top
|
||||
4, 5, 6, 6, 7, 4, // bottom
|
||||
8, 9, 10, 10, 11, 8, // right
|
||||
12, 13, 14, 14, 15, 12, // left
|
||||
16, 17, 18, 18, 19, 16, // front
|
||||
20, 21, 22, 22, 23, 20, // back
|
||||
];
|
||||
|
||||
Mesh {
|
||||
primitive_topology: PrimitiveTopology::TriangleStrip,
|
||||
attributes: vec![
|
||||
VertexAttribute::position(positions),
|
||||
VertexAttribute::normal(normals),
|
||||
VertexAttribute::uv(uvs),
|
||||
],
|
||||
indices: Some(indices),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Quad {
|
||||
pub size: Vec2,
|
||||
}
|
||||
|
||||
impl From<Quad> for Mesh {
|
||||
fn from(quad: Quad) -> Self {
|
||||
let extent_x = quad.size.x() / 2.0;
|
||||
let extent_y = quad.size.y() / 2.0;
|
||||
|
||||
let north_west = vec2(-extent_x, extent_y);
|
||||
let north_east = vec2(extent_x, extent_y);
|
||||
let south_west = vec2(-extent_x, -extent_y);
|
||||
let south_east = vec2(extent_x, -extent_y);
|
||||
let vertices = &[
|
||||
(
|
||||
[south_west.x(), south_west.y(), 0.0],
|
||||
[0.0, 0.0, 1.0],
|
||||
[0.0, 1.0],
|
||||
),
|
||||
(
|
||||
[north_west.x(), north_west.y(), 0.0],
|
||||
[0.0, 0.0, 1.0],
|
||||
[0.0, 0.0],
|
||||
),
|
||||
(
|
||||
[north_east.x(), north_east.y(), 0.0],
|
||||
[0.0, 0.0, 1.0],
|
||||
[1.0, 0.0],
|
||||
),
|
||||
(
|
||||
[south_east.x(), south_east.y(), 0.0],
|
||||
[0.0, 0.0, 1.0],
|
||||
[1.0, 1.0],
|
||||
),
|
||||
];
|
||||
|
||||
let indices = vec![0, 2, 1, 0, 3, 2];
|
||||
|
||||
let mut positions = Vec::new();
|
||||
let mut normals = Vec::new();
|
||||
let mut uvs = Vec::new();
|
||||
for (position, normal, uv) in vertices.iter() {
|
||||
positions.push(position.clone());
|
||||
normals.push(normal.clone());
|
||||
uvs.push(uv.clone());
|
||||
}
|
||||
|
||||
Mesh {
|
||||
primitive_topology: PrimitiveTopology::TriangleStrip,
|
||||
attributes: vec![
|
||||
VertexAttribute::position(positions),
|
||||
VertexAttribute::normal(normals),
|
||||
VertexAttribute::uv(uvs),
|
||||
],
|
||||
indices: Some(indices),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Plane {
|
||||
pub size: f32,
|
||||
}
|
||||
|
||||
impl From<Plane> for Mesh {
|
||||
fn from(plane: Plane) -> Self {
|
||||
Quad {
|
||||
size: Vec2::new(plane.size, plane.size)
|
||||
}.into()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mesh_batcher_system() -> Box<dyn Schedulable> {
|
||||
|
|
|
@ -83,7 +83,7 @@ pub struct UniformProperty {
|
|||
|
||||
#[derive(Hash, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
|
||||
pub enum UniformPropertyType {
|
||||
// TODO: Add all types here
|
||||
// TODO: Use VertexFormat here
|
||||
Int,
|
||||
Float,
|
||||
UVec4,
|
||||
|
|
|
@ -8,7 +8,7 @@ struct Light {
|
|||
vec4 color;
|
||||
};
|
||||
|
||||
layout(location = 0) in vec4 v_Position;
|
||||
layout(location = 0) in vec3 v_Position;
|
||||
layout(location = 1) in vec3 v_Normal;
|
||||
layout(location = 2) in vec2 v_Uv;
|
||||
|
||||
|
@ -46,7 +46,7 @@ void main() {
|
|||
for (int i=0; i<int(NumLights.x) && i<MAX_LIGHTS; ++i) {
|
||||
Light light = SceneLights[i];
|
||||
// compute Lambertian diffuse term
|
||||
vec3 light_dir = normalize(light.pos.xyz - v_Position.xyz);
|
||||
vec3 light_dir = normalize(light.pos.xyz - v_Position);
|
||||
float diffuse = max(0.0, dot(normal, light_dir));
|
||||
// add light contribution
|
||||
color += diffuse * light.color.xyz;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#version 450
|
||||
|
||||
layout(location = 0) in vec4 Vertex_Position;
|
||||
layout(location = 1) in vec4 Vertex_Normal;
|
||||
layout(location = 0) in vec3 Vertex_Position;
|
||||
layout(location = 1) in vec3 Vertex_Normal;
|
||||
layout(location = 2) in vec2 Vertex_Uv;
|
||||
|
||||
# ifdef INSTANCING
|
||||
|
@ -11,7 +11,7 @@ layout(location = 5) in vec4 I_Object_Model_2;
|
|||
layout(location = 6) in vec4 I_Object_Model_3;
|
||||
# endif
|
||||
|
||||
layout(location = 0) out vec4 v_Position;
|
||||
layout(location = 0) out vec3 v_Position;
|
||||
layout(location = 1) out vec3 v_Normal;
|
||||
layout(location = 2) out vec2 v_Uv;
|
||||
|
||||
|
@ -35,8 +35,8 @@ void main() {
|
|||
);
|
||||
# endif
|
||||
|
||||
v_Normal = mat3(Model) * vec3(Vertex_Normal.xyz);
|
||||
v_Position = Model * Vertex_Position;
|
||||
v_Normal = (Model * vec4(Vertex_Normal, 1.0)).xyz;
|
||||
v_Position = (Model * vec4(Vertex_Position, 1.0)).xyz;
|
||||
v_Uv = Vertex_Uv;
|
||||
gl_Position = ViewProj * v_Position;
|
||||
gl_Position = ViewProj * vec4(v_Position, 1.0);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#version 450
|
||||
|
||||
layout(location = 0) in vec4 v_Position;
|
||||
layout(location = 0) in vec3 v_Position;
|
||||
layout(location = 1) in vec3 v_Normal;
|
||||
layout(location = 2) in vec2 v_Uv;
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
#version 450
|
||||
|
||||
layout(location = 0) in vec4 a_Pos;
|
||||
layout(location = 1) in vec4 a_Normal;
|
||||
layout(location = 2) in vec2 a_Uv;
|
||||
layout(location = 0) in vec3 Vertex_Position;
|
||||
layout(location = 1) in vec3 Vertex_Normal;
|
||||
layout(location = 2) in vec2 Vertex_Uv;
|
||||
|
||||
layout(location = 0) out vec4 v_Position;
|
||||
layout(location = 0) out vec3 v_Position;
|
||||
layout(location = 1) out vec3 v_Normal;
|
||||
layout(location = 2) out vec2 v_Uv;
|
||||
|
||||
|
@ -21,7 +21,7 @@ layout(set = 1, binding = 1) uniform StandardMaterial_albedo {
|
|||
};
|
||||
|
||||
void main() {
|
||||
v_Normal = mat3(Model) * vec3(a_Normal.xyz);
|
||||
v_Position = Model * a_Pos;
|
||||
v_Normal = (Model * vec4(Vertex_Normal, 1.0)).xyz;
|
||||
v_Position = (Model * vec4(Vertex_Position, 1.0)).xyz;
|
||||
gl_Position = ViewProj * v_Position;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#version 450
|
||||
|
||||
layout(location = 0) in vec4 Vertex_Position;
|
||||
layout(location = 1) in vec4 Vertex_Normal;
|
||||
layout(location = 0) in vec3 Vertex_Position;
|
||||
layout(location = 1) in vec3 Vertex_Normal;
|
||||
layout(location = 2) in vec2 Vertex_Uv;
|
||||
|
||||
layout (location = 3) in vec2 I_Rect_Position;
|
||||
|
@ -17,7 +17,7 @@ layout(set = 0, binding = 0) uniform Camera2d {
|
|||
|
||||
void main() {
|
||||
v_Color = I_Rect_Color;
|
||||
vec4 position = Vertex_Position * vec4(I_Rect_Size, 0.0, 1.0);
|
||||
vec3 position = Vertex_Position * vec3(I_Rect_Size, 0.0);
|
||||
position = position + vec4(I_Rect_Position + I_Rect_Size / 2.0, -I_Rect_ZIndex, 0.0);
|
||||
gl_Position = ViewProj * position;
|
||||
gl_Position = ViewProj * vec4(position, 1.0);
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use super::VertexFormat;
|
||||
use std::collections::HashMap;
|
||||
use std::{borrow::Cow, collections::HashMap};
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct VertexBufferDescriptor {
|
||||
pub name: String,
|
||||
pub name: Cow<'static, str>,
|
||||
pub stride: u64,
|
||||
pub step_mode: InputStepMode,
|
||||
pub attributes: Vec<VertexAttributeDescriptor>,
|
||||
|
@ -37,7 +37,7 @@ pub enum InputStepMode {
|
|||
|
||||
#[derive(Clone, Debug, Hash, Eq, PartialEq)]
|
||||
pub struct VertexAttributeDescriptor {
|
||||
pub name: String,
|
||||
pub name: Cow<'static, str>,
|
||||
pub offset: u64,
|
||||
pub format: VertexFormat,
|
||||
pub shader_location: u32,
|
||||
|
|
|
@ -18,7 +18,7 @@ pub fn camera_resource_provider_system(resources: &mut Resources) -> Box<dyn Sch
|
|||
let mut camera_buffer = None;
|
||||
let mut tmp_buffer = None;
|
||||
let mut window_resized_event_reader = resources.get_event_reader::<WindowResized>();
|
||||
SystemBuilder::new("mesh_resource_provider")
|
||||
SystemBuilder::new("camera_resource_provider")
|
||||
.read_resource::<GlobalRenderResourceContext>()
|
||||
// TODO: this write on RenderResourceAssignments will prevent this system from running in parallel with other systems that do the same
|
||||
.write_resource::<RenderResourceAssignments>()
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{
|
||||
mesh::{self, Mesh},
|
||||
pipeline::VertexBufferDescriptors,
|
||||
pipeline::{state_descriptors::IndexFormat, VertexBufferDescriptors},
|
||||
render_resource::{AssetBatchers, BufferInfo, BufferUsage},
|
||||
renderer_2::GlobalRenderResourceContext,
|
||||
shader::AsUniforms,
|
||||
|
@ -8,17 +8,19 @@ use crate::{
|
|||
};
|
||||
use bevy_asset::AssetStorage;
|
||||
use legion::prelude::*;
|
||||
use zerocopy::AsBytes;
|
||||
|
||||
pub fn mesh_resource_provider_system(resources: &mut Resources) -> Box<dyn Schedulable> {
|
||||
let mut vertex_buffer_descriptors = resources.get_mut::<VertexBufferDescriptors>().unwrap();
|
||||
vertex_buffer_descriptors.set(Vertex::get_vertex_buffer_descriptor().cloned().unwrap());
|
||||
// TODO: allow pipelines to specialize on vertex_buffer_descriptor and index_format
|
||||
let vertex_buffer_descriptor = Vertex::get_vertex_buffer_descriptor().unwrap();
|
||||
let index_format = IndexFormat::Uint16;
|
||||
vertex_buffer_descriptors.set(vertex_buffer_descriptor.clone());
|
||||
SystemBuilder::new("mesh_resource_provider")
|
||||
.read_resource::<GlobalRenderResourceContext>()
|
||||
.read_resource::<AssetStorage<Mesh>>()
|
||||
.write_resource::<AssetBatchers>()
|
||||
.build(
|
||||
|_, _, (render_resource_context, meshes, asset_batchers), _| {
|
||||
move |_, _, (render_resource_context, meshes, asset_batchers), _| {
|
||||
let render_resources = &render_resource_context.context;
|
||||
if let Some(batches) = asset_batchers.get_handle_batches_mut::<Mesh>() {
|
||||
for batch in batches {
|
||||
|
@ -35,20 +37,22 @@ pub fn mesh_resource_provider_system(resources: &mut Resources) -> Box<dyn Sched
|
|||
)
|
||||
} else {
|
||||
let mesh_asset = meshes.get(&handle).unwrap();
|
||||
let vertex_bytes = mesh_asset.get_vertex_buffer_bytes(&vertex_buffer_descriptor).unwrap();
|
||||
// TODO: use a staging buffer here
|
||||
let vertex_buffer = render_resources.create_buffer_with_data(
|
||||
BufferInfo {
|
||||
buffer_usage: BufferUsage::VERTEX,
|
||||
..Default::default()
|
||||
},
|
||||
mesh_asset.vertices.as_bytes(),
|
||||
&vertex_bytes,
|
||||
);
|
||||
let index_bytes = mesh_asset.get_index_buffer_bytes(index_format).unwrap();
|
||||
let index_buffer = render_resources.create_buffer_with_data(
|
||||
BufferInfo {
|
||||
buffer_usage: BufferUsage::INDEX,
|
||||
..Default::default()
|
||||
},
|
||||
mesh_asset.indices.as_bytes(),
|
||||
&index_bytes,
|
||||
);
|
||||
|
||||
render_resources.set_asset_resource(
|
||||
|
|
|
@ -32,6 +32,7 @@ pub fn glsl_to_spirv(
|
|||
options.add_macro_definition(shader_def.as_str(), None);
|
||||
}
|
||||
}
|
||||
|
||||
let binary_result = compiler
|
||||
.compile_into_spirv(
|
||||
glsl_source,
|
||||
|
|
|
@ -98,7 +98,7 @@ impl ShaderLayout {
|
|||
|
||||
current_descriptor = Some(VertexBufferDescriptor {
|
||||
attributes: vec![vertex_attribute_descriptor],
|
||||
name: current_buffer_name,
|
||||
name: current_buffer_name.into(),
|
||||
step_mode: if instance {
|
||||
InputStepMode::Instance
|
||||
} else {
|
||||
|
@ -142,7 +142,7 @@ fn reflect_vertex_attribute_descriptor(
|
|||
input_variable: &ReflectInterfaceVariable,
|
||||
) -> VertexAttributeDescriptor {
|
||||
VertexAttributeDescriptor {
|
||||
name: input_variable.name.clone(),
|
||||
name: input_variable.name.clone().into(),
|
||||
format: reflect_vertex_format(input_variable.type_description.as_ref().unwrap()),
|
||||
offset: 0,
|
||||
shader_location: input_variable.location,
|
||||
|
|
|
@ -19,31 +19,31 @@ static VERTEX_BUFFER_DESCRIPTOR: Lazy<VertexBufferDescriptor> =
|
|||
Lazy::new(|| VertexBufferDescriptor {
|
||||
attributes: vec![
|
||||
VertexAttributeDescriptor {
|
||||
name: "I_Object_Model_0".to_string(),
|
||||
name: "I_Object_Model_0".into(),
|
||||
format: VertexFormat::Float4,
|
||||
offset: 0,
|
||||
shader_location: 0,
|
||||
},
|
||||
VertexAttributeDescriptor {
|
||||
name: "I_Object_Model_1".to_string(),
|
||||
name: "I_Object_Model_1".into(),
|
||||
format: VertexFormat::Float4,
|
||||
offset: 16,
|
||||
shader_location: 1,
|
||||
},
|
||||
VertexAttributeDescriptor {
|
||||
name: "I_Object_Model_2".to_string(),
|
||||
name: "I_Object_Model_2".into(),
|
||||
format: VertexFormat::Float4,
|
||||
offset: 32,
|
||||
shader_location: 2,
|
||||
},
|
||||
VertexAttributeDescriptor {
|
||||
name: "I_Object_Model_3".to_string(),
|
||||
name: "I_Object_Model_3".into(),
|
||||
format: VertexFormat::Float4,
|
||||
offset: 48,
|
||||
shader_location: 3,
|
||||
},
|
||||
],
|
||||
name: "Object".to_string(),
|
||||
name: "Object".into(),
|
||||
step_mode: InputStepMode::Instance,
|
||||
stride: 64,
|
||||
});
|
||||
|
|
|
@ -10,64 +10,9 @@ use bevy_derive::Uniforms;
|
|||
#[module(meta = false, bevy_render = "crate")]
|
||||
pub struct Vertex {
|
||||
#[uniform(vertex)]
|
||||
pub position: [f32; 4],
|
||||
pub position: [f32; 3],
|
||||
#[uniform(vertex)]
|
||||
pub normal: [f32; 4],
|
||||
pub normal: [f32; 3],
|
||||
#[uniform(vertex)]
|
||||
pub uv: [f32; 2],
|
||||
}
|
||||
|
||||
impl From<([f32; 4], [f32; 4], [f32; 2])> for Vertex {
|
||||
fn from((position, normal, uv): ([f32; 4], [f32; 4], [f32; 2])) -> Self {
|
||||
Vertex {
|
||||
position,
|
||||
normal,
|
||||
uv,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<([f32; 3], [f32; 3], [f32; 2])> for Vertex {
|
||||
fn from((position, normal, uv): ([f32; 3], [f32; 3], [f32; 2])) -> Self {
|
||||
Vertex {
|
||||
position: [position[0], position[1], position[2], 1.0],
|
||||
normal: [normal[0], normal[1], normal[2], 0.0],
|
||||
uv,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<([i8; 4], [i8; 4], [i8; 2])> for Vertex {
|
||||
fn from((position, normal, uv): ([i8; 4], [i8; 4], [i8; 2])) -> Self {
|
||||
Vertex {
|
||||
position: [
|
||||
position[0] as f32,
|
||||
position[1] as f32,
|
||||
position[2] as f32,
|
||||
position[3] as f32,
|
||||
],
|
||||
normal: [
|
||||
normal[0] as f32,
|
||||
normal[1] as f32,
|
||||
normal[2] as f32,
|
||||
normal[3] as f32,
|
||||
],
|
||||
uv: [uv[0] as f32, uv[1] as f32],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<([i8; 3], [i8; 3], [i8; 2])> for Vertex {
|
||||
fn from((position, normal, uv): ([i8; 3], [i8; 3], [i8; 2])) -> Self {
|
||||
Vertex {
|
||||
position: [
|
||||
position[0] as f32,
|
||||
position[1] as f32,
|
||||
position[2] as f32,
|
||||
1.0,
|
||||
],
|
||||
normal: [normal[0] as f32, normal[1] as f32, normal[2] as f32, 0.0],
|
||||
uv: [uv[0] as f32, uv[1] as f32],
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -173,7 +173,7 @@ impl WgpuRenderer {
|
|||
pub fn handle_window_resized_events(
|
||||
&mut self,
|
||||
resources: &Resources,
|
||||
global_render_resources: &mut WgpuRenderResourceContext,
|
||||
global_render_resources: &dyn RenderResourceContext,
|
||||
) {
|
||||
let windows = resources.get::<Windows>().unwrap();
|
||||
let window_resized_events = resources.get::<Events<WindowResized>>().unwrap();
|
||||
|
|
|
@ -14,7 +14,7 @@ pub fn setup(world: &mut World, resources: &mut Resources) {
|
|||
let mut material_storage = resources
|
||||
.get_mut::<AssetStorage<StandardMaterial>>()
|
||||
.unwrap();
|
||||
let cube_handle = mesh_storage.add(Mesh::load(MeshType::Cube));
|
||||
let cube_handle = mesh_storage.add(Mesh::from(shape::Cube));
|
||||
let cube_material_handle = material_storage.add(StandardMaterial {
|
||||
albedo: Color::rgb(0.5, 0.4, 0.3),
|
||||
..Default::default()
|
||||
|
|
|
@ -153,8 +153,8 @@ fn setup(world: &mut World, resources: &mut Resources) {
|
|||
let mut material_storage = resources
|
||||
.get_mut::<AssetStorage<StandardMaterial>>()
|
||||
.unwrap();
|
||||
let cube_handle = mesh_storage.add(Mesh::load(MeshType::Cube));
|
||||
let plane_handle = mesh_storage.add(Mesh::load(MeshType::Plane { size: 10.0 }));
|
||||
let cube_handle = mesh_storage.add(Mesh::from(shape::Cube));
|
||||
let plane_handle = mesh_storage.add(Mesh::from(shape::Plane { size: 10.0 }));
|
||||
|
||||
let cube_material_handle = material_storage.add(StandardMaterial {
|
||||
albedo: Color::rgb(0.5, 0.3, 0.3),
|
||||
|
|
|
@ -61,7 +61,7 @@ fn setup(world: &mut World, resources: &mut Resources) {
|
|||
let mut material_storage = resources
|
||||
.get_mut::<AssetStorage<StandardMaterial>>()
|
||||
.unwrap();
|
||||
let cube_handle = mesh_storage.add(Mesh::load(MeshType::Cube));
|
||||
let cube_handle = mesh_storage.add(Mesh::from(shape::Cube));
|
||||
let cube_material_handle = material_storage.add(StandardMaterial {
|
||||
albedo: Color::rgb(0.5, 0.4, 0.3),
|
||||
..Default::default()
|
||||
|
|
|
@ -33,8 +33,8 @@ fn setup(world: &mut World, resources: &mut Resources) {
|
|||
let mut material_storage = resources
|
||||
.get_mut::<AssetStorage<StandardMaterial>>()
|
||||
.unwrap();
|
||||
let cube_handle = mesh_storage.add(Mesh::load(MeshType::Cube));
|
||||
let plane_handle = mesh_storage.add(Mesh::load(MeshType::Plane { size: 10.0 }));
|
||||
let cube_handle = mesh_storage.add(Mesh::from(shape::Cube));
|
||||
let plane_handle = mesh_storage.add(Mesh::from(shape::Plane { size: 10.0 }));
|
||||
let cube_material_handle = material_storage.add(StandardMaterial {
|
||||
albedo: Color::rgb(0.5, 0.4, 0.3),
|
||||
..Default::default()
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use bevy::{asset, prelude::*};
|
||||
use bevy::{gltf, prelude::*};
|
||||
|
||||
fn main() {
|
||||
asset::load_gltf("examples/assets/Box.gltf").unwrap();
|
||||
App::build().add_default_plugins().run();
|
||||
let mesh = gltf::load_gltf("examples/assets/Box.gltf").unwrap().unwrap();
|
||||
// App::build().add_default_plugins().run();
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ fn setup(world: &mut World, resources: &mut Resources) {
|
|||
.get_mut::<AssetStorage<StandardMaterial>>()
|
||||
.unwrap();
|
||||
|
||||
let cube_handle = mesh_storage.add(Mesh::load(MeshType::Cube));
|
||||
let cube_handle = mesh_storage.add(Mesh::from(shape::Cube));
|
||||
let cube_material_handle = material_storage.add(StandardMaterial {
|
||||
albedo: Color::rgb(0.5, 0.4, 0.3),
|
||||
..Default::default()
|
||||
|
|
|
@ -12,8 +12,8 @@ fn setup(world: &mut World, resources: &mut Resources) {
|
|||
env_logger::init();
|
||||
// create a cube and a plane mesh
|
||||
let mut mesh_storage = resources.get_mut::<AssetStorage<Mesh>>().unwrap();
|
||||
let cube_handle = mesh_storage.add(Mesh::load(MeshType::Cube));
|
||||
let plane_handle = mesh_storage.add(Mesh::load(MeshType::Plane { size: 10.0 }));
|
||||
let cube_handle = mesh_storage.add(Mesh::from(shape::Cube));
|
||||
let plane_handle = mesh_storage.add(Mesh::from(shape::Plane { size: 10.0 }));
|
||||
|
||||
// create materials for our cube and plane
|
||||
let mut material_storage = resources
|
||||
|
|
|
@ -87,7 +87,7 @@ fn setup(world: &mut World, resources: &mut Resources) {
|
|||
let pipeline_handle = pipeline_storage.get_named("MyMaterial").unwrap();
|
||||
|
||||
let mut mesh_storage = resources.get_mut::<AssetStorage<Mesh>>().unwrap();
|
||||
let cube_handle = mesh_storage.add(Mesh::load(MeshType::Cube));
|
||||
let cube_handle = mesh_storage.add(Mesh::from(shape::Cube));
|
||||
|
||||
world
|
||||
.build()
|
||||
|
|
|
@ -103,7 +103,7 @@ fn setup(world: &mut World, resources: &mut Resources) {
|
|||
let pipeline_handle = pipeline_storage.get_named("MyMaterial").unwrap();
|
||||
|
||||
let mut mesh_storage = resources.get_mut::<AssetStorage<Mesh>>().unwrap();
|
||||
let cube_handle = mesh_storage.add(Mesh::load(MeshType::Cube));
|
||||
let cube_handle = mesh_storage.add(Mesh::from(shape::Cube));
|
||||
|
||||
world
|
||||
.build()
|
||||
|
|
|
@ -33,8 +33,8 @@ fn setup(world: &mut World, resources: &mut Resources) {
|
|||
let mut material_storage = resources
|
||||
.get_mut::<AssetStorage<StandardMaterial>>()
|
||||
.unwrap();
|
||||
let cube_handle = mesh_storage.add(Mesh::load(MeshType::Cube));
|
||||
let plane_handle = mesh_storage.add(Mesh::load(MeshType::Plane { size: 10.0 }));
|
||||
let cube_handle = mesh_storage.add(Mesh::from(shape::Cube));
|
||||
let plane_handle = mesh_storage.add(Mesh::from(shape::Plane { size: 10.0 }));
|
||||
let cube_material_handle = material_storage.add(StandardMaterial {
|
||||
albedo: Color::rgb(0.5, 0.4, 0.3),
|
||||
..Default::default()
|
||||
|
|
|
@ -15,7 +15,7 @@ pub fn startup_system() -> Box<dyn Schedulable> {
|
|||
.write_resource::<AssetStorage<Mesh>>()
|
||||
.write_resource::<AssetStorage<StandardMaterial>>()
|
||||
.build(move |command_buffer, _, (meshes, materials), _| {
|
||||
let cube_handle = meshes.add(Mesh::load(MeshType::Cube));
|
||||
let cube_handle = meshes.add(Mesh::from(shape::Cube));
|
||||
let cube_material_handle = materials.add(StandardMaterial {
|
||||
albedo: Color::rgb(0.5, 0.4, 0.3),
|
||||
..Default::default()
|
||||
|
|
|
@ -20,7 +20,7 @@ fn setup(world: &mut World, resources: &mut Resources) {
|
|||
// create a new quad mesh. this is what we will apply the texture to
|
||||
let mut mesh_storage = resources.get_mut::<AssetStorage<Mesh>>().unwrap();
|
||||
let quad_width = 8.0;
|
||||
let quad_handle = mesh_storage.add(Mesh::load(MeshType::Quad {
|
||||
let quad_handle = mesh_storage.add(Mesh::from(shape::Quad {
|
||||
size: Vec2::new(quad_width, quad_width * aspect),
|
||||
}));
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ fn setup(world: &mut World, resources: &mut Resources) {
|
|||
let mut material_storage = resources
|
||||
.get_mut::<AssetStorage<StandardMaterial>>()
|
||||
.unwrap();
|
||||
let cube_handle = mesh_storage.add(Mesh::load(MeshType::Cube));
|
||||
let cube_handle = mesh_storage.add(Mesh::from(shape::Cube));
|
||||
let cube_material_handle = material_storage.add(StandardMaterial {
|
||||
albedo: Color::rgb(0.5, 0.3, 0.3),
|
||||
..Default::default()
|
||||
|
|
|
@ -47,6 +47,8 @@ pub use bevy_core as core;
|
|||
pub use bevy_derive as derive;
|
||||
#[cfg(feature = "diagnostic")]
|
||||
pub use bevy_diagnostic as diagnostic;
|
||||
#[cfg(feature = "gltf")]
|
||||
pub use bevy_gltf as gltf;
|
||||
#[cfg(feature = "input")]
|
||||
pub use bevy_input as input;
|
||||
#[cfg(feature = "render")]
|
||||
|
|
|
@ -12,7 +12,7 @@ pub use crate::diagnostic::DiagnosticsPlugin;
|
|||
#[cfg(feature = "render")]
|
||||
pub use crate::render::{
|
||||
entity::*,
|
||||
mesh::{Mesh, MeshType},
|
||||
mesh::{Mesh, shape},
|
||||
pipeline::PipelineDescriptor,
|
||||
render_graph::RenderGraph,
|
||||
render_resource::{resource_name, resource_providers::UniformResourceProvider, AssetBatchers},
|
||||
|
|
Loading…
Reference in a new issue