wip: engine enhancements and fixes
This commit is contained in:
parent
9816f14f53
commit
cc7921a5fe
27 changed files with 347 additions and 32 deletions
15
Cargo.lock
generated
15
Cargo.lock
generated
|
|
@ -75,9 +75,9 @@ checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anyhow"
|
name = "anyhow"
|
||||||
version = "1.0.98"
|
version = "1.0.99"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487"
|
checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "arrayref"
|
name = "arrayref"
|
||||||
|
|
@ -1258,10 +1258,19 @@ dependencies = [
|
||||||
"winit",
|
"winit",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "raidillon_ecs"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"glam",
|
||||||
|
"raidillon_assets",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "raidillon_game"
|
name = "raidillon_game"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"glam",
|
||||||
"raidillon_core",
|
"raidillon_core",
|
||||||
"raidillon_glium",
|
"raidillon_glium",
|
||||||
"raidillon_platform",
|
"raidillon_platform",
|
||||||
|
|
@ -1278,6 +1287,7 @@ dependencies = [
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"raidillon_assets",
|
"raidillon_assets",
|
||||||
"raidillon_core",
|
"raidillon_core",
|
||||||
|
"raidillon_ecs",
|
||||||
"raidillon_platform",
|
"raidillon_platform",
|
||||||
"winit",
|
"winit",
|
||||||
]
|
]
|
||||||
|
|
@ -1286,6 +1296,7 @@ dependencies = [
|
||||||
name = "raidillon_platform"
|
name = "raidillon_platform"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"glam",
|
||||||
"raidillon_assets",
|
"raidillon_assets",
|
||||||
"raidillon_core",
|
"raidillon_core",
|
||||||
"winit",
|
"winit",
|
||||||
|
|
|
||||||
|
|
@ -4,5 +4,6 @@ members = [
|
||||||
"glium_platform",
|
"glium_platform",
|
||||||
"platform",
|
"platform",
|
||||||
"asset",
|
"asset",
|
||||||
"game"
|
"game",
|
||||||
|
"ecs"
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -2,5 +2,3 @@
|
||||||
name = "raidillon_assets"
|
name = "raidillon_assets"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,10 @@
|
||||||
pub mod model_manager;
|
pub mod model_manager;
|
||||||
|
|
||||||
pub use crate::model_manager::{ModelManager, ModelManagerRef};
|
pub use crate::model_manager::{ModelManager, ModelManagerRef};
|
||||||
|
|
||||||
|
pub use crate::model_manager::ModelID;
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! include_shader {
|
||||||
|
($path:expr) => {
|
||||||
|
include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/../assets/shaders/", $path))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -1,14 +1,17 @@
|
||||||
|
use std::any::Any;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::path::Path;
|
use std::path::{Path, PathBuf};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
pub type ModelManagerRef = Rc<RefCell<Box<dyn ModelManager>>>;
|
pub type ModelManagerRef = Rc<RefCell<Box<dyn ModelManager>>>;
|
||||||
|
pub type ModelID = PathBuf;
|
||||||
|
|
||||||
/// The asset manager trait of Raidillon.
|
/// The asset manager trait of Raidillon.
|
||||||
pub trait ModelManager {
|
pub trait ModelManager: Any {
|
||||||
/// Loads a gltf model to VRAM.
|
/// Loads a gltf model to VRAM.
|
||||||
fn load_gltf(&mut self, path: &Path);
|
fn load_gltf(&mut self, path: &Path);
|
||||||
/// Unloads the loaded model from VRAM.
|
/// Unloads the loaded model from VRAM.
|
||||||
fn unload_model(&mut self, path: &Path);
|
fn unload_model(&mut self, path: &Path);
|
||||||
|
|
||||||
|
fn get_model(&self, id: &ModelID) -> Option<&dyn Any>;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
34
assets/shaders/gl_textured.frag
Normal file
34
assets/shaders/gl_textured.frag
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
in vec3 v_normal;
|
||||||
|
in vec2 v_tex;
|
||||||
|
in vec3 v_position;
|
||||||
|
|
||||||
|
out vec4 frag_color;
|
||||||
|
|
||||||
|
uniform vec3 u_light;
|
||||||
|
uniform sampler2D tex;
|
||||||
|
uniform vec3 color; // base colour factor (acts as solid colour when no texture)
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
// Combine base texture (or constant white) with colour factor supplied by CPU.
|
||||||
|
vec3 base_col = texture(tex, v_tex).rgb * color;
|
||||||
|
|
||||||
|
vec3 ambient_color = base_col * 0.2;
|
||||||
|
vec3 diffuse_color = base_col * 0.6;
|
||||||
|
vec3 specular_color = vec3(1.0);
|
||||||
|
|
||||||
|
// u_light is the direction **from the light towards the fragment**.
|
||||||
|
float diffuse = max(dot(normalize(v_normal), normalize(u_light)), 0.0);
|
||||||
|
|
||||||
|
vec3 camera_dir = normalize(-v_position);
|
||||||
|
vec3 half_dir = normalize(normalize(u_light) + camera_dir);
|
||||||
|
float specular = pow(max(dot(half_dir, normalize(v_normal)), 0.0), 16.0);
|
||||||
|
|
||||||
|
vec3 result = ambient_color + diffuse * diffuse_color + specular * specular_color;
|
||||||
|
|
||||||
|
// Convert from linear to sRGB for display (approximate γ-correction)
|
||||||
|
result = pow(result, vec3(1.0 / 2.2));
|
||||||
|
|
||||||
|
frag_color = vec4(result, 1.0);
|
||||||
|
}
|
||||||
23
assets/shaders/gl_textured.vert
Normal file
23
assets/shaders/gl_textured.vert
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
in vec3 position;
|
||||||
|
in vec3 normal;
|
||||||
|
in vec2 tex_coords;
|
||||||
|
|
||||||
|
uniform mat4 model;
|
||||||
|
uniform mat4 view;
|
||||||
|
uniform mat4 projection;
|
||||||
|
uniform vec2 uv_offset;
|
||||||
|
uniform vec2 uv_scale;
|
||||||
|
|
||||||
|
out vec3 v_normal;
|
||||||
|
out vec2 v_tex;
|
||||||
|
out vec3 v_position;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
mat4 modelview = view * model;
|
||||||
|
v_normal = transpose(inverse(mat3(modelview))) * normal;
|
||||||
|
v_tex = tex_coords * uv_scale + uv_offset;
|
||||||
|
v_position = (modelview * vec4(position, 1.0)).xyz;
|
||||||
|
gl_Position = projection * modelview * vec4(position, 1.0);
|
||||||
|
}
|
||||||
22
assets/shaders/skybox.frag
Normal file
22
assets/shaders/skybox.frag
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
in vec3 direction;
|
||||||
|
|
||||||
|
out vec4 frag_color;
|
||||||
|
|
||||||
|
uniform sampler2D equirect;
|
||||||
|
|
||||||
|
const vec2 inv_atan = vec2(0.15915494309, 0.31830988618);
|
||||||
|
|
||||||
|
vec2 sample_spherical_map(vec3 v) {
|
||||||
|
vec2 uv = vec2(atan(v.z, v.x), asin(v.y));
|
||||||
|
uv *= inv_atan;
|
||||||
|
uv += 0.5;
|
||||||
|
return uv;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec2 uv = sample_spherical_map(normalize(direction));
|
||||||
|
vec3 color = texture(equirect, uv).rgb;
|
||||||
|
frag_color = vec4(color, 1.0);
|
||||||
|
}
|
||||||
15
assets/shaders/skybox.vert
Normal file
15
assets/shaders/skybox.vert
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
in vec3 position;
|
||||||
|
|
||||||
|
uniform mat4 view;
|
||||||
|
|
||||||
|
uniform mat4 projection;
|
||||||
|
|
||||||
|
out vec3 direction;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
direction = position;
|
||||||
|
vec4 pos = projection * view * vec4(position, 1.0);
|
||||||
|
gl_Position = pos.xyww;
|
||||||
|
}
|
||||||
|
|
@ -2,9 +2,9 @@ use std::collections::HashMap;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
pub struct Scene {
|
pub struct Scene {
|
||||||
title: String,
|
pub title: String,
|
||||||
world: hecs::World,
|
pub world: hecs::World,
|
||||||
skybox_texture_path: Option<PathBuf>,
|
pub skybox_texture_path: Option<PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Scene {
|
impl Scene {
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ pub trait System {
|
||||||
fn update(&mut self, ctx: &mut SystemContext);
|
fn update(&mut self, ctx: &mut SystemContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type SystemID = String;
|
pub type SystemID = &'static str;
|
||||||
pub struct SystemManager {
|
pub struct SystemManager {
|
||||||
pub systems: IndexMap<SystemID, Box<dyn System>>,
|
pub systems: IndexMap<SystemID, Box<dyn System>>,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
8
ecs/Cargo.toml
Normal file
8
ecs/Cargo.toml
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
[package]
|
||||||
|
name = "raidillon_ecs"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
glam = "0.30.5"
|
||||||
|
raidillon_assets = { path = "../asset" }
|
||||||
15
ecs/src/components.rs
Normal file
15
ecs/src/components.rs
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
use glam::{Vec3, Quat, Mat4};
|
||||||
|
pub use raidillon_assets::ModelID;
|
||||||
|
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub struct Transform {
|
||||||
|
pub translation: Vec3,
|
||||||
|
pub rotation: Quat,
|
||||||
|
pub scale: Vec3,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Transform {
|
||||||
|
pub fn matrix(&self) -> Mat4 {
|
||||||
|
Mat4::from_scale_rotation_translation(self.scale, self.rotation, self.translation)
|
||||||
|
}
|
||||||
|
}
|
||||||
3
ecs/src/lib.rs
Normal file
3
ecs/src/lib.rs
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
pub mod components;
|
||||||
|
|
||||||
|
pub use components::{Transform, ModelID};
|
||||||
|
|
@ -11,3 +11,4 @@ glium = ["raidillon_glium"]
|
||||||
raidillon_core = { path = "../core" }
|
raidillon_core = { path = "../core" }
|
||||||
raidillon_platform = { path = "../platform" }
|
raidillon_platform = { path = "../platform" }
|
||||||
raidillon_glium = { path = "../glium_platform", optional = true }
|
raidillon_glium = { path = "../glium_platform", optional = true }
|
||||||
|
glam = "0.30.5"
|
||||||
|
|
@ -1,14 +1,39 @@
|
||||||
use raidillon_core::{Engine, Scene};
|
use glam::Vec3;
|
||||||
use raidillon_platform::Platform;
|
use raidillon_core::{Engine, Scene, System};
|
||||||
|
use raidillon_core::system::SystemContext;
|
||||||
|
use raidillon_platform::{Platform, Camera};
|
||||||
|
|
||||||
#[cfg(feature = "glium")]
|
#[cfg(feature = "glium")]
|
||||||
use raidillon_glium::GliumPlatform;
|
use raidillon_glium::GliumPlatform;
|
||||||
|
|
||||||
|
const RENDERING_TEST_SYSTEM: &str = "rendering_test_system";
|
||||||
|
struct RenderingTestSystem;
|
||||||
|
|
||||||
|
impl System for RenderingTestSystem {
|
||||||
|
fn initialize(&mut self) {}
|
||||||
|
fn load_world(&mut self, ctx: &mut SystemContext) {
|
||||||
|
ctx.scene.world.spawn((Camera {
|
||||||
|
eye: Vec3::new(0.0, 0.0, 2.0),
|
||||||
|
center: Vec3::ZERO,
|
||||||
|
up: Vec3::Y,
|
||||||
|
fovy: 60_f32.to_radians(),
|
||||||
|
aspect: 1920 as f32 / 1080 as f32, // FIXME
|
||||||
|
znear: 0.1,
|
||||||
|
zfar: 100.0,
|
||||||
|
},));
|
||||||
|
|
||||||
|
// TODO: Load a sample glTF file
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update(&mut self, ctx: &mut SystemContext) {}
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut engine = Engine::new();
|
let mut engine = Engine::new();
|
||||||
// Define systems
|
// Define systems
|
||||||
// engine.system_manager.add_system("spawn_chunks".to_string(), ChunkSystem);
|
// engine.system_manager.add_system("spawn_chunks".to_string(), ChunkSystem);
|
||||||
// engine.system_manager.add_system("movement".to_string(), MovementSystem);
|
// engine.system_manager.add_system("movement".to_string(), MovementSystem);
|
||||||
|
engine.system_manager.add_system(RENDERING_TEST_SYSTEM, Box::new(RenderingTestSystem));
|
||||||
|
|
||||||
// Set up the scene
|
// Set up the scene
|
||||||
let main_scene_id = "Main".to_owned();
|
let main_scene_id = "Main".to_owned();
|
||||||
|
|
|
||||||
|
|
@ -11,5 +11,6 @@ gltf = { version = "1.4.1", features = ["import", "utils", "KHR_texture_transfor
|
||||||
raidillon_platform = { path = "../platform" }
|
raidillon_platform = { path = "../platform" }
|
||||||
raidillon_core = { path = "../core" }
|
raidillon_core = { path = "../core" }
|
||||||
raidillon_assets = { path = "../asset" }
|
raidillon_assets = { path = "../asset" }
|
||||||
|
raidillon_ecs = { path = "../ecs" }
|
||||||
winit = "0.30.12"
|
winit = "0.30.12"
|
||||||
indexmap = "2.10.0"
|
indexmap = "2.10.0"
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::any::Any;
|
||||||
|
use std::cell::RefCell;
|
||||||
use raidillon_assets::{ModelManagerRef, ModelManager};
|
use raidillon_assets::{ModelManagerRef, ModelManager};
|
||||||
use crate::model::Model;
|
use crate::model::Model;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
@ -5,10 +7,12 @@ use crate::gltf_loader::load_gltf;
|
||||||
use glium::backend::Facade;
|
use glium::backend::Facade;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::collections::hash_map::Entry;
|
use std::collections::hash_map::Entry;
|
||||||
|
use std::rc::Rc;
|
||||||
|
use raidillon_assets::model_manager::ModelID;
|
||||||
|
|
||||||
/// Glium platform asset manager implementation.
|
/// Glium platform asset manager implementation.
|
||||||
pub struct GliumAssetManager {
|
pub struct GliumAssetManager {
|
||||||
models: HashMap<PathBuf, Model>,
|
pub models: HashMap<PathBuf, Model>,
|
||||||
facade: Box<dyn Facade>,
|
facade: Box<dyn Facade>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -42,4 +46,8 @@ impl ModelManager for GliumAssetManager {
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
fn get_model(&self, id: &ModelID) -> Option<&dyn Any> {
|
||||||
|
self.models.get(id).map(|model| model as &dyn Any)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,6 @@ pub mod gltf_loader;
|
||||||
pub mod system;
|
pub mod system;
|
||||||
mod render;
|
mod render;
|
||||||
|
|
||||||
pub use assets::GliumAssetManager;
|
pub use assets::{GliumAssetManager};
|
||||||
pub use platform::GliumPlatform;
|
pub use platform::GliumPlatform;
|
||||||
pub use system::RenderingSystem;
|
pub use system::RenderingSystem;
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
use std::any::{Any, TypeId};
|
||||||
use glium::{IndexBuffer, VertexBuffer, implement_vertex};
|
use glium::{IndexBuffer, VertexBuffer, implement_vertex};
|
||||||
use glium::texture::{SrgbTexture2d, Texture2d};
|
use glium::texture::{SrgbTexture2d, Texture2d};
|
||||||
use glium::uniforms::SamplerBehavior;
|
use glium::uniforms::SamplerBehavior;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use std::str::FromStr;
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
use raidillon_platform::Platform;
|
use raidillon_platform::Platform;
|
||||||
use glium::winit::event_loop::EventLoop;
|
use glium::winit::event_loop::EventLoop;
|
||||||
|
|
@ -8,12 +9,14 @@ use glium::backend::glutin::Display;
|
||||||
use glium::glutin::surface::WindowSurface;
|
use glium::glutin::surface::WindowSurface;
|
||||||
use glium::backend::glutin::SimpleWindowBuilder;
|
use glium::backend::glutin::SimpleWindowBuilder;
|
||||||
use glium::Surface;
|
use glium::Surface;
|
||||||
use crate::system::{RenderingSystemManager, RenderingSystem, RenderingContext};
|
use crate::system::{RenderingSystemManager, RenderingSystem, RenderingContext, SystemID};
|
||||||
use winit::event::{Event, WindowEvent};
|
use winit::event::{Event, WindowEvent};
|
||||||
use raidillon_assets::{ModelManager, ModelManagerRef};
|
use raidillon_assets::{ModelManager, ModelManagerRef};
|
||||||
use raidillon_core::Engine;
|
use raidillon_core::Engine;
|
||||||
use crate::GliumAssetManager;
|
use crate::{GliumAssetManager};
|
||||||
use crate::render::BasicRenderingSystem;
|
use crate::render::BasicMeshRenderingSystem;
|
||||||
|
|
||||||
|
pub const MESH_RENDERER: &str = "mesh_renderer";
|
||||||
|
|
||||||
pub struct GliumPlatform {
|
pub struct GliumPlatform {
|
||||||
event_loop: EventLoop<()>,
|
event_loop: EventLoop<()>,
|
||||||
|
|
@ -36,8 +39,15 @@ impl Platform for GliumPlatform {
|
||||||
.build(&event_loop);
|
.build(&event_loop);
|
||||||
|
|
||||||
let asset_manager: ModelManagerRef = Rc::new(RefCell::new(Box::new(GliumAssetManager::new(Box::new(display.clone())))));
|
let asset_manager: ModelManagerRef = Rc::new(RefCell::new(Box::new(GliumAssetManager::new(Box::new(display.clone())))));
|
||||||
let rendering_system_manager = RenderingSystemManager::new();
|
let mut rendering_system_manager = RenderingSystemManager::new();
|
||||||
engine.set_model_manager(asset_manager.clone());
|
engine.set_model_manager(asset_manager.clone());
|
||||||
|
|
||||||
|
// Install rendering systems
|
||||||
|
rendering_system_manager.add_system(
|
||||||
|
MESH_RENDERER,
|
||||||
|
Box::new(BasicMeshRenderingSystem::initialize(&display))
|
||||||
|
);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
event_loop,
|
event_loop,
|
||||||
window,
|
window,
|
||||||
|
|
@ -49,6 +59,7 @@ impl Platform for GliumPlatform {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(mut self) {
|
fn run(mut self) {
|
||||||
|
self.engine.initialize();
|
||||||
let _ = &self.event_loop.run(move |event, el| {
|
let _ = &self.event_loop.run(move |event, el| {
|
||||||
match event {
|
match event {
|
||||||
Event::WindowEvent { event, .. } => match event {
|
Event::WindowEvent { event, .. } => match event {
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,111 @@
|
||||||
use crate::RenderingSystem;
|
use std::any::Any;
|
||||||
|
use glium::{uniform, Display, Program, Surface};
|
||||||
|
use glium::glutin::surface::WindowSurface;
|
||||||
|
use glium::texture::{RawImage2d, SrgbTexture2d};
|
||||||
|
use crate::{GliumAssetManager, RenderingSystem};
|
||||||
use crate::system::RenderingContext;
|
use crate::system::RenderingContext;
|
||||||
|
use raidillon_assets::include_shader;
|
||||||
|
pub use raidillon_platform::Camera;
|
||||||
|
use glam::Vec3;
|
||||||
|
use glium::uniforms::{MagnifySamplerFilter, MinifySamplerFilter, SamplerWrapFunction};
|
||||||
|
use raidillon_ecs::{Transform, ModelID};
|
||||||
|
use crate::model::Model;
|
||||||
|
|
||||||
/// A basic renderer pipeline step.
|
/// A basic renderer pipeline step.
|
||||||
pub struct BasicRenderingSystem;
|
pub struct BasicMeshRenderingSystem {
|
||||||
|
program: Program,
|
||||||
|
white_tex: SrgbTexture2d,
|
||||||
|
params: glium::DrawParameters<'static>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RenderingSystem for BasicMeshRenderingSystem {
|
||||||
|
fn initialize(display: &Display<WindowSurface>) -> Self {
|
||||||
|
const VERT_SRC: &str = include_shader!("gl_textured.vert");
|
||||||
|
const FRAG_SRC: &str = include_shader!("gl_textured.frag");
|
||||||
|
|
||||||
|
let program = Program::from_source(display, VERT_SRC, FRAG_SRC, None).unwrap();
|
||||||
|
|
||||||
|
let white_tex = {
|
||||||
|
let data = vec![255u8, 255u8, 255u8, 255u8];
|
||||||
|
let raw = RawImage2d::from_raw_rgba(data, (1, 1));
|
||||||
|
SrgbTexture2d::new(display, raw).unwrap()
|
||||||
|
};
|
||||||
|
|
||||||
|
let params = glium::DrawParameters {
|
||||||
|
depth: glium::Depth {
|
||||||
|
test: glium::draw_parameters::DepthTest::IfLess,
|
||||||
|
write: true,
|
||||||
|
.. Default::default()
|
||||||
|
},
|
||||||
|
.. Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
Self {
|
||||||
|
program, white_tex, params
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl RenderingSystem for BasicRenderingSystem {
|
|
||||||
fn render(&mut self, ctx: &mut RenderingContext) {
|
fn render(&mut self, ctx: &mut RenderingContext) {
|
||||||
todo!()
|
let cam = match ctx.scene.world.query::<&Camera>().iter().next() {
|
||||||
|
Some((_, cam)) => *cam,
|
||||||
|
None => {
|
||||||
|
eprintln!("[renderer] No camera component found. Skipping frame");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Direction from the light source (0,+Y) towards the scene.
|
||||||
|
let light_dir: Vec3 = Vec3::new(0.0, -1.0, 0.0).normalize();
|
||||||
|
|
||||||
|
// let asset_manager = ctx.asset_manager.borrow();
|
||||||
|
// let any_ref: &dyn Any = &**asset_manager;
|
||||||
|
// if let Some(glium_manager) = any_ref.downcast_ref::<GliumAssetManager>() {
|
||||||
|
// &glium_manager.models;
|
||||||
|
// }
|
||||||
|
|
||||||
|
let asset_manager = ctx.asset_manager.borrow();
|
||||||
|
|
||||||
|
for (_, (tr, mh)) in ctx.scene.world.query::<(&Transform, &ModelID)>().iter() {
|
||||||
|
let model = match asset_manager.get_model(mh) {
|
||||||
|
Some(model) => model,
|
||||||
|
_ => continue,
|
||||||
|
};
|
||||||
|
|
||||||
|
let model = match model.downcast_ref::<Model>() {
|
||||||
|
Some(model) => model,
|
||||||
|
None => continue,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mesh = &model.mesh;
|
||||||
|
let mat = &model.material;
|
||||||
|
|
||||||
|
let tex_ref: &SrgbTexture2d = mat.base_color.as_ref().unwrap_or(&self.white_tex);
|
||||||
|
|
||||||
|
let mut sampler = tex_ref.sampled();
|
||||||
|
sampler = sampler.wrap_function(SamplerWrapFunction::Repeat);
|
||||||
|
sampler = sampler.minify_filter(MinifySamplerFilter::Linear);
|
||||||
|
sampler = sampler.magnify_filter(MagnifySamplerFilter::Linear);
|
||||||
|
|
||||||
|
let c = mat.base_color_factor;
|
||||||
|
|
||||||
|
let uniforms = uniform! {
|
||||||
|
model: tr.matrix().to_cols_array_2d(),
|
||||||
|
view: cam.view().to_cols_array_2d(),
|
||||||
|
projection: cam.projection().to_cols_array_2d(),
|
||||||
|
u_light: [light_dir.x, light_dir.y, light_dir.z],
|
||||||
|
tex: sampler,
|
||||||
|
color: [c[0], c[1], c[2]],
|
||||||
|
uv_offset: [mat.uv_offset.x, mat.uv_offset.y],
|
||||||
|
uv_scale: [mat.uv_scale.x, mat.uv_scale.y],
|
||||||
|
};
|
||||||
|
|
||||||
|
ctx.target.draw(
|
||||||
|
&mesh.vbuf,
|
||||||
|
&mesh.ibuf,
|
||||||
|
&self.program,
|
||||||
|
&uniforms,
|
||||||
|
&self.params,
|
||||||
|
).unwrap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,2 @@
|
||||||
mod basic;
|
mod basic;
|
||||||
pub use basic::BasicRenderingSystem;
|
pub use basic::BasicMeshRenderingSystem;
|
||||||
|
|
@ -1,8 +1,11 @@
|
||||||
|
use std::cell::RefCell;
|
||||||
|
use std::rc::Rc;
|
||||||
use raidillon_core::Scene;
|
use raidillon_core::Scene;
|
||||||
use glium::Frame;
|
use glium::{Display, Frame};
|
||||||
use crate::GliumAssetManager;
|
use glium::glutin::surface::WindowSurface;
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
use raidillon_assets::ModelManagerRef;
|
use raidillon_assets::ModelManagerRef;
|
||||||
|
use crate::GliumAssetManager;
|
||||||
|
|
||||||
pub struct RenderingContext<'a> {
|
pub struct RenderingContext<'a> {
|
||||||
pub scene: &'a Scene,
|
pub scene: &'a Scene,
|
||||||
|
|
@ -14,10 +17,10 @@ pub struct RenderingContext<'a> {
|
||||||
/// This is unrelated to the main System trait in core.
|
/// This is unrelated to the main System trait in core.
|
||||||
pub trait RenderingSystem {
|
pub trait RenderingSystem {
|
||||||
fn render(&mut self, ctx: &mut RenderingContext);
|
fn render(&mut self, ctx: &mut RenderingContext);
|
||||||
fn compile_shaders(&mut self) {}
|
fn initialize(display: &Display<WindowSurface>) -> Self where Self: Sized;
|
||||||
}
|
}
|
||||||
|
|
||||||
type SystemID = String;
|
pub type SystemID = &'static str;
|
||||||
|
|
||||||
pub struct RenderingSystemManager {
|
pub struct RenderingSystemManager {
|
||||||
pub systems: IndexMap<SystemID, Box<dyn RenderingSystem>>,
|
pub systems: IndexMap<SystemID, Box<dyn RenderingSystem>>,
|
||||||
|
|
|
||||||
|
|
@ -7,3 +7,4 @@ edition = "2024"
|
||||||
winit = "0.30.12"
|
winit = "0.30.12"
|
||||||
raidillon_core = { path = "../core" }
|
raidillon_core = { path = "../core" }
|
||||||
raidillon_assets = { path = "../asset" }
|
raidillon_assets = { path = "../asset" }
|
||||||
|
glam = "0.30.5"
|
||||||
|
|
|
||||||
24
platform/src/camera.rs
Normal file
24
platform/src/camera.rs
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
use glam::{Mat4, Vec3};
|
||||||
|
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub struct Camera {
|
||||||
|
pub eye: Vec3,
|
||||||
|
pub center: Vec3,
|
||||||
|
pub up: Vec3,
|
||||||
|
pub fovy: f32,
|
||||||
|
pub aspect: f32,
|
||||||
|
pub znear: f32,
|
||||||
|
pub zfar: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Camera {
|
||||||
|
pub fn view(&self) -> Mat4 {
|
||||||
|
Mat4::look_at_rh(self.eye, self.center, self.up)
|
||||||
|
}
|
||||||
|
pub fn projection(&self) -> Mat4 {
|
||||||
|
Mat4::perspective_rh(self.fovy, self.aspect, self.znear, self.zfar)
|
||||||
|
}
|
||||||
|
pub fn view_proj(&self) -> Mat4 {
|
||||||
|
self.projection() * self.view()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
pub mod platform;
|
pub mod platform;
|
||||||
pub mod context;
|
mod camera;
|
||||||
|
|
||||||
pub use context::PlatformContext;
|
|
||||||
pub use platform::Platform;
|
pub use platform::Platform;
|
||||||
|
pub use camera::Camera;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue