Compare commits
4 Commits
visualisat
...
main
Author | SHA1 | Date |
---|---|---|
|
63c44f9f7a | |
|
dd201108e6 | |
|
6ccfb7e818 | |
|
cced3c5c83 |
64
Makefile
64
Makefile
|
@ -1,33 +1,33 @@
|
|||
# Detect OS
|
||||
OS := $(shell uname)
|
||||
|
||||
GLEW_LIBS := $(shell pkgconf --libs glew)
|
||||
GLFW_LIBS := $(shell pkgconf --libs glfw3)
|
||||
|
||||
# Set libraries for Linux
|
||||
ifeq ($(OS), Linux)
|
||||
OPENGL_LIB := -lGL
|
||||
# Set libraries for Windows (MSYS2)
|
||||
else
|
||||
OPENGL_LIB := -lopengl32
|
||||
endif
|
||||
|
||||
# Source files
|
||||
SRC := src/main.c src/log.c src/shader.c src/matrix-math.c
|
||||
|
||||
# Output binary
|
||||
OUT := cg1
|
||||
|
||||
# Compiler
|
||||
CC := gcc
|
||||
|
||||
# Build target
|
||||
$(OUT): $(SRC)
|
||||
$(CC) -o $(OUT) $(SRC) $(GLEW_LIBS) $(GLFW_LIBS) $(OPENGL_LIB)
|
||||
|
||||
# Clean target
|
||||
clean:
|
||||
rm -f $(OUT)
|
||||
|
||||
# mark phony targets
|
||||
# Detect OS
|
||||
OS := $(shell uname)
|
||||
|
||||
GLEW_LIBS := $(shell pkgconf --libs glew)
|
||||
GLFW_LIBS := $(shell pkgconf --libs glfw3)
|
||||
|
||||
# Set libraries for Linux
|
||||
ifeq ($(OS), Linux)
|
||||
OPENGL_LIB := -lGL
|
||||
# Set libraries for Windows (MSYS2)
|
||||
else
|
||||
OPENGL_LIB := -lopengl32
|
||||
endif
|
||||
|
||||
# Source files
|
||||
SRC := src/main.c src/log.c src/shader.c
|
||||
|
||||
# Output binary
|
||||
OUT := cg1
|
||||
|
||||
# Compiler
|
||||
CC := gcc
|
||||
|
||||
# Build target
|
||||
$(OUT): $(SRC)
|
||||
$(CC) -o $(OUT) $(SRC) $(GLEW_LIBS) $(GLFW_LIBS) $(OPENGL_LIB)
|
||||
|
||||
# Clean target
|
||||
clean:
|
||||
rm -f $(OUT)
|
||||
|
||||
# mark phony targets
|
||||
.PHONY: clean
|
|
@ -7,7 +7,8 @@ src_files = [
|
|||
'./src/main.c',
|
||||
'./src/shader.c',
|
||||
'./src/log.c',
|
||||
'./src/matrix-math.c'
|
||||
'./src/matrix-math.c',
|
||||
'./src/wavefrontobj.c'
|
||||
]
|
||||
|
||||
executable('cg1',
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
# 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
377
src/main.c
377
src/main.c
|
@ -11,31 +11,21 @@
|
|||
#include "log.h"
|
||||
#include "shader.h"
|
||||
#include "matrix-math.h"
|
||||
#include "wavefrontobj.h"
|
||||
|
||||
#define STATUS_INTERVAL 0.5
|
||||
#define PI 3.14159f
|
||||
|
||||
GLFWwindow* window;
|
||||
|
||||
GLuint program;
|
||||
GLuint originProgram;
|
||||
GLuint floorProgram;
|
||||
|
||||
GLuint vertexArrayObject;
|
||||
|
||||
GLuint originVAO;
|
||||
|
||||
GLuint indexBuffer;
|
||||
GLuint lineIndexBuffer;
|
||||
GLuint floorIndexBuffer;
|
||||
GLuint numVertices;
|
||||
|
||||
GLuint initialWindowWidth = 800;
|
||||
GLuint initialWindowHeight = 600;
|
||||
|
||||
GLfloat aspect;
|
||||
mat4 realProjectionMatrix;
|
||||
|
||||
GLfloat currentTime = 0.0f;
|
||||
mat4 projectionMatrix;
|
||||
|
||||
int frameCount = 0;
|
||||
struct timespec last_time, current_time;
|
||||
|
@ -87,19 +77,19 @@ void updateStatusDisplay() {
|
|||
double fps = frameCount / elapsed;
|
||||
frameCount = 0;
|
||||
last_time = current_time;
|
||||
printf("\rFPS: %5.2f - currentTime: %5.2f", fps, currentTime);
|
||||
printf("\rFPS: %.2f ", fps);
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
void recalculateProjectionMatrix() {
|
||||
mat4BuildPerspective(realProjectionMatrix, 90 * M_PI / 180, aspect, 0.1, 50);
|
||||
mat4BuildPerspective(projectionMatrix, 60 * M_PI / 180, aspect, 0.1, 10);
|
||||
DEBUG("Recalculating Projection Matrix");
|
||||
}
|
||||
|
||||
void init(void) {
|
||||
|
||||
INFO("Building main program...");
|
||||
INFO("Building Programs...");
|
||||
ProgramLinkResult linkResult = buildShaderProgram("src/shaders/vertex.glsl", "src/shaders/fragment.glsl");
|
||||
if (!linkResult.success) {
|
||||
FATAL("Failed to link Program");
|
||||
|
@ -108,25 +98,6 @@ void init(void) {
|
|||
|
||||
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.");
|
||||
|
||||
// create triangle buffer
|
||||
|
@ -151,73 +122,15 @@ void init(void) {
|
|||
*
|
||||
*/
|
||||
|
||||
GLfloat vertices[] = {
|
||||
// X // Y
|
||||
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("Loading OBJ File");
|
||||
ParsedObjFile f = readObjFile("obj/smooth_monkey.obj");
|
||||
numVertices = f.length * sizeof(face) / sizeof(vertex);
|
||||
|
||||
DEBUG("Creating vertext buffer");
|
||||
GLuint vertexBuffer;
|
||||
glGenBuffers(1, &vertexBuffer);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
||||
glBufferData(GL_ARRAY_BUFFER, f.length * sizeof(face), f.faces, GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
DEBUG("Creating vertex array object");
|
||||
|
@ -232,83 +145,32 @@ void init(void) {
|
|||
3, // number of values to read
|
||||
GL_FLOAT, // type of value
|
||||
GL_FALSE, // if values are normalised
|
||||
3 * sizeof(GLfloat), // stride - distance between vertices
|
||||
sizeof(vertex), // stride - distance between vertices
|
||||
0 // start offset
|
||||
);
|
||||
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
|
||||
1,
|
||||
3,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
sizeof(vertex),
|
||||
(void*)offsetof(vertex, normal)
|
||||
);
|
||||
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_ELEMENT_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
|
||||
|
||||
glClearColor(0.3f, 0.3f, 0.4f, 1.0f);
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 0.3f);
|
||||
glViewport(0, 0, initialWindowWidth, initialWindowHeight);
|
||||
|
||||
// glEnable(GL_CULL_FACE);
|
||||
glEnable(GL_CULL_FACE);
|
||||
glFrontFace(GL_CCW);
|
||||
|
||||
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();
|
||||
|
||||
recalculateProjectionMatrix();
|
||||
|
@ -316,213 +178,48 @@ void init(void) {
|
|||
INFO("--- Initialisation done ---");
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
GLfloat currentHue = 0.0f;
|
||||
|
||||
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();
|
||||
|
||||
mat4 identity;
|
||||
mat4Identity(identity);
|
||||
|
||||
mat4 projectionMatrix;
|
||||
// mat4Interpolate(projectionMatrix, identity, projectionMatrix, mapTo01(currentHue, 0.0f, 0.1f));
|
||||
|
||||
// counter for animation
|
||||
currentTime += 0.0001f;
|
||||
int state = glfwGetKey(window, GLFW_KEY_SPACE);
|
||||
if (state == GLFW_PRESS)
|
||||
{
|
||||
currentTime += 0.001f;
|
||||
}
|
||||
if (currentTime > 0.55f) currentTime = 0.0f;
|
||||
currentHue += 0.005f;
|
||||
if (currentHue > 1.0) currentHue = 0.0f;
|
||||
|
||||
// clear colour and depth buffer
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// select program
|
||||
glUseProgram(program);
|
||||
|
||||
// build view matrix
|
||||
mat4 viewMatrix;
|
||||
|
||||
// mat4Identity(viewMatrix);
|
||||
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.0f, 0.0f};
|
||||
vec3 cameraPos = {cos(currentHue * M_PI * 2), 0.0f, sin(currentHue * M_PI * 2)};
|
||||
vec3 cameraLookAt = {0.0f, 0.2f, 0.0f};
|
||||
vec3 cameraUp = {0.0f, 1.0f, 0.0f};
|
||||
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");
|
||||
glUniformMatrix4fv(projectionLocation, 1, GL_FALSE, projectionMatrix);
|
||||
|
||||
// cubes.
|
||||
|
||||
// build model Matrix
|
||||
mat4 modelMatrix;
|
||||
vec3 scale;
|
||||
vec3 position;
|
||||
mat4 modelViewMatrix;
|
||||
|
||||
vec3 scale = {0.2f, 0.2f, 0.2f};
|
||||
|
||||
// cube 1
|
||||
mat4Identity(modelMatrix);
|
||||
|
||||
vec3Set(scale, 0.5f, 0.5f, 0.5f);
|
||||
mat4Scale(modelMatrix, modelMatrix, scale);
|
||||
mat4Multiply(modelViewMatrix, viewMatrix, modelMatrix);
|
||||
|
||||
mat4RotateY(modelMatrix, modelMatrix, 0.5f);
|
||||
glUniformMatrix4fv(glGetUniformLocation(program, "uModelView"), 1, GL_FALSE, modelViewMatrix);
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, numVertices);
|
||||
}
|
||||
|
||||
void framebuffer_size_callback(GLFWwindow* window, int width, int height) {
|
||||
|
@ -551,7 +248,9 @@ int main(int argc, char const *argv[])
|
|||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
|
||||
window = glfwCreateWindow(initialWindowWidth, initialWindowHeight, "CG1", NULL, NULL);
|
||||
glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER , GLFW_TRUE);
|
||||
|
||||
GLFWwindow* window = glfwCreateWindow(initialWindowWidth, initialWindowHeight, "CG1", NULL, NULL);
|
||||
|
||||
aspect = (float)initialWindowWidth / initialWindowHeight;
|
||||
if (!window) {
|
||||
|
|
|
@ -422,6 +422,18 @@ void vec3Set(vec3 out, GLfloat x, GLfloat y, GLfloat 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) {
|
||||
for (int i = 0; i < 9; i++) {
|
||||
|
|
|
@ -9,10 +9,12 @@
|
|||
|
||||
typedef GLfloat vec4[4];
|
||||
typedef GLfloat vec3[3];
|
||||
typedef GLfloat vec2[2];
|
||||
|
||||
typedef GLfloat mat4[16];
|
||||
typedef GLfloat mat3[9];
|
||||
|
||||
|
||||
extern void mat4Identity(mat4 mat);
|
||||
extern void mat4Copy(mat4 src, mat4 dst);
|
||||
extern void mat4Empty(mat4 mat);
|
||||
|
@ -36,6 +38,9 @@ extern void vec3Normalise(vec3 out, vec3 in);
|
|||
extern GLfloat vec3Length(vec3 in);
|
||||
extern GLfloat vec3DotProduct(vec3 a, vec3 b);
|
||||
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 mat3Inverse(mat3 out, mat3 in);
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
#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);
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
#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;
|
||||
}
|
|
@ -1,17 +1,6 @@
|
|||
#version 330 core
|
||||
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;
|
||||
in vec3 vNormal;
|
||||
|
||||
void main() {
|
||||
// hacky solution to give each side a different colour
|
||||
int side = gl_PrimitiveID / 2;
|
||||
gl_FragColor = vec4(colors[side] * uBrightness, 1.0);
|
||||
gl_FragColor = vec4(vNormal * 0.5 + vec3(0.5), 1.0);
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
#version 330 core
|
||||
|
||||
in vec3 vertexColor;
|
||||
|
||||
void main() {
|
||||
gl_FragColor = vec4(vertexColor, 1.0);
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
#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);
|
||||
}
|
|
@ -1,8 +1,12 @@
|
|||
#version 330 core
|
||||
layout (location = 0) in vec3 aPosition;
|
||||
layout (location = 1) in vec3 aNormal;
|
||||
uniform mat4 uModelView;
|
||||
uniform mat4 uProjection;
|
||||
|
||||
out vec3 vNormal;
|
||||
|
||||
void main() {
|
||||
vNormal = aNormal;
|
||||
gl_Position = uProjection * uModelView * vec4(aPosition, 1.0);
|
||||
}
|
|
@ -0,0 +1,242 @@
|
|||
#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);
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
#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
|
Loading…
Reference in New Issue