00: Objectives

01: Setup

main.cpp:

#include "libopengl.h"

void renderScene(void)
{
  glClear( GL_COLOR_BUFFER_BIT);

  glFlush();
}

void setupRC()
{
  glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

  glColor3f(0.0f, 1.0f, 0.0f);

  glOrtho(-1.0f, +1.0f, -1.0f, +1.0f, -1.0f, +1.0f);
}

int main(int argc, char* argv[])
{
  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
  glutCreateWindow("lab04");
  glutInitWindowSize(800, 600);
  glutDisplayFunc(renderScene);
  setupRC();
  glutMainLoop();

  return 0;
}

simple.h

#pragma once

void loadAndDraw(char* fileName);

simple.cpp

#include "simple.h"
#include "libopengl.h"
#include <fstream>
#include <vector>

using namespace std;

void loadAndDraw(char * fileName)
{
  fstream inStream;
  inStream.open(fileName, ios::in);
  if (inStream.fail())
    return;
  GLint numpolys, numLines;
  inStream >> numpolys;
  for (int j = 0; j < numpolys; j++)
  {
    inStream >> numLines;
    glBegin( GL_LINE_STRIP);
    for (int i = 0; i < numLines; i++)
    {
      float x, y;
      inStream >> x >> y;
      glVertex2f(x, y);
    }
    glEnd();
  }
  inStream.close();
}

02: Simple Model

struct Vertex
{
  float x;
  float y;
};

struct LineStrip
{
  int size;
  Vertex *vertices;
};

struct Model
{
  int size;
  LineStrip* lineStrips;
};
Model loadSimple(char *fileName)
{
  Model model;

  fstream inStream;
  inStream.open(fileName, ios::in);
  if (inStream.fail())
    exit(1);
  inStream >> model.size;
  model.lineStrips = new LineStrip[model.size];
  for (int polyIndex = 0; polyIndex < model.size; polyIndex++)
  {
    inStream >> model.lineStrips[polyIndex].size;
    model.lineStrips[polyIndex].vertices = new Vertex[model.lineStrips[polyIndex].size];
    for (int vertexIndex = 0; vertexIndex < model.lineStrips[polyIndex].size; vertexIndex++)
    {
      inStream >> model.lineStrips[polyIndex].vertices[vertexIndex].x >> model.lineStrips[polyIndex].vertices[vertexIndex].y;
    }
  }
  inStream.close();

  return model;
}

03: Simple Render

void renderSimple(Model &amp;model)
{
  for (int polyIndex=0; polyIndex < model.size; polyIndex++)
  {
    glBegin( GL_LINE_STRIP);
    for (int vertexIndex = 0; vertexIndex < model.lineStrips[polyIndex].size; vertexIndex++)
    {
      glVertex2f(model.lineStrips[polyIndex].vertices[vertexIndex].x, model.lineStrips[polyIndex].vertices[vertexIndex].y);
    }
    glEnd();
  }
}

04: Improved Model

struct Vertex
{
  float x;
  float y;
};

struct LineStrip
{
  vector<Vertex> vertices;
};

struct Model
{
  vector<LineStrip> lineStrips;
};
Model loadModel(char *fileName)
{
  Model model;

  fstream inStream;
  inStream.open(fileName, ios::in);
  if (inStream.fail())
    exit(1);
  int numberPolys;
  inStream >> numberPolys;
  for (int polyIndex = 0; polyIndex <  numberPolys; polyIndex++)
  {
    LineStrip LineStrip;
    int numberVertices;
    inStream >> numberVertices;
    for (int vertexIndex = 0; vertexIndex < numberVertices; vertexIndex++)
    {
      Vertex vertex;
      inStream >> vertex.x >> vertex.y;
      LineStrip.vertices.push_back(vertex);
    }
    model.lineStrips.push_back(LineStrip);
  }
  inStream.close();

  return model;
}

05: Improved Render

void renderModel(Model &amp;model)
{
  for (unsigned int polyIndex=0; polyIndex < model.lineStrips.size(); polyIndex++)
  {
    glBegin( GL_LINE_STRIP);
    for (unsigned int vertexIndex = 0; vertexIndex < model.lineStrips[polyIndex].vertices.size(); vertexIndex++)
    {
      glVertex2f(model.lineStrips[polyIndex].vertices[vertexIndex].x, model.lineStrips[polyIndex].vertices[vertexIndex].y);
    }
    glEnd();
  }
}

