//---------------------------------------------------------------------
// Ukazkovy priklad cislo 5
// Autor: Pavel Tisnovsky
//
// Program otevre jedno hlavni okno a vykresli nekolik trojuhelniku,
// ktere maji nastaveny ruzne vlastnosti. Okno (a tim i celou aplikaci)
// lze ukoncit stiskem klavesy ESC nebo uzavrenim hlavniho okna programu.
//---------------------------------------------------------------------

#include <GL/glut.h>                            // hlavickovy soubor funkci GLUTu a OpenGL



//---------------------------------------------------------------------
// Nastaveni souradneho systemu v zavislosti na velikosti okna
//---------------------------------------------------------------------
void onResize(int w, int h)                     // parametry w a h reprezentuji novou velikost okna
{
    glViewport(0, 0, w, h);                     // viditelna oblast pres cele okno
    glMatrixMode(GL_PROJECTION);                // zacatek modifikace projekcni matice
    glLoadIdentity();                           // vymazani projekcni matice (=identita)
    glOrtho(0, w, 0, h, -1, 1);                 // mapovani abstraktnich souradnic do souradnic okna
}



//---------------------------------------------------------------------
// Tato funkce slouzi k vykresleni RGB trojuhelniku na pozici x, y
//---------------------------------------------------------------------
void drawTriangle(GLint x, GLint y)
{
    glBegin(GL_TRIANGLES);
        glColor3f(1.0f, 0.0f, 0.0f);            // kazdy vertex bude vykresleny jinou barvou
        glVertex2i(x, y);
        glColor3f(0.0f, 1.0f, 0.0f);
        glVertex2i(x+100, y);
        glColor3f(0.0f, 0.0f, 1.0f);
        glVertex2i(x+50, y+80);
    glEnd();
}



//---------------------------------------------------------------------
// Tato funkce je volana pri kazdem prekresleni okna
// Po zavolani teto funkce se vykresli nekolik trojuhelniku s ruznymi
// vlastnostmi
//---------------------------------------------------------------------
void onDisplay(void)
{
    GLubyte pattern1[32*4]={                    // prvni vyplnovy vzorek
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x03, 0x80, 0x01, 0xC0, 0x06, 0xC0, 0x03, 0x60,
        0x04, 0x60, 0x06, 0x20, 0x04, 0x30, 0x0C, 0x20,
        0x04, 0x18, 0x18, 0x20, 0x04, 0x0C, 0x30, 0x20,
        0x04, 0x06, 0x60, 0x20, 0x44, 0x03, 0xC0, 0x22,
        0x44, 0x01, 0x80, 0x22, 0x44, 0x01, 0x80, 0x22,
        0x44, 0x01, 0x80, 0x22, 0x44, 0x01, 0x80, 0x22,
        0x44, 0x01, 0x80, 0x22, 0x44, 0x01, 0x80, 0x22,
        0x66, 0x01, 0x80, 0x66, 0x33, 0x01, 0x80, 0xCC,
        0x19, 0x81, 0x81, 0x98, 0x0C, 0xC1, 0x83, 0x30,
        0x07, 0xe1, 0x87, 0xe0, 0x03, 0x3f, 0xfc, 0xc0,
        0x03, 0x31, 0x8c, 0xc0, 0x03, 0x33, 0xcc, 0xc0,
        0x06, 0x64, 0x26, 0x60, 0x0c, 0xcc, 0x33, 0x30,
        0x18, 0xcc, 0x33, 0x18, 0x10, 0xc4, 0x23, 0x08,
        0x10, 0x63, 0xC6, 0x08, 0x10, 0x30, 0x0c, 0x08,
        0x10, 0x18, 0x18, 0x08, 0x10, 0x00, 0x00, 0x08};

    GLubyte pattern2[32*4]={                    // druhy vyplnovy vzorek
        0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa,
        0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa,
        0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa,
        0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa,
        0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa,
        0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa,
        0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa,
        0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa,
        0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa,
        0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa,
        0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa,
        0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa,
        0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa,
        0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa,
        0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa,
        0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa};

    glClearColor(0.0, 0.0, 0.0, 0.0);           // nastaveni mazaci barvy na cernou
    glClear(GL_COLOR_BUFFER_BIT);               // vymazani bitovych rovin barvoveho bufferu

    glPointSize(5.0f);                          // velikost bodu je rovna peti pixelum
    glLineWidth(2.0f);                          // tloustka usecek je rovna dvema pixelum
    glEnable(GL_POINT_SMOOTH);                  // povoleni antialiasingu bodu
    glEnable(GL_LINE_SMOOTH);                   // povoleni antialiasingu usecek
    glDisable(GL_POLYGON_STIPPLE);              // zakazat vzorek
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);  // vykreslovani vyplnenych trojuhelniku
    drawTriangle(50, 50);
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);  // vykreslovani pouze hran trojuhelniku
    drawTriangle(180, 50);
    glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); // vykreslovani pouze vrcholu trojuhelniku
    drawTriangle(310, 50);
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);  // vykreslovani vyplnenych trojuhelniku
    glEnable(GL_POLYGON_STIPPLE);               // povolit vzorek
    glPolygonStipple(pattern1);                 // zadat prvni vzorek
    drawTriangle(110, 190);
    glPolygonStipple(pattern2);                 // zadat druhy vzorek
    drawTriangle(240, 190);
    glFlush();                                  // provedeni a vykresleni zmen
}



//---------------------------------------------------------------------
// Tato funkce je volana pri stlaceni ASCII klavesy
//---------------------------------------------------------------------
void onKeyboard(unsigned char key, int x, int y)
{
    if (key==27) exit(0);                       // pokud byla stlacena klavesa ESC, konec programu
}



//---------------------------------------------------------------------
// Hlavni funkce konzolove aplikace
//---------------------------------------------------------------------
int main(int argc, char **argv)
{
    glutInit(&argc, argv);                      // inicializace knihovny GLUT
    glutCreateWindow("Priklad na OpenGL cislo 5");// vytvoreni okna pro kresleni
    glutReshapeWindow(450, 300);                // zmena velikosti okna
    glutPositionWindow(100, 100);               // pozice leveho horniho rohu okna
    glutDisplayFunc(onDisplay);                 // registrace funkce volane pri prekreslovani okna
    glutReshapeFunc(onResize);                  // registrace funkce volane pri zmene velikosti okna
    glutKeyboardFunc(onKeyboard);               // registrace funkce volani pri stlaceni klavesy
    glutMainLoop();                             // nekonecna smycka, kde se volaji zaregistrovane funkce
    return 0;                                   // navratova hodnota vracena operacnimu systemu
}



//---------------------------------------------------------------------
// Konec zdrojoveho souboru
//---------------------------------------------------------------------