summaryrefslogtreecommitdiff
path: root/engine/src/renderer
diff options
context:
space:
mode:
Diffstat (limited to 'engine/src/renderer')
-rw-r--r--engine/src/renderer/opengl.rs124
-rw-r--r--engine/src/renderer/opengl/glsl/light.glsl4
2 files changed, 57 insertions, 71 deletions
diff --git a/engine/src/renderer/opengl.rs b/engine/src/renderer/opengl.rs
index c036cc0..c44a479 100644
--- a/engine/src/renderer/opengl.rs
+++ b/engine/src/renderer/opengl.rs
@@ -9,6 +9,7 @@ use std::process::abort;
use ecs::actions::Actions;
use ecs::component::local::Local;
+use ecs::phase::{PRESENT as PRESENT_PHASE, START as START_PHASE};
use ecs::query::options::{Not, With};
use ecs::sole::Single;
use ecs::system::{Into as _, System};
@@ -18,7 +19,6 @@ use crate::camera::{Active as ActiveCamera, Camera};
use crate::color::Color;
use crate::data_types::dimens::Dimens;
use crate::draw_flags::{DrawFlags, NoDraw, PolygonModeConfig};
-use crate::event::{Present as PresentEvent, Start as StartEvent};
use crate::lighting::{DirectionalLight, GlobalLight, PointLight};
use crate::material::{Flags as MaterialFlags, Material};
use crate::matrix::Matrix;
@@ -61,22 +61,22 @@ use crate::opengl::{
Capability,
ContextFlags,
};
-use crate::projection::{new_perspective_matrix, Projection};
+use crate::projection::{ClipVolume, Projection};
use crate::texture::{Id as TextureId, Texture};
use crate::transform::{Position, Scale};
-use crate::util::NeverDrop;
+use crate::util::{defer, Defer, RefOrValue};
use crate::vector::{Vec2, Vec3};
use crate::vertex::{AttributeComponentType, Vertex};
use crate::window::Window;
-type RenderableEntity = (
- Mesh,
- Material,
- Option<MaterialFlags>,
- Option<Position>,
- Option<Scale>,
- Option<DrawFlags>,
- Option<GlObjects>,
+type RenderableEntity<'a> = (
+ &'a Mesh,
+ &'a Material,
+ &'a Option<MaterialFlags>,
+ &'a Option<Position>,
+ &'a Option<Scale>,
+ &'a Option<DrawFlags>,
+ &'a Option<GlObjects>,
);
#[derive(Debug, Default)]
@@ -87,10 +87,10 @@ impl ecs::extension::Extension for Extension
{
fn collect(self, mut collector: ecs::extension::Collector<'_>)
{
- collector.add_system(StartEvent, initialize);
+ collector.add_system(*START_PHASE, initialize);
collector.add_system(
- PresentEvent,
+ *PRESENT_PHASE,
render
.into_system()
.initialize((GlobalGlObjects::default(),)),
@@ -133,10 +133,10 @@ fn initialize(window: Single<Window>)
#[allow(clippy::too_many_arguments)]
fn render(
- query: Query<RenderableEntity, Not<With<NoDraw>>>,
- point_light_query: Query<(PointLight,)>,
- directional_lights: Query<(DirectionalLight,)>,
- camera_query: Query<(Camera, Position, ActiveCamera)>,
+ query: Query<RenderableEntity<'_>, Not<With<NoDraw>>>,
+ point_light_query: Query<(&PointLight,)>,
+ directional_lights: Query<(&DirectionalLight,)>,
+ camera_query: Query<(&Camera, &Position, &ActiveCamera)>,
window: Single<Window>,
global_light: Single<GlobalLight>,
mut gl_objects: Local<GlobalGlObjects>,
@@ -166,32 +166,25 @@ fn render(
clear_buffers(BufferClearMask::COLOR | BufferClearMask::DEPTH);
for (
- entity_index,
+ euid,
(mesh, material, material_flags, position, scale, draw_flags, gl_objects),
- ) in query.iter().enumerate()
+ ) in query.iter_with_euids()
{
let material_flags = material_flags
.map(|material_flags| material_flags.clone())
.unwrap_or_default();
- let new_gl_objects;
-
- let gl_objects = if let Some(gl_objects) = gl_objects.as_deref() {
- gl_objects
- } else {
- // TODO: Account for when meshes are changed
- let gl_objects = GlObjects::new(&mesh);
-
- new_gl_objects = Some(gl_objects.clone());
-
- actions.add_components(
- query.get_entity_uid(entity_index).unwrap(),
- (gl_objects,),
- );
-
- &*new_gl_objects.unwrap()
+ let gl_objs = match gl_objects.as_deref() {
+ Some(gl_objs) => RefOrValue::Ref(gl_objs),
+ None => RefOrValue::Value(Some(GlObjects::new(&mesh))),
};
+ defer!(|gl_objs| {
+ if let RefOrValue::Value(opt_gl_objs) = gl_objs {
+ actions.add_components(euid, (opt_gl_objs.take().unwrap(),));
+ };
+ });
+
apply_transformation_matrices(
Transformation {
position: position.map(|pos| *pos).unwrap_or_default().position,
@@ -238,7 +231,7 @@ fn render(
);
}
- draw_mesh(gl_objects);
+ draw_mesh(gl_objs.get().unwrap());
if draw_flags.is_some() {
let default_polygon_mode_config = PolygonModeConfig::default();
@@ -276,9 +269,9 @@ fn draw_mesh(gl_objects: &GlObjects)
gl_objects.vertex_arr.bind();
if gl_objects.index_buffer.is_some() {
- VertexArray::draw_elements(PrimitiveKind::Triangles, 0, gl_objects.index_cnt);
+ VertexArray::draw_elements(PrimitiveKind::Triangles, 0, gl_objects.element_cnt);
} else {
- VertexArray::draw_arrays(PrimitiveKind::Triangles, 0, 3);
+ VertexArray::draw_arrays(PrimitiveKind::Triangles, 0, gl_objects.element_cnt);
}
}
@@ -363,9 +356,9 @@ fn get_glsl_shader_content(path: &Path) -> Result<Vec<u8>, std::io::Error>
struct GlObjects
{
/// Vertex and index buffer has to live as long as the vertex array
- vertex_buffer: Buffer<Vertex>,
+ _vertex_buffer: Buffer<Vertex>,
index_buffer: Option<Buffer<u32>>,
- index_cnt: u32,
+ element_cnt: u32,
vertex_arr: VertexArray,
}
@@ -418,37 +411,27 @@ impl GlObjects
vertex_arr.bind_element_buffer(&index_buffer);
return Self {
- vertex_buffer,
+ _vertex_buffer: vertex_buffer,
index_buffer: Some(index_buffer),
- index_cnt: indices.len().try_into().unwrap(),
+ element_cnt: indices
+ .len()
+ .try_into()
+ .expect("Mesh index count does not fit into a 32-bit unsigned int"),
vertex_arr,
};
}
Self {
- vertex_buffer,
+ _vertex_buffer: vertex_buffer,
index_buffer: None,
- index_cnt: 0,
+ element_cnt: mesh
+ .vertices()
+ .len()
+ .try_into()
+ .expect("Mesh vertex count does not fit into a 32-bit unsigned int"),
vertex_arr,
}
}
-
- pub fn clone(&self) -> NeverDrop<Self>
- {
- NeverDrop::new(Self {
- // SAFETY: The vertex buffer will never become dropped (NeverDrop ensures it)
- vertex_buffer: unsafe { self.vertex_buffer.clone_weak() },
- index_buffer: self
- .index_buffer
- .as_ref()
- // SAFETY: The index buffer will never become dropped (NeverDrop ensures
- // it)
- .map(|index_buffer| unsafe { index_buffer.clone_weak() }),
- index_cnt: self.index_cnt,
- // SAFETY: The vertex array will never become dropped (NeverDrop ensures it)
- vertex_arr: unsafe { self.vertex_arr.clone_unsafe() },
- })
- }
}
fn apply_transformation_matrices(
@@ -462,19 +445,22 @@ fn apply_transformation_matrices(
gl_shader_program
.set_uniform_matrix_4fv(c"model", &create_transformation_matrix(transformation));
- let view = create_view(camera, camera_pos);
+ let view_matrix = create_view_matrix(camera, &camera_pos.position);
- gl_shader_program.set_uniform_matrix_4fv(c"view", &view);
+ gl_shader_program.set_uniform_matrix_4fv(c"view", &view_matrix);
#[allow(clippy::cast_precision_loss)]
- let projection = match &camera.projection {
- Projection::Perspective(perspective) => new_perspective_matrix(
- perspective,
+ let proj_matrix = match &camera.projection {
+ Projection::Perspective(perspective_proj) => perspective_proj.to_matrix_rh(
window_size.width as f32 / window_size.height as f32,
+ ClipVolume::NegOneToOne,
),
+ Projection::Orthographic(orthographic_proj) => {
+ orthographic_proj.to_matrix_rh(&camera_pos.position, ClipVolume::NegOneToOne)
+ }
};
- gl_shader_program.set_uniform_matrix_4fv(c"projection", &projection);
+ gl_shader_program.set_uniform_matrix_4fv(c"projection", &proj_matrix);
}
fn apply_light<PointLightHolder>(
@@ -687,11 +673,11 @@ fn create_light_uniform_name(
}
}
-fn create_view(camera: &Camera, camera_pos: &Position) -> Matrix<f32, 4, 4>
+fn create_view_matrix(camera: &Camera, camera_pos: &Vec3<f32>) -> Matrix<f32, 4, 4>
{
let mut view = Matrix::new();
- view.look_at(&camera_pos.position, &camera.target, &camera.global_up);
+ view.look_at(&camera_pos, &camera.target, &camera.global_up);
view
}
diff --git a/engine/src/renderer/opengl/glsl/light.glsl b/engine/src/renderer/opengl/glsl/light.glsl
index 1bc23a4..f12b5fe 100644
--- a/engine/src/renderer/opengl/glsl/light.glsl
+++ b/engine/src/renderer/opengl/glsl/light.glsl
@@ -80,10 +80,10 @@ vec3 calc_specular_light(
{
vec3 view_direction = normalize(view_pos - frag_pos);
- vec3 reflect_direction = reflect(-light_dir, norm);
+ vec3 halfway_direction = normalize(light_dir + view_direction);
float spec =
- pow(max(dot(view_direction, reflect_direction), 0.0), material.shininess);
+ pow(max(dot(norm, halfway_direction), 0.0), material.shininess);
return light_phong.specular * (
spec * (vec3(texture(material.specular_map, texture_coords)) * material.specular)