Ported most of the textures and models related methods

This commit is contained in:
Capucho 2020-08-21 21:38:00 +01:00 committed by Avi Weinstock
parent 0a5ef49d05
commit a8981aef67
8 changed files with 352 additions and 352 deletions

View File

@ -1,4 +1,3 @@
use super::RenderError;
use wgpu::util::DeviceExt; use wgpu::util::DeviceExt;
use zerocopy::AsBytes; use zerocopy::AsBytes;
@ -45,7 +44,9 @@ impl<T: Copy + AsBytes> Buffer<T> {
vals: &[T], vals: &[T],
offset: usize, offset: usize,
) { ) {
queue.write_buffer(&self.buf, offset, vals.as_bytes()) if !vals.is_empty() {
queue.write_buffer(&self.buf, offset, vals.as_bytes())
}
} }
pub fn count(&self) -> usize { self.count } pub fn count(&self) -> usize { self.count }

View File

@ -24,6 +24,12 @@ impl<V: Vertex> Model<V> {
} }
} }
pub fn new_dynamic(device: &wgpu::Device, size: usize) -> Self {
Self {
vbuf: Buffer::new(device, size, wgpu::BufferUsage::VERTEX),
}
}
/// Create a model with a slice of a portion of this model to send to the /// Create a model with a slice of a portion of this model to send to the
/// renderer. /// renderer.
pub fn submodel(&self, vertex_range: Range<u32>) -> SubModel<V> { pub fn submodel(&self, vertex_range: Range<u32>) -> SubModel<V> {

View File

@ -1,7 +1,4 @@
use super::{ use super::super::{Mesh, Model, TerrainPipeline};
super::{Mesh, Model, TerrainPipeline, TgtColorFmt, TgtDepthStencilFmt},
shadow, Globals, Light, Shadow,
};
use crate::mesh::greedy::GreedyMesh; use crate::mesh::greedy::GreedyMesh;
use vek::*; use vek::*;
use zerocopy::AsBytes; use zerocopy::AsBytes;

View File

@ -1,44 +1,48 @@
use super::{ use super::super::TerrainLocals;
super::{Pipeline, TerrainLocals, TgtColorFmt, TgtDepthStencilFmt},
shadow, Globals, Light, Shadow,
};
use gfx::{
self, gfx_defines, gfx_impl_struct_meta, gfx_pipeline, gfx_pipeline_inner,
gfx_vertex_struct_meta, state::ColorMask,
};
use vek::*; use vek::*;
use zerocopy::AsBytes;
gfx_defines! { #[repr(C)]
vertex Vertex { #[derive(Copy, Clone, Debug, AsBytes)]
pos_norm: u32 = "v_pos_norm", struct Vertex {
} pos_norm: u32,
pipeline pipe {
vbuf: gfx::VertexBuffer<Vertex> = (),
locals: gfx::ConstantBuffer<TerrainLocals> = "u_locals",
globals: gfx::ConstantBuffer<Globals> = "u_globals",
lights: gfx::ConstantBuffer<Light> = "u_lights",
shadows: gfx::ConstantBuffer<Shadow> = "u_shadows",
point_shadow_maps: gfx::TextureSampler<f32> = "t_point_shadow_maps",
directed_shadow_maps: gfx::TextureSampler<f32> = "t_directed_shadow_maps",
alt: gfx::TextureSampler<[f32; 2]> = "t_alt",
horizon: gfx::TextureSampler<[f32; 4]> = "t_horizon",
noise: gfx::TextureSampler<f32> = "t_noise",
waves: gfx::TextureSampler<[f32; 4]> = "t_waves",
// Shadow stuff
light_shadows: gfx::ConstantBuffer<shadow::Locals> = "u_light_shadows",
tgt_color: gfx::BlendTarget<TgtColorFmt> = ("tgt_color", ColorMask::all(), gfx::preset::blend::ALPHA),
tgt_depth_stencil: gfx::DepthTarget<TgtDepthStencilFmt> = gfx::preset::depth::LESS_EQUAL_TEST,
// tgt_depth_stencil: gfx::DepthStencilTarget<TgtDepthStencilFmt> = (gfx::preset::depth::LESS_EQUAL_TEST,Stencil::new(Comparison::Always,0xff,(StencilOp::Keep,StencilOp::Keep,StencilOp::Keep))),
}
} }
// gfx_defines! {
// vertex Vertex {
// pos_norm: u32 = "v_pos_norm",
// }
// pipeline pipe {
// vbuf: gfx::VertexBuffer<Vertex> = (),
// locals: gfx::ConstantBuffer<TerrainLocals> = "u_locals",
// globals: gfx::ConstantBuffer<Globals> = "u_globals",
// lights: gfx::ConstantBuffer<Light> = "u_lights",
// shadows: gfx::ConstantBuffer<Shadow> = "u_shadows",
// point_shadow_maps: gfx::TextureSampler<f32> = "t_point_shadow_maps",
// directed_shadow_maps: gfx::TextureSampler<f32> =
// "t_directed_shadow_maps",
// alt: gfx::TextureSampler<[f32; 2]> = "t_alt",
// horizon: gfx::TextureSampler<[f32; 4]> = "t_horizon",
// noise: gfx::TextureSampler<f32> = "t_noise",
// waves: gfx::TextureSampler<[f32; 4]> = "t_waves",
// // Shadow stuff
// light_shadows: gfx::ConstantBuffer<shadow::Locals> =
// "u_light_shadows",
// tgt_color: gfx::BlendTarget<TgtColorFmt> = ("tgt_color",
// ColorMask::all(), gfx::preset::blend::ALPHA), tgt_depth_stencil:
// gfx::DepthTarget<TgtDepthStencilFmt> = gfx::preset::depth::LESS_EQUAL_TEST,
// // tgt_depth_stencil: gfx::DepthStencilTarget<TgtDepthStencilFmt> =
// (gfx::preset::depth::LESS_EQUAL_TEST,Stencil::new(Comparison::Always,0xff,
// (StencilOp::Keep,StencilOp::Keep,StencilOp::Keep))), }
// }
impl Vertex { impl Vertex {
#[allow(clippy::identity_op)] // TODO: Pending review in #587 #[allow(clippy::identity_op)] // TODO: Pending review in #587
#[allow(clippy::into_iter_on_ref)] // TODO: Pending review in #587 #[allow(clippy::into_iter_on_ref)] // TODO: Pending review in #587
@ -62,9 +66,3 @@ impl Vertex {
} }
} }
} }
pub struct FluidPipeline;
impl Pipeline for FluidPipeline {
type Vertex = Vertex;
}

