Compare commits

...

5 Commits

8 changed files with 361 additions and 70 deletions

View File

@ -13,7 +13,7 @@ else
endif endif
# Source files # Source files
SRC := src/main.c src/log.c src/shader.c SRC := src/main.c src/log.c src/shader.c src/matrix-math.c
# Output binary # Output binary
OUT := cg1 OUT := cg1

View File

@ -15,17 +15,27 @@
#define STATUS_INTERVAL 0.5 #define STATUS_INTERVAL 0.5
#define PI 3.14159f #define PI 3.14159f
GLFWwindow* window;
GLuint program; GLuint program;
GLuint originProgram;
GLuint floorProgram;
GLuint vertexArrayObject; GLuint vertexArrayObject;
GLuint originVAO;
GLuint indexBuffer; GLuint indexBuffer;
GLuint lineIndexBuffer;
GLuint floorIndexBuffer;
GLuint initialWindowWidth = 800; GLuint initialWindowWidth = 800;
GLuint initialWindowHeight = 600; GLuint initialWindowHeight = 600;
GLfloat aspect; GLfloat aspect;
mat4 projectionMatrix; mat4 realProjectionMatrix;
GLfloat currentTime = 0.0f;
int frameCount = 0; int frameCount = 0;
struct timespec last_time, current_time; struct timespec last_time, current_time;
@ -77,19 +87,19 @@ void updateStatusDisplay() {
double fps = frameCount / elapsed; double fps = frameCount / elapsed;
frameCount = 0; frameCount = 0;
last_time = current_time; last_time = current_time;
printf("\rFPS: %.2f ", fps); printf("\rFPS: %5.2f - currentTime: %5.2f", fps, currentTime);
fflush(stdout); fflush(stdout);
} }
} }
void recalculateProjectionMatrix() { void recalculateProjectionMatrix() {
mat4BuildPerspective(projectionMatrix, 60 * M_PI / 180, aspect, 0.1, 10); mat4BuildPerspective(realProjectionMatrix, 90 * M_PI / 180, aspect, 0.1, 50);
DEBUG("Recalculating Projection Matrix"); DEBUG("Recalculating Projection Matrix");
} }
void init(void) { void init(void) {
INFO("Building Programs..."); INFO("Building main program...");
ProgramLinkResult linkResult = buildShaderProgram("src/shaders/vertex.glsl", "src/shaders/fragment.glsl"); ProgramLinkResult linkResult = buildShaderProgram("src/shaders/vertex.glsl", "src/shaders/fragment.glsl");
if (!linkResult.success) { if (!linkResult.success) {
FATAL("Failed to link Program"); FATAL("Failed to link Program");
@ -98,6 +108,25 @@ void init(void) {
program = linkResult.program; program = linkResult.program;
INFO("Building origin program...");
linkResult = buildShaderProgram("src/shaders/origin-vertex.glsl", "src/shaders/origin-fragment.glsl");
if (!linkResult.success) {
FATAL("Failed to link Program");
exit(1);
}
originProgram = linkResult.program;
INFO("Building floor program...");
linkResult = buildShaderProgram("src/shaders/floor-vertex.glsl", "src/shaders/floor-fragment.glsl");
if (!linkResult.success) {
FATAL("Failed to link Program");
exit(1);
}
floorProgram = linkResult.program;
INFO("Shader Program Done."); INFO("Shader Program Done.");
// create triangle buffer // create triangle buffer
@ -158,6 +187,32 @@ void init(void) {
7, 3, 6 7, 3, 6
}; };
GLuint lineIndices[] = {
0, 1,
0, 2,
0, 4,
1, 3,
1, 5,
2, 3,
2, 6,
3, 7,
4, 5,
4, 6,
5, 7,
6, 7
};
GLuint floorIndices[] = {
2, 3, 6,
3, 7, 6
};
DEBUG("Creating vertext buffer"); DEBUG("Creating vertext buffer");
GLuint vertexBuffer; GLuint vertexBuffer;
glGenBuffers(1, &vertexBuffer); glGenBuffers(1, &vertexBuffer);
@ -181,24 +236,79 @@ void init(void) {
0 // start offset 0 // start offset
); );
glEnableVertexAttribArray(0); glEnableVertexAttribArray(0);
glVertexAttribPointer(
1, // shader location
3, // number of values to read
GL_FLOAT, // type of value
GL_FALSE, // if values are normalised
3 * sizeof(GLfloat), // stride - distance between vertices
0 // start offset
);
glEnableVertexAttribArray(1);
DEBUG("Creating index buffers");
DEBUG("Creating index buffer");
glGenBuffers(1, &indexBuffer); glGenBuffers(1, &indexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glGenBuffers(1, &lineIndexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, lineIndexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(lineIndices), lineIndices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glGenBuffers(1, &floorIndexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, floorIndexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(floorIndices), floorIndices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(0); glBindVertexArray(0);
glClearColor(0.0f, 0.0f, 0.0f, 0.3f);
glClearColor(0.3f, 0.3f, 0.4f, 1.0f);
glViewport(0, 0, initialWindowWidth, initialWindowHeight); glViewport(0, 0, initialWindowWidth, initialWindowHeight);
glEnable(GL_CULL_FACE); // glEnable(GL_CULL_FACE);
glFrontFace(GL_CCW); glFrontFace(GL_CCW);
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
DEBUG("Creating origin vertex buffer");
GLfloat originVertices[] = {
// X Y Z R G B
0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f
};
GLuint originVBO;
glGenBuffers(1, &originVBO);
glBindBuffer(GL_ARRAY_BUFFER, originVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(originVertices), originVertices, GL_STATIC_DRAW);
glGenVertexArrays(1, &originVAO);
glBindVertexArray(originVAO);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), 0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (void*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, 0);
initialiseStatusDisplay(); initialiseStatusDisplay();
recalculateProjectionMatrix(); recalculateProjectionMatrix();
@ -206,15 +316,8 @@ void init(void) {
INFO("--- Initialisation done ---"); INFO("--- Initialisation done ---");
} }
GLfloat currentHue = 0.0f; void drawCube(mat4 modelMatrix, mat4 viewMatrix) {
void drawCube(vec3 position, mat4 initialModelMatrix, mat4 viewMatrix) {
mat4 modelMatrix;
mat4 modelViewMatrix; mat4 modelViewMatrix;
mat4Translate(modelMatrix, initialModelMatrix, position);
// combine model and view matrix to model-view matrix
mat4Multiply(modelViewMatrix, viewMatrix, modelMatrix); mat4Multiply(modelViewMatrix, viewMatrix, modelMatrix);
// send modelView and projection matrix to shader // send modelView and projection matrix to shader
@ -227,54 +330,199 @@ void drawCube(vec3 position, mat4 initialModelMatrix, mat4 viewMatrix) {
glDrawElements(GL_TRIANGLES, 48, GL_UNSIGNED_INT, 0); glDrawElements(GL_TRIANGLES, 48, GL_UNSIGNED_INT, 0);
} }
GLfloat clamp(GLfloat d, GLfloat min, GLfloat max) {
const GLfloat t = d < min ? min : d;
return t > max ? max : t;
}
GLfloat mapTo01(GLfloat d, GLfloat min, GLfloat max) {
return (clamp(d, min, max) - min) * (1 / (max - min));
}
void draw(void) { void draw(void) {
// 0.0: virtual view
// 0.1 transition to real view
// 0.15 done
// 0.3 start view transformation
// 0.35 done
// 0.4 start projection
// 0.45 done
// 0.55 - repeat
updateStatusDisplay(); updateStatusDisplay();
mat4 identity;
mat4Identity(identity);
mat4 projectionMatrix;
// mat4Interpolate(projectionMatrix, identity, projectionMatrix, mapTo01(currentHue, 0.0f, 0.1f));
// counter for animation // counter for animation
currentHue += 0.0005f; currentTime += 0.0001f;
if (currentHue > 1.0) currentHue = 0.0f; int state = glfwGetKey(window, GLFW_KEY_SPACE);
if (state == GLFW_PRESS)
{
currentTime += 0.001f;
}
if (currentTime > 0.55f) currentTime = 0.0f;
// clear colour and depth buffer // clear colour and depth buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// select program
glUseProgram(program);
// build view matrix // build view matrix
mat4 viewMatrix; mat4 viewMatrix;
// mat4Identity(viewMatrix); // mat4Identity(viewMatrix);
vec3 cameraPos = {0.0f, 1.0f, 1.3f}; vec3 cameraPos = {cos(currentTime * 6 * M_PI) * 3.0f, 3.0f + sin(currentTime * 12 * M_PI) * 0.5, sin(currentTime * 6 * M_PI) * 3.0f};
vec3 cameraLookAt = {0.0f, 0.2f, 0.0f}; vec3 cameraLookAt = {0.0f, 0.0f, 0.0f};
vec3 cameraUp = {0.0f, 1.0f, 0.0f}; vec3 cameraUp = {0.0f, 1.0f, 0.0f};
mat4BuildLookAt(viewMatrix, cameraPos, cameraLookAt, cameraUp); mat4BuildLookAt(viewMatrix, cameraPos, cameraLookAt, cameraUp);
vec3 virtualCameraPosition = {1.5f, 1.0f, 1.0f};
vec3 virtualCameraLookAt = {0.0f, 0.0f, -1.0f};
// calculate virtual lookAt and projection
mat4 virtualViewMatrix;
mat4 virtualProjectionMatrix;
mat4BuildLookAt(virtualViewMatrix, virtualCameraPosition, virtualCameraLookAt, cameraUp);
mat4BuildPerspective(virtualProjectionMatrix, 60 * M_PI / 180, aspect, 1, 4);
mat4 inverseVirtualView;
mat4Inverse(inverseVirtualView, virtualViewMatrix);
mat4Interpolate(inverseVirtualView, inverseVirtualView, identity, mapTo01(currentTime, 0.3f, 0.35f));
mat4 inverseVirtualProjection;
mat4Inverse(inverseVirtualProjection, virtualProjectionMatrix);
mat4 viewFrustumModelView;
mat4Multiply(viewFrustumModelView, inverseVirtualView, inverseVirtualProjection);
mat3 mat3CameraRotationMatrix;
mat3From4(mat3CameraRotationMatrix, virtualViewMatrix);
mat3Inverse(mat3CameraRotationMatrix, mat3CameraRotationMatrix);
mat4 cameraRotationMatrix;
mat4From3(cameraRotationMatrix, mat3CameraRotationMatrix);
mat4Interpolate(projectionMatrix, virtualProjectionMatrix, realProjectionMatrix, mapTo01(currentTime, 0.1f, 0.15f));
mat4Interpolate(viewMatrix, virtualViewMatrix, viewMatrix, mapTo01(currentTime, 0.1f, 0.15f));
mat4Interpolate(virtualViewMatrix, identity, virtualViewMatrix, mapTo01(currentTime, 0.3f, 0.35f));
mat4Interpolate(virtualProjectionMatrix, identity, virtualProjectionMatrix, mapTo01(currentTime, 0.4f, 0.45f) * mapTo01(currentTime, 0.4f, 0.45f));
glUseProgram(program);
GLuint brightnessLocation = glGetUniformLocation(program, "uBrightness");
GLuint projectionLocation = glGetUniformLocation(program, "uProjection"); GLuint projectionLocation = glGetUniformLocation(program, "uProjection");
glUniformMatrix4fv(projectionLocation, 1, GL_FALSE, projectionMatrix); glUniformMatrix4fv(projectionLocation, 1, GL_FALSE, projectionMatrix);
// cubes.
// build model Matrix
mat4 modelMatrix; mat4 modelMatrix;
vec3 scale; vec3 scale;
vec3 position; vec3 position;
float scales[] = {0.5f, 0.4f, 0.3f, 0.2f, 0.1f, 0.09f, 0.08f, 0.07f, 0.06f, 0.05f}; // cube 1
for (int i = 0; i < 10; i++) {
mat4Identity(modelMatrix); mat4Identity(modelMatrix);
vec3Set(scale, scales[i], 0.05f, scales[i]); vec3Set(scale, 0.5f, 0.5f, 0.5f);
mat4Scale(modelMatrix, modelMatrix, scale); mat4Scale(modelMatrix, modelMatrix, scale);
mat4RotateY(modelMatrix, modelMatrix, currentHue * 2 * M_PI + (i / 5.0f * M_PI)); mat4RotateY(modelMatrix, modelMatrix, 0.5f);
vec3Set(position, 0.0f, i * 0.05f, 0.0f); vec3Set(position, -0.3f, 0.5f, -0.4f);
mat4Translate(modelMatrix, modelMatrix, position); mat4Translate(modelMatrix, modelMatrix, position);
drawCube(position, modelMatrix, viewMatrix); mat4Multiply(modelMatrix, virtualViewMatrix, modelMatrix);
mat4Multiply(modelMatrix, virtualProjectionMatrix, modelMatrix);
glUniform1f(brightnessLocation, 1.0f);
drawCube(modelMatrix, viewMatrix);
// cube 2
mat4Identity(modelMatrix);
vec3Set(scale, 0.3f, 0.3f, 0.3f);
mat4Scale(modelMatrix, modelMatrix, scale);
mat4RotateY(modelMatrix, modelMatrix, 0.5f);
vec3Set(position, -0.9f, 0.3f, -3.8f);
mat4Translate(modelMatrix, modelMatrix, position);
mat4Multiply(modelMatrix, virtualViewMatrix, modelMatrix);
mat4Multiply(modelMatrix, virtualProjectionMatrix, modelMatrix);
glUniform1f(brightnessLocation, 1.0f);
drawCube(modelMatrix, viewMatrix);
// draw virtual camera
mat4Identity(modelMatrix);
vec3Set(scale, 0.2f, 0.15f, 0.05f);
mat4Scale(modelMatrix, modelMatrix, scale);
// apply rotations to camera
mat4Multiply(modelMatrix, cameraRotationMatrix, modelMatrix);
mat4Translate(modelMatrix, modelMatrix, virtualCameraPosition);
mat4Multiply(modelMatrix, virtualViewMatrix, modelMatrix);
glUniform1f(brightnessLocation, 0.0f);
if (currentTime < 0.37f) {
drawCube(modelMatrix, viewMatrix);
} }
glUseProgram(originProgram);
projectionLocation = glGetUniformLocation(originProgram, "uProjection");
glUniformMatrix4fv(projectionLocation, 1, GL_FALSE, projectionMatrix);
GLuint modelViewLocation = glGetUniformLocation(originProgram, "uModelView");
glUniformMatrix4fv(modelViewLocation, 1, GL_FALSE, viewMatrix);
glBindVertexArray(originVAO);
glLineWidth(5.0f);
glDrawArrays(GL_LINES, 0, 6);
if (currentTime < 0.65) {
mat4Multiply(viewFrustumModelView, virtualProjectionMatrix, viewFrustumModelView);
mat4Multiply(viewFrustumModelView, viewMatrix, viewFrustumModelView);
glUniformMatrix4fv(modelViewLocation, 1, GL_FALSE, viewFrustumModelView);
glBindVertexArray(vertexArrayObject);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, lineIndexBuffer);
glDrawElements(GL_LINES, 24, GL_UNSIGNED_INT, 0);
}
// draw floor
glUseProgram(floorProgram);
glBindVertexArray(vertexArrayObject);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, floorIndexBuffer);
glUniformMatrix4fv(glGetUniformLocation(floorProgram, "uView"), 1, GL_FALSE, viewMatrix);
glUniformMatrix4fv(glGetUniformLocation(floorProgram, "uProjection"), 1, GL_FALSE, projectionMatrix);
mat4 floorModelMatrix;
vec3 floorScale;
mat4Identity(floorModelMatrix);
vec3Set(floorScale, 10.0f, 0.01f, 10.0f);
mat4Scale(floorModelMatrix, floorModelMatrix, floorScale);
glUniformMatrix4fv(glGetUniformLocation(floorProgram, "uModel"), 1, GL_FALSE, floorModelMatrix);
glDepthMask(GL_FALSE);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glDepthMask(GL_TRUE);
} }
void framebuffer_size_callback(GLFWwindow* window, int width, int height) { void framebuffer_size_callback(GLFWwindow* window, int width, int height) {
@ -303,9 +551,7 @@ int main(int argc, char const *argv[])
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER , GLFW_TRUE); window = glfwCreateWindow(initialWindowWidth, initialWindowHeight, "CG1", NULL, NULL);
GLFWwindow* window = glfwCreateWindow(initialWindowWidth, initialWindowHeight, "CG1", NULL, NULL);
aspect = (float)initialWindowWidth / initialWindowHeight; aspect = (float)initialWindowWidth / initialWindowHeight;
if (!window) { if (!window) {

View File

@ -1,6 +1,7 @@
#include "matrix-math.h" #include "matrix-math.h"
#include <math.h> #include <math.h>
#include <stdio.h> #include <stdio.h>
#include <string.h>
/** /**
* overwrites a 4x4 matrix with the identity matrix * overwrites a 4x4 matrix with the identity matrix
@ -195,6 +196,7 @@ void mat4BuildProjection(mat4 out, GLfloat r, GLfloat l, GLfloat t, GLfloat b, G
out[11] = -1.0f / n; out[11] = -1.0f / n;
out[14] = - 2.0f * f / (f - n); out[14] = - 2.0f * f / (f - n);
out[15] = 0.0f;
} }
/** /**
@ -457,7 +459,6 @@ void mat3Minor(mat3 out, mat3 in) {
result[4] = in[0] * in[8] - in[2] * in[6]; result[4] = in[0] * in[8] - in[2] * in[6];
result[5] = in[0] * in[7] - in[1] * in[6]; result[5] = in[0] * in[7] - in[1] * in[6];
result[6] = in[1] * in[5] - in[2] * in[4]; result[6] = in[1] * in[5] - in[2] * in[4];
result[7] = in[0] * in[5] - in[2] * in[3]; result[7] = in[0] * in[5] - in[2] * in[3];
result[8] = in[0] * in[4] - in[1] * in[3]; result[8] = in[0] * in[4] - in[1] * in[3];

View File

@ -0,0 +1,8 @@
#version 330 core
in vec4 vPosition;
void main() {
gl_FragColor = mix(vec4(1,1,1,0.5), vec4(0.8,0.8,0.8,0.5), step(0, sin(vPosition.x * 3.14159) * sin(vPosition.z * 3.14159)));
// gl_FragColor = vec4(1,0,0,1);
}

View File

@ -0,0 +1,14 @@
#version 330 core
layout (location = 0) in vec3 aPosition;
uniform mat4 uModel;
uniform mat4 uView;
uniform mat4 uProjection;
out vec4 vPosition;
void main() {
vPosition = uModel * vec4(aPosition, 1);
gl_Position = uProjection * uView * vPosition;
}

View File

@ -8,8 +8,10 @@ vec3 colors[6] = vec3[6](
vec3(0.5, 1.0, 1.0) vec3(0.5, 1.0, 1.0)
); );
uniform float uBrightness;
void main() { void main() {
// hacky solution to give each side a different colour // hacky solution to give each side a different colour
int side = gl_PrimitiveID / 2; int side = gl_PrimitiveID / 2;
gl_FragColor = vec4(colors[side], 1.0); gl_FragColor = vec4(colors[side] * uBrightness, 1.0);
} }

View File

@ -0,0 +1,7 @@
#version 330 core
in vec3 vertexColor;
void main() {
gl_FragColor = vec4(vertexColor, 1.0);
}

View File

@ -0,0 +1,13 @@
#version 330 core
layout (location = 0) in vec3 aPosition;
layout (location = 1) in vec3 aColor;
uniform mat4 uModelView;
uniform mat4 uProjection;
out vec3 vertexColor;
void main() {
vertexColor = aColor;
gl_Position = uProjection * uModelView * vec4(aPosition, 1.0);
}