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 zerocopy::AsBytes;
@ -45,7 +44,9 @@ impl<T: Copy + AsBytes> Buffer<T> {
vals: &[T],
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 }

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
/// renderer.
pub fn submodel(&self, vertex_range: Range<u32>) -> SubModel<V> {

View File

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

View File

@ -1,44 +1,48 @@
use super::{
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 super::super::TerrainLocals;
use vek::*;
use zerocopy::AsBytes;
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))),
}
#[repr(C)]
#[derive(Copy, Clone, Debug, AsBytes)]
struct Vertex {
pos_norm: u32,
}
// 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 {
#[allow(clippy::identity_op)] // 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,
};
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 zerocopy::AsBytes;
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))),
}
#[repr(C)]
#[derive(Copy, Clone, Debug, AsBytes)]
struct Vertex {
pos: [f32; 2],
}
// 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 {
pub fn new(pos: Vec2<f32>) -> 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 map: Texture<LodColorFmt>,
pub alt: Texture<LodAltFmt>,

View File

@ -13,53 +13,58 @@ pub mod ui;
use super::Consts;
use crate::scene::camera::CameraMode;
use common::terrain::BlockKind;
use gfx::{self, gfx_constant_struct_meta, gfx_defines, gfx_impl_struct_meta};
use vek::*;
use zerocopy::AsBytes;
pub const MAX_POINT_LIGHT_COUNT: usize = 31;
pub const MAX_FIGURE_SHADOW_COUNT: usize = 24;
pub const MAX_DIRECTED_LIGHT_COUNT: usize = 6;
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",
}
#[repr(C)]
#[derive(Copy, Clone, Debug, AsBytes)]
pub struct Globals {
view_mat: [[f32; 4]; 4],
proj_mat: [[f32; 4]; 4],
all_mat: [[f32; 4]; 4],
cam_pos: [f32; 4],
focus_off: [f32; 4],
focus_pos: [f32; 4],
/// 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],
time_of_day: [f32; 4], // TODO: Make this f64.
sun_dir: [f32; 4],
moon_dir: [f32; 4],
tick: [f32; 4],
/// x, y represent the resolution of the screen;
/// w, z represent the near and far planes of the shadow map.
screen_res: [f32; 4],
light_shadow_count: [u32; 4],
shadow_proj_factors: [f32; 4],
medium: [u32; 4],
select_pos: [i32; 4],
gamma_exposure: [f32; 4],
ambiance: f32,
cam_mode: u32,
sprite_render_distance: f32,
}
constant Light {
pos: [f32; 4] = "light_pos",
col: [f32; 4] = "light_col",
}
#[repr(C)]
#[derive(Copy, Clone, Debug, AsBytes)]
pub struct Light {
pos: [f32; 4],
col: [f32; 4],
}
constant Shadow {
pos_radius: [f32; 4] = "shadow_pos_radius",
}
#[repr(C)]
#[derive(Copy, Clone, Debug, AsBytes)]
pub struct Shadow {
pos_radius: [f32; 4],
}
impl Globals {
@ -219,3 +224,35 @@ pub struct GlobalModel {
pub shadows: Consts<Shadow>,
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,
instances::Instances,
mesh::Mesh,
model::{Model},
model::Model,
pipelines::{
clouds, figure, fluid, lod_terrain, particle, postprocess, shadow, skybox, sprite, terrain,
ui, GlobalModel, Globals,
},
texture::Texture,
AaMode, CloudMode, FilterMode, FluidMode, LightingMode, RenderError, RenderMode,
ShadowMapMode, ShadowMode, AddressMode,
AaMode, AddressMode, CloudMode, FilterMode, FluidMode, LightingMode, RenderError, RenderMode,
ShadowMapMode, ShadowMode, Vertex,
};
use common::assets::{self, AssetExt, AssetHandle};
use common_base::span;
@ -18,76 +18,78 @@ use glsl_include::Context as IncludeContext;
use tracing::{error, info, warn};
use vek::*;
/// Represents the format of the pre-processed color target.
// TODO: `(gfx::format::R11_G11_B10, gfx::format::Float)` would be better in
// theory, but it doesn't seem to work
pub type TgtColorFmt = gfx::format::Rgba16F;
/// Represents the format of the pre-processed depth and stencil target.
pub type TgtDepthStencilFmt = gfx::format::Depth;
/// Represents the format of the window's color target.
pub type WinColorFmt = gfx::format::Srgba8;
/// Represents the format of the window's depth target.
pub type WinDepthFmt = gfx::format::Depth;
/// Represents the format of the pre-processed shadow depth target.
pub type ShadowDepthStencilFmt = gfx::format::Depth;
/// A handle to a pre-processed color target.
pub type TgtColorView = gfx::handle::RenderTargetView<gfx_backend::Resources, TgtColorFmt>;
/// A handle to a pre-processed depth target.
pub type TgtDepthStencilView =
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 depth target.
pub type WinDepthView = gfx::handle::DepthStencilView<gfx_backend::Resources, WinDepthFmt>;
/// Represents the format of LOD shadows.
pub type LodTextureFmt = (gfx::format::R8_G8_B8_A8, gfx::format::Unorm);
/// Represents the format of LOD altitudes.
pub type LodAltFmt = (gfx::format::R16_G16, gfx::format::Unorm);
/// Represents the format of LOD map colors.
pub type LodColorFmt = (gfx::format::R8_G8_B8_A8, gfx::format::Srgb);
/// Represents the format of greedy meshed color-light textures.
pub type ColLightFmt = (gfx::format::R8_G8_B8_A8, gfx::format::Unorm);
/// A handle to a shadow depth target.
pub type ShadowDepthStencilView =
gfx::handle::DepthStencilView<gfx_backend::Resources, ShadowDepthStencilFmt>;
/// A handle to a shadow depth target as a resource.
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,
<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,
<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,
<ColLightFmt as gfx::format::Formatted>::View,
>;
/// A type representing data that can be converted to an immutable texture map
/// of ColLight data (used for texture atlases created during greedy meshing).
pub type ColLightInfo = (
Vec<<<ColLightFmt as gfx::format::Formatted>::Surface as gfx::format::SurfaceTyped>::DataType>,
Vec2<u16>,
);
// /// Represents the format of the pre-processed color target.
// // TODO: `(gfx::format::R11_G11_B10, gfx::format::Float)` would be better in
// // theory, but it doesn't seem to work
// pub type TgtColorFmt = gfx::format::Rgba16F;
// /// Represents the format of the pre-processed depth and stencil target.
// pub type TgtDepthStencilFmt = gfx::format::Depth;
//
// /// Represents the format of the window's color target.
// pub type WinColorFmt = gfx::format::Srgba8;
// /// Represents the format of the window's depth target.
// pub type WinDepthFmt = gfx::format::Depth;
//
// /// Represents the format of the pre-processed shadow depth target.
// pub type ShadowDepthStencilFmt = gfx::format::Depth;
//
// /// A handle to a pre-processed color target.
// pub type TgtColorView = gfx::handle::RenderTargetView<gfx_backend::Resources,
// TgtColorFmt>; /// A handle to a pre-processed depth target.
// pub type TgtDepthStencilView =
// 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 depth target.
// pub type WinDepthView = gfx::handle::DepthStencilView<gfx_backend::Resources,
// WinDepthFmt>;
//
// /// Represents the format of LOD shadows.
// pub type LodTextureFmt = (gfx::format::R8_G8_B8_A8, gfx::format::Unorm);
//
// /// Represents the format of LOD altitudes.
// pub type LodAltFmt = (gfx::format::R16_G16, gfx::format::Unorm);
//
// /// Represents the format of LOD map colors.
// pub type LodColorFmt = (gfx::format::R8_G8_B8_A8, gfx::format::Srgb);
//
// /// Represents the format of greedy meshed color-light textures.
// pub type ColLightFmt = (gfx::format::R8_G8_B8_A8, gfx::format::Unorm);
//
// /// A handle to a shadow depth target.
// pub type ShadowDepthStencilView =
// gfx::handle::DepthStencilView<gfx_backend::Resources,
// ShadowDepthStencilFmt>; /// A handle to a shadow depth target as a resource.
// 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,
// <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,
// <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,
// <ColLightFmt as gfx::format::Formatted>::View,
// >;
// /// A type representing data that can be converted to an immutable texture
// map /// of ColLight data (used for texture atlases created during greedy
// meshing). pub type ColLightInfo = (
// Vec<<<ColLightFmt as gfx::format::Formatted>::Surface as
// gfx::format::SurfaceTyped>::DataType>, Vec2<u16>,
// );
/// Load from a GLSL file.
pub struct Glsl(String);
@ -224,9 +226,9 @@ pub struct ShadowMapRenderer {
point_depth_stencil_view: wgpu::TextureView,
point_sampler: wgpu::Sampler,
point_pipeline: GfxPipeline<shadow::pipe::Init<'static>>,
terrain_directed_pipeline: GfxPipeline<shadow::pipe::Init<'static>>,
figure_directed_pipeline: GfxPipeline<shadow::figure_pipe::Init<'static>>,
point_pipeline: wgpu::RenderPipeline,
terrain_directed_pipeline: wgpu::RenderPipeline,
figure_directed_pipeline: wgpu::RenderPipeline,
}
/// A type that encapsulates rendering state. `Renderer` is central to Voxygen's
@ -237,6 +239,7 @@ pub struct Renderer {
device: wgpu::Device,
queue: wgpu::Queue,
swap_chain: wgpu::SwapChain,
sc_desc: wgpu::SwapChainDescriptor,
win_depth_view: wgpu::TextureView,
@ -249,22 +252,22 @@ pub struct Renderer {
shadow_map: Option<ShadowMapRenderer>,
skybox_pipeline: GfxPipeline<skybox::pipe::Init<'static>>,
figure_pipeline: GfxPipeline<figure::pipe::Init<'static>>,
terrain_pipeline: GfxPipeline<terrain::pipe::Init<'static>>,
fluid_pipeline: GfxPipeline<fluid::pipe::Init<'static>>,
sprite_pipeline: GfxPipeline<sprite::pipe::Init<'static>>,
particle_pipeline: GfxPipeline<particle::pipe::Init<'static>>,
ui_pipeline: GfxPipeline<ui::pipe::Init<'static>>,
lod_terrain_pipeline: GfxPipeline<lod_terrain::pipe::Init<'static>>,
clouds_pipeline: GfxPipeline<clouds::pipe::Init<'static>>,
postprocess_pipeline: GfxPipeline<postprocess::pipe::Init<'static>>,
skybox_pipeline: wgpu::RenderPipeline,
figure_pipeline: wgpu::RenderPipeline,
terrain_pipeline: wgpu::RenderPipeline,
fluid_pipeline: wgpu::RenderPipeline,
sprite_pipeline: wgpu::RenderPipeline,
particle_pipeline: wgpu::RenderPipeline,
ui_pipeline: wgpu::RenderPipeline,
lod_terrain_pipeline: wgpu::RenderPipeline,
clouds_pipeline: wgpu::RenderPipeline,
postprocess_pipeline: wgpu::RenderPipeline,
#[allow(dead_code)] //TODO: remove ?
player_shadow_pipeline: GfxPipeline<figure::pipe::Init<'static>>,
player_shadow_pipeline: wgpu::RenderPipeline,
shaders: AssetHandle<Shaders>,
noise_tex: Texture<(gfx::format::R8, gfx::format::Unorm)>,
noise_tex: Texture,
mode: RenderMode,
}
@ -324,13 +327,15 @@ impl Renderer {
"selected graphics device"
);
let swap_chain = device.create_swap_chain(&surface, &wgpu::SwapChainDescriptor {
let sc_desc = wgpu::SwapChainDescriptor {
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
format: wgpu::TextureFormat::Bgra8UnormSrgb,
width: dims.0,
height: dims.1,
present_mode: wgpu::PresentMode::Immediate,
});
};
let swap_chain = device.create_swap_chain(&surface, &sc_desc);
let shadow_views = Self::create_shadow_views(
&device,
@ -365,12 +370,8 @@ impl Renderer {
shadow_views.is_some(),
)?;
let (
tgt_color_view,
tgt_depth_stencil_view,
tgt_color_pp_view,
win_depth_view,
) = Self::create_rt_views(&device, (dims.0, dims.1), &mode)?;
let (tgt_color_view, 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 (
Some(point_pipeline),
@ -432,6 +433,7 @@ impl Renderer {
device,
queue,
swap_chain,
sc_desc,
win_depth_view,
@ -466,30 +468,14 @@ impl Renderer {
/// Get references to the internal render target views that get rendered to
/// before post-processing.
#[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)
}
/// Get references to the internal render target views that get displayed
/// directly by the window.
#[allow(dead_code)]
pub fn win_views(&self) -> (&WinColorView, &WinDepthView) {
(&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)
}
pub fn win_views(&self) -> &wgpu::TextureView { &self.win_depth_view }
/// Change the render mode.
pub fn set_render_mode(&mut self, mode: RenderMode) -> Result<(), RenderError> {
@ -561,7 +547,15 @@ impl Renderer {
device: &wgpu::Device,
size: (u16, u16),
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)
.map(|e: u16| (e as f32 * mode.upscale_mode.factor) as u16)
.into_tuple();
@ -654,7 +648,12 @@ impl Renderer {
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.
@ -677,9 +676,7 @@ impl Renderer {
// (Attempt to) apply resolution factor to shadow map resolution.
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
// wgpu this is just a sane standard for now
let max_texture_size = 8000;
let max_texture_size = Self::max_texture_size_raw(device);
// Limit to max texture size, rather than erroring.
let size = Vec2::new(size.0, size.1).map(|e| {
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
/// available.
#[allow(unsafe_code)]
fn enable_seamless_cube_maps(device: &mut gfx_backend::Device) {
fn enable_seamless_cube_maps() {
todo!()
// unsafe {
// // 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.
pub fn create_consts<T: Copy + gfx::traits::Pod>(
pub fn create_consts<T: Copy + zerocopy::AsBytes>(
&mut self,
vals: &[T],
) -> Result<Consts<T>, RenderError> {
@ -980,7 +977,7 @@ impl Renderer {
}
/// 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,
consts: &mut Consts<T>,
vals: &[T],
@ -989,7 +986,7 @@ impl Renderer {
}
/// 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,
vals: &[T],
) -> Result<Instances<T>, RenderError> {
@ -999,23 +996,23 @@ impl Renderer {
}
/// 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))
}
/// 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,
size: usize,
) -> Result<DynamicModel<P>, RenderError> {
DynamicModel::new(&mut self.factory, size)
) -> Result<Model<V>, RenderError> {
Model::new(&self.device, size)
}
/// Update a dynamic model with a mesh and a offset.
pub fn update_model<P: Pipeline>(
pub fn update_model<V: Vertex>(
&mut self,
model: &DynamicModel<P>,
mesh: &Mesh<P>,
model: &Model<V>,
mesh: &Mesh<V>,
offset: usize,
) -> Result<(), RenderError> {
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) }
/// Return the maximum supported texture size from the factory.
fn max_texture_size_raw(factory: &gfx_backend::Factory) -> u16 {
/// NOTE: OpenGL requirement.
const MAX_TEXTURE_SIZE_MIN: u16 = 1024;
#[cfg(target_os = "macos")]
/// 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)
fn max_texture_size_raw(device: &wgpu::Device) -> u16 {
// This value is temporary as there are plans to include a way to get this in
// wgpu this is just a sane standard for now
8192
}
/// 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,
kind: gfx::texture::Kind,
mipmap: gfx::texture::Mipmap,
data: &[&[<F::Surface as gfx::format::SurfaceTyped>::DataType]],
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_immutable_raw(&mut self.factory, kind, mipmap, data, sampler_info)
texture_info: wgpu::TextureDescriptor,
sampler_info: wgpu::SamplerDescriptor,
bytes_per_row: u32,
size: [u16; 2],
data: &[u8],
) -> Texture {
let tex = Texture::new_raw(&self.device, texture_info, sampler_info);
tex.update(&self.device, &self.queue, [0; 2], size, data, bytes_per_row);
tex
}
/// Create a new raw texture.
pub fn create_texture_raw<F: gfx::format::Formatted>(
pub fn create_texture_raw(
&mut self,
kind: gfx::texture::Kind,
max_levels: u8,
bind: gfx::memory::Bind,
usage: gfx::memory::Usage,
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,
)
texture_info: wgpu::TextureDescriptor,
sampler_info: wgpu::SamplerDescriptor,
) -> Texture {
Texture::new_raw(&self.device, texture_info, sampler_info)
}
/// Create a new texture from the provided image.
pub fn create_texture<F: gfx::format::Formatted>(
pub fn create_texture(
&mut self,
image: &image::DynamicImage,
filter_method: Option<FilterMethod>,
wrap_mode: Option<WrapMode>,
border: Option<gfx::texture::PackedColor>,
) -> 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(&mut self.factory, image, filter_method, wrap_mode, border)
filter_method: Option<FilterMode>,
addresse_mode: Option<AddressMode>,
) -> Texture {
Texture::new(
&self.device,
&self.queue,
image,
filter_method,
addresse_mode,
)
}
/// Create a new dynamic texture (gfx::memory::Usage::Dynamic) with the
/// 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)
}
/// Update a texture with the provided offset, size, and data.
pub fn update_texture<T: gfx::format::Formatted>(
pub fn update_texture(
&mut self,
texture: &Texture<T>,
texture: &Texture, /* <T> */
offset: [u16; 2],
size: [u16; 2],
data: &[<<T as gfx::format::Formatted>::Surface as gfx::format::SurfaceTyped>::DataType],
) -> Result<(), RenderError>
where
<T as gfx::format::Formatted>::Surface: gfx::format::TextureSurface,
<T as gfx::format::Formatted>::Channel: gfx::format::TextureChannel,
<<T as gfx::format::Formatted>::Surface as gfx::format::SurfaceTyped>::DataType: Copy,
{
texture.update(&mut self.encoder, offset, size, data)
// TODO
// data: &[<<T as gfx::format::Formatted>::Surface as
// gfx::format::SurfaceTyped>::DataType], ) -> Result<(), RenderError>
// where
// <T as gfx::format::Formatted>::Surface: gfx::format::TextureSurface,
// <T as gfx::format::Formatted>::Channel: gfx::format::TextureChannel,
// <<T as gfx::format::Formatted>::Surface as gfx::format::SurfaceTyped>::DataType:
// 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
@ -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.
#[allow(clippy::type_complexity)] // TODO: Pending review in #587
fn create_pipelines(
@ -1907,20 +1873,20 @@ fn create_pipelines(
has_shadow_views: bool,
) -> Result<
(
GfxPipeline<skybox::pipe::Init<'static>>,
GfxPipeline<figure::pipe::Init<'static>>,
GfxPipeline<terrain::pipe::Init<'static>>,
GfxPipeline<fluid::pipe::Init<'static>>,
GfxPipeline<sprite::pipe::Init<'static>>,
GfxPipeline<particle::pipe::Init<'static>>,
GfxPipeline<ui::pipe::Init<'static>>,
GfxPipeline<lod_terrain::pipe::Init<'static>>,
GfxPipeline<clouds::pipe::Init<'static>>,
GfxPipeline<postprocess::pipe::Init<'static>>,
GfxPipeline<figure::pipe::Init<'static>>,
Option<GfxPipeline<shadow::pipe::Init<'static>>>,
Option<GfxPipeline<shadow::pipe::Init<'static>>>,
Option<GfxPipeline<shadow::figure_pipe::Init<'static>>>,
wgpu::RenderPipeline,
wgpu::RenderPipeline,
wgpu::RenderPipeline,
wgpu::RenderPipeline,
wgpu::RenderPipeline,
wgpu::RenderPipeline,
wgpu::RenderPipeline,
wgpu::RenderPipeline,
wgpu::RenderPipeline,
wgpu::RenderPipeline,
wgpu::RenderPipeline,
Option<wgpu::RenderPipeline>,
Option<wgpu::RenderPipeline>,
Option<wgpu::RenderPipeline>,
),
RenderError,
> {

View File

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