summaryrefslogtreecommitdiff
path: root/engine/src/renderer/opengl
diff options
context:
space:
mode:
Diffstat (limited to 'engine/src/renderer/opengl')
-rw-r--r--engine/src/renderer/opengl/glsl/fragment.glsl73
-rw-r--r--engine/src/renderer/opengl/glsl/light.glsl133
-rw-r--r--engine/src/renderer/opengl/glsl/vertex.glsl24
-rw-r--r--engine/src/renderer/opengl/glsl/vertex_data.glsl11
-rw-r--r--engine/src/renderer/opengl/vertex.rs64
5 files changed, 305 insertions, 0 deletions
diff --git a/engine/src/renderer/opengl/glsl/fragment.glsl b/engine/src/renderer/opengl/glsl/fragment.glsl
new file mode 100644
index 0000000..5bf5ff2
--- /dev/null
+++ b/engine/src/renderer/opengl/glsl/fragment.glsl
@@ -0,0 +1,73 @@
+#version 330 core
+
+#preinclude "light.glsl"
+#preinclude "vertex_data.glsl"
+
+#define MAX_LIGHT_CNT 64
+
+out vec4 FragColor;
+
+in VertexData vertex_data;
+
+uniform vec3 view_pos;
+uniform sampler2D input_texture;
+uniform Material material;
+
+uniform PointLight point_lights[MAX_LIGHT_CNT];
+uniform int point_light_cnt;
+
+uniform DirectionalLight directional_lights[MAX_LIGHT_CNT];
+uniform int directional_light_cnt;
+
+void main()
+{
+ vec3 ambient_light = calc_ambient_light(material, vertex_data.texture_coords);
+
+ vec3 directional_light_sum = vec3(0.0, 0.0, 0.0);
+
+ for (int dl_index = 0; dl_index < directional_light_cnt; dl_index++) {
+ CalculatedLight calculated_dir_light;
+
+ calc_light(
+ // Negated since we want the light to point from the light direction
+ normalize(-directional_lights[dl_index].direction),
+ directional_lights[dl_index].phong,
+ vertex_data,
+ view_pos,
+ material,
+ calculated_dir_light
+ );
+
+ directional_light_sum +=
+ calculated_dir_light.diffuse + calculated_dir_light.specular;
+ }
+
+ vec3 point_light_sum = vec3(0.0, 0.0, 0.0);
+
+ for (int pl_index = 0; pl_index < point_light_cnt; pl_index++) {
+ vec3 light_direction =
+ normalize(point_lights[pl_index].position - vertex_data.world_space_pos);
+
+ CalculatedLight calculated_point_light;
+
+ calc_light(
+ light_direction,
+ point_lights[pl_index].phong,
+ vertex_data,
+ view_pos,
+ material,
+ calculated_point_light
+ );
+
+ float attenuation =
+ calc_attenuation(point_lights[pl_index], vertex_data.world_space_pos);
+
+ calculated_point_light.diffuse *= attenuation;
+ calculated_point_light.specular *= attenuation;
+
+ point_light_sum +=
+ calculated_point_light.diffuse + calculated_point_light.specular;
+ }
+
+ FragColor = vec4((ambient_light + directional_light_sum + point_light_sum), 1.0);
+}
diff --git a/engine/src/renderer/opengl/glsl/light.glsl b/engine/src/renderer/opengl/glsl/light.glsl
new file mode 100644
index 0000000..f12b5fe
--- /dev/null
+++ b/engine/src/renderer/opengl/glsl/light.glsl
@@ -0,0 +1,133 @@
+#version 330 core
+
+#ifndef LIGHT_GLSL
+#define LIGHT_GLSL
+
+#preinclude "vertex_data.glsl"
+
+struct Material
+{
+ vec3 ambient;
+ vec3 diffuse;
+ vec3 specular;
+ sampler2D ambient_map;
+ sampler2D diffuse_map;
+ sampler2D specular_map;
+ float shininess;
+};
+
+struct LightPhong
+{
+ vec3 diffuse;
+ vec3 specular;
+};
+
+struct AttenuationProperties
+{
+ float constant;
+ float linear;
+ float quadratic;
+};
+
+struct PointLight
+{
+ LightPhong phong;
+ vec3 position;
+ AttenuationProperties attenuation_props;
+};
+
+struct DirectionalLight
+{
+ LightPhong phong;
+ vec3 direction;
+};
+
+struct CalculatedLight
+{
+ vec3 diffuse;
+ vec3 specular;
+};
+
+vec3 calc_ambient_light(in Material material, in vec2 texture_coords)
+{
+ return vec3(texture(material.ambient_map, texture_coords)) * material.ambient;
+}
+
+vec3 calc_diffuse_light(
+ in Material material,
+ in LightPhong light_phong,
+ in vec3 light_dir,
+ in vec3 norm,
+ in vec2 texture_coords
+)
+{
+ float diff = max(dot(norm, light_dir), 0.0);
+
+ return light_phong.diffuse * (
+ diff * (vec3(texture(material.diffuse_map, texture_coords)) * material.diffuse)
+ );
+}
+
+vec3 calc_specular_light(
+ in Material material,
+ in LightPhong light_phong,
+ in vec3 light_dir,
+ in vec3 norm,
+ in vec3 view_pos,
+ in vec3 frag_pos,
+ in vec2 texture_coords
+)
+{
+ vec3 view_direction = normalize(view_pos - frag_pos);
+
+ vec3 halfway_direction = normalize(light_dir + view_direction);
+
+ float spec =
+ pow(max(dot(norm, halfway_direction), 0.0), material.shininess);
+
+ return light_phong.specular * (
+ spec * (vec3(texture(material.specular_map, texture_coords)) * material.specular)
+ );
+}
+
+float calc_attenuation(in PointLight point_light, in vec3 position)
+{
+ float light_distance = length(point_light.position - position);
+
+ return 1.0 / (point_light.attenuation_props.constant
+ + point_light.attenuation_props.linear
+ * light_distance + point_light.attenuation_props.quadratic
+ * pow(light_distance, 2));
+}
+
+void calc_light(
+ in vec3 light_direction,
+ in LightPhong light_phong,
+ in VertexData vertex_data,
+ in vec3 view_pos,
+ in Material material,
+ out CalculatedLight calculated_light
+)
+{
+ vec3 norm = normalize(vertex_data.world_space_normal);
+
+ calculated_light.diffuse = calc_diffuse_light(
+ material,
+ light_phong,
+ light_direction,
+ norm,
+ vertex_data.texture_coords
+ );
+
+ calculated_light.specular = calc_specular_light(
+ material,
+ light_phong,
+ light_direction,
+ norm,
+ view_pos,
+ vertex_data.world_space_pos,
+ vertex_data.texture_coords
+ );
+}
+
+#endif
diff --git a/engine/src/renderer/opengl/glsl/vertex.glsl b/engine/src/renderer/opengl/glsl/vertex.glsl
new file mode 100644
index 0000000..b57caa6
--- /dev/null
+++ b/engine/src/renderer/opengl/glsl/vertex.glsl
@@ -0,0 +1,24 @@
+#version 330 core
+
+#preinclude "vertex_data.glsl"
+
+layout (location = 0) in vec3 pos;
+layout (location = 1) in vec2 texture_coords;
+layout (location = 2) in vec3 normal;
+
+out VertexData vertex_data;
+
+uniform mat4 model;
+uniform mat4 view;
+uniform mat4 projection;
+
+void main()
+{
+ gl_Position = projection * view * model * vec4(pos, 1.0);
+
+ vertex_data.world_space_pos = vec3(model * vec4(pos, 1.0));
+ vertex_data.texture_coords = texture_coords;
+
+ // TODO: Do this using CPU for performance increase
+ vertex_data.world_space_normal = mat3(transpose(inverse(model))) * normal;
+}
diff --git a/engine/src/renderer/opengl/glsl/vertex_data.glsl b/engine/src/renderer/opengl/glsl/vertex_data.glsl
new file mode 100644
index 0000000..486d445
--- /dev/null
+++ b/engine/src/renderer/opengl/glsl/vertex_data.glsl
@@ -0,0 +1,11 @@
+#ifndef VERTEX_DATA_GLSL
+#define VERTEX_DATA_GLSL
+
+struct VertexData
+{
+ vec2 texture_coords;
+ vec3 world_space_pos;
+ vec3 world_space_normal;
+};
+
+#endif
diff --git a/engine/src/renderer/opengl/vertex.rs b/engine/src/renderer/opengl/vertex.rs
new file mode 100644
index 0000000..499b94b
--- /dev/null
+++ b/engine/src/renderer/opengl/vertex.rs
@@ -0,0 +1,64 @@
+use crate::vector::{Vec2, Vec3};
+
+#[derive(Debug, Clone)]
+#[repr(C)]
+pub struct Vertex
+{
+ pub pos: Vec3<f32>,
+ pub texture_coords: Vec2<f32>,
+ pub normal: Vec3<f32>,
+}
+
+impl Vertex
+{
+ pub fn attrs() -> &'static [Attribute]
+ {
+ #[allow(clippy::cast_possible_truncation)]
+ &[
+ Attribute {
+ index: 0,
+ component_type: AttributeComponentType::Float,
+ component_cnt: AttributeComponentCnt::Three,
+ component_size: size_of::<f32>() as u32,
+ },
+ Attribute {
+ index: 1,
+ component_type: AttributeComponentType::Float,
+ component_cnt: AttributeComponentCnt::Two,
+ component_size: size_of::<f32>() as u32,
+ },
+ Attribute {
+ index: 2,
+ component_type: AttributeComponentType::Float,
+ component_cnt: AttributeComponentCnt::Three,
+ component_size: size_of::<f32>() as u32,
+ },
+ ]
+ }
+}
+
+#[derive(Debug)]
+pub struct Attribute
+{
+ pub index: u32,
+ pub component_type: AttributeComponentType,
+ pub component_cnt: AttributeComponentCnt,
+ pub component_size: u32,
+}
+
+#[derive(Debug)]
+pub enum AttributeComponentType
+{
+ Float,
+}
+
+#[derive(Debug, Clone, Copy)]
+#[repr(u32)]
+#[allow(dead_code)]
+pub enum AttributeComponentCnt
+{
+ One = 1,
+ Two = 2,
+ Three = 3,
+ Four = 4,
+}