//------------------------------------------------------------------------------------- // // JGE++ is a hardware accelerated 2D game SDK for PSP/Windows. // // Licensed under the BSD license, see LICENSE in JGE root for details. // // Copyright (c) 2007 James Hui (a.k.a. Dr.Watson) // //------------------------------------------------------------------------------------- #include "../include/JTypes.h" #include "../include/JFileSystem.h" #include "../include/JRenderer.h" #include "../include/JOBJModel.h" JOBJModel::JOBJModel() { mPolygons = NULL; mTexture = NULL; } JOBJModel::~JOBJModel() { if (mPolygons) delete [] mPolygons; if (mTexture) delete mTexture; } int JOBJModel::ReadLine(char *output, const char *buffer, int start, int size) { int index = 0; while (start < size && buffer[start] != '\n' && buffer[start] != '\r') output[index++] = buffer[start++]; while ((start < size && buffer[start] == '\n') || buffer[start] == '\r') start++; output[index] = 0; return start; } bool JOBJModel::Load(const char *modelName, const char *textureName) { JFileSystem* fileSys = JFileSystem::GetInstance(); if (!fileSys->OpenFile(modelName)) return false; int size = fileSys->GetFileSize(); char *buffer = new char[size]; fileSys->ReadFile(buffer, size); fileSys->CloseFile(); Vector3D vert; vector faceList; vector normalList; vector texList; vector vertList; normalList.reserve(32); texList.reserve(32); vertList.reserve(32); faceList.reserve(32); int filePtr = 0; char tmpLine[256]; char s1[256]; int count; while (filePtr < size) { filePtr = ReadLine(tmpLine, buffer, filePtr, size); { if ((tmpLine[0] == '#') || (strlen(tmpLine) < 3)) { } else if (tmpLine[0] == 'v') { count = sscanf(tmpLine, "%s %f %f %f", s1, &vert.x, &vert.y, &vert.z); if (count == 4) { if (strcmp(s1, "vn") == 0) normalList.push_back(vert); else if (strcmp(s1, "vt") == 0) texList.push_back(vert); else if (strcmp(s1, "v") == 0) vertList.push_back(vert); } else if (count == 3) { if (strcmp(s1, "vt") == 0) texList.push_back(vert); } } else if (tmpLine[0] == 'f') { Face face; face.mVertCount = 0; char *p = strchr(tmpLine, ' '); char *pNext = p; int vertIdx, texIdx, norIdx; while (p != NULL) { while (((*p) == ' ') || ((*p) == '\n') || ((*p) == '\t')) ++p; strcpy(s1, p); count = sscanf(s1, "%d/%d/%d", &vertIdx, &texIdx, &norIdx); if (count == 3) { if (face.mVertCount < 4) { face.mVertIdx[face.mVertCount] = vertIdx - 1; face.mTexIdx[face.mVertCount] = texIdx - 1; face.mNormalIdx[face.mVertCount] = norIdx - 1; face.mVertCount++; } } else if (count == 2) { if (face.mVertCount < 4) { face.mVertIdx[face.mVertCount] = vertIdx - 1; face.mTexIdx[face.mVertCount] = texIdx - 1; face.mNormalIdx[face.mVertCount] = 0; face.mVertCount++; } } else if (count == 1) { if (face.mVertCount < 4) { face.mVertIdx[face.mVertCount] = vertIdx - 1; face.mTexIdx[face.mVertCount] = 0; face.mNormalIdx[face.mVertCount] = 0; face.mVertCount++; } } pNext = strchr(p, ' '); p = pNext; } if (face.mVertCount == 3) // we do triangles only ;) faceList.push_back(face); } else if (tmpLine[0] == 'g') { } else if (tmpLine[0] == 'u') { } } } mPolycount = faceList.size(); mPolygons = new Vertex3D[mPolycount*3]; int idx = 0; for (int i=0;iLoadTexture(textureName); return true; } void JOBJModel::Render() { JRenderer::GetInstance()->RenderTriangles(mTexture, mPolygons, 0, mPolycount); }