From: Josh Simmons Date: Sat, 11 May 2024 11:13:26 +0000 (+0200) Subject: shark: Rename Text shader to Ui X-Git-Url: https://git.nega.tv//gitweb.cgi?a=commitdiff_plain;h=c683151f27077dd730f50d319062becb5109081e;p=josh%2Fnarcissus shark: Rename Text shader to Ui --- diff --git a/title/shark-shaders/build.rs b/title/shark-shaders/build.rs index 4934ede..ff53b83 100644 --- a/title/shark-shaders/build.rs +++ b/title/shark-shaders/build.rs @@ -35,11 +35,11 @@ const SHADERS: [Shader; 4] = [ }, Shader { stage: ShaderStage::Vertex, - name: "text", + name: "ui", }, Shader { stage: ShaderStage::Fragment, - name: "text", + name: "ui", }, ]; diff --git a/title/shark-shaders/shaders/text.frag.glsl b/title/shark-shaders/shaders/ui.frag.glsl similarity index 100% rename from title/shark-shaders/shaders/text.frag.glsl rename to title/shark-shaders/shaders/ui.frag.glsl diff --git a/title/shark-shaders/shaders/text.vert.glsl b/title/shark-shaders/shaders/ui.vert.glsl similarity index 100% rename from title/shark-shaders/shaders/text.vert.glsl rename to title/shark-shaders/shaders/ui.vert.glsl diff --git a/title/shark/src/main.rs b/title/shark/src/main.rs index fd87d79..1b331a7 100644 --- a/title/shark/src/main.rs +++ b/title/shark/src/main.rs @@ -1,3 +1,4 @@ +use std::fmt::Write; use std::path::Path; use std::time::{Duration, Instant}; @@ -19,7 +20,7 @@ use narcissus_image as image; use narcissus_maths::{ clamp, perlin_noise3, sin_pi_f32, vec3, Affine3, Deg, HalfTurn, Mat3, Mat4, Point3, Vec3, }; -use pipelines::{BasicPipeline, BasicUniforms, PrimitiveInstance, PrimitiveVertex, TextPipeline}; +use pipelines::{BasicPipeline, BasicUniforms, PrimitiveInstance, PrimitiveVertex, UiPipeline}; use spring::simple_spring_damper_exact; mod fonts; @@ -438,6 +439,9 @@ struct UiState<'a> { scale: f32, fonts: &'a Fonts<'a>, glyph_cache: GlyphCache<'a, Fonts<'a>>, + + tmp_string: String, + primitive_instances: Vec, primitive_vertices: Vec, } @@ -450,19 +454,30 @@ impl<'a> UiState<'a> { scale, fonts, glyph_cache, + tmp_string: default(), primitive_instances: vec![], primitive_vertices: vec![], } } - fn text(&mut self, mut x: f32, y: f32, font_family: FontFamily, font_size_px: f32, text: &str) { + fn text_fmt( + &mut self, + mut x: f32, + y: f32, + font_family: FontFamily, + font_size_px: f32, + args: std::fmt::Arguments, + ) { let font = self.fonts.font(font_family); let font_size_px = font_size_px * self.scale; let scale = font.scale_for_size_px(font_size_px); let mut prev_index = None; - for c in text.chars() { + self.tmp_string.clear(); + self.tmp_string.write_fmt(args).unwrap(); + + for c in self.tmp_string.chars() { let glyph_index = font .glyph_index(c) .unwrap_or_else(|| font.glyph_index('□').unwrap()); @@ -539,7 +554,7 @@ struct DrawState<'device> { gpu: &'device Gpu, basic_pipeline: BasicPipeline, - text_pipeline: TextPipeline, + ui_pipeline: UiPipeline, width: u32, height: u32, @@ -686,7 +701,7 @@ fn load_images(gpu: &Gpu, thread_token: &ThreadToken) -> Images { impl<'device> DrawState<'device> { fn new(gpu: &'device Gpu, thread_token: &ThreadToken) -> Self { let basic_pipeline = BasicPipeline::new(gpu); - let text_pipeline = TextPipeline::new(gpu); + let ui_pipeline = UiPipeline::new(gpu); let models = load_models(gpu); let images = load_images(gpu, thread_token); @@ -694,7 +709,7 @@ impl<'device> DrawState<'device> { Self { gpu, basic_pipeline, - text_pipeline, + ui_pipeline, width: 0, height: 0, depth_image: default(), @@ -1014,25 +1029,90 @@ impl<'device> DrawState<'device> { // We're done with you now! self.transforms.clear(); + } - // Render text stuff. - self.text_pipeline.bind( - gpu, + // Render UI stuff. + { + let ui_uniforms = &pipelines::UiUniforms { + screen_width: width, + screen_height: height, + atlas_width, + atlas_height, + }; + let primitive_vertices = ui_state.primitive_vertices.as_slice(); + let primitive_instances = ui_state.primitive_instances.as_slice(); + let uniforms_buffer = gpu.request_transient_buffer_with_data( frame, thread_token, - cmd_encoder, - &pipelines::TextUniforms { - screen_width: width, - screen_height: height, - atlas_width, - atlas_height, - }, - ui_state.primitive_vertices.as_slice(), + BufferUsageFlags::UNIFORM, + ui_uniforms, + ); + let primitive_vertex_buffer = gpu.request_transient_buffer_with_data( + frame, + thread_token, + BufferUsageFlags::STORAGE, + primitive_vertices, + ); + let cached_glyphs_buffer = gpu.request_transient_buffer_with_data( + frame, + thread_token, + BufferUsageFlags::STORAGE, touched_glyphs, - ui_state.primitive_instances.as_slice(), - self.glyph_atlas_image, + ); + let glyph_instance_buffer = gpu.request_transient_buffer_with_data( + frame, + thread_token, + BufferUsageFlags::STORAGE, + primitive_instances, ); + { + gpu.cmd_set_pipeline(cmd_encoder, self.ui_pipeline.pipeline); + gpu.cmd_set_bind_group( + frame, + cmd_encoder, + self.ui_pipeline.bind_group_layout, + 0, + &[ + Bind { + binding: 0, + array_element: 0, + typed: TypedBind::UniformBuffer(&[uniforms_buffer.to_arg()]), + }, + Bind { + binding: 1, + array_element: 0, + typed: TypedBind::StorageBuffer( + &[primitive_vertex_buffer.to_arg()], + ), + }, + Bind { + binding: 2, + array_element: 0, + typed: TypedBind::StorageBuffer(&[cached_glyphs_buffer.to_arg()]), + }, + Bind { + binding: 3, + array_element: 0, + typed: TypedBind::StorageBuffer(&[glyph_instance_buffer.to_arg()]), + }, + Bind { + binding: 4, + array_element: 0, + typed: TypedBind::Sampler(&[self.ui_pipeline.sampler]), + }, + Bind { + binding: 5, + array_element: 0, + typed: TypedBind::Image(&[( + ImageLayout::Optimal, + self.glyph_atlas_image, + )]), + }, + ], + ); + }; + gpu.cmd_draw( cmd_encoder, ui_state.primitive_vertices.len() as u32, @@ -1043,7 +1123,7 @@ impl<'device> DrawState<'device> { ui_state.primitive_instances.clear(); ui_state.primitive_vertices.clear(); - }; + } gpu.cmd_end_rendering(cmd_encoder); } @@ -1193,15 +1273,21 @@ pub fn main() { let tick_duration = Instant::now() - tick_start; - ui_state.text( + ui_state.text_fmt( 5.0, 30.0, FontFamily::RobotoRegular, 22.0, - format!("tick: {:?}", tick_duration).as_str(), + format_args!("tick: {:?}", tick_duration), ); - ui_state.text(5.0, 60.0, FontFamily::NotoSansJapanese, 22.0, "お握り"); + ui_state.text_fmt( + 5.0, + 60.0, + FontFamily::NotoSansJapanese, + 18.0, + format_args!("お握り The Quick Brown Fox Jumped Over The Lazy Dog"), + ); draw_state.draw( thread_token, diff --git a/title/shark/src/pipelines/mod.rs b/title/shark/src/pipelines/mod.rs index 303a68c..2626abb 100644 --- a/title/shark/src/pipelines/mod.rs +++ b/title/shark/src/pipelines/mod.rs @@ -1,6 +1,6 @@ mod basic; -mod text; +mod ui; pub use basic::{BasicPipeline, BasicUniforms, Vertex}; -pub use text::{PrimitiveInstance, PrimitiveVertex, TextPipeline, TextUniforms}; +pub use ui::{PrimitiveInstance, PrimitiveVertex, UiPipeline, UiUniforms}; diff --git a/title/shark/src/pipelines/text.rs b/title/shark/src/pipelines/ui.rs similarity index 53% rename from title/shark/src/pipelines/text.rs rename to title/shark/src/pipelines/ui.rs index bdfe8f8..9a30c45 100644 --- a/title/shark/src/pipelines/text.rs +++ b/title/shark/src/pipelines/ui.rs @@ -1,18 +1,17 @@ use narcissus_core::default; -use narcissus_font::{TouchedGlyph, TouchedGlyphIndex}; +use narcissus_font::TouchedGlyphIndex; use narcissus_gpu::{ - Bind, BindGroupLayout, BindGroupLayoutDesc, BindGroupLayoutEntryDesc, BindingType, BlendMode, - BufferUsageFlags, CmdEncoder, CompareOp, CullingMode, DeviceExt, Frame, FrontFace, - GraphicsPipelineDesc, GraphicsPipelineLayout, Image, ImageFormat, ImageLayout, Pipeline, - PolygonMode, Sampler, SamplerAddressMode, SamplerDesc, SamplerFilter, ShaderDesc, - ShaderStageFlags, ThreadToken, Topology, TypedBind, + BindGroupLayout, BindGroupLayoutDesc, BindGroupLayoutEntryDesc, BindingType, BlendMode, + CompareOp, CullingMode, FrontFace, GraphicsPipelineDesc, GraphicsPipelineLayout, ImageFormat, + Pipeline, PolygonMode, Sampler, SamplerAddressMode, SamplerDesc, SamplerFilter, ShaderDesc, + ShaderStageFlags, Topology, }; use crate::Gpu; #[allow(unused)] #[repr(C)] -pub struct TextUniforms { +pub struct UiUniforms { pub screen_width: u32, pub screen_height: u32, pub atlas_width: u32, @@ -45,13 +44,13 @@ pub struct PrimitiveInstance { pub color: u32, } -pub struct TextPipeline { - bind_group_layout: BindGroupLayout, - sampler: Sampler, - pipeline: Pipeline, +pub struct UiPipeline { + pub bind_group_layout: BindGroupLayout, + pub sampler: Sampler, + pub pipeline: Pipeline, } -impl TextPipeline { +impl UiPipeline { pub fn new(gpu: &Gpu) -> Self { let bind_group_layout = gpu.create_bind_group_layout(&BindGroupLayoutDesc { entries: &[ @@ -106,11 +105,11 @@ impl TextPipeline { let pipeline = gpu.create_graphics_pipeline(&GraphicsPipelineDesc { vertex_shader: ShaderDesc { entry: c"main", - code: shark_shaders::TEXT_VERT_SPV, + code: shark_shaders::UI_VERT_SPV, }, fragment_shader: ShaderDesc { entry: c"main", - code: shark_shaders::TEXT_FRAG_SPV, + code: shark_shaders::UI_FRAG_SPV, }, bind_group_layouts: &[bind_group_layout], layout: GraphicsPipelineLayout { @@ -139,82 +138,4 @@ impl TextPipeline { pipeline, } } - - pub fn bind( - &self, - gpu: &Gpu, - frame: &Frame, - thread_token: &ThreadToken, - cmd_encoder: &mut CmdEncoder, - text_uniforms: &TextUniforms, - primitive_vertices: &[PrimitiveVertex], - touched_glyphs: &[TouchedGlyph], - primitive_instances: &[PrimitiveInstance], - glyph_atlas_image: Image, - ) { - let uniforms_buffer = gpu.request_transient_buffer_with_data( - frame, - thread_token, - BufferUsageFlags::UNIFORM, - text_uniforms, - ); - let primitive_vertex_buffer = gpu.request_transient_buffer_with_data( - frame, - thread_token, - BufferUsageFlags::STORAGE, - primitive_vertices, - ); - let cached_glyphs_buffer = gpu.request_transient_buffer_with_data( - frame, - thread_token, - BufferUsageFlags::STORAGE, - touched_glyphs, - ); - let glyph_instance_buffer = gpu.request_transient_buffer_with_data( - frame, - thread_token, - BufferUsageFlags::STORAGE, - primitive_instances, - ); - - gpu.cmd_set_pipeline(cmd_encoder, self.pipeline); - gpu.cmd_set_bind_group( - frame, - cmd_encoder, - self.bind_group_layout, - 0, - &[ - Bind { - binding: 0, - array_element: 0, - typed: TypedBind::UniformBuffer(&[uniforms_buffer.to_arg()]), - }, - Bind { - binding: 1, - array_element: 0, - typed: TypedBind::StorageBuffer(&[primitive_vertex_buffer.to_arg()]), - }, - Bind { - binding: 2, - array_element: 0, - typed: TypedBind::StorageBuffer(&[cached_glyphs_buffer.to_arg()]), - }, - Bind { - binding: 3, - array_element: 0, - typed: TypedBind::StorageBuffer(&[glyph_instance_buffer.to_arg()]), - }, - Bind { - binding: 4, - array_element: 0, - typed: TypedBind::Sampler(&[self.sampler]), - }, - Bind { - binding: 5, - array_element: 0, - typed: TypedBind::Image(&[(ImageLayout::Optimal, glyph_atlas_image)]), - }, - ], - ); - } }