06: Model Abstractions

struct Vertex
{
  float x;
  float y;

  Vertex(istream&amp; is);
  void render();
};

struct LineStrip
{
  vector<Vertex> vertices;

  LineStrip(istream&amp; is);
  void render();
};

struct Model
{
  vector<LineStrip> lineStrips;

  Model(istream&amp; is);
  void render();
};

07: Model Implementation

Vertex

Vertex::Vertex(istream &amp;is)
{
  is >> x >> y;
}
void Vertex::render()
{
  glVertex2f(x, y);
}

LineStrip

LineStrip::LineStrip(istream &amp;is)
{
  int size;
  is >> size;
  for (int i = 0; i < size; i++)
  {
    Vertex vertex(is);
    vertices.push_back(vertex);
  }
}

void LineStrip::render()
{
  glBegin( GL_LINE_STRIP);
  for (unsigned int i = 0; i < vertices.size(); i++)
  {
    vertices[i].render();
  }
  glEnd();
}

Model


Model::Model(istream &amp;is)
{
  int size;
  is >> size;
  for (int i = 0; i < size; i++)
  {
    LineStrip LineStrip(is);
    lineStrips.push_back(LineStrip);
  }
}

void Model::render()
{
  for (unsigned int i = 0; i < lineStrips.size(); i++)
  {
    lineStrips[i].render();
  }
}

Test

Model *model;

void renderScene(void)
{
  glClear( GL_COLOR_BUFFER_BIT);

  model->render();

  glFlush();
}

void setupRC()
{
  glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

  glColor3f(0.0f, 1.0f, 0.0f);

  glOrtho(-1.0f, +1.0f, -1.0f, +1.0f, -1.0f, +1.0f);

  fstream modelStream;
  modelStream.open("bighouse.txt", ios::in);
  if (modelStream.fail())
    exit(1);
  model = new Model(modelStream);
}

08: Model File Format

#scale
150 150
#number of entities
4
# 1st entity
# 0 = line strip
0
# number of vertices
6
# vertices
40 40
40 90
70 120
100 90
100 40
40 40
# 2nd entity
# 0 = line strip
0
# number of vertices
4
# vertices
50 100
50 120
60 120
60 110
void skipComment(istream &amp;is)
{
  char ch;
  is >> ch;
  if (ch == '#')
  {
    do
    {
      string buf;
      getline(is, buf);
      is >> ch;
    } while (ch == '#');
  }
  is.putback(ch);
}

09: Revised Model Definition

enum EntityType {LineStripId, TriangleId};
struct Model
{
  int maxX, maxY;
  vector<LineStrip> lines;

  Model(istream&amp; is);
  void render();
}

10: Revised Model Implementation

Vertex::Vertex(istream &amp;is)
{
  skipComment(is);
  is >> x >> y;
}
LineStrip::LineStrip(istream &amp;is)
{
  int size;
  skipComment(is);
  is >> size;
  for (int i = 0; i < size; i++)
  {
    Vertex vertex(is);
    vertices.push_back(vertex);
  }
}
Model::Model(istream &amp;is)
{
  int size;
  skipComment(is);
  is >> maxX >> maxY;
  skipComment(is);
  is >> size;
    int typeId;
    skipComment(is);
    is >> typeId;
    switch (typeId)
    {
      case LineStripId: { LineStrip line(is);
                          lines.push_back(line);
                          break;
                        }
    }

11: Exercise: Model Extension

#scale
150 150
#number of entities
4
# 1st entity
# 0 = line strip
0
# number of vertices
6
# vertices
40 40
40 90
70 120
100 90
100 40
40 40
# 2nd entity
# 0 = line strip
0
# number of vertices
4
# vertices
50 100
50 120
60 120
60 110
# 3rd entity
# 1 = triangle
1
# 3 vertices
20 10
100 22
22 22
# 1 = triangle
1
# 3 vertices
120 10
10 22
102 22

12: Exercise: Model Revision

void Model::render()
{
  for (unsigned int i = 0; i < lines.size(); i++)
  {
    lines[i].render();
  }
  for (unsigned int i = 0; i < triangles.size(); i++)
  {
    triangles[i].render();
  }
}

void Model::render()
{
  for (unsigned int i=0; i<entities.size(); i++)
  {
    entities[i]->render();
  }
}