Created
January 29, 2025 17:42
-
-
Save joshbodily/5cfb89169e413260893b0d28482621f0 to your computer and use it in GitHub Desktop.
Parse .OBJ file for OpenGL
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
MyVertex* parseObjFile(const char* file, int* faces, int* lines) { | |
FILE* fp = NULL; | |
errno_t ferr = fopen_s(&fp, file, "r"); | |
fseek(fp, 0, SEEK_END); | |
long size = ftell(fp); | |
fseek(fp, 0, SEEK_SET); | |
char* buffer = (char*)malloc(size + 1); | |
fread(buffer, 1, size, fp); | |
buffer[size] = '\0'; | |
int numVertices = 0; | |
int numFaces = 0; | |
int numLines = 0; | |
char* start = buffer; | |
for (int i = 0; i < size;) { | |
// Search for the end | |
int lineLength = 0; | |
while (start[lineLength++] != '\n'); | |
float vx, vy, vz; | |
int f1, f2, f3, t1, t2, t3; | |
if (sscanf_s(start, "v %f %f %f", &vx, &vy, &vz) == 3) { | |
numVertices++; | |
} else if (sscanf_s(start, "f %d/%d %d/%d %d/%d", &f1, &t1, &f2, &t2, &f3, &t3) == 6) { | |
numFaces++; | |
} | |
else if (sscanf_s(start, "l %d %d", &f1, &f2) == 2) { | |
numLines++; | |
} | |
assert(lineLength >= 0); | |
start += lineLength; | |
i += lineLength; | |
} | |
// Temporary for holding vertex definitions | |
MyVertex* verticesList = (MyVertex*)malloc(sizeof(MyVertex) * numVertices); | |
// "Actual" vertices | |
int numActualVertices = numFaces * 3 + numLines * 2; | |
MyVertex* vertices = (MyVertex*)malloc(sizeof(MyVertex) * numActualVertices); | |
start = buffer; | |
int vertex = 0; | |
for (int i = 0; i < size;) { | |
// Search for the end | |
int lineLength = 0; | |
while (start[lineLength++] != '\n'); | |
float vx, vy, vz; | |
int f1, f2, f3, t1, t2, t3; | |
if (sscanf_s(start, "v %f %f %f", &vx, &vy, &vz) == 3) { | |
verticesList[vertex].x = vx; | |
verticesList[vertex].y = vy; | |
verticesList[vertex++].z = vz; | |
} | |
start += lineLength; | |
i += lineLength; | |
} | |
int currentMaterial = 0; | |
start = buffer; | |
vertex = 0; | |
for (int i = 0; i < size;) { | |
// Search for the end | |
int lineLength = 0; | |
while (start[lineLength++] != '\n'); | |
float vx, vy, vz; | |
int f1, f2, f3, t1, t2, t3; | |
if (sscanf_s(start, "f %d/%d %d/%d %d/%d", &f1, &t1, &f2, &t2, &f3, &t3) == 6) { | |
vertices[vertex] = verticesList[f1 - 1]; | |
setMaterial(&vertices[vertex++], currentMaterial, t1 - 1); | |
vertices[vertex] = verticesList[f2 - 1]; | |
setMaterial(&vertices[vertex++], currentMaterial, t2 - 1); | |
vertices[vertex] = verticesList[f3 - 1]; | |
setMaterial(&vertices[vertex++], currentMaterial, t3 - 1); | |
assert(vertex <= numActualVertices); | |
} | |
else if (sscanf_s(start, "l %d %d", &f1, &f2) == 2) { | |
vertices[vertex] = verticesList[f1 - 1]; | |
setMaterial(&vertices[vertex++], currentMaterial, 0); | |
vertices[vertex] = verticesList[f2 - 1]; | |
setMaterial(&vertices[vertex++], currentMaterial, 0); | |
assert(vertex <= numActualVertices); | |
} | |
else if (sscanf_s(start, "usemtl mtl_%X", ¤tMaterial) == 1) { | |
// TODO: Make sure currentMaterial doesn't change if no match | |
} | |
start += lineLength; | |
i += lineLength; | |
} | |
free(verticesList); | |
free(buffer); | |
*faces = numFaces; | |
*lines = numLines; | |
return vertices; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment