summaryrefslogtreecommitdiff
path: root/engine/src/rendering/shader.rs
diff options
context:
space:
mode:
Diffstat (limited to 'engine/src/rendering/shader.rs')
-rw-r--r--engine/src/rendering/shader.rs120
1 files changed, 110 insertions, 10 deletions
diff --git a/engine/src/rendering/shader.rs b/engine/src/rendering/shader.rs
index 3142400..6f50a79 100644
--- a/engine/src/rendering/shader.rs
+++ b/engine/src/rendering/shader.rs
@@ -1,7 +1,7 @@
use std::any::type_name;
use std::borrow::Cow;
-use std::collections::HashMap;
-use std::fmt::Debug;
+use std::collections::{HashMap, HashSet};
+use std::fmt::{Debug, Display, Write};
use std::path::Path;
use std::str::Utf8Error;
use std::sync::Arc;
@@ -34,10 +34,16 @@ use crate::ecs::pair::ChildOf;
use crate::ecs::phase::{Phase, POST_UPDATE as POST_UPDATE_PHASE};
use crate::ecs::sole::Single;
use crate::ecs::{declare_entity, pair, Component, Sole};
+use crate::mesh::vertex_buffer::VertexLabel;
pub mod cursor;
pub mod default;
+pub const STD_VERTEX_INPUT_SEMANTIC_NAME_POSITION: &str = "STD_POSITION";
+pub const STD_VERTEX_INPUT_SEMANTIC_NAME_NORMAL: &str = "STD_NORMAL";
+pub const STD_VERTEX_INPUT_SEMANTIC_NAME_UV: &str = "STD_UV";
+pub const STD_VERTEX_INPUT_SEMANTIC_NAME_COLOR: &str = "STD_COLOR";
+
#[derive(Debug, Clone, Component)]
pub struct Shader
{
@@ -983,15 +989,31 @@ impl VertexDescription
);
});
+ let mut seen_inputs = HashSet::<VertexInputSemName>::new();
+
Ok(Self {
inputs: inputs
.filter(|var_input| var_input.type_layout.kind() != TypeKind::Struct)
.map(|var_input| {
- let name = var_input
- .var_layout
- .name()
- .unwrap_or("<unnamed>")
- .to_string();
+ let name = var_input.var_layout.name().unwrap_or("<unnamed>");
+
+ let semantic_name =
+ var_input.var_layout.semantic_name().ok_or_else(|| {
+ VertexDescriptionError::VertexInputMissingSemanticName {
+ name: name.to_owned(),
+ }
+ })?;
+
+ let semantic_name =
+ VertexInputSemName::from_semantic_name(semantic_name);
+
+ if seen_inputs.contains(&semantic_name) {
+ return Err(
+ VertexDescriptionError::VertexInputHasOccupiedSemanticName {
+ name: name.to_owned(),
+ },
+ );
+ }
let scalar_type = match (
var_input.type_layout.kind(),
@@ -1002,14 +1024,16 @@ impl VertexDescription
_ => {
return Err(
VertexDescriptionError::UnsupportedVertexInputType {
- name,
+ name: name.to_owned(),
},
);
}
};
+ seen_inputs.insert(semantic_name.clone());
+
Ok(VertexInputDescription {
- name: name.into_boxed_str(),
+ semantic_name,
index: var_input.index,
type_kind: var_input.type_layout.kind(),
scalar_type,
@@ -1022,14 +1046,76 @@ impl VertexDescription
}
#[derive(Debug)]
+#[non_exhaustive]
pub struct VertexInputDescription
{
- pub name: Box<str>,
+ pub semantic_name: VertexInputSemName,
pub index: usize,
pub type_kind: TypeKind,
pub scalar_type: ScalarType,
}
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+#[non_exhaustive]
+pub enum VertexInputSemName
+{
+ Position,
+ Normal,
+ Uv,
+ Color,
+ Other(Box<str>),
+}
+
+impl VertexInputSemName
+{
+ fn from_semantic_name(semantic_name: &str) -> Self
+ {
+ match semantic_name {
+ STD_VERTEX_INPUT_SEMANTIC_NAME_POSITION => Self::Position,
+ STD_VERTEX_INPUT_SEMANTIC_NAME_NORMAL => Self::Normal,
+ STD_VERTEX_INPUT_SEMANTIC_NAME_UV => Self::Uv,
+ STD_VERTEX_INPUT_SEMANTIC_NAME_COLOR => Self::Color,
+ _ => Self::Other(semantic_name.to_lowercase().into_boxed_str()),
+ }
+ }
+
+ pub fn matches_vertex_label(&self, vertex_label: &VertexLabel) -> bool
+ {
+ match (self, vertex_label) {
+ (Self::Position, VertexLabel::Position)
+ | (Self::Normal, VertexLabel::Normal)
+ | (Self::Uv, VertexLabel::Uv)
+ | (Self::Color, VertexLabel::Color) => true,
+ (Self::Other(other), VertexLabel::Other(other_vertex_label)) => {
+ **other == *other_vertex_label
+ }
+ _ => false,
+ }
+ }
+}
+
+impl Display for VertexInputSemName
+{
+ fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result
+ {
+ match self {
+ Self::Position => {
+ formatter.write_str(STD_VERTEX_INPUT_SEMANTIC_NAME_POSITION)
+ }
+ Self::Normal => formatter.write_str(STD_VERTEX_INPUT_SEMANTIC_NAME_NORMAL),
+ Self::Uv => formatter.write_str(STD_VERTEX_INPUT_SEMANTIC_NAME_UV),
+ Self::Color => formatter.write_str(STD_VERTEX_INPUT_SEMANTIC_NAME_COLOR),
+ Self::Other(other) => {
+ for character in other.chars() {
+ formatter.write_char(character.to_ascii_uppercase())?;
+ }
+
+ Ok(())
+ }
+ }
+ }
+}
+
#[derive(Debug, thiserror::Error)]
pub enum VertexDescriptionError
{
@@ -1041,6 +1127,20 @@ pub enum VertexDescriptionError
{
name: String
},
+
+ #[error("Vertex input '{name}' is missing a semantic name")]
+ VertexInputMissingSemanticName
+ {
+ name: String
+ },
+
+ #[error(
+ "Vertex input '{name}' has a semantic name already used by another vertex input"
+ )]
+ VertexInputHasOccupiedSemanticName
+ {
+ name: String
+ },
}
#[derive(Debug, thiserror::Error)]