Are there any “simple” ways to load a model that I can use in OpenGL?
I’m currently trying to parse Wavefront OBJ files but it isn’t going very well.
Nothing is displayed, unless I use the console output from the program in my code instead of the loop to draw the vertices and faces. Even when this happens the model isn’t actually what it should be.
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <vector>
#include <gl/freeglut.h>
#include <boost/algorithm/string.hpp>
std::vector<float> vertexData;
std::vector<int> faceData;
std::vector<float> drawThis;
float angle = 0.1;
void display();
void framerate(int timer);
int main(int argc, char **argv)
{
std::fstream in("cube.obj");
std::cout.precision(6);
in.precision(6);
if(in.is_open())
{
while(!in.eof())
{
std::string buffer;
std::getline(in, buffer);
if(buffer != "")
{ // If vertex, put in vertexData vector
if(buffer[0] == 'v')
{
std::vector<std::string> splitVector;
boost::split(splitVector, buffer, boost::is_any_of(" "));
for(int i = 1; i < splitVector.size(); i++)
{
std::stringstream ss;
float tempFloat;
ss << splitVector[i];
ss >> tempFloat;
vertexData.push_back(tempFloat);
}
}
else if(buffer.find("usemtl") != std::string::npos)
{
// Material stuff
}
else if(buffer[0] == 'f')
{ // If face, put in faceData vector
std::vector<std::string> splitVector;
boost::split(splitVector, buffer, boost::is_any_of(" "));
for(int i = 1; i < splitVector.size(); i++)
{
std::stringstream ss;
int tempInt;
ss << splitVector[i];
ss >> tempInt;
faceData.push_back(tempInt);
}
}
}
}
for(int i = 0; i < faceData.size(); i++)
{
std::cout << "glVertex3f(" << vertexData[faceData[i]] << ", ";
std::cout << vertexData[faceData[i] + 1] << ", ";
std::cout << vertexData[faceData[i] + 2] << ");" << std::endl;
// An object IS displayed if I use this output in my code instead of the for loop but the
// object still isn't correct.
}
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(500, 500);
glutInitWindowPosition(0, 0);
glutCreateWindow("modeltest");
glEnable(GL_DEPTH_TEST);
glClearColor(1.0, 1.0, 1.0, 1.0);
glutDisplayFunc(display);
glutTimerFunc(1000/100, framerate, 1);
glutMainLoop();
}
else
{
return 0;
}
system("pause");
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glRotatef(angle, 0.5, 0.5, 0.5);
glColor4f(1.0, 0.0, 0.0, 1.0);
glBegin(GL_TRIANGLES);
for(int i = 0; i < faceData.size(); i++)
{
glVertex3f(vertexData[faceData[i]], vertexData[faceData[i]] + 1, vertexData[faceData[i]] + 2);
}
// Nothing displayed
glEnd();
glutSwapBuffers();
}
void framerate(int timer)
{
angle += 0.5;
glutPostRedisplay();
glutTimerFunc(1000/60, framerate, timer);
}
The file I’m trying to read is a triangulated cube exported from Blender.
# Blender3D v249 OBJ File:
# www.blender3d.org
mtllib cube.mtl
v 1.000000 -1.000000 -1.000000
v 1.000000 -1.000000 1.000000
v -1.000000 -1.000000 1.000000
v -1.000000 -1.000000 -1.000000
v 1.000000 1.000000 -1.000000
v 0.999999 1.000000 1.000001
v -1.000000 1.000000 1.000000
v -1.000000 1.000000 -1.000000
usemtl Material
s off
f 5 1 4
f 5 4 8
f 3 7 8
f 3 8 4
f 2 6 3
f 6 7 3
f 1 5 2
f 5 6 2
f 5 8 6
f 8 7 6
f 1 2 3
f 1 3 4
Maybe there already is a library for loading OBJ files, or would another model format be more appropriate?