Skip to content

Commit

Permalink
Updated rendering structure.
Browse files Browse the repository at this point in the history
  • Loading branch information
facundo-villa committed Dec 10, 2023
1 parent 6d6a74a commit 182518a
Show file tree
Hide file tree
Showing 24 changed files with 2,010 additions and 1,263 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "Docs DevContainer",
"name": "📖 Docs",
"image": "mcr.microsoft.com/devcontainers/javascript-node:1-20-bullseye",
"postCreateCommand": "npm install retypeapp --global"
}
13 changes: 13 additions & 0 deletions .devcontainer/rust/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "🦀 Rust",
"image": "mcr.microsoft.com/devcontainers/rust:1-1-bullseye",
"onCreateCommand": "apt update && apt install -y cmake && git clone https://github.com/rui314/mold.git && mkdir mold/build && cd mold/build && git checkout v2.4.0 && ../install-build-deps.sh && cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER=c++ .. && cmake --build . -j $(nproc) && sudo cmake --build . --target install"
// Use 'mounts' to make the cargo cache persistent in a Docker Volume.
// "mounts": [
// {
// "source": "devcontainer-cargo-cache-${devcontainerId}",
// "target": "/usr/local/cargo",
// "type": "volume"
// }
// ]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
icon: sun
8 changes: 4 additions & 4 deletions src/application.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ pub struct GraphicsApplication {
window_system_handle: orchestrator::EntityHandle<window_system::WindowSystem>,
mouse_device_handle: input_manager::DeviceHandle,
input_system_handle: orchestrator::EntityHandle<input_manager::InputManager>,
visibility_render_domain_handle: orchestrator::EntityHandle<rendering::visibility_model::render_domain::VisibilityWorldRenderDomain>,
renderer_handle: orchestrator::EntityHandle<rendering::renderer::Renderer>,
render_system_handle: orchestrator::EntityHandle<render_system::RenderSystemImplementation>,
}

Expand Down Expand Up @@ -165,13 +165,13 @@ impl Application for GraphicsApplication {

let render_system_handle = rendering::create_render_system(&orchestrator);

let visibility_render_domain_handle = orchestrator.spawn_entity(rendering::visibility_model::render_domain::VisibilityWorldRenderDomain::new()).unwrap();
let renderer_handle = orchestrator.spawn_entity(rendering::renderer::Renderer::new_as_system()).unwrap();

orchestrator.spawn_entity(rendering::render_orchestrator::RenderOrchestrator::new());

let _: orchestrator::EntityHandle<window_system::Window> = orchestrator.spawn(window_system::Window{ name: "Main Window".to_string(), extent: crate::Extent { width: 1920, height: 1080, depth: 1 }, id_name: "main_window".to_string() });

GraphicsApplication { application, file_tracker_handle, window_system_handle, input_system_handle, mouse_device_handle, visibility_render_domain_handle, tick_count: 0, render_system_handle }
GraphicsApplication { application, file_tracker_handle, window_system_handle, input_system_handle, mouse_device_handle, renderer_handle, tick_count: 0, render_system_handle }
}

