Skip to content

Commit

Permalink
fix: #62 and cleaned up bloat
Browse files Browse the repository at this point in the history
  • Loading branch information
ElhamAryanpur committed Jul 13, 2024
1 parent 790dcf8 commit 7421479
Show file tree
Hide file tree
Showing 8 changed files with 56 additions and 66 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "blue_engine"
version = "0.5.13"
version = "0.5.14"
authors = ["Elham Aryanpur <elhamaryanpur5@gmail.com>"]
edition = "2021"
description = "General-Purpose, Easy-to-use, Fast, and Portable graphics engine"
Expand Down
2 changes: 1 addition & 1 deletion examples/shapes/square.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ pub fn square(name: impl StringBuffer, engine: &mut Engine) -> eyre::Result<()>
],
vec![2, 1, 0, 2, 0, 3],
ObjectSettings {
camera_effect: false,
camera_effect: None,
..Default::default()
},
&mut engine.renderer,
Expand Down
4 changes: 2 additions & 2 deletions examples/utils/render_order.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ fn main() {
.expect("failed to gete object");
// set a color to differentiate it
layer1
.set_uniform_color(1f32, 0.5, 0f32, 1f32)
.set_color(1f32, 0.5, 0f32, 1f32)
.expect("failed to set color");
// move it to left a bit
layer1.set_position(-0.5, 0f32, 0f32);
Expand All @@ -50,7 +50,7 @@ fn main() {
.expect("failed to gete object");
// set a color to differentiate it
layer2
.set_uniform_color(0f32, 0f32, 1f32, 1f32)
.set_color(0f32, 0f32, 1f32, 1f32)
.expect("failed to set color");
// move it to right a bit
layer2.set_position(0.5, 0f32, 0f32);
Expand Down
26 changes: 15 additions & 11 deletions src/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ unsafe impl Sync for Vertex {}
/// customize almost everything there is about them!
pub struct Object {
/// Give your object a name, which can help later on for debugging.
pub name: String,
pub name: std::sync::Arc<str>,
/// A list of Vertex
pub vertices: Vec<Vertex>,
/// A list of indices that dictates the order that vertices appear
Expand All @@ -106,10 +106,8 @@ pub struct Object {
pub instances: Vec<Instance>,
/// instance buffer
pub instance_buffer: wgpu::Buffer,
/// Dictates the size of your object in pixels
/// Dictates the size of your object in relation to the world
pub size: glm::Vec3,
/// Dictates the scale of your object. Which by default it's 1,1,1 where the screen is size of 2
pub scale: glm::Vec3,
/// Dictates the position of your object in pixels
pub position: glm::Vec3,
/// Dictates the rotation of your object
Expand All @@ -128,16 +126,14 @@ pub struct Object {
/// Transformation matrix, but inversed
pub inverse_transformation_matrix: crate::uniform_type::Matrix,
/// The main color of your object
pub uniform_color: crate::uniform_type::Array4,
/// The color of your object that is sent to gpu
pub color: crate::uniform_type::Array4,
/// A struct making it easier to manipulate specific parts of shader
pub shader_builder: crate::objects::ShaderBuilder,
/// Shader settings
pub shader_settings: ShaderSettings,
/// Camera have any effect on the object?
pub camera_effect: bool,
/// Uniform Buffers to be sent to GPU
pub camera_effect: Option<std::sync::Arc<str>>,
/// Uniform Buffers to be sent to GPU. These are raw and not compiled for GPU yet
pub uniform_buffers: Vec<wgpu::Buffer>,
/// Should be rendered or not
pub is_visible: bool,
Expand All @@ -148,17 +144,17 @@ unsafe impl Send for Object {}
unsafe impl Sync for Object {}

/// Extra settings to customize objects on time of creation
#[derive(Debug, Clone, Copy)]
#[derive(Debug, Clone)]
pub struct ObjectSettings {
/// Should it be affected by camera?
pub camera_effect: bool,
pub camera_effect: Option<std::sync::Arc<str>>,
/// Shader Settings
pub shader_settings: ShaderSettings,
}
impl Default for ObjectSettings {
fn default() -> Self {
Self {
camera_effect: true,
camera_effect: Some("main".into()),
shader_settings: ShaderSettings::default(),
}
}
Expand Down Expand Up @@ -597,6 +593,8 @@ pub trait StringBufferTrait {
fn as_str(&self) -> &str;
/// Returns the string as [`String`]
fn as_string(&self) -> String;
/// Returns Arc<str> for ease of computation
fn as_arc(&self) -> std::sync::Arc<str>;
}

impl StringBufferTrait for String {
Expand All @@ -606,6 +604,9 @@ impl StringBufferTrait for String {
fn as_string(&self) -> String {
self.clone()
}
fn as_arc(&self) -> std::sync::Arc<str> {
self.as_str().into()
}
}
impl StringBuffer for String {}
impl StringBufferTrait for &str {
Expand All @@ -615,6 +616,9 @@ impl StringBufferTrait for &str {
fn as_string(&self) -> String {
self.to_string()
}
fn as_arc(&self) -> std::sync::Arc<str> {
self.as_str().into()
}
}
impl StringBuffer for &str {}

Expand Down
63 changes: 17 additions & 46 deletions src/objects.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ impl Renderer {
),
])?;

let shader_source = ShaderBuilder::new(DEFAULT_SHADER.to_string(), settings.camera_effect);
let shader_source =
ShaderBuilder::new(DEFAULT_SHADER.to_string(), settings.camera_effect.clone());

let shader = self.build_shader(
name.as_str(),
Expand All @@ -67,7 +68,7 @@ impl Renderer {
let instance_buffer = self.build_instance(vec![instance.to_raw()]);

Ok(Object {
name: name.as_string(),
name: name.as_arc(),
vertices,
indices,
pipeline: Pipeline {
Expand All @@ -79,8 +80,7 @@ impl Renderer {
instances: vec![instance],
instance_buffer,
uniform_layout: uniform.1,
size: glm::vec3(100f32, 100f32, 100f32),
scale: glm::vec3(1f32, 1f32, 1f32),
size: glm::vec3(1f32, 1f32, 1f32),
position: glm::vec3(0f32, 0f32, 0f32),
rotation: glm::vec3(0f32, 0f32, 0f32),
changed: false,
Expand All @@ -90,9 +90,6 @@ impl Renderer {
inverse_transformation_matrix: Matrix::from_im(nalgebra_glm::transpose(
&nalgebra_glm::inverse(&DEFAULT_MATRIX_4.to_im()),
)),
uniform_color: crate::uniform_type::Array4 {
data: crate::utils::default_resources::DEFAULT_COLOR,
},
color: crate::uniform_type::Array4 {
data: crate::utils::default_resources::DEFAULT_COLOR,
},
Expand Down Expand Up @@ -129,13 +126,6 @@ impl ObjectStorage {
renderer.build_object(name.clone(), vertices, indices, settings)?,
)?;

/*self.update_object(name, |object| {
object.scale(1f32, 1f32, 1f32);
object.position(
0f32, 0f32, 0f32
);
}); */

Ok(())
}

Expand Down Expand Up @@ -172,7 +162,7 @@ impl ObjectStorage {
impl Object {
/// Sets the name of the object
pub fn set_name(&mut self, name: impl StringBuffer) {
self.name = name.as_string();
self.name = name.as_arc();
}

/// Scales an object. e.g. 2.0 doubles the size and 0.5 halves
Expand Down Expand Up @@ -304,22 +294,6 @@ impl Object {
Ok(())
}

/// Changes the main color of the object hat is sent to GPU. If textures exist, the color of textures will change
pub fn set_uniform_color(
&mut self,
red: f32,
green: f32,
blue: f32,
alpha: f32,
) -> eyre::Result<()> {
self.uniform_color = Array4 {
data: [red, green, blue, alpha],
};
self.changed = true;

Ok(())
}

/// Changes the render order of the Object.
///
/// Objects with higher number get rendered later and appear "on top" when occupying the same space
Expand Down Expand Up @@ -402,7 +376,7 @@ impl Object {
/// Update and apply changes done to the shader
pub fn update_shader(&mut self, renderer: &mut Renderer) -> eyre::Result<()> {
let updated_shader = renderer.build_shader(
self.name.as_str(),
self.name.as_ref(),
self.shader_builder.shader.clone(),
Some(&self.uniform_layout),
self.shader_settings,
Expand All @@ -418,13 +392,13 @@ impl Object {
renderer: &mut Renderer,
) -> eyre::Result<crate::Shaders> {
let updated_shader = renderer.build_shader(
self.name.as_str(),
self.name.as_ref(),
self.shader_builder.shader.clone(),
Some(&self.uniform_layout),
self.shader_settings,
)?;
let updated_shader2 = renderer.build_shader(
self.name.as_str(),
self.name.as_ref(),
self.shader_builder.shader.clone(),
Some(&self.uniform_layout),
self.shader_settings,
Expand All @@ -442,7 +416,7 @@ impl Object {
self.position_matrix * self.rotation_matrix * self.scale_matrix,
),
);
self.uniform_buffers[1] = renderer.build_uniform_buffer_part("Color", self.uniform_color);
self.uniform_buffers[1] = renderer.build_uniform_buffer_part("Color", self.color);

let updated_buffer = renderer.build_uniform_buffer(&self.uniform_buffers)?;

Expand All @@ -463,7 +437,7 @@ impl Object {
self.position_matrix * self.rotation_matrix * self.scale_matrix,
),
);
self.uniform_buffers[1] = renderer.build_uniform_buffer_part("Color", self.uniform_color);
self.uniform_buffers[1] = renderer.build_uniform_buffer_part("Color", self.color);

let updated_buffer = renderer.build_uniform_buffer(&self.uniform_buffers)?;
let updated_buffer2 = renderer.build_uniform_buffer(&self.uniform_buffers)?;
Expand Down Expand Up @@ -533,33 +507,30 @@ impl Object {
}

/// Configuration type for ShaderBuilder
pub type ShaderConfigs = Vec<(String, Box<dyn Fn(bool) -> String>)>;
pub type ShaderConfigs = Vec<(String, Box<dyn Fn(Option<std::sync::Arc<str>>) -> String>)>;

/// Helps with building and updating shader code
pub struct ShaderBuilder {
/// the shader itself
pub shader: String,
/// Should the camera effect be applied
pub camera_effect: bool,
pub camera_effect: Option<std::sync::Arc<str>>,
/// configurations to be applied to the shader
///
/// the way it works is: `("key to look for", ("shader code with camera effects", "shader code without camera effects"))`
pub configs: ShaderConfigs,
}

impl ShaderBuilder {
/// Creates a new shader builder
pub fn new(shader_source: String, camera_effect: bool) -> Self {
pub fn new(shader_source: String, camera_effect: Option<std::sync::Arc<str>>) -> Self {
let mut shader_builder = Self {
shader: shader_source,
camera_effect,
configs: vec![
(
"//@CAMERA_STRUCT".to_string(),
Box::new(|camera_effect| {
if camera_effect {
r#"
struct CameraUniforms {
if camera_effect.is_some() {
r#"struct CameraUniforms {
camera_matrix: mat4x4<f32>,
};
@group(1) @binding(0)
Expand All @@ -573,7 +544,7 @@ impl ShaderBuilder {
(
"//@CAMERA_VERTEX".to_string(),
Box::new(|camera_effect| {
if camera_effect {
if camera_effect.is_some() {
r#"out.position = camera_uniform.camera_matrix * model_matrix * (transform_uniform.transform_matrix * vec4<f32>(input.position, 1.0));"#
.to_string()
} else {
Expand All @@ -591,7 +562,7 @@ impl ShaderBuilder {
/// Builds the shader with the configuration defined
pub fn build(&mut self) {
for i in &self.configs {
self.shader = self.shader.replace(&i.0, &i.1(self.camera_effect));
self.shader = self.shader.replace(&i.0, &i.1(self.camera_effect.clone()));
}
}
}
Expand Down
15 changes: 14 additions & 1 deletion src/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -293,13 +293,26 @@ impl Renderer {

render_pass.set_bind_group(0, &default_data.0, &[]);
render_pass.set_pipeline(&default_data.1);
render_pass.set_bind_group(1, &camera.get("main").unwrap().uniform_data, &[]);

// sort the object list in descending render order
let mut object_list: Vec<_> = objects.iter().collect();
object_list.sort_by(|(_, a), (_, b)| a.render_order.cmp(&b.render_order).reverse());

for (_, i) in object_list {
if let Some(camera_data) = i.camera_effect.as_ref() {
render_pass.set_bind_group(
1,
&camera.get(camera_data.as_ref()).unwrap().uniform_data,
&[],
);
} else {
render_pass.set_bind_group(
1,
&camera.get("main".into()).unwrap().uniform_data,
&[],
);
}

if i.is_visible {
let vertex_buffer = get_pipeline_vertex_buffer(&i.pipeline.vertex_buffer, objects);
let shader = get_pipeline_shader(&i.pipeline.shader, objects);
Expand Down
8 changes: 5 additions & 3 deletions src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,9 +234,11 @@ impl Engine {
);
});

camera
.update_view_projection(&mut renderer)
.expect("Couldn't update camera");
for camera_value in camera.values_mut() {
camera_value
.update_view_projection(&mut renderer)
.expect("Couldn't update camera");
}
objects.iter_mut().for_each(|i| {
if i.1.changed {
i.1.update(&mut renderer).expect("Couldn't update objects");
Expand Down

0 comments on commit 7421479

Please sign in to comment.