Switched from zerocopy to bytemuck

Fixing errors
This commit is contained in:
Capucho 2020-09-13 18:26:23 +01:00 committed by Imbris
parent acd13b87f3
commit 9000b756a8
27 changed files with 153 additions and 164 deletions

View File

@ -42,8 +42,8 @@ anim = {package = "veloren-voxygen-anim", path = "anim"}
# Graphics # Graphics
winit = {version = "0.24.0", features = ["serde"]} winit = {version = "0.24.0", features = ["serde"]}
wgpu = {git="https://github.com/gfx-rs/wgpu-rs.git"} wgpu = { git="https://github.com/gfx-rs/wgpu-rs.git", rev= "ab8b0e3766558d541206da2790dfd63f15b13bc4" }
zerocopy = "0.3" bytemuck = { version="1.4", features=["derive"] }
shaderc = "0.6.2" shaderc = "0.6.2"
# Ui # Ui

View File

@ -1,15 +1,15 @@
use bytemuck::Pod;
use wgpu::util::DeviceExt; use wgpu::util::DeviceExt;
use zerocopy::AsBytes;
#[derive(Clone)] #[derive(Clone)]
pub struct Buffer<T: Copy + AsBytes> { pub struct Buffer<T: Copy + Pod> {
pub buf: wgpu::Buffer, pub buf: wgpu::Buffer,
// bytes // bytes
count: usize, count: usize,
phantom_data: std::marker::PhantomData<T>, phantom_data: std::marker::PhantomData<T>,
} }
impl<T: Copy + AsBytes> Buffer<T> { impl<T: Copy + Pod> Buffer<T> {
pub fn new(device: &mut wgpu::Device, cap: usize, usage: wgpu::BufferUsage) -> Self { pub fn new(device: &mut wgpu::Device, cap: usize, usage: wgpu::BufferUsage) -> Self {
Self { Self {
buf: device.create_buffer(&wgpu::BufferDescriptor { buf: device.create_buffer(&wgpu::BufferDescriptor {

View File

@ -1,15 +1,15 @@
use super::{buffer::Buffer, RenderError}; use super::buffer::Buffer;
use zerocopy::AsBytes; use bytemuck::Pod;
/// A handle to a series of constants sitting on the GPU. This is used to hold /// A handle to a series of constants sitting on the GPU. This is used to hold
/// information used in the rendering process that does not change throughout a /// information used in the rendering process that does not change throughout a
/// single render pass. /// single render pass.
#[derive(Clone)] #[derive(Clone)]
pub struct Consts<T: Copy + AsBytes> { pub struct Consts<T: Copy + Pod> {
buf: Buffer<T>, buf: Buffer<T>,
} }
impl<T: Copy + AsBytes> Consts<T> { impl<T: Copy + Pod> Consts<T> {
/// Create a new `Const<T>`. /// Create a new `Const<T>`.
pub fn new(device: &mut wgpu::Device, len: usize) -> Self { pub fn new(device: &mut wgpu::Device, len: usize) -> Self {
Self { Self {
@ -24,7 +24,7 @@ impl<T: Copy + AsBytes> Consts<T> {
queue: &wgpu::Queue, queue: &wgpu::Queue,
vals: &[T], vals: &[T],
offset: usize, offset: usize,
) -> Result<(), RenderError> { ) {
self.buf.update(device, queue, vals, offset) self.buf.update(device, queue, vals, offset)
} }

View File

@ -1,13 +1,13 @@
use super::{buffer::Buffer, RenderError}; use super::{buffer::Buffer, RenderError};
use zerocopy::AsBytes; use bytemuck::Pod;
/// Represents a mesh that has been sent to the GPU. /// Represents a mesh that has been sent to the GPU.
#[derive(Clone)] #[derive(Clone)]
pub struct Instances<T: Copy + AsBytes> { pub struct Instances<T: Copy + Pod> {
buf: Buffer<T>, buf: Buffer<T>,
} }
impl<T: Copy + AsBytes> Instances<T> { impl<T: Copy + Pod> Instances<T> {
pub fn new(device: &mut wgpu::Device, len: usize) -> Self { pub fn new(device: &mut wgpu::Device, len: usize) -> Self {
Self { Self {
buf: Buffer::new(device, len, wgpu::BufferUsage::VERTEX), buf: Buffer::new(device, len, wgpu::BufferUsage::VERTEX),

View File

@ -22,17 +22,18 @@ pub use self::{
BoneData as FigureBoneData, BoneMeshes, FigureLayout, FigureModel, BoneData as FigureBoneData, BoneMeshes, FigureLayout, FigureModel,
Locals as FigureLocals, Locals as FigureLocals,
}, },
lod_terrain::LodData, fluid::Vertex as FluidVertex,
particle::Instance as ParticleInstance, lod_terrain::{LodData, Vertex as LodTerrainVertex},
postprocess::create_mesh as create_pp_mesh, particle::{Instance as ParticleInstance, Vertex as ParticleVertex},
postprocess::{create_mesh as create_pp_mesh, Vertex as PostProcessVertex},
shadow::Locals as ShadowLocals, shadow::Locals as ShadowLocals,
skybox::create_mesh as create_skybox_mesh, skybox::{create_mesh as create_skybox_mesh, Vertex as SkyboxVertex},
sprite::{Instance as SpriteInstance, Locals as SpriteLocals}, sprite::{Instance as SpriteInstance, Locals as SpriteLocals, Vertex as SpriteVertex},
terrain::{Locals as TerrainLocals, TerrainLayout, Vertex as TerrainVertex}, terrain::{Locals as TerrainLocals, TerrainLayout, Vertex as TerrainVertex},
ui::{ ui::{
create_quad as create_ui_quad, create_quad as create_ui_quad,
create_quad_vert_gradient as create_ui_quad_vert_gradient, create_tri as create_ui_tri, create_quad_vert_gradient as create_ui_quad_vert_gradient, create_tri as create_ui_tri,
Locals as UiLocals, Mode as UiMode, Locals as UiLocals, Mode as UiMode, Vertex as UiVertex,
}, },
GlobalModel, Globals, GlobalsLayouts, Light, Shadow, GlobalModel, Globals, GlobalsLayouts, Light, Shadow,
}, },
@ -41,7 +42,7 @@ pub use self::{
}; };
pub use wgpu::{AddressMode, FilterMode}; pub use wgpu::{AddressMode, FilterMode};
trait Vertex = Clone + zerocopy::AsBytes; pub trait Vertex = Clone + bytemuck::Pod;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
/// Anti-aliasing modes /// Anti-aliasing modes

View File

@ -3,11 +3,11 @@ use super::{
terrain::Vertex, terrain::Vertex,
}; };
use crate::mesh::greedy::GreedyMesh; use crate::mesh::greedy::GreedyMesh;
use bytemuck::Pod;
use vek::*; use vek::*;
use zerocopy::AsBytes;
#[repr(C)] #[repr(C)]
#[derive(Copy, Clone, Debug, AsBytes)] #[derive(Copy, Clone, Debug, Pod)]
pub struct Locals { pub struct Locals {
model_mat: [[f32; 4]; 4], model_mat: [[f32; 4]; 4],
highlight_col: [f32; 4], highlight_col: [f32; 4],
@ -19,7 +19,7 @@ pub struct Locals {
} }
#[repr(C)] #[repr(C)]
#[derive(Copy, Clone, Debug, AsBytes)] #[derive(Copy, Clone, Debug, Pod)]
pub struct BoneData { pub struct BoneData {
bone_mat: [[f32; 4]; 4], bone_mat: [[f32; 4]; 4],
normals_mat: [[f32; 4]; 4], normals_mat: [[f32; 4]; 4],

View File

@ -1,9 +1,9 @@
use super::super::{AaMode, GlobalsLayouts}; use super::super::{AaMode, GlobalsLayouts};
use bytemuck::Pod;
use vek::*; use vek::*;
use zerocopy::AsBytes;
#[repr(C)] #[repr(C)]
#[derive(Copy, Clone, Debug, AsBytes)] #[derive(Copy, Clone, Debug, Pod)]
pub struct Vertex { pub struct Vertex {
pos_norm: u32, pos_norm: u32,
} }

View File

@ -1,9 +1,9 @@
use super::super::{AaMode, GlobalsLayouts, Renderer, Texture}; use super::super::{AaMode, GlobalsLayouts, Renderer, Texture};
use bytemuck::Pod;
use vek::*; use vek::*;
use zerocopy::AsBytes;
#[repr(C)] #[repr(C)]
#[derive(Copy, Clone, Debug, AsBytes)] #[derive(Copy, Clone, Debug, Pod)]
pub struct Vertex { pub struct Vertex {
pos: [f32; 2], pos: [f32; 2],
} }

View File

@ -12,16 +12,16 @@ pub mod ui;
use super::Consts; use super::Consts;
use crate::scene::camera::CameraMode; use crate::scene::camera::CameraMode;
use bytemuck::Pod;
use common::terrain::BlockKind; use common::terrain::BlockKind;
use vek::*; use vek::*;
use zerocopy::AsBytes;
pub const MAX_POINT_LIGHT_COUNT: usize = 31; pub const MAX_POINT_LIGHT_COUNT: usize = 31;
pub const MAX_FIGURE_SHADOW_COUNT: usize = 24; pub const MAX_FIGURE_SHADOW_COUNT: usize = 24;
pub const MAX_DIRECTED_LIGHT_COUNT: usize = 6; pub const MAX_DIRECTED_LIGHT_COUNT: usize = 6;
#[repr(C)] #[repr(C)]
#[derive(Copy, Clone, Debug, AsBytes)] #[derive(Copy, Clone, Debug, Pod)]
pub struct Globals { pub struct Globals {
view_mat: [[f32; 4]; 4], view_mat: [[f32; 4]; 4],
proj_mat: [[f32; 4]; 4], proj_mat: [[f32; 4]; 4],
@ -55,14 +55,14 @@ pub struct Globals {
} }
#[repr(C)] #[repr(C)]
#[derive(Copy, Clone, Debug, AsBytes)] #[derive(Copy, Clone, Debug, Pod)]
pub struct Light { pub struct Light {
pos: [f32; 4], pos: [f32; 4],
col: [f32; 4], col: [f32; 4],
} }
#[repr(C)] #[repr(C)]
#[derive(Copy, Clone, Debug, AsBytes)] #[derive(Copy, Clone, Debug, Pod)]
pub struct Shadow { pub struct Shadow {
pos_radius: [f32; 4], pos_radius: [f32; 4],
} }

View File

@ -1,9 +1,9 @@
use super::super::{AaMode, GlobalsLayouts}; use super::super::{AaMode, GlobalsLayouts};
use bytemuck::Pod;
use vek::*; use vek::*;
use zerocopy::AsBytes;
#[repr(C)] #[repr(C)]
#[derive(Copy, Clone, Debug, AsBytes)] #[derive(Copy, Clone, Debug, Pod)]
pub struct Vertex { pub struct Vertex {
pos: [f32; 3], pos: [f32; 3],
// ____BBBBBBBBGGGGGGGGRRRRRRRR // ____BBBBBBBBGGGGGGGGRRRRRRRR
@ -76,7 +76,7 @@ impl ParticleMode {
} }
#[repr(C)] #[repr(C)]
#[derive(Copy, Clone, Debug, AsBytes)] #[derive(Copy, Clone, Debug, Pod)]
pub struct Instance { pub struct Instance {
// created_at time, so we can calculate time relativity, needed for relative animation. // created_at time, so we can calculate time relativity, needed for relative animation.
// can save 32 bits per instance, for particles that are not relatively animated. // can save 32 bits per instance, for particles that are not relatively animated.

View File

@ -1,9 +1,9 @@
use super::super::{AaMode, GlobalsLayouts, Mesh, Tri}; use super::super::{AaMode, GlobalsLayouts, Mesh, Tri};
use bytemuck::Pod;
use vek::*; use vek::*;
use zerocopy::AsBytes;
#[repr(C)] #[repr(C)]
#[derive(Copy, Clone, Debug, AsBytes)] #[derive(Copy, Clone, Debug, Pod)]
pub struct Locals { pub struct Locals {
proj_mat_inv: [[f32; 4]; 4], proj_mat_inv: [[f32; 4]; 4],
view_mat_inv: [[f32; 4]; 4], view_mat_inv: [[f32; 4]; 4],
@ -23,7 +23,7 @@ impl Locals {
} }
#[repr(C)] #[repr(C)]
#[derive(Copy, Clone, Debug, AsBytes)] #[derive(Copy, Clone, Debug, Pod)]
pub struct Vertex { pub struct Vertex {
pub pos: [f32; 2], pub pos: [f32; 2],
} }

View File

@ -2,11 +2,11 @@ use super::super::{
AaMode, ColLightInfo, FigureLayout, GlobalsLayouts, Renderer, TerrainLayout, TerrainVertex, AaMode, ColLightInfo, FigureLayout, GlobalsLayouts, Renderer, TerrainLayout, TerrainVertex,
Texture, Texture,
}; };
use bytemuck::Pod;
use vek::*; use vek::*;
use zerocopy::AsBytes;
#[repr(C)] #[repr(C)]
#[derive(Copy, Clone, Debug, AsBytes)] #[derive(Copy, Clone, Debug, Pod)]
pub struct Locals { pub struct Locals {
shadow_matrices: [[f32; 4]; 4], shadow_matrices: [[f32; 4]; 4],
texture_mats: [[f32; 4]; 4], texture_mats: [[f32; 4]; 4],

View File

@ -1,8 +1,8 @@
use super::super::{AaMode, GlobalsLayouts, Mesh, Quad}; use super::super::{AaMode, GlobalsLayouts, Mesh, Quad};
use zerocopy::AsBytes; use bytemuck::Pod;
#[repr(C)] #[repr(C)]
#[derive(Copy, Clone, Debug, AsBytes)] #[derive(Copy, Clone, Debug, Pod)]
pub struct Vertex { pub struct Vertex {
pub pos: [f32; 3], pub pos: [f32; 3],
} }

View File

@ -1,10 +1,10 @@
use super::super::{AaMode, GlobalsLayouts, TerrainLayout}; use super::super::{AaMode, GlobalsLayouts, TerrainLayout};
use bytemuck::Pod;
use core::fmt; use core::fmt;
use vek::*; use vek::*;
use zerocopy::AsBytes;
#[repr(C)] #[repr(C)]
#[derive(Copy, Clone, Debug, AsBytes)] #[derive(Copy, Clone, Debug, Pod)]
pub struct Vertex { pub struct Vertex {
pos: [f32; 3], pos: [f32; 3],
// Because we try to restrict terrain sprite data to a 128×128 block // Because we try to restrict terrain sprite data to a 128×128 block
@ -70,7 +70,7 @@ impl Vertex {
} }
#[repr(C)] #[repr(C)]
#[derive(Copy, Clone, Debug, AsBytes)] #[derive(Copy, Clone, Debug, Pod)]
pub struct Instance { pub struct Instance {
pos_ori: u32, pos_ori: u32,
inst_mat0: [f32; 4], inst_mat0: [f32; 4],
@ -122,7 +122,7 @@ impl Default for Instance {
} }
#[repr(C)] #[repr(C)]
#[derive(Copy, Clone, Debug, AsBytes)] #[derive(Copy, Clone, Debug, Pod)]
pub struct Locals { pub struct Locals {
// Each matrix performs rotatation, translation, and scaling, relative to the sprite // Each matrix performs rotatation, translation, and scaling, relative to the sprite
// origin, for all sprite instances. The matrix will be in an array indexed by the // origin, for all sprite instances. The matrix will be in an array indexed by the

View File

@ -1,9 +1,9 @@
use super::super::{AaMode, GlobalsLayouts}; use super::super::{AaMode, GlobalsLayouts};
use bytemuck::Pod;
use vek::*; use vek::*;
use zerocopy::AsBytes;
#[repr(C)] #[repr(C)]
#[derive(Copy, Clone, Debug, AsBytes)] #[derive(Copy, Clone, Debug, Pod)]
pub struct Vertex { pub struct Vertex {
pos_norm: u32, pos_norm: u32,
atlas_pos: u32, atlas_pos: u32,
@ -129,7 +129,7 @@ impl Vertex {
} }
#[repr(C)] #[repr(C)]
#[derive(Copy, Clone, Debug, AsBytes)] #[derive(Copy, Clone, Debug, Pod)]
pub struct Locals { pub struct Locals {
model_offs: [f32; 3], model_offs: [f32; 3],
load_time: f32, load_time: f32,

View File

@ -1,9 +1,9 @@
use super::super::{AaMode, GlobalsLayouts, Quad, Tri}; use super::super::{AaMode, GlobalsLayouts, Quad, Tri};
use bytemuck::Pod;
use vek::*; use vek::*;
use zerocopy::AsBytes;
#[repr(C)] #[repr(C)]
#[derive(Copy, Clone, Debug, AsBytes)] #[derive(Copy, Clone, Debug, Pod)]
pub struct Vertex { pub struct Vertex {
pos: [f32; 2], pos: [f32; 2],
uv: [f32; 2], uv: [f32; 2],
@ -24,7 +24,7 @@ impl Vertex {
} }
#[repr(C)] #[repr(C)]
#[derive(Copy, Clone, Debug, AsBytes)] #[derive(Copy, Clone, Debug, Pod)]
pub struct Locals { pub struct Locals {
pos: [f32; 4], pos: [f32; 4],
} }

View File

@ -944,7 +944,7 @@ impl Renderer {
} }
/// Create a new set of constants with the provided values. /// Create a new set of constants with the provided values.
pub fn create_consts<T: Copy + zerocopy::AsBytes>( pub fn create_consts<T: Copy + bytemuck::Pod>(
&mut self, &mut self,
vals: &[T], vals: &[T],
) -> Result<Consts<T>, RenderError> { ) -> Result<Consts<T>, RenderError> {
@ -954,16 +954,12 @@ impl Renderer {
} }
/// Update a set of constants with the provided values. /// Update a set of constants with the provided values.
pub fn update_consts<T: Copy + zerocopy::AsBytes>( pub fn update_consts<T: Copy + bytemuck::Pod>(&mut self, consts: &mut Consts<T>, vals: &[T]) {
&mut self,
consts: &mut Consts<T>,
vals: &[T],
) -> Result<(), RenderError> {
consts.update(&mut self.encoder, vals, 0) consts.update(&mut self.encoder, vals, 0)
} }
/// Create a new set of instances with the provided values. /// Create a new set of instances with the provided values.
pub fn create_instances<T: Copy + zerocopy::AsBytes>( pub fn create_instances<T: Copy + bytemuck::Pod>(
&mut self, &mut self,
vals: &[T], vals: &[T],
) -> Result<Instances<T>, RenderError> { ) -> Result<Instances<T>, RenderError> {

View File

@ -1,9 +1,7 @@
use super::{load::BodySpec, FigureModelEntry}; use super::{load::BodySpec, FigureModelEntry};
use crate::{ use crate::{
mesh::{greedy::GreedyMesh, Meshable}, mesh::{greedy::GreedyMesh, Meshable},
render::{ render::{BoneMeshes, ColLightInfo, FigureModel, Mesh, Renderer, TerrainVertex},
BoneMeshes, ColLightInfo, FigureModel, FigurePipeline, Mesh, Renderer, TerrainPipeline,
},
scene::camera::CameraMode, scene::camera::CameraMode,
}; };
use anim::Skeleton; use anim::Skeleton;
@ -411,7 +409,7 @@ where
// Then, set up meshing context. // Then, set up meshing context.
let mut greedy = FigureModel::make_greedy(); let mut greedy = FigureModel::make_greedy();
let mut opaque = Mesh::<TerrainPipeline>::new(); let mut opaque = Mesh::<TerrainVertex>::new();
// Choose the most conservative bounds for any LOD model. // Choose the most conservative bounds for any LOD model.
let mut figure_bounds = anim::vek::Aabb { let mut figure_bounds = anim::vek::Aabb {
min: anim::vek::Vec3::zero(), min: anim::vek::Vec3::zero(),
@ -473,13 +471,13 @@ where
fn generate_mesh<'a>( fn generate_mesh<'a>(
greedy: &mut GreedyMesh<'a>, greedy: &mut GreedyMesh<'a>,
opaque_mesh: &mut Mesh<TerrainPipeline>, opaque_mesh: &mut Mesh<TerrainVertex>,
segment: &'a Segment, segment: &'a Segment,
offset: Vec3<f32>, offset: Vec3<f32>,
bone_idx: u8, bone_idx: u8,
) -> BoneMeshes { ) -> BoneMeshes {
let (opaque, _, _, bounds) = let (opaque, _, _, bounds) =
Meshable::<FigurePipeline, &mut GreedyMesh>::generate_mesh( Meshable::<TerrainVertex, &mut GreedyMesh>::generate_mesh(
segment, segment,
(greedy, opaque_mesh, offset, Vec3::one(), bone_idx), (greedy, opaque_mesh, offset, Vec3::one(), bone_idx),
); );
@ -488,14 +486,14 @@ where
fn generate_mesh_lod_mid<'a>( fn generate_mesh_lod_mid<'a>(
greedy: &mut GreedyMesh<'a>, greedy: &mut GreedyMesh<'a>,
opaque_mesh: &mut Mesh<TerrainPipeline>, opaque_mesh: &mut Mesh<TerrainVertex>,
segment: &'a Segment, segment: &'a Segment,
offset: Vec3<f32>, offset: Vec3<f32>,
bone_idx: u8, bone_idx: u8,
) -> BoneMeshes { ) -> BoneMeshes {
let lod_scale = 0.6; let lod_scale = 0.6;
let (opaque, _, _, bounds) = let (opaque, _, _, bounds) =
Meshable::<FigurePipeline, &mut GreedyMesh>::generate_mesh( Meshable::<TerrainVertex, &mut GreedyMesh>::generate_mesh(
segment.scaled_by(Vec3::broadcast(lod_scale)), segment.scaled_by(Vec3::broadcast(lod_scale)),
( (
greedy, greedy,
@ -510,14 +508,14 @@ where
fn generate_mesh_lod_low<'a>( fn generate_mesh_lod_low<'a>(
greedy: &mut GreedyMesh<'a>, greedy: &mut GreedyMesh<'a>,
opaque_mesh: &mut Mesh<TerrainPipeline>, opaque_mesh: &mut Mesh<TerrainVertex>,
segment: &'a Segment, segment: &'a Segment,
offset: Vec3<f32>, offset: Vec3<f32>,
bone_idx: u8, bone_idx: u8,
) -> BoneMeshes { ) -> BoneMeshes {
let lod_scale = 0.3; let lod_scale = 0.3;
let (opaque, _, _, bounds) = let (opaque, _, _, bounds) =
Meshable::<FigurePipeline, &mut GreedyMesh>::generate_mesh( Meshable::<TerrainVertex, &mut GreedyMesh>::generate_mesh(
segment.scaled_by(Vec3::broadcast(lod_scale)), segment.scaled_by(Vec3::broadcast(lod_scale)),
( (
greedy, greedy,

View File

@ -7,8 +7,8 @@ pub use load::load_mesh; // TODO: Don't make this public.
use crate::{ use crate::{
ecs::comp::Interpolated, ecs::comp::Interpolated,
render::{ render::{
ColLightFmt, ColLightInfo, Consts, FigureBoneData, FigureLocals, FigureModel, GlobalModel, pipelines, ColLightInfo, Consts, FigureBoneData, FigureLocals, FigureModel, GlobalModel,
Mesh, RenderError, Renderer, ShadowPipeline, TerrainPipeline, Texture, Mesh, RenderError, Renderer, TerrainVertex, Texture,
}, },
scene::{ scene::{
camera::{Camera, CameraMode, Dependents}, camera::{Camera, CameraMode, Dependents},
@ -64,7 +64,7 @@ pub type FigureModelRef<'a> = (
&'a Consts<FigureLocals>, &'a Consts<FigureLocals>,
&'a Consts<FigureBoneData>, &'a Consts<FigureBoneData>,
&'a FigureModel, &'a FigureModel,
&'a Texture<ColLightFmt>, &'a Texture, /* <ColLightFmt> */
); );
/// An entry holding enough information to draw or destroy a figure in a /// An entry holding enough information to draw or destroy a figure in a
@ -80,7 +80,7 @@ pub struct FigureModelEntry<const N: usize> {
/// Texture used to store color/light information for this figure entry. /// Texture used to store color/light information for this figure entry.
/* TODO: Consider using mipmaps instead of storing multiple texture atlases for different /* TODO: Consider using mipmaps instead of storing multiple texture atlases for different
* LOD levels. */ * LOD levels. */
col_lights: Texture<ColLightFmt>, col_lights: Texture, /* <ColLightFmt> */
/// Models stored in this figure entry; there may be several for one figure, /// Models stored in this figure entry; there may be several for one figure,
/// because of LOD models. /// because of LOD models.
pub models: [FigureModel; N], pub models: [FigureModel; N],
@ -4897,10 +4897,8 @@ impl FigureColLights {
} }
/// Find the correct texture for this model entry. /// Find the correct texture for this model entry.
pub fn texture<'a, const N: usize>( pub fn texture<'a, const N: usize>(&'a self, model: &'a FigureModelEntry<N>) -> &'a Texture /* <ColLightFmt> */
&'a self, {
model: &'a FigureModelEntry<N>,
) -> &'a Texture<ColLightFmt> {
/* &self.col_lights */ /* &self.col_lights */
&model.col_lights &model.col_lights
} }
@ -4915,7 +4913,7 @@ impl FigureColLights {
&mut self, &mut self,
renderer: &mut Renderer, renderer: &mut Renderer,
(tex, tex_size): ColLightInfo, (tex, tex_size): ColLightInfo,
(opaque, bounds): (Mesh<TerrainPipeline>, math::Aabb<f32>), (opaque, bounds): (Mesh<TerrainVertex>, math::Aabb<f32>),
vertex_range: [Range<u32>; N], vertex_range: [Range<u32>; N],
) -> Result<FigureModelEntry<N>, RenderError> { ) -> Result<FigureModelEntry<N>, RenderError> {
span!(_guard, "create_figure", "FigureColLights::create_figure"); span!(_guard, "create_figure", "FigureColLights::create_figure");
@ -4926,7 +4924,7 @@ impl FigureColLights {
i32::from(tex_size.y), i32::from(tex_size.y),
)) ))
.expect("Not yet implemented: allocate new atlas on allocation failure."); .expect("Not yet implemented: allocate new atlas on allocation failure.");
let col_lights = ShadowPipeline::create_col_lights(renderer, &(tex, tex_size))?; let col_lights = pipelines::shadow::create_col_lights(renderer, &(tex, tex_size))?;
let model_len = u32::try_from(opaque.vertices().len()) let model_len = u32::try_from(opaque.vertices().len())
.expect("The model size for this figure does not fit in a u32!"); .expect("The model size for this figure does not fit in a u32!");
let model = renderer.create_model(&opaque)?; let model = renderer.create_model(&opaque)?;
@ -5196,5 +5194,5 @@ impl<S: Skeleton> FigureState<S> {
fn figure_bone_data_from_anim( fn figure_bone_data_from_anim(
mats: &[anim::FigureBoneData; anim::MAX_BONE_COUNT], mats: &[anim::FigureBoneData; anim::MAX_BONE_COUNT],
) -> &[FigureBoneData] { ) -> &[FigureBoneData] {
gfx::memory::cast_slice(mats) bytemuck::cast_slice(mats)
} }

View File

@ -1,7 +1,7 @@
use crate::{ use crate::{
render::{ render::{
pipelines::lod_terrain::{Locals, LodData, Vertex}, pipelines::lod_terrain::{LodData, Vertex},
Consts, GlobalModel, LodTerrainPipeline, Mesh, Model, Quad, Renderer, GlobalModel, LodTerrainVertex, Mesh, Model, Quad, Renderer,
}, },
settings::Settings, settings::Settings,
}; };
@ -10,8 +10,7 @@ use common::{spiral::Spiral2d, util::srgba_to_linear};
use vek::*; use vek::*;
pub struct Lod { pub struct Lod {
model: Option<(u32, Model<LodTerrainPipeline>)>, model: Option<(u32, Model<LodTerrainVertex>)>,
locals: Consts<Locals>,
data: LodData, data: LodData,
} }
@ -25,7 +24,6 @@ impl Lod {
pub fn new(renderer: &mut Renderer, client: &Client, settings: &Settings) -> Self { pub fn new(renderer: &mut Renderer, client: &Client, settings: &Settings) -> Self {
Self { Self {
model: None, model: None,
locals: renderer.create_consts(&[Locals::default()]).unwrap(),
data: LodData::new( data: LodData::new(
renderer, renderer,
client.world_data().chunk_size(), client.world_data().chunk_size(),
@ -33,7 +31,7 @@ impl Lod {
client.world_data().lod_alt.raw(), client.world_data().lod_alt.raw(),
client.world_data().lod_horizon.raw(), client.world_data().lod_horizon.raw(),
settings.graphics.lod_detail.max(100).min(2500), settings.graphics.lod_detail.max(100).min(2500),
water_color().into_array().into(), // water_color().into_array().into(),
), ),
} }
} }
@ -68,7 +66,7 @@ impl Lod {
} }
} }
fn create_lod_terrain_mesh(detail: u32) -> Mesh<LodTerrainPipeline> { fn create_lod_terrain_mesh(detail: u32) -> Mesh<LodTerrainVertex> {
// detail is even, so we choose odd detail (detail + 1) to create two even // detail is even, so we choose odd detail (detail + 1) to create two even
// halves with an empty hole. // halves with an empty hole.
let detail = detail + 1; let detail = detail + 1;

View File

@ -17,8 +17,8 @@ use crate::{
audio::{ambient::AmbientMgr, music::MusicMgr, sfx::SfxMgr, AudioFrontend}, audio::{ambient::AmbientMgr, music::MusicMgr, sfx::SfxMgr, AudioFrontend},
render::{ render::{
create_clouds_mesh, create_pp_mesh, create_skybox_mesh, CloudsLocals, CloudsPipeline, create_clouds_mesh, create_pp_mesh, create_skybox_mesh, CloudsLocals, CloudsPipeline,
Consts, GlobalModel, Globals, Light, LodData, Model, PostProcessLocals, Consts, GlobalModel, Globals, Light, LodData, Model, PostProcessLocals, Renderer, Shadow,
PostProcessPipeline, Renderer, Shadow, ShadowLocals, SkyboxLocals, SkyboxPipeline, ShadowLocals, SkyboxLocals,
}, },
settings::Settings, settings::Settings,
window::{AnalogGameInput, Event}, window::{AnalogGameInput, Event},
@ -67,8 +67,7 @@ struct EventLight {
} }
struct Skybox { struct Skybox {
model: Model<SkyboxPipeline>, model: Model<SkyboxVertex>,
locals: Consts<SkyboxLocals>,
} }
struct Clouds { struct Clouds {
@ -77,8 +76,7 @@ struct Clouds {
} }
struct PostProcess { struct PostProcess {
model: Model<PostProcessPipeline>, model: Model<PostProcessVertex>,
locals: Consts<PostProcessLocals>,
} }
pub struct Scene { pub struct Scene {
@ -295,7 +293,6 @@ impl Scene {
skybox: Skybox { skybox: Skybox {
model: renderer.create_model(&create_skybox_mesh()).unwrap(), model: renderer.create_model(&create_skybox_mesh()).unwrap(),
locals: renderer.create_consts(&[SkyboxLocals::default()]).unwrap(),
}, },
clouds: Clouds { clouds: Clouds {
model: renderer.create_model(&create_clouds_mesh()).unwrap(), model: renderer.create_model(&create_clouds_mesh()).unwrap(),
@ -303,9 +300,6 @@ impl Scene {
}, },
postprocess: PostProcess { postprocess: PostProcess {
model: renderer.create_model(&create_pp_mesh()).unwrap(), model: renderer.create_model(&create_pp_mesh()).unwrap(),
locals: renderer
.create_consts(&[PostProcessLocals::default()])
.unwrap(),
}, },
terrain: Terrain::new(renderer, sprite_render_context), terrain: Terrain::new(renderer, sprite_render_context),
lod: Lod::new(renderer, client, settings), lod: Lod::new(renderer, client, settings),

View File

@ -3,7 +3,7 @@ use crate::{
mesh::{greedy::GreedyMesh, Meshable}, mesh::{greedy::GreedyMesh, Meshable},
render::{ render::{
pipelines::particle::ParticleMode, GlobalModel, Instances, Light, LodData, Model, pipelines::particle::ParticleMode, GlobalModel, Instances, Light, LodData, Model,
ParticleInstance, ParticlePipeline, Renderer, ParticleInstance, ParticleVertex, Renderer,
}, },
}; };
use common::{ use common::{
@ -38,7 +38,7 @@ pub struct ParticleMgr {
instances: Instances<ParticleInstance>, instances: Instances<ParticleInstance>,
/// GPU Vertex Buffers /// GPU Vertex Buffers
model_cache: HashMap<&'static str, Model<ParticlePipeline>>, model_cache: HashMap<&'static str, Model<ParticleVertex>>,
} }
impl ParticleMgr { impl ParticleMgr {
@ -1103,7 +1103,7 @@ fn default_instances(renderer: &mut Renderer) -> Instances<ParticleInstance> {
const DEFAULT_MODEL_KEY: &str = "voxygen.voxel.particle"; const DEFAULT_MODEL_KEY: &str = "voxygen.voxel.particle";
fn default_cache(renderer: &mut Renderer) -> HashMap<&'static str, Model<ParticlePipeline>> { fn default_cache(renderer: &mut Renderer) -> HashMap<&'static str, Model<ParticleVertex>> {
let mut model_cache = HashMap::new(); let mut model_cache = HashMap::new();
model_cache.entry(DEFAULT_MODEL_KEY).or_insert_with(|| { model_cache.entry(DEFAULT_MODEL_KEY).or_insert_with(|| {
@ -1119,7 +1119,7 @@ fn default_cache(renderer: &mut Renderer) -> HashMap<&'static str, Model<Particl
let segment = Segment::from(&vox.read().0); let segment = Segment::from(&vox.read().0);
let segment_size = segment.size(); let segment_size = segment.size();
let mut mesh = let mut mesh =
Meshable::<ParticlePipeline, &mut GreedyMesh>::generate_mesh(segment, &mut greedy).0; Meshable::<ParticleVertex, &mut GreedyMesh>::generate_mesh(segment, &mut greedy).0;
// Center particle vertices around origin // Center particle vertices around origin
for vert in mesh.vertices_mut() { for vert in mesh.vertices_mut() {
vert.pos[0] -= segment_size.x as f32 / 2.0; vert.pos[0] -= segment_size.x as f32 / 2.0;

View File

@ -1,10 +1,10 @@
use crate::{ use crate::{
mesh::{greedy::GreedyMesh, Meshable}, mesh::{greedy::GreedyMesh, Meshable},
render::{ render::{
create_clouds_mesh, create_pp_mesh, create_skybox_mesh, BoneMeshes, CloudsLocals, create_clouds_mesh, create_pp_mesh, create_skybox_mesh, BoneMeshes, CloudsLocals, Consts,
CloudsPipeline, Consts, FigureModel, FigurePipeline, GlobalModel, Globals, Light, Mesh, FigureModel, GlobalModel, Globals, Light, Mesh, Model, PostProcessLocals,
Model, PostProcessLocals, PostProcessPipeline, Renderer, Shadow, ShadowLocals, PostProcessVertex, Renderer, Shadow, ShadowLocals, SkyboxLocals, SkyboxVertex,
SkyboxLocals, SkyboxPipeline, TerrainPipeline, TerrainVertex,
}, },
scene::{ scene::{
camera::{self, Camera, CameraMode}, camera::{self, Camera, CameraMode},
@ -45,13 +45,13 @@ impl ReadVol for VoidVol {
fn generate_mesh<'a>( fn generate_mesh<'a>(
greedy: &mut GreedyMesh<'a>, greedy: &mut GreedyMesh<'a>,
mesh: &mut Mesh<TerrainPipeline>, mesh: &mut Mesh<TerrainVertex>,
segment: Segment, segment: Segment,
offset: Vec3<f32>, offset: Vec3<f32>,
bone_idx: u8, bone_idx: u8,
) -> BoneMeshes { ) -> BoneMeshes {
let (opaque, _, /* shadow */ _, bounds) = let (opaque, _, /* shadow */ _, bounds) =
Meshable::<FigurePipeline, &mut GreedyMesh>::generate_mesh( Meshable::<TerrainVertex, &mut GreedyMesh>::generate_mesh(
segment, segment,
(greedy, mesh, offset, Vec3::one(), bone_idx), (greedy, mesh, offset, Vec3::one(), bone_idx),
); );
@ -59,13 +59,11 @@ fn generate_mesh<'a>(
} }
struct Skybox { struct Skybox {
model: Model<SkyboxPipeline>, model: Model<SkyboxVertex>,
locals: Consts<SkyboxLocals>,
} }
struct PostProcess { struct PostProcess {
model: Model<PostProcessPipeline>, model: Model<PostProcessVertex>,
locals: Consts<PostProcessLocals>,
} }
struct Clouds { struct Clouds {
@ -139,7 +137,6 @@ impl Scene {
skybox: Skybox { skybox: Skybox {
model: renderer.create_model(&create_skybox_mesh()).unwrap(), model: renderer.create_model(&create_skybox_mesh()).unwrap(),
locals: renderer.create_consts(&[SkyboxLocals::default()]).unwrap(),
}, },
clouds: Clouds { clouds: Clouds {
model: renderer.create_model(&create_clouds_mesh()).unwrap(), model: renderer.create_model(&create_clouds_mesh()).unwrap(),
@ -147,9 +144,6 @@ impl Scene {
}, },
postprocess: PostProcess { postprocess: PostProcess {
model: renderer.create_model(&create_pp_mesh()).unwrap(), model: renderer.create_model(&create_pp_mesh()).unwrap(),
locals: renderer
.create_consts(&[PostProcessLocals::default()])
.unwrap(),
}, },
lod: LodData::new( lod: LodData::new(
renderer, renderer,

View File

@ -4,9 +4,9 @@ pub use self::watcher::{BlocksOfInterest, Interaction};
use crate::{ use crate::{
mesh::{greedy::GreedyMesh, terrain::SUNLIGHT, Meshable}, mesh::{greedy::GreedyMesh, terrain::SUNLIGHT, Meshable},
render::{ render::{
ColLightFmt, ColLightInfo, Consts, FluidPipeline, GlobalModel, Instances, Mesh, Model, pipelines, ColLightInfo, Consts, FluidVertex, GlobalModel, Instances, Mesh, Model,
RenderError, Renderer, ShadowPipeline, SpriteInstance, SpriteLocals, SpritePipeline, RenderError, Renderer, SpriteInstance, SpriteLocals, SpriteVertex, TerrainLocals,
TerrainLocals, TerrainPipeline, Texture, TerrainVertex, Texture,
}, },
}; };
@ -58,8 +58,8 @@ impl Visibility {
pub struct TerrainChunkData { pub struct TerrainChunkData {
// GPU data // GPU data
load_time: f32, load_time: f32,
opaque_model: Model<TerrainPipeline>, opaque_model: Model<TerrainVertex>,
fluid_model: Option<Model<FluidPipeline>>, fluid_model: Option<Model<FluidVertex>>,
/// If this is `None`, this texture is not allocated in the current atlas, /// If this is `None`, this texture is not allocated in the current atlas,
/// and therefore there is no need to free its allocation. /// and therefore there is no need to free its allocation.
col_lights: Option<guillotiere::AllocId>, col_lights: Option<guillotiere::AllocId>,
@ -69,7 +69,7 @@ pub struct TerrainChunkData {
/// shadow chunks will still keep it alive; we could deal with this by /// shadow chunks will still keep it alive; we could deal with this by
/// making this an `Option`, but it probably isn't worth it since they /// making this an `Option`, but it probably isn't worth it since they
/// shouldn't be that much more nonlocal than regular chunks). /// shouldn't be that much more nonlocal than regular chunks).
texture: Texture<ColLightFmt>, texture: Arc<Texture>, // TODO: make this actually work with a bind group
light_map: Box<dyn Fn(Vec3<i32>) -> f32 + Send + Sync>, light_map: Box<dyn Fn(Vec3<i32>) -> f32 + Send + Sync>,
glow_map: Box<dyn Fn(Vec3<i32>) -> f32 + Send + Sync>, glow_map: Box<dyn Fn(Vec3<i32>) -> f32 + Send + Sync>,
sprite_instances: HashMap<(SpriteKind, usize), Instances<SpriteInstance>>, sprite_instances: HashMap<(SpriteKind, usize), Instances<SpriteInstance>>,
@ -95,8 +95,8 @@ struct ChunkMeshState {
struct MeshWorkerResponse { struct MeshWorkerResponse {
pos: Vec2<i32>, pos: Vec2<i32>,
z_bounds: (f32, f32), z_bounds: (f32, f32),
opaque_mesh: Mesh<TerrainPipeline>, opaque_mesh: Mesh<TerrainVertex>,
fluid_mesh: Mesh<FluidPipeline>, fluid_mesh: Mesh<FluidVertex>,
col_lights_info: ColLightInfo, col_lights_info: ColLightInfo,
light_map: Box<dyn Fn(Vec3<i32>) -> f32 + Send + Sync>, light_map: Box<dyn Fn(Vec3<i32>) -> f32 + Send + Sync>,
glow_map: Box<dyn Fn(Vec3<i32>) -> f32 + Send + Sync>, glow_map: Box<dyn Fn(Vec3<i32>) -> f32 + Send + Sync>,
@ -237,7 +237,7 @@ fn mesh_worker<V: BaseVol<Vox = Block> + RectRasterableVol + ReadVol + Debug + '
struct SpriteData { struct SpriteData {
/* mat: Mat4<f32>, */ /* mat: Mat4<f32>, */
locals: Consts<SpriteLocals>, locals: Consts<SpriteLocals>,
model: Model<SpritePipeline>, model: Model<SpriteVertex>,
/* scale: Vec3<f32>, */ /* scale: Vec3<f32>, */
offset: Vec3<f32>, offset: Vec3<f32>,
} }
@ -289,12 +289,12 @@ pub struct Terrain<V: RectRasterableVol = TerrainChunk> {
// GPU data // GPU data
sprite_data: Arc<HashMap<(SpriteKind, usize), Vec<SpriteData>>>, sprite_data: Arc<HashMap<(SpriteKind, usize), Vec<SpriteData>>>,
sprite_col_lights: Texture<ColLightFmt>, sprite_col_lights: Texture, /* <ColLightFmt> */
/// As stated previously, this is always the very latest texture into which /// As stated previously, this is always the very latest texture into which
/// we allocate. Code cannot assume that this is the assigned texture /// we allocate. Code cannot assume that this is the assigned texture
/// for any particular chunk; look at the `texture` field in /// for any particular chunk; look at the `texture` field in
/// `TerrainChunkData` for that. /// `TerrainChunkData` for that.
col_lights: Texture<ColLightFmt>, col_lights: Texture, /* <ColLightFmt> */
waves: Texture, waves: Texture,
phantom: PhantomData<V>, phantom: PhantomData<V>,
@ -308,7 +308,7 @@ impl TerrainChunkData {
pub struct SpriteRenderContext { pub struct SpriteRenderContext {
sprite_config: Arc<SpriteSpec>, sprite_config: Arc<SpriteSpec>,
sprite_data: Arc<HashMap<(SpriteKind, usize), Vec<SpriteData>>>, sprite_data: Arc<HashMap<(SpriteKind, usize), Vec<SpriteData>>>,
sprite_col_lights: Texture<ColLightFmt>, sprite_col_lights: Texture, /* <ColLightFmt> */
} }
pub type SpriteRenderContextLazy = Box<dyn FnMut(&mut Renderer) -> SpriteRenderContext>; pub type SpriteRenderContextLazy = Box<dyn FnMut(&mut Renderer) -> SpriteRenderContext>;
@ -320,7 +320,7 @@ impl SpriteRenderContext {
struct SpriteDataResponse { struct SpriteDataResponse {
locals: [SpriteLocals; 8], locals: [SpriteLocals; 8],
model: Mesh<SpritePipeline>, model: Mesh<SpriteVertex>,
offset: Vec3<f32>, offset: Vec3<f32>,
} }
@ -341,7 +341,6 @@ impl SpriteRenderContext {
let mut locals_buffer = [SpriteLocals::default(); 8]; let mut locals_buffer = [SpriteLocals::default(); 8];
let sprite_config_ = &sprite_config; let sprite_config_ = &sprite_config;
// NOTE: Tracks the start vertex of the next model to be meshed. // NOTE: Tracks the start vertex of the next model to be meshed.
let sprite_data: HashMap<(SpriteKind, usize), _> = SpriteKind::into_enum_iter() let sprite_data: HashMap<(SpriteKind, usize), _> = SpriteKind::into_enum_iter()
.filter_map(|kind| Some((kind, kind.elim_case_pure(&sprite_config_.0).as_ref()?))) .filter_map(|kind| Some((kind, kind.elim_case_pure(&sprite_config_.0).as_ref()?)))
.flat_map(|(kind, sprite_config)| { .flat_map(|(kind, sprite_config)| {
@ -401,7 +400,7 @@ impl SpriteRenderContext {
// has no // has no
// interesting return value, but updates the mesh. // interesting return value, but updates the mesh.
let mut opaque_mesh = Mesh::new(); let mut opaque_mesh = Mesh::new();
Meshable::<SpritePipeline, &mut GreedyMesh>::generate_mesh( Meshable::<SpriteVertex, &mut GreedyMesh>::generate_mesh(
Segment::from(&model.read().0).scaled_by(lod_scale), Segment::from(&model.read().0).scaled_by(lod_scale),
(greedy, &mut opaque_mesh, false), (greedy, &mut opaque_mesh, false),
); );
@ -494,8 +493,9 @@ impl SpriteRenderContext {
) )
}) })
.collect(); .collect();
let sprite_col_lights = ShadowPipeline::create_col_lights(renderer, &sprite_col_lights) let sprite_col_lights =
.expect("Failed to upload sprite color and light data to the GPU!"); pipelines::shadow::create_col_lights(renderer, &sprite_col_lights)
.expect("Failed to upload sprite color and light data to the GPU!");
Self { Self {
sprite_config: Arc::clone(&sprite_config), sprite_config: Arc::clone(&sprite_config),
@ -530,9 +530,8 @@ impl<V: RectRasterableVol> Terrain<V> {
waves: renderer waves: renderer
.create_texture( .create_texture(
&assets::Image::load_expect("voxygen.texture.waves").read().0, &assets::Image::load_expect("voxygen.texture.waves").read().0,
Some(gfx::texture::FilterMethod::Trilinear), Some(wgpu::FilterMode::Linear),
Some(gfx::texture::WrapMode::Tile), Some(wgpu::AddressMode::Repeat),
None,
) )
.expect("Failed to create wave texture"), .expect("Failed to create wave texture"),
col_lights, col_lights,
@ -542,7 +541,7 @@ impl<V: RectRasterableVol> Terrain<V> {
fn make_atlas( fn make_atlas(
renderer: &mut Renderer, renderer: &mut Renderer,
) -> Result<(AtlasAllocator, Texture<ColLightFmt>), RenderError> { ) -> Result<(AtlasAllocator, Texture /* <ColLightFmt> */), RenderError> {
span!(_guard, "make_atlas", "Terrain::make_atlas"); span!(_guard, "make_atlas", "Terrain::make_atlas");
let max_texture_size = renderer.max_texture_size(); let max_texture_size = renderer.max_texture_size();
let atlas_size = let atlas_size =
@ -554,20 +553,29 @@ impl<V: RectRasterableVol> Terrain<V> {
..guillotiere::AllocatorOptions::default() ..guillotiere::AllocatorOptions::default()
}); });
let texture = renderer.create_texture_raw( let texture = renderer.create_texture_raw(
gfx::texture::Kind::D2( wgpu::TextureDescriptor {
max_texture_size, label: Some("Atlas texture"),
max_texture_size, size: wgpu::Extent3d {
gfx::texture::AaMode::Single, width: max_texture_size,
), height: max_texture_size,
1_u8, depth: 1,
gfx::memory::Bind::SHADER_RESOURCE, },
gfx::memory::Usage::Dynamic, mip_level_count: 1,
(0, 0), sample_count: 1,
gfx::format::Swizzle::new(), dimension: wgpu::TextureDimension::D1,
gfx::texture::SamplerInfo::new( format: wgpu::TextureFormat::Rgba8UnormSrgb,
gfx::texture::FilterMethod::Bilinear, usage: wgpu::TextureUsage::COPY_DST | wgpu::TextureUsage::SAMPLED,
gfx::texture::WrapMode::Clamp, },
), wgpu::SamplerDescriptor {
label: Some("Atlas sampler"),
address_mode_u: wgpu::AddressMode::ClampToEdge,
address_mode_v: wgpu::AddressMode::ClampToEdge,
address_mode_w: wgpu::AddressMode::ClampToEdge,
mag_filter: wgpu::FilterMode::Linear,
min_filter: wgpu::FilterMode::Linear,
mipmap_filter: wgpu::FilterMode::Nearest,
..Default::default()
},
)?; )?;
Ok((atlas, texture)) Ok((atlas, texture))
} }

View File

@ -1,6 +1,6 @@
use super::graphic::{Graphic, GraphicCache, Id as GraphicId}; use super::graphic::{Graphic, GraphicCache, Id as GraphicId};
use crate::{ use crate::{
render::{Mesh, Renderer, Texture, UiPipeline}, render::{Mesh, Renderer, Texture, UIVertex},
Error, Error,
}; };
use conrod_core::{text::GlyphCache, widget::Id}; use conrod_core::{text::GlyphCache, widget::Id};
@ -13,7 +13,7 @@ const GLYPH_CACHE_SIZE: u16 = 1;
const SCALE_TOLERANCE: f32 = 0.5; const SCALE_TOLERANCE: f32 = 0.5;
const POSITION_TOLERANCE: f32 = 0.5; const POSITION_TOLERANCE: f32 = 0.5;
type TextCache = HashMap<Id, Mesh<UiPipeline>>; type TextCache = HashMap<Id, Mesh<UIVertex>>;
pub struct Cache { pub struct Cache {
// Map from text ids to their positioned glyphs. // Map from text ids to their positioned glyphs.

View File

@ -3,7 +3,7 @@ mod renderer;
pub use renderer::{SampleStrat, Transform}; pub use renderer::{SampleStrat, Transform};
use crate::render::{RenderError, Renderer, Texture}; use crate::render::{Renderer, Texture};
use common::figure::Segment; use common::figure::Segment;
use guillotiere::{size2, SimpleAtlasAllocator}; use guillotiere::{size2, SimpleAtlasAllocator};
use hashbrown::{hash_map::Entry, HashMap}; use hashbrown::{hash_map::Entry, HashMap};
@ -443,21 +443,17 @@ fn upload_image(renderer: &mut Renderer, aabr: Aabr<u16>, tex: &Texture, image:
size, size,
// NOTE: Rgba texture, so each pixel is 4 bytes, ergo this cannot fail. // NOTE: Rgba texture, so each pixel is 4 bytes, ergo this cannot fail.
// We make the cast parameters explicit for clarity. // We make the cast parameters explicit for clarity.
gfx::memory::cast_slice::<u8, [u8; 4]>(&image), bytemuck::cast_slice::<u8, [u8; 4]>(&image),
) { ) {
warn!(?e, "Failed to update texture"); warn!(?e, "Failed to update texture");
} }
} }
fn create_image( fn create_image(renderer: &mut Renderer, image: RgbaImage, border_color: Rgba<f32>) {
renderer: &mut Renderer,
image: RgbaImage,
border_color: Rgba<f32>,
) -> Result<Texture, RenderError> {
renderer.create_texture( renderer.create_texture(
&DynamicImage::ImageRgba8(image), &DynamicImage::ImageRgba8(image),
None, None,
Some(gfx::texture::WrapMode::Border), Some(wgpu::AddressMode::ClampToBorder),
Some(border_color.into_array().into()), Some(border_color.into_array().into()),
) )
} }

View File

@ -25,8 +25,8 @@ pub use widgets::{
use crate::{ use crate::{
render::{ render::{
create_ui_quad, create_ui_tri, Consts, DynamicModel, Globals, Mesh, RenderError, Renderer, create_ui_quad, create_ui_tri, Consts, Globals, Mesh, Model, RenderError, Renderer,
UiLocals, UiMode, UiPipeline, UIVertex, UiLocals, UiMode,
}, },
window::Window, window::Window,
Error, Error,
@ -107,9 +107,9 @@ pub struct Ui {
draw_commands: Vec<DrawCommand>, draw_commands: Vec<DrawCommand>,
// Mesh buffer for UI vertices; we reuse its allocation in order to limit vector reallocations // Mesh buffer for UI vertices; we reuse its allocation in order to limit vector reallocations
// during redrawing. // during redrawing.
mesh: Mesh<UiPipeline>, mesh: Mesh<UIVertex>,
// Model for drawing the ui // Model for drawing the ui
model: DynamicModel<UiPipeline>, model: Model<UIVertex>,
// Consts for default ui drawing position (ie the interface) // Consts for default ui drawing position (ie the interface)
interface_locals: Consts<UiLocals>, interface_locals: Consts<UiLocals>,
default_globals: Consts<Globals>, default_globals: Consts<Globals>,
@ -568,7 +568,13 @@ impl Ui {
.map(|x| [255, 255, 255, *x]) .map(|x| [255, 255, 255, *x])
.collect::<Vec<[u8; 4]>>(); .collect::<Vec<[u8; 4]>>();
if let Err(err) = renderer.update_texture(cache_tex, offset, size, &new_data) { if let Err(err) = renderer.update_texture(
cache_tex,
offset,
size,
&new_data,
rect.width() * 4,
) {
warn!("Failed to update texture: {:?}", err); warn!("Failed to update texture: {:?}", err);
} }
}) { }) {