Skip to content

Commit 707c228

Browse files
[render] test texture loading
1 parent 3e7d9ce commit 707c228

File tree

5 files changed

+111
-8
lines changed

5 files changed

+111
-8
lines changed

assets/texture/test_tree.png

27.5 KB
Loading

crates/eqx_core/src/util_macros.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,6 @@ macro_rules! shader_src {
1313
#[macro_export]
1414
macro_rules! asset_file {
1515
($path:literal) => {
16-
include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/../../assets/", $path))
16+
include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/../../assets/", $path))
1717
};
1818
}

crates/eqx_window/src/primitives.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1+
// TODO: change from bytemuck to encase for automatic padding/alignment
12
#[repr(C)]
23
#[derive(Copy, Clone, Debug, bytemuck::Zeroable, bytemuck::Pod)]
34
pub struct Vertex {
45
position: [f32; 3],
56
color: [f32; 3],
7+
tex_coords: [f32; 2],
68
}
79

810
impl Vertex {
9-
const ATTRIBUTE: [wgpu::VertexAttribute; 2] =
10-
wgpu::vertex_attr_array![0 => Float32x3, 1 => Float32x3];
11+
const ATTRIBUTE: [wgpu::VertexAttribute; 3] =
12+
wgpu::vertex_attr_array![0 => Float32x3, 1 => Float32x3, 2 => Float32x2];
1113

1214
pub fn descriptor() -> wgpu::VertexBufferLayout<'static> {
1315
wgpu::VertexBufferLayout {
@@ -22,22 +24,27 @@ pub const TEST_VERTICES: &[Vertex] = &[
2224
Vertex {
2325
position: [-0.0868241, 0.49240386, 0.0],
2426
color: [0.5, 0.0, 0.5],
27+
tex_coords: [0.4131759, 0.00759614],
2528
}, // A
2629
Vertex {
2730
position: [-0.49513406, 0.06958647, 0.0],
2831
color: [0.5, 0.0, 0.5],
32+
tex_coords: [0.0048659444, 0.43041354],
2933
}, // B
3034
Vertex {
3135
position: [-0.21918549, -0.44939706, 0.0],
3236
color: [0.5, 0.0, 0.5],
37+
tex_coords: [0.28081453, 0.949397],
3338
}, // C
3439
Vertex {
3540
position: [0.35966998, -0.3473291, 0.0],
3641
color: [0.5, 0.0, 0.5],
42+
tex_coords: [0.85967, 0.84732914],
3743
}, // D
3844
Vertex {
3945
position: [0.44147372, 0.2347359, 0.0],
4046
color: [0.5, 0.0, 0.5],
47+
tex_coords: [0.9414737, 0.2652641],
4148
}, // E
4249
];
4350

crates/eqx_window/src/window.rs

Lines changed: 92 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
use wgpu::util::{BufferInitDescriptor, DeviceExt};
2-
31
use crate::primitives::{Vertex, TEST_INDICES, TEST_VERTICES};
4-
52
use eqx_app::prelude::Module;
3+
use wgpu::util::{BufferInitDescriptor, DeviceExt};
64

75
use winit::{
86
event::*,
@@ -26,6 +24,7 @@ struct State<'a> {
2624
render_pipeline: wgpu::RenderPipeline,
2725
vertex_buffer: wgpu::Buffer,
2826
index_buffer: wgpu::Buffer,
27+
texture_bind_group: wgpu::BindGroup,
2928
}
3029

3130
impl<'a> State<'a> {
@@ -82,6 +81,93 @@ impl<'a> State<'a> {
8281
desired_maximum_frame_latency: 2,
8382
};
8483

84+
let texture_bytes = eqx_core::asset_file!("texture/test_tree.png");
85+
let texture_img = image::load_from_memory(texture_bytes).unwrap();
86+
let texture_rgba = texture_img.to_rgba8();
87+
let texture_dimensions = texture_rgba.dimensions();
88+
let texture_size = wgpu::Extent3d {
89+
width: texture_dimensions.0,
90+
height: texture_dimensions.1,
91+
depth_or_array_layers: 1,
92+
};
93+
94+
let texture = device.create_texture(&wgpu::TextureDescriptor {
95+
label: Some("Texture"),
96+
size: texture_size,
97+
mip_level_count: 1,
98+
sample_count: 1,
99+
dimension: wgpu::TextureDimension::D2,
100+
format: wgpu::TextureFormat::Rgba8UnormSrgb,
101+
usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
102+
view_formats: &[],
103+
});
104+
queue.write_texture(
105+
wgpu::TexelCopyTextureInfo {
106+
texture: &texture,
107+
mip_level: 0,
108+
origin: wgpu::Origin3d::ZERO,
109+
aspect: wgpu::TextureAspect::All,
110+
},
111+
&texture_rgba,
112+
wgpu::TexelCopyBufferLayout {
113+
offset: 0,
114+
bytes_per_row: Some(4 * texture_dimensions.0), // 4 = rgba
115+
rows_per_image: Some(texture_dimensions.1),
116+
},
117+
texture_size,
118+
);
119+
120+
let texture_view = texture.create_view(&wgpu::TextureViewDescriptor::default());
121+
let texture_sampler = device.create_sampler(&wgpu::SamplerDescriptor {
122+
label: Some("TextureSampler"),
123+
address_mode_u: wgpu::AddressMode::ClampToEdge,
124+
address_mode_v: wgpu::AddressMode::ClampToEdge,
125+
address_mode_w: wgpu::AddressMode::ClampToEdge,
126+
mag_filter: wgpu::FilterMode::Linear,
127+
min_filter: wgpu::FilterMode::Linear,
128+
mipmap_filter: wgpu::FilterMode::Nearest,
129+
..Default::default()
130+
});
131+
132+
let texture_bind_group_layout =
133+
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
134+
label: Some("TextureBindGroupLayout"),
135+
entries: &[
136+
wgpu::BindGroupLayoutEntry {
137+
binding: 0,
138+
visibility: wgpu::ShaderStages::FRAGMENT,
139+
ty: wgpu::BindingType::Texture {
140+
multisampled: false,
141+
view_dimension: wgpu::TextureViewDimension::D2,
142+
sample_type: wgpu::TextureSampleType::Float { filterable: true },
143+
},
144+
count: None,
145+
},
146+
wgpu::BindGroupLayoutEntry {
147+
binding: 1,
148+
visibility: wgpu::ShaderStages::FRAGMENT,
149+
// This should match the filterable field of the
150+
// corresponding Texture entry above.
151+
ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
152+
count: None,
153+
},
154+
],
155+
});
156+
let texture_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
157+
label: Some("TextureBindGroup"),
158+
layout: &texture_bind_group_layout,
159+
entries: &[
160+
wgpu::BindGroupEntry {
161+
binding: 0,
162+
resource: wgpu::BindingResource::TextureView(&texture_view),
163+
},
164+
wgpu::BindGroupEntry {
165+
binding: 1,
166+
resource: wgpu::BindingResource::Sampler(&texture_sampler),
167+
},
168+
],
169+
});
170+
85171
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
86172
label: Some("TrigShader"),
87173
source: wgpu::ShaderSource::Wgsl(eqx_core::shader_src!("trig/shader").into()),
@@ -90,7 +176,7 @@ impl<'a> State<'a> {
90176
let render_pipeline_layout =
91177
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
92178
label: Some("RenderPipelineLayout"),
93-
bind_group_layouts: &[],
179+
bind_group_layouts: &[&texture_bind_group_layout],
94180
push_constant_ranges: &[],
95181
});
96182

