#include <stdio.h>
#include <stdlib.h>
#define _USE_MATH_DEFINES
#include <math3d.h>
#include <GL/glut.h>
#include <GL/glext.h>
#include <ctime>

//Pozicije kamere i svjetla
float camx = 2.1f, camy = 7.0f, camz = 5.0f;
float cameraPosition[] = {camx, camy, camz};
float lightPosition[] = {-3.0f, 5.8f, 1.0f};
float center[] = {0.0f, 2.0f, 0.0f};

//Boje
float bijelo[] = {1.0f, 1.0f, 1.0f, 1.0f};
float tamno[] = {0.2f, 0.2f, 0.2f, 1.0f};
float crno[] = {0.0f, 0.0f, 0.0f, 1.0f};

//Polja za slucajno generiranje objekata
int ro[15], rx[15], rz[15], rr[15], rv[15], rcr[15], rcg[15], rcb[15];

//Proporcije lika
double prop = 0.7;

//Kretanje lika
double nn = 0.0, ld = 0.0;
double okret = 0.0;

//Duzina vrata
double duzina = 0.0;

//Metode rjesavanja akni
int cul = 1, cor = 1;

//Velicina mape sjene
const int shadowMapSize = 512;

//Texture
GLuint shadowMapTexture;

//Velicina prozora
int windowWidth, windowHeight;

//Matrice
M3DMatrix44f lightProjectionMatrix, lightViewMatrix;
M3DMatrix44f cameraProjectionMatrix, cameraViewMatrix;
M3DMatrix44f textureMatrix;

//Pretvaranje u stupnjeve i radijane
double toRad(double stup) {
    return stup * M_PI / 180;
}

double toDeg(double rad) {
    return rad * 180 / M_PI;
}

//Normiranje vektora
void normiraj(double *v) {
    double d = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
    v[0] /= d;
    v[1] /= d;
    v[2] /= d;
}

//Izracun vektorskog produkta
void vprodukt(double *v, double a0, double a1, double a2,
        double b0, double b1, double b2) {
    v[0] = a1 * b2 - a2 * b1;
    v[1] = a2 * b0 - a0 * b2;
    v[2] = a0 * b1 - a1 * b0;
}

//Kreiranje kocke
void kocka(double a) {
    glPushMatrix();
      glTranslated(-a / 2, -a / 2, -a / 2);
      glBegin(GL_QUADS);
        glNormal3d(0.0, 0.0, -1.0);
        glVertex3d(0.0, 0.0, 0.0);
        glVertex3d(0.0, a, 0.0);
        glVertex3d(a, a, 0.0);
        glVertex3d(a, 0.0, 0.0);

        glNormal3d(0.0, 0.0, 1.0);
        glVertex3d(0.0, 0.0, a);
        glVertex3d(a, 0.0, a);
        glVertex3d(a, a, a);
        glVertex3d(0.0, a, a);
      glEnd();

      glBegin(GL_QUAD_STRIP);
        glNormal3d(0.0, -1.0, 0.0);
        glVertex3d(0.0, 0.0, a);
        glVertex3d(0.0, 0.0, 0.0);
        glVertex3d(a, 0.0, a);
        glVertex3d(a, 0.0, 0.0);

        glNormal3d(1.0, 0.0, 0.0);
        glVertex3d(a, a, a);
        glVertex3d(a, a, 0.0);

        glNormal3d(0.0, 1.0, 0.0);
        glVertex3d(0.0, a, a);
        glVertex3d(0.0, a, 0.0);

        glNormal3d(-1.0, 0.0, 0.0);
        glVertex3d(0.0, 0.0, a);
        glVertex3d(0.0, 0.0, 0.0);
      glEnd();
    glPopMatrix();
}


//Kreiranje stosca - koristi se ugradjena metoda zbog kompliciranog postavljanja
// normala
void stozac(double r, double h, int n) {
    glPushMatrix();
      glRotated(-90.0, 1.0, 0.0, 0.0);
      glutSolidCone(r, h, n, n);
    glPopMatrix();
}

