mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Render Ui
This commit is contained in:
parent
9f399f9076
commit
617ae80d02
@ -11,9 +11,9 @@ uniform u_locals {
|
|||||||
vec4 w_pos;
|
vec4 w_pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
layout(set = 1, binding = 1)
|
layout(set = 2, binding = 0)
|
||||||
uniform texture2D t_tex;
|
uniform texture2D t_tex;
|
||||||
layout(set = 1, binding = 2)
|
layout(set = 2, binding = 1)
|
||||||
uniform sampler s_tex;
|
uniform sampler s_tex;
|
||||||
|
|
||||||
layout(location = 0) out vec4 tgt_color;
|
layout(location = 0) out vec4 tgt_color;
|
||||||
|
@ -13,9 +13,9 @@ uniform u_locals {
|
|||||||
vec4 w_pos;
|
vec4 w_pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
layout(set = 1, binding = 1)
|
layout(set = 2, binding = 0)
|
||||||
uniform texture2D t_tex;
|
uniform texture2D t_tex;
|
||||||
layout(set = 1, binding = 2)
|
layout(set = 2, binding = 1)
|
||||||
uniform sampler s_tex;
|
uniform sampler s_tex;
|
||||||
|
|
||||||
layout(location = 0) out vec2 f_uv;
|
layout(location = 0) out vec2 f_uv;
|
||||||
@ -33,10 +33,10 @@ void main() {
|
|||||||
f_uv = v_uv;
|
f_uv = v_uv;
|
||||||
// Fixed scale In-game element
|
// Fixed scale In-game element
|
||||||
vec4 projected_pos = /*proj_mat * view_mat*/all_mat * vec4(w_pos.xyz - focus_off.xyz, 1.0);
|
vec4 projected_pos = /*proj_mat * view_mat*/all_mat * vec4(w_pos.xyz - focus_off.xyz, 1.0);
|
||||||
gl_Position = vec4(projected_pos.xy / projected_pos.w + v_pos/* * projected_pos.w*/, -1.0, /*projected_pos.w*/1.0);
|
gl_Position = vec4(projected_pos.xy / projected_pos.w + v_pos/* * projected_pos.w*/, 0.0, /*projected_pos.w*/1.0);
|
||||||
} else if (v_mode == uint(3)) {
|
} else if (v_mode == uint(3)) {
|
||||||
// HACK: North facing source rectangle.
|
// HACK: North facing source rectangle.
|
||||||
gl_Position = vec4(v_pos, -1.0, 1.0);
|
gl_Position = vec4(v_pos, 0.0, 1.0);
|
||||||
vec2 look_at_dir = normalize(vec2(-view_mat[0][2], -view_mat[1][2]));
|
vec2 look_at_dir = normalize(vec2(-view_mat[0][2], -view_mat[1][2]));
|
||||||
// TODO: Consider cleaning up matrix to something more efficient (e.g. a mat3).
|
// TODO: Consider cleaning up matrix to something more efficient (e.g. a mat3).
|
||||||
vec2 aspect_ratio = textureSize(sampler2D(t_tex, s_tex), 0).yx;
|
vec2 aspect_ratio = textureSize(sampler2D(t_tex, s_tex), 0).yx;
|
||||||
@ -53,11 +53,11 @@ void main() {
|
|||||||
mat2 look_at = mat2(look_at_dir.y, -look_at_dir.x, look_at_dir.x, look_at_dir.y);
|
mat2 look_at = mat2(look_at_dir.y, -look_at_dir.x, look_at_dir.x, look_at_dir.y);
|
||||||
vec2 v_centered = (v_pos - v_center) / aspect_ratio;
|
vec2 v_centered = (v_pos - v_center) / aspect_ratio;
|
||||||
vec2 v_rotated = look_at * v_centered;
|
vec2 v_rotated = look_at * v_centered;
|
||||||
gl_Position = vec4(aspect_ratio * v_rotated + v_center, -1.0, 1.0);
|
gl_Position = vec4(aspect_ratio * v_rotated + v_center, 0.0, 1.0);
|
||||||
} else {
|
} else {
|
||||||
// Interface element
|
// Interface element
|
||||||
f_uv = v_uv;
|
f_uv = v_uv;
|
||||||
gl_Position = vec4(v_pos, -1.0, 1.0);
|
gl_Position = vec4(v_pos, 0.0, 1.0);
|
||||||
}
|
}
|
||||||
f_mode = v_mode;
|
f_mode = v_mode;
|
||||||
}
|
}
|
||||||
|
@ -1584,7 +1584,8 @@ impl CharSelectionUi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: do we need globals?
|
// TODO: do we need globals?
|
||||||
pub fn render(&self, renderer: &mut Renderer) { self.ui.render(renderer); }
|
pub fn render(&self, renderer: &mut Renderer) { /* self.ui.render(renderer);*/
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
mod client_init;
|
mod client_init;
|
||||||
|
mod scene;
|
||||||
mod ui;
|
mod ui;
|
||||||
|
|
||||||
use super::char_selection::CharSelectionState;
|
use super::char_selection::CharSelectionState;
|
||||||
@ -20,6 +21,7 @@ use client::{
|
|||||||
use client_init::{ClientConnArgs, ClientInit, Error as InitError, Msg as InitMsg};
|
use client_init::{ClientConnArgs, ClientInit, Error as InitError, Msg as InitMsg};
|
||||||
use common::comp;
|
use common::comp;
|
||||||
use common_base::span;
|
use common_base::span;
|
||||||
|
use scene::Scene;
|
||||||
use std::{fmt::Debug, sync::Arc};
|
use std::{fmt::Debug, sync::Arc};
|
||||||
use tokio::runtime;
|
use tokio::runtime;
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
@ -29,6 +31,7 @@ pub struct MainMenuState {
|
|||||||
main_menu_ui: MainMenuUi,
|
main_menu_ui: MainMenuUi,
|
||||||
// Used for client creation.
|
// Used for client creation.
|
||||||
client_init: Option<ClientInit>,
|
client_init: Option<ClientInit>,
|
||||||
|
scene: Scene,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MainMenuState {
|
impl MainMenuState {
|
||||||
@ -37,6 +40,7 @@ impl MainMenuState {
|
|||||||
Self {
|
Self {
|
||||||
main_menu_ui: MainMenuUi::new(global_state),
|
main_menu_ui: MainMenuUi::new(global_state),
|
||||||
client_init: None,
|
client_init: None,
|
||||||
|
scene: Scene::new(global_state.window.renderer_mut()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -342,8 +346,18 @@ impl PlayState for MainMenuState {
|
|||||||
fn name(&self) -> &'static str { "Title" }
|
fn name(&self) -> &'static str { "Title" }
|
||||||
|
|
||||||
fn render(&mut self, renderer: &mut Renderer, _: &Settings) {
|
fn render(&mut self, renderer: &mut Renderer, _: &Settings) {
|
||||||
|
// TODO: maybe the drawer should be passed in from above?
|
||||||
|
let mut drawer = match renderer
|
||||||
|
.start_recording_frame(self.scene.global_bind_group())
|
||||||
|
.unwrap()
|
||||||
|
{
|
||||||
|
Some(d) => d,
|
||||||
|
// Couldn't get swap chain texture this fime
|
||||||
|
None => return,
|
||||||
|
};
|
||||||
|
|
||||||
// Draw the UI to the screen.
|
// Draw the UI to the screen.
|
||||||
self.main_menu_ui.render(renderer);
|
self.main_menu_ui.render(&mut drawer.third_pass().draw_ui());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
28
voxygen/src/menu/main/scene.rs
Normal file
28
voxygen/src/menu/main/scene.rs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
use crate::render::{
|
||||||
|
GlobalModel, Globals, GlobalsBindGroup, Light, LodData, Renderer, Shadow, ShadowLocals,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct Scene {
|
||||||
|
// global_data: GlobalModel,
|
||||||
|
// lod_data: LodData,
|
||||||
|
bind_group: GlobalsBindGroup,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Scene {
|
||||||
|
pub fn new(renderer: &mut Renderer) -> Self {
|
||||||
|
let global_data = GlobalModel {
|
||||||
|
globals: renderer.create_consts(&[Globals::default()]),
|
||||||
|
lights: renderer.create_consts(&[Light::default(); 32]),
|
||||||
|
shadows: renderer.create_consts(&[Shadow::default(); 32]),
|
||||||
|
shadow_mats: renderer.create_consts(&[ShadowLocals::default(); 6]),
|
||||||
|
};
|
||||||
|
|
||||||
|
let lod_data = LodData::dummy(renderer);
|
||||||
|
|
||||||
|
let bind_group = renderer.bind_globals(&global_data, &lod_data);
|
||||||
|
|
||||||
|
Self { bind_group }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn global_bind_group(&self) -> &GlobalsBindGroup { &self.bind_group }
|
||||||
|
}
|
@ -6,7 +6,7 @@ mod servers;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
i18n::{LanguageMetadata, LocalizationHandle},
|
i18n::{LanguageMetadata, LocalizationHandle},
|
||||||
render::Renderer,
|
render::UiDrawer,
|
||||||
ui::{
|
ui::{
|
||||||
self,
|
self,
|
||||||
fonts::IcedFonts as Fonts,
|
fonts::IcedFonts as Fonts,
|
||||||
@ -477,7 +477,7 @@ pub struct MainMenuUi {
|
|||||||
controls: Controls,
|
controls: Controls,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> MainMenuUi {
|
impl MainMenuUi {
|
||||||
pub fn new(global_state: &mut GlobalState) -> Self {
|
pub fn new(global_state: &mut GlobalState) -> Self {
|
||||||
// Load language
|
// Load language
|
||||||
let i18n = &global_state.i18n.read();
|
let i18n = &global_state.i18n.read();
|
||||||
@ -582,5 +582,5 @@ impl<'a> MainMenuUi {
|
|||||||
events
|
events
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render(&self, renderer: &mut Renderer) { self.ui.render(renderer); }
|
pub fn render<'a>(&'a self, drawer: &mut UiDrawer<'_, 'a>) { self.ui.render(drawer); }
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ use bytemuck::Pod;
|
|||||||
use wgpu::util::DeviceExt;
|
use wgpu::util::DeviceExt;
|
||||||
|
|
||||||
pub struct Buffer<T: Copy + Pod> {
|
pub struct Buffer<T: Copy + Pod> {
|
||||||
pub buf: wgpu::Buffer,
|
pub(super) buf: wgpu::Buffer,
|
||||||
// Size in number of elements
|
// Size in number of elements
|
||||||
// TODO: determine if this is a good name
|
// TODO: determine if this is a good name
|
||||||
len: usize,
|
len: usize,
|
||||||
|
@ -37,11 +37,12 @@ pub use self::{
|
|||||||
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, Vertex as UiVertex,
|
Locals as UiLocals, LocalsBindGroup as UiLocalsBindGroup, Mode as UiMode,
|
||||||
|
TextureBindGroup as UiTextureBindGroup, Vertex as UiVertex,
|
||||||
},
|
},
|
||||||
GlobalModel, Globals, GlobalsLayouts, Light, Shadow,
|
GlobalModel, Globals, GlobalsBindGroup, GlobalsLayouts, Light, Shadow,
|
||||||
},
|
},
|
||||||
renderer::{ColLightInfo, Renderer},
|
renderer::{ColLightInfo, Drawer, Renderer, UiDrawer},
|
||||||
texture::Texture,
|
texture::Texture,
|
||||||
};
|
};
|
||||||
pub use wgpu::{AddressMode, FilterMode};
|
pub use wgpu::{AddressMode, FilterMode};
|
||||||
|
@ -13,7 +13,7 @@ pub struct SubModel<'a, V: Vertex> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, V: Vertex> SubModel<'a, V> {
|
impl<'a, V: Vertex> SubModel<'a, V> {
|
||||||
pub fn buf(&self) -> &wgpu::Buffer { self.buf }
|
pub(super) fn buf(&self) -> &wgpu::Buffer { self.buf }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents a mesh that has been sent to the GPU.
|
/// Represents a mesh that has been sent to the GPU.
|
||||||
@ -38,7 +38,7 @@ impl<V: Vertex> Model<V> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn buf(&self) -> &wgpu::Buffer { &self.vbuf.buf }
|
pub(super) fn buf(&self) -> &wgpu::Buffer { &self.vbuf.buf }
|
||||||
|
|
||||||
pub fn len(&self) -> usize { self.vbuf.len() }
|
pub fn len(&self) -> usize { self.vbuf.len() }
|
||||||
}
|
}
|
||||||
|
@ -150,7 +150,6 @@ impl CloudsPipeline {
|
|||||||
let samples = match aa_mode {
|
let samples = match aa_mode {
|
||||||
AaMode::None | AaMode::Fxaa => 1,
|
AaMode::None | AaMode::Fxaa => 1,
|
||||||
// TODO: Ensure sampling in the shader is exactly between the 4 texels
|
// TODO: Ensure sampling in the shader is exactly between the 4 texels
|
||||||
AaMode::SsaaX4 => 1,
|
|
||||||
AaMode::MsaaX4 => 4,
|
AaMode::MsaaX4 => 4,
|
||||||
AaMode::MsaaX8 => 8,
|
AaMode::MsaaX8 => 8,
|
||||||
AaMode::MsaaX16 => 16,
|
AaMode::MsaaX16 => 16,
|
||||||
|
@ -143,7 +143,6 @@ impl FigureLayout {
|
|||||||
},
|
},
|
||||||
count: None,
|
count: None,
|
||||||
},
|
},
|
||||||
// TODO: does this change at the same frequency?
|
|
||||||
// col lights
|
// col lights
|
||||||
wgpu::BindGroupLayoutEntry {
|
wgpu::BindGroupLayoutEntry {
|
||||||
binding: 2,
|
binding: 2,
|
||||||
@ -192,7 +191,6 @@ impl FigurePipeline {
|
|||||||
let samples = match aa_mode {
|
let samples = match aa_mode {
|
||||||
AaMode::None | AaMode::Fxaa => 1,
|
AaMode::None | AaMode::Fxaa => 1,
|
||||||
// TODO: Ensure sampling in the shader is exactly between the 4 texels
|
// TODO: Ensure sampling in the shader is exactly between the 4 texels
|
||||||
AaMode::SsaaX4 => 1,
|
|
||||||
AaMode::MsaaX4 => 4,
|
AaMode::MsaaX4 => 4,
|
||||||
AaMode::MsaaX8 => 8,
|
AaMode::MsaaX8 => 8,
|
||||||
AaMode::MsaaX16 => 16,
|
AaMode::MsaaX16 => 16,
|
||||||
|
@ -105,7 +105,6 @@ impl FluidPipeline {
|
|||||||
let samples = match aa_mode {
|
let samples = match aa_mode {
|
||||||
AaMode::None | AaMode::Fxaa => 1,
|
AaMode::None | AaMode::Fxaa => 1,
|
||||||
// TODO: Ensure sampling in the shader is exactly between the 4 texels
|
// TODO: Ensure sampling in the shader is exactly between the 4 texels
|
||||||
AaMode::SsaaX4 => 1,
|
|
||||||
AaMode::MsaaX4 => 4,
|
AaMode::MsaaX4 => 4,
|
||||||
AaMode::MsaaX8 => 8,
|
AaMode::MsaaX8 => 8,
|
||||||
AaMode::MsaaX16 => 16,
|
AaMode::MsaaX16 => 16,
|
||||||
|
@ -35,6 +35,25 @@ pub struct LodData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl LodData {
|
impl LodData {
|
||||||
|
pub fn dummy(renderer: &mut Renderer) -> Self {
|
||||||
|
let map_size = Vec2::new(1, 1);
|
||||||
|
let map_border = [0.0, 0.0, 0.0, 0.0];
|
||||||
|
let map_image = [0];
|
||||||
|
let alt_image = [0];
|
||||||
|
let horizon_image = [0x_00_01_00_01];
|
||||||
|
//let map_border = [0.0, 0.0, 0.0, 0.0];
|
||||||
|
|
||||||
|
Self::new(
|
||||||
|
renderer,
|
||||||
|
map_size,
|
||||||
|
&map_image,
|
||||||
|
&alt_image,
|
||||||
|
&horizon_image,
|
||||||
|
1,
|
||||||
|
//map_border.into(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn new(
|
pub fn new(
|
||||||
renderer: &mut Renderer,
|
renderer: &mut Renderer,
|
||||||
map_size: Vec2<u32>,
|
map_size: Vec2<u32>,
|
||||||
@ -44,65 +63,54 @@ impl LodData {
|
|||||||
tgt_detail: u32,
|
tgt_detail: u32,
|
||||||
//border_color: gfx::texture::PackedColor,
|
//border_color: gfx::texture::PackedColor,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let mut texture_info = wgpu::TextureDescriptor {
|
let mut create_texture = |format, data| {
|
||||||
label: None,
|
let texture_info = wgpu::TextureDescriptor {
|
||||||
size: wgpu::Extent3d {
|
label: None,
|
||||||
width: map_size.x,
|
size: wgpu::Extent3d {
|
||||||
height: map_size.y,
|
width: map_size.x,
|
||||||
depth: 1,
|
height: map_size.y,
|
||||||
},
|
depth: 1,
|
||||||
mip_level_count: 1,
|
},
|
||||||
sample_count: 1,
|
mip_level_count: 1,
|
||||||
dimension: wgpu::TextureDimension::D2,
|
sample_count: 1,
|
||||||
format: wgpu::TextureFormat::Rgba8UnormSrgb,
|
dimension: wgpu::TextureDimension::D2,
|
||||||
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::COPY_DST,
|
format,
|
||||||
};
|
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::COPY_DST,
|
||||||
|
};
|
||||||
|
|
||||||
let sampler_info = wgpu::SamplerDescriptor {
|
let sampler_info = wgpu::SamplerDescriptor {
|
||||||
label: None,
|
label: None,
|
||||||
address_mode_u: wgpu::AddressMode::ClampToEdge,
|
address_mode_u: wgpu::AddressMode::ClampToEdge,
|
||||||
address_mode_v: wgpu::AddressMode::ClampToEdge,
|
address_mode_v: wgpu::AddressMode::ClampToEdge,
|
||||||
address_mode_w: wgpu::AddressMode::ClampToEdge,
|
address_mode_w: wgpu::AddressMode::ClampToEdge,
|
||||||
mag_filter: wgpu::FilterMode::Linear,
|
mag_filter: wgpu::FilterMode::Linear,
|
||||||
min_filter: wgpu::FilterMode::Linear,
|
min_filter: wgpu::FilterMode::Linear,
|
||||||
mipmap_filter: wgpu::FilterMode::Nearest,
|
mipmap_filter: wgpu::FilterMode::Nearest,
|
||||||
border_color: Some(wgpu::SamplerBorderColor::TransparentBlack),
|
border_color: Some(wgpu::SamplerBorderColor::TransparentBlack),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut view_info = wgpu::TextureViewDescriptor {
|
let view_info = wgpu::TextureViewDescriptor {
|
||||||
label: None,
|
label: None,
|
||||||
format: Some(wgpu::TextureFormat::Rgba8UnormSrgb),
|
format: Some(format),
|
||||||
dimension: Some(wgpu::TextureViewDimension::D2),
|
dimension: Some(wgpu::TextureViewDimension::D2),
|
||||||
aspect: wgpu::TextureAspect::All,
|
aspect: wgpu::TextureAspect::All,
|
||||||
base_mip_level: 0,
|
base_mip_level: 0,
|
||||||
level_count: None,
|
level_count: None,
|
||||||
base_array_layer: 0,
|
base_array_layer: 0,
|
||||||
array_layer_count: None,
|
array_layer_count: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let map = renderer.create_texture_with_data_raw(
|
renderer.create_texture_with_data_raw(
|
||||||
&texture_info,
|
&texture_info,
|
||||||
&view_info,
|
&view_info,
|
||||||
&sampler_info,
|
&sampler_info,
|
||||||
bytemuck::cast_slice(lod_base),
|
bytemuck::cast_slice(data),
|
||||||
);
|
)
|
||||||
texture_info.format = wgpu::TextureFormat::Rg16Uint;
|
};
|
||||||
view_info.format = Some(wgpu::TextureFormat::Rg16Uint);
|
let map = create_texture(wgpu::TextureFormat::Rgba8UnormSrgb, lod_base);
|
||||||
let alt = renderer.create_texture_with_data_raw(
|
let alt = create_texture(wgpu::TextureFormat::Rg16Uint, lod_alt);
|
||||||
&texture_info,
|
let horizon = create_texture(wgpu::TextureFormat::Rgba8Unorm, lod_horizon);
|
||||||
&view_info,
|
|
||||||
&sampler_info,
|
|
||||||
bytemuck::cast_slice(lod_base),
|
|
||||||
);
|
|
||||||
texture_info.format = wgpu::TextureFormat::Rgba8Unorm;
|
|
||||||
view_info.format = Some(wgpu::TextureFormat::Rg16Uint);
|
|
||||||
let horizon = renderer.create_texture_with_data_raw(
|
|
||||||
&texture_info,
|
|
||||||
&view_info,
|
|
||||||
&sampler_info,
|
|
||||||
bytemuck::cast_slice(lod_base),
|
|
||||||
);
|
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
map,
|
map,
|
||||||
@ -173,7 +181,6 @@ impl LodTerrainPipeline {
|
|||||||
let samples = match aa_mode {
|
let samples = match aa_mode {
|
||||||
AaMode::None | AaMode::Fxaa => 1,
|
AaMode::None | AaMode::Fxaa => 1,
|
||||||
// TODO: Ensure sampling in the shader is exactly between the 4 texels
|
// TODO: Ensure sampling in the shader is exactly between the 4 texels
|
||||||
AaMode::SsaaX4 => 1,
|
|
||||||
AaMode::MsaaX4 => 4,
|
AaMode::MsaaX4 => 4,
|
||||||
AaMode::MsaaX8 => 8,
|
AaMode::MsaaX8 => 8,
|
||||||
AaMode::MsaaX16 => 16,
|
AaMode::MsaaX16 => 16,
|
||||||
|
@ -10,7 +10,7 @@ pub mod sprite;
|
|||||||
pub mod terrain;
|
pub mod terrain;
|
||||||
pub mod ui;
|
pub mod ui;
|
||||||
|
|
||||||
use super::Consts;
|
use super::{Consts, Texture};
|
||||||
use crate::scene::camera::CameraMode;
|
use crate::scene::camera::CameraMode;
|
||||||
use bytemuck::{Pod, Zeroable};
|
use bytemuck::{Pod, Zeroable};
|
||||||
use common::terrain::BlockKind;
|
use common::terrain::BlockKind;
|
||||||
@ -225,6 +225,10 @@ pub struct GlobalModel {
|
|||||||
pub shadow_mats: Consts<shadow::Locals>,
|
pub shadow_mats: Consts<shadow::Locals>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct GlobalsBindGroup {
|
||||||
|
pub(super) bind_group: wgpu::BindGroup,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct GlobalsLayouts {
|
pub struct GlobalsLayouts {
|
||||||
pub globals: wgpu::BindGroupLayout,
|
pub globals: wgpu::BindGroupLayout,
|
||||||
}
|
}
|
||||||
@ -315,7 +319,7 @@ impl GlobalsLayouts {
|
|||||||
ty: wgpu::BindingType::Sampler { comparison: false },
|
ty: wgpu::BindingType::Sampler { comparison: false },
|
||||||
count: None,
|
count: None,
|
||||||
},
|
},
|
||||||
// light shadows
|
// light shadows (ie shadows from a light?)
|
||||||
wgpu::BindGroupLayoutEntry {
|
wgpu::BindGroupLayoutEntry {
|
||||||
binding: 9,
|
binding: 9,
|
||||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||||
@ -382,4 +386,96 @@ impl GlobalsLayouts {
|
|||||||
|
|
||||||
Self { globals }
|
Self { globals }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn bind(
|
||||||
|
&self,
|
||||||
|
device: &wgpu::Device,
|
||||||
|
global_model: &GlobalModel,
|
||||||
|
lod_data: &lod_terrain::LodData,
|
||||||
|
noise: &Texture,
|
||||||
|
point_shadow_map: &Texture,
|
||||||
|
directed_shadow_map: &Texture,
|
||||||
|
) -> GlobalsBindGroup {
|
||||||
|
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||||
|
label: None,
|
||||||
|
layout: &self.globals,
|
||||||
|
entries: &[
|
||||||
|
// Global uniform
|
||||||
|
wgpu::BindGroupEntry {
|
||||||
|
binding: 0,
|
||||||
|
resource: global_model.globals.buf().as_entire_binding(),
|
||||||
|
},
|
||||||
|
// Noise tex
|
||||||
|
wgpu::BindGroupEntry {
|
||||||
|
binding: 1,
|
||||||
|
resource: wgpu::BindingResource::TextureView(&noise.view),
|
||||||
|
},
|
||||||
|
wgpu::BindGroupEntry {
|
||||||
|
binding: 2,
|
||||||
|
resource: wgpu::BindingResource::Sampler(&noise.sampler),
|
||||||
|
},
|
||||||
|
// Light uniform
|
||||||
|
wgpu::BindGroupEntry {
|
||||||
|
binding: 3,
|
||||||
|
resource: global_model.lights.buf().as_entire_binding(),
|
||||||
|
},
|
||||||
|
// Shadow uniform
|
||||||
|
wgpu::BindGroupEntry {
|
||||||
|
binding: 4,
|
||||||
|
resource: global_model.shadows.buf().as_entire_binding(),
|
||||||
|
},
|
||||||
|
// Alt texture
|
||||||
|
wgpu::BindGroupEntry {
|
||||||
|
binding: 5,
|
||||||
|
resource: wgpu::BindingResource::TextureView(&lod_data.alt.view),
|
||||||
|
},
|
||||||
|
wgpu::BindGroupEntry {
|
||||||
|
binding: 6,
|
||||||
|
resource: wgpu::BindingResource::Sampler(&lod_data.alt.sampler),
|
||||||
|
},
|
||||||
|
// Horizon texture
|
||||||
|
wgpu::BindGroupEntry {
|
||||||
|
binding: 7,
|
||||||
|
resource: wgpu::BindingResource::TextureView(&lod_data.horizon.view),
|
||||||
|
},
|
||||||
|
wgpu::BindGroupEntry {
|
||||||
|
binding: 8,
|
||||||
|
resource: wgpu::BindingResource::Sampler(&lod_data.horizon.sampler),
|
||||||
|
},
|
||||||
|
// light shadows
|
||||||
|
wgpu::BindGroupEntry {
|
||||||
|
binding: 9,
|
||||||
|
resource: global_model.shadow_mats.buf().as_entire_binding(),
|
||||||
|
},
|
||||||
|
wgpu::BindGroupEntry {
|
||||||
|
binding: 10,
|
||||||
|
resource: wgpu::BindingResource::TextureView(&point_shadow_map.view),
|
||||||
|
},
|
||||||
|
wgpu::BindGroupEntry {
|
||||||
|
binding: 11,
|
||||||
|
resource: wgpu::BindingResource::Sampler(&point_shadow_map.sampler),
|
||||||
|
},
|
||||||
|
// directed shadow maps
|
||||||
|
wgpu::BindGroupEntry {
|
||||||
|
binding: 12,
|
||||||
|
resource: wgpu::BindingResource::TextureView(&directed_shadow_map.view),
|
||||||
|
},
|
||||||
|
wgpu::BindGroupEntry {
|
||||||
|
binding: 13,
|
||||||
|
resource: wgpu::BindingResource::Sampler(&directed_shadow_map.sampler),
|
||||||
|
},
|
||||||
|
// lod map (t_map)
|
||||||
|
wgpu::BindGroupEntry {
|
||||||
|
binding: 14,
|
||||||
|
resource: wgpu::BindingResource::TextureView(&lod_data.map.view),
|
||||||
|
},
|
||||||
|
wgpu::BindGroupEntry {
|
||||||
|
binding: 15,
|
||||||
|
resource: wgpu::BindingResource::Sampler(&lod_data.map.sampler),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
GlobalsBindGroup { bind_group }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -189,7 +189,6 @@ impl ParticlePipeline {
|
|||||||
let samples = match aa_mode {
|
let samples = match aa_mode {
|
||||||
AaMode::None | AaMode::Fxaa => 1,
|
AaMode::None | AaMode::Fxaa => 1,
|
||||||
// TODO: Ensure sampling in the shader is exactly between the 4 texels
|
// TODO: Ensure sampling in the shader is exactly between the 4 texels
|
||||||
AaMode::SsaaX4 => 1,
|
|
||||||
AaMode::MsaaX4 => 4,
|
AaMode::MsaaX4 => 4,
|
||||||
AaMode::MsaaX8 => 8,
|
AaMode::MsaaX8 => 8,
|
||||||
AaMode::MsaaX16 => 16,
|
AaMode::MsaaX16 => 16,
|
||||||
|
@ -146,7 +146,6 @@ impl PostProcessPipeline {
|
|||||||
let samples = match aa_mode {
|
let samples = match aa_mode {
|
||||||
AaMode::None | AaMode::Fxaa => 1,
|
AaMode::None | AaMode::Fxaa => 1,
|
||||||
// TODO: Ensure sampling in the shader is exactly between the 4 texels
|
// TODO: Ensure sampling in the shader is exactly between the 4 texels
|
||||||
AaMode::SsaaX4 => 1,
|
|
||||||
AaMode::MsaaX4 => 4,
|
AaMode::MsaaX4 => 4,
|
||||||
AaMode::MsaaX8 => 8,
|
AaMode::MsaaX8 => 8,
|
||||||
AaMode::MsaaX16 => 16,
|
AaMode::MsaaX16 => 16,
|
||||||
|
@ -22,7 +22,6 @@ impl Locals {
|
|||||||
|
|
||||||
pub fn default() -> Self { Self::new(Mat4::identity(), Mat4::identity()) }
|
pub fn default() -> Self { Self::new(Mat4::identity(), Mat4::identity()) }
|
||||||
|
|
||||||
// TODO: unused?
|
|
||||||
fn layout(device: &wgpu::Device) -> wgpu::BindGroupLayout {
|
fn layout(device: &wgpu::Device) -> wgpu::BindGroupLayout {
|
||||||
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||||
label: None,
|
label: None,
|
||||||
@ -131,7 +130,6 @@ impl ShadowFigurePipeline {
|
|||||||
let samples = match aa_mode {
|
let samples = match aa_mode {
|
||||||
AaMode::None | AaMode::Fxaa => 1,
|
AaMode::None | AaMode::Fxaa => 1,
|
||||||
// TODO: Ensure sampling in the shader is exactly between the 4 texels
|
// TODO: Ensure sampling in the shader is exactly between the 4 texels
|
||||||
AaMode::SsaaX4 => 1,
|
|
||||||
AaMode::MsaaX4 => 4,
|
AaMode::MsaaX4 => 4,
|
||||||
AaMode::MsaaX8 => 8,
|
AaMode::MsaaX8 => 8,
|
||||||
AaMode::MsaaX16 => 16,
|
AaMode::MsaaX16 => 16,
|
||||||
@ -214,7 +212,6 @@ impl ShadowPipeline {
|
|||||||
let samples = match aa_mode {
|
let samples = match aa_mode {
|
||||||
AaMode::None | AaMode::Fxaa => 1,
|
AaMode::None | AaMode::Fxaa => 1,
|
||||||
// TODO: Ensure sampling in the shader is exactly between the 4 texels
|
// TODO: Ensure sampling in the shader is exactly between the 4 texels
|
||||||
AaMode::SsaaX4 => 1,
|
|
||||||
AaMode::MsaaX4 => 4,
|
AaMode::MsaaX4 => 4,
|
||||||
AaMode::MsaaX8 => 8,
|
AaMode::MsaaX8 => 8,
|
||||||
AaMode::MsaaX16 => 16,
|
AaMode::MsaaX16 => 16,
|
||||||
|
@ -46,7 +46,6 @@ impl SkyboxPipeline {
|
|||||||
let samples = match aa_mode {
|
let samples = match aa_mode {
|
||||||
AaMode::None | AaMode::Fxaa => 1,
|
AaMode::None | AaMode::Fxaa => 1,
|
||||||
// TODO: Ensure sampling in the shader is exactly between the 4 texels
|
// TODO: Ensure sampling in the shader is exactly between the 4 texels
|
||||||
AaMode::SsaaX4 => 1,
|
|
||||||
AaMode::MsaaX4 => 4,
|
AaMode::MsaaX4 => 4,
|
||||||
AaMode::MsaaX8 => 8,
|
AaMode::MsaaX8 => 8,
|
||||||
AaMode::MsaaX16 => 16,
|
AaMode::MsaaX16 => 16,
|
||||||
|
@ -176,7 +176,6 @@ impl SpriteLayout {
|
|||||||
label: None,
|
label: None,
|
||||||
entries: &[
|
entries: &[
|
||||||
// locals
|
// locals
|
||||||
// TODO: different freq
|
|
||||||
wgpu::BindGroupLayoutEntry {
|
wgpu::BindGroupLayoutEntry {
|
||||||
binding: 0,
|
binding: 0,
|
||||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||||
@ -239,7 +238,6 @@ impl SpritePipeline {
|
|||||||
let samples = match aa_mode {
|
let samples = match aa_mode {
|
||||||
AaMode::None | AaMode::Fxaa => 1,
|
AaMode::None | AaMode::Fxaa => 1,
|
||||||
// TODO: Ensure sampling in the shader is exactly between the 4 texels
|
// TODO: Ensure sampling in the shader is exactly between the 4 texels
|
||||||
AaMode::SsaaX4 => 1,
|
|
||||||
AaMode::MsaaX4 => 4,
|
AaMode::MsaaX4 => 4,
|
||||||
AaMode::MsaaX8 => 8,
|
AaMode::MsaaX8 => 8,
|
||||||
AaMode::MsaaX16 => 16,
|
AaMode::MsaaX16 => 16,
|
||||||
|
@ -170,7 +170,6 @@ impl TerrainLayout {
|
|||||||
count: None,
|
count: None,
|
||||||
},
|
},
|
||||||
// col lights
|
// col lights
|
||||||
// TODO: same frequency?
|
|
||||||
wgpu::BindGroupLayoutEntry {
|
wgpu::BindGroupLayoutEntry {
|
||||||
binding: 1,
|
binding: 1,
|
||||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||||
@ -218,7 +217,6 @@ impl TerrainPipeline {
|
|||||||
let samples = match aa_mode {
|
let samples = match aa_mode {
|
||||||
AaMode::None | AaMode::Fxaa => 1,
|
AaMode::None | AaMode::Fxaa => 1,
|
||||||
// TODO: Ensure sampling in the shader is exactly between the 4 texels
|
// TODO: Ensure sampling in the shader is exactly between the 4 texels
|
||||||
AaMode::SsaaX4 => 1,
|
|
||||||
AaMode::MsaaX4 => 4,
|
AaMode::MsaaX4 => 4,
|
||||||
AaMode::MsaaX8 => 8,
|
AaMode::MsaaX8 => 8,
|
||||||
AaMode::MsaaX16 => 16,
|
AaMode::MsaaX16 => 16,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use super::super::{AaMode, GlobalsLayouts, Quad, Tri};
|
use super::super::{AaMode, Consts, GlobalsLayouts, Quad, Texture, Tri};
|
||||||
use bytemuck::{Pod, Zeroable};
|
use bytemuck::{Pod, Zeroable};
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
@ -80,11 +80,20 @@ impl Mode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct UILayout {
|
pub struct LocalsBindGroup {
|
||||||
pub locals: wgpu::BindGroupLayout,
|
pub(in super::super) bind_group: wgpu::BindGroup,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UILayout {
|
pub struct TextureBindGroup {
|
||||||
|
pub(in super::super) bind_group: wgpu::BindGroup,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct UiLayout {
|
||||||
|
pub locals: wgpu::BindGroupLayout,
|
||||||
|
pub texture: wgpu::BindGroupLayout,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UiLayout {
|
||||||
pub fn new(device: &wgpu::Device) -> Self {
|
pub fn new(device: &wgpu::Device) -> Self {
|
||||||
Self {
|
Self {
|
||||||
locals: device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
locals: device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||||
@ -100,9 +109,14 @@ impl UILayout {
|
|||||||
},
|
},
|
||||||
count: None,
|
count: None,
|
||||||
},
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
texture: device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||||
|
label: None,
|
||||||
|
entries: &[
|
||||||
// texture
|
// texture
|
||||||
wgpu::BindGroupLayoutEntry {
|
wgpu::BindGroupLayoutEntry {
|
||||||
binding: 1,
|
binding: 0,
|
||||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||||
ty: wgpu::BindingType::SampledTexture {
|
ty: wgpu::BindingType::SampledTexture {
|
||||||
component_type: wgpu::TextureComponentType::Float,
|
component_type: wgpu::TextureComponentType::Float,
|
||||||
@ -112,7 +126,7 @@ impl UILayout {
|
|||||||
count: None,
|
count: None,
|
||||||
},
|
},
|
||||||
wgpu::BindGroupLayoutEntry {
|
wgpu::BindGroupLayoutEntry {
|
||||||
binding: 2,
|
binding: 1,
|
||||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||||
ty: wgpu::BindingType::Sampler { comparison: false },
|
ty: wgpu::BindingType::Sampler { comparison: false },
|
||||||
count: None,
|
count: None,
|
||||||
@ -121,33 +135,64 @@ impl UILayout {
|
|||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn bind_locals(&self, device: &wgpu::Device, locals: &Consts<Locals>) -> LocalsBindGroup {
|
||||||
|
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||||
|
label: None,
|
||||||
|
layout: &self.locals,
|
||||||
|
entries: &[wgpu::BindGroupEntry {
|
||||||
|
binding: 0,
|
||||||
|
resource: locals.buf().as_entire_binding(),
|
||||||
|
}],
|
||||||
|
});
|
||||||
|
|
||||||
|
LocalsBindGroup { bind_group }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bind_texture(&self, device: &wgpu::Device, texture: &Texture) -> TextureBindGroup {
|
||||||
|
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||||
|
label: None,
|
||||||
|
layout: &self.texture,
|
||||||
|
entries: &[
|
||||||
|
wgpu::BindGroupEntry {
|
||||||
|
binding: 0,
|
||||||
|
resource: wgpu::BindingResource::TextureView(&texture.view),
|
||||||
|
},
|
||||||
|
wgpu::BindGroupEntry {
|
||||||
|
binding: 1,
|
||||||
|
resource: wgpu::BindingResource::Sampler(&texture.sampler),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
TextureBindGroup { bind_group }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct UIPipeline {
|
pub struct UiPipeline {
|
||||||
pub pipeline: wgpu::RenderPipeline,
|
pub pipeline: wgpu::RenderPipeline,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UIPipeline {
|
impl UiPipeline {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
device: &wgpu::Device,
|
device: &wgpu::Device,
|
||||||
vs_module: &wgpu::ShaderModule,
|
vs_module: &wgpu::ShaderModule,
|
||||||
fs_module: &wgpu::ShaderModule,
|
fs_module: &wgpu::ShaderModule,
|
||||||
sc_desc: &wgpu::SwapChainDescriptor,
|
sc_desc: &wgpu::SwapChainDescriptor,
|
||||||
global_layout: &GlobalsLayouts,
|
global_layout: &GlobalsLayouts,
|
||||||
layout: &UILayout,
|
layout: &UiLayout,
|
||||||
aa_mode: AaMode,
|
aa_mode: AaMode,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let render_pipeline_layout =
|
let render_pipeline_layout =
|
||||||
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||||
label: Some("UI pipeline layout"),
|
label: Some("Ui pipeline layout"),
|
||||||
push_constant_ranges: &[],
|
push_constant_ranges: &[],
|
||||||
bind_group_layouts: &[&global_layout.globals, &layout.locals],
|
bind_group_layouts: &[&global_layout.globals, &layout.locals, &layout.texture],
|
||||||
});
|
});
|
||||||
|
|
||||||
let samples = match aa_mode {
|
let samples = match aa_mode {
|
||||||
AaMode::None | AaMode::Fxaa => 1,
|
AaMode::None | AaMode::Fxaa => 1,
|
||||||
// TODO: Ensure sampling in the shader is exactly between the 4 texels
|
// TODO: Ensure sampling in the shader is exactly between the 4 texels
|
||||||
AaMode::SsaaX4 => 1,
|
|
||||||
AaMode::MsaaX4 => 4,
|
AaMode::MsaaX4 => 4,
|
||||||
AaMode::MsaaX8 => 8,
|
AaMode::MsaaX8 => 8,
|
||||||
AaMode::MsaaX16 => 16,
|
AaMode::MsaaX16 => 16,
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
mod bind_group;
|
||||||
|
mod drawer;
|
||||||
|
|
||||||
|
pub use drawer::{Drawer, UiDrawer};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
consts::Consts,
|
consts::Consts,
|
||||||
instances::Instances,
|
instances::Instances,
|
||||||
@ -8,8 +13,8 @@ use super::{
|
|||||||
ui, GlobalsLayouts,
|
ui, GlobalsLayouts,
|
||||||
},
|
},
|
||||||
texture::Texture,
|
texture::Texture,
|
||||||
AaMode, AddressMode, CloudMode, FilterMode, FluidMode, LightingMode, RenderError, RenderMode,
|
AaMode, AddressMode, CloudMode, FilterMode, FluidMode, GlobalsBindGroup, LightingMode,
|
||||||
ShadowMapMode, ShadowMode, Vertex,
|
RenderError, RenderMode, ShadowMapMode, ShadowMode, Vertex,
|
||||||
};
|
};
|
||||||
use common::assets::{self, AssetExt, AssetHandle};
|
use common::assets::{self, AssetExt, AssetHandle};
|
||||||
use common_base::span;
|
use common_base::span;
|
||||||
@ -20,6 +25,7 @@ use vek::*;
|
|||||||
|
|
||||||
/// A type representing data that can be converted to an immutable texture map
|
/// A type representing data that can be converted to an immutable texture map
|
||||||
/// of ColLight data (used for texture atlases created during greedy meshing).
|
/// of ColLight data (used for texture atlases created during greedy meshing).
|
||||||
|
// TODO: revert to u16
|
||||||
pub type ColLightInfo = (Vec<[u8; 4]>, Vec2<u32>);
|
pub type ColLightInfo = (Vec<[u8; 4]>, Vec2<u32>);
|
||||||
|
|
||||||
/// Load from a GLSL file.
|
/// Load from a GLSL file.
|
||||||
@ -116,9 +122,9 @@ impl Shaders {
|
|||||||
pub struct ShadowMapRenderer {
|
pub struct ShadowMapRenderer {
|
||||||
// directed_encoder: gfx::Encoder<gfx_backend::Resources, gfx_backend::CommandBuffer>,
|
// directed_encoder: gfx::Encoder<gfx_backend::Resources, gfx_backend::CommandBuffer>,
|
||||||
// point_encoder: gfx::Encoder<gfx_backend::Resources, gfx_backend::CommandBuffer>,
|
// point_encoder: gfx::Encoder<gfx_backend::Resources, gfx_backend::CommandBuffer>,
|
||||||
directed_depth_stencil: Texture,
|
directed_depth: Texture,
|
||||||
|
|
||||||
point_depth_stencil: Texture,
|
point_depth: Texture,
|
||||||
|
|
||||||
point_pipeline: shadow::ShadowPipeline,
|
point_pipeline: shadow::ShadowPipeline,
|
||||||
terrain_directed_pipeline: shadow::ShadowPipeline,
|
terrain_directed_pipeline: shadow::ShadowPipeline,
|
||||||
@ -128,6 +134,7 @@ pub struct ShadowMapRenderer {
|
|||||||
|
|
||||||
/// A type that stores all the layouts associated with this renderer.
|
/// A type that stores all the layouts associated with this renderer.
|
||||||
pub struct Layouts {
|
pub struct Layouts {
|
||||||
|
// TODO: pub(self)??
|
||||||
pub(self) global: GlobalsLayouts,
|
pub(self) global: GlobalsLayouts,
|
||||||
|
|
||||||
pub(self) clouds: clouds::CloudsLayout,
|
pub(self) clouds: clouds::CloudsLayout,
|
||||||
@ -137,7 +144,7 @@ pub struct Layouts {
|
|||||||
pub(self) shadow: shadow::ShadowLayout,
|
pub(self) shadow: shadow::ShadowLayout,
|
||||||
pub(self) sprite: sprite::SpriteLayout,
|
pub(self) sprite: sprite::SpriteLayout,
|
||||||
pub(self) terrain: terrain::TerrainLayout,
|
pub(self) terrain: terrain::TerrainLayout,
|
||||||
pub(self) ui: ui::UILayout,
|
pub(self) ui: ui::UiLayout,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A type that encapsulates rendering state. `Renderer` is central to Voxygen's
|
/// A type that encapsulates rendering state. `Renderer` is central to Voxygen's
|
||||||
@ -156,7 +163,7 @@ pub struct Renderer {
|
|||||||
win_depth_view: wgpu::TextureView,
|
win_depth_view: wgpu::TextureView,
|
||||||
|
|
||||||
tgt_color_view: wgpu::TextureView,
|
tgt_color_view: wgpu::TextureView,
|
||||||
tgt_depth_stencil_view: wgpu::TextureView,
|
tgt_depth_view: wgpu::TextureView,
|
||||||
// TODO: rename
|
// TODO: rename
|
||||||
tgt_color_pp_view: wgpu::TextureView,
|
tgt_color_pp_view: wgpu::TextureView,
|
||||||
|
|
||||||
@ -177,7 +184,7 @@ pub struct Renderer {
|
|||||||
skybox_pipeline: skybox::SkyboxPipeline,
|
skybox_pipeline: skybox::SkyboxPipeline,
|
||||||
sprite_pipeline: sprite::SpritePipeline,
|
sprite_pipeline: sprite::SpritePipeline,
|
||||||
terrain_pipeline: terrain::TerrainPipeline,
|
terrain_pipeline: terrain::TerrainPipeline,
|
||||||
ui_pipeline: ui::UIPipeline,
|
ui_pipeline: ui::UiPipeline,
|
||||||
|
|
||||||
shaders: AssetHandle<Shaders>,
|
shaders: AssetHandle<Shaders>,
|
||||||
|
|
||||||
@ -273,7 +280,7 @@ impl Renderer {
|
|||||||
let shadow = shadow::ShadowLayout::new(&device);
|
let shadow = shadow::ShadowLayout::new(&device);
|
||||||
let sprite = sprite::SpriteLayout::new(&device);
|
let sprite = sprite::SpriteLayout::new(&device);
|
||||||
let terrain = terrain::TerrainLayout::new(&device);
|
let terrain = terrain::TerrainLayout::new(&device);
|
||||||
let ui = ui::UILayout::new(&device);
|
let ui = ui::UiLayout::new(&device);
|
||||||
|
|
||||||
Layouts {
|
Layouts {
|
||||||
global,
|
global,
|
||||||
@ -313,7 +320,7 @@ impl Renderer {
|
|||||||
shadow_views.is_some(),
|
shadow_views.is_some(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let (tgt_color_view, tgt_depth_stencil_view, tgt_color_pp_view, win_depth_view) =
|
let (tgt_color_view, tgt_depth_view, tgt_color_pp_view, win_depth_view) =
|
||||||
Self::create_rt_views(&device, (dims.width, dims.height), &mode)?;
|
Self::create_rt_views(&device, (dims.width, dims.height), &mode)?;
|
||||||
|
|
||||||
let shadow_map = if let (
|
let shadow_map = if let (
|
||||||
@ -327,16 +334,16 @@ impl Renderer {
|
|||||||
figure_directed_shadow_pipeline,
|
figure_directed_shadow_pipeline,
|
||||||
shadow_views,
|
shadow_views,
|
||||||
) {
|
) {
|
||||||
let (point_depth_stencil, directed_depth_stencil) = shadow_views;
|
let (point_depth, directed_depth) = shadow_views;
|
||||||
|
|
||||||
let layout = shadow::ShadowLayout::new(&device);
|
let layout = shadow::ShadowLayout::new(&device);
|
||||||
|
|
||||||
Some(ShadowMapRenderer {
|
Some(ShadowMapRenderer {
|
||||||
directed_depth_stencil,
|
directed_depth,
|
||||||
|
|
||||||
// point_encoder: factory.create_command_buffer().into(),
|
// point_encoder: factory.create_command_buffer().into(),
|
||||||
// directed_encoder: factory.create_command_buffer().into(),
|
// directed_encoder: factory.create_command_buffer().into(),
|
||||||
point_depth_stencil,
|
point_depth,
|
||||||
|
|
||||||
point_pipeline,
|
point_pipeline,
|
||||||
terrain_directed_pipeline,
|
terrain_directed_pipeline,
|
||||||
@ -378,7 +385,7 @@ impl Renderer {
|
|||||||
win_depth_view,
|
win_depth_view,
|
||||||
|
|
||||||
tgt_color_view,
|
tgt_color_view,
|
||||||
tgt_depth_stencil_view,
|
tgt_depth_view,
|
||||||
tgt_color_pp_view,
|
tgt_color_pp_view,
|
||||||
|
|
||||||
sampler,
|
sampler,
|
||||||
@ -411,7 +418,7 @@ impl Renderer {
|
|||||||
/// before post-processing.
|
/// before post-processing.
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn tgt_views(&self) -> (&wgpu::TextureView, &wgpu::TextureView) {
|
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_view)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get references to the internal render target views that get displayed
|
/// Get references to the internal render target views that get displayed
|
||||||
@ -446,19 +453,19 @@ impl Renderer {
|
|||||||
self.swap_chain = self.device.create_swap_chain(&self.surface, &self.sc_desc);
|
self.swap_chain = self.device.create_swap_chain(&self.surface, &self.sc_desc);
|
||||||
|
|
||||||
// Resize other render targets
|
// Resize other render targets
|
||||||
let (tgt_color_view, tgt_depth_stencil_view, tgt_color_pp_view, win_depth_view) =
|
let (tgt_color_view, tgt_depth_view, tgt_color_pp_view, win_depth_view) =
|
||||||
Self::create_rt_views(&mut self.device, (dims.x, dims.y), &self.mode)?;
|
Self::create_rt_views(&mut self.device, (dims.x, dims.y), &self.mode)?;
|
||||||
self.win_depth_view = win_depth_view;
|
self.win_depth_view = win_depth_view;
|
||||||
self.tgt_color_view = tgt_color_view;
|
self.tgt_color_view = tgt_color_view;
|
||||||
self.tgt_depth_stencil_view = tgt_depth_stencil_view;
|
self.tgt_depth_view = tgt_depth_view;
|
||||||
self.tgt_color_pp_view = tgt_color_pp_view;
|
self.tgt_color_pp_view = tgt_color_pp_view;
|
||||||
if let (Some(shadow_map), ShadowMode::Map(mode)) =
|
if let (Some(shadow_map), ShadowMode::Map(mode)) =
|
||||||
(self.shadow_map.as_mut(), self.mode.shadow)
|
(self.shadow_map.as_mut(), self.mode.shadow)
|
||||||
{
|
{
|
||||||
match Self::create_shadow_views(&mut self.device, (dims.x, dims.y), &mode) {
|
match Self::create_shadow_views(&mut self.device, (dims.x, dims.y), &mode) {
|
||||||
Ok((point_depth_stencil, directed_depth_stencil)) => {
|
Ok((point_depth, directed_depth)) => {
|
||||||
shadow_map.point_depth_stencil = point_depth_stencil;
|
shadow_map.point_depth = point_depth;
|
||||||
shadow_map.directed_depth_stencil = directed_depth_stencil;
|
shadow_map.directed_depth = directed_depth;
|
||||||
},
|
},
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
warn!("Could not create shadow map views: {:?}", err);
|
warn!("Could not create shadow map views: {:?}", err);
|
||||||
@ -496,7 +503,7 @@ impl Renderer {
|
|||||||
};
|
};
|
||||||
let levels = 1;
|
let levels = 1;
|
||||||
|
|
||||||
let mut color_view = || {
|
let color_view = || {
|
||||||
let tex = device.create_texture(&wgpu::TextureDescriptor {
|
let tex = device.create_texture(&wgpu::TextureDescriptor {
|
||||||
label: None,
|
label: None,
|
||||||
size: wgpu::Extent3d {
|
size: wgpu::Extent3d {
|
||||||
@ -527,7 +534,7 @@ impl Renderer {
|
|||||||
let tgt_color_view = color_view();
|
let tgt_color_view = color_view();
|
||||||
let tgt_color_pp_view = color_view();
|
let tgt_color_pp_view = color_view();
|
||||||
|
|
||||||
let tgt_depth_stencil_tex = device.create_texture(&wgpu::TextureDescriptor {
|
let tgt_depth_tex = device.create_texture(&wgpu::TextureDescriptor {
|
||||||
label: None,
|
label: None,
|
||||||
size: wgpu::Extent3d {
|
size: wgpu::Extent3d {
|
||||||
width,
|
width,
|
||||||
@ -540,17 +547,16 @@ impl Renderer {
|
|||||||
format: wgpu::TextureFormat::Depth24Plus,
|
format: wgpu::TextureFormat::Depth24Plus,
|
||||||
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::RENDER_ATTACHMENT,
|
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::RENDER_ATTACHMENT,
|
||||||
});
|
});
|
||||||
let tgt_depth_stencil_view =
|
let tgt_depth_view = tgt_depth_tex.create_view(&wgpu::TextureViewDescriptor {
|
||||||
tgt_depth_stencil_tex.create_view(&wgpu::TextureViewDescriptor {
|
label: None,
|
||||||
label: None,
|
format: Some(wgpu::TextureFormat::Depth24Plus),
|
||||||
format: Some(wgpu::TextureFormat::Depth24Plus),
|
dimension: Some(wgpu::TextureViewDimension::D2),
|
||||||
dimension: Some(wgpu::TextureViewDimension::D2),
|
aspect: wgpu::TextureAspect::DepthOnly,
|
||||||
aspect: wgpu::TextureAspect::DepthOnly,
|
base_mip_level: 0,
|
||||||
base_mip_level: 0,
|
level_count: None,
|
||||||
level_count: None,
|
base_array_layer: 0,
|
||||||
base_array_layer: 0,
|
array_layer_count: None,
|
||||||
array_layer_count: None,
|
});
|
||||||
});
|
|
||||||
|
|
||||||
let win_depth_tex = device.create_texture(&wgpu::TextureDescriptor {
|
let win_depth_tex = device.create_texture(&wgpu::TextureDescriptor {
|
||||||
label: None,
|
label: None,
|
||||||
@ -565,7 +571,7 @@ impl Renderer {
|
|||||||
format: wgpu::TextureFormat::Depth24Plus,
|
format: wgpu::TextureFormat::Depth24Plus,
|
||||||
usage: wgpu::TextureUsage::RENDER_ATTACHMENT,
|
usage: wgpu::TextureUsage::RENDER_ATTACHMENT,
|
||||||
});
|
});
|
||||||
let win_depth_view = tgt_depth_stencil_tex.create_view(&wgpu::TextureViewDescriptor {
|
let win_depth_view = tgt_depth_tex.create_view(&wgpu::TextureViewDescriptor {
|
||||||
label: None,
|
label: None,
|
||||||
format: Some(wgpu::TextureFormat::Depth24Plus),
|
format: Some(wgpu::TextureFormat::Depth24Plus),
|
||||||
dimension: Some(wgpu::TextureViewDimension::D2),
|
dimension: Some(wgpu::TextureViewDimension::D2),
|
||||||
@ -578,7 +584,7 @@ impl Renderer {
|
|||||||
|
|
||||||
Ok((
|
Ok((
|
||||||
tgt_color_view,
|
tgt_color_view,
|
||||||
tgt_depth_stencil_view,
|
tgt_depth_view,
|
||||||
tgt_color_pp_view,
|
tgt_color_pp_view,
|
||||||
win_depth_view,
|
win_depth_view,
|
||||||
))
|
))
|
||||||
@ -656,7 +662,7 @@ impl Renderer {
|
|||||||
};
|
};
|
||||||
|
|
||||||
//TODO: (0, levels - 1), ?? from master
|
//TODO: (0, levels - 1), ?? from master
|
||||||
let mut point_shadow_view = wgpu::TextureViewDescriptor {
|
let point_shadow_view = wgpu::TextureViewDescriptor {
|
||||||
label: None,
|
label: None,
|
||||||
format: Some(wgpu::TextureFormat::Depth24Plus),
|
format: Some(wgpu::TextureFormat::Depth24Plus),
|
||||||
dimension: Some(wgpu::TextureViewDimension::Cube),
|
dimension: Some(wgpu::TextureViewDimension::Cube),
|
||||||
@ -723,8 +729,8 @@ impl Renderer {
|
|||||||
pub fn get_shadow_resolution(&self) -> (Vec2<u32>, Vec2<u32>) {
|
pub fn get_shadow_resolution(&self) -> (Vec2<u32>, Vec2<u32>) {
|
||||||
if let Some(shadow_map) = &self.shadow_map {
|
if let Some(shadow_map) = &self.shadow_map {
|
||||||
(
|
(
|
||||||
shadow_map.point_depth_stencil.get_dimensions().xy(),
|
shadow_map.point_depth.get_dimensions().xy(),
|
||||||
shadow_map.directed_depth_stencil.get_dimensions().xy(),
|
shadow_map.directed_depth.get_dimensions().xy(),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
(Vec2::new(1, 1), Vec2::new(1, 1))
|
(Vec2::new(1, 1), Vec2::new(1, 1))
|
||||||
@ -741,10 +747,10 @@ impl Renderer {
|
|||||||
// if let Some(shadow_map) = self.shadow_map.as_mut() {
|
// if let Some(shadow_map) = self.shadow_map.as_mut() {
|
||||||
// // let point_encoder = &mut shadow_map.point_encoder;
|
// // let point_encoder = &mut shadow_map.point_encoder;
|
||||||
// let point_encoder = &mut self.encoder;
|
// let point_encoder = &mut self.encoder;
|
||||||
// point_encoder.clear_depth(&shadow_map.point_depth_stencil_view, 1.0);
|
// point_encoder.clear_depth(&shadow_map.point_depth_view, 1.0);
|
||||||
// // let directed_encoder = &mut shadow_map.directed_encoder;
|
// // let directed_encoder = &mut shadow_map.directed_encoder;
|
||||||
// let directed_encoder = &mut self.encoder;
|
// let directed_encoder = &mut self.encoder;
|
||||||
// directed_encoder.clear_depth(&shadow_map.directed_depth_stencil_view,
|
// directed_encoder.clear_depth(&shadow_map.directed_depth_view,
|
||||||
// 1.0); }
|
// 1.0); }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
@ -802,51 +808,20 @@ impl Renderer {
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
/// Perform all queued draw calls for this frame and clean up discarded
|
/// Start recording the frame
|
||||||
/// items.
|
/// When the returned `Drawer` is dropped the recorded draw calls will be
|
||||||
pub fn flush(&mut self) -> Result<(), RenderError> {
|
/// submitted to the queue
|
||||||
span!(_guard, "flush", "Renderer::flush");
|
/// If there is an intermittent issue with the swap chain then Ok(None) will
|
||||||
let frame = match self.swap_chain.get_current_frame() {
|
/// be returned
|
||||||
Ok(frame) => frame.output,
|
pub fn start_recording_frame<'a>(
|
||||||
// If lost recreate the swap chain
|
&'a mut self,
|
||||||
Err(err @ wgpu::SwapChainError::Lost) => {
|
globals: &'a GlobalsBindGroup,
|
||||||
warn!("{}. Recreating swap chain. A frame will be missed", err);
|
) -> Result<Option<Drawer<'a>>, RenderError> {
|
||||||
return self.on_resize(self.resolution);
|
span!(
|
||||||
},
|
_guard,
|
||||||
Err(err @ wgpu::SwapChainError::Timeout) => {
|
"start_recording_frame",
|
||||||
warn!("{}. This will probably be resolved on the next frame", err);
|
"Renderer::start_recording_frame"
|
||||||
return Ok(());
|
);
|
||||||
},
|
|
||||||
Err(err @ wgpu::SwapChainError::Outdated) => {
|
|
||||||
warn!("{}. This will probably be resolved on the next frame", err);
|
|
||||||
return Ok(());
|
|
||||||
},
|
|
||||||
Err(err @ wgpu::SwapChainError::OutOfMemory) => return Err(err.into()),
|
|
||||||
};
|
|
||||||
let mut encoder = self
|
|
||||||
.device
|
|
||||||
.create_command_encoder(&wgpu::CommandEncoderDescriptor {
|
|
||||||
label: Some("A render encoder"),
|
|
||||||
});
|
|
||||||
{
|
|
||||||
let _render_pas = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
|
||||||
color_attachments: &[wgpu::RenderPassColorAttachmentDescriptor {
|
|
||||||
attachment: &frame.view,
|
|
||||||
resolve_target: None,
|
|
||||||
ops: wgpu::Operations {
|
|
||||||
load: wgpu::LoadOp::Clear(wgpu::Color {
|
|
||||||
r: 0.1,
|
|
||||||
g: 0.7,
|
|
||||||
b: 0.3,
|
|
||||||
a: 1.0,
|
|
||||||
}),
|
|
||||||
store: true,
|
|
||||||
},
|
|
||||||
}],
|
|
||||||
depth_stencil_attachment: None,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
self.queue.submit(std::iter::once(encoder.finish()));
|
|
||||||
|
|
||||||
self.device.poll(wgpu::Maintain::Poll);
|
self.device.poll(wgpu::Maintain::Poll);
|
||||||
|
|
||||||
@ -855,7 +830,30 @@ impl Renderer {
|
|||||||
self.recreate_pipelines();
|
self.recreate_pipelines();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
let tex = match self.swap_chain.get_current_frame() {
|
||||||
|
Ok(frame) => frame.output,
|
||||||
|
// If lost recreate the swap chain
|
||||||
|
Err(err @ wgpu::SwapChainError::Lost) => {
|
||||||
|
warn!("{}. Recreating swap chain. A frame will be missed", err);
|
||||||
|
return self.on_resize(self.resolution).map(|()| None);
|
||||||
|
},
|
||||||
|
Err(err @ wgpu::SwapChainError::Timeout) => {
|
||||||
|
warn!("{}. This will probably be resolved on the next frame", err);
|
||||||
|
return Ok(None);
|
||||||
|
},
|
||||||
|
Err(err @ wgpu::SwapChainError::Outdated) => {
|
||||||
|
warn!("{}. This will probably be resolved on the next frame", err);
|
||||||
|
return Ok(None);
|
||||||
|
},
|
||||||
|
Err(err @ wgpu::SwapChainError::OutOfMemory) => return Err(err.into()),
|
||||||
|
};
|
||||||
|
let encoder = self
|
||||||
|
.device
|
||||||
|
.create_command_encoder(&wgpu::CommandEncoderDescriptor {
|
||||||
|
label: Some("A render encoder"),
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok(Some(Drawer::new(encoder, self, tex, globals)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Recreate the pipelines
|
/// Recreate the pipelines
|
||||||
@ -916,14 +914,10 @@ 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 + bytemuck::Pod>(
|
pub fn create_consts<T: Copy + bytemuck::Pod>(&mut self, vals: &[T]) -> Consts<T> {
|
||||||
&mut self,
|
|
||||||
vals: &[T],
|
|
||||||
// TODO: don't use result here
|
|
||||||
) -> Result<Consts<T>, RenderError> {
|
|
||||||
let mut consts = Consts::new(&self.device, vals.len());
|
let mut consts = Consts::new(&self.device, vals.len());
|
||||||
consts.update(&self.device, &self.queue, vals, 0);
|
consts.update(&self.device, &self.queue, vals, 0);
|
||||||
Ok(consts)
|
consts
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update a set of constants with the provided values.
|
/// Update a set of constants with the provided values.
|
||||||
@ -1134,8 +1128,8 @@ impl Renderer {
|
|||||||
// self.noise_tex.sampler.clone()), alt: (lod.alt.srv.clone(),
|
// self.noise_tex.sampler.clone()), alt: (lod.alt.srv.clone(),
|
||||||
// lod.alt.sampler.clone()), horizon: (lod.horizon.srv.clone(),
|
// lod.alt.sampler.clone()), horizon: (lod.horizon.srv.clone(),
|
||||||
// lod.horizon.sampler.clone()), tgt_color:
|
// lod.horizon.sampler.clone()), tgt_color:
|
||||||
// self.tgt_color_view.clone(), tgt_depth_stencil:
|
// self.tgt_color_view.clone(), tgt_depth:
|
||||||
// (self.tgt_depth_stencil_view.clone()/* , (1, 1) */), },
|
// (self.tgt_depth_view.clone()/* , (1, 1) */), },
|
||||||
// );
|
// );
|
||||||
// }
|
// }
|
||||||
|
|
||||||
@ -1193,8 +1187,8 @@ impl Renderer {
|
|||||||
// self.noise_tex.sampler.clone()), alt: (lod.alt.srv.clone(),
|
// self.noise_tex.sampler.clone()), alt: (lod.alt.srv.clone(),
|
||||||
// lod.alt.sampler.clone()), horizon: (lod.horizon.srv.clone(),
|
// lod.alt.sampler.clone()), horizon: (lod.horizon.srv.clone(),
|
||||||
// lod.horizon.sampler.clone()), tgt_color:
|
// lod.horizon.sampler.clone()), tgt_color:
|
||||||
// self.tgt_color_view.clone(), tgt_depth_stencil:
|
// self.tgt_color_view.clone(), tgt_depth:
|
||||||
// (self.tgt_depth_stencil_view.clone()/* , (1, 1) */), },
|
// (self.tgt_depth_view.clone()/* , (1, 1) */), },
|
||||||
// );
|
// );
|
||||||
// }
|
// }
|
||||||
|
|
||||||
@ -1253,8 +1247,8 @@ impl Renderer {
|
|||||||
// self.noise_tex.sampler.clone()), alt: (lod.alt.srv.clone(),
|
// self.noise_tex.sampler.clone()), alt: (lod.alt.srv.clone(),
|
||||||
// lod.alt.sampler.clone()), horizon: (lod.horizon.srv.clone(),
|
// lod.alt.sampler.clone()), horizon: (lod.horizon.srv.clone(),
|
||||||
// lod.horizon.sampler.clone()), tgt_color:
|
// lod.horizon.sampler.clone()), tgt_color:
|
||||||
// self.tgt_color_view.clone(), tgt_depth_stencil:
|
// self.tgt_color_view.clone(), tgt_depth:
|
||||||
// (self.tgt_depth_stencil_view.clone()/* , (0, 0) */), },
|
// (self.tgt_depth_view.clone()/* , (0, 0) */), },
|
||||||
// ); */
|
// ); */
|
||||||
// }
|
// }
|
||||||
|
|
||||||
@ -1312,8 +1306,8 @@ impl Renderer {
|
|||||||
// self.noise_tex.sampler.clone()), alt: (lod.alt.srv.clone(),
|
// self.noise_tex.sampler.clone()), alt: (lod.alt.srv.clone(),
|
||||||
// lod.alt.sampler.clone()), horizon: (lod.horizon.srv.clone(),
|
// lod.alt.sampler.clone()), horizon: (lod.horizon.srv.clone(),
|
||||||
// lod.horizon.sampler.clone()), tgt_color:
|
// lod.horizon.sampler.clone()), tgt_color:
|
||||||
// self.tgt_color_view.clone(), tgt_depth_stencil:
|
// self.tgt_color_view.clone(), tgt_depth:
|
||||||
// (self.tgt_depth_stencil_view.clone()/* , (1, 1) */), },
|
// (self.tgt_depth_view.clone()/* , (1, 1) */), },
|
||||||
// );
|
// );
|
||||||
// }
|
// }
|
||||||
|
|
||||||
@ -1371,8 +1365,8 @@ impl Renderer {
|
|||||||
// self.noise_tex.sampler.clone()), alt: (lod.alt.srv.clone(),
|
// self.noise_tex.sampler.clone()), alt: (lod.alt.srv.clone(),
|
||||||
// lod.alt.sampler.clone()), horizon: (lod.horizon.srv.clone(),
|
// lod.alt.sampler.clone()), horizon: (lod.horizon.srv.clone(),
|
||||||
// lod.horizon.sampler.clone()), tgt_color:
|
// lod.horizon.sampler.clone()), tgt_color:
|
||||||
// self.tgt_color_view.clone(), tgt_depth_stencil:
|
// self.tgt_color_view.clone(), tgt_depth:
|
||||||
// (self.tgt_depth_stencil_view.clone()/* , (1, 1) */), },
|
// (self.tgt_depth_view.clone()/* , (1, 1) */), },
|
||||||
// );
|
// );
|
||||||
// }
|
// }
|
||||||
|
|
||||||
@ -1414,7 +1408,7 @@ impl Renderer {
|
|||||||
|
|
||||||
// // Shadow stuff
|
// // Shadow stuff
|
||||||
// light_shadows: locals.buf.clone(),
|
// light_shadows: locals.buf.clone(),
|
||||||
// tgt_depth_stencil: shadow_map.point_depth_stencil_view.clone(),
|
// tgt_depth: shadow_map.point_depth_view.clone(),
|
||||||
// },
|
// },
|
||||||
// );
|
// );
|
||||||
// }
|
// }
|
||||||
@ -1457,8 +1451,8 @@ impl Renderer {
|
|||||||
|
|
||||||
// // Shadow stuff
|
// // Shadow stuff
|
||||||
// light_shadows: locals.buf.clone(),
|
// light_shadows: locals.buf.clone(),
|
||||||
// tgt_depth_stencil:
|
// tgt_depth:
|
||||||
// shadow_map.directed_depth_stencil_view.clone(), },
|
// shadow_map.directed_depth_view.clone(), },
|
||||||
// );
|
// );
|
||||||
// }
|
// }
|
||||||
|
|
||||||
@ -1503,8 +1497,8 @@ impl Renderer {
|
|||||||
|
|
||||||
// // Shadow stuff
|
// // Shadow stuff
|
||||||
// light_shadows: locals.buf.clone(),
|
// light_shadows: locals.buf.clone(),
|
||||||
// tgt_depth_stencil:
|
// tgt_depth:
|
||||||
// shadow_map.directed_depth_stencil_view.clone(), },
|
// shadow_map.directed_depth_view.clone(), },
|
||||||
// );
|
// );
|
||||||
// }
|
// }
|
||||||
|
|
||||||
@ -1560,8 +1554,8 @@ impl Renderer {
|
|||||||
// noise: (self.noise_tex.srv.clone(),
|
// noise: (self.noise_tex.srv.clone(),
|
||||||
// self.noise_tex.sampler.clone()), waves: (waves.srv.clone(),
|
// self.noise_tex.sampler.clone()), waves: (waves.srv.clone(),
|
||||||
// waves.sampler.clone()), tgt_color:
|
// waves.sampler.clone()), tgt_color:
|
||||||
// self.tgt_color_view.clone(), tgt_depth_stencil:
|
// self.tgt_color_view.clone(), tgt_depth:
|
||||||
// (self.tgt_depth_stencil_view.clone()/* , (1, 1) */), },
|
// (self.tgt_depth_view.clone()/* , (1, 1) */), },
|
||||||
// );
|
// );
|
||||||
// }
|
// }
|
||||||
|
|
||||||
@ -1625,8 +1619,8 @@ impl Renderer {
|
|||||||
// self.noise_tex.sampler.clone()), alt: (lod.alt.srv.clone(),
|
// self.noise_tex.sampler.clone()), alt: (lod.alt.srv.clone(),
|
||||||
// lod.alt.sampler.clone()), horizon: (lod.horizon.srv.clone(),
|
// lod.alt.sampler.clone()), horizon: (lod.horizon.srv.clone(),
|
||||||
// lod.horizon.sampler.clone()), tgt_color:
|
// lod.horizon.sampler.clone()), tgt_color:
|
||||||
// self.tgt_color_view.clone(), tgt_depth_stencil:
|
// self.tgt_color_view.clone(), tgt_depth:
|
||||||
// (self.tgt_depth_stencil_view.clone()/* , (1, 1) */), },
|
// (self.tgt_depth_view.clone()/* , (1, 1) */), },
|
||||||
// );
|
// );
|
||||||
// }
|
// }
|
||||||
|
|
||||||
@ -1657,8 +1651,8 @@ impl Renderer {
|
|||||||
// lod.map.sampler.clone()), alt: (lod.alt.srv.clone(),
|
// lod.map.sampler.clone()), alt: (lod.alt.srv.clone(),
|
||||||
// lod.alt.sampler.clone()), horizon: (lod.horizon.srv.clone(),
|
// lod.alt.sampler.clone()), horizon: (lod.horizon.srv.clone(),
|
||||||
// lod.horizon.sampler.clone()), tgt_color:
|
// lod.horizon.sampler.clone()), tgt_color:
|
||||||
// self.tgt_color_view.clone(), tgt_depth_stencil:
|
// self.tgt_color_view.clone(), tgt_depth:
|
||||||
// (self.tgt_depth_stencil_view.clone()/* , (1, 1) */), },
|
// (self.tgt_depth_view.clone()/* , (1, 1) */), },
|
||||||
// );
|
// );
|
||||||
// }
|
// }
|
||||||
|
|
||||||
@ -1711,8 +1705,8 @@ impl Renderer {
|
|||||||
// self.noise_tex.sampler.clone()), alt: (lod.alt.srv.clone(),
|
// self.noise_tex.sampler.clone()), alt: (lod.alt.srv.clone(),
|
||||||
// lod.alt.sampler.clone()), horizon: (lod.horizon.srv.clone(),
|
// lod.alt.sampler.clone()), horizon: (lod.horizon.srv.clone(),
|
||||||
// lod.horizon.sampler.clone()), tgt_color:
|
// lod.horizon.sampler.clone()), tgt_color:
|
||||||
// self.tgt_color_view.clone(), tgt_depth_stencil:
|
// self.tgt_color_view.clone(), tgt_depth:
|
||||||
// (self.tgt_depth_stencil_view.clone()/* , (1, 1) */), },
|
// (self.tgt_depth_view.clone()/* , (1, 1) */), },
|
||||||
// );
|
// );
|
||||||
// }
|
// }
|
||||||
|
|
||||||
@ -1836,7 +1830,7 @@ fn create_pipelines(
|
|||||||
fluid::FluidPipeline,
|
fluid::FluidPipeline,
|
||||||
sprite::SpritePipeline,
|
sprite::SpritePipeline,
|
||||||
particle::ParticlePipeline,
|
particle::ParticlePipeline,
|
||||||
ui::UIPipeline,
|
ui::UiPipeline,
|
||||||
lod_terrain::LodTerrainPipeline,
|
lod_terrain::LodTerrainPipeline,
|
||||||
clouds::CloudsPipeline,
|
clouds::CloudsPipeline,
|
||||||
postprocess::PostProcessPipeline,
|
postprocess::PostProcessPipeline,
|
||||||
@ -2029,7 +2023,7 @@ fn create_pipelines(
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Construct a pipeline for rendering UI elements
|
// Construct a pipeline for rendering UI elements
|
||||||
let ui_pipeline = ui::UIPipeline::new(
|
let ui_pipeline = ui::UiPipeline::new(
|
||||||
device,
|
device,
|
||||||
&create_shader("ui-vert", ShaderKind::Vertex)?,
|
&create_shader("ui-vert", ShaderKind::Vertex)?,
|
||||||
&create_shader("ui-frag", ShaderKind::Fragment)?,
|
&create_shader("ui-frag", ShaderKind::Fragment)?,
|
||||||
@ -2077,7 +2071,7 @@ fn create_pipelines(
|
|||||||
// let player_shadow_pipeline = create_pipeline(
|
// let player_shadow_pipeline = create_pipeline(
|
||||||
// factory,
|
// factory,
|
||||||
// figure::pipe::Init {
|
// figure::pipe::Init {
|
||||||
// tgt_depth_stencil: (gfx::preset::depth::PASS_TEST/*,
|
// tgt_depth: (gfx::preset::depth::PASS_TEST/*,
|
||||||
// Stencil::new(
|
// Stencil::new(
|
||||||
// Comparison::Equal,
|
// Comparison::Equal,
|
||||||
// 0xff,
|
// 0xff,
|
||||||
|
38
voxygen/src/render/renderer/bind_group.rs
Normal file
38
voxygen/src/render/renderer/bind_group.rs
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
use super::{
|
||||||
|
super::{
|
||||||
|
consts::Consts,
|
||||||
|
pipelines::{lod_terrain, ui, GlobalModel, GlobalsBindGroup},
|
||||||
|
texture::Texture,
|
||||||
|
},
|
||||||
|
Renderer,
|
||||||
|
};
|
||||||
|
|
||||||
|
impl Renderer {
|
||||||
|
pub fn bind_globals(
|
||||||
|
&self,
|
||||||
|
global_model: &GlobalModel,
|
||||||
|
lod_data: &lod_terrain::LodData,
|
||||||
|
) -> GlobalsBindGroup {
|
||||||
|
let (point_shadow_map, directed_shadow_map) = match &self.shadow_map {
|
||||||
|
Some(shadow_map) => (&shadow_map.point_depth, &shadow_map.directed_depth),
|
||||||
|
None => (&self.noise_tex, &self.noise_tex),
|
||||||
|
};
|
||||||
|
|
||||||
|
self.layouts.global.bind(
|
||||||
|
&self.device,
|
||||||
|
global_model,
|
||||||
|
lod_data,
|
||||||
|
&self.noise_tex,
|
||||||
|
point_shadow_map,
|
||||||
|
directed_shadow_map,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ui_bind_locals(&self, locals: &Consts<ui::Locals>) -> ui::LocalsBindGroup {
|
||||||
|
self.layouts.ui.bind_locals(&self.device, locals)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ui_bind_texture(&self, texture: &Texture) -> ui::TextureBindGroup {
|
||||||
|
self.layouts.ui.bind_texture(&self.device, texture)
|
||||||
|
}
|
||||||
|
}
|
360
voxygen/src/render/renderer/drawer.rs
Normal file
360
voxygen/src/render/renderer/drawer.rs
Normal file
@ -0,0 +1,360 @@
|
|||||||
|
use super::{
|
||||||
|
super::{
|
||||||
|
buffer::Buffer,
|
||||||
|
consts::Consts,
|
||||||
|
instances::Instances,
|
||||||
|
model::{DynamicModel, Model},
|
||||||
|
pipelines::{
|
||||||
|
figure, fluid, postprocess, sprite, terrain, ui, GlobalsBindGroup, Light, Shadow,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Renderer,
|
||||||
|
};
|
||||||
|
use std::ops::Range;
|
||||||
|
use vek::Aabr;
|
||||||
|
|
||||||
|
pub struct Drawer<'a> {
|
||||||
|
encoder: Option<wgpu::CommandEncoder>,
|
||||||
|
renderer: &'a mut Renderer,
|
||||||
|
tex: wgpu::SwapChainTexture,
|
||||||
|
globals: &'a GlobalsBindGroup,
|
||||||
|
//pub(super) postprocess_locals: wgpu::BindGroup,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Drawer<'a> {
|
||||||
|
pub fn new(
|
||||||
|
encoder: wgpu::CommandEncoder,
|
||||||
|
renderer: &'a mut Renderer,
|
||||||
|
tex: wgpu::SwapChainTexture,
|
||||||
|
globals: &'a GlobalsBindGroup,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
encoder: Some(encoder),
|
||||||
|
renderer,
|
||||||
|
tex,
|
||||||
|
globals,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*pub fn first_pass(&mut self) -> FirstPassDrawer {
|
||||||
|
let render_pass =
|
||||||
|
self.encoder
|
||||||
|
.as_mut()
|
||||||
|
.unwrap()
|
||||||
|
.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||||
|
color_attachments: &[wgpu::RenderPassColorAttachmentDescriptor {
|
||||||
|
attachment: &self.renderer.tgt_color_view,
|
||||||
|
resolve_target: None,
|
||||||
|
load_op: wgpu::LoadOp::Clear,
|
||||||
|
store_op: wgpu::StoreOp::Store,
|
||||||
|
clear_color: wgpu::Color::TRANSPARENT,
|
||||||
|
}],
|
||||||
|
depth_stencil_attachment: Some(
|
||||||
|
wgpu::RenderPassDepthStencilAttachmentDescriptor {
|
||||||
|
attachment: &self.renderer.depth_stencil_texture.view,
|
||||||
|
depth_load_op: wgpu::LoadOp::Clear,
|
||||||
|
depth_store_op: wgpu::StoreOp::Store,
|
||||||
|
clear_depth: 1.0,
|
||||||
|
stencil_load_op: wgpu::LoadOp::Clear,
|
||||||
|
stencil_store_op: wgpu::StoreOp::Store,
|
||||||
|
clear_stencil: 0,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
|
render_pass.set_bind_group(0, &self.globals.bind_group, &[]);
|
||||||
|
|
||||||
|
FirstPassDrawer {
|
||||||
|
render_pass,
|
||||||
|
renderer: &self.renderer,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn second_pass(&mut self) -> SecondPassDrawer {
|
||||||
|
let render_pass =
|
||||||
|
self.encoder
|
||||||
|
.as_mut()
|
||||||
|
.unwrap()
|
||||||
|
.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||||
|
color_attachments: &[wgpu::RenderPassColorAttachmentDescriptor {
|
||||||
|
attachment: &self.renderer.tgt_color_pp_view,
|
||||||
|
resolve_target: None,
|
||||||
|
load_op: wgpu::LoadOp::Clear,
|
||||||
|
store_op: wgpu::StoreOp::Store,
|
||||||
|
clear_color: wgpu::Color::TRANSPARENT,
|
||||||
|
}],
|
||||||
|
depth_stencil_attachment: None,
|
||||||
|
});
|
||||||
|
|
||||||
|
render_pass.set_bind_group(0, &self.globals.bind_group, &[]);
|
||||||
|
|
||||||
|
SecondPassDrawer {
|
||||||
|
render_pass,
|
||||||
|
renderer: &self.renderer,
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
pub fn third_pass(&mut self) -> ThirdPassDrawer {
|
||||||
|
let mut render_pass =
|
||||||
|
self.encoder
|
||||||
|
.as_mut()
|
||||||
|
.unwrap()
|
||||||
|
.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||||
|
color_attachments: &[wgpu::RenderPassColorAttachmentDescriptor {
|
||||||
|
attachment: &self.tex.view,
|
||||||
|
resolve_target: None,
|
||||||
|
ops: wgpu::Operations {
|
||||||
|
load: wgpu::LoadOp::Clear(wgpu::Color {
|
||||||
|
r: 1.0,
|
||||||
|
g: 0.25,
|
||||||
|
b: 0.5,
|
||||||
|
a: 0.5,
|
||||||
|
}),
|
||||||
|
store: true,
|
||||||
|
},
|
||||||
|
}],
|
||||||
|
// TODO: do we need this?
|
||||||
|
depth_stencil_attachment: Some(
|
||||||
|
wgpu::RenderPassDepthStencilAttachmentDescriptor {
|
||||||
|
attachment: &self.renderer.win_depth_view,
|
||||||
|
depth_ops: Some(wgpu::Operations {
|
||||||
|
load: wgpu::LoadOp::Clear(1.0),
|
||||||
|
store: true,
|
||||||
|
}),
|
||||||
|
stencil_ops: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
|
render_pass.set_bind_group(0, &self.globals.bind_group, &[]);
|
||||||
|
|
||||||
|
ThirdPassDrawer {
|
||||||
|
render_pass,
|
||||||
|
renderer: &self.renderer,
|
||||||
|
//postprocess_locals: &self.postprocess_locals,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Drop for Drawer<'a> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
self.renderer
|
||||||
|
.queue
|
||||||
|
.submit(std::iter::once(self.encoder.take().unwrap().finish()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*pub struct FirstPassDrawer<'a> {
|
||||||
|
pub(super) render_pass: wgpu::RenderPass<'a>,
|
||||||
|
pub renderer: &'a Renderer,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> FirstPassDrawer<'a> {
|
||||||
|
pub fn draw_skybox<'b: 'a>(
|
||||||
|
&mut self,
|
||||||
|
model: &'b Model,
|
||||||
|
globals: &'b Consts<Globals>,
|
||||||
|
verts: Range<u32>,
|
||||||
|
) {
|
||||||
|
self.render_pass
|
||||||
|
.set_pipeline(&self.renderer.skybox_pipeline.pipeline);
|
||||||
|
self.render_pass.set_bind_group(0, &globals.bind_group, &[]);
|
||||||
|
self.render_pass.set_vertex_buffer(0, &model.vbuf, 0, 0);
|
||||||
|
self.render_pass.draw(verts, 0..1);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn draw_figure<'b: 'a>(
|
||||||
|
&mut self,
|
||||||
|
model: &'b Model,
|
||||||
|
locals: &'b Consts<figure::Locals>,
|
||||||
|
bones: &'b Consts<figure::BoneData>,
|
||||||
|
globals: &'b Consts<Globals>,
|
||||||
|
lights: &'b Consts<Light>,
|
||||||
|
shadows: &'b Consts<Shadow>,
|
||||||
|
verts: Range<u32>,
|
||||||
|
) {
|
||||||
|
self.render_pass
|
||||||
|
.set_pipeline(&self.renderer.figure_pipeline.pipeline);
|
||||||
|
self.render_pass.set_bind_group(0, &globals.bind_group, &[]);
|
||||||
|
self.render_pass.set_bind_group(1, &lights.bind_group, &[]);
|
||||||
|
self.render_pass.set_bind_group(2, &shadows.bind_group, &[]);
|
||||||
|
self.render_pass.set_bind_group(3, &locals.bind_group, &[]);
|
||||||
|
self.render_pass.set_bind_group(4, &bones.bind_group, &[]);
|
||||||
|
self.render_pass.set_vertex_buffer(0, &model.vbuf, 0, 0);
|
||||||
|
self.render_pass.draw(verts, 0..1);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn draw_terrain<'b: 'a>(
|
||||||
|
&mut self,
|
||||||
|
model: &'b Model,
|
||||||
|
locals: &'b Consts<terrain::Locals>,
|
||||||
|
globals: &'b Consts<Globals>,
|
||||||
|
lights: &'b Consts<Light>,
|
||||||
|
shadows: &'b Consts<Shadow>,
|
||||||
|
verts: Range<u32>,
|
||||||
|
) {
|
||||||
|
self.render_pass
|
||||||
|
.set_pipeline(&self.renderer.terrain_pipeline.pipeline);
|
||||||
|
self.render_pass.set_bind_group(0, &globals.bind_group, &[]);
|
||||||
|
self.render_pass.set_bind_group(1, &lights.bind_group, &[]);
|
||||||
|
self.render_pass.set_bind_group(2, &shadows.bind_group, &[]);
|
||||||
|
self.render_pass.set_bind_group(3, &locals.bind_group, &[]);
|
||||||
|
self.render_pass.set_vertex_buffer(0, &model.vbuf, 0, 0);
|
||||||
|
self.render_pass.draw(verts, 0..1)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn draw_fluid<'b: 'a>(
|
||||||
|
&mut self,
|
||||||
|
model: &'b Model,
|
||||||
|
locals: &'b Consts<terrain::Locals>,
|
||||||
|
waves: &'b Consts<fluid::Locals>,
|
||||||
|
globals: &'b Consts<Globals>,
|
||||||
|
lights: &'b Consts<Light>,
|
||||||
|
shadows: &'b Consts<Shadow>,
|
||||||
|
verts: Range<u32>,
|
||||||
|
) {
|
||||||
|
self.render_pass
|
||||||
|
.set_pipeline(&self.renderer.fluid_pipeline.pipeline);
|
||||||
|
self.render_pass.set_bind_group(0, &globals.bind_group, &[]);
|
||||||
|
self.render_pass.set_bind_group(1, &lights.bind_group, &[]);
|
||||||
|
self.render_pass.set_bind_group(2, &shadows.bind_group, &[]);
|
||||||
|
self.render_pass.set_bind_group(3, &locals.bind_group, &[]);
|
||||||
|
self.render_pass.set_bind_group(4, &waves.bind_group, &[]);
|
||||||
|
self.render_pass.set_vertex_buffer(0, &model.vbuf, 0, 0);
|
||||||
|
self.render_pass.draw(verts, 0..1);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn draw_sprite<'b: 'a>(
|
||||||
|
&mut self,
|
||||||
|
model: &'b Model,
|
||||||
|
instances: &'a Instances<sprite::Instance>,
|
||||||
|
globals: &'b Consts<Globals>,
|
||||||
|
lights: &'b Consts<Light>,
|
||||||
|
shadows: &'b Consts<Shadow>,
|
||||||
|
verts: Range<u32>,
|
||||||
|
) {
|
||||||
|
self.render_pass
|
||||||
|
.set_pipeline(&self.renderer.sprite_pipeline.pipeline);
|
||||||
|
self.render_pass.set_bind_group(0, &globals.bind_group, &[]);
|
||||||
|
self.render_pass.set_bind_group(1, &lights.bind_group, &[]);
|
||||||
|
self.render_pass.set_bind_group(2, &shadows.bind_group, &[]);
|
||||||
|
self.render_pass.set_vertex_buffer(0, &model.vbuf, 0, 0);
|
||||||
|
self.render_pass.set_vertex_buffer(1, &instances.ibuf, 0, 0);
|
||||||
|
self.render_pass.draw(verts, 0..instances.count() as u32);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct SecondPassDrawer<'a> {
|
||||||
|
pub(super) render_pass: wgpu::RenderPass<'a>,
|
||||||
|
pub renderer: &'a Renderer,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> SecondPassDrawer<'a> {
|
||||||
|
pub fn draw_post_process<'b: 'a>(
|
||||||
|
&mut self,
|
||||||
|
model: &'b Model,
|
||||||
|
globals: &'b Consts<Globals>,
|
||||||
|
verts: Range<u32>,
|
||||||
|
) {
|
||||||
|
self.render_pass
|
||||||
|
.set_pipeline(&self.renderer.postprocess_pipeline.pipeline);
|
||||||
|
self.render_pass.set_bind_group(0, &globals.bind_group, &[]);
|
||||||
|
self.render_pass
|
||||||
|
.set_bind_group(1, self.postprocess_locals, &[]);
|
||||||
|
self.render_pass.set_vertex_buffer(0, &model.vbuf, 0, 0);
|
||||||
|
self.render_pass.draw(verts, 0..1);
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
pub struct ThirdPassDrawer<'a> {
|
||||||
|
render_pass: wgpu::RenderPass<'a>,
|
||||||
|
renderer: &'a Renderer,
|
||||||
|
//postprocess_locals: &'a wgpu::BindGroup,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> ThirdPassDrawer<'a> {
|
||||||
|
pub fn draw_post_process<'b: 'a>(
|
||||||
|
&mut self,
|
||||||
|
model: &'b Model<postprocess::Vertex>,
|
||||||
|
verts: Range<u32>,
|
||||||
|
) {
|
||||||
|
self.render_pass
|
||||||
|
.set_pipeline(&self.renderer.postprocess_pipeline.pipeline);
|
||||||
|
//self.render_pass
|
||||||
|
// .set_bind_group(1, self.postprocess_locals, &[]);
|
||||||
|
self.render_pass.set_vertex_buffer(0, model.buf().slice(..));
|
||||||
|
self.render_pass.draw(verts, 0..1);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn draw_ui<'c>(&'c mut self) -> UiDrawer<'c, 'a> {
|
||||||
|
self.render_pass
|
||||||
|
.set_pipeline(&self.renderer.ui_pipeline.pipeline);
|
||||||
|
|
||||||
|
UiDrawer {
|
||||||
|
render_pass: &mut self.render_pass,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct UiDrawer<'pass_ref, 'pass: 'pass_ref> {
|
||||||
|
render_pass: &'pass_ref mut wgpu::RenderPass<'pass>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct PreparedUiDrawer<'pass_ref, 'pass: 'pass_ref> {
|
||||||
|
render_pass: &'pass_ref mut wgpu::RenderPass<'pass>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'pass_ref, 'pass: 'pass_ref> UiDrawer<'pass_ref, 'pass> {
|
||||||
|
/// Set vertex buffer, initial scissor, and locals
|
||||||
|
/// These can be changed later but this ensures that they don't have to be
|
||||||
|
/// set with every draw call
|
||||||
|
pub fn prepare<'data: 'pass>(
|
||||||
|
&mut self,
|
||||||
|
locals: &'data ui::LocalsBindGroup,
|
||||||
|
//texture: &'b ui::TextureBindGroup,
|
||||||
|
buf: &'data DynamicModel<ui::Vertex>,
|
||||||
|
scissor: Aabr<u16>,
|
||||||
|
) -> PreparedUiDrawer<'_, 'pass> {
|
||||||
|
// Note: not actually prepared yet
|
||||||
|
// we do this to avoid having to write extra code for the set functions
|
||||||
|
let mut prepared = PreparedUiDrawer {
|
||||||
|
render_pass: self.render_pass,
|
||||||
|
};
|
||||||
|
// Prepare
|
||||||
|
prepared.set_locals(locals);
|
||||||
|
//prepared.set_texture(texture);
|
||||||
|
prepared.set_model(buf);
|
||||||
|
prepared.set_scissor(scissor);
|
||||||
|
|
||||||
|
prepared
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'pass_ref, 'pass: 'pass_ref> PreparedUiDrawer<'pass_ref, 'pass> {
|
||||||
|
pub fn set_locals<'data: 'pass>(&mut self, locals: &'data ui::LocalsBindGroup) {
|
||||||
|
self.render_pass.set_bind_group(1, &locals.bind_group, &[]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//pub fn set_texture<'b: 'a>(&mut self, texture: &'b ui::TextureBindGroup) {
|
||||||
|
// self.render_pass.set_bind_group(1, &texture.bind_group, &[]);
|
||||||
|
//}
|
||||||
|
|
||||||
|
pub fn set_model<'data: 'pass>(&mut self, model: &'data DynamicModel<ui::Vertex>) {
|
||||||
|
self.render_pass.set_vertex_buffer(0, model.buf().slice(..))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_scissor<'data: 'pass>(&mut self, scissor: Aabr<u16>) {
|
||||||
|
let Aabr { min, max } = scissor;
|
||||||
|
//self.render_pass.set_scissor_rect(
|
||||||
|
// min.x as u32,
|
||||||
|
// min.y as u32,
|
||||||
|
// (max.x - min.x) as u32,
|
||||||
|
// (max.y - min.y) as u32,
|
||||||
|
//);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn draw<'data: 'pass>(&mut self, texture: &'data ui::TextureBindGroup, verts: Range<u32>) {
|
||||||
|
self.render_pass.set_bind_group(2, &texture.bind_group, &[]);
|
||||||
|
self.render_pass.draw(verts, 0..1);
|
||||||
|
}
|
||||||
|
}
|
@ -179,7 +179,7 @@ impl Texture {
|
|||||||
data: &[u8],
|
data: &[u8],
|
||||||
) {
|
) {
|
||||||
// Note: we only accept 4 bytes per pixel
|
// Note: we only accept 4 bytes per pixel
|
||||||
// (enforce this is API?)
|
// (enforce this in API?)
|
||||||
debug_assert_eq!(data.len(), size[0] as usize * size[1] as usize * 4);
|
debug_assert_eq!(data.len(), size[0] as usize * size[1] as usize * 4);
|
||||||
// TODO: Only works for 2D images
|
// TODO: Only works for 2D images
|
||||||
queue.write_texture(
|
queue.write_texture(
|
||||||
|
@ -176,7 +176,7 @@ fn handle_main_events_cleared(
|
|||||||
last.render(renderer, &global_state.settings);
|
last.render(renderer, &global_state.settings);
|
||||||
// Finish the frame.
|
// Finish the frame.
|
||||||
// TODO: do this as part of dropping rendering thing
|
// TODO: do this as part of dropping rendering thing
|
||||||
global_state.window.renderer_mut().flush().unwrap();
|
//global_state.window.renderer_mut().flush().unwrap();
|
||||||
// // Display the frame on the window.
|
// // Display the frame on the window.
|
||||||
// global_state
|
// global_state
|
||||||
// .window
|
// .window
|
||||||
|
@ -8,13 +8,13 @@ use crate::{
|
|||||||
ecs::comp::Interpolated,
|
ecs::comp::Interpolated,
|
||||||
render::{
|
render::{
|
||||||
pipelines, ColLightInfo, Consts, FigureBoneData, FigureLocals, FigureModel, GlobalModel,
|
pipelines, ColLightInfo, Consts, FigureBoneData, FigureLocals, FigureModel, GlobalModel,
|
||||||
Mesh, RenderError, Renderer, SubModel, TerrainVertex, Texture,
|
LodData, Mesh, RenderError, Renderer, SubModel, TerrainVertex, Texture,
|
||||||
},
|
},
|
||||||
scene::{
|
scene::{
|
||||||
camera::{Camera, CameraMode, Dependents},
|
camera::{Camera, CameraMode, Dependents},
|
||||||
math,
|
math,
|
||||||
terrain::Terrain,
|
terrain::Terrain,
|
||||||
LodData, SceneData,
|
SceneData,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use anim::{
|
use anim::{
|
||||||
@ -5352,8 +5352,8 @@ impl<S: Skeleton> FigureState<S> {
|
|||||||
let bone_consts = figure_bone_data_from_anim(&buf);
|
let bone_consts = figure_bone_data_from_anim(&buf);
|
||||||
Self {
|
Self {
|
||||||
meta: FigureStateMeta {
|
meta: FigureStateMeta {
|
||||||
bone_consts: renderer.create_consts(bone_consts).unwrap(),
|
bone_consts: renderer.create_consts(bone_consts),
|
||||||
locals: renderer.create_consts(&[FigureLocals::default()]).unwrap(),
|
locals: renderer.create_consts(&[FigureLocals::default()]),
|
||||||
lantern_offset,
|
lantern_offset,
|
||||||
state_time: 0.0,
|
state_time: 0.0,
|
||||||
last_ori: Ori::default().into(),
|
last_ori: Ori::default().into(),
|
||||||
|
@ -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, CloudsVertex, Consts,
|
create_clouds_mesh, create_pp_mesh, create_skybox_mesh, CloudsLocals, CloudsVertex, Consts,
|
||||||
GlobalModel, Globals, Light, LodData, Model, PostProcessLocals, PostProcessVertex,
|
GlobalModel, Globals, Light, Model, PostProcessLocals, PostProcessVertex, Renderer, Shadow,
|
||||||
Renderer, Shadow, ShadowLocals, SkyboxVertex,
|
ShadowLocals, SkyboxVertex,
|
||||||
},
|
},
|
||||||
settings::Settings,
|
settings::Settings,
|
||||||
window::{AnalogGameInput, Event},
|
window::{AnalogGameInput, Event},
|
||||||
@ -277,16 +277,11 @@ impl Scene {
|
|||||||
|
|
||||||
Self {
|
Self {
|
||||||
data: GlobalModel {
|
data: GlobalModel {
|
||||||
globals: renderer.create_consts(&[Globals::default()]).unwrap(),
|
globals: renderer.create_consts(&[Globals::default()]),
|
||||||
lights: renderer
|
lights: renderer.create_consts(&[Light::default(); MAX_LIGHT_COUNT]),
|
||||||
.create_consts(&[Light::default(); MAX_LIGHT_COUNT])
|
shadows: renderer.create_consts(&[Shadow::default(); MAX_SHADOW_COUNT]),
|
||||||
.unwrap(),
|
|
||||||
shadows: renderer
|
|
||||||
.create_consts(&[Shadow::default(); MAX_SHADOW_COUNT])
|
|
||||||
.unwrap(),
|
|
||||||
shadow_mats: renderer
|
shadow_mats: renderer
|
||||||
.create_consts(&[ShadowLocals::default(); MAX_LIGHT_COUNT * 6 + 6])
|
.create_consts(&[ShadowLocals::default(); MAX_LIGHT_COUNT * 6 + 6]),
|
||||||
.unwrap(),
|
|
||||||
},
|
},
|
||||||
camera: Camera::new(resolution.x / resolution.y, CameraMode::ThirdPerson),
|
camera: Camera::new(resolution.x / resolution.y, CameraMode::ThirdPerson),
|
||||||
camera_input_state: Vec2::zero(),
|
camera_input_state: Vec2::zero(),
|
||||||
@ -297,13 +292,11 @@ impl Scene {
|
|||||||
},
|
},
|
||||||
clouds: Clouds {
|
clouds: Clouds {
|
||||||
model: renderer.create_model(&create_clouds_mesh()).unwrap(),
|
model: renderer.create_model(&create_clouds_mesh()).unwrap(),
|
||||||
locals: renderer.create_consts(&[CloudsLocals::default()]).unwrap(),
|
locals: renderer.create_consts(&[CloudsLocals::default()]),
|
||||||
},
|
},
|
||||||
postprocess: PostProcess {
|
postprocess: PostProcess {
|
||||||
model: renderer.create_model(&create_pp_mesh()).unwrap(),
|
model: renderer.create_model(&create_pp_mesh()).unwrap(),
|
||||||
locals: renderer
|
locals: renderer.create_consts(&[PostProcessLocals::default()]),
|
||||||
.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),
|
||||||
|
@ -2,14 +2,13 @@ use crate::{
|
|||||||
mesh::{greedy::GreedyMesh, segment::generate_mesh_base_vol_terrain},
|
mesh::{greedy::GreedyMesh, segment::generate_mesh_base_vol_terrain},
|
||||||
render::{
|
render::{
|
||||||
create_clouds_mesh, create_pp_mesh, create_skybox_mesh, BoneMeshes, CloudsLocals,
|
create_clouds_mesh, create_pp_mesh, create_skybox_mesh, BoneMeshes, CloudsLocals,
|
||||||
CloudsVertex, Consts, FigureModel, GlobalModel, Globals, Light, Mesh, Model,
|
CloudsVertex, Consts, FigureModel, GlobalModel, Globals, Light, LodData, Mesh, Model,
|
||||||
PostProcessLocals, PostProcessVertex, Renderer, Shadow, ShadowLocals, SkyboxVertex,
|
PostProcessLocals, PostProcessVertex, Renderer, Shadow, ShadowLocals, SkyboxVertex,
|
||||||
TerrainVertex,
|
TerrainVertex,
|
||||||
},
|
},
|
||||||
scene::{
|
scene::{
|
||||||
camera::{self, Camera, CameraMode},
|
camera::{self, Camera, CameraMode},
|
||||||
figure::{load_mesh, FigureColLights, FigureModelCache, FigureModelEntry, FigureState},
|
figure::{load_mesh, FigureColLights, FigureModelCache, FigureModelEntry, FigureState},
|
||||||
LodData,
|
|
||||||
},
|
},
|
||||||
window::{Event, PressState},
|
window::{Event, PressState},
|
||||||
};
|
};
|
||||||
@ -110,10 +109,6 @@ impl Scene {
|
|||||||
client.world_data().min_chunk_alt(),
|
client.world_data().min_chunk_alt(),
|
||||||
client.world_data().max_chunk_alt(),
|
client.world_data().max_chunk_alt(),
|
||||||
);
|
);
|
||||||
let map_border = [0.0, 0.0, 0.0, 0.0];
|
|
||||||
let map_image = [0];
|
|
||||||
let alt_image = [0];
|
|
||||||
let horizon_image = [0x_00_01_00_01];
|
|
||||||
|
|
||||||
let mut camera = Camera::new(resolution.x / resolution.y, CameraMode::ThirdPerson);
|
let mut camera = Camera::new(resolution.x / resolution.y, CameraMode::ThirdPerson);
|
||||||
camera.set_focus_pos(Vec3::unit_z() * 1.5);
|
camera.set_focus_pos(Vec3::unit_z() * 1.5);
|
||||||
@ -124,12 +119,10 @@ impl Scene {
|
|||||||
|
|
||||||
Self {
|
Self {
|
||||||
data: GlobalModel {
|
data: GlobalModel {
|
||||||
globals: renderer.create_consts(&[Globals::default()]).unwrap(),
|
globals: renderer.create_consts(&[Globals::default()]),
|
||||||
lights: renderer.create_consts(&[Light::default(); 32]).unwrap(),
|
lights: renderer.create_consts(&[Light::default(); 32]),
|
||||||
shadows: renderer.create_consts(&[Shadow::default(); 32]).unwrap(),
|
shadows: renderer.create_consts(&[Shadow::default(); 32]),
|
||||||
shadow_mats: renderer
|
shadow_mats: renderer.create_consts(&[ShadowLocals::default(); 6]),
|
||||||
.create_consts(&[ShadowLocals::default(); 6])
|
|
||||||
.unwrap(),
|
|
||||||
},
|
},
|
||||||
|
|
||||||
skybox: Skybox {
|
skybox: Skybox {
|
||||||
@ -137,23 +130,13 @@ impl Scene {
|
|||||||
},
|
},
|
||||||
clouds: Clouds {
|
clouds: Clouds {
|
||||||
model: renderer.create_model(&create_clouds_mesh()).unwrap(),
|
model: renderer.create_model(&create_clouds_mesh()).unwrap(),
|
||||||
locals: renderer.create_consts(&[CloudsLocals::default()]).unwrap(),
|
locals: renderer.create_consts(&[CloudsLocals::default()]),
|
||||||
},
|
},
|
||||||
postprocess: PostProcess {
|
postprocess: PostProcess {
|
||||||
model: renderer.create_model(&create_pp_mesh()).unwrap(),
|
model: renderer.create_model(&create_pp_mesh()).unwrap(),
|
||||||
locals: renderer
|
locals: renderer.create_consts(&[PostProcessLocals::default()]),
|
||||||
.create_consts(&[PostProcessLocals::default()])
|
|
||||||
.unwrap(),
|
|
||||||
},
|
},
|
||||||
lod: LodData::new(
|
lod: LodData::dummy(renderer),
|
||||||
renderer,
|
|
||||||
Vec2::new(1, 1),
|
|
||||||
&map_image,
|
|
||||||
&alt_image,
|
|
||||||
&horizon_image,
|
|
||||||
1,
|
|
||||||
//map_border.into(),
|
|
||||||
),
|
|
||||||
map_bounds,
|
map_bounds,
|
||||||
|
|
||||||
figure_model_cache: FigureModelCache::new(),
|
figure_model_cache: FigureModelCache::new(),
|
||||||
|
@ -8,13 +8,13 @@ use crate::{
|
|||||||
terrain::{generate_mesh, SUNLIGHT},
|
terrain::{generate_mesh, SUNLIGHT},
|
||||||
},
|
},
|
||||||
render::{
|
render::{
|
||||||
pipelines, ColLightInfo, Consts, FluidVertex, GlobalModel, Instances, Mesh, Model,
|
pipelines, ColLightInfo, Consts, FluidVertex, GlobalModel, Instances, LodData, Mesh, Model,
|
||||||
RenderError, Renderer, SpriteInstance, SpriteLocals, SpriteVertex, TerrainLocals,
|
RenderError, Renderer, SpriteInstance, SpriteLocals, SpriteVertex, TerrainLocals,
|
||||||
TerrainVertex, Texture,
|
TerrainVertex, Texture,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{math, LodData, SceneData};
|
use super::{math, SceneData};
|
||||||
use common::{
|
use common::{
|
||||||
assets::{self, AssetExt, DotVoxAsset},
|
assets::{self, AssetExt, DotVoxAsset},
|
||||||
figure::Segment,
|
figure::Segment,
|
||||||
@ -517,9 +517,7 @@ impl SpriteRenderContext {
|
|||||||
offset,
|
offset,
|
||||||
}| {
|
}| {
|
||||||
SpriteData {
|
SpriteData {
|
||||||
locals: renderer
|
locals: renderer.create_consts(&locals_buffer),
|
||||||
.create_consts(&locals)
|
|
||||||
.expect("Failed to upload sprite locals to the GPU!"),
|
|
||||||
model: renderer.create_model(&model).expect(
|
model: renderer.create_model(&model).expect(
|
||||||
"Failed to upload sprite model data to the GPU!",
|
"Failed to upload sprite model data to the GPU!",
|
||||||
),
|
),
|
||||||
@ -1161,24 +1159,22 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
light_map: mesh.light_map,
|
light_map: mesh.light_map,
|
||||||
glow_map: mesh.glow_map,
|
glow_map: mesh.glow_map,
|
||||||
sprite_instances,
|
sprite_instances,
|
||||||
locals: renderer
|
locals: renderer.create_consts(&[TerrainLocals {
|
||||||
.create_consts(&[TerrainLocals {
|
model_offs: Vec3::from(
|
||||||
model_offs: Vec3::from(
|
response.pos.map2(VolGrid2d::<V>::chunk_size(), |e, sz| {
|
||||||
response.pos.map2(VolGrid2d::<V>::chunk_size(), |e, sz| {
|
e as f32 * sz as f32
|
||||||
e as f32 * sz as f32
|
}),
|
||||||
}),
|
)
|
||||||
)
|
.into_array(),
|
||||||
.into_array(),
|
atlas_offs: Vec4::new(
|
||||||
atlas_offs: Vec4::new(
|
atlas_offs.x as i32,
|
||||||
atlas_offs.x as i32,
|
atlas_offs.y as i32,
|
||||||
atlas_offs.y as i32,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
)
|
||||||
)
|
.into_array(),
|
||||||
.into_array(),
|
load_time,
|
||||||
load_time,
|
}]),
|
||||||
}])
|
|
||||||
.expect("Failed to upload chunk locals to the GPU!"),
|
|
||||||
visible: Visibility {
|
visible: Visibility {
|
||||||
in_range: false,
|
in_range: false,
|
||||||
in_frustum: false,
|
in_frustum: false,
|
||||||
|
@ -3,7 +3,7 @@ mod renderer;
|
|||||||
|
|
||||||
pub use renderer::{SampleStrat, Transform};
|
pub use renderer::{SampleStrat, Transform};
|
||||||
|
|
||||||
use crate::render::{Renderer, Texture};
|
use crate::render::{Renderer, Texture, UiTextureBindGroup};
|
||||||
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};
|
||||||
@ -139,7 +139,7 @@ pub struct GraphicCache {
|
|||||||
|
|
||||||
// Atlases with the index of their texture in the textures vec
|
// Atlases with the index of their texture in the textures vec
|
||||||
atlases: Vec<(SimpleAtlasAllocator, usize)>,
|
atlases: Vec<(SimpleAtlasAllocator, usize)>,
|
||||||
textures: Vec<Texture>,
|
textures: Vec<(Texture, UiTextureBindGroup)>,
|
||||||
// Stores the location of graphics rendered at a particular resolution and cached on the cpu
|
// Stores the location of graphics rendered at a particular resolution and cached on the cpu
|
||||||
cache_map: HashMap<Parameters, CachedDetails>,
|
cache_map: HashMap<Parameters, CachedDetails>,
|
||||||
}
|
}
|
||||||
@ -184,7 +184,7 @@ impl GraphicCache {
|
|||||||
pub fn get_graphic(&self, id: Id) -> Option<&Graphic> { self.graphic_map.get(&id) }
|
pub fn get_graphic(&self, id: Id) -> Option<&Graphic> { self.graphic_map.get(&id) }
|
||||||
|
|
||||||
/// Used to acquire textures for rendering
|
/// Used to acquire textures for rendering
|
||||||
pub fn get_tex(&self, id: TexId) -> &Texture {
|
pub fn get_tex(&self, id: TexId) -> &(Texture, UiTextureBindGroup) {
|
||||||
self.textures.get(id.0).expect("Invalid TexId used")
|
self.textures.get(id.0).expect("Invalid TexId used")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -284,7 +284,7 @@ impl GraphicCache {
|
|||||||
// color.
|
// color.
|
||||||
assert!(border.is_none());
|
assert!(border.is_none());
|
||||||
// Transfer to the gpu
|
// Transfer to the gpu
|
||||||
upload_image(renderer, aabr, &textures[idx], &image);
|
upload_image(renderer, aabr, &textures[idx].0, &image);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Some((transformed_aabr(aabr.map(|e| e as f64)), TexId(idx)));
|
return Some((transformed_aabr(aabr.map(|e| e as f64)), TexId(idx)));
|
||||||
@ -324,7 +324,7 @@ impl GraphicCache {
|
|||||||
valid: true,
|
valid: true,
|
||||||
aabr,
|
aabr,
|
||||||
});
|
});
|
||||||
upload_image(renderer, aabr, &textures[texture_idx], &image);
|
upload_image(renderer, aabr, &textures[texture_idx].0, &image);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -344,7 +344,7 @@ impl GraphicCache {
|
|||||||
let atlas_idx = atlases.len();
|
let atlas_idx = atlases.len();
|
||||||
textures.push(texture);
|
textures.push(texture);
|
||||||
atlases.push((atlas, tex_idx));
|
atlases.push((atlas, tex_idx));
|
||||||
upload_image(renderer, aabr, &textures[tex_idx], &image);
|
upload_image(renderer, aabr, &textures[tex_idx].0, &image);
|
||||||
CachedDetails::Atlas {
|
CachedDetails::Atlas {
|
||||||
atlas_idx,
|
atlas_idx,
|
||||||
valid: true,
|
valid: true,
|
||||||
@ -354,7 +354,11 @@ impl GraphicCache {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Create a texture just for this
|
// Create a texture just for this
|
||||||
let texture = renderer.create_dynamic_texture(dims.map(|e| e as u32));
|
let texture = {
|
||||||
|
let tex = renderer.create_dynamic_texture(dims.map(|e| e as u32));
|
||||||
|
let bind = renderer.ui_bind_texture(&tex);
|
||||||
|
(tex, bind)
|
||||||
|
};
|
||||||
// NOTE: All mutations happen only after the texture creation succeeds!
|
// NOTE: All mutations happen only after the texture creation succeeds!
|
||||||
let index = textures.len();
|
let index = textures.len();
|
||||||
textures.push(texture);
|
textures.push(texture);
|
||||||
@ -365,7 +369,7 @@ impl GraphicCache {
|
|||||||
// Note texture should always match the cached dimensions
|
// Note texture should always match the cached dimensions
|
||||||
max: dims,
|
max: dims,
|
||||||
},
|
},
|
||||||
&textures[index],
|
&textures[index].0,
|
||||||
&image,
|
&image,
|
||||||
);
|
);
|
||||||
CachedDetails::Texture { index, valid: true }
|
CachedDetails::Texture { index, valid: true }
|
||||||
@ -419,11 +423,18 @@ fn atlas_size(renderer: &Renderer) -> Vec2<u32> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_atlas_texture(renderer: &mut Renderer) -> (SimpleAtlasAllocator, Texture) {
|
fn create_atlas_texture(
|
||||||
|
renderer: &mut Renderer,
|
||||||
|
) -> (SimpleAtlasAllocator, (Texture, UiTextureBindGroup)) {
|
||||||
let size = atlas_size(renderer);
|
let size = atlas_size(renderer);
|
||||||
// Note: here we assume the atlas size is under i32::MAX
|
// Note: here we assume the atlas size is under i32::MAX
|
||||||
let atlas = SimpleAtlasAllocator::new(size2(size.x as i32, size.y as i32));
|
let atlas = SimpleAtlasAllocator::new(size2(size.x as i32, size.y as i32));
|
||||||
let texture = renderer.create_dynamic_texture(size);
|
let texture = {
|
||||||
|
let tex = renderer.create_dynamic_texture(size);
|
||||||
|
let bind = renderer.ui_bind_texture(&tex);
|
||||||
|
(tex, bind)
|
||||||
|
};
|
||||||
|
|
||||||
(atlas, texture)
|
(atlas, texture)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -449,8 +460,12 @@ fn upload_image(renderer: &mut Renderer, aabr: Aabr<u16>, tex: &Texture, image:
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_image(renderer: &mut Renderer, image: RgbaImage, border_color: Rgba<f32>) -> Texture {
|
fn create_image(
|
||||||
renderer
|
renderer: &mut Renderer,
|
||||||
|
image: RgbaImage,
|
||||||
|
border_color: Rgba<f32>,
|
||||||
|
) -> (Texture, UiTextureBindGroup) {
|
||||||
|
let tex = renderer
|
||||||
.create_texture(
|
.create_texture(
|
||||||
&DynamicImage::ImageRgba8(image),
|
&DynamicImage::ImageRgba8(image),
|
||||||
None,
|
None,
|
||||||
@ -458,5 +473,8 @@ fn create_image(renderer: &mut Renderer, image: RgbaImage, border_color: Rgba<f3
|
|||||||
// Some(border_color.into_array().into()),
|
// Some(border_color.into_array().into()),
|
||||||
Some(wgpu::AddressMode::ClampToBorder),
|
Some(wgpu::AddressMode::ClampToBorder),
|
||||||
)
|
)
|
||||||
.expect("create_texture only panics is non ImageRbga8 is passed")
|
.expect("create_texture only panics is non ImageRbga8 is passed");
|
||||||
|
let bind = renderer.ui_bind_texture(&tex);
|
||||||
|
|
||||||
|
(tex, bind)
|
||||||
}
|
}
|
||||||
|
@ -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::{Renderer, Texture},
|
render::{Renderer, Texture, UiTextureBindGroup},
|
||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
use common::assets::{self, AssetExt};
|
use common::assets::{self, AssetExt};
|
||||||
@ -46,7 +46,7 @@ pub struct FontId(pub(super) glyph_brush::FontId);
|
|||||||
|
|
||||||
pub struct Cache {
|
pub struct Cache {
|
||||||
glyph_brush: RefCell<GlyphBrush>,
|
glyph_brush: RefCell<GlyphBrush>,
|
||||||
glyph_cache_tex: Texture,
|
glyph_cache_tex: (Texture, UiTextureBindGroup),
|
||||||
graphic_cache: GraphicCache,
|
graphic_cache: GraphicCache,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,16 +66,22 @@ impl Cache {
|
|||||||
.draw_cache_position_tolerance(POSITION_TOLERANCE)
|
.draw_cache_position_tolerance(POSITION_TOLERANCE)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
let glyph_cache_tex = {
|
||||||
|
let tex = renderer.create_dynamic_texture(glyph_cache_dims);
|
||||||
|
let bind = renderer.ui_bind_texture(&tex);
|
||||||
|
(tex, bind)
|
||||||
|
};
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
glyph_brush: RefCell::new(glyph_brush),
|
glyph_brush: RefCell::new(glyph_brush),
|
||||||
glyph_cache_tex: renderer.create_dynamic_texture(glyph_cache_dims),
|
glyph_cache_tex,
|
||||||
graphic_cache: GraphicCache::new(renderer),
|
graphic_cache: GraphicCache::new(renderer),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn glyph_cache_tex(&self) -> &Texture { &self.glyph_cache_tex }
|
pub fn glyph_cache_tex(&self) -> &(Texture, UiTextureBindGroup) { &self.glyph_cache_tex }
|
||||||
|
|
||||||
pub fn glyph_cache_mut_and_tex(&mut self) -> (&mut GlyphBrush, &Texture) {
|
pub fn glyph_cache_mut_and_tex(&mut self) -> (&mut GlyphBrush, &(Texture, UiTextureBindGroup)) {
|
||||||
(self.glyph_brush.get_mut(), &self.glyph_cache_tex)
|
(self.glyph_brush.get_mut(), &self.glyph_cache_tex)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,6 +123,7 @@ impl Cache {
|
|||||||
self.graphic_cache.replace_graphic(id, graphic)
|
self.graphic_cache.replace_graphic(id, graphic)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: combine resize functions
|
||||||
// Resizes and clears the GraphicCache
|
// Resizes and clears the GraphicCache
|
||||||
pub fn resize_graphic_cache(&mut self, renderer: &mut Renderer) {
|
pub fn resize_graphic_cache(&mut self, renderer: &mut Renderer) {
|
||||||
self.graphic_cache.clear_cache(renderer);
|
self.graphic_cache.clear_cache(renderer);
|
||||||
@ -134,7 +141,12 @@ impl Cache {
|
|||||||
.initial_cache_size((cache_dims.x, cache_dims.y))
|
.initial_cache_size((cache_dims.x, cache_dims.y))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
self.glyph_cache_tex = renderer.create_dynamic_texture(cache_dims);
|
self.glyph_cache_tex = {
|
||||||
|
let tex = renderer.create_dynamic_texture(cache_dims);
|
||||||
|
let bind = renderer.ui_bind_texture(&tex);
|
||||||
|
(tex, bind)
|
||||||
|
};
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,11 @@ use super::{
|
|||||||
graphic::{self, Graphic},
|
graphic::{self, Graphic},
|
||||||
scale::{Scale, ScaleMode},
|
scale::{Scale, ScaleMode},
|
||||||
};
|
};
|
||||||
use crate::{render::Renderer, window::Window, Error};
|
use crate::{
|
||||||
|
render::{Renderer, UiDrawer},
|
||||||
|
window::Window,
|
||||||
|
Error,
|
||||||
|
};
|
||||||
use common_base::span;
|
use common_base::span;
|
||||||
use iced::{mouse, Cache, Size, UserInterface};
|
use iced::{mouse, Cache, Size, UserInterface};
|
||||||
use iced_winit::Clipboard;
|
use iced_winit::Clipboard;
|
||||||
@ -212,5 +216,5 @@ impl IcedUi {
|
|||||||
(messages, mouse_interaction)
|
(messages, mouse_interaction)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render(&self, renderer: &mut Renderer) { self.renderer.render(renderer, None); }
|
pub fn render<'a>(&'a self, drawer: &mut UiDrawer<'_, 'a>) { self.renderer.render(drawer); }
|
||||||
}
|
}
|
||||||
|
@ -15,8 +15,8 @@ use super::{
|
|||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
render::{
|
render::{
|
||||||
create_ui_quad, create_ui_quad_vert_gradient, Consts, DynamicModel, Globals, Mesh,
|
create_ui_quad, create_ui_quad_vert_gradient, Consts, DynamicModel, Mesh, Renderer,
|
||||||
Renderer, UiLocals, UiMode, UiVertex,
|
UiDrawer, UiLocals, UiLocalsBindGroup, UiMode, UiVertex,
|
||||||
},
|
},
|
||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
@ -85,10 +85,10 @@ pub struct IcedRenderer {
|
|||||||
// Model for drawing the ui
|
// Model for drawing the ui
|
||||||
model: DynamicModel<UiVertex>,
|
model: DynamicModel<UiVertex>,
|
||||||
// Consts to specify positions of ingame elements (e.g. Nametags)
|
// Consts to specify positions of ingame elements (e.g. Nametags)
|
||||||
ingame_locals: Vec<Consts<UiLocals>>,
|
ingame_locals: Vec<(Consts<UiLocals>, UiLocalsBindGroup)>,
|
||||||
// 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>, UiLocalsBindGroup),
|
||||||
default_globals: Consts<Globals>,
|
//default_globals: Consts<Globals>,
|
||||||
|
|
||||||
// Used to delay cache resizing until after current frame is drawn
|
// Used to delay cache resizing until after current frame is drawn
|
||||||
//need_cache_resize: bool,
|
//need_cache_resize: bool,
|
||||||
@ -125,12 +125,18 @@ impl IcedRenderer {
|
|||||||
let (half_res, align, p_scale) =
|
let (half_res, align, p_scale) =
|
||||||
Self::calculate_resolution_dependents(physical_resolution, scaled_resolution);
|
Self::calculate_resolution_dependents(physical_resolution, scaled_resolution);
|
||||||
|
|
||||||
|
let interface_locals = {
|
||||||
|
let locals = renderer.create_consts(&[UiLocals::default()]);
|
||||||
|
let bind = renderer.ui_bind_locals(&locals);
|
||||||
|
(locals, bind)
|
||||||
|
};
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
cache: Cache::new(renderer, default_font)?,
|
cache: Cache::new(renderer, default_font)?,
|
||||||
draw_commands: Vec::new(),
|
draw_commands: Vec::new(),
|
||||||
model: renderer.create_dynamic_model(100),
|
model: renderer.create_dynamic_model(100),
|
||||||
interface_locals: renderer.create_consts(&[UiLocals::default()])?,
|
interface_locals,
|
||||||
default_globals: renderer.create_consts(&[Globals::default()])?,
|
//default_globals: renderer.create_consts(&[Globals::default()]),
|
||||||
ingame_locals: Vec::new(),
|
ingame_locals: Vec::new(),
|
||||||
mesh: Mesh::new(),
|
mesh: Mesh::new(),
|
||||||
glyphs: Vec::new(),
|
glyphs: Vec::new(),
|
||||||
@ -222,7 +228,7 @@ impl IcedRenderer {
|
|||||||
.push(DrawCommand::plain(self.start..self.mesh.vertices().len()));*/
|
.push(DrawCommand::plain(self.start..self.mesh.vertices().len()));*/
|
||||||
|
|
||||||
// Fill in placeholder glyph quads
|
// Fill in placeholder glyph quads
|
||||||
let (glyph_cache, cache_tex) = self.cache.glyph_cache_mut_and_tex();
|
let (glyph_cache, (cache_tex, _)) = self.cache.glyph_cache_mut_and_tex();
|
||||||
let half_res = self.half_res;
|
let half_res = self.half_res;
|
||||||
|
|
||||||
let brush_result = glyph_cache.process_queued(
|
let brush_result = glyph_cache.process_queued(
|
||||||
@ -542,6 +548,7 @@ impl IcedRenderer {
|
|||||||
Some((aabr, tex_id)) => {
|
Some((aabr, tex_id)) => {
|
||||||
let cache_dims = graphic_cache
|
let cache_dims = graphic_cache
|
||||||
.get_tex(tex_id)
|
.get_tex(tex_id)
|
||||||
|
.0
|
||||||
.get_dimensions()
|
.get_dimensions()
|
||||||
.xy()
|
.xy()
|
||||||
.map(|e| e as f32);
|
.map(|e| e as f32);
|
||||||
@ -763,28 +770,32 @@ impl IcedRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render(&self, renderer: &mut Renderer, maybe_globals: Option<&Consts<Globals>>) {
|
pub fn render<'pass_ref, 'pass: 'pass_ref, 'data: 'pass>(
|
||||||
|
&'data self,
|
||||||
|
drawer: &mut UiDrawer<'pass_ref, 'pass>, /* maybe_globals: Option<&Consts<Globals>> */
|
||||||
|
) {
|
||||||
span!(_guard, "render", "IcedRenderer::render");
|
span!(_guard, "render", "IcedRenderer::render");
|
||||||
let mut scissor = self.window_scissor;
|
let mut drawer = drawer.prepare(&self.interface_locals.1, &self.model, self.window_scissor);
|
||||||
let globals = maybe_globals.unwrap_or(&self.default_globals);
|
//let mut scissor = self.window_scissor;
|
||||||
let mut locals = &self.interface_locals;
|
//let globals = maybe_globals.unwrap_or(&self.default_globals);
|
||||||
|
//let mut locals = &self.interface_locals.1;
|
||||||
for draw_command in self.draw_commands.iter() {
|
for draw_command in self.draw_commands.iter() {
|
||||||
match draw_command {
|
match draw_command {
|
||||||
DrawCommand::Scissor(new_scissor) => {
|
DrawCommand::Scissor(new_scissor) => {
|
||||||
scissor = *new_scissor;
|
drawer.set_scissor(*new_scissor);
|
||||||
},
|
},
|
||||||
DrawCommand::WorldPos(index) => {
|
DrawCommand::WorldPos(index) => {
|
||||||
locals = index.map_or(&self.interface_locals, |i| &self.ingame_locals[i]);
|
drawer.set_locals(
|
||||||
|
index.map_or(&self.interface_locals.1, |i| &self.ingame_locals[i].1),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
DrawCommand::Draw { kind, verts } => {
|
DrawCommand::Draw { kind, verts } => {
|
||||||
|
// TODO: don't make these assert!(!verts.is_empty());
|
||||||
let tex = match kind {
|
let tex = match kind {
|
||||||
DrawKind::Image(tex_id) => self.cache.graphic_cache().get_tex(*tex_id),
|
DrawKind::Image(tex_id) => self.cache.graphic_cache().get_tex(*tex_id),
|
||||||
DrawKind::Plain => self.cache.glyph_cache_tex(),
|
DrawKind::Plain => self.cache.glyph_cache_tex(),
|
||||||
};
|
};
|
||||||
let model = self.model.submodel(verts.clone());
|
drawer.draw(&tex.1, verts.clone()); // Note: trivial clone
|
||||||
// TODO
|
|
||||||
//renderer.render_ui_element(model, tex, scissor, globals,
|
|
||||||
// locals);
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -163,8 +163,8 @@ impl Ui {
|
|||||||
draw_commands: Vec::new(),
|
draw_commands: Vec::new(),
|
||||||
mesh: Mesh::new(),
|
mesh: Mesh::new(),
|
||||||
model: renderer.create_dynamic_model(100),
|
model: renderer.create_dynamic_model(100),
|
||||||
interface_locals: renderer.create_consts(&[UiLocals::default()])?,
|
interface_locals: renderer.create_consts(&[UiLocals::default()]),
|
||||||
default_globals: renderer.create_consts(&[Globals::default()])?,
|
default_globals: renderer.create_consts(&[Globals::default()]),
|
||||||
ingame_locals: Vec::new(),
|
ingame_locals: Vec::new(),
|
||||||
window_resized: None,
|
window_resized: None,
|
||||||
scale_factor_changed: None,
|
scale_factor_changed: None,
|
||||||
@ -812,6 +812,7 @@ impl Ui {
|
|||||||
Some((aabr, tex_id)) => {
|
Some((aabr, tex_id)) => {
|
||||||
let cache_dims = graphic_cache
|
let cache_dims = graphic_cache
|
||||||
.get_tex(tex_id)
|
.get_tex(tex_id)
|
||||||
|
.0
|
||||||
.get_dimensions()
|
.get_dimensions()
|
||||||
.xy()
|
.xy()
|
||||||
.map(|e| e as f32);
|
.map(|e| e as f32);
|
||||||
@ -953,7 +954,7 @@ impl Ui {
|
|||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
self.ingame_locals
|
self.ingame_locals
|
||||||
.push(renderer.create_consts(&[world_pos.into()]).unwrap());
|
.push(renderer.create_consts(&[world_pos.into()]));
|
||||||
}
|
}
|
||||||
self.draw_commands
|
self.draw_commands
|
||||||
.push(DrawCommand::WorldPos(Some(ingame_local_index)));
|
.push(DrawCommand::WorldPos(Some(ingame_local_index)));
|
||||||
@ -1019,11 +1020,12 @@ impl Ui {
|
|||||||
locals = index.map_or(&self.interface_locals, |i| &self.ingame_locals[i]);
|
locals = index.map_or(&self.interface_locals, |i| &self.ingame_locals[i]);
|
||||||
},
|
},
|
||||||
DrawCommand::Draw { kind, verts } => {
|
DrawCommand::Draw { kind, verts } => {
|
||||||
let tex = match kind {
|
//let tex = match kind {
|
||||||
DrawKind::Image(tex_id) => self.cache.graphic_cache().get_tex(*tex_id),
|
// DrawKind::Image(tex_id) =>
|
||||||
DrawKind::Plain => self.cache.glyph_cache_tex(),
|
// self.cache.graphic_cache().get_tex(*tex_id),
|
||||||
};
|
// DrawKind::Plain => self.cache.glyph_cache_tex(),
|
||||||
let model = self.model.submodel(verts.clone());
|
//};
|
||||||
|
//let model = self.model.submodel(verts.clone());
|
||||||
// TODO
|
// TODO
|
||||||
//renderer.render_ui_element(model, tex, scissor, globals,
|
//renderer.render_ui_element(model, tex, scissor, globals,
|
||||||
// locals);
|
// locals);
|
||||||
|
Loading…
Reference in New Issue
Block a user