use bevy::{
core::Byteable,
prelude::*,
reflect::TypeUuid,
render::{
pipeline::PipelineDescriptor,
render_graph::{base, RenderGraph, RenderResourcesNode},
renderer::{RenderResource, RenderResources},
},
};
pub const LDTK_TILEMAP_PIPELINE_HANDLE: HandleUntyped =
HandleUntyped::weak_from_u64(PipelineDescriptor::TYPE_UUID, 10348532193540037685);
fn build_ldtk_tilemap_pipeline(shaders: &mut Assets<Shader>) -> PipelineDescriptor {
use bevy::render::{
pipeline::*,
shader::{ShaderStage, ShaderStages},
texture::*,
};
return PipelineDescriptor {
depth_stencil: Some(DepthStencilState {
format: TextureFormat::Depth32Float,
depth_write_enabled: true,
depth_compare: CompareFunction::LessEqual,
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,
},
clamp_depth: false,
}),
color_target_states: vec![ColorTargetState {
format: TextureFormat::default(),
color_blend: BlendState {
src_factor: BlendFactor::SrcAlpha,
dst_factor: BlendFactor::OneMinusSrcAlpha,
operation: BlendOperation::Add,
},
alpha_blend: BlendState {
src_factor: BlendFactor::One,
dst_factor: BlendFactor::One,
operation: BlendOperation::Add,
},
write_mask: ColorWrite::ALL,
}],
primitive: PrimitiveState {
topology: PrimitiveTopology::TriangleList,
strip_index_format: None,
front_face: FrontFace::Ccw,
cull_mode: CullMode::Back,
polygon_mode: PolygonMode::Fill,
},
..PipelineDescriptor::new(ShaderStages {
vertex: shaders.add(Shader::from_glsl(
ShaderStage::Vertex,
include_str!("pipeline/tilemap.vert"),
)),
fragment: Some(shaders.add(Shader::from_glsl(
ShaderStage::Fragment,
include_str!("pipeline/tilemap.frag"),
))),
})
};
}
#[derive(RenderResources, Default, TypeUuid)]
#[uuid = "3bf9e364-f29d-4d6c-92cf-93298466c620"]
pub struct LdtkTilemapLayer {
pub scale: f32,
pub map_info: LdtkTilemapMapInfo,
pub tileset_info: LdtkTilemapTilesetInfo,
pub texture: Handle<Texture>,
#[render_resources(buffer)]
pub tiles: Vec<LdtkTilemapTileInfo>,
}
#[repr(C)]
#[derive(RenderResource, Default, Debug, Clone, Copy)]
pub struct LdtkTilemapMapInfo {
pub width: u32,
pub height: u32,
pub layer_index: u32,
pub sublayer_index: u32,
pub center_map: u32,
}
unsafe impl Byteable for LdtkTilemapMapInfo {}
#[repr(C)]
#[derive(RenderResource, Default, Debug, Clone, Copy)]
pub struct LdtkTilemapTilesetInfo {
pub width: u32,
pub height: u32,
pub grid_size: u32,
}
unsafe impl Byteable for LdtkTilemapTilesetInfo {}
#[repr(C)]
#[derive(RenderResource, Default, Debug, Clone, Copy)]
pub struct LdtkTilemapTileInfo {
pub tile_index: u32,
pub flip_bits: u32,
}
unsafe impl Byteable for LdtkTilemapTileInfo {}
pub mod node {
pub const LDTK_TILEMAP: &'static str = "ldtk_tile_map";
}
pub(crate) fn configure_pipeline(app: &mut AppBuilder) {
let world_cell = app.world_mut().cell();
let mut pipelines = world_cell.get_resource_mut::<Assets<PipelineDescriptor>>().unwrap();
let mut shaders = world_cell.get_resource_mut::<Assets<Shader>>().unwrap();
let mut render_graph = world_cell.get_resource_mut::<RenderGraph>().unwrap();
pipelines.set_untracked(
LDTK_TILEMAP_PIPELINE_HANDLE,
build_ldtk_tilemap_pipeline(&mut shaders),
);
render_graph.add_system_node(
node::LDTK_TILEMAP,
RenderResourcesNode::<LdtkTilemapLayer>::new(false),
);
render_graph
.add_node_edge(node::LDTK_TILEMAP, base::node::MAIN_PASS)
.unwrap();
}