View File

@ -5,38 +5,43 @@ use super::{
}, },
Globals, Globals,
}; };
use gfx::{
self, gfx_constant_struct_meta, gfx_defines, gfx_impl_struct_meta, gfx_pipeline,
gfx_pipeline_inner, gfx_vertex_struct_meta, texture::SamplerInfo,
};
use vek::*; use vek::*;
use zerocopy::AsBytes;
gfx_defines! { #[repr(C)]
vertex Vertex { #[derive(Copy, Clone, Debug, AsBytes)]
pos: [f32; 2] = "v_pos", struct Vertex {
} pos: [f32; 2],
constant Locals {
nul: [f32; 4] = "nul",
}
pipeline pipe {
vbuf: gfx::VertexBuffer<Vertex> = (),
locals: gfx::ConstantBuffer<Locals> = "u_locals",
globals: gfx::ConstantBuffer<Globals> = "u_globals",
map: gfx::TextureSampler<[f32; 4]> = "t_map",
alt: gfx::TextureSampler<[f32; 2]> = "t_alt",
horizon: gfx::TextureSampler<[f32; 4]> = "t_horizon",
noise: gfx::TextureSampler<f32> = "t_noise",
tgt_color: gfx::RenderTarget<TgtColorFmt> = "tgt_color",
tgt_depth_stencil: gfx::DepthTarget<TgtDepthStencilFmt> = gfx::preset::depth::LESS_EQUAL_WRITE,
// tgt_depth_stencil: gfx::DepthStencilTarget<TgtDepthStencilFmt> = (gfx::preset::depth::LESS_EQUAL_WRITE,Stencil::new(Comparison::Always,0xff,(StencilOp::Keep,StencilOp::Keep,StencilOp::Keep))),
}
} }
// gfx_defines! {
// vertex Vertex {
// pos: [f32; 2] = "v_pos",
// }
// constant Locals {
// nul: [f32; 4] = "nul",
// }
// pipeline pipe {
// vbuf: gfx::VertexBuffer<Vertex> = (),
// locals: gfx::ConstantBuffer<Locals> = "u_locals",
// globals: gfx::ConstantBuffer<Globals> = "u_globals",
// map: gfx::TextureSampler<[f32; 4]> = "t_map",
// alt: gfx::TextureSampler<[f32; 2]> = "t_alt",
// horizon: gfx::TextureSampler<[f32; 4]> = "t_horizon",
// noise: gfx::TextureSampler<f32> = "t_noise",
// tgt_color: gfx::RenderTarget<TgtColorFmt> = "tgt_color",
// tgt_depth_stencil: gfx::DepthTarget<TgtDepthStencilFmt> =
// gfx::preset::depth::LESS_EQUAL_WRITE, // tgt_depth_stencil:
// gfx::DepthStencilTarget<TgtDepthStencilFmt> =
// (gfx::preset::depth::LESS_EQUAL_WRITE,Stencil::new(Comparison::Always,0xff,
// (StencilOp::Keep,StencilOp::Keep,StencilOp::Keep))), }
// }
impl Vertex { impl Vertex {
pub fn new(pos: Vec2<f32>) -> Self { pub fn new(pos: Vec2<f32>) -> Self {
Self { Self {
@ -45,16 +50,6 @@ impl Vertex {
} }
} }
impl Locals {
pub fn default() -> Self { Self { nul: [0.0; 4] } }
}
pub struct LodTerrainPipeline;
impl Pipeline for LodTerrainPipeline {
type Vertex = Vertex;
}
pub struct LodData { pub struct LodData {
pub map: Texture<LodColorFmt>, pub map: Texture<LodColorFmt>,
pub alt: Texture<LodAltFmt>, pub alt: Texture<LodAltFmt>,

View File

@ -13,53 +13,58 @@ pub mod ui;
use super::Consts; use super::Consts;
use crate::scene::camera::CameraMode; use crate::scene::camera::CameraMode;
use common::terrain::BlockKind; use common::terrain::BlockKind;
use gfx::{self, gfx_constant_struct_meta, gfx_defines, gfx_impl_struct_meta};
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;
gfx_defines! { #[repr(C)]
constant Globals { #[derive(Copy, Clone, Debug, AsBytes)]
view_mat: [[f32; 4]; 4] = "view_mat", pub struct Globals {
proj_mat: [[f32; 4]; 4] = "proj_mat", view_mat: [[f32; 4]; 4],
all_mat: [[f32; 4]; 4] = "all_mat", proj_mat: [[f32; 4]; 4],
cam_pos: [f32; 4] = "cam_pos", all_mat: [[f32; 4]; 4],
focus_off: [f32; 4] = "focus_off", cam_pos: [f32; 4],
focus_pos: [f32; 4] = "focus_pos", focus_off: [f32; 4],
/// NOTE: view_distance.x is the horizontal view distance, view_distance.y is the LOD focus_pos: [f32; 4],
/// detail, view_distance.z is the /// NOTE: view_distance.x is the horizontal view distance, view_distance.y
/// minimum height over any land chunk (i.e. the sea level), and view_distance.w is the /// is the LOD detail, view_distance.z is the
/// maximum height over this minimum height. /// minimum height over any land chunk (i.e. the sea level), and
/// /// view_distance.w is the maximum height over this minimum height.
/// TODO: Fix whatever alignment issue requires these uniforms to be aligned. ///
view_distance: [f32; 4] = "view_distance", /// TODO: Fix whatever alignment issue requires these uniforms to be
time_of_day: [f32; 4] = "time_of_day", // TODO: Make this f64. /// aligned.
sun_dir: [f32; 4] = "sun_dir", view_distance: [f32; 4],
moon_dir: [f32; 4] = "moon_dir", time_of_day: [f32; 4], // TODO: Make this f64.
tick: [f32; 4] = "tick", sun_dir: [f32; 4],
/// x, y represent the resolution of the screen; moon_dir: [f32; 4],
/// w, z represent the near and far planes of the shadow map. tick: [f32; 4],
screen_res: [f32; 4] = "screen_res", /// x, y represent the resolution of the screen;
light_shadow_count: [u32; 4] = "light_shadow_count", /// w, z represent the near and far planes of the shadow map.
shadow_proj_factors: [f32; 4] = "shadow_proj_factors", screen_res: [f32; 4],
medium: [u32; 4] = "medium", light_shadow_count: [u32; 4],
select_pos: [i32; 4] = "select_pos", shadow_proj_factors: [f32; 4],
gamma_exposure: [f32; 4] = "gamma_exposure", medium: [u32; 4],
ambiance: f32 = "ambiance", select_pos: [i32; 4],
cam_mode: u32 = "cam_mode", gamma_exposure: [f32; 4],
sprite_render_distance: f32 = "sprite_render_distance", ambiance: f32,
} cam_mode: u32,
sprite_render_distance: f32,
}
constant Light { #[repr(C)]
pos: [f32; 4] = "light_pos", #[derive(Copy, Clone, Debug, AsBytes)]
col: [f32; 4] = "light_col", pub struct Light {
} pos: [f32; 4],
col: [f32; 4],
}
constant Shadow { #[repr(C)]
pos_radius: [f32; 4] = "shadow_pos_radius", #[derive(Copy, Clone, Debug, AsBytes)]
} pub struct Shadow {
pos_radius: [f32; 4],
} }
impl Globals { impl Globals {
@ -219,3 +224,35 @@ pub struct GlobalModel {
pub shadows: Consts<Shadow>, pub shadows: Consts<Shadow>,
pub shadow_mats: Consts<shadow::Locals>, pub shadow_mats: Consts<shadow::Locals>,
} }
//gfx_defines! {
// constant Globals {
// view_mat: [[f32; 4]; 4] = "view_mat",
// proj_mat: [[f32; 4]; 4] = "proj_mat",
// all_mat: [[f32; 4]; 4] = "all_mat",
// cam_pos: [f32; 4] = "cam_pos",
// focus_off: [f32; 4] = "focus_off",
// focus_pos: [f32; 4] = "focus_pos",
// /// NOTE: view_distance.x is the horizontal view distance,
// view_distance.y is the LOD /// detail, view_distance.z is the
// /// minimum height over any land chunk (i.e. the sea level), and
// view_distance.w is the /// maximum height over this minimum height.
// ///
// /// TODO: Fix whatever alignment issue requires these uniforms to be
// aligned. view_distance: [f32; 4] = "view_distance",
// time_of_day: [f32; 4] = "time_of_day", // TODO: Make this f64.
// sun_dir: [f32; 4] = "sun_dir",
// moon_dir: [f32; 4] = "moon_dir",
// tick: [f32; 4] = "tick",
// /// x, y represent the resolution of the screen;
// /// w, z represent the near and far planes of the shadow map.
// screen_res: [f32; 4] = "screen_res",
// light_shadow_count: [u32; 4] = "light_shadow_count",
// shadow_proj_factors: [f32; 4] = "shadow_proj_factors",
// medium: [u32; 4] = "medium",
// select_pos: [i32; 4] = "select_pos",
// gamma_exposure: [f32; 4] = "gamma_exposure",
// ambiance: f32 = "ambiance",
// cam_mode: u32 = "cam_mode",
// sprite_render_distance: f32 = "sprite_render_distance",
// }

View File

@ -2,14 +2,14 @@ use super::{
consts::Consts, consts::Consts,
instances::Instances, instances::Instances,
mesh::Mesh, mesh::Mesh,
model::{Model}, model::Model,
pipelines::{ pipelines::{
clouds, figure, fluid, lod_terrain, particle, postprocess, shadow, skybox, sprite, terrain, clouds, figure, fluid, lod_terrain, particle, postprocess, shadow, skybox, sprite, terrain,
ui, GlobalModel, Globals, ui, GlobalModel, Globals,
}, },
texture::Texture, texture::Texture,
AaMode, CloudMode, FilterMode, FluidMode, LightingMode, RenderError, RenderMode, AaMode, AddressMode, CloudMode, FilterMode, FluidMode, LightingMode, RenderError, RenderMode,
ShadowMapMode, ShadowMode, AddressMode, ShadowMapMode, ShadowMode, Vertex,
}; };
use common::assets::{self, AssetExt, AssetHandle}; use common::assets::{self, AssetExt, AssetHandle};
use common_base::span; use common_base::span;
@ -18,76 +18,78 @@ use glsl_include::Context as IncludeContext;
use tracing::{error, info, warn}; use tracing::{error, info, warn};
use vek::*; use vek::*;
/// Represents the format of the pre-processed color target. // /// Represents the format of the pre-processed color target.
// TODO: `(gfx::format::R11_G11_B10, gfx::format::Float)` would be better in // // TODO: `(gfx::format::R11_G11_B10, gfx::format::Float)` would be better in
// theory, but it doesn't seem to work // // theory, but it doesn't seem to work
pub type TgtColorFmt = gfx::format::Rgba16F; // pub type TgtColorFmt = gfx::format::Rgba16F;
/// Represents the format of the pre-processed depth and stencil target. // /// Represents the format of the pre-processed depth and stencil target.
pub type TgtDepthStencilFmt = gfx::format::Depth; // pub type TgtDepthStencilFmt = gfx::format::Depth;
//
/// Represents the format of the window's color target. // /// Represents the format of the window's color target.
pub type WinColorFmt = gfx::format::Srgba8; // pub type WinColorFmt = gfx::format::Srgba8;
/// Represents the format of the window's depth target. // /// Represents the format of the window's depth target.
pub type WinDepthFmt = gfx::format::Depth; // pub type WinDepthFmt = gfx::format::Depth;
//
/// Represents the format of the pre-processed shadow depth target. // /// Represents the format of the pre-processed shadow depth target.
pub type ShadowDepthStencilFmt = gfx::format::Depth; // pub type ShadowDepthStencilFmt = gfx::format::Depth;
//
/// A handle to a pre-processed color target. // /// A handle to a pre-processed color target.
pub type TgtColorView = gfx::handle::RenderTargetView<gfx_backend::Resources, TgtColorFmt>; // pub type TgtColorView = gfx::handle::RenderTargetView<gfx_backend::Resources,
/// A handle to a pre-processed depth target. // TgtColorFmt>; /// A handle to a pre-processed depth target.
pub type TgtDepthStencilView = // pub type TgtDepthStencilView =
gfx::handle::DepthStencilView<gfx_backend::Resources, TgtDepthStencilFmt>; // gfx::handle::DepthStencilView<gfx_backend::Resources,
// TgtDepthStencilFmt>;
/// A handle to a window color target. //
pub type WinColorView = gfx::handle::RenderTargetView<gfx_backend::Resources, WinColorFmt>; // /// A handle to a window color target.
/// A handle to a window depth target. // pub type WinColorView = gfx::handle::RenderTargetView<gfx_backend::Resources,
pub type WinDepthView = gfx::handle::DepthStencilView<gfx_backend::Resources, WinDepthFmt>; // WinColorFmt>; /// A handle to a window depth target.
// pub type WinDepthView = gfx::handle::DepthStencilView<gfx_backend::Resources,
/// Represents the format of LOD shadows. // WinDepthFmt>;
pub type LodTextureFmt = (gfx::format::R8_G8_B8_A8, gfx::format::Unorm); //
// /// Represents the format of LOD shadows.
/// Represents the format of LOD altitudes. // pub type LodTextureFmt = (gfx::format::R8_G8_B8_A8, gfx::format::Unorm);
pub type LodAltFmt = (gfx::format::R16_G16, gfx::format::Unorm); //
// /// Represents the format of LOD altitudes.
/// Represents the format of LOD map colors. // pub type LodAltFmt = (gfx::format::R16_G16, gfx::format::Unorm);
pub type LodColorFmt = (gfx::format::R8_G8_B8_A8, gfx::format::Srgb); //
// /// Represents the format of LOD map colors.
/// Represents the format of greedy meshed color-light textures. // pub type LodColorFmt = (gfx::format::R8_G8_B8_A8, gfx::format::Srgb);
pub type ColLightFmt = (gfx::format::R8_G8_B8_A8, gfx::format::Unorm); //
// /// Represents the format of greedy meshed color-light textures.
/// A handle to a shadow depth target. // pub type ColLightFmt = (gfx::format::R8_G8_B8_A8, gfx::format::Unorm);
pub type ShadowDepthStencilView = //
gfx::handle::DepthStencilView<gfx_backend::Resources, ShadowDepthStencilFmt>; // /// A handle to a shadow depth target.
/// A handle to a shadow depth target as a resource. // pub type ShadowDepthStencilView =
pub type ShadowResourceView = gfx::handle::ShaderResourceView< // gfx::handle::DepthStencilView<gfx_backend::Resources,
gfx_backend::Resources, // ShadowDepthStencilFmt>; /// A handle to a shadow depth target as a resource.
<ShadowDepthStencilFmt as gfx::format::Formatted>::View, // pub type ShadowResourceView = gfx::handle::ShaderResourceView<
>; // gfx_backend::Resources,
// <ShadowDepthStencilFmt as gfx::format::Formatted>::View,
/// A handle to a render color target as a resource. // >;
pub type TgtColorRes = gfx::handle::ShaderResourceView< //
gfx_backend::Resources, // /// A handle to a render color target as a resource.
<TgtColorFmt as gfx::format::Formatted>::View, // pub type TgtColorRes = gfx::handle::ShaderResourceView<
>; // gfx_backend::Resources,
// <TgtColorFmt as gfx::format::Formatted>::View,
/// A handle to a render depth target as a resource. // >;
pub type TgtDepthRes = gfx::handle::ShaderResourceView< //
gfx_backend::Resources, // /// A handle to a render depth target as a resource.
<TgtDepthStencilFmt as gfx::format::Formatted>::View, // pub type TgtDepthRes = gfx::handle::ShaderResourceView<
>; // gfx_backend::Resources,
// <TgtDepthStencilFmt as gfx::format::Formatted>::View,
/// A handle to a greedy meshed color-light texture as a resource. // >;
pub type ColLightRes = gfx::handle::ShaderResourceView< //
gfx_backend::Resources, // /// A handle to a greedy meshed color-light texture as a resource.
<ColLightFmt as gfx::format::Formatted>::View, // pub type ColLightRes = gfx::handle::ShaderResourceView<
>; // gfx_backend::Resources,
/// A type representing data that can be converted to an immutable texture map // <ColLightFmt as gfx::format::Formatted>::View,
/// of ColLight data (used for texture atlases created during greedy meshing). // >;
pub type ColLightInfo = ( // /// A type representing data that can be converted to an immutable texture
Vec<<<ColLightFmt as gfx::format::Formatted>::Surface as gfx::format::SurfaceTyped>::DataType>, // map /// of ColLight data (used for texture atlases created during greedy
Vec2<u16>, // meshing). pub type ColLightInfo = (
); // Vec<<<ColLightFmt as gfx::format::Formatted>::Surface as
// gfx::format::SurfaceTyped>::DataType>, Vec2<u16>,
// );
/// Load from a GLSL file. /// Load from a GLSL file.
pub struct Glsl(String); pub struct Glsl(String);
@ -224,9 +226,9 @@ pub struct ShadowMapRenderer {
point_depth_stencil_view: wgpu::TextureView, point_depth_stencil_view: wgpu::TextureView,
point_sampler: wgpu::Sampler, point_sampler: wgpu::Sampler,
point_pipeline: GfxPipeline<shadow::pipe::Init<'static>>, point_pipeline: wgpu::RenderPipeline,
terrain_directed_pipeline: GfxPipeline<shadow::pipe::Init<'static>>, terrain_directed_pipeline: wgpu::RenderPipeline,
figure_directed_pipeline: GfxPipeline<shadow::figure_pipe::Init<'static>>, figure_directed_pipeline: wgpu::RenderPipeline,
} }
/// A type that encapsulates rendering state. `Renderer` is central to Voxygen's /// A type that encapsulates rendering state. `Renderer` is central to Voxygen's
@ -237,6 +239,7 @@ pub struct Renderer {
device: wgpu::Device, device: wgpu::Device,
queue: wgpu::Queue, queue: wgpu::Queue,
swap_chain: wgpu::SwapChain, swap_chain: wgpu::SwapChain,
sc_desc: wgpu::SwapChainDescriptor,
win_depth_view: wgpu::TextureView, win_depth_view: wgpu::TextureView,
@ -249,22 +252,22 @@ pub struct Renderer {
shadow_map: Option<ShadowMapRenderer>, shadow_map: Option<ShadowMapRenderer>,
skybox_pipeline: GfxPipeline<skybox::pipe::Init<'static>>, skybox_pipeline: wgpu::RenderPipeline,
figure_pipeline: GfxPipeline<figure::pipe::Init<'static>>, figure_pipeline: wgpu::RenderPipeline,
terrain_pipeline: GfxPipeline<terrain::pipe::Init<'static>>, terrain_pipeline: wgpu::RenderPipeline,
fluid_pipeline: GfxPipeline<fluid::pipe::Init<'static>>, fluid_pipeline: wgpu::RenderPipeline,
sprite_pipeline: GfxPipeline<sprite::pipe::Init<'static>>, sprite_pipeline: wgpu::RenderPipeline,
particle_pipeline: GfxPipeline<particle::pipe::Init<'static>>, particle_pipeline: wgpu::RenderPipeline,
ui_pipeline: GfxPipeline<ui::pipe::Init<'static>>, ui_pipeline: wgpu::RenderPipeline,
lod_terrain_pipeline: GfxPipeline<lod_terrain::pipe::Init<'static>>, lod_terrain_pipeline: wgpu::RenderPipeline,
clouds_pipeline: GfxPipeline<clouds::pipe::Init<'static>>, clouds_pipeline: wgpu::RenderPipeline,
postprocess_pipeline: GfxPipeline<postprocess::pipe::Init<'static>>, postprocess_pipeline: wgpu::RenderPipeline,
#[allow(dead_code)] //TODO: remove ? #[allow(dead_code)] //TODO: remove ?
player_shadow_pipeline: GfxPipeline<figure::pipe::Init<'static>>, player_shadow_pipeline: wgpu::RenderPipeline,
shaders: AssetHandle<Shaders>, shaders: AssetHandle<Shaders>,
noise_tex: Texture<(gfx::format::R8, gfx::format::Unorm)>, noise_tex: Texture,
mode: RenderMode, mode: RenderMode,
} }
@ -324,13 +327,15 @@ impl Renderer {
"selected graphics device" "selected graphics device"
); );
let swap_chain = device.create_swap_chain(&surface, &wgpu::SwapChainDescriptor { let sc_desc = wgpu::SwapChainDescriptor {
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT, usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
format: wgpu::TextureFormat::Bgra8UnormSrgb, format: wgpu::TextureFormat::Bgra8UnormSrgb,
width: dims.0, width: dims.0,
height: dims.1, height: dims.1,
present_mode: wgpu::PresentMode::Immediate, present_mode: wgpu::PresentMode::Immediate,
}); };
let swap_chain = device.create_swap_chain(&surface, &sc_desc);
let shadow_views = Self::create_shadow_views( let shadow_views = Self::create_shadow_views(
&device, &device,
@ -365,12 +370,8 @@ impl Renderer {
shadow_views.is_some(), shadow_views.is_some(),
)?; )?;
let ( let (tgt_color_view, tgt_depth_stencil_view, tgt_color_pp_view, win_depth_view) =
tgt_color_view, Self::create_rt_views(&device, (dims.0, dims.1), &mode)?;
tgt_depth_stencil_view,
tgt_color_pp_view,
win_depth_view,
) = Self::create_rt_views(&device, (dims.0, dims.1), &mode)?;
let shadow_map = if let ( let shadow_map = if let (
Some(point_pipeline), Some(point_pipeline),
@ -432,6 +433,7 @@ impl Renderer {
device, device,
queue, queue,
swap_chain, swap_chain,
sc_desc,
win_depth_view, win_depth_view,
@ -466,30 +468,14 @@ impl Renderer {
/// Get references to the internal render target views that get rendered to /// Get references to the internal render target views that get rendered to
/// before post-processing. /// before post-processing.
#[allow(dead_code)] #[allow(dead_code)]
pub fn tgt_views(&self) -> (&TgtColorView, &TgtDepthStencilView) { pub fn tgt_views(&self) -> (&wgpu::TextureView, &wgpu::TextureView) {
(&self.tgt_color_view, &self.tgt_depth_stencil_view) (&self.tgt_color_view, &self.tgt_depth_stencil_view)
} }
/// Get references to the internal render target views that get displayed /// Get references to the internal render target views that get displayed
/// directly by the window. /// directly by the window.
#[allow(dead_code)] #[allow(dead_code)]
pub fn win_views(&self) -> (&WinColorView, &WinDepthView) { pub fn win_views(&self) -> &wgpu::TextureView { &self.win_depth_view }
(&self.win_color_view, &self.win_depth_view)
}
/// Get mutable references to the internal render target views that get
/// rendered to before post-processing.
#[allow(dead_code)]
pub fn tgt_views_mut(&mut self) -> (&mut TgtColorView, &mut TgtDepthStencilView) {
(&mut self.tgt_color_view, &mut self.tgt_depth_stencil_view)
}
/// Get mutable references to the internal render target views that get
/// displayed directly by the window.
#[allow(dead_code)]
pub fn win_views_mut(&mut self) -> (&mut WinColorView, &mut WinDepthView) {
(&mut self.win_color_view, &mut self.win_depth_view)
}
/// Change the render mode. /// Change the render mode.
pub fn set_render_mode(&mut self, mode: RenderMode) -> Result<(), RenderError> { pub fn set_render_mode(&mut self, mode: RenderMode) -> Result<(), RenderError> {
@ -561,7 +547,15 @@ impl Renderer {
device: &wgpu::Device, device: &wgpu::Device,
size: (u16, u16), size: (u16, u16),
mode: &RenderMode, mode: &RenderMode,
) -> Result<(wgpu::TextureView, wgpu::TextureView, wgpu::TextureView, wgpu::TextureView), RenderError> { ) -> Result<
(
wgpu::TextureView,
wgpu::TextureView,
wgpu::TextureView,
wgpu::TextureView,
),
RenderError,
> {
let upscaled = Vec2::from(size) let upscaled = Vec2::from(size)
.map(|e: u16| (e as f32 * mode.upscale_mode.factor) as u16) .map(|e: u16| (e as f32 * mode.upscale_mode.factor) as u16)
.into_tuple(); .into_tuple();
@ -654,7 +648,12 @@ impl Renderer {
array_layer_count: None, array_layer_count: None,
}); });
Ok((tgt_color_view, tgt_depth_stencil_view, tgt_color_pp_view, win_depth_view)) Ok((
tgt_color_view,
tgt_depth_stencil_view,
tgt_color_pp_view,
win_depth_view,
))
} }
/// Create textures and views for shadow maps. /// Create textures and views for shadow maps.
@ -677,9 +676,7 @@ impl Renderer {
// (Attempt to) apply resolution factor to shadow map resolution. // (Attempt to) apply resolution factor to shadow map resolution.
let resolution_factor = mode.resolution.clamped(0.25, 4.0); let resolution_factor = mode.resolution.clamped(0.25, 4.0);
// This value is temporary as there are plans to include a way to get this in let max_texture_size = Self::max_texture_size_raw(device);
// wgpu this is just a sane standard for now
let max_texture_size = 8000;
// Limit to max texture size, rather than erroring. // Limit to max texture size, rather than erroring.
let size = Vec2::new(size.0, size.1).map(|e| { let size = Vec2::new(size.0, size.1).map(|e| {
let size = f32::from(e) * resolution_factor; let size = f32::from(e) * resolution_factor;
@ -846,7 +843,7 @@ impl Renderer {
/// impact is relatively small, so there is no reason not to enable it where /// impact is relatively small, so there is no reason not to enable it where
/// available. /// available.
#[allow(unsafe_code)] #[allow(unsafe_code)]
fn enable_seamless_cube_maps(device: &mut gfx_backend::Device) { fn enable_seamless_cube_maps() {
todo!() todo!()
// unsafe { // unsafe {
// // NOTE: Currently just fail silently rather than complain if the // // NOTE: Currently just fail silently rather than complain if the
@ -970,7 +967,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 + gfx::traits::Pod>( pub fn create_consts<T: Copy + zerocopy::AsBytes>(
&mut self, &mut self,
vals: &[T], vals: &[T],
) -> Result<Consts<T>, RenderError> { ) -> Result<Consts<T>, RenderError> {
@ -980,7 +977,7 @@ 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 + gfx::traits::Pod>( pub fn update_consts<T: Copy + zerocopy::AsBytes>(
&mut self, &mut self,
consts: &mut Consts<T>, consts: &mut Consts<T>,
vals: &[T], vals: &[T],
@ -989,7 +986,7 @@ impl Renderer {
} }
/// 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 + gfx::traits::Pod>( pub fn create_instances<T: Copy + zerocopy::AsBytes>(
&mut self, &mut self,
vals: &[T], vals: &[T],
) -> Result<Instances<T>, RenderError> { ) -> Result<Instances<T>, RenderError> {
@ -999,23 +996,23 @@ impl Renderer {
} }
/// Create a new model from the provided mesh. /// Create a new model from the provided mesh.
pub fn create_model<P: Pipeline>(&mut self, mesh: &Mesh<P>) -> Result<Model<P>, RenderError> { pub fn create_model<V: Vertex>(&mut self, mesh: &Mesh<V>) -> Result<Model<V>, RenderError> {
Ok(Model::new(&mut self.factory, mesh)) Ok(Model::new(&mut self.factory, mesh))
} }
/// Create a new dynamic model with the specified size. /// Create a new dynamic model with the specified size.
pub fn create_dynamic_model<P: Pipeline>( pub fn create_dynamic_model<V: Vertex>(
&mut self, &mut self,
size: usize, size: usize,
) -> Result<DynamicModel<P>, RenderError> { ) -> Result<Model<V>, RenderError> {
DynamicModel::new(&mut self.factory, size) Model::new(&self.device, size)
} }
/// Update a dynamic model with a mesh and a offset. /// Update a dynamic model with a mesh and a offset.
pub fn update_model<P: Pipeline>( pub fn update_model<V: Vertex>(
&mut self, &mut self,
model: &DynamicModel<P>, model: &Model<V>,
mesh: &Mesh<P>, mesh: &Mesh<V>,
offset: usize, offset: usize,
) -> Result<(), RenderError> { ) -> Result<(), RenderError> {
model.update(&mut self.encoder, mesh, offset) model.update(&mut self.encoder, mesh, offset)
@ -1025,105 +1022,78 @@ impl Renderer {
pub fn max_texture_size(&self) -> u16 { Self::max_texture_size_raw(&self.factory) } pub fn max_texture_size(&self) -> u16 { Self::max_texture_size_raw(&self.factory) }
/// Return the maximum supported texture size from the factory. /// Return the maximum supported texture size from the factory.
fn max_texture_size_raw(factory: &gfx_backend::Factory) -> u16 { fn max_texture_size_raw(device: &wgpu::Device) -> u16 {
/// NOTE: OpenGL requirement. // This value is temporary as there are plans to include a way to get this in
const MAX_TEXTURE_SIZE_MIN: u16 = 1024; // wgpu this is just a sane standard for now
#[cfg(target_os = "macos")] 8192
/// NOTE: Because Macs lie about their max supported texture size.
const MAX_TEXTURE_SIZE_MAX: u16 = 8192;
#[cfg(not(target_os = "macos"))]
/// NOTE: Apparently Macs aren't the only machines that lie.
///
/// TODO: Find a way to let graphics cards that don't lie do better.
const MAX_TEXTURE_SIZE_MAX: u16 = 8192;
// NOTE: Many APIs for textures require coordinates to fit in u16, which is why
// we perform this conversion.
u16::try_from(factory.get_capabilities().max_texture_size)
.unwrap_or(MAX_TEXTURE_SIZE_MIN)
.min(MAX_TEXTURE_SIZE_MAX)
} }
/// Create a new immutable texture from the provided image. /// Create a new immutable texture from the provided image.
pub fn create_texture_immutable_raw<F: gfx::format::Formatted>( pub fn create_texture_with_data_raw(
&mut self, &mut self,
kind: gfx::texture::Kind, texture_info: wgpu::TextureDescriptor,
mipmap: gfx::texture::Mipmap, sampler_info: wgpu::SamplerDescriptor,
data: &[&[<F::Surface as gfx::format::SurfaceTyped>::DataType]], bytes_per_row: u32,
sampler_info: gfx::texture::SamplerInfo, size: [u16; 2],
) -> Result<Texture<F>, RenderError> data: &[u8],
where ) -> Texture {
F::Surface: gfx::format::TextureSurface, let tex = Texture::new_raw(&self.device, texture_info, sampler_info);
F::Channel: gfx::format::TextureChannel,
<F::Surface as gfx::format::SurfaceTyped>::DataType: Copy, tex.update(&self.device, &self.queue, [0; 2], size, data, bytes_per_row);
{
Texture::new_immutable_raw(&mut self.factory, kind, mipmap, data, sampler_info) tex
} }
/// Create a new raw texture. /// Create a new raw texture.
pub fn create_texture_raw<F: gfx::format::Formatted>( pub fn create_texture_raw(
&mut self, &mut self,
kind: gfx::texture::Kind, texture_info: wgpu::TextureDescriptor,
max_levels: u8, sampler_info: wgpu::SamplerDescriptor,
bind: gfx::memory::Bind, ) -> Texture {
usage: gfx::memory::Usage, Texture::new_raw(&self.device, texture_info, sampler_info)
levels: (u8, u8),
swizzle: gfx::format::Swizzle,
sampler_info: gfx::texture::SamplerInfo,
) -> Result<Texture<F>, RenderError>
where
F::Surface: gfx::format::TextureSurface,
F::Channel: gfx::format::TextureChannel,
<F::Surface as gfx::format::SurfaceTyped>::DataType: Copy,
{
Texture::new_raw(
&mut self.device,
&mut self.factory,
kind,
max_levels,
bind,
usage,
levels,
swizzle,
sampler_info,
)
} }
/// Create a new texture from the provided image. /// Create a new texture from the provided image.
pub fn create_texture<F: gfx::format::Formatted>( pub fn create_texture(
&mut self, &mut self,
image: &image::DynamicImage, image: &image::DynamicImage,
filter_method: Option<FilterMethod>, filter_method: Option<FilterMode>,
wrap_mode: Option<WrapMode>, addresse_mode: Option<AddressMode>,
border: Option<gfx::texture::PackedColor>, ) -> Texture {
) -> Result<Texture<F>, RenderError> Texture::new(
where &self.device,
F::Surface: gfx::format::TextureSurface, &self.queue,
F::Channel: gfx::format::TextureChannel, image,
<F::Surface as gfx::format::SurfaceTyped>::DataType: Copy, filter_method,
{ addresse_mode,
Texture::new(&mut self.factory, image, filter_method, wrap_mode, border) )
} }
/// Create a new dynamic texture (gfx::memory::Usage::Dynamic) with the /// Create a new dynamic texture (gfx::memory::Usage::Dynamic) with the
/// specified dimensions. /// specified dimensions.
pub fn create_dynamic_texture(&mut self, dims: Vec2<u16>) -> Result<Texture, RenderError> { pub fn create_dynamic_texture(&mut self, dims: Vec2<u16>) -> Texture {
Texture::new_dynamic(&mut self.factory, dims.x, dims.y) Texture::new_dynamic(&mut self.factory, dims.x, dims.y)
} }
/// Update a texture with the provided offset, size, and data. /// Update a texture with the provided offset, size, and data.
pub fn update_texture<T: gfx::format::Formatted>( pub fn update_texture(
&mut self, &mut self,
texture: &Texture<T>, texture: &Texture, /* <T> */
offset: [u16; 2], offset: [u16; 2],
size: [u16; 2], size: [u16; 2],
data: &[<<T as gfx::format::Formatted>::Surface as gfx::format::SurfaceTyped>::DataType], // TODO
) -> Result<(), RenderError> // data: &[<<T as gfx::format::Formatted>::Surface as
where // gfx::format::SurfaceTyped>::DataType], ) -> Result<(), RenderError>
<T as gfx::format::Formatted>::Surface: gfx::format::TextureSurface, // where
<T as gfx::format::Formatted>::Channel: gfx::format::TextureChannel, // <T as gfx::format::Formatted>::Surface: gfx::format::TextureSurface,
<<T as gfx::format::Formatted>::Surface as gfx::format::SurfaceTyped>::DataType: Copy, // <T as gfx::format::Formatted>::Channel: gfx::format::TextureChannel,
{ // <<T as gfx::format::Formatted>::Surface as gfx::format::SurfaceTyped>::DataType:
texture.update(&mut self.encoder, offset, size, data) // Copy, {
// texture.update(&mut self.encoder, offset, size, data)
data: &[[u8; 4]],
bytes_per_row: u32,
) {
texture.update(&mut self.encoder, offset, size, data, bytes_per_row)
} }
/// Creates a download buffer, downloads the win_color_view, and converts to /// Creates a download buffer, downloads the win_color_view, and converts to
@ -1894,10 +1864,6 @@ impl Renderer {
} }
} }
struct GfxPipeline<P: gfx::pso::PipelineInit> {
pso: gfx::pso::PipelineState<gfx_backend::Resources, P::Meta>,
}
/// Creates all the pipelines used to render. /// Creates all the pipelines used to render.
#[allow(clippy::type_complexity)] // TODO: Pending review in #587 #[allow(clippy::type_complexity)] // TODO: Pending review in #587
fn create_pipelines( fn create_pipelines(
@ -1907,20 +1873,20 @@ fn create_pipelines(
has_shadow_views: bool, has_shadow_views: bool,
) -> Result< ) -> Result<
( (
GfxPipeline<skybox::pipe::Init<'static>>, wgpu::RenderPipeline,
GfxPipeline<figure::pipe::Init<'static>>, wgpu::RenderPipeline,
GfxPipeline<terrain::pipe::Init<'static>>, wgpu::RenderPipeline,
GfxPipeline<fluid::pipe::Init<'static>>, wgpu::RenderPipeline,
GfxPipeline<sprite::pipe::Init<'static>>, wgpu::RenderPipeline,
GfxPipeline<particle::pipe::Init<'static>>, wgpu::RenderPipeline,
GfxPipeline<ui::pipe::Init<'static>>, wgpu::RenderPipeline,
GfxPipeline<lod_terrain::pipe::Init<'static>>, wgpu::RenderPipeline,
GfxPipeline<clouds::pipe::Init<'static>>, wgpu::RenderPipeline,
GfxPipeline<postprocess::pipe::Init<'static>>, wgpu::RenderPipeline,
GfxPipeline<figure::pipe::Init<'static>>, wgpu::RenderPipeline,
Option<GfxPipeline<shadow::pipe::Init<'static>>>, Option<wgpu::RenderPipeline>,
Option<GfxPipeline<shadow::pipe::Init<'static>>>, Option<wgpu::RenderPipeline>,
Option<GfxPipeline<shadow::figure_pipe::Init<'static>>>, Option<wgpu::RenderPipeline>,
), ),
RenderError, RenderError,
> { > {

View File

@ -1,7 +1,6 @@
use super::RenderError; use super::RenderError;
use image::{DynamicImage, GenericImageView}; use image::{DynamicImage, GenericImageView};
use vek::Vec2; use wgpu::Extent3d;
use wgpu::{util::DeviceExt, Extent3d};
/// Represents an image that has been uploaded to the GPU. /// Represents an image that has been uploaded to the GPU.
pub struct Texture { pub struct Texture {
@ -133,6 +132,7 @@ impl Texture {
offset: [u16; 2], offset: [u16; 2],
size: [u16; 2], size: [u16; 2],
data: &[u8], data: &[u8],
bytes_per_row: u32,
) -> Result<(), RenderError> { ) -> Result<(), RenderError> {
// TODO: Only works for 2D images // TODO: Only works for 2D images
queue.write_texture( queue.write_texture(
@ -150,7 +150,7 @@ impl Texture {
// formats that are not Rgba8 // formats that are not Rgba8
wgpu::TextureDataLayout { wgpu::TextureDataLayout {
offset: 0, offset: 0,
bytes_per_row: self.size.x * 4, bytes_per_row,
rows_per_image: self.size.y, rows_per_image: self.size.y,
}, },
wgpu::Extent3d { wgpu::Extent3d {