mirror of
https://github.com/bevyengine/bevy
synced 2024-11-10 07:04:33 +00:00
text: immediate-mode atlased text rendering works, but theres no character positioning/layout yet
This commit is contained in:
parent
a3c1b7930e
commit
da3d6983a7
5 changed files with 95 additions and 56 deletions
|
@ -126,7 +126,6 @@ pub struct DrawContext<'a> {
|
|||
pub pipeline_compiler: ResMut<'a, PipelineCompiler>,
|
||||
pub render_resource_context: Res<'a, Box<dyn RenderResourceContext>>,
|
||||
pub vertex_buffer_descriptors: Res<'a, VertexBufferDescriptors>,
|
||||
pub asset_render_resource_bindings: Res<'a, AssetRenderResourceBindings>,
|
||||
pub shared_buffers: Res<'a, SharedBuffers>,
|
||||
pub current_pipeline: Option<Handle<PipelineDescriptor>>,
|
||||
}
|
||||
|
@ -145,12 +144,6 @@ impl<'a> ResourceSet for DrawContext<'a> {
|
|||
resources.get::<VertexBufferDescriptors>().unwrap().deref()
|
||||
as *const VertexBufferDescriptors,
|
||||
),
|
||||
asset_render_resource_bindings: Res::new(
|
||||
resources
|
||||
.get::<AssetRenderResourceBindings>()
|
||||
.unwrap()
|
||||
.deref() as *const AssetRenderResourceBindings,
|
||||
),
|
||||
shared_buffers: Res::new(
|
||||
resources.get::<SharedBuffers>().unwrap().deref() as *const SharedBuffers
|
||||
),
|
||||
|
@ -277,6 +270,26 @@ impl<'a> DrawContext<'a> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn create_bind_group_resource(
|
||||
&self,
|
||||
index: u32,
|
||||
bind_group: &BindGroup,
|
||||
) -> Result<(), DrawError> {
|
||||
let pipeline = self
|
||||
.current_pipeline
|
||||
.ok_or_else(|| DrawError::NoPipelineSet)?;
|
||||
let pipeline_descriptor = self
|
||||
.pipelines
|
||||
.get(&pipeline)
|
||||
.ok_or_else(|| DrawError::NonExistentPipeline)?;
|
||||
let layout = pipeline_descriptor
|
||||
.get_layout()
|
||||
.ok_or_else(|| DrawError::PipelineHasNoLayout)?;
|
||||
let bind_group_descriptor = &layout.bind_groups[index as usize];
|
||||
self.render_resource_context.create_bind_group(bind_group_descriptor.id, bind_group);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn set_vertex_buffers_from_bindings(
|
||||
&self,
|
||||
draw: &mut Draw,
|
||||
|
|
|
@ -1,13 +1,17 @@
|
|||
use crate::{Font, FontAtlasSet};
|
||||
use bevy_asset::Assets;
|
||||
use bevy_render::{
|
||||
draw::{DrawContext, DrawError, Drawable, Draw},
|
||||
draw::{Draw, DrawContext, DrawError, Drawable},
|
||||
mesh,
|
||||
render_resource::{BindGroup, BufferUsage, RenderResourceId},
|
||||
Color, pipeline::PipelineSpecialization,
|
||||
pipeline::PipelineSpecialization,
|
||||
render_resource::{
|
||||
AssetRenderResourceBindings, BindGroup, BufferUsage, RenderResourceBindings,
|
||||
RenderResourceId,
|
||||
},
|
||||
Color,
|
||||
};
|
||||
use bevy_sprite::{TextureAtlas, TextureAtlasSprite};
|
||||
use glam::{Vec2, Vec3};
|
||||
use glam::Vec3;
|
||||
|
||||
pub struct TextStyle {
|
||||
pub font_size: f32,
|
||||
|
@ -19,7 +23,9 @@ pub struct DrawableText<'a> {
|
|||
font: &'a Font,
|
||||
font_atlas_set: &'a FontAtlasSet,
|
||||
texture_atlases: &'a Assets<TextureAtlas>,
|
||||
position: Vec2,
|
||||
render_resource_bindings: &'a mut RenderResourceBindings,
|
||||
asset_render_resource_bindings: &'a mut AssetRenderResourceBindings,
|
||||
position: Vec3,
|
||||
style: &'a TextStyle,
|
||||
text: &'a str,
|
||||
}
|
||||
|
@ -29,7 +35,9 @@ impl<'a> DrawableText<'a> {
|
|||
font: &'a Font,
|
||||
font_atlas_set: &'a FontAtlasSet,
|
||||
texture_atlases: &'a Assets<TextureAtlas>,
|
||||
position: Vec2,
|
||||
render_resource_bindings: &'a mut RenderResourceBindings,
|
||||
asset_render_resource_bindings: &'a mut AssetRenderResourceBindings,
|
||||
position: Vec3,
|
||||
style: &'a TextStyle,
|
||||
text: &'a str,
|
||||
) -> Self {
|
||||
|
@ -37,6 +45,8 @@ impl<'a> DrawableText<'a> {
|
|||
font,
|
||||
font_atlas_set,
|
||||
texture_atlases,
|
||||
render_resource_bindings,
|
||||
asset_render_resource_bindings,
|
||||
position,
|
||||
style,
|
||||
text,
|
||||
|
@ -46,7 +56,12 @@ impl<'a> DrawableText<'a> {
|
|||
|
||||
impl<'a> Drawable for DrawableText<'a> {
|
||||
fn draw(&mut self, draw: &mut Draw, context: &mut DrawContext) -> Result<(), DrawError> {
|
||||
context.set_pipeline(draw, bevy_sprite::SPRITE_SHEET_PIPELINE_HANDLE, PipelineSpecialization::empty())?;
|
||||
context.set_pipeline(
|
||||
draw,
|
||||
bevy_sprite::SPRITE_SHEET_PIPELINE_HANDLE,
|
||||
PipelineSpecialization::empty(),
|
||||
)?;
|
||||
|
||||
let render_resource_context = &**context.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)
|
||||
|
@ -58,17 +73,16 @@ impl<'a> Drawable for DrawableText<'a> {
|
|||
.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) = render_resource_context
|
||||
.get_buffer_info(quad_index_buffer)
|
||||
{
|
||||
if let Some(buffer_info) = render_resource_context.get_buffer_info(quad_index_buffer) {
|
||||
indices = 0..(buffer_info.size / 2) as u32;
|
||||
} else {
|
||||
panic!("expected buffer type");
|
||||
}
|
||||
}
|
||||
|
||||
let current_position = Vec3::new(0.0, 0.0, 0.0);
|
||||
// set global bindings
|
||||
// context.set_bind_groups_from_bindings(draw, &mut[context.render_resource_bindings])?;
|
||||
context.set_bind_groups_from_bindings(draw, &mut [self.render_resource_bindings])?;
|
||||
|
||||
// set local per-character bindings
|
||||
for character in self.text.chars() {
|
||||
|
@ -76,21 +90,24 @@ impl<'a> Drawable for DrawableText<'a> {
|
|||
.font_atlas_set
|
||||
.get_glyph_atlas_info(self.style.font_size, character)
|
||||
{
|
||||
// let atlas_render_resource_bindings = context
|
||||
// .asset_render_resource_bindings
|
||||
// .get_mut(glyph_atlas_info.texture_atlas)
|
||||
// .unwrap();
|
||||
// context.set_bind_groups_from_bindings(draw, &mut[atlas_render_resource_bindings])?;
|
||||
let atlas_render_resource_bindings = self
|
||||
.asset_render_resource_bindings
|
||||
.get_mut(glyph_atlas_info.texture_atlas)
|
||||
.unwrap();
|
||||
context
|
||||
.set_bind_groups_from_bindings(draw, &mut [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,
|
||||
position: current_position,
|
||||
scale: 1.0,
|
||||
};
|
||||
|
||||
let sprite_buffer = context
|
||||
.shared_buffers
|
||||
.get_buffer(&sprite_buffer, BufferUsage::UNIFORM)
|
||||
.unwrap();
|
||||
let sprite_bind_group = BindGroup::build().add_binding(0, sprite_buffer).finish();
|
||||
context.create_bind_group_resource(2, &sprite_bind_group)?;
|
||||
draw.set_bind_group(2, &sprite_bind_group);
|
||||
draw.draw_indexed(indices.clone(), 0, 0..1);
|
||||
}
|
||||
|
|
|
@ -1,8 +1,14 @@
|
|||
use bevy_asset::{Assets, Handle};
|
||||
use bevy_render::{draw::{DrawContext, Draw}, texture::Texture, Color};
|
||||
use bevy_render::{
|
||||
draw::{Draw, DrawContext, Drawable},
|
||||
render_resource::{AssetRenderResourceBindings, RenderResourceBindings},
|
||||
texture::Texture,
|
||||
Color,
|
||||
};
|
||||
use bevy_sprite::{ColorMaterial, ComMut, Quad, TextureAtlas};
|
||||
use bevy_text::{Font, FontAtlasSet, TextStyle};
|
||||
use bevy_text::{DrawableText, Font, FontAtlasSet, TextStyle};
|
||||
use legion::prelude::{Com, Res, ResMut};
|
||||
use glam::Vec3;
|
||||
|
||||
pub struct Label {
|
||||
pub text: String,
|
||||
|
@ -51,6 +57,11 @@ impl Label {
|
|||
label.style.font_size,
|
||||
&label.text,
|
||||
);
|
||||
|
||||
let material = color_materials.get_or_insert_with(*color_material_handle, || {
|
||||
ColorMaterial::from(Handle::<Texture>::new())
|
||||
});
|
||||
|
||||
let texture = font.render_text(
|
||||
&label.text,
|
||||
label.style.color,
|
||||
|
@ -59,36 +70,33 @@ impl Label {
|
|||
height as usize,
|
||||
);
|
||||
|
||||
let material = color_materials.get_or_insert_with(*color_material_handle, || {
|
||||
ColorMaterial::from(Handle::<Texture>::new())
|
||||
});
|
||||
if let Some(texture_handle) = material.texture {
|
||||
textures.set(texture_handle, texture);
|
||||
} else {
|
||||
material.texture = Some(textures.add(texture));
|
||||
}
|
||||
material.texture = Some(textures.add(texture));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn draw_label_system(
|
||||
mut _draw_context: DrawContext,
|
||||
_fonts: Res<Assets<Font>>,
|
||||
_font_atlas_sets: Res<Assets<FontAtlasSet>>,
|
||||
_texture_atlases: Res<Assets<TextureAtlas>>,
|
||||
mut _draw: ComMut<Draw>,
|
||||
_label: Com<Label>,
|
||||
_quad: Com<Quad>,
|
||||
mut draw_context: DrawContext,
|
||||
fonts: Res<Assets<Font>>,
|
||||
font_atlas_sets: Res<Assets<FontAtlasSet>>,
|
||||
texture_atlases: Res<Assets<TextureAtlas>>,
|
||||
mut render_resource_bindings: ResMut<RenderResourceBindings>,
|
||||
mut asset_render_resource_bindings: ResMut<AssetRenderResourceBindings>,
|
||||
mut draw: ComMut<Draw>,
|
||||
label: Com<Label>,
|
||||
quad: Com<Quad>,
|
||||
) {
|
||||
// let mut drawable_text = DrawableText::new(
|
||||
// fonts.get(&label.font).unwrap(),
|
||||
// font_atlas_sets
|
||||
// .get(&label.font.as_handle::<FontAtlasSet>())
|
||||
// .unwrap(),
|
||||
// &texture_atlases,
|
||||
// quad.position,
|
||||
// &label.style,
|
||||
// &label.text,
|
||||
// );
|
||||
// drawable_text.draw(&mut draw, &mut draw_context).unwrap();
|
||||
let mut drawable_text = DrawableText::new(
|
||||
fonts.get(&label.font).unwrap(),
|
||||
font_atlas_sets
|
||||
.get(&label.font.as_handle::<FontAtlasSet>())
|
||||
.unwrap(),
|
||||
&texture_atlases,
|
||||
&mut render_resource_bindings,
|
||||
&mut asset_render_resource_bindings,
|
||||
Vec3::new(quad.position.x(), quad.position.y(), 0.0),
|
||||
&label.style,
|
||||
&label.text,
|
||||
);
|
||||
drawable_text.draw(&mut draw, &mut draw_context).unwrap();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,11 +37,11 @@ fn atlas_render_system(
|
|||
return;
|
||||
}
|
||||
if let Some(set) = font_atlas_sets.get(&state.handle.as_handle::<FontAtlasSet>()) {
|
||||
for (_size, atlas) in set.iter() {
|
||||
for (_size, font_atlas) in set.iter() {
|
||||
state.added = true;
|
||||
let atlas = texture_atlases.get(&atlas.texture_atlas).unwrap();
|
||||
let texture_atlas = texture_atlases.get(&font_atlas.texture_atlas).unwrap();
|
||||
command_buffer.build().add_entity(SpriteEntity {
|
||||
material: materials.add(atlas.texture.into()),
|
||||
material: materials.add(texture_atlas.texture.into()),
|
||||
quad: Quad {
|
||||
position: Vec2::new(-300.0, 0.),
|
||||
..Default::default()
|
||||
|
|
|
@ -25,6 +25,7 @@ fn setup(command_buffer: &mut CommandBuffer, asset_server: Res<AssetServer>) {
|
|||
command_buffer
|
||||
.build()
|
||||
// 2d camera
|
||||
.add_entity(OrthographicCameraEntity::default())
|
||||
.add_entity(OrthographicCameraEntity::ui())
|
||||
// texture
|
||||
.add_entity(LabelEntity {
|
||||
|
|
Loading…
Reference in a new issue