From 8d888af644a4291df660d1fb016b50363f84bae7 Mon Sep 17 00:00:00 2001 From: Kyle K Date: Mon, 4 Jul 2011 22:48:47 -0500 Subject: sync up --- obj.c | 232 +++++++++++++++++++++++++++++++++++++++++++----------------- obj.h | 10 +-- objloader.c | 7 +- 3 files changed, 177 insertions(+), 72 deletions(-) diff --git a/obj.c b/obj.c index 576f89f..5ca1d4e 100644 --- a/obj.c +++ b/obj.c @@ -18,7 +18,7 @@ #include #include "obj.h" -char obj_last_fname[101]; +char ObjLastFname[101]; ObjModel* ObjLoadModel(char *memory, size_t size) { @@ -26,7 +26,6 @@ ObjModel* ObjLoadModel(char *memory, size_t size) if (!size) return NULL; - char *p = NULL, *e = NULL; ObjModel *ret = (ObjModel *) malloc(sizeof(ObjModel)); if (!ret) { @@ -37,16 +36,26 @@ ObjModel* ObjLoadModel(char *memory, size_t size) /* initialize to zero */ memset(ret, 0, sizeof(ObjModel)); + + char *p = NULL, *e = NULL; + unsigned int line = 1; p = memory; e = memory + size; /* count the number of normals, texcoords, vertices, and faces, line by line */ while (p != e) { - if (memcmp(p, "vn", 2) == 0) ret->nNormal++; - else if (memcmp(p, "vt", 2) == 0) ret->nTexCoord++; - else if (memcmp(p, "v", 1) == 0) ret->nVertex++; - else if (memcmp(p, "f", 1) == 0) ret->nFace++; + /* skip commented lines */ + if (memcmp(p, "#", 1) == 0) + ; + else if (memcmp(p, "vn", 2) == 0) + ret->nNormal++; + else if (memcmp(p, "vt", 2) == 0) + ret->nTexCoord++; + else if (memcmp(p, "v", 1) == 0) + ret->nVertex++; + else if (memcmp(p, "f", 1) == 0) + ret->nFace++; /* seek to new line */ while (*p++ != (char) 0x0a) @@ -54,10 +63,10 @@ ObjModel* ObjLoadModel(char *memory, size_t size) } /* allocate memory for arrays */ - ret->VertexArray = (ObjVertex *) malloc(sizeof(ObjVertex) * ret->nVertex); - ret->NormalArray = (ObjNormal *) malloc(sizeof(ObjNormal) * ret->nNormal); + ret->VertexArray = (ObjVertex *) malloc(sizeof(ObjVertex) * ret->nVertex); + ret->NormalArray = (ObjNormal *) malloc(sizeof(ObjNormal) * ret->nNormal); ret->TexCoordArray = (ObjTexCoord *) malloc(sizeof(ObjTexCoord) * ret->nTexCoord); - ret->FaceArray = (ObjFace *) malloc(sizeof(ObjFace) * ret->nFace); + ret->FaceArray = (ObjFace *) malloc(sizeof(ObjFace) * ret->nFace); ret->mtllib = (char *) malloc(sizeof(char) * 31); ret->objectName = (char *) malloc(sizeof(char) * 31); ret->usemtl = (char *) malloc(sizeof(char) * 31); @@ -81,19 +90,19 @@ ObjModel* ObjLoadModel(char *memory, size_t size) while (p != e) { + /* skip commented lines */ + if (memcmp(p, "#", 1) == 0) + ; /* check for mtl file */ - if (memcmp(p, "mtllib", 6) == 0) + else if (memcmp(p, "mtllib", 6) == 0) sscanf(p, "mtllib %s", ret->mtllib); /* valgrind reports this as false positive */ - /* check if mtl file will be used */ - if (memcmp(p, "usemtl", 6) == 0) + else if (memcmp(p, "usemtl", 6) == 0) sscanf(p, "usemtl %s", ret->usemtl); - - if (memcmp(p, "g", 1) == 0) + else if (memcmp(p, "g", 1) == 0) sscanf(p, "g %s", ret->objectName); - /* parse a normal */ - if (memcmp(p, "vn", 2) == 0) + else if (memcmp(p, "vn", 2) == 0) { nread = sscanf(p, "vn %f %f %f", &ret->NormalArray[nN].x, &ret->NormalArray[nN].y, @@ -106,12 +115,13 @@ ObjModel* ObjLoadModel(char *memory, size_t size) /* parse a texture coordinates */ else if (memcmp(p, "vt", 2) == 0) { - nread = sscanf(p, "vt %f %f", &ret->TexCoordArray[nT].u, - &ret->TexCoordArray[nT].v); + nread = sscanf(p, "vt %f %f", &ret->TexCoordArray[nT].s, + &ret->TexCoordArray[nT].t); if (nread != 2) printf("vt: read only %d instead of 2\n", nread); - ret->TexCoordArray[nT].w = 0.0f; + ret->TexCoordArray[nT].r = 0.0f; + ret->TexCoordArray[nT].q = 1.0f; nT++; } /* parse a vertex */ @@ -123,7 +133,7 @@ ObjModel* ObjLoadModel(char *memory, size_t size) if (nread != 3) printf("v: read only %d instead of 3\n", nread); - ret->VertexArray[nV].w = 0.0f; + ret->VertexArray[nV].w = 1.0f; nV++; } /* quad */ @@ -143,6 +153,20 @@ ObjModel* ObjLoadModel(char *memory, size_t size) &ret->FaceArray[nF].TexCoord[3], &ret->FaceArray[nF].Normal[3]); + /* obj file counts from 1, I want to count from 0 */ + ret->FaceArray[nF].Vertex[0]--, + ret->FaceArray[nF].TexCoord[0]--, + ret->FaceArray[nF].Normal[0]--, + ret->FaceArray[nF].Vertex[1]--, + ret->FaceArray[nF].TexCoord[1]--, + ret->FaceArray[nF].Normal[1]--, + ret->FaceArray[nF].Vertex[2]--, + ret->FaceArray[nF].TexCoord[2]--, + ret->FaceArray[nF].Normal[2]--, + ret->FaceArray[nF].Vertex[3]--, + ret->FaceArray[nF].TexCoord[3]--, + ret->FaceArray[nF].Normal[3]--; + if (nread != 12) printf("f: read only %d instead of 12\n", nread); @@ -152,13 +176,15 @@ ObjModel* ObjLoadModel(char *memory, size_t size) /* seek to a newline */ while (*p++ != (char) 0x0a) ; + + line++; } /* sanity check */ if ((ret->nVertex != nV) || (ret->nNormal != nN) || (ret->nTexCoord != nT) || (ret->nFace != nF)) { - fprintf(stdout, "ObjLoadModel: warning, the number of scanned items does not equal to number of read\n"); + fprintf(stdout, "ObjLoadModel(): warning, the number of scanned items does not equal to number of read\n"); if (ret->nVertex != nV) fprintf(stdout, "vertices: scanned %d, read %d\n", ret->nVertex, nV); if (ret->nNormal != nN) @@ -250,7 +276,7 @@ ObjModel* ObjLoadModel(char *memory, size_t size) if (memcmp(st, "map_Kd", 6) == 0) sscanf(st, "map_Kd %s", mtl->map_Kd); - /* go to next line */ + /* go to the next line */ while (*st++ != (char) 0x0a) ; } @@ -275,7 +301,7 @@ ObjModel* ObjLoadModel(char *memory, size_t size) size_t ObjLoadFile(char *szFileName, char **memory) { - strcpy(obj_last_fname, szFileName); /* seems useful for tracking */ + strcpy(ObjLastFname, szFileName); /* seems useful for tracking */ size_t bytes = 0; FILE *file = fopen(szFileName, "rt"); @@ -323,7 +349,7 @@ void ObjList(ObjModel *model) printf("%d texture coordinates\n", model->nTexCoord); for (i = 0; i < model->nTexCoord; i++) - printf("v %f %f\n", model->TexCoordArray[i].u, model->TexCoordArray[i].v); + printf("v %f %f\n", model->TexCoordArray[i].s, model->TexCoordArray[i].t); printf("%d faces\n", model->nFace); for (i = 0; i < model->nFace; i++) @@ -346,7 +372,7 @@ void ObjList(ObjModel *model) char *ObjGetPath(const char *fname) { - if (fname == NULL || obj_last_fname == NULL) + if (fname == NULL || ObjLastFname == NULL) return NULL; char *path = (char *) malloc(sizeof(char) * 101); @@ -357,61 +383,137 @@ char *ObjGetPath(const char *fname) exit(-1); } - char *delimeter = strrchr(obj_last_fname, '/'); - unsigned int offset = delimeter - obj_last_fname; + char *delimeter = strrchr(ObjLastFname, '/'); + unsigned int offset = delimeter - ObjLastFname; #if 0 fprintf(stdout, "ObjGetPath(): fname = \"%s\", delim = \"%s\", offset = %u" - ", obj_last_fname = \"%s\"\n", fname, delimeter, offset, obj_last_fname); + ", ObjLastFname = \"%s\"\n", fname, delimeter, offset, ObjLastFname); #endif - strncpy(path, obj_last_fname, offset + 1); + strncpy(path, ObjLastFname, offset + 1); strcpy(path + offset + 1, fname); /* strcat(path, fname); */ return path; } -void ObjPutFaceGLCmd(const ObjModel *model, const unsigned i) +void ObjSubmitIndexedVertexArrayQuad(const ObjModel *model) +{ + int i; + + glVertexPointer(4, GL_FLOAT, 0, model->VertexArray); + glNormalPointer(GL_FLOAT, 0, model->NormalArray); + + /* XXX: why aren't textcoords working :/ ? */ + glTexCoordPointer(4, GL_FLOAT, 0, model->TexCoordArray); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + /* vertices */ + for (i = 0; i < model->nFace; i++) + glDrawElements(GL_QUADS, 4, GL_UNSIGNED_INT, model->FaceArray[i].Vertex); + + /* normals */ + for (i = 0; i < model->nFace; i++) + glDrawElements(GL_QUADS, 4, GL_UNSIGNED_INT, model->FaceArray[i].Normal); + + /* texture coordinates */ + for (i = 0; i < model->nFace; i++) + glDrawElements(GL_QUADS, 4, GL_UNSIGNED_INT, model->FaceArray[i].TexCoord); + +#if 0 + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); +#endif +} + +/* OpenGL immediate command generator for quads */ +void ObjSubmitGLCommandsQuad(const ObjModel *model) +{ + if (!model) + return; + + int i; + for (i = 0; i < model->nFace; i++) + { + glNormal3f(model->NormalArray[model->FaceArray[i].Normal[0]].x, + model->NormalArray[model->FaceArray[i].Normal[0]].y, + model->NormalArray[model->FaceArray[i].Normal[0]].z ); + glTexCoord2f(model->TexCoordArray[model->FaceArray[i].TexCoord[0]].s, + model->TexCoordArray[model->FaceArray[i].TexCoord[0]].t); + glVertex3f(model->VertexArray[model->FaceArray[i].Vertex[0]].x, + model->VertexArray[model->FaceArray[i].Vertex[0]].y, + model->VertexArray[model->FaceArray[i].Vertex[0]].z ); + + glNormal3f(model->NormalArray[model->FaceArray[i].Normal[1]].x, + model->NormalArray[model->FaceArray[i].Normal[1]].y, + model->NormalArray[model->FaceArray[i].Normal[1]].z ); + glTexCoord2f(model->TexCoordArray[model->FaceArray[i].TexCoord[1]].s, + model->TexCoordArray[model->FaceArray[i].TexCoord[1]].t); + glVertex3f(model->VertexArray[model->FaceArray[i].Vertex[1]].x, + model->VertexArray[model->FaceArray[i].Vertex[1]].y, + model->VertexArray[model->FaceArray[i].Vertex[1]].z ); + + glNormal3f(model->NormalArray[model->FaceArray[i].Normal[2]].x, + model->NormalArray[model->FaceArray[i].Normal[2]].y, + model->NormalArray[model->FaceArray[i].Normal[2]].z ); + glTexCoord2f(model->TexCoordArray[model->FaceArray[i].TexCoord[2]].s, + model->TexCoordArray[model->FaceArray[i].TexCoord[2]].t); + glVertex3f(model->VertexArray[model->FaceArray[i].Vertex[2]].x, + model->VertexArray[model->FaceArray[i].Vertex[2]].y, + model->VertexArray[model->FaceArray[i].Vertex[2]].z ); + + glNormal3f(model->NormalArray[model->FaceArray[i].Normal[3]].x, + model->NormalArray[model->FaceArray[i].Normal[3]].y, + model->NormalArray[model->FaceArray[i].Normal[3]].z ); + glTexCoord2f(model->TexCoordArray[model->FaceArray[i].TexCoord[3]].s, + model->TexCoordArray[model->FaceArray[i].TexCoord[3]].t); + glVertex3f(model->VertexArray[model->FaceArray[i].Vertex[3]].x, + model->VertexArray[model->FaceArray[i].Vertex[3]].y, + model->VertexArray[model->FaceArray[i].Vertex[3]].z ); + } +} + +/* OpenGL immediate command generator for triangles */ +void ObjSubmitGLCommandsTriangle(const ObjModel *model) { if (!model) return; - glNormal3f(model->NormalArray[model->FaceArray[i].Normal[0] - 1].x, - model->NormalArray[model->FaceArray[i].Normal[0] - 1].y, - model->NormalArray[model->FaceArray[i].Normal[0] - 1].z ); - glTexCoord2f(model->TexCoordArray[model->FaceArray[i].TexCoord[0] - 1].u, - model->TexCoordArray[model->FaceArray[i].TexCoord[0] - 1].v); - glVertex3f(model->VertexArray[model->FaceArray[i].Vertex[0] - 1].x, - model->VertexArray[model->FaceArray[i].Vertex[0] - 1].y, - model->VertexArray[model->FaceArray[i].Vertex[0] - 1].z ); - - glNormal3f(model->NormalArray[model->FaceArray[i].Normal[1] - 1].x, - model->NormalArray[model->FaceArray[i].Normal[1] - 1].y, - model->NormalArray[model->FaceArray[i].Normal[1] - 1].z ); - glTexCoord2f(model->TexCoordArray[model->FaceArray[i].TexCoord[1] - 1].u, - model->TexCoordArray[model->FaceArray[i].TexCoord[1] - 1].v); - glVertex3f(model->VertexArray[model->FaceArray[i].Vertex[1] - 1].x, - model->VertexArray[model->FaceArray[i].Vertex[1] - 1].y, - model->VertexArray[model->FaceArray[i].Vertex[1] - 1].z ); - - glNormal3f(model->NormalArray[model->FaceArray[i].Normal[2] - 1].x, - model->NormalArray[model->FaceArray[i].Normal[2] - 1].y, - model->NormalArray[model->FaceArray[i].Normal[2] - 1].z ); - glTexCoord2f(model->TexCoordArray[model->FaceArray[i].TexCoord[2] - 1].u, - model->TexCoordArray[model->FaceArray[i].TexCoord[2] - 1].v); - glVertex3f(model->VertexArray[model->FaceArray[i].Vertex[2] - 1].x, - model->VertexArray[model->FaceArray[i].Vertex[2] - 1].y, - model->VertexArray[model->FaceArray[i].Vertex[2] - 1].z ); - - glNormal3f(model->NormalArray[model->FaceArray[i].Normal[3] - 1].x, - model->NormalArray[model->FaceArray[i].Normal[3] - 1].y, - model->NormalArray[model->FaceArray[i].Normal[3] - 1].z ); - glTexCoord2f(model->TexCoordArray[model->FaceArray[i].TexCoord[3] - 1].u, - model->TexCoordArray[model->FaceArray[i].TexCoord[3] - 1].v); - glVertex3f(model->VertexArray[model->FaceArray[i].Vertex[3] - 1].x, - model->VertexArray[model->FaceArray[i].Vertex[3] - 1].y, - model->VertexArray[model->FaceArray[i].Vertex[3] - 1].z ); + int i; + for (i = 0; i < model->nFace; i++) + { + glNormal3f(model->NormalArray[model->FaceArray[i].Normal[0]].x, + model->NormalArray[model->FaceArray[i].Normal[0]].y, + model->NormalArray[model->FaceArray[i].Normal[0]].z ); + glTexCoord2f(model->TexCoordArray[model->FaceArray[i].TexCoord[0]].s, + model->TexCoordArray[model->FaceArray[i].TexCoord[0]].t); + glVertex3f(model->VertexArray[model->FaceArray[i].Vertex[0]].x, + model->VertexArray[model->FaceArray[i].Vertex[0]].y, + model->VertexArray[model->FaceArray[i].Vertex[0]].z ); + + glNormal3f(model->NormalArray[model->FaceArray[i].Normal[1]].x, + model->NormalArray[model->FaceArray[i].Normal[1]].y, + model->NormalArray[model->FaceArray[i].Normal[1]].z ); + glTexCoord2f(model->TexCoordArray[model->FaceArray[i].TexCoord[1]].s, + model->TexCoordArray[model->FaceArray[i].TexCoord[1]].t); + glVertex3f(model->VertexArray[model->FaceArray[i].Vertex[1]].x, + model->VertexArray[model->FaceArray[i].Vertex[1]].y, + model->VertexArray[model->FaceArray[i].Vertex[1]].z ); + + glNormal3f(model->NormalArray[model->FaceArray[i].Normal[2]].x, + model->NormalArray[model->FaceArray[i].Normal[2]].y, + model->NormalArray[model->FaceArray[i].Normal[2]].z ); + glTexCoord2f(model->TexCoordArray[model->FaceArray[i].TexCoord[2]].s, + model->TexCoordArray[model->FaceArray[i].TexCoord[2]].t); + glVertex3f(model->VertexArray[model->FaceArray[i].Vertex[2]].x, + model->VertexArray[model->FaceArray[i].Vertex[2]].y, + model->VertexArray[model->FaceArray[i].Vertex[2]].z ); + } } void ObjFree(ObjModel *model) diff --git a/obj.h b/obj.h index d0ba3b5..6451b18 100644 --- a/obj.h +++ b/obj.h @@ -1,9 +1,8 @@ #ifndef _OBJLOADER_H_ #define _OBJLOADER_H_ -extern char obj_last_fname[101]; +extern char ObjLastFname[101]; -#pragma pack(1) typedef struct { float x, y, z, w; @@ -16,7 +15,7 @@ typedef struct typedef struct { - float u, v, w; + float s, t, r, q; } ObjTexCoord; typedef struct @@ -68,7 +67,10 @@ void ObjList(ObjModel *); * mtl or texture that resides in the same folder */ char *ObjGetPath(const char *); -void ObjPutFaceGLCmd(const ObjModel *, const unsigned); +void ObjSubmitIndexedVertexArrayQuad(const ObjModel *); + +void ObjSubmitGLCommandsQuad(const ObjModel *); +void ObjSubmitGLCommandsTriangle(const ObjModel *); void ObjFree(ObjModel *); static inline ObjNormal *ObjGetNormal(const ObjModel *model, const unsigned i, diff --git a/objloader.c b/objloader.c index 699efdd..162e5b9 100644 --- a/objloader.c +++ b/objloader.c @@ -108,6 +108,7 @@ static void setup_opengl(ObjModel *model) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_BORDER); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glEnable(GL_TEXTURE_2D); @@ -166,11 +167,11 @@ static void render(ObjModel *model) glTranslatef(5.0f, 0.0f, -150.0f); glBegin(GL_QUADS); - int i; - for (i = 0; i < model->nFace; i++) - ObjPutFaceGLCmd(model, i); + ObjSubmitGLCommandsQuad(model); glEnd(); + /* ObjSubmitIndexedVertexArrayQuad(model); */ + glPopMatrix(); /* buffer swap */ -- cgit v1.2.3