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,35 +113,63 @@ fn vertex_main(
) -> VertexOutput { ) -> VertexOutput {
var out: VertexOutput; var out: VertexOutput;
out.position = transform_vertex( // Pick texture size by the size of the visible texture
objects[instance.object_index], // (texture index 0 is special, it's the "hidden" texture)
vertex.position.xy, if instance.texture_index.x == 0u && instance.texture_index.y == 0u {
instance.texture_index.x 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(
objects[instance.object_index],
vertex.position.xy,
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;
let t = global_atlas[instance.texture_index.x]; // Texture 0 is special, it's the empty texture
out.texture_index_a = u32(t.atlas_texture); if instance.texture_index.x == 0u {
out.texture_coords_a = vec2(t.xpos, t.ypos); out.texture_index_a = 0u;
if vertex.texture_coords.x == 1.0 { out.texture_coords_a = vec2(0.0, 0.0);
out.texture_coords_a = out.texture_coords_a + vec2(t.width, 0.0); } else {
} let t = global_atlas[instance.texture_index.x];
if vertex.texture_coords.y == 1.0 { out.texture_index_a = t.atlas_texture;
out.texture_coords_a = out.texture_coords_a + vec2(0.0, t.height); out.texture_coords_a = vec2(t.xpos, t.ypos);
if vertex.texture_coords.x == 1.0 {
out.texture_coords_a = out.texture_coords_a + vec2(t.width, 0.0);
}
if vertex.texture_coords.y == 1.0 {
out.texture_coords_a = out.texture_coords_a + vec2(0.0, t.height);
}
} }
let b = global_atlas[instance.texture_index.y]; if instance.texture_index.y == 0u {
out.texture_index_b = u32(b.atlas_texture); out.texture_index_b = u32(0u);
out.texture_coords_b = vec2(b.xpos, b.ypos); out.texture_coords_b = vec2(0.0, 0.0);
if vertex.texture_coords.x == 1.0 { } else {
out.texture_coords_b = out.texture_coords_b + vec2(b.width, 0.0); let b = global_atlas[instance.texture_index.y];
} out.texture_index_b = u32(b.atlas_texture);
if vertex.texture_coords.y == 1.0 { out.texture_coords_b = vec2(b.xpos, b.ypos);
out.texture_coords_b = out.texture_coords_b + vec2(0.0, b.height); if vertex.texture_coords.x == 1.0 {
out.texture_coords_b = out.texture_coords_b + vec2(b.width, 0.0);
}
if vertex.texture_coords.y == 1.0 {
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,15 +112,23 @@ 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!
xpos: image.x, //
ypos: image.y, // This happens rarely---only when two different sections
width: image.w, // use the same frame.
height: image.h, let idx = NonZeroU32::new(*idx);
atlas_texture: image.atlas, if idx.is_some() {
_padding: Default::default(), let image = ct.get_image(idx.unwrap());
}; image_locations.data[idx.unwrap().get() as usize] = AtlasImageLocation {
xpos: image.x,
ypos: image.y,
width: image.w,
height: image.h,
atlas_texture: image.atlas,
_padding: Default::default(),
};
}
} }
} }
} }