migrate cloud pipeline, migrate iced renderer, rebase fixes

This commit is contained in:
Imbris 2020-11-28 21:14:22 -05:00
parent 4fb189c388
commit df87b0cf8a
16 changed files with 294 additions and 105 deletions

View File

@ -228,7 +228,6 @@ fn calc_light<V: RectRasterableVol<Vox = Block> + ReadVol + Debug>(
#[allow(clippy::or_fun_call)] // TODO: Pending review in #587
pub fn generate_mesh<'a, V: RectRasterableVol<Vox = Block> + ReadVol + Debug + 'static>(
vol: &'a VolGrid2d<V>,
(range, max_texture_size): (Aabb<i32>, Vec2<u16>),
(range, max_texture_size, _boi): (Aabb<i32>, Vec2<u16>, &'a BlocksOfInterest),
) -> MeshGen<
TerrainVertex,
@ -252,13 +251,13 @@ pub fn generate_mesh<'a, V: RectRasterableVol<Vox = Block> + ReadVol + Debug + '
// let glow_blocks = boi.lights
// .iter()
// .map(|(pos, glow)| (*pos + range.min.xy(), *glow));
/* DefaultVolIterator::new(self, range.min - MAX_LIGHT_DIST, range.max + MAX_LIGHT_DIST)
/* DefaultVolIterator::new(vol, range.min - MAX_LIGHT_DIST, range.max + MAX_LIGHT_DIST)
.filter_map(|(pos, block)| block.get_glow().map(|glow| (pos, glow))); */
let mut glow_blocks = Vec::new();
// TODO: This expensive, use BlocksOfInterest instead
let mut volume = self.cached();
let mut volume = vol.cached();
for x in -MAX_LIGHT_DIST..range.size().w + MAX_LIGHT_DIST {
for y in -MAX_LIGHT_DIST..range.size().h + MAX_LIGHT_DIST {
for z in -1..range.size().d + 1 {
@ -273,8 +272,8 @@ pub fn generate_mesh<'a, V: RectRasterableVol<Vox = Block> + ReadVol + Debug + '
}
// Calculate chunk lighting (sunlight defaults to 1.0, glow to 0.0)
let light = calc_light(true, SUNLIGHT, range, self, core::iter::empty());
let glow = calc_light(false, 0, range, self, glow_blocks.into_iter());
let light = calc_light(true, SUNLIGHT, range, vol, core::iter::empty());
let glow = calc_light(false, 0, range, vol, glow_blocks.into_iter());
let mut opaque_limits = None::<Limits>;
let mut fluid_limits = None::<Limits>;

View File

@ -26,7 +26,7 @@ impl<V: Vertex> Mesh<V> {
pub fn vertices(&self) -> &[V] { &self.verts }
/// Get a mutable slice referencing the vertices of this mesh.
pub fn vertices_mut(&mut self) -> &mut [P::Vertex] { &mut self.verts }
pub fn vertices_mut(&mut self) -> &mut [V] { &mut self.verts }
/// Push a new vertex onto the end of this mesh.
pub fn push(&mut self, vert: V) { self.verts.push(vert); }
@ -55,7 +55,7 @@ impl<V: Vertex> Mesh<V> {
}
/// Overwrite a quad
pub fn replace_quad(&mut self, index: usize, quad: Quad<P>) {
pub fn replace_quad(&mut self, index: usize, quad: Quad<V>) {
debug_assert!(index % 3 == 0);
assert!(index + 5 < self.verts.len());
// Tri 1

View File

@ -17,7 +17,9 @@ pub use self::{
mesh::{Mesh, Quad, Tri},
model::{DynamicModel, Model, SubModel},
pipelines::{
clouds::{create_mesh as create_clouds_mesh, Locals as CloudsLocals},
clouds::{
create_mesh as create_clouds_mesh, Locals as CloudsLocals, Vertex as CloudsVertex,
},
figure::{
BoneData as FigureBoneData, BoneMeshes, FigureLayout, FigureModel,
Locals as FigureLocals,
@ -25,7 +27,9 @@ pub use self::{
fluid::Vertex as FluidVertex,
lod_terrain::{LodData, Vertex as LodTerrainVertex},
particle::{Instance as ParticleInstance, Vertex as ParticleVertex},
postprocess::{create_mesh as create_pp_mesh, Vertex as PostProcessVertex},
postprocess::{
create_mesh as create_pp_mesh, Locals as PostProcessLocals, Vertex as PostProcessVertex,
},
shadow::Locals as ShadowLocals,
skybox::{create_mesh as create_skybox_mesh, Vertex as SkyboxVertex},
sprite::{Instance as SpriteInstance, Locals as SpriteLocals, Vertex as SpriteVertex},

View File

@ -1,40 +1,15 @@
use super::{
super::{Mesh, Pipeline, TgtColorFmt, TgtDepthStencilFmt, Tri},
Globals,
};
use gfx::{
self, gfx_constant_struct_meta, gfx_defines, gfx_impl_struct_meta, gfx_pipeline,
gfx_pipeline_inner, gfx_vertex_struct_meta,
super::{AaMode, Mesh, Tri},
GlobalsLayouts,
};
use bytemuck::{Pod, Zeroable};
use vek::*;
gfx_defines! {
vertex Vertex {
pos: [f32; 2] = "v_pos",
}
constant Locals {
proj_mat_inv: [[f32; 4]; 4] = "proj_mat_inv",
view_mat_inv: [[f32; 4]; 4] = "view_mat_inv",
}
pipeline pipe {
vbuf: gfx::VertexBuffer<Vertex> = (),
locals: gfx::ConstantBuffer<Locals> = "u_locals",
globals: gfx::ConstantBuffer<Globals> = "u_globals",
map: gfx::TextureSampler<[f32; 4]> = "t_map",
alt: gfx::TextureSampler<[f32; 2]> = "t_alt",
horizon: gfx::TextureSampler<[f32; 4]> = "t_horizon",
color_sampler: gfx::TextureSampler<<TgtColorFmt as gfx::format::Formatted>::View> = "src_color",
depth_sampler: gfx::TextureSampler<<TgtDepthStencilFmt as gfx::format::Formatted>::View> = "src_depth",
noise: gfx::TextureSampler<f32> = "t_noise",
tgt_color: gfx::RenderTarget<TgtColorFmt> = "tgt_color",
}
#[repr(C)]
#[derive(Copy, Clone, Debug, Zeroable, Pod)]
pub struct Locals {
proj_mat_inv: [[f32; 4]; 4],
view_mat_inv: [[f32; 4]; 4],
}
impl Default for Locals {
@ -50,13 +25,26 @@ impl Locals {
}
}
pub struct CloudsPipeline;
impl Pipeline for CloudsPipeline {
type Vertex = Vertex;
#[repr(C)]
#[derive(Copy, Clone, Debug, Zeroable, Pod)]
pub struct Vertex {
pos: [f32; 2],
}
pub fn create_mesh() -> Mesh<CloudsPipeline> {
impl Vertex {
fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> {
use std::mem;
const ATTRIBUTES: [wgpu::VertexAttributeDescriptor; 1] =
wgpu::vertex_attr_array![0 => Float2];
wgpu::VertexBufferDescriptor {
stride: mem::size_of::<Self>() as wgpu::BufferAddress,
step_mode: wgpu::InputStepMode::Vertex,
attributes: &ATTRIBUTES,
}
}
}
pub fn create_mesh() -> Mesh<Vertex> {
let mut mesh = Mesh::new();
#[rustfmt::skip]
@ -75,3 +63,147 @@ pub fn create_mesh() -> Mesh<CloudsPipeline> {
mesh
}
pub struct CloudsLayout {
pub layout: wgpu::BindGroupLayout,
}
impl CloudsLayout {
pub fn new(device: &wgpu::Device) -> Self {
Self {
layout: device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
label: None,
entries: &[
// Color source
wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
ty: wgpu::BindingType::SampledTexture {
component_type: wgpu::TextureComponentType::Float,
dimension: wgpu::TextureViewDimension::D2,
multisampled: false,
},
count: None,
},
wgpu::BindGroupLayoutEntry {
binding: 1,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
ty: wgpu::BindingType::Sampler { comparison: false },
count: None,
},
// Depth source
wgpu::BindGroupLayoutEntry {
binding: 2,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
ty: wgpu::BindingType::SampledTexture {
// TODO: is this float?
component_type: wgpu::TextureComponentType::Float,
dimension: wgpu::TextureViewDimension::D2,
multisampled: false,
},
count: None,
},
wgpu::BindGroupLayoutEntry {
binding: 3,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
ty: wgpu::BindingType::Sampler { comparison: false },
count: None,
},
// Locals
wgpu::BindGroupLayoutEntry {
binding: 4,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
ty: wgpu::BindingType::UniformBuffer {
dynamic: false,
min_binding_size: None,
},
count: None,
},
],
}),
}
}
}
pub struct CloudsPipeline {
pub pipeline: wgpu::RenderPipeline,
}
impl CloudsPipeline {
pub fn new(
device: &wgpu::Device,
vs_module: &wgpu::ShaderModule,
fs_module: &wgpu::ShaderModule,
sc_desc: &wgpu::SwapChainDescriptor,
global_layout: &GlobalsLayouts,
layout: &CloudsLayout,
aa_mode: AaMode,
) -> Self {
let render_pipeline_layout =
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
label: Some("Clouds pipeline layout"),
push_constant_ranges: &[],
bind_group_layouts: &[&global_layout.globals, &layout.layout],
});
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,
};
let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
label: Some("Clouds pipeline"),
layout: Some(&render_pipeline_layout),
vertex_stage: wgpu::ProgrammableStageDescriptor {
module: vs_module,
entry_point: "main",
},
fragment_stage: Some(wgpu::ProgrammableStageDescriptor {
module: fs_module,
entry_point: "main",
}),
rasterization_state: Some(wgpu::RasterizationStateDescriptor {
front_face: wgpu::FrontFace::Ccw,
cull_mode: wgpu::CullMode::Back,
polygon_mode: wgpu::PolygonMode::Fill,
clamp_depth: false,
depth_bias: 0,
depth_bias_slope_scale: 0.0,
depth_bias_clamp: 0.0,
}),
primitive_topology: wgpu::PrimitiveTopology::TriangleList,
color_states: &[wgpu::ColorStateDescriptor {
format: sc_desc.format,
color_blend: wgpu::BlendDescriptor::REPLACE,
alpha_blend: wgpu::BlendDescriptor::REPLACE,
write_mask: wgpu::ColorWrite::ALL,
}],
depth_stencil_state: Some(wgpu::DepthStencilStateDescriptor {
format: wgpu::TextureFormat::Depth24Plus,
depth_write_enabled: false,
depth_compare: wgpu::CompareFunction::Always,
stencil: wgpu::StencilStateDescriptor {
front: wgpu::StencilStateFaceDescriptor::IGNORE,
back: wgpu::StencilStateFaceDescriptor::IGNORE,
read_mask: !0,
write_mask: !0,
},
}),
vertex_state: wgpu::VertexStateDescriptor {
index_format: wgpu::IndexFormat::Uint16,
vertex_buffers: &[Vertex::desc()],
},
sample_count: samples,
sample_mask: !0,
alpha_to_coverage_enabled: false,
});
Self {
pipeline: render_pipeline,
}
}
}

View File

@ -5,7 +5,7 @@ use vek::*;
#[repr(C)]
#[derive(Copy, Clone, Debug, Zeroable, Pod)]
pub struct Vertex {
pos: [f32; 3],
pub pos: [f32; 3],
// ____BBBBBBBBGGGGGGGGRRRRRRRR
// col: u32 = "v_col",
// ...AANNN

View File

@ -3,7 +3,7 @@ use bytemuck::{Pod, Zeroable};
use vek::*;
#[repr(C)]
#[derive(Copy, Clone, Debug, Pod)]
#[derive(Copy, Clone, Debug, Zeroable, Pod)]
pub struct Locals {
proj_mat_inv: [[f32; 4]; 4],
view_mat_inv: [[f32; 4]; 4],
@ -71,6 +71,7 @@ impl PostProcessLayout {
src_color: device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
label: None,
entries: &[
// src color
wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
@ -87,6 +88,33 @@ impl PostProcessLayout {
ty: wgpu::BindingType::Sampler { comparison: false },
count: None,
},
// src depth
wgpu::BindGroupLayoutEntry {
binding: 2,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
ty: wgpu::BindingType::SampledTexture {
component_type: wgpu::TextureComponentType::Float,
dimension: wgpu::TextureViewDimension::D2,
multisampled: false,
},
count: None,
},
wgpu::BindGroupLayoutEntry {
binding: 3,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
ty: wgpu::BindingType::Sampler { comparison: false },
count: None,
},
// Locals
wgpu::BindGroupLayoutEntry {
binding: 4,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
ty: wgpu::BindingType::UniformBuffer {
dynamic: false,
min_binding_size: None,
},
count: None,
},
],
}),
}

View File

@ -164,6 +164,7 @@ pub struct ShadowMapRenderer {
pub struct Layouts {
pub(self) global: GlobalsLayouts,
pub(self) clouds: clouds::CloudsLayout,
pub(self) figure: figure::FigureLayout,
pub(self) fluid: fluid::FluidLayout,
pub(self) postprocess: postprocess::PostProcessLayout,
@ -202,7 +203,7 @@ pub struct Renderer {
fluid_pipeline: fluid::FluidPipeline,
lod_terrain_pipeline: lod_terrain::LodTerrainPipeline,
particle_pipeline: particle::ParticlePipeline,
//clouds_pipeline: wgpu::RenderPipeline,
clouds_pipeline: clouds::CloudsPipeline,
postprocess_pipeline: postprocess::PostProcessPipeline,
// Consider reenabling at some time
// player_shadow_pipeline: figure::FigurePipeline,
@ -298,6 +299,7 @@ impl Renderer {
let layouts = {
let global = GlobalsLayouts::new(&device);
let clouds = clouds::CloudsLayout::new(&device);
let figure = figure::FigureLayout::new(&device);
let fluid = fluid::FluidLayout::new(&device);
let postprocess = postprocess::PostProcessLayout::new(&device);
@ -309,6 +311,7 @@ impl Renderer {
Layouts {
global,
clouds,
figure,
fluid,
postprocess,
@ -502,8 +505,8 @@ impl Renderer {
),
RenderError,
> {
let upscaled = Vec2::from(size)
.map(|e: u16| (e as f32 * mode.upscale_mode.factor) as u16)
let upscaled = Vec2::<u32>::from(size)
.map(|e| (e as f32 * mode.upscale_mode.factor) as u32)
.into_tuple();
let (width, height, sample_count) = match mode.aa {
AaMode::None | AaMode::Fxaa => (upscaled.0, upscaled.1, 1),
@ -894,6 +897,7 @@ impl Renderer {
pub fn create_consts<T: Copy + bytemuck::Pod>(
&mut self,
vals: &[T],
// TODO: don't use result here
) -> Result<Consts<T>, RenderError> {
let mut consts = Consts::new(&self.device, vals.len());
consts.update(&self.device, &self.queue, vals, 0);
@ -1812,7 +1816,7 @@ fn create_pipelines(
particle::ParticlePipeline,
ui::UIPipeline,
lod_terrain::LodTerrainPipeline,
// TODO: clouds
clouds::CloudsPipeline,
postprocess::PostProcessPipeline,
//figure::FigurePipeline,
Option<shadow::ShadowPipeline>,
@ -1957,7 +1961,7 @@ fn create_pipelines(
let directed_shadow_frag_mod = create_shader_module(
device,
&mut compiler,
directed_shadow_frag,
&directed_shadow_frag,
ShaderKind::Fragment,
"light-shadows-directed-frag.glsl",
&options,
@ -2158,15 +2162,29 @@ fn create_pipelines(
);
// Construct a pipeline for rendering our clouds (a kind of post-processing)
// let clouds_pipeline = create_pipeline(
// factory,
// clouds::pipe::new(),
// &Glsl::load_watched("voxygen.shaders.clouds-vert",
// shader_reload_indicator).unwrap(), &Glsl::load_watched("voxygen.
// shaders.clouds-frag", shader_reload_indicator).unwrap(),
// &include_ctx,
// gfx::state::CullFace::Back,
// )?;
let clouds_pipeline = clouds::CloudsPipeline::new(
device,
&create_shader_module(
device,
&mut compiler,
&Glsl::load_watched("voxygen.shaders.clouds-vert", shader_reload_indicator).unwrap(),
ShaderKind::Vertex,
"clouds-vert.glsl",
&options,
)?,
&create_shader_module(
device,
&mut compiler,
&Glsl::load_watched("voxygen.shaders.clouds-frag", shader_reload_indicator).unwrap(),
ShaderKind::Fragment,
"clouds-frag.glsl",
&options,
)?,
sc_desc,
&layouts.global,
&layouts.clouds,
mode.aa,
);
// Construct a pipeline for rendering our post-processing
let postprocess_pipeline = postprocess::PostProcessPipeline::new(

View File

@ -32,7 +32,7 @@ use vek::*;
/// needed to mesh figures.
struct MeshWorkerResponse<const N: usize> {
col_light: ColLightInfo,
opaque: Mesh<TerrainPipeline>,
opaque: Mesh<TerrainVertex>,
bounds: anim::vek::Aabb<f32>,
vertex_range: [Range<u32>; N],
}

View File

@ -16,9 +16,9 @@ pub use self::{
use crate::{
audio::{ambient::AmbientMgr, music::MusicMgr, sfx::SfxMgr, AudioFrontend},
render::{
create_clouds_mesh, create_pp_mesh, create_skybox_mesh, CloudsLocals, CloudsPipeline,
Consts, GlobalModel, Globals, Light, LodData, Model, PostProcessLocals, Renderer, Shadow,
ShadowLocals, SkyboxLocals,
create_clouds_mesh, create_pp_mesh, create_skybox_mesh, CloudsLocals, CloudsVertex, Consts,
GlobalModel, Globals, Light, LodData, Model, PostProcessLocals, PostProcessVertex,
Renderer, Shadow, ShadowLocals, SkyboxVertex,
},
settings::Settings,
window::{AnalogGameInput, Event},
@ -71,12 +71,13 @@ struct Skybox {
}
struct Clouds {
model: Model<CloudsPipeline>,
model: Model<CloudsVertex>,
locals: Consts<CloudsLocals>,
}
struct PostProcess {
model: Model<PostProcessVertex>,
locals: Consts<PostProcessLocals>,
}
pub struct Scene {
@ -300,6 +301,9 @@ impl Scene {
},
postprocess: PostProcess {
model: renderer.create_model(&create_pp_mesh()).unwrap(),
locals: renderer
.create_consts(&[PostProcessLocals::default()])
.unwrap(),
},
terrain: Terrain::new(renderer, sprite_render_context),
lod: Lod::new(renderer, client, settings),

View File

@ -1118,7 +1118,7 @@ fn default_cache(renderer: &mut Renderer) -> HashMap<&'static str, Model<Particl
let segment = Segment::from(&vox.read().0);
let segment_size = segment.size();
let mesh = generate_mesh_base_vol_particle(segment, &mut greedy).0;
let mut mesh = generate_mesh_base_vol_particle(segment, &mut greedy).0;
// Center particle vertices around origin
for vert in mesh.vertices_mut() {
vert.pos[0] -= segment_size.x as f32 / 2.0;

View File

@ -1,9 +1,9 @@
use crate::{
mesh::{greedy::GreedyMesh, segment::generate_mesh_base_vol_terrain},
render::{
create_clouds_mesh, create_pp_mesh, create_skybox_mesh, BoneMeshes, CloudsLocals, Consts,
FigureModel, GlobalModel, Globals, Light, Mesh, Model, PostProcessLocals,
PostProcessVertex, Renderer, Shadow, ShadowLocals, SkyboxLocals, SkyboxVertex,
create_clouds_mesh, create_pp_mesh, create_skybox_mesh, BoneMeshes, CloudsLocals,
CloudsVertex, Consts, FigureModel, GlobalModel, Globals, Light, Mesh, Model,
PostProcessLocals, PostProcessVertex, Renderer, Shadow, ShadowLocals, SkyboxVertex,
TerrainVertex,
},
scene::{
@ -60,10 +60,11 @@ struct Skybox {
struct PostProcess {
model: Model<PostProcessVertex>,
locals: Consts<PostProcessLocals>,
}
struct Clouds {
model: Model<CloudsPipeline>,
model: Model<CloudsVertex>,
locals: Consts<CloudsLocals>,
}
@ -140,6 +141,9 @@ impl Scene {
},
postprocess: PostProcess {
model: renderer.create_model(&create_pp_mesh()).unwrap(),
locals: renderer
.create_consts(&[PostProcessLocals::default()])
.unwrap(),
},
lod: LodData::new(
renderer,

View File

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

View File

@ -12,7 +12,7 @@ use std::{
use vek::*;
// Multiplied by current window size
const GLYPH_CACHE_SIZE: u16 = 1;
const GLYPH_CACHE_SIZE: u32 = 1;
// Glyph cache tolerances
// TODO: consider scaling based on dpi as well as providing as an option to the
// user
@ -53,22 +53,22 @@ pub struct Cache {
// TODO: Should functions be returning UiError instead of Error?
impl Cache {
pub fn new(renderer: &mut Renderer, default_font: Font) -> Result<Self, Error> {
let (w, h) = renderer.get_resolution().into_tuple();
let (w, h) = renderer.resolution().into_tuple();
let max_texture_size = renderer.max_texture_size();
let glyph_cache_dims =
Vec2::new(w, h).map(|e| (e * GLYPH_CACHE_SIZE).min(max_texture_size as u16).max(512));
Vec2::new(w, h).map(|e| (e * GLYPH_CACHE_SIZE).min(max_texture_size).max(512));
let glyph_brush = GlyphBrushBuilder::using_font(default_font)
.initial_cache_size((glyph_cache_dims.x as u32, glyph_cache_dims.y as u32))
.initial_cache_size((glyph_cache_dims.x, glyph_cache_dims.y))
.draw_cache_scale_tolerance(SCALE_TOLERANCE)
.draw_cache_position_tolerance(POSITION_TOLERANCE)
.build();
Ok(Self {
glyph_brush: RefCell::new(glyph_brush),
glyph_cache_tex: renderer.create_dynamic_texture(glyph_cache_dims.map(|e| e as u16))?,
glyph_cache_tex: renderer.create_dynamic_texture(glyph_cache_dims),
graphic_cache: GraphicCache::new(renderer),
})
}
@ -126,15 +126,15 @@ impl Cache {
pub fn resize_glyph_cache(&mut self, renderer: &mut Renderer) -> Result<(), Error> {
let max_texture_size = renderer.max_texture_size();
let cache_dims = renderer
.get_resolution()
.map(|e| (e * GLYPH_CACHE_SIZE).min(max_texture_size as u16).max(512));
.resolution()
.map(|e| (e * GLYPH_CACHE_SIZE).min(max_texture_size).max(512));
let glyph_brush = self.glyph_brush.get_mut();
*glyph_brush = glyph_brush
.to_builder()
.initial_cache_size((cache_dims.x as u32, cache_dims.y as u32))
.initial_cache_size((cache_dims.x, cache_dims.y))
.build();
self.glyph_cache_tex = renderer.create_dynamic_texture(cache_dims.map(|e| e as u16))?;
self.glyph_cache_tex = renderer.create_dynamic_texture(cache_dims);
Ok(())
}
}

View File

@ -16,7 +16,7 @@ use super::{
use crate::{
render::{
create_ui_quad, create_ui_quad_vert_gradient, Consts, DynamicModel, Globals, Mesh,
Renderer, UiLocals, UiMode, UiPipeline,
Renderer, UiLocals, UiMode, UiVertex,
},
Error,
};
@ -83,7 +83,7 @@ pub struct IcedRenderer {
//image_map: Map<(Image, Rotation)>,
cache: Cache,
// Model for drawing the ui
model: DynamicModel<UiPipeline>,
model: DynamicModel<UiVertex>,
// Consts to specify positions of ingame elements (e.g. Nametags)
ingame_locals: Vec<Consts<UiLocals>>,
// Consts for default ui drawing position (ie the interface)
@ -105,7 +105,7 @@ pub struct IcedRenderer {
// Per-frame/update
current_state: State,
mesh: Mesh<UiPipeline>,
mesh: Mesh<UiVertex>,
glyphs: Vec<(usize, usize, Rgba<f32>, Vec2<u32>)>,
// Output from glyph_brush in the previous frame
// It can sometimes ask you to redraw with these instead (idk if that is done with
@ -128,7 +128,7 @@ impl IcedRenderer {
Ok(Self {
cache: Cache::new(renderer, default_font)?,
draw_commands: Vec::new(),
model: renderer.create_dynamic_model(100)?,
model: renderer.create_dynamic_model(100),
interface_locals: renderer.create_consts(&[UiLocals::default()])?,
default_globals: renderer.create_consts(&[Globals::default()])?,
ingame_locals: Vec::new(),
@ -227,17 +227,15 @@ impl IcedRenderer {
let brush_result = glyph_cache.process_queued(
|rect, tex_data| {
let offset = [rect.min[0] as u16, rect.min[1] as u16];
let size = [rect.width() as u16, rect.height() as u16];
let offset = rect.min;
let size = [rect.width(), rect.height()];
let new_data = tex_data
.iter()
.map(|x| [255, 255, 255, *x])
.collect::<Vec<[u8; 4]>>();
if let Err(err) = renderer.update_texture(cache_tex, offset, size, &new_data) {
tracing::warn!("Failed to update glyph cache texture: {:?}", err);
}
renderer.update_texture(cache_tex, offset, size, &new_data);
},
// Urgh more allocation we don't need
|vertex_data| {
@ -308,13 +306,11 @@ impl IcedRenderer {
// Create a larger dynamic model if the mesh is larger than the current model
// size.
if self.model.vbuf.len() < self.mesh.vertices().len() {
self.model = renderer
.create_dynamic_model(self.mesh.vertices().len() * 4 / 3)
.unwrap();
if self.model.len() < self.mesh.vertices().len() {
self.model = renderer.create_dynamic_model(self.mesh.vertices().len() * 4 / 3);
}
// Update model with new mesh.
renderer.update_model(&self.model, &self.mesh, 0).unwrap();
renderer.update_model(&self.model, &self.mesh, 0);
}
// Returns (half_res, align)
@ -547,6 +543,7 @@ impl IcedRenderer {
let cache_dims = graphic_cache
.get_tex(tex_id)
.get_dimensions()
.xy()
.map(|e| e as f32);
let min = Vec2::new(aabr.min.x as f32, aabr.max.y as f32) / cache_dims;
let max = Vec2::new(aabr.max.x as f32, aabr.min.y as f32) / cache_dims;
@ -785,7 +782,9 @@ impl IcedRenderer {
DrawKind::Plain => self.cache.glyph_cache_tex(),
};
let model = self.model.submodel(verts.clone());
renderer.render_ui_element(model, tex, scissor, globals, locals);
// TODO
//renderer.render_ui_element(model, tex, scissor, globals,
// locals);
},
}
}

View File

@ -26,7 +26,7 @@ pub use widgets::{
use crate::{
render::{
create_ui_quad, create_ui_tri, Consts, DynamicModel, Globals, Mesh, RenderError, Renderer,
UIVertex, UiLocals, UiMode,
UiLocals, UiMode, UiVertex,
},
window::Window,
Error,
@ -107,9 +107,9 @@ pub struct Ui {
draw_commands: Vec<DrawCommand>,
// Mesh buffer for UI vertices; we reuse its allocation in order to limit vector reallocations
// during redrawing.
mesh: Mesh<UIVertex>,
mesh: Mesh<UiVertex>,
// Model for drawing the ui
model: DynamicModel<UIVertex>,
model: DynamicModel<UiVertex>,
// Consts for default ui drawing position (ie the interface)
interface_locals: Consts<UiLocals>,
default_globals: Consts<Globals>,

View File

@ -606,7 +606,7 @@ impl Window {
channel::Receiver<String>,
) = channel::unbounded::<String>();
let scale_factor = window.window().scale_factor();
let scale_factor = window.scale_factor();
let key_layout = match KeyLayout::new_from_window(window.window()) {
Ok(kl) => Some(kl),
@ -670,6 +670,7 @@ impl Window {
}
pub fn fetch_events(&mut self) -> Vec<Event> {
span!(_guard, "fetch_events", "Window::fetch_events");
// Refresh ui size (used when changing playstates)
if self.needs_refresh_resize {
let logical_size = self.logical_size();
@ -1309,7 +1310,7 @@ impl Window {
}
pub fn set_fullscreen_mode(&mut self, fullscreen: FullScreenSettings) {
let window = self.window;
let window = &self.window;
self.fullscreen = fullscreen;
window.set_fullscreen(fullscreen.enabled.then(|| match fullscreen.mode {
FullscreenMode::Exclusive => {
@ -1429,7 +1430,7 @@ impl Window {
self.remapping_keybindings = Some(game_input);
}
pub fn window(&self) -> &winit::window::Window { self.window.window() }
pub fn window(&self) -> &winit::window::Window { &self.window }
pub fn modifiers(&self) -> winit::event::ModifiersState { self.modifiers }