oglc/src/main.c

155 lines
4.5 KiB
C
Raw Normal View History

2021-07-04 02:53:37 +01:00
#include "main.h"
#include "gfx.h"
2021-08-02 09:35:39 +01:00
const int WIDTH = 420;
const int HEIGHT = 420;
2021-07-04 02:53:37 +01:00
// forward declarations
2021-07-05 08:51:55 +01:00
// input
2021-07-04 02:53:37 +01:00
int checkQuit();
2021-07-05 08:51:55 +01:00
// time
float time();
2021-08-02 09:35:39 +01:00
void updateUniforms(GLuint shaderProgram);
void updateCameraUniforms(GLuint shaderProgram);
2021-07-04 02:53:37 +01:00
int main()
{
2021-07-10 16:16:01 +01:00
// create a window and opengl context
2021-08-02 09:35:39 +01:00
SDL_Window* window = gfxInit(WIDTH, HEIGHT);
2021-07-06 21:20:01 +01:00
2021-07-10 16:16:01 +01:00
// create a texture for the compute shader to write to
2021-08-02 09:35:39 +01:00
GLuint textureOutput = createWriteOnlyTexture(WIDTH, HEIGHT);
2021-07-10 16:16:01 +01:00
printWorkGroupLimits();
2021-07-04 02:53:37 +01:00
2021-07-10 16:16:01 +01:00
// compile shader programs
2021-07-29 23:39:04 +01:00
unsigned int computeProgram = compileComputeShaderProgram(
2021-08-02 19:43:05 +01:00
"bin/rt.compute");
2021-07-10 16:16:01 +01:00
unsigned int quadProgram = compileQuadShaderProgram(
2021-08-02 19:43:05 +01:00
"bin/shader.vert",
"bin/shader.frag");
2021-07-04 02:53:37 +01:00
2021-07-10 16:16:01 +01:00
// initialise quad
initBuffers();
setVertexAttributes();
2021-07-05 08:51:55 +01:00
2021-07-05 01:05:37 +01:00
// render loop
2021-07-04 02:53:37 +01:00
while (!checkQuit())
{
2021-07-10 16:16:01 +01:00
glUseProgram(computeProgram);
2021-08-02 09:35:39 +01:00
updateUniforms(computeProgram);
2021-07-10 16:16:01 +01:00
// dispatch compute shader
2021-08-02 09:35:39 +01:00
glDispatchCompute((GLuint)WIDTH, (GLuint)HEIGHT, 1);
2021-07-10 16:16:01 +01:00
// make sure we're finished writing to the texture before trying to read it
glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
// normal drawing pass
glUseProgram(quadProgram);
2021-07-24 01:31:35 +01:00
glActiveTexture(GL_TEXTURE0); // use computed texture
2021-07-10 16:16:01 +01:00
glBindTexture(GL_TEXTURE_2D, textureOutput);
2021-07-24 01:31:35 +01:00
2021-07-05 08:51:55 +01:00
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
2021-07-10 16:16:01 +01:00
// swip swap
2021-07-05 01:05:37 +01:00
SDL_GL_SwapWindow(window);
2021-07-04 02:53:37 +01:00
}
return 0;
}
2021-08-02 09:35:39 +01:00
void updateUniforms(GLuint shaderProgram)
{
float t = time(); // time
float sin_t = sin(t);
int tLocation = glGetUniformLocation(shaderProgram, "t");
glUniform4f(tLocation, t, sin_t, (1.0 + sin_t)*0.5, 0.0f);
updateCameraUniforms(shaderProgram);
}
void updateCameraUniforms(GLuint shaderProgram)
{
// set up perspective projection matrix and its inverse
mat4 proj, proji;
float fovy = 60.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]);
// form view space axes
vec3 u,v;
vec3 up = {0.0,1.0,0.0};
vec3 w = {0.0,0.0,-1.0};
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 fovy 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]);
}
2021-07-05 08:51:55 +01:00
float time()
{
2021-08-02 09:35:39 +01:00
// ms / 1000.0 = seconds since start
return (float)SDL_GetTicks() / 1000.0f;
2021-07-05 08:51:55 +01:00
}
2021-07-04 02:53:37 +01:00
int checkQuit()
{
SDL_Event event;
if (SDL_PollEvent(&event) && event.type == SDL_QUIT) return 1;
return 0;
}