more work on lighting

This commit is contained in:
hippoz 2023-07-25 11:52:12 +03:00
parent 85f87152ad
commit 28c4f16d71
Signed by: hippoz
GPG key ID: 56C4E02A85F2FBED
9 changed files with 240 additions and 96 deletions

BIN
assets/fish-map.qoi Normal file

Binary file not shown.

BIN
assets/fish.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

View file

@ -1,14 +0,0 @@
#version 330 core
in vec2 TexCoord;
out vec4 FragColor;
uniform sampler2D tex;
void main()
{
FragColor = texture(tex, TexCoord);
}

View file

@ -0,0 +1,7 @@
#version 330 core
out vec4 FragColor;
void main()
{
FragColor = vec4(1.0);
}

View file

@ -0,0 +1,11 @@
#version 330 core
layout (location = 0) in vec3 aPos;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
gl_Position = projection * view * model * vec4(aPos, 1.0);
}

View file

@ -0,0 +1,88 @@
#version 330 core
out vec4 FragColor;
in vec3 Normal;
in vec3 FragPos;
in vec2 TexCoords;
struct Material {
sampler2D diffuse;
sampler2D specular;
float shininess;
};
struct PointLight {
vec3 position;
vec3 ambient;
vec3 diffuse;
vec3 specular;
float constant;
float linear;
float quadratic;
};
struct DirectionalLight {
vec3 direction;
vec3 ambient;
vec3 diffuse;
vec3 specular;
};
#define POINT_LIGHTS_COUNT 4
uniform Material material;
uniform vec3 viewPos;
uniform DirectionalLight directionalLight;
uniform PointLight pointLights[POINT_LIGHTS_COUNT];
vec3 ComputeDirectionalLight(DirectionalLight light, vec3 norm, vec3 viewDir)
{
vec3 lightDir = normalize(-light.direction);
vec3 reflectDir = reflect(-lightDir, norm);
float diff = max(dot(norm, lightDir), 0.0);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords));
vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords));
vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords));
return (ambient + diffuse + specular);
}
vec3 ComputePointLight(PointLight light, vec3 norm, vec3 viewDir)
{
float distance = length(light.position - FragPos);
float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance));
vec3 lightDir = normalize(light.position - FragPos);
vec3 reflectDir = reflect(-lightDir, norm);
float diff = max(dot(norm, lightDir), 0.0);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords));
vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords));
vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords));
return (ambient * attenuation + diffuse * attenuation + specular * attenuation);
}
void main()
{
vec3 norm = normalize(Normal);
vec3 viewDir = normalize(viewPos - FragPos);
vec3 result = vec3(0.0);
result += ComputeDirectionalLight(directionalLight, norm, viewDir);
for (int i = 0; i < POINT_LIGHTS_COUNT; i++) {
result += ComputePointLight(pointLights[i], norm, viewDir);
}
FragColor = vec4(result, 1.0);
}

View file

@ -0,0 +1,20 @@
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
layout (location = 2) in vec2 aTexCoords;
out vec3 Normal;
out vec3 FragPos;
out vec2 TexCoords;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
gl_Position = projection * view * model * vec4(aPos, 1.0);
FragPos = vec3(model * vec4(aPos, 1.0));
Normal = mat3(transpose(inverse(model))) * aNormal;
TexCoords = aTexCoords;
}

View file

@ -1,18 +0,0 @@
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoord;
out vec2 TexCoord;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
gl_Position = projection * view * model * vec4(aPos, 1.0);
TexCoord = aTexCoord;
}

View file

