这是indexloc提供的服务,不要输入任何密码
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ jobs:
run: cargo clippy -- -Dwarnings

- name: build
run: cargo build --example=minimal
run: cargo build

- name: test
run: cargo test

# - name: build (web)
# run: cargo build --example=minimal --target wasm32-unknown-unknown --release
5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "bevy_interleave"
description = "bevy support for e2e packed to planar bind groups"
version = "0.1.1"
version = "0.2.0"
edition = "2021"
authors = ["mosure <mitchell@mosure.me>"]
license = "MIT"
Expand Down Expand Up @@ -35,8 +35,9 @@ bytemuck = "1.14"
serde = "1.0"

[dependencies.bevy]
version = "0.12"
version = "0.13"
default-features = false
features = ["bevy_asset", "bevy_render"]


[target.'cfg(target_arch = "wasm32")'.dependencies]
Expand Down
38 changes: 33 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,28 +13,55 @@ bevy support for e2e packed to planar bind groups
```rust
use bevy_interleave::prelude::*;

#[derive(Planar)]
#[derive(
Debug,
Planar,
ReflectInterleaved,
StorageBindings,
TextureBindings,
)]
pub struct MyStruct {
#[texture_format(TextureFormat::R32Sint)]
pub field: i32,
pub field2: i32,

#[texture_format(TextureFormat::R32Uint)]
pub field2: u32,

#[texture_format(TextureFormat::R8Unorm)]
pub bool_field: bool,

#[texture_format(TextureFormat::Rgba32Uint)]
pub array: [u32; 4],
}

fn main() {
let interleaved = vec![
MyStruct { field: 0, field2: 1 },
MyStruct { field: 2, field2: 3 },
MyStruct { field: 4, field2: 5 },
MyStruct { field: 0, field2: 1_u32, bool_field: true, array: [0, 1, 2, 3] },
MyStruct { field: 2, field2: 3_u32, bool_field: false, array: [4, 5, 6, 7] },
MyStruct { field: 4, field2: 5_u32, bool_field: true, array: [8, 9, 10, 11] },
];

let planar = PlanarMyStruct::from_interleaved(interleaved);

println!("{:?}", planar.field);
println!("{:?}", planar.field2);
println!("{:?}", planar.bool_field);
println!("{:?}", planar.array);

// Prints:
// [0, 2, 4]
// [1, 3, 5]
// [true, false, true]
// [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]]

println!("\n\n{:?}", MyStruct::min_binding_sizes());
println!("{:?}", MyStruct::ordered_field_names());

// Prints:
// [4, 4, 1, 16]
// ["field", "field2", "bool_field", "array"]
}

```


