//------------------------------------------------------------------------------
// file: tomprogs_opengl_tutorial_03.cpp
// description: Contains the whole code used in the Tutorial
//              'C++ OpenGL Tutorials - Perspektive und der Z-Buffer'
//              at www.tomprogs.at
//------------------------------------------------------------------------------
// Copyright (c) 2008 - 2010, Thomas Geymayer
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
//    * Redistributions of source code must retain the above copyright
//      notice, this list of conditions and the following disclaimer.
//    * Redistributions in binary form must reproduce the above
//      copyright notice, this list of conditions and the following
//      disclaimer in the documentation and/or other materials provided
//      with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//------------------------------------------------------------------------------
#include "SDL.h"
#include "SDL_opengl.h"

#include <iostream>

#include "application_window.h"

using std::cout;
using std::endl;


// Polling-Funktion für Events
bool pollEvents()
{
  SDL_Event event;

  while( SDL_PollEvent(&event) ) // Nächste Nachricht holen
  {
    switch(event.type)
    {
      case SDL_QUIT:
        return false; // Programm sollte beendet werden
      default:
        break;
    }
  }

  return true;
}

int main(int argc, char **argv)
{
  if( SDL_Init( SDL_INIT_VIDEO ) != 0 ) // Initialisieren des SDL Video
                                        // Subsystems
  {
    cout << "Die SDL konnte nicht initalisiert werden ("
         << SDL_GetError() << ")" << endl;
    return 1;
  }

  // Ein Fenster mit 800*600 Pixeln bei 32 Bit Farbtiefe anlegen
  TomprogsTutorial_::ApplicationWindow *game_window =
    new TomprogsTutorial_::ApplicationWindow( 800, 600, 32 );

  // Den Fenstertitel setzen
  game_window->setCaption( "Tomprogs Tutorial - Perspektive und Z-Buffer" );

  // Und schließlich das Fenster erzeugen lassen
  game_window->create();

  glClearColor( 1.0, 0.5, 0.4, 0.0 ); // Farbe zum Löschen setzen
  glEnable( GL_DEPTH_TEST );          // Z-Buffer und Tiefentest aktivieren

  //--------------------------
  // Die Projektion festlegen:
  // Diesmal außerhalb der
  // Endlosschleife.
  //--------------------------

  glMatrixMode( GL_PROJECTION ); // Die Projektionsmatrix
  glLoadIdentity();              // zurücksetzen

  // Eine perspektivische Projektion setzen.
  glFrustum( -1.6, 1.6, -1.2, 1.2, 1.5, 6.5 ); // Die Near-Clipping-Plane
                                               // befindet sich in einer
                                               // Entfernung von 1.5 Einheiten
                                               // hat die Abmessungen 3.2 * 2.4
                                               // Einheiten.
                                               // Die Far-Clipping-Plane ist 6.5
                                               // Einheiten entfernt.

  glMatrixMode( GL_MODELVIEW ); // Die Transformationsmatrix
  glLoadIdentity();             // zurücksetzen...

  glTranslatef(0,0,-3.5); // ... und den Quader um 3.5 Einheiten in den
  glRotatef(60,1,1,0);    // Bildschirm verschieben und etwas rotieren.

  // Und noch einmal die Endlosschleife
  while(true)
  {
    if( !pollEvents() ) break; // Nachrichten verarbeiten

    // Bildpuffer und Z-Buffer zurücksetzen:
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    //----------------------
    // Den Quader zeichnen:
    //----------------------

    glBegin( GL_QUADS ); // Wir bauen den Würfel aus Quadraten (Quads) auf

      glColor3f(1, 0,   0  );   // Ab jetzt werden alle gezeichneten Punkte rot
        glVertex3f( 1,  1, -1);
        glVertex3f( 1, -1, -1);
        glVertex3f(-1, -1, -1);
        glVertex3f(-1,  1, -1);

      glColor3f(0, 1,   0  );   // Ab jetzt werden alle gezeichneten Punkte grün
        glVertex3f( 1,  1,  1);
        glVertex3f(-1,  1,  1);
        glVertex3f(-1, -1,  1);
        glVertex3f( 1, -1,  1);

      glColor3f(0, 0,   1  );
        glVertex3f( 1,  1, -1);
        glVertex3f( 1,  1,  1);
        glVertex3f( 1, -1,  1);
        glVertex3f( 1, -1, -1);

      glColor3f(1, 1,   0  );
        glVertex3f( 1, -1, -1);
        glVertex3f( 1, -1,  1);
        glVertex3f(-1, -1,  1);
        glVertex3f(-1, -1, -1);

      glColor3f(0, 0.5, 1  );
        glVertex3f(-1, -1, -1);
        glVertex3f(-1, -1,  1);
        glVertex3f(-1,  1,  1);
        glVertex3f(-1,  1, -1);

      glColor3f(1, 0.1, 0.8);
        glVertex3f( 1,  1,  1);
        glVertex3f( 1,  1, -1);
        glVertex3f(-1,  1, -1);
        glVertex3f(-1,  1,  1);

    glEnd(); // Wir sind fertig mit dem Zeichnen

    SDL_GL_SwapBuffers(); // Bildbuffer vertauschen
  }

  SDL_Quit();

  return 0;
}

