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;
|
||||
};
|
||||
|
||||
layout(set = 1, binding = 1)
|
||||
layout(set = 2, binding = 0)
|
||||
uniform texture2D t_tex;
|
||||
layout(set = 1, binding = 2)
|
||||
layout(set = 2, binding = 1)
|
||||
uniform sampler s_tex;
|
||||
|
||||
layout(location = 0) out vec4 tgt_color;
|
||||
|
@ -13,9 +13,9 @@ uniform u_locals {
|
||||
vec4 w_pos;
|
||||
};
|
||||
|
||||
layout(set = 1, binding = 1)
|
||||
layout(set = 2, binding = 0)
|
||||
uniform texture2D t_tex;
|
||||
layout(set = 1, binding = 2)
|
||||
layout(set = 2, binding = 1)
|
||||
uniform sampler s_tex;
|
||||
|
||||
layout(location = 0) out vec2 f_uv;
|
||||
@ -33,10 +33,10 @@ void main() {
|
||||
f_uv = v_uv;
|
||||
// Fixed scale In-game element
|
||||
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)) {
|
||||
// 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]));
|
||||
// TODO: Consider cleaning up matrix to something more efficient (e.g. a mat3).
|
||||
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);
|
||||
vec2 v_centered = (v_pos - v_center) / aspect_ratio;
|
||||
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 {
|
||||
// Interface element
|
||||
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;
|
||||
}
|
||||
|
@ -1584,7 +1584,8 @@ impl CharSelectionUi {
|
||||
}
|
||||
|
||||
// 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)]
|
||||
|
@ -1,4 +1,5 @@
|
||||
mod client_init;
|
||||
mod scene;
|
||||
mod ui;
|
||||
|
||||
use super::char_selection::CharSelectionState;
|
||||
@ -20,6 +21,7 @@ use client::{
|
||||
use client_init::{ClientConnArgs, ClientInit, Error as InitError, Msg as InitMsg};
|
||||
use common::comp;
|
||||
use common_base::span;
|
||||
use scene::Scene;
|
||||
use std::{fmt::Debug, sync::Arc};
|
||||
use tokio::runtime;
|
||||
use tracing::error;
|
||||
@ -29,6 +31,7 @@ pub struct MainMenuState {
|
||||
main_menu_ui: MainMenuUi,
|
||||
// Used for client creation.
|
||||
client_init: Option<ClientInit>,
|
||||
scene: Scene,
|
||||
}
|
||||
|
||||
impl MainMenuState {
|
||||
@ -37,6 +40,7 @@ impl MainMenuState {
|
||||
Self {
|
||||
main_menu_ui: MainMenuUi::new(global_state),
|
||||
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 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.
|
||||
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::{
|
||||
i18n::{LanguageMetadata, LocalizationHandle},
|
||||
render::Renderer,
|
||||
render::UiDrawer,
|
||||
ui::{
|
||||
self,
|
||||
fonts::IcedFonts as Fonts,
|
||||
@ -477,7 +477,7 @@ pub struct MainMenuUi {
|
||||
controls: Controls,
|
||||
}
|
||||
|
||||
impl<'a> MainMenuUi {
|
||||
impl MainMenuUi {
|
||||
pub fn new(global_state: &mut GlobalState) -> Self {
|
||||
// Load language
|
||||
let i18n = &global_state.i18n.read();
|
||||
@ -582,5 +582,5 @@ impl<'a> MainMenuUi {
|
||||
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;
|
||||
|
||||
pub struct Buffer<T: Copy + Pod> {
|
||||
pub buf: wgpu::Buffer,
|
||||
pub(super) buf: wgpu::Buffer,
|
||||
// Size in number of elements
|
||||
// TODO: determine if this is a good name
|
||||
len: usize,
|
||||
|
@ -37,11 +37,12 @@ pub use self::{
|
||||
ui::{
|
||||
create_quad as create_ui_quad,
|
||||
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,
|
||||
};
|
||||
pub use wgpu::{AddressMode, FilterMode};
|
||||
|
@ -13,7 +13,7 @@ pub struct SubModel<'a, V: Vertex> {
|
||||
}
|
||||
|
||||
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.
|
||||
@ -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() }
|
||||
}
|
||||
|
@ -150,7 +150,6 @@ impl CloudsPipeline {
|
||||
let samples = match aa_mode {
|
||||
AaMode::None | AaMode::Fxaa => 1,
|
||||
// TODO: Ensure sampling in the shader is exactly between the 4 texels
|
||||
AaMode::SsaaX4 => 1,
|
||||
AaMode::MsaaX4 => 4,
|
||||
AaMode::MsaaX8 => 8,
|
||||
AaMode::MsaaX16 => 16,
|
||||
|
@ -143,7 +143,6 @@ impl FigureLayout {
|
||||
},
|
||||
count: None,
|
||||
},
|
||||
// TODO: does this change at the same frequency?
|
||||
// col lights
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 2,
|
||||
@ -192,7 +191,6 @@ impl FigurePipeline {
|
||||
let samples = match aa_mode {
|
||||
AaMode::None | AaMode::Fxaa => 1,
|
||||
// TODO: Ensure sampling in the shader is exactly between the 4 texels
|
||||
AaMode::SsaaX4 => 1,
|
||||
AaMode::MsaaX4 => 4,
|
||||
AaMode::MsaaX8 => 8,
|
||||
AaMode::MsaaX16 => 16,
|
||||
|
@ -105,7 +105,6 @@ impl FluidPipeline {
|
||||
let samples = match aa_mode {
|
||||
AaMode::None | AaMode::Fxaa => 1,
|
||||
// TODO: Ensure sampling in the shader is exactly between the 4 texels
|
||||
AaMode::SsaaX4 => 1,
|
||||
AaMode::MsaaX4 => 4,
|
||||
AaMode::MsaaX8 => 8,
|
||||
AaMode::MsaaX16 => 16,
|
||||
|
@ -35,6 +35,25 @@ pub struct 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(
|
||||
renderer: &mut Renderer,
|
||||
map_size: Vec2<u32>,
|
||||
@ -44,65 +63,54 @@ impl LodData {
|
||||
tgt_detail: u32,
|
||||
//border_color: gfx::texture::PackedColor,
|
||||
) -> Self {
|
||||
let mut texture_info = wgpu::TextureDescriptor {
|
||||
label: None,
|
||||
size: wgpu::Extent3d {
|
||||
width: map_size.x,
|
||||
height: map_size.y,
|
||||
depth: 1,
|
||||
},
|
||||
mip_level_count: 1,
|
||||
sample_count: 1,
|
||||
dimension: wgpu::TextureDimension::D2,
|
||||
format: wgpu::TextureFormat::Rgba8UnormSrgb,
|
||||
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::COPY_DST,
|
||||
};
|
||||
let mut create_texture = |format, data| {
|
||||
let texture_info = wgpu::TextureDescriptor {
|
||||
label: None,
|
||||
size: wgpu::Extent3d {
|
||||
width: map_size.x,
|
||||
height: map_size.y,
|
||||
depth: 1,
|
||||
},
|
||||
mip_level_count: 1,
|
||||
sample_count: 1,
|
||||
dimension: wgpu::TextureDimension::D2,
|
||||
format,
|
||||
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::COPY_DST,
|
||||
};
|
||||
|
||||
let sampler_info = wgpu::SamplerDescriptor {
|
||||
label: None,
|
||||
address_mode_u: wgpu::AddressMode::ClampToEdge,
|
||||
address_mode_v: wgpu::AddressMode::ClampToEdge,
|
||||
address_mode_w: wgpu::AddressMode::ClampToEdge,
|
||||
mag_filter: wgpu::FilterMode::Linear,
|
||||
min_filter: wgpu::FilterMode::Linear,
|
||||
mipmap_filter: wgpu::FilterMode::Nearest,
|
||||
border_color: Some(wgpu::SamplerBorderColor::TransparentBlack),
|
||||
..Default::default()
|
||||
};
|
||||
let sampler_info = wgpu::SamplerDescriptor {
|
||||
label: None,
|
||||
address_mode_u: wgpu::AddressMode::ClampToEdge,
|
||||
address_mode_v: wgpu::AddressMode::ClampToEdge,
|
||||
address_mode_w: wgpu::AddressMode::ClampToEdge,
|
||||
mag_filter: wgpu::FilterMode::Linear,
|
||||
min_filter: wgpu::FilterMode::Linear,
|
||||
mipmap_filter: wgpu::FilterMode::Nearest,
|
||||
border_color: Some(wgpu::SamplerBorderColor::TransparentBlack),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let mut view_info = wgpu::TextureViewDescriptor {
|
||||
label: None,
|
||||
format: Some(wgpu::TextureFormat::Rgba8UnormSrgb),
|
||||
dimension: Some(wgpu::TextureViewDimension::D2),
|
||||
aspect: wgpu::TextureAspect::All,
|
||||
base_mip_level: 0,
|
||||
level_count: None,
|
||||
base_array_layer: 0,
|
||||
array_layer_count: None,
|
||||
};
|
||||
let view_info = wgpu::TextureViewDescriptor {
|
||||
label: None,
|
||||
format: Some(format),
|
||||
dimension: Some(wgpu::TextureViewDimension::D2),
|
||||
aspect: wgpu::TextureAspect::All,
|
||||
base_mip_level: 0,
|
||||
level_count: None,
|
||||
base_array_layer: 0,
|
||||
array_layer_count: None,
|
||||
};
|
||||
|
||||
let map = renderer.create_texture_with_data_raw(
|
||||
&texture_info,
|
||||
&view_info,
|
||||
&sampler_info,
|
||||
bytemuck::cast_slice(lod_base),
|
||||
);
|
||||
texture_info.format = wgpu::TextureFormat::Rg16Uint;
|
||||
view_info.format = Some(wgpu::TextureFormat::Rg16Uint);
|
||||
let alt = renderer.create_texture_with_data_raw(
|
||||
&texture_info,
|
||||
&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),
|
||||
);
|
||||
renderer.create_texture_with_data_raw(
|
||||
&texture_info,
|
||||
&view_info,
|
||||
&sampler_info,
|
||||
bytemuck::cast_slice(data),
|
||||
)
|
||||
};
|
||||
let map = create_texture(wgpu::TextureFormat::Rgba8UnormSrgb, lod_base);
|
||||
let alt = create_texture(wgpu::TextureFormat::Rg16Uint, lod_alt);
|
||||
let horizon = create_texture(wgpu::TextureFormat::Rgba8Unorm, lod_horizon);
|
||||
|
||||
Self {
|
||||
map,
|
||||
@ -173,7 +181,6 @@ impl LodTerrainPipeline {
|
||||
let samples = match aa_mode {
|
||||
AaMode::None | AaMode::Fxaa => 1,
|
||||
// TODO: Ensure sampling in the shader is exactly between the 4 texels
|
||||
AaMode::SsaaX4 => 1,
|
||||
AaMode::MsaaX4 => 4,
|
||||
AaMode::MsaaX8 => 8,
|
||||
AaMode::MsaaX16 => 16,
|
||||
|
@ -10,7 +10,7 @@ pub mod sprite;
|
||||
pub mod terrain;
|
||||
pub mod ui;
|
||||
|
||||
use super::Consts;
|
||||
use super::{Consts, Texture};
|
||||
use crate::scene::camera::CameraMode;
|
||||
use bytemuck::{Pod, Zeroable};
|
||||
use common::terrain::BlockKind;
|
||||
@ -225,6 +225,10 @@ pub struct GlobalModel {
|
||||
pub shadow_mats: Consts<shadow::Locals>,
|
||||
}
|
||||
|
||||
pub struct GlobalsBindGroup {
|
||||
pub(super) bind_group: wgpu::BindGroup,
|
||||
}
|
||||
|
||||
pub struct GlobalsLayouts {
|
||||
pub globals: wgpu::BindGroupLayout,
|
||||
}
|
||||
@ -315,7 +319,7 @@ impl GlobalsLayouts {
|
||||
ty: wgpu::BindingType::Sampler { comparison: false },
|
||||
count: None,
|
||||
},
|
||||
// light shadows
|
||||
// light shadows (ie shadows from a light?)
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 9,
|
||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||
@ -382,4 +386,96 @@ impl GlobalsLayouts {
|
||||
|
||||
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 {
|
||||
AaMode::None | AaMode::Fxaa => 1,
|
||||
// TODO: Ensure sampling in the shader is exactly between the 4 texels
|
||||
AaMode::SsaaX4 => 1,
|
||||
AaMode::MsaaX4 => 4,
|
||||
AaMode::MsaaX8 => 8,
|
||||
AaMode::MsaaX16 => 16,
|
||||
|
@ -146,7 +146,6 @@ impl PostProcessPipeline {
|
||||
let samples = match aa_mode {
|
||||
AaMode::None | AaMode::Fxaa => 1,
|
||||
// TODO: Ensure sampling in the shader is exactly between the 4 texels
|
||||
AaMode::SsaaX4 => 1,
|
||||
AaMode::MsaaX4 => 4,
|
||||
AaMode::MsaaX8 => 8,
|
||||
AaMode::MsaaX16 => 16,
|
||||
|
@ -22,7 +22,6 @@ impl Locals {
|
||||
|
||||
pub fn default() -> Self { Self::new(Mat4::identity(), Mat4::identity()) }
|
||||
|
||||
// TODO: unused?
|
||||
fn layout(device: &wgpu::Device) -> wgpu::BindGroupLayout {
|
||||
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
label: None,
|
||||
@ -131,7 +130,6 @@ impl ShadowFigurePipeline {
|
||||
let samples = match aa_mode {
|
||||
AaMode::None | AaMode::Fxaa => 1,
|
||||
// TODO: Ensure sampling in the shader is exactly between the 4 texels
|
||||
AaMode::SsaaX4 => 1,
|
||||
AaMode::MsaaX4 => 4,
|
||||
AaMode::MsaaX8 => 8,
|
||||
AaMode::MsaaX16 => 16,
|
||||
@ -214,7 +212,6 @@ impl ShadowPipeline {
|
||||
let samples = match aa_mode {
|
||||
AaMode::None | AaMode::Fxaa => 1,
|
||||
// TODO: Ensure sampling in the shader is exactly between the 4 texels
|
||||
AaMode::SsaaX4 => 1,
|
||||
AaMode::MsaaX4 => 4,
|
||||
AaMode::MsaaX8 => 8,
|
||||
AaMode::MsaaX16 => 16,
|
||||
|
@ -46,7 +46,6 @@ impl SkyboxPipeline {
|
||||
let samples = match aa_mode {
|
||||
AaMode::None | AaMode::Fxaa => 1,
|
||||
// TODO: Ensure sampling in the shader is exactly between the 4 texels
|
||||
AaMode::SsaaX4 => 1,
|
||||
AaMode::MsaaX4 => 4,
|
||||
AaMode::MsaaX8 => 8,
|
||||
AaMode::MsaaX16 => 16,
|
||||
|
@ -176,7 +176,6 @@ impl SpriteLayout {
|
||||
label: None,
|
||||
entries: &[
|
||||
// locals
|
||||
// TODO: different freq
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 0,
|
||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||
@ -239,7 +238,6 @@ impl SpritePipeline {
|
||||
let samples = match aa_mode {
|
||||
AaMode::None | AaMode::Fxaa => 1,
|
||||
// TODO: Ensure sampling in the shader is exactly between the 4 texels
|
||||
AaMode::SsaaX4 => 1,
|
||||
AaMode::MsaaX4 => 4,
|
||||
AaMode::MsaaX8 => 8,
|
||||
AaMode::MsaaX16 => 16,
|
||||
|
@ -170,7 +170,6 @@ impl TerrainLayout {
|
||||
count: None,
|
||||
},
|
||||
// col lights
|
||||
// TODO: same frequency?
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 1,
|
||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||
@ -218,7 +217,6 @@ impl TerrainPipeline {
|
||||
let samples = match aa_mode {
|
||||
AaMode::None | AaMode::Fxaa => 1,
|
||||
// TODO: Ensure sampling in the shader is exactly between the 4 texels
|
||||
AaMode::SsaaX4 => 1,
|
||||
AaMode::MsaaX4 => 4,
|
||||
AaMode::MsaaX8 => 8,
|
||||
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 vek::*;
|
||||
|
||||
@ -80,11 +80,20 @@ impl Mode {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct UILayout {
|
||||
pub locals: wgpu::BindGroupLayout,
|
||||
pub struct LocalsBindGroup {
|
||||
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 {
|
||||
Self {
|
||||
locals: device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
@ -100,9 +109,14 @@ impl UILayout {
|
||||
},
|
||||
count: None,
|
||||
},
|
||||
],
|
||||
}),
|
||||
texture: device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
label: None,
|
||||
entries: &[
|
||||
// texture
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 1,
|
||||
binding: 0,
|
||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||
ty: wgpu::BindingType::SampledTexture {
|
||||
component_type: wgpu::TextureComponentType::Float,
|
||||
@ -112,7 +126,7 @@ impl UILayout {
|
||||
count: None,
|
||||
},
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 2,
|
||||
binding: 1,
|
||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||
ty: wgpu::BindingType::Sampler { comparison: false },
|
||||
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,
|
||||
}
|
||||
|
||||
impl UIPipeline {
|
||||
impl UiPipeline {
|
||||
pub fn new(
|
||||
device: &wgpu::Device,
|
||||
vs_module: &wgpu::ShaderModule,
|
||||
fs_module: &wgpu::ShaderModule,
|
||||
sc_desc: &wgpu::SwapChainDescriptor,
|
||||
global_layout: &GlobalsLayouts,
|
||||
layout: &UILayout,
|
||||
layout: &UiLayout,
|
||||
aa_mode: AaMode,
|
||||
) -> Self {
|
||||
let render_pipeline_layout =
|
||||
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||
label: Some("UI pipeline layout"),
|
||||
label: Some("Ui pipeline layout"),
|
||||
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 {
|
||||
AaMode::None | AaMode::Fxaa => 1,
|
||||
// TODO: Ensure sampling in the shader is exactly between the 4 texels
|
||||
AaMode::SsaaX4 => 1,
|
||||
AaMode::MsaaX4 => 4,
|
||||
AaMode::MsaaX8 => 8,
|
||||
AaMode::MsaaX16 => 16,
|
||||
|
@ -1,3 +1,8 @@
|
||||
mod bind_group;
|
||||
mod drawer;
|
||||
|
||||
pub use drawer::{Drawer, UiDrawer};
|
||||
|
||||
use super::{
|
||||
consts::Consts,
|
||||
instances::Instances,
|
||||
@ -8,8 +13,8 @@ use super::{
|
||||
ui, GlobalsLayouts,
|
||||
},
|
||||
texture::Texture,
|
||||
AaMode, AddressMode, CloudMode, FilterMode, FluidMode, LightingMode, RenderError, RenderMode,
|
||||
ShadowMapMode, ShadowMode, Vertex,
|
||||
AaMode, AddressMode, CloudMode, FilterMode, FluidMode, GlobalsBindGroup, LightingMode,
|
||||
RenderError, RenderMode, ShadowMapMode, ShadowMode, Vertex,
|
||||
};
|
||||
use common::assets::{self, AssetExt, AssetHandle};
|
||||
use common_base::span;
|
||||
@ -20,6 +25,7 @@ use vek::*;
|
||||
|
||||
/// A type representing data that can be converted to an immutable texture map
|
||||
/// of ColLight data (used for texture atlases created during greedy meshing).
|
||||
// TODO: revert to u16
|
||||
pub type ColLightInfo = (Vec<[u8; 4]>, Vec2<u32>);
|
||||
|
||||
/// Load from a GLSL file.
|
||||
@ -116,9 +122,9 @@ impl Shaders {
|
||||
pub struct ShadowMapRenderer {
|
||||
// directed_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,
|
||||
terrain_directed_pipeline: shadow::ShadowPipeline,
|
||||
@ -128,6 +134,7 @@ pub struct ShadowMapRenderer {
|
||||
|
||||
/// A type that stores all the layouts associated with this renderer.
|
||||
pub struct Layouts {
|
||||
// TODO: pub(self)??
|
||||
pub(self) global: GlobalsLayouts,
|
||||
|
||||
pub(self) clouds: clouds::CloudsLayout,
|
||||
@ -137,7 +144,7 @@ pub struct Layouts {
|
||||
pub(self) shadow: shadow::ShadowLayout,
|
||||
pub(self) sprite: sprite::SpriteLayout,
|
||||
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
|
||||
@ -156,7 +163,7 @@ pub struct Renderer {
|
||||
win_depth_view: wgpu::TextureView,
|
||||
|
||||
tgt_color_view: wgpu::TextureView,
|
||||
tgt_depth_stencil_view: wgpu::TextureView,
|
||||
tgt_depth_view: wgpu::TextureView,
|
||||
// TODO: rename
|
||||
tgt_color_pp_view: wgpu::TextureView,
|
||||
|
||||
@ -177,7 +184,7 @@ pub struct Renderer {
|
||||
skybox_pipeline: skybox::SkyboxPipeline,
|
||||
sprite_pipeline: sprite::SpritePipeline,
|
||||
terrain_pipeline: terrain::TerrainPipeline,
|
||||
ui_pipeline: ui::UIPipeline,
|
||||
ui_pipeline: ui::UiPipeline,
|
||||
|
||||
shaders: AssetHandle<Shaders>,
|
||||
|
||||
@ -273,7 +280,7 @@ impl Renderer {
|
||||
let shadow = shadow::ShadowLayout::new(&device);
|
||||
let sprite = sprite::SpriteLayout::new(&device);
|
||||
let terrain = terrain::TerrainLayout::new(&device);
|
||||
let ui = ui::UILayout::new(&device);
|
||||
let ui = ui::UiLayout::new(&device);
|
||||
|
||||
Layouts {
|
||||
global,
|
||||
@ -313,7 +320,7 @@ impl Renderer {
|
||||
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)?;
|
||||
|
||||
let shadow_map = if let (
|
||||
@ -327,16 +334,16 @@ impl Renderer {
|
||||
figure_directed_shadow_pipeline,
|
||||
shadow_views,
|
||||
) {
|
||||
let (point_depth_stencil, directed_depth_stencil) = shadow_views;
|
||||
let (point_depth, directed_depth) = shadow_views;
|
||||
|
||||
let layout = shadow::ShadowLayout::new(&device);
|
||||
|
||||
Some(ShadowMapRenderer {
|
||||
directed_depth_stencil,
|
||||
directed_depth,
|
||||
|
||||
// point_encoder: factory.create_command_buffer().into(),
|
||||
// directed_encoder: factory.create_command_buffer().into(),
|
||||
point_depth_stencil,
|
||||
point_depth,
|
||||
|
||||
point_pipeline,
|
||||
terrain_directed_pipeline,
|
||||
@ -378,7 +385,7 @@ impl Renderer {
|
||||
win_depth_view,
|
||||
|
||||
tgt_color_view,
|
||||
tgt_depth_stencil_view,
|
||||
tgt_depth_view,
|
||||
tgt_color_pp_view,
|
||||
|
||||
sampler,
|
||||
@ -411,7 +418,7 @@ impl Renderer {
|
||||
/// before post-processing.
|
||||
#[allow(dead_code)]
|
||||
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
|
||||
@ -446,19 +453,19 @@ impl Renderer {
|
||||
self.swap_chain = self.device.create_swap_chain(&self.surface, &self.sc_desc);
|
||||
|
||||
// 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.win_depth_view = win_depth_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;
|
||||
if let (Some(shadow_map), ShadowMode::Map(mode)) =
|
||||
(self.shadow_map.as_mut(), self.mode.shadow)
|
||||
{
|
||||
match Self::create_shadow_views(&mut self.device, (dims.x, dims.y), &mode) {
|
||||
Ok((point_depth_stencil, directed_depth_stencil)) => {
|
||||
shadow_map.point_depth_stencil = point_depth_stencil;
|
||||
shadow_map.directed_depth_stencil = directed_depth_stencil;
|
||||
Ok((point_depth, directed_depth)) => {
|
||||
shadow_map.point_depth = point_depth;
|
||||
shadow_map.directed_depth = directed_depth;
|
||||
},
|
||||
Err(err) => {
|
||||
warn!("Could not create shadow map views: {:?}", err);
|
||||
@ -496,7 +503,7 @@ impl Renderer {
|
||||
};
|
||||
let levels = 1;
|
||||
|
||||
let mut color_view = || {
|
||||
let color_view = || {
|
||||
let tex = device.create_texture(&wgpu::TextureDescriptor {
|
||||
label: None,
|
||||
size: wgpu::Extent3d {
|
||||
@ -527,7 +534,7 @@ impl Renderer {
|
||||
let tgt_color_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,
|
||||
size: wgpu::Extent3d {
|
||||
width,
|
||||
@ -540,17 +547,16 @@ impl Renderer {
|
||||
format: wgpu::TextureFormat::Depth24Plus,
|
||||
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::RENDER_ATTACHMENT,
|
||||
});
|
||||
let tgt_depth_stencil_view =
|
||||
tgt_depth_stencil_tex.create_view(&wgpu::TextureViewDescriptor {
|
||||
label: None,
|
||||
format: Some(wgpu::TextureFormat::Depth24Plus),
|
||||
dimension: Some(wgpu::TextureViewDimension::D2),
|
||||
aspect: wgpu::TextureAspect::DepthOnly,
|
||||
base_mip_level: 0,
|
||||
level_count: None,
|
||||
base_array_layer: 0,
|
||||
array_layer_count: None,
|
||||
});
|
||||
let tgt_depth_view = tgt_depth_tex.create_view(&wgpu::TextureViewDescriptor {
|
||||
label: None,
|
||||
format: Some(wgpu::TextureFormat::Depth24Plus),
|
||||
dimension: Some(wgpu::TextureViewDimension::D2),
|
||||
aspect: wgpu::TextureAspect::DepthOnly,
|
||||
base_mip_level: 0,
|
||||
level_count: None,
|
||||
base_array_layer: 0,
|
||||
array_layer_count: None,
|
||||
});
|
||||
|
||||
let win_depth_tex = device.create_texture(&wgpu::TextureDescriptor {
|
||||
label: None,
|
||||
@ -565,7 +571,7 @@ impl Renderer {
|
||||
format: wgpu::TextureFormat::Depth24Plus,
|
||||
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,
|
||||
format: Some(wgpu::TextureFormat::Depth24Plus),
|
||||
dimension: Some(wgpu::TextureViewDimension::D2),
|
||||
@ -578,7 +584,7 @@ impl Renderer {
|
||||
|
||||
Ok((
|
||||
tgt_color_view,
|
||||
tgt_depth_stencil_view,
|
||||
tgt_depth_view,
|
||||
tgt_color_pp_view,
|
||||
win_depth_view,
|
||||
))
|
||||
@ -656,7 +662,7 @@ impl Renderer {
|
||||
};
|
||||
|
||||
//TODO: (0, levels - 1), ?? from master
|
||||
let mut point_shadow_view = wgpu::TextureViewDescriptor {
|
||||
let point_shadow_view = wgpu::TextureViewDescriptor {
|
||||
label: None,
|
||||
format: Some(wgpu::TextureFormat::Depth24Plus),
|
||||
dimension: Some(wgpu::TextureViewDimension::Cube),
|
||||
@ -723,8 +729,8 @@ impl Renderer {
|
||||
pub fn get_shadow_resolution(&self) -> (Vec2<u32>, Vec2<u32>) {
|
||||
if let Some(shadow_map) = &self.shadow_map {
|
||||
(
|
||||
shadow_map.point_depth_stencil.get_dimensions().xy(),
|
||||
shadow_map.directed_depth_stencil.get_dimensions().xy(),
|
||||
shadow_map.point_depth.get_dimensions().xy(),
|
||||
shadow_map.directed_depth.get_dimensions().xy(),
|
||||
)
|
||||
} else {
|
||||
(Vec2::new(1, 1), Vec2::new(1, 1))
|
||||
@ -741,10 +747,10 @@ impl Renderer {
|
||||
// if let Some(shadow_map) = self.shadow_map.as_mut() {
|
||||
// // let point_encoder = &mut shadow_map.point_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 self.encoder;
|
||||
// directed_encoder.clear_depth(&shadow_map.directed_depth_stencil_view,
|
||||
// directed_encoder.clear_depth(&shadow_map.directed_depth_view,
|
||||
// 1.0); }
|
||||
// }
|
||||
|
||||
@ -802,51 +808,20 @@ impl Renderer {
|
||||
// }
|
||||
// }
|
||||
|
||||
/// Perform all queued draw calls for this frame and clean up discarded
|
||||
/// items.
|
||||
pub fn flush(&mut self) -> Result<(), RenderError> {
|
||||
span!(_guard, "flush", "Renderer::flush");
|
||||
let frame = 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);
|
||||
},
|
||||
Err(err @ wgpu::SwapChainError::Timeout) => {
|
||||
warn!("{}. This will probably be resolved on the next frame", err);
|
||||
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()));
|
||||
/// Start recording the frame
|
||||
/// When the returned `Drawer` is dropped the recorded draw calls will be
|
||||
/// submitted to the queue
|
||||
/// If there is an intermittent issue with the swap chain then Ok(None) will
|
||||
/// be returned
|
||||
pub fn start_recording_frame<'a>(
|
||||
&'a mut self,
|
||||
globals: &'a GlobalsBindGroup,
|
||||
) -> Result<Option<Drawer<'a>>, RenderError> {
|
||||
span!(
|
||||
_guard,
|
||||
"start_recording_frame",
|
||||
"Renderer::start_recording_frame"
|
||||
);
|
||||
|
||||
self.device.poll(wgpu::Maintain::Poll);
|
||||
|
||||
@ -855,7 +830,30 @@ impl Renderer {
|
||||
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
|
||||
@ -916,14 +914,10 @@ impl Renderer {
|
||||
}
|
||||
|
||||
/// Create a new set of constants with the provided values.
|
||||
pub fn create_consts<T: Copy + bytemuck::Pod>(
|
||||
&mut self,
|
||||
vals: &[T],
|
||||
// TODO: don't use result here
|
||||
) -> Result<Consts<T>, RenderError> {
|
||||
pub fn create_consts<T: Copy + bytemuck::Pod>(&mut self, vals: &[T]) -> Consts<T> {
|
||||
let mut consts = Consts::new(&self.device, vals.len());
|
||||
consts.update(&self.device, &self.queue, vals, 0);
|
||||
Ok(consts)
|
||||
consts
|
||||
}
|
||||
|
||||
/// 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(),
|
||||
// lod.alt.sampler.clone()), horizon: (lod.horizon.srv.clone(),
|
||||
// lod.horizon.sampler.clone()), tgt_color:
|
||||
// self.tgt_color_view.clone(), tgt_depth_stencil:
|
||||
// (self.tgt_depth_stencil_view.clone()/* , (1, 1) */), },
|
||||
// self.tgt_color_view.clone(), tgt_depth:
|
||||
// (self.tgt_depth_view.clone()/* , (1, 1) */), },
|
||||
// );
|
||||
// }
|
||||
|
||||
@ -1193,8 +1187,8 @@ impl Renderer {
|
||||
// self.noise_tex.sampler.clone()), alt: (lod.alt.srv.clone(),
|
||||
// lod.alt.sampler.clone()), horizon: (lod.horizon.srv.clone(),
|
||||
// lod.horizon.sampler.clone()), tgt_color:
|
||||
// self.tgt_color_view.clone(), tgt_depth_stencil:
|
||||
// (self.tgt_depth_stencil_view.clone()/* , (1, 1) */), },
|
||||
// self.tgt_color_view.clone(), tgt_depth:
|
||||
// (self.tgt_depth_view.clone()/* , (1, 1) */), },
|
||||
// );
|
||||
// }
|
||||
|
||||
@ -1253,8 +1247,8 @@ impl Renderer {
|
||||
// self.noise_tex.sampler.clone()), alt: (lod.alt.srv.clone(),
|
||||
// lod.alt.sampler.clone()), horizon: (lod.horizon.srv.clone(),
|
||||
// lod.horizon.sampler.clone()), tgt_color:
|
||||
// self.tgt_color_view.clone(), tgt_depth_stencil:
|
||||
// (self.tgt_depth_stencil_view.clone()/* , (0, 0) */), },
|
||||
// self.tgt_color_view.clone(), tgt_depth:
|
||||
// (self.tgt_depth_view.clone()/* , (0, 0) */), },
|
||||
// ); */
|
||||
// }
|
||||
|
||||
@ -1312,8 +1306,8 @@ impl Renderer {
|
||||
// self.noise_tex.sampler.clone()), alt: (lod.alt.srv.clone(),
|
||||
// lod.alt.sampler.clone()), horizon: (lod.horizon.srv.clone(),
|
||||
// lod.horizon.sampler.clone()), tgt_color:
|
||||
// self.tgt_color_view.clone(), tgt_depth_stencil:
|
||||
// (self.tgt_depth_stencil_view.clone()/* , (1, 1) */), },
|
||||
// self.tgt_color_view.clone(), tgt_depth:
|
||||
// (self.tgt_depth_view.clone()/* , (1, 1) */), },
|
||||
// );
|
||||
// }
|
||||
|
||||
@ -1371,8 +1365,8 @@ impl Renderer {
|
||||
// self.noise_tex.sampler.clone()), alt: (lod.alt.srv.clone(),
|
||||
// lod.alt.sampler.clone()), horizon: (lod.horizon.srv.clone(),
|
||||
// lod.horizon.sampler.clone()), tgt_color:
|
||||
// self.tgt_color_view.clone(), tgt_depth_stencil:
|
||||
// (self.tgt_depth_stencil_view.clone()/* , (1, 1) */), },
|
||||
// self.tgt_color_view.clone(), tgt_depth:
|
||||
// (self.tgt_depth_view.clone()/* , (1, 1) */), },
|
||||
// );
|
||||
// }
|
||||
|
||||
@ -1414,7 +1408,7 @@ impl Renderer {
|
||||
|
||||
// // Shadow stuff
|
||||
// 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
|
||||
// light_shadows: locals.buf.clone(),
|
||||
// tgt_depth_stencil:
|
||||
// shadow_map.directed_depth_stencil_view.clone(), },
|
||||
// tgt_depth:
|
||||
// shadow_map.directed_depth_view.clone(), },
|
||||
// );
|
||||
// }
|
||||
|
||||
@ -1503,8 +1497,8 @@ impl Renderer {
|
||||
|
||||
// // Shadow stuff
|
||||
// light_shadows: locals.buf.clone(),
|
||||
// tgt_depth_stencil:
|
||||
// shadow_map.directed_depth_stencil_view.clone(), },
|
||||
// tgt_depth:
|
||||
// shadow_map.directed_depth_view.clone(), },
|
||||
// );
|
||||
// }
|
||||
|
||||
@ -1560,8 +1554,8 @@ impl Renderer {
|
||||
// noise: (self.noise_tex.srv.clone(),
|
||||
// self.noise_tex.sampler.clone()), waves: (waves.srv.clone(),
|
||||
// waves.sampler.clone()), tgt_color:
|
||||
// self.tgt_color_view.clone(), tgt_depth_stencil:
|
||||
// (self.tgt_depth_stencil_view.clone()/* , (1, 1) */), },
|
||||
// self.tgt_color_view.clone(), tgt_depth:
|
||||
// (self.tgt_depth_view.clone()/* , (1, 1) */), },
|
||||
// );
|
||||
// }
|
||||
|
||||
@ -1625,8 +1619,8 @@ impl Renderer {
|
||||
// self.noise_tex.sampler.clone()), alt: (lod.alt.srv.clone(),
|
||||
// lod.alt.sampler.clone()), horizon: (lod.horizon.srv.clone(),
|
||||
// lod.horizon.sampler.clone()), tgt_color:
|
||||
// self.tgt_color_view.clone(), tgt_depth_stencil:
|
||||
// (self.tgt_depth_stencil_view.clone()/* , (1, 1) */), },
|
||||
// self.tgt_color_view.clone(), tgt_depth:
|
||||
// (self.tgt_depth_view.clone()/* , (1, 1) */), },
|
||||
// );
|
||||
// }
|
||||
|
||||
@ -1657,8 +1651,8 @@ impl Renderer {
|
||||
// lod.map.sampler.clone()), alt: (lod.alt.srv.clone(),
|
||||
// lod.alt.sampler.clone()), horizon: (lod.horizon.srv.clone(),
|
||||
// lod.horizon.sampler.clone()), tgt_color:
|
||||
// self.tgt_color_view.clone(), tgt_depth_stencil:
|
||||
// (self.tgt_depth_stencil_view.clone()/* , (1, 1) */), },
|
||||
// self.tgt_color_view.clone(), tgt_depth:
|
||||
// (self.tgt_depth_view.clone()/* , (1, 1) */), },
|
||||
// );
|
||||
// }
|
||||
|
||||
@ -1711,8 +1705,8 @@ impl Renderer {
|
||||
// self.noise_tex.sampler.clone()), alt: (lod.alt.srv.clone(),
|
||||
// lod.alt.sampler.clone()), horizon: (lod.horizon.srv.clone(),
|
||||
// lod.horizon.sampler.clone()), tgt_color:
|
||||
// self.tgt_color_view.clone(), tgt_depth_stencil:
|
||||
// (self.tgt_depth_stencil_view.clone()/* , (1, 1) */), },
|
||||
// self.tgt_color_view.clone(), tgt_depth:
|
||||
// (self.tgt_depth_view.clone()/* , (1, 1) */), },
|
||||
// );
|
||||
// }
|
||||
|
||||
@ -1836,7 +1830,7 @@ fn create_pipelines(
|
||||
fluid::FluidPipeline,
|
||||
sprite::SpritePipeline,
|
||||
particle::ParticlePipeline,
|
||||
ui::UIPipeline,
|
||||
ui::UiPipeline,
|
||||
lod_terrain::LodTerrainPipeline,
|
||||
clouds::CloudsPipeline,
|
||||
postprocess::PostProcessPipeline,
|
||||
@ -2029,7 +2023,7 @@ fn create_pipelines(
|
||||
);
|
||||
|
||||
// Construct a pipeline for rendering UI elements
|
||||
let ui_pipeline = ui::UIPipeline::new(
|
||||
let ui_pipeline = ui::UiPipeline::new(
|
||||
device,
|
||||
&create_shader("ui-vert", ShaderKind::Vertex)?,
|
||||
&create_shader("ui-frag", ShaderKind::Fragment)?,
|
||||
@ -2077,7 +2071,7 @@ fn create_pipelines(
|
||||
// let player_shadow_pipeline = create_pipeline(
|
||||
// factory,
|
||||
// figure::pipe::Init {
|
||||
// tgt_depth_stencil: (gfx::preset::depth::PASS_TEST/*,
|
||||
// tgt_depth: (gfx::preset::depth::PASS_TEST/*,
|
||||
// Stencil::new(
|
||||
// Comparison::Equal,
|
||||
// 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],
|
||||
) {
|
||||
// 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);
|
||||
// TODO: Only works for 2D images
|
||||
queue.write_texture(
|
||||
|
@ -176,7 +176,7 @@ fn handle_main_events_cleared(
|
||||
last.render(renderer, &global_state.settings);
|
||||
// Finish the frame.
|
||||
// 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.
|
||||
// global_state
|
||||
// .window
|
||||
|
@ -8,13 +8,13 @@ use crate::{
|
||||
ecs::comp::Interpolated,
|
||||
render::{
|
||||
pipelines, ColLightInfo, Consts, FigureBoneData, FigureLocals, FigureModel, GlobalModel,
|
||||
Mesh, RenderError, Renderer, SubModel, TerrainVertex, Texture,
|
||||
LodData, Mesh, RenderError, Renderer, SubModel, TerrainVertex, Texture,
|
||||
},
|
||||
scene::{
|
||||
camera::{Camera, CameraMode, Dependents},
|
||||
math,
|
||||
terrain::Terrain,
|
||||
LodData, SceneData,
|
||||
SceneData,
|
||||
},
|
||||
};
|
||||
use anim::{
|
||||
@ -5352,8 +5352,8 @@ impl<S: Skeleton> FigureState<S> {
|
||||
let bone_consts = figure_bone_data_from_anim(&buf);
|
||||
Self {
|
||||
meta: FigureStateMeta {
|
||||
bone_consts: renderer.create_consts(bone_consts).unwrap(),
|
||||
locals: renderer.create_consts(&[FigureLocals::default()]).unwrap(),
|
||||
bone_consts: renderer.create_consts(bone_consts),
|
||||
locals: renderer.create_consts(&[FigureLocals::default()]),
|
||||
lantern_offset,
|
||||
state_time: 0.0,
|
||||
last_ori: Ori::default().into(),
|
||||
|
@ -17,8 +17,8 @@ use crate::{
|
||||
audio::{ambient::AmbientMgr, music::MusicMgr, sfx::SfxMgr, AudioFrontend},
|
||||
render::{
|
||||
create_clouds_mesh, create_pp_mesh, create_skybox_mesh, CloudsLocals, CloudsVertex, Consts,
|
||||
GlobalModel, Globals, Light, LodData, Model, PostProcessLocals, PostProcessVertex,
|
||||
Renderer, Shadow, ShadowLocals, SkyboxVertex,
|
||||
GlobalModel, Globals, Light, Model, PostProcessLocals, PostProcessVertex, Renderer, Shadow,
|
||||
ShadowLocals, SkyboxVertex,
|
||||
},
|
||||
settings::Settings,
|
||||
window::{AnalogGameInput, Event},
|
||||
@ -277,16 +277,11 @@ impl Scene {
|
||||
|
||||
Self {
|
||||
data: GlobalModel {
|
||||
globals: renderer.create_consts(&[Globals::default()]).unwrap(),
|
||||
lights: renderer
|
||||
.create_consts(&[Light::default(); MAX_LIGHT_COUNT])
|
||||
.unwrap(),
|
||||
shadows: renderer
|
||||
.create_consts(&[Shadow::default(); MAX_SHADOW_COUNT])
|
||||
.unwrap(),
|
||||
globals: renderer.create_consts(&[Globals::default()]),
|
||||
lights: renderer.create_consts(&[Light::default(); MAX_LIGHT_COUNT]),
|
||||
shadows: renderer.create_consts(&[Shadow::default(); MAX_SHADOW_COUNT]),
|
||||
shadow_mats: renderer
|
||||
.create_consts(&[ShadowLocals::default(); MAX_LIGHT_COUNT * 6 + 6])
|
||||
.unwrap(),
|
||||
.create_consts(&[ShadowLocals::default(); MAX_LIGHT_COUNT * 6 + 6]),
|
||||
},
|
||||
camera: Camera::new(resolution.x / resolution.y, CameraMode::ThirdPerson),
|
||||
camera_input_state: Vec2::zero(),
|
||||
@ -297,13 +292,11 @@ impl Scene {
|
||||
},
|
||||
clouds: Clouds {
|
||||
model: renderer.create_model(&create_clouds_mesh()).unwrap(),
|
||||
locals: renderer.create_consts(&[CloudsLocals::default()]).unwrap(),
|
||||
locals: renderer.create_consts(&[CloudsLocals::default()]),
|
||||
},
|
||||
postprocess: PostProcess {
|
||||
model: renderer.create_model(&create_pp_mesh()).unwrap(),
|
||||
locals: renderer
|
||||
.create_consts(&[PostProcessLocals::default()])
|
||||
.unwrap(),
|
||||
locals: renderer.create_consts(&[PostProcessLocals::default()]),
|
||||
},
|
||||
terrain: Terrain::new(renderer, sprite_render_context),
|
||||
lod: Lod::new(renderer, client, settings),
|
||||
|
@ -2,14 +2,13 @@ use crate::{
|
||||
mesh::{greedy::GreedyMesh, segment::generate_mesh_base_vol_terrain},
|
||||
render::{
|
||||
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,
|
||||
TerrainVertex,
|
||||
},
|
||||
scene::{
|
||||
camera::{self, Camera, CameraMode},
|
||||
figure::{load_mesh, FigureColLights, FigureModelCache, FigureModelEntry, FigureState},
|
||||
LodData,
|
||||
},
|
||||
window::{Event, PressState},
|
||||
};
|
||||
@ -110,10 +109,6 @@ impl Scene {
|
||||
client.world_data().min_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);
|
||||
camera.set_focus_pos(Vec3::unit_z() * 1.5);
|
||||
@ -124,12 +119,10 @@ impl Scene {
|
||||
|
||||
Self {
|
||||
data: GlobalModel {
|
||||
globals: renderer.create_consts(&[Globals::default()]).unwrap(),
|
||||
lights: renderer.create_consts(&[Light::default(); 32]).unwrap(),
|
||||
shadows: renderer.create_consts(&[Shadow::default(); 32]).unwrap(),
|
||||
shadow_mats: renderer
|
||||
.create_consts(&[ShadowLocals::default(); 6])
|
||||
.unwrap(),
|
||||
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]),
|
||||
},
|
||||
|
||||
skybox: Skybox {
|
||||
@ -137,23 +130,13 @@ impl Scene {
|
||||
},
|
||||
clouds: Clouds {
|
||||
model: renderer.create_model(&create_clouds_mesh()).unwrap(),
|
||||
locals: renderer.create_consts(&[CloudsLocals::default()]).unwrap(),
|
||||
locals: renderer.create_consts(&[CloudsLocals::default()]),
|
||||
},
|
||||
postprocess: PostProcess {
|
||||
model: renderer.create_model(&create_pp_mesh()).unwrap(),
|
||||
locals: renderer
|
||||
.create_consts(&[PostProcessLocals::default()])
|
||||
.unwrap(),
|
||||
locals: renderer.create_consts(&[PostProcessLocals::default()]),
|
||||
},
|
||||
lod: LodData::new(
|
||||
renderer,
|
||||
Vec2::new(1, 1),
|
||||
&map_image,
|
||||
&alt_image,
|
||||
&horizon_image,
|
||||
1,
|
||||
//map_border.into(),
|
||||
),
|
||||
lod: LodData::dummy(renderer),
|
||||
map_bounds,
|
||||
|
||||
figure_model_cache: FigureModelCache::new(),
|
||||
|
@ -8,13 +8,13 @@ use crate::{
|
||||
terrain::{generate_mesh, SUNLIGHT},
|
||||
},
|
||||
render::{
|
||||
pipelines, ColLightInfo, Consts, FluidVertex, GlobalModel, Instances, Mesh, Model,
|
||||
pipelines, ColLightInfo, Consts, FluidVertex, GlobalModel, Instances, LodData, Mesh, Model,
|
||||
RenderError, Renderer, SpriteInstance, SpriteLocals, SpriteVertex, TerrainLocals,
|
||||
TerrainVertex, Texture,
|
||||
},
|
||||
};
|
||||
|
||||
use super::{math, LodData, SceneData};
|
||||
use super::{math, SceneData};
|
||||
use common::{
|
||||
assets::{self, AssetExt, DotVoxAsset},
|
||||
figure::Segment,
|
||||
@ -517,9 +517,7 @@ impl SpriteRenderContext {
|
||||
offset,
|
||||
}| {
|
||||
SpriteData {
|
||||
locals: renderer
|
||||
.create_consts(&locals)
|
||||
.expect("Failed to upload sprite locals to the GPU!"),
|
||||
locals: renderer.create_consts(&locals_buffer),
|
||||
model: renderer.create_model(&model).expect(
|
||||
"Failed to upload sprite model data to the GPU!",
|
||||
),
|
||||
@ -1161,24 +1159,22 @@ impl<V: RectRasterableVol> Terrain<V> {
|
||||
light_map: mesh.light_map,
|
||||
glow_map: mesh.glow_map,
|
||||
sprite_instances,
|
||||
locals: renderer
|
||||
.create_consts(&[TerrainLocals {
|
||||
model_offs: Vec3::from(
|
||||
response.pos.map2(VolGrid2d::<V>::chunk_size(), |e, sz| {
|
||||
e as f32 * sz as f32
|
||||
}),
|
||||
)
|
||||
.into_array(),
|
||||
atlas_offs: Vec4::new(
|
||||
atlas_offs.x as i32,
|
||||
atlas_offs.y as i32,
|
||||
0,
|
||||
0,
|
||||
)
|
||||
.into_array(),
|
||||
load_time,
|
||||
}])
|
||||
.expect("Failed to upload chunk locals to the GPU!"),
|
||||
locals: renderer.create_consts(&[TerrainLocals {
|
||||
model_offs: Vec3::from(
|
||||
response.pos.map2(VolGrid2d::<V>::chunk_size(), |e, sz| {
|
||||
e as f32 * sz as f32
|
||||
}),
|
||||
)
|
||||
.into_array(),
|
||||
atlas_offs: Vec4::new(
|
||||
atlas_offs.x as i32,
|
||||
atlas_offs.y as i32,
|
||||
0,
|
||||
0,
|
||||
)
|
||||
.into_array(),
|
||||
load_time,
|
||||
}]),
|
||||
visible: Visibility {
|
||||
in_range: false,
|
||||
in_frustum: false,
|
||||
|
@ -3,7 +3,7 @@ mod renderer;
|
||||
|
||||
pub use renderer::{SampleStrat, Transform};
|
||||
|
||||
use crate::render::{Renderer, Texture};
|
||||
use crate::render::{Renderer, Texture, UiTextureBindGroup};
|
||||
use common::figure::Segment;
|
||||
use guillotiere::{size2, SimpleAtlasAllocator};
|
||||
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: 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
|
||||
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) }
|
||||
|
||||
/// 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")
|
||||
}
|
||||
|
||||
@ -284,7 +284,7 @@ impl GraphicCache {
|
||||
// color.
|
||||
assert!(border.is_none());
|
||||
// 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)));
|
||||
@ -324,7 +324,7 @@ impl GraphicCache {
|
||||
valid: true,
|
||||
aabr,
|
||||
});
|
||||
upload_image(renderer, aabr, &textures[texture_idx], &image);
|
||||
upload_image(renderer, aabr, &textures[texture_idx].0, &image);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -344,7 +344,7 @@ impl GraphicCache {
|
||||
let atlas_idx = atlases.len();
|
||||
textures.push(texture);
|
||||
atlases.push((atlas, tex_idx));
|
||||
upload_image(renderer, aabr, &textures[tex_idx], &image);
|
||||
upload_image(renderer, aabr, &textures[tex_idx].0, &image);
|
||||
CachedDetails::Atlas {
|
||||
atlas_idx,
|
||||
valid: true,
|
||||
@ -354,7 +354,11 @@ impl GraphicCache {
|
||||
}
|
||||
} else {
|
||||
// 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!
|
||||
let index = textures.len();
|
||||
textures.push(texture);
|
||||
@ -365,7 +369,7 @@ impl GraphicCache {
|
||||
// Note texture should always match the cached dimensions
|
||||
max: dims,
|
||||
},
|
||||
&textures[index],
|
||||
&textures[index].0,
|
||||
&image,
|
||||
);
|
||||
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);
|
||||
// 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 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)
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
renderer
|
||||
fn create_image(
|
||||
renderer: &mut Renderer,
|
||||
image: RgbaImage,
|
||||
border_color: Rgba<f32>,
|
||||
) -> (Texture, UiTextureBindGroup) {
|
||||
let tex = renderer
|
||||
.create_texture(
|
||||
&DynamicImage::ImageRgba8(image),
|
||||
None,
|
||||
@ -458,5 +473,8 @@ fn create_image(renderer: &mut Renderer, image: RgbaImage, border_color: Rgba<f3
|
||||
// Some(border_color.into_array().into()),
|
||||
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 crate::{
|
||||
render::{Renderer, Texture},
|
||||
render::{Renderer, Texture, UiTextureBindGroup},
|
||||
Error,
|
||||
};
|
||||
use common::assets::{self, AssetExt};
|
||||
@ -46,7 +46,7 @@ pub struct FontId(pub(super) glyph_brush::FontId);
|
||||
|
||||
pub struct Cache {
|
||||
glyph_brush: RefCell<GlyphBrush>,
|
||||
glyph_cache_tex: Texture,
|
||||
glyph_cache_tex: (Texture, UiTextureBindGroup),
|
||||
graphic_cache: GraphicCache,
|
||||
}
|
||||
|
||||
@ -66,16 +66,22 @@ impl Cache {
|
||||
.draw_cache_position_tolerance(POSITION_TOLERANCE)
|
||||
.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 {
|
||||
glyph_brush: RefCell::new(glyph_brush),
|
||||
glyph_cache_tex: renderer.create_dynamic_texture(glyph_cache_dims),
|
||||
glyph_cache_tex,
|
||||
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)
|
||||
}
|
||||
|
||||
@ -117,6 +123,7 @@ impl Cache {
|
||||
self.graphic_cache.replace_graphic(id, graphic)
|
||||
}
|
||||
|
||||
// TODO: combine resize functions
|
||||
// Resizes and clears the GraphicCache
|
||||
pub fn resize_graphic_cache(&mut self, renderer: &mut Renderer) {
|
||||
self.graphic_cache.clear_cache(renderer);
|
||||
@ -134,7 +141,12 @@ impl Cache {
|
||||
.initial_cache_size((cache_dims.x, cache_dims.y))
|
||||
.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(())
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,11 @@ use super::{
|
||||
graphic::{self, Graphic},
|
||||
scale::{Scale, ScaleMode},
|
||||
};
|
||||
use crate::{render::Renderer, window::Window, Error};
|
||||
use crate::{
|
||||
render::{Renderer, UiDrawer},
|
||||
window::Window,
|
||||
Error,
|
||||
};
|
||||
use common_base::span;
|
||||
use iced::{mouse, Cache, Size, UserInterface};
|
||||
use iced_winit::Clipboard;
|
||||
@ -212,5 +216,5 @@ impl IcedUi {
|
||||
(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::{
|
||||
render::{
|
||||
create_ui_quad, create_ui_quad_vert_gradient, Consts, DynamicModel, Globals, Mesh,
|
||||
Renderer, UiLocals, UiMode, UiVertex,
|
||||
create_ui_quad, create_ui_quad_vert_gradient, Consts, DynamicModel, Mesh, Renderer,
|
||||
UiDrawer, UiLocals, UiLocalsBindGroup, UiMode, UiVertex,
|
||||
},
|
||||
Error,
|
||||
};
|
||||
@ -85,10 +85,10 @@ pub struct IcedRenderer {
|
||||
// Model for drawing the ui
|
||||
model: DynamicModel<UiVertex>,
|
||||
// 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)
|
||||
interface_locals: Consts<UiLocals>,
|
||||
default_globals: Consts<Globals>,
|
||||
interface_locals: (Consts<UiLocals>, UiLocalsBindGroup),
|
||||
//default_globals: Consts<Globals>,
|
||||
|
||||
// Used to delay cache resizing until after current frame is drawn
|
||||
//need_cache_resize: bool,
|
||||
@ -125,12 +125,18 @@ impl IcedRenderer {
|
||||
let (half_res, align, p_scale) =
|
||||
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 {
|
||||
cache: Cache::new(renderer, default_font)?,
|
||||
draw_commands: Vec::new(),
|
||||
model: renderer.create_dynamic_model(100),
|
||||
interface_locals: renderer.create_consts(&[UiLocals::default()])?,
|
||||
default_globals: renderer.create_consts(&[Globals::default()])?,
|
||||
interface_locals,
|
||||
//default_globals: renderer.create_consts(&[Globals::default()]),
|
||||
ingame_locals: Vec::new(),
|
||||
mesh: Mesh::new(),
|
||||
glyphs: Vec::new(),
|
||||
@ -222,7 +228,7 @@ impl IcedRenderer {
|
||||
.push(DrawCommand::plain(self.start..self.mesh.vertices().len()));*/
|
||||
|
||||
// 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 brush_result = glyph_cache.process_queued(
|
||||
@ -542,6 +548,7 @@ impl IcedRenderer {
|
||||
Some((aabr, tex_id)) => {
|
||||
let cache_dims = graphic_cache
|
||||
.get_tex(tex_id)
|
||||
.0
|
||||
.get_dimensions()
|
||||
.xy()
|
||||
.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");
|
||||
let mut scissor = self.window_scissor;
|
||||
let globals = maybe_globals.unwrap_or(&self.default_globals);
|
||||
let mut locals = &self.interface_locals;
|
||||
let mut drawer = drawer.prepare(&self.interface_locals.1, &self.model, self.window_scissor);
|
||||
//let mut scissor = self.window_scissor;
|
||||
//let globals = maybe_globals.unwrap_or(&self.default_globals);
|
||||
//let mut locals = &self.interface_locals.1;
|
||||
for draw_command in self.draw_commands.iter() {
|
||||
match draw_command {
|
||||
DrawCommand::Scissor(new_scissor) => {
|
||||
scissor = *new_scissor;
|
||||
drawer.set_scissor(*new_scissor);
|
||||
},
|
||||
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 } => {
|
||||
// TODO: don't make these assert!(!verts.is_empty());
|
||||
let tex = match kind {
|
||||
DrawKind::Image(tex_id) => self.cache.graphic_cache().get_tex(*tex_id),
|
||||
DrawKind::Plain => self.cache.glyph_cache_tex(),
|
||||
};
|
||||
let model = self.model.submodel(verts.clone());
|
||||
// TODO
|
||||
//renderer.render_ui_element(model, tex, scissor, globals,
|
||||
// locals);
|
||||
drawer.draw(&tex.1, verts.clone()); // Note: trivial clone
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -163,8 +163,8 @@ impl Ui {
|
||||
draw_commands: Vec::new(),
|
||||
mesh: Mesh::new(),
|
||||
model: renderer.create_dynamic_model(100),
|
||||
interface_locals: renderer.create_consts(&[UiLocals::default()])?,
|
||||
default_globals: renderer.create_consts(&[Globals::default()])?,
|
||||
interface_locals: renderer.create_consts(&[UiLocals::default()]),
|
||||
default_globals: renderer.create_consts(&[Globals::default()]),
|
||||
ingame_locals: Vec::new(),
|
||||
window_resized: None,
|
||||
scale_factor_changed: None,
|
||||
@ -812,6 +812,7 @@ impl Ui {
|
||||
Some((aabr, tex_id)) => {
|
||||
let cache_dims = graphic_cache
|
||||
.get_tex(tex_id)
|
||||
.0
|
||||
.get_dimensions()
|
||||
.xy()
|
||||
.map(|e| e as f32);
|
||||
@ -953,7 +954,7 @@ impl Ui {
|
||||
)
|
||||
} else {
|
||||
self.ingame_locals
|
||||
.push(renderer.create_consts(&[world_pos.into()]).unwrap());
|
||||
.push(renderer.create_consts(&[world_pos.into()]));
|
||||
}
|
||||
self.draw_commands
|
||||
.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]);
|
||||
},
|
||||
DrawCommand::Draw { kind, verts } => {
|
||||
let tex = match kind {
|
||||
DrawKind::Image(tex_id) => self.cache.graphic_cache().get_tex(*tex_id),
|
||||
DrawKind::Plain => self.cache.glyph_cache_tex(),
|
||||
};
|
||||
let model = self.model.submodel(verts.clone());
|
||||
//let tex = match kind {
|
||||
// DrawKind::Image(tex_id) =>
|
||||
// self.cache.graphic_cache().get_tex(*tex_id),
|
||||
// DrawKind::Plain => self.cache.glyph_cache_tex(),
|
||||
//};
|
||||
//let model = self.model.submodel(verts.clone());
|
||||
// TODO
|
||||
//renderer.render_ui_element(model, tex, scissor, globals,
|
||||
// locals);
|
||||
|
Loading…
Reference in New Issue
Block a user