From f6d058be6639c8e052c5a38dea4f33d6b26ae20c Mon Sep 17 00:00:00 2001 From: Tengu712 Date: Sat, 26 Sep 2026 21:36:43 +0900 Subject: add texture --- src/graphics.rs | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 66 insertions(+), 2 deletions(-) (limited to 'src/graphics.rs') diff --git a/src/graphics.rs b/src/graphics.rs index 6fa13b3..bbe07df 100644 --- a/src/graphics.rs +++ b/src/graphics.rs @@ -2,6 +2,10 @@ use std::{borrow::Cow, sync::Arc}; use wgpu::*; use winit::{dpi::PhysicalSize, event_loop::OwnedDisplayHandle, window::Window}; +mod texture; + +use texture::TextureWrapper; + pub enum AcquireSurfaceTextureResult { Ok(SurfaceTexture), ShouldSkip, @@ -16,6 +20,9 @@ pub struct Renderer { view_format: TextureFormat, present_mode: PresentMode, pipeline: RenderPipeline, + + font_tex: TextureWrapper, + fixed_bind_group: BindGroup, } impl Renderer { @@ -26,7 +33,6 @@ impl Renderer { let size = window.inner_size(); let instance = Instance::new(InstanceDescriptor::new_with_display_handle(display)); - let surface = instance.create_surface(window).map_err(|e| e.to_string())?; let adapter = instance @@ -67,9 +73,30 @@ impl Renderer { source: ShaderSource::Wgsl(Cow::Borrowed(include_str!("shader.wgsl"))), }); + let fixed_bind_group_layout = device.create_bind_group_layout(&BindGroupLayoutDescriptor { + label: None, + entries: &[ + BindGroupLayoutEntry { + binding: 0, + visibility: ShaderStages::FRAGMENT, + ty: BindingType::Sampler(SamplerBindingType::Filtering), + count: None, + }, + BindGroupLayoutEntry { + binding: 1, + visibility: ShaderStages::FRAGMENT, + ty: BindingType::Texture { + sample_type: TextureSampleType::Float { filterable: true }, + view_dimension: TextureViewDimension::D2, + multisampled: false, + }, + count: None, + }, + ], + }); let pipeline_layout = device.create_pipeline_layout(&PipelineLayoutDescriptor { label: None, - bind_group_layouts: &[], + bind_group_layouts: &[Some(&fixed_bind_group_layout)], immediate_size: 0, }); let pipeline = device.create_render_pipeline(&RenderPipelineDescriptor { @@ -98,6 +125,40 @@ impl Renderer { cache: None, }); + // NOTE: 本ゲームではlinearなサンプラしか用意しないので、ここで1個だけ作成すれば良い。 + let sampler = device.create_sampler(&SamplerDescriptor { + label: None, + address_mode_u: AddressMode::ClampToEdge, + address_mode_v: AddressMode::ClampToEdge, + address_mode_w: AddressMode::ClampToEdge, + mag_filter: FilterMode::Linear, + min_filter: FilterMode::Linear, + mipmap_filter: MipmapFilterMode::Linear, + ..Default::default() + }); + // NOTE: 文字テクスチャアトラスは使い回すので、ここで1個だけ作成すれば良い。 + let font_tex = TextureWrapper::new( + &device, + 128, + 128, + TextureFormat::R8Unorm, + TextureUsages::TEXTURE_BINDING | TextureUsages::COPY_DST, + ); + let fixed_bind_group = device.create_bind_group(&BindGroupDescriptor { + label: None, + layout: &fixed_bind_group_layout, + entries: &[ + BindGroupEntry { + binding: 0, + resource: BindingResource::Sampler(&sampler), + }, + BindGroupEntry { + binding: 1, + resource: BindingResource::TextureView(&font_tex.view), + }, + ], + }); + let v = Self { device, queue, @@ -106,6 +167,8 @@ impl Renderer { view_format, present_mode, pipeline, + font_tex, + fixed_bind_group, }; v.configure_surface(size); @@ -161,6 +224,7 @@ impl Renderer { }); render_pass.set_pipeline(&self.pipeline); + render_pass.set_bind_group(0, &self.fixed_bind_group, &[]); // TODO: 描画 -- cgit v1.3.1