//Kreiranje valjka
void valjak(double r, double h, int n) {
    int i;
    double pomkut = 360.0 / n;

    glBegin(GL_TRIANGLE_FAN);
      glNormal3d(0.0, 1.0, 0.0);
      glVertex3d(0.0, h, 0.0);
      for (i = 0; i <= n; i++) {
        glVertex3d(r * sin(toRad(i * pomkut)), h, r * cos(toRad(i * pomkut)));
      }
    glEnd();

    glBegin(GL_TRIANGLE_FAN);
      glNormal3d(0.0, -1.0, 0.0);
      glVertex3d(0.0, 0.0, 0.0);
      for (i = 0; i <= n; i++) {
        glVertex3d(r * sin(toRad(-i * pomkut)), 0.0, r * cos(toRad(-i * pomkut)));
      }
    glEnd();

    glBegin(GL_QUAD_STRIP);
      for (i = 0; i <= n; i++) {
        double vv[3];
        vv[0] = r * sin(toRad(-i * pomkut));
        vv[1] = 0.0;
        vv[2] = r * cos(toRad(-i * pomkut));

        normiraj(vv);
        glNormal3dv(vv);
        glVertex3d(r * sin(toRad(-i * pomkut)), 0.0, r * cos(toRad(-i * pomkut)));
        glVertex3d(r * sin(toRad(-i * pomkut)), h, r * cos(toRad(-i * pomkut)));
      }
    glEnd();

}

//Kreiranje kugle, odnosno sfere
void kugla(double r, int m, int n, double k) {
    double pomi = 180.0 / n, pomj = 360.0 / m, vvv[3];
    int i, j;
    for (i = 0; i < n; i += 1) {
        glBegin(GL_QUAD_STRIP);
          for (j = 0; j <= m * k; j += 1) {
            if (j > m / 2.0) {
                vvv[0] = r * cos(toRad((i + 1) * pomi)) * sin(toRad(j * pomj));
                vvv[1] = r * cos(toRad(j * pomj));
                vvv[2] = r * sin(toRad((i + 1) * pomi)) * sin(toRad(j * pomj));
                normiraj(vvv);
                glNormal3dv(vvv);
                glVertex3d(r * cos(toRad((i + 1) * pomi)) * sin(toRad(j * pomj)), 
                           r * cos(toRad(j * pomj)), 
                           r * sin(toRad((i + 1) * pomi)) * sin(toRad(j * pomj)));
                vvv[0] = r * cos(toRad(i * pomi)) * sin(toRad(j * pomj));
                vvv[1] = r * cos(toRad(j * pomj));
                vvv[2] = r * sin(toRad(i * pomi)) * sin(toRad(j * pomj));
                normiraj(vvv);
                glNormal3dv(vvv);
                glVertex3d(r * cos(toRad(i * pomi)) * sin(toRad(j * pomj)), 
                           r * cos(toRad(j * pomj)), 
                           r * sin(toRad(i * pomi)) * sin(toRad(j * pomj)));
            }
            else {
                vvv[0] = r * cos(toRad(i * pomi)) * sin(toRad(j * pomj));
                vvv[1] = r * cos(toRad(j * pomj));
                vvv[2] = r * sin(toRad(i * pomi)) * sin(toRad(j * pomj));
                normiraj(vvv);
                glNormal3dv(vvv);
                glVertex3d(r * cos(toRad(i * pomi)) * sin(toRad(j * pomj)), 
                           r * cos(toRad(j * pomj)), 
                           r * sin(toRad(i * pomi)) * sin(toRad(j * pomj)));
                vvv[0] = r * cos(toRad((i + 1) * pomi)) * sin(toRad(j * pomj));
                vvv[1] = r * cos(toRad(j * pomj));
                vvv[2] = r * sin(toRad((i + 1) * pomi)) * sin(toRad(j * pomj));
                normiraj(vvv);
                glNormal3dv(vvv);
                glVertex3d(r * cos(toRad((i + 1) * pomi)) * sin(toRad(j * pomj)), 
                           r * cos(toRad(j * pomj)), 
                           r * sin(toRad((i + 1) * pomi)) * sin(toRad(j * pomj)));
            }
          }
        glEnd();
    }
}