fn initialize(&mut self, _arguments: std::env::Args) {
Expand Down Expand Up @@ -224,7 +224,7 @@ impl Application for GraphicsApplication {
// visibility_render_domain.render(self.get_orchestrator(), render_system, self.tick_count as u32);
// });

self.application.get_orchestrator().invoke_mut(self.visibility_render_domain_handle.copy(), rendering::visibility_model::render_domain::VisibilityWorldRenderDomain::render);
self.application.get_orchestrator().invoke_mut(self.renderer_handle.copy(), rendering::renderer::Renderer::render);

if !window_res {
self.application.close();
Expand Down
2 changes: 1 addition & 1 deletion src/file_tracker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub struct FileTracker {
}

impl FileTracker {
pub fn new() -> orchestrator::EntityReturn<FileTracker> {
pub fn new() -> orchestrator::EntityReturn<'static, FileTracker> {
std::fs::create_dir_all(".byte-editor").unwrap();

let db = polodb_core::Database::open_file(".byte-editor/files.db").unwrap();
Expand Down
2 changes: 1 addition & 1 deletion src/input_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ impl InputManager {
}
}

pub fn new_as_system() -> orchestrator::EntityReturn<InputManager> {
pub fn new_as_system() -> orchestrator::EntityReturn<'static, InputManager> {
orchestrator::EntityReturn::new(Self::new())
.add_listener::<Action<bool>>()
.add_listener::<Action<Vector2>>()
Expand Down
37 changes: 37 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,38 @@ impl Extent {
depth,
}
}

pub fn line(width: u32) -> Self {
Self {
width,
height: 1,
depth: 1,
}
}

pub fn square(size: u32) -> Self {
Self {
width: size,
height: size,
depth: 1,
}
}

pub fn plane(width: u32, height: u32) -> Self {
Self {
width,
height,
depth: 1,
}
}

pub fn volume(width: u32, height: u32, depth: u32) -> Self {
Self {
width,
height,
depth,
}
}
}

#[derive(Debug, Clone, Copy, PartialEq)]
Expand All @@ -57,6 +89,11 @@ pub struct RGBA {
pub a: f32,
}

impl RGBA {
pub fn black() -> Self { Self { r: 0.0, g: 0.0, b: 0.0, a: 1.0, } }
pub fn white() -> Self { Self { r: 1.0, g: 1.0, b: 1.0, a: 1.0, } }
}

fn insert_return_length<T>(collection: &mut Vec<T>, value: T) -> usize {
let length = collection.len();
collection.push(value);
Expand Down
27 changes: 18 additions & 9 deletions src/orchestrator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,14 +113,14 @@ pub enum PPP<T> {
}

/// Entity creation functions must return this type.
pub struct EntityReturn<T> {
pub struct EntityReturn<'c, T> {
// entity: T,
create: std::boxed::Box<dyn FnOnce(OrchestratorReference) -> T>,
create: std::boxed::Box<dyn FnOnce(OrchestratorReference) -> T + 'c>,
post_creation_functions: Vec<std::boxed::Box<dyn Fn(&mut T, OrchestratorReference)>>,
listens_to: Vec<(&'static str, Box<dyn Fn(&Orchestrator, u32, (u32, u32))>)>,
}

impl <T: 'static> EntityReturn<T> {
impl <'c, T: 'static> EntityReturn<'c, T> {
// pub fn new(entity: T) -> Self {
// Self {
// entity,
Expand All @@ -137,7 +137,7 @@ impl <T: 'static> EntityReturn<T> {
}
}

pub fn new_from_function(function: fn(OrchestratorReference) -> T) -> Self {
pub fn new_from_function(function: impl FnOnce(OrchestratorReference) -> T + 'c) -> Self {
Self {
create: std::boxed::Box::new(function),
post_creation_functions: Vec::new(),
Expand Down Expand Up @@ -216,7 +216,7 @@ impl Orchestrator {
}

/// Spawn entity is a function that spawns an entity and returns a handle to it.
pub fn spawn_entity<T, P, F>(&self, function: F) -> Option<EntityHandle<T>> where T: Entity + Send + 'static, F: IntoHandler<P, T> {
pub fn spawn_entity<'c, T, P, F: 'c>(&self, function: F) -> Option<EntityHandle<T>> where T: Entity + Send + 'static, F: IntoHandler<P, T> {
let handle = function.call(self)?;

trace!("{}", std::any::type_name::<T>());
Expand Down Expand Up @@ -427,6 +427,11 @@ impl Orchestrator {
let systems_data = self.systems_data.read().unwrap();
EntityReference { lock: systems_data.systems[&systems_data.systems_by_name[std::any::type_name::<S>()]].clone(), phantom: std::marker::PhantomData }
}

pub fn get_entity<S: System + 'static>(&self, entity_handle: &EntityHandle<S>) -> EntityReference<S> {
let systems_data = self.systems_data.read().unwrap();
EntityReference { lock: systems_data.systems[&entity_handle.internal_id].clone(), phantom: std::marker::PhantomData }
}
}

pub struct EntityReference<T> where T: ?Sized {
Expand Down Expand Up @@ -559,7 +564,7 @@ mod tests {
impl super::System for System {}

impl System {
fn new() -> EntityReturn<System> {
fn new<'c>() -> EntityReturn<'c, System> {
EntityReturn::new(System {}).add_listener::<Component>()
}
}
Expand Down Expand Up @@ -782,8 +787,8 @@ impl <'a> OrchestratorReference<'a> {
self.orchestrator.tie(&EntityHandle::<T>{ internal_id: self.internal_id, external_id: 0, phantom: std::marker::PhantomData }, consuming_property, sender_component_handle, j);
}

pub fn spawn_entity<T, P, F>(&self, function: F) -> Option<EntityHandle<T>> where T: Entity + Send + 'static, F: IntoHandler<P, T> {
self.orchestrator.spawn_entity::<T, P, F>(function)
pub fn spawn_entity<'c, T, P, F: 'c>(&self, function: F) -> Option<EntityHandle<T>> where T: Entity + Send + 'static, F: IntoHandler<P, T> {
self.orchestrator.spawn_entity::<'c, T, P, F>(function)
}

pub fn spawn<C: Component>(&self, component: C) -> EntityHandle<C> {
Expand All @@ -798,6 +803,10 @@ impl <'a> OrchestratorReference<'a> {
self.orchestrator.set_owned_property::<E, T, S>(self.internal_id, internal_id, property, value);
}

pub fn get_entity<S: System + 'static>(&self, entity_handle: &EntityHandle<S>) -> EntityReference<S> {
self.orchestrator.get_entity::<S>(entity_handle)
}

pub fn get_by_class<S: System + 'static>(&self) -> EntityReference<S> {
self.orchestrator.get_by_class::<S>()
}
Expand All @@ -814,7 +823,7 @@ pub trait IntoHandler<P, R> {
fn call(self, orchestrator: &Orchestrator,) -> Option<EntityHandle<R>>;
}

impl <R: Entity + Send + 'static> IntoHandler<(), R> for EntityReturn<R> {
impl <R: Entity + Send + 'static> IntoHandler<(), R> for EntityReturn<'_, R> {
fn call(self, orchestrator: &Orchestrator,) -> Option<EntityHandle<R>> {
let internal_id = {
let mut systems_data = orchestrator.systems_data.write().unwrap();
Expand Down
145 changes: 145 additions & 0 deletions src/rendering/aces_tonemap_render_pass.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
use crate::{Extent, orchestrator::{self, Entity, System}};

use super::{render_system, tonemap_render_pass};

pub struct AcesToneMapPass {
pipeline_layout: render_system::PipelineLayoutHandle,
pipeline: render_system::PipelineHandle,
descriptor_set_layout: render_system::DescriptorSetTemplateHandle,
descriptor_set: render_system::DescriptorSetHandle,

source_image_handle: render_system::ImageHandle,
result_image_handle: render_system::ImageHandle,
}

impl AcesToneMapPass {
fn new(render_system: &mut dyn render_system::RenderSystem, source_image: render_system::ImageHandle, result_image: render_system::ImageHandle) -> AcesToneMapPass {
let bindings = [
render_system::DescriptorSetBindingTemplate::new(0, render_system::DescriptorType::StorageImage, render_system::Stages::COMPUTE),
render_system::DescriptorSetBindingTemplate::new(1, render_system::DescriptorType::StorageImage, render_system::Stages::COMPUTE),
];

let descriptor_set_layout = render_system.create_descriptor_set_template(Some("Tonemap Pass Set Layout"), &bindings);

let pipeline_layout = render_system.create_pipeline_layout(&[descriptor_set_layout], &[]);

let descriptor_set = render_system.create_descriptor_set(Some("Tonemap Pass Descriptor Set"), &descriptor_set_layout);

let albedo_binding = render_system.create_descriptor_binding(descriptor_set, &bindings[0]);
let result_binding = render_system.create_descriptor_binding(descriptor_set, &bindings[1]);

render_system.write(&[
render_system::DescriptorWrite {
binding_handle: albedo_binding,
array_element: 0,
descriptor: render_system::Descriptor::Image{ handle: source_image, layout: render_system::Layouts::General },
},
render_system::DescriptorWrite {
binding_handle: result_binding,
array_element: 0,
descriptor: render_system::Descriptor::Image{ handle: result_image, layout: render_system::Layouts::General },
},
]);

let tone_mapping_shader = render_system.create_shader(render_system::ShaderSource::GLSL(TONE_MAPPING_SHADER), render_system::ShaderTypes::Compute,);
let tone_mapping_pipeline = render_system.create_compute_pipeline(&pipeline_layout, (&tone_mapping_shader, render_system::ShaderTypes::Compute, vec![]));

AcesToneMapPass {
descriptor_set_layout,
pipeline_layout,
descriptor_set,
pipeline: tone_mapping_pipeline,

source_image_handle: source_image,
result_image_handle: result_image,
}
}

pub fn new_as_system(render_system: &mut dyn render_system::RenderSystem, source_image: render_system::ImageHandle, result_image: render_system::ImageHandle) -> orchestrator::EntityReturn<Self> {
orchestrator::EntityReturn::new_from_function(move |orchestrator| {
AcesToneMapPass::new(render_system, source_image, result_image)
})
}
}

impl tonemap_render_pass::ToneMapRenderPass for AcesToneMapPass {
fn render(&self, command_buffer_recording: &mut dyn render_system::CommandBufferRecording,) {
command_buffer_recording.consume_resources(&[
render_system::Consumption{
handle: render_system::Handle::Image(self.source_image_handle),
stages: render_system::Stages::COMPUTE,
access: render_system::AccessPolicies::READ,
layout: render_system::Layouts::General,
},
render_system::Consumption{
handle: render_system::Handle::Image(self.result_image_handle),
stages: render_system::Stages::COMPUTE,
access: render_system::AccessPolicies::WRITE,
layout: render_system::Layouts::General,
},
]);

command_buffer_recording.bind_compute_pipeline(&self.pipeline);
command_buffer_recording.bind_descriptor_sets(&self.pipeline_layout, &[self.descriptor_set]);
command_buffer_recording.dispatch(render_system::DispatchExtent { workgroup_extent: Extent::square(32), dispatch_extent: Extent { width: 1920, height: 1080, depth: 1 } });
}
}

impl Entity for AcesToneMapPass {}
impl System for AcesToneMapPass {}

const TONE_MAPPING_SHADER: &'static str = r#"
#version 450
#pragma shader_stage(compute)
#extension GL_EXT_scalar_block_layout: enable
#extension GL_EXT_buffer_reference2: enable
#extension GL_EXT_shader_explicit_arithmetic_types_int16 : enable
layout(set=0, binding=0, rgba16) uniform readonly image2D source;
layout(set=0, binding=1, rgba8) uniform image2D result;
vec3 ACESNarkowicz(vec3 x) {
const float a = 2.51;
const float b = 0.03;
const float c = 2.43;
const float d = 0.59;
const float e = 0.14;
return clamp((x*(a*x+b))/(x*(c*x+d)+e), 0.0, 1.0);
}
const mat3 ACES_INPUT_MAT = mat3(
vec3( 0.59719, 0.35458, 0.04823),
vec3( 0.07600, 0.90834, 0.01566),
vec3( 0.02840, 0.13383, 0.83777)
);
const mat3 ACES_OUTPUT_MAT = mat3(
vec3( 1.60475, -0.53108, -0.07367),
vec3(-0.10208, 1.10813, -0.00605),
vec3(-0.00327, -0.07276, 1.07602)
);
vec3 RRTAndODTFit(vec3 v) {
vec3 a = v * (v + 0.0245786) - 0.000090537;
vec3 b = v * (0.983729 * v + 0.4329510) + 0.238081;
return a / b;
}
vec3 ACESFitted(vec3 x) {
return clamp(ACES_OUTPUT_MAT * RRTAndODTFit(ACES_INPUT_MAT * x), 0.0, 1.0);
}
layout(local_size_x=32, local_size_y=32) in;
void main() {
if (gl_GlobalInvocationID.x >= imageSize(source).x || gl_GlobalInvocationID.y >= imageSize(source).y) { return; }
vec4 source_color = imageLoad(source, ivec2(gl_GlobalInvocationID.xy));
vec3 result_color = ACESNarkowicz(source_color.rgb);
result_color = pow(result_color, vec3(1.0 / 2.2));
imageStore(result, ivec2(gl_GlobalInvocationID.xy), vec4(result_color, 1.0));
}
"#;
9 changes: 9 additions & 0 deletions src/rendering/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,17 @@ pub mod mesh;
pub mod cct;
mod vulkan_render_system;

pub mod world_render_domain;
pub mod visibility_model;

pub mod renderer;

pub mod tonemap_render_pass;

pub mod shadow_render_pass;
pub mod ssao_render_pass;
pub mod aces_tonemap_render_pass;

pub(crate) mod shader_compilation;

pub fn create_render_system(orchestrator: &orchestrator::Orchestrator) -> orchestrator::EntityHandle<render_system::RenderSystemImplementation> {
Expand Down
2 changes: 1 addition & 1 deletion src/rendering/render_orchestrator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub struct RenderOrchestrator {
}

impl RenderOrchestrator {
pub fn new() -> orchestrator::EntityReturn<RenderOrchestrator> {
pub fn new() -> orchestrator::EntityReturn<'static, RenderOrchestrator> {
orchestrator::EntityReturn::new(Self { render_passes: Vec::new(), })
}

Expand Down
Loading

0 comments on commit 182518a

Please sign in to comment.