Compare commits

..

5 Commits

17 changed files with 427 additions and 2052435 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

@ -7,8 +7,7 @@ src_files = [
'./src/main.c', './src/main.c',
'./src/shader.c', './src/shader.c',
'./src/log.c', './src/log.c',
'./src/matrix-math.c', './src/matrix-math.c'
'./src/wavefrontobj.c'
] ]
executable('cg1', executable('cg1',

View File

@ -1,34 +0,0 @@
# Blender 4.4.3
# www.blender.org
o Cube
v 1.000000 1.000000 -1.000000
v 1.000000 -1.000000 -1.000000
v 1.000000 1.000000 1.000000
v 1.000000 -1.000000 1.000000
v -1.000000 1.000000 -1.000000
v -1.000000 -1.000000 -1.000000
v -1.000000 1.000000 1.000000
v -1.000000 -1.000000 1.000000
vn -0.0000 1.0000 -0.0000
vn -0.0000 -0.0000 1.0000
vn -1.0000 -0.0000 -0.0000
vn -0.0000 -1.0000 -0.0000
vn 1.0000 -0.0000 -0.0000
vn -0.0000 -0.0000 -1.0000
vt 1.000000 0.000000
vt 0.000000 1.000000
vt 0.000000 0.000000
vt 1.000000 1.000000
s 0
f 5/1/1 3/2/1 1/3/1
f 3/1/2 8/2/2 4/3/2
f 7/1/3 6/2/3 8/3/3
f 2/1/4 8/2/4 6/3/4
f 1/1/5 4/2/5 2/3/5
f 5/1/6 2/2/6 6/3/6
f 5/1/1 7/4/1 3/2/1
f 3/1/2 7/4/2 8/2/2
f 7/1/3 5/4/3 6/2/3
f 2/1/4 4/4/4 8/2/4
f 1/1/5 3/4/5 4/2/5
f 5/1/6 1/4/6 2/2/6

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -11,21 +11,31 @@
#include "log.h" #include "log.h"
#include "shader.h" #include "shader.h"
#include "matrix-math.h" #include "matrix-math.h"
#include "wavefrontobj.h"
#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 numVertices;
GLuint originVAO;
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
@ -122,15 +151,73 @@ void init(void) {
* *
*/ */
DEBUG("Loading OBJ File"); GLfloat vertices[] = {
ParsedObjFile f = readObjFile("obj/smooth_monkey.obj"); // X // Y
numVertices = f.length * sizeof(face) / sizeof(vertex); 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, -1.0f,
1.0f, -1.0f, 1.0f,
1.0f, -1.0f, -1.0f,
-1.0f, 1.0f, 1.0f,
-1.0f, 1.0f, -1.0f,
-1.0f, -1.0f, 1.0f,
-1.0f, -1.0f, -1.0f,
};
GLuint restart = 128;
glEnable(GL_PRIMITIVE_RESTART);
glPrimitiveRestartIndex(restart);
GLuint indices[] = {
1, 0, 2,
1, 2, 3,
4, 0, 1,
5, 4, 1,
5, 1, 7,
1, 3, 7,
5, 7, 6,
4, 5, 6,
0, 4, 6,
2, 0, 6,
3, 2, 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);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, f.length * sizeof(face), f.faces, GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
DEBUG("Creating vertex array object"); DEBUG("Creating vertex array object");
@ -145,32 +232,83 @@ void init(void) {
3, // number of values to read 3, // number of values to read
GL_FLOAT, // type of value GL_FLOAT, // type of value
GL_FALSE, // if values are normalised GL_FALSE, // if values are normalised
sizeof(vertex), // stride - distance between vertices 3 * sizeof(GLfloat), // stride - distance between vertices
0 // start offset 0 // start offset
); );
glEnableVertexAttribArray(0); glEnableVertexAttribArray(0);
glVertexAttribPointer( glVertexAttribPointer(
1, 1, // shader location
3, 3, // number of values to read
GL_FLOAT, GL_FLOAT, // type of value
GL_FALSE, GL_FALSE, // if values are normalised
sizeof(vertex), 3 * sizeof(GLfloat), // stride - distance between vertices
(void*)offsetof(vertex, normal) 0 // start offset
); );
glEnableVertexAttribArray(1); glEnableVertexAttribArray(1);
DEBUG("Creating index buffers");
glGenBuffers(1, &indexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
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();
@ -178,48 +316,213 @@ void init(void) {
INFO("--- Initialisation done ---"); INFO("--- Initialisation done ---");
} }
GLfloat currentHue = 0.0f; void drawCube(mat4 modelMatrix, mat4 viewMatrix) {
mat4 modelViewMatrix;
mat4Multiply(modelViewMatrix, viewMatrix, modelMatrix);
// send modelView and projection matrix to shader
GLuint modelViewLocation = glGetUniformLocation(program, "uModelView");
glUniformMatrix4fv(modelViewLocation, 1, GL_FALSE, modelViewMatrix);
// draw cube
glBindVertexArray(vertexArrayObject);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
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.005f; 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 = {cos(currentHue * M_PI * 2), 0.0f, sin(currentHue * M_PI * 2)}; 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;
mat4 modelViewMatrix; vec3 scale;
vec3 position;
vec3 scale = {0.2f, 0.2f, 0.2f};
// cube 1
mat4Identity(modelMatrix); mat4Identity(modelMatrix);
mat4Scale(modelMatrix, modelMatrix, scale);
mat4Multiply(modelViewMatrix, viewMatrix, modelMatrix);
glUniformMatrix4fv(glGetUniformLocation(program, "uModelView"), 1, GL_FALSE, modelViewMatrix); vec3Set(scale, 0.5f, 0.5f, 0.5f);
mat4Scale(modelMatrix, modelMatrix, scale);
mat4RotateY(modelMatrix, modelMatrix, 0.5f);
vec3Set(position, -0.3f, 0.5f, -0.4f);
mat4Translate(modelMatrix, modelMatrix, position);
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); glBindVertexArray(vertexArrayObject);
glDrawArrays(GL_TRIANGLES, 0, numVertices); 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) {
@ -248,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

@ -422,18 +422,6 @@ void vec3Set(vec3 out, GLfloat x, GLfloat y, GLfloat z) {
out[2] = z; out[2] = z;
} }
void vec3Multiply(vec3 out, vec3 in, GLfloat x) {
out[0] = in[0] * x;
out[1] = in[1] * x;
out[2] = in[2] * x;
}
void vec2Subtract(vec2 out, vec2 a, vec2 b) {
out[0] = a[0] - b[0];
out[1] = a[1] - b[1];
}
void mat3Copy(mat3 src, mat3 dst) { void mat3Copy(mat3 src, mat3 dst) {
for (int i = 0; i < 9; i++) { for (int i = 0; i < 9; i++) {

View File

@ -9,12 +9,10 @@
typedef GLfloat vec4[4]; typedef GLfloat vec4[4];
typedef GLfloat vec3[3]; typedef GLfloat vec3[3];
typedef GLfloat vec2[2];
typedef GLfloat mat4[16]; typedef GLfloat mat4[16];
typedef GLfloat mat3[9]; typedef GLfloat mat3[9];
extern void mat4Identity(mat4 mat); extern void mat4Identity(mat4 mat);
extern void mat4Copy(mat4 src, mat4 dst); extern void mat4Copy(mat4 src, mat4 dst);
extern void mat4Empty(mat4 mat); extern void mat4Empty(mat4 mat);
@ -38,9 +36,6 @@ extern void vec3Normalise(vec3 out, vec3 in);
extern GLfloat vec3Length(vec3 in); extern GLfloat vec3Length(vec3 in);
extern GLfloat vec3DotProduct(vec3 a, vec3 b); extern GLfloat vec3DotProduct(vec3 a, vec3 b);
extern void vec3Set(vec3 out, GLfloat x, GLfloat y, GLfloat z); extern void vec3Set(vec3 out, GLfloat x, GLfloat y, GLfloat z);
extern void vec3Multiply(vec3 out, vec3 in, GLfloat x);
extern void vec2Subtract(vec2 out, vec2 a, vec2 b);
extern void mat3Copy(mat3 src, mat3 dst); extern void mat3Copy(mat3 src, mat3 dst);
extern void mat3Inverse(mat3 out, mat3 in); extern void mat3Inverse(mat3 out, mat3 in);

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

@ -1,6 +1,17 @@
#version 330 core #version 330 core
in vec3 vNormal; vec3 colors[6] = vec3[6](
vec3(1.0, 0.5, 0.5),
vec3(0.5, 1.0, 0.5),
vec3(0.5, 0.5, 1.0),
vec3(1.0, 1.0, 0.5),
vec3(1.0, 0.5, 1.0),
vec3(0.5, 1.0, 1.0)
);
uniform float uBrightness;
void main() { void main() {
gl_FragColor = vec4(vNormal * 0.5 + vec3(0.5), 1.0); // hacky solution to give each side a different colour
int side = gl_PrimitiveID / 2;
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);
}

View File

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

View File

@ -1,242 +0,0 @@
#include <GL/glew.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "wavefrontobj.h"
#define OBJ_LINE_BUFFER_SIZE 256
/**
*
* ADJUSTMENT NEEDED FOR
* - Face Definitions other than vertex/texture/normal
* - Vertex positions including w
* - Any faces using vertices yet to be defined
* (File is read top to bottom. A face using a vertex
* defined underneath it in the file will not work)
*
*/
void storeFace(
face* f,
vec3 v1, vec2 vt1, vec3 vn1,
vec3 v2, vec2 vt2, vec3 vn2,
vec3 v3, vec2 vt3, vec3 vn3
) {
memcpy(&f->v1.position, v1, sizeof(vec3));
memcpy(&f->v2.position, v2, sizeof(vec3));
memcpy(&f->v3.position, v3, sizeof(vec3));
memcpy(&f->v1.normal, vn1, sizeof(vec3));
memcpy(&f->v2.normal, vn2, sizeof(vec3));
memcpy(&f->v3.normal, vn3, sizeof(vec3));
memcpy(&f->v1.texture, vt1, sizeof(vec2));
memcpy(&f->v2.texture, vt2, sizeof(vec2));
memcpy(&f->v3.texture, vt3, sizeof(vec2));
}
// void storeTB(face* f,
// vec3 v1, vec2 vt1, vec3 vn1,
// vec3 v2, vec2 vt2, vec3 vn2,
// vec3 v3, vec2 vt3, vec3 vn3
// ) {
// // https://www.opengl-tutorial.org/intermediate-tutorials/tutorial-13-normal-mapping/
// vec3 deltaPos1;
// vec3 deltaPos2;
// vec3Subtract(deltaPos1, v2, v1);
// vec3Subtract(deltaPos1, v3, v1);
// vec2 deltaTex1;
// vec2 deltaTex2;
// vec2Subtract(deltaTex1, vt2, vt1);
// vec2Subtract(deltaTex2, vt3, vt1);
// GLfloat r = 1.0f / (deltaTex1[0] * deltaTex2[1] - deltaTex1[1] * deltaTex2[0]);
// vec3Multiply(deltaPos1, deltaPos1, deltaTex2[1]);
// vec3Multiply(deltaPos2, deltaPos2, deltaTex1[1]);
// vec3 tangent;
// vec3Subtract(tangent, deltaPos1, deltaPos2);
// vec3Multiply(tangent, tangent, r);
// memcpy(&f->v1.tangent, &tangent, sizeof(vec3));
// memcpy(&f->v2.tangent, &tangent, sizeof(vec3));
// memcpy(&f->v3.tangent, &tangent, sizeof(vec3));
// }
ParsedObjFile readObjFile(char* path) {
ParsedObjFile parsedFile;
FILE* fp = fopen(path, "r");
if (fp == NULL) {
fprintf(stderr, "File could not be opened: %s", path);
parsedFile.faces = NULL;
parsedFile.length = 0;
}
uint numVertices = 0;
uint numVertexNormals = 0;
uint numFaces = 0;
uint numTextureCoords = 0;
char buf[OBJ_LINE_BUFFER_SIZE];
while (fgets(buf, OBJ_LINE_BUFFER_SIZE, fp)) {
if (buf[0] == 'v') {
if (buf[1] == ' ') {
numVertices++;
} else if (buf[1] == 't') {
numTextureCoords++;
} else if (buf[1] == 'n') {
numVertexNormals++;
}
}
if (buf[0] == 'f') {
int numSpaces = 0;
for (int i = 0; i < strlen(buf); i++) {
if (buf[i] == ' ') {
numSpaces++;
}
}
numFaces += numSpaces - 2;
}
}
// printf("Vertices: %d\nFaces: %d\nNormals:%d\nTextures:%d\n", numVertices, numFaces, numVertexNormals, numTextureCoords);
vec3* vertices = (vec3*) malloc(sizeof(vec3) * numVertices);
vec3* normals = (vec3*) malloc(sizeof(vec3) * numVertexNormals);
vec2* textures = (vec2*) malloc(sizeof(vec2) * numTextureCoords);
face* faces = (face*) malloc(sizeof(face) * numFaces);
parsedFile.faces = faces;
parsedFile.length = numFaces;
rewind(fp);
uint curVertex = 0;
uint curNormal = 0;
uint curFace = 0;
uint curTexture = 0;
while (fgets(buf, OBJ_LINE_BUFFER_SIZE, fp)) {
if (buf[0] == 'v') {
if (buf[1] == ' ') {
sscanf(buf,
"v %f %f %f",
&vertices[curVertex][0],
&vertices[curVertex][1],
&vertices[curVertex][2]
);
curVertex++;
} else if (buf[1] == 't') {
int readValues = sscanf(buf,
"vt %f %f",
&textures[curTexture][0],
&textures[curTexture][1]
);
if (readValues != 2) {
textures[curTexture][1] = 0;
}
curTexture++;
} else if (buf[1] == 'n') {
sscanf(buf,
"vn %f %f %f",
&normals[curNormal][0],
&normals[curNormal][1],
&normals[curNormal][2]
);
curNormal++;
}
}
if (buf[0] == 'f') {
int v1, v2, v3;
int vt1, vt2, vt3;
int vn1, vn2, vn3;
sscanf(buf,
"f %d/%d/%d %d/%d/%d %d/%d/%d",
&v1, &vt1, &vn1,
&v2, &vt2, &vn2,
&v3, &vt3, &vn3
);
storeFace(&faces[curFace],
vertices[v1 - 1], textures[vt1 - 1], normals[vn1 - 1],
vertices[v2 - 1], textures[vt2 - 1], normals[vn2 - 1],
vertices[v3 - 1], textures[vt3 - 1], normals[vn3 - 1]
);
// storeTB(&faces[curFace],
// vertices[v1 - 1], textures[vt1 - 1], normals[vn1 - 1],
// vertices[v2 - 1], textures[vt2 - 1], normals[vn2 - 1],
// vertices[v3 - 1], textures[vt3 - 1], normals[vn3 - 1]
// );
curFace++;
int numSpaces = 0;
for (int i = 0; i < strlen(buf); i++) {
if (buf[i] == ' ') {
numSpaces++;
}
}
if (numSpaces == 4) {
// storeTB(&faces[curFace],
// vertices[v1 - 1], textures[vt1 - 1], normals[vn1 - 1],
// vertices[v2 - 1], textures[vt2 - 1], normals[vn2 - 1],
// vertices[v3 - 1], textures[vt3 - 1], normals[vn3 - 1]
// );
sscanf(buf,
"f %d/%d/%d %*d/%*d/%*d %d/%d/%d %d/%d/%d",
&v1, &vt1, &vn1,
&v2, &vt2, &vn2,
&v3, &vt3, &vn3
);
storeFace(&faces[curFace],
vertices[v1 - 1], textures[vt1 - 1], normals[vn1 - 1],
vertices[v2 - 1], textures[vt2 - 1], normals[vn2 - 1],
vertices[v3 - 1], textures[vt3 - 1], normals[vn3 - 1]
);
curFace++;
}
// TODO: textures
}
}
free(vertices);
free(normals);
fclose(fp);
return parsedFile;
}
void clearParsedFile(ParsedObjFile file) {
free(file.faces);
}

View File

@ -1,30 +0,0 @@
#ifndef WAVEFRONTOBJ_H
#define WAVEFRONTOBJ_H
#include <GL/glew.h>
#include "matrix-math.h"
typedef struct {
vec3 position;
vec3 normal;
vec2 texture;
// vec3 tangent;
} vertex;
typedef struct {
vertex v1;
vertex v2;
vertex v3;
} face;
typedef struct {
face* faces;
GLuint length;
} ParsedObjFile;
extern ParsedObjFile readObjFile(char* path);
extern void clearParsedFile(ParsedObjFile file);
#endif