Skip to content

Commit

Permalink
Thing
Browse files Browse the repository at this point in the history
  • Loading branch information
jamescarterbell committed Jan 3, 2024
1 parent 5b7f348 commit d52b017
Show file tree
Hide file tree
Showing 15 changed files with 261 additions and 192 deletions.
5 changes: 2 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ opt-level = 3
aery = "0.5.1"
bevy = {version = "0.12.1", default-features = false}
rstest = "0.18.2"
regex = "1.10.2"
bimap = "0.6.3"

[workspace.lints.clippy]
Expand Down
1 change: 0 additions & 1 deletion crates/bevy_tiles_render/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ bevy = { workspace = true, features = [
"bevy_sprite",
] }
bevy_tiles = {path = "../bevy_tiles"}
regex = { workspace = true }

[dev-dependencies]
rstest = {workspace = true}
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_tiles_render/examples/hello_tile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use bevy::{
DefaultPlugins,
};
use bevy_tiles::TilesPlugin;
use bevy_tiles_render::{tiles::TriThing, TilesRenderPlugin};
use bevy_tiles_render::{settings::ChunkRenderSettings, tiles::TriThing, TilesRenderPlugin};

fn main() {
App::new()
Expand Down
24 changes: 9 additions & 15 deletions crates/bevy_tiles_render/src/bindings.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,16 @@
use std::{mem::size_of, num::NonZeroU64, ops::Deref};

use bevy::{
ecs::{system::Resource, world::FromWorld},
log::info,
math::{Affine3, Mat3A, Mat4, Vec2, Vec4},
ecs::world::FromWorld,
math::{Affine3, Vec4},
render::{
mesh::{Mesh, MeshVertexAttribute},
render_resource::{
self, BindGroupLayout, BindGroupLayoutDescriptor, BindGroupLayoutEntry, BindingType,
Buffer, BufferInitDescriptor, BufferUsages, PrimitiveTopology, ShaderDefVal,
ShaderStages, ShaderType, VertexAttribute, VertexBufferLayout, VertexFormat,
},
render_resource::{BindGroupLayout, BindGroupLayoutDescriptor, ShaderStages, ShaderType},
renderer::RenderDevice,
},
transform::components::GlobalTransform,
};

use crate::gpu_storage_buffer::GpuStorageBuffer;
use crate::buffer_helpers::*;

#[derive(ShaderType, Clone)]
#[derive(ShaderType, Clone, Default)]
pub struct TilesChunkModelUniform {
// Affine 4x3 matrix transposed to 3x4
pub transform: [Vec4; 3],
Expand All @@ -43,7 +35,7 @@ impl From<&GlobalTransform> for TilesChunkModelUniform {
}

pub struct TilesChunkBindGroupLayouts {
pub mesh_layout: BindGroupLayout,
pub model_layout: BindGroupLayout,
}

impl FromWorld for TilesChunkBindGroupLayouts {
Expand All @@ -61,6 +53,8 @@ impl FromWorld for TilesChunkBindGroupLayouts {
)],
});