//Kreiranje objekata
void objekt(void) {

    //Podloga
    glPushMatrix();
      glTranslated(0.0, -0.5, 0.0);
      glScaled(1.0, 0.01, 1.0);
      glColor3d(0.2, 0.9, 0.3);
      kocka(100.0);
    glPopMatrix();

    //Slucajni objekti u okolini
    int i;
    for (i = 0; i <= 15; i++) {
        glPushMatrix();
          glTranslated((float) (rx[i] - 10), -0.1, (float) (rz[i]));
          glColor3d((double) (rcr[i] / 10.0), (double) (rcg[i] / 10.0), (double) (rcb[i] / 10.0));
          if (ro[i] == 0) {
            stozac((float) rr[i], (float) rv[i], 24);
          } else {
            valjak((float) rr[i], (float) rv[i], 24);
          }
        glPopMatrix();
    }

    //Covjeculjak
    glPushMatrix();

      //Skaliranje lika
      glScaled(prop, prop, prop);

      //Kretanje
      glTranslated(-ld, 0.0, -nn);
      glRotated(okret, 0.0, 1.0, 0.0);
      
      //Tijelo
      glPushMatrix();
        glTranslated(0.0, 0.3, 0.0);
        glColor3d(0.8, 0.4, 0.3);
        valjak(0.5, 2.0, 40);
      glPopMatrix();

      //kotaci i ruke
      glPushMatrix();

        glTranslated(0.0, 0.6, 0.0);
        glRotated(90.0, 1.0, 0.0, 0.0);

        //ruke
        glPushMatrix();
          glTranslated(0.0, 0.0, -1.4);
          glTranslated(0.0, -1.5, 0.0);
          glColor3d(0.7, 0.6, 0.5);
          valjak(0.05, 3.0, 12);
        glPopMatrix();

        // rotacija oko y osi za kretanje
        glPushMatrix();
          glRotated(-((ld - nn)*180.0) / (0.6 * M_PI), 0.0, 1.0, 0.0);

          //prvi kotac
          glTranslated(0.0, -0.7, 0.0);
          glColor3d(0.3, 0.3, 0.3);
          valjak(0.6, 0.2, 24);

          glPushMatrix();
            glTranslated(0.0, -0.05, 0.0);
            glColor3d(0.3, 0.4, 0.8);
            valjak(0.45, 0.1, 24);
          glPopMatrix();

        glPopMatrix();

        //drugi kotac
        glPushMatrix();
          glRotated(-((ld - nn)*180.0) / (0.6 * M_PI), 0.0, 1.0, 0.0);

          glTranslated(0.0, 0.5, 0.0);
          glColor3d(0.3, 0.3, 0.3);
          valjak(0.6, 0.2, 24);

          glPushMatrix();
            glTranslated(0.0, 0.15, 0.0);
            glColor3d(0.3, 0.4, 0.8);
            valjak(0.45, 0.1, 24);
          glPopMatrix();

        glPopMatrix();

      glPopMatrix();

      //vrat i glava
      glPushMatrix();

        //vrat + duzina
        glTranslated(0.0, 2.25, 0.0);
        glColor3d(0.9, 0.6, 0.4);
        valjak(0.1, 0.6 + duzina, 40);

        //glava + duzina
        glTranslated(0.0, 1.1 + duzina, 0.0);
        glColor3d(0.9, 0.6, 0.1);
        kugla(0.6, 48, 12, 1.0);

        //kapa
        glPushMatrix();
          glTranslated(0.0, 0.45, 0.0);
          glColor3d(0.1, 0.4, 0.6);
          stozac(0.4, 0.6, 40);
        glPopMatrix();

        //nos
        glRotated(-90.0, 0.0, 0.0, 1.0);
        glTranslated(0.0, 0.5, 0.0);
        glColor3d(0.9, 0.5, 0.1);
        stozac(0.2, 0.4, 40);

        //oci
        glTranslated(0.0, -0.2, 0.0);
        glTranslated(-0.3, 0.0, 0.0);
        glColor3d(0.0, 0.5, 0.5);

        glPushMatrix();
          glTranslated(0.0, 0.0, 0.2);
          valjak(0.1, 0.2, 20);
        glPopMatrix();

        glPushMatrix();
          glTranslated(0.0, 0.0, -0.2);
          valjak(0.1, 0.2, 20);
        glPopMatrix();

      glPopMatrix();

    glPopMatrix();
}


