I'm having some trouble drawing some 3d objects. I wrote a very simple .obj parser and I know it doesn't support all types of .obj files but that's fine and for me it doesn't need to. I just need to get something rendering on the screen correctly. Here's my parser
Mesh * Loader::loadObj(char * path) {
Mesh * objectMesh;
vector<Vertex *> indexedVertices;
vector<Vector3 * > normals;
vector<TextureCoordinate *> textureCoords;
vector<vector<GLushort>> meshIndices;
vector<GLushort> verticesIndexed;
vector<GLushort> texturesIndexed;
vector<GLushort> normalsIndexed;
ifstream inFile;
inFile.open(path);
if (!inFile.good())
{
cerr << "Can't open texture file " << path << endl;
return false;
}
std::cout << "Loading .obj file" << endl;
while (!inFile.eof()) {
string line;
std::getline(inFile, line);
if (line.substr(0, 2) == "v ") {//vertices
std::vector<string> elements = Operations::split(Operations::trim(line.substr(3)), *" ");
if (elements.size() > 1) {
std::cout << "Loading vertex data: " << line << endl;
Vertex * v = new Vertex(std::atof(elements.at(0).c_str()), std::atof(elements.at(1).c_str()), std::atof(elements.at(2).c_str()));
indexedVertices.push_back(v);
}
}
else if (line.substr(0, 2) == "vn") {//normals
std::vector<string> elements = Operations::split(Operations::trim(line.substr(3)), *" ");
std::cout << "Loading normal data: " << line << endl;
if (elements.size() > 1) {
Vector3 * v = new Vector3(std::atof(elements.at(0).c_str()), std::atof(elements.at(1).c_str()), std::atof(elements.at(2).c_str()));
normals.push_back(v);
}
}
else if (line.substr(0, 2) == "vt") {//tex coords
std::cout << "Loading texture data: " << line << endl;
std::vector<string> elements = Operations::split(Operations::trim(line.substr(3)), *" ");
if (elements.size() > 1) {
TextureCoordinate * t = new TextureCoordinate(std::atof(elements.at(0).c_str()), std::atof(elements.at(1).c_str()));
textureCoords.push_back(t);
}
}
else if (line.substr(0, 2) == "f ") {//faces / indices
std::cout << "Loading face data: " << line << endl;
std::vector<string> elements = Operations::split(Operations::trim(line.substr(2)), *" ");
if (elements.size() > 1) {
for (int i = 0; i < elements.size(); i++) {
std::vector<string> e = Operations::split(Operations::trim(elements.at(i)), *"/");
if (e.size() > 1) {
verticesIndexed.push_back(std::atof(e.at(0).c_str()) - 1);
texturesIndexed.push_back(std::atof(e.at(1).c_str()) - 1);
normalsIndexed.push_back(std::atof(e.at(2).c_str()) - 1);
}
}
}
}
}
meshIndices.push_back(verticesIndexed);
meshIndices.push_back(texturesIndexed);
meshIndices.push_back(normalsIndexed);
std::cout << "Face count: " << verticesIndexed.size() << " " << texturesIndexed.size() << " " << normalsIndexed.size() << endl;
objectMesh = new Mesh(indexedVertices, normals, textureCoords, meshIndices);
std::cout << "Vertices count: " << indexedVertices.size() << endl;
std::cout << "Normals count: " << normals.size() << endl;
std::cout << "Textures count: " << textureCoords.size() << endl;
inFile.close();
return objectMesh;
}
I believe this parses the data correctly, as the ending size of the vectors match the data in the file i.e. it would print 4700 vertices for example, and there would be 4700 vertices in the file.
I'm drawing the object using the following
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
for (int i = 0; i < mesh->meshIndices.size(); i++) {
glVertexPointer(3, GL_FLOAT, 0, mesh->indexedVertices[0]);
glNormalPointer(GL_FLOAT, 0, mesh->normals[0]);
glTexCoordPointer(2, GL_FLOAT, 0, mesh->textureCoords[0]);
glDrawElements(GL_TRIANGLES, mesh->meshIndices[i].size(), GL_UNSIGNED_SHORT, &mesh->meshIndices[i][0]);
}
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
Why aren't the objects drawing correctly?
Edit: This works, but it's extremely slow
glBegin(GL_TRIANGLES);
for (int i = 0; i < mesh->meshIndices[0].size(); i++)//36
{
glTexCoord2fv(&mesh->textureCoords[mesh->meshIndices[1][i]]->u);
glNormal3fv(&mesh->normals[mesh->meshIndices[2][i]]->x);
glVertex3fv(&mesh->indexedVertices[mesh->meshIndices[0][i]]->x);
}