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)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
find_package(OpenGL REQUIRED)
|
||||
find_package(GLEW REQUIRED)
|
||||
@ -11,6 +12,7 @@ find_package(glfw3 REQUIRED)
|
||||
file(GLOB SOURCES src/*.h src/*.cpp)
|
||||
add_executable(opengl_test ${SOURCES})
|
||||
|
||||
target_include_directories(opengl_test PUBLIC include)
|
||||
target_link_libraries(opengl_test
|
||||
OpenGL::GL
|
||||
GLEW::GLEW
|
||||
|
||||
@ -2,11 +2,25 @@
|
||||
|
||||
in vec4 vertex_color;
|
||||
in vec2 texture_coord;
|
||||
in vec3 normal;
|
||||
|
||||
out vec4 color;
|
||||
|
||||
struct Directional_Light {
|
||||
vec3 color;
|
||||
float ambient_intensity;
|
||||
vec3 direction;
|
||||
float diffuse_intensity;
|
||||
};
|
||||
|
||||
uniform sampler2D tex;
|
||||
uniform Directional_Light sun;
|
||||
|
||||
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 = 1) in vec2 tex;
|
||||
layout (location = 2) in vec3 norm;
|
||||
|
||||
out vec4 vertex_color;
|
||||
out vec2 texture_coord;
|
||||
out vec3 normal;
|
||||
|
||||
uniform mat4 projection;
|
||||
uniform mat4 model;
|
||||
@ -14,4 +16,5 @@ void main() {
|
||||
gl_Position = projection * view * model * vec4(pos, 1.0);
|
||||
vertex_color = vec4(clamp(pos, 0.0f, 1.0f), 1.0f);
|
||||
texture_coord = tex;
|
||||
normal = mat3(transpose(inverse(model))) * norm;
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
#include "file.h"
|
||||
|
||||
std::string read_entire_file(const char *path) {
|
||||
std::string content;
|
||||
string read_entire_file(const char *path) {
|
||||
string content;
|
||||
std::ifstream file_stream(path, std::ios::in);
|
||||
|
||||
if (!file_stream.is_open()) {
|
||||
@ -9,7 +9,7 @@ std::string read_entire_file(const char *path) {
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string line = "";
|
||||
string line = "";
|
||||
while (!file_stream.eof())
|
||||
{
|
||||
std::getline(file_stream, line);
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#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 "camera.h"
|
||||
#include "texture.h"
|
||||
#include "light.h"
|
||||
|
||||
|
||||
static const char *vertex_shader_code = "shaders/shader.vert";
|
||||
@ -24,11 +25,11 @@ int main() {
|
||||
{
|
||||
// Create a mesh
|
||||
f32 vertices[] = {
|
||||
// x y z u v
|
||||
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, -1.0f, 1.0f, 1.0f, 0.0f,
|
||||
1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 0.0f, 1.0f
|
||||
// x y z u v nx ny nz
|
||||
-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, 0.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, 0.0f, 0.0f
|
||||
};
|
||||
|
||||
u32 indices[] = {
|
||||
@ -38,12 +39,14 @@ int main() {
|
||||
0, 1, 2
|
||||
};
|
||||
|
||||
calculate_normals_avg(vertices, 32, 8, indices, 12, 5);
|
||||
|
||||
Mesh *pyramid1 = new Mesh();
|
||||
create_mesh(pyramid1, vertices, indices, 20, 12);
|
||||
create_mesh(pyramid1, vertices, indices, 32, 12);
|
||||
meshes[0] = pyramid1;
|
||||
|
||||
Mesh *pyramid2 = new Mesh();
|
||||
create_mesh(pyramid2, vertices, indices, 20, 12);
|
||||
create_mesh(pyramid2, vertices, indices, 32, 12);
|
||||
meshes[1] = pyramid2;
|
||||
}
|
||||
|
||||
@ -60,9 +63,9 @@ int main() {
|
||||
Texture plaster_texture = Texture((char *)"assets/textures/plaster_texture_1k.png");
|
||||
load_texture(&plaster_texture);
|
||||
|
||||
Matrix4 projection = glm::perspective(
|
||||
45.0f, (f32)window.buffer_width / (f32)window.buffer_height, 0.1f,
|
||||
100.0f);
|
||||
Light sun_light(Vector3(1.0f, 1.0f, 1.0f), 0.2f, Vector3(2.0f, -1.0, -2.0f), 1.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);
|
||||
|
||||
@ -74,9 +77,6 @@ int main() {
|
||||
dt = now - last_dt;
|
||||
last_dt = now;
|
||||
|
||||
// Get and handle user input events
|
||||
glfwPollEvents();
|
||||
|
||||
key_control(&camera, window.ascii_keys, dt);
|
||||
mouse_control(&camera, window.x_change_position, window.y_change_position);
|
||||
|
||||
@ -90,6 +90,12 @@ int main() {
|
||||
|
||||
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);
|
||||
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
|
||||
// buffer.
|
||||
glfwSwapBuffers(window.gl_window);
|
||||
|
||||
// Get and handle user input events
|
||||
glfwPollEvents();
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
// #include <cstdint>
|
||||
#include <string>
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
@ -34,5 +35,7 @@ typedef double f64;
|
||||
|
||||
using Matrix4 = glm::mat4;
|
||||
using Vector3 = glm::vec3;
|
||||
using string = std::string;
|
||||
|
||||
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);
|
||||
|
||||
// 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);
|
||||
|
||||
// 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);
|
||||
|
||||
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(vertices[0]) * 8, (void *)(sizeof(vertices[0]) * 5));
|
||||
glEnableVertexAttribArray(2);
|
||||
|
||||
// Unbinding
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
@ -73,3 +76,51 @@ void clear_mesh(Mesh *mesh) {
|
||||
|
||||
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 render_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) {
|
||||
std::string vertex_shader_code = read_entire_file(vertex_shader_path);
|
||||
std::string fragment_shader_code = read_entire_file(fragment_shader_path);
|
||||
string vertex_shader_code = read_entire_file(vertex_shader_path);
|
||||
string fragment_shader_code = read_entire_file(fragment_shader_path);
|
||||
|
||||
|
||||
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_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;
|
||||
}
|
||||
|
||||
|
||||
@ -15,6 +15,10 @@ struct Shader {
|
||||
u32 uniform_projection;
|
||||
u32 uniform_model;
|
||||
u32 uniform_view;
|
||||
u32 uniform_ambient_color;
|
||||
u32 uniform_ambient_intensity;
|
||||
u32 uniform_diffuse_direction;
|
||||
u32 uniform_diffuse_intensity;
|
||||
|
||||
Shader();
|
||||
~Shader();
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <GL/glew.h>
|
||||
#include <stb_image.h>
|
||||
#include "math.h"
|
||||
#include "../lib/stb_image.h"
|
||||
|
||||
struct Texture {
|
||||
u32 id = 0;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user