Move basic rendering context to RenderContext

This way they can be passed around much more easily
This commit is contained in:
Sijmen 2021-06-01 16:47:28 +02:00
parent a3236f610a
commit bfa7a48483
Signed by: vijfhoek
GPG key ID: 82D05C89B28B0DAE
6 changed files with 442 additions and 420 deletions

View file

@ -8,6 +8,7 @@ mod time;
mod uniforms;
mod vertex;
mod world;
mod render_context;
use std::time::{Duration, Instant};
use wgpu::SwapChainError;

7
src/render_context.rs Normal file
View file

@ -0,0 +1,7 @@
pub struct RenderContext {
pub surface: wgpu::Surface,
pub device: wgpu::Device,
pub queue: wgpu::Queue,
pub swap_chain_descriptor: wgpu::SwapChainDescriptor,
pub swap_chain: wgpu::SwapChain,
}

View file

@ -3,7 +3,7 @@ use wgpu::{
CommandEncoder, Device, Queue, SwapChainDescriptor, SwapChainTexture,
};
use crate::{texture::Texture, vertex::Vertex};
use crate::{render_context::RenderContext, texture::Texture, vertex::Vertex};
const UI_SCALE_X: f32 = 0.0045;
const UI_SCALE_Y: f32 = 0.008;
@ -16,27 +16,25 @@ pub struct HudState {
}
impl HudState {
pub fn new(
render_device: &Device,
render_queue: &Queue,
swap_chain_descriptor: &SwapChainDescriptor,
) -> Self {
let (texture_bind_group_layout, texture_bind_group) =
Self::create_textures(render_device, render_queue);
pub fn new(render_context: &RenderContext) -> Self {
let (texture_bind_group_layout, texture_bind_group) = Self::create_textures(render_context);
let render_pipeline = Self::create_render_pipeline(
&render_device,
&swap_chain_descriptor,
&[&texture_bind_group_layout],
);
let render_pipeline =
Self::create_render_pipeline(render_context, &[&texture_bind_group_layout]);
let crosshair_vertex_buffer = render_device.create_buffer_init(&BufferInitDescriptor {
let crosshair_vertex_buffer =
render_context
.device
.create_buffer_init(&BufferInitDescriptor {
label: Some("HUD crosshair vertex buffer"),
contents: bytemuck::cast_slice(&CROSSHAIR_VERTICES),
usage: wgpu::BufferUsage::VERTEX,
});
let crosshair_index_buffer = render_device.create_buffer_init(&BufferInitDescriptor {
let crosshair_index_buffer =
render_context
.device
.create_buffer_init(&BufferInitDescriptor {
label: Some("HUD crosshair index buffer"),
contents: bytemuck::cast_slice(CROSSHAIR_INDICES),
usage: wgpu::BufferUsage::INDEX,
@ -81,26 +79,26 @@ impl HudState {
Ok(CROSSHAIR_INDICES.len() / 3)
}
fn create_textures(
render_device: &wgpu::Device,
render_queue: &wgpu::Queue,
) -> (wgpu::BindGroupLayout, wgpu::BindGroup) {
fn create_textures(render_context: &RenderContext) -> (wgpu::BindGroupLayout, wgpu::BindGroup) {
let texture = Texture::from_bytes(
render_device,
render_queue,
render_context,
include_bytes!("../../assets/gui/widgets.png"),
"Texture GUI widgets",
)
.unwrap();
let sampler = render_device.create_sampler(&wgpu::SamplerDescriptor {
let sampler = render_context
.device
.create_sampler(&wgpu::SamplerDescriptor {
mag_filter: wgpu::FilterMode::Nearest,
min_filter: wgpu::FilterMode::Linear,
..wgpu::SamplerDescriptor::default()
});
let bind_group_layout =
render_device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
render_context
.device
.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
label: Some("GUI texture bind group layout"),
entries: &[
wgpu::BindGroupLayoutEntry {
@ -125,7 +123,9 @@ impl HudState {
],
});
let bind_group = render_device.create_bind_group(&wgpu::BindGroupDescriptor {
let bind_group = render_context
.device
.create_bind_group(&wgpu::BindGroupDescriptor {
label: Some("GUI texture bind group"),
layout: &bind_group_layout,
entries: &[
@ -144,24 +144,29 @@ impl HudState {
}
fn create_render_pipeline(
render_device: &wgpu::Device,
swap_chain_descriptor: &SwapChainDescriptor,
render_context: &RenderContext,
bind_group_layouts: &[&wgpu::BindGroupLayout],
) -> wgpu::RenderPipeline {
let module = &render_device.create_shader_module(&wgpu::ShaderModuleDescriptor {
let module = &render_context
.device
.create_shader_module(&wgpu::ShaderModuleDescriptor {
label: Some("UI shader"),
flags: wgpu::ShaderFlags::all(),
source: wgpu::ShaderSource::Wgsl(include_str!("../shaders/ui.wgsl").into()),
});
let pipeline_layout =
render_device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
render_context
.device
.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
label: Some("UI render pipeline layout"),
bind_group_layouts,
push_constant_ranges: &[],
});
render_device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
render_context
.device
.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
label: Some("UI render pipeline"),
layout: Some(&pipeline_layout),
vertex: wgpu::VertexState {
@ -173,7 +178,7 @@ impl HudState {
module,
entry_point: "main",
targets: &[wgpu::ColorTargetState {
format: swap_chain_descriptor.format,
format: render_context.swap_chain_descriptor.format,
blend: Some(wgpu::BlendState::ALPHA_BLENDING),
write_mask: wgpu::ColorWrite::ALL,
}],

View file

@ -4,6 +4,7 @@ pub mod world_state;
use std::time::Duration;
use winit::{
dpi::PhysicalSize,
event::{DeviceEvent, ElementState, KeyboardInput, VirtualKeyCode},
window::Window,
};
@ -11,15 +12,11 @@ use winit::{
use hud_state::HudState;
use world_state::WorldState;
use crate::render_context::RenderContext;
pub struct State {
pub window_size: winit::dpi::PhysicalSize<u32>,
render_surface: wgpu::Surface,
render_device: wgpu::Device,
render_queue: wgpu::Queue,
swap_chain_descriptor: wgpu::SwapChainDescriptor,
swap_chain: wgpu::SwapChain,
pub window_size: PhysicalSize<u32>,
render_context: RenderContext,
world_state: WorldState,
hud_state: HudState,
@ -87,17 +84,21 @@ impl State {
let (swap_chain_descriptor, swap_chain) =
Self::create_swap_chain(window, &render_adapter, &render_device, &render_surface);
let world_state = WorldState::new(&render_device, &render_queue, &swap_chain_descriptor);
let hud_state = HudState::new(&render_device, &render_queue, &swap_chain_descriptor);
Self {
window_size,
render_surface,
render_device,
render_queue,
let render_context = RenderContext {
surface: render_surface,
device: render_device,
queue: render_queue,
swap_chain_descriptor,
swap_chain,
};
let world_state = WorldState::new(&render_context);
let hud_state = HudState::new(&render_context);
Self {
window_size,
render_context,
world_state,
hud_state,
@ -106,25 +107,25 @@ impl State {
}
}
pub fn resize(&mut self, new_size: winit::dpi::PhysicalSize<u32>) {
pub fn resize(&mut self, new_size: PhysicalSize<u32>) {
println!("resizing to {:?}", new_size);
self.window_size = new_size;
self.swap_chain_descriptor.width = new_size.width;
self.swap_chain_descriptor.height = new_size.height;
self.render_context.swap_chain_descriptor.width = new_size.width;
self.render_context.swap_chain_descriptor.height = new_size.height;
self.world_state
.resize(&self.render_device, &self.swap_chain_descriptor, new_size);
self.world_state.resize(&self.render_context, new_size);
self.swap_chain = self
.render_device
.create_swap_chain(&self.render_surface, &self.swap_chain_descriptor);
self.render_context.swap_chain = self.render_context.device.create_swap_chain(
&self.render_context.surface,
&self.render_context.swap_chain_descriptor,
);
}
fn input_keyboard(&mut self, key_code: &VirtualKeyCode, state: &ElementState) {
match key_code {
VirtualKeyCode::F1 if state == &ElementState::Pressed => self
.world_state
.toggle_wireframe(&self.render_device, &self.swap_chain_descriptor),
VirtualKeyCode::F1 if state == &ElementState::Pressed => {
self.world_state.toggle_wireframe(&self.render_context)
}
_ => self.world_state.input_keyboard(key_code, state),
}
}
@ -148,29 +149,30 @@ impl State {
state: ElementState::Pressed,
} if self.mouse_grabbed => self
.world_state
.input_mouse_button(*button, &self.render_device),
.input_mouse_button(*button, &self.render_context),
DeviceEvent::MouseMotion { delta: (dx, dy) } => self.input_mouse(*dx, *dy),
_ => (),
}
}
pub fn update(&mut self, dt: Duration) {
self.world_state
.update(dt, &self.render_device, &self.render_queue);
self.world_state.update(dt, &self.render_context);
}
pub fn render(&mut self) -> anyhow::Result<usize> {
let frame = self.swap_chain.get_current_frame()?.output;
let frame = self.render_context.swap_chain.get_current_frame()?.output;
let mut render_encoder = self
.render_device
.render_context
.device
.create_command_encoder(&Default::default());
let mut triangle_count = 0;
triangle_count += self.world_state.render(&frame, &mut render_encoder);
triangle_count += self.hud_state.render(&frame, &mut render_encoder)?;
self.render_queue
self.render_context
.queue
.submit(std::iter::once(render_encoder.finish()));
Ok(triangle_count)

View file

@ -14,6 +14,7 @@ use winit::{
use crate::{
camera::{Camera, Projection},
chunk::{Block, BlockType, CHUNK_SIZE},
render_context::RenderContext,
texture::{Texture, TextureManager},
time::Time,
uniforms::Uniforms,
@ -48,15 +49,13 @@ pub struct WorldState {
}
impl WorldState {
fn create_textures(render_device: &wgpu::Device, render_queue: &wgpu::Queue) -> TextureManager {
let mut texture_manager = TextureManager::new(render_device);
texture_manager
.load_all(render_device, render_queue)
.unwrap();
fn create_textures(render_context: &RenderContext) -> TextureManager {
let mut texture_manager = TextureManager::new(&render_context.device);
texture_manager.load_all(render_context).unwrap();
texture_manager
}
fn create_camera(swap_chain_descriptor: &wgpu::SwapChainDescriptor) -> (Camera, Projection) {
fn create_camera(render_context: &RenderContext) -> (Camera, Projection) {
let camera = Camera::new(
(-10.0, 140.0, -10.0).into(),
cgmath::Deg(45.0).into(),
@ -64,8 +63,8 @@ impl WorldState {
);
let projection = Projection::new(
swap_chain_descriptor.width,
swap_chain_descriptor.height,
render_context.swap_chain_descriptor.width,
render_context.swap_chain_descriptor.height,
cgmath::Deg(45.0),
0.1,
5000.0,
@ -77,7 +76,7 @@ impl WorldState {
fn create_uniforms(
camera: &Camera,
projection: &Projection,
render_device: &wgpu::Device,
render_context: &RenderContext,
) -> (
Uniforms,
wgpu::Buffer,
@ -87,14 +86,18 @@ impl WorldState {
let mut uniforms = Uniforms::new();
uniforms.update_view_projection(camera, projection);
let uniform_buffer = render_device.create_buffer_init(&BufferInitDescriptor {
let uniform_buffer = render_context
.device
.create_buffer_init(&BufferInitDescriptor {
label: Some("uniform_buffer"),
contents: bytemuck::cast_slice(&[uniforms]),
usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST,
});
let uniform_bind_group_layout =
render_device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
render_context
.device
.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
entries: &[wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
@ -108,7 +111,10 @@ impl WorldState {
label: Some("uniform_bind_group_layout"),
});
let uniform_bind_group = render_device.create_bind_group(&wgpu::BindGroupDescriptor {
let uniform_bind_group =
render_context
.device
.create_bind_group(&wgpu::BindGroupDescriptor {
layout: &uniform_bind_group_layout,
entries: &[wgpu::BindGroupEntry {
binding: 0,
@ -126,18 +132,22 @@ impl WorldState {
}
fn create_time(
render_device: &wgpu::Device,
render_context: &RenderContext,
) -> (Time, wgpu::Buffer, wgpu::BindGroupLayout, wgpu::BindGroup) {
let time = Time::new();
let buffer = render_device.create_buffer_init(&BufferInitDescriptor {
let buffer = render_context
.device
.create_buffer_init(&BufferInitDescriptor {
label: Some("time_buffer"),
contents: bytemuck::cast_slice(&[time]),
usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST,
});
let bind_group_layout =
render_device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
render_context
.device
.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
entries: &[wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
@ -151,7 +161,9 @@ impl WorldState {
label: Some("time_bind_group_layout"),
});
let bind_group = render_device.create_bind_group(&wgpu::BindGroupDescriptor {
let bind_group = render_context
.device
.create_bind_group(&wgpu::BindGroupDescriptor {
layout: &bind_group_layout,
entries: &[wgpu::BindGroupEntry {
binding: 0,
@ -164,13 +176,14 @@ impl WorldState {
}
fn create_render_pipeline(
render_device: &wgpu::Device,
swap_chain_descriptor: &wgpu::SwapChainDescriptor,
render_context: &RenderContext,
shader: &wgpu::ShaderModule,
pipeline_layout: &wgpu::PipelineLayout,
wireframe: bool,
) -> wgpu::RenderPipeline {
render_device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
render_context
.device
.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
label: Some("Render Pipeline"),
layout: Some(&pipeline_layout),
vertex: wgpu::VertexState {
@ -182,7 +195,7 @@ impl WorldState {
module: &shader,
entry_point: "main",
targets: &[wgpu::ColorTargetState {
format: swap_chain_descriptor.format,
format: render_context.swap_chain_descriptor.format,
blend: Some(wgpu::BlendState {
alpha: wgpu::BlendComponent::REPLACE,
color: wgpu::BlendComponent::REPLACE,
@ -210,7 +223,7 @@ impl WorldState {
})
}
pub fn update_world_geometry(&mut self, render_device: &wgpu::Device) {
pub fn update_world_geometry(&mut self, render_context: &RenderContext) {
let instant = Instant::now();
let world_geometry = self.world.to_geometry(self.highlighted);
@ -219,12 +232,16 @@ impl WorldState {
self.chunk_buffers.insert(
chunk_position,
(
render_device.create_buffer_init(&BufferInitDescriptor {
render_context
.device
.create_buffer_init(&BufferInitDescriptor {
label: None,
contents: &bytemuck::cast_slice(&chunk_vertices),
usage: wgpu::BufferUsage::VERTEX,
}),
render_device.create_buffer_init(&BufferInitDescriptor {
render_context
.device
.create_buffer_init(&BufferInitDescriptor {
label: None,
contents: &bytemuck::cast_slice(&chunk_indices),
usage: wgpu::BufferUsage::INDEX,
@ -240,10 +257,9 @@ impl WorldState {
pub fn update_chunk_geometry(
&mut self,
render_device: &wgpu::Device,
render_context: &RenderContext,
chunk_position: Vector3<usize>,
) {
// println!("Updating chunk {:?}", chunk_position);
let chunk = &mut self.world.chunks[chunk_position.y][chunk_position.z][chunk_position.x];
let offset = chunk_position.map(|f| (f * CHUNK_SIZE) as i32);
let (vertices, indices) = chunk.to_geometry(
@ -254,12 +270,16 @@ impl WorldState {
self.chunk_buffers.insert(
chunk_position,
(
render_device.create_buffer_init(&BufferInitDescriptor {
render_context
.device
.create_buffer_init(&BufferInitDescriptor {
label: None,
contents: &bytemuck::cast_slice(&vertices),
usage: wgpu::BufferUsage::VERTEX,
}),
render_device.create_buffer_init(&BufferInitDescriptor {
render_context
.device
.create_buffer_init(&BufferInitDescriptor {
label: None,
contents: &bytemuck::cast_slice(&indices),
usage: wgpu::BufferUsage::INDEX,
@ -269,38 +289,29 @@ impl WorldState {
);
}
pub fn toggle_wireframe(
&mut self,
render_device: &wgpu::Device,
swap_chain_descriptor: &wgpu::SwapChainDescriptor,
) {
pub fn toggle_wireframe(&mut self, render_context: &RenderContext) {
self.wireframe = !self.wireframe;
self.render_pipeline = Self::create_render_pipeline(
render_device,
swap_chain_descriptor,
render_context,
&self.shader,
&self.render_pipeline_layout,
self.wireframe,
)
}
pub fn new(
render_device: &wgpu::Device,
render_queue: &wgpu::Queue,
swap_chain_descriptor: &wgpu::SwapChainDescriptor,
) -> WorldState {
pub fn new(render_context: &RenderContext) -> WorldState {
let world = World::generate();
let texture_manager = Self::create_textures(render_device, render_queue);
let texture_manager = Self::create_textures(render_context);
let (camera, projection) = Self::create_camera(swap_chain_descriptor);
let (camera, projection) = Self::create_camera(render_context);
let (uniforms, uniform_buffer, world_uniform_layout, uniform_bind_group) =
Self::create_uniforms(&camera, &projection, render_device);
Self::create_uniforms(&camera, &projection, render_context);
let (time, time_buffer, time_layout, time_bind_group) = Self::create_time(&render_device);
let (time, time_buffer, time_layout, time_bind_group) = Self::create_time(render_context);
let shader = render_device.create_shader_module(
let shader = render_context.device.create_shader_module(
&(wgpu::ShaderModuleDescriptor {
label: Some("shader"),
flags: wgpu::ShaderFlags::all(),
@ -309,7 +320,9 @@ impl WorldState {
);
let render_pipeline_layout =
render_device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
render_context
.device
.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
label: Some("render_pipeline_layout"),
push_constant_ranges: &[],
bind_group_layouts: &[
@ -319,16 +332,10 @@ impl WorldState {
],
});
let render_pipeline = Self::create_render_pipeline(
&render_device,
&swap_chain_descriptor,
&shader,
&render_pipeline_layout,
false,
);
let render_pipeline =
Self::create_render_pipeline(&render_context, &shader, &render_pipeline_layout, false);
let depth_texture =
Texture::create_depth_texture(&render_device, &swap_chain_descriptor, "depth_texture");
let depth_texture = Texture::create_depth_texture(render_context, "depth_texture");
let mut world_state = Self {
render_pipeline,
@ -357,7 +364,7 @@ impl WorldState {
sprinting: false,
};
world_state.update_world_geometry(render_device);
world_state.update_world_geometry(render_context);
world_state
}
@ -428,7 +435,7 @@ impl WorldState {
}
}
fn update_aim(&mut self, render_device: &wgpu::Device) {
fn update_aim(&mut self, render_context: &RenderContext) {
let camera = &self.camera;
let old = self.highlighted;
@ -443,26 +450,26 @@ impl WorldState {
self.highlighted = new;
if let Some(old_chunk_) = old_chunk {
self.update_chunk_geometry(&render_device, old_chunk_);
self.update_chunk_geometry(render_context, old_chunk_);
}
if let Some(new_chunk_) = new_chunk {
// Don't update the same chunk twice
if old_chunk != new_chunk {
self.update_chunk_geometry(&render_device, new_chunk_);
self.update_chunk_geometry(render_context, new_chunk_);
}
}
}
}
pub fn input_mouse_button(&mut self, button: u32, render_device: &wgpu::Device) {
pub fn input_mouse_button(&mut self, button: u32, render_context: &RenderContext) {
let camera = &self.camera;
let world = &mut self.world;
if let Some((pos, axis)) = world.raycast(camera.position.to_vec(), camera.direction()) {
if button == 1 {
world.set_block(pos.x as isize, pos.y as isize, pos.z as isize, None);
self.update_chunk_geometry(&render_device, pos / CHUNK_SIZE);
self.update_chunk_geometry(render_context, pos / CHUNK_SIZE);
} else if button == 3 {
let new_pos = pos.cast().unwrap() - axis;
@ -475,7 +482,7 @@ impl WorldState {
}),
);
self.update_chunk_geometry(&render_device, pos / CHUNK_SIZE);
self.update_chunk_geometry(render_context, pos / CHUNK_SIZE);
}
}
}
@ -514,35 +521,28 @@ impl WorldState {
self.camera.position += Vector3::unit_y() * self.up_speed * speed * dt_seconds;
}
pub fn update(
&mut self,
dt: Duration,
render_device: &wgpu::Device,
render_queue: &wgpu::Queue,
) {
pub fn update(&mut self, dt: Duration, render_context: &RenderContext) {
self.update_position(dt);
self.update_aim(render_device);
self.update_aim(render_context);
self.uniforms
.update_view_projection(&self.camera, &self.projection);
render_queue.write_buffer(
render_context.queue.write_buffer(
&self.uniform_buffer,
0,
bytemuck::cast_slice(&[self.uniforms]),
);
self.time.time += dt.as_secs_f32();
render_queue.write_buffer(&self.time_buffer, 0, &bytemuck::cast_slice(&[self.time]));
render_context.queue.write_buffer(
&self.time_buffer,
0,
&bytemuck::cast_slice(&[self.time]),
);
}
pub fn resize(
&mut self,
render_device: &wgpu::Device,
swap_chain_descriptor: &wgpu::SwapChainDescriptor,
new_size: PhysicalSize<u32>,
) {
pub fn resize(&mut self, render_context: &RenderContext, new_size: PhysicalSize<u32>) {
self.projection.resize(new_size.width, new_size.height);
self.depth_texture =
Texture::create_depth_texture(render_device, swap_chain_descriptor, "depth_texture");
self.depth_texture = Texture::create_depth_texture(render_context, "depth_texture");
}
}

View file

@ -3,6 +3,8 @@ use std::num::NonZeroU32;
use image::EncodableLayout;
use wgpu::Origin3d;
use crate::render_context::RenderContext;
pub struct Texture {
pub texture: wgpu::Texture,
pub sampler: Option<wgpu::Sampler>,
@ -12,18 +14,16 @@ pub struct Texture {
impl Texture {
pub const DEPTH_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Depth32Float;
pub fn create_depth_texture(
device: &wgpu::Device,
swap_chain_descriptor: &wgpu::SwapChainDescriptor,
label: &str,
) -> Self {
pub fn create_depth_texture(render_context: &RenderContext, label: &str) -> Self {
let size = wgpu::Extent3d {
width: swap_chain_descriptor.width,
height: swap_chain_descriptor.height,
width: render_context.swap_chain_descriptor.width,
height: render_context.swap_chain_descriptor.height,
depth_or_array_layers: 1,
};
let texture = device.create_texture(&wgpu::TextureDescriptor {
let texture = render_context
.device
.create_texture(&wgpu::TextureDescriptor {
label: Some(label),
size,
mip_level_count: 1,
@ -34,7 +34,9 @@ impl Texture {
});
let view = texture.create_view(&wgpu::TextureViewDescriptor::default());
let sampler = device.create_sampler(&wgpu::SamplerDescriptor {
let sampler = render_context
.device
.create_sampler(&wgpu::SamplerDescriptor {
address_mode_u: wgpu::AddressMode::ClampToEdge,
address_mode_v: wgpu::AddressMode::ClampToEdge,
address_mode_w: wgpu::AddressMode::ClampToEdge,
@ -55,8 +57,7 @@ impl Texture {
}
pub fn from_bytes(
device: &wgpu::Device,
queue: &wgpu::Queue,
render_context: &RenderContext,
bytes: &[u8],
label: &str,
) -> anyhow::Result<Self> {
@ -70,7 +71,9 @@ impl Texture {
depth_or_array_layers: 1,
};
let texture = device.create_texture(&wgpu::TextureDescriptor {
let texture = render_context
.device
.create_texture(&wgpu::TextureDescriptor {
label: Some(label),
size: texture_size,
mip_level_count: 1,
@ -82,7 +85,7 @@ impl Texture {
| wgpu::TextureUsage::COPY_SRC,
});
queue.write_texture(
render_context.queue.write_texture(
wgpu::ImageCopyTexture {
texture: &texture,
mip_level: 0,
@ -165,22 +168,24 @@ impl TextureManager {
}
}
pub fn load_all(&mut self, device: &wgpu::Device, queue: &wgpu::Queue) -> anyhow::Result<()> {
self.load(device, queue, "assets/block/cobblestone.png")?; // 0
self.load(device, queue, "assets/block/dirt.png")?; // 1
self.load(device, queue, "assets/block/stone.png")?; // 2
self.load(device, queue, "assets/grass_block_top_plains.png")?; // 3
self.load(device, queue, "assets/grass_block_side_plains.png")?; // 4
self.load(device, queue, "assets/block/bedrock.png")?; // 5
self.load(device, queue, "assets/block/sand.png")?; // 6
self.load(device, queue, "assets/block/gravel.png")?; // 7
pub fn load_all(&mut self, render_context: &RenderContext) -> anyhow::Result<()> {
self.load(render_context, "assets/block/cobblestone.png")?; // 0
self.load(render_context, "assets/block/dirt.png")?; // 1
self.load(render_context, "assets/block/stone.png")?; // 2
self.load(render_context, "assets/grass_block_top_plains.png")?; // 3
self.load(render_context, "assets/grass_block_side_plains.png")?; // 4
self.load(render_context, "assets/block/bedrock.png")?; // 5
self.load(render_context, "assets/block/sand.png")?; // 6
self.load(render_context, "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
self.load(render_context, &path)?; // 8 - 71
}
assert_eq!(TEXTURE_COUNT, self.textures.len());
let texture_array = device.create_texture(&wgpu::TextureDescriptor {
let texture_array = render_context
.device
.create_texture(&wgpu::TextureDescriptor {
label: None,
size: wgpu::Extent3d {
width: 512,
@ -194,7 +199,10 @@ impl TextureManager {
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::COPY_DST,
});
let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor {
let mut encoder =
render_context
.device
.create_command_encoder(&wgpu::CommandEncoderDescriptor {
label: Some("texture copy encoder"),
});
@ -222,7 +230,9 @@ impl TextureManager {
)
}
queue.submit(std::iter::once(encoder.finish()));
render_context
.queue
.submit(std::iter::once(encoder.finish()));
let view = texture_array.create_view(&wgpu::TextureViewDescriptor {
label: None,
@ -231,7 +241,8 @@ impl TextureManager {
..wgpu::TextureViewDescriptor::default()
});
self.bind_group = Some(device.create_bind_group(&wgpu::BindGroupDescriptor {
self.bind_group = Some(render_context.device.create_bind_group(
&wgpu::BindGroupDescriptor {
label: Some(&("Block texture bind group")),
layout: &self.bind_group_layout,
entries: &[
@ -244,19 +255,15 @@ impl TextureManager {
resource: wgpu::BindingResource::TextureView(&view),
},
],
}));
},
));
Ok(())
}
pub fn load(
&mut self,
device: &wgpu::Device,
queue: &wgpu::Queue,
path: &str,
) -> anyhow::Result<usize> {
pub fn load(&mut self, render_context: &RenderContext, path: &str) -> anyhow::Result<usize> {
let bytes = std::fs::read(path)?;
let texture = Texture::from_bytes(device, queue, &bytes, path)?;
let texture = Texture::from_bytes(render_context, &bytes, path)?;
let id = self.textures.len();
self.textures.push(texture);