mirror of
https://github.com/bevyengine/bevy
synced 2024-11-21 20:23:28 +00:00
initial ui pass
This commit is contained in:
parent
edd0bca622
commit
eb1233d9f0
15 changed files with 329 additions and 18 deletions
|
@ -168,10 +168,17 @@ fn main() {
|
||||||
|
|
||||||
let cube = Mesh::load(MeshType::Cube);
|
let cube = Mesh::load(MeshType::Cube);
|
||||||
let plane = Mesh::load(MeshType::Plane{ size: 24.5 });
|
let plane = Mesh::load(MeshType::Plane{ size: 24.5 });
|
||||||
|
let quad = Mesh::load(MeshType::Quad {
|
||||||
|
north_west: math::vec2(100.0, 200.0),
|
||||||
|
north_east: math::vec2(200.0, 200.0),
|
||||||
|
south_west: math::vec2(100.0, 100.0),
|
||||||
|
south_east: math::vec2(200.0, 100.0),
|
||||||
|
});
|
||||||
let mut mesh_storage = AssetStorage::<Mesh, MeshType>::new();
|
let mut mesh_storage = AssetStorage::<Mesh, MeshType>::new();
|
||||||
|
|
||||||
let _cube_handle = mesh_storage.add(cube, "cube");
|
let _cube_handle = mesh_storage.add(cube, "cube");
|
||||||
let plane_handle = mesh_storage.add(plane, "plane");
|
let plane_handle = mesh_storage.add(plane, "plane");
|
||||||
|
let quad_handle = mesh_storage.add(quad, "quad");
|
||||||
world.resources.insert(mesh_storage);
|
world.resources.insert(mesh_storage);
|
||||||
|
|
||||||
let transform_system_bundle = transform_system_bundle::build(&mut world);
|
let transform_system_bundle = transform_system_bundle::build(&mut world);
|
||||||
|
@ -254,6 +261,7 @@ fn main() {
|
||||||
far: 1000.0,
|
far: 1000.0,
|
||||||
aspect_ratio: 1.0,
|
aspect_ratio: 1.0,
|
||||||
}),
|
}),
|
||||||
|
ActiveCamera,
|
||||||
LocalToWorld(Mat4::look_at_rh(
|
LocalToWorld(Mat4::look_at_rh(
|
||||||
Vec3::new(6.0, -40.0, 20.0),
|
Vec3::new(6.0, -40.0, 20.0),
|
||||||
Vec3::new(0.0, 0.0, 0.0),
|
Vec3::new(0.0, 0.0, 0.0),
|
||||||
|
@ -262,6 +270,31 @@ fn main() {
|
||||||
)
|
)
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
world.insert((), vec![
|
||||||
|
|
||||||
|
// camera
|
||||||
|
(
|
||||||
|
Camera::new(CameraType::Orthographic {
|
||||||
|
left: 0.0,
|
||||||
|
right: 0.0,
|
||||||
|
bottom: 0.0,
|
||||||
|
top: 0.0,
|
||||||
|
near: 0.0,
|
||||||
|
far: 1.0,
|
||||||
|
}),
|
||||||
|
ActiveCamera2d,
|
||||||
|
)
|
||||||
|
]);
|
||||||
|
|
||||||
|
world.insert((), vec![
|
||||||
|
|
||||||
|
// camera
|
||||||
|
(
|
||||||
|
quad_handle,
|
||||||
|
Mesh2d,
|
||||||
|
)
|
||||||
|
]);
|
||||||
|
|
||||||
let mut rng = StdRng::from_entropy();
|
let mut rng = StdRng::from_entropy();
|
||||||
for _ in 0 .. 70000 {
|
for _ in 0 .. 70000 {
|
||||||
create_person(&mut world, _cube_handle.clone(),
|
create_person(&mut world, _cube_handle.clone(),
|
||||||
|
|
|
@ -22,12 +22,14 @@ impl Application {
|
||||||
fn add_default_passes(&mut self) {
|
fn add_default_passes(&mut self) {
|
||||||
self.render_graph.add_render_resource_manager(Box::new(render_resources::MaterialResourceManager));
|
self.render_graph.add_render_resource_manager(Box::new(render_resources::MaterialResourceManager));
|
||||||
self.render_graph.add_render_resource_manager(Box::new(render_resources::LightResourceManager::new(10)));
|
self.render_graph.add_render_resource_manager(Box::new(render_resources::LightResourceManager::new(10)));
|
||||||
self.render_graph.add_render_resource_manager(Box::new(render_resources::CameraResourceManager));
|
self.render_graph.add_render_resource_manager(Box::new(render_resources::GlobalResourceManager));
|
||||||
|
self.render_graph.add_render_resource_manager(Box::new(render_resources::Global2dResourceManager));
|
||||||
|
|
||||||
let depth_format = wgpu::TextureFormat::Depth32Float;
|
let depth_format = wgpu::TextureFormat::Depth32Float;
|
||||||
self.render_graph.set_pass("forward", Box::new(ForwardPass::new(depth_format)));
|
self.render_graph.set_pass("forward", Box::new(ForwardPass::new(depth_format)));
|
||||||
self.render_graph.set_pipeline("forward", "forward", Box::new(ForwardPipeline::new()));
|
self.render_graph.set_pipeline("forward", "forward", Box::new(ForwardPipeline::new()));
|
||||||
self.render_graph.set_pipeline("forward", "forward_instanced", Box::new(ForwardInstancedPipeline::new(depth_format)));
|
self.render_graph.set_pipeline("forward", "forward_instanced", Box::new(ForwardInstancedPipeline::new(depth_format)));
|
||||||
|
self.render_graph.set_pipeline("forward", "ui", Box::new(UiPipeline::new()));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(&mut self) {
|
fn update(&mut self) {
|
||||||
|
|
|
@ -1,12 +1,23 @@
|
||||||
use crate::math::Mat4;
|
use crate::math::Mat4;
|
||||||
|
|
||||||
|
pub struct ActiveCamera;
|
||||||
|
pub struct ActiveCamera2d;
|
||||||
|
|
||||||
pub enum CameraType {
|
pub enum CameraType {
|
||||||
Projection {
|
Projection {
|
||||||
fov: f32,
|
fov: f32,
|
||||||
aspect_ratio: f32,
|
aspect_ratio: f32,
|
||||||
near: f32,
|
near: f32,
|
||||||
far: f32
|
far: f32
|
||||||
}
|
},
|
||||||
|
Orthographic {
|
||||||
|
left: f32,
|
||||||
|
right: f32,
|
||||||
|
bottom: f32,
|
||||||
|
top: f32,
|
||||||
|
near: f32,
|
||||||
|
far: f32,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Camera {
|
pub struct Camera {
|
||||||
|
@ -26,18 +37,29 @@ impl Camera {
|
||||||
match &mut self.camera_type {
|
match &mut self.camera_type {
|
||||||
CameraType::Projection { aspect_ratio, fov, near, far } => {
|
CameraType::Projection { aspect_ratio, fov, near, far } => {
|
||||||
*aspect_ratio = width as f32 / height as f32;
|
*aspect_ratio = width as f32 / height as f32;
|
||||||
self.view_matrix = get_projection_matrix(*fov, *aspect_ratio, *near, *far)
|
self.view_matrix = get_perspective_projection_matrix(*fov, *aspect_ratio, *near, *far)
|
||||||
|
},
|
||||||
|
CameraType::Orthographic { left, right, bottom, top, near, far} => {
|
||||||
|
*right = width as f32;
|
||||||
|
*top = height as f32;
|
||||||
|
self.view_matrix = get_orthographic_projection_matrix(*left, *right, *bottom, *top, *near, *far)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_projection_matrix(fov: f32, aspect_ratio: f32, near: f32, far: f32) -> Mat4 {
|
pub fn get_perspective_projection_matrix(fov: f32, aspect_ratio: f32, near: f32, far: f32) -> Mat4 {
|
||||||
let projection = Mat4::perspective_rh_gl(fov, aspect_ratio, near, far);
|
let projection = Mat4::perspective_rh_gl(fov, aspect_ratio, near, far);
|
||||||
|
|
||||||
opengl_to_wgpu_matrix() * projection
|
opengl_to_wgpu_matrix() * projection
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_orthographic_projection_matrix(left: f32, right: f32, bottom: f32, top: f32, near: f32, far: f32) -> Mat4 {
|
||||||
|
let projection = Mat4::orthographic_rh_gl(left, right, bottom, top, near, far);
|
||||||
|
|
||||||
|
opengl_to_wgpu_matrix() * projection
|
||||||
|
}
|
||||||
|
|
||||||
pub fn opengl_to_wgpu_matrix() -> Mat4 {
|
pub fn opengl_to_wgpu_matrix() -> Mat4 {
|
||||||
Mat4::from_cols_array(&[
|
Mat4::from_cols_array(&[
|
||||||
1.0, 0.0, 0.0, 0.0,
|
1.0, 0.0, 0.0, 0.0,
|
||||||
|
|
|
@ -20,7 +20,7 @@ pub struct LightRaw {
|
||||||
|
|
||||||
impl LightRaw {
|
impl LightRaw {
|
||||||
pub fn from(light: &Light, transform: &math::Mat4, translation: &Translation) -> LightRaw {
|
pub fn from(light: &Light, transform: &math::Mat4, translation: &Translation) -> LightRaw {
|
||||||
let proj = camera::get_projection_matrix(light.fov, 1.0, light.depth.start, light.depth.end) * *transform;
|
let proj = camera::get_perspective_projection_matrix(light.fov, 1.0, light.depth.start, light.depth.end) * *transform;
|
||||||
let (x, y, z) = translation.0.into();
|
let (x, y, z) = translation.0.into();
|
||||||
LightRaw {
|
LightRaw {
|
||||||
proj: proj.to_cols_array_2d(),
|
proj: proj.to_cols_array_2d(),
|
||||||
|
|
|
@ -1,12 +1,21 @@
|
||||||
use crate::{vertex::Vertex, asset::Asset};
|
use crate::{vertex::Vertex, asset::Asset, math::*};
|
||||||
use wgpu::{Buffer, Device};
|
use wgpu::{Buffer, Device};
|
||||||
use zerocopy::AsBytes;
|
use zerocopy::AsBytes;
|
||||||
|
|
||||||
|
// TODO: this is pretty dirty. work out a cleaner way to distinguish between 3d and 2d meshes
|
||||||
|
pub struct Mesh2d;
|
||||||
|
|
||||||
pub enum MeshType {
|
pub enum MeshType {
|
||||||
Cube,
|
Cube,
|
||||||
Plane {
|
Plane {
|
||||||
size: f32
|
size: f32
|
||||||
},
|
},
|
||||||
|
Quad {
|
||||||
|
north_west: Vec2,
|
||||||
|
north_east: Vec2,
|
||||||
|
south_west: Vec2,
|
||||||
|
south_east: Vec2,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Mesh {
|
pub struct Mesh {
|
||||||
|
@ -33,6 +42,7 @@ impl Asset<MeshType> for Mesh {
|
||||||
let (vertices, indices) = match descriptor {
|
let (vertices, indices) = match descriptor {
|
||||||
MeshType::Cube => create_cube(),
|
MeshType::Cube => create_cube(),
|
||||||
MeshType::Plane { size } => create_plane(size),
|
MeshType::Plane { size } => create_plane(size),
|
||||||
|
MeshType::Quad { north_west, north_east, south_west, south_east } => create_quad(north_west, north_east, south_west, south_east),
|
||||||
};
|
};
|
||||||
|
|
||||||
Mesh {
|
Mesh {
|
||||||
|
@ -44,6 +54,18 @@ impl Asset<MeshType> for Mesh {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn create_quad(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])),
|
||||||
|
Vertex::from(([north_west.x(), north_west.y(), 0.0], [0.0, 0.0, 1.0])),
|
||||||
|
Vertex::from(([north_east.x(), north_east.y(), 0.0], [0.0, 0.0, 1.0])),
|
||||||
|
Vertex::from(([south_east.x(), south_east.y(), 0.0], [0.0, 0.0, 1.0])),
|
||||||
|
];
|
||||||
|
|
||||||
|
let index_data: &[u16] = &[ 0, 1, 2, 0, 2, 3 ];
|
||||||
|
return (vertex_data.to_vec(), index_data.to_vec());
|
||||||
|
}
|
||||||
|
|
||||||
pub fn create_cube() -> (Vec<Vertex>, Vec<u16>) {
|
pub fn create_cube() -> (Vec<Vertex>, Vec<u16>) {
|
||||||
let vertex_data = [
|
let vertex_data = [
|
||||||
// top (0, 0, 1)
|
// top (0, 0, 1)
|
||||||
|
@ -98,6 +120,7 @@ pub fn create_plane(size: f32) -> (Vec<Vertex>, Vec<u16>) {
|
||||||
Vertex::from(([-size, size, 0.0], [0.0, 0.0, 1.0])),
|
Vertex::from(([-size, size, 0.0], [0.0, 0.0, 1.0])),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// TODO: make sure this order is correct
|
||||||
let index_data: &[u16] = &[0, 1, 2, 2, 1, 3];
|
let index_data: &[u16] = &[0, 1, 2, 2, 1, 3];
|
||||||
|
|
||||||
(vertex_data.to_vec(), index_data.to_vec())
|
(vertex_data.to_vec(), index_data.to_vec())
|
||||||
|
|
|
@ -127,7 +127,7 @@ impl Pipeline for ForwardPipeline {
|
||||||
let mut mesh_query =
|
let mut mesh_query =
|
||||||
<(Read<Material>, Read<Handle<Mesh>>)>::query()
|
<(Read<Material>, Read<Handle<Mesh>>)>::query()
|
||||||
.filter(!component::<Instanced>());
|
.filter(!component::<Instanced>());
|
||||||
for (entity, mesh) in mesh_query.iter_immutable(world) {
|
for (material, mesh) in mesh_query.iter_immutable(world) {
|
||||||
let current_mesh_id = *mesh.id.read().unwrap();
|
let current_mesh_id = *mesh.id.read().unwrap();
|
||||||
|
|
||||||
let mut should_load_mesh = last_mesh_id == None;
|
let mut should_load_mesh = last_mesh_id == None;
|
||||||
|
@ -144,7 +144,7 @@ impl Pipeline for ForwardPipeline {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(ref mesh_asset) = mesh_storage.get(*mesh.id.read().unwrap()) {
|
if let Some(ref mesh_asset) = mesh_storage.get(*mesh.id.read().unwrap()) {
|
||||||
pass.set_bind_group(1, entity.bind_group.as_ref().unwrap(), &[]);
|
pass.set_bind_group(1, material.bind_group.as_ref().unwrap(), &[]);
|
||||||
pass.draw_indexed(0 .. mesh_asset.indices.len() as u32, 0, 0 .. 1);
|
pass.draw_indexed(0 .. mesh_asset.indices.len() as u32, 0, 0 .. 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -147,10 +147,10 @@ impl Pipeline for ForwardShadowPassNew {
|
||||||
pass.set_bind_group(0, self.bind_group.as_ref().unwrap(), &[]);
|
pass.set_bind_group(0, self.bind_group.as_ref().unwrap(), &[]);
|
||||||
|
|
||||||
let mut mesh_storage = world.resources.get_mut::<AssetStorage<Mesh, MeshType>>().unwrap();
|
let mut mesh_storage = world.resources.get_mut::<AssetStorage<Mesh, MeshType>>().unwrap();
|
||||||
for (entity, mesh) in mesh_query.iter_immutable(world) {
|
for (material, mesh) in mesh_query.iter_immutable(world) {
|
||||||
if let Some(mesh_asset) = mesh_storage.get(*mesh.id.read().unwrap()) {
|
if let Some(mesh_asset) = mesh_storage.get(*mesh.id.read().unwrap()) {
|
||||||
mesh_asset.setup_buffers(&render_graph.device);
|
mesh_asset.setup_buffers(&render_graph.device);
|
||||||
pass.set_bind_group(1, entity.bind_group.as_ref().unwrap(), &[]);
|
pass.set_bind_group(1, material.bind_group.as_ref().unwrap(), &[]);
|
||||||
pass.set_index_buffer(mesh_asset.index_buffer.as_ref().unwrap(), 0);
|
pass.set_index_buffer(mesh_asset.index_buffer.as_ref().unwrap(), 0);
|
||||||
pass.set_vertex_buffers(0, &[(&mesh_asset.vertex_buffer.as_ref().unwrap(), 0)]);
|
pass.set_vertex_buffers(0, &[(&mesh_asset.vertex_buffer.as_ref().unwrap(), 0)]);
|
||||||
pass.draw_indexed(0 .. mesh_asset.indices.len() as u32, 0, 0 .. 1);
|
pass.draw_indexed(0 .. mesh_asset.indices.len() as u32, 0, 0 .. 1);
|
||||||
|
|
|
@ -3,8 +3,10 @@ mod forward;
|
||||||
mod forward_shadow;
|
mod forward_shadow;
|
||||||
mod forward_instanced;
|
mod forward_instanced;
|
||||||
mod shadow;
|
mod shadow;
|
||||||
|
mod ui;
|
||||||
|
|
||||||
pub use forward::{ForwardUniforms, ForwardPipeline, ForwardPass};
|
pub use forward::{ForwardUniforms, ForwardPipeline, ForwardPass};
|
||||||
pub use forward_shadow::{ForwardShadowPassNew};
|
pub use forward_shadow::{ForwardShadowPassNew};
|
||||||
pub use forward_instanced::ForwardInstancedPipeline;
|
pub use forward_instanced::ForwardInstancedPipeline;
|
||||||
pub use shadow::ShadowPass;
|
pub use shadow::ShadowPass;
|
||||||
|
pub use ui::UiPipeline;
|
|
@ -146,11 +146,11 @@ impl Pipeline for ShadowPipeline {
|
||||||
.resources
|
.resources
|
||||||
.get_mut::<AssetStorage<Mesh, MeshType>>()
|
.get_mut::<AssetStorage<Mesh, MeshType>>()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
for (entity, mesh) in mesh_query.iter_immutable(world) {
|
for (material, mesh) in mesh_query.iter_immutable(world) {
|
||||||
if let Some(mesh_asset) = mesh_storage.get(*mesh.id.read().unwrap()) {
|
if let Some(mesh_asset) = mesh_storage.get(*mesh.id.read().unwrap()) {
|
||||||
mesh_asset.setup_buffers(&render_graph.device);
|
mesh_asset.setup_buffers(&render_graph.device);
|
||||||
|
|
||||||
pass.set_bind_group(1, entity.bind_group.as_ref().unwrap(), &[]);
|
pass.set_bind_group(1, material.bind_group.as_ref().unwrap(), &[]);
|
||||||
pass.set_index_buffer(&mesh_asset.index_buffer.as_ref().unwrap(), 0);
|
pass.set_index_buffer(&mesh_asset.index_buffer.as_ref().unwrap(), 0);
|
||||||
pass.set_vertex_buffers(0, &[(&mesh_asset.vertex_buffer.as_ref().unwrap(), 0)]);
|
pass.set_vertex_buffers(0, &[(&mesh_asset.vertex_buffer.as_ref().unwrap(), 0)]);
|
||||||
pass.draw_indexed(0..mesh_asset.indices.len() as u32, 0, 0..1);
|
pass.draw_indexed(0..mesh_asset.indices.len() as u32, 0, 0..1);
|
||||||
|
|
149
src/render/passes/ui/mod.rs
Normal file
149
src/render/passes/ui/mod.rs
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
use crate::{render::*, asset::*, render::mesh::*};
|
||||||
|
use legion::prelude::*;
|
||||||
|
use wgpu::SwapChainOutput;
|
||||||
|
|
||||||
|
pub struct UiPipeline {
|
||||||
|
pub pipeline: Option<wgpu::RenderPipeline>,
|
||||||
|
pub depth_format: wgpu::TextureFormat,
|
||||||
|
pub bind_group: Option<wgpu::BindGroup>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UiPipeline {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
UiPipeline {
|
||||||
|
pipeline: None,
|
||||||
|
bind_group: None,
|
||||||
|
depth_format: wgpu::TextureFormat::Depth32Float
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Pipeline for UiPipeline {
|
||||||
|
fn initialize(&mut self, render_graph: &mut RenderGraphData, _: &mut World) {
|
||||||
|
let vs_bytes = shader::load_glsl(
|
||||||
|
include_str!("ui.vert"),
|
||||||
|
shader::ShaderStage::Vertex,
|
||||||
|
);
|
||||||
|
let fs_bytes = shader::load_glsl(
|
||||||
|
include_str!("ui.frag"),
|
||||||
|
shader::ShaderStage::Fragment,
|
||||||
|
);
|
||||||
|
|
||||||
|
let bind_group_layout =
|
||||||
|
render_graph.device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||||
|
bindings: &[
|
||||||
|
wgpu::BindGroupLayoutBinding {
|
||||||
|
binding: 0, // global_2d
|
||||||
|
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||||
|
ty: wgpu::BindingType::UniformBuffer { dynamic: false },
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
self.bind_group = Some({
|
||||||
|
|
||||||
|
let global_2d_uniform_buffer = render_graph.get_uniform_buffer(render_resources::GLOBAL_2D_UNIFORM_BUFFER_NAME).unwrap();
|
||||||
|
|
||||||
|
// Create bind group
|
||||||
|
render_graph.device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||||
|
layout: &bind_group_layout,
|
||||||
|
bindings: &[
|
||||||
|
wgpu::Binding {
|
||||||
|
binding: 0,
|
||||||
|
resource: global_2d_uniform_buffer.get_binding_resource(),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
let pipeline_layout = render_graph.device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||||
|
bind_group_layouts: &[&bind_group_layout],
|
||||||
|
});
|
||||||
|
|
||||||
|
let vertex_buffer_descriptor = get_vertex_buffer_descriptor();
|
||||||
|
|
||||||
|
let vs_module = render_graph.device.create_shader_module(&vs_bytes);
|
||||||
|
let fs_module = render_graph.device.create_shader_module(&fs_bytes);
|
||||||
|
|
||||||
|
self.pipeline = Some(render_graph.device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||||
|
layout: &pipeline_layout,
|
||||||
|
vertex_stage: wgpu::ProgrammableStageDescriptor {
|
||||||
|
module: &vs_module,
|
||||||
|
entry_point: "main",
|
||||||
|
},
|
||||||
|
fragment_stage: Some(wgpu::ProgrammableStageDescriptor {
|
||||||
|
module: &fs_module,
|
||||||
|
entry_point: "main",
|
||||||
|
}),
|
||||||
|
rasterization_state: Some(wgpu::RasterizationStateDescriptor {
|
||||||
|
front_face: wgpu::FrontFace::Ccw,
|
||||||
|
cull_mode: wgpu::CullMode::None,
|
||||||
|
depth_bias: 0,
|
||||||
|
depth_bias_slope_scale: 0.0,
|
||||||
|
depth_bias_clamp: 0.0,
|
||||||
|
}),
|
||||||
|
primitive_topology: wgpu::PrimitiveTopology::TriangleList,
|
||||||
|
color_states: &[
|
||||||
|
wgpu::ColorStateDescriptor {
|
||||||
|
format: render_graph.swap_chain_descriptor.format,
|
||||||
|
color_blend: wgpu::BlendDescriptor::REPLACE,
|
||||||
|
alpha_blend: wgpu::BlendDescriptor::REPLACE,
|
||||||
|
write_mask: wgpu::ColorWrite::ALL,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
depth_stencil_state: Some(wgpu::DepthStencilStateDescriptor {
|
||||||
|
format: self.depth_format,
|
||||||
|
depth_write_enabled: true,
|
||||||
|
depth_compare: wgpu::CompareFunction::Less,
|
||||||
|
stencil_front: wgpu::StencilStateFaceDescriptor::IGNORE,
|
||||||
|
stencil_back: wgpu::StencilStateFaceDescriptor::IGNORE,
|
||||||
|
stencil_read_mask: 0,
|
||||||
|
stencil_write_mask: 0,
|
||||||
|
}),
|
||||||
|
index_format: wgpu::IndexFormat::Uint16,
|
||||||
|
vertex_buffers: &[vertex_buffer_descriptor],
|
||||||
|
sample_count: 1,
|
||||||
|
sample_mask: !0,
|
||||||
|
alpha_to_coverage_enabled: false,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render(&mut self, render_graph: &RenderGraphData, pass: &mut wgpu::RenderPass, _: &SwapChainOutput, world: &mut World) {
|
||||||
|
pass.set_bind_group(0, self.bind_group.as_ref().unwrap(), &[]);
|
||||||
|
|
||||||
|
let mut mesh_storage = world.resources.get_mut::<AssetStorage<Mesh, MeshType>>().unwrap();
|
||||||
|
let mut last_mesh_id = None;
|
||||||
|
let mut mesh_query =
|
||||||
|
<(Read<Handle<Mesh>>, Read<Mesh2d>)>::query()
|
||||||
|
.filter(!component::<Instanced>());
|
||||||
|
for (mesh, _) in mesh_query.iter_immutable(world) {
|
||||||
|
let current_mesh_id = *mesh.id.read().unwrap();
|
||||||
|
|
||||||
|
let mut should_load_mesh = last_mesh_id == None;
|
||||||
|
if let Some(last) = last_mesh_id {
|
||||||
|
should_load_mesh = last != current_mesh_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
if should_load_mesh {
|
||||||
|
if let Some(mesh_asset) = mesh_storage.get(*mesh.id.read().unwrap()) {
|
||||||
|
mesh_asset.setup_buffers(&render_graph.device);
|
||||||
|
pass.set_index_buffer(mesh_asset.index_buffer.as_ref().unwrap(), 0);
|
||||||
|
pass.set_vertex_buffers(0, &[(&mesh_asset.vertex_buffer.as_ref().unwrap(), 0)]);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(ref mesh_asset) = mesh_storage.get(*mesh.id.read().unwrap()) {
|
||||||
|
pass.draw_indexed(0 .. mesh_asset.indices.len() as u32, 0, 0 .. 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
last_mesh_id = Some(current_mesh_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn resize(&mut self, _: &RenderGraphData) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_pipeline(&self) -> &wgpu::RenderPipeline {
|
||||||
|
self.pipeline.as_ref().unwrap()
|
||||||
|
}
|
||||||
|
}
|
10
src/render/passes/ui/ui.frag
Normal file
10
src/render/passes/ui/ui.frag
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
#version 450
|
||||||
|
|
||||||
|
layout(location = 0) in vec3 v_Normal;
|
||||||
|
layout(location = 1) in vec4 v_Position;
|
||||||
|
|
||||||
|
layout(location = 0) out vec4 o_Target;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
o_Target = vec4(1.0, 0.0, 0.0, 1.0);
|
||||||
|
}
|
17
src/render/passes/ui/ui.vert
Normal file
17
src/render/passes/ui/ui.vert
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
#version 450
|
||||||
|
|
||||||
|
layout(location = 0) in vec4 a_Pos;
|
||||||
|
layout(location = 1) in vec4 a_Normal;
|
||||||
|
|
||||||
|
layout(location = 0) out vec3 v_Normal;
|
||||||
|
layout(location = 1) out vec4 v_Position;
|
||||||
|
|
||||||
|
layout(set = 0, binding = 0) uniform Globals {
|
||||||
|
mat4 u_ViewProj;
|
||||||
|
};
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
v_Normal = vec3(a_Normal.xyz);
|
||||||
|
v_Position = vec4(a_Pos);
|
||||||
|
gl_Position = u_ViewProj * v_Position;
|
||||||
|
}
|
51
src/render/render_resources/global_2d_resource_manager.rs
Normal file
51
src/render/render_resources/global_2d_resource_manager.rs
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
use crate::{render::*, math};
|
||||||
|
|
||||||
|
use legion::prelude::*;
|
||||||
|
use std::mem;
|
||||||
|
use zerocopy::{AsBytes, FromBytes};
|
||||||
|
|
||||||
|
pub const GLOBAL_2D_UNIFORM_BUFFER_NAME: &str = "global_2d";
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Clone, Copy, AsBytes, FromBytes)]
|
||||||
|
pub struct Global2dUniforms {
|
||||||
|
pub projection_matrix: [[f32; 4]; 4],
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Global2dResourceManager;
|
||||||
|
|
||||||
|
impl RenderResourceManager for Global2dResourceManager {
|
||||||
|
fn initialize(&self, render_graph: &mut RenderGraphData, _: &mut World) {
|
||||||
|
let uniform_size = mem::size_of::<Global2dUniforms>() as wgpu::BufferAddress;
|
||||||
|
let ui_uniforms = Global2dUniforms {
|
||||||
|
projection_matrix: math::Mat4::identity().to_cols_array_2d(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let buffer = render_graph.device.create_buffer_with_data(
|
||||||
|
ui_uniforms.as_bytes(),
|
||||||
|
wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST,
|
||||||
|
);
|
||||||
|
|
||||||
|
let uniform_buffer = UniformBuffer {
|
||||||
|
buffer: buffer,
|
||||||
|
size: uniform_size,
|
||||||
|
};
|
||||||
|
render_graph.set_uniform_buffer(GLOBAL_2D_UNIFORM_BUFFER_NAME, uniform_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update<'a>(&mut self, _render_graph: &mut RenderGraphData, _encoder: &'a mut wgpu::CommandEncoder, _world: &mut World) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fn resize<'a>(&self, render_graph: &mut RenderGraphData, encoder: &'a mut wgpu::CommandEncoder, world: &mut World) {
|
||||||
|
for (mut camera, _) in <(Write<Camera>, Read<ActiveCamera2d>)>::query().iter(world) {
|
||||||
|
camera.update(render_graph.swap_chain_descriptor.width, render_graph.swap_chain_descriptor.height);
|
||||||
|
let camera_matrix: [[f32; 4]; 4] = camera.view_matrix.to_cols_array_2d();
|
||||||
|
let matrix_size = mem::size_of::<[[f32; 4]; 4]>() as u64;
|
||||||
|
let temp_camera_buffer =
|
||||||
|
render_graph.device.create_buffer_with_data(camera_matrix.as_bytes(), wgpu::BufferUsage::COPY_SRC);
|
||||||
|
let global_2d_uniform_buffer = render_graph.get_uniform_buffer(GLOBAL_2D_UNIFORM_BUFFER_NAME).unwrap();
|
||||||
|
encoder.copy_buffer_to_buffer(&temp_camera_buffer, 0, &global_2d_uniform_buffer.buffer, 0, matrix_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,9 +6,9 @@ use zerocopy::AsBytes;
|
||||||
|
|
||||||
pub const FORWARD_UNIFORM_BUFFER_NAME: &str = "forward";
|
pub const FORWARD_UNIFORM_BUFFER_NAME: &str = "forward";
|
||||||
|
|
||||||
pub struct CameraResourceManager;
|
pub struct GlobalResourceManager;
|
||||||
|
|
||||||
impl RenderResourceManager for CameraResourceManager {
|
impl RenderResourceManager for GlobalResourceManager {
|
||||||
fn initialize(&self, render_graph: &mut RenderGraphData, world: &mut World) {
|
fn initialize(&self, render_graph: &mut RenderGraphData, world: &mut World) {
|
||||||
let light_count = <Read<Light>>::query().iter_immutable(world).count();
|
let light_count = <Read<Light>>::query().iter_immutable(world).count();
|
||||||
let forward_uniforms = ForwardUniforms {
|
let forward_uniforms = ForwardUniforms {
|
||||||
|
@ -32,7 +32,7 @@ impl RenderResourceManager for CameraResourceManager {
|
||||||
|
|
||||||
}
|
}
|
||||||
fn resize<'a>(&self, render_graph: &mut RenderGraphData, encoder: &'a mut wgpu::CommandEncoder, world: &mut World) {
|
fn resize<'a>(&self, render_graph: &mut RenderGraphData, encoder: &'a mut wgpu::CommandEncoder, world: &mut World) {
|
||||||
for (mut camera, local_to_world) in <(Write<Camera>, Read<LocalToWorld>)>::query().iter(world) {
|
for (mut camera, local_to_world, _) in <(Write<Camera>, Read<LocalToWorld>, Read<ActiveCamera>)>::query().iter(world) {
|
||||||
camera.update(render_graph.swap_chain_descriptor.width, render_graph.swap_chain_descriptor.height);
|
camera.update(render_graph.swap_chain_descriptor.width, render_graph.swap_chain_descriptor.height);
|
||||||
let camera_matrix: [[f32; 4]; 4] = (camera.view_matrix * local_to_world.0).to_cols_array_2d();
|
let camera_matrix: [[f32; 4]; 4] = (camera.view_matrix * local_to_world.0).to_cols_array_2d();
|
||||||
let matrix_size = mem::size_of::<[[f32; 4]; 4]>() as u64;
|
let matrix_size = mem::size_of::<[[f32; 4]; 4]>() as u64;
|
|
@ -1,7 +1,9 @@
|
||||||
mod light_resource_manager;
|
mod light_resource_manager;
|
||||||
mod camera_resource_manager;
|
mod global_resource_manager;
|
||||||
|
mod global_2d_resource_manager;
|
||||||
mod material_resource_manager;
|
mod material_resource_manager;
|
||||||
|
|
||||||
pub use light_resource_manager::*;
|
pub use light_resource_manager::*;
|
||||||
pub use camera_resource_manager::*;
|
pub use global_resource_manager::*;
|
||||||
|
pub use global_2d_resource_manager::*;
|
||||||
pub use material_resource_manager::*;
|
pub use material_resource_manager::*;
|
Loading…
Reference in a new issue