From 026bf263d5106449e2e0ed04f55bb152003d80b1 Mon Sep 17 00:00:00 2001 From: Kyle K Date: Sat, 16 Oct 2010 01:52:02 -0500 Subject: Inital mtl --- obj.c | 126 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- obj.h | 45 +++++++++++++++------- objloader.c | 19 +++------ 3 files changed, 160 insertions(+), 30 deletions(-) diff --git a/obj.c b/obj.c index c6d9966..7f42e35 100644 --- a/obj.c +++ b/obj.c @@ -1,3 +1,14 @@ +/* obj.c + * + * OBJ Loader + * inital code: http://www.gamedev.net/community/forums/topic.asp?topic_id=312335 + * + * notes: the mtl file should be implemented using arrays + * more that one mtl needs to be supported some day + * only works for *quads* now + * + */ + #include #include #include @@ -28,6 +39,12 @@ ObjModel* ObjLoadModel(char *memory, size_t size) 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->mtllib = (char *) malloc(sizeof(char) * 21); + ret->objectName = (char *) malloc(sizeof(char) * 21); + ret->usemtl = (char *) malloc(sizeof(char) * 21); + memset(ret->mtllib, 0, 21); + memset(ret->objectName, 0, 21); + memset(ret->usemtl, 0, 21); p = memory; @@ -36,6 +53,17 @@ ObjModel* ObjLoadModel(char *memory, size_t size) while (p != e) { + /* check for mtl file */ + if (memcmp(p, "mtllib", 6) == 0) + sscanf(p, "mtllib %s", ret->mtllib); + + /* check if mtl file will be used*/ + if (memcmp(p, "usemtl", 6) == 0) + sscanf(p, "usemtl %s", ret->usemtl); + + if (memcmp(p, "g", 1) == 0) + sscanf(p, "g %s", ret->objectName); + if (memcmp(p, "vn", 2) == 0) { nread = sscanf(p, "vn %f %f %f", &ret->NormalArray[nN].x, @@ -50,7 +78,7 @@ ObjModel* ObjLoadModel(char *memory, size_t size) nread = sscanf(p, "vt %f %f", &ret->TexCoordArray[nT].u, &ret->TexCoordArray[nT].v); if (nread != 2) - printf("vt: read only %d instead of 2\n", nread); + printf("vt: read only %d instead of 2\n", nread); nT++; } else if (memcmp(p, "v", 1) == 0) /* or *p == 'v' */ @@ -79,7 +107,7 @@ ObjModel* ObjLoadModel(char *memory, size_t size) &ret->FaceArray[nF].TexCoord[3], &ret->FaceArray[nF].Normal[3]); if (nread != 12) - printf("f: read only %d instead of 12\n", nread); + printf("f: read only %d instead of 12\n", nread); nF++; } /* seek to a newline */ @@ -99,8 +127,89 @@ ObjModel* ObjLoadModel(char *memory, size_t size) fprintf(stdout, "texcoords: scanned %d, read %d\n", ret->nTexCoord, nT); if (ret->nFace != nF) fprintf(stdout, "faces: scanned %d, read %d\n", ret->nFace, nF); - } + } + /* load the mtl file */ + if (ret->mtllib != NULL && ret->usemtl) + { + /* append directory to filename */ + char *fname = (char *) malloc(sizeof(char) * 21); + sprintf(fname, "./cube/%s", ret->mtllib); + + char *mtl_mem = NULL; + size_t mtl_bytes = ObjLoadFile(fname, &mtl_mem); + + if (mtl_bytes) + { + ObjMtl *mtl = (ObjMtl *) calloc(1, sizeof(ObjMtl)); + memset(mtl, 0, sizeof(ObjMtl)); + + /* allocate space for members */ + mtl->map_Ka = (char *) malloc(sizeof(char) * 21); + mtl->map_Kd = (char *) malloc(sizeof(char) * 21); + /* set, what about rest? */ + mtl->Ns = 0.0f; + mtl->Ni = 0.0f; + mtl->d = 0.0f; + mtl->Tr = 0.0f; + mtl->illum = 0; + + char *st = mtl_mem; + char *ed = st + mtl_bytes; + + while (st != ed) + { + /* skip spaces */ + while (*st++ == (char) 0x20); + + if (memcmp(st, "Ns", 2) == 0) + sscanf(st, "Ns %f", &mtl->Ns); + + if (memcmp(st, "Ni", 2) == 0) + sscanf(st, "Ni %f", &mtl->Ni); + + if (memcmp(st, "d", 1) == 0) + sscanf(st, "d %f", &mtl->d); + + if (memcmp(st, "Tr", 2) == 0) + sscanf(st, "Tr %f", &mtl->Tr); + + if (memcmp(st, "Tf", 2) == 0) + sscanf(st, "Tf %f %f %f", &mtl->Tf.x, &mtl->Tf.y, &mtl->Tf.z); + + if (memcmp(st, "illum", 5) == 0) + sscanf(st, "illum %d", &mtl->illum); + + if (memcmp(st, "Ka", 2) == 0) + sscanf(st, "Ka %f %f %f", &mtl->Ka.x, &mtl->Ka.y, &mtl->Ka.z); + + if (memcmp(st, "Kd", 2) == 0) + sscanf(st, "Kd %f %f %f", &mtl->Kd.x, &mtl->Kd.y, &mtl->Kd.z); + + if (memcmp(st, "Ks", 2) == 0) + sscanf(st, "Ks %f %f %f", &mtl->Ks.x, &mtl->Ks.y, &mtl->Ks.z); + + if (memcmp(st, "Ke", 2) == 0) + sscanf(st, "Ke %f %f %f", &mtl->Ke.x, &mtl->Ke.y, &mtl->Ke.z); + + if (memcmp(st, "map_Ka", 6) == 0) + sscanf(st, "map_Ka %s", mtl->map_Ka); + + if (memcmp(st, "map_Kd", 6) == 0) + sscanf(st, "map_Kd %s", mtl->map_Kd); + + /* got to next line */ + while (*st++ != (char) 0x0a); + } + /* set the mtl */ + ret->mtl = mtl; + } + else + ret->mtl = NULL; + + free(fname); + } + return ret; } @@ -123,6 +232,7 @@ size_t ObjLoadFile(char *szFileName, char **memory) return bytes; } +/* trivial, meh */ void ObjList(ObjModel *model) { int i; @@ -140,7 +250,7 @@ void ObjList(ObjModel *model) for (i = 0; i < model->nTexCoord; i++) printf("v %f %f\n", model->TexCoordArray[i].u, model->TexCoordArray[i].v); - printf("%d faces\n", model->nFace); + printf("%d faces\n", model->nFace); for (i = 0; i < model->nFace; i++) { printf("f %d/%d/%d %d/%d/%d %d/%d/%d %d/%d/%d\n", @@ -165,6 +275,14 @@ void ObjFree(ObjModel *model) free(model->TexCoordArray); free(model->FaceArray); free(model->VertexArray); + free(model->mtllib); + free(model->objectName); + free(model->usemtl); + + free(model->mtl->map_Ka); + free(model->mtl->map_Kd); + free(model->mtl); + free(model); } diff --git a/obj.h b/obj.h index 51acb3a..f9a4a26 100644 --- a/obj.h +++ b/obj.h @@ -3,32 +3,51 @@ typedef struct { - float x, y, z; + float x, y, z; } ObjVertex; typedef ObjVertex ObjNormal; typedef struct { - float u, v; + float u, v; } ObjTexCoord; typedef struct { - int Vertex[4]; - int Normal[4]; - int TexCoord[4]; + int Vertex[4]; + int Normal[4]; + int TexCoord[4]; } ObjFace; typedef struct { - char *mtllib; - char *objectName; - char *groupName; - int nVertex, nNormal, nTexCoord, nFace; - ObjVertex *VertexArray; - ObjNormal *NormalArray; - ObjTexCoord *TexCoordArray; - ObjFace *FaceArray; + float Ns; + float Ni; + float d; + float Tr; + ObjVertex Tf; + int illum; + ObjVertex Ka; + ObjVertex Kd; + ObjVertex Ks; + ObjVertex Ke; + char *map_Ka; + char *map_Kd; +} ObjMtl; + +typedef struct +{ + char *mtllib; + char *objectName; + char *groupName; + char *usemtl; + + ObjMtl *mtl; + int nVertex, nNormal, nTexCoord, nFace; + ObjVertex *VertexArray; + ObjNormal *NormalArray; + ObjTexCoord *TexCoordArray; + ObjFace *FaceArray; } ObjModel; /* function prototypes */ diff --git a/objloader.c b/objloader.c index 7521822..34de2b9 100644 --- a/objloader.c +++ b/objloader.c @@ -7,6 +7,10 @@ * Code: * http://www.gamedev.net/community/forums/topic.asp?topic_id=312335 * + * todo: move obj files and texures into folder named e.g. "obj", or find some way + * of figuring out the current directory, hmm, could modify a path string, e.g. + * "./cube/cube.obj" -> "/cube/*", I would need to loop for last occurence of "/" + * */ #include @@ -143,19 +147,6 @@ void render(ObjModel *model) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); draw_ground(); -#if 0 - glPushMatrix(); - glTranslatef(0.0f, 0.0f, -50.0f); - glScalef(0.2f, 0.2f, 0.2f); - glColor3f(1.0f, 0.0f, 0.0f); - glBegin(GL_QUADS); - glVertex3f(25.0f, 0.0f, 0.0f); - glVertex3f(25.0f, 50.0f, 0.0f); - glVertex3f(-25.0f, 50.0f, 0.0f); - glVertex3f(-25.0f, 0.0f, 0.0f); - glEnd(); -#endif - glPushMatrix(); glScalef(0.1f, 0.1f, 0.1f); glTranslatef(0.0f, 0.0f, -150.0f); @@ -231,6 +222,8 @@ int main(void) ObjModel *model = ObjLoadModel(memory, bytes); printf("Object Model has: %d faces!\n", model->nFace); + if (model->mtl != NULL) + printf("ambient texture map: %s\n", model->mtl->map_Ka); /* main loop */ while (program_running) -- cgit v1.2.3