render: more progress on immediate mode rendering and DrawableText

This commit is contained in:
Carter Anderson 2020-06-17 13:10:33 -07:00
parent f4acbdddad
commit e57fdca1bc
16 changed files with 259 additions and 158 deletions

View File

@ -1,8 +1,8 @@
use crate::{
pipeline::{BindGroupDescriptor, BindGroupDescriptorId, PipelineDescriptor},
pipeline::{PipelineDescriptor, PipelineLayout},
render_resource::{
BindGroup, BindGroupId, BufferId, BufferUsage, RenderResource, RenderResourceBinding,
RenderResourceBindings, SharedBuffers,
AssetRenderResourceBindings, BindGroup, BindGroupId, BufferId, BufferUsage, RenderResource,
RenderResourceBinding, RenderResourceBindings, SharedBuffers,
},
renderer::RenderResourceContext,
};
@ -31,7 +31,6 @@ pub enum RenderCommand {
},
SetBindGroup {
index: u32,
bind_group_descriptor: BindGroupDescriptorId,
bind_group: BindGroupId,
dynamic_uniform_indices: Option<Arc<Vec<u32>>>,
},
@ -64,6 +63,7 @@ impl Draw {
pipelines: &'a Assets<PipelineDescriptor>,
render_resource_context: &'a dyn RenderResourceContext,
render_resource_bindings: &'a RenderResourceBindings,
asset_render_resource_bindings: &'a AssetRenderResourceBindings,
shared_buffers: &'a SharedBuffers,
) -> DrawContext {
DrawContext {
@ -71,6 +71,7 @@ impl Draw {
pipelines,
render_resource_context,
render_resource_bindings,
asset_render_resource_bindings,
shared_buffers,
current_pipeline: None,
}
@ -89,6 +90,8 @@ pub enum DrawError {
NoPipelineSet,
#[error("Pipeline has no layout")]
PipelineHasNoLayout,
#[error("A BindGroup with the given index does not exist")]
BindGroupDescriptorDoesNotExist { index: u32 },
#[error("Failed to get a buffer for the given RenderResource.")]
BufferAllocationFailure,
}
@ -98,6 +101,7 @@ pub struct DrawContext<'a> {
pub pipelines: &'a Assets<PipelineDescriptor>,
pub render_resource_context: &'a dyn RenderResourceContext,
pub render_resource_bindings: &'a RenderResourceBindings,
pub asset_render_resource_bindings: &'a AssetRenderResourceBindings,
pub shared_buffers: &'a SharedBuffers,
pub current_pipeline: Option<&'a PipelineDescriptor>,
}
@ -146,14 +150,9 @@ impl<'a> DrawContext<'a> {
self.render_command(RenderCommand::SetIndexBuffer { buffer, offset });
}
pub fn set_bind_group(
&mut self,
bind_group_descriptor: &BindGroupDescriptor,
bind_group: &BindGroup,
) {
pub fn set_bind_group(&mut self, index: u32, bind_group: &BindGroup) {
self.render_command(RenderCommand::SetBindGroup {
index: bind_group_descriptor.index,
bind_group_descriptor: bind_group_descriptor.id,
index,
bind_group: bind_group.id,
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]
pub fn render_command(&mut self, render_command: RenderCommand) {
self.draw.render_commands.push(render_command);
@ -185,6 +218,7 @@ pub fn draw_system<T: Drawable + Component>(
pipelines: Res<Assets<PipelineDescriptor>>,
render_resource_bindings: Res<RenderResourceBindings>,
render_resource_context: Res<Box<dyn RenderResourceContext>>,
asset_render_resource_bindings: Res<AssetRenderResourceBindings>,
shared_buffers: Res<SharedBuffers>,
mut draw: ComMut<Draw>,
mut drawable: ComMut<T>,
@ -193,6 +227,7 @@ pub fn draw_system<T: Drawable + Component>(
&pipelines,
&**render_resource_context,
&render_resource_bindings,
&asset_render_resource_bindings,
&shared_buffers,
);
draw_context.draw(drawable.as_mut()).unwrap();

View File

@ -18,7 +18,7 @@ pub trait RenderPass {
fn set_bind_group(
&mut self,
index: u32,
bind_group_descriptor: BindGroupDescriptorId,
bind_group_descriptor_id: BindGroupDescriptorId,
bind_group: BindGroupId,
dynamic_uniform_indices: Option<&[u32]>,
);

View File

@ -1,5 +1,5 @@
use super::{
state_descriptors::PrimitiveTopology, PipelineDescriptor, RenderPipeline, RenderPipelines,
state_descriptors::PrimitiveTopology, PipelineDescriptor, RenderPipelines,
VertexBufferDescriptors,
};
use crate::{
@ -8,9 +8,8 @@ use crate::{
shader::{Shader, ShaderSource},
};
use bevy_asset::{Assets, Handle};
use std::collections::{HashMap, HashSet};
use legion::prelude::*;
use std::collections::{HashMap, HashSet};
#[derive(Clone, Eq, PartialEq, Debug, Default)]
pub struct PipelineSpecialization {
@ -78,20 +77,22 @@ impl PipelineCompiler {
fn compile_pipeline(
&mut self,
vertex_buffer_descriptors: &VertexBufferDescriptors,
render_resource_context: &dyn RenderResourceContext,
pipelines: &mut Assets<PipelineDescriptor>,
shaders: &mut Assets<Shader>,
pipeline_descriptor: &PipelineDescriptor,
render_pipeline: &RenderPipeline,
source_pipeline: Handle<PipelineDescriptor>,
vertex_buffer_descriptors: &VertexBufferDescriptors,
pipeline_specialization: &PipelineSpecialization,
render_resource_bindings: &RenderResourceBindings,
) -> PipelineDescriptor {
let mut compiled_pipeline_descriptor = pipeline_descriptor.clone();
compiled_pipeline_descriptor.shader_stages.vertex = self.compile_shader(
) -> Handle<PipelineDescriptor> {
let source_descriptor = pipelines.get(&source_pipeline).unwrap();
let mut compiled_descriptor = source_descriptor.clone();
compiled_descriptor.shader_stages.vertex = self.compile_shader(
shaders,
&pipeline_descriptor.shader_stages.vertex,
&render_pipeline.specialization.shader_specialization,
&compiled_descriptor.shader_stages.vertex,
&pipeline_specialization.shader_specialization,
);
compiled_pipeline_descriptor.shader_stages.fragment = pipeline_descriptor
compiled_descriptor.shader_stages.fragment = compiled_descriptor
.shader_stages
.fragment
.as_ref()
@ -99,23 +100,42 @@ impl PipelineCompiler {
self.compile_shader(
shaders,
fragment,
&render_pipeline.specialization.shader_specialization,
&pipeline_specialization.shader_specialization,
)
});
compiled_pipeline_descriptor.reflect_layout(
compiled_descriptor.reflect_layout(
shaders,
true,
Some(vertex_buffer_descriptors),
Some(render_resource_bindings),
);
compiled_pipeline_descriptor.primitive_topology =
render_pipeline.specialization.primitive_topology;
compiled_pipeline_descriptor
compiled_descriptor.primitive_topology = pipeline_specialization.primitive_topology;
let compiled_pipeline_handle =
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,
vertex_buffer_descriptors: &VertexBufferDescriptors,
pipelines: &mut Assets<PipelineDescriptor>,
@ -125,44 +145,27 @@ impl PipelineCompiler {
) {
for render_pipeline in render_pipelines.pipelines.iter_mut() {
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)) =
self.specialized_pipelines
.get_mut(&source_pipeline)
.unwrap()
.iter()
.find(|(pipeline_specialization, _compiled_pipeline_handle)| {
*pipeline_specialization == render_pipeline.specialization
.and_then(|specialized_pipelines| {
specialized_pipelines.iter().find(
|(pipeline_specialization, _compiled_pipeline_handle)| {
*pipeline_specialization == render_pipeline.specialization
},
)
}) {
*compiled_pipeline_handle
} else {
let pipeline_descriptor = pipelines.get(&source_pipeline).unwrap();
let compiled_pipeline_descriptor = self.compile_pipeline(
vertex_buffer_descriptors,
self.compile_pipeline(
render_resource_context,
pipelines,
shaders,
pipeline_descriptor,
render_pipeline,
source_pipeline,
vertex_buffer_descriptors,
&render_pipeline.specialization,
&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);
@ -198,15 +201,44 @@ pub fn compile_pipelines_system(
mut pipeline_compiler: ResMut<PipelineCompiler>,
mut shaders: ResMut<Assets<Shader>>,
mut pipelines: ResMut<Assets<PipelineDescriptor>>,
// pipeline_asset_events: Res<Events<AssetEvent<PipelineDescriptor>>>,
vertex_buffer_descriptors: Res<VertexBufferDescriptors>,
render_resource_context: Res<Box<dyn RenderResourceContext>>,
query: &mut Query<Write<RenderPipelines>>,
) {
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
for mut render_pipelines in query.iter_mut(world) {
pipeline_compiler.compile_pipelines(
pipeline_compiler.compile_render_pipelines(
&vertex_buffer_descriptors,
&mut pipelines,
&mut shaders,

View File

@ -9,6 +9,12 @@ pub struct 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 {
let mut bind_groups = HashMap::<u32, BindGroupDescriptor>::new();
let mut vertex_buffer_descriptors = Vec::new();

View File

@ -69,12 +69,12 @@ impl Drawable for RenderPipelines {
.bindings
.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
.render_resource_bindings
.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;

View File

@ -80,6 +80,10 @@ impl CommandQueue {
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) {
for command in self.queue.lock().unwrap().drain(..) {
match command {

View File

@ -131,13 +131,15 @@ impl Node for MainPassNode {
}
RenderCommand::SetBindGroup {
index,
bind_group_descriptor,
bind_group,
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(
*index,
*bind_group_descriptor,
bind_group_descriptor.id,
*bind_group,
dynamic_uniform_indices
.as_ref()

View File

@ -1,13 +1,15 @@
mod camera_node;
mod pass_node;
mod main_pass_node;
mod render_resources_node;
mod shared_buffers_node;
mod texture_copy_node;
mod window_swapchain_node;
mod window_texture_node;
pub use camera_node::*;
pub use pass_node::*;
pub use main_pass_node::*;
pub use render_resources_node::*;
pub use shared_buffers_node::*;
pub use texture_copy_node::*;
pub use window_swapchain_node::*;
pub use window_texture_node::*;

View File

@ -1,6 +1,5 @@
use crate::{
render_graph::{Node, ResourceSlots},
render_resource::SharedBuffers,
renderer::RenderContext,
};
use legion::prelude::*;
@ -12,13 +11,14 @@ impl Node for SharedBuffersNode {
fn update(
&mut self,
_world: &World,
resources: &Resources,
render_context: &mut dyn RenderContext,
_resources: &Resources,
_render_context: &mut dyn RenderContext,
_input: &ResourceSlots,
_output: &mut ResourceSlots,
) {
let shared_buffers = resources.get::<SharedBuffers>().unwrap();
let mut command_queue = shared_buffers.reset_command_queue();
// TODO: enable me
// let shared_buffers = resources.get::<SharedBuffers>().unwrap();
// let mut command_queue = shared_buffers.reset_command_queue();
// command_queue.execute(render_context);
}
}

View File

@ -1,5 +1,5 @@
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 std::{
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> {
self.bind_groups.get(&id)
}

View File

@ -1,41 +1,11 @@
use crate::{
pipeline::{PipelineCompiler, PipelineDescriptor, RenderPipelines},
render_resource::{BindGroupStatus, RenderResourceBindings},
render_resource::RenderResourceBindings,
renderer::RenderResourceContext,
};
use bevy_asset::Assets;
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(
world: &mut SubWorld,
pipelines: Res<Assets<PipelineDescriptor>>,
@ -47,11 +17,7 @@ pub fn bind_groups_system(
let render_resource_context = &**render_resource_context;
for compiled_pipeline_handle in pipeline_compiler.iter_all_compiled_pipelines() {
let pipeline = pipelines.get(compiled_pipeline_handle).unwrap();
update_bind_groups(
pipeline,
&mut render_resource_bindings,
render_resource_context,
)
render_resource_bindings.update_bind_groups(pipeline, render_resource_context);
}
for mut render_pipelines in query.iter_mut(world) {
let render_pipelines = render_pipelines.as_mut();
@ -59,11 +25,7 @@ pub fn bind_groups_system(
let pipeline = pipelines
.get(&render_pipeline.specialized_pipeline.unwrap())
.unwrap();
update_bind_groups(
pipeline,
&mut render_pipelines.bindings,
render_resource_context,
)
render_pipelines.bindings.update_bind_groups(pipeline, render_resource_context);
}
}
}

View File

@ -1,11 +1,13 @@
use crate::{Font, FontAtlasSet};
use bevy_asset::{Assets, Handle};
use bevy_asset::Assets;
use bevy_render::{
draw::{DrawError, Drawable},
draw::{DrawContext, DrawError, Drawable},
mesh,
render_resource::{BindGroup, BufferUsage, RenderResourceId},
Color,
};
use bevy_sprite::TextureAtlas;
use glam::Vec2;
use bevy_sprite::{TextureAtlas, TextureAtlasSprite};
use glam::{Vec2, Vec3};
pub struct TextStyle {
pub font_size: f32,
@ -14,9 +16,8 @@ pub struct TextStyle {
#[allow(dead_code)]
pub struct DrawableText<'a> {
font_handle: Handle<Font>,
fonts: &'a Assets<Font>,
font_atlas_sets: &'a Assets<FontAtlasSet>,
font: &'a Font,
font_atlas_set: &'a FontAtlasSet,
texture_atlases: &'a Assets<TextureAtlas>,
position: Vec2,
style: &'a TextStyle,
@ -25,18 +26,16 @@ pub struct DrawableText<'a> {
impl<'a> DrawableText<'a> {
pub fn new(
font_handle: Handle<Font>,
fonts: &'a Assets<Font>,
font_atlas_sets: &'a Assets<FontAtlasSet>,
font: &'a Font,
font_atlas_set: &'a FontAtlasSet,
texture_atlases: &'a Assets<TextureAtlas>,
position: Vec2,
style: &'a TextStyle,
text: &'a str,
) -> Self {
Self {
font_handle,
fonts,
font_atlas_sets,
font,
font_atlas_set,
texture_atlases,
position,
style,
@ -46,25 +45,58 @@ impl<'a> DrawableText<'a> {
}
impl<'a> Drawable for DrawableText<'a> {
fn draw(&mut self, _draw: &mut bevy_render::draw::DrawContext) -> Result<(), DrawError> {
// draw.set_pipeline(bevy_sprite::SPRITE_SHEET_PIPELINE_HANDLE)?;
// let render_resource_context = draw.render_resource_context;
// // TODO: add draw.set_mesh(slot)
// let quad_vertex_buffer = render_resource_context
// .get_asset_resource(bevy_sprite::QUAD_HANDLE, mesh::VERTEX_BUFFER_ASSET_INDEX)
// .unwrap();
// let quad_index_buffer = render_resource_context
// .get_asset_resource(bevy_sprite::QUAD_HANDLE, mesh::INDEX_BUFFER_ASSET_INDEX)
// .unwrap();
// draw.set_vertex_buffer(0, quad_vertex_buffer, 0);
// draw.set_index_buffer(quad_index_buffer, 0);
// draw.set_global_bind_groups()?;
fn draw(&mut self, draw: &mut DrawContext) -> Result<(), DrawError> {
draw.set_pipeline(bevy_sprite::SPRITE_SHEET_PIPELINE_HANDLE)?;
let render_resource_context = draw.render_resource_context;
// TODO: add draw.set_mesh(slot)
if let Some(RenderResourceId::Buffer(quad_vertex_buffer)) = render_resource_context
.get_asset_resource(bevy_sprite::QUAD_HANDLE, mesh::VERTEX_BUFFER_ASSET_INDEX)
{
draw.set_vertex_buffer(0, quad_vertex_buffer, 0);
}
let mut indices = 0..0;
if let Some(RenderResourceId::Buffer(quad_index_buffer)) = render_resource_context
.get_asset_resource(bevy_sprite::QUAD_HANDLE, mesh::INDEX_BUFFER_ASSET_INDEX)
{
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
// // here using render_resource_context.get_asset_bind_group(texture_atlas)
// let mut atlas_set = RenderResourceSet::build()
// .add_assignment(0, draw.get_uniform_buffer(&10)?)
// .finish();
// set global bindings
draw.set_bind_groups_from_bindings(&draw.render_resource_bindings)?;
// set local per-character bindings
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(())
}
}

View File

@ -2,7 +2,7 @@ use bevy_asset::{Assets, Handle};
use bevy_render::{
draw::Draw,
pipeline::PipelineDescriptor,
render_resource::{RenderResourceBindings, SharedBuffers},
render_resource::{AssetRenderResourceBindings, RenderResourceBindings, SharedBuffers},
renderer::RenderResourceContext,
texture::Texture,
Color,
@ -80,6 +80,7 @@ impl Label {
pub fn draw_label_system(
_pipelines: Res<Assets<PipelineDescriptor>>,
_render_resource_bindings: Res<RenderResourceBindings>,
_asset_render_resource_bindings: Res<AssetRenderResourceBindings>,
_render_resource_context: Res<Box<dyn RenderResourceContext>>,
_shared_buffers: Res<SharedBuffers>,
_fonts: Res<Assets<Font>>,
@ -89,19 +90,18 @@ impl Label {
_label: Com<Label>,
_quad: Com<Quad>,
) {
// let context = &*render_resources.context;
// let mut draw_context = draw.get_context(
// &pipelines,
// context,
// &**render_resource_context,
// &render_resource_bindings,
// &asset_render_resource_bindings,
// &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(
// label.font,
// &fonts,
// &font_atlas_sets,
// fonts.get(&label.font).unwrap(),
// font_atlas_sets.get(&label.font.as_handle::<FontAtlasSet>()).unwrap(),
// &texture_atlases,
// quad.position,
// &label.style,

View File

@ -52,11 +52,11 @@ impl<'a> RenderPass for WgpuRenderPass<'a> {
fn set_bind_group(
&mut self,
index: u32,
bind_group_descriptor: BindGroupDescriptorId,
bind_group_descriptor_id: BindGroupDescriptorId,
bind_group: BindGroupId,
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) {
const EMPTY: &'static [u32] = &[];
let dynamic_uniform_indices =
@ -68,7 +68,7 @@ impl<'a> RenderPass for WgpuRenderPass<'a> {
log::trace!(
"set bind group {:?} {:?}: {:?}",
bind_group_descriptor,
bind_group_descriptor_id,
dynamic_uniform_indices,
bind_group
);

View File

@ -36,7 +36,7 @@ fn atlas_render_system(
if state.added {
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() {
state.added = true;
let atlas = texture_atlases.get(&atlas.texture_atlas).unwrap();

View File

@ -8,7 +8,7 @@ fn main() {
.add_default_plugins()
.add_plugin(FrameTimeDiagnosticsPlugin::default())
.add_startup_system(setup.system())
.add_system(text_update_system.system())
// .add_system(text_update_system.system())
.run();
}