diff --git a/engine/auxiliary/lowlevel_rustabi/src/argus/lowlevel/c_interop.rs b/engine/auxiliary/lowlevel_rustabi/src/argus/lowlevel/c_interop.rs index c5fdd6fa..8e7ca03e 100644 --- a/engine/auxiliary/lowlevel_rustabi/src/argus/lowlevel/c_interop.rs +++ b/engine/auxiliary/lowlevel_rustabi/src/argus/lowlevel/c_interop.rs @@ -15,7 +15,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ - +use std::ffi; use std::ffi::CStr; use crate::lowlevel_cabi::*; @@ -24,18 +24,21 @@ use crate::lowlevel_cabi; pub use crate::lowlevel_cabi::StringArray; pub use crate::lowlevel_cabi::StringArrayConst; -pub fn string_array_to_vec(sa: StringArray) -> Vec { +pub trait FfiWrapper { + fn of(ptr: *mut ffi::c_void) -> Self; +} + +pub unsafe fn string_array_to_vec(sa: StringArray) -> Vec { unsafe { let count = string_array_get_count(sa); - let mut vec = Vec::::new(); - vec.reserve(count); + let mut vec = Vec::::with_capacity(count); for i in 0..count { let s = string_array_get_element(sa, i); vec[i] = CStr::from_ptr(s).to_str().unwrap().to_string(); } - return vec; + vec } } diff --git a/engine/auxiliary/lowlevel_rustabi/src/argus/lowlevel/math/vector.rs b/engine/auxiliary/lowlevel_rustabi/src/argus/lowlevel/math/vector.rs index 5b4c324e..3e30ed14 100644 --- a/engine/auxiliary/lowlevel_rustabi/src/argus/lowlevel/math/vector.rs +++ b/engine/auxiliary/lowlevel_rustabi/src/argus/lowlevel/math/vector.rs @@ -22,7 +22,7 @@ use crate::lowlevel_cabi::*; #[repr(C)] #[ffi_repr(argus_vector_2d_t)] -#[derive(Clone, Copy, Debug, Default)] +#[derive(Clone, Copy, Debug, Default, PartialEq, PartialOrd)] pub struct Vector2d { pub x: f64, pub y: f64, @@ -30,7 +30,7 @@ pub struct Vector2d { #[repr(C)] #[ffi_repr(argus_vector_3d_t)] -#[derive(Clone, Copy, Debug, Default)] +#[derive(Clone, Copy, Debug, Default, PartialEq, PartialOrd)] pub struct Vector3d { pub x: f64, pub y: f64, @@ -39,7 +39,7 @@ pub struct Vector3d { #[repr(C)] #[ffi_repr(argus_vector_4d_t)] -#[derive(Clone, Copy, Debug, Default)] +#[derive(Clone, Copy, Debug, Default, PartialEq, PartialOrd)] pub struct Vector4d { pub x: f64, pub y: f64, @@ -49,7 +49,7 @@ pub struct Vector4d { #[repr(C)] #[ffi_repr(argus_vector_2f_t)] -#[derive(Clone, Copy, Debug, Default)] +#[derive(Clone, Copy, Debug, Default, PartialEq, PartialOrd)] pub struct Vector2f { pub x: f32, pub y: f32, @@ -57,7 +57,7 @@ pub struct Vector2f { #[repr(C)] #[ffi_repr(argus_vector_3f_t)] -#[derive(Clone, Copy, Debug, Default)] +#[derive(Clone, Copy, Debug, Default, PartialEq, PartialOrd)] pub struct Vector3f { pub x: f32, pub y: f32, @@ -66,7 +66,7 @@ pub struct Vector3f { #[repr(C)] #[ffi_repr(argus_vector_4f_t)] -#[derive(Clone, Copy, Debug, Default)] +#[derive(Clone, Copy, Debug, Default, PartialEq, PartialOrd)] pub struct Vector4f { pub x: f32, pub y: f32, @@ -76,15 +76,15 @@ pub struct Vector4f { #[repr(C)] #[ffi_repr(argus_vector_2i_t)] -#[derive(Clone, Copy, Debug, Default)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)] pub struct Vector2i { - pub x: f32, - pub y: f32, + pub x: i32, + pub y: i32, } #[repr(C)] #[ffi_repr(argus_vector_3i_t)] -#[derive(Clone, Copy, Debug, Default)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)] pub struct Vector3i { pub x: i32, pub y: i32, @@ -93,7 +93,7 @@ pub struct Vector3i { #[repr(C)] #[ffi_repr(argus_vector_4i_t)] -#[derive(Clone, Copy, Debug, Default)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)] pub struct Vector4i { pub x: i32, pub y: i32, @@ -103,7 +103,7 @@ pub struct Vector4i { #[repr(C)] #[ffi_repr(argus_vector_2u_t)] -#[derive(Clone, Copy, Debug, Default)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)] pub struct Vector2u { pub x: u32, pub y: u32, @@ -111,7 +111,7 @@ pub struct Vector2u { #[repr(C)] #[ffi_repr(argus_vector_3u_t)] -#[derive(Clone, Copy, Debug, Default)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)] pub struct Vector3u { pub x: u32, pub y: u32, @@ -120,7 +120,7 @@ pub struct Vector3u { #[repr(C)] #[ffi_repr(argus_vector_4u_t)] -#[derive(Clone, Copy, Debug, Default)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)] pub struct Vector4u { pub x: u32, pub y: u32, diff --git a/engine/auxiliary/render_rustabi/src/argus/render/common/attached_viewport.rs b/engine/auxiliary/render_rustabi/src/argus/render/common/attached_viewport.rs index 497d5fb9..f4cfe818 100644 --- a/engine/auxiliary/render_rustabi/src/argus/render/common/attached_viewport.rs +++ b/engine/auxiliary/render_rustabi/src/argus/render/common/attached_viewport.rs @@ -17,47 +17,53 @@ */ use std::ffi::c_char; - +use std::ptr; use num_enum::UnsafeFromPrimitive; - +use lowlevel_rustabi::argus::lowlevel::Handle; use lowlevel_rustabi::util::{cstr_to_string, str_to_cstring}; use crate::argus::render::{AttachedViewport2d, SceneType, Viewport}; use crate::render_cabi::*; +#[derive(Clone)] pub struct AttachedViewport { - handle: argus_attached_viewport_t, + ffi_handle: argus_attached_viewport_t, } impl AttachedViewport { pub(crate) fn of(handle: argus_attached_viewport_t) -> Self { - Self { handle } + Self { ffi_handle: handle } } - + pub fn as_2d(&self) -> AttachedViewport2d { - AttachedViewport2d::of(self.handle) + AttachedViewport2d::of(self.ffi_handle) + } + + pub fn get_id(&self) -> u32 { + unsafe { argus_attached_viewport_get_id(self.ffi_handle) } } pub fn get_type(&self) -> SceneType { unsafe { - SceneType::unchecked_transmute_from(argus_attached_viewport_get_type(self.handle)) + SceneType::unchecked_transmute_from(argus_attached_viewport_get_type(self.ffi_handle)) } } pub fn get_viewport(&self) -> Viewport { - unsafe { argus_attached_viewport_get_viewport(self.handle).into() } + unsafe { argus_attached_viewport_get_viewport(self.ffi_handle).into() } } pub fn get_z_index(&self) -> u32 { - unsafe { argus_attached_viewport_get_z_index(self.handle) } + unsafe { argus_attached_viewport_get_z_index(self.ffi_handle) } } pub fn get_postprocessing_shaders(&self) -> Vec { unsafe { - let count = argus_attached_viewport_get_postprocessing_shaders_count(self.handle); - let mut shader_uids: Vec<*const c_char> = Vec::new(); + let count = argus_attached_viewport_get_postprocessing_shaders_count(self.ffi_handle); + let mut shader_uids: Vec<*const c_char> = Vec::with_capacity(count); + shader_uids.resize(count, ptr::null()); argus_attached_viewport_get_postprocessing_shaders( - self.handle, + self.ffi_handle, shader_uids.as_mut_ptr(), count, ); @@ -68,14 +74,14 @@ impl AttachedViewport { pub fn add_postprocessing_shader(&mut self, shader_uid: &str) { unsafe { let uid_c = str_to_cstring(shader_uid); - argus_attached_viewport_add_postprocessing_shader(self.handle, uid_c.as_ptr()) + argus_attached_viewport_add_postprocessing_shader(self.ffi_handle, uid_c.as_ptr()) } } pub fn remove_postprocessing_shader(&mut self, shader_uid: &str) { unsafe { let uid_c = str_to_cstring(shader_uid); - argus_attached_viewport_remove_postprocessing_shader(self.handle, uid_c.as_ptr()) + argus_attached_viewport_remove_postprocessing_shader(self.ffi_handle, uid_c.as_ptr()) } } } diff --git a/engine/auxiliary/render_rustabi/src/argus/render/common/canvas.rs b/engine/auxiliary/render_rustabi/src/argus/render/common/canvas.rs index 0cb94b5a..eb142762 100644 --- a/engine/auxiliary/render_rustabi/src/argus/render/common/canvas.rs +++ b/engine/auxiliary/render_rustabi/src/argus/render/common/canvas.rs @@ -15,7 +15,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ - +use std::ptr; use crate::argus::render::{AttachedViewport, AttachedViewport2d, Camera2d, Viewport}; use crate::render_cabi::*; use lowlevel_rustabi::util::str_to_cstring; @@ -27,6 +27,10 @@ pub struct Canvas { } impl Canvas { + pub fn of(handle: argus_canvas_t) -> Self { + Self { handle } + } + pub fn get_window(&self) -> Window { unsafe { Window::of(argus_canvas_get_window(self.handle)) } } @@ -36,6 +40,7 @@ impl Canvas { let count = argus_canvas_get_viewports_2d_count(self.handle); let mut viewport_handles: Vec = Vec::with_capacity(count); + viewport_handles.resize(count, ptr::null_mut()); argus_canvas_get_viewports_2d(self.handle, viewport_handles.as_mut_ptr(), count); viewport_handles diff --git a/engine/auxiliary/render_rustabi/src/argus/render/common/material.rs b/engine/auxiliary/render_rustabi/src/argus/render/common/material.rs index 716dbb24..1733620b 100644 --- a/engine/auxiliary/render_rustabi/src/argus/render/common/material.rs +++ b/engine/auxiliary/render_rustabi/src/argus/render/common/material.rs @@ -17,18 +17,21 @@ */ use lowlevel_rustabi::util::cstr_to_str; use std::ffi::c_char; - +use std::ptr; +use lowlevel_rustabi::argus::lowlevel::FfiWrapper; use crate::render_cabi::*; pub struct Material { handle: argus_material_t, } -impl Material { - pub fn of(handle: argus_material_t) -> Self { +impl FfiWrapper for Material { + fn of(handle: argus_material_t) -> Self { Self { handle } } +} +impl Material { pub fn get_texture_uid(&self) -> &str { unsafe { cstr_to_str(argus_material_get_texture_uid(self.handle)) } } @@ -37,7 +40,8 @@ impl Material { unsafe { let count = argus_material_get_shader_uids_count(self.handle); - let mut cstrs: Vec<*const c_char> = Vec::new(); + let mut cstrs: Vec<*const c_char> = Vec::with_capacity(count); + cstrs.resize(count, ptr::null()); argus_material_get_shader_uids(self.handle, cstrs.as_mut_ptr(), count); cstrs.into_iter().map(|s| cstr_to_str(s)).collect() diff --git a/engine/auxiliary/render_rustabi/src/argus/render/common/shader.rs b/engine/auxiliary/render_rustabi/src/argus/render/common/shader.rs index 2d7bd0e9..17c99146 100644 --- a/engine/auxiliary/render_rustabi/src/argus/render/common/shader.rs +++ b/engine/auxiliary/render_rustabi/src/argus/render/common/shader.rs @@ -21,6 +21,7 @@ use std::{ptr, slice}; use lowlevel_rustabi::util::{cstr_to_string, str_to_cstring}; use num_enum::{IntoPrimitive, UnsafeFromPrimitive}; +use lowlevel_rustabi::argus::lowlevel::FfiWrapper; pub struct Shader { handle: argus_shader_t, @@ -37,11 +38,13 @@ pub enum ShaderStage { Fragment = ARGUS_SHADER_STAGE_FRAGMENT, } -impl Shader { - pub(crate) fn of(handle: argus_shader_t) -> Self { +impl FfiWrapper for Shader { + fn of(handle: argus_shader_t) -> Self { Self { handle } } +} +impl Shader { pub(crate) fn get_handle(&self) -> argus_shader_const_t { self.handle } @@ -61,7 +64,7 @@ impl Shader { } pub fn copy(&self) -> Self { - unsafe { Self { handle: argus_shader_copy(self.handle) } } + unsafe { Self::of(argus_shader_copy(self.handle)) } } pub fn destroy(&mut self) { diff --git a/engine/auxiliary/render_rustabi/src/argus/render/common/shader_compilation.rs b/engine/auxiliary/render_rustabi/src/argus/render/common/shader_compilation.rs index f69b3465..9ceec2f8 100644 --- a/engine/auxiliary/render_rustabi/src/argus/render/common/shader_compilation.rs +++ b/engine/auxiliary/render_rustabi/src/argus/render/common/shader_compilation.rs @@ -17,7 +17,7 @@ */ use std::ptr; use std::ptr::null_mut; - +use lowlevel_rustabi::argus::lowlevel::FfiWrapper; use crate::argus::render::{Shader, ShaderReflectionInfo}; use crate::render_cabi::*; @@ -48,7 +48,7 @@ pub fn compile_glsl_to_spirv( ( compiled_shaders .into_iter() - .map(|handle| Shader::of(handle)) + .map(Shader::of) .collect(), ShaderReflectionInfo::of(refl_info), ) diff --git a/engine/auxiliary/render_rustabi/src/argus/render/common/texture_data.rs b/engine/auxiliary/render_rustabi/src/argus/render/common/texture_data.rs index ced73e08..0a525f2b 100644 --- a/engine/auxiliary/render_rustabi/src/argus/render/common/texture_data.rs +++ b/engine/auxiliary/render_rustabi/src/argus/render/common/texture_data.rs @@ -17,13 +17,19 @@ */ use std::slice; - +use lowlevel_rustabi::argus::lowlevel::FfiWrapper; use crate::render_cabi::*; pub struct TextureData { handle: argus_texture_data_t, } +impl FfiWrapper for TextureData { + fn of(handle: argus_texture_data_t) -> Self { + Self { handle } + } +} + impl TextureData { pub fn get_width(&self) -> u32 { unsafe { argus_texture_data_get_width(self.handle) } diff --git a/engine/auxiliary/render_rustabi/src/argus/render/common/transform.rs b/engine/auxiliary/render_rustabi/src/argus/render/common/transform.rs index 98dfbd4c..5e98db9d 100644 --- a/engine/auxiliary/render_rustabi/src/argus/render/common/transform.rs +++ b/engine/auxiliary/render_rustabi/src/argus/render/common/transform.rs @@ -17,7 +17,7 @@ */ use std::ptr; use argus_macros::ffi_repr; -use lowlevel_rustabi::argus::lowlevel::Vector2f; +use lowlevel_rustabi::argus::lowlevel::{Vector2f, Vector4f}; use crate::render_cabi::*; @@ -25,16 +25,16 @@ use crate::render_cabi::*; #[ffi_repr(ArgusTransform2d)] #[derive(Clone, Copy, Debug, Default)] pub struct Transform2d { - translation: Vector2f, - scale: Vector2f, - rotation: f32, + pub translation: Vector2f, + pub scale: Vector2f, + pub rotation: f32, } #[repr(C)] #[ffi_repr(argus_matrix_4x4_t)] #[derive(Clone, Copy, Debug, Default)] pub struct Matrix4x4 { - cells: [f32; 16], + pub cells: [f32; 16], } impl Transform2d { @@ -64,7 +64,57 @@ impl Transform2d { } impl Matrix4x4 { - pub fn at(&self, row: usize, col: usize) -> f32 { + pub fn from_row_major(vals: [f32; 16]) -> Self { + Self { cells: [ + vals[0], vals[4], vals[8], vals[12], + vals[1], vals[5], vals[9], vals[13], + vals[2], vals[6], vals[10], vals[14], + vals[3], vals[7], vals[11], vals[15], + ] } + } + + pub fn get(&self, row: usize, col: usize) -> f32 { self.cells[col * 4 + row] } + + pub fn get_mut(&mut self, row: usize, col: usize) -> &mut f32 { + &mut self.cells[col * 4 + row] + } + + pub fn multiply_matrix(&self, other: Self) -> Self { + let mut res: [f32; 16] = Default::default(); + + // naive implementation + for i in 0..4 { + for j in 0..4 { + res[j * 4 + i] = 0.0; + for k in 0..4 { + res[j * 4 + i] += self.get(i, k) * other.get(k, j); + } + } + } + + Self { cells: res } + } + + pub fn multiply_vector(&self, vector: Vector4f) -> Vector4f { + Vector4f { + x: self.get(0, 0) * vector.x + + self.get(0, 1) * vector.y + + self.get(0, 2) * vector.z + + self.get(0, 3) * vector.w, + y: self.get(1, 0) * vector.x + + self.get(1, 1) * vector.y + + self.get(1, 2) * vector.z + + self.get(1, 3) * vector.w, + z: self.get(2, 0) * vector.x + + self.get(2, 1) * vector.y + + self.get(2, 2) * vector.z + + self.get(2, 3) * vector.w, + w: self.get(3, 0) * vector.x + + self.get(3, 1) * vector.y + + self.get(3, 2) * vector.z + + self.get(3, 3) * vector.w + } + } } diff --git a/engine/auxiliary/render_rustabi/src/argus/render/twod/attached_viewport_2d.rs b/engine/auxiliary/render_rustabi/src/argus/render/twod/attached_viewport_2d.rs index 1228520e..34272faf 100644 --- a/engine/auxiliary/render_rustabi/src/argus/render/twod/attached_viewport_2d.rs +++ b/engine/auxiliary/render_rustabi/src/argus/render/twod/attached_viewport_2d.rs @@ -26,7 +26,11 @@ impl AttachedViewport2d { pub(crate) fn of(handle: argus_attached_viewport_2d_t) -> Self { Self { handle } } - + + pub fn as_generic(&self) -> AttachedViewport { + AttachedViewport::of(self.handle) + } + pub fn get_camera(&self) -> Camera2d { unsafe { Camera2d::of(argus_attached_viewport_2d_get_camera(self.handle)) } } diff --git a/engine/auxiliary/render_rustabi/src/argus/render/twod/render_object_2d.rs b/engine/auxiliary/render_rustabi/src/argus/render/twod/render_object_2d.rs index 8dd0a7be..6aa68051 100644 --- a/engine/auxiliary/render_rustabi/src/argus/render/twod/render_object_2d.rs +++ b/engine/auxiliary/render_rustabi/src/argus/render/twod/render_object_2d.rs @@ -16,12 +16,12 @@ * along with this program. If not, see . */ -use std::mem; +use std::{mem, slice}; use lowlevel_rustabi::argus::lowlevel::{Handle, ValueAndDirtyFlag, Vector2f, Vector2u}; use lowlevel_rustabi::util::cstr_to_str; -use crate::argus::render::{RenderGroup2d, Scene2d}; +use crate::argus::render::{RenderGroup2d, RenderPrimitive2d, Scene2d}; use crate::render_cabi::*; pub struct RenderObject2d { @@ -49,8 +49,19 @@ impl RenderObject2d { unsafe { cstr_to_str(argus_render_object_2d_get_material(self.handle)) } } - pub fn get_primitives_count(&self) -> usize { - unsafe { argus_render_object_2d_get_primitives_count(self.handle) } + pub fn get_primitives(&self) -> Vec { + unsafe { + let count = argus_render_object_2d_get_primitives_count(self.handle); + let mut buf: Vec = Vec::with_capacity(count); + buf.resize(count, mem::zeroed()); + argus_render_object_2d_get_primitives(self.handle, buf.as_mut_ptr(), count); + buf.into_iter() + .map(|prim| RenderPrimitive2d { + vertices: slice::from_raw_parts(prim.vertices.cast(), prim.vertex_count) + .to_vec(), + }) + .collect() + } } pub fn get_anchor_point(&self) -> Vector2f { diff --git a/engine/auxiliary/render_rustabi/src/argus/render/twod/render_prim_2d.rs b/engine/auxiliary/render_rustabi/src/argus/render/twod/render_prim_2d.rs index f1319701..f589e129 100644 --- a/engine/auxiliary/render_rustabi/src/argus/render/twod/render_prim_2d.rs +++ b/engine/auxiliary/render_rustabi/src/argus/render/twod/render_prim_2d.rs @@ -20,14 +20,14 @@ use crate::argus::render::Vertex2d; use crate::render_cabi::*; pub struct RenderPrimitive2d { - vertices: Vec, + pub vertices: Vec, } -impl Into for &RenderPrimitive2d { - fn into(self) -> ArgusRenderPrimitive2d { +impl From<&RenderPrimitive2d> for ArgusRenderPrimitive2d { + fn from(value: &RenderPrimitive2d) -> Self { ArgusRenderPrimitive2d { - vertices: self.vertices.as_ptr().cast(), - vertex_count: self.vertices.len(), + vertices: value.vertices.as_ptr().cast(), + vertex_count: value.vertices.len(), } } } diff --git a/engine/auxiliary/render_rustabi/src/argus/render/twod/scene_2d.rs b/engine/auxiliary/render_rustabi/src/argus/render/twod/scene_2d.rs index 8bd9de6b..40389965 100644 --- a/engine/auxiliary/render_rustabi/src/argus/render/twod/scene_2d.rs +++ b/engine/auxiliary/render_rustabi/src/argus/render/twod/scene_2d.rs @@ -15,12 +15,14 @@ * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ - +use std::ffi::CStr; +use std::ptr; use lowlevel_rustabi::argus::lowlevel::{Handle, ValueAndDirtyFlag, Vector2f, Vector3f}; use lowlevel_rustabi::util::str_to_cstring; use crate::argus::render::*; use crate::render_cabi::*; +#[derive(Clone)] pub struct Scene2d { handle: argus_scene_2d_t, } @@ -41,6 +43,10 @@ impl Scene2d { } } + pub fn get_id(&self) -> String { + unsafe { CStr::from_ptr(argus_scene_2d_get_id(self.handle)).to_string_lossy().to_string() } + } + pub fn is_lighting_enabled(&self) -> bool { unsafe { argus_scene_2d_is_lighting_enabled(self.handle) } } @@ -85,9 +91,10 @@ impl Scene2d { unsafe { let count = argus_scene_2d_get_lights_count(self.handle); let mut lights: Vec = Vec::with_capacity(count); + lights.resize(count, ptr::null_mut()); argus_scene_2d_get_lights(self.handle, lights.as_mut_ptr(), count); - lights.into_iter().map(|ptr| Light2d::of(ptr)).collect() + lights.into_iter().map(Light2d::of).collect() } } @@ -95,9 +102,10 @@ impl Scene2d { unsafe { let count = argus_scene_2d_get_lights_count_for_render(self.handle); let mut lights: Vec = Vec::with_capacity(count); + lights.resize(count, ptr::null_mut()); argus_scene_2d_get_lights_for_render(self.handle, lights.as_mut_ptr(), count); - lights.into_iter().map(|ptr| Light2d::of(ptr)).collect() + lights.into_iter().map(Light2d::of).collect() } } diff --git a/engine/auxiliary/render_rustabi/src/argus/render/util/object_processor.rs b/engine/auxiliary/render_rustabi/src/argus/render/util/object_processor.rs index 2bf403f4..c9bd6807 100644 --- a/engine/auxiliary/render_rustabi/src/argus/render/util/object_processor.rs +++ b/engine/auxiliary/render_rustabi/src/argus/render/util/object_processor.rs @@ -25,43 +25,53 @@ use crate::render_cabi::*; type ProcessedRenderObject2d = argus_processed_render_object_2d_t; -type ProcessRenderObject2dFn = fn(obj: RenderObject2d, transform: Matrix4x4) -> *mut u8; +type ProcessRenderObject2dFn = fn( + obj: &mut RenderObject2d, + transform: &Matrix4x4, + extra: *mut c_void +) -> argus_processed_render_object_2d_t; type UpdateRenderObject2dFn = fn( - obj: RenderObject2d, + obj: &mut RenderObject2d, proc_obj: ProcessedRenderObject2d, - transform: Matrix4x4, + transform: &Matrix4x4, is_transform_dirty: bool, + extra: *mut c_void, ); #[repr(C)] #[ffi_repr(ArgusProcessedObjectMap)] -struct FfiProcessedObjectMap { +#[derive(Clone)] +pub struct FfiProcessedObjectMap { count: usize, capacity: usize, keys: *const Handle, values: *const ProcessedRenderObject2d, } -pub struct ProcessedObjectMap { - ffi_map: FfiProcessedObjectMap, - rust_map: HashMap, +pub struct ProcessedObjectMap { + pub ffi_map: FfiProcessedObjectMap, + pub rust_map: HashMap, } -struct ObjProcFns { +struct ObjProcContext { process_new_fn: ProcessRenderObject2dFn, update_fn: UpdateRenderObject2dFn, + extra: *mut c_void, } unsafe extern "C" fn process_object_proxy( obj: argus_render_object_2d_const_t, transform: argus_matrix_4x4_t, - extra: *mut c_void + context_ptr: *mut c_void ) -> argus_processed_render_object_2d_t { - let fns: &ObjProcFns = *extra.cast(); - - (fns.process_new_fn)( - RenderObject2d::of(obj.cast_mut()), - transform.into() + let context: &ObjProcContext = &*context_ptr.cast(); + + let mut obj = RenderObject2d::of(obj.cast_mut()); + let mat = transform.into(); + (context.process_new_fn)( + &mut obj, + &mat, + context.extra, ).cast() } @@ -70,44 +80,55 @@ unsafe extern "C" fn update_object_proxy( proc_obj: argus_processed_render_object_2d_t, transform: argus_matrix_4x4_t, is_transform_dirty: bool, - extra: *mut c_void + context_ptr: *mut c_void, ) { - let fns: &ObjProcFns = *extra.cast(); - - (fns.update_fn)( - RenderObject2d::of(obj.cast_mut()), - proc_obj.into(), - transform.into(), - is_transform_dirty + let context: &ObjProcContext = &*context_ptr.cast(); + + let mut obj = RenderObject2d::of(obj.cast_mut()); + let tfm = transform.into(); + (context.update_fn)( + &mut obj, + proc_obj, + &tfm, + is_transform_dirty, + context.extra, ); } pub fn process_objects_2d( - scene: Scene2d, - obj_map: &mut ProcessedObjectMap, + scene: &Scene2d, + obj_map: &mut FfiProcessedObjectMap, process_new_fn: ProcessRenderObject2dFn, update_fn: UpdateRenderObject2dFn, + extra: *mut c_void, ) { unsafe { - let mut fns = ObjProcFns { + let mut context = ObjProcContext { process_new_fn, update_fn, + extra, }; argus_process_objects_2d( scene.get_ffi_handle(), - <&mut ArgusProcessedObjectMap>::from(&mut obj_map.ffi_map), + <&mut ArgusProcessedObjectMap>::from(obj_map), Some(process_object_proxy), Some(update_object_proxy), - ptr::addr_of_mut!(fns).cast(), + ptr::addr_of_mut!(context).cast(), ); - - obj_map.rebuild(); } } -impl ProcessedObjectMap { - fn rebuild(&mut self) { +impl<'a, T> ProcessedObjectMap { + pub fn get(&self, handle: &Handle) -> &'a T { + unsafe { &**self.rust_map.get(handle).unwrap() } + } + + pub fn get_mut(&mut self, handle: &Handle) -> &'a mut T { + unsafe { &mut **self.rust_map.get_mut(handle).unwrap() } + } + + pub fn rebuild(&mut self) { unsafe { self.rust_map.clear(); if self.ffi_map.count > self.rust_map.capacity() { @@ -118,12 +139,18 @@ impl ProcessedObjectMap { let k = self.ffi_map.keys.add(i); let v = self.ffi_map.values.add(i); - self.rust_map.insert(*k, *v); + self.rust_map.insert(*k, *v.cast()); } } } - pub fn new() -> Self { + pub fn free(&mut self) { + unsafe { argus_processed_object_map_free(ptr::addr_of_mut!(self.ffi_map).cast()); } + } +} + +impl Default for ProcessedObjectMap { + fn default() -> Self { ProcessedObjectMap { ffi_map: FfiProcessedObjectMap { count: 0, @@ -134,14 +161,16 @@ impl ProcessedObjectMap { rust_map: HashMap::new(), } } +} - pub fn free(&mut self) { - unsafe { argus_processed_object_map_free(ptr::addr_of_mut!(self.ffi_map).cast()); } +impl<'a, T> From<&'a ProcessedObjectMap> for &'a HashMap { + fn from(value: &'a ProcessedObjectMap) -> Self { + &value.rust_map } } -impl<'a> Into<&'a HashMap> for &'a ProcessedObjectMap { - fn into(self) -> &'a HashMap { - &self.rust_map +impl<'a, T> From<&'a mut ProcessedObjectMap> for &'a mut HashMap { + fn from(value: &'a mut ProcessedObjectMap) -> Self { + &mut value.rust_map } } diff --git a/engine/auxiliary/render_rustabi/src/render_cabi/bindings.rs b/engine/auxiliary/render_rustabi/src/render_cabi/bindings.rs index 034145b4..8376513b 100644 --- a/engine/auxiliary/render_rustabi/src/render_cabi/bindings.rs +++ b/engine/auxiliary/render_rustabi/src/render_cabi/bindings.rs @@ -101,7 +101,7 @@ pub type argus_scene_2d_t = *mut ::std::os::raw::c_void; pub type argus_scene_2d_const_t = *const ::std::os::raw::c_void; pub type argus_attached_viewport_2d_t = *mut ::std::os::raw::c_void; pub type argus_attached_viewport_2d_const_t = *const ::std::os::raw::c_void; -pub type argus_material_t = *const ::std::os::raw::c_void; +pub type argus_material_t = *mut ::std::os::raw::c_void; pub const k_shader_type_glsl: &[u8; 5] = b"glsl\0"; pub const k_shader_type_spirv: &[u8; 6] = b"spirv\0"; pub type argus_shader_t = *mut ::std::os::raw::c_void; @@ -468,7 +468,7 @@ pub struct glslang_spv_options_s { pub compile_only: bool, } pub type glslang_spv_options_t = glslang_spv_options_s; -pub type argus_texture_data_t = *const ::std::os::raw::c_void; +pub type argus_texture_data_t = *mut ::std::os::raw::c_void; #[repr(C)] pub struct ArgusVertex2d { pub position: argus_vector_2f_t, @@ -538,6 +538,7 @@ extern "C" { pub fn argus_attached_viewport_get_type( viewport: argus_attached_viewport_const_t, ) -> ArgusSceneType; + pub fn argus_attached_viewport_get_id(viewport: argus_attached_viewport_const_t) -> u32; pub fn argus_attached_viewport_get_viewport( viewport: argus_attached_viewport_const_t, ) -> ArgusViewport; @@ -874,6 +875,7 @@ extern "C" { ); pub fn argus_render_group_2d_copy(group: argus_render_group_2d_t) -> argus_render_group_2d_t; pub fn argus_scene_2d_create(id: *const ::std::os::raw::c_char) -> argus_scene_2d_t; + pub fn argus_scene_2d_get_id(scene: argus_scene_2d_const_t) -> *const ::std::os::raw::c_char; pub fn argus_scene_2d_is_lighting_enabled(scene: argus_scene_2d_const_t) -> bool; pub fn argus_scene_2d_set_lighting_enabled(scene: argus_scene_2d_t, enabled: bool); pub fn argus_scene_2d_peek_ambient_light_level(scene: argus_scene_2d_const_t) -> f32; @@ -970,6 +972,11 @@ extern "C" { pub fn argus_render_object_2d_get_primitives_count( obj: argus_render_object_2d_const_t, ) -> usize; + pub fn argus_render_object_2d_get_primitives( + obj: argus_render_object_2d_const_t, + buf: *mut ArgusRenderPrimitive2d, + count: usize, + ); pub fn argus_render_object_2d_get_anchor_point( obj: argus_render_object_2d_const_t, ) -> argus_vector_2f_t; diff --git a/engine/auxiliary/resman_rustabi/src/argus/resman/resource.rs b/engine/auxiliary/resman_rustabi/src/argus/resman/resource.rs index fcbe63c0..8bdc0045 100644 --- a/engine/auxiliary/resman_rustabi/src/argus/resman/resource.rs +++ b/engine/auxiliary/resman_rustabi/src/argus/resman/resource.rs @@ -15,13 +15,15 @@ * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ - +use std::ffi; +use std::fmt::Debug; use lowlevel_rustabi::util::*; use num_enum::{IntoPrimitive, TryFromPrimitive}; use std::path::PathBuf; - +use lowlevel_rustabi::argus::lowlevel::FfiWrapper; use crate::resman_cabi::*; +#[derive(Clone)] pub struct Resource { handle: argus_resource_const_t, } @@ -33,7 +35,7 @@ pub struct ResourcePrototype { } pub(crate) unsafe fn unwrap_resource_prototype( - proto: &argus_resource_prototype_t, + proto: argus_resource_prototype_t, ) -> ResourcePrototype { ResourcePrototype { uid: cstr_to_string(proto.uid), @@ -53,7 +55,7 @@ impl Resource { } pub fn get_prototype(&self) -> ResourcePrototype { - unsafe { unwrap_resource_prototype(&argus_resource_get_prototype(self.handle)) } + unsafe { unwrap_resource_prototype(argus_resource_get_prototype(self.handle)) } } pub fn release(&self) -> () { @@ -70,6 +72,11 @@ impl Resource { t_ptr.as_ref().unwrap() } } + + pub fn get_ffi(&self) -> T where T : FfiWrapper { + let p = unsafe { argus_resource_get_data_ptr(self.handle) }; + unsafe { T::of(p.cast_mut()) } + } } #[derive(Debug, Eq, Ord, PartialEq, PartialOrd, IntoPrimitive, TryFromPrimitive)] diff --git a/engine/auxiliary/resman_rustabi/src/argus/resman/resource_event.rs b/engine/auxiliary/resman_rustabi/src/argus/resman/resource_event.rs index eac4a98e..ab6712d4 100644 --- a/engine/auxiliary/resman_rustabi/src/argus/resman/resource_event.rs +++ b/engine/auxiliary/resman_rustabi/src/argus/resman/resource_event.rs @@ -46,7 +46,7 @@ impl ResourceEvent { } pub fn get_prototype(&self) -> ResourcePrototype { - unsafe { unwrap_resource_prototype(&argus_resource_event_get_prototype(self.handle)) } + unsafe { unwrap_resource_prototype(argus_resource_event_get_prototype(self.handle)) } } pub fn get_resource(&mut self) -> Resource { diff --git a/engine/auxiliary/resman_rustabi/src/argus/resman/resource_loader.rs b/engine/auxiliary/resman_rustabi/src/argus/resman/resource_loader.rs index 253bc99b..62ef7485 100644 --- a/engine/auxiliary/resman_rustabi/src/argus/resman/resource_loader.rs +++ b/engine/auxiliary/resman_rustabi/src/argus/resman/resource_loader.rs @@ -81,7 +81,7 @@ pub trait ResourceLoader { &mut self, handle: WrappedResourceLoader, manager: ResourceManager, - prototype: &ResourcePrototype, + prototype: ResourcePrototype, read_callback: Box usize>, size: usize, ) -> Result<*mut u8, ResourceError>; @@ -90,7 +90,7 @@ pub trait ResourceLoader { &mut self, handle: WrappedResourceLoader, manager: ResourceManager, - prototype: &ResourcePrototype, + prototype: ResourcePrototype, src_data: *mut u8, ) -> Result<*mut u8, ResourceError>; @@ -114,7 +114,7 @@ unsafe extern "C" fn load_resource_proxy( let res = real_loader.load_resource( WrappedResourceLoader::of(loader), ResourceManager::of(manager), - &unwrap_resource_prototype(&prototype), + unwrap_resource_prototype(prototype), Box::new(move |dst, len| read_callback_unwrapped(dst.as_mut_ptr().cast(), len, engine_data)), size, @@ -140,7 +140,7 @@ unsafe extern "C" fn copy_resource_proxy( let res = real_loader.copy_resource( WrappedResourceLoader::of(loader), ResourceManager::of(manager), - &unwrap_resource_prototype(&prototype), + unwrap_resource_prototype(prototype), src.cast(), ); // re-wrap the loader diff --git a/engine/auxiliary/wm_rustabi/src/argus/wm/window.rs b/engine/auxiliary/wm_rustabi/src/argus/wm/window.rs index 3ed13038..bb38a463 100644 --- a/engine/auxiliary/wm_rustabi/src/argus/wm/window.rs +++ b/engine/auxiliary/wm_rustabi/src/argus/wm/window.rs @@ -18,6 +18,7 @@ use std::ffi::c_void; use std::marker::PhantomData; +use std::mem; use std::ptr::null_mut; use std::time::Duration; @@ -181,7 +182,7 @@ impl Window { let mut res: ValueAndDirtyFlag = std::mem::zeroed(); argus_window_get_resolution( self.handle, - &mut res.value.into(), + mem::transmute(&mut res.value), &mut res.dirty, ); return res; diff --git a/engine/dynamic/render_opengl_rust/src/argus/render_opengl_rust/loader/shader_loader.rs b/engine/dynamic/render_opengl_rust/src/argus/render_opengl_rust/loader/shader_loader.rs index 6a5aeee4..90e7ab59 100644 --- a/engine/dynamic/render_opengl_rust/src/argus/render_opengl_rust/loader/shader_loader.rs +++ b/engine/dynamic/render_opengl_rust/src/argus/render_opengl_rust/loader/shader_loader.rs @@ -36,7 +36,7 @@ impl ResourceLoader for ShaderLoader { &mut self, handle: WrappedResourceLoader, manager: ResourceManager, - prototype: &ResourcePrototype, + prototype: ResourcePrototype, read_callback: Box usize>, size: usize ) -> Result<*mut u8, ResourceError> { @@ -67,7 +67,7 @@ impl ResourceLoader for ShaderLoader { &mut self, handle: WrappedResourceLoader, manager: ResourceManager, - prototype: &ResourcePrototype, + prototype: ResourcePrototype, src_data: *mut u8, ) -> Result<*mut u8, ResourceError> { println!("copy_resource called!"); diff --git a/engine/libs/lowlevel/src/uuid.cpp b/engine/libs/lowlevel/src/uuid.cpp index 9b1d0dc4..3f4d78c1 100644 --- a/engine/libs/lowlevel/src/uuid.cpp +++ b/engine/libs/lowlevel/src/uuid.cpp @@ -110,14 +110,14 @@ namespace argus { } std::string Uuid::to_string(void) const { - std::string rendered(37, '\0'); - snprintf(rendered.data(), rendered.size(), "%08x-%04x-%04x-%04x-%08x%04x", + char rendered[37]; + snprintf(rendered, sizeof(rendered), "%08x-%04x-%04x-%04x-%08x%04x", *reinterpret_cast(&data[0]), *reinterpret_cast(&data[4]), *reinterpret_cast(&data[6]), *reinterpret_cast(&data[8]), *reinterpret_cast(&data[10]), *reinterpret_cast(&data[14])); - return rendered; + return std::string(rendered); } } diff --git a/engine/libs/shadertools/src/shadertools.rs b/engine/libs/shadertools/src/shadertools.rs index 672b6794..25c2a2ee 100644 --- a/engine/libs/shadertools/src/shadertools.rs +++ b/engine/libs/shadertools/src/shadertools.rs @@ -131,12 +131,7 @@ pub fn compile_glsl_to_spirv( ) -> Result { let mut res = HashMap::>::with_capacity(glsl_sources.len()); - let processed_glsl = match process_glsl(glsl_sources) { - Ok(v) => v, - Err(e) => { - return Err(e); - } - }; + let processed_glsl = process_glsl(glsl_sources)?; for glsl in &processed_glsl { let mut program = Program::create(); @@ -145,7 +140,7 @@ pub fn compile_glsl_to_spirv( glslang::initialize_process(); - let input = &Input { + let input = Input { language: Source::Glsl, stage: glsl.stage, client, @@ -153,7 +148,7 @@ pub fn compile_glsl_to_spirv( target_language: TargetLanguage::Spv, target_language_version: spirv_version, /* Shader source code */ - code: CString::new(glsl.source.as_bytes()).unwrap(), + code: glsl.source.clone(), default_version: 0, default_profile: Profile::Core, force_default_version_and_profile: 0, @@ -170,21 +165,19 @@ pub fn compile_glsl_to_spirv( let mut shader = Shader::create(input); - if !shader.preprocess(input) { + if !shader.preprocess() { println!("{}", shader.get_info_log()); println!("{}", shader.get_info_debug_log()); return Err(GlslCompileError { - message: "Failed to preprocess shader for stage ".to_owned() - + &(glsl.stage as i32).to_string(), + message: format!("Failed to preprocess shader for stage {:?}", glsl.stage), }); } - if !shader.parse(input) { + if !shader.parse() { println!("{}", shader.get_info_log()); println!("{}", shader.get_info_debug_log()); return Err(GlslCompileError { - message: "Failed to parse shader for stage ".to_owned() - + &(glsl.stage as i32).to_string(), + message: format!("Failed to parse shader for stage {:?}", glsl.stage), }); } diff --git a/engine/static/render/include/argus/render/2d/scene_2d.hpp b/engine/static/render/include/argus/render/2d/scene_2d.hpp index 1ce9bd09..7727da2e 100644 --- a/engine/static/render/include/argus/render/2d/scene_2d.hpp +++ b/engine/static/render/include/argus/render/2d/scene_2d.hpp @@ -74,6 +74,8 @@ namespace argus { [[nodiscard]] pimpl_Scene *get_pimpl(void) const override; + [[nodiscard]] const std::string &get_id(void) const; + [[nodiscard]] bool is_lighting_enabled(void) const; void set_lighting_enabled(bool enabled); diff --git a/engine/static/render/include/argus/render/cabi/2d/render_object_2d.h b/engine/static/render/include/argus/render/cabi/2d/render_object_2d.h index e0122fe2..27dc30c2 100644 --- a/engine/static/render/include/argus/render/cabi/2d/render_object_2d.h +++ b/engine/static/render/include/argus/render/cabi/2d/render_object_2d.h @@ -44,7 +44,8 @@ const char *argus_render_object_2d_get_material(argus_render_object_2d_const_t o size_t argus_render_object_2d_get_primitives_count(argus_render_object_2d_const_t obj); -//TODO: get_primitives (it requires heap allocation and isn't used outside this module) +void argus_render_object_2d_get_primitives(argus_render_object_2d_const_t obj, + ArgusRenderPrimitive2d *buf, size_t count); argus_vector_2f_t argus_render_object_2d_get_anchor_point(argus_render_object_2d_const_t obj); diff --git a/engine/static/render/include/argus/render/cabi/2d/scene_2d.h b/engine/static/render/include/argus/render/cabi/2d/scene_2d.h index dac0c6a7..1712bde7 100644 --- a/engine/static/render/include/argus/render/cabi/2d/scene_2d.h +++ b/engine/static/render/include/argus/render/cabi/2d/scene_2d.h @@ -42,6 +42,8 @@ typedef const void *argus_scene_2d_const_t; argus_scene_2d_t argus_scene_2d_create(const char *id); +const char *argus_scene_2d_get_id(argus_scene_2d_const_t scene); + bool argus_scene_2d_is_lighting_enabled(argus_scene_2d_const_t scene); void argus_scene_2d_set_lighting_enabled(argus_scene_2d_t scene, bool enabled); @@ -64,7 +66,7 @@ void argus_scene_2d_get_lights(argus_scene_2d_t scene, argus_light_2d_t *dest, s size_t argus_scene_2d_get_lights_count_for_render(argus_scene_2d_t scene); -void argus_scene_2d_get_lights_for_render(argus_scene_2d_t scene, argus_light_2d_t *dest, size_t count); +void argus_scene_2d_get_lights_for_render(argus_scene_2d_t scene, argus_light_2d_const_t *dest, size_t count); ArgusHandle argus_scene_2d_add_light(argus_scene_2d_t scene, ArgusLight2dType type, bool is_occludable, argus_vector_3f_t color, ArgusLight2dParameters params, ArgusTransform2d initial_transform); diff --git a/engine/static/render/include/argus/render/cabi/common/attached_viewport.h b/engine/static/render/include/argus/render/cabi/common/attached_viewport.h index 56642648..2e259091 100644 --- a/engine/static/render/include/argus/render/cabi/common/attached_viewport.h +++ b/engine/static/render/include/argus/render/cabi/common/attached_viewport.h @@ -33,6 +33,8 @@ typedef const void *argus_attached_viewport_const_t; ArgusSceneType argus_attached_viewport_get_type(argus_attached_viewport_const_t viewport); +uint32_t argus_attached_viewport_get_id(argus_attached_viewport_const_t viewport); + ArgusViewport argus_attached_viewport_get_viewport(argus_attached_viewport_const_t viewport); uint32_t argus_attached_viewport_get_z_index(argus_attached_viewport_const_t viewport); diff --git a/engine/static/render/include/argus/render/cabi/common/material.h b/engine/static/render/include/argus/render/cabi/common/material.h index 3861463d..b5521940 100644 --- a/engine/static/render/include/argus/render/cabi/common/material.h +++ b/engine/static/render/include/argus/render/cabi/common/material.h @@ -24,7 +24,7 @@ extern "C" { #include -typedef const void *argus_material_t; +typedef void *argus_material_t; const char *argus_material_get_texture_uid(argus_material_t material); diff --git a/engine/static/render/include/argus/render/cabi/common/texture_data.h b/engine/static/render/include/argus/render/cabi/common/texture_data.h index 40d533c9..8e9bd696 100644 --- a/engine/static/render/include/argus/render/cabi/common/texture_data.h +++ b/engine/static/render/include/argus/render/cabi/common/texture_data.h @@ -24,7 +24,7 @@ extern "C" { #include -typedef const void *argus_texture_data_t; +typedef void *argus_texture_data_t; uint32_t argus_texture_data_get_width(argus_texture_data_t tex_data); diff --git a/engine/static/render/include/argus/render/common/attached_viewport.hpp b/engine/static/render/include/argus/render/common/attached_viewport.hpp index 3f6379e1..ce50cb58 100644 --- a/engine/static/render/include/argus/render/common/attached_viewport.hpp +++ b/engine/static/render/include/argus/render/common/attached_viewport.hpp @@ -22,6 +22,7 @@ #include "argus/render/common/scene.hpp" #include "argus/render/common/viewport.hpp" +#include "argus/lowlevel/handle.hpp" #include #include @@ -49,6 +50,8 @@ namespace argus { virtual ~AttachedViewport(void) = 0; + [[nodiscard]] uint32_t get_id(void) const; + [[nodiscard]] Viewport get_viewport(void) const; [[nodiscard]] uint32_t get_z_index(void) const; diff --git a/engine/static/render/include/internal/render/common/attached_viewport.hpp b/engine/static/render/include/internal/render/common/attached_viewport.hpp new file mode 100644 index 00000000..676189fa --- /dev/null +++ b/engine/static/render/include/internal/render/common/attached_viewport.hpp @@ -0,0 +1,25 @@ +/* + * This file is a part of Argus. + * Copyright (c) 2019-2024, Max Roncace + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include + +namespace argus { + extern uint32_t g_viewport_next_id; +} diff --git a/engine/static/render/include/internal/render/pimpl/2d/attached_viewport_2d.hpp b/engine/static/render/include/internal/render/pimpl/2d/attached_viewport_2d.hpp index 259cf0db..4ae4689e 100644 --- a/engine/static/render/include/internal/render/pimpl/2d/attached_viewport_2d.hpp +++ b/engine/static/render/include/internal/render/pimpl/2d/attached_viewport_2d.hpp @@ -35,8 +35,8 @@ namespace argus { struct pimpl_AttachedViewport2D : pimpl_AttachedViewport { Camera2D &camera; - pimpl_AttachedViewport2D(const Viewport &viewport, Camera2D &camera, uint32_t z_index): - pimpl_AttachedViewport(viewport, z_index), + pimpl_AttachedViewport2D(uint32_t id, const Viewport &viewport, Camera2D &camera, uint32_t z_index): + pimpl_AttachedViewport(id, viewport, z_index), camera(camera) { } }; diff --git a/engine/static/render/include/internal/render/pimpl/common/attached_viewport.hpp b/engine/static/render/include/internal/render/pimpl/common/attached_viewport.hpp index f809fe3f..4e630130 100644 --- a/engine/static/render/include/internal/render/pimpl/common/attached_viewport.hpp +++ b/engine/static/render/include/internal/render/pimpl/common/attached_viewport.hpp @@ -28,12 +28,14 @@ namespace argus { struct pimpl_AttachedViewport { protected: - pimpl_AttachedViewport(const Viewport &viewport, uint32_t z_index): + pimpl_AttachedViewport(uint32_t id, const Viewport &viewport, uint32_t z_index): + id(id), viewport(viewport), z_index(z_index) { } public: + const uint32_t id; const Viewport viewport; const uint32_t z_index; diff --git a/engine/static/render/res/render/shader/lighting_frag.frag b/engine/static/render/res/render/shader/lighting_frag.frag index c1e7fc9b..19d74e9c 100644 --- a/engine/static/render/res/render/shader/lighting_frag.frag +++ b/engine/static/render/res/render/shader/lighting_frag.frag @@ -43,7 +43,11 @@ void main() { vec3 light_sum = vec3(scene.AmbientLightColor.rgb * scene.AmbientLightLevel); - for (int i = 0; i < scene.LightCount; i++) { + for (int i = 0; i < LIGHTS_MAX; i++) { + if (i >= scene.LightCount) { + break; + } + Light2D light = scene.Lights[i]; vec2 light_pos = light.position.xy; diff --git a/engine/static/render/res/render/shader/shadowmap_frag.frag b/engine/static/render/res/render/shader/shadowmap_frag.frag index c5d852b2..b471718a 100644 --- a/engine/static/render/res/render/shader/shadowmap_frag.frag +++ b/engine/static/render/res/render/shader/shadowmap_frag.frag @@ -53,7 +53,11 @@ void main() { uint ray_count = 720; - for (uint i = 0; i < scene.LightCount; i++) { + for (int i = 0; i < LIGHTS_MAX; i++) { + if (i >= scene.LightCount) { + break; + } + Light2D light = scene.Lights[i]; vec2 light_pos = light.position.xy; diff --git a/engine/static/render/src/2d/attached_viewport_2d.cpp b/engine/static/render/src/2d/attached_viewport_2d.cpp index ada82681..7556c5d7 100644 --- a/engine/static/render/src/2d/attached_viewport_2d.cpp +++ b/engine/static/render/src/2d/attached_viewport_2d.cpp @@ -20,6 +20,7 @@ #include "argus/render/2d/attached_viewport_2d.hpp" #include "argus/render/common/attached_viewport.hpp" +#include "internal/render/common/attached_viewport.hpp" #include "internal/render/pimpl/2d/attached_viewport_2d.hpp" namespace argus { @@ -27,7 +28,7 @@ namespace argus { AttachedViewport2D::AttachedViewport2D(const Viewport &viewport, Camera2D &camera, uint32_t z_index): AttachedViewport(SceneType::TwoD), - m_pimpl(&g_pimpl_pool.construct(viewport, camera, z_index)) { + m_pimpl(&g_pimpl_pool.construct(g_viewport_next_id++, viewport, camera, z_index)) { } AttachedViewport2D::AttachedViewport2D(AttachedViewport2D &&rhs) noexcept: diff --git a/engine/static/render/src/2d/scene_2d.cpp b/engine/static/render/src/2d/scene_2d.cpp index 7a1e93dd..d7ac1601 100644 --- a/engine/static/render/src/2d/scene_2d.cpp +++ b/engine/static/render/src/2d/scene_2d.cpp @@ -82,6 +82,10 @@ namespace argus { return dynamic_cast(m_pimpl); } + const std::string &Scene2D::get_id(void) const { + return m_pimpl->id; + } + bool Scene2D::is_lighting_enabled(void) const { return m_pimpl->lighting_enabled; } diff --git a/engine/static/render/src/cabi/2d/render_object_2d.cpp b/engine/static/render/src/cabi/2d/render_object_2d.cpp index ac2678e2..45a0570e 100644 --- a/engine/static/render/src/cabi/2d/render_object_2d.cpp +++ b/engine/static/render/src/cabi/2d/render_object_2d.cpp @@ -18,18 +18,24 @@ #include "argus/render/cabi/2d/render_group_2d.h" #include "argus/render/cabi/2d/render_object_2d.h" +#include "argus/render/cabi/2d/render_prim_2d.h" #include "internal/render/cabi/common/transform.hpp" - #include "argus/lowlevel/cabi/handle.h" #include "argus/lowlevel/cabi/math/vector.h" #include "internal/lowlevel/cabi/handle.hpp" +#include "argus/core/engine.hpp" + #include "argus/render/2d/render_object_2d.hpp" #include "argus/render/2d/render_prim_2d.hpp" #include "argus/lowlevel/math/vector.hpp" +#include + +#include + static inline argus::RenderObject2D &_as_ref(argus_render_object_2d_t obj) { return *reinterpret_cast(obj); } @@ -60,6 +66,18 @@ size_t argus_render_object_2d_get_primitives_count(argus_render_object_2d_const_ return _as_ref(obj).get_primitives().size(); } +void argus_render_object_2d_get_primitives(argus_render_object_2d_const_t obj, + ArgusRenderPrimitive2d *buf, size_t count) { + auto &prims = _as_ref(obj).get_primitives(); + affirm_precond(count == prims.size(), "argus_render_object_2d_get_primitives called with wrong count parameter"); + std::transform(prims.begin(), prims.end(), buf, [](const auto &prim) { + return ArgusRenderPrimitive2d { + reinterpret_cast(prim.get_vertices().data()), + prim.get_vertex_count() + }; + }); +} + argus_vector_2f_t argus_render_object_2d_get_anchor_point(argus_render_object_2d_const_t obj) { return *reinterpret_cast(&_as_ref(obj).get_anchor_point()); } diff --git a/engine/static/render/src/cabi/2d/scene_2d.cpp b/engine/static/render/src/cabi/2d/scene_2d.cpp index b7b09a83..5a1641e8 100644 --- a/engine/static/render/src/cabi/2d/scene_2d.cpp +++ b/engine/static/render/src/cabi/2d/scene_2d.cpp @@ -55,6 +55,10 @@ argus_scene_2d_t argus_scene_2d_create(const char *id) { return &argus::Scene2D::create(id); } +const char *argus_scene_2d_get_id(argus_scene_2d_const_t scene) { + return _as_ref(scene).get_id().c_str(); +} + bool argus_scene_2d_is_lighting_enabled(argus_scene_2d_const_t scene) { return _as_ref(scene).is_lighting_enabled(); } @@ -105,8 +109,8 @@ size_t argus_scene_2d_get_lights_count_for_render(argus_scene_2d_t scene) { return _as_ref(scene).get_lights_for_render().size(); } -void argus_scene_2d_get_lights_for_render(argus_scene_2d_t scene, argus_light_2d_t *dest, size_t count) { - const auto lights = _as_ref(scene).get_lights(); +void argus_scene_2d_get_lights_for_render(argus_scene_2d_t scene, argus_light_2d_const_t *dest, size_t count) { + const auto lights = _as_ref(scene).get_lights_for_render(); affirm_precond(count == lights.size(), "argus_scene_2d_get_lights_for_render called with wrong count parameter"); std::transform(lights.begin(), lights.end(), dest, [](auto light_ref) { return &light_ref.get(); }); } diff --git a/engine/static/render/src/cabi/common/attached_viewport.cpp b/engine/static/render/src/cabi/common/attached_viewport.cpp index 94ec5dd3..5275fcf0 100644 --- a/engine/static/render/src/cabi/common/attached_viewport.cpp +++ b/engine/static/render/src/cabi/common/attached_viewport.cpp @@ -45,6 +45,10 @@ ArgusSceneType argus_attached_viewport_get_type(argus_attached_viewport_const_t return ArgusSceneType(_as_ref(viewport).m_type); } +uint32_t argus_attached_viewport_get_id(argus_attached_viewport_const_t viewport) { + return _as_ref(viewport).get_id(); +} + ArgusViewport argus_attached_viewport_get_viewport(argus_attached_viewport_const_t viewport) { const auto real_viewport = _as_ref(viewport).get_viewport(); return *reinterpret_cast(&real_viewport); diff --git a/engine/static/render/src/cabi/common/canvas.cpp b/engine/static/render/src/cabi/common/canvas.cpp index 3330326d..342d6c9b 100644 --- a/engine/static/render/src/cabi/common/canvas.cpp +++ b/engine/static/render/src/cabi/common/canvas.cpp @@ -48,7 +48,7 @@ void argus_canvas_get_viewports_2d(argus_canvas_const_t canvas, argus_attached_v affirm_precond(count == viewports.size(), "Call to argus_canvas_get_viewports_2d with wrong count parameter"); for (size_t i = 0; i < count; i++) { - dest[i] = &viewports.at(i); + dest[i] = &viewports.at(i).get(); } } diff --git a/engine/static/render/src/common/attached_viewport.cpp b/engine/static/render/src/common/attached_viewport.cpp index d5c754e0..0a3da95c 100644 --- a/engine/static/render/src/common/attached_viewport.cpp +++ b/engine/static/render/src/common/attached_viewport.cpp @@ -17,6 +17,7 @@ */ #include "argus/render/common/attached_viewport.hpp" +#include "internal/render/common/attached_viewport.hpp" #include "internal/render/pimpl/common/attached_viewport.hpp" #include @@ -24,12 +25,18 @@ #include namespace argus { + uint32_t g_viewport_next_id = 0; + AttachedViewport::AttachedViewport(SceneType type): m_type(type) { } AttachedViewport::~AttachedViewport(void) = default; + uint32_t AttachedViewport::get_id(void) const { + return get_pimpl()->id; + } + Viewport AttachedViewport::get_viewport(void) const { return get_pimpl()->viewport; } diff --git a/engine/static/resman/src/cabi/resource.cpp b/engine/static/resman/src/cabi/resource.cpp index 463ebd83..01cc23af 100644 --- a/engine/static/resman/src/cabi/resource.cpp +++ b/engine/static/resman/src/cabi/resource.cpp @@ -37,7 +37,7 @@ extern "C" { #endif argus_resource_prototype_t argus_resource_get_prototype(argus_resource_const_t resource) { - auto cpp_proto = _as_ref(resource).prototype; + const auto &cpp_proto = _as_ref(resource).prototype; argus_resource_prototype_t c_proto { cpp_proto.uid.c_str(), cpp_proto.media_type.c_str(), diff --git a/engine/static/resman/src/cabi/resource_manager.cpp b/engine/static/resman/src/cabi/resource_manager.cpp index 06fe6aa7..610c1631 100644 --- a/engine/static/resman/src/cabi/resource_manager.cpp +++ b/engine/static/resman/src/cabi/resource_manager.cpp @@ -35,8 +35,8 @@ static inline ResourceManager &_as_ref(argus_resource_manager_t ptr) { } static inline const ResourceOrResourceError _wrap_result(const Result &res) { - ResourceOrResourceError wrapped; - wrapped.is_ok = res.is_ok(); + ResourceOrResourceError wrapped; + wrapped.is_ok = res.is_ok(); if (res.is_ok()) { wrapped.ve.value = &res.unwrap(); } else { diff --git a/external-bindings/glslang/src/wrapper.rs b/external-bindings/glslang/src/wrapper.rs index 38840a03..4a85d4dd 100644 --- a/external-bindings/glslang/src/wrapper.rs +++ b/external-bindings/glslang/src/wrapper.rs @@ -18,9 +18,11 @@ #![allow(dead_code)] -use std::{ffi, mem}; +use std::{ffi, mem, ptr}; +use std::ffi::CString; use crate::bindings::*; +#[repr(C)] #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] pub enum Stage { Vertex = GLSLANG_STAGE_VERTEX as isize, @@ -39,6 +41,7 @@ pub enum Stage { Mesh = GLSLANG_STAGE_MESH as isize, } +#[repr(C)] #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] pub enum StageMask { Vertex = GLSLANG_STAGE_VERTEX_MASK as isize, @@ -57,6 +60,7 @@ pub enum StageMask { Mesh = GLSLANG_STAGE_MESH_MASK as isize, } +#[repr(C)] #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] pub enum Source { None = GLSLANG_SOURCE_NONE as isize, @@ -64,6 +68,7 @@ pub enum Source { Hlsl = GLSLANG_SOURCE_HLSL as isize, } +#[repr(C)] #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] pub enum Client { None = GLSLANG_CLIENT_NONE as isize, @@ -71,12 +76,14 @@ pub enum Client { OpenGL = GLSLANG_CLIENT_OPENGL as isize, } +#[repr(C)] #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] pub enum TargetLanguage { None = GLSLANG_TARGET_NONE as isize, Spv = GLSLANG_TARGET_SPV as isize, } +#[repr(C)] #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] pub enum TargetClientVersion { Vulkan1_0 = GLSLANG_TARGET_VULKAN_1_0 as isize, @@ -86,6 +93,7 @@ pub enum TargetClientVersion { OpenGL450 = GLSLANG_TARGET_OPENGL_450 as isize, } +#[repr(C)] #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] pub enum TargetLanguageVersion { Spv1_0 = GLSLANG_TARGET_SPV_1_0 as isize, @@ -97,12 +105,14 @@ pub enum TargetLanguageVersion { Spv1_6 = GLSLANG_TARGET_SPV_1_6 as isize, } +#[repr(C)] #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] pub enum Executable { VertexFragment = GLSLANG_EX_VERTEX_FRAGMENT as isize, Fragment = GLSLANG_EX_FRAGMENT as isize, } +#[repr(C)] #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] pub enum OptimizationLevel { NoGeneration = GLSLANG_OPT_NO_GENERATION as isize, @@ -111,12 +121,14 @@ pub enum OptimizationLevel { Full = GLSLANG_OPT_FULL as isize, } +#[repr(C)] #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] pub enum TextureSamplerTransformMode { Keep = GLSLANG_TEX_SAMP_TRANS_KEEP as isize, RemoveSampler = GLSLANG_TEX_SAMP_TRANS_UPGRADE_TEXTURE_REMOVE_SAMPLER as isize, } +#[repr(C)] #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] pub enum Messages { Default = GLSLANG_MSG_DEFAULT_BIT as isize, @@ -138,6 +150,7 @@ pub enum Messages { Enhanced = GLSLANG_MSG_ENHANCED as isize, } +#[repr(C)] #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] pub enum ReflectionOptions { Default = GLSLANG_REFLECTION_DEFAULT_BIT as isize, @@ -152,6 +165,7 @@ pub enum ReflectionOptions { SharedStd140Ubo = GLSLANG_REFLECTION_SHARED_STD140_UBO_BIT as isize, } +#[repr(C)] #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] pub enum Profile { Bad = GLSLANG_BAD_PROFILE as isize, @@ -161,6 +175,7 @@ pub enum Profile { Es = GLSLANG_ES_PROFILE as isize, } +#[repr(C)] #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] pub enum ShaderOptions { Default = GLSLANG_SHADER_DEFAULT_BIT as isize, @@ -169,6 +184,7 @@ pub enum ShaderOptions { VulkanRulesRelaxed = GLSLANG_SHADER_VULKAN_RULES_RELAXED as isize, } +#[repr(C)] #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] pub enum ResourceType { Sampler = GLSLANG_RESOURCE_TYPE_SAMPLER as isize, @@ -330,7 +346,7 @@ pub struct Input { pub client_version: TargetClientVersion, pub target_language: TargetLanguage, pub target_language_version: TargetLanguageVersion, - pub code: ffi::CString, + pub code: String, pub default_version: i32, pub default_profile: Profile, pub force_default_version_and_profile: i32, @@ -341,8 +357,8 @@ pub struct Input { pub callbacks_ctx: *mut ffi::c_void, } -impl Into for &Input { - fn into(self) -> glslang_input_t { +impl Input { + fn to_ffi_repr(&self, code_storage: &CString) -> glslang_input_t { glslang_input_t { language: self.language as glslang_target_language_t, stage: self.stage as glslang_stage_t, @@ -350,8 +366,8 @@ impl Into for &Input { client_version: self.client_version as glslang_target_client_version_t, target_language: self.target_language as glslang_target_language_t, target_language_version: - self.target_language_version as glslang_target_language_version_t, - code: self.code.as_ptr(), + self.target_language_version as glslang_target_language_version_t, + code: code_storage.as_ptr(), default_version: self.default_version as ffi::c_int, default_profile: self.default_profile as glslang_profile_t, force_default_version_and_profile: self.force_default_version_and_profile as ffi::c_int, @@ -376,14 +392,34 @@ pub fn finalize_process() { pub struct Shader { handle: *mut glslang_shader_t, + input: Box, + // glslang annoyingly stores a pointer to the C string (i.e. a char**), so + // we need the char pointer to live at a fixed (heap) address since keeping + // it on the stack would cause the glslang shader object to outlive the + // pointer when the wrapper Shader object gets moved to a different address. + // This also means that the CString needs to be on the heap so that the + // pointer doesn't end up pointing to invalid memory. + code: Box, + input_ffi: Box, + //input: Box, + //resource: Box, } impl Shader { - pub fn create(input: &Input) -> Shader { - unsafe { - Shader { - handle: glslang_shader_create(&input.into()), - } + pub fn create(input: Input) -> Shader { + let code_cstr = Box::new( + CString::new(input.code.as_bytes()).expect("Shader source string has bad encoding") + ); + let code_ptr = Box::new(code_cstr.as_ptr()); + + let input_ffi = Box::new(input.to_ffi_repr(&*code_cstr)); + let handle = unsafe { glslang_shader_create(&*input_ffi) }; + + Shader { + handle, + input: Box::new(input), + code: code_cstr, + input_ffi, } } @@ -408,12 +444,12 @@ impl Shader { unsafe { glslang_shader_set_glsl_version(self.handle, version); } } - pub fn preprocess(&mut self, input: &Input) -> bool { - unsafe { glslang_shader_preprocess(self.handle, &input.into()) != 0 } + pub fn preprocess(&mut self) -> bool { + unsafe { glslang_shader_preprocess(self.handle, &*self.input_ffi) != 0 } } - pub fn parse(&mut self, input: &Input) -> bool { - unsafe { glslang_shader_parse(self.handle, &input.into()) != 0 } + pub fn parse(&mut self) -> bool { + unsafe { glslang_shader_parse(self.handle, &*self.input_ffi) != 0 } } pub fn get_preprocessed_code<'a>(&mut self) -> &'a str { @@ -485,7 +521,7 @@ impl Program { self.handle, stage as glslang_stage_t, c_str.as_ptr(), - len + len, ); } }