//Inicijalizacija
void Init(void) {
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glShadeModel(GL_SMOOTH);
    glClearColor(0.69, 0.93, 0.93, 0.0);
    glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

    glClearDepth(1.0f);
    glDepthFunc(GL_LEQUAL);
    glEnable(GL_DEPTH_TEST);

    glEnable(GL_NORMALIZE);

    glGenTextures(1, &shadowMapTexture);
    glBindTexture(GL_TEXTURE_2D, shadowMapTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, shadowMapSize, shadowMapSize, 0,
                 GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

    glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
    glEnable(GL_COLOR_MATERIAL);

    glMaterialfv(GL_FRONT, GL_SPECULAR, bijelo);
    glMaterialf(GL_FRONT, GL_SHININESS, 20.0f);

    glPushMatrix();

      glLoadIdentity();
      gluPerspective(90.0f, (float) windowWidth / windowHeight, 1.0f, 250.0f);
      glGetFloatv(GL_MODELVIEW_MATRIX, cameraProjectionMatrix);

      glLoadIdentity();
      gluLookAt(cameraPosition[0], cameraPosition[1], cameraPosition[2],
                center[0], center[1], center[2],
                0.0f, 1.0f, 0.0f);
      glGetFloatv(GL_MODELVIEW_MATRIX, cameraViewMatrix);

      glLoadIdentity();
      gluPerspective(90.0f, 1.0f, 1.0f, 250.0f);
      glGetFloatv(GL_MODELVIEW_MATRIX, lightProjectionMatrix);

      glLoadIdentity();
      gluLookAt(lightPosition[0], lightPosition[1], lightPosition[2],
                center[0], center[1], center[2],
                0.0f, 1.0f, 0.0f);
      glGetFloatv(GL_MODELVIEW_MATRIX, lightViewMatrix);

    glPopMatrix();
}

//Iscrtavanje
void Display(void) {
    Init();
    //Prvi prolaz - pogled svjetla
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glMatrixMode(GL_PROJECTION);
    glLoadMatrixf(lightProjectionMatrix);

    glMatrixMode(GL_MODELVIEW);
    glLoadMatrixf(lightViewMatrix);

    glViewport(0, 0, shadowMapSize, shadowMapSize);

    //Odstupanje za rjesavanje akni
    if (cor == 1) {    
        glEnable(GL_POLYGON_OFFSET_FILL);
        glPolygonOffset(1.0f, 1.0f);
    }

    //Selektivno odbacivanje za rjesavanje akni
    if (cul == 1) {
        glEnable(GL_CULL_FACE);
        glCullFace(GL_FRONT);
    }

    //Micanje boja
    glShadeModel(GL_FLAT);
    glColorMask(0, 0, 0, 0);

    //Isrtavanje objekata u pogled svjetla
    objekt();

    glBindTexture(GL_TEXTURE_2D, shadowMapTexture);
    glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, shadowMapSize, shadowMapSize);

    glCullFace(GL_BACK);

    glDisable(GL_POLYGON_OFFSET_FILL);
    glDisable(GL_CULL_FACE);
    glEnable(GL_DEPTH_TEST);

    glShadeModel(GL_SMOOTH);
    glColorMask(1, 1, 1, 1);

    //iscrtavanje s pozicije kamere - tamni pogled
    glClear(GL_DEPTH_BUFFER_BIT);

    glMatrixMode(GL_PROJECTION);
    glLoadMatrixf(cameraProjectionMatrix);

    glMatrixMode(GL_MODELVIEW);
    glLoadMatrixf(cameraViewMatrix);

    glViewport(0, 0, windowWidth, windowHeight);

    glLightfv(GL_LIGHT1, GL_POSITION, lightPosition);
    glLightfv(GL_LIGHT1, GL_AMBIENT, tamno);
    glLightfv(GL_LIGHT1, GL_DIFFUSE, tamno);
    glLightfv(GL_LIGHT1, GL_SPECULAR, crno);
    glEnable(GL_LIGHT1);
    glEnable(GL_LIGHTING);

    objekt();

    glLightfv(GL_LIGHT1, GL_POSITION, lightPosition);
    glLightfv(GL_LIGHT1, GL_DIFFUSE, bijelo);
    glLightfv(GL_LIGHT1, GL_SPECULAR, bijelo);

    //Izracun tekstura za konacnu projekciju
    M3DMatrix44f tempMatrix = {0.5f, 0.0f, 0.0f, 0.0f,
                               0.0f, 0.5f, 0.0f, 0.0f,
                               0.0f, 0.0f, 0.5f, 0.0f,
                               0.5f, 0.5f, 0.5f, 1.0f};

    m3dMatrixMultiply44(textureMatrix, tempMatrix, lightProjectionMatrix);
    m3dMatrixMultiply44(tempMatrix, textureMatrix, lightViewMatrix);
    m3dTransposeMatrix44(textureMatrix, tempMatrix);

    glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
    glTexGenfv(GL_S, GL_EYE_PLANE, &textureMatrix[0]);
    glEnable(GL_TEXTURE_GEN_S);

    glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
    glTexGenfv(GL_T, GL_EYE_PLANE, &textureMatrix[4]);
    glEnable(GL_TEXTURE_GEN_T);

    glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
    glTexGenfv(GL_R, GL_EYE_PLANE, &textureMatrix[8]);
    glEnable(GL_TEXTURE_GEN_R);

    glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
    glTexGenfv(GL_Q, GL_EYE_PLANE, &textureMatrix[12]);
    glEnable(GL_TEXTURE_GEN_Q);

    glBindTexture(GL_TEXTURE_2D, shadowMapTexture);
    glEnable(GL_TEXTURE_2D);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);

    glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_INTENSITY);

    glAlphaFunc(GL_GEQUAL, 0.99f);
    glEnable(GL_ALPHA_TEST);

    //Iscrtavanje s pozicije kamere - svjetli pogled i objekt svjetla
    glMaterialfv(GL_FRONT, GL_EMISSION, bijelo);
    glColor3d(1.0, 1.0, 1.0);
    glPushMatrix();
      glTranslated(lightPosition[0], lightPosition[1], lightPosition[2]);
      glPushMatrix();
        glTranslated(0.4, -0.1, 0.0);
        glRotated(80.0, 0.0, 0.0, 1.0);
        stozac(0.2, 0.5, 24);
      glPopMatrix();
      glMaterialfv(GL_FRONT, GL_EMISSION, crno);
      glTranslated(0.0, -lightPosition[1], 0.0);
      valjak(0.05, lightPosition[1], 40);
    glPopMatrix();

    objekt();

    glutSwapBuffers();
}

