summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKyle K <kylek389@gmail.com>2010-10-16 01:52:02 -0500
committerKamil Kaminski <kamilkss@gmail.com>2010-10-16 01:52:02 -0500
commit026bf263d5106449e2e0ed04f55bb152003d80b1 (patch)
treeb728a7c2ab63b78c363b20b57a04f55de1596964
parent6eab93bc13fea3e1ca8ada24130350774de911ca (diff)
downloadOBJLoader-026bf263d5106449e2e0ed04f55bb152003d80b1.tar.gz
OBJLoader-026bf263d5106449e2e0ed04f55bb152003d80b1.tar.bz2
OBJLoader-026bf263d5106449e2e0ed04f55bb152003d80b1.zip
Inital mtl
-rw-r--r--obj.c126
-rw-r--r--obj.h45
-rw-r--r--objloader.c19
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 <stdlib.h>
#include <stdio.h>
#include <memory.h>
@@ -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 <SDL/SDL.h>
@@ -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)