Self { mesh_layout }
Self {
model_layout: mesh_layout,
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::{marker::PhantomData, mem};

use bevy::{
ecs::{system::Resource, world::FromWorld},
ecs::{component::Component, system::Resource, world::FromWorld},
render::{
render_resource::{
BindGroupLayoutEntry, BindingResource, BindingType, BufferBindingType,
Expand All @@ -14,7 +14,7 @@ use bevy::{

/// Stores an array of elements to be transferred to the GPU and made accessible to shaders as a read-only array.
/// This is modified from bevy's GpuArrayBuffer
#[derive(Resource)]
#[derive(Resource, Component)]
pub struct GpuStorageBuffer<T: GpuArrayBufferable> {
gpu_buffer: StorageBuffer<Vec<T>>,
buffer: Vec<T>,
Expand Down Expand Up @@ -69,4 +69,25 @@ impl<T: GpuArrayBufferable> GpuStorageBuffer<T> {
pub fn batch_size(device: &RenderDevice) -> Option<u32> {
None
}

// Fails if used on the wrong size buffer
/// SAFETY: Use carefully, this is to allow for parallel writes to sections of a buffer.
pub unsafe fn raw_insert(&self, index: usize, value: T) {
let spot: *const T = self.buffer.get(index).unwrap();
let spot: *mut T = spot as *mut T;
unsafe { *spot = value };
}
}

impl<T: GpuArrayBufferable> GpuStorageBuffer<T>
where
T: Default,
{
/// Creates a buffer of the given size filled with default values
pub fn with_size(size: usize) -> Self {
Self {
buffer: vec![T::default(); size],
gpu_buffer: Default::default(),
}
}
}
3 changes: 3 additions & 0 deletions crates/bevy_tiles_render/src/buffer_helpers/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub mod gpu_storage_buffer;

pub use gpu_storage_buffer::*;
7 changes: 7 additions & 0 deletions crates/bevy_tiles_render/src/chunk/internal.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
use bevy::{ecs::component::Component, prelude::Deref};

#[derive(Component)]
pub struct TileInstances(Vec<bool>);

#[derive(Component, Deref)]
pub struct BatchSize(pub usize);
4 changes: 4 additions & 0 deletions crates/bevy_tiles_render/src/chunk/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
//! Components that can effect chunk rendering
/// Components used by rendering pipeline
pub(crate) mod internal;
118 changes: 21 additions & 97 deletions crates/bevy_tiles_render/src/draw.rs
Original file line number Diff line number Diff line change
@@ -1,121 +1,45 @@
//! Contains commands given to the Transparent2D render step
//! to draw tiles.
//!
//! In order to batch draw calls of batched chunk draws (used for larger scenes if for lower memory situations)
//! the draw commands consist of copying individual chunk buffers to the various instance buffers before
//! issuing a draw call for a given batch of chunks.
use bevy::{
core_pipeline::core_2d::Transparent2d,
ecs::{
query::ROQueryItem,
system::{
lifetimeless::{Read, SRes, SResMut},
SystemParamItem,
},
system::{lifetimeless::Read, SystemParamItem},
},
log::info,
render::{
render_phase::{
PhaseItem, RenderCommand, RenderCommandResult, SetItemPipeline, TrackedRenderPass,
},
render_resource::{BindGroupEntries, PipelineCache},
renderer::{RenderDevice, RenderQueue},
log::debug,
render::render_phase::{
PhaseItem, RenderCommand, RenderCommandResult, SetItemPipeline, TrackedRenderPass,
},
sprite::{DrawMesh2d, SetMesh2dViewBindGroup},
transform::components::GlobalTransform,
sprite::SetMesh2dViewBindGroup,
};

use crate::{
bindings::TilesChunkModelUniform, gpu_storage_buffer::GpuStorageBuffer,
pipeline::TilesChunkPipeline, prepare::TilesChunkMeshBindGroup,
tiles_render::TriThingBindGroups,
};

pub type LoadChunk = AddTransform;
use crate::queue::ChunkBatchBindGroups;

pub type DrawChunks = (
// Set the pipeline
SetItemPipeline,
// Set the view uniform as bind group 0
SetMesh2dViewBindGroup<0>,
// Set the mesh uniform as bind group 1
SetChunkBindGroup<1>,
// Draw the mesh
DrawChunkBatch,
);

pub struct AddTransform;
impl RenderCommand<Transparent2d> for AddTransform {
type Param = SResMut<GpuStorageBuffer<TilesChunkModelUniform>>;

type ViewWorldQuery = ();

type ItemWorldQuery = Read<GlobalTransform>;

#[inline]
fn render<'w>(
item: &Transparent2d,
_view: (),
uniforms: ROQueryItem<'w, Self::ItemWorldQuery>,
mut chunk_uniforms: SystemParamItem<'w, '_, Self::Param>,
pass: &mut TrackedRenderPass<'w>,
) -> RenderCommandResult {
chunk_uniforms.push(uniforms.into());
RenderCommandResult::Success
}
}
pub struct CreateUniformBindGroups;
impl RenderCommand<Transparent2d> for CreateUniformBindGroups {
type Param = (
SRes<RenderDevice>,
SRes<RenderQueue>,
SRes<TilesChunkPipeline>,
SRes<GpuStorageBuffer<TilesChunkModelUniform>>,
SResMut<TilesChunkMeshBindGroup>,
);

type ViewWorldQuery = ();

type ItemWorldQuery = ();

#[inline]
fn render<'w>(
item: &Transparent2d,
_view: (),
_item_query: (),
(device, queue, base_pipeline, mut model_buffer, mut bind_groups): SystemParamItem<
'w,
'_,
Self::Param,
>,
pass: &mut TrackedRenderPass<'w>,
) -> RenderCommandResult {
model_buffer.write_buffer(&device, &queue);

let Some(binding) = model_buffer.binding() else {
return RenderCommandResult::Failure;
};

let bind_group = device.create_bind_group(
"tiles_bind_group",
&base_pipeline.tiles_bind_groups.mesh_layout,
&BindGroupEntries::single(binding),
);

bind_groups.value = Some(bind_group);

RenderCommandResult::Success
}
}

pub struct SetChunkBindGroup<const I: usize>;
impl<const I: usize> RenderCommand<Transparent2d> for SetChunkBindGroup<I> {
type Param = SRes<TilesChunkMeshBindGroup>;
type Param = ();

type ViewWorldQuery = ();

type ItemWorldQuery = ();
type ItemWorldQuery = Read<ChunkBatchBindGroups>;

#[inline]
fn render<'w>(
item: &Transparent2d,
_view: (),
_item_query: (),
mesh2d_bind_group: SystemParamItem<'w, '_, Self::Param>,
bind_groups: ROQueryItem<'w, Self::ItemWorldQuery>,
_: SystemParamItem<'w, '_, Self::Param>,
pass: &mut TrackedRenderPass<'w>,
) -> RenderCommandResult {
let mut dynamic_offsets: [u32; 1] = Default::default();
Expand All @@ -125,11 +49,11 @@ impl<const I: usize> RenderCommand<Transparent2d> for SetChunkBindGroup<I> {
offset_count += 1;
}

let Some(model_bindgroup) = mesh2d_bind_group.value else {
return RenderCommandResult::Failure;
};

pass.set_bind_group(I, &model_bindgroup, &dynamic_offsets[..offset_count]);
pass.set_bind_group(
I,
&bind_groups.model_bind_group,
&dynamic_offsets[..offset_count],
);
RenderCommandResult::Success
}
}
Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_tiles_render/src/extract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use bevy::{
entity::Entity,
system::{Commands, Query, ResMut},
},
log::info,
log::{debug, info},
prelude::SpatialBundle,
render::Extract,
sprite::{Mesh2d, RenderMesh2dInstance, RenderMesh2dInstances},
Expand All @@ -17,6 +17,6 @@ pub fn extract_chunks(
tri_things: Extract<Query<(Entity, &GlobalTransform, &TriThing)>>,
) {
let tri_things = Vec::from_iter(tri_things.iter().map(|(e, gt, tt)| (e, (*gt, *tt))));
info!("Extracting! {:?}", tri_things.len());
debug!("Extracted {:?} Chunks", tri_things.len());
commands.insert_or_spawn_batch(tri_things);
}
Loading

0 comments on commit d52b017

Please sign in to comment.