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
3502699732
commit
08b787e049
15
Cargo.toml
15
Cargo.toml
@ -95,11 +95,6 @@ incremental = true
|
|||||||
inherits = 'release'
|
inherits = 'release'
|
||||||
debug = 1
|
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]
|
[workspace.metadata.nix]
|
||||||
systems = ["x86_64-linux"]
|
systems = ["x86_64-linux"]
|
||||||
|
|
||||||
@ -110,3 +105,13 @@ key = "veloren-nix.cachix.org-1:zokfKJqVsNV6kI/oJdLF6TYBdNPYGSb+diMVQPn/5Rc="
|
|||||||
[workspace.metadata.nix.crateOverride.veloren-network]
|
[workspace.metadata.nix.crateOverride.veloren-network]
|
||||||
buildInputs = ["openssl"]
|
buildInputs = ["openssl"]
|
||||||
nativeBuildInputs = ["pkg-config"]
|
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
|
# Graphics
|
||||||
winit = {version = "0.24.0", features = ["serde"]}
|
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"] }
|
bytemuck = { version="1.4", features=["derive"] }
|
||||||
shaderc = "0.6.2"
|
shaderc = "0.6.2"
|
||||||
|
|
||||||
|
@ -3,44 +3,60 @@ use wgpu::util::DeviceExt;
|
|||||||
|
|
||||||
pub struct Buffer<T: Copy + Pod> {
|
pub struct Buffer<T: Copy + Pod> {
|
||||||
pub buf: wgpu::Buffer,
|
pub buf: wgpu::Buffer,
|
||||||
// bytes
|
// Size in number of elements
|
||||||
count: usize,
|
// TODO: determine if this is a good name
|
||||||
|
len: usize,
|
||||||
phantom_data: std::marker::PhantomData<T>,
|
phantom_data: std::marker::PhantomData<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Copy + Pod> Buffer<T> {
|
impl<T: Copy + Pod> Buffer<T> {
|
||||||
pub fn new(device: &wgpu::Device, cap: u64, usage: wgpu::BufferUsage) -> Self {
|
pub fn new(device: &wgpu::Device, usage: wgpu::BufferUsage, data: &[T]) -> 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 {
|
|
||||||
let contents = bytemuck::cast_slice(data);
|
let contents = bytemuck::cast_slice(data);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
buf: device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
buf: device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||||
label: None,
|
label: None,
|
||||||
contents,
|
contents,
|
||||||
usage: usage | wgpu::BufferUsage::MAP_WRITE,
|
usage,
|
||||||
}),
|
}),
|
||||||
count: data.len(),
|
len: data.len(),
|
||||||
phantom_data: std::marker::PhantomData,
|
phantom_data: std::marker::PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(&mut self, device: &wgpu::Device, queue: &wgpu::Queue, vals: &[T], offset: u64) {
|
pub fn len(&self) -> usize { self.len }
|
||||||
if !vals.is_empty() {
|
}
|
||||||
queue.write_buffer(&self.buf, offset, bytemuck::cast_slice(vals))
|
|
||||||
}
|
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;
|
use bytemuck::Pod;
|
||||||
|
|
||||||
/// A handle to a series of constants sitting on the GPU. This is used to hold
|
/// 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
|
/// information used in the rendering process that does not change throughout a
|
||||||
/// single render pass.
|
/// single render pass.
|
||||||
pub struct Consts<T: Copy + Pod> {
|
pub struct Consts<T: Copy + Pod> {
|
||||||
buf: Buffer<T>,
|
buf: DynamicBuffer<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Copy + Pod> Consts<T> {
|
impl<T: Copy + Pod> Consts<T> {
|
||||||
/// Create a new `Const<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 {
|
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.
|
/// 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)
|
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
|
/// Used to represent one of many possible errors that may be omitted by the
|
||||||
/// rendering subsystem.
|
/// rendering subsystem.
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum RenderError {
|
pub enum RenderError {
|
||||||
RequestDeviceError(wgpu::RequestDeviceError),
|
RequestDeviceError(wgpu::RequestDeviceError),
|
||||||
MappingError(wgpu::BufferAsyncError),
|
MappingError(wgpu::BufferAsyncError),
|
||||||
@ -11,6 +10,23 @@ pub enum RenderError {
|
|||||||
ShaderError(shaderc::Error),
|
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 {
|
impl From<wgpu::RequestDeviceError> for RenderError {
|
||||||
fn from(err: wgpu::RequestDeviceError) -> Self { Self::RequestDeviceError(err) }
|
fn from(err: wgpu::RequestDeviceError) -> Self { Self::RequestDeviceError(err) }
|
||||||
}
|
}
|
||||||
|
@ -1,21 +1,30 @@
|
|||||||
use super::buffer::Buffer;
|
use super::buffer::DynamicBuffer;
|
||||||
use bytemuck::Pod;
|
use bytemuck::Pod;
|
||||||
|
|
||||||
/// Represents a mesh that has been sent to the GPU.
|
/// Represents a mesh that has been sent to the GPU.
|
||||||
pub struct Instances<T: Copy + Pod> {
|
pub struct Instances<T: Copy + Pod> {
|
||||||
buf: Buffer<T>,
|
buf: DynamicBuffer<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Copy + Pod> Instances<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 {
|
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)
|
self.buf.update(device, queue, vals, offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ pub use self::{
|
|||||||
error::RenderError,
|
error::RenderError,
|
||||||
instances::Instances,
|
instances::Instances,
|
||||||
mesh::{Mesh, Quad, Tri},
|
mesh::{Mesh, Quad, Tri},
|
||||||
model::{Model, SubModel},
|
model::{DynamicModel, Model, SubModel},
|
||||||
pipelines::{
|
pipelines::{
|
||||||
clouds::{create_mesh as create_clouds_mesh, Locals as CloudsLocals},
|
clouds::{create_mesh as create_clouds_mesh, Locals as CloudsLocals},
|
||||||
figure::{
|
figure::{
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
use super::{buffer::Buffer, mesh::Mesh, Vertex};
|
use super::{
|
||||||
|
buffer::{Buffer, DynamicBuffer},
|
||||||
|
mesh::Mesh,
|
||||||
|
Vertex,
|
||||||
|
};
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
|
|
||||||
/// Represents a mesh that has been sent to the GPU.
|
/// Represents a mesh that has been sent to the GPU.
|
||||||
@ -20,13 +24,7 @@ pub struct Model<V: Vertex> {
|
|||||||
impl<V: Vertex> Model<V> {
|
impl<V: Vertex> Model<V> {
|
||||||
pub fn new(device: &wgpu::Device, mesh: &Mesh<V>) -> Self {
|
pub fn new(device: &wgpu::Device, mesh: &Mesh<V>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
vbuf: Buffer::new_with_data(device, wgpu::BufferUsage::VERTEX, mesh.vertices()),
|
vbuf: Buffer::new(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),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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(
|
pub fn update(
|
||||||
&mut self,
|
&self,
|
||||||
device: &wgpu::Device,
|
device: &wgpu::Device,
|
||||||
queue: &wgpu::Queue,
|
queue: &wgpu::Queue,
|
||||||
mesh: &Mesh<V>,
|
mesh: &Mesh<V>,
|
||||||
offset: u64,
|
offset: usize,
|
||||||
) {
|
) {
|
||||||
self.vbuf.update(device, queue, mesh.vertices(), offset)
|
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 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 {
|
rasterization_state: Some(wgpu::RasterizationStateDescriptor {
|
||||||
front_face: wgpu::FrontFace::Ccw,
|
front_face: wgpu::FrontFace::Ccw,
|
||||||
cull_mode: wgpu::CullMode::Back,
|
cull_mode: wgpu::CullMode::Back,
|
||||||
|
polygon_mode: wgpu::PolygonMode::Fill,
|
||||||
clamp_depth: false,
|
clamp_depth: false,
|
||||||
depth_bias: 0,
|
depth_bias: 0,
|
||||||
depth_bias_slope_scale: 0.0,
|
depth_bias_slope_scale: 0.0,
|
||||||
|
@ -33,14 +33,12 @@ impl Vertex {
|
|||||||
|
|
||||||
fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> {
|
fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> {
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
const ATTRIBUTES: [wgpu::VertexAttributeDescriptor; 1] =
|
||||||
|
wgpu::vertex_attr_array![0 => Uint];
|
||||||
wgpu::VertexBufferDescriptor {
|
wgpu::VertexBufferDescriptor {
|
||||||
stride: mem::size_of::<Self>() as wgpu::BufferAddress,
|
stride: mem::size_of::<Self>() as wgpu::BufferAddress,
|
||||||
step_mode: wgpu::InputStepMode::Vertex,
|
step_mode: wgpu::InputStepMode::Vertex,
|
||||||
attributes: &[wgpu::VertexAttributeDescriptor {
|
attributes: &ATTRIBUTES,
|
||||||
offset: 0,
|
|
||||||
shader_location: 0,
|
|
||||||
format: wgpu::VertexFormat::Uint,
|
|
||||||
}],
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -121,6 +119,7 @@ impl FluidPipeline {
|
|||||||
rasterization_state: Some(wgpu::RasterizationStateDescriptor {
|
rasterization_state: Some(wgpu::RasterizationStateDescriptor {
|
||||||
front_face: wgpu::FrontFace::Ccw,
|
front_face: wgpu::FrontFace::Ccw,
|
||||||
cull_mode: wgpu::CullMode::None,
|
cull_mode: wgpu::CullMode::None,
|
||||||
|
polygon_mode: wgpu::PolygonMode::Fill,
|
||||||
clamp_depth: false,
|
clamp_depth: false,
|
||||||
depth_bias: 0,
|
depth_bias: 0,
|
||||||
depth_bias_slope_scale: 0.0,
|
depth_bias_slope_scale: 0.0,
|
||||||
|
@ -17,14 +17,12 @@ impl Vertex {
|
|||||||
|
|
||||||
fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> {
|
fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> {
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
const ATTRIBUTES: [wgpu::VertexAttributeDescriptor; 1] =
|
||||||
|
wgpu::vertex_attr_array![0 => Float2];
|
||||||
wgpu::VertexBufferDescriptor {
|
wgpu::VertexBufferDescriptor {
|
||||||
stride: mem::size_of::<Self>() as wgpu::BufferAddress,
|
stride: mem::size_of::<Self>() as wgpu::BufferAddress,
|
||||||
step_mode: wgpu::InputStepMode::Vertex,
|
step_mode: wgpu::InputStepMode::Vertex,
|
||||||
attributes: &[wgpu::VertexAttributeDescriptor {
|
attributes: &ATTRIBUTES,
|
||||||
offset: 0,
|
|
||||||
shader_location: 0,
|
|
||||||
format: wgpu::VertexFormat::Float2,
|
|
||||||
}],
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -87,7 +85,6 @@ impl LodData {
|
|||||||
&texture_info,
|
&texture_info,
|
||||||
&view_info,
|
&view_info,
|
||||||
&sampler_info,
|
&sampler_info,
|
||||||
map_size.x * 4,
|
|
||||||
bytemuck::cast_slice(lod_base),
|
bytemuck::cast_slice(lod_base),
|
||||||
);
|
);
|
||||||
texture_info.format = wgpu::TextureFormat::Rg16Uint;
|
texture_info.format = wgpu::TextureFormat::Rg16Uint;
|
||||||
@ -96,7 +93,6 @@ impl LodData {
|
|||||||
&texture_info,
|
&texture_info,
|
||||||
&view_info,
|
&view_info,
|
||||||
&sampler_info,
|
&sampler_info,
|
||||||
map_size.x * 4,
|
|
||||||
bytemuck::cast_slice(lod_base),
|
bytemuck::cast_slice(lod_base),
|
||||||
);
|
);
|
||||||
texture_info.format = wgpu::TextureFormat::Rgba8Unorm;
|
texture_info.format = wgpu::TextureFormat::Rgba8Unorm;
|
||||||
@ -105,7 +101,6 @@ impl LodData {
|
|||||||
&texture_info,
|
&texture_info,
|
||||||
&view_info,
|
&view_info,
|
||||||
&sampler_info,
|
&sampler_info,
|
||||||
map_size.x * 4,
|
|
||||||
bytemuck::cast_slice(lod_base),
|
bytemuck::cast_slice(lod_base),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -198,6 +193,7 @@ impl LodTerrainPipeline {
|
|||||||
rasterization_state: Some(wgpu::RasterizationStateDescriptor {
|
rasterization_state: Some(wgpu::RasterizationStateDescriptor {
|
||||||
front_face: wgpu::FrontFace::Ccw,
|
front_face: wgpu::FrontFace::Ccw,
|
||||||
cull_mode: wgpu::CullMode::Back,
|
cull_mode: wgpu::CullMode::Back,
|
||||||
|
polygon_mode: wgpu::PolygonMode::Fill,
|
||||||
clamp_depth: false,
|
clamp_depth: false,
|
||||||
depth_bias: 0,
|
depth_bias: 0,
|
||||||
depth_bias_slope_scale: 0.0,
|
depth_bias_slope_scale: 0.0,
|
||||||
|
@ -33,10 +33,12 @@ impl Vertex {
|
|||||||
|
|
||||||
fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> {
|
fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> {
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
const ATTRIBUTES: [wgpu::VertexAttributeDescriptor; 2] =
|
||||||
|
wgpu::vertex_attr_array![0 => Float3, 1 => Uint];
|
||||||
wgpu::VertexBufferDescriptor {
|
wgpu::VertexBufferDescriptor {
|
||||||
stride: mem::size_of::<Self>() as wgpu::BufferAddress,
|
stride: mem::size_of::<Self>() as wgpu::BufferAddress,
|
||||||
step_mode: wgpu::InputStepMode::Vertex,
|
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> {
|
fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> {
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
const ATTRIBUTES: [wgpu::VertexAttributeDescriptor; 5] =
|
||||||
|
wgpu::vertex_attr_array![0 => Float, 1 => Float, 2 => Float, 3 => Int, 4 => Float3];
|
||||||
wgpu::VertexBufferDescriptor {
|
wgpu::VertexBufferDescriptor {
|
||||||
stride: mem::size_of::<Self>() as wgpu::BufferAddress,
|
stride: mem::size_of::<Self>() as wgpu::BufferAddress,
|
||||||
step_mode: wgpu::InputStepMode::Instance,
|
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 {
|
rasterization_state: Some(wgpu::RasterizationStateDescriptor {
|
||||||
front_face: wgpu::FrontFace::Ccw,
|
front_face: wgpu::FrontFace::Ccw,
|
||||||
cull_mode: wgpu::CullMode::Back,
|
cull_mode: wgpu::CullMode::Back,
|
||||||
|
polygon_mode: wgpu::PolygonMode::Fill,
|
||||||
clamp_depth: false,
|
clamp_depth: false,
|
||||||
depth_bias: 0,
|
depth_bias: 0,
|
||||||
depth_bias_slope_scale: 0.0,
|
depth_bias_slope_scale: 0.0,
|
||||||
|
@ -31,14 +31,12 @@ pub struct Vertex {
|
|||||||
impl Vertex {
|
impl Vertex {
|
||||||
fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> {
|
fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> {
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
const ATTRIBUTES: [wgpu::VertexAttributeDescriptor; 1] =
|
||||||
|
wgpu::vertex_attr_array![0 => Float2];
|
||||||
wgpu::VertexBufferDescriptor {
|
wgpu::VertexBufferDescriptor {
|
||||||
stride: mem::size_of::<Self>() as wgpu::BufferAddress,
|
stride: mem::size_of::<Self>() as wgpu::BufferAddress,
|
||||||
step_mode: wgpu::InputStepMode::Vertex,
|
step_mode: wgpu::InputStepMode::Vertex,
|
||||||
attributes: &[wgpu::VertexAttributeDescriptor {
|
attributes: &ATTRIBUTES,
|
||||||
offset: 0,
|
|
||||||
shader_location: 0,
|
|
||||||
format: wgpu::VertexFormat::Float2,
|
|
||||||
}],
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -139,6 +137,7 @@ impl PostProcessPipeline {
|
|||||||
rasterization_state: Some(wgpu::RasterizationStateDescriptor {
|
rasterization_state: Some(wgpu::RasterizationStateDescriptor {
|
||||||
front_face: wgpu::FrontFace::Ccw,
|
front_face: wgpu::FrontFace::Ccw,
|
||||||
cull_mode: wgpu::CullMode::Back,
|
cull_mode: wgpu::CullMode::Back,
|
||||||
|
polygon_mode: wgpu::PolygonMode::Fill,
|
||||||
clamp_depth: false,
|
clamp_depth: false,
|
||||||
depth_bias: 0,
|
depth_bias: 0,
|
||||||
depth_bias_slope_scale: 0.0,
|
depth_bias_slope_scale: 0.0,
|
||||||
|
@ -95,7 +95,6 @@ pub fn create_col_lights(
|
|||||||
&texture_info,
|
&texture_info,
|
||||||
&view_info,
|
&view_info,
|
||||||
&sampler_info,
|
&sampler_info,
|
||||||
col_lights_size.x * 4,
|
|
||||||
bytemuck::cast_slice(&col_lights),
|
bytemuck::cast_slice(&col_lights),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -149,6 +148,7 @@ impl ShadowFigurePipeline {
|
|||||||
rasterization_state: Some(wgpu::RasterizationStateDescriptor {
|
rasterization_state: Some(wgpu::RasterizationStateDescriptor {
|
||||||
front_face: wgpu::FrontFace::Ccw,
|
front_face: wgpu::FrontFace::Ccw,
|
||||||
cull_mode: wgpu::CullMode::Back,
|
cull_mode: wgpu::CullMode::Back,
|
||||||
|
polygon_mode: wgpu::PolygonMode::Fill,
|
||||||
clamp_depth: false,
|
clamp_depth: false,
|
||||||
depth_bias: 0,
|
depth_bias: 0,
|
||||||
depth_bias_slope_scale: 0.0,
|
depth_bias_slope_scale: 0.0,
|
||||||
@ -231,6 +231,7 @@ impl ShadowPipeline {
|
|||||||
rasterization_state: Some(wgpu::RasterizationStateDescriptor {
|
rasterization_state: Some(wgpu::RasterizationStateDescriptor {
|
||||||
front_face: wgpu::FrontFace::Ccw,
|
front_face: wgpu::FrontFace::Ccw,
|
||||||
cull_mode: wgpu::CullMode::Back,
|
cull_mode: wgpu::CullMode::Back,
|
||||||
|
polygon_mode: wgpu::PolygonMode::Fill,
|
||||||
clamp_depth: false,
|
clamp_depth: false,
|
||||||
depth_bias: 0,
|
depth_bias: 0,
|
||||||
depth_bias_slope_scale: 0.0,
|
depth_bias_slope_scale: 0.0,
|
||||||
|
@ -65,6 +65,7 @@ impl SkyboxPipeline {
|
|||||||
rasterization_state: Some(wgpu::RasterizationStateDescriptor {
|
rasterization_state: Some(wgpu::RasterizationStateDescriptor {
|
||||||
front_face: wgpu::FrontFace::Ccw,
|
front_face: wgpu::FrontFace::Ccw,
|
||||||
cull_mode: wgpu::CullMode::Back,
|
cull_mode: wgpu::CullMode::Back,
|
||||||
|
polygon_mode: wgpu::PolygonMode::Fill,
|
||||||
clamp_depth: false,
|
clamp_depth: false,
|
||||||
depth_bias: 0,
|
depth_bias: 0,
|
||||||
depth_bias_slope_scale: 0.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> {
|
pub fn create_mesh() -> Mesh<Vertex> {
|
||||||
let mut mesh = Mesh::new();
|
let mut mesh = Mesh::new();
|
||||||
|
|
||||||
|
@ -61,10 +61,12 @@ impl Vertex {
|
|||||||
|
|
||||||
fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> {
|
fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> {
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
const ATTRIBUTES: [wgpu::VertexAttributeDescriptor; 3] =
|
||||||
|
wgpu::vertex_attr_array![0 => Float3, 1 => Uint, 2 => Uint];
|
||||||
wgpu::VertexBufferDescriptor {
|
wgpu::VertexBufferDescriptor {
|
||||||
stride: mem::size_of::<Self>() as wgpu::BufferAddress,
|
stride: mem::size_of::<Self>() as wgpu::BufferAddress,
|
||||||
step_mode: wgpu::InputStepMode::Vertex,
|
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> {
|
fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> {
|
||||||
use std::mem;
|
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 {
|
wgpu::VertexBufferDescriptor {
|
||||||
stride: mem::size_of::<Self>() as wgpu::BufferAddress,
|
stride: mem::size_of::<Self>() as wgpu::BufferAddress,
|
||||||
step_mode: wgpu::InputStepMode::Instance,
|
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 {
|
rasterization_state: Some(wgpu::RasterizationStateDescriptor {
|
||||||
front_face: wgpu::FrontFace::Ccw,
|
front_face: wgpu::FrontFace::Ccw,
|
||||||
cull_mode: wgpu::CullMode::Back,
|
cull_mode: wgpu::CullMode::Back,
|
||||||
|
polygon_mode: wgpu::PolygonMode::Fill,
|
||||||
clamp_depth: false,
|
clamp_depth: false,
|
||||||
depth_bias: 0,
|
depth_bias: 0,
|
||||||
depth_bias_slope_scale: 0.0,
|
depth_bias_slope_scale: 0.0,
|
||||||
|
@ -120,20 +120,23 @@ impl Vertex {
|
|||||||
|
|
||||||
pub fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> {
|
pub fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> {
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
const ATTRIBUTES: [wgpu::VertexAttributeDescriptor; 2] =
|
||||||
|
wgpu::vertex_attr_array![0 => Uint,1 => Uint];
|
||||||
wgpu::VertexBufferDescriptor {
|
wgpu::VertexBufferDescriptor {
|
||||||
stride: mem::size_of::<Self>() as wgpu::BufferAddress,
|
stride: mem::size_of::<Self>() as wgpu::BufferAddress,
|
||||||
step_mode: wgpu::InputStepMode::Vertex,
|
step_mode: wgpu::InputStepMode::Vertex,
|
||||||
attributes: &wgpu::vertex_attr_array![0 => Uint,1 => Uint],
|
attributes: &ATTRIBUTES,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Copy, Clone, Debug, Zeroable, Pod)]
|
#[derive(Copy, Clone, Debug, Zeroable, Pod)]
|
||||||
|
// TODO: new function and private fields??
|
||||||
pub struct Locals {
|
pub struct Locals {
|
||||||
model_offs: [f32; 3],
|
pub model_offs: [f32; 3],
|
||||||
load_time: f32,
|
pub load_time: f32,
|
||||||
atlas_offs: [i32; 4],
|
pub atlas_offs: [i32; 4],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Locals {
|
impl Locals {
|
||||||
@ -233,6 +236,7 @@ impl TerrainPipeline {
|
|||||||
rasterization_state: Some(wgpu::RasterizationStateDescriptor {
|
rasterization_state: Some(wgpu::RasterizationStateDescriptor {
|
||||||
front_face: wgpu::FrontFace::Ccw,
|
front_face: wgpu::FrontFace::Ccw,
|
||||||
cull_mode: wgpu::CullMode::Back,
|
cull_mode: wgpu::CullMode::Back,
|
||||||
|
polygon_mode: wgpu::PolygonMode::Fill,
|
||||||
clamp_depth: false,
|
clamp_depth: false,
|
||||||
depth_bias: 0,
|
depth_bias: 0,
|
||||||
depth_bias_slope_scale: 0.0,
|
depth_bias_slope_scale: 0.0,
|
||||||
|
@ -15,10 +15,12 @@ pub struct Vertex {
|
|||||||
impl Vertex {
|
impl Vertex {
|
||||||
fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> {
|
fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> {
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
const ATTRIBUTES: [wgpu::VertexAttributeDescriptor; 5] =
|
||||||
|
wgpu::vertex_attr_array![0 => Float2, 1 => Float2, 2 => Float4, 3 => Float2, 4 => Uint];
|
||||||
wgpu::VertexBufferDescriptor {
|
wgpu::VertexBufferDescriptor {
|
||||||
stride: mem::size_of::<Self>() as wgpu::BufferAddress,
|
stride: mem::size_of::<Self>() as wgpu::BufferAddress,
|
||||||
step_mode: wgpu::InputStepMode::Vertex,
|
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 {
|
rasterization_state: Some(wgpu::RasterizationStateDescriptor {
|
||||||
front_face: wgpu::FrontFace::Ccw,
|
front_face: wgpu::FrontFace::Ccw,
|
||||||
cull_mode: wgpu::CullMode::Back,
|
cull_mode: wgpu::CullMode::Back,
|
||||||
|
polygon_mode: wgpu::PolygonMode::Fill,
|
||||||
clamp_depth: false,
|
clamp_depth: false,
|
||||||
depth_bias: 0,
|
depth_bias: 0,
|
||||||
depth_bias_slope_scale: 0.0,
|
depth_bias_slope_scale: 0.0,
|
||||||
|
@ -2,7 +2,7 @@ use super::{
|
|||||||
consts::Consts,
|
consts::Consts,
|
||||||
instances::Instances,
|
instances::Instances,
|
||||||
mesh::Mesh,
|
mesh::Mesh,
|
||||||
model::Model,
|
model::{DynamicModel, Model},
|
||||||
pipelines::{
|
pipelines::{
|
||||||
clouds, figure, fluid, lod_terrain, particle, postprocess, shadow, skybox, sprite, terrain,
|
clouds, figure, fluid, lod_terrain, particle, postprocess, shadow, skybox, sprite, terrain,
|
||||||
ui, GlobalsLayouts,
|
ui, GlobalsLayouts,
|
||||||
@ -177,9 +177,9 @@ pub struct Layouts {
|
|||||||
/// rendering subsystem and contains any state necessary to interact with the
|
/// rendering subsystem and contains any state necessary to interact with the
|
||||||
/// GPU, along with pipeline state objects (PSOs) needed to renderer different
|
/// GPU, along with pipeline state objects (PSOs) needed to renderer different
|
||||||
/// kinds of models to the screen.
|
/// kinds of models to the screen.
|
||||||
pub struct Renderer<'a> {
|
pub struct Renderer {
|
||||||
window: &'a winit::window::Window,
|
// TODO: why????
|
||||||
|
//window: &'a winit::window::Window,
|
||||||
device: wgpu::Device,
|
device: wgpu::Device,
|
||||||
queue: wgpu::Queue,
|
queue: wgpu::Queue,
|
||||||
swap_chain: wgpu::SwapChain,
|
swap_chain: wgpu::SwapChain,
|
||||||
@ -216,12 +216,14 @@ pub struct Renderer<'a> {
|
|||||||
noise_tex: Texture,
|
noise_tex: Texture,
|
||||||
|
|
||||||
mode: RenderMode,
|
mode: RenderMode,
|
||||||
|
|
||||||
|
resolution: Vec2<u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Renderer<'a> {
|
impl Renderer {
|
||||||
/// Create a new `Renderer` from a variety of backend-specific components
|
/// Create a new `Renderer` from a variety of backend-specific components
|
||||||
/// and the window targets.
|
/// 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
|
// Enable seamless cubemaps globally, where available--they are essentially a
|
||||||
// strict improvement on regular cube maps.
|
// strict improvement on regular cube maps.
|
||||||
//
|
//
|
||||||
@ -231,7 +233,9 @@ impl<'a> Renderer<'a> {
|
|||||||
|
|
||||||
let dims = window.inner_size();
|
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
|
// 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
|
// 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(
|
let (device, queue) = futures::executor::block_on(adapter.request_device(
|
||||||
&wgpu::DeviceDescriptor {
|
&wgpu::DeviceDescriptor {
|
||||||
// TODO
|
// TODO
|
||||||
|
label: None,
|
||||||
features: Features::DEPTH_CLAMPING | Features::ADDRESS_MODE_CLAMP_TO_BORDER,
|
features: Features::DEPTH_CLAMPING | Features::ADDRESS_MODE_CLAMP_TO_BORDER,
|
||||||
limits: Limits::default(),
|
limits: Limits::default(),
|
||||||
shader_validation: true,
|
shader_validation: true,
|
||||||
@ -269,7 +274,7 @@ impl<'a> Renderer<'a> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let sc_desc = wgpu::SwapChainDescriptor {
|
let sc_desc = wgpu::SwapChainDescriptor {
|
||||||
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
|
usage: wgpu::TextureUsage::RENDER_ATTACHMENT,
|
||||||
format: wgpu::TextureFormat::Bgra8UnormSrgb,
|
format: wgpu::TextureFormat::Bgra8UnormSrgb,
|
||||||
width: dims.width,
|
width: dims.width,
|
||||||
height: dims.height,
|
height: dims.height,
|
||||||
@ -387,8 +392,6 @@ impl<'a> Renderer<'a> {
|
|||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
window,
|
|
||||||
|
|
||||||
device,
|
device,
|
||||||
queue,
|
queue,
|
||||||
swap_chain,
|
swap_chain,
|
||||||
@ -423,6 +426,8 @@ impl<'a> Renderer<'a> {
|
|||||||
noise_tex,
|
noise_tex,
|
||||||
|
|
||||||
mode,
|
mode,
|
||||||
|
|
||||||
|
resolution: Vec2::new(dims.width, dims.height),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -443,7 +448,7 @@ impl<'a> Renderer<'a> {
|
|||||||
self.mode = mode;
|
self.mode = mode;
|
||||||
|
|
||||||
// Recreate render target
|
// Recreate render target
|
||||||
self.on_resize()?;
|
self.on_resize(self.resolution)?;
|
||||||
|
|
||||||
// Recreate pipelines with the new AA mode
|
// Recreate pipelines with the new AA mode
|
||||||
self.recreate_pipelines();
|
self.recreate_pipelines();
|
||||||
@ -455,13 +460,11 @@ impl<'a> Renderer<'a> {
|
|||||||
pub fn render_mode(&self) -> &RenderMode { &self.mode }
|
pub fn render_mode(&self) -> &RenderMode { &self.mode }
|
||||||
|
|
||||||
/// Resize internal render targets to match window render target dimensions.
|
/// Resize internal render targets to match window render target dimensions.
|
||||||
pub fn on_resize(&mut self) -> Result<(), RenderError> {
|
pub fn on_resize(&mut self, dims: Vec2<u32>) -> Result<(), RenderError> {
|
||||||
let dims = self.window.inner_size();
|
|
||||||
|
|
||||||
// Avoid panics when creating texture with w,h of 0,0.
|
// 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) =
|
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.win_depth_view = win_depth_view;
|
||||||
self.tgt_color_view = tgt_color_view;
|
self.tgt_color_view = tgt_color_view;
|
||||||
self.tgt_depth_stencil_view = tgt_depth_stencil_view;
|
self.tgt_depth_stencil_view = tgt_depth_stencil_view;
|
||||||
@ -469,8 +472,7 @@ impl<'a> Renderer<'a> {
|
|||||||
if let (Some(shadow_map), ShadowMode::Map(mode)) =
|
if let (Some(shadow_map), ShadowMode::Map(mode)) =
|
||||||
(self.shadow_map.as_mut(), self.mode.shadow)
|
(self.shadow_map.as_mut(), self.mode.shadow)
|
||||||
{
|
{
|
||||||
match Self::create_shadow_views(&mut self.device, (dims.width, dims.height), &mode)
|
match Self::create_shadow_views(&mut self.device, (dims.x, dims.y), &mode) {
|
||||||
{
|
|
||||||
Ok((point_depth_stencil, directed_depth_stencil)) => {
|
Ok((point_depth_stencil, directed_depth_stencil)) => {
|
||||||
shadow_map.point_depth_stencil = point_depth_stencil;
|
shadow_map.point_depth_stencil = point_depth_stencil;
|
||||||
shadow_map.directed_depth_stencil = directed_depth_stencil;
|
shadow_map.directed_depth_stencil = directed_depth_stencil;
|
||||||
@ -480,6 +482,8 @@ impl<'a> Renderer<'a> {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.resolution = dims;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -523,7 +527,7 @@ impl<'a> Renderer<'a> {
|
|||||||
sample_count,
|
sample_count,
|
||||||
dimension: wgpu::TextureDimension::D2,
|
dimension: wgpu::TextureDimension::D2,
|
||||||
format: wgpu::TextureFormat::Rgba8UnormSrgb,
|
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 {
|
tex.create_view(&wgpu::TextureViewDescriptor {
|
||||||
@ -553,7 +557,7 @@ impl<'a> Renderer<'a> {
|
|||||||
sample_count,
|
sample_count,
|
||||||
dimension: wgpu::TextureDimension::D2,
|
dimension: wgpu::TextureDimension::D2,
|
||||||
format: wgpu::TextureFormat::Depth24Plus,
|
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 =
|
let tgt_depth_stencil_view =
|
||||||
tgt_depth_stencil_tex.create_view(&wgpu::TextureViewDescriptor {
|
tgt_depth_stencil_tex.create_view(&wgpu::TextureViewDescriptor {
|
||||||
@ -578,7 +582,7 @@ impl<'a> Renderer<'a> {
|
|||||||
sample_count,
|
sample_count,
|
||||||
dimension: wgpu::TextureDimension::D2,
|
dimension: wgpu::TextureDimension::D2,
|
||||||
format: wgpu::TextureFormat::Depth24Plus,
|
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 {
|
let win_depth_view = tgt_depth_stencil_tex.create_view(&wgpu::TextureViewDescriptor {
|
||||||
label: None,
|
label: None,
|
||||||
@ -667,7 +671,19 @@ impl<'a> Renderer<'a> {
|
|||||||
sample_count: 1,
|
sample_count: 1,
|
||||||
dimension: wgpu::TextureDimension::D2,
|
dimension: wgpu::TextureDimension::D2,
|
||||||
format: wgpu::TextureFormat::Depth24Plus,
|
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 {
|
let directed_shadow_tex = wgpu::TextureDescriptor {
|
||||||
@ -681,10 +697,10 @@ impl<'a> Renderer<'a> {
|
|||||||
sample_count: 1,
|
sample_count: 1,
|
||||||
dimension: wgpu::TextureDimension::D2,
|
dimension: wgpu::TextureDimension::D2,
|
||||||
format: wgpu::TextureFormat::Depth24Plus,
|
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,
|
label: None,
|
||||||
format: Some(wgpu::TextureFormat::Depth24Plus),
|
format: Some(wgpu::TextureFormat::Depth24Plus),
|
||||||
dimension: Some(wgpu::TextureViewDimension::D2),
|
dimension: Some(wgpu::TextureViewDimension::D2),
|
||||||
@ -707,30 +723,27 @@ impl<'a> Renderer<'a> {
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let point_tgt_shadow =
|
let point_shadow_tex =
|
||||||
Texture::new_raw(device, &point_shadow_tex, &view_info, &sampler_info);
|
Texture::new_raw(device, &point_shadow_tex, &point_shadow_view, &sampler_info);
|
||||||
view_info.dimension = Some(wgpu::TextureViewDimension::Cube);
|
let directed_shadow_tex = Texture::new_raw(
|
||||||
let directed_shadow_tex =
|
device,
|
||||||
Texture::new_raw(device, &directed_shadow_tex, &view_info, &sampler_info);
|
&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.
|
/// Get the resolution of the render target.
|
||||||
pub fn get_resolution(&self) -> Vec2<u32> {
|
pub fn resolution(&self) -> Vec2<u32> { self.resolution }
|
||||||
let dims = self.window.inner_size();
|
|
||||||
|
|
||||||
Vec2::new(dims.width, dims.height)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the resolution of the shadow render target.
|
/// Get the resolution of the shadow render target.
|
||||||
pub fn get_shadow_resolution(&self) -> (Vec2<u32>, Vec2<u32>) {
|
pub fn get_shadow_resolution(&self) -> (Vec2<u32>, Vec2<u32>) {
|
||||||
if let Some(shadow_map) = &self.shadow_map {
|
if let Some(shadow_map) = &self.shadow_map {
|
||||||
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),
|
shadow_map.point_depth_stencil.get_dimensions().xy(),
|
||||||
Vec2::new(directed_dims.width, directed_dims.height),
|
shadow_map.directed_depth_stencil.get_dimensions().xy(),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
(Vec2::new(1, 1), Vec2::new(1, 1))
|
(Vec2::new(1, 1), Vec2::new(1, 1))
|
||||||
@ -882,7 +895,7 @@ impl<'a> Renderer<'a> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
vals: &[T],
|
vals: &[T],
|
||||||
) -> Result<Consts<T>, RenderError> {
|
) -> 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);
|
consts.update(&self.device, &self.queue, vals, 0);
|
||||||
Ok(consts)
|
Ok(consts)
|
||||||
}
|
}
|
||||||
@ -897,7 +910,7 @@ impl<'a> Renderer<'a> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
vals: &[T],
|
vals: &[T],
|
||||||
) -> Result<Instances<T>, RenderError> {
|
) -> 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);
|
instances.update(&self.device, &self.queue, vals, 0);
|
||||||
Ok(instances)
|
Ok(instances)
|
||||||
}
|
}
|
||||||
@ -908,12 +921,12 @@ impl<'a> Renderer<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new dynamic model with the specified size.
|
/// Create a new dynamic model with the specified size.
|
||||||
pub fn create_dynamic_model<V: Vertex>(&mut self, size: u64) -> Model<V> {
|
pub fn create_dynamic_model<V: Vertex>(&mut self, size: usize) -> DynamicModel<V> {
|
||||||
Model::new_dynamic(&self.device, size)
|
DynamicModel::new(&self.device, size)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update a dynamic model with a mesh and a offset.
|
/// 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)
|
model.update(&self.device, &self.queue, mesh, offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -933,7 +946,6 @@ impl<'a> Renderer<'a> {
|
|||||||
texture_info: &wgpu::TextureDescriptor,
|
texture_info: &wgpu::TextureDescriptor,
|
||||||
view_info: &wgpu::TextureViewDescriptor,
|
view_info: &wgpu::TextureViewDescriptor,
|
||||||
sampler_info: &wgpu::SamplerDescriptor,
|
sampler_info: &wgpu::SamplerDescriptor,
|
||||||
bytes_per_row: u32,
|
|
||||||
data: &[u8],
|
data: &[u8],
|
||||||
) -> Texture {
|
) -> Texture {
|
||||||
let tex = Texture::new_raw(&self.device, &texture_info, &view_info, &sampler_info);
|
let tex = Texture::new_raw(&self.device, &texture_info, &view_info, &sampler_info);
|
||||||
@ -944,7 +956,6 @@ impl<'a> Renderer<'a> {
|
|||||||
[0; 2],
|
[0; 2],
|
||||||
[texture_info.size.width, texture_info.size.height],
|
[texture_info.size.width, texture_info.size.height],
|
||||||
data,
|
data,
|
||||||
bytes_per_row,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
tex
|
tex
|
||||||
@ -1004,7 +1015,6 @@ impl<'a> Renderer<'a> {
|
|||||||
// Copy, {
|
// Copy, {
|
||||||
// texture.update(&mut self.encoder, offset, size, data)
|
// texture.update(&mut self.encoder, offset, size, data)
|
||||||
data: &[[u8; 4]],
|
data: &[[u8; 4]],
|
||||||
bytes_per_row: u32,
|
|
||||||
) {
|
) {
|
||||||
texture.update(
|
texture.update(
|
||||||
&self.device,
|
&self.device,
|
||||||
@ -1012,7 +1022,6 @@ impl<'a> Renderer<'a> {
|
|||||||
offset,
|
offset,
|
||||||
size,
|
size,
|
||||||
bytemuck::cast_slice(data),
|
bytemuck::cast_slice(data),
|
||||||
bytes_per_row,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1882,16 +1891,16 @@ fn create_pipelines(
|
|||||||
Ok(ResolvedInclude {
|
Ok(ResolvedInclude {
|
||||||
resolved_name: name.to_string(),
|
resolved_name: name.to_string(),
|
||||||
content: match name {
|
content: match name {
|
||||||
"constants.glsl" => constants,
|
"constants.glsl" => constants.clone(),
|
||||||
"globals.glsl" => *globals,
|
"globals.glsl" => globals.as_ref().clone(),
|
||||||
"shadows.glsl" => *shadows,
|
"shadows.glsl" => shadows.as_ref().clone(),
|
||||||
"sky.glsl" => *sky,
|
"sky.glsl" => sky.as_ref().clone(),
|
||||||
"light.glsl" => *light,
|
"light.glsl" => light.as_ref().clone(),
|
||||||
"srgb.glsl" => *srgb,
|
"srgb.glsl" => srgb.as_ref().clone(),
|
||||||
"random.glsl" => *random,
|
"random.glsl" => random.as_ref().clone(),
|
||||||
"lod.glsl" => *lod,
|
"lod.glsl" => lod.as_ref().clone(),
|
||||||
"anti-aliasing.glsl" => *anti_alias,
|
"anti-aliasing.glsl" => anti_alias.as_ref().clone(),
|
||||||
"cloud.glsl" => *cloud,
|
"cloud.glsl" => cloud.as_ref().clone(),
|
||||||
other => return Err(format!("Include {} is not defined", other)),
|
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,
|
device: &wgpu::Device,
|
||||||
compiler: &mut shaderc::Compiler,
|
compiler: &mut shaderc::Compiler,
|
||||||
source: &str,
|
source: &str,
|
||||||
|
@ -18,7 +18,7 @@ impl Texture {
|
|||||||
filter_method: Option<wgpu::FilterMode>,
|
filter_method: Option<wgpu::FilterMode>,
|
||||||
address_mode: Option<wgpu::AddressMode>,
|
address_mode: Option<wgpu::AddressMode>,
|
||||||
) -> Result<Self, RenderError> {
|
) -> 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(|| {
|
let buffer = image.as_flat_samples_u8().ok_or_else(|| {
|
||||||
RenderError::CustomError(
|
RenderError::CustomError(
|
||||||
"We currently do not support color formats using more than 4 bytes / pixel.".into(),
|
"We currently do not support color formats using more than 4 bytes / pixel.".into(),
|
||||||
@ -38,7 +38,7 @@ impl Texture {
|
|||||||
sample_count: 1,
|
sample_count: 1,
|
||||||
dimension: wgpu::TextureDimension::D2,
|
dimension: wgpu::TextureDimension::D2,
|
||||||
format: wgpu::TextureFormat::Rgba8UnormSrgb,
|
format: wgpu::TextureFormat::Rgba8UnormSrgb,
|
||||||
usage: wgpu::TextureUsage::COPY_DST | wgpu::TextureUsage::SAMPLED,
|
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::COPY_DST,
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut command_encoder =
|
let mut command_encoder =
|
||||||
@ -107,7 +107,8 @@ impl Texture {
|
|||||||
sample_count: 1,
|
sample_count: 1,
|
||||||
dimension: wgpu::TextureDimension::D2,
|
dimension: wgpu::TextureDimension::D2,
|
||||||
format: wgpu::TextureFormat::Rgba8UnormSrgb,
|
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 {
|
let sampler_info = wgpu::SamplerDescriptor {
|
||||||
@ -161,8 +162,10 @@ impl Texture {
|
|||||||
offset: [u32; 2],
|
offset: [u32; 2],
|
||||||
size: [u32; 2],
|
size: [u32; 2],
|
||||||
data: &[u8],
|
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
|
// TODO: Only works for 2D images
|
||||||
queue.write_texture(
|
queue.write_texture(
|
||||||
wgpu::TextureCopyViewBase {
|
wgpu::TextureCopyViewBase {
|
||||||
@ -177,8 +180,8 @@ impl Texture {
|
|||||||
data,
|
data,
|
||||||
wgpu::TextureDataLayout {
|
wgpu::TextureDataLayout {
|
||||||
offset: 0,
|
offset: 0,
|
||||||
bytes_per_row,
|
bytes_per_row: size[0] * 4,
|
||||||
rows_per_image: self.size.height,
|
rows_per_image: size[1],
|
||||||
},
|
},
|
||||||
wgpu::Extent3d {
|
wgpu::Extent3d {
|
||||||
width: size[0],
|
width: size[0],
|
||||||
@ -189,5 +192,7 @@ impl Texture {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get dimensions of the represented image.
|
/// 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,
|
ecs::comp::Interpolated,
|
||||||
render::{
|
render::{
|
||||||
pipelines, ColLightInfo, Consts, FigureBoneData, FigureLocals, FigureModel, GlobalModel,
|
pipelines, ColLightInfo, Consts, FigureBoneData, FigureLocals, FigureModel, GlobalModel,
|
||||||
Mesh, RenderError, Renderer, TerrainVertex, Texture,
|
Mesh, RenderError, Renderer, SubModel, TerrainVertex, Texture,
|
||||||
},
|
},
|
||||||
scene::{
|
scene::{
|
||||||
camera::{Camera, CameraMode, Dependents},
|
camera::{Camera, CameraMode, Dependents},
|
||||||
@ -63,7 +63,7 @@ pub type CameraData<'a> = (&'a Camera, f32);
|
|||||||
pub type FigureModelRef<'a> = (
|
pub type FigureModelRef<'a> = (
|
||||||
&'a Consts<FigureLocals>,
|
&'a Consts<FigureLocals>,
|
||||||
&'a Consts<FigureBoneData>,
|
&'a Consts<FigureBoneData>,
|
||||||
&'a FigureModel,
|
SubModel<'a, TerrainVertex>,
|
||||||
&'a Texture, /* <ColLightFmt> */
|
&'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
|
/* TODO: Consider using mipmaps instead of storing multiple texture atlases for different
|
||||||
* LOD levels. */
|
* LOD levels. */
|
||||||
col_lights: Texture, /* <ColLightFmt> */
|
col_lights: Texture, /* <ColLightFmt> */
|
||||||
/// Models stored in this figure entry; there may be several for one figure,
|
/// Vertex ranges stored in this figure entry; there may be several for one
|
||||||
/// because of LOD models.
|
/// figure, because of LOD models.
|
||||||
pub models: [FigureModel; N],
|
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 {
|
struct FigureMgrStates {
|
||||||
@ -4734,13 +4744,14 @@ impl FigureMgr {
|
|||||||
figure_lod_render_distance * scale.map_or(1.0, |s| s.0),
|
figure_lod_render_distance * scale.map_or(1.0, |s| s.0),
|
||||||
|state| state.can_shadow_sun(),
|
|state| state.can_shadow_sun(),
|
||||||
) {
|
) {
|
||||||
renderer.render_figure_shadow_directed(
|
// TODO
|
||||||
model,
|
//renderer.render_figure_shadow_directed(
|
||||||
global,
|
// model,
|
||||||
locals,
|
// global,
|
||||||
bone_consts,
|
// locals,
|
||||||
&global.shadow_mats,
|
// bone_consts,
|
||||||
);
|
// &global.shadow_mats,
|
||||||
|
//);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -4791,7 +4802,8 @@ impl FigureMgr {
|
|||||||
figure_lod_render_distance * scale.map_or(1.0, |s| s.0),
|
figure_lod_render_distance * scale.map_or(1.0, |s| s.0),
|
||||||
|state| state.visible(),
|
|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,
|
figure_lod_render_distance,
|
||||||
|state| state.visible(),
|
|state| state.visible(),
|
||||||
) {
|
) {
|
||||||
renderer.render_player(model, &col_lights, global, locals, bone_consts, lod);
|
//renderer.render_player(model, &col_lights, global, locals,
|
||||||
renderer.render_player_shadow(
|
// bone_consts, lod);
|
||||||
|
/*renderer.render_player_shadow(
|
||||||
model,
|
model,
|
||||||
&col_lights,
|
&col_lights,
|
||||||
global,
|
global,
|
||||||
bone_consts,
|
bone_consts,
|
||||||
lod,
|
lod,
|
||||||
&global.shadow_mats,
|
&global.shadow_mats,
|
||||||
);
|
);*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5175,11 +5188,11 @@ impl FigureMgr {
|
|||||||
let figure_mid_detail_distance = figure_lod_render_distance * 0.5;
|
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) {
|
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) {
|
} else if pos.distance_squared(cam_pos) > figure_mid_detail_distance.powi(2) {
|
||||||
&model_entry.models[1]
|
model_entry.lod_model(1)
|
||||||
} else {
|
} else {
|
||||||
&model_entry.models[0]
|
model_entry.lod_model(0)
|
||||||
};
|
};
|
||||||
|
|
||||||
Some((locals, bone_consts, model, col_lights_.texture(model_entry)))
|
Some((locals, bone_consts, model, col_lights_.texture(model_entry)))
|
||||||
@ -5225,7 +5238,7 @@ impl FigureColLights {
|
|||||||
renderer: &mut Renderer,
|
renderer: &mut Renderer,
|
||||||
(tex, tex_size): ColLightInfo,
|
(tex, tex_size): ColLightInfo,
|
||||||
(opaque, bounds): (Mesh<TerrainVertex>, math::Aabb<f32>),
|
(opaque, bounds): (Mesh<TerrainVertex>, math::Aabb<f32>),
|
||||||
vertex_range: [Range<u32>; N],
|
vertex_ranges: [Range<u32>; N],
|
||||||
) -> Result<FigureModelEntry<N>, RenderError> {
|
) -> Result<FigureModelEntry<N>, RenderError> {
|
||||||
span!(_guard, "create_figure", "FigureColLights::create_figure");
|
span!(_guard, "create_figure", "FigureColLights::create_figure");
|
||||||
let atlas = &mut self.atlas;
|
let atlas = &mut self.atlas;
|
||||||
@ -5237,22 +5250,22 @@ impl FigureColLights {
|
|||||||
.expect("The model size for this figure does not fit in a u32!");
|
.expect("The model size for this figure does not fit in a u32!");
|
||||||
let model = renderer.create_model(&opaque)?;
|
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 {
|
Ok(FigureModelEntry {
|
||||||
_bounds: bounds,
|
_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,
|
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) {
|
pub fn render(&self, renderer: &mut Renderer, global: &GlobalModel) {
|
||||||
if let Some((_, model)) = self.model.as_ref() {
|
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,
|
client: &Client,
|
||||||
settings: &Settings,
|
settings: &Settings,
|
||||||
) -> Self {
|
) -> 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);
|
let sprite_render_context = lazy_init(renderer);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
@ -642,7 +642,7 @@ impl Scene {
|
|||||||
self.map_bounds,
|
self.map_bounds,
|
||||||
time_of_day,
|
time_of_day,
|
||||||
scene_data.state.get_time(),
|
scene_data.state.get_time(),
|
||||||
renderer.get_resolution().as_(),
|
renderer.resolution().as_(),
|
||||||
Vec2::new(SHADOW_NEAR, SHADOW_FAR),
|
Vec2::new(SHADOW_NEAR, SHADOW_FAR),
|
||||||
lights.len(),
|
lights.len(),
|
||||||
shadows.len(),
|
shadows.len(),
|
||||||
@ -1061,7 +1061,7 @@ impl Scene {
|
|||||||
self.lod.render(renderer, global);
|
self.lod.render(renderer, global);
|
||||||
|
|
||||||
// Render the skybox.
|
// 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(
|
self.terrain.render_translucent(
|
||||||
renderer,
|
renderer,
|
||||||
@ -1075,19 +1075,20 @@ impl Scene {
|
|||||||
// Render particle effects.
|
// Render particle effects.
|
||||||
self.particle_mgr.render(renderer, scene_data, global, lod);
|
self.particle_mgr.render(renderer, scene_data, global, lod);
|
||||||
|
|
||||||
// Render clouds (a post-processing effect)
|
// TODO:
|
||||||
renderer.render_clouds(
|
// // Render clouds (a post-processing effect)
|
||||||
&self.clouds.model,
|
// renderer.render_clouds(
|
||||||
&global.globals,
|
// &self.clouds.model,
|
||||||
&self.clouds.locals,
|
// &global.globals,
|
||||||
self.lod.get_data(),
|
// &self.clouds.locals,
|
||||||
);
|
// self.lod.get_data(),
|
||||||
|
// );
|
||||||
|
|
||||||
renderer.render_post_process(
|
// renderer.render_post_process(
|
||||||
&self.postprocess.model,
|
// &self.postprocess.model,
|
||||||
&global.globals,
|
// &global.globals,
|
||||||
&self.postprocess.locals,
|
// &self.postprocess.locals,
|
||||||
self.lod.get_data(),
|
// self.lod.get_data(),
|
||||||
);
|
// );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1192,7 +1192,8 @@ impl ParticleMgr {
|
|||||||
.get(DEFAULT_MODEL_KEY)
|
.get(DEFAULT_MODEL_KEY)
|
||||||
.expect("Expected particle model in cache");
|
.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,
|
terrain::BlockKind,
|
||||||
vol::{BaseVol, ReadVol},
|
vol::{BaseVol, ReadVol},
|
||||||
};
|
};
|
||||||
use tracing::error;
|
|
||||||
use vek::*;
|
use vek::*;
|
||||||
use winit::event::MouseButton;
|
use winit::event::MouseButton;
|
||||||
|
|
||||||
@ -104,7 +103,7 @@ pub struct SceneData<'a> {
|
|||||||
impl Scene {
|
impl Scene {
|
||||||
pub fn new(renderer: &mut Renderer, backdrop: Option<&str>, client: &Client) -> Self {
|
pub fn new(renderer: &mut Renderer, backdrop: Option<&str>, client: &Client) -> Self {
|
||||||
let start_angle = 90.0f32.to_radians();
|
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(
|
let map_bounds = Vec2::new(
|
||||||
client.world_data().min_chunk_alt(),
|
client.world_data().min_chunk_alt(),
|
||||||
@ -278,7 +277,7 @@ impl Scene {
|
|||||||
self.map_bounds,
|
self.map_bounds,
|
||||||
TIME,
|
TIME,
|
||||||
scene_data.time,
|
scene_data.time,
|
||||||
renderer.get_resolution().as_(),
|
renderer.resolution().as_(),
|
||||||
Vec2::new(SHADOW_NEAR, SHADOW_FAR),
|
Vec2::new(SHADOW_NEAR, SHADOW_FAR),
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
@ -380,12 +379,12 @@ impl Scene {
|
|||||||
body: Option<humanoid::Body>,
|
body: Option<humanoid::Body>,
|
||||||
inventory: Option<&Inventory>,
|
inventory: Option<&Inventory>,
|
||||||
) {
|
) {
|
||||||
renderer.render_skybox(
|
/*renderer.render_skybox(
|
||||||
&self.skybox.model,
|
&self.skybox.model,
|
||||||
&self.data,
|
&self.data,
|
||||||
&self.skybox.locals,
|
&self.skybox.locals,
|
||||||
&self.lod,
|
&self.lod,
|
||||||
);
|
);*/
|
||||||
|
|
||||||
if let Some(body) = body {
|
if let Some(body) = body {
|
||||||
let model = &self.figure_model_cache.get_model(
|
let model = &self.figure_model_cache.get_model(
|
||||||
@ -398,40 +397,40 @@ impl Scene {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if let Some(model) = model {
|
if let Some(model) = model {
|
||||||
renderer.render_figure(
|
// renderer.render_figure(
|
||||||
&model.models[0],
|
// &model.models[0],
|
||||||
&self.col_lights.texture(model),
|
// &self.col_lights.texture(model),
|
||||||
&self.data,
|
// &self.data,
|
||||||
self.figure_state.locals(),
|
// self.figure_state.locals(),
|
||||||
self.figure_state.bone_consts(),
|
// self.figure_state.bone_consts(),
|
||||||
&self.lod,
|
// &self.lod,
|
||||||
);
|
// );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some((model, state)) = &self.backdrop {
|
if let Some((model, state)) = &self.backdrop {
|
||||||
renderer.render_figure(
|
/*renderer.render_figure(
|
||||||
&model.models[0],
|
&model.models[0],
|
||||||
&self.col_lights.texture(model),
|
&self.col_lights.texture(model),
|
||||||
&self.data,
|
&self.data,
|
||||||
state.locals(),
|
state.locals(),
|
||||||
state.bone_consts(),
|
state.bone_consts(),
|
||||||
&self.lod,
|
&self.lod,
|
||||||
);
|
);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
renderer.render_clouds(
|
// renderer.render_clouds(
|
||||||
&self.clouds.model,
|
// &self.clouds.model,
|
||||||
&self.data.globals,
|
// &self.data.globals,
|
||||||
&self.clouds.locals,
|
// &self.clouds.locals,
|
||||||
&self.lod,
|
// &self.lod,
|
||||||
);
|
// );
|
||||||
|
|
||||||
renderer.render_post_process(
|
// renderer.render_post_process(
|
||||||
&self.postprocess.model,
|
// &self.postprocess.model,
|
||||||
&self.data.globals,
|
// &self.data.globals,
|
||||||
&self.postprocess.locals,
|
// &self.postprocess.locals,
|
||||||
&self.lod,
|
// &self.lod,
|
||||||
);
|
// );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1429,12 +1429,12 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
.chain(self.shadow_chunks.iter().map(|(_, chunk)| chunk))
|
.chain(self.shadow_chunks.iter().map(|(_, chunk)| chunk))
|
||||||
.for_each(|chunk| {
|
.for_each(|chunk| {
|
||||||
// Directed light shadows.
|
// Directed light shadows.
|
||||||
renderer.render_terrain_shadow_directed(
|
/*renderer.render_terrain_shadow_directed(
|
||||||
&chunk.opaque_model,
|
&chunk.opaque_model,
|
||||||
global,
|
global,
|
||||||
&chunk.locals,
|
&chunk.locals,
|
||||||
&global.shadow_mats,
|
&global.shadow_mats,
|
||||||
);
|
);*/
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1445,12 +1445,12 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
light_data.iter().take(1).for_each(|_light| {
|
light_data.iter().take(1).for_each(|_light| {
|
||||||
chunk_iter.clone().for_each(|chunk| {
|
chunk_iter.clone().for_each(|chunk| {
|
||||||
if chunk.can_shadow_point {
|
if chunk.can_shadow_point {
|
||||||
renderer.render_shadow_point(
|
/*renderer.render_shadow_point(
|
||||||
&chunk.opaque_model,
|
&chunk.opaque_model,
|
||||||
global,
|
global,
|
||||||
&chunk.locals,
|
&chunk.locals,
|
||||||
&global.shadow_mats,
|
&global.shadow_mats,
|
||||||
);
|
);*/
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -1477,13 +1477,13 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
|
|
||||||
for (_, chunk) in chunk_iter {
|
for (_, chunk) in chunk_iter {
|
||||||
if chunk.visible.is_visible() {
|
if chunk.visible.is_visible() {
|
||||||
renderer.render_terrain_chunk(
|
/* renderer.render_terrain_chunk(
|
||||||
&chunk.opaque_model,
|
&chunk.opaque_model,
|
||||||
&chunk.texture,
|
&chunk.texture,
|
||||||
global,
|
global,
|
||||||
&chunk.locals,
|
&chunk.locals,
|
||||||
lod,
|
lod,
|
||||||
);
|
);*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1558,7 +1558,7 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
} else {
|
} else {
|
||||||
&self.sprite_data[&kind][4]
|
&self.sprite_data[&kind][4]
|
||||||
};
|
};
|
||||||
renderer.render_sprites(
|
/*renderer.render_sprites(
|
||||||
model,
|
model,
|
||||||
&self.sprite_col_lights,
|
&self.sprite_col_lights,
|
||||||
global,
|
global,
|
||||||
@ -1566,7 +1566,7 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
locals,
|
locals,
|
||||||
&instances,
|
&instances,
|
||||||
lod,
|
lod,
|
||||||
);
|
);*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1587,13 +1587,13 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
.into_iter()
|
.into_iter()
|
||||||
.rev() // Render back-to-front
|
.rev() // Render back-to-front
|
||||||
.for_each(|(model, locals)| {
|
.for_each(|(model, locals)| {
|
||||||
renderer.render_fluid_chunk(
|
/*renderer.render_fluid_chunk(
|
||||||
model,
|
model,
|
||||||
global,
|
global,
|
||||||
locals,
|
locals,
|
||||||
lod,
|
lod,
|
||||||
&self.waves,
|
&self.waves,
|
||||||
)
|
)*/
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ use hashbrown::HashMap;
|
|||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
// Multiplied by current window size
|
// Multiplied by current window size
|
||||||
const GLYPH_CACHE_SIZE: u16 = 1;
|
const GLYPH_CACHE_SIZE: u32 = 1;
|
||||||
// Glyph cache tolerances
|
// Glyph cache tolerances
|
||||||
const SCALE_TOLERANCE: f32 = 0.5;
|
const SCALE_TOLERANCE: f32 = 0.5;
|
||||||
const POSITION_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?
|
// TODO: Should functions be returning UiError instead of Error?
|
||||||
impl Cache {
|
impl Cache {
|
||||||
pub fn new(renderer: &mut Renderer) -> Result<Self, Error> {
|
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();
|
let max_texture_size = renderer.max_texture_size();
|
||||||
|
|
||||||
@ -36,11 +36,11 @@ impl Cache {
|
|||||||
Ok(Self {
|
Ok(Self {
|
||||||
text_cache: Default::default(),
|
text_cache: Default::default(),
|
||||||
glyph_cache: GlyphCache::builder()
|
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)
|
.scale_tolerance(SCALE_TOLERANCE)
|
||||||
.position_tolerance(POSITION_TOLERANCE)
|
.position_tolerance(POSITION_TOLERANCE)
|
||||||
.build(),
|
.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),
|
graphic_cache: GraphicCache::new(renderer),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -82,14 +82,14 @@ impl Cache {
|
|||||||
self.text_cache.clear();
|
self.text_cache.clear();
|
||||||
let max_texture_size = renderer.max_texture_size();
|
let max_texture_size = renderer.max_texture_size();
|
||||||
let cache_dims = renderer
|
let cache_dims = renderer
|
||||||
.get_resolution()
|
.resolution()
|
||||||
.map(|e| (e * GLYPH_CACHE_SIZE).min(max_texture_size).max(512));
|
.map(|e| (e * GLYPH_CACHE_SIZE).min(max_texture_size).max(512));
|
||||||
self.glyph_cache = GlyphCache::builder()
|
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)
|
.scale_tolerance(SCALE_TOLERANCE)
|
||||||
.position_tolerance(POSITION_TOLERANCE)
|
.position_tolerance(POSITION_TOLERANCE)
|
||||||
.build();
|
.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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ pub enum Rotation {
|
|||||||
/// Fraction of the total graphic cache size
|
/// Fraction of the total graphic cache size
|
||||||
const ATLAS_CUTOFF_FRAC: f32 = 0.2;
|
const ATLAS_CUTOFF_FRAC: f32 = 0.2;
|
||||||
/// Multiplied by current window size
|
/// 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)]
|
#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)]
|
||||||
pub struct Id(u32);
|
pub struct Id(u32);
|
||||||
@ -303,7 +303,7 @@ impl GraphicCache {
|
|||||||
// Graphics over a particular size are sent to their own textures
|
// Graphics over a particular size are sent to their own textures
|
||||||
let location = if let Some(border_color) = border_color {
|
let location = if let Some(border_color) = border_color {
|
||||||
// Create a new immutable texture.
|
// 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!
|
// NOTE: All mutations happen only after the upload succeeds!
|
||||||
let index = textures.len();
|
let index = textures.len();
|
||||||
textures.push(texture);
|
textures.push(texture);
|
||||||
@ -354,7 +354,7 @@ impl GraphicCache {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Create a texture just for this
|
// 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!
|
// NOTE: All mutations happen only after the texture creation succeeds!
|
||||||
let index = textures.len();
|
let index = textures.len();
|
||||||
textures.push(texture);
|
textures.push(texture);
|
||||||
@ -409,10 +409,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();
|
let max_texture_size = renderer.max_texture_size();
|
||||||
|
|
||||||
renderer.get_resolution().map(|e| {
|
renderer.resolution().map(|e| {
|
||||||
(e * GRAPHIC_CACHE_RELATIVE_SIZE)
|
(e * GRAPHIC_CACHE_RELATIVE_SIZE)
|
||||||
.max(512)
|
.max(512)
|
||||||
.min(max_texture_size)
|
.min(max_texture_size)
|
||||||
@ -421,8 +421,9 @@ fn atlas_size(renderer: &Renderer) -> Vec2<u16> {
|
|||||||
|
|
||||||
fn create_atlas_texture(renderer: &mut Renderer) -> (SimpleAtlasAllocator, Texture) {
|
fn create_atlas_texture(renderer: &mut Renderer) -> (SimpleAtlasAllocator, Texture) {
|
||||||
let size = atlas_size(renderer);
|
let size = atlas_size(renderer);
|
||||||
let atlas = SimpleAtlasAllocator::new(size2(i32::from(size.x), i32::from(size.y)));
|
// Note: here we assume the atlas size is under i32::MAX
|
||||||
let texture = renderer.create_dynamic_texture(size).unwrap();
|
let atlas = SimpleAtlasAllocator::new(size2(size.x as i32, size.y as i32));
|
||||||
|
let texture = renderer.create_dynamic_texture(size);
|
||||||
(atlas, texture)
|
(atlas, texture)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -435,25 +436,27 @@ fn aabr_from_alloc_rect(rect: guillotiere::Rectangle) -> Aabr<u16> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn upload_image(renderer: &mut Renderer, aabr: Aabr<u16>, tex: &Texture, image: &RgbaImage) {
|
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 offset = aabr.min.into_array();
|
||||||
let size = aabr.size().into_array();
|
let size = aabr.size().into_array();
|
||||||
if let Err(e) = renderer.update_texture(
|
renderer.update_texture(
|
||||||
tex,
|
tex,
|
||||||
offset,
|
offset,
|
||||||
size,
|
size,
|
||||||
// NOTE: Rgba texture, so each pixel is 4 bytes, ergo this cannot fail.
|
// NOTE: Rgba texture, so each pixel is 4 bytes, ergo this cannot fail.
|
||||||
// We make the cast parameters explicit for clarity.
|
// We make the cast parameters explicit for clarity.
|
||||||
bytemuck::cast_slice::<u8, [u8; 4]>(&image),
|
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>) {
|
fn create_image(renderer: &mut Renderer, image: RgbaImage, border_color: Rgba<f32>) -> Texture {
|
||||||
renderer.create_texture(
|
renderer
|
||||||
&DynamicImage::ImageRgba8(image),
|
.create_texture(
|
||||||
None,
|
&DynamicImage::ImageRgba8(image),
|
||||||
Some(wgpu::AddressMode::ClampToBorder),
|
None,
|
||||||
Some(border_color.into_array().into()),
|
//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")
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ pub use widgets::{
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
render::{
|
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,
|
UIVertex, UiLocals, UiMode,
|
||||||
},
|
},
|
||||||
window::Window,
|
window::Window,
|
||||||
@ -109,7 +109,7 @@ pub struct Ui {
|
|||||||
// during redrawing.
|
// during redrawing.
|
||||||
mesh: Mesh<UIVertex>,
|
mesh: Mesh<UIVertex>,
|
||||||
// Model for drawing the ui
|
// Model for drawing the ui
|
||||||
model: Model<UIVertex>,
|
model: DynamicModel<UIVertex>,
|
||||||
// Consts for default ui drawing position (ie the interface)
|
// Consts for default ui drawing position (ie the interface)
|
||||||
interface_locals: Consts<UiLocals>,
|
interface_locals: Consts<UiLocals>,
|
||||||
default_globals: Consts<Globals>,
|
default_globals: Consts<Globals>,
|
||||||
@ -162,7 +162,7 @@ impl Ui {
|
|||||||
cache: Cache::new(renderer)?,
|
cache: Cache::new(renderer)?,
|
||||||
draw_commands: Vec::new(),
|
draw_commands: Vec::new(),
|
||||||
mesh: Mesh::new(),
|
mesh: Mesh::new(),
|
||||||
model: renderer.create_dynamic_model(100)?,
|
model: renderer.create_dynamic_model(100),
|
||||||
interface_locals: renderer.create_consts(&[UiLocals::default()])?,
|
interface_locals: renderer.create_consts(&[UiLocals::default()])?,
|
||||||
default_globals: renderer.create_consts(&[Globals::default()])?,
|
default_globals: renderer.create_consts(&[Globals::default()])?,
|
||||||
ingame_locals: Vec::new(),
|
ingame_locals: Vec::new(),
|
||||||
@ -334,7 +334,7 @@ impl Ui {
|
|||||||
// Avoid resetting cache if window size didn't change
|
// Avoid resetting cache if window size didn't change
|
||||||
// Somewhat inefficient for elements that won't change size after a window
|
// Somewhat inefficient for elements that won't change size after a window
|
||||||
// resize
|
// resize
|
||||||
let res = renderer.get_resolution();
|
let res = renderer.resolution();
|
||||||
res.x > 0 && res.y > 0 && !(old_w == w && old_h == h)
|
res.x > 0 && res.y > 0 && !(old_w == w && old_h == h)
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
@ -381,7 +381,7 @@ impl Ui {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let (half_res, x_align, y_align) = {
|
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.map(|e| e as f32 / 2.0),
|
||||||
(res.x & 1) as f32 * 0.5,
|
(res.x & 1) as f32 * 0.5,
|
||||||
@ -560,23 +560,15 @@ impl Ui {
|
|||||||
tracing::debug!("Updating glyphs and clearing text cache.");
|
tracing::debug!("Updating glyphs and clearing text cache.");
|
||||||
|
|
||||||
if let Err(err) = glyph_cache.cache_queued(|rect, data| {
|
if let Err(err) = glyph_cache.cache_queued(|rect, data| {
|
||||||
let offset = [rect.min.x as u16, rect.min.y as u16];
|
let offset = [rect.min.x as u32, rect.min.y as u32];
|
||||||
let size = [rect.width() as u16, rect.height() as u16];
|
let size = [rect.width() as u32, rect.height() as u32];
|
||||||
|
|
||||||
let new_data = data
|
let new_data = data
|
||||||
.iter()
|
.iter()
|
||||||
.map(|x| [255, 255, 255, *x])
|
.map(|x| [255, 255, 255, *x])
|
||||||
.collect::<Vec<[u8; 4]>>();
|
.collect::<Vec<[u8; 4]>>();
|
||||||
|
|
||||||
if let Err(err) = renderer.update_texture(
|
renderer.update_texture(cache_tex, offset, size, &new_data);
|
||||||
cache_tex,
|
|
||||||
offset,
|
|
||||||
size,
|
|
||||||
&new_data,
|
|
||||||
rect.width() * 4,
|
|
||||||
) {
|
|
||||||
warn!("Failed to update texture: {:?}", err);
|
|
||||||
}
|
|
||||||
}) {
|
}) {
|
||||||
// FIXME: If we actually hit this error, it's still possible we could salvage
|
// 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
|
// things in various ways (for instance, the current queue might have extra
|
||||||
@ -821,6 +813,7 @@ impl Ui {
|
|||||||
let cache_dims = graphic_cache
|
let cache_dims = graphic_cache
|
||||||
.get_tex(tex_id)
|
.get_tex(tex_id)
|
||||||
.get_dimensions()
|
.get_dimensions()
|
||||||
|
.xy()
|
||||||
.map(|e| e as f32);
|
.map(|e| e as f32);
|
||||||
let min = Vec2::new(aabr.min.x as f32, aabr.max.y as f32) / cache_dims;
|
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;
|
let max = Vec2::new(aabr.max.x as f32, aabr.min.y as f32) / cache_dims;
|
||||||
@ -954,12 +947,10 @@ impl Ui {
|
|||||||
// Push new position command
|
// Push new position command
|
||||||
let world_pos = Vec4::from_point(parameters.pos);
|
let world_pos = Vec4::from_point(parameters.pos);
|
||||||
if self.ingame_locals.len() > ingame_local_index {
|
if self.ingame_locals.len() > ingame_local_index {
|
||||||
renderer
|
renderer.update_consts(
|
||||||
.update_consts(
|
&mut self.ingame_locals[ingame_local_index],
|
||||||
&mut self.ingame_locals[ingame_local_index],
|
&[world_pos.into()],
|
||||||
&[world_pos.into()],
|
)
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
} else {
|
} else {
|
||||||
self.ingame_locals
|
self.ingame_locals
|
||||||
.push(renderer.create_consts(&[world_pos.into()]).unwrap());
|
.push(renderer.create_consts(&[world_pos.into()]).unwrap());
|
||||||
@ -1007,13 +998,11 @@ impl Ui {
|
|||||||
|
|
||||||
// Create a larger dynamic model if the mesh is larger than the current model
|
// Create a larger dynamic model if the mesh is larger than the current model
|
||||||
// size.
|
// size.
|
||||||
if self.model.vbuf.len() < self.mesh.vertices().len() {
|
if self.model.len() < self.mesh.vertices().len() {
|
||||||
self.model = renderer
|
self.model = renderer.create_dynamic_model(self.mesh.vertices().len() * 4 / 3);
|
||||||
.create_dynamic_model(self.mesh.vertices().len() * 4 / 3)
|
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
// Update model with new mesh.
|
// 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>>) {
|
pub fn render(&self, renderer: &mut Renderer, maybe_globals: Option<&Consts<Globals>>) {
|
||||||
@ -1035,7 +1024,9 @@ impl Ui {
|
|||||||
DrawKind::Plain => self.cache.glyph_cache_tex(),
|
DrawKind::Plain => self.cache.glyph_cache_tex(),
|
||||||
};
|
};
|
||||||
let model = self.model.submodel(verts.clone());
|
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);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1043,12 +1034,12 @@ impl Ui {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn default_scissor(renderer: &Renderer) -> Aabr<u16> {
|
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 {
|
Aabr {
|
||||||
min: Vec2 { x: 0, y: 0 },
|
min: Vec2 { x: 0, y: 0 },
|
||||||
max: Vec2 {
|
max: Vec2 {
|
||||||
x: screen_w,
|
x: screen_w as u16,
|
||||||
y: screen_h,
|
y: screen_h as u16,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -518,7 +518,7 @@ impl KeyMouse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct Window {
|
pub struct Window {
|
||||||
renderer: Renderer<'static>,
|
renderer: Renderer,
|
||||||
window: winit::window::Window,
|
window: winit::window::Window,
|
||||||
cursor_grabbed: bool,
|
cursor_grabbed: bool,
|
||||||
pub pan_sensitivity: u32,
|
pub pan_sensitivity: u32,
|
||||||
@ -658,7 +658,7 @@ impl Window {
|
|||||||
|
|
||||||
pub fn renderer(&self) -> &Renderer { &self.renderer }
|
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) {
|
pub fn resolve_deduplicated_events(&mut self, settings: &mut Settings) {
|
||||||
// Handle screenshots and toggling fullscreen
|
// Handle screenshots and toggling fullscreen
|
||||||
@ -941,7 +941,9 @@ impl Window {
|
|||||||
// let (mut color_view, mut depth_view) = self.renderer.win_views_mut();
|
// let (mut color_view, mut depth_view) = self.renderer.win_views_mut();
|
||||||
// self.window.resize(physical);
|
// self.window.resize(physical);
|
||||||
// self.window.update_gfx(&mut color_view, &mut depth_view);
|
// 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
|
// TODO: update users of this event with the fact that it is now the physical
|
||||||
// size
|
// size
|
||||||
let winit::dpi::PhysicalSize { width, height } = physical;
|
let winit::dpi::PhysicalSize { width, height } = physical;
|
||||||
|
Loading…
Reference in New Issue
Block a user