Skip to content

Commit

Permalink
Drawing wireframes
Browse files Browse the repository at this point in the history
  • Loading branch information
Neo-Zhixing committed Feb 6, 2021
1 parent 506f224 commit ae27107
Show file tree
Hide file tree
Showing 6 changed files with 200 additions and 0 deletions.
1 change: 1 addition & 0 deletions crates/bevy_render/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pub mod render_graph;
pub mod renderer;
pub mod shader;
pub mod texture;
pub mod wireframe;

use bevy_ecs::{IntoSystem, SystemStage};
use bevy_reflect::RegisterTypeBuilder;
Expand Down
130 changes: 130 additions & 0 deletions crates/bevy_render/src/wireframe/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
use crate::{
pipeline::{
BlendFactor, BlendOperation, ColorWrite,
CompareFunction, CullMode, FrontFace, PipelineDescriptor,
PolygonMode, RenderPipeline,
},
prelude::*,
shader::{Shader, ShaderStage, ShaderStages},
texture::TextureFormat,
};
use bevy_app::prelude::*;
use bevy_asset::{Assets, Handle, HandleUntyped};
use bevy_ecs::{Entity, World, ResMut, Res, Query};
use bevy_reflect::TypeUuid;
use crate::draw::DrawContext;
use crate::renderer::RenderResourceBindings;
use crate::mesh::Indices;
use crate::pipeline::{PipelineSpecialization, VertexBufferLayout};
use bevy_ecs::IntoSystem;
use bevy_utils::HashSet;

mod pipeline;

pub const WIREFRAME_PIPELINE_HANDLE: HandleUntyped =
HandleUntyped::weak_from_u64(PipelineDescriptor::TYPE_UUID, 0x137c75ab7e9ad7f5);

#[derive(Debug, Default)]
pub struct WireframePlugin;

impl Plugin for WireframePlugin {
fn build(&self, app: &mut AppBuilder) {
app
.add_system_to_stage(crate::stage::DRAW, draw_wireframes_system.system());
let resources = app.resources();
let mut shaders = resources.get_mut::<Assets<Shader>>().unwrap();
let mut pipelines = resources.get_mut::<Assets<PipelineDescriptor>>().unwrap();
pipelines.set(
WIREFRAME_PIPELINE_HANDLE,
pipeline::build_wireframe_pipeline(&mut shaders),
);
}
}