@ -26,6 +26,9 @@ int main()
qoi_desc fish_desc; qoi_desc fish_desc;
void *fish_rgba = qoi_read("assets/fish.qoi", &fish_desc, 4); void *fish_rgba = qoi_read("assets/fish.qoi", &fish_desc, 4);
qoi_desc fish_map_desc;
void *fish_map_rgba = qoi_read("assets/fish-map.qoi", &fish_map_desc, 4);
if (!glfwInit()) { if (!glfwInit()) {
return 1; return 1;
@ -59,81 +62,99 @@ int main()
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
float verts[] = { float cube_verts[] = {
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, // positions // normals // texture coords
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f, -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f, -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 1.0f, 1.0f, -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f, -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f, -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f, -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f, -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f, -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f, -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f
}; };
unsigned int program = create_program("shaders/vertex.glsl", "shaders/fragment.glsl"); unsigned int fish_texture;
glGenTextures(1, &fish_texture);
unsigned int texture; glBindTexture(GL_TEXTURE_2D, fish_texture);
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, fish_desc.width, fish_desc.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, fish_rgba); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, fish_desc.width, fish_desc.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, fish_rgba);
glGenerateMipmap(GL_TEXTURE_2D); glGenerateMipmap(GL_TEXTURE_2D);
unsigned int vertex_array; unsigned int fish_map_texture;
glGenVertexArrays(1, &vertex_array); glGenTextures(1, &fish_map_texture);
glBindVertexArray(vertex_array); glBindTexture(GL_TEXTURE_2D, fish_map_texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, fish_map_desc.width, fish_map_desc.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, fish_map_rgba);
glGenerateMipmap(GL_TEXTURE_2D);
unsigned int buffer = 0; unsigned int lighting_program = create_program("shaders/lighting_vertex.glsl", "shaders/lighting_fragment.glsl");
glGenBuffers(1, &buffer); unsigned int light_cube_program = create_program("shaders/light_cube_vertex.glsl", "shaders/light_cube_fragment.glsl");
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(verts), &verts, GL_STATIC_DRAW); unsigned int cube_buffer = 0;
glGenBuffers(1, &cube_buffer);
glBindBuffer(GL_ARRAY_BUFFER, cube_buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(cube_verts), &cube_verts, GL_STATIC_DRAW);
unsigned int object_vao;
glGenVertexArrays(1, &object_vao);
glBindVertexArray(object_vao);
// position // position
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (const void*)0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (const void*)0);
glEnableVertexAttribArray(0);
// normal
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (const void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
// texture coord
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (const void*)(6 * sizeof(float)));
glEnableVertexAttribArray(2);
unsigned int light_source_vao;
glGenVertexArrays(1, &light_source_vao);
glBindVertexArray(light_source_vao);
// position
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (const void*)0);
glEnableVertexAttribArray(0); glEnableVertexAttribArray(0);
// texture coords
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (const void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
glm::mat4 projection = glm::mat4(1.0f); glm::mat4 projection = glm::mat4(1.0f);
Camera camera; Camera camera;
framebuffer_size_callback = [&projection, program](int width, int height) { framebuffer_size_callback = [&projection](int width, int height) {
projection = glm::perspective(glm::radians(45.0f), (float)width / (float)height, 0.1f, 100.0f); projection = glm::perspective(glm::radians(45.0f), (float)width / (float)height, 0.1f, 100.0f);
glUniformMatrix4fv(glGetUniformLocation(program, "projection"), 1, GL_FALSE, glm::value_ptr(projection));
glViewport(0, 0, width, height); glViewport(0, 0, width, height);
}; };
@ -144,6 +165,8 @@ int main()
float delta_time = 0.0f; float delta_time = 0.0f;
float last_frame_time = 0.0f; float last_frame_time = 0.0f;
glm::vec3 light_position(1.2f, 1.0f, 2.0f);
while (!glfwWindowShouldClose(window)) { while (!glfwWindowShouldClose(window)) {
float current_frame_time = glfwGetTime(); float current_frame_time = glfwGetTime();
delta_time = current_frame_time - last_frame_time; delta_time = current_frame_time - last_frame_time;
@ -171,16 +194,43 @@ int main()
glClearColor(0.5, 0.5, 0.5, 1.0); glClearColor(0.5, 0.5, 0.5, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(program); {
glUniformMatrix4fv(glGetUniformLocation(program, "view"), 1, GL_FALSE, glm::value_ptr(camera.view)); /* lit object */
{
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, fish_texture);
glActiveTexture (GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, fish_map_texture);
glBindTexture(GL_TEXTURE_2D, texture); glUseProgram(lighting_program);
glBindVertexArray(vertex_array);
for (int i = 0; i < 12; i++) { glBindVertexArray(object_vao);
glm::mat4 model = glm::translate(glm::mat4(1.0), glm::vec3(2 * i, 0.0f, 0.0f)); glUniformMatrix4fv(glGetUniformLocation(lighting_program, "projection"), 1, GL_FALSE, glm::value_ptr(projection));
glUniformMatrix4fv(glGetUniformLocation(program, "model"), 1, GL_FALSE, glm::value_ptr(model)); glUniformMatrix4fv(glGetUniformLocation(lighting_program, "view"), 1, GL_FALSE, glm::value_ptr(camera.view));
glDrawArrays(GL_TRIANGLES, 0, 36); glUniformMatrix4fv(glGetUniformLocation(lighting_program, "model"), 1, GL_FALSE, glm::value_ptr(glm::mat4(1.0f)));
glUniform3fv(glGetUniformLocation(lighting_program, "viewPos"), 1, glm::value_ptr(camera.position));
glUniform1i(glGetUniformLocation(lighting_program, "material.diffuse"), 0);
glUniform1i(glGetUniformLocation(lighting_program, "material.specular"), 1);
glUniform1f(glGetUniformLocation(lighting_program, "material.shininess"), 32.0f);
glUniform3fv(glGetUniformLocation(lighting_program, "light.position"), 1, glm::value_ptr(light_position));
glUniform3f(glGetUniformLocation(lighting_program, "light.ambient"), 0.2f, 0.2f, 0.2f);
glUniform3f(glGetUniformLocation(lighting_program, "light.diffuse"), 0.5f, 0.5f, 0.5f);
glUniform3f(glGetUniformLocation(lighting_program, "light.specular"), 1.0f, 1.0f, 1.0f);
glDrawArrays(GL_TRIANGLES, 0, 36);
}
/* lamp object */
{
glUseProgram(light_cube_program);
glBindVertexArray(light_source_vao);
glUniformMatrix4fv(glGetUniformLocation(light_cube_program, "projection"), 1, GL_FALSE, glm::value_ptr(projection));
glUniformMatrix4fv(glGetUniformLocation(light_cube_program, "view"), 1, GL_FALSE, glm::value_ptr(camera.view));
glUniformMatrix4fv(glGetUniformLocation(light_cube_program, "model"), 1, GL_FALSE, glm::value_ptr(glm::scale(glm::translate(glm::mat4(1.0f), light_position), glm::vec3(0.2f))));
glDrawArrays(GL_TRIANGLES, 0, 36);
}
} }
glfwSwapBuffers(window); glfwSwapBuffers(window);