summaryrefslogtreecommitdiff
path: root/src/graphics.rs
diff options
context:
space:
mode:
authorTengu712 <genreihoutengu@gmail.com>2026-10-07 00:57:01 +0900
committerTengu712 <genreihoutengu@gmail.com>2026-10-07 00:57:01 +0900
commit3bbe5ebcdb2a5aa6810dd05576c6ec031efdc1c7 (patch)
tree844e4ba5efc755dabf091a51178937a93e1d47ed /src/graphics.rs
parent503486e2ce889858aac619985516374bddeb7a8f (diff)
render imageHEADmain
Diffstat (limited to 'src/graphics.rs')
-rw-r--r--src/graphics.rs53
1 files changed, 43 insertions, 10 deletions
diff --git a/src/graphics.rs b/src/graphics.rs
index bab9f05..92defc2 100644
--- a/src/graphics.rs
+++ b/src/graphics.rs
@@ -1,25 +1,31 @@
-use glam::{Vec2, Vec4};
-use std::{borrow::Cow, mem, slice, sync::Arc};
+use glam::{Mat2, Vec2};
+use std::{borrow::Cow, mem, num::NonZeroU32, slice, sync::Arc};
use wgpu::*;
use winit::{dpi::PhysicalSize, event_loop::OwnedDisplayHandle, window::Window};
pub mod command;
mod font;
+pub mod image;
mod texture;
use command::RenderCommand;
use font::CharAtlas;
+use image::ImageId;
+use texture::TextureWrapper;
pub const INSTANCE_MAX_COUNT: u64 = 128;
+const IMAGE_SLOT_COUNT: u32 = 5;
#[repr(C)]
struct InstanceData {
+ // 拡縮・回転行列 NDCを考慮していること
+ transform: Mat2,
// 中央原点 左→右[-1, 1] 下→上[-1, 1]
- position: Vec2,
- // 拡大率 (width, height): [0, 1]^2
- scale: Vec2,
- // (u, v, width, height): [0, 1]^4
- uv: Vec4,
+ translation: Vec2,
+ uv_offset: Vec2,
+ uv_size: Vec2,
+ tex_id: u32,
+ _pad: u32,
}
pub enum AcquireSurfaceTextureResult {
@@ -40,6 +46,7 @@ pub struct Renderer {
instances: Buffer,
trans_bind_group: BindGroup,
char_atlas: CharAtlas,
+ images: Vec<TextureWrapper>,
fixed_bind_group: BindGroup,
}
@@ -61,7 +68,15 @@ impl Renderer {
.await
.map_err(|e| e.to_string())?;
let (device, queue) = adapter
- .request_device(&DeviceDescriptor::default())
+ .request_device(&DeviceDescriptor {
+ required_features: Features::TEXTURE_BINDING_ARRAY
+ | Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING,
+ required_limits: Limits {
+ max_binding_array_elements_per_shader_stage: IMAGE_SLOT_COUNT,
+ ..Default::default()
+ },
+ ..Default::default()
+ })
.await
.map_err(|e| e.to_string())?;
@@ -110,6 +125,16 @@ impl Renderer {
},
count: None,
},
+ BindGroupLayoutEntry {
+ binding: 2,
+ visibility: ShaderStages::FRAGMENT,
+ ty: BindingType::Texture {
+ sample_type: TextureSampleType::Float { filterable: true },
+ view_dimension: TextureViewDimension::D2,
+ multisampled: false,
+ },
+ count: NonZeroU32::new(IMAGE_SLOT_COUNT),
+ },
],
});
let pipeline_layout = device.create_pipeline_layout(&PipelineLayoutDescriptor {
@@ -183,6 +208,8 @@ impl Renderer {
});
// NOTE: 文字テクスチャアトラスは使い回すので、ここで1個だけ作成すれば良い。
let char_atlas = CharAtlas::new(scale_factor, &device);
+ // NOTE: 画像テクスチャ配列は使いまわすので、ここで1個だけ作成すればいい。
+ let images = image::create_textures(&device, &queue);
let fixed_bind_group = device.create_bind_group(&BindGroupDescriptor {
label: None,
layout: &fixed_bind_group_layout,
@@ -195,6 +222,12 @@ impl Renderer {
binding: 1,
resource: BindingResource::TextureView(&char_atlas.texture.view),
},
+ BindGroupEntry {
+ binding: 2,
+ resource: BindingResource::TextureViewArray(
+ &[&images[ImageId::Image as usize].view; IMAGE_SLOT_COUNT as usize],
+ ),
+ },
],
});
@@ -209,6 +242,7 @@ impl Renderer {
instances,
trans_bind_group,
char_atlas,
+ images,
fixed_bind_group,
};
@@ -282,10 +316,9 @@ impl Renderer {
window.scale_factor() as f32,
&self.queue,
&mut self.char_atlas,
+ &self.images,
&mut instances,
);
- // TODO: 今はfont_texしか使わないので1ドローコールで済むが、
- // bind groupを変える必要があればドローコールを切る。
}
instances.truncate(INSTANCE_MAX_COUNT as usize);
let bytes = unsafe {