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
@ -113,35 +113,63 @@ fn vertex_main(
) -> VertexOutput {
var out: VertexOutput;
out.position = transform_vertex(
objects[instance.object_index],
vertex.position.xy,
instance.texture_index.x
);
// 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(
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;
let t = global_atlas[instance.texture_index.x];
out.texture_index_a = u32(t.atlas_texture);
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);
// 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];
out.texture_index_a = t.atlas_texture;
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];
out.texture_index_b = u32(b.atlas_texture);
out.texture_coords_b = vec2(b.xpos, b.ypos);
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);
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];
out.texture_index_b = u32(b.atlas_texture);
out.texture_coords_b = vec2(b.xpos, b.ypos);
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;
@ -150,19 +178,42 @@ fn vertex_main(
@fragment
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],
sampler_array[0],
in.texture_coords_a,
0.0
).rgba,
textureSampleLevel(
).rgba;
}
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],
sampler_array[0],
in.texture_coords_b,
0.0
).rgba,
).rgba;
}
let color = mix(
texture_a,
texture_b,
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_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_size_limits: [
input.ct.get_config().starfield_min_size,

View File

@ -112,15 +112,23 @@ impl TextureArray {
for sprite in &ct.sprites {
for section in sprite.iter_sections() {
for idx in &section.frames {
let image = ct.get_image(*idx);
image_locations.data[*idx as usize] = AtlasImageLocation {
xpos: image.x,
ypos: image.y,
width: image.w,
height: image.h,
atlas_texture: image.atlas,
_padding: Default::default(),
};
// Some atlas entries may be written twice here,
// 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,
ypos: image.y,
width: image.w,
height: image.h,
atlas_texture: image.atlas,
_padding: Default::default(),
};
}
}
}
}