summaryrefslogtreecommitdiffstats
path: root/obj.c
diff options
context:
space:
mode:
Diffstat (limited to 'obj.c')
-rw-r--r--obj.c206
1 files changed, 154 insertions, 52 deletions
diff --git a/obj.c b/obj.c
index 20f66ca..e6262d3 100644
--- a/obj.c
+++ b/obj.c
@@ -12,6 +12,7 @@
*
*/
+#include <GL/glew.h>
#include <stdlib.h>
#include <stdio.h>
#include <memory.h>
@@ -19,18 +20,24 @@
ObjModel* ObjLoadModel(char *memory, size_t size)
{
- char *p = NULL, *e = NULL;
- ObjModel *ret = (ObjModel *) calloc(1, sizeof(ObjModel));
- /* initialize to zero */
- memset(ret, 0, sizeof(ObjModel));
-
/* if size is 0, meaning file was not loaded correctly, return null */
if (!size)
- return ret;
+ return NULL;
+ char *p = NULL, *e = NULL;
+ ObjModel *ret = (ObjModel *) malloc(sizeof(ObjModel));
+ if (!ret)
+ {
+ fprintf(stderr, "ObjLoadModel() failed, %s:%d\n", __FILE__, __LINE__);
+ perror("malloc");
+ exit(-1);
+ }
+
+ /* initialize to zero */
+ memset(ret, 0, sizeof(ObjModel));
p = memory;
e = memory + size;
-
+
/* count the number of normals, texcoords, vertices, and faces, line by line */
while (p != e)
{
@@ -39,87 +46,114 @@ ObjModel* ObjLoadModel(char *memory, size_t size)
else if (memcmp(p, "v", 1) == 0) ret->nVertex++;
else if (memcmp(p, "f", 1) == 0) ret->nFace++;
- while (*p++ != (char) 0x0a);
+ /* seek to new line */
+ while (*p++ != (char) 0x0a)
+ ;
}
/* allocate memory for arrays */
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->mtllib = (char *) malloc(sizeof(char) * 21);
- ret->objectName = (char *) malloc(sizeof(char) * 21);
- ret->usemtl = (char *) malloc(sizeof(char) * 21);
+ 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);
+
+ *ret->mtllib = '\0';
+ *ret->objectName = '\0';
+ *ret->usemtl = '\0';
+
+ if (!ret->VertexArray || !ret->NormalArray || !ret->TexCoordArray ||
+ !ret->FaceArray || !ret->mtllib || !ret->objectName || !ret->usemtl)
+ {
+ fprintf(stderr, "ObjLoadModel() failed, %s:%d\n", __FILE__, __LINE__);
+ perror("malloc");
+ exit(-1);
+ }
+
+#if 0 /* already done by memset */
memset(ret->mtllib, 0, 21);
memset(ret->objectName, 0, 21);
memset(ret->usemtl, 0, 21);
+#endif
p = memory;
-
- int nV = 0, nN = 0, nT = 0, nF = 0;
- int nread = 0;
-
+
+ unsigned int nV = 0, nN = 0, nT = 0, nF = 0;
+ unsigned int nread = 0;
+
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*/
+ /* 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);
-
+
+ /* parse a normal */
if (memcmp(p, "vn", 2) == 0)
{
nread = sscanf(p, "vn %f %f %f", &ret->NormalArray[nN].x,
- &ret->NormalArray[nN].y,
- &ret->NormalArray[nN].z);
+ &ret->NormalArray[nN].y,
+ &ret->NormalArray[nN].z);
if (nread != 3)
printf("vn: read only %d instead of 3\n", nread);
+
nN++;
}
+ /* 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);
+ &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++;
}
+ /* parse a vertex */
else if (memcmp(p, "v", 1) == 0) /* or *p == 'v' */
{
nread = sscanf(p, "v %f %f %f", &ret->VertexArray[nV].x,
- &ret->VertexArray[nV].y,
- &ret->VertexArray[nV].z);
+ &ret->VertexArray[nV].y,
+ &ret->VertexArray[nV].z);
if (nread != 3)
printf("v: read only %d instead of 3\n", nread);
+
nV++;
}
/* quad */
else if (memcmp(p, "f", 1) == 0) /* or *p == 'f' */
{
nread = sscanf(p, "f %d/%d/%d %d/%d/%d %d/%d/%d %d/%d/%d",
- &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]);
+ &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);
+ printf("f: read only %d instead of 12\n", nread);
+
nF++;
}
+
/* seek to a newline */
- while (*p++ != (char) 0x0a);
+ while (*p++ != (char) 0x0a)
+ ;
}
/* sanity check */
@@ -136,7 +170,7 @@ ObjModel* ObjLoadModel(char *memory, size_t size)
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)
{
@@ -149,13 +183,27 @@ ObjModel* ObjLoadModel(char *memory, size_t size)
if (mtl_bytes)
{
- ObjMtl *mtl = (ObjMtl *) calloc(1, sizeof(ObjMtl));
+ ObjMtl *mtl = (ObjMtl *) malloc(sizeof(ObjMtl));
+ if (!mtl)
+ {
+ fprintf(stderr, "ObjLoadModel() failed, %s:%d\n", __FILE__, __LINE__);
+ perror("malloc");
+ exit(-1);
+ }
+
/* initialize to zero */
memset(mtl, 0, sizeof(ObjMtl));
/* allocate space for dynamic members */
mtl->map_Ka = (char *) malloc(sizeof(char) * 21);
mtl->map_Kd = (char *) malloc(sizeof(char) * 21);
+ if (!mtl->map_Ka || !mtl->map_Kd)
+ {
+ fprintf(stderr, "ObjLoadModel() failed, %s:%d\n", __FILE__, __LINE__);
+ perror("malloc");
+ exit(-1);
+ }
+
*mtl->map_Ka = '\0';
*mtl->map_Kd = '\0';
@@ -165,7 +213,8 @@ ObjModel* ObjLoadModel(char *memory, size_t size)
while (st != ed)
{
/* skip spaces */
- while (*st++ == (char) 0x20);
+ while (*st++ == (char) 0x20)
+ ;
if (memcmp(st, "Ns", 2) == 0)
sscanf(st, "Ns %f", &mtl->Ns);
@@ -204,16 +253,18 @@ ObjModel* ObjLoadModel(char *memory, size_t size)
sscanf(st, "map_Kd %s", mtl->map_Kd);
/* go to next line */
- while (*st++ != (char) 0x0a);
+ while (*st++ != (char) 0x0a)
+ ;
}
/* set the mtl */
ret->mtl = mtl;
}
else
- ret->mtl = NULL;
+ ret->mtl = NULL; /* should already be NULL but what the hell */
- free(fname);
- }
+ if (fname)
+ free(fname);
+ }
return ret;
}
@@ -230,13 +281,16 @@ size_t ObjLoadFile(char *szFileName, char **memory)
size_t end = ftell(file);
fseek(file, 0, SEEK_SET);
- *memory = (char *) malloc(end);
+ *memory = (char *) malloc(sizeof(char) * end);
bytes = fread(*memory, sizeof(char), end, file);
fclose(file);
}
else
- perror("fopen");
+ {
+ fprintf(stderr, "ObjLoadModel() failed, %s:%d\n", __FILE__, __LINE__);
+ perror("fopen");
+ }
return bytes;
}
@@ -259,7 +313,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",
@@ -283,7 +337,7 @@ char *ObjGetPath(char *fname)
if (obj_last_fname == NULL)
return NULL;
- char *path = (char *) malloc(sizeof(char) * 31);
+ char *path = (char *) malloc(sizeof(char) * 101);
char *delimeter = strrchr(obj_last_fname, '/');
unsigned int offset = delimeter - obj_last_fname;
strncpy(path, obj_last_fname, offset + 1);
@@ -292,8 +346,53 @@ char *ObjGetPath(char *fname)
return path;
}
+void ObjPutFaceGLCmd(const ObjModel *model, const unsigned i)
+{
+ 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 );
+}
+
void ObjFree(ObjModel *model)
{
+ if (model == NULL)
+ return;
+
free(model->NormalArray);
free(model->TexCoordArray);
free(model->FaceArray);
@@ -302,9 +401,12 @@ void ObjFree(ObjModel *model)
free(model->objectName);
free(model->usemtl);
- free(model->mtl->map_Ka);
- free(model->mtl->map_Kd);
- free(model->mtl);
+ if (model->mtl)
+ {
+ free(model->mtl->map_Ka);
+ free(model->mtl->map_Kd);
+ free(model->mtl);
+ }
free(model);
}