pub fn draw_wireframes_system(
mut draw_context: DrawContext,
mut render_resource_bindings: ResMut<RenderResourceBindings>,
msaa: Res<Msaa>,
meshes: Res<Assets<Mesh>>,
mut query: Query<(&mut Draw, &mut RenderPipelines, &Handle<Mesh>, &Visible)>,
) {
for (mut draw, mut render_pipelines, mesh_handle, visible) in query.iter_mut() {
if !visible.is_visible {
continue;
}

// don't render if the mesh isn't loaded yet
let mesh = if let Some(mesh) = meshes.get(mesh_handle) {
mesh
} else {
continue;
};

let index_range = match mesh.indices() {
Some(Indices::U32(indices)) => Some(0..indices.len() as u32),
Some(Indices::U16(indices)) => Some(0..indices.len() as u32),
None => None,
};

let mut render_pipeline = RenderPipeline::specialized(
WIREFRAME_PIPELINE_HANDLE.typed(),
PipelineSpecialization {
sample_count: msaa.samples,
strip_index_format: None,
shader_specialization: Default::default(),
primitive_topology: mesh.primitive_topology(),
dynamic_bindings: Default::default(),
vertex_buffer_layout: mesh.get_vertex_buffer_layout(),
},
);
if render_pipeline.dynamic_bindings_generation
!= render_pipelines.bindings.dynamic_bindings_generation()
{
render_pipeline.specialization.dynamic_bindings = render_pipelines
.bindings
.iter_dynamic_bindings()
.map(|name| name.to_string())
.collect::<HashSet<String>>();
render_pipeline.dynamic_bindings_generation =
render_pipelines.bindings.dynamic_bindings_generation();
for (handle, _) in render_pipelines.bindings.iter_assets() {
if let Some(bindings) = draw_context
.asset_render_resource_bindings
.get_untyped(handle)
{
for binding in bindings.iter_dynamic_bindings() {
render_pipeline
.specialization
.dynamic_bindings
.insert(binding.to_string());
}
}
}
}

let render_resource_bindings = &mut [
&mut render_pipelines.bindings,
&mut render_resource_bindings,
];
draw_context
.set_pipeline(
&mut draw,
&render_pipeline.pipeline,
&render_pipeline.specialization,
)
.unwrap();
draw_context
.set_bind_groups_from_bindings(&mut draw, render_resource_bindings)
.unwrap();
draw_context
.set_vertex_buffers_from_bindings(&mut draw, &[&render_pipelines.bindings])
.unwrap();
if let Some(indices) = index_range.clone() {
draw.draw_indexed(indices, 0, 0..1);
} else {
draw.draw(0..mesh.count_vertices() as u32, 0..1)
}
}
}
37 changes: 37 additions & 0 deletions crates/bevy_render/src/wireframe/pipeline.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use crate::{
pipeline::{
BlendFactor, BlendOperation, ColorWrite,
CompareFunction, CullMode, FrontFace,
PolygonMode,

},
prelude::*,
shader::{Shader, ShaderStage, ShaderStages},
texture::TextureFormat,
};
use bevy_app::prelude::*;
use bevy_asset::{Assets, Handle};
use crate::pipeline::{PrimitiveState, PrimitiveTopology, DepthStencilState, StencilState, StencilFaceState, DepthBiasState, MultisampleState, PipelineDescriptor};

pub(crate) fn build_wireframe_pipeline(shaders: &mut Assets<Shader>) -> PipelineDescriptor {
PipelineDescriptor {
name: Some("wireframe".into()),
primitive: PrimitiveState {
topology: PrimitiveTopology::TriangleList,
strip_index_format: None,
front_face: FrontFace::Ccw,
cull_mode: CullMode::None,
polygon_mode: PolygonMode::Line,
},
..PipelineDescriptor::default_config(ShaderStages {
vertex: shaders.add(Shader::from_glsl(
ShaderStage::Vertex,
include_str!("wireframe.vert"),
)),
fragment: Some(shaders.add(Shader::from_glsl(
ShaderStage::Fragment,
include_str!("wireframe.frag"),
))),
})
}
}
8 changes: 8 additions & 0 deletions crates/bevy_render/src/wireframe/wireframe.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#version 450

layout(location = 0) out vec4 o_Target;


void main() {
o_Target = vec4(1.0, 1.0, 1.0, 1.0);
}
16 changes: 16 additions & 0 deletions crates/bevy_render/src/wireframe/wireframe.vert
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#version 450

layout(location = 0) in vec3 Vertex_Position;

layout(set = 0, binding = 0) uniform Camera {
mat4 ViewProj;
};

layout(set = 1, binding = 0) uniform Transform {
mat4 Model;
};

void main() {
vec3 v_Position = (Model * vec4(Vertex_Position, 1.0)).xyz;
gl_Position = ViewProj * vec4(v_Position, 1.0);
}
8 changes: 8 additions & 0 deletions examples/3d/3d_scene.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
use bevy::prelude::*;
use bevy_internal::render::wireframe::WireframePlugin;
use bevy_internal::wgpu::{WgpuOptions, WgpuFeatures};

fn main() {
App::build()
.insert_resource(Msaa { samples: 4 })
.insert_resource(WgpuOptions {
name: Some("3d_scene"),
features: WgpuFeatures::NON_FILL_POLYGON_MODE,
..Default::default()
})
.add_plugins(DefaultPlugins)
.add_plugin(WireframePlugin)
.add_startup_system(setup.system())
.run();
}
Expand Down

0 comments on commit ae27107

Please sign in to comment.