opengl

Sample code from LearnOpenGL.com
Log | Files | Refs

commit 2785631a14bd5bc2863f2f2ea6c7847189703d25
parent de129c37493ff9583111691e52c16f0dd379f953
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Wed, 28 Jun 2023 12:01:18 +0900

add perspective

Diffstat:
Mglm.c | 29+++++++++++++++++++++++++++++
Mglm.h | 3+++
Mmain.c | 32++++++++++++++++++++++++--------
Mmain.h | 1+
Mshader.c | 8++++++++
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