load obj files
This commit is contained in:
parent
6ccfb7e818
commit
dd201108e6
|
@ -7,7 +7,8 @@ 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',
|
||||||
|
|
|
@ -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
107
src/main.c
107
src/main.c
|
@ -11,6 +11,7 @@
|
||||||
#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
|
||||||
|
@ -18,8 +19,7 @@
|
||||||
GLuint program;
|
GLuint program;
|
||||||
|
|
||||||
GLuint vertexArrayObject;
|
GLuint vertexArrayObject;
|
||||||
|
GLuint numVertices;
|
||||||
GLuint indexBuffer;
|
|
||||||
|
|
||||||
GLuint initialWindowWidth = 800;
|
GLuint initialWindowWidth = 800;
|
||||||
GLuint initialWindowHeight = 600;
|
GLuint initialWindowHeight = 600;
|
||||||
|
@ -122,47 +122,15 @@ void init(void) {
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
GLfloat vertices[] = {
|
DEBUG("Loading OBJ File");
|
||||||
// X // Y
|
ParsedObjFile f = readObjFile("obj/teapot.obj");
|
||||||
1.0f, 1.0f, 1.0f,
|
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,
|
|
||||||
};
|
|
||||||
|
|
||||||
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
|
|
||||||
};
|
|
||||||
|
|
||||||
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, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
glBufferData(GL_ARRAY_BUFFER, f.length * sizeof(face), f.faces, GL_STATIC_DRAW);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
DEBUG("Creating vertex array object");
|
DEBUG("Creating vertex array object");
|
||||||
|
@ -177,17 +145,21 @@ 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
|
||||||
3 * sizeof(GLfloat), // stride - distance between vertices
|
sizeof(vertex), // stride - distance between vertices
|
||||||
0 // start offset
|
0 // start offset
|
||||||
);
|
);
|
||||||
glEnableVertexAttribArray(0);
|
glEnableVertexAttribArray(0);
|
||||||
|
|
||||||
DEBUG("Creating index buffer");
|
glVertexAttribPointer(
|
||||||
glGenBuffers(1, &indexBuffer);
|
1,
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
|
3,
|
||||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
|
GL_FLOAT,
|
||||||
|
GL_FALSE,
|
||||||
|
sizeof(vertex),
|
||||||
|
(void*)offsetof(vertex, normal)
|
||||||
|
);
|
||||||
|
glEnableVertexAttribArray(1);
|
||||||
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
|
|
||||||
|
@ -208,30 +180,11 @@ void init(void) {
|
||||||
|
|
||||||
GLfloat currentHue = 0.0f;
|
GLfloat currentHue = 0.0f;
|
||||||
|
|
||||||
void drawCube(vec3 position, mat4 initialModelMatrix, mat4 viewMatrix) {
|
|
||||||
mat4 modelMatrix;
|
|
||||||
mat4 modelViewMatrix;
|
|
||||||
|
|
||||||
mat4Translate(modelMatrix, initialModelMatrix, position);
|
|
||||||
|
|
||||||
// combine model and view matrix to model-view matrix
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
void draw(void) {
|
void draw(void) {
|
||||||
updateStatusDisplay();
|
updateStatusDisplay();
|
||||||
|
|
||||||
// counter for animation
|
// counter for animation
|
||||||
currentHue += 0.0005f;
|
currentHue += 0.005f;
|
||||||
if (currentHue > 1.0) currentHue = 0.0f;
|
if (currentHue > 1.0) currentHue = 0.0f;
|
||||||
|
|
||||||
// clear colour and depth buffer
|
// clear colour and depth buffer
|
||||||
|
@ -244,7 +197,7 @@ void draw(void) {
|
||||||
mat4 viewMatrix;
|
mat4 viewMatrix;
|
||||||
|
|
||||||
// mat4Identity(viewMatrix);
|
// mat4Identity(viewMatrix);
|
||||||
vec3 cameraPos = {0.0f, 1.0f, 1.3f};
|
vec3 cameraPos = {cos(currentHue * M_PI * 2), 1.0f, sin(currentHue * M_PI * 2)};
|
||||||
vec3 cameraLookAt = {0.0f, 0.2f, 0.0f};
|
vec3 cameraLookAt = {0.0f, 0.2f, 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);
|
||||||
|
@ -255,26 +208,18 @@ void draw(void) {
|
||||||
|
|
||||||
// build model Matrix
|
// build model Matrix
|
||||||
mat4 modelMatrix;
|
mat4 modelMatrix;
|
||||||
vec3 scale;
|
mat4 modelViewMatrix;
|
||||||
vec3 position;
|
|
||||||
|
|
||||||
float scales[] = {0.5f, 0.4f, 0.3f, 0.2f, 0.1f, 0.09f, 0.08f, 0.07f, 0.06f, 0.05f};
|
vec3 scale = {0.2f, 0.2f, 0.2f};
|
||||||
for (int i = 0; i < 10; i++) {
|
|
||||||
mat4Identity(modelMatrix);
|
|
||||||
|
|
||||||
vec3Set(scale, scales[i], 0.05f, scales[i]);
|
mat4Identity(modelMatrix);
|
||||||
mat4Scale(modelMatrix, modelMatrix, scale);
|
mat4Scale(modelMatrix, modelMatrix, scale);
|
||||||
|
mat4Multiply(modelViewMatrix, viewMatrix, modelMatrix);
|
||||||
mat4RotateY(modelMatrix, modelMatrix, currentHue * 2 * M_PI + (i / 5.0f * M_PI));
|
|
||||||
|
|
||||||
vec3Set(position, 0.0f, i * 0.05f, 0.0f);
|
|
||||||
mat4Translate(modelMatrix, modelMatrix, position);
|
|
||||||
|
|
||||||
drawCube(position, modelMatrix, viewMatrix);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
glUniformMatrix4fv(glGetUniformLocation(program, "uModelView"), 1, GL_FALSE, modelViewMatrix);
|
||||||
|
|
||||||
|
glBindVertexArray(vertexArrayObject);
|
||||||
|
glDrawArrays(GL_TRIANGLES, 0, numVertices);
|
||||||
}
|
}
|
||||||
|
|
||||||
void framebuffer_size_callback(GLFWwindow* window, int width, int height) {
|
void framebuffer_size_callback(GLFWwindow* window, int width, int height) {
|
||||||
|
|
|
@ -422,6 +422,18 @@ 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++) {
|
||||||
|
|
|
@ -9,10 +9,12 @@
|
||||||
|
|
||||||
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);
|
||||||
|
@ -36,6 +38,9 @@ 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);
|
||||||
|
|
|
@ -1,15 +1,6 @@
|
||||||
#version 330 core
|
#version 330 core
|
||||||
vec3 colors[6] = vec3[6](
|
in vec3 vNormal;
|
||||||
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)
|
|
||||||
);
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
// hacky solution to give each side a different colour
|
gl_FragColor = vec4(vNormal * 0.5 + vec3(0.5), 1.0);
|
||||||
int side = gl_PrimitiveID / 2;
|
|
||||||
gl_FragColor = vec4(colors[side], 1.0);
|
|
||||||
}
|
}
|
|
@ -1,8 +1,12 @@
|
||||||
#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);
|
||||||
}
|
}
|
|
@ -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