From b9616df5b83957ec5a9a465c367bc38f2dc74c2a Mon Sep 17 00:00:00 2001 From: ktyl Date: Sat, 7 Aug 2021 15:19:22 +0100 Subject: [PATCH] extract camera to file --- src/cam.c | 61 +++++++++++++++++++++++++++++++++++ src/cam.h | 9 ++++++ src/main.c | 94 +++--------------------------------------------------- todo.md | 8 +---- 4 files changed, 75 insertions(+), 97 deletions(-) create mode 100644 src/cam.c create mode 100644 src/cam.h diff --git a/src/cam.c b/src/cam.c new file mode 100644 index 0000000..ab28110 --- /dev/null +++ b/src/cam.c @@ -0,0 +1,61 @@ +#include "cam.h" + +void updateCameraUniforms(GLuint shaderProgram, float aspect) +{ + float t = now(); + + // wobble up dir + vec3 cdir, cright, cup; + vec3 up = {0.1*sin(t),1.0,0.2*cos(t)}; + glm_vec3_normalize(up); + + // camera and target pos + float d = 10.0+sin(t); + float pt = -t; + vec3 cpos = {sin(pt)*d,3.0+cos(0.5*t)*2.5,cos(pt)*d}; + vec3 tpos = {0.0}; + int loc = glGetUniformLocation(shaderProgram, "_cpos"); + glUniform3fv(loc, 1, cpos); + + // form camera space axes + glm_vec3_sub(cpos,tpos,cdir); + glm_vec3_normalize(cdir); + glm_vec3_cross(up,cdir,cright); + glm_vec3_normalize(cright); + glm_vec3_cross(cdir,cright,cup); + glm_vec3_normalize(cup); + loc = glGetUniformLocation(shaderProgram, "_w"); + glUniform3fv(loc, 1, cdir); + loc = glGetUniformLocation(shaderProgram, "_u"); + glUniform3fv(loc, 1, cright); + loc = glGetUniformLocation(shaderProgram, "_v"); + glUniform3fv(loc, 1, cup); + + // camera properties + float fovy = 90.0; + float f = 1.0; + float theta = glm_rad(fovy); + float h = tan(theta*0.5); + float vph = 2.0*h; + float vpw = aspect*vph; + + // set up image plane axes + vec3 camh={0},camv={0},camll={0},camhh={0},camvh={0},fw={0}; + + glm_vec3_scale(cright,f*vpw,camh); + loc = glGetUniformLocation(shaderProgram, "_camh"); + glUniform3fv(loc, 1, camh); + glm_vec3_scale(cup,f*vph,camv); + loc = glGetUniformLocation(shaderProgram, "_camv"); + glUniform3fv(loc, 1, camv); + + // camera lower left corner + glm_vec3_scale(cright,f*vpw*0.5,camhh); + glm_vec3_scale(cup,f*vph*0.5,camvh); + glm_vec3_scale(cdir,f,fw); + glm_vec3_sub(camll,camhh,camll); + glm_vec3_sub(camll,camvh,camll); + glm_vec3_sub(camll,fw,camll); + loc = glGetUniformLocation(shaderProgram, "_camll"); + glUniform3fv(loc, 1, camll); +} diff --git a/src/cam.h b/src/cam.h new file mode 100644 index 0000000..7298001 --- /dev/null +++ b/src/cam.h @@ -0,0 +1,9 @@ +#pragma once + +#include + +#include + +#include "time.h" + +void updateCameraUniforms(GLuint shaderProgram, float aspect); diff --git a/src/main.c b/src/main.c index bbf88ba..5e153bc 100644 --- a/src/main.c +++ b/src/main.c @@ -3,13 +3,14 @@ #include "time.h" #include "sphere.h" +#include "cam.h" const int WIDTH = 420; const int HEIGHT = 420; // forward declarations void updateUniforms(GLuint shaderProgram); -void updateCameraUniforms(GLuint shaderProgram); +//void updateCameraUniforms(GLuint shaderProgram); int main() { @@ -66,7 +67,8 @@ void updateUniforms(GLuint shaderProgram) int tLocation = glGetUniformLocation(shaderProgram, "_t"); glUniform4f(tLocation, t, sin_t, (1.0 + sin_t)*0.5, 0.0f); - updateCameraUniforms(shaderProgram); + float aspect = (float)WIDTH/(float)HEIGHT; + updateCameraUniforms(shaderProgram, aspect); const int sphereCount = 42; struct Sphere spheres[sphereCount]; @@ -74,91 +76,3 @@ void updateUniforms(GLuint shaderProgram) updateSphereUniforms(shaderProgram, spheres, sphereCount); } - -void updateCameraUniforms(GLuint shaderProgram) -{ - // set up perspective projection matrix and its inverse - mat4 proj, proji; - float fovy = 90.0; // vertical field of view in deg - float near = 0.1; - float far = 1000.0; - float aspect = (float)WIDTH/(float)HEIGHT; - glm_perspective(fovy,aspect,near,far,proj); // TODO: radians or degrees?? - glm_mat4_inv(proj, proji); - int inverseProjLocation = glGetUniformLocation(shaderProgram, "_cameraInverseProjection"); - glUniformMatrix4fv(inverseProjLocation, 1, GL_FALSE, proji[0]); - - float t = now(); - - vec3 cdir, cright, cup; - vec3 up = {0.1*sin(t),1.0,0.2*cos(t)}; // world up - glm_vec3_normalize(up); - - // lookat vector and view matrix - float d = 10.0 + sin(t); - float pt = -t; - vec3 cpos = {sin(pt)*d,cos(0.5*t)*5.0,cos(pt)*d}; // camera pos - vec3 tpos = {0.0,0.0,0.0}; // target pos - glm_vec3_sub(cpos,tpos,cdir); // look dir (inverted cause opengl noises) - glm_vec3_normalize(cdir); - glm_vec3_cross(up,cdir,cright); // camera right - glm_vec3_normalize(cright); - glm_vec3_cross(cdir,cright,cup); // camera up - glm_vec3_normalize(cup); - mat4 view; - glm_lookat(cpos,tpos,cup,view); - int cposLocation = glGetUniformLocation(shaderProgram, "_cpos"); - glUniform3f(cposLocation, cpos[0],cpos[1],cpos[2]); - - // form view space axes - vec3 w,u,v; - glm_vec3_copy(cdir,w); - - glm_vec3_norm(w); - glm_vec3_cross(up,w,u); - glm_vec3_norm(u); - glm_vec3_cross(w, u, v); - int wLocation = glGetUniformLocation(shaderProgram, "_w"); - glUniform3f(wLocation+0, w[0], w[1], w[2]); // w - glUniform3f(wLocation+1, u[0], u[1], u[2]); // u - glUniform3f(wLocation+2, v[0], v[1], v[2]); // v - - - // get camera properties - float theta = glm_rad(fovy); // convert fov to radians - float h = tan(theta*0.5); - float vph = 2.0*h; // viewport height - float vpw = aspect*vph; // viewport width - - // TODO: actual focal length lmao - float f = 1.0; - - // camera axes - // - // use vec3_scale instead of vec3_multiply to get scalar multiplication - // https://cglm.readthedocs.io/en/latest/vec3.html#c.glm_vec3_scale - vec3 camh={0}, - camv={0}, - camll={0}, - camhh={0}, - camvh={0}, - fw={0}; - - glm_vec3_scale(u,f*vpw,camh); - int camhLocation = glGetUniformLocation(shaderProgram, "_camh"); - glUniform3f(camhLocation, camh[0], camh[1], camh[2]); - glm_vec3_scale(v,f*vph,camv); - int camvLocation = camhLocation+1; - glUniform3f(camvLocation, camv[0], camv[1], camv[2]); - - // camera lower left corner - // calculate half-axes and w*f to establish 3d position of ll corner in camera space - glm_vec3_scale(u,f*vpw*0.5,camhh); - glm_vec3_scale(v,f*vph*0.5,camvh); - glm_vec3_scale(w,f,fw); - glm_vec3_sub(camll,camhh,camll); - glm_vec3_sub(camll,camvh,camll); - glm_vec3_sub(camll,fw,camll); - int camllLocation = glGetUniformLocation(shaderProgram, "_camll"); - glUniform3f(camllLocation, camll[0], camll[1], camll[2]); -} diff --git a/todo.md b/todo.md index 270d329..c47ca15 100644 --- a/todo.md +++ b/todo.md @@ -1,10 +1,3 @@ -* [x] basic opengl initialisation -* [x] shader pre-processor - * [x] ppp.py - * [x] read root shaders - * [x] read include shaders - * [x] write processed shaders to bin/res/shader/ - * [x] compile processed shaders * [-] render image with compute shader * [x] render a texture to a full-screen quad * [x] pass uniforms to shader to animate it @@ -26,6 +19,7 @@ * [ ] mandelbrot * [ ] julia * [ ] trongle +* [ ] resizable window * [ ] output frame to a file * [ ] detect input keydown s * [ ] get timestamp