Expand All @@ -47,4 +74,5 @@ fn main() {

| `bevy_interleave` | `bevy` |
| :-- | :-- |
| `0.2` | `0.13` |
| `0.1` | `0.12` |
2 changes: 1 addition & 1 deletion crates/bevy_interleave_interface/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ keywords = [


[dependencies.bevy]
version = "0.12"
version = "0.13"
default-features = false
features = ["bevy_render"]
30 changes: 28 additions & 2 deletions crates/bevy_interleave_interface/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
pub mod planar;
pub mod texture;

pub trait GpuStoragePlanar {

pub trait PlanarStorage {
type PackedType;
type PlanarType;

Expand All @@ -10,7 +13,6 @@ pub trait GpuStoragePlanar {
) -> bevy::render::render_resource::BindGroup;

fn bind_group_layout(
&self,
render_device: &bevy::render::renderer::RenderDevice,
read_only: bool,
) -> bevy::render::render_resource::BindGroupLayout;
Expand All @@ -22,6 +24,30 @@ pub trait GpuStoragePlanar {
}


pub trait PlanarTexture {
type PackedType;
type PlanarType;

fn bind_group(
&self,
render_device: &bevy::render::renderer::RenderDevice,
gpu_images: &bevy::render::render_asset::RenderAssets<bevy::render::texture::Image>,
layout: &bevy::render::render_resource::BindGroupLayout,
) -> bevy::render::render_resource::BindGroup;

fn bind_group_layout(
render_device: &bevy::render::renderer::RenderDevice,
) -> bevy::render::render_resource::BindGroupLayout;

fn prepare(
images: &mut bevy::asset::Assets<bevy::render::texture::Image>,
planar: &Self::PlanarType,
) -> Self;

fn get_asset_handles(&self) -> Vec<bevy::asset::Handle<bevy::render::texture::Image>>;
}


pub trait ReflectInterleaved {
type PackedType;

Expand Down
31 changes: 31 additions & 0 deletions crates/bevy_interleave_interface/src/planar.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
use std::marker::PhantomData;

use bevy::{
prelude::*,
reflect::GetTypeRegistration,
};

use crate::Planar;


pub struct PlanarPlugin<R> {
phantom: PhantomData<fn() -> R>,
}
impl<R> Default for PlanarPlugin<R> {
fn default() -> Self {
Self {
phantom: PhantomData,
}
}
}

impl<R> Plugin for PlanarPlugin<R>
where
R: Planar + Default + Asset + GetTypeRegistration + Clone + Reflect + FromReflect,
{
fn build(&self, app: &mut App) {
app.register_type::<R>();
app.init_asset::<R>();
app.register_asset_reflect::<R>();
}
}
160 changes: 160 additions & 0 deletions crates/bevy_interleave_interface/src/texture.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
use std::marker::PhantomData;

use bevy::{
prelude::*,
reflect::GetTypeRegistration,
render::extract_component::{
ExtractComponent,
ExtractComponentPlugin,
},
};

use crate::PlanarTexture;


pub struct PlanarTexturePlugin<R> {
phantom: PhantomData<fn() -> R>,
}
impl<R> Default for PlanarTexturePlugin<R> {
fn default() -> Self {
Self {
phantom: PhantomData,
}
}
}

impl<R> Plugin for PlanarTexturePlugin<R>
where
R: PlanarTexture + Default + Component + ExtractComponent + GetTypeRegistration + Clone + Reflect,
R::PlanarType: Asset,
{
fn build(&self, app: &mut App) {
app.register_type::<R>();

app.add_plugins(ExtractComponentPlugin::<R>::default());

app.add_systems(Update, prepare_textures::<R>);

let render_app = app.sub_app_mut(bevy::render::RenderApp);
render_app.add_systems(
bevy::render::Render,
queue_gpu_texture_buffers::<R>.in_set(bevy::render::RenderSet::PrepareAssets),
);
}

fn finish(&self, app: &mut App) {
if let Ok(render_app) = app.get_sub_app_mut(bevy::render::RenderApp) {
render_app.init_resource::<PlanarTextureLayouts::<R>>();
}
}
}


#[derive(bevy::prelude::Resource)]
pub struct PlanarTextureLayouts<R: PlanarTexture + Default + Component + ExtractComponent + GetTypeRegistration + Clone + Reflect> {
pub bind_group_layout: bevy::render::render_resource::BindGroupLayout,
pub phantom: PhantomData<fn() -> R>,
}

impl<R: PlanarTexture + Default + Component + ExtractComponent + GetTypeRegistration + Clone + Reflect>
FromWorld for PlanarTextureLayouts<R> {
fn from_world(world: &mut World) -> Self {
let render_device = world.resource::<bevy::render::renderer::RenderDevice>();

let bind_group_layout = R::bind_group_layout(
render_device,
);

PlanarTextureLayouts::<R> {
bind_group_layout,
phantom: PhantomData,
}
}
}

fn prepare_textures<R>(
mut commands: Commands,
asset_server: Res<AssetServer>,
cloud_res: Res<Assets<R::PlanarType>>,
mut images: ResMut<Assets<Image>>,
clouds: Query<
(
Entity,
&Handle<R::PlanarType>,
),
Without<R>,
>,
)
where
R: PlanarTexture + Default + Component + ExtractComponent + GetTypeRegistration + Clone + Reflect,
R::PlanarType: Asset,
{
for (entity, cloud_handle) in clouds.iter() {
if Some(bevy::asset::LoadState::Loading) == asset_server.get_load_state(cloud_handle){
continue;
}

if cloud_res.get(cloud_handle).is_none() {
continue;
}

let cloud = cloud_res.get(cloud_handle).unwrap();

let buffers = R::prepare(
&mut images,
cloud,
);

commands.entity(entity).insert(buffers);
}
}


#[derive(bevy::prelude::Component, Clone, Debug)]
pub struct PlanarTextureBindGroup<R: PlanarTexture + Default + Component + ExtractComponent + GetTypeRegistration + Clone + Reflect> {
pub bind_group: bevy::render::render_resource::BindGroup,
pub phantom: PhantomData<fn() -> R>,
}


fn queue_gpu_texture_buffers<R>(
mut commands: Commands,
render_device: ResMut<bevy::render::renderer::RenderDevice>,
gpu_images: Res<bevy::render::render_asset::RenderAssets<Image>>,
bind_group_layout: Res<PlanarTextureLayouts<R>>,
clouds: Query<
(
Entity,
&R,
),
Without<PlanarTextureBindGroup::<R>>,
>,
)
where
R: PlanarTexture + Default + Component + ExtractComponent + GetTypeRegistration + Clone + Reflect,
R::PlanarType: Asset,
{
let layout = &bind_group_layout.bind_group_layout;

for (entity, texture_buffers,) in clouds.iter() {
let not_ready = texture_buffers.get_asset_handles().iter()
.map(|handle| gpu_images.get(handle).is_none())
.reduce(|a, b| a || b)
.unwrap_or(true);

if not_ready {
continue;
}

let bind_group = texture_buffers.bind_group(
&render_device,
&gpu_images,
layout,
);

commands.entity(entity).insert(PlanarTextureBindGroup::<R> {
bind_group,
phantom: PhantomData,
});
}
}
4 changes: 2 additions & 2 deletions crates/bevy_interleave_macros/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ sha1 = "0.10"
syn = "2.0"

[dependencies.bevy]
version = "0.12"
version = "0.13"
default-features = false
features = ["bevy_render"]
features = ["bevy_asset", "bevy_render"]


[lib]
Expand Down
Loading