Add diffuse lighting
This commit is contained in:
parent
5adc6e80e6
commit
c746f1d8eb
@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.19)
|
|||||||
project(OpenGLTest CXX)
|
project(OpenGLTest CXX)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
|
|
||||||
find_package(OpenGL REQUIRED)
|
find_package(OpenGL REQUIRED)
|
||||||
find_package(GLEW REQUIRED)
|
find_package(GLEW REQUIRED)
|
||||||
@ -11,6 +12,7 @@ find_package(glfw3 REQUIRED)
|
|||||||
file(GLOB SOURCES src/*.h src/*.cpp)
|
file(GLOB SOURCES src/*.h src/*.cpp)
|
||||||
add_executable(opengl_test ${SOURCES})
|
add_executable(opengl_test ${SOURCES})
|
||||||
|
|
||||||
|
target_include_directories(opengl_test PUBLIC include)
|
||||||
target_link_libraries(opengl_test
|
target_link_libraries(opengl_test
|
||||||
OpenGL::GL
|
OpenGL::GL
|
||||||
GLEW::GLEW
|
GLEW::GLEW
|
||||||
|
|||||||
@ -2,11 +2,25 @@
|
|||||||
|
|
||||||
in vec4 vertex_color;
|
in vec4 vertex_color;
|
||||||
in vec2 texture_coord;
|
in vec2 texture_coord;
|
||||||
|
in vec3 normal;
|
||||||
|
|
||||||
out vec4 color;
|
out vec4 color;
|
||||||
|
|
||||||
|
struct Directional_Light {
|
||||||
|
vec3 color;
|
||||||
|
float ambient_intensity;
|
||||||
|
vec3 direction;
|
||||||
|
float diffuse_intensity;
|
||||||
|
};
|
||||||
|
|
||||||
uniform sampler2D tex;
|
uniform sampler2D tex;
|
||||||
|
uniform Directional_Light sun;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
color = texture(tex, texture_coord);
|
vec4 ambient_color = vec4(sun.color, 1.0f) * sun.ambient_intensity;
|
||||||
|
|
||||||
|
float diffuse_factor = max(dot(normalize(normal), normalize(sun.direction)), 0.0f);
|
||||||
|
vec4 diffuse_color = vec4(sun.color, 1.0f) * sun.diffuse_intensity * diffuse_factor;
|
||||||
|
|
||||||
|
color = texture(tex, texture_coord) * (ambient_color + diffuse_color);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,9 +2,11 @@
|
|||||||
|
|
||||||
layout (location = 0) in vec3 pos;
|
layout (location = 0) in vec3 pos;
|
||||||
layout (location = 1) in vec2 tex;
|
layout (location = 1) in vec2 tex;
|
||||||
|
layout (location = 2) in vec3 norm;
|
||||||
|
|
||||||
out vec4 vertex_color;
|
out vec4 vertex_color;
|
||||||
out vec2 texture_coord;
|
out vec2 texture_coord;
|
||||||
|
out vec3 normal;
|
||||||
|
|
||||||
uniform mat4 projection;
|
uniform mat4 projection;
|
||||||
uniform mat4 model;
|
uniform mat4 model;
|
||||||
@ -14,4 +16,5 @@ void main() {
|
|||||||
gl_Position = projection * view * model * vec4(pos, 1.0);
|
gl_Position = projection * view * model * vec4(pos, 1.0);
|
||||||
vertex_color = vec4(clamp(pos, 0.0f, 1.0f), 1.0f);
|
vertex_color = vec4(clamp(pos, 0.0f, 1.0f), 1.0f);
|
||||||
texture_coord = tex;
|
texture_coord = tex;
|
||||||
|
normal = mat3(transpose(inverse(model))) * norm;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
#include "file.h"
|
#include "file.h"
|
||||||
|
|
||||||
std::string read_entire_file(const char *path) {
|
string read_entire_file(const char *path) {
|
||||||
std::string content;
|
string content;
|
||||||
std::ifstream file_stream(path, std::ios::in);
|
std::ifstream file_stream(path, std::ios::in);
|
||||||
|
|
||||||
if (!file_stream.is_open()) {
|
if (!file_stream.is_open()) {
|
||||||
@ -9,7 +9,7 @@ std::string read_entire_file(const char *path) {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string line = "";
|
string line = "";
|
||||||
while (!file_stream.eof())
|
while (!file_stream.eof())
|
||||||
{
|
{
|
||||||
std::getline(file_stream, line);
|
std::getline(file_stream, line);
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <iostream>
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include "math.h"
|
||||||
|
|
||||||
std::string read_entire_file(const char *path);
|
string read_entire_file(const char *path);
|
||||||
|
|||||||
12
src/light.cpp
Normal file
12
src/light.cpp
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#include "light.h"
|
||||||
|
|
||||||
|
Light::Light(Vector3 color, f32 ambient_intensity, Vector3 direction, f32 diffuse_intensity) : color(color), ambient_intensity(ambient_intensity), direction(direction), diffuse_intensity(diffuse_intensity) {}
|
||||||
|
|
||||||
|
void use_light(Light *light, f32 color_location, f32 ambient_intensity_location, f32 direction_location, f32 diffuse_intensity_location) {
|
||||||
|
glUniform3f(color_location, light->color.x, light->color.y, light->color.z);
|
||||||
|
glUniform1f(ambient_intensity_location, light->ambient_intensity);
|
||||||
|
|
||||||
|
glUniform3f(direction_location, light->direction.x, light->direction.y, light->direction.z);
|
||||||
|
glUniform1f(diffuse_intensity_location, light->diffuse_intensity);
|
||||||
|
}
|
||||||
|
|
||||||
19
src/light.h
Normal file
19
src/light.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include "math.h"
|
||||||
|
|
||||||
|
struct Light {
|
||||||
|
Vector3 color = Vector3(1.0f, 1.0f, 1.0f);
|
||||||
|
f32 ambient_intensity = 1.0f;
|
||||||
|
|
||||||
|
// For a directional light
|
||||||
|
Vector3 direction = Vector3(0.0f, -1.0f, 0.0f); // Default to down
|
||||||
|
f32 diffuse_intensity = 0.0f;
|
||||||
|
|
||||||
|
Light(Vector3 color, f32 ambient_intensity, Vector3 direction, f32 diffuse_intensity);
|
||||||
|
~Light() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
void use_light(Light *light, f32 color_location, f32 ambient_intensity_location, f32 direction_location, f32 diffuse_intensity_location);
|
||||||
35
src/main.cpp
35
src/main.cpp
@ -5,6 +5,7 @@
|
|||||||
#include "window.h"
|
#include "window.h"
|
||||||
#include "camera.h"
|
#include "camera.h"
|
||||||
#include "texture.h"
|
#include "texture.h"
|
||||||
|
#include "light.h"
|
||||||
|
|
||||||
|
|
||||||
static const char *vertex_shader_code = "shaders/shader.vert";
|
static const char *vertex_shader_code = "shaders/shader.vert";
|
||||||
@ -24,11 +25,11 @@ int main() {
|
|||||||
{
|
{
|
||||||
// Create a mesh
|
// Create a mesh
|
||||||
f32 vertices[] = {
|
f32 vertices[] = {
|
||||||
// x y z u v
|
// x y z u v nx ny nz
|
||||||
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
|
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
|
||||||
0.0f, -1.0f, 1.0f, 1.0f, 0.0f,
|
0.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
|
||||||
1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
|
1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
|
||||||
0.0f, 1.0f, 0.0f, 0.0f, 1.0f
|
0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f
|
||||||
};
|
};
|
||||||
|
|
||||||
u32 indices[] = {
|
u32 indices[] = {
|
||||||
@ -38,12 +39,14 @@ int main() {
|
|||||||
0, 1, 2
|
0, 1, 2
|
||||||
};
|
};
|
||||||
|
|
||||||
|
calculate_normals_avg(vertices, 32, 8, indices, 12, 5);
|
||||||
|
|
||||||
Mesh *pyramid1 = new Mesh();
|
Mesh *pyramid1 = new Mesh();
|
||||||
create_mesh(pyramid1, vertices, indices, 20, 12);
|
create_mesh(pyramid1, vertices, indices, 32, 12);
|
||||||
meshes[0] = pyramid1;
|
meshes[0] = pyramid1;
|
||||||
|
|
||||||
Mesh *pyramid2 = new Mesh();
|
Mesh *pyramid2 = new Mesh();
|
||||||
create_mesh(pyramid2, vertices, indices, 20, 12);
|
create_mesh(pyramid2, vertices, indices, 32, 12);
|
||||||
meshes[1] = pyramid2;
|
meshes[1] = pyramid2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,9 +63,9 @@ int main() {
|
|||||||
Texture plaster_texture = Texture((char *)"assets/textures/plaster_texture_1k.png");
|
Texture plaster_texture = Texture((char *)"assets/textures/plaster_texture_1k.png");
|
||||||
load_texture(&plaster_texture);
|
load_texture(&plaster_texture);
|
||||||
|
|
||||||
Matrix4 projection = glm::perspective(
|
Light sun_light(Vector3(1.0f, 1.0f, 1.0f), 0.2f, Vector3(2.0f, -1.0, -2.0f), 1.0f);
|
||||||
45.0f, (f32)window.buffer_width / (f32)window.buffer_height, 0.1f,
|
|
||||||
100.0f);
|
Matrix4 projection = glm::perspective(45.0f, (f32)window.buffer_width / (f32)window.buffer_height, 0.1f, 100.0f);
|
||||||
|
|
||||||
Camera camera(Vector3(0.0f, 0.0f, 0.0f), Vector3(0.0f, 1.0f, 0.0f), 90.0f, 0.0f, 5.0f, 1.0f);
|
Camera camera(Vector3(0.0f, 0.0f, 0.0f), Vector3(0.0f, 1.0f, 0.0f), 90.0f, 0.0f, 5.0f, 1.0f);
|
||||||
|
|
||||||
@ -74,9 +77,6 @@ int main() {
|
|||||||
dt = now - last_dt;
|
dt = now - last_dt;
|
||||||
last_dt = now;
|
last_dt = now;
|
||||||
|
|
||||||
// Get and handle user input events
|
|
||||||
glfwPollEvents();
|
|
||||||
|
|
||||||
key_control(&camera, window.ascii_keys, dt);
|
key_control(&camera, window.ascii_keys, dt);
|
||||||
mouse_control(&camera, window.x_change_position, window.y_change_position);
|
mouse_control(&camera, window.x_change_position, window.y_change_position);
|
||||||
|
|
||||||
@ -90,6 +90,12 @@ int main() {
|
|||||||
|
|
||||||
glUseProgram(shaders[0].id);
|
glUseProgram(shaders[0].id);
|
||||||
|
|
||||||
|
use_light(
|
||||||
|
&sun_light,
|
||||||
|
shaders[0].uniform_ambient_color, shaders[0].uniform_ambient_intensity,
|
||||||
|
shaders[0].uniform_diffuse_direction, shaders[0].uniform_diffuse_intensity
|
||||||
|
);
|
||||||
|
|
||||||
{
|
{
|
||||||
Matrix4 model(1.0f);
|
Matrix4 model(1.0f);
|
||||||
model = glm::translate(model, Vector3(0.0f, 0.0f, -2.5f));
|
model = glm::translate(model, Vector3(0.0f, 0.0f, -2.5f));
|
||||||
@ -125,6 +131,9 @@ int main() {
|
|||||||
// that it now shows. We then can start drawing on the other
|
// that it now shows. We then can start drawing on the other
|
||||||
// buffer.
|
// buffer.
|
||||||
glfwSwapBuffers(window.gl_window);
|
glfwSwapBuffers(window.gl_window);
|
||||||
|
|
||||||
|
// Get and handle user input events
|
||||||
|
glfwPollEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cstdint>
|
// #include <cstdint>
|
||||||
|
#include <string>
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
#include <glm/gtc/type_ptr.hpp>
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
@ -34,5 +35,7 @@ typedef double f64;
|
|||||||
|
|
||||||
using Matrix4 = glm::mat4;
|
using Matrix4 = glm::mat4;
|
||||||
using Vector3 = glm::vec3;
|
using Vector3 = glm::vec3;
|
||||||
|
using string = std::string;
|
||||||
|
|
||||||
const f32 RADIAN_FACTOR = 3.14159265f / 180.0f;
|
const f32 RADIAN_FACTOR = 3.14159265f / 180.0f;
|
||||||
|
|
||||||
|
|||||||
55
src/mesh.cpp
55
src/mesh.cpp
@ -32,13 +32,16 @@ void create_mesh(
|
|||||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices_count, vertices, GL_STATIC_DRAW);
|
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices_count, vertices, GL_STATIC_DRAW);
|
||||||
|
|
||||||
// Position vertices
|
// Position vertices
|
||||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(vertices[0]) * 5, 0);
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(vertices[0]) * 8, 0);
|
||||||
glEnableVertexAttribArray(0);
|
glEnableVertexAttribArray(0);
|
||||||
|
|
||||||
// Texture coordinates
|
// Texture coordinates
|
||||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(vertices[0]) * 5, (void *)(sizeof(vertices[0]) * 3));
|
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(vertices[0]) * 8, (void *)(sizeof(vertices[0]) * 3));
|
||||||
glEnableVertexAttribArray(1);
|
glEnableVertexAttribArray(1);
|
||||||
|
|
||||||
|
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(vertices[0]) * 8, (void *)(sizeof(vertices[0]) * 5));
|
||||||
|
glEnableVertexAttribArray(2);
|
||||||
|
|
||||||
// Unbinding
|
// Unbinding
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
@ -73,3 +76,51 @@ void clear_mesh(Mesh *mesh) {
|
|||||||
|
|
||||||
mesh->index_count = 0;
|
mesh->index_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void calculate_normals_avg(f32 *vertices, u32 vertices_count, u32 vertices_length, u32 *indices, u32 indices_count, u32 normal_offset) {
|
||||||
|
for (size_t i = 0; i< indices_count; i+=3) {
|
||||||
|
u32 in0 = indices[i] * vertices_length;
|
||||||
|
u32 in1 = indices[i+1] * vertices_length;
|
||||||
|
u32 in2 = indices[i+2] * vertices_length;
|
||||||
|
|
||||||
|
Vector3 v1;
|
||||||
|
v1.x = vertices[in1] - vertices[in0];
|
||||||
|
v1.y = vertices[in1+1] - vertices[in0+1];
|
||||||
|
v1.z = vertices[in1+2] - vertices[in0+2];
|
||||||
|
|
||||||
|
Vector3 v2;
|
||||||
|
v2.x = vertices[in2] - vertices[in0];
|
||||||
|
v2.y = vertices[in2+1] - vertices[in0+1];
|
||||||
|
v2.z = vertices[in2+2] - vertices[in0+2];
|
||||||
|
|
||||||
|
Vector3 normal = glm::cross(v1, v2);
|
||||||
|
normal = glm::normalize(normal);
|
||||||
|
|
||||||
|
in0 += normal_offset;
|
||||||
|
in1 += normal_offset;
|
||||||
|
in2 += normal_offset;
|
||||||
|
|
||||||
|
vertices[in0] += normal.x;
|
||||||
|
vertices[in0+1] += normal.y;
|
||||||
|
vertices[in0+2] += normal.z;
|
||||||
|
|
||||||
|
vertices[in1] += normal.x;
|
||||||
|
vertices[in1+1] += normal.y;
|
||||||
|
vertices[in1+2] += normal.z;
|
||||||
|
|
||||||
|
vertices[in2] += normal.x;
|
||||||
|
vertices[in2+1] += normal.y;
|
||||||
|
vertices[in2+2] += normal.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(size_t i=0; i<vertices_count/vertices_length; i++) {
|
||||||
|
u32 n_offset = i * vertices_length + normal_offset;
|
||||||
|
Vector3 vector(vertices[n_offset], vertices[n_offset+1], vertices[n_offset+2]);
|
||||||
|
vector = glm::normalize(vector);
|
||||||
|
|
||||||
|
vertices[n_offset] = vector.x;
|
||||||
|
vertices[n_offset+1] = vector.y;
|
||||||
|
vertices[n_offset+2] = vector.z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@ -14,4 +14,5 @@ struct Mesh {
|
|||||||
void create_mesh(Mesh *mesh, f32 *vertices, u32 *indices, u32 vertices_count, u32 indices_count);
|
void create_mesh(Mesh *mesh, f32 *vertices, u32 *indices, u32 vertices_count, u32 indices_count);
|
||||||
void render_mesh(Mesh *mesh);
|
void render_mesh(Mesh *mesh);
|
||||||
void clear_mesh(Mesh *mesh);
|
void clear_mesh(Mesh *mesh);
|
||||||
|
void calculate_normals_avg(f32 *vertices, u32 vertices_count, u32 vertices_length, u32 *indices, u32 indices_count, u32 normal_offset);
|
||||||
|
|
||||||
|
|||||||
@ -11,8 +11,8 @@ Shader::~Shader() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool create_shader(Shader *shader, const char *vertex_shader_path, const char *fragment_shader_path) {
|
bool create_shader(Shader *shader, const char *vertex_shader_path, const char *fragment_shader_path) {
|
||||||
std::string vertex_shader_code = read_entire_file(vertex_shader_path);
|
string vertex_shader_code = read_entire_file(vertex_shader_path);
|
||||||
std::string fragment_shader_code = read_entire_file(fragment_shader_path);
|
string fragment_shader_code = read_entire_file(fragment_shader_path);
|
||||||
|
|
||||||
|
|
||||||
shader->id = glCreateProgram();
|
shader->id = glCreateProgram();
|
||||||
@ -65,6 +65,12 @@ bool create_shader(Shader *shader, const char *vertex_shader_path, const char *f
|
|||||||
shader->uniform_model = glGetUniformLocation(shader->id, "model");
|
shader->uniform_model = glGetUniformLocation(shader->id, "model");
|
||||||
shader->uniform_view = glGetUniformLocation(shader->id, "view");
|
shader->uniform_view = glGetUniformLocation(shader->id, "view");
|
||||||
|
|
||||||
|
shader->uniform_ambient_color = glGetUniformLocation(shader->id, "sun.color");
|
||||||
|
shader->uniform_ambient_intensity = glGetUniformLocation(shader->id, "sun.ambient_intensity");
|
||||||
|
|
||||||
|
shader->uniform_diffuse_direction = glGetUniformLocation(shader->id, "sun.direction");
|
||||||
|
shader->uniform_diffuse_intensity = glGetUniformLocation(shader->id, "sun.diffuse_intensity");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -15,6 +15,10 @@ struct Shader {
|
|||||||
u32 uniform_projection;
|
u32 uniform_projection;
|
||||||
u32 uniform_model;
|
u32 uniform_model;
|
||||||
u32 uniform_view;
|
u32 uniform_view;
|
||||||
|
u32 uniform_ambient_color;
|
||||||
|
u32 uniform_ambient_intensity;
|
||||||
|
u32 uniform_diffuse_direction;
|
||||||
|
u32 uniform_diffuse_intensity;
|
||||||
|
|
||||||
Shader();
|
Shader();
|
||||||
~Shader();
|
~Shader();
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
|
#include <stb_image.h>
|
||||||
#include "math.h"
|
#include "math.h"
|
||||||
#include "../lib/stb_image.h"
|
|
||||||
|
|
||||||
struct Texture {
|
struct Texture {
|
||||||
u32 id = 0;
|
u32 id = 0;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user