Skip to content

Commit

Permalink
sprite sheets are fully operational
Browse files Browse the repository at this point in the history
  • Loading branch information
cart committed Jun 4, 2020
1 parent 8c19613 commit 5927bad
Show file tree
Hide file tree
Showing 22 changed files with 191 additions and 198 deletions.
19 changes: 19 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -1416,6 +1416,25 @@
"args": [],
"cwd": "${workspaceFolder}"
},
{
"type": "lldb",
"request": "launch",
"name": "Debug example 'sprite_sheet'",
"env": { "CARGO_MANIFEST_DIR": "${workspaceFolder}" },
"cargo": {
"args": [
"build",
"--example=sprite_sheet",
"--package=bevy"
],
"filter": {
"name": "sprite_sheet",
"kind": "example"
}
},
"args": [],
"cwd": "${workspaceFolder}"
},
{
"type": "lldb",
"request": "launch",
Expand Down
6 changes: 5 additions & 1 deletion CREDITS.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,8 @@
## Inspiration

* amethyst
* coffee
* coffee

## Assets

* Generic RPG Pack (CC0 license) by [Bakudas](https://twitter.com/bakudas) and [Gabe Fern](https://twitter.com/_Gabrielfer)
Binary file added assets/textures/character_run.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
22 changes: 18 additions & 4 deletions crates/bevy_derive/src/uniforms.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
use crate::modules::{get_modules, get_path};
use darling::FromMeta;
use inflector::Inflector;
use crate::modules::{get_modules, get_path};
use proc_macro::TokenStream;
use quote::{format_ident, quote};
use syn::{parse_macro_input, Data, DataStruct, DeriveInput, Field, Fields, Path};

// TODO: ensure shader_def and instance/vertex are mutually exclusive
#[derive(FromMeta, Debug, Default)]
struct UniformAttributeArgs {
#[darling(default)]
Expand Down Expand Up @@ -88,6 +87,7 @@ pub fn derive_uniforms(input: TokenStream) -> TokenStream {
let mut texture_and_sampler_name_strings = Vec::new();
let mut texture_and_sampler_name_idents = Vec::new();
let mut field_infos = Vec::new();
let mut get_field_bind_types = Vec::new();

let mut vertex_buffer_field_names_pascal = Vec::new();
let mut vertex_buffer_field_types = Vec::new();
Expand All @@ -98,6 +98,7 @@ pub fn derive_uniforms(input: TokenStream) -> TokenStream {
for (f, attrs) in field_attributes.iter() {
let field_name = f.ident.as_ref().unwrap().to_string();
if !attrs.ignore {
let active_uniform_field_name = &f.ident;
active_uniform_field_names.push(&f.ident);
active_uniform_field_name_strings.push(field_name.clone());
let uniform = format!("{}_{}", struct_name, field_name);
Expand All @@ -117,6 +118,19 @@ pub fn derive_uniforms(input: TokenStream) -> TokenStream {
is_instanceable: #is_instanceable,
}));

if attrs.buffer {
get_field_bind_types.push(quote!({
let bind_type = self.#active_uniform_field_name.get_bind_type();
let size = if let Some(#bevy_render_path::shader::FieldBindType::Uniform { size }) = bind_type {
size
} else {
panic!("Uniform field was labeled as a 'buffer', but it does not have a compatible type.")
};
Some(#bevy_render_path::shader::FieldBindType::Buffer { size })
}))
} else {
get_field_bind_types.push(quote!(self.#active_uniform_field_name.get_bind_type()))
}
}

if attrs.shader_def {
Expand Down Expand Up @@ -192,7 +206,7 @@ pub fn derive_uniforms(input: TokenStream) -> TokenStream {
fn get_field_bind_type(&self, name: &str) -> Option<#bevy_render_path::shader::FieldBindType> {
use #bevy_render_path::shader::GetFieldBindType;
match name {
#(#active_uniform_field_name_strings => self.#active_uniform_field_names.get_bind_type(),)*
#(#active_uniform_field_name_strings => #get_field_bind_types,)*
_ => None,
}
}
Expand Down Expand Up @@ -314,4 +328,4 @@ pub fn derive_uniform(input: TokenStream) -> TokenStream {
}
}
})
}
}
2 changes: 1 addition & 1 deletion crates/bevy_render/src/pipeline/binding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub enum BindType {
dynamic: bool,
properties: Vec<UniformProperty>,
},
Buffer {
StorageBuffer {
dynamic: bool,
readonly: bool,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ impl Node for TextureCopyNode {
render_context.copy_buffer_to_texture(
texture_buffer,
0,
(4 * texture.width) as u32,
4 * texture.size.x() as u32,
texture_resource,
[0, 0, 0],
0,
Expand Down
69 changes: 40 additions & 29 deletions crates/bevy_render/src/render_graph/nodes/uniform_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ where

fn increment_uniform_counts(&mut self, uniforms: &T) {
for (i, field_info) in T::get_field_infos().iter().enumerate() {
if let Some(FieldBindType::Uniform { size }) =
if let Some(FieldBindType::Uniform { size }) | Some(FieldBindType::Buffer { size }) =
uniforms.get_field_bind_type(&field_info.name)
{
if let Some((ref _name, ref mut buffer_array_status)) = self.uniform_arrays[i] {
Expand Down Expand Up @@ -186,8 +186,9 @@ where
for (i, field_info) in T::get_field_infos().iter().enumerate() {
let bind_type = uniforms.get_field_bind_type(&field_info.name);
match bind_type {
Some(FieldBindType::Uniform { size }) => {
Some(FieldBindType::Uniform { size }) | Some(FieldBindType::Buffer { size }) => {
let (_name, uniform_buffer_status) = self.uniform_arrays[i].as_mut().unwrap();
let range = 0..size as u64;
let (target_buffer, target_offset) = if dynamic_uniforms {
let buffer = uniform_buffer_status.buffer.unwrap();
let index = uniform_buffer_status
Expand All @@ -199,31 +200,38 @@ where
dynamic_index: Some(
(index * uniform_buffer_status.aligned_size) as u32,
),
range: 0..size as u64,
range,
},
);
(buffer, index * uniform_buffer_status.aligned_size)
} else {
let resource =
match render_resource_assignments.get(field_info.uniform_name) {
Some(assignment) => assignment.get_resource(),
None => {
let resource = render_resources.create_buffer(BufferInfo {
size,
buffer_usage: BufferUsage::COPY_DST | BufferUsage::UNIFORM,
..Default::default()
});
render_resource_assignments.set(
&field_info.uniform_name,
RenderResourceAssignment::Buffer {
resource,
range: 0..size as u64,
dynamic_index: None,
},
);
resource
}
};
let resource = match render_resource_assignments
.get(field_info.uniform_name)
{
Some(assignment) => assignment.get_resource(),
None => {
let usage = if let Some(FieldBindType::Buffer { .. }) = bind_type {
BufferUsage::STORAGE
} else {
BufferUsage::UNIFORM
};
let resource = render_resources.create_buffer(BufferInfo {
size,
buffer_usage: BufferUsage::COPY_DST | usage,
..Default::default()
});

render_resource_assignments.set(
&field_info.uniform_name,
RenderResourceAssignment::Buffer {
resource,
range,
dynamic_index: None,
},
);
resource
}
};

(resource, 0)
};
Expand All @@ -232,14 +240,16 @@ where
+ (uniform_buffer_status.queued_buffer_writes.len()
* uniform_buffer_status.item_size);
let uniform_byte_len = uniforms.uniform_byte_len(&field_info.uniform_name);
if uniform_byte_len > 0
{
if uniform_byte_len > 0 {
if size != uniform_byte_len {
panic!("The number of bytes produced for {} do not match the expected count. Actual: {}. Expected: {}.", field_info.uniform_name, uniform_byte_len, size);
}

uniforms.write_uniform_bytes(&field_info.uniform_name, &mut staging_buffer
[staging_buffer_start..(staging_buffer_start + uniform_byte_len)]);
uniforms.write_uniform_bytes(
&field_info.uniform_name,
&mut staging_buffer
[staging_buffer_start..(staging_buffer_start + uniform_byte_len)],
);
} else {
panic!(
"failed to get data from uniform: {}",
Expand All @@ -254,7 +264,8 @@ where
offset: target_offset,
});
}
_ => {}
Some(FieldBindType::Texture) => { /* ignore textures */ }
None => { /* ignore None */ }
}
}
}
Expand Down Expand Up @@ -680,7 +691,7 @@ fn setup_uniform_texture_resources<T>(
entities_waiting_for_assets: &EntitiesWaitingForAssets,
render_resource_assignments: &mut RenderResourceAssignments,
) where
T: AsUniforms,
T: AsUniforms,
{
for field_info in T::get_field_infos().iter() {
let bind_type = uniforms.get_field_bind_type(&field_info.name);
Expand Down
17 changes: 3 additions & 14 deletions crates/bevy_render/src/render_resource/buffer.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
bitflags::bitflags! {
#[repr(transparent)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "trace", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct BufferUsage: u32 {
const MAP_READ = 1;
const MAP_WRITE = 2;
Expand All @@ -11,17 +12,5 @@ bitflags::bitflags! {
const UNIFORM = 64;
const STORAGE = 128;
const INDIRECT = 256;
const STORAGE_READ = 512;
const NONE = 0;
/// The combination of all read-only usages.
const READ_ALL = Self::MAP_READ.bits | Self::COPY_SRC.bits |
Self::INDEX.bits | Self::VERTEX.bits | Self::UNIFORM.bits |
Self::STORAGE_READ.bits | Self::INDIRECT.bits;
/// The combination of all write-only and read-write usages.
const WRITE_ALL = Self::MAP_WRITE.bits | Self::COPY_DST.bits | Self::STORAGE.bits;
/// The combination of all usages that the are guaranteed to be be ordered by the hardware.
/// If a usage is not ordered, then even if it doesn't change between draw calls, there
/// still need to be pipeline barriers inserted for synchronization.
const ORDERED = Self::READ_ALL.bits;
}
}
}
2 changes: 1 addition & 1 deletion crates/bevy_render/src/render_resource/resource_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ impl Default for BufferInfo {
fn default() -> Self {
BufferInfo {
size: 0,
buffer_usage: BufferUsage::NONE,
buffer_usage: BufferUsage::empty(),
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_render/src/shader/shader_reflect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,8 +198,8 @@ fn reflect_binding(binding: &ReflectDescriptorBinding) -> BindingDescriptor {
},
),
ReflectDescriptorType::StorageBuffer => (
&binding.name,
BindType::Buffer {
&type_description.type_name,
BindType::StorageBuffer {
dynamic: false,
readonly: true,
},
Expand Down
3 changes: 2 additions & 1 deletion crates/bevy_render/src/shader/uniform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,9 @@ impl ShaderDefSuffixProvider for bool {

#[derive(Clone, Debug, Eq, PartialEq)]
pub enum FieldBindType {
// TODO: maybe change this to Buffer
Uniform { size: usize },
Buffer,
Buffer { size: usize },
Texture,
}

Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_render/src/texture/png_texture_loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use super::Texture;
use anyhow::Result;
use bevy_asset::AssetLoader;
use std::path::Path;
use glam::Vec2;

#[derive(Clone, Default)]
pub struct PngTextureLoader;
Expand All @@ -14,8 +15,7 @@ impl AssetLoader<Texture> for PngTextureLoader {
reader.next_frame(&mut data)?;
Ok(Texture {
data,
width: info.width as usize,
height: info.height as usize,
size: Vec2::new(info.width as f32, info.height as f32),
})
}
fn extensions(&self) -> &[&str] {
Expand Down
9 changes: 4 additions & 5 deletions crates/bevy_render/src/texture/texture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use bevy_asset::{AssetEvent, Assets, Handle};
use bevy_derive::FromResources;
use legion::prelude::*;
use std::{collections::HashSet, fs::File};
use glam::Vec2;

pub const TEXTURE_ASSET_INDEX: usize = 0;
pub const SAMPLER_ASSET_INDEX: usize = 1;
Expand All @@ -18,13 +19,12 @@ pub enum TextureType {

pub struct Texture {
pub data: Vec<u8>,
pub width: usize,
pub height: usize,
pub size: Vec2,
}

impl Texture {
pub fn aspect(&self) -> f32 {
self.height as f32 / self.width as f32
self.size.y() / self.size.x()
}

pub fn load(descriptor: TextureType) -> Self {
Expand All @@ -41,8 +41,7 @@ impl Texture {

Texture {
data,
width,
height,
size: Vec2::new(width as f32, height as f32)
}
}

Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_render/src/texture/texture_descriptor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ impl From<&Texture> for TextureDescriptor {
fn from(texture: &Texture) -> Self {
TextureDescriptor {
size: Extent3d {
height: texture.height as u32,
width: texture.width as u32,
width: texture.size.x() as u32,
height: texture.size.y() as u32,
depth: 1,
},
mip_level_count: 1,
Expand Down
4 changes: 0 additions & 4 deletions crates/bevy_sprite/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,6 @@ impl AppPlugin for SpritePlugin {
.add_system_to_stage(
stage::POST_UPDATE,
asset_shader_def_system::<ColorMaterial>.system(),
)
.init_system_to_stage(
bevy_render::stage::RENDER_RESOURCE,
sprite_sheet_resource_provider_system,
);

let resources = app.resources();
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_sprite/src/render/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ impl SpriteRenderGraphBuilder for RenderGraph {

self.add_system_node(
node::SPRITE_SHEET,
AssetUniformNode::<SpriteSheet>::new(true),
AssetUniformNode::<SpriteSheet>::new(false),
);

self.add_system_node(
Expand Down
6 changes: 3 additions & 3 deletions crates/bevy_sprite/src/render/sprite_sheet.frag
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ layout(location = 0) in vec2 v_Uv;

layout(location = 0) out vec4 o_Target;

layout(set = 1, binding = 1) uniform texture2D SpriteSheet_texture;
layout(set = 1, binding = 2) uniform sampler SpriteSheet_texture_sampler;
layout(set = 1, binding = 2) uniform texture2D SpriteSheet_texture;
layout(set = 1, binding = 3) uniform sampler SpriteSheet_texture_sampler;

void main() {
o_Target = texture(
sampler2D(SpriteSheet_texture, SpriteSheet_texture_sampler),
v_Uv);;
v_Uv);
}
Loading

0 comments on commit 5927bad

Please sign in to comment.