Skip to content

Commit

Permalink
Working :)
Browse files Browse the repository at this point in the history
  • Loading branch information
jamescarterbell committed Jan 7, 2024
1 parent 261e767 commit 5ba7785
Show file tree
Hide file tree
Showing 12 changed files with 224 additions and 214 deletions.
9 changes: 8 additions & 1 deletion crates/bevy_tiles/src/coords.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
use bevy::log::debug;

/// Calculate the coordinate of a chunk from a given tile coordinate and chunk size
#[inline]
pub fn calculate_chunk_coordinate<const N: usize>(
mut tile_c: [isize; N],
chunk_size: usize,
) -> [isize; N] {
for i in tile_c.iter_mut() {
*i = *i / (chunk_size as isize) - if *i < 0 { 1 } else { 0 }
if *i < 0 {
*i = (*i + 1) / (chunk_size as isize) - 1;
} else {
*i /= chunk_size as isize;
}
}
tile_c
}
Expand Down Expand Up @@ -173,6 +179,7 @@ mod tests {
#[case(16, [15, 15], 255)]
#[case(16, [-1, -1], 255)]
#[case(16, [-16, -16], 0)]
#[case(8, [-8, -0], 0)]
fn tile_index_test(
#[case] chunk_size: usize,
#[case] tile_c: [isize; 2],
Expand Down
119 changes: 0 additions & 119 deletions crates/bevy_tiles_render/examples/basic_2d.rs

This file was deleted.

22 changes: 12 additions & 10 deletions crates/bevy_tiles_render/examples/hello_tile.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use bevy::{
app::{App, Startup},
core_pipeline::core_2d::Camera2dBundle,
diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin},
ecs::system::Commands,
math::{Quat, Vec3},
transform::{
Expand All @@ -9,15 +10,21 @@ use bevy::{
},
DefaultPlugins,
};
use bevy_tiles::{commands::TileCommandExt, maps::TileMapLabel, TilesPlugin};
use bevy_tiles::{
commands::TileCommandExt, coords::CoordIterator, maps::TileMapLabel, TilesPlugin,
};
use bevy_tiles_render::{
maps::{TileGridSize, TileMapRenderer, TileMapRenderingBundle, TileSize},
TilesRenderPlugin,
};

fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugins((
DefaultPlugins,
FrameTimeDiagnosticsPlugin,
LogDiagnosticsPlugin::default(),
))
.add_plugins((TilesPlugin, TilesRenderPlugin))
.add_systems(Startup, spawn)
.run();
Expand All @@ -26,23 +33,18 @@ fn main() {
struct GameLayer;

impl TileMapLabel for GameLayer {
const CHUNK_SIZE: usize = 16;
const CHUNK_SIZE: usize = 8;
}

fn spawn(mut commands: Commands) {
let mut tile_commands = commands.tiles::<GameLayer, 2>();
tile_commands.spawn_map(TileMapRenderingBundle {
tile_size: TileSize(16.0),
grid_size: TileGridSize(24.0),
grid_size: TileGridSize(18.0),
..Default::default()
});

for i in -10..10 {
tile_commands.spawn_tile([0, 10 * i], ());
}
for i in -10..10 {
tile_commands.spawn_tile([10 * i, 0], ());
}
tile_commands.spawn_tile_batch(CoordIterator::new([-100, -100], [100, 100]), move |_| ());

commands.spawn(Camera2dBundle {
..Default::default()
Expand Down
109 changes: 102 additions & 7 deletions crates/bevy_tiles_render/src/bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,124 @@ use std::num::NonZeroU64;

use bevy::{
ecs::{component::Component, world::FromWorld},
log::debug,
math::{Affine3, Vec2, Vec4},
render::{
render_resource::{
BindGroup, BindGroupEntries, BindGroupLayout, BindGroupLayoutDescriptor,
BindGroupLayoutEntry, BindingType, Buffer, BufferBindingType, BufferInitDescriptor,
BufferUsages, ShaderSize, ShaderStages, ShaderType, UniformBuffer,
BindGroupLayoutEntry, BindingType, Buffer, BufferAddress, BufferBindingType,
BufferDescriptor, BufferInitDescriptor, BufferUsages, CommandEncoder, ShaderSize,
ShaderStages, ShaderType, StorageBuffer, UniformBuffer,
},
renderer::{RenderDevice, RenderQueue},
},
transform::components::GlobalTransform,
};

use crate::{buffer_helpers::*, maps::internal::MapInfo};
use crate::{
buffer_helpers::*,
chunk::{self, internal::ChunkUniforms},
maps::internal::MapInfo,
};

#[derive(Component)]
pub struct ChunkBatchBindGroups {
pub map_bind_group: BindGroup,
pub chunk_bind_group: BindGroup,
}

/// Contains all the data for an individual chunk that can be
/// consolidated into the batch buffers.
#[derive(Component)]
pub struct ChunkBuffer {
pub chunk_offset: Vec2,
pub tile_instances: GpuStorageBuffer<u32>,
}

impl ChunkBuffer {
pub fn new(chunk_uniforms: &ChunkUniforms) -> Self {
Self {
chunk_offset: Vec2::from(&chunk_uniforms.chunk_coord),
tile_instances: GpuStorageBuffer::<u32>::from(chunk_uniforms.tile_instances.clone()),
}
}

pub fn write_buffer(&mut self, device: &RenderDevice, queue: &RenderQueue) {
self.tile_instances.write_buffer(device, queue);
}
}

#[derive(Component)]
pub struct ChunkBatchBuffer {
total_chunk_size: u64,
batch_size: u64,
pub chunk_offsets: GpuStorageBuffer<Vec2>,
pub tile_instances: Buffer,
}

impl ChunkBatchBuffer {
pub fn with_size_no_default_values(
batch_size: usize,
chunk_size: usize,
device: &RenderDevice,
) -> Self {
let total_chunk_size = chunk_size as u64 * chunk_size as u64;
Self {
total_chunk_size,
batch_size: batch_size as u64,
chunk_offsets: GpuStorageBuffer::<Vec2>::default(),
tile_instances: device.create_buffer(&BufferDescriptor {
label: None,
size: total_chunk_size * batch_size as u64 * u32::SHADER_SIZE.get(),
usage: BufferUsages::COPY_DST | BufferUsages::STORAGE,
mapped_at_creation: false,
}),
}
}

/// # Note
/// after call push, write_buffer needs to be called as well as using the commands
/// from the command encoders to finish the copying.
pub fn push(&mut self, command_encoder: &mut CommandEncoder, chunk_buffer: &ChunkBuffer) {
let index = self.chunk_offsets.push(chunk_buffer.chunk_offset);
command_encoder.copy_buffer_to_buffer(
chunk_buffer.tile_instances.gpu_buffer().unwrap(),
0,
&self.tile_instances,
index.get() as u64 * self.total_chunk_size * u32::SHADER_SIZE.get(),
self.total_chunk_size * u32::SHADER_SIZE.get(),
)
}

pub fn write_buffer(&mut self, device: &RenderDevice, queue: &RenderQueue) {
self.chunk_offsets.write_buffer(device, queue);
}

pub fn bindings(&self) -> BindGroupEntries<2> {
BindGroupEntries::with_indices((
(0, self.chunk_offsets.binding().unwrap()),
(1, self.tile_instances.as_entire_binding()),
))
}

pub fn layout_entries() -> Vec<BindGroupLayoutEntry> {
vec![
// off_sets
GpuStorageBuffer::<Vec2>::binding_layout(0, ShaderStages::VERTEX_FRAGMENT),
BindGroupLayoutEntry {
binding: 1,
visibility: ShaderStages::VERTEX_FRAGMENT,
ty: BindingType::Buffer {
ty: BufferBindingType::Storage { read_only: true },
has_dynamic_offset: false,
min_binding_size: Some(u32::min_size()),
},
count: None,
},
]
}
}

#[derive(Component)]
pub struct MapBatchBuffer {
chunk_size: UniformBuffer<u32>,
Expand Down Expand Up @@ -148,10 +246,7 @@ impl FromWorld for ChunkBatchBindGroupLayouts {

let chunk_layouts = device.create_bind_group_layout(&BindGroupLayoutDescriptor {
label: Some("bevy_tiles_chunk_bind_group"),
entries: &[GpuStorageBuffer::<Vec2>::binding_layout(
0,
ShaderStages::VERTEX_FRAGMENT,
)],
entries: &ChunkBatchBuffer::layout_entries(),
});

Self {
Expand Down
Loading

0 comments on commit 5ba7785

Please sign in to comment.