我用c ++编写了一个OBJ文件解析器,但它确实有用。它可以将任何OBJ文件加载到模型中。然而它非常缓慢。加载一个低多边形模型最多可能需要十秒钟。有没有办法优化这个或者我的计算机是极低的?非常感谢任何帮助。
RawModel OBJLoader::loadModel(const std::string& filePath, Loader* loader)
{
std::ifstream file(filePath);
std::vector<glm::vec3> positions;
std::vector<glm::vec2> uvs;
std::vector<glm::vec3> normals;
std::vector<unsigned int> indices;
float* positionsArray = nullptr;
float* uvsArray = nullptr;
float* normalsArray = nullptr;
unsigned int* indicesArray = nullptr;
bool firstFace = true;
std::string line;
while (std::getline(file, line))
{
std::vector<std::string> currentLine = split(line, ' ');
if (line[0] == 'v' && line[1] == ' ')
{
glm::vec3 pos(parseFloat(currentLine[1]), parseFloat(currentLine[2]), parseFloat(currentLine[3]));
positions.push_back(pos);
}
else if (line[0] == 'v' && line[1] == 't')
{
glm::vec2 uv(parseFloat(currentLine[1]), parseFloat(currentLine[2]));
uvs.push_back(uv);
}
else if (line[0] == 'v' && line[1] == 'n')
{
glm::vec3 norm(parseFloat(currentLine[1]), parseFloat(currentLine[2]), parseFloat(currentLine[3]));
normals.push_back(norm);
}
else if (line[0] == 'f' && line[1] == ' ')
{
if (firstFace)
{
uvsArray = new float[positions.size() * 2];
normalsArray = new float[positions.size() * 3];
firstFace = false;
}
std::vector<std::string> vert1 = split(currentLine[1], '/');
std::vector<std::string> vert2 = split(currentLine[2], '/');
std::vector<std::string> vert3 = split(currentLine[3], '/');
processVertex(vert1, &indices, uvs, normals, uvsArray, normalsArray);
processVertex(vert2, &indices, uvs, normals, uvsArray, normalsArray);
processVertex(vert3, &indices, uvs, normals, uvsArray, normalsArray);
}
}
positionsArray = new float[positions.size() * 3];
indicesArray = new unsigned int[indices.size()];
for (int i = 0; i < positions.size(); i++)
{
positionsArray[i*3] = positions[i].x;
positionsArray[i*3+1] = positions[i].y;
positionsArray[i*3+2] = positions[i].z;
}
for (int i = 0; i < indices.size(); i++) indicesArray[i] = indices[i];
return loader->loadToVao(positionsArray, positions.size() * 3, indicesArray, indices.size(), uvsArray,positions.size()*2);
}
float parseFloat(const std::string& str)
{
return std::stof(str);
}
int parseInt(const std::string& str)
{
return std::stoi(str);
}
void processVertex(std::vector<std::string> vertData, std::vector<unsigned int>* indices, std::vector<glm::vec2> uvs, std::vector<glm::vec3> normals,
float* uvsArray, float* normalsArray)
{
unsigned int currentVertexPointer = parseInt(vertData[0]) - 1;
indices->push_back(currentVertexPointer);
glm::vec2 currentUv = uvs[parseInt(vertData[1]) - 1];
uvsArray[currentVertexPointer * 2] = currentUv.x;
uvsArray[currentVertexPointer * 2 + 1] = 1 - currentUv.y;
glm::vec3 currentNorm = normals[parseInt(vertData[2]) - 1];
normalsArray[currentVertexPointer * 3] = currentNorm.x;
normalsArray[currentVertexPointer * 3+1] = currentNorm.y;
normalsArray[currentVertexPointer * 3+2] = currentNorm.z;
}
std::vector<std::string> split(const std::string &str, const char &delim)
{
typedef std::string::const_iterator iter;
iter beg = str.begin();
std::vector<std::string> tokens;
while (beg != str.end()) {
//cout << ":" << beg._Myptr << ":" << endl;
iter temp = find(beg, str.end(), delim);
if (beg != str.end())
tokens.push_back(std::string(beg, temp));
beg = temp;
while ((beg != str.end()) && (*beg == delim))
beg++;
}
return tokens;
}