#include "model.h" #include "utils.h" Model::Model() { //初始化材质 memset(mAmbientMaterial, 0, sizeof(mAmbientMaterial)); memset(mDiffuseMaterial, 0, sizeof(mDiffuseMaterial)); memset(mSpecularMaterial, 0, sizeof(mSpecularMaterial)); } void Model::Init(const char * modelPath) { struct FloatData { float v[3]; }; struct VertexDefine { int posIndex; int texcoordIndex; int normalIndex; }; int nFileSize = 0; unsigned char* fileContent = LoadFileContent(modelPath, nFileSize); if (fileContent == nullptr) { return; } std::vector positions, texcoords, normals; std::vector vertexes; std::vector indexes; std::string temp; //存储文件内容,内存块 std::stringstream ssFileContent((char*)fileContent); //存储行数据 char szOneLine[256]; //使用流来读取文件 while (!ssFileContent.eof()) { //读取一行 memset(szOneLine, 0, 256); ssFileContent.getline(szOneLine, 256); //空行不处理 if (strlen(szOneLine) > 0) { if (szOneLine[0] == 'v') { std::stringstream ssOneLine(szOneLine); if (szOneLine[1] == 't') { ssOneLine >> temp;//通过流输出vt到 temp FloatData floatData; ssOneLine >> floatData.v[0]; ssOneLine >> floatData.v[1]; texcoords.push_back(floatData); printf("texcoord : %f,%f\n", floatData.v[0], floatData.v[1]); } else if (szOneLine[1] == 'n') { ssOneLine >> temp; FloatData floatData; ssOneLine >> floatData.v[0]; ssOneLine >> floatData.v[1]; ssOneLine >> floatData.v[2]; normals.push_back(floatData); printf("normal : %f,%f,%f\n", floatData.v[0], floatData.v[1], floatData.v[2]); } else { ssOneLine >> temp; FloatData floatData; ssOneLine >> floatData.v[0]; ssOneLine >> floatData.v[1]; ssOneLine >> floatData.v[2]; positions.push_back(floatData); printf("position : %f,%f,%f\n", floatData.v[0], floatData.v[1], floatData.v[2]); } } else if (szOneLine[0] == 'f') { std::stringstream ssOneLine(szOneLine); ssOneLine >> temp; std::string vertexStr; for (int i = 0; i < 3; i++) { ssOneLine >> vertexStr; //获取position索引 size_t pos = vertexStr.find_first_of('/'); std::string posIndexStr = vertexStr.substr(0, pos); //获取texcoord索引 size_t pos2 = vertexStr.find_first_of('/', pos + 1); std::string texcoordIndexStr = vertexStr.substr(pos + 1, pos2 - 1 - pos); //获取normal索引 std::string normalIndexStr = vertexStr.substr(pos2 + 1, vertexStr.length() - 1 - pos2); VertexDefine vd; vd.posIndex = atoi(posIndexStr.c_str()); vd.texcoordIndex = atoi(texcoordIndexStr.c_str()); vd.normalIndex = atoi(normalIndexStr.c_str()); //去除重复 int nCurrentVertexIndex = -1; int nCurrentVertexCount = (int)vertexes.size(); for (int j = 0; j < nCurrentVertexCount; j++) { if (vertexes[j].posIndex == vd.posIndex && vertexes[j].texcoordIndex == vd.texcoordIndex && vertexes[j].normalIndex == vd.normalIndex) { nCurrentVertexIndex = j; break; } } if (nCurrentVertexIndex == -1) { nCurrentVertexIndex = (int)vertexes.size(); vertexes.push_back(vd); } indexes.push_back(nCurrentVertexIndex); } printf("draw command : %s\n", szOneLine); } } } //TODO为啥要复制??? mIndexCount = (int)indexes.size(); mIndexes = new unsigned short[mIndexCount]; for (int i = 0; i < mIndexCount; ++i) { mIndexes[i] = indexes[i]; } int vertexCount = (int)vertexes.size(); mVertexes = new VertexData[vertexCount]; for (int i = 0; i < vertexCount; i++) { memcpy(mVertexes[i].position, positions[vertexes[i].posIndex - 1].v, sizeof(float) * 3); memcpy(mVertexes[i].texcoord, texcoords[vertexes[i].texcoordIndex - 1].v, sizeof(float) * 2); memcpy(mVertexes[i].normal, normals[vertexes[i].normalIndex - 1].v, sizeof(float) * 3); } delete fileContent; } void Model::Draw() { //开启光照 glEnable(GL_LIGHTING); glMaterialfv(GL_FRONT, GL_AMBIENT, mAmbientMaterial); glMaterialfv(GL_FRONT, GL_DIFFUSE, mDiffuseMaterial); glMaterialfv(GL_FRONT, GL_SPECULAR, mSpecularMaterial); //开启纹理 glEnable(GL_TEXTURE_2D); //glMaterialf(GL_FRONT, GL_SHININESS, 64.0f); //glDisable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, mTexture); glEnable(GL_DEPTH_TEST); glPushMatrix(); glTranslatef(0.0f, 0.0f, -5.0f); static float t = 0.0; glRotated(t, 1.0f, 1.0f, 1.0f); t += 0.05; glBegin(GL_TRIANGLES); for (int i = 0; i < mIndexCount; i++) { glTexCoord2fv(mVertexes[mIndexes[i]].texcoord); glNormal3fv(mVertexes[mIndexes[i]].normal); glVertex3fv(mVertexes[mIndexes[i]].position); } glEnd(); glPopMatrix(); } void Model::SetAmbientMaterial(float r, float g, float b, float a) { mAmbientMaterial[0] = r; mAmbientMaterial[1] = g; mAmbientMaterial[2] = b; mAmbientMaterial[3] = a; } void Model::SetDiffuseMaterial(float r, float g, float b, float a) { mDiffuseMaterial[0] = r; mDiffuseMaterial[1] = g; mDiffuseMaterial[2] = b; mDiffuseMaterial[3] = a; } void Model::SetSpecularMaterial(float r, float g, float b, float a) { mSpecularMaterial[0] = r; mSpecularMaterial[1] = g; mSpecularMaterial[2] = b; mSpecularMaterial[3] = a; }