146 lines
4.1 KiB
Rust
146 lines
4.1 KiB
Rust
use crate::render::{color::ColorSource, render_graph::{BindType, TextureViewDimension}};
|
|
use legion::prelude::Entity;
|
|
use std::collections::HashMap;
|
|
|
|
// TODO: add ability to specify specific pipeline for uniforms
|
|
pub trait AsUniforms {
|
|
fn get_uniform_infos(&self) -> &[FieldUniformName];
|
|
fn get_uniform_bytes(&self, name: &str) -> Option<Vec<u8>>;
|
|
fn get_shader_defs(&self) -> Option<Vec<String>>;
|
|
fn get_field_bind_type(&self, name: &str) -> Option<FieldBindType>;
|
|
// TODO: support zero-copy uniforms
|
|
// fn get_uniform_bytes_ref(&self, name: &str) -> Option<&[u8]>;
|
|
}
|
|
|
|
pub trait ShaderDefSuffixProvider {
|
|
fn get_shader_def(&self) -> Option<&'static str>;
|
|
}
|
|
|
|
impl ShaderDefSuffixProvider for bool {
|
|
fn get_shader_def(&self) -> Option<&'static str> {
|
|
match *self {
|
|
true => Some(""),
|
|
false => None,
|
|
}
|
|
}
|
|
}
|
|
|
|
pub enum FieldBindType {
|
|
Uniform,
|
|
Texture,
|
|
}
|
|
|
|
pub struct UniformInfoIter<'a, T: AsUniforms> {
|
|
pub field_uniform_names: &'a [FieldUniformName],
|
|
pub uniforms: &'a T,
|
|
pub index: usize,
|
|
pub add_sampler: bool,
|
|
|
|
|
|
}
|
|
|
|
impl<'a, T> UniformInfoIter<'a, T> where T: AsUniforms {
|
|
pub fn new(field_uniform_names: &'a [FieldUniformName], uniforms: &'a T) -> Self {
|
|
UniformInfoIter {
|
|
field_uniform_names,
|
|
uniforms,
|
|
index: 0,
|
|
add_sampler: false,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'a, T> Iterator for UniformInfoIter<'a, T> where T: AsUniforms {
|
|
type Item = UniformInfo<'a>;
|
|
fn next(&mut self) -> Option<Self::Item> {
|
|
if self.add_sampler {
|
|
self.add_sampler = false;
|
|
Some(UniformInfo {
|
|
name: self.field_uniform_names[self.index - 1].sampler,
|
|
bind_type: BindType::Sampler,
|
|
})
|
|
} else {
|
|
if self.index == self.field_uniform_names.len() {
|
|
None
|
|
} else {
|
|
let index = self.index;
|
|
self.index += 1;
|
|
let field_uniform_name = self.field_uniform_names[index];
|
|
let bind_type = self.uniforms.get_field_bind_type(field_uniform_name.field).unwrap();
|
|
Some(match bind_type {
|
|
FieldBindType::Uniform => UniformInfo {
|
|
bind_type: BindType::Uniform {
|
|
dynamic: false,
|
|
properties: Vec::new(),
|
|
},
|
|
name: field_uniform_name.uniform,
|
|
},
|
|
FieldBindType::Texture => {
|
|
self.add_sampler = true;
|
|
UniformInfo {
|
|
bind_type: BindType::SampledTexture {
|
|
dimension: TextureViewDimension::D2,
|
|
multisampled: false,
|
|
},
|
|
name: field_uniform_name.texture,
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
pub struct FieldUniformName {
|
|
field: &'static str,
|
|
uniform: &'static str,
|
|
texture: &'static str,
|
|
sampler: &'static str,
|
|
}
|
|
|
|
pub trait AsFieldBindType {
|
|
fn get_field_uniform_type(&self) -> FieldBindType;
|
|
}
|
|
|
|
impl AsFieldBindType for ColorSource {
|
|
fn get_field_uniform_type(&self) -> FieldBindType {
|
|
match *self {
|
|
ColorSource::Texture(_) => FieldBindType::Texture,
|
|
ColorSource::Color(_) => FieldBindType::Uniform,
|
|
}
|
|
}
|
|
}
|
|
|
|
// impl<T> AsFieldBindType for T
|
|
// where
|
|
// T: GetBytes,
|
|
// {
|
|
// fn get_field_uniform_type(&self) -> FieldBindType {
|
|
// FieldBindType::Uniform
|
|
// }
|
|
// }
|
|
|
|
pub struct UniformInfo<'a> {
|
|
pub name: &'a str,
|
|
pub bind_type: BindType,
|
|
}
|
|
|
|
pub struct DynamicUniformBufferInfo {
|
|
pub indices: HashMap<usize, Entity>,
|
|
pub offsets: HashMap<Entity, u64>,
|
|
pub capacity: u64,
|
|
pub count: u64,
|
|
}
|
|
|
|
impl DynamicUniformBufferInfo {
|
|
pub fn new() -> Self {
|
|
DynamicUniformBufferInfo {
|
|
capacity: 0,
|
|
count: 0,
|
|
indices: HashMap::new(),
|
|
offsets: HashMap::new(),
|
|
}
|
|
}
|
|
}
|