feat(rendering): add default checkerboard texture
This commit is contained in:
parent
415cc477f7
commit
0127f57045
3 changed files with 57 additions and 18 deletions
52
src/main.rs
52
src/main.rs
|
@ -1,12 +1,13 @@
|
||||||
use bytemuck::bytes_of;
|
use bytemuck::bytes_of;
|
||||||
use image::EncodableLayout;
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::io::BufReader;
|
use std::io::BufReader;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tobj::LoadOptions;
|
use std::time::Instant;
|
||||||
use tracing::info;
|
use tracing::info;
|
||||||
use wgpu::util::DeviceExt;
|
use wgpu::util::DeviceExt;
|
||||||
use wgpu::{Backends, BufferUsages, Device, FragmentState, IndexFormat, Instance, InstanceDescriptor, PipelineCompilationOptions};
|
use wgpu::{
|
||||||
|
Backends, FragmentState, IndexFormat, Instance, InstanceDescriptor, PipelineCompilationOptions,
|
||||||
|
};
|
||||||
use winit::application::ApplicationHandler;
|
use winit::application::ApplicationHandler;
|
||||||
use winit::event::{ElementState, MouseButton};
|
use winit::event::{ElementState, MouseButton};
|
||||||
use winit::event_loop::{ActiveEventLoop, EventLoop};
|
use winit::event_loop::{ActiveEventLoop, EventLoop};
|
||||||
|
@ -45,8 +46,9 @@ struct WgpuRenderer<'surface> {
|
||||||
camera_buffer: wgpu::Buffer,
|
camera_buffer: wgpu::Buffer,
|
||||||
camera_bind_group: wgpu::BindGroup,
|
camera_bind_group: wgpu::BindGroup,
|
||||||
pumpkin: model::Model,
|
pumpkin: model::Model,
|
||||||
|
delta: f32,
|
||||||
zenyx_logo: wgpu::BindGroup,
|
last_frame_time: Instant,
|
||||||
|
default_texture: wgpu::BindGroup,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WgpuRenderer<'_> {
|
impl WgpuRenderer<'_> {
|
||||||
|
@ -88,7 +90,7 @@ impl WgpuRenderer<'_> {
|
||||||
.material
|
.material
|
||||||
.and_then(|i| self.pumpkin.materials.get(i))
|
.and_then(|i| self.pumpkin.materials.get(i))
|
||||||
.map(|m| &m.bind_group)
|
.map(|m| &m.bind_group)
|
||||||
.unwrap_or(&self.zenyx_logo);
|
.unwrap_or(&self.default_texture);
|
||||||
rpass.set_bind_group(1, bind_group, &[]);
|
rpass.set_bind_group(1, bind_group, &[]);
|
||||||
rpass.set_vertex_buffer(0, mesh.vertex_buffer.slice(..));
|
rpass.set_vertex_buffer(0, mesh.vertex_buffer.slice(..));
|
||||||
rpass.set_index_buffer(mesh.index_buffer.slice(..), IndexFormat::Uint32);
|
rpass.set_index_buffer(mesh.index_buffer.slice(..), IndexFormat::Uint32);
|
||||||
|
@ -96,7 +98,11 @@ impl WgpuRenderer<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.queue.submit(Some(encoder.finish()));
|
self.queue.submit(Some(encoder.finish()));
|
||||||
surface_texture.present()
|
let delta_time = std::time::Instant::now() - self.last_frame_time;
|
||||||
|
self.delta = delta_time.as_secs_f32();
|
||||||
|
info!("{}", self.delta);
|
||||||
|
surface_texture.present();
|
||||||
|
self.last_frame_time = std::time::Instant::now();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,8 +140,8 @@ struct WgpuState {
|
||||||
instance: wgpu::Instance,
|
instance: wgpu::Instance,
|
||||||
}
|
}
|
||||||
|
|
||||||
static ICON: &[u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/assets/Badge.png"));
|
static _ICON: &[u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/assets/Badge.png"));
|
||||||
static PUMPKIN: &[u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/Pumpkin.obj"));
|
static _PUMPKIN: &[u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/Pumpkin.obj"));
|
||||||
|
|
||||||
impl WgpuState {
|
impl WgpuState {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
|
@ -303,24 +309,35 @@ impl WgpuState {
|
||||||
&queue,
|
&queue,
|
||||||
&texture_bind_group_layout,
|
&texture_bind_group_layout,
|
||||||
);
|
);
|
||||||
|
let checkerboard_img = crate::texture::create_checkerboard();
|
||||||
|
let checkerboard_texture =
|
||||||
|
texture::Texture::from_image(&device, &queue, &checkerboard_img, Some("checkerboard"))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let zenyx_logo = texture::Texture::from_bytes(&device, &queue, ICON, "zenyx-icon").unwrap();
|
let checkerboard_sampler = device.create_sampler(&wgpu::SamplerDescriptor {
|
||||||
|
address_mode_u: wgpu::AddressMode::Repeat,
|
||||||
|
address_mode_v: wgpu::AddressMode::Repeat,
|
||||||
|
address_mode_w: wgpu::AddressMode::Repeat,
|
||||||
|
mag_filter: wgpu::FilterMode::Nearest,
|
||||||
|
min_filter: wgpu::FilterMode::Nearest,
|
||||||
|
mipmap_filter: wgpu::FilterMode::Nearest,
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
|
||||||
let zenyx_logo = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
let default_texture = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||||
label: Some("zenyx-logo-diffuse"),
|
label: Some("checkerboard-bind-group"),
|
||||||
layout: &texture_bind_group_layout,
|
layout: &texture_bind_group_layout,
|
||||||
entries: &[
|
entries: &[
|
||||||
wgpu::BindGroupEntry {
|
wgpu::BindGroupEntry {
|
||||||
binding: 0,
|
binding: 0,
|
||||||
resource: wgpu::BindingResource::TextureView(&zenyx_logo.view),
|
resource: wgpu::BindingResource::TextureView(&checkerboard_texture.view),
|
||||||
},
|
},
|
||||||
wgpu::BindGroupEntry {
|
wgpu::BindGroupEntry {
|
||||||
binding: 1,
|
binding: 1,
|
||||||
resource: wgpu::BindingResource::Sampler(&zenyx_logo.sampler),
|
resource: wgpu::BindingResource::Sampler(&checkerboard_sampler),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
let (depth_texture, depth_texture_view) =
|
let (depth_texture, depth_texture_view) =
|
||||||
create_depth_texture(&device, surface_config.width, surface_config.height);
|
create_depth_texture(&device, surface_config.width, surface_config.height);
|
||||||
let camera = camera::Camera {
|
let camera = camera::Camera {
|
||||||
|
@ -370,10 +387,11 @@ impl WgpuState {
|
||||||
camera_bind_group,
|
camera_bind_group,
|
||||||
depth_texture_view,
|
depth_texture_view,
|
||||||
pumpkin,
|
pumpkin,
|
||||||
zenyx_logo,
|
default_texture,
|
||||||
|
delta: 0f32,
|
||||||
|
last_frame_time: Instant::now(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_depth_texture(
|
fn create_depth_texture(
|
||||||
|
|
|
@ -48,7 +48,7 @@ impl Model {
|
||||||
let Some(texture) = &m.diffuse_texture else {
|
let Some(texture) = &m.diffuse_texture else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
let diffuse_texture = load_texture(&m.name, texture, device, queue);
|
let diffuse_texture = load_texture(&m.name, texture, device, queue);
|
||||||
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||||
label: Some("model-texture-bind"),
|
label: Some("model-texture-bind"),
|
||||||
layout,
|
layout,
|
||||||
|
|
|
@ -85,3 +85,24 @@ impl Texture {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn create_checkerboard() -> image::DynamicImage {
|
||||||
|
let size = 512;
|
||||||
|
let tile_size = 24;
|
||||||
|
let mut img = image::RgbaImage::new(size, size);
|
||||||
|
|
||||||
|
for y in 0..size {
|
||||||
|
for x in 0..size {
|
||||||
|
let tile_x = x / tile_size;
|
||||||
|
let tile_y = y / tile_size;
|
||||||
|
let color = if (tile_x + tile_y) % 2 == 0 {
|
||||||
|
[0, 0, 0, 255]
|
||||||
|
} else {
|
||||||
|
[255, 5, 255, 255]
|
||||||
|
};
|
||||||
|
img.put_pixel(x, y, image::Rgba(color));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
image::DynamicImage::ImageRgba8(img)
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue