diff options
| -rw-r--r-- | obj.c | 126 | ||||
| -rw-r--r-- | obj.h | 45 | ||||
| -rw-r--r-- | objloader.c | 19 | 
3 files changed, 160 insertions, 30 deletions
| @@ -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);  } @@ -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) | 
