summaryrefslogtreecommitdiff
path: root/engine/src/rendering
diff options
context:
space:
mode:
Diffstat (limited to 'engine/src/rendering')
-rw-r--r--engine/src/rendering/backend/opengl/graphics_mesh.rs29
-rw-r--r--engine/src/rendering/shader.rs120
2 files changed, 129 insertions, 20 deletions
diff --git a/engine/src/rendering/backend/opengl/graphics_mesh.rs b/engine/src/rendering/backend/opengl/graphics_mesh.rs
index fba60c8..f6b7d56 100644
--- a/engine/src/rendering/backend/opengl/graphics_mesh.rs
+++ b/engine/src/rendering/backend/opengl/graphics_mesh.rs
@@ -12,8 +12,12 @@ use opengl_bindings::MaybeCurrentContextWithFns as GlCurrentContextWithFns;
use crate::mesh::vertex_buffer::VertexAttrProperties as MeshVertexAttrProperties;
use crate::mesh::{Mesh, VertexAttrType};
-use crate::rendering::shader::VertexDescription as ShaderVertexDescription;
+use crate::rendering::shader::{
+ VertexDescription as ShaderVertexDescription,
+ VertexInputSemName,
+};
use crate::rendering::MeshUsage;
+use crate::util::DisplaySlice;
const VERTEX_BUF_BINDING_INDEX: u32 = 0;
@@ -171,7 +175,9 @@ impl GraphicsMesh
for vertex_attr_props in &self.vertex_attr_props {
let Some(vertex_input_desc) =
shader_vertex_desc.inputs.iter().find(|vertex_input_desc| {
- *vertex_input_desc.name == vertex_attr_props.name
+ vertex_input_desc
+ .semantic_name
+ .matches_vertex_label(&vertex_attr_props.label)
})
else {
continue;
@@ -221,15 +227,15 @@ impl GraphicsMesh
.inputs
.iter()
.filter_map(|vertex_input_desc| {
- if self
- .vertex_attr_props
- .iter()
- .any(|prop| prop.name == *vertex_input_desc.name)
- {
+ if self.vertex_attr_props.iter().any(|props| {
+ vertex_input_desc
+ .semantic_name
+ .matches_vertex_label(&props.label)
+ }) {
return None;
}
- Some(vertex_input_desc.name.clone())
+ Some(vertex_input_desc.semantic_name.clone())
})
.collect(),
));
@@ -262,8 +268,11 @@ pub enum Error
#[derive(Debug, thiserror::Error)]
pub enum VertexAttrsUpdatingError
{
- #[error("Mesh is missing vertex attribute(s) required by shader: {0:?}")]
- MissingVertexAttrs(Vec<Box<str>>),
+ #[error(
+ "Mesh is missing equivalent vertex attribute(s) for shader's vertex inputs: {}",
+ DisplaySlice::new(.0)
+ )]
+ MissingVertexAttrs(Vec<VertexInputSemName>),
}
fn mesh_usage_to_gl_buffer_usage(mesh_usage: MeshUsage) -> GlBufferUsage
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)]