//Promjena velicine prozora
void Reshape(int w, int h) {
    windowWidth = w, windowHeight = h;
    glPushMatrix();
      glLoadIdentity();
      gluPerspective(90.0f, (float) windowWidth / windowHeight, 1.0f, 250.0f);
      glGetFloatv(GL_MODELVIEW_MATRIX, cameraProjectionMatrix);
    glPopMatrix();
}

//Postupanje s tipkama
void Keyboard(unsigned char key, int x, int y) {
    if (key == 27) exit(0);
    if (key == 'q') cameraPosition[1] += 0.2;
    if (key == 'Q') cameraPosition[1] -= 0.2;
    if (key == 'w') cameraPosition[0] += 0.2;
    if (key == 'W') cameraPosition[0] -= 0.2;
    if (key == 'e') cameraPosition[2] += 0.2;
    if (key == 'E') cameraPosition[2] -= 0.2;

    if (key == 'r') center[1] += 0.2;
    if (key == 'R') center[1] -= 0.2;
    if (key == 't') center[0] += 0.2;
    if (key == 'T') center[0] -= 0.2;
    if (key == 'z') center[2] += 0.2;
    if (key == 'Z') center[2] -= 0.2;

    if (key == 'a') lightPosition[1] += 0.1;
    if (key == 'A') lightPosition[1] -= 0.1;
    if (key == 's') lightPosition[0] += 0.1;
    if (key == 'S') lightPosition[0] -= 0.1;
    if (key == 'd') lightPosition[2] += 0.1;
    if (key == 'D') lightPosition[2] -= 0.1;

    if (key == 'y') {
        cul = 0;
        printf("Ispravljanje akni - odbacivanje iskljuceno \n");
    }
    if (key == 'Y') {
        cul = 1;
        printf("Ispravljanje akni - odbacivanje ukljuceno \n");
    }
    if (key == 'x') {
        cor = 0;
        printf("Ispravljanje akni - odstupanje iskljuceno \n");
    }
    if (key == 'X') {
        cor = 1;
        printf("Ispravljanje akni - odstupanje ukljuceno \n");
    }

    if (key == 'k') prop -= 0.05;
    if (key == 'K') prop += 0.05;

    if (key == '+') if (duzina < 5) duzina += 0.05;
    if (key == '-') if (duzina > -0.5) duzina -= 0.05;

    if (key == 'L') {
        camx = cameraPosition[0];
        camy = cameraPosition[1];
        camz = cameraPosition[2];
        cameraPosition[0] = lightPosition[0];
        cameraPosition[1] = lightPosition[1];
        cameraPosition[2] = lightPosition[2];
    }
    if (key == 'l') {
        cameraPosition[0] = camx;
        cameraPosition[1] = camy;
        cameraPosition[2] = camz;
    }
}