@@ -154,6 +240,7 @@ impl<'a> State<'a> {
154240
render_pipeline,
155241
vertex_buffer,
156242
index_buffer,
243+
texture_bind_group,
157244
}
158245
}
159246

@@ -211,6 +298,7 @@ impl<'a> State<'a> {
211298
});
212299

213300
render_pass.set_pipeline(&self.render_pipeline);
301+
render_pass.set_bind_group(0, &self.texture_bind_group, &[]);
214302
render_pass.set_vertex_buffer(0, self.vertex_buffer.slice(..));
215303
render_pass.set_index_buffer(self.index_buffer.slice(..), wgpu::IndexFormat::Uint16);
216304
render_pass.draw_indexed(0..TEST_INDICES.len() as u32, 0, 0..1);

shaders/trig/shader.wgsl

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
struct VertexInput {
22
@location(0) vert_pos: vec3<f32>,
33
@location(1) vert_color: vec3<f32>,
4+
@location(2) vert_tex: vec2<f32>,
45
}
56

67
struct VertexOutput {
78
@builtin(position) clip_position: vec4<f32>,
89
@location(0) color: vec3<f32>,
10+
@location(1) tex_coord: vec2<f32>,
911
}
1012

1113
@vertex
@@ -15,13 +17,19 @@ fn vs_main(
1517
var out: VertexOutput;
1618
out.clip_position = vec4<f32>(model.vert_pos, 1.0);
1719
out.color = model.vert_color;
20+
out.tex_coord = model.vert_tex;
1821
return out;
1922
}
2023

24+
@group(0) @binding(0)
25+
var t_diffuse: texture_2d<f32>;
26+
@group(0) @binding(1)
27+
var s_diffuse: sampler;
28+
2129
@fragment
2230
fn fs_main(
2331
in: VertexOutput
2432
) -> @location(0) vec4<f32> {
25-
return vec4<f32>(in.color, 1.0);
33+
return textureSample(t_diffuse, s_diffuse, in.tex_coord);
2634
}
2735

0 commit comments

Comments
 (0)