program grafika;

{

  budeme pouzivat knihovny OpenGL a GLUT,
  ta prvni obsahuje rozhrani pro vykreslovani
  3d grafiky pomoc graficke karty, ta druha
  za nas udela vytvoreni noveho okna a dalsi
  nudne okenkove zalezitosti

  nezapomente rict kompilatoru, kde ma tyto
  knihovny hledat, na Windows jsou standardne
  v adresari:
  C:\Program Files\FPC\units\i386-win32\opengl
  je tedy nutne tento adresar pridat do seznamu
  adresaru pouzitych pri hledani knihoven;
  ten nastavite v menu Options > Directories
  (jde o prvni zalozku)

}

uses GL, GLUT;

{

  nejake globalni promenne

}

var
  alpha : real;

{

  init je procedura zavolana na zacatku behu
  programu, muzeme v ni provest nejake vlastni
  inicializace

}

procedure init;
begin
  { nejake OpenGL zalezitosti }
  glShadeModel(GL_SMOOTH); // chceme hladke stinovani
  glClearColor(0.0, 0.0, 0.0, 0.5); // cerne pozadi
  glClearDepth(1.0);
  glEnable(GL_DEPTH_TEST); // nechame na OpenGL testovani viditelnosti
  glDepthFunc(GL_LEQUAL);
  glEnable(GL_COLOR_MATERIAL);
  glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

  { a ted veci specificke pro nasi aplikaci }
  alpha := 0;
end;

{

  funkce idle je zavolana pokazde, kdyz program
  zdrovna nema co na praci; my zatim proste
  oznamime, ze by bylo vhodne prekreslit obrazovku

}

procedure idle; cdecl;
begin
  alpha := alpha + 1.2;
  glutPostRedisplay();
end;


{

  reshape je zavolana po kazde zmene velikosti
  okna aplikace; neni moc zajimava, jen provede
  par rutinnich operaci, aby bylo vykreslovani
  provadeno porad pres celou obrazovku

}

procedure reshape(width, height : LongInt); cdecl;
var
  aspect : real;
begin
  aspect := width / height;
  glViewport(0, 0, width, height);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity;
  glFrustum(-aspect, aspect, 1.0, -1.0, 1.0, 20.0);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity;
  glutReshapeWindow(width, height);
end;

{

  draw je naopak dulezita funkce; je zavolana
  pokazde, kdyz ma dojit k prekresleni obsahu
  naseho okna

}
procedure draw; cdecl;
begin
  { vymazeme obrazovku, nastavime pozici kamery atd. }
  glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  glLoadIdentity();
  glPushMatrix();
  glTranslatef(0.0, 0.0, -3.6); { posuneme svetem o 3.6 metru dopredu }
  glRotatef(alpha, 0.0, 1.0, 0.0); { orotujeme svetem o alpha stupnu kolem osy y }

  { no a ted hlavni cast: rekneme, co chceme vykreslit }
  glBegin(GL_TRIANGLES);
  glColor3f(1.0,0.0,0.0);
  glVertex3f(0.0, 1.0, 0.0);
  glColor3f(0.0,1.0,0.0);
  glVertex3f(-1.0,-1.0, 1.0);
  glColor3f(0.0,0.0,1.0);
  glVertex3f( 1.0,-1.0, 1.0);
  glColor3f(1.0,0.0,0.0);
  glVertex3f( 0.0, 1.0, 0.0);
  glColor3f(0.0,0.0,1.0);
  glVertex3f( 1.0,-1.0, 1.0);
  glColor3f(0.0,1.0,0.0);
  glVertex3f( 1.0,-1.0, -1.0);
  glColor3f(1.0,0.0,0.0);
  glVertex3f( 0.0, 1.0, 0.0);
  glColor3f(0.0,1.0,0.0);
  glVertex3f( 1.0,-1.0, -1.0);
  glColor3f(0.0,0.0,1.0);
  glVertex3f(-1.0,-1.0, -1.0);
  glColor3f(1.0,0.0,0.0);
  glVertex3f( 0.0, 1.0, 0.0);
  glColor3f(0.0,0.0,1.0);
  glVertex3f(-1.0,-1.0,-1.0);
  glColor3f(0.0,1.0,0.0);
  glVertex3f(-1.0,-1.0, 1.0);
  glEnd();
  glBegin(GL_POLYGON);
    glColor3f(1, 1, 0);
    glVertex3f(1, 1, 0);
    glColor3f(1, 1, 0);
    glVertex3f(-1, 1, 0);
    glColor3f(1, 1, 0);
    glVertex3f(-1, -1, 0);
    glColor3f(1, 1, 1);
    glVertex3f(1, -1, 0);
  glEnd;

  { obraz zobrazime v okne }
  glutSwapBuffers();
end;

{

  hlavni telo programu

}
begin
  // inicializace okna a OpenGL
  glutInit(@argc, argv);
  glutInitDisplayMode(GLUT_DEPTH or GLUT_DOUBLE or GLUT_RGBA);
  glutInitWindowSize(800, 800);
  glutCreateWindow('OpenGL programek');
  glutDisplayFunc(@draw);
  glutReshapeFunc(@reshape);
  glutIdleFunc(@idle);
  init;

  // spustime hlavni smycku aplikace
  glutMainLoop;
end.