void Special(int c, int x, int y) {
    // pomak lika
    if (c == GLUT_KEY_UP) {
        nn += 0.2;
        okret = 90.0;
    }
    if (c == GLUT_KEY_DOWN) {
        nn -= 0.2;
        okret = 270.0;
    }
    if (c == GLUT_KEY_LEFT) {
        ld += 0.2;
        okret = 180.0;
    }
    if (c == GLUT_KEY_RIGHT) {
        ld -= 0.2;
        okret = 0.0;
    }
}

void Timer(int id) {
    glutPostRedisplay();
    glutTimerFunc(40, Timer, 0);
}

int main(int argc, char** argv) {
    //Generiranje slucajnih brojeva za objekte
    srand((unsigned) time(0));
    int i;
    for (i = 0; i <= 15; i++) {
        ro[i] = rand() % 2;
        rx[i] = rand() % 35;
        rz[i] = -rand() % 35;
        rr[i] = rand() % 4;
        rv[i] = rand() % 5;
        rcr[i] = rand() % 11 + 1;
        rcg[i] = rand() % 11 + 1;
        rcb[i] = rand() % 11 + 1;
    }
    printf("ISCRTAVANJE SJENA POMOCU SPREMNIKA DUBINE\n");
    printf("AUTORI: Franjo Kovacic, Ivan Vuljak\n");
    printf("_________________________________________\n");
    printf("KONTROLE:\n");
    printf("\ty/Y, x/X   >>>   ispravljanje akni isklj./uklj. odbacivanje, odstupanje\n");
    printf("\tq/Q, w/W, e/E   >>>   x, y, z  koordinate kamere \n");
    printf("\ta/A, s/S, d/D   >>>   x, y, z  koordinate svjetla \n");
    printf("\tr/R, t/T, z/Z   >>>   x, y, z  koordinate centralne tocke pogleda\n");
    printf("\tL/l   >>>   prebacivanje kamere u polozaj svjetla/pocetni polozaj\n");
    printf("\tstrelice   >>>   kretanje lika\n");
    printf("\t+/-   >>>   duzina vrata\n");
    printf("\tk/K   >>>   povecavanje/smanjivanje lika\n");
    printf("\t[Esc]   >>>   izlaz\n");
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowSize(700, 700);
    glutCreateWindow("Sjene");

    glutDisplayFunc(Display);
    glutReshapeFunc(Reshape);
    glutKeyboardFunc(Keyboard);
    glutSpecialFunc(Special);
    glutTimerFunc(50, Timer, 0);
    glutMainLoop();
    return 0;
}
