summaryrefslogtreecommitdiff
path: root/engine/src/rendering/backend/opengl.rs
diff options
context:
space:
mode:
Diffstat (limited to 'engine/src/rendering/backend/opengl.rs')
-rw-r--r--engine/src/rendering/backend/opengl.rs164
1 files changed, 104 insertions, 60 deletions
diff --git a/engine/src/rendering/backend/opengl.rs b/engine/src/rendering/backend/opengl.rs
index 12aaaf0..0dfe960 100644
--- a/engine/src/rendering/backend/opengl.rs
+++ b/engine/src/rendering/backend/opengl.rs
@@ -47,7 +47,6 @@ use opengl_bindings::shader::{
Kind as ShaderKind,
Program as GlShaderProgram,
Shader as GlShader,
- // UniformLocation as GlUniformLocation,
};
use opengl_bindings::texture::{
ColorSpace as GlTextureColorSpace,
@@ -101,9 +100,9 @@ use crate::rendering::shader::cursor::{
BindingValue as ShaderBindingValue,
};
use crate::rendering::shader::{
- Context as ShaderContext,
Error as ShaderError,
Program as ShaderProgram,
+ ProgramMetadata as ShaderProgramMetadata,
Stage as ShaderStage,
};
use crate::rendering::{
@@ -173,7 +172,12 @@ enum GraphicsContextObject
Mesh
{
mesh: GraphicsMesh,
- compatible_shader_program_obj_id: ObjectId,
+ vertex_attrs_updated_for_shader: Option<ObjectId>,
+ },
+ Shader
+ {
+ program: GlShaderProgram,
+ program_metadata: ShaderProgramMetadata,
},
}
@@ -443,7 +447,6 @@ fn handle_commands(
mut object_store: Single<ObjectStore>,
mut command_queue: Single<CommandQueue>,
assets: Single<Assets>,
- shader_context: Single<ShaderContext>,
) -> Result<(), crate::Error>
{
let Ok(graphics_ctx) = graphics_ctx.get_mut() else {
@@ -453,7 +456,6 @@ fn handle_commands(
let object_store = object_store.get_mut()?;
let command_queue = command_queue.get_mut()?;
let assets = assets.get()?;
- let shader_context = shader_context.get()?;
let GraphicsContext {
ref gl_context,
@@ -467,7 +469,11 @@ fn handle_commands(
return Ok(());
};
- let mut activated_gl_shader_program: Option<(ObjectId, GlShaderProgram)> = None;
+ let mut activated_gl_shader_program: Option<(
+ ObjectId,
+ GlShaderProgram,
+ ShaderProgramMetadata,
+ )> = None;
for command in command_queue.drain() {
let tracing_span = tracing::info_span!(
@@ -593,35 +599,80 @@ fn handle_commands(
}
};
+ let key = *next_graphics_ctx_object_key;
+
+ graphics_ctx_objects.insert(
+ key,
+ GraphicsContextObject::Shader {
+ program: gl_shader_program,
+ program_metadata: shader_program.metadata().clone(),
+ },
+ );
+
object_store.insert(
shader_program_obj_id,
- Object::from_raw(
- gl_shader_program.into_raw(),
- ObjectKind::ShaderProgram,
- ),
+ Object::from_raw(key, ObjectKind::ShaderProgram),
);
+
+ *next_graphics_ctx_object_key += 1;
}
Command::ActivateShader(shader_program_obj_id) => {
let Some(shader_program_obj) =
- object_store.get_shader_program_obj(&shader_program_obj_id)
+ object_store.get_obj(&shader_program_obj_id)
else {
- tracing::error!("Shader object does not exist or has a wrong kind");
+ tracing::error!(
+ object_id = ?shader_program_obj_id,
+ "Object does not exist"
+ );
+
continue;
};
- let gl_shader_program =
- GlShaderProgram::from_raw(shader_program_obj.as_raw());
+ if shader_program_obj.kind() != ObjectKind::ShaderProgram {
+ tracing::error!(
+ object_id = ?shader_program_obj_id,
+ actual_kind = ?shader_program_obj.kind(),
+ "Invalid object kind: not a shader program"
+ );
- gl_shader_program.activate(gl_context);
+ continue;
+ }
+
+ let key = shader_program_obj.as_raw();
- activated_gl_shader_program =
- Some((shader_program_obj_id, gl_shader_program));
+ let Some(graphics_ctx_obj) = graphics_ctx_objects.get(&key) else {
+ tracing::error!(
+ object_id = ?shader_program_obj_id,
+ key = key,
+ "Object not found in graphics context object store"
+ );
+ continue;
+ };
+
+ let GraphicsContextObject::Shader { program, program_metadata } =
+ graphics_ctx_obj
+ else {
+ tracing::error!(
+ object_id = ?shader_program_obj_id,
+ key = key,
+ "Graphics context object is not a shader"
+ );
+ continue;
+ };
+
+ program.activate(gl_context);
+
+ activated_gl_shader_program = Some((
+ shader_program_obj_id,
+ program.clone(),
+ program_metadata.clone(),
+ ));
}
Command::SetShaderBinding(ShaderBinding {
location: binding_location,
value: binding_value,
}) => {
- let Some((activated_gl_shader_program_obj_id, _)) =
+ let Some((activated_gl_shader_program_obj_id, _, _)) =
&activated_gl_shader_program
else {
tracing::error!("No shader program is activated");
@@ -786,24 +837,6 @@ fn handle_commands(
continue;
}
- let Some((ObjectId::Asset(curr_shader_program_asset_id), _)) =
- &activated_gl_shader_program
- else {
- tracing::error!("No shader program is activated");
- continue;
- };
-
- let curr_shader_program_metadata = shader_context
- .get_program_metadata(curr_shader_program_asset_id)
- .expect("Not possible");
-
- let Some(vertex_desc) = &curr_shader_program_metadata.vertex_desc else {
- tracing::error!(
- "Current shader program does not have a vertex description"
- );
- continue;
- };
-
let key = *next_graphics_ctx_object_key;
let mesh = match &mesh {
@@ -821,12 +854,8 @@ fn handle_commands(
AssetOrValue::Value(mesh) => mesh,
};
- let graphics_mesh = match GraphicsMesh::new(
- gl_context,
- &mesh,
- mesh_usage,
- &vertex_desc,
- ) {
+ let graphics_mesh = match GraphicsMesh::new(gl_context, &mesh, mesh_usage)
+ {
Ok(graphics_mesh) => graphics_mesh,
Err(err) => {
tracing::error!("Failed to create mesh: {err}");
@@ -838,9 +867,7 @@ fn handle_commands(
key,
GraphicsContextObject::Mesh {
mesh: graphics_mesh,
- compatible_shader_program_obj_id: ObjectId::Asset(
- *curr_shader_program_asset_id,
- ),
+ vertex_attrs_updated_for_shader: None,
},
);
@@ -881,7 +908,7 @@ fn handle_commands(
#[allow(irrefutable_let_patterns)]
let GraphicsContextObject::Mesh {
mesh: graphics_mesh,
- compatible_shader_program_obj_id: _,
+ vertex_attrs_updated_for_shader: _,
} = mesh_graphics_ctx_obj
else {
tracing::error!(
@@ -947,7 +974,7 @@ fn handle_commands(
};
let Some(mesh_graphics_ctx_obj) =
- graphics_ctx_objects.get(&mesh_graphics_ctx_obj_key)
+ graphics_ctx_objects.get_mut(&mesh_graphics_ctx_obj_key)
else {
tracing::error!(
object_id=?mesh_object_id,
@@ -957,10 +984,9 @@ fn handle_commands(
continue;
};
- #[allow(irrefutable_let_patterns)]
let GraphicsContextObject::Mesh {
mesh: graphics_mesh,
- compatible_shader_program_obj_id,
+ vertex_attrs_updated_for_shader,
} = mesh_graphics_ctx_obj
else {
tracing::error!(
@@ -971,18 +997,36 @@ fn handle_commands(
continue;
};
- if Some(compatible_shader_program_obj_id)
- != activated_gl_shader_program.as_ref().map(
- |(activated_gl_shader_program_obj_id, _)| {
- activated_gl_shader_program_obj_id
- },
- )
- {
- tracing::error!(concat!(
- "Activated shader program is not the ",
- "compatible shader program of the mesh"
- ));
+ let Some((shader_program_obj_id, _, shader_program_metadata)) =
+ &activated_gl_shader_program
+ else {
+ tracing::error!("No shader program is activated");
continue;
+ };
+
+ if vertex_attrs_updated_for_shader.is_none_or(
+ |vertex_attrs_updated_for_shader| {
+ vertex_attrs_updated_for_shader != *shader_program_obj_id
+ },
+ ) {
+ let Some(shader_program_vertex_desc) =
+ &shader_program_metadata.vertex_desc
+ else {
+ tracing::error!(
+ "Activated shader program does not have a vertex description"
+ );
+ continue;
+ };
+
+ if let Err(err) = graphics_mesh.update_vertex_attrs_for_shader(
+ gl_context,
+ shader_program_vertex_desc,
+ ) {
+ tracing::error!("Cannot draw mesh: {err}");
+ continue;
+ }
+
+ *vertex_attrs_updated_for_shader = Some(*shader_program_obj_id);
}
if let Err(err) = draw_mesh(gl_context, graphics_mesh, &draw_mesh_opts) {