mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Make compile through various changes, update wgpu to latest git
This commit is contained in:
parent
8c3995298b
commit
d9c523ba0d
15
Cargo.toml
15
Cargo.toml
@ -98,11 +98,6 @@ incremental = true
|
||||
inherits = 'release'
|
||||
debug = 1
|
||||
|
||||
[patch.crates-io]
|
||||
# macos CI fix isn't merged yet
|
||||
winit = { git = "https://gitlab.com/veloren/winit.git", branch = "macos-test-spiffed" }
|
||||
vek = { git = "https://gitlab.com/veloren/vek.git", branch = "fix_intrinsics2" }
|
||||
|
||||
[workspace.metadata.nix]
|
||||
systems = ["x86_64-linux"]
|
||||
|
||||
@ -113,3 +108,13 @@ key = "veloren-nix.cachix.org-1:zokfKJqVsNV6kI/oJdLF6TYBdNPYGSb+diMVQPn/5Rc="
|
||||
[workspace.metadata.nix.crateOverride.veloren-network]
|
||||
buildInputs = ["openssl"]
|
||||
nativeBuildInputs = ["pkg-config"]
|
||||
|
||||
[patch.crates-io]
|
||||
# macos CI fix isn't merged yet
|
||||
winit = { git = "https://gitlab.com/veloren/winit.git", branch = "macos-test-spiffed" }
|
||||
vek = { git = "https://gitlab.com/veloren/vek.git", branch = "fix_intrinsics2" }
|
||||
# see https://github.com/rustwasm/wasm-bindgen/issues/2371
|
||||
wasm-bindgen = { git = "https://github.com/rustwasm/wasm-bindgen", rev = "316c5a70fdc4a052fb65ef82bf02d52107b5671b" }
|
||||
wasm-bindgen-futures = { git = "https://github.com/rustwasm/wasm-bindgen", rev = "316c5a70fdc4a052fb65ef82bf02d52107b5671b" }
|
||||
web-sys = { git = "https://github.com/rustwasm/wasm-bindgen", rev = "316c5a70fdc4a052fb65ef82bf02d52107b5671b" }
|
||||
js-sys = { git = "https://github.com/rustwasm/wasm-bindgen", rev = "316c5a70fdc4a052fb65ef82bf02d52107b5671b" }
|
||||
|
@ -45,7 +45,7 @@ i18n = {package = "veloren-i18n", path = "i18n"}
|
||||
|
||||
# Graphics
|
||||
winit = {version = "0.24.0", features = ["serde"]}
|
||||
wgpu = { git="https://github.com/gfx-rs/wgpu-rs.git", rev= "ab8b0e3766558d541206da2790dfd63f15b13bc4" }
|
||||
wgpu = { git="https://github.com/Imberflur/wgpu-rs.git" }
|
||||
bytemuck = { version="1.4", features=["derive"] }
|
||||
shaderc = "0.6.2"
|
||||
|
||||
|
@ -3,44 +3,60 @@ use wgpu::util::DeviceExt;
|
||||
|
||||
pub struct Buffer<T: Copy + Pod> {
|
||||
pub buf: wgpu::Buffer,
|
||||
// bytes
|
||||
count: usize,
|
||||
// Size in number of elements
|
||||
// TODO: determine if this is a good name
|
||||
len: usize,
|
||||
phantom_data: std::marker::PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<T: Copy + Pod> Buffer<T> {
|
||||
pub fn new(device: &wgpu::Device, cap: u64, usage: wgpu::BufferUsage) -> Self {
|
||||
Self {
|
||||
buf: device.create_buffer(&wgpu::BufferDescriptor {
|
||||
label: None,
|
||||
mapped_at_creation: false,
|
||||
size: cap,
|
||||
usage: usage | wgpu::BufferUsage::MAP_WRITE,
|
||||
}),
|
||||
count: 0,
|
||||
phantom_data: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_with_data(device: &wgpu::Device, usage: wgpu::BufferUsage, data: &[T]) -> Self {
|
||||
pub fn new(device: &wgpu::Device, usage: wgpu::BufferUsage, data: &[T]) -> Self {
|
||||
let contents = bytemuck::cast_slice(data);
|
||||
|
||||
Self {
|
||||
buf: device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: None,
|
||||
contents,
|
||||
usage: usage | wgpu::BufferUsage::MAP_WRITE,
|
||||
usage,
|
||||
}),
|
||||
count: data.len(),
|
||||
len: data.len(),
|
||||
phantom_data: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update(&mut self, device: &wgpu::Device, queue: &wgpu::Queue, vals: &[T], offset: u64) {
|
||||
if !vals.is_empty() {
|
||||
queue.write_buffer(&self.buf, offset, bytemuck::cast_slice(vals))
|
||||
}
|
||||
pub fn len(&self) -> usize { self.len }
|
||||
}
|
||||
|
||||
pub struct DynamicBuffer<T: Copy + Pod>(Buffer<T>);
|
||||
|
||||
impl<T: Copy + Pod> DynamicBuffer<T> {
|
||||
pub fn new(device: &wgpu::Device, len: usize, usage: wgpu::BufferUsage) -> Self {
|
||||
let buffer = Buffer {
|
||||
buf: device.create_buffer(&wgpu::BufferDescriptor {
|
||||
label: None,
|
||||
mapped_at_creation: false,
|
||||
size: (len / std::mem::size_of::<T>()) as u64,
|
||||
usage: usage | wgpu::BufferUsage::COPY_DST,
|
||||
}),
|
||||
len,
|
||||
phantom_data: std::marker::PhantomData,
|
||||
};
|
||||
Self(buffer)
|
||||
}
|
||||
|
||||
pub fn count(&self) -> usize { self.count }
|
||||
pub fn update(&self, device: &wgpu::Device, queue: &wgpu::Queue, vals: &[T], offset: usize) {
|
||||
if !vals.is_empty() {
|
||||
queue.write_buffer(
|
||||
&self.buf,
|
||||
(offset / std::mem::size_of::<T>()) as u64,
|
||||
bytemuck::cast_slice(vals),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + Pod> std::ops::Deref for DynamicBuffer<T> {
|
||||
type Target = Buffer<T>;
|
||||
|
||||
fn deref(&self) -> &Self::Target { &self.0 }
|
||||
}
|
||||
|
@ -1,23 +1,30 @@
|
||||
use super::buffer::Buffer;
|
||||
use super::buffer::DynamicBuffer;
|
||||
use bytemuck::Pod;
|
||||
|
||||
/// A handle to a series of constants sitting on the GPU. This is used to hold
|
||||
/// information used in the rendering process that does not change throughout a
|
||||
/// single render pass.
|
||||
pub struct Consts<T: Copy + Pod> {
|
||||
buf: Buffer<T>,
|
||||
buf: DynamicBuffer<T>,
|
||||
}
|
||||
|
||||
impl<T: Copy + Pod> Consts<T> {
|
||||
/// Create a new `Const<T>`.
|
||||
pub fn new(device: &wgpu::Device, len: u64) -> Self {
|
||||
pub fn new(device: &wgpu::Device, len: usize) -> Self {
|
||||
Self {
|
||||
buf: Buffer::new(device, len, wgpu::BufferUsage::UNIFORM),
|
||||
// TODO: examine if all our consts need to be updateable
|
||||
buf: DynamicBuffer::new(device, len, wgpu::BufferUsage::UNIFORM),
|
||||
}
|
||||
}
|
||||
|
||||
/// Update the GPU-side value represented by this constant handle.
|
||||
pub fn update(&mut self, device: &wgpu::Device, queue: &wgpu::Queue, vals: &[T], offset: u64) {
|
||||
pub fn update(
|
||||
&mut self,
|
||||
device: &wgpu::Device,
|
||||
queue: &wgpu::Queue,
|
||||
vals: &[T],
|
||||
offset: usize,
|
||||
) {
|
||||
self.buf.update(device, queue, vals, offset)
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
/// Used to represent one of many possible errors that may be omitted by the
|
||||
/// rendering subsystem.
|
||||
#[derive(Debug)]
|
||||
pub enum RenderError {
|
||||
RequestDeviceError(wgpu::RequestDeviceError),
|
||||
MappingError(wgpu::BufferAsyncError),
|
||||
@ -11,6 +10,23 @@ pub enum RenderError {
|
||||
ShaderError(shaderc::Error),
|
||||
}
|
||||
|
||||
use std::fmt;
|
||||
impl fmt::Debug for RenderError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Self::RequestDeviceError(err) => {
|
||||
f.debug_tuple("RequestDeviceError").field(err).finish()
|
||||
},
|
||||
Self::MappingError(err) => f.debug_tuple("MappingError").field(err).finish(),
|
||||
Self::SwapChainError(err) => f.debug_tuple("SwapChainError").field(err).finish(),
|
||||
Self::CustomError(err) => f.debug_tuple("CustomError").field(err).finish(),
|
||||
Self::CouldNotFindAdapter => f.debug_tuple("CouldNotFindAdapter").finish(),
|
||||
Self::ErrorInitializingCompiler => f.debug_tuple("ErrorInitializingCompiler").finish(),
|
||||
Self::ShaderError(err) => write!(f, "{}", err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<wgpu::RequestDeviceError> for RenderError {
|
||||
fn from(err: wgpu::RequestDeviceError) -> Self { Self::RequestDeviceError(err) }
|
||||
}
|
||||
|
@ -1,21 +1,30 @@
|
||||
use super::buffer::Buffer;
|
||||
use super::buffer::DynamicBuffer;
|
||||
use bytemuck::Pod;
|
||||
|
||||
/// Represents a mesh that has been sent to the GPU.
|
||||
pub struct Instances<T: Copy + Pod> {
|
||||
buf: Buffer<T>,
|
||||
buf: DynamicBuffer<T>,
|
||||
}
|
||||
|
||||
impl<T: Copy + Pod> Instances<T> {
|
||||
pub fn new(device: &wgpu::Device, len: u64) -> Self {
|
||||
pub fn new(device: &wgpu::Device, len: usize) -> Self {
|
||||
Self {
|
||||
buf: Buffer::new(device, len, wgpu::BufferUsage::VERTEX),
|
||||
// TODO: examine if we have Intances that are not updated and if there would be any
|
||||
// gains from separating those out
|
||||
buf: DynamicBuffer::new(device, len, wgpu::BufferUsage::VERTEX),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn count(&self) -> usize { self.buf.count() }
|
||||
// TODO: count vs len naming scheme??
|
||||
pub fn count(&self) -> usize { self.buf.len() }
|
||||
|
||||
pub fn update(&mut self, device: &wgpu::Device, queue: &wgpu::Queue, vals: &[T], offset: u64) {
|
||||
pub fn update(
|
||||
&mut self,
|
||||
device: &wgpu::Device,
|
||||
queue: &wgpu::Queue,
|
||||
vals: &[T],
|
||||
offset: usize,
|
||||
) {
|
||||
self.buf.update(device, queue, vals, offset)
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@ pub use self::{
|
||||
error::RenderError,
|
||||
instances::Instances,
|
||||
mesh::{Mesh, Quad, Tri},
|
||||
model::{Model, SubModel},
|
||||
model::{DynamicModel, Model, SubModel},
|
||||
pipelines::{
|
||||
clouds::{create_mesh as create_clouds_mesh, Locals as CloudsLocals},
|
||||
figure::{
|
||||
|
@ -1,4 +1,8 @@
|
||||
use super::{buffer::Buffer, mesh::Mesh, Vertex};
|
||||
use super::{
|
||||
buffer::{Buffer, DynamicBuffer},
|
||||
mesh::Mesh,
|
||||
Vertex,
|
||||
};
|
||||
use std::ops::Range;
|
||||
|
||||
/// Represents a mesh that has been sent to the GPU.
|
||||
@ -20,13 +24,7 @@ pub struct Model<V: Vertex> {
|
||||
impl<V: Vertex> Model<V> {
|
||||
pub fn new(device: &wgpu::Device, mesh: &Mesh<V>) -> Self {
|
||||
Self {
|
||||
vbuf: Buffer::new_with_data(device, wgpu::BufferUsage::VERTEX, mesh.vertices()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_dynamic(device: &wgpu::Device, size: u64) -> Self {
|
||||
Self {
|
||||
vbuf: Buffer::new(device, size, wgpu::BufferUsage::VERTEX),
|
||||
vbuf: Buffer::new(device, wgpu::BufferUsage::VERTEX, mesh.vertices()),
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,15 +38,44 @@ impl<V: Vertex> Model<V> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn buf(&self) -> &wgpu::Buffer { &self.vbuf.buf }
|
||||
|
||||
pub fn len(&self) -> usize { self.vbuf.len() }
|
||||
}
|
||||
|
||||
/// Represents a mesh that has been sent to the GPU.
|
||||
pub struct DynamicModel<V: Vertex> {
|
||||
vbuf: DynamicBuffer<V>,
|
||||
}
|
||||
|
||||
impl<V: Vertex> DynamicModel<V> {
|
||||
pub fn new(device: &wgpu::Device, size: usize) -> Self {
|
||||
Self {
|
||||
vbuf: DynamicBuffer::new(device, size, wgpu::BufferUsage::VERTEX),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update(
|
||||
&mut self,
|
||||
&self,
|
||||
device: &wgpu::Device,
|
||||
queue: &wgpu::Queue,
|
||||
mesh: &Mesh<V>,
|
||||
offset: u64,
|
||||
offset: usize,
|
||||
) {
|
||||
self.vbuf.update(device, queue, mesh.vertices(), offset)
|
||||
}
|
||||
|
||||
/// Create a model with a slice of a portion of this model to send to the
|
||||
/// renderer.
|
||||
pub fn submodel(&self, vertex_range: Range<u32>) -> SubModel<V> {
|
||||
SubModel {
|
||||
vertex_range,
|
||||
buf: self.buf(),
|
||||
phantom_data: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn buf(&self) -> &wgpu::Buffer { &self.vbuf.buf }
|
||||
|
||||
pub fn len(&self) -> usize { self.vbuf.len() }
|
||||
}
|
||||
|
@ -209,6 +209,7 @@ impl FigurePipeline {
|
||||
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,
|
||||
|
@ -33,14 +33,12 @@ impl Vertex {
|
||||
|
||||
fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> {
|
||||
use std::mem;
|
||||
const ATTRIBUTES: [wgpu::VertexAttributeDescriptor; 1] =
|
||||
wgpu::vertex_attr_array![0 => Uint];
|
||||
wgpu::VertexBufferDescriptor {
|
||||
stride: mem::size_of::<Self>() as wgpu::BufferAddress,
|
||||
step_mode: wgpu::InputStepMode::Vertex,
|
||||
attributes: &[wgpu::VertexAttributeDescriptor {
|
||||
offset: 0,
|
||||
shader_location: 0,
|
||||
format: wgpu::VertexFormat::Uint,
|
||||
}],
|
||||
attributes: &ATTRIBUTES,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -121,6 +119,7 @@ impl FluidPipeline {
|
||||
rasterization_state: Some(wgpu::RasterizationStateDescriptor {
|
||||
front_face: wgpu::FrontFace::Ccw,
|
||||
cull_mode: wgpu::CullMode::None,
|
||||
polygon_mode: wgpu::PolygonMode::Fill,
|
||||
clamp_depth: false,
|
||||
depth_bias: 0,
|
||||
depth_bias_slope_scale: 0.0,
|
||||
|
@ -17,14 +17,12 @@ 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: &[wgpu::VertexAttributeDescriptor {
|
||||
offset: 0,
|
||||
shader_location: 0,
|
||||
format: wgpu::VertexFormat::Float2,
|
||||
}],
|
||||
attributes: &ATTRIBUTES,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -87,7 +85,6 @@ impl LodData {
|
||||
&texture_info,
|
||||
&view_info,
|
||||
&sampler_info,
|
||||
map_size.x * 4,
|
||||
bytemuck::cast_slice(lod_base),
|
||||
);
|
||||
texture_info.format = wgpu::TextureFormat::Rg16Uint;
|
||||
@ -96,7 +93,6 @@ impl LodData {
|
||||
&texture_info,
|
||||
&view_info,
|
||||
&sampler_info,
|
||||
map_size.x * 4,
|
||||
bytemuck::cast_slice(lod_base),
|
||||
);
|
||||
texture_info.format = wgpu::TextureFormat::Rgba8Unorm;
|
||||
@ -105,7 +101,6 @@ impl LodData {
|
||||
&texture_info,
|
||||
&view_info,
|
||||
&sampler_info,
|
||||
map_size.x * 4,
|
||||
bytemuck::cast_slice(lod_base),
|
||||
);
|
||||
|
||||
@ -198,6 +193,7 @@ impl LodTerrainPipeline {
|
||||
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,
|
||||
|
@ -33,10 +33,12 @@ impl Vertex {
|
||||
|
||||
fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> {
|
||||
use std::mem;
|
||||
const ATTRIBUTES: [wgpu::VertexAttributeDescriptor; 2] =
|
||||
wgpu::vertex_attr_array![0 => Float3, 1 => Uint];
|
||||
wgpu::VertexBufferDescriptor {
|
||||
stride: mem::size_of::<Self>() as wgpu::BufferAddress,
|
||||
step_mode: wgpu::InputStepMode::Vertex,
|
||||
attributes: &wgpu::vertex_attr_array![0 => Float3, 1 => Uint],
|
||||
attributes: &ATTRIBUTES,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -150,10 +152,12 @@ impl Instance {
|
||||
|
||||
fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> {
|
||||
use std::mem;
|
||||
const ATTRIBUTES: [wgpu::VertexAttributeDescriptor; 5] =
|
||||
wgpu::vertex_attr_array![0 => Float, 1 => Float, 2 => Float, 3 => Int, 4 => Float3];
|
||||
wgpu::VertexBufferDescriptor {
|
||||
stride: mem::size_of::<Self>() as wgpu::BufferAddress,
|
||||
step_mode: wgpu::InputStepMode::Instance,
|
||||
attributes: &wgpu::vertex_attr_array![0 => Float, 1 => Float, 2 => Float, 3 => Int, 4 => Float3],
|
||||
attributes: &ATTRIBUTES,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -205,6 +209,7 @@ impl ParticlePipeline {
|
||||
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,
|
||||
|
@ -31,14 +31,12 @@ pub struct Vertex {
|
||||
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: &[wgpu::VertexAttributeDescriptor {
|
||||
offset: 0,
|
||||
shader_location: 0,
|
||||
format: wgpu::VertexFormat::Float2,
|
||||
}],
|
||||
attributes: &ATTRIBUTES,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -139,6 +137,7 @@ impl PostProcessPipeline {
|
||||
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,
|
||||
|
@ -95,7 +95,6 @@ pub fn create_col_lights(
|
||||
&texture_info,
|
||||
&view_info,
|
||||
&sampler_info,
|
||||
col_lights_size.x * 4,
|
||||
bytemuck::cast_slice(&col_lights),
|
||||
)
|
||||
}
|
||||
@ -149,6 +148,7 @@ impl ShadowFigurePipeline {
|
||||
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,
|
||||
@ -231,6 +231,7 @@ impl ShadowPipeline {
|
||||
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,
|
||||
|
@ -65,6 +65,7 @@ impl SkyboxPipeline {
|
||||
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,
|
||||
@ -103,6 +104,7 @@ impl SkyboxPipeline {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: generate mesh in vertex shader
|
||||
pub fn create_mesh() -> Mesh<Vertex> {
|
||||
let mut mesh = Mesh::new();
|
||||
|
||||
|
@ -61,10 +61,12 @@ impl Vertex {
|
||||
|
||||
fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> {
|
||||
use std::mem;
|
||||
const ATTRIBUTES: [wgpu::VertexAttributeDescriptor; 3] =
|
||||
wgpu::vertex_attr_array![0 => Float3, 1 => Uint, 2 => Uint];
|
||||
wgpu::VertexBufferDescriptor {
|
||||
stride: mem::size_of::<Self>() as wgpu::BufferAddress,
|
||||
step_mode: wgpu::InputStepMode::Vertex,
|
||||
attributes: &wgpu::vertex_attr_array![0 => Float3, 1 => Uint, 2 => Uint],
|
||||
attributes: &ATTRIBUTES,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -109,10 +111,11 @@ impl Instance {
|
||||
|
||||
fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> {
|
||||
use std::mem;
|
||||
const ATTRIBUTES: [wgpu::VertexAttributeDescriptor; 6] = wgpu::vertex_attr_array![0 => Uint, 1 => Float4,2 => Float4, 3 => Float4,4 => Float4, 5 => Float];
|
||||
wgpu::VertexBufferDescriptor {
|
||||
stride: mem::size_of::<Self>() as wgpu::BufferAddress,
|
||||
step_mode: wgpu::InputStepMode::Instance,
|
||||
attributes: &wgpu::vertex_attr_array![0 => Uint, 1 => Float4,2 => Float4, 3 => Float4,4 => Float4,5 => Float],
|
||||
attributes: &ATTRIBUTES,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -253,6 +256,7 @@ impl SpritePipeline {
|
||||
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,
|
||||
|
@ -120,20 +120,23 @@ impl Vertex {
|
||||
|
||||
pub fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> {
|
||||
use std::mem;
|
||||
const ATTRIBUTES: [wgpu::VertexAttributeDescriptor; 2] =
|
||||
wgpu::vertex_attr_array![0 => Uint,1 => Uint];
|
||||
wgpu::VertexBufferDescriptor {
|
||||
stride: mem::size_of::<Self>() as wgpu::BufferAddress,
|
||||
step_mode: wgpu::InputStepMode::Vertex,
|
||||
attributes: &wgpu::vertex_attr_array![0 => Uint,1 => Uint],
|
||||
attributes: &ATTRIBUTES,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, Zeroable, Pod)]
|
||||
// TODO: new function and private fields??
|
||||
pub struct Locals {
|
||||
model_offs: [f32; 3],
|
||||
load_time: f32,
|
||||
atlas_offs: [i32; 4],
|
||||
pub model_offs: [f32; 3],
|
||||
pub load_time: f32,
|
||||
pub atlas_offs: [i32; 4],
|
||||
}
|
||||
|
||||
impl Locals {
|
||||
@ -233,6 +236,7 @@ impl TerrainPipeline {
|
||||
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,
|
||||
|
@ -15,10 +15,12 @@ pub struct Vertex {
|
||||
impl Vertex {
|
||||
fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> {
|
||||
use std::mem;
|
||||
const ATTRIBUTES: [wgpu::VertexAttributeDescriptor; 5] =
|
||||
wgpu::vertex_attr_array![0 => Float2, 1 => Float2, 2 => Float4, 3 => Float2, 4 => Uint];
|
||||
wgpu::VertexBufferDescriptor {
|
||||
stride: mem::size_of::<Self>() as wgpu::BufferAddress,
|
||||
step_mode: wgpu::InputStepMode::Vertex,
|
||||
attributes: &wgpu::vertex_attr_array![0 => Float2, 1 => Float2, 2 => Float4, 3 => Float2, 4 => Uint],
|
||||
attributes: &ATTRIBUTES,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -165,6 +167,7 @@ impl UIPipeline {
|
||||
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,
|
||||
|
@ -2,7 +2,7 @@ use super::{
|
||||
consts::Consts,
|
||||
instances::Instances,
|
||||
mesh::Mesh,
|
||||
model::Model,
|
||||
model::{DynamicModel, Model},
|
||||
pipelines::{
|
||||
clouds, figure, fluid, lod_terrain, particle, postprocess, shadow, skybox, sprite, terrain,
|
||||
ui, GlobalsLayouts,
|
||||
@ -177,9 +177,9 @@ pub struct Layouts {
|
||||
/// rendering subsystem and contains any state necessary to interact with the
|
||||
/// GPU, along with pipeline state objects (PSOs) needed to renderer different
|
||||
/// kinds of models to the screen.
|
||||
pub struct Renderer<'a> {
|
||||
window: &'a winit::window::Window,
|
||||
|
||||
pub struct Renderer {
|
||||
// TODO: why????
|
||||
//window: &'a winit::window::Window,
|
||||
device: wgpu::Device,
|
||||
queue: wgpu::Queue,
|
||||
swap_chain: wgpu::SwapChain,
|
||||
@ -216,12 +216,14 @@ pub struct Renderer<'a> {
|
||||
noise_tex: Texture,
|
||||
|
||||
mode: RenderMode,
|
||||
|
||||
resolution: Vec2<u32>,
|
||||
}
|
||||
|
||||
impl<'a> Renderer<'a> {
|
||||
impl Renderer {
|
||||
/// Create a new `Renderer` from a variety of backend-specific components
|
||||
/// and the window targets.
|
||||
pub fn new(window: &'a winit::window::Window, mode: RenderMode) -> Result<Self, RenderError> {
|
||||
pub fn new(window: &winit::window::Window, mode: RenderMode) -> Result<Self, RenderError> {
|
||||
// Enable seamless cubemaps globally, where available--they are essentially a
|
||||
// strict improvement on regular cube maps.
|
||||
//
|
||||
@ -231,7 +233,9 @@ impl<'a> Renderer<'a> {
|
||||
|
||||
let dims = window.inner_size();
|
||||
|
||||
let instance = wgpu::Instance::new(wgpu::BackendBit::PRIMARY | wgpu::BackendBit::SECONDARY);
|
||||
let instance = wgpu::Instance::new(
|
||||
wgpu::BackendBit::PRIMARY, /* | wgpu::BackendBit::SECONDARY */
|
||||
);
|
||||
|
||||
// This is unsafe because the window handle must be valid, if you find a way to
|
||||
// have an invalid winit::Window then you have bigger issues
|
||||
@ -251,6 +255,7 @@ impl<'a> Renderer<'a> {
|
||||
let (device, queue) = futures::executor::block_on(adapter.request_device(
|
||||
&wgpu::DeviceDescriptor {
|
||||
// TODO
|
||||
label: None,
|
||||
features: Features::DEPTH_CLAMPING | Features::ADDRESS_MODE_CLAMP_TO_BORDER,
|
||||
limits: Limits::default(),
|
||||
shader_validation: true,
|
||||
@ -269,7 +274,7 @@ impl<'a> Renderer<'a> {
|
||||
);
|
||||
|
||||
let sc_desc = wgpu::SwapChainDescriptor {
|
||||
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
|
||||
usage: wgpu::TextureUsage::RENDER_ATTACHMENT,
|
||||
format: wgpu::TextureFormat::Bgra8UnormSrgb,
|
||||
width: dims.width,
|
||||
height: dims.height,
|
||||
@ -387,8 +392,6 @@ impl<'a> Renderer<'a> {
|
||||
)?;
|
||||
|
||||
Ok(Self {
|
||||
window,
|
||||
|
||||
device,
|
||||
queue,
|
||||
swap_chain,
|
||||
@ -423,6 +426,8 @@ impl<'a> Renderer<'a> {
|
||||
noise_tex,
|
||||
|
||||
mode,
|
||||
|
||||
resolution: Vec2::new(dims.width, dims.height),
|
||||
})
|
||||
}
|
||||
|
||||
@ -443,7 +448,7 @@ impl<'a> Renderer<'a> {
|
||||
self.mode = mode;
|
||||
|
||||
// Recreate render target
|
||||
self.on_resize()?;
|
||||
self.on_resize(self.resolution)?;
|
||||
|
||||
// Recreate pipelines with the new AA mode
|
||||
self.recreate_pipelines();
|
||||
@ -455,13 +460,11 @@ impl<'a> Renderer<'a> {
|
||||
pub fn render_mode(&self) -> &RenderMode { &self.mode }
|
||||
|
||||
/// Resize internal render targets to match window render target dimensions.
|
||||
pub fn on_resize(&mut self) -> Result<(), RenderError> {
|
||||
let dims = self.window.inner_size();
|
||||
|
||||
pub fn on_resize(&mut self, dims: Vec2<u32>) -> Result<(), RenderError> {
|
||||
// Avoid panics when creating texture with w,h of 0,0.
|
||||
if dims.width != 0 && dims.height != 0 {
|
||||
if dims.x != 0 && dims.y != 0 {
|
||||
let (tgt_color_view, tgt_depth_stencil_view, tgt_color_pp_view, win_depth_view) =
|
||||
Self::create_rt_views(&mut self.device, (dims.width, dims.height), &self.mode)?;
|
||||
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;
|
||||
@ -469,8 +472,7 @@ impl<'a> Renderer<'a> {
|
||||
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.width, dims.height), &mode)
|
||||
{
|
||||
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;
|
||||
@ -480,6 +482,8 @@ impl<'a> Renderer<'a> {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
self.resolution = dims;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -523,7 +527,7 @@ impl<'a> Renderer<'a> {
|
||||
sample_count,
|
||||
dimension: wgpu::TextureDimension::D2,
|
||||
format: wgpu::TextureFormat::Rgba8UnormSrgb,
|
||||
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::OUTPUT_ATTACHMENT,
|
||||
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::RENDER_ATTACHMENT,
|
||||
});
|
||||
|
||||
tex.create_view(&wgpu::TextureViewDescriptor {
|
||||
@ -553,7 +557,7 @@ impl<'a> Renderer<'a> {
|
||||
sample_count,
|
||||
dimension: wgpu::TextureDimension::D2,
|
||||
format: wgpu::TextureFormat::Depth24Plus,
|
||||
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::OUTPUT_ATTACHMENT,
|
||||
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::RENDER_ATTACHMENT,
|
||||
});
|
||||
let tgt_depth_stencil_view =
|
||||
tgt_depth_stencil_tex.create_view(&wgpu::TextureViewDescriptor {
|
||||
@ -578,7 +582,7 @@ impl<'a> Renderer<'a> {
|
||||
sample_count,
|
||||
dimension: wgpu::TextureDimension::D2,
|
||||
format: wgpu::TextureFormat::Depth24Plus,
|
||||
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
|
||||
usage: wgpu::TextureUsage::RENDER_ATTACHMENT,
|
||||
});
|
||||
let win_depth_view = tgt_depth_stencil_tex.create_view(&wgpu::TextureViewDescriptor {
|
||||
label: None,
|
||||
@ -667,7 +671,19 @@ impl<'a> Renderer<'a> {
|
||||
sample_count: 1,
|
||||
dimension: wgpu::TextureDimension::D2,
|
||||
format: wgpu::TextureFormat::Depth24Plus,
|
||||
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::OUTPUT_ATTACHMENT,
|
||||
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::RENDER_ATTACHMENT,
|
||||
};
|
||||
|
||||
//TODO: (0, levels - 1), ?? from master
|
||||
let mut point_shadow_view = wgpu::TextureViewDescriptor {
|
||||
label: None,
|
||||
format: Some(wgpu::TextureFormat::Depth24Plus),
|
||||
dimension: Some(wgpu::TextureViewDimension::Cube),
|
||||
aspect: wgpu::TextureAspect::DepthOnly,
|
||||
base_mip_level: 0,
|
||||
level_count: None,
|
||||
base_array_layer: 0,
|
||||
array_layer_count: None,
|
||||
};
|
||||
|
||||
let directed_shadow_tex = wgpu::TextureDescriptor {
|
||||
@ -681,10 +697,10 @@ impl<'a> Renderer<'a> {
|
||||
sample_count: 1,
|
||||
dimension: wgpu::TextureDimension::D2,
|
||||
format: wgpu::TextureFormat::Depth24Plus,
|
||||
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::OUTPUT_ATTACHMENT,
|
||||
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::RENDER_ATTACHMENT,
|
||||
};
|
||||
|
||||
let mut view_info = wgpu::TextureViewDescriptor {
|
||||
let directed_shadow_view = wgpu::TextureViewDescriptor {
|
||||
label: None,
|
||||
format: Some(wgpu::TextureFormat::Depth24Plus),
|
||||
dimension: Some(wgpu::TextureViewDimension::D2),
|
||||
@ -707,30 +723,27 @@ impl<'a> Renderer<'a> {
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let point_tgt_shadow =
|
||||
Texture::new_raw(device, &point_shadow_tex, &view_info, &sampler_info);
|
||||
view_info.dimension = Some(wgpu::TextureViewDimension::Cube);
|
||||
let directed_shadow_tex =
|
||||
Texture::new_raw(device, &directed_shadow_tex, &view_info, &sampler_info);
|
||||
let point_shadow_tex =
|
||||
Texture::new_raw(device, &point_shadow_tex, &point_shadow_view, &sampler_info);
|
||||
let directed_shadow_tex = Texture::new_raw(
|
||||
device,
|
||||
&directed_shadow_tex,
|
||||
&directed_shadow_view,
|
||||
&sampler_info,
|
||||
);
|
||||
|
||||
Ok((point_tgt_shadow, directed_shadow_tex))
|
||||
Ok((point_shadow_tex, directed_shadow_tex))
|
||||
}
|
||||
|
||||
/// Get the resolution of the render target.
|
||||
pub fn get_resolution(&self) -> Vec2<u32> {
|
||||
let dims = self.window.inner_size();
|
||||
|
||||
Vec2::new(dims.width, dims.height)
|
||||
}
|
||||
pub fn resolution(&self) -> Vec2<u32> { self.resolution }
|
||||
|
||||
/// Get the resolution of the shadow render target.
|
||||
pub fn get_shadow_resolution(&self) -> (Vec2<u32>, Vec2<u32>) {
|
||||
if let Some(shadow_map) = &self.shadow_map {
|
||||
let point_dims = shadow_map.point_depth_stencil.get_dimensions();
|
||||
let directed_dims = shadow_map.directed_depth_stencil.get_dimensions();
|
||||
(
|
||||
Vec2::new(point_dims.width, point_dims.height),
|
||||
Vec2::new(directed_dims.width, directed_dims.height),
|
||||
shadow_map.point_depth_stencil.get_dimensions().xy(),
|
||||
shadow_map.directed_depth_stencil.get_dimensions().xy(),
|
||||
)
|
||||
} else {
|
||||
(Vec2::new(1, 1), Vec2::new(1, 1))
|
||||
@ -882,7 +895,7 @@ impl<'a> Renderer<'a> {
|
||||
&mut self,
|
||||
vals: &[T],
|
||||
) -> Result<Consts<T>, RenderError> {
|
||||
let mut consts = Consts::new(&self.device, vals.len() as u64);
|
||||
let mut consts = Consts::new(&self.device, vals.len());
|
||||
consts.update(&self.device, &self.queue, vals, 0);
|
||||
Ok(consts)
|
||||
}
|
||||
@ -897,7 +910,7 @@ impl<'a> Renderer<'a> {
|
||||
&mut self,
|
||||
vals: &[T],
|
||||
) -> Result<Instances<T>, RenderError> {
|
||||
let mut instances = Instances::new(&self.device, vals.len() as u64);
|
||||
let mut instances = Instances::new(&self.device, vals.len());
|
||||
instances.update(&self.device, &self.queue, vals, 0);
|
||||
Ok(instances)
|
||||
}
|
||||
@ -908,12 +921,12 @@ impl<'a> Renderer<'a> {
|
||||
}
|
||||
|
||||
/// Create a new dynamic model with the specified size.
|
||||
pub fn create_dynamic_model<V: Vertex>(&mut self, size: u64) -> Model<V> {
|
||||
Model::new_dynamic(&self.device, size)
|
||||
pub fn create_dynamic_model<V: Vertex>(&mut self, size: usize) -> DynamicModel<V> {
|
||||
DynamicModel::new(&self.device, size)
|
||||
}
|
||||
|
||||
/// Update a dynamic model with a mesh and a offset.
|
||||
pub fn update_model<V: Vertex>(&mut self, model: &Model<V>, mesh: &Mesh<V>, offset: u64) {
|
||||
pub fn update_model<V: Vertex>(&self, model: &DynamicModel<V>, mesh: &Mesh<V>, offset: usize) {
|
||||
model.update(&self.device, &self.queue, mesh, offset)
|
||||
}
|
||||
|
||||
@ -933,7 +946,6 @@ impl<'a> Renderer<'a> {
|
||||
texture_info: &wgpu::TextureDescriptor,
|
||||
view_info: &wgpu::TextureViewDescriptor,
|
||||
sampler_info: &wgpu::SamplerDescriptor,
|
||||
bytes_per_row: u32,
|
||||
data: &[u8],
|
||||
) -> Texture {
|
||||
let tex = Texture::new_raw(&self.device, &texture_info, &view_info, &sampler_info);
|
||||
@ -944,7 +956,6 @@ impl<'a> Renderer<'a> {
|
||||
[0; 2],
|
||||
[texture_info.size.width, texture_info.size.height],
|
||||
data,
|
||||
bytes_per_row,
|
||||
);
|
||||
|
||||
tex
|
||||
@ -1004,7 +1015,6 @@ impl<'a> Renderer<'a> {
|
||||
// Copy, {
|
||||
// texture.update(&mut self.encoder, offset, size, data)
|
||||
data: &[[u8; 4]],
|
||||
bytes_per_row: u32,
|
||||
) {
|
||||
texture.update(
|
||||
&self.device,
|
||||
@ -1012,7 +1022,6 @@ impl<'a> Renderer<'a> {
|
||||
offset,
|
||||
size,
|
||||
bytemuck::cast_slice(data),
|
||||
bytes_per_row,
|
||||
)
|
||||
}
|
||||
|
||||
@ -1882,16 +1891,16 @@ fn create_pipelines(
|
||||
Ok(ResolvedInclude {
|
||||
resolved_name: name.to_string(),
|
||||
content: match name {
|
||||
"constants.glsl" => constants,
|
||||
"globals.glsl" => *globals,
|
||||
"shadows.glsl" => *shadows,
|
||||
"sky.glsl" => *sky,
|
||||
"light.glsl" => *light,
|
||||
"srgb.glsl" => *srgb,
|
||||
"random.glsl" => *random,
|
||||
"lod.glsl" => *lod,
|
||||
"anti-aliasing.glsl" => *anti_alias,
|
||||
"cloud.glsl" => *cloud,
|
||||
"constants.glsl" => constants.clone(),
|
||||
"globals.glsl" => globals.as_ref().clone(),
|
||||
"shadows.glsl" => shadows.as_ref().clone(),
|
||||
"sky.glsl" => sky.as_ref().clone(),
|
||||
"light.glsl" => light.as_ref().clone(),
|
||||
"srgb.glsl" => srgb.as_ref().clone(),
|
||||
"random.glsl" => random.as_ref().clone(),
|
||||
"lod.glsl" => lod.as_ref().clone(),
|
||||
"anti-aliasing.glsl" => anti_alias.as_ref().clone(),
|
||||
"cloud.glsl" => cloud.as_ref().clone(),
|
||||
other => return Err(format!("Include {} is not defined", other)),
|
||||
},
|
||||
})
|
||||
@ -2298,7 +2307,7 @@ fn create_pipelines(
|
||||
))
|
||||
}
|
||||
|
||||
pub fn create_shader_module(
|
||||
fn create_shader_module(
|
||||
device: &wgpu::Device,
|
||||
compiler: &mut shaderc::Compiler,
|
||||
source: &str,
|
||||
|
@ -18,7 +18,7 @@ impl Texture {
|
||||
filter_method: Option<wgpu::FilterMode>,
|
||||
address_mode: Option<wgpu::AddressMode>,
|
||||
) -> Result<Self, RenderError> {
|
||||
// TODO: Actualy handle images that aren't in rgba format properly.
|
||||
// TODO: Actually handle images that aren't in rgba format properly.
|
||||
let buffer = image.as_flat_samples_u8().ok_or_else(|| {
|
||||
RenderError::CustomError(
|
||||
"We currently do not support color formats using more than 4 bytes / pixel.".into(),
|
||||
@ -38,7 +38,7 @@ impl Texture {
|
||||
sample_count: 1,
|
||||
dimension: wgpu::TextureDimension::D2,
|
||||
format: wgpu::TextureFormat::Rgba8UnormSrgb,
|
||||
usage: wgpu::TextureUsage::COPY_DST | wgpu::TextureUsage::SAMPLED,
|
||||
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::COPY_DST,
|
||||
});
|
||||
|
||||
let mut command_encoder =
|
||||
@ -107,7 +107,8 @@ impl Texture {
|
||||
sample_count: 1,
|
||||
dimension: wgpu::TextureDimension::D2,
|
||||
format: wgpu::TextureFormat::Rgba8UnormSrgb,
|
||||
usage: wgpu::TextureUsage::COPY_DST | wgpu::TextureUsage::SAMPLED,
|
||||
// TODO: nondynamic version doesn't seeem to have different usage, unify code?
|
||||
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::COPY_DST,
|
||||
};
|
||||
|
||||
let sampler_info = wgpu::SamplerDescriptor {
|
||||
@ -161,8 +162,10 @@ impl Texture {
|
||||
offset: [u32; 2],
|
||||
size: [u32; 2],
|
||||
data: &[u8],
|
||||
bytes_per_row: u32,
|
||||
) {
|
||||
// Note: we only accept 4 bytes per pixel
|
||||
// (enforce this is API?)
|
||||
debug_assert_eq!(data.len(), size[0] as usize * size[1] as usize * 4);
|
||||
// TODO: Only works for 2D images
|
||||
queue.write_texture(
|
||||
wgpu::TextureCopyViewBase {
|
||||
@ -177,8 +180,8 @@ impl Texture {
|
||||
data,
|
||||
wgpu::TextureDataLayout {
|
||||
offset: 0,
|
||||
bytes_per_row,
|
||||
rows_per_image: self.size.height,
|
||||
bytes_per_row: size[0] * 4,
|
||||
rows_per_image: size[1],
|
||||
},
|
||||
wgpu::Extent3d {
|
||||
width: size[0],
|
||||
@ -189,5 +192,7 @@ impl Texture {
|
||||
}
|
||||
|
||||
/// Get dimensions of the represented image.
|
||||
pub fn get_dimensions(&self) -> Extent3d { self.size }
|
||||
pub fn get_dimensions(&self) -> vek::Vec3<u32> {
|
||||
vek::Vec3::new(self.size.width, self.size.height, self.size.depth)
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ use crate::{
|
||||
ecs::comp::Interpolated,
|
||||
render::{
|
||||
pipelines, ColLightInfo, Consts, FigureBoneData, FigureLocals, FigureModel, GlobalModel,
|
||||
Mesh, RenderError, Renderer, TerrainVertex, Texture,
|
||||
Mesh, RenderError, Renderer, SubModel, TerrainVertex, Texture,
|
||||
},
|
||||
scene::{
|
||||
camera::{Camera, CameraMode, Dependents},
|
||||
@ -63,7 +63,7 @@ pub type CameraData<'a> = (&'a Camera, f32);
|
||||
pub type FigureModelRef<'a> = (
|
||||
&'a Consts<FigureLocals>,
|
||||
&'a Consts<FigureBoneData>,
|
||||
&'a FigureModel,
|
||||
SubModel<'a, TerrainVertex>,
|
||||
&'a Texture, /* <ColLightFmt> */
|
||||
);
|
||||
|
||||
@ -81,9 +81,19 @@ pub struct FigureModelEntry<const N: usize> {
|
||||
/* TODO: Consider using mipmaps instead of storing multiple texture atlases for different
|
||||
* LOD levels. */
|
||||
col_lights: Texture, /* <ColLightFmt> */
|
||||
/// Models stored in this figure entry; there may be several for one figure,
|
||||
/// because of LOD models.
|
||||
pub models: [FigureModel; N],
|
||||
/// Vertex ranges stored in this figure entry; there may be several for one
|
||||
/// figure, because of LOD models.
|
||||
lod_vertex_ranges: [Range<u32>; N],
|
||||
model: FigureModel,
|
||||
}
|
||||
|
||||
impl<const N: usize> FigureModelEntry<N> {
|
||||
pub fn lod_model(&self, lod: usize) -> SubModel<TerrainVertex> {
|
||||
// Note: Range doesn't impl Copy even for trivially Cloneable things
|
||||
self.model
|
||||
.opaque
|
||||
.submodel(self.lod_vertex_ranges[lod].clone())
|
||||
}
|
||||
}
|
||||
|
||||
struct FigureMgrStates {
|
||||
@ -4734,13 +4744,14 @@ impl FigureMgr {
|
||||
figure_lod_render_distance * scale.map_or(1.0, |s| s.0),
|
||||
|state| state.can_shadow_sun(),
|
||||
) {
|
||||
renderer.render_figure_shadow_directed(
|
||||
model,
|
||||
global,
|
||||
locals,
|
||||
bone_consts,
|
||||
&global.shadow_mats,
|
||||
);
|
||||
// TODO
|
||||
//renderer.render_figure_shadow_directed(
|
||||
// model,
|
||||
// global,
|
||||
// locals,
|
||||
// bone_consts,
|
||||
// &global.shadow_mats,
|
||||
//);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -4791,7 +4802,8 @@ impl FigureMgr {
|
||||
figure_lod_render_distance * scale.map_or(1.0, |s| s.0),
|
||||
|state| state.visible(),
|
||||
) {
|
||||
renderer.render_figure(model, &col_lights, global, locals, bone_consts, lod);
|
||||
// renderer.render_figure(model, &col_lights, global,
|
||||
// locals, bone_consts, lod);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4839,15 +4851,16 @@ impl FigureMgr {
|
||||
figure_lod_render_distance,
|
||||
|state| state.visible(),
|
||||
) {
|
||||
renderer.render_player(model, &col_lights, global, locals, bone_consts, lod);
|
||||
renderer.render_player_shadow(
|
||||
//renderer.render_player(model, &col_lights, global, locals,
|
||||
// bone_consts, lod);
|
||||
/*renderer.render_player_shadow(
|
||||
model,
|
||||
&col_lights,
|
||||
global,
|
||||
bone_consts,
|
||||
lod,
|
||||
&global.shadow_mats,
|
||||
);
|
||||
);*/
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5175,11 +5188,11 @@ impl FigureMgr {
|
||||
let figure_mid_detail_distance = figure_lod_render_distance * 0.5;
|
||||
|
||||
let model = if pos.distance_squared(cam_pos) > figure_low_detail_distance.powi(2) {
|
||||
&model_entry.models[2]
|
||||
model_entry.lod_model(2)
|
||||
} else if pos.distance_squared(cam_pos) > figure_mid_detail_distance.powi(2) {
|
||||
&model_entry.models[1]
|
||||
model_entry.lod_model(1)
|
||||
} else {
|
||||
&model_entry.models[0]
|
||||
model_entry.lod_model(0)
|
||||
};
|
||||
|
||||
Some((locals, bone_consts, model, col_lights_.texture(model_entry)))
|
||||
@ -5225,7 +5238,7 @@ impl FigureColLights {
|
||||
renderer: &mut Renderer,
|
||||
(tex, tex_size): ColLightInfo,
|
||||
(opaque, bounds): (Mesh<TerrainVertex>, math::Aabb<f32>),
|
||||
vertex_range: [Range<u32>; N],
|
||||
vertex_ranges: [Range<u32>; N],
|
||||
) -> Result<FigureModelEntry<N>, RenderError> {
|
||||
span!(_guard, "create_figure", "FigureColLights::create_figure");
|
||||
let atlas = &mut self.atlas;
|
||||
@ -5237,22 +5250,22 @@ impl FigureColLights {
|
||||
.expect("The model size for this figure does not fit in a u32!");
|
||||
let model = renderer.create_model(&opaque)?;
|
||||
|
||||
vertex_ranges.iter().for_each(|range| {
|
||||
assert!(
|
||||
range.start <= range.end && range.end <= model_len,
|
||||
"The provided vertex range for figure mesh {:?} does not fit in the model, which \
|
||||
is of size {:?}!",
|
||||
range,
|
||||
model_len
|
||||
);
|
||||
});
|
||||
|
||||
Ok(FigureModelEntry {
|
||||
_bounds: bounds,
|
||||
models: vertex_range.map(|range| {
|
||||
assert!(
|
||||
range.start <= range.end && range.end <= model_len,
|
||||
"The provided vertex range for figure mesh {:?} does not fit in the model, \
|
||||
which is of size {:?}!",
|
||||
range,
|
||||
model_len
|
||||
);
|
||||
FigureModel {
|
||||
opaque: model.submodel(range),
|
||||
}
|
||||
}),
|
||||
col_lights,
|
||||
allocation,
|
||||
col_lights,
|
||||
lod_vertex_ranges: vertex_ranges,
|
||||
model: FigureModel { opaque: model },
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -61,7 +61,8 @@ impl Lod {
|
||||
|
||||
pub fn render(&self, renderer: &mut Renderer, global: &GlobalModel) {
|
||||
if let Some((_, model)) = self.model.as_ref() {
|
||||
renderer.render_lod_terrain(&model, global, &self.locals, &self.data);
|
||||
//renderer.render_lod_terrain(&model, global, &self.locals,
|
||||
// &self.data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -271,7 +271,7 @@ impl Scene {
|
||||
client: &Client,
|
||||
settings: &Settings,
|
||||
) -> Self {
|
||||
let resolution = renderer.get_resolution().map(|e| e as f32);
|
||||
let resolution = renderer.resolution().map(|e| e as f32);
|
||||
let sprite_render_context = lazy_init(renderer);
|
||||
|
||||
Self {
|
||||
@ -642,7 +642,7 @@ impl Scene {
|
||||
self.map_bounds,
|
||||
time_of_day,
|
||||
scene_data.state.get_time(),
|
||||
renderer.get_resolution().as_(),
|
||||
renderer.resolution().as_(),
|
||||
Vec2::new(SHADOW_NEAR, SHADOW_FAR),
|
||||
lights.len(),
|
||||
shadows.len(),
|
||||
@ -1061,7 +1061,7 @@ impl Scene {
|
||||
self.lod.render(renderer, global);
|
||||
|
||||
// Render the skybox.
|
||||
renderer.render_skybox(&self.skybox.model, global, &self.skybox.locals, lod);
|
||||
// TODO: renderer.render_skybox(&self.skybox.model, global, lod);
|
||||
|
||||
self.terrain.render_translucent(
|
||||
renderer,
|
||||
@ -1075,19 +1075,20 @@ impl Scene {
|
||||
// Render particle effects.
|
||||
self.particle_mgr.render(renderer, scene_data, global, lod);
|
||||
|
||||
// Render clouds (a post-processing effect)
|
||||
renderer.render_clouds(
|
||||
&self.clouds.model,
|
||||
&global.globals,
|
||||
&self.clouds.locals,
|
||||
self.lod.get_data(),
|
||||
);
|
||||
// TODO:
|
||||
// // Render clouds (a post-processing effect)
|
||||
// renderer.render_clouds(
|
||||
// &self.clouds.model,
|
||||
// &global.globals,
|
||||
// &self.clouds.locals,
|
||||
// self.lod.get_data(),
|
||||
// );
|
||||
|
||||
renderer.render_post_process(
|
||||
&self.postprocess.model,
|
||||
&global.globals,
|
||||
&self.postprocess.locals,
|
||||
self.lod.get_data(),
|
||||
);
|
||||
// renderer.render_post_process(
|
||||
// &self.postprocess.model,
|
||||
// &global.globals,
|
||||
// &self.postprocess.locals,
|
||||
// self.lod.get_data(),
|
||||
// );
|
||||
}
|
||||
}
|
||||
|
@ -1192,7 +1192,8 @@ impl ParticleMgr {
|
||||
.get(DEFAULT_MODEL_KEY)
|
||||
.expect("Expected particle model in cache");
|
||||
|
||||
renderer.render_particles(model, global, &self.instances, lod);
|
||||
/* renderer.render_particles(model, global, &self.instances,
|
||||
* lod); */
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,6 @@ use common::{
|
||||
terrain::BlockKind,
|
||||
vol::{BaseVol, ReadVol},
|
||||
};
|
||||
use tracing::error;
|
||||
use vek::*;
|
||||
use winit::event::MouseButton;
|
||||
|
||||
@ -104,7 +103,7 @@ pub struct SceneData<'a> {
|
||||
impl Scene {
|
||||
pub fn new(renderer: &mut Renderer, backdrop: Option<&str>, client: &Client) -> Self {
|
||||
let start_angle = 90.0f32.to_radians();
|
||||
let resolution = renderer.get_resolution().map(|e| e as f32);
|
||||
let resolution = renderer.resolution().map(|e| e as f32);
|
||||
|
||||
let map_bounds = Vec2::new(
|
||||
client.world_data().min_chunk_alt(),
|
||||
@ -278,7 +277,7 @@ impl Scene {
|
||||
self.map_bounds,
|
||||
TIME,
|
||||
scene_data.time,
|
||||
renderer.get_resolution().as_(),
|
||||
renderer.resolution().as_(),
|
||||
Vec2::new(SHADOW_NEAR, SHADOW_FAR),
|
||||
0,
|
||||
0,
|
||||
@ -380,12 +379,12 @@ impl Scene {
|
||||
body: Option<humanoid::Body>,
|
||||
inventory: Option<&Inventory>,
|
||||
) {
|
||||
renderer.render_skybox(
|
||||
/*renderer.render_skybox(
|
||||
&self.skybox.model,
|
||||
&self.data,
|
||||
&self.skybox.locals,
|
||||
&self.lod,
|
||||
);
|
||||
);*/
|
||||
|
||||
if let Some(body) = body {
|
||||
let model = &self.figure_model_cache.get_model(
|
||||
@ -398,40 +397,40 @@ impl Scene {
|
||||
);
|
||||
|
||||
if let Some(model) = model {
|
||||
renderer.render_figure(
|
||||
&model.models[0],
|
||||
&self.col_lights.texture(model),
|
||||
&self.data,
|
||||
self.figure_state.locals(),
|
||||
self.figure_state.bone_consts(),
|
||||
&self.lod,
|
||||
);
|
||||
// renderer.render_figure(
|
||||
// &model.models[0],
|
||||
// &self.col_lights.texture(model),
|
||||
// &self.data,
|
||||
// self.figure_state.locals(),
|
||||
// self.figure_state.bone_consts(),
|
||||
// &self.lod,
|
||||
// );
|
||||
}
|
||||
}
|
||||
|
||||
if let Some((model, state)) = &self.backdrop {
|
||||
renderer.render_figure(
|
||||
/*renderer.render_figure(
|
||||
&model.models[0],
|
||||
&self.col_lights.texture(model),
|
||||
&self.data,
|
||||
state.locals(),
|
||||
state.bone_consts(),
|
||||
&self.lod,
|
||||
);
|
||||
);*/
|
||||
}
|
||||
|
||||
renderer.render_clouds(
|
||||
&self.clouds.model,
|
||||
&self.data.globals,
|
||||
&self.clouds.locals,
|
||||
&self.lod,
|
||||
);
|
||||
// renderer.render_clouds(
|
||||
// &self.clouds.model,
|
||||
// &self.data.globals,
|
||||
// &self.clouds.locals,
|
||||
// &self.lod,
|
||||
// );
|
||||
|
||||
renderer.render_post_process(
|
||||
&self.postprocess.model,
|
||||
&self.data.globals,
|
||||
&self.postprocess.locals,
|
||||
&self.lod,
|
||||
);
|
||||
// renderer.render_post_process(
|
||||
// &self.postprocess.model,
|
||||
// &self.data.globals,
|
||||
// &self.postprocess.locals,
|
||||
// &self.lod,
|
||||
// );
|
||||
}
|
||||
}
|
||||
|
@ -1429,12 +1429,12 @@ impl<V: RectRasterableVol> Terrain<V> {
|
||||
.chain(self.shadow_chunks.iter().map(|(_, chunk)| chunk))
|
||||
.for_each(|chunk| {
|
||||
// Directed light shadows.
|
||||
renderer.render_terrain_shadow_directed(
|
||||
/*renderer.render_terrain_shadow_directed(
|
||||
&chunk.opaque_model,
|
||||
global,
|
||||
&chunk.locals,
|
||||
&global.shadow_mats,
|
||||
);
|
||||
);*/
|
||||
});
|
||||
}
|
||||
|
||||
@ -1445,12 +1445,12 @@ impl<V: RectRasterableVol> Terrain<V> {
|
||||
light_data.iter().take(1).for_each(|_light| {
|
||||
chunk_iter.clone().for_each(|chunk| {
|
||||
if chunk.can_shadow_point {
|
||||
renderer.render_shadow_point(
|
||||
/*renderer.render_shadow_point(
|
||||
&chunk.opaque_model,
|
||||
global,
|
||||
&chunk.locals,
|
||||
&global.shadow_mats,
|
||||
);
|
||||
);*/
|
||||
}
|
||||
});
|
||||
});
|
||||
@ -1477,13 +1477,13 @@ impl<V: RectRasterableVol> Terrain<V> {
|
||||
|
||||
for (_, chunk) in chunk_iter {
|
||||
if chunk.visible.is_visible() {
|
||||
renderer.render_terrain_chunk(
|
||||
/* renderer.render_terrain_chunk(
|
||||
&chunk.opaque_model,
|
||||
&chunk.texture,
|
||||
global,
|
||||
&chunk.locals,
|
||||
lod,
|
||||
);
|
||||
);*/
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1558,7 +1558,7 @@ impl<V: RectRasterableVol> Terrain<V> {
|
||||
} else {
|
||||
&self.sprite_data[&kind][4]
|
||||
};
|
||||
renderer.render_sprites(
|
||||
/*renderer.render_sprites(
|
||||
model,
|
||||
&self.sprite_col_lights,
|
||||
global,
|
||||
@ -1566,7 +1566,7 @@ impl<V: RectRasterableVol> Terrain<V> {
|
||||
locals,
|
||||
&instances,
|
||||
lod,
|
||||
);
|
||||
);*/
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1587,13 +1587,13 @@ impl<V: RectRasterableVol> Terrain<V> {
|
||||
.into_iter()
|
||||
.rev() // Render back-to-front
|
||||
.for_each(|(model, locals)| {
|
||||
renderer.render_fluid_chunk(
|
||||
/*renderer.render_fluid_chunk(
|
||||
model,
|
||||
global,
|
||||
locals,
|
||||
lod,
|
||||
&self.waves,
|
||||
)
|
||||
)*/
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ use hashbrown::HashMap;
|
||||
use vek::*;
|
||||
|
||||
// Multiplied by current window size
|
||||
const GLYPH_CACHE_SIZE: u16 = 1;
|
||||
const GLYPH_CACHE_SIZE: u32 = 1;
|
||||
// Glyph cache tolerances
|
||||
const SCALE_TOLERANCE: f32 = 0.5;
|
||||
const POSITION_TOLERANCE: f32 = 0.5;
|
||||
@ -26,7 +26,7 @@ pub struct Cache {
|
||||
// TODO: Should functions be returning UiError instead of Error?
|
||||
impl Cache {
|
||||
pub fn new(renderer: &mut Renderer) -> 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();
|
||||
|
||||
@ -36,11 +36,11 @@ impl Cache {
|
||||
Ok(Self {
|
||||
text_cache: Default::default(),
|
||||
glyph_cache: GlyphCache::builder()
|
||||
.dimensions(glyph_cache_dims.x as u32, glyph_cache_dims.y as u32)
|
||||
.dimensions(glyph_cache_dims.x, glyph_cache_dims.y)
|
||||
.scale_tolerance(SCALE_TOLERANCE)
|
||||
.position_tolerance(POSITION_TOLERANCE)
|
||||
.build(),
|
||||
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),
|
||||
})
|
||||
}
|
||||
@ -82,14 +82,14 @@ impl Cache {
|
||||
self.text_cache.clear();
|
||||
let max_texture_size = renderer.max_texture_size();
|
||||
let cache_dims = renderer
|
||||
.get_resolution()
|
||||
.resolution()
|
||||
.map(|e| (e * GLYPH_CACHE_SIZE).min(max_texture_size).max(512));
|
||||
self.glyph_cache = GlyphCache::builder()
|
||||
.dimensions(cache_dims.x as u32, cache_dims.y as u32)
|
||||
.dimensions(cache_dims.x, cache_dims.y)
|
||||
.scale_tolerance(SCALE_TOLERANCE)
|
||||
.position_tolerance(POSITION_TOLERANCE)
|
||||
.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(())
|
||||
}
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ pub enum Rotation {
|
||||
/// Fraction of the total graphic cache size
|
||||
const ATLAS_CUTOFF_FRAC: f32 = 0.2;
|
||||
/// Multiplied by current window size
|
||||
const GRAPHIC_CACHE_RELATIVE_SIZE: u16 = 1;
|
||||
const GRAPHIC_CACHE_RELATIVE_SIZE: u32 = 1;
|
||||
|
||||
#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)]
|
||||
pub struct Id(u32);
|
||||
@ -314,7 +314,7 @@ impl GraphicCache {
|
||||
// Graphics over a particular size are sent to their own textures
|
||||
let location = if let Some(border_color) = border_color {
|
||||
// Create a new immutable texture.
|
||||
let texture = create_image(renderer, image, border_color).unwrap();
|
||||
let texture = create_image(renderer, image, border_color);
|
||||
// NOTE: All mutations happen only after the upload succeeds!
|
||||
let index = textures.len();
|
||||
textures.push(texture);
|
||||
@ -365,7 +365,7 @@ impl GraphicCache {
|
||||
}
|
||||
} else {
|
||||
// Create a texture just for this
|
||||
let texture = renderer.create_dynamic_texture(dims).unwrap();
|
||||
let texture = renderer.create_dynamic_texture(dims.map(|e| e as u32));
|
||||
// NOTE: All mutations happen only after the texture creation succeeds!
|
||||
let index = textures.len();
|
||||
textures.push(texture);
|
||||
@ -440,10 +440,10 @@ fn draw_graphic(
|
||||
}
|
||||
}
|
||||
|
||||
fn atlas_size(renderer: &Renderer) -> Vec2<u16> {
|
||||
fn atlas_size(renderer: &Renderer) -> Vec2<u32> {
|
||||
let max_texture_size = renderer.max_texture_size();
|
||||
|
||||
renderer.get_resolution().map(|e| {
|
||||
renderer.resolution().map(|e| {
|
||||
(e * GRAPHIC_CACHE_RELATIVE_SIZE)
|
||||
.max(512)
|
||||
.min(max_texture_size)
|
||||
@ -452,8 +452,9 @@ fn atlas_size(renderer: &Renderer) -> Vec2<u16> {
|
||||
|
||||
fn create_atlas_texture(renderer: &mut Renderer) -> (SimpleAtlasAllocator, Texture) {
|
||||
let size = atlas_size(renderer);
|
||||
let atlas = SimpleAtlasAllocator::new(size2(i32::from(size.x), i32::from(size.y)));
|
||||
let texture = renderer.create_dynamic_texture(size).unwrap();
|
||||
// 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);
|
||||
(atlas, texture)
|
||||
}
|
||||
|
||||
@ -466,25 +467,27 @@ fn aabr_from_alloc_rect(rect: guillotiere::Rectangle) -> Aabr<u16> {
|
||||
}
|
||||
|
||||
fn upload_image(renderer: &mut Renderer, aabr: Aabr<u16>, tex: &Texture, image: &RgbaImage) {
|
||||
let aabr = aabr.map(|e| e as u32);
|
||||
let offset = aabr.min.into_array();
|
||||
let size = aabr.size().into_array();
|
||||
if let Err(e) = renderer.update_texture(
|
||||
renderer.update_texture(
|
||||
tex,
|
||||
offset,
|
||||
size,
|
||||
// NOTE: Rgba texture, so each pixel is 4 bytes, ergo this cannot fail.
|
||||
// We make the cast parameters explicit for clarity.
|
||||
bytemuck::cast_slice::<u8, [u8; 4]>(&image),
|
||||
) {
|
||||
warn!(?e, "Failed to update texture");
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
fn create_image(renderer: &mut Renderer, image: RgbaImage, border_color: Rgba<f32>) {
|
||||
renderer.create_texture(
|
||||
&DynamicImage::ImageRgba8(image),
|
||||
None,
|
||||
Some(wgpu::AddressMode::ClampToBorder),
|
||||
Some(border_color.into_array().into()),
|
||||
)
|
||||
fn create_image(renderer: &mut Renderer, image: RgbaImage, border_color: Rgba<f32>) -> Texture {
|
||||
renderer
|
||||
.create_texture(
|
||||
&DynamicImage::ImageRgba8(image),
|
||||
None,
|
||||
//TODO: either use the desktop only border color or just emulate this
|
||||
// Some(border_color.into_array().into()),
|
||||
Some(wgpu::AddressMode::ClampToBorder),
|
||||
)
|
||||
.expect("create_texture only panics is non ImageRbga8 is passed")
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ pub use widgets::{
|
||||
|
||||
use crate::{
|
||||
render::{
|
||||
create_ui_quad, create_ui_tri, Consts, Globals, Mesh, Model, RenderError, Renderer,
|
||||
create_ui_quad, create_ui_tri, Consts, DynamicModel, Globals, Mesh, RenderError, Renderer,
|
||||
UIVertex, UiLocals, UiMode,
|
||||
},
|
||||
window::Window,
|
||||
@ -111,7 +111,7 @@ pub struct Ui {
|
||||
// during redrawing.
|
||||
mesh: Mesh<UIVertex>,
|
||||
// Model for drawing the ui
|
||||
model: Model<UIVertex>,
|
||||
model: DynamicModel<UIVertex>,
|
||||
// Consts for default ui drawing position (ie the interface)
|
||||
interface_locals: Consts<UiLocals>,
|
||||
default_globals: Consts<Globals>,
|
||||
@ -164,7 +164,7 @@ impl Ui {
|
||||
cache: Cache::new(renderer)?,
|
||||
draw_commands: Vec::new(),
|
||||
mesh: Mesh::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(),
|
||||
@ -341,7 +341,7 @@ impl Ui {
|
||||
// Avoid resetting cache if window size didn't change
|
||||
// Somewhat inefficient for elements that won't change size after a window
|
||||
// resize
|
||||
let res = renderer.get_resolution();
|
||||
let res = renderer.resolution();
|
||||
res.x > 0 && res.y > 0 && !(old_w == w && old_h == h)
|
||||
} else {
|
||||
false
|
||||
@ -389,7 +389,7 @@ impl Ui {
|
||||
};
|
||||
|
||||
let (half_res, x_align, y_align) = {
|
||||
let res = renderer.get_resolution();
|
||||
let res = renderer.resolution();
|
||||
(
|
||||
res.map(|e| e as f32 / 2.0),
|
||||
(res.x & 1) as f32 * 0.5,
|
||||
@ -569,23 +569,15 @@ impl Ui {
|
||||
tracing::debug!("Updating glyphs and clearing text cache.");
|
||||
|
||||
if let Err(err) = glyph_cache.cache_queued(|rect, data| {
|
||||
let offset = [rect.min.x as u16, rect.min.y as u16];
|
||||
let size = [rect.width() as u16, rect.height() as u16];
|
||||
let offset = [rect.min.x as u32, rect.min.y as u32];
|
||||
let size = [rect.width() as u32, rect.height() as u32];
|
||||
|
||||
let new_data = 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,
|
||||
rect.width() * 4,
|
||||
) {
|
||||
warn!("Failed to update texture: {:?}", err);
|
||||
}
|
||||
renderer.update_texture(cache_tex, offset, size, &new_data);
|
||||
}) {
|
||||
// FIXME: If we actually hit this error, it's still possible we could salvage
|
||||
// things in various ways (for instance, the current queue might have extra
|
||||
@ -831,6 +823,7 @@ impl Ui {
|
||||
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;
|
||||
@ -964,12 +957,10 @@ impl Ui {
|
||||
// Push new position command
|
||||
let world_pos = Vec4::from_point(parameters.pos);
|
||||
if self.ingame_locals.len() > ingame_local_index {
|
||||
renderer
|
||||
.update_consts(
|
||||
&mut self.ingame_locals[ingame_local_index],
|
||||
&[world_pos.into()],
|
||||
)
|
||||
.unwrap();
|
||||
renderer.update_consts(
|
||||
&mut self.ingame_locals[ingame_local_index],
|
||||
&[world_pos.into()],
|
||||
)
|
||||
} else {
|
||||
self.ingame_locals
|
||||
.push(renderer.create_consts(&[world_pos.into()]).unwrap());
|
||||
@ -1017,13 +1008,11 @@ impl Ui {
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
pub fn render(&self, renderer: &mut Renderer, maybe_globals: Option<&Consts<Globals>>) {
|
||||
@ -1045,7 +1034,9 @@ impl Ui {
|
||||
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);
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -1053,12 +1044,12 @@ impl Ui {
|
||||
}
|
||||
|
||||
fn default_scissor(renderer: &Renderer) -> Aabr<u16> {
|
||||
let (screen_w, screen_h) = renderer.get_resolution().into_tuple();
|
||||
let (screen_w, screen_h) = renderer.resolution().into_tuple();
|
||||
Aabr {
|
||||
min: Vec2 { x: 0, y: 0 },
|
||||
max: Vec2 {
|
||||
x: screen_w,
|
||||
y: screen_h,
|
||||
x: screen_w as u16,
|
||||
y: screen_h as u16,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -518,7 +518,7 @@ impl KeyMouse {
|
||||
}
|
||||
|
||||
pub struct Window {
|
||||
renderer: Renderer<'static>,
|
||||
renderer: Renderer,
|
||||
window: winit::window::Window,
|
||||
cursor_grabbed: bool,
|
||||
pub pan_sensitivity: u32,
|
||||
@ -658,7 +658,7 @@ impl Window {
|
||||
|
||||
pub fn renderer(&self) -> &Renderer { &self.renderer }
|
||||
|
||||
pub fn renderer_mut(&mut self) -> &mut Renderer<'static> { &mut self.renderer }
|
||||
pub fn renderer_mut(&mut self) -> &mut Renderer { &mut self.renderer }
|
||||
|
||||
pub fn resolve_deduplicated_events(&mut self, settings: &mut Settings) {
|
||||
// Handle screenshots and toggling fullscreen
|
||||
@ -941,7 +941,9 @@ impl Window {
|
||||
// let (mut color_view, mut depth_view) = self.renderer.win_views_mut();
|
||||
// self.window.resize(physical);
|
||||
// self.window.update_gfx(&mut color_view, &mut depth_view);
|
||||
self.renderer.on_resize().unwrap();
|
||||
self.renderer
|
||||
.on_resize(Vec2::new(physical.width, physical.height))
|
||||
.unwrap();
|
||||
// TODO: update users of this event with the fact that it is now the physical
|
||||
// size
|
||||
let winit::dpi::PhysicalSize { width, height } = physical;
|
||||
|
Loading…
Reference in New Issue
Block a user