extract camera to file

This commit is contained in:
ktyl 2021-08-07 15:19:22 +01:00
parent 730cb70b39
commit b9616df5b8
4 changed files with 75 additions and 97 deletions

61
src/cam.c Normal file
View File

@ -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);
}

9
src/cam.h Normal file
View File

@ -0,0 +1,9 @@
#pragma once
#include <GL/glew.h>
#include <cglm/cam.h>
#include "time.h"
void updateCameraUniforms(GLuint shaderProgram, float aspect);

View File

@ -3,13 +3,14 @@
#include "time.h" #include "time.h"
#include "sphere.h" #include "sphere.h"
#include "cam.h"
const int WIDTH = 420; const int WIDTH = 420;
const int HEIGHT = 420; const int HEIGHT = 420;
// forward declarations // forward declarations
void updateUniforms(GLuint shaderProgram); void updateUniforms(GLuint shaderProgram);
void updateCameraUniforms(GLuint shaderProgram); //void updateCameraUniforms(GLuint shaderProgram);
int main() int main()
{ {
@ -66,7 +67,8 @@ void updateUniforms(GLuint shaderProgram)
int tLocation = glGetUniformLocation(shaderProgram, "_t"); int tLocation = glGetUniformLocation(shaderProgram, "_t");
glUniform4f(tLocation, t, sin_t, (1.0 + sin_t)*0.5, 0.0f); 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; const int sphereCount = 42;
struct Sphere spheres[sphereCount]; struct Sphere spheres[sphereCount];
@ -74,91 +76,3 @@ void updateUniforms(GLuint shaderProgram)
updateSphereUniforms(shaderProgram, spheres, sphereCount); 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]);
}

View File

@ -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 * [-] render image with compute shader
* [x] render a texture to a full-screen quad * [x] render a texture to a full-screen quad
* [x] pass uniforms to shader to animate it * [x] pass uniforms to shader to animate it
@ -26,6 +19,7 @@
* [ ] mandelbrot * [ ] mandelbrot
* [ ] julia * [ ] julia
* [ ] trongle * [ ] trongle
* [ ] resizable window
* [ ] output frame to a file * [ ] output frame to a file
* [ ] detect input keydown s * [ ] detect input keydown s
* [ ] get timestamp * [ ] get timestamp