Objectives

Setup

Refactor

Face

struct Face
{
  int vertices[3];
  int textures[3];

  Face(std::istream& is);
  void render(std::vector <Vector3>&amp;);
};
Face::Face(istream&amp; is)
{
  char ch1;
  for (int i = 0; i < 4; i++)
  {
    string separator;
    is >> vertices[i];
    is >> ch1;
    is >> textures[i];
  }
}

void Face::render(std::vector <Vector3>&amp;defaultTable)
{
  glBegin(GL_QUADS);
  for (int i=0; i<4; i++)
  {
    glVertex3f( defaultTable[vertices[i] - 1].X,
                defaultTable[vertices[i] - 1].Y,
                defaultTable[vertices[i] - 1].Z );
    cout << defaultTable[vertices[i] - 1].X << " " << defaultTable[vertices[i] - 1].Y << " " << defaultTable[vertices[i] - 1].Z << endl;
  }
  glEnd();
}
...
f 2/2 1/1 41/83
f 3/3 2/2 41/83
f 4/4 3/3 41/83
...
struct Face
{
  std::vector<int> vertexIndices;
  std::vector<int> textureIndices;

  Face(std::istream&amp; is);
  void render(std::vector <Vector3>&amp;);
};
#include <sstream>

using namespace std;

Face::Face(istream&amp; is)
{
  string line;
  getline (is, line);

  stringstream allIndexSets (line);
  string singleIndexSet;

  while( getline(allIndexSets, singleIndexSet, ' ') )
  {
   if (singleIndexSet.size() > 0)
   {
     string vertexIndex = singleIndexSet.substr(0, singleIndexSet.find('/'));
     int index = atoi(vertexIndex.c_str());
     vertexIndices.push_back(index);
   }
  }
}
void Face::render(std::vector <Vector3>&amp;vertexTable)
{
  vertexIndices.size() == 3?
     glBegin(GL_TRIANGLES)
    :glBegin(GL_QUADS);

  for (unsigned int i=0; i<vertexIndices.size(); i++)
   {
   glVertex3f( vertexTable[vertexIndices[i] - 1].X,
               vertexTable[vertexIndices[i] - 1].Y,
               vertexTable[vertexIndices[i] - 1].Z );
   }
   glEnd();
}

Groups

...
g default
...
g pCylinder1
...
g default
...
g pSphere1
...

VertexGroup

struct VertexGroup
{
  std::vector <Vector3> vertices;

  VertexGroup();
  void load(std::istream&amp;);
};

VertexGroup::VertexGroup()
{}

void VertexGroup::load(istream&amp; is)
{
  string indicator;
  bool stillGroup=true;
  do
  {
    is >> indicator;
    if (indicator == "v")
    {
      vertices.push_back(Vector3(is));
    }
    else if (indicator == "g")
    {
      stillGroup = false;
    }
    else
    {
      string buf;
      getline(is, buf);
    }
  } while (stillGroup &amp;&amp; ##is.eof());
  is.putback(indicator[0]);
}

Model::load

struct Model
{
  //...
  VertexGroup defaultGroup;
  //...
};
bool Model::load(istream&amp; is)
{
  string indicator;
  is >> indicator;
  while (##is.eof())
  {
    if (indicator == "#")
    {
      string buf;
      getline(is, buf);
    }
    else if (indicator == "g")
    {
      string name;
      is >> name;
      if (name == "default")
      {
        defaultGroup.load(is);
      }
      else
      {
        Mesh a(name, is);
        if (modelObjects.find(a.name) == modelObjects.end())
        {
          modelObjects[a.name] = a;
        }
      }
    }
    is >> indicator;
  }
  return true;
}

Mesh

struct Mesh
{
  std::string name;
  std::vector<Face> faces;

  Mesh();
  Mesh(std::string name, std::istream&amp;);
  void render(std::vector <Vector3>&amp;);
};
Mesh::Mesh(string groupName, istream&amp; is)
: name(groupName)
{
  string indicator;
  bool stillGroup=true;
  do
  {
    is >> indicator;
    if (indicator == "f")
    {
      faces.push_back(Face(is));
    }
    else if (indicator == "g")
    {
      stillGroup = false;
    }
    else
    {
      string buf;
      getline(is, buf);
    }
  } while (stillGroup &amp;&amp; ##is.eof());
  is.putback(indicator[0]);
}

Model::render

void Model::render()
{
  for (ModelMapIterator iter = modelObjects.begin(); iter ##= modelObjects.end(); iter++)
  {
    iter->second.render(defaultGroup.vertices);
  }
}

Exercises

Exercise 1:Additional objects

Exercise 2: Perspective

Exercise 3: Camera