aboutsummaryrefslogtreecommitdiff
path: root/src_testbed/lines/render_dim.rs
diff options
context:
space:
mode:
authorSébastien Crozet <developer@crozet.re>2022-04-28 18:24:01 +0200
committerGitHub <noreply@github.com>2022-04-28 18:24:01 +0200
commit488aad0af3f772e14fd85b27bfff6c1db5d23829 (patch)
tree4c19f613750fcd8779714915dbb752ce369a4173 /src_testbed/lines/render_dim.rs
parent21a31bc1026d17d30b3a5ac35e6bb716dc66be6e (diff)
parent7dc038aec66783d72abda446d6251385e6ad30f4 (diff)
downloadrapier-488aad0af3f772e14fd85b27bfff6c1db5d23829.tar.gz
rapier-488aad0af3f772e14fd85b27bfff6c1db5d23829.tar.bz2
rapier-488aad0af3f772e14fd85b27bfff6c1db5d23829.zip
Merge pull request #315 from dimforge/debug-renderer
Add a basic lines-based debug-renderer
Diffstat (limited to 'src_testbed/lines/render_dim.rs')
-rw-r--r--src_testbed/lines/render_dim.rs335
1 files changed, 335 insertions, 0 deletions
diff --git a/src_testbed/lines/render_dim.rs b/src_testbed/lines/render_dim.rs
new file mode 100644
index 0000000..92215f2
--- /dev/null
+++ b/src_testbed/lines/render_dim.rs
@@ -0,0 +1,335 @@
+pub mod r3d {
+ use bevy::{
+ core_pipeline::Opaque3d,
+ pbr::{
+ DrawMesh, MeshPipeline, MeshPipelineKey, MeshUniform, SetMeshBindGroup,
+ SetMeshViewBindGroup,
+ },
+ prelude::*,
+ render::{
+ mesh::MeshVertexBufferLayout,
+ render_asset::RenderAssets,
+ render_phase::{DrawFunctions, RenderPhase, SetItemPipeline},
+ render_resource::{
+ BlendState, ColorTargetState, ColorWrites, CompareFunction, DepthBiasState,
+ DepthStencilState, FragmentState, FrontFace, MultisampleState, PipelineCache,
+ PolygonMode, PrimitiveState, PrimitiveTopology, RenderPipelineDescriptor,
+ SpecializedMeshPipeline, SpecializedMeshPipelineError, SpecializedMeshPipelines,
+ StencilFaceState, StencilState, TextureFormat, VertexAttribute, VertexBufferLayout,
+ VertexFormat, VertexState, VertexStepMode,
+ },
+ texture::BevyDefault,
+ view::{ExtractedView, Msaa},
+ },
+ utils::Hashed,
+ };
+
+ use crate::lines::{DebugLinesConfig, RenderDebugLinesMesh, DEBUG_LINES_SHADER_HANDLE};
+
+ pub(crate) struct DebugLinePipeline {
+ mesh_pipeline: MeshPipeline,
+ shader: Handle<Shader>,
+ //always_in_front: bool,
+ }
+ impl FromWorld for DebugLinePipeline {
+ fn from_world(render_world: &mut World) -> Self {
+ //let config = render_world.get_resource::<DebugLinesConfig>().unwrap();
+ DebugLinePipeline {
+ mesh_pipeline: render_world.get_resource::<MeshPipeline>().unwrap().clone(),
+ shader: DEBUG_LINES_SHADER_HANDLE.typed(),
+ //always_in_front: config.always_in_front,
+ }
+ }
+ }
+
+ impl SpecializedMeshPipeline for DebugLinePipeline {
+ type Key = (bool, MeshPipelineKey);
+
+ fn specialize(
+ &self,
+ (depth_test, key): Self::Key,
+ layout: &MeshVertexBufferLayout,
+ ) -> Result<RenderPipelineDescriptor, SpecializedMeshPipelineError> {
+ //use VertexFormat::{Float32x3, Float32x4};
+
+ let mut shader_defs = Vec::new();
+ shader_defs.push("LINES_3D".to_string());
+ if depth_test {
+ shader_defs.push("DEPTH_TEST_ENABLED".to_string());
+ }
+
+ let vertex_buffer_layout = layout.get_layout(&[
+ Mesh::ATTRIBUTE_POSITION.at_shader_location(0),
+ Mesh::ATTRIBUTE_COLOR.at_shader_location(1),
+ ])?;
+ let (label, blend, depth_write_enabled);
+ if key.contains(MeshPipelineKey::TRANSPARENT_MAIN_PASS) {
+ label = "transparent_mesh_pipeline".into();
+ blend = Some(BlendState::ALPHA_BLENDING);
+ // For the transparent pass, fragments that are closer will be alpha
+ // blended but their depth is not written to the depth buffer.
+ depth_write_enabled = false;
+ } else {
+ label = "opaque_mesh_pipeline".into();
+ blend = Some(BlendState::REPLACE);
+ // For the opaque and alpha mask passes, fragments that are closer
+ // will replace the current fragment value in the output and the depth is
+ // written to the depth buffer.
+ depth_write_enabled = true;
+ }
+
+ Ok(RenderPipelineDescriptor {
+ vertex: VertexState {
+ shader: self.shader.clone_weak(),
+ entry_point: "vertex".into(),
+ shader_defs: shader_defs.clone(),
+ buffers: vec![vertex_buffer_layout],
+ },
+ fragment: Some(FragmentState {
+ shader: self.shader.clone_weak(),
+ shader_defs,
+ entry_point: "fragment".into(),
+ targets: vec![ColorTargetState {
+ format: TextureFormat::bevy_default(),
+ blend,
+ write_mask: ColorWrites::ALL,
+ }],
+ }),
+ layout: Some(vec![self.mesh_pipeline.view_layout.clone()]),
+ primitive: PrimitiveState {
+ front_face: FrontFace::Ccw,
+ cull_mode: None,
+ unclipped_depth: false,
+ polygon_mode: PolygonMode::Fill,
+ conservative: false,
+ topology: PrimitiveTopology::LineList,
+ strip_index_format: None,
+ },
+ depth_stencil: Some(DepthStencilState {
+ format: TextureFormat::Depth32Float,
+ depth_write_enabled,
+ depth_compare: CompareFunction::Greater,
+ stencil: StencilState {
+ front: StencilFaceState::IGNORE,
+ back: StencilFaceState::IGNORE,
+ read_mask: 0,
+ write_mask: 0,
+ },
+ bias: DepthBiasState {
+ constant: 0,
+ slope_scale: 0.0,
+ clamp: 0.0,
+ },
+ }),
+ multisample: MultisampleState {
+ count: key.msaa_samples(),
+ mask: !0,
+ alpha_to_coverage_enabled: false,
+ },
+ label: Some(label),
+ })
+ }
+ }
+
+ pub(crate) fn queue(
+ opaque_3d_draw_functions: Res<DrawFunctions<Opaque3d>>,
+ debug_line_pipeline: Res<DebugLinePipeline>,
+ mut pipelines: ResMut<SpecializedMeshPipelines<DebugLinePipeline>>,
+ mut pipeline_cache: ResMut<PipelineCache>,
+ render_meshes: Res<RenderAssets<Mesh>>,
+ msaa: Res<Msaa>,
+ material_meshes: Query<(Entity, &MeshUniform, &Handle<Mesh>), With<RenderDebugLinesMesh>>,
+ config: Res<DebugLinesConfig>,
+ mut views: Query<(&ExtractedView, &mut RenderPhase<Opaque3d>)>,
+ ) {
+ let draw_custom = opaque_3d_draw_functions
+ .read()
+ .get_id::<DrawDebugLines>()
+ .unwrap();
+ let key = MeshPipelineKey::from_msaa_samples(msaa.samples);
+ for (view, mut transparent_phase) in views.iter_mut() {
+ let view_matrix = view.transform.compute_matrix();
+ let view_row_2 = view_matrix.row(2);
+ for (entity, mesh_uniform, mesh_handle) in material_meshes.iter() {
+ if let Some(mesh) = render_meshes.get(mesh_handle) {
+ let pipeline = pipelines
+ .specialize(
+ &mut pipeline_cache,
+ &debug_line_pipeline,
+ (config.depth_test, key),
+ &mesh.layout,
+ )
+ .unwrap();
+ transparent_phase.add(Opaque3d {
+ entity,
+ pipeline,
+ draw_function: draw_custom,
+ distance: view_row_2.dot(mesh_uniform.transform.col(3)),
+ });
+ }
+ }
+ }
+ }
+
+ pub(crate) type DrawDebugLines = (
+ SetItemPipeline,
+ SetMeshViewBindGroup<0>,
+ SetMeshBindGroup<1>,
+ DrawMesh,
+ );
+}
+
+pub mod r2d {
+ use bevy::{
+ asset::Handle,
+ core::FloatOrd,
+ core_pipeline::Transparent2d,
+ prelude::*,
+ render::{
+ mesh::MeshVertexBufferLayout,
+ render_asset::RenderAssets,
+ render_phase::{DrawFunctions, RenderPhase, SetItemPipeline},
+ render_resource::{
+ BlendState, ColorTargetState, ColorWrites, CompareFunction, DepthBiasState,
+ DepthStencilState, FragmentState, FrontFace, MultisampleState, PipelineCache,
+ PolygonMode, PrimitiveState, PrimitiveTopology, RenderPipelineDescriptor, Shader,
+ SpecializedMeshPipeline, SpecializedMeshPipelineError, SpecializedMeshPipelines,
+ StencilFaceState, StencilState, TextureFormat, VertexAttribute, VertexBufferLayout,
+ VertexFormat, VertexState, VertexStepMode,
+ },
+ texture::BevyDefault,
+ view::{Msaa, VisibleEntities},
+ },
+ sprite::{
+ DrawMesh2d, Mesh2dHandle, Mesh2dPipeline, Mesh2dPipelineKey, Mesh2dUniform,
+ SetMesh2dBindGroup, SetMesh2dViewBindGroup,
+ },
+ };
+
+ use crate::lines::{RenderDebugLinesMesh, DEBUG_LINES_SHADER_HANDLE};
+
+ pub(crate) struct DebugLinePipeline {
+ mesh_pipeline: Mesh2dPipeline,
+ shader: Handle<Shader>,
+ }
+ impl FromWorld for DebugLinePipeline {
+ fn from_world(render_world: &mut World) -> Self {
+ DebugLinePipeline {
+ mesh_pipeline: render_world
+ .get_resource::<Mesh2dPipeline>()
+ .unwrap()
+ .clone(),
+ shader: DEBUG_LINES_SHADER_HANDLE.typed(),
+ }
+ }
+ }
+
+ impl SpecializedMeshPipeline for DebugLinePipeline {
+ type Key = Mesh2dPipelineKey;
+
+ fn specialize(
+ &self,
+ key: Self::Key,
+ layout: &MeshVertexBufferLayout,
+ ) -> Result<RenderPipelineDescriptor, SpecializedMeshPipelineError> {
+ /*
+ let mut shader_defs = Vec::new();
+ shader_defs.push("LINES_3D".to_string());
+ if depth_test {
+ shader_defs.push("DEPTH_TEST_ENABLED".to_string());
+ }
+ */
+
+ let vertex_buffer_layout = layout.get_layout(&[
+ Mesh::ATTRIBUTE_POSITION.at_shader_location(0),
+ Mesh::ATTRIBUTE_COLOR.at_shader_location(1),
+ ])?;
+
+ Ok(RenderPipelineDescriptor {
+ vertex: VertexState {
+ shader: self.shader.clone_weak(),
+ entry_point: "vertex".into(),
+ shader_defs: vec![],
+ buffers: vec![vertex_buffer_layout],
+ },
+ fragment: Some(FragmentState {
+ shader: self.shader.clone_weak(),
+ shader_defs: vec![],
+ entry_point: "fragment".into(),
+ targets: vec![ColorTargetState {
+ format: TextureFormat::bevy_default(),
+ blend: Some(BlendState::ALPHA_BLENDING),
+ write_mask: ColorWrites::ALL,
+ }],
+ }),
+ layout: Some(vec![self.mesh_pipeline.view_layout.clone()]),
+ primitive: PrimitiveState {
+ front_face: FrontFace::Ccw,
+ cull_mode: None,
+ unclipped_depth: false,
+ polygon_mode: PolygonMode::Fill,
+ conservative: false,
+ topology: PrimitiveTopology::LineList,
+ strip_index_format: None,
+ },
+ depth_stencil: None,
+ multisample: MultisampleState {
+ count: key.msaa_samples(),
+ mask: !0,
+ alpha_to_coverage_enabled: false,
+ },
+ label: None,
+ })
+ }
+ }
+
+ pub(crate) fn queue(
+ draw2d_functions: Res<DrawFunctions<Transparent2d>>,
+ debug_line_pipeline: Res<DebugLinePipeline>,
+ mut pipeline_cache: ResMut<PipelineCache>,
+ mut specialized_pipelines: ResMut<SpecializedMeshPipelines<DebugLinePipeline>>,
+ render_meshes: Res<RenderAssets<Mesh>>,
+ msaa: Res<Msaa>,
+ material_meshes: Query<(&Mesh2dUniform, &Mesh2dHandle), With<RenderDebugLinesMesh>>,
+ mut views: Query<(&VisibleEntities, &mut RenderPhase<Transparent2d>)>,
+ ) {
+ for (view, mut phase) in views.iter_mut() {
+ let draw_mesh2d = draw2d_functions.read().get_id::<DrawDebugLines>().unwrap();
+ let msaa_key = Mesh2dPipelineKey::from_msaa_samples(msaa.samples);
+
+ for visible_entity in &view.entities {
+ if let Ok((uniform, mesh_handle)) = material_meshes.get(*visible_entity) {
+ if let Some(mesh) = render_meshes.get(&mesh_handle.0) {
+ let mesh_key = msaa_key
+ | Mesh2dPipelineKey::from_primitive_topology(
+ PrimitiveTopology::LineList,
+ );
+ let mesh_z = uniform.transform.w_axis.z;
+ let pipeline = specialized_pipelines
+ .specialize(
+ &mut pipeline_cache,
+ &debug_line_pipeline,
+ mesh_key,
+ &mesh.layout,
+ )
+ .unwrap();
+ phase.add(Transparent2d {
+ entity: *visible_entity,
+ draw_function: draw_mesh2d,
+ pipeline,
+ sort_key: FloatOrd(mesh_z),
+ batch_range: None,
+ });
+ }
+ }
+ }
+ }
+ }
+
+ pub(crate) type DrawDebugLines = (
+ SetItemPipeline,
+ SetMesh2dViewBindGroup<0>,
+ SetMesh2dBindGroup<1>,
+ DrawMesh2d,
+ );
+}