commit 2785631a14bd5bc2863f2f2ea6c7847189703d25
parent de129c37493ff9583111691e52c16f0dd379f953
Author: Matsuda Kenji <info@mtkn.jp>
Date: Wed, 28 Jun 2023 12:01:18 +0900
add perspective
Diffstat:
5 files changed, 65 insertions(+), 8 deletions(-)
diff --git a/glm.c b/glm.c
@@ -155,6 +155,23 @@ matMakeIdent(int size)
return m;
}
+mat *
+matMakePers(float fov, float aspect, float near, float far)
+{
+ mat *m = (mat *)malloc(sizeof(mat));
+ m->data = (float *)calloc(sizeof(float), 16);
+ m->data[0] = 1 / (aspect * tanf(fov/2));
+ m->data[5] = 1 / tanf(fov/2);
+ m->data[10] = -(far + near) / (far - near);
+ m->data[11] = -1;
+ m->data[14] = -(2 * far * near) / (far - near);
+
+ m->size = 4;
+ numMat++;
+ return m;
+}
+
+
void
matFree(mat *m)
{
@@ -237,3 +254,15 @@ rotate(mat *m, float rad, vec *axis)
matFree(rot);
return m;
}
+
+mat *
+scale(mat *m, float s)
+{
+ mat *scl = matMakeIdent(m->size);
+ for (int i = 0; i < m->size; i++) {
+ scl->data[i + m->size*i] = s;
+ }
+ matDot(m, scl);
+ matFree(scl);
+ return m;
+}
diff --git a/glm.h b/glm.h
@@ -30,7 +30,9 @@ vec *vecCross(vec *v, const vec *w);
char *matStr(char *s, mat *m);
mat *matMake(float *data, int size);
mat *matMakeIdent(int size);
+mat *matMakePers(float fov, float aspect, float near, float far);
void matFree(mat *m);
+mat *matDot(mat *m, const mat *n);
int matCount(void);
mat *matCopy(const mat *m);
@@ -39,3 +41,4 @@ float *matDataPtr(mat *m);
mat *translate(mat *m, const vec *v);
// axis must be an unit vector
mat *rotate(mat *m, float rad, vec *axis);
+mat *scale(mat *m, float s);
diff --git a/main.c b/main.c
@@ -50,6 +50,9 @@ processInput(GLFWwindow *window)
int
main(void)
{
+ int width = 600;
+ int height = 600;
+
float vertices[] = {
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f,
@@ -94,13 +97,21 @@ main(void)
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f
};
- int numCube = 2;
+ int numCube = 3;
vec *cubePositions[numCube];
- cubePositions[0] = vecMake((float []){0.0, 0.0, 0.0}, 3);
- cubePositions[1] = vecMake((float []){0.5, 0.5, 0.0}, 3);
+ cubePositions[0] = vecMake((float []){-2.0, 0.0, -10.0}, 3);
+ cubePositions[1] = vecMake((float []){0.0, 3.0, -20.0}, 3);
+ cubePositions[2] = vecMake((float []){1.0, 1.0, -2.0}, 3);
mat *modelMat[numCube];
- for (int i = 0; i < numCube; i++)
- modelMat[i] = translate(matMakeIdent(4), cubePositions[i]);
+ for (int i = 0; i < numCube; i++) {
+ modelMat[i] = scale(matMakeIdent(4), 0.1);
+ translate(modelMat[i], cubePositions[i]);
+ }
+ mat *viewMat = matMakeIdent(4);
+ mat *projMat = matMakePers((float)M_PI*80/180, (float)width/(float)height,
+ 0.1, 100.0);
+ char s[256];
+ printf("%s", matStr(s, projMat));
vec *axis0 = vecMake((float[]){1.41421356/2, 1.41421356/2, 0.0}, 3);
vec *axis1 = vecMake((float[]){0.0, 0.0, 1.0}, 3);
@@ -112,7 +123,8 @@ main(void)
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
// create glfw window
- GLFWwindow *window = glfwCreateWindow(600, 600, "opengl", NULL, NULL);
+ GLFWwindow *window = glfwCreateWindow(width, height, "opengl",
+ NULL, NULL);
if (window == NULL) {
fprintf(stderr, "main: failed to open window\n");
glfwTerminate();
@@ -202,8 +214,10 @@ main(void)
rotation += now-lastTime;
}
rotate(transform, rotation, axis0);
- glUniformMatrix4fv(tloc, 1, GL_FALSE,
- matDataPtr(transform));
+
+ ShaderSetMat4(shader, "model", matDataPtr(transform));
+ ShaderSetMat4(shader, "view", matDataPtr(viewMat));
+ ShaderSetMat4(shader, "proj", matDataPtr(projMat));
glDrawArrays(GL_TRIANGLES, 0, 36);
matFree(transform);
}
@@ -219,6 +233,8 @@ main(void)
vecFree(cubePositions[i]);
matFree(modelMat[i]);
}
+ matFree(viewMat);
+ matFree(projMat);
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
diff --git a/main.h b/main.h
@@ -12,4 +12,5 @@ Shader *ShaderInit(const char *vs, const char *fs);
void ShaderUse(Shader *s);
void ShaderDelete(Shader *s);
void ShaderSetFloat(Shader *s, const char *name, float value);
+void ShaderSetMat4(Shader *s, const char *name, float *mat);
diff --git a/shader.c b/shader.c
@@ -140,3 +140,10 @@ ShaderSetFloat(Shader *s, const char *name, float value)
{
glUniform1f(glGetUniformLocation(s->ID, name), value);
}
+
+void
+ShaderSetMat4(Shader *s, const char *name, float *mat)
+{
+ glUniformMatrix4fv(glGetUniformLocation(s->ID, name), 1,
+ GL_FALSE, mat);
+}
+\ No newline at end of file