// This code example is created for educational purpose
// by Thorsten Thormaehlen (contact: www.thormae.de).
// It is distributed without any warranty.

#include <GL/freeglut.h> // we use glut here as window manager

class Renderer {

private:
  void drawTriangle() {
    glBegin(GL_TRIANGLES);
    glVertex3f(-0.5f, -0.5f, 0.0f);
    glVertex3f( 0.5f, -0.5f, 0.0f);
    glVertex3f( 0.0f,  0.5f, 0.0f);
    glEnd();
  }

public:
  void init() {}
  void resize(int w, int h) {
    glViewport(0, 0, w, h);
  }
  void display() {
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    glLoadIdentity();
    glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f);
    glColor3f(1.0f, 1.0f, 1.0f);
    drawTriangle();

    glColor3f(0.0f, 0.0f, 1.0f);
    glScalef(0.5f, 0.5f, 0.0f); // resize to 50%
    drawTriangle();

    glColor3f(1.0f, 0.0f, 0.0f);
    glRotatef(45.0f, 0.0f, 0.0f, 1.0f); //rotate by 45 degrees
    drawTriangle();

    glColor3f(0.0f, 1.0f, 0.0f);
    glTranslatef(0.5f, 0.5f, 0.0f); // translate
    drawTriangle();
  }
  void dispose() {
  }
};

//this is a static pointer to a Renderer used in the glut callback functions
static Renderer* renderer;

//glut static callbacks start
static void glutResize(int w, int h)
{
  renderer->resize(300, 300);
}

static void glutDisplay()
{
  renderer->display();
  glutSwapBuffers();
}

static void glutClose()
{
  renderer->dispose();
}

int main(int argc, char** argv)
{
  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
  glutInitWindowPosition(100, 100);
  glutInitWindowSize(320, 320);

  glutCreateWindow("TriangleTransform");

  glutDisplayFunc(glutDisplay);
  glutReshapeFunc(glutResize);
  glutCloseFunc(glutClose);

  renderer = new Renderer;
  renderer->init();

  glutMainLoop();
}