diff options
| author | HampusM <hampus@hampusmat.com> | 2026-08-11 14:11:10 +0200 |
|---|---|---|
| committer | HampusM <hampus@hampusmat.com> | 2026-08-11 17:04:29 +0200 |
| commit | 99e69bc233caa9b73a5297286487476f44f539f9 (patch) | |
| tree | 955cd549adac7b8173c407354f7644c317e41e13 /engine/src/rendering/backend/opengl.rs | |
| parent | 8a62f8c8737d59df11a9627fc031248ddbf3fe6c (diff) | |
Diffstat (limited to 'engine/src/rendering/backend/opengl.rs')
| -rw-r--r-- | engine/src/rendering/backend/opengl.rs | 164 |
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) { |
