Compare commits
No commits in common. "main" and "u02" have entirely different histories.
10
meson.build
10
meson.build
|
@ -1,14 +1,9 @@
|
|||
project('cg1', 'c')
|
||||
|
||||
cc = meson.get_compiler('c')
|
||||
m_dep = cc.find_library('m', required : false)
|
||||
|
||||
src_files = [
|
||||
'./src/main.c',
|
||||
'./src/shader.c',
|
||||
'./src/log.c',
|
||||
'./src/matrix-math.c',
|
||||
'./src/wavefrontobj.c'
|
||||
'./src/log.c'
|
||||
]
|
||||
|
||||
executable('cg1',
|
||||
|
@ -16,7 +11,6 @@ executable('cg1',
|
|||
dependencies: [
|
||||
dependency('GL'),
|
||||
dependency('glew'),
|
||||
dependency('glfw3'),
|
||||
m_dep
|
||||
dependency('glfw3')
|
||||
]
|
||||
)
|
34
obj/cube.obj
34
obj/cube.obj
|
@ -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
|
2066
obj/monkey.obj
2066
obj/monkey.obj
File diff suppressed because it is too large
Load Diff
2033859
obj/smooth_monkey.obj
2033859
obj/smooth_monkey.obj
File diff suppressed because it is too large
Load Diff
16109
obj/teapot.obj
16109
obj/teapot.obj
File diff suppressed because it is too large
Load Diff
10
src/log.h
10
src/log.h
|
@ -22,10 +22,10 @@ extern unsigned int logLevel;
|
|||
#define DEBUG_COL "\x1B[90m"
|
||||
#define NORMAL_COL "\x1B[0m"
|
||||
|
||||
#define FATAL(...) if (logLevel >= LOG_LEVEL_FATAL) { fprintf(stderr, "| %sFATAL%s | ", FATAL_COL, NORMAL_COL); fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n"); }
|
||||
#define ERROR(...) if (logLevel >= LOG_LEVEL_ERROR) { fprintf(stderr, "| %sERROR%s | ", ERROR_COL, NORMAL_COL); fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n"); }
|
||||
#define WARN(...) if (logLevel >= LOG_LEVEL_WARN) { fprintf(stderr, "| %sWARN%s | ", WARN_COL, NORMAL_COL); fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n"); }
|
||||
#define INFO(...) if (logLevel >= LOG_LEVEL_INFO) { fprintf(stderr, "| %sINFO%s | ", INFO_COL, NORMAL_COL); fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n"); }
|
||||
#define DEBUG(...) if (logLevel >= LOG_LEVEL_DEBUG) { fprintf(stderr, "| %sDEBUG%s | ", DEBUG_COL, NORMAL_COL); fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n"); }
|
||||
#define FATAL(...) if (logLevel >= LOG_LEVEL_FATAL) { printf("| %sFATAL%s | ", FATAL_COL, NORMAL_COL); printf(__VA_ARGS__); printf("\n"); }
|
||||
#define ERROR(...) if (logLevel >= LOG_LEVEL_ERROR) { printf("| %sERROR%s | ", ERROR_COL, NORMAL_COL); printf(__VA_ARGS__); printf("\n"); }
|
||||
#define WARN(...) if (logLevel >= LOG_LEVEL_WARN) { printf("| %sWARN%s | ", WARN_COL, NORMAL_COL); printf(__VA_ARGS__); printf("\n"); }
|
||||
#define INFO(...) if (logLevel >= LOG_LEVEL_INFO) { printf("| %sINFO%s | ", INFO_COL, NORMAL_COL); printf(__VA_ARGS__); printf("\n"); }
|
||||
#define DEBUG(...) if (logLevel >= LOG_LEVEL_DEBUG) { printf("| %sDEBUG%s | ", DEBUG_COL, NORMAL_COL); printf(__VA_ARGS__); printf("\n"); }
|
||||
|
||||
#endif // LOG_H
|
164
src/main.c
164
src/main.c
|
@ -1,5 +1,4 @@
|
|||
#include <GL/glew.h>
|
||||
#include <GL/gl.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
@ -10,23 +9,16 @@
|
|||
#include "shader.h"
|
||||
#include "log.h"
|
||||
#include "shader.h"
|
||||
#include "matrix-math.h"
|
||||
#include "wavefrontobj.h"
|
||||
|
||||
#define STATUS_INTERVAL 0.5
|
||||
#define PI 3.14159f
|
||||
|
||||
GLuint program;
|
||||
|
||||
GLuint vertexArrayObject;
|
||||
GLuint numVertices;
|
||||
|
||||
GLuint initialWindowWidth = 800;
|
||||
GLuint initialWindowHeight = 600;
|
||||
|
||||
GLfloat aspect;
|
||||
mat4 projectionMatrix;
|
||||
|
||||
int frameCount = 0;
|
||||
struct timespec last_time, current_time;
|
||||
|
||||
|
@ -47,7 +39,7 @@ GLfloat hueToRgb(GLfloat p, GLfloat q, GLfloat t) {
|
|||
return p;
|
||||
}
|
||||
|
||||
// Color Conversion Functions from https://gist.github.com/ciembor/1494530
|
||||
// Color Conversion Functions by Copilot
|
||||
ColorRGB hslToRgb(GLfloat h, GLfloat s, GLfloat l) {
|
||||
ColorRGB result = {0, 0, 0};
|
||||
|
||||
|
@ -82,15 +74,29 @@ void updateStatusDisplay() {
|
|||
}
|
||||
}
|
||||
|
||||
void recalculateProjectionMatrix() {
|
||||
mat4BuildPerspective(projectionMatrix, 60 * M_PI / 180, aspect, 0.1, 10);
|
||||
DEBUG("Recalculating Projection Matrix");
|
||||
}
|
||||
|
||||
void init(void) {
|
||||
INFO("Compiling Shaders...");
|
||||
|
||||
INFO("Building Programs...");
|
||||
ProgramLinkResult linkResult = buildShaderProgram("src/shaders/vertex.glsl", "src/shaders/fragment.glsl");
|
||||
// create and compile vertex shader
|
||||
INFO("Compiling Vertex Shader...");
|
||||
ShaderCompileResult vertexShader = readAndCompileShaderFromFile("src/shaders/vertex.glsl", GL_VERTEX_SHADER);
|
||||
|
||||
if (!vertexShader.success) {
|
||||
FATAL("Failed to compile Vertex Shader");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// create and compile fragment shader
|
||||
INFO("Compiling Fragment Shader...");
|
||||
ShaderCompileResult fragmentShader = readAndCompileShaderFromFile("src/shaders/fragment.glsl", GL_FRAGMENT_SHADER);
|
||||
if (!fragmentShader.success) {
|
||||
FATAL("Failed to compile Vertex Shader");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// create and link shader program
|
||||
INFO("Linking Shader Program...");
|
||||
ProgramLinkResult linkResult = linkShaderProgram(vertexShader.shader, fragmentShader.shader);
|
||||
if (!linkResult.success) {
|
||||
FATAL("Failed to link Program");
|
||||
exit(1);
|
||||
|
@ -106,31 +112,67 @@ void init(void) {
|
|||
* | -0.2 0.2 |
|
||||
* | | | |
|
||||
*
|
||||
* 0----1 4----5 --- 0.6
|
||||
* +----+ +----+ --- 0.6
|
||||
* | | | |
|
||||
* | | | |
|
||||
* | 2--------3 | --- 0.1
|
||||
* | +--------+ | --- 0.1
|
||||
* | |
|
||||
* | 9--------8 | --- -0.1
|
||||
* | +--------+ | --- -0.1
|
||||
* | | | |
|
||||
* | | | |
|
||||
* 11---10 7----6 --- -0.6
|
||||
* +----+ +----+ --- -0.6
|
||||
*
|
||||
* 12-----------------13 --- -0.7
|
||||
* +------------------+ --- -0.7
|
||||
* | |
|
||||
* 15-----------------14 --- -0.9
|
||||
* +------------------+ --- -0.9
|
||||
*
|
||||
*/
|
||||
|
||||
DEBUG("Loading OBJ File");
|
||||
ParsedObjFile f = readObjFile("obj/smooth_monkey.obj");
|
||||
numVertices = f.length * sizeof(face) / sizeof(vertex);
|
||||
GLfloat vertices[] = {
|
||||
// X // Y
|
||||
|
||||
// left vertical bar
|
||||
-0.35f, -0.6f,
|
||||
-0.35f, 0.6f,
|
||||
-0.2f, 0.6f,
|
||||
|
||||
-0.35f, -0.6f,
|
||||
-0.2f, 0.6f,
|
||||
-0.2f, -0.6f,
|
||||
|
||||
// right vertical bar
|
||||
0.35f, -0.6f,
|
||||
0.35f, 0.6f,
|
||||
0.2f, 0.6f,
|
||||
|
||||
0.35f, -0.6f,
|
||||
0.2f, 0.6f,
|
||||
0.2f, -0.6f,
|
||||
|
||||
// middle bar
|
||||
-0.2f, -0.1f,
|
||||
-0.2f, 0.1f,
|
||||
0.2f, 0.1f,
|
||||
|
||||
-0.2f, -0.1f,
|
||||
0.2f, 0.1f,
|
||||
0.2f, -0.1f,
|
||||
|
||||
// bottom bar
|
||||
-0.35f, -0.7f,
|
||||
-0.35f, -0.9f,
|
||||
0.35f, -0.9f,
|
||||
|
||||
-0.35f, -0.7f,
|
||||
0.35f, -0.9f,
|
||||
0.35f, -0.7f
|
||||
};
|
||||
|
||||
DEBUG("Creating vertext buffer");
|
||||
GLuint vertexBuffer;
|
||||
glGenBuffers(1, &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);
|
||||
|
||||
DEBUG("Creating vertex array object");
|
||||
|
@ -142,39 +184,22 @@ void init(void) {
|
|||
// vertex position data
|
||||
glVertexAttribPointer(
|
||||
0, // shader location
|
||||
3, // number of values to read
|
||||
2, // number of values to read
|
||||
GL_FLOAT, // type of value
|
||||
GL_FALSE, // if values are normalised
|
||||
sizeof(vertex), // stride - distance between vertices
|
||||
2 * sizeof(GLfloat), // stride - distance between vertices
|
||||
0 // start offset
|
||||
);
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
glVertexAttribPointer(
|
||||
1,
|
||||
3,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
sizeof(vertex),
|
||||
(void*)offsetof(vertex, normal)
|
||||
);
|
||||
glEnableVertexAttribArray(1);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 0.3f);
|
||||
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
|
||||
glViewport(0, 0, initialWindowWidth, initialWindowHeight);
|
||||
|
||||
glEnable(GL_CULL_FACE);
|
||||
glFrontFace(GL_CCW);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
initialiseStatusDisplay();
|
||||
|
||||
recalculateProjectionMatrix();
|
||||
|
||||
INFO("--- Initialisation done ---");
|
||||
}
|
||||
|
||||
|
@ -183,50 +208,25 @@ GLfloat currentHue = 0.0f;
|
|||
void draw(void) {
|
||||
updateStatusDisplay();
|
||||
|
||||
// counter for animation
|
||||
currentHue += 0.005f;
|
||||
currentHue += 0.001f;
|
||||
if (currentHue > 1.0) currentHue = 0.0f;
|
||||
|
||||
// clear colour and depth buffer
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// select program
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glUseProgram(program);
|
||||
|
||||
// build view matrix
|
||||
mat4 viewMatrix;
|
||||
GLuint colorLocation = glGetUniformLocation(program, "uColor");
|
||||
ColorRGB color = hslToRgb(currentHue, 1.0f, 0.5f);
|
||||
glUniform3f(colorLocation, color.r, color.g, color.b);
|
||||
|
||||
// mat4Identity(viewMatrix);
|
||||
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);
|
||||
|
||||
GLuint projectionLocation = glGetUniformLocation(program, "uProjection");
|
||||
glUniformMatrix4fv(projectionLocation, 1, GL_FALSE, projectionMatrix);
|
||||
|
||||
|
||||
// build model Matrix
|
||||
mat4 modelMatrix;
|
||||
mat4 modelViewMatrix;
|
||||
|
||||
vec3 scale = {0.2f, 0.2f, 0.2f};
|
||||
|
||||
mat4Identity(modelMatrix);
|
||||
mat4Scale(modelMatrix, modelMatrix, scale);
|
||||
mat4Multiply(modelViewMatrix, viewMatrix, modelMatrix);
|
||||
|
||||
glUniformMatrix4fv(glGetUniformLocation(program, "uModelView"), 1, GL_FALSE, modelViewMatrix);
|
||||
GLuint positionLocation = glGetUniformLocation(program, "uPosition");
|
||||
glUniform2f(positionLocation, cos(currentHue * 2 * M_PI) * 0.2f, sin(currentHue * 2 * M_PI) * 0.2f);
|
||||
|
||||
glBindVertexArray(vertexArrayObject);
|
||||
glDrawArrays(GL_TRIANGLES, 0, numVertices);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 48);
|
||||
}
|
||||
|
||||
void framebuffer_size_callback(GLFWwindow* window, int width, int height) {
|
||||
glViewport(0, 0, width, height);
|
||||
aspect = (float)width / height;
|
||||
|
||||
recalculateProjectionMatrix();
|
||||
}
|
||||
|
||||
int main(int argc, char const *argv[])
|
||||
|
@ -248,11 +248,7 @@ int main(int argc, char const *argv[])
|
|||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
|
||||
glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER , GLFW_TRUE);
|
||||
|
||||
GLFWwindow* window = glfwCreateWindow(initialWindowWidth, initialWindowHeight, "CG1", NULL, NULL);
|
||||
|
||||
aspect = (float)initialWindowWidth / initialWindowHeight;
|
||||
GLFWwindow *window = glfwCreateWindow(initialWindowWidth, initialWindowHeight, "CG1", NULL, NULL);
|
||||
if (!window) {
|
||||
FATAL("Failed to open window");
|
||||
glfwTerminate();
|
||||
|
|
|
@ -1,518 +0,0 @@
|
|||
#include "matrix-math.h"
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* overwrites a 4x4 matrix with the identity matrix
|
||||
*/
|
||||
void mat4Identity(mat4 mat) {
|
||||
for (int i = 0; i < 16; i++) {
|
||||
mat[i] = (i % 4 == i / 4) ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* copies a mat4 from src to dst
|
||||
*/
|
||||
void mat4Copy(mat4 src, mat4 dst) {
|
||||
for (int i = 0; i < 16; i++) {
|
||||
dst[i] = src[i];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* sets all the values in a mat4 to zero
|
||||
*/
|
||||
void mat4Empty(mat4 mat) {
|
||||
for (int i = 0; i < 16; i++) {
|
||||
mat[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* mutliplies A with B and stores the result in result
|
||||
*/
|
||||
void mat4Multiply(mat4 result, mat4 A, mat4 B) {
|
||||
// if result is one of the arguments, modify copy instead of result directly
|
||||
if (result == A || result == B) {
|
||||
mat4 tempResult;
|
||||
mat4Multiply(tempResult, A, B);
|
||||
mat4Copy(tempResult, result);
|
||||
return;
|
||||
}
|
||||
|
||||
// loops over cells of the result matrix
|
||||
for (int i = 0; i < 16; i++) {
|
||||
int col = i / 4;
|
||||
int row = i % 4;
|
||||
|
||||
// pointer to the current cell
|
||||
GLfloat* curr = &(result[i]);
|
||||
|
||||
// initialise current cell with 0
|
||||
*curr = 0;
|
||||
|
||||
// loop over the row of A and column of B
|
||||
// continuously adding the multiplication of the two values to the result cell
|
||||
for (int j = 0; j < 4; j++) {
|
||||
*curr += A[row + j * 4] * B[j + col * 4];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* prints a mat4 to the screen
|
||||
*/
|
||||
void mat4Print(mat4 m) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
printf("%.2f ", m[j * 4 + i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* translates by the vector v
|
||||
*/
|
||||
void mat4Translate(mat4 out, mat4 in, vec3 v) {
|
||||
mat4 T;
|
||||
mat4Identity(T);
|
||||
|
||||
T[12] = v[0];
|
||||
T[13] = v[1];
|
||||
T[14] = v[2];
|
||||
|
||||
mat4Multiply(out, T, in);
|
||||
}
|
||||
|
||||
/**
|
||||
* scales by the vector v
|
||||
*/
|
||||
void mat4Scale(mat4 out, mat4 in, vec3 v) {
|
||||
mat4 T;
|
||||
mat4Identity(T);
|
||||
|
||||
T[0] = v[0];
|
||||
T[5] = v[1];
|
||||
T[10] = v[2];
|
||||
|
||||
mat4Multiply(out, T, in);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* rotates around the X axis by the angle a (in radians)
|
||||
*/
|
||||
void mat4RotateX(mat4 out, mat4 in, GLfloat a) {
|
||||
mat4 T;
|
||||
mat4Identity(T);
|
||||
|
||||
T[5] = cos(a);
|
||||
T[6] = sin(a);
|
||||
T[9] = -sin(a);
|
||||
T[10] = cos(a);
|
||||
|
||||
mat4Multiply(out, T, in);
|
||||
}
|
||||
|
||||
/**
|
||||
* rotates around the Y axis by the angle a (in radians)
|
||||
*/
|
||||
void mat4RotateY(mat4 out, mat4 in, GLfloat a) {
|
||||
mat4 T;
|
||||
mat4Identity(T);
|
||||
|
||||
T[0] = cos(a);
|
||||
T[2] = -sin(a);
|
||||
T[8] = sin(a);
|
||||
T[10] = cos(a);
|
||||
|
||||
mat4Multiply(out, T, in);
|
||||
}
|
||||
|
||||
/**
|
||||
* rotates around the Z axis by the angle a (in radians)
|
||||
*/
|
||||
void mat4RotateZ(mat4 out, mat4 in, GLfloat a) {
|
||||
mat4 T;
|
||||
mat4Identity(T);
|
||||
|
||||
T[0] = cos(a);
|
||||
T[1] = sin(a);
|
||||
T[4] = -sin(a);
|
||||
T[5] = cos(a);
|
||||
|
||||
mat4Multiply(out, T, in);
|
||||
}
|
||||
|
||||
/**
|
||||
* builds a look-at matrix, overwriting out
|
||||
* eye is the position of the camera
|
||||
* look is the position of the target to be looked at
|
||||
* up is the up vector
|
||||
*/
|
||||
void mat4BuildLookAt(mat4 out, vec3 eye, vec3 look, vec3 up) {
|
||||
vec3 n;
|
||||
vec3 u;
|
||||
vec3 v;
|
||||
vec3 t;
|
||||
|
||||
vec3Subtract(n, eye, look);
|
||||
|
||||
vec3CrossProduct(u, up, n);
|
||||
|
||||
vec3CrossProduct(v, n, u);
|
||||
|
||||
vec3Normalise(n, n);
|
||||
vec3Normalise(u, u);
|
||||
vec3Normalise(v, v);
|
||||
|
||||
t[0] = - vec3DotProduct(u, eye);
|
||||
t[1] = - vec3DotProduct(v, eye);
|
||||
t[2] = - vec3DotProduct(n, eye);
|
||||
|
||||
out[0] = u[0]; out[4] = u[1]; out[8] = u[2]; out[12] = t[0];
|
||||
out[1] = v[0]; out[5] = v[1]; out[9] = v[2]; out[13] = t[1];
|
||||
out[2] = n[0]; out[6] = n[1]; out[10] = n[2]; out[14] = t[2];
|
||||
out[3] = 0; out[7] = 0; out[11] = 0; out[15] = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* builds a projection matrix, overwriting out
|
||||
* r, l, t, b are the right, left, top and bottom of the frustum
|
||||
* n and f are the distance of the near and far planes from the camera
|
||||
*/
|
||||
void mat4BuildProjection(mat4 out, GLfloat r, GLfloat l, GLfloat t, GLfloat b, GLfloat n, GLfloat f) {
|
||||
mat4Identity(out);
|
||||
|
||||
out[0] = 2.0f / (r - l);
|
||||
out[5] = 2.0f / (t - b);
|
||||
|
||||
out[8] = 1.0f / n * (r + l) / (r - l);
|
||||
out[9] = 1.0f / n * (t + b) / (t - b);
|
||||
out[10] = -1.0f / n * (f + n) / (f - n);
|
||||
out[11] = -1.0f / n;
|
||||
|
||||
out[14] = - 2.0f * f / (f - n);
|
||||
out[15] = 0.0f;
|
||||
}
|
||||
|
||||
/**
|
||||
* builds a perspective projection matrix, overwriting out
|
||||
* fovy is the field of view in the y direction
|
||||
* aspect is the aspect ratio
|
||||
* n and f are the distance of the near and far planes from the camera
|
||||
*/
|
||||
void mat4BuildPerspective(mat4 out, GLfloat fovy, GLfloat aspect, GLfloat n, GLfloat f) {
|
||||
GLfloat t = n * tan(0.5f * fovy);
|
||||
GLfloat b = -t;
|
||||
|
||||
GLfloat r = aspect * t;
|
||||
GLfloat l = -r;
|
||||
|
||||
mat4BuildProjection(out, r, l, t, b, n, f);
|
||||
}
|
||||
|
||||
/**
|
||||
* linearly interpolates between a and b, storing the result in out
|
||||
*/
|
||||
void mat4Interpolate(mat4 out, mat4 a, mat4 b, GLfloat f) {
|
||||
for (int i = 0; i < 16; i++) {
|
||||
out[i] = (1 - f) * a[i] + f * b[i];
|
||||
}
|
||||
}
|
||||
|
||||
void mat4From3(mat4 out, mat3 in) {
|
||||
mat4Identity(out);
|
||||
memcpy(&out[0], &in[0], sizeof(GLfloat) * 3);
|
||||
memcpy(&out[4], &in[3], sizeof(GLfloat) * 3);
|
||||
memcpy(&out[8], &in[6], sizeof(GLfloat) * 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* https://stackoverflow.com/questions/1148309/inverting-a-4x4-matrix
|
||||
*/
|
||||
void mat4Inverse(mat4 out, mat4 m) {
|
||||
GLfloat inv[16], det;
|
||||
int i;
|
||||
|
||||
inv[0] = m[5] * m[10] * m[15] -
|
||||
m[5] * m[11] * m[14] -
|
||||
m[9] * m[6] * m[15] +
|
||||
m[9] * m[7] * m[14] +
|
||||
m[13] * m[6] * m[11] -
|
||||
m[13] * m[7] * m[10];
|
||||
|
||||
inv[4] = -m[4] * m[10] * m[15] +
|
||||
m[4] * m[11] * m[14] +
|
||||
m[8] * m[6] * m[15] -
|
||||
m[8] * m[7] * m[14] -
|
||||
m[12] * m[6] * m[11] +
|
||||
m[12] * m[7] * m[10];
|
||||
|
||||
inv[8] = m[4] * m[9] * m[15] -
|
||||
m[4] * m[11] * m[13] -
|
||||
m[8] * m[5] * m[15] +
|
||||
m[8] * m[7] * m[13] +
|
||||
m[12] * m[5] * m[11] -
|
||||
m[12] * m[7] * m[9];
|
||||
|
||||
inv[12] = -m[4] * m[9] * m[14] +
|
||||
m[4] * m[10] * m[13] +
|
||||
m[8] * m[5] * m[14] -
|
||||
m[8] * m[6] * m[13] -
|
||||
m[12] * m[5] * m[10] +
|
||||
m[12] * m[6] * m[9];
|
||||
|
||||
inv[1] = -m[1] * m[10] * m[15] +
|
||||
m[1] * m[11] * m[14] +
|
||||
m[9] * m[2] * m[15] -
|
||||
m[9] * m[3] * m[14] -
|
||||
m[13] * m[2] * m[11] +
|
||||
m[13] * m[3] * m[10];
|
||||
|
||||
inv[5] = m[0] * m[10] * m[15] -
|
||||
m[0] * m[11] * m[14] -
|
||||
m[8] * m[2] * m[15] +
|
||||
m[8] * m[3] * m[14] +
|
||||
m[12] * m[2] * m[11] -
|
||||
m[12] * m[3] * m[10];
|
||||
|
||||
inv[9] = -m[0] * m[9] * m[15] +
|
||||
m[0] * m[11] * m[13] +
|
||||
m[8] * m[1] * m[15] -
|
||||
m[8] * m[3] * m[13] -
|
||||
m[12] * m[1] * m[11] +
|
||||
m[12] * m[3] * m[9];
|
||||
|
||||
inv[13] = m[0] * m[9] * m[14] -
|
||||
m[0] * m[10] * m[13] -
|
||||
m[8] * m[1] * m[14] +
|
||||
m[8] * m[2] * m[13] +
|
||||
m[12] * m[1] * m[10] -
|
||||
m[12] * m[2] * m[9];
|
||||
|
||||
inv[2] = m[1] * m[6] * m[15] -
|
||||
m[1] * m[7] * m[14] -
|
||||
m[5] * m[2] * m[15] +
|
||||
m[5] * m[3] * m[14] +
|
||||
m[13] * m[2] * m[7] -
|
||||
m[13] * m[3] * m[6];
|
||||
|
||||
inv[6] = -m[0] * m[6] * m[15] +
|
||||
m[0] * m[7] * m[14] +
|
||||
m[4] * m[2] * m[15] -
|
||||
m[4] * m[3] * m[14] -
|
||||
m[12] * m[2] * m[7] +
|
||||
m[12] * m[3] * m[6];
|
||||
|
||||
inv[10] = m[0] * m[5] * m[15] -
|
||||
m[0] * m[7] * m[13] -
|
||||
m[4] * m[1] * m[15] +
|
||||
m[4] * m[3] * m[13] +
|
||||
m[12] * m[1] * m[7] -
|
||||
m[12] * m[3] * m[5];
|
||||
|
||||
inv[14] = -m[0] * m[5] * m[14] +
|
||||
m[0] * m[6] * m[13] +
|
||||
m[4] * m[1] * m[14] -
|
||||
m[4] * m[2] * m[13] -
|
||||
m[12] * m[1] * m[6] +
|
||||
m[12] * m[2] * m[5];
|
||||
|
||||
inv[3] = -m[1] * m[6] * m[11] +
|
||||
m[1] * m[7] * m[10] +
|
||||
m[5] * m[2] * m[11] -
|
||||
m[5] * m[3] * m[10] -
|
||||
m[9] * m[2] * m[7] +
|
||||
m[9] * m[3] * m[6];
|
||||
|
||||
inv[7] = m[0] * m[6] * m[11] -
|
||||
m[0] * m[7] * m[10] -
|
||||
m[4] * m[2] * m[11] +
|
||||
m[4] * m[3] * m[10] +
|
||||
m[8] * m[2] * m[7] -
|
||||
m[8] * m[3] * m[6];
|
||||
|
||||
inv[11] = -m[0] * m[5] * m[11] +
|
||||
m[0] * m[7] * m[9] +
|
||||
m[4] * m[1] * m[11] -
|
||||
m[4] * m[3] * m[9] -
|
||||
m[8] * m[1] * m[7] +
|
||||
m[8] * m[3] * m[5];
|
||||
|
||||
inv[15] = m[0] * m[5] * m[10] -
|
||||
m[0] * m[6] * m[9] -
|
||||
m[4] * m[1] * m[10] +
|
||||
m[4] * m[2] * m[9] +
|
||||
m[8] * m[1] * m[6] -
|
||||
m[8] * m[2] * m[5];
|
||||
|
||||
det = m[0] * inv[0] + m[1] * inv[4] + m[2] * inv[8] + m[3] * inv[12];
|
||||
|
||||
if (det == 0) {
|
||||
mat4Copy(m, out); // singular matrix, can't invert
|
||||
return;
|
||||
}
|
||||
|
||||
det = 1.0 / det;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
out[i] = inv[i] * det;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* subtracts b from a, storing the result in out
|
||||
*/
|
||||
void vec3Subtract(vec3 out, vec3 a, vec3 b) {
|
||||
out[0] = a[0] - b[0];
|
||||
out[1] = a[1] - b[1];
|
||||
out[2] = a[2] - b[2];
|
||||
}
|
||||
|
||||
/**
|
||||
* calculates the cross product of a and b, storing the result in out
|
||||
*/
|
||||
void vec3CrossProduct(vec3 out, vec3 a, vec3 b) {
|
||||
vec3 result;
|
||||
result[0] = a[1] * b[2] - a[2] * b[1];
|
||||
result[1] = a[2] * b[0] - a[0] * b[2];
|
||||
result[2] = a[0] * b[1] - a[1] * b[0];
|
||||
|
||||
out[0] = result[0];
|
||||
out[1] = result[1];
|
||||
out[2] = result[2];
|
||||
}
|
||||
|
||||
/**
|
||||
* normalizes in storing the result in out
|
||||
*/
|
||||
void vec3Normalise(vec3 out, vec3 in) {
|
||||
GLfloat length = vec3Length(in);
|
||||
out[0] = in[0] / length;
|
||||
out[1] = in[1] / length;
|
||||
out[2] = in[2] / length;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the length of the vector in
|
||||
*/
|
||||
GLfloat vec3Length(vec3 in) {
|
||||
return sqrt(in[0] * in[0] + in[1] * in[1] + in[2] * in[2]);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the dot product of the vectors a and b
|
||||
*/
|
||||
GLfloat vec3DotProduct(vec3 a, vec3 b) {
|
||||
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the values of out to x, y and z
|
||||
*/
|
||||
void vec3Set(vec3 out, GLfloat x, GLfloat y, GLfloat z) {
|
||||
out[0] = x;
|
||||
out[1] = y;
|
||||
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++) {
|
||||
dst[i] = src[i];
|
||||
}
|
||||
}
|
||||
|
||||
void mat3From4(mat3 out, mat4 in) {
|
||||
memcpy(&out[0], &in[0], sizeof(GLfloat) * 3);
|
||||
memcpy(&out[3], &in[4], sizeof(GLfloat) * 3);
|
||||
memcpy(&out[6], &in[8], sizeof(GLfloat) * 3);
|
||||
}
|
||||
|
||||
void mat3Transpose(mat3 out, mat3 in) {
|
||||
mat3 result;
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
result[i * 3 + j] = in[j * 3 + i];
|
||||
}
|
||||
}
|
||||
|
||||
mat3Copy(result, out);
|
||||
}
|
||||
|
||||
void mat3Minor(mat3 out, mat3 in) {
|
||||
mat3 result;
|
||||
|
||||
// TODO: check if this is correct
|
||||
result[0] = in[4] * in[8] - in[5] * in[7];
|
||||
result[1] = in[3] * in[8] - in[5] * in[6];
|
||||
result[2] = in[3] * in[7] - in[4] * in[6];
|
||||
|
||||
result[3] = in[1] * in[8] - in[2] * in[7];
|
||||
result[4] = in[0] * in[8] - in[2] * in[6];
|
||||
result[5] = in[0] * in[7] - in[1] * in[6];
|
||||
|
||||
result[6] = in[1] * in[5] - in[2] * in[4];
|
||||
result[7] = in[0] * in[5] - in[2] * in[3];
|
||||
result[8] = in[0] * in[4] - in[1] * in[3];
|
||||
|
||||
mat3Copy(result, out);
|
||||
}
|
||||
|
||||
void mat3Cofactor(mat3 out, mat3 in) {
|
||||
mat3Minor(out, in);
|
||||
|
||||
out[1] *= -1;
|
||||
out[3] *= -1;
|
||||
out[5] *= -1;
|
||||
out[7] *= -1;
|
||||
}
|
||||
|
||||
void mat3Adjoint(mat3 out, mat3 in) {
|
||||
mat3Cofactor(out, in);
|
||||
mat3Transpose(out, in);
|
||||
}
|
||||
|
||||
void mat3MultiplyScalar(mat3 out, mat3 in, GLfloat x) {
|
||||
for (int i = 0; i < 9; i++) {
|
||||
out[i] = in[i] * x;
|
||||
}
|
||||
}
|
||||
|
||||
GLfloat mat3Determinant(mat3 M) {
|
||||
return
|
||||
+ M[0] * M[4] * M[8]
|
||||
+ M[3] * M[7] * M[2]
|
||||
+ M[6] * M[1] * M[5]
|
||||
|
||||
- M[2] * M[4] * M[6]
|
||||
- M[5] * M[7] * M[0]
|
||||
- M[8] * M[1] * M[3]
|
||||
;
|
||||
}
|
||||
|
||||
void mat3Inverse(mat3 out, mat3 in) {
|
||||
mat3 result;
|
||||
mat3Adjoint(result, in);
|
||||
mat3MultiplyScalar(result, result, 1 / mat3Determinant(in));
|
||||
mat3Copy(result, out);
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
#ifndef MATRIX_MATH_H
|
||||
#define MATRIX_MATH_H
|
||||
|
||||
#include <GL/gl.h>
|
||||
|
||||
/**
|
||||
* !!! ALL matrices are in column major
|
||||
*/
|
||||
|
||||
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);
|
||||
extern void mat4Multiply(mat4 result, mat4 A, mat4 B);
|
||||
extern void mat4Print(mat4 m);
|
||||
extern void mat4Translate(mat4 out, mat4 in, vec3 v);
|
||||
extern void mat4Scale(mat4 out, mat4 in, vec3 v);
|
||||
extern void mat4RotateX(mat4 out, mat4 in, GLfloat a);
|
||||
extern void mat4RotateY(mat4 out, mat4 in, GLfloat a);
|
||||
extern void mat4RotateZ(mat4 out, mat4 in, GLfloat a);
|
||||
extern void mat4BuildLookAt(mat4 out, vec3 eye, vec3 center, vec3 up);
|
||||
extern void mat4BuildProjection(mat4 out, GLfloat r, GLfloat l, GLfloat t, GLfloat b, GLfloat n, GLfloat f);
|
||||
extern void mat4BuildPerspective(mat4 out, GLfloat fovy, GLfloat aspect, GLfloat n, GLfloat f);
|
||||
extern void mat4Interpolate(mat4 out, mat4 a, mat4 b, GLfloat f);
|
||||
extern void mat4From3(mat4 out, mat3 in);
|
||||
extern void mat4Inverse(mat4 m, mat4 out);
|
||||
|
||||
extern void vec3Subtract(vec3 out, vec3 a, vec3 b);
|
||||
extern void vec3CrossProduct(vec3 out, vec3 a, vec3 b);
|
||||
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);
|
||||
extern GLfloat mat3Determinant(mat3 m);
|
||||
extern void mat3MultiplyScalar(mat3 out, mat3 in, GLfloat x);
|
||||
extern void mat3Adjoint(mat3 out, mat3 in);
|
||||
extern void mat3Cofactor(mat3 out, mat3 in);
|
||||
extern void mat3Minor(mat3 out, mat3 in);
|
||||
extern void mat3Transpose(mat3 out, mat3 in);
|
||||
extern void mat3From4(mat3 out, mat4 in);
|
||||
|
||||
#endif
|
25
src/shader.c
25
src/shader.c
|
@ -116,27 +116,4 @@ ProgramLinkResult linkShaderProgram(GLuint vertexShader, GLuint fragmentShader)
|
|||
|
||||
result.success = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
ProgramLinkResult buildShaderProgram(const char* vertexShaderPath, const char* fragmentShaderPath) {
|
||||
ProgramLinkResult result = { .success = false, .program = 0 };
|
||||
|
||||
ShaderCompileResult vertexShader = readAndCompileShaderFromFile(vertexShaderPath, GL_VERTEX_SHADER);
|
||||
if (!vertexShader.success) {
|
||||
FATAL("Failed to compile vertex shader");
|
||||
return result;
|
||||
}
|
||||
|
||||
ShaderCompileResult fragmentShader = readAndCompileShaderFromFile(fragmentShaderPath, GL_FRAGMENT_SHADER);
|
||||
if (!fragmentShader.success) {
|
||||
FATAL("Failed to compile fragment shader");
|
||||
return result;
|
||||
}
|
||||
|
||||
result = linkShaderProgram(vertexShader.shader, fragmentShader.shader);
|
||||
|
||||
glDeleteShader(vertexShader.shader);
|
||||
glDeleteShader(fragmentShader.shader);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -17,6 +17,5 @@ typedef struct {
|
|||
extern const char* readFileToMemory(const char* filepath);
|
||||
extern ShaderCompileResult readAndCompileShaderFromFile(const char* filepath, GLenum shaderType);
|
||||
extern ProgramLinkResult linkShaderProgram(GLuint vertexShader, GLuint fragmentShader);
|
||||
extern ProgramLinkResult buildShaderProgram(const char* vertexShaderPath, const char* fragmentShaderPath);
|
||||
|
||||
#endif // SHADER_H
|
|
@ -1,6 +1,5 @@
|
|||
#version 330 core
|
||||
in vec3 vNormal;
|
||||
|
||||
in vec3 vertexColor;
|
||||
void main() {
|
||||
gl_FragColor = vec4(vNormal * 0.5 + vec3(0.5), 1.0);
|
||||
gl_FragColor = vec4(vertexColor, 1.0);
|
||||
}
|
|
@ -1,12 +1,11 @@
|
|||
#version 330 core
|
||||
layout (location = 0) in vec3 aPosition;
|
||||
layout (location = 1) in vec3 aNormal;
|
||||
uniform mat4 uModelView;
|
||||
uniform mat4 uProjection;
|
||||
layout (location = 0) in vec2 aPosition;
|
||||
uniform vec3 uColor;
|
||||
uniform vec2 uPosition;
|
||||
|
||||
out vec3 vNormal;
|
||||
out vec3 vertexColor;
|
||||
|
||||
void main() {
|
||||
vNormal = aNormal;
|
||||
gl_Position = uProjection * uModelView * vec4(aPosition, 1.0);
|
||||
vertexColor = uColor;
|
||||
gl_Position = vec4(uPosition + aPosition, 0.0, 1.0);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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
|
Loading…
Reference in New Issue