Add super cool water

This commit is contained in:
Sijmen 2021-05-31 21:24:59 +02:00
parent 1f0a1975a5
commit ff20d5ad29
Signed by: vijfhoek
GPG key ID: 82D05C89B28B0DAE
9 changed files with 125 additions and 95 deletions

View file

@ -15,6 +15,7 @@ pub enum BlockType {
Bedrock, Bedrock,
Sand, Sand,
Gravel, Gravel,
Water,
} }
impl BlockType { impl BlockType {
@ -28,6 +29,7 @@ impl BlockType {
BlockType::Bedrock => ( 5, 5, 5, 5, 5, 5), BlockType::Bedrock => ( 5, 5, 5, 5, 5, 5),
BlockType::Sand => ( 6, 6, 6, 6, 6, 6), BlockType::Sand => ( 6, 6, 6, 6, 6, 6),
BlockType::Gravel => ( 7, 7, 7, 7, 7, 7), BlockType::Gravel => ( 7, 7, 7, 7, 7, 7),
BlockType::Water => ( 8, 8, 8, 8, 8, 8), // up to 71
}; };
indices indices
} }
@ -82,7 +84,7 @@ impl Chunk {
let mut blocks: ChunkBlocks = Default::default(); let mut blocks: ChunkBlocks = Default::default();
for z in 0..CHUNK_SIZE { for z in 0..CHUNK_SIZE {
for x in 0..CHUNK_SIZE { for x in 0..CHUNK_SIZE {
let v = terrain_noise.get_value(x, z) * 20.0 + 64.0; let v = terrain_noise.get_value(x, z) * 20.0 + 128.0;
let v = v.round() as i32; let v = v.round() as i32;
let s = stone_noise.get_value(x, z) * 20.0 + 4.5; let s = stone_noise.get_value(x, z) * 20.0 + 4.5;
@ -113,6 +115,15 @@ impl Chunk {
block_type: BlockType::Bedrock, block_type: BlockType::Bedrock,
}); });
} }
if chunk_y < 128 / CHUNK_SIZE as i32 {
for y in 0..CHUNK_SIZE {
if blocks[y][z][x].is_none() {
blocks[y][z][x] = Some(Block {
block_type: BlockType::Water,
});
}
}
}
} }
} }
@ -176,6 +187,12 @@ impl Chunk {
visited.insert((x, z)); visited.insert((x, z));
if let Some(&block_type) = &culled.get(&(x, z)) { if let Some(&block_type) = &culled.get(&(x, z)) {
if block_type == BlockType::Water {
let quad = Quad::new(x as i32, z as i32, 1, 1);
quads.push((block_type, y as i32, offset, quad));
continue;
}
// Extend horizontally // Extend horizontally
let mut xmax = x + 1; let mut xmax = x + 1;
for x_ in x..CHUNK_SIZE { for x_ in x..CHUNK_SIZE {
@ -218,9 +235,8 @@ impl Chunk {
let mut vertices = Vec::new(); let mut vertices = Vec::new();
let mut indices = Vec::new(); let mut indices = Vec::new();
for (quad_index, (block_type, y, offset, quad)) in quads.iter().enumerate() { for (quad_index, (block_type, y, offset, quad)) in quads.iter().enumerate() {
#[rustfmt::skip] let texture_indices = block_type.texture_indices();
let v = cube::vertices(quad, *y, *offset, block_type.texture_indices()); vertices.extend(&cube::vertices(quad, *y, 1.0, *offset, texture_indices));
vertices.extend(&v);
for index in cube::INDICES { for index in cube::INDICES {
indices.push(index + quad_index as u16 * 24); indices.push(index + quad_index as u16 * 24);

View file

@ -6,11 +6,13 @@ use crate::{quad::Quad, vertex::Vertex};
pub fn vertices( pub fn vertices(
quad: &Quad, quad: &Quad,
y: i32, y: i32,
z_height: f32,
offset: Vector3<i32>, offset: Vector3<i32>,
texture_indices: (usize, usize, usize, usize, usize, usize), texture_indices: (usize, usize, usize, usize, usize, usize),
) -> [Vertex; 24] { ) -> [Vertex; 24] {
let w = quad.w as f32; let w = quad.w as f32;
let h = quad.h as f32; let h = quad.h as f32;
let zh = z_height;
let x = (quad.x + offset.x) as f32; let x = (quad.x + offset.x) as f32;
let y = (y + offset.y) as f32; let y = (y + offset.y) as f32;
@ -23,25 +25,25 @@ pub fn vertices(
// Left // Left
Vertex { position: [x, y, z ], texture_coordinates: [h, 1.0, t.0 as f32], normal: [-1.0, 0.0, 0.0] }, Vertex { position: [x, y, z ], texture_coordinates: [h, 1.0, t.0 as f32], normal: [-1.0, 0.0, 0.0] },
Vertex { position: [x, y, z + h ], texture_coordinates: [0.0, 1.0, t.0 as f32], normal: [-1.0, 0.0, 0.0] }, Vertex { position: [x, y, z + h ], texture_coordinates: [0.0, 1.0, t.0 as f32], normal: [-1.0, 0.0, 0.0] },
Vertex { position: [x, y + 1.0, z + h ], texture_coordinates: [0.0, 0.0, t.0 as f32], normal: [-1.0, 0.0, 0.0] }, Vertex { position: [x, y + zh, z + h ], texture_coordinates: [0.0, 0.0, t.0 as f32], normal: [-1.0, 0.0, 0.0] },
Vertex { position: [x, y + 1.0, z ], texture_coordinates: [h, 0.0, t.0 as f32], normal: [-1.0, 0.0, 0.0] }, Vertex { position: [x, y + zh, z ], texture_coordinates: [h, 0.0, t.0 as f32], normal: [-1.0, 0.0, 0.0] },
// Right // Right
Vertex { position: [x + w, y, z ], texture_coordinates: [0.0, 1.0, t.1 as f32], normal: [1.0, 0.0, 0.0] }, Vertex { position: [x + w, y, z ], texture_coordinates: [0.0, 1.0, t.1 as f32], normal: [1.0, 0.0, 0.0] },
Vertex { position: [x + w, y, z + h ], texture_coordinates: [h, 1.0, t.1 as f32], normal: [1.0, 0.0, 0.0] }, Vertex { position: [x + w, y, z + h ], texture_coordinates: [h, 1.0, t.1 as f32], normal: [1.0, 0.0, 0.0] },
Vertex { position: [x + w, y + 1.0, z + h ], texture_coordinates: [h, 0.0, t.1 as f32], normal: [1.0, 0.0, 0.0] }, Vertex { position: [x + w, y + zh, z + h ], texture_coordinates: [h, 0.0, t.1 as f32], normal: [1.0, 0.0, 0.0] },
Vertex { position: [x + w, y + 1.0, z ], texture_coordinates: [0.0, 0.0, t.1 as f32], normal: [1.0, 0.0, 0.0] }, Vertex { position: [x + w, y + zh, z ], texture_coordinates: [0.0, 0.0, t.1 as f32], normal: [1.0, 0.0, 0.0] },
// Back // Back
Vertex { position: [x, y, z ], texture_coordinates: [w, 1.0, t.2 as f32], normal: [0.0, 0.0, -1.0] }, Vertex { position: [x, y, z ], texture_coordinates: [w, 1.0, t.2 as f32], normal: [0.0, 0.0, -1.0] },
Vertex { position: [x, y + 1.0, z ], texture_coordinates: [w, 0.0, t.2 as f32], normal: [0.0, 0.0, -1.0] }, Vertex { position: [x, y + zh, z ], texture_coordinates: [w, 0.0, t.2 as f32], normal: [0.0, 0.0, -1.0] },
Vertex { position: [x + w, y + 1.0, z ], texture_coordinates: [0.0, 0.0, t.2 as f32], normal: [0.0, 0.0, -1.0] }, Vertex { position: [x + w, y + zh, z ], texture_coordinates: [0.0, 0.0, t.2 as f32], normal: [0.0, 0.0, -1.0] },
Vertex { position: [x + w, y, z ], texture_coordinates: [0.0, 1.0, t.2 as f32], normal: [0.0, 0.0, -1.0] }, Vertex { position: [x + w, y, z ], texture_coordinates: [0.0, 1.0, t.2 as f32], normal: [0.0, 0.0, -1.0] },
// Front // Front
Vertex { position: [x, y, z + h ], texture_coordinates: [0.0, 1.0, t.3 as f32], normal: [0.0, 0.0, 1.0] }, Vertex { position: [x, y, z + h ], texture_coordinates: [0.0, 1.0, t.3 as f32], normal: [0.0, 0.0, 1.0] },
Vertex { position: [x, y + 1.0, z + h ], texture_coordinates: [0.0, 0.0, t.3 as f32], normal: [0.0, 0.0, 1.0] }, Vertex { position: [x, y + zh, z + h ], texture_coordinates: [0.0, 0.0, t.3 as f32], normal: [0.0, 0.0, 1.0] },
Vertex { position: [x + w, y + 1.0, z + h ], texture_coordinates: [w, 0.0, t.3 as f32], normal: [0.0, 0.0, 1.0] }, Vertex { position: [x + w, y + zh, z + h ], texture_coordinates: [w, 0.0, t.3 as f32], normal: [0.0, 0.0, 1.0] },
Vertex { position: [x + w, y, z + h ], texture_coordinates: [w, 1.0, t.3 as f32], normal: [0.0, 0.0, 1.0] }, Vertex { position: [x + w, y, z + h ], texture_coordinates: [w, 1.0, t.3 as f32], normal: [0.0, 0.0, 1.0] },
// Bottom // Bottom
@ -51,10 +53,10 @@ pub fn vertices(
Vertex { position: [x + w, y, z ], texture_coordinates: [0.0, 0.0, t.4 as f32], normal: [0.0, -1.0, 0.0] }, Vertex { position: [x + w, y, z ], texture_coordinates: [0.0, 0.0, t.4 as f32], normal: [0.0, -1.0, 0.0] },
// Top // Top
Vertex { position: [x, y + 1.0, z ], texture_coordinates: [0.0, 0.0, t.5 as f32], normal: [0.0, 1.0, 0.0] }, Vertex { position: [x, y + zh, z ], texture_coordinates: [0.0, 0.0, t.5 as f32], normal: [0.0, 1.0, 0.0] },
Vertex { position: [x, y + 1.0, z + h ], texture_coordinates: [0.0, h, t.5 as f32], normal: [0.0, 1.0, 0.0] }, Vertex { position: [x, y + zh, z + h ], texture_coordinates: [0.0, h, t.5 as f32], normal: [0.0, 1.0, 0.0] },
Vertex { position: [x + w, y + 1.0, z + h ], texture_coordinates: [w, h, t.5 as f32], normal: [0.0, 1.0, 0.0] }, Vertex { position: [x + w, y + zh, z + h ], texture_coordinates: [w, h, t.5 as f32], normal: [0.0, 1.0, 0.0] },
Vertex { position: [x + w, y + 1.0, z ], texture_coordinates: [w, 0.0, t.5 as f32], normal: [0.0, 1.0, 0.0] }, Vertex { position: [x + w, y + zh, z ], texture_coordinates: [w, 0.0, t.5 as f32], normal: [0.0, 1.0, 0.0] },
]; ];
vertices vertices
} }

View file

@ -1,19 +0,0 @@
use cgmath::Vector3;
#[repr(C)]
#[derive(Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
pub struct Light {
pub position: [f32; 3],
pub _padding: u32,
pub color: [f32; 3],
}
impl Light {
pub fn new(position: Vector3<f32>, color: Vector3<f32>) -> Self {
Self {
position: position.into(),
_padding: 0,
color: color.into(),
}
}
}

View file

@ -1,7 +1,7 @@
mod camera; mod camera;
mod chunk; mod chunk;
mod cube; mod cube;
mod light; mod time;
mod quad; mod quad;
mod state; mod state;
mod texture; mod texture;

View file

@ -5,16 +5,15 @@ struct Uniforms {
}; };
[[block]] [[block]]
struct Light { struct Time {
position: vec3<f32>; time: f32;
color: vec3<f32>;
}; };
[[group(1), binding(0)]] [[group(1), binding(0)]]
var<uniform> uniforms: Uniforms; var<uniform> uniforms: Uniforms;
[[group(2), binding(0)]] [[group(2), binding(0)]]
var<uniform> light: Light; var<uniform> time: Time;
struct VertexInput { struct VertexInput {
[[location(0)]] position: vec3<f32>; [[location(0)]] position: vec3<f32>;
@ -32,9 +31,18 @@ struct VertexOutput {
[[stage(vertex)]] [[stage(vertex)]]
fn main(model: VertexInput) -> VertexOutput { fn main(model: VertexInput) -> VertexOutput {
var out: VertexOutput; var out: VertexOutput;
out.texture_coordinates = model.texture_coordinates;
out.world_normal = model.normal; out.world_normal = model.normal;
if (model.texture_coordinates.z == 8.0) {
// water
let offset = (sin(time.time * 0.5 + model.position.x) * cos(time.time * 0.9 + model.position.y) + 2.5) / 10.0;
out.world_position = vec3<f32>(model.position.x, model.position.y - offset, model.position.z);
out.texture_coordinates = vec3<f32>(model.texture_coordinates.xy + (time.time / 10.0), 8.0 + (time.time * 10.0) % 64.0);
} else {
out.world_position = model.position; out.world_position = model.position;
out.texture_coordinates = model.texture_coordinates;
}
out.clip_position = uniforms.view_projection * vec4<f32>(out.world_position, 1.0); out.clip_position = uniforms.view_projection * vec4<f32>(out.world_position, 1.0);
return out; return out;
} }
@ -51,18 +59,21 @@ fn main(in: VertexOutput) -> [[location(0)]] vec4<f32> {
i32(in.texture_coordinates.z) i32(in.texture_coordinates.z)
); );
let ambient_strength = 0.1; let light_position = vec3<f32>(256.0, 500.0, 200.0);
let ambient_color = light.color * ambient_strength; let light_color = vec3<f32>(1.0, 1.0, 1.0);
let light_direction = normalize(light.position - in.world_position); let ambient_strength = 0.1;
let ambient_color = light_color * ambient_strength;
let light_direction = normalize(light_position - in.world_position);
let view_direction = normalize(uniforms.view_position.xyz - in.world_position); let view_direction = normalize(uniforms.view_position.xyz - in.world_position);
let half_direction = normalize(view_direction + light_direction); let half_direction = normalize(view_direction + light_direction);
let diffuse_strength = max(dot(in.world_normal, light_direction), 0.0); let diffuse_strength = max(dot(in.world_normal, light_direction), 0.0);
let diffuse_color = light.color * diffuse_strength; let diffuse_color = light_color * diffuse_strength;
let specular_strength = pow(max(dot(in.world_normal, half_direction), 0.0), 32.0); let specular_strength = pow(max(dot(in.world_normal, half_direction), 0.0), 32.0);
let specular_color = specular_strength * light.color; let specular_color = specular_strength * light_color;
var result: vec3<f32> = (ambient_color + diffuse_color + specular_color) * object_color.xyz; var result: vec3<f32> = (ambient_color + diffuse_color + specular_color) * object_color.xyz;

View file

@ -3,7 +3,7 @@ mod world;
use std::time::Duration; use std::time::Duration;
use cgmath::{InnerSpace, Rad}; use cgmath::{InnerSpace, Rad, Vector3};
use winit::{ use winit::{
event::{DeviceEvent, ElementState, KeyboardInput, VirtualKeyCode}, event::{DeviceEvent, ElementState, KeyboardInput, VirtualKeyCode},
window::Window, window::Window,
@ -219,20 +219,23 @@ impl State {
let (yaw_sin, yaw_cos) = self.world_state.camera.yaw.0.sin_cos(); let (yaw_sin, yaw_cos) = self.world_state.camera.yaw.0.sin_cos();
let forward = cgmath::Vector3::new(yaw_cos, 0.0, yaw_sin).normalize(); let forward = Vector3::new(yaw_cos, 0.0, yaw_sin).normalize();
self.world_state.camera.position += forward * self.forward_speed * 15.0 * dt_secs; self.world_state.camera.position += forward * self.forward_speed * 15.0 * dt_secs;
let right = cgmath::Vector3::new(-yaw_sin, 0.0, yaw_cos).normalize(); let right = Vector3::new(-yaw_sin, 0.0, yaw_cos).normalize();
self.world_state.camera.position += right * self.right_speed * 15.0 * dt_secs; self.world_state.camera.position += right * self.right_speed * 15.0 * dt_secs;
let up = cgmath::Vector3::new(0.0, 1.0, 0.0).normalize(); let up = Vector3::new(0.0, 1.0, 0.0).normalize();
self.world_state.camera.position += up * self.up_speed * 15.0 * dt_secs; self.world_state.camera.position += up * self.up_speed * 15.0 * dt_secs;
self.world_state.update(dt, &self.render_queue);
self.update_aim(); self.update_aim();
self.world_state self.world_state
.uniforms .uniforms
.update_view_projection(&self.world_state.camera, &self.world_state.projection); .update_view_projection(&self.world_state.camera, &self.world_state.projection);
self.render_queue.write_buffer( self.render_queue.write_buffer(
&self.world_state.uniform_buffer, &self.world_state.uniform_buffer,
0, 0,
@ -280,7 +283,7 @@ impl State {
let tm = &self.world_state.texture_manager; let tm = &self.world_state.texture_manager;
render_pass.set_bind_group(0, tm.bind_group.as_ref().unwrap(), &[]); render_pass.set_bind_group(0, tm.bind_group.as_ref().unwrap(), &[]);
render_pass.set_bind_group(1, &self.world_state.uniform_bind_group, &[]); render_pass.set_bind_group(1, &self.world_state.uniform_bind_group, &[]);
render_pass.set_bind_group(2, &self.world_state.light_bind_group, &[]); render_pass.set_bind_group(2, &self.world_state.time_bind_group, &[]);
for (chunk_vertices, chunk_indices, index_count) in &self.world_state.chunk_buffers { for (chunk_vertices, chunk_indices, index_count) in &self.world_state.chunk_buffers {
render_pass.set_vertex_buffer(0, chunk_vertices.slice(..)); render_pass.set_vertex_buffer(0, chunk_vertices.slice(..));

View file

@ -1,13 +1,12 @@
use std::time::Instant; use std::time::{Duration, Instant};
use cgmath::Vector3;
use wgpu::util::{BufferInitDescriptor, DeviceExt}; use wgpu::util::{BufferInitDescriptor, DeviceExt};
use winit::dpi::PhysicalSize; use winit::dpi::PhysicalSize;
use crate::{ use crate::{
camera::{Camera, Projection}, camera::{Camera, Projection},
light::Light,
texture::{Texture, TextureManager}, texture::{Texture, TextureManager},
time::Time,
uniforms::Uniforms, uniforms::Uniforms,
vertex::Vertex, vertex::Vertex,
world::World, world::World,
@ -22,10 +21,12 @@ pub struct WorldState {
pub camera: Camera, pub camera: Camera,
pub projection: Projection, pub projection: Projection,
pub depth_texture: Texture, pub depth_texture: Texture,
pub light_bind_group: wgpu::BindGroup, pub time_bind_group: wgpu::BindGroup,
pub world: World, pub world: World,
pub chunk_buffers: Vec<(wgpu::Buffer, wgpu::Buffer, usize)>, pub chunk_buffers: Vec<(wgpu::Buffer, wgpu::Buffer, usize)>,
time: Time,
time_buffer: wgpu::Buffer,
} }
impl WorldState { impl WorldState {
@ -39,8 +40,8 @@ impl WorldState {
fn create_camera(swap_chain_descriptor: &wgpu::SwapChainDescriptor) -> (Camera, Projection) { fn create_camera(swap_chain_descriptor: &wgpu::SwapChainDescriptor) -> (Camera, Projection) {
let camera = Camera::new( let camera = Camera::new(
(0.0, 80.0, 0.0).into(), (-10.0, 140.0, -10.0).into(),
cgmath::Deg(0.0).into(), cgmath::Deg(45.0).into(),
cgmath::Deg(-20.0).into(), cgmath::Deg(-20.0).into(),
); );
@ -106,21 +107,18 @@ impl WorldState {
) )
} }
fn create_light( fn create_time(
render_device: &wgpu::Device, render_device: &wgpu::Device,
) -> (Light, wgpu::Buffer, wgpu::BindGroupLayout, wgpu::BindGroup) { ) -> (Time, wgpu::Buffer, wgpu::BindGroupLayout, wgpu::BindGroup) {
let light = Light::new( let time = Time::new();
Vector3::new(256.0, 500.0, 200.0),
Vector3::new(1.0, 1.0, 1.0),
);
let light_buffer = render_device.create_buffer_init(&BufferInitDescriptor { let buffer = render_device.create_buffer_init(&BufferInitDescriptor {
label: Some("light_buffer"), label: Some("time_buffer"),
contents: bytemuck::cast_slice(&[light]), contents: bytemuck::cast_slice(&[time]),
usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST, usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST,
}); });
let light_bind_group_layout = let bind_group_layout =
render_device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { render_device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
entries: &[wgpu::BindGroupLayoutEntry { entries: &[wgpu::BindGroupLayoutEntry {
binding: 0, binding: 0,
@ -132,24 +130,19 @@ impl WorldState {
}, },
count: None, count: None,
}], }],
label: Some("light_bind_group_layout"), label: Some("time_bind_group_layout"),
}); });
let light_bind_group = render_device.create_bind_group(&wgpu::BindGroupDescriptor { let bind_group = render_device.create_bind_group(&wgpu::BindGroupDescriptor {
layout: &light_bind_group_layout, layout: &bind_group_layout,
entries: &[wgpu::BindGroupEntry { entries: &[wgpu::BindGroupEntry {
binding: 0, binding: 0,
resource: light_buffer.as_entire_binding(), resource: buffer.as_entire_binding(),
}], }],
label: Some("light_bind_group"), label: Some("time_bind_group"),
}); });
( (time, buffer, bind_group_layout, bind_group)
light,
light_buffer,
light_bind_group_layout,
light_bind_group,
)
} }
fn create_render_pipeline( fn create_render_pipeline(
@ -253,7 +246,7 @@ impl WorldState {
let (uniforms, uniform_buffer, world_uniform_layout, uniform_bind_group) = let (uniforms, uniform_buffer, world_uniform_layout, uniform_bind_group) =
Self::create_uniforms(&camera, &projection, render_device); Self::create_uniforms(&camera, &projection, render_device);
let (_, _, world_light_layout, light_bind_group) = Self::create_light(&render_device); let (time, time_buffer, time_layout, time_bind_group) = Self::create_time(&render_device);
let render_pipeline = Self::create_render_pipeline( let render_pipeline = Self::create_render_pipeline(
&render_device, &render_device,
@ -261,7 +254,7 @@ impl WorldState {
&[ &[
&texture_manager.bind_group_layout, &texture_manager.bind_group_layout,
&world_uniform_layout, &world_uniform_layout,
&world_light_layout, &time_layout,
], ],
); );
@ -277,7 +270,11 @@ impl WorldState {
camera, camera,
projection, projection,
depth_texture, depth_texture,
light_bind_group,
time,
time_buffer,
time_bind_group,
world, world,
chunk_buffers: Vec::new(), chunk_buffers: Vec::new(),
}; };
@ -287,6 +284,11 @@ impl WorldState {
world_state world_state
} }
pub fn update(&mut self, dt: Duration, render_queue: &wgpu::Queue) {
self.time.time += dt.as_secs_f32();
render_queue.write_buffer(&self.time_buffer, 0, &bytemuck::cast_slice(&[self.time]));
}
pub fn resize( pub fn resize(
&mut self, &mut self,
render_device: &wgpu::Device, render_device: &wgpu::Device,

View file

@ -111,7 +111,7 @@ impl Texture {
} }
} }
pub const TEXTURE_COUNT: usize = 8; pub const TEXTURE_COUNT: usize = 72;
pub struct TextureManager { pub struct TextureManager {
pub bind_group_layout: wgpu::BindGroupLayout, pub bind_group_layout: wgpu::BindGroupLayout,
@ -174,6 +174,10 @@ impl TextureManager {
self.load(device, queue, "assets/block/bedrock.png")?; // 5 self.load(device, queue, "assets/block/bedrock.png")?; // 5
self.load(device, queue, "assets/block/sand.png")?; // 6 self.load(device, queue, "assets/block/sand.png")?; // 6
self.load(device, queue, "assets/block/gravel.png")?; // 7 self.load(device, queue, "assets/block/gravel.png")?; // 7
for i in 0..64 {
let path = format!("assets/water_still_plains/frame-{}.png", i);
self.load(device, queue, &path)?; // 8 - 71
}
assert_eq!(TEXTURE_COUNT, self.textures.len()); assert_eq!(TEXTURE_COUNT, self.textures.len());
let texture_array = device.create_texture(&wgpu::TextureDescriptor { let texture_array = device.create_texture(&wgpu::TextureDescriptor {

11
src/time.rs Normal file
View file

@ -0,0 +1,11 @@
#[repr(C)]
#[derive(Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
pub struct Time {
pub time: f32,
}
impl Time {
pub fn new() -> Self {
Self { time: 0.0 }
}
}