aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjvech <jmvalenciae@unal.edu.co>2022-09-11 13:54:51 -0500
committerjvech <jmvalenciae@unal.edu.co>2022-09-11 13:54:51 -0500
commit86c7bdee944ce2f60d63124e9ddb76198ddbc676 (patch)
treeb15a18f9439f11a92de94bf3be16c736a8c927ed
parentab2160bdd347f4cd827835f1687437d25fae94c6 (diff)
learn: 14. Materials learnopengl book
-rw-r--r--shaders/color.fsh44
-rw-r--r--shaders/color.vsh17
-rw-r--r--shaders/fragment.fsh9
-rw-r--r--shaders/lightsource.fsh7
-rw-r--r--shaders/lightsource.vsh (renamed from shaders/vertex.vsh)3
-rw-r--r--src/main.c116
-rw-r--r--src/main.h7
-rw-r--r--src/shader.c22
-rw-r--r--src/shader.h15
9 files changed, 195 insertions, 45 deletions
diff --git a/shaders/color.fsh b/shaders/color.fsh
new file mode 100644
index 0000000..4989d73
--- /dev/null
+++ b/shaders/color.fsh
@@ -0,0 +1,44 @@
+# version 330 core
+
+struct Material {
+ vec3 ambient;
+ vec3 diffuse;
+ vec3 specular;
+ float shininess;
+};
+
+struct Light {
+ vec3 position;
+ vec3 ambient;
+ vec3 diffuse;
+ vec3 specular;
+};
+
+in vec3 Normal;
+in vec3 FragPos;
+
+out vec4 FragColor;
+
+uniform vec3 viewPos;
+uniform Material material;
+uniform Light light;
+
+void main()
+{
+ // ambient
+ vec3 ambient = material.ambient * light.ambient;
+
+ // diffuse
+ vec3 norm = normalize(Normal);
+ vec3 lightDir = normalize(light.position - FragPos);
+ float diff = max(dot(norm, lightDir), 0.0);
+ vec3 diffuse = light.diffuse * diff * material.diffuse;
+
+ // specular
+ vec3 viewDir = normalize(viewPos - FragPos);
+ vec3 reflectDir = reflect(-lightDir, norm);
+ float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
+ vec3 specular = light.specular * spec * material.specular;
+
+ FragColor = vec4((specular + ambient + diffuse), 1.0f);
+}
diff --git a/shaders/color.vsh b/shaders/color.vsh
new file mode 100644
index 0000000..ff878be
--- /dev/null
+++ b/shaders/color.vsh
@@ -0,0 +1,17 @@
+# version 330 core
+
+layout (location = 0) in vec3 aPos;
+layout (location = 1) in vec3 aNormal;
+
+uniform mat4 model, view, proj;
+uniform mat4 rotNormals;
+
+out vec3 FragPos;
+out vec3 Normal;
+
+void main()
+{
+ gl_Position = proj * view * model * vec4(aPos, 1.0f);
+ FragPos = vec3(model * vec4(aPos, 1.0));
+ Normal = vec3(rotNormals * vec4(aNormal, 1.0));
+}
diff --git a/shaders/fragment.fsh b/shaders/fragment.fsh
deleted file mode 100644
index 2d87daa..0000000
--- a/shaders/fragment.fsh
+++ /dev/null
@@ -1,9 +0,0 @@
-# version 330 core
-
-in vec3 vertexColor;
-out vec4 FragColor;
-
-void main()
-{
- FragColor = vec4(vertexColor, 0.0f);
-}
diff --git a/shaders/lightsource.fsh b/shaders/lightsource.fsh
new file mode 100644
index 0000000..1bd96c6
--- /dev/null
+++ b/shaders/lightsource.fsh
@@ -0,0 +1,7 @@
+#version 330 core
+out vec4 FragColor;
+
+void main()
+{
+ FragColor = vec4(1.0);
+}
diff --git a/shaders/vertex.vsh b/shaders/lightsource.vsh
index 987dc3b..3525c32 100644
--- a/shaders/vertex.vsh
+++ b/shaders/lightsource.vsh
@@ -1,13 +1,10 @@
# version 330 core
layout (location = 0) in vec3 aPos;
-layout (location = 1) in vec3 aColor;
uniform mat4 model, view, proj;
-out vec3 vertexColor;
void main()
{
gl_Position = proj * view * model * vec4(aPos, 1.0f);
- vertexColor = aColor;
}
diff --git a/src/main.c b/src/main.c
index bd7f95c..c296691 100644
--- a/src/main.c
+++ b/src/main.c
@@ -8,6 +8,7 @@
#include <math.h>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
+#include "../include/stb_image.h"
#include "main.h"
#include "linear.h"
@@ -20,14 +21,47 @@ struct Camera {
};
float vertices[] = {
- -0.5,-0.5,-0.5, 1.0, 1.0, 1.0,
- 0.5,-0.5,-0.5, 1.0, 1.0, 0.0,
- -0.5, 0.5,-0.5, 1.0, 0.0, 1.0,
- 0.5, 0.5,-0.5, 1.0, 0.0, 0.0,
- -0.5,-0.5, 0.5, 0.0, 1.0, 1.0,
- 0.5,-0.5, 0.5, 0.0, 1.0, 0.0,
+ -0.5,-0.5,-0.5, 0.0, 0.0,-1.0,
+ 0.5,-0.5,-0.5, 0.0, 0.0,-1.0,
+ 0.5, 0.5,-0.5, 0.0, 0.0,-0.0,
+ 0.5, 0.5,-0.5, 0.0, 0.0,-0.0,
+ -0.5, 0.5,-0.5, 0.0, 0.0,-1.0,
+ -0.5,-0.5,-0.5, 0.0, 0.0,-1.0,
+
+ -0.5,-0.5, 0.5, 0.0, 0.0, 1.0,
+ 0.5,-0.5, 0.5, 0.0, 0.0, 1.0,
+ 0.5, 0.5, 0.5, 0.0, 0.0, 1.0,
+ 0.5, 0.5, 0.5, 0.0, 0.0, 1.0,
-0.5, 0.5, 0.5, 0.0, 0.0, 1.0,
- 0.5, 0.5, 0.5, 0.0, 0.0, 0.0,
+ -0.5,-0.5, 0.5, 0.0, 0.0, 1.0,
+
+ -0.5,-0.5,-0.5,-1.0, 0.0, 0.0,
+ -0.5, 0.5,-0.5,-1.0, 0.0, 0.0,
+ -0.5, 0.5, 0.5,-1.0, 0.0, 0.0,
+ -0.5, 0.5, 0.5,-1.0, 0.0, 0.0,
+ -0.5,-0.5, 0.5,-1.0, 0.0, 0.0,
+ -0.5,-0.5,-0.5,-1.0, 0.0, 0.0,
+
+ 0.5,-0.5,-0.5, 1.0, 0.0, 0.0,
+ 0.5, 0.5,-0.5, 1.0, 0.0, 0.0,
+ 0.5, 0.5, 0.5, 1.0, 0.0, 0.0,
+ 0.5, 0.5, 0.5, 1.0, 0.0, 0.0,
+ 0.5,-0.5, 0.5, 1.0, 0.0, 0.0,
+ 0.5,-0.5,-0.5, 1.0, 0.0, 0.0,
+
+ -0.5,-0.5,-0.5, 0.0,-1.0, 0.0,
+ 0.5,-0.5,-0.5, 0.0,-1.0, 0.0,
+ 0.5,-0.5, 0.5, 0.0,-1.0, 0.0,
+ 0.5,-0.5, 0.5, 0.0,-1.0, 0.0,
+ -0.5,-0.5, 0.5, 0.0,-1.0, 0.0,
+ -0.5,-0.5,-0.5, 0.0,-1.0, 0.0,
+
+ -0.5, 0.5,-0.5, 0.0, 1.0, 0.0,
+ 0.5, 0.5,-0.5, 0.0, 1.0, 0.0,
+ 0.5, 0.5, 0.5, 0.0, 1.0, 0.0,
+ 0.5, 0.5, 0.5, 0.0, 1.0, 0.0,
+ -0.5, 0.5, 0.5, 0.0, 1.0, 0.0,
+ -0.5, 0.5,-0.5, 0.0, 1.0, 0.0,
};
unsigned int indices[] = {
@@ -122,7 +156,7 @@ processCameraInput(GLFWwindow *window, struct Camera *camObj, float deltaTime)
static int firstMouse = 1;
float sensibility = 0.1f;
- static float yaw = 90.0;
+ static float yaw = -90.0;
static float pitch = 0.0;
double xpos, ypos;
@@ -188,8 +222,12 @@ int main()
}
glEnable(GL_DEPTH_TEST);
+ unsigned int programColor = shaderCreateProgram("shaders/color.vsh",
+ "shaders/color.fsh");
+ unsigned int programLight = shaderCreateProgram("shaders/lightsource.vsh",
+ "shaders/lightsource.fsh");
- unsigned int VBO, VAO, EBO;
+ unsigned int VBO, VAO, EBO, lightVAO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
@@ -201,25 +239,30 @@ int main()
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glBindVertexArray(VAO);
+
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void *)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void *)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
+ glBindVertexArray(lightVAO);
+
+ glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void *)0);
+ glEnableVertexAttribArray(0);
+
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
- unsigned int shaderProgram = shaderCreateProgram("shaders/vertex.vsh",
- "shaders/fragment.fsh");
struct Camera mainCamera;
- mainCamera.position = linearVec3(0.0, 0.0, -3.0);
- mainCamera.front = linearVec3(0.0, 0.0, 0.0);
+ mainCamera.position = linearVec3(0.0, 0.0, 3.0);
+ mainCamera.front = linearVec3(0.0, 0.0, -1.0);
mainCamera.up = linearVec3(0.0, 1.0, 0.0);
Mat4 model, view, proj;
Mat4 T, S, R;
+ Vec3 lightPos = linearVec3(0.0, 3.0, -10.0);
float dt, t, t0;
int width, height;
@@ -227,15 +270,16 @@ int main()
while (!glfwWindowShouldClose(window)) {
processInput(window);
- glClearColor(0.2f, 0.2f, 0.2f, 1.0f);
+ glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
t = (float)glfwGetTime();
dt = t - t0;
t0 = t;
- T = linearTranslate(0.0, 0.0, 0.0);
- R = linearRotate(180 * t / M_PI, 0.0, 1.0, 0.0);
+ /* Color Object */
+ T = linearTranslate(0.0, 0.0, -4.0);
+ R = linearRotate(180 * t / M_PI, 0, 1, 0);
S = linearScale(1.0, 1.0, 1.0);
model = linearMat4Muln(3, T, R, S);
@@ -243,17 +287,45 @@ int main()
view = processCameraInput(window, &mainCamera, dt);
glfwGetWindowSize(window, &width, &height);
- proj = linearPerspective(35, width / (float)height, 0.1, 100);
+ proj = linearPerspective(35, (float)width / height, 0.1, 100);
- glUseProgram(shaderProgram);
+ glUseProgram(programColor);
glBindVertexArray(VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
- shaderSetUniformMatrix4fv(shaderProgram, "model", model.matrix[0]);
- shaderSetUniformMatrix4fv(shaderProgram, "view", view.matrix[0]);
- shaderSetUniformMatrix4fv(shaderProgram, "proj", proj.matrix[0]);
- glDrawElements(GL_TRIANGLES, sizeof(indices) / sizeof(int), GL_UNSIGNED_INT, 0);
+ shaderSetMatrixfv(programColor, "model", model.matrix[0], glUniformMatrix4fv);
+ shaderSetMatrixfv(programColor, "view", view.matrix[0], glUniformMatrix4fv);
+ shaderSetMatrixfv(programColor, "proj", proj.matrix[0], glUniformMatrix4fv);
+ shaderSetMatrixfv(programColor, "rotNormals", R.matrix[0], glUniformMatrix4fv);
+
+ shaderSetfv(programColor, "material.ambient", vec3(1.0, 0.5, 0.31), glUniform3fv);
+ shaderSetfv(programColor, "material.diffuse", vec3(1.0, 0.5, 0.31), glUniform3fv);
+ shaderSetfv(programColor, "material.specular", vec3(0.5, 0.5, 0.5), glUniform3fv);
+ shaderSet1f(programColor, "material.shininess", 32.0f);
+
+ shaderSetfv(programColor, "light.ambient", vec3(0.1, 0.1, 0.1), glUniform3fv);
+ shaderSetfv(programColor, "light.diffuse", vec3(0.5, 0.5, 0.5), glUniform3fv);
+ shaderSetfv(programColor, "light.specular", vec3(1.0, 1.0, 1.0), glUniform3fv);
+ shaderSetfv(programColor, "light.position", lightPos.vector, glUniform3fv);
+ shaderSetfv(programColor, "viewPos", mainCamera.position.vector, glUniform3fv);
+
+
+ glDrawArrays(GL_TRIANGLES, 0, sizeof(vertices) / sizeof(float));
+
+ /* Light Source */
+ model = linearMat4Mul(linearTranslatev(lightPos), linearScale(0.5, 0.5, 0.5));
+
+ glUseProgram(programLight);
+ glBindVertexArray(lightVAO);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
+
+ shaderSetMatrixfv(programColor, "model", model.matrix[0], glUniformMatrix4fv);
+ shaderSetMatrixfv(programColor, "view", view.matrix[0], glUniformMatrix4fv);
+ shaderSetMatrixfv(programColor, "proj", proj.matrix[0], glUniformMatrix4fv);
+
+ glDrawArrays(GL_TRIANGLES, 0, sizeof(vertices) / sizeof(float));
+
glfwSwapBuffers(window);
glfwPollEvents();
}
diff --git a/src/main.h b/src/main.h
index d93f941..13b7b28 100644
--- a/src/main.h
+++ b/src/main.h
@@ -1,6 +1 @@
-typedef struct {
- float pos[3];
- float color[3];
-} vertex;
-
-enum AXIS {X_AXIS, Y_AXIS, Z_AXIS};
+#define vec3(x, y, z) linearVec3(x, y, z).vector
diff --git a/src/shader.c b/src/shader.c
index ae2f08e..a82c25d 100644
--- a/src/shader.c
+++ b/src/shader.c
@@ -101,14 +101,30 @@ shaderCreateProgram(const char *vertexShaderPath, const char *fragmentShaderPath
}
void
-shaderSetUniformMatrix4fv(unsigned int program, char *uniformVariable, float *data)
+shaderSetfv(
+ unsigned int program,
+ char *uniformVariable,
+ float *data,
+ void (*uniform_callback)(int, int, const float *))
{
unsigned int varLoc = glGetUniformLocation(program, uniformVariable);
- glUniformMatrix4fv(varLoc, 1, GL_TRUE, data);
+ uniform_callback(varLoc, 1, data);
+}
+
+
+void
+shaderSetMatrixfv(
+ unsigned int program,
+ char *uniformVariable,
+ float *data,
+ void (*uniform_callback)(int, int, unsigned char, const float *))
+{
+ unsigned int varLoc = glGetUniformLocation(program, uniformVariable);
+ uniform_callback(varLoc, 1, GL_TRUE, data);
}
void
-shaderSetUniform1f(unsigned int program, char *uniformVariable, float data)
+shaderSet1f(unsigned int program, char *uniformVariable, float data)
{
unsigned int varLoc = glGetUniformLocation(program, uniformVariable);
glUniform1f(varLoc, data);
diff --git a/src/shader.h b/src/shader.h
index aa92314..ed02ade 100644
--- a/src/shader.h
+++ b/src/shader.h
@@ -2,6 +2,17 @@
#define __SHADER__
unsigned int shaderCreateProgram(const char *vertexShaderPath, const char *fragmentShaderPath);
-void shaderSetUniformMatrix4fv(unsigned int program, char *uniformVariable, float *data);
-void shaderSetUniform1f(unsigned int program, char *uniformVariable, float data);
+void shaderSetfv(
+ unsigned int program,
+ char *uniformVariable,
+ float *data,
+ void (*uniform_callback)(int, int, const float *));
+
+void shaderSetMatrixfv(
+ unsigned int program,
+ char *uniformVariable,
+ float *data,
+ void (*uniform_callback)(int, int, unsigned char, const float *));
+
+void shaderSet1f(unsigned int program, char *uniformVariable, float data);
#endif
Feel free to download, copy and edit any repo