Skip to content

Commit

Permalink
Start doing some work on shader uniforms
Browse files Browse the repository at this point in the history
  • Loading branch information
mattkleiny committed Jul 13, 2024
1 parent fd33540 commit 78637be
Show file tree
Hide file tree
Showing 15 changed files with 117 additions and 126 deletions.
2 changes: 2 additions & 0 deletions crates/common/src/abstractions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
//! know about the `scene` module, but graphics components can be present in a
//! scene.
pub use assets::*;
pub use os::*;
pub use variant::*;

mod assets;
mod os;
mod variant;
25 changes: 25 additions & 0 deletions crates/common/src/abstractions/assets.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//! Asset management for the engine
/// An error that can occur when loading an asset
#[derive(Debug)]
pub enum AssetError {
/// The asset could not be found
NotFound,
/// The asset could not be loaded
LoadFailed,
/// The asset is not of the expected type
TypeMismatch,
}

/// Represents an asset that can be loaded and used by the engine
pub trait Asset {}

/// An entry in the asset manager
enum AssetEntry {
Unloaded,
Loaded(Box<dyn Asset>),
}

/// A manager for assets
#[derive(Default)]
pub struct AssetManager {}
2 changes: 2 additions & 0 deletions crates/graphics/src/images.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ use common::FileSystemError;

use super::*;

// TODO: refactor this module

// common image types
pub type ColorImage = image::ImageBuffer<Color, Vec<f32>>;
pub type Color32Image = image::ImageBuffer<Color32, Vec<u8>>;
Expand Down
14 changes: 7 additions & 7 deletions crates/graphics/src/meshes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,13 @@ impl VertexKind {
/// Returns the size of this element type, in bytes.
pub const fn size(&self) -> Size {
Size::from_bytes(match self {
VertexKind::U8 => std::mem::size_of::<u8>(),
VertexKind::U16 => std::mem::size_of::<u16>(),
VertexKind::U32 => std::mem::size_of::<u32>(),
VertexKind::I16 => std::mem::size_of::<i16>(),
VertexKind::I32 => std::mem::size_of::<i32>(),
VertexKind::F32 => std::mem::size_of::<f32>(),
VertexKind::F64 => std::mem::size_of::<f64>(),
VertexKind::U8 => size_of::<u8>(),
VertexKind::U16 => size_of::<u16>(),
VertexKind::U32 => size_of::<u32>(),
VertexKind::I16 => size_of::<i16>(),
VertexKind::I32 => size_of::<i32>(),
VertexKind::F32 => size_of::<f32>(),
VertexKind::F64 => size_of::<f64>(),
})
}
}
Expand Down
65 changes: 26 additions & 39 deletions crates/graphics/src/shaders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,48 +10,15 @@ use std::{cell::RefCell, rc::Rc};

use bitflags::bitflags;
use common::*;
pub use lang::*;
pub use templates::*;

use super::*;

mod lang;
mod templates;

pub mod lang {
pub use glsl::*;
pub use shady::*;

use super::*;

mod glsl;
mod shady;

/// An environment used to parse and compile shader programs.
#[derive(Default)]
pub struct ShaderEnvironment {
pub constants: Vec<ShaderConstant>,
}

impl ShaderEnvironment {
/// An empty shader environment.
pub const EMPTY: Self = Self { constants: Vec::new() };
}

/// A constant value that can be used in a shader.
pub struct ShaderConstant {
pub name: String,
pub value: ShaderUniform,
}

/// Represents a language for [`ShaderKernel`]s.
pub trait ShaderLanguage {
/// The environment type used to parse and compile shader programs.
type Environment: Default = ShaderEnvironment;

/// Parses the given raw source code into one or more [`ShaderKernel`]s.
fn parse_kernels(source_code: &str) -> Result<Vec<ShaderKernel>, ShaderError>;
}
}
pub use lang::*;
pub use macros::ToShaderUniformSet;
pub use templates::*;

/// The nominal max number of texture units that might be bound in the GPU
/// for a single shader program.
Expand Down Expand Up @@ -393,6 +360,12 @@ impl<'a> IntoIterator for &'a ShaderUniformSet {
}
}

/// Allows a type to be converted into a [`ShaderUniform`] set.
pub trait ToShaderUniformSet {
/// Applies the type to the given [`ShaderUniformSet`].
fn apply_to(&self, set: &mut ShaderUniformSet);
}

/// Keeps texture assignments uniquely associated with slot indices.
///
/// This is useful for tracking unique texture assignments across multiple
Expand Down Expand Up @@ -431,13 +404,27 @@ impl TextureBindingSet {
self.slots.fill(None);
}

/// Returns an iterator over all texture IDs in the set.
pub fn iter(&self) -> impl Iterator<Item = &TextureId> {
self.slots.iter().filter_map(|slot| slot.as_ref())
}

/// Returns a vector of all texture IDs in the set.
pub fn to_vec(&self) -> Vec<TextureId> {
self.iter().copied().collect()
}

/// Returns an iterator over all texture IDs in the set.
pub fn iter(&self) -> impl Iterator<Item = &TextureId> {
self.slots.iter().filter_map(|slot| slot.as_ref())
pub fn into_vec(self) -> Vec<TextureId> {
self.slots.into_iter().filter_map(|slot| slot).collect()
}
}

impl<'a> IntoIterator for &'a TextureBindingSet {
type Item = &'a TextureId;
type IntoIter = impl Iterator<Item = Self::Item>;

fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
15 changes: 15 additions & 0 deletions crates/graphics/src/shaders/lang.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//! Shader language abstractions and templating.
pub use glsl::*;
pub use shady::*;

use super::*;

mod glsl;
mod shady;

/// Represents a language for [`ShaderKernel`]s.
pub trait ShaderLanguage {
/// Parses the given raw source code into one or more [`ShaderKernel`]s.
fn parse_kernels(source_code: &str) -> Result<Vec<ShaderKernel>, ShaderError>;
}
28 changes: 0 additions & 28 deletions crates/graphics/src/shaders/lang/glsl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,6 @@ use std::fmt::Write;

use super::*;

/// Possible versions of OpenGL that can be targeted by a shader program.
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub enum OpenGLVersion {
Glsl330,
Glsl410,
Glsl420,
}

/// The OpenGL environment for a shader program.
pub struct OpenGLEnvironment {
pub version: OpenGLVersion,
pub constants: Vec<ShaderConstant>,
}

impl Default for OpenGLEnvironment {
fn default() -> Self {
Self {
version: OpenGLVersion::Glsl410,
constants: vec![ShaderConstant {
name: "MAX_TEXTURES".to_string(),
value: ShaderUniform::U32(MAX_TEXTURE_UNITS as u32),
}],
}
}
}

/// The OpenGL [`ShaderLanguage`] implementation.
pub struct GLSL;

Expand All @@ -49,8 +23,6 @@ impl ShaderProgram {
}

impl ShaderLanguage for GLSL {
type Environment = OpenGLEnvironment;

/// Parses the given raw GLSL source and performs some basic pre-processing.
///
/// Allows for the following basic transformations:
Expand Down
3 changes: 0 additions & 3 deletions crates/graphics/src/shaders/templates.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@ use super::*;

/// A templated shader program that can be used to generate new
/// [`ShaderProgram`] instances at runtime.
///
/// Compilation will be performed on all calls to [`to_program`], so it is
/// recommended to cache the result if possible.
pub struct ShaderTemplate<S: ShaderLanguage> {
code: &'static str,
_phantom: std::marker::PhantomData<S>,
Expand Down
38 changes: 4 additions & 34 deletions crates/graphics/src/textures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,43 +301,13 @@ impl TextureRegion {

Rectangle::from_corner_points(left, top, right, bottom)
}
}

/// An atlas of textures, which is a subdivision of a texture into a smaller
/// grid of [`TextureRegion`]s.
#[derive(Clone)]
pub struct TextureAtlas {
texture: Texture,
width: u32,
height: u32,
}

impl TextureAtlas {
/// Creates a new texture atlas from the given texture.
pub fn new(width: u32, height: u32, texture: &Texture) -> Self {
/// Slices the texture region into a smaller region.
pub fn slice(&self, x: u32, y: u32, width: u32, height: u32) -> Self {
Self {
texture: texture.clone(),
width,
height,
}
}

/// The width of the atlas, in sub-regions.
pub fn width(&self) -> u32 {
self.texture.width() / self.width
}

/// The height of the atlas, in sub-regions.
pub fn height(&self) -> u32 {
self.texture.width() / self.height
}

/// Gets a sub-region of the texture atlas at the given position.
pub fn slice(&self, x: u32, y: u32) -> TextureRegion {
TextureRegion {
texture: self.texture.clone(),
offset: uvec2(x * self.width, y * self.height),
size: uvec2(self.width, self.height),
offset: uvec2(self.offset.x + x, self.offset.y + y),
size: uvec2(width, height),
}
}
}
Expand Down
7 changes: 7 additions & 0 deletions crates/macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use proc_macro::TokenStream;
mod profiling;
mod reflect;
mod singleton;
mod uniforms;
mod vertex;

/// Implements the Singleton pattern for a type.
Expand All @@ -25,6 +26,12 @@ pub fn profiling(_attr: TokenStream, item: TokenStream) -> TokenStream {
profiling::impl_profiling(item)
}

/// Derives the `ToShaderUniformSet` trait for a type.
#[proc_macro_derive(ToShaderUniformSet, attributes(uniform))]
pub fn derive_uniform_set(input: TokenStream) -> TokenStream {
uniforms::impl_uniform_set_trait(input)
}

/// Derives the `Vertex` trait for a type.
#[proc_macro_derive(Vertex, attributes(vertex))]
pub fn derive_vertex(input: TokenStream) -> TokenStream {
Expand Down
4 changes: 2 additions & 2 deletions crates/macros/src/profiling.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ use syn::{parse_macro_input, parse_quote};
pub fn impl_profiling(item: TokenStream) -> TokenStream {
let mut function = parse_macro_input!(item as syn::ItemFn);

let name = function.sig.ident.clone();
let ident = function.sig.ident.clone();
let block = function.block;

// rewrite the function to wrap the block in a profiling scope
function.block = Box::new(parse_quote! {{
common::profile_function!(#name);
common::profile_function!(#ident);
#block
}});

Expand Down
6 changes: 3 additions & 3 deletions crates/macros/src/singleton.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ use syn::{parse_macro_input, DeriveInput};

pub fn impl_singleton(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let name = &input.ident;
let ident = &input.ident;

let expanded = quote! {
impl Singleton for #name {
impl Singleton for #ident {
fn instance() -> &'static Self {
static INSTANCE: std::sync::LazyLock<#name> = std::sync::LazyLock::new(|| #name::default());
static INSTANCE: std::sync::LazyLock<#ident> = std::sync::LazyLock::new(|| #ident::default());

std::ops::Deref::deref(&INSTANCE)
}
Expand Down
18 changes: 18 additions & 0 deletions crates/macros/src/uniforms.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, DeriveInput};

pub fn impl_uniform_set_trait(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let ident = &input.ident;

let expanded = quote! {
impl ToShaderUniformSet for #ident {
fn apply_to(&self, set: &mut ShaderUniformSet) {
// TODO: implement me
}
}
};

expanded.into()
}
10 changes: 5 additions & 5 deletions crates/macros/src/vertex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ use syn::{parse_macro_input, spanned::Spanned, Attribute, Data, DeriveInput, Fie
pub fn impl_vertex_trait(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let descriptors = parse_struct(&input.data);
let name = &input.ident;
let ident = &input.ident;

let expanded = quote! {
impl Vertex for #name {
impl Vertex for #ident {
const DESCRIPTORS: &'static [VertexDescriptor] = &[
#(#descriptors),*
];
Expand All @@ -26,7 +26,7 @@ fn parse_struct(data: &Data) -> Vec<proc_macro2::TokenStream> {
.named
.iter()
.map(|field| {
let (count, kind, normalize) = parse_vertex_attributes(&field.attrs);
let (count, kind, normalize) = parse_fields(&field.attrs);

quote_spanned! { field.span() =>
VertexDescriptor {
Expand All @@ -45,8 +45,8 @@ fn parse_struct(data: &Data) -> Vec<proc_macro2::TokenStream> {
}
}

/// Parses the `#[vertex]` attribute on a field.
fn parse_vertex_attributes(attributes: &Vec<Attribute>) -> (usize, proc_macro2::TokenStream, bool) {
/// Parses the `#[vertex]` attributes on a field.
fn parse_fields(attributes: &Vec<Attribute>) -> (usize, proc_macro2::TokenStream, bool) {
let mut count = None;
let mut kind = None;
let mut normalize = false;
Expand Down
Loading

0 comments on commit 78637be

Please sign in to comment.