Implemented hidden texture in render code

master
Mark 2024-01-21 12:43:55 -08:00
parent 7820458404
commit 64f930b391
Signed by: Mark
GPG Key ID: C6D63995FE72FD80
3 changed files with 99 additions and 40 deletions

View File

@ -103,7 +103,7 @@ fn transform_vertex(obj: ObjectData, vertex_position: vec2<f32>, texture_index:
); );
} }
return vec4<f32>(pos, 0.0, 1.0);; return vec4<f32>(pos, 0.0, 1.0);
} }
@vertex @vertex
@ -113,19 +113,41 @@ fn vertex_main(
) -> VertexOutput { ) -> VertexOutput {
var out: VertexOutput; var out: VertexOutput;
// Pick texture size by the size of the visible texture
// (texture index 0 is special, it's the "hidden" texture)
if instance.texture_index.x == 0u && instance.texture_index.y == 0u {
out.position = vec4<f32>(0.0, 0.0, 0.0, 1.0);
} else if instance.texture_index.x == 0u {
out.position = transform_vertex(
objects[instance.object_index],
vertex.position.xy,
instance.texture_index.y
);
} else if instance.texture_index.y == 0u {
out.position = transform_vertex( out.position = transform_vertex(
objects[instance.object_index], objects[instance.object_index],
vertex.position.xy, vertex.position.xy,
instance.texture_index.x instance.texture_index.x
); );
} else {
out.position = transform_vertex(
objects[instance.object_index],
vertex.position.xy,
instance.texture_index.x
);
}
// Compute texture coordinates
let age = global_data.current_time.x;
out.tween = instance.texture_fade; out.tween = instance.texture_fade;
// Texture 0 is special, it's the empty texture
if instance.texture_index.x == 0u {
out.texture_index_a = 0u;
out.texture_coords_a = vec2(0.0, 0.0);
} else {
let t = global_atlas[instance.texture_index.x]; let t = global_atlas[instance.texture_index.x];
out.texture_index_a = u32(t.atlas_texture); out.texture_index_a = t.atlas_texture;
out.texture_coords_a = vec2(t.xpos, t.ypos); out.texture_coords_a = vec2(t.xpos, t.ypos);
if vertex.texture_coords.x == 1.0 { if vertex.texture_coords.x == 1.0 {
out.texture_coords_a = out.texture_coords_a + vec2(t.width, 0.0); out.texture_coords_a = out.texture_coords_a + vec2(t.width, 0.0);
@ -133,7 +155,12 @@ fn vertex_main(
if vertex.texture_coords.y == 1.0 { if vertex.texture_coords.y == 1.0 {
out.texture_coords_a = out.texture_coords_a + vec2(0.0, t.height); out.texture_coords_a = out.texture_coords_a + vec2(0.0, t.height);
} }
}
if instance.texture_index.y == 0u {
out.texture_index_b = u32(0u);
out.texture_coords_b = vec2(0.0, 0.0);
} else {
let b = global_atlas[instance.texture_index.y]; let b = global_atlas[instance.texture_index.y];
out.texture_index_b = u32(b.atlas_texture); out.texture_index_b = u32(b.atlas_texture);
out.texture_coords_b = vec2(b.xpos, b.ypos); out.texture_coords_b = vec2(b.xpos, b.ypos);
@ -143,6 +170,7 @@ fn vertex_main(
if vertex.texture_coords.y == 1.0 { if vertex.texture_coords.y == 1.0 {
out.texture_coords_b = out.texture_coords_b + vec2(0.0, b.height); out.texture_coords_b = out.texture_coords_b + vec2(0.0, b.height);
} }
}
return out; return out;
} }
@ -150,19 +178,42 @@ fn vertex_main(
@fragment @fragment
fn fragment_main(in: VertexOutput) -> @location(0) vec4<f32> { fn fragment_main(in: VertexOutput) -> @location(0) vec4<f32> {
return mix(
textureSampleLevel( var texture_a: vec4<f32> = vec4(0.0, 0.0, 0.0, 0.0);
if !(
(in.texture_index_a == 0u) &&
(in.texture_coords_a.x == 0.0) &&
(in.texture_coords_a.y == 0.0)
) {
texture_a = textureSampleLevel(
texture_array[in.texture_index_a], texture_array[in.texture_index_a],
sampler_array[0], sampler_array[0],
in.texture_coords_a, in.texture_coords_a,
0.0 0.0
).rgba, ).rgba;
textureSampleLevel( }
var texture_b: vec4<f32> = vec4(0.0, 0.0, 0.0, 0.0);
if !(
(in.texture_index_b == 0u) &&
(in.texture_coords_b.x == 0.0) &&
(in.texture_coords_b.y == 0.0)
) {
texture_b = textureSampleLevel(
texture_array[in.texture_index_b], texture_array[in.texture_index_b],
sampler_array[0], sampler_array[0],
in.texture_coords_b, in.texture_coords_b,
0.0 0.0
).rgba, ).rgba;
}
let color = mix(
texture_a,
texture_b,
in.tween in.tween
); );
return color;
} }

View File

@ -306,7 +306,7 @@ impl<'a> super::GPUState {
], ],
window_scale: [self.state.window.scale_factor() as f32, 0.0], window_scale: [self.state.window.scale_factor() as f32, 0.0],
window_aspect: [self.state.window_aspect, 0.0], window_aspect: [self.state.window_aspect, 0.0],
starfield_sprite: [input.ct.get_config().starfield_texture, 0], starfield_sprite: [input.ct.get_config().starfield_texture.into(), 0],
starfield_tile_size: [input.ct.get_config().starfield_size, 0.0], starfield_tile_size: [input.ct.get_config().starfield_size, 0.0],
starfield_size_limits: [ starfield_size_limits: [
input.ct.get_config().starfield_min_size, input.ct.get_config().starfield_min_size,

View File

@ -112,8 +112,15 @@ impl TextureArray {
for sprite in &ct.sprites { for sprite in &ct.sprites {
for section in sprite.iter_sections() { for section in sprite.iter_sections() {
for idx in &section.frames { for idx in &section.frames {
let image = ct.get_image(*idx); // Some atlas entries may be written twice here,
image_locations.data[*idx as usize] = AtlasImageLocation { // but that's not really a problem. They're all the same!
//
// This happens rarely---only when two different sections
// use the same frame.
let idx = NonZeroU32::new(*idx);
if idx.is_some() {
let image = ct.get_image(idx.unwrap());
image_locations.data[idx.unwrap().get() as usize] = AtlasImageLocation {
xpos: image.x, xpos: image.x,
ypos: image.y, ypos: image.y,
width: image.w, width: image.w,
@ -124,6 +131,7 @@ impl TextureArray {
} }
} }
} }
}
let sampler = device.create_sampler(&wgpu::SamplerDescriptor { let sampler = device.create_sampler(&wgpu::SamplerDescriptor {
address_mode_u: wgpu::AddressMode::ClampToEdge, address_mode_u: wgpu::AddressMode::ClampToEdge,