render: more progress on immediate mode rendering and DrawableText
This commit is contained in:
parent
f4acbdddad
commit
e57fdca1bc
@ -1,8 +1,8 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
pipeline::{BindGroupDescriptor, BindGroupDescriptorId, PipelineDescriptor},
|
pipeline::{PipelineDescriptor, PipelineLayout},
|
||||||
render_resource::{
|
render_resource::{
|
||||||
BindGroup, BindGroupId, BufferId, BufferUsage, RenderResource, RenderResourceBinding,
|
AssetRenderResourceBindings, BindGroup, BindGroupId, BufferId, BufferUsage, RenderResource,
|
||||||
RenderResourceBindings, SharedBuffers,
|
RenderResourceBinding, RenderResourceBindings, SharedBuffers,
|
||||||
},
|
},
|
||||||
renderer::RenderResourceContext,
|
renderer::RenderResourceContext,
|
||||||
};
|
};
|
||||||
@ -31,7 +31,6 @@ pub enum RenderCommand {
|
|||||||
},
|
},
|
||||||
SetBindGroup {
|
SetBindGroup {
|
||||||
index: u32,
|
index: u32,
|
||||||
bind_group_descriptor: BindGroupDescriptorId,
|
|
||||||
bind_group: BindGroupId,
|
bind_group: BindGroupId,
|
||||||
dynamic_uniform_indices: Option<Arc<Vec<u32>>>,
|
dynamic_uniform_indices: Option<Arc<Vec<u32>>>,
|
||||||
},
|
},
|
||||||
@ -64,6 +63,7 @@ impl Draw {
|
|||||||
pipelines: &'a Assets<PipelineDescriptor>,
|
pipelines: &'a Assets<PipelineDescriptor>,
|
||||||
render_resource_context: &'a dyn RenderResourceContext,
|
render_resource_context: &'a dyn RenderResourceContext,
|
||||||
render_resource_bindings: &'a RenderResourceBindings,
|
render_resource_bindings: &'a RenderResourceBindings,
|
||||||
|
asset_render_resource_bindings: &'a AssetRenderResourceBindings,
|
||||||
shared_buffers: &'a SharedBuffers,
|
shared_buffers: &'a SharedBuffers,
|
||||||
) -> DrawContext {
|
) -> DrawContext {
|
||||||
DrawContext {
|
DrawContext {
|
||||||
@ -71,6 +71,7 @@ impl Draw {
|
|||||||
pipelines,
|
pipelines,
|
||||||
render_resource_context,
|
render_resource_context,
|
||||||
render_resource_bindings,
|
render_resource_bindings,
|
||||||
|
asset_render_resource_bindings,
|
||||||
shared_buffers,
|
shared_buffers,
|
||||||
current_pipeline: None,
|
current_pipeline: None,
|
||||||
}
|
}
|
||||||
@ -89,6 +90,8 @@ pub enum DrawError {
|
|||||||
NoPipelineSet,
|
NoPipelineSet,
|
||||||
#[error("Pipeline has no layout")]
|
#[error("Pipeline has no layout")]
|
||||||
PipelineHasNoLayout,
|
PipelineHasNoLayout,
|
||||||
|
#[error("A BindGroup with the given index does not exist")]
|
||||||
|
BindGroupDescriptorDoesNotExist { index: u32 },
|
||||||
#[error("Failed to get a buffer for the given RenderResource.")]
|
#[error("Failed to get a buffer for the given RenderResource.")]
|
||||||
BufferAllocationFailure,
|
BufferAllocationFailure,
|
||||||
}
|
}
|
||||||
@ -98,6 +101,7 @@ pub struct DrawContext<'a> {
|
|||||||
pub pipelines: &'a Assets<PipelineDescriptor>,
|
pub pipelines: &'a Assets<PipelineDescriptor>,
|
||||||
pub render_resource_context: &'a dyn RenderResourceContext,
|
pub render_resource_context: &'a dyn RenderResourceContext,
|
||||||
pub render_resource_bindings: &'a RenderResourceBindings,
|
pub render_resource_bindings: &'a RenderResourceBindings,
|
||||||
|
pub asset_render_resource_bindings: &'a AssetRenderResourceBindings,
|
||||||
pub shared_buffers: &'a SharedBuffers,
|
pub shared_buffers: &'a SharedBuffers,
|
||||||
pub current_pipeline: Option<&'a PipelineDescriptor>,
|
pub current_pipeline: Option<&'a PipelineDescriptor>,
|
||||||
}
|
}
|
||||||
@ -146,14 +150,9 @@ impl<'a> DrawContext<'a> {
|
|||||||
self.render_command(RenderCommand::SetIndexBuffer { buffer, offset });
|
self.render_command(RenderCommand::SetIndexBuffer { buffer, offset });
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_bind_group(
|
pub fn set_bind_group(&mut self, index: u32, bind_group: &BindGroup) {
|
||||||
&mut self,
|
|
||||||
bind_group_descriptor: &BindGroupDescriptor,
|
|
||||||
bind_group: &BindGroup,
|
|
||||||
) {
|
|
||||||
self.render_command(RenderCommand::SetBindGroup {
|
self.render_command(RenderCommand::SetBindGroup {
|
||||||
index: bind_group_descriptor.index,
|
index,
|
||||||
bind_group_descriptor: bind_group_descriptor.id,
|
|
||||||
bind_group: bind_group.id,
|
bind_group: bind_group.id,
|
||||||
dynamic_uniform_indices: bind_group.dynamic_uniform_indices.clone(),
|
dynamic_uniform_indices: bind_group.dynamic_uniform_indices.clone(),
|
||||||
});
|
});
|
||||||
@ -167,6 +166,40 @@ impl<'a> DrawContext<'a> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_pipeline_descriptor(&self) -> Result<&PipelineDescriptor, DrawError> {
|
||||||
|
self.current_pipeline
|
||||||
|
.ok_or_else(|| DrawError::NoPipelineSet)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_pipeline_layout(&self) -> Result<&PipelineLayout, DrawError> {
|
||||||
|
self.get_pipeline_descriptor().and_then(|descriptor| {
|
||||||
|
descriptor
|
||||||
|
.get_layout()
|
||||||
|
.ok_or_else(|| DrawError::PipelineHasNoLayout)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_bind_groups_from_bindings(
|
||||||
|
&mut self,
|
||||||
|
render_resource_bindings: &RenderResourceBindings,
|
||||||
|
) -> Result<(), DrawError> {
|
||||||
|
let pipeline = self
|
||||||
|
.current_pipeline
|
||||||
|
.ok_or_else(|| DrawError::NoPipelineSet)?;
|
||||||
|
let layout = pipeline
|
||||||
|
.get_layout()
|
||||||
|
.ok_or_else(|| DrawError::PipelineHasNoLayout)?;
|
||||||
|
for bind_group_descriptor in layout.bind_groups.iter() {
|
||||||
|
if let Some(local_bind_group) =
|
||||||
|
render_resource_bindings.get_descriptor_bind_group(bind_group_descriptor.id)
|
||||||
|
{
|
||||||
|
self.set_bind_group(bind_group_descriptor.index, local_bind_group);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn render_command(&mut self, render_command: RenderCommand) {
|
pub fn render_command(&mut self, render_command: RenderCommand) {
|
||||||
self.draw.render_commands.push(render_command);
|
self.draw.render_commands.push(render_command);
|
||||||
@ -185,6 +218,7 @@ pub fn draw_system<T: Drawable + Component>(
|
|||||||
pipelines: Res<Assets<PipelineDescriptor>>,
|
pipelines: Res<Assets<PipelineDescriptor>>,
|
||||||
render_resource_bindings: Res<RenderResourceBindings>,
|
render_resource_bindings: Res<RenderResourceBindings>,
|
||||||
render_resource_context: Res<Box<dyn RenderResourceContext>>,
|
render_resource_context: Res<Box<dyn RenderResourceContext>>,
|
||||||
|
asset_render_resource_bindings: Res<AssetRenderResourceBindings>,
|
||||||
shared_buffers: Res<SharedBuffers>,
|
shared_buffers: Res<SharedBuffers>,
|
||||||
mut draw: ComMut<Draw>,
|
mut draw: ComMut<Draw>,
|
||||||
mut drawable: ComMut<T>,
|
mut drawable: ComMut<T>,
|
||||||
@ -193,6 +227,7 @@ pub fn draw_system<T: Drawable + Component>(
|
|||||||
&pipelines,
|
&pipelines,
|
||||||
&**render_resource_context,
|
&**render_resource_context,
|
||||||
&render_resource_bindings,
|
&render_resource_bindings,
|
||||||
|
&asset_render_resource_bindings,
|
||||||
&shared_buffers,
|
&shared_buffers,
|
||||||
);
|
);
|
||||||
draw_context.draw(drawable.as_mut()).unwrap();
|
draw_context.draw(drawable.as_mut()).unwrap();
|
||||||
|
@ -18,7 +18,7 @@ pub trait RenderPass {
|
|||||||
fn set_bind_group(
|
fn set_bind_group(
|
||||||
&mut self,
|
&mut self,
|
||||||
index: u32,
|
index: u32,
|
||||||
bind_group_descriptor: BindGroupDescriptorId,
|
bind_group_descriptor_id: BindGroupDescriptorId,
|
||||||
bind_group: BindGroupId,
|
bind_group: BindGroupId,
|
||||||
dynamic_uniform_indices: Option<&[u32]>,
|
dynamic_uniform_indices: Option<&[u32]>,
|
||||||
);
|
);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use super::{
|
use super::{
|
||||||
state_descriptors::PrimitiveTopology, PipelineDescriptor, RenderPipeline, RenderPipelines,
|
state_descriptors::PrimitiveTopology, PipelineDescriptor, RenderPipelines,
|
||||||
VertexBufferDescriptors,
|
VertexBufferDescriptors,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -8,9 +8,8 @@ use crate::{
|
|||||||
shader::{Shader, ShaderSource},
|
shader::{Shader, ShaderSource},
|
||||||
};
|
};
|
||||||
use bevy_asset::{Assets, Handle};
|
use bevy_asset::{Assets, Handle};
|
||||||
use std::collections::{HashMap, HashSet};
|
|
||||||
|
|
||||||
use legion::prelude::*;
|
use legion::prelude::*;
|
||||||
|
use std::collections::{HashMap, HashSet};
|
||||||
|
|
||||||
#[derive(Clone, Eq, PartialEq, Debug, Default)]
|
#[derive(Clone, Eq, PartialEq, Debug, Default)]
|
||||||
pub struct PipelineSpecialization {
|
pub struct PipelineSpecialization {
|
||||||
@ -78,20 +77,22 @@ impl PipelineCompiler {
|
|||||||
|
|
||||||
fn compile_pipeline(
|
fn compile_pipeline(
|
||||||
&mut self,
|
&mut self,
|
||||||
vertex_buffer_descriptors: &VertexBufferDescriptors,
|
render_resource_context: &dyn RenderResourceContext,
|
||||||
|
pipelines: &mut Assets<PipelineDescriptor>,
|
||||||
shaders: &mut Assets<Shader>,
|
shaders: &mut Assets<Shader>,
|
||||||
pipeline_descriptor: &PipelineDescriptor,
|
source_pipeline: Handle<PipelineDescriptor>,
|
||||||
render_pipeline: &RenderPipeline,
|
vertex_buffer_descriptors: &VertexBufferDescriptors,
|
||||||
|
pipeline_specialization: &PipelineSpecialization,
|
||||||
render_resource_bindings: &RenderResourceBindings,
|
render_resource_bindings: &RenderResourceBindings,
|
||||||
) -> PipelineDescriptor {
|
) -> Handle<PipelineDescriptor> {
|
||||||
let mut compiled_pipeline_descriptor = pipeline_descriptor.clone();
|
let source_descriptor = pipelines.get(&source_pipeline).unwrap();
|
||||||
|
let mut compiled_descriptor = source_descriptor.clone();
|
||||||
compiled_pipeline_descriptor.shader_stages.vertex = self.compile_shader(
|
compiled_descriptor.shader_stages.vertex = self.compile_shader(
|
||||||
shaders,
|
shaders,
|
||||||
&pipeline_descriptor.shader_stages.vertex,
|
&compiled_descriptor.shader_stages.vertex,
|
||||||
&render_pipeline.specialization.shader_specialization,
|
&pipeline_specialization.shader_specialization,
|
||||||
);
|
);
|
||||||
compiled_pipeline_descriptor.shader_stages.fragment = pipeline_descriptor
|
compiled_descriptor.shader_stages.fragment = compiled_descriptor
|
||||||
.shader_stages
|
.shader_stages
|
||||||
.fragment
|
.fragment
|
||||||
.as_ref()
|
.as_ref()
|
||||||
@ -99,23 +100,42 @@ impl PipelineCompiler {
|
|||||||
self.compile_shader(
|
self.compile_shader(
|
||||||
shaders,
|
shaders,
|
||||||
fragment,
|
fragment,
|
||||||
&render_pipeline.specialization.shader_specialization,
|
&pipeline_specialization.shader_specialization,
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
compiled_pipeline_descriptor.reflect_layout(
|
compiled_descriptor.reflect_layout(
|
||||||
shaders,
|
shaders,
|
||||||
true,
|
true,
|
||||||
Some(vertex_buffer_descriptors),
|
Some(vertex_buffer_descriptors),
|
||||||
Some(render_resource_bindings),
|
Some(render_resource_bindings),
|
||||||
);
|
);
|
||||||
|
|
||||||
compiled_pipeline_descriptor.primitive_topology =
|
compiled_descriptor.primitive_topology = pipeline_specialization.primitive_topology;
|
||||||
render_pipeline.specialization.primitive_topology;
|
let compiled_pipeline_handle =
|
||||||
compiled_pipeline_descriptor
|
if *pipeline_specialization == PipelineSpecialization::default() {
|
||||||
|
pipelines.set(source_pipeline, compiled_descriptor);
|
||||||
|
source_pipeline
|
||||||
|
} else {
|
||||||
|
pipelines.add(compiled_descriptor)
|
||||||
|
};
|
||||||
|
|
||||||
|
render_resource_context.create_render_pipeline(
|
||||||
|
compiled_pipeline_handle,
|
||||||
|
pipelines.get(&compiled_pipeline_handle).unwrap(),
|
||||||
|
&shaders,
|
||||||
|
);
|
||||||
|
|
||||||
|
let compiled_pipelines = self
|
||||||
|
.specialized_pipelines
|
||||||
|
.entry(source_pipeline)
|
||||||
|
.or_insert_with(|| Vec::new());
|
||||||
|
compiled_pipelines.push((pipeline_specialization.clone(), compiled_pipeline_handle));
|
||||||
|
|
||||||
|
compiled_pipeline_handle
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compile_pipelines(
|
fn compile_render_pipelines(
|
||||||
&mut self,
|
&mut self,
|
||||||
vertex_buffer_descriptors: &VertexBufferDescriptors,
|
vertex_buffer_descriptors: &VertexBufferDescriptors,
|
||||||
pipelines: &mut Assets<PipelineDescriptor>,
|
pipelines: &mut Assets<PipelineDescriptor>,
|
||||||
@ -125,44 +145,27 @@ impl PipelineCompiler {
|
|||||||
) {
|
) {
|
||||||
for render_pipeline in render_pipelines.pipelines.iter_mut() {
|
for render_pipeline in render_pipelines.pipelines.iter_mut() {
|
||||||
let source_pipeline = render_pipeline.pipeline;
|
let source_pipeline = render_pipeline.pipeline;
|
||||||
if let None = self.specialized_pipelines.get(&source_pipeline) {
|
|
||||||
self.specialized_pipelines
|
|
||||||
.insert(source_pipeline, Vec::new());
|
|
||||||
}
|
|
||||||
let compiled_pipeline_handle = if let Some((_shader_defs, compiled_pipeline_handle)) =
|
let compiled_pipeline_handle = if let Some((_shader_defs, compiled_pipeline_handle)) =
|
||||||
self.specialized_pipelines
|
self.specialized_pipelines
|
||||||
.get_mut(&source_pipeline)
|
.get_mut(&source_pipeline)
|
||||||
.unwrap()
|
.and_then(|specialized_pipelines| {
|
||||||
.iter()
|
specialized_pipelines.iter().find(
|
||||||
.find(|(pipeline_specialization, _compiled_pipeline_handle)| {
|
|(pipeline_specialization, _compiled_pipeline_handle)| {
|
||||||
*pipeline_specialization == render_pipeline.specialization
|
*pipeline_specialization == render_pipeline.specialization
|
||||||
|
},
|
||||||
|
)
|
||||||
}) {
|
}) {
|
||||||
*compiled_pipeline_handle
|
*compiled_pipeline_handle
|
||||||
} else {
|
} else {
|
||||||
let pipeline_descriptor = pipelines.get(&source_pipeline).unwrap();
|
self.compile_pipeline(
|
||||||
let compiled_pipeline_descriptor = self.compile_pipeline(
|
render_resource_context,
|
||||||
vertex_buffer_descriptors,
|
pipelines,
|
||||||
shaders,
|
shaders,
|
||||||
pipeline_descriptor,
|
source_pipeline,
|
||||||
render_pipeline,
|
vertex_buffer_descriptors,
|
||||||
|
&render_pipeline.specialization,
|
||||||
&render_pipelines.bindings,
|
&render_pipelines.bindings,
|
||||||
);
|
)
|
||||||
let compiled_pipeline_handle = pipelines.add(compiled_pipeline_descriptor);
|
|
||||||
render_resource_context.create_render_pipeline(
|
|
||||||
compiled_pipeline_handle,
|
|
||||||
pipelines.get(&compiled_pipeline_handle).unwrap(),
|
|
||||||
&shaders,
|
|
||||||
);
|
|
||||||
|
|
||||||
let compiled_pipelines = self
|
|
||||||
.specialized_pipelines
|
|
||||||
.get_mut(&source_pipeline)
|
|
||||||
.unwrap();
|
|
||||||
compiled_pipelines.push((
|
|
||||||
render_pipeline.specialization.clone(),
|
|
||||||
compiled_pipeline_handle,
|
|
||||||
));
|
|
||||||
compiled_pipeline_handle
|
|
||||||
};
|
};
|
||||||
|
|
||||||
render_pipeline.specialized_pipeline = Some(compiled_pipeline_handle);
|
render_pipeline.specialized_pipeline = Some(compiled_pipeline_handle);
|
||||||
@ -198,15 +201,44 @@ pub fn compile_pipelines_system(
|
|||||||
mut pipeline_compiler: ResMut<PipelineCompiler>,
|
mut pipeline_compiler: ResMut<PipelineCompiler>,
|
||||||
mut shaders: ResMut<Assets<Shader>>,
|
mut shaders: ResMut<Assets<Shader>>,
|
||||||
mut pipelines: ResMut<Assets<PipelineDescriptor>>,
|
mut pipelines: ResMut<Assets<PipelineDescriptor>>,
|
||||||
|
// pipeline_asset_events: Res<Events<AssetEvent<PipelineDescriptor>>>,
|
||||||
vertex_buffer_descriptors: Res<VertexBufferDescriptors>,
|
vertex_buffer_descriptors: Res<VertexBufferDescriptors>,
|
||||||
render_resource_context: Res<Box<dyn RenderResourceContext>>,
|
render_resource_context: Res<Box<dyn RenderResourceContext>>,
|
||||||
query: &mut Query<Write<RenderPipelines>>,
|
query: &mut Query<Write<RenderPipelines>>,
|
||||||
) {
|
) {
|
||||||
let render_resource_context = &**render_resource_context;
|
let render_resource_context = &**render_resource_context;
|
||||||
|
// let default_specialization = PipelineSpecialization::default();
|
||||||
|
// NOTE: this intentionally only handles events that happened prior to this system during this frame. this results in
|
||||||
|
// "specialized pipeline" events being ignored.
|
||||||
|
// for event in pipeline_asset_events.iter_current_update_events() {
|
||||||
|
// let handle_to_compile = match event {
|
||||||
|
// AssetEvent::Created { handle } => Some(*handle),
|
||||||
|
// AssetEvent::Modified { handle } => {
|
||||||
|
// // TODO: clean up old pipelines
|
||||||
|
// Some(*handle)
|
||||||
|
// }
|
||||||
|
// AssetEvent::Removed { handle } => {
|
||||||
|
// // TODO: clean up old pipelines
|
||||||
|
// None
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
|
||||||
|
// if let Some(handle_to_compile) = handle_to_compile {
|
||||||
|
// pipeline_compiler.compile_pipeline(
|
||||||
|
// render_resource_context,
|
||||||
|
// &mut pipelines,
|
||||||
|
// &mut shaders,
|
||||||
|
// handle_to_compile,
|
||||||
|
// &vertex_buffer_descriptors,
|
||||||
|
// &default_specialization,
|
||||||
|
// None,
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
// TODO: only update when RenderPipelines is changed
|
// TODO: only update when RenderPipelines is changed
|
||||||
for mut render_pipelines in query.iter_mut(world) {
|
for mut render_pipelines in query.iter_mut(world) {
|
||||||
pipeline_compiler.compile_pipelines(
|
pipeline_compiler.compile_render_pipelines(
|
||||||
&vertex_buffer_descriptors,
|
&vertex_buffer_descriptors,
|
||||||
&mut pipelines,
|
&mut pipelines,
|
||||||
&mut shaders,
|
&mut shaders,
|
||||||
|
@ -9,6 +9,12 @@ pub struct PipelineLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl PipelineLayout {
|
impl PipelineLayout {
|
||||||
|
pub fn get_bind_group(&self, index: u32) -> Option<&BindGroupDescriptor> {
|
||||||
|
self.bind_groups
|
||||||
|
.iter()
|
||||||
|
.find(|bind_group| bind_group.index == index)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn from_shader_layouts(shader_layouts: &mut [ShaderLayout]) -> Self {
|
pub fn from_shader_layouts(shader_layouts: &mut [ShaderLayout]) -> Self {
|
||||||
let mut bind_groups = HashMap::<u32, BindGroupDescriptor>::new();
|
let mut bind_groups = HashMap::<u32, BindGroupDescriptor>::new();
|
||||||
let mut vertex_buffer_descriptors = Vec::new();
|
let mut vertex_buffer_descriptors = Vec::new();
|
||||||
|
@ -69,12 +69,12 @@ impl Drawable for RenderPipelines {
|
|||||||
.bindings
|
.bindings
|
||||||
.get_descriptor_bind_group(bind_group_descriptor.id)
|
.get_descriptor_bind_group(bind_group_descriptor.id)
|
||||||
{
|
{
|
||||||
draw.set_bind_group(bind_group_descriptor, local_bind_group);
|
draw.set_bind_group(bind_group_descriptor.index, local_bind_group);
|
||||||
} else if let Some(global_bind_group) = draw
|
} else if let Some(global_bind_group) = draw
|
||||||
.render_resource_bindings
|
.render_resource_bindings
|
||||||
.get_descriptor_bind_group(bind_group_descriptor.id)
|
.get_descriptor_bind_group(bind_group_descriptor.id)
|
||||||
{
|
{
|
||||||
draw.set_bind_group(bind_group_descriptor, global_bind_group);
|
draw.set_bind_group(bind_group_descriptor.index, global_bind_group);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let mut indices = 0..0;
|
let mut indices = 0..0;
|
||||||
|
@ -80,6 +80,10 @@ impl CommandQueue {
|
|||||||
self.push(Command::FreeBuffer(buffer));
|
self.push(Command::FreeBuffer(buffer));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn clear(&mut self) {
|
||||||
|
self.queue.lock().unwrap().clear();
|
||||||
|
}
|
||||||
|
|
||||||
pub fn execute(&mut self, render_context: &mut dyn RenderContext) {
|
pub fn execute(&mut self, render_context: &mut dyn RenderContext) {
|
||||||
for command in self.queue.lock().unwrap().drain(..) {
|
for command in self.queue.lock().unwrap().drain(..) {
|
||||||
match command {
|
match command {
|
||||||
|
@ -131,13 +131,15 @@ impl Node for MainPassNode {
|
|||||||
}
|
}
|
||||||
RenderCommand::SetBindGroup {
|
RenderCommand::SetBindGroup {
|
||||||
index,
|
index,
|
||||||
bind_group_descriptor,
|
|
||||||
bind_group,
|
bind_group,
|
||||||
dynamic_uniform_indices,
|
dynamic_uniform_indices,
|
||||||
} => {
|
} => {
|
||||||
|
let pipeline = pipelines.get(&draw_state.pipeline.unwrap()).unwrap();
|
||||||
|
let layout = pipeline.get_layout().unwrap();
|
||||||
|
let bind_group_descriptor = layout.get_bind_group(*index).unwrap();
|
||||||
render_pass.set_bind_group(
|
render_pass.set_bind_group(
|
||||||
*index,
|
*index,
|
||||||
*bind_group_descriptor,
|
bind_group_descriptor.id,
|
||||||
*bind_group,
|
*bind_group,
|
||||||
dynamic_uniform_indices
|
dynamic_uniform_indices
|
||||||
.as_ref()
|
.as_ref()
|
@ -1,13 +1,15 @@
|
|||||||
mod camera_node;
|
mod camera_node;
|
||||||
mod pass_node;
|
mod main_pass_node;
|
||||||
mod render_resources_node;
|
mod render_resources_node;
|
||||||
|
mod shared_buffers_node;
|
||||||
mod texture_copy_node;
|
mod texture_copy_node;
|
||||||
mod window_swapchain_node;
|
mod window_swapchain_node;
|
||||||
mod window_texture_node;
|
mod window_texture_node;
|
||||||
|
|
||||||
pub use camera_node::*;
|
pub use camera_node::*;
|
||||||
pub use pass_node::*;
|
pub use main_pass_node::*;
|
||||||
pub use render_resources_node::*;
|
pub use render_resources_node::*;
|
||||||
|
pub use shared_buffers_node::*;
|
||||||
pub use texture_copy_node::*;
|
pub use texture_copy_node::*;
|
||||||
pub use window_swapchain_node::*;
|
pub use window_swapchain_node::*;
|
||||||
pub use window_texture_node::*;
|
pub use window_texture_node::*;
|
@ -1,6 +1,5 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
render_graph::{Node, ResourceSlots},
|
render_graph::{Node, ResourceSlots},
|
||||||
render_resource::SharedBuffers,
|
|
||||||
renderer::RenderContext,
|
renderer::RenderContext,
|
||||||
};
|
};
|
||||||
use legion::prelude::*;
|
use legion::prelude::*;
|
||||||
@ -12,13 +11,14 @@ impl Node for SharedBuffersNode {
|
|||||||
fn update(
|
fn update(
|
||||||
&mut self,
|
&mut self,
|
||||||
_world: &World,
|
_world: &World,
|
||||||
resources: &Resources,
|
_resources: &Resources,
|
||||||
render_context: &mut dyn RenderContext,
|
_render_context: &mut dyn RenderContext,
|
||||||
_input: &ResourceSlots,
|
_input: &ResourceSlots,
|
||||||
_output: &mut ResourceSlots,
|
_output: &mut ResourceSlots,
|
||||||
) {
|
) {
|
||||||
let shared_buffers = resources.get::<SharedBuffers>().unwrap();
|
// TODO: enable me
|
||||||
let mut command_queue = shared_buffers.reset_command_queue();
|
// let shared_buffers = resources.get::<SharedBuffers>().unwrap();
|
||||||
|
// let mut command_queue = shared_buffers.reset_command_queue();
|
||||||
// command_queue.execute(render_context);
|
// command_queue.execute(render_context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use super::{BindGroup, BindGroupId, BufferId, RenderResourceId, SamplerId, TextureId};
|
use super::{BindGroup, BindGroupId, BufferId, RenderResourceId, SamplerId, TextureId};
|
||||||
use crate::pipeline::{BindGroupDescriptor, BindGroupDescriptorId};
|
use crate::{renderer::RenderResourceContext, pipeline::{BindGroupDescriptor, BindGroupDescriptorId, PipelineDescriptor}};
|
||||||
use bevy_asset::{Handle, HandleUntyped};
|
use bevy_asset::{Handle, HandleUntyped};
|
||||||
use std::{
|
use std::{
|
||||||
collections::{HashMap, HashSet},
|
collections::{HashMap, HashSet},
|
||||||
@ -162,6 +162,32 @@ impl RenderResourceBindings {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn update_bind_groups(&mut self, pipeline: &PipelineDescriptor, render_resource_context: &dyn RenderResourceContext) {
|
||||||
|
let layout = pipeline.get_layout().unwrap();
|
||||||
|
for bind_group_descriptor in layout.bind_groups.iter() {
|
||||||
|
match self.update_bind_group(bind_group_descriptor) {
|
||||||
|
BindGroupStatus::Changed(id) => {
|
||||||
|
let bind_group = self
|
||||||
|
.get_bind_group(id)
|
||||||
|
.expect("RenderResourceSet was just changed, so it should exist");
|
||||||
|
render_resource_context.create_bind_group(bind_group_descriptor.id, bind_group);
|
||||||
|
}
|
||||||
|
// TODO: Don't re-create bind groups if they havent changed. this will require cleanup of orphan bind groups and
|
||||||
|
// removal of global context.clear_bind_groups()
|
||||||
|
// PERF: see above
|
||||||
|
BindGroupStatus::Unchanged(id) => {
|
||||||
|
let bind_group = self
|
||||||
|
.get_bind_group(id)
|
||||||
|
.expect("RenderResourceSet was just changed, so it should exist");
|
||||||
|
render_resource_context.create_bind_group(bind_group_descriptor.id, bind_group);
|
||||||
|
}
|
||||||
|
BindGroupStatus::NoMatch => {
|
||||||
|
// ignore unchanged / unmatched render resource sets
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_bind_group(&self, id: BindGroupId) -> Option<&BindGroup> {
|
pub fn get_bind_group(&self, id: BindGroupId) -> Option<&BindGroup> {
|
||||||
self.bind_groups.get(&id)
|
self.bind_groups.get(&id)
|
||||||
}
|
}
|
||||||
|
@ -1,41 +1,11 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
pipeline::{PipelineCompiler, PipelineDescriptor, RenderPipelines},
|
pipeline::{PipelineCompiler, PipelineDescriptor, RenderPipelines},
|
||||||
render_resource::{BindGroupStatus, RenderResourceBindings},
|
render_resource::RenderResourceBindings,
|
||||||
renderer::RenderResourceContext,
|
renderer::RenderResourceContext,
|
||||||
};
|
};
|
||||||
use bevy_asset::Assets;
|
use bevy_asset::Assets;
|
||||||
use legion::prelude::*;
|
use legion::prelude::*;
|
||||||
|
|
||||||
fn update_bind_groups(
|
|
||||||
pipeline: &PipelineDescriptor,
|
|
||||||
render_resource_bindings: &mut RenderResourceBindings,
|
|
||||||
render_resource_context: &dyn RenderResourceContext,
|
|
||||||
) {
|
|
||||||
let layout = pipeline.get_layout().unwrap();
|
|
||||||
for bind_group_descriptor in layout.bind_groups.iter() {
|
|
||||||
match render_resource_bindings.update_bind_group(bind_group_descriptor) {
|
|
||||||
BindGroupStatus::Changed(id) => {
|
|
||||||
let bind_group = render_resource_bindings
|
|
||||||
.get_bind_group(id)
|
|
||||||
.expect("RenderResourceSet was just changed, so it should exist");
|
|
||||||
render_resource_context.create_bind_group(bind_group_descriptor.id, bind_group);
|
|
||||||
}
|
|
||||||
// TODO: Don't re-create bind groups if they havent changed. this will require cleanup of orphan bind groups and
|
|
||||||
// removal of global context.clear_bind_groups()
|
|
||||||
// PERF: see above
|
|
||||||
BindGroupStatus::Unchanged(id) => {
|
|
||||||
let bind_group = render_resource_bindings
|
|
||||||
.get_bind_group(id)
|
|
||||||
.expect("RenderResourceSet was just changed, so it should exist");
|
|
||||||
render_resource_context.create_bind_group(bind_group_descriptor.id, bind_group);
|
|
||||||
}
|
|
||||||
BindGroupStatus::NoMatch => {
|
|
||||||
// ignore unchanged / unmatched render resource sets
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn bind_groups_system(
|
pub fn bind_groups_system(
|
||||||
world: &mut SubWorld,
|
world: &mut SubWorld,
|
||||||
pipelines: Res<Assets<PipelineDescriptor>>,
|
pipelines: Res<Assets<PipelineDescriptor>>,
|
||||||
@ -47,11 +17,7 @@ pub fn bind_groups_system(
|
|||||||
let render_resource_context = &**render_resource_context;
|
let render_resource_context = &**render_resource_context;
|
||||||
for compiled_pipeline_handle in pipeline_compiler.iter_all_compiled_pipelines() {
|
for compiled_pipeline_handle in pipeline_compiler.iter_all_compiled_pipelines() {
|
||||||
let pipeline = pipelines.get(compiled_pipeline_handle).unwrap();
|
let pipeline = pipelines.get(compiled_pipeline_handle).unwrap();
|
||||||
update_bind_groups(
|
render_resource_bindings.update_bind_groups(pipeline, render_resource_context);
|
||||||
pipeline,
|
|
||||||
&mut render_resource_bindings,
|
|
||||||
render_resource_context,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
for mut render_pipelines in query.iter_mut(world) {
|
for mut render_pipelines in query.iter_mut(world) {
|
||||||
let render_pipelines = render_pipelines.as_mut();
|
let render_pipelines = render_pipelines.as_mut();
|
||||||
@ -59,11 +25,7 @@ pub fn bind_groups_system(
|
|||||||
let pipeline = pipelines
|
let pipeline = pipelines
|
||||||
.get(&render_pipeline.specialized_pipeline.unwrap())
|
.get(&render_pipeline.specialized_pipeline.unwrap())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
update_bind_groups(
|
render_pipelines.bindings.update_bind_groups(pipeline, render_resource_context);
|
||||||
pipeline,
|
|
||||||
&mut render_pipelines.bindings,
|
|
||||||
render_resource_context,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
use crate::{Font, FontAtlasSet};
|
use crate::{Font, FontAtlasSet};
|
||||||
use bevy_asset::{Assets, Handle};
|
use bevy_asset::Assets;
|
||||||
use bevy_render::{
|
use bevy_render::{
|
||||||
draw::{DrawError, Drawable},
|
draw::{DrawContext, DrawError, Drawable},
|
||||||
|
mesh,
|
||||||
|
render_resource::{BindGroup, BufferUsage, RenderResourceId},
|
||||||
Color,
|
Color,
|
||||||
};
|
};
|
||||||
use bevy_sprite::TextureAtlas;
|
use bevy_sprite::{TextureAtlas, TextureAtlasSprite};
|
||||||
use glam::Vec2;
|
use glam::{Vec2, Vec3};
|
||||||
|
|
||||||
pub struct TextStyle {
|
pub struct TextStyle {
|
||||||
pub font_size: f32,
|
pub font_size: f32,
|
||||||
@ -14,9 +16,8 @@ pub struct TextStyle {
|
|||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub struct DrawableText<'a> {
|
pub struct DrawableText<'a> {
|
||||||
font_handle: Handle<Font>,
|
font: &'a Font,
|
||||||
fonts: &'a Assets<Font>,
|
font_atlas_set: &'a FontAtlasSet,
|
||||||
font_atlas_sets: &'a Assets<FontAtlasSet>,
|
|
||||||
texture_atlases: &'a Assets<TextureAtlas>,
|
texture_atlases: &'a Assets<TextureAtlas>,
|
||||||
position: Vec2,
|
position: Vec2,
|
||||||
style: &'a TextStyle,
|
style: &'a TextStyle,
|
||||||
@ -25,18 +26,16 @@ pub struct DrawableText<'a> {
|
|||||||
|
|
||||||
impl<'a> DrawableText<'a> {
|
impl<'a> DrawableText<'a> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
font_handle: Handle<Font>,
|
font: &'a Font,
|
||||||
fonts: &'a Assets<Font>,
|
font_atlas_set: &'a FontAtlasSet,
|
||||||
font_atlas_sets: &'a Assets<FontAtlasSet>,
|
|
||||||
texture_atlases: &'a Assets<TextureAtlas>,
|
texture_atlases: &'a Assets<TextureAtlas>,
|
||||||
position: Vec2,
|
position: Vec2,
|
||||||
style: &'a TextStyle,
|
style: &'a TextStyle,
|
||||||
text: &'a str,
|
text: &'a str,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
font_handle,
|
font,
|
||||||
fonts,
|
font_atlas_set,
|
||||||
font_atlas_sets,
|
|
||||||
texture_atlases,
|
texture_atlases,
|
||||||
position,
|
position,
|
||||||
style,
|
style,
|
||||||
@ -46,25 +45,58 @@ impl<'a> DrawableText<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Drawable for DrawableText<'a> {
|
impl<'a> Drawable for DrawableText<'a> {
|
||||||
fn draw(&mut self, _draw: &mut bevy_render::draw::DrawContext) -> Result<(), DrawError> {
|
fn draw(&mut self, draw: &mut DrawContext) -> Result<(), DrawError> {
|
||||||
// draw.set_pipeline(bevy_sprite::SPRITE_SHEET_PIPELINE_HANDLE)?;
|
draw.set_pipeline(bevy_sprite::SPRITE_SHEET_PIPELINE_HANDLE)?;
|
||||||
// let render_resource_context = draw.render_resource_context;
|
let render_resource_context = draw.render_resource_context;
|
||||||
// // TODO: add draw.set_mesh(slot)
|
// TODO: add draw.set_mesh(slot)
|
||||||
// let quad_vertex_buffer = render_resource_context
|
if let Some(RenderResourceId::Buffer(quad_vertex_buffer)) = render_resource_context
|
||||||
// .get_asset_resource(bevy_sprite::QUAD_HANDLE, mesh::VERTEX_BUFFER_ASSET_INDEX)
|
.get_asset_resource(bevy_sprite::QUAD_HANDLE, mesh::VERTEX_BUFFER_ASSET_INDEX)
|
||||||
// .unwrap();
|
{
|
||||||
// let quad_index_buffer = render_resource_context
|
draw.set_vertex_buffer(0, quad_vertex_buffer, 0);
|
||||||
// .get_asset_resource(bevy_sprite::QUAD_HANDLE, mesh::INDEX_BUFFER_ASSET_INDEX)
|
}
|
||||||
// .unwrap();
|
let mut indices = 0..0;
|
||||||
// draw.set_vertex_buffer(0, quad_vertex_buffer, 0);
|
if let Some(RenderResourceId::Buffer(quad_index_buffer)) = render_resource_context
|
||||||
// draw.set_index_buffer(quad_index_buffer, 0);
|
.get_asset_resource(bevy_sprite::QUAD_HANDLE, mesh::INDEX_BUFFER_ASSET_INDEX)
|
||||||
// draw.set_global_bind_groups()?;
|
{
|
||||||
|
draw.set_index_buffer(quad_index_buffer, 0);
|
||||||
|
if let Some(buffer_info) = draw
|
||||||
|
.render_resource_context
|
||||||
|
.get_buffer_info(quad_index_buffer)
|
||||||
|
{
|
||||||
|
indices = 0..(buffer_info.size / 2) as u32;
|
||||||
|
} else {
|
||||||
|
panic!("expected buffer type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// // TODO: ideally the TexureAtlas bind group is automatically generated by AssetRenderResourcesNode and is retrievable
|
// set global bindings
|
||||||
// // here using render_resource_context.get_asset_bind_group(texture_atlas)
|
draw.set_bind_groups_from_bindings(&draw.render_resource_bindings)?;
|
||||||
// let mut atlas_set = RenderResourceSet::build()
|
|
||||||
// .add_assignment(0, draw.get_uniform_buffer(&10)?)
|
// set local per-character bindings
|
||||||
// .finish();
|
for character in self.text.chars() {
|
||||||
|
if let Some(glyph_atlas_info) = self
|
||||||
|
.font_atlas_set
|
||||||
|
.get_glyph_atlas_info(self.style.font_size, character)
|
||||||
|
{
|
||||||
|
let atlas_render_resource_bindings = draw
|
||||||
|
.asset_render_resource_bindings
|
||||||
|
.get(glyph_atlas_info.texture_atlas)
|
||||||
|
.unwrap();
|
||||||
|
draw.set_bind_groups_from_bindings(&atlas_render_resource_bindings)?;
|
||||||
|
let sprite_buffer = TextureAtlasSprite {
|
||||||
|
index: glyph_atlas_info.char_index,
|
||||||
|
position: Vec3::new(300.0, 300.0, 0.0),
|
||||||
|
scale: 5.0,
|
||||||
|
};
|
||||||
|
let sprite_buffer = draw
|
||||||
|
.shared_buffers
|
||||||
|
.get_buffer(&sprite_buffer, BufferUsage::UNIFORM)
|
||||||
|
.unwrap();
|
||||||
|
let sprite_bind_group = BindGroup::build().add_binding(0, sprite_buffer).finish();
|
||||||
|
draw.set_bind_group(2, &sprite_bind_group);
|
||||||
|
draw.draw_indexed(indices.clone(), 0, 0..1);
|
||||||
|
}
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ use bevy_asset::{Assets, Handle};
|
|||||||
use bevy_render::{
|
use bevy_render::{
|
||||||
draw::Draw,
|
draw::Draw,
|
||||||
pipeline::PipelineDescriptor,
|
pipeline::PipelineDescriptor,
|
||||||
render_resource::{RenderResourceBindings, SharedBuffers},
|
render_resource::{AssetRenderResourceBindings, RenderResourceBindings, SharedBuffers},
|
||||||
renderer::RenderResourceContext,
|
renderer::RenderResourceContext,
|
||||||
texture::Texture,
|
texture::Texture,
|
||||||
Color,
|
Color,
|
||||||
@ -80,6 +80,7 @@ impl Label {
|
|||||||
pub fn draw_label_system(
|
pub fn draw_label_system(
|
||||||
_pipelines: Res<Assets<PipelineDescriptor>>,
|
_pipelines: Res<Assets<PipelineDescriptor>>,
|
||||||
_render_resource_bindings: Res<RenderResourceBindings>,
|
_render_resource_bindings: Res<RenderResourceBindings>,
|
||||||
|
_asset_render_resource_bindings: Res<AssetRenderResourceBindings>,
|
||||||
_render_resource_context: Res<Box<dyn RenderResourceContext>>,
|
_render_resource_context: Res<Box<dyn RenderResourceContext>>,
|
||||||
_shared_buffers: Res<SharedBuffers>,
|
_shared_buffers: Res<SharedBuffers>,
|
||||||
_fonts: Res<Assets<Font>>,
|
_fonts: Res<Assets<Font>>,
|
||||||
@ -89,19 +90,18 @@ impl Label {
|
|||||||
_label: Com<Label>,
|
_label: Com<Label>,
|
||||||
_quad: Com<Quad>,
|
_quad: Com<Quad>,
|
||||||
) {
|
) {
|
||||||
// let context = &*render_resources.context;
|
|
||||||
// let mut draw_context = draw.get_context(
|
// let mut draw_context = draw.get_context(
|
||||||
// &pipelines,
|
// &pipelines,
|
||||||
// context,
|
// &**render_resource_context,
|
||||||
// &render_resource_bindings,
|
// &render_resource_bindings,
|
||||||
|
// &asset_render_resource_bindings,
|
||||||
// &shared_buffers,
|
// &shared_buffers,
|
||||||
// );
|
// );
|
||||||
|
|
||||||
// // TODO: getting a font mutably will send out font change events. the atlas should be split from the font to avoid this
|
// TODO: getting a font mutably will send out font change events. the atlas should be split from the font to avoid this
|
||||||
// let mut drawable_text = DrawableText::new(
|
// let mut drawable_text = DrawableText::new(
|
||||||
// label.font,
|
// fonts.get(&label.font).unwrap(),
|
||||||
// &fonts,
|
// font_atlas_sets.get(&label.font.as_handle::<FontAtlasSet>()).unwrap(),
|
||||||
// &font_atlas_sets,
|
|
||||||
// &texture_atlases,
|
// &texture_atlases,
|
||||||
// quad.position,
|
// quad.position,
|
||||||
// &label.style,
|
// &label.style,
|
||||||
|
@ -52,11 +52,11 @@ impl<'a> RenderPass for WgpuRenderPass<'a> {
|
|||||||
fn set_bind_group(
|
fn set_bind_group(
|
||||||
&mut self,
|
&mut self,
|
||||||
index: u32,
|
index: u32,
|
||||||
bind_group_descriptor: BindGroupDescriptorId,
|
bind_group_descriptor_id: BindGroupDescriptorId,
|
||||||
bind_group: BindGroupId,
|
bind_group: BindGroupId,
|
||||||
dynamic_uniform_indices: Option<&[u32]>,
|
dynamic_uniform_indices: Option<&[u32]>,
|
||||||
) {
|
) {
|
||||||
if let Some(bind_group_info) = self.wgpu_resources.bind_groups.get(&bind_group_descriptor) {
|
if let Some(bind_group_info) = self.wgpu_resources.bind_groups.get(&bind_group_descriptor_id) {
|
||||||
if let Some(wgpu_bind_group) = bind_group_info.bind_groups.get(&bind_group) {
|
if let Some(wgpu_bind_group) = bind_group_info.bind_groups.get(&bind_group) {
|
||||||
const EMPTY: &'static [u32] = &[];
|
const EMPTY: &'static [u32] = &[];
|
||||||
let dynamic_uniform_indices =
|
let dynamic_uniform_indices =
|
||||||
@ -68,7 +68,7 @@ impl<'a> RenderPass for WgpuRenderPass<'a> {
|
|||||||
|
|
||||||
log::trace!(
|
log::trace!(
|
||||||
"set bind group {:?} {:?}: {:?}",
|
"set bind group {:?} {:?}: {:?}",
|
||||||
bind_group_descriptor,
|
bind_group_descriptor_id,
|
||||||
dynamic_uniform_indices,
|
dynamic_uniform_indices,
|
||||||
bind_group
|
bind_group
|
||||||
);
|
);
|
||||||
|
@ -36,7 +36,7 @@ fn atlas_render_system(
|
|||||||
if state.added {
|
if state.added {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if let Some(set) = font_atlas_sets.get(&Handle::from_id(state.handle.id)) {
|
if let Some(set) = font_atlas_sets.get(&state.handle.as_handle::<FontAtlasSet>()) {
|
||||||
for (_size, atlas) in set.iter() {
|
for (_size, atlas) in set.iter() {
|
||||||
state.added = true;
|
state.added = true;
|
||||||
let atlas = texture_atlases.get(&atlas.texture_atlas).unwrap();
|
let atlas = texture_atlases.get(&atlas.texture_atlas).unwrap();
|
||||||
|
@ -8,7 +8,7 @@ fn main() {
|
|||||||
.add_default_plugins()
|
.add_default_plugins()
|
||||||
.add_plugin(FrameTimeDiagnosticsPlugin::default())
|
.add_plugin(FrameTimeDiagnosticsPlugin::default())
|
||||||
.add_startup_system(setup.system())
|
.add_startup_system(setup.system())
|
||||||
.add_system(text_update_system.system())
|
// .add_system(text_update_system.system())
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user