
{*******************************************************}
{                                                       }
{       Materiał i mgła - Delphi                        }
{       Wykorzystanie komponentu GlBox i OpenGL         }
{                                                       }
{       autor: Waldemara Pokuta - 2003                  }
{                                                       }
{*******************************************************}

unit Unit1;

interface

uses
  Windows, SysUtils, Classes, Forms, Dialogs, GLBox, OpenGl, ExtCtrls,
  Controls, StdCtrls;

type
  TForm1 = class(TForm)
    Timer1: TTimer;
    gl: TGLBox;
    procedure UstawOswietlenie;
    procedure UstalRozmiar;
    procedure glRender(Sender: TObject);
    procedure glSetupRC(Sender: TObject);
    procedure glResize(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  procedure Szescian(rozm: real);
var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure Szescian(rozm: real);
var
  i: integer;
begin
  glPushMatrix;
  for i := 0 to 5 do begin
    glBegin(GL_QUADS);
      glNormal3f(    0,    0,    1);
      glVertex3f(-rozm, rozm, rozm);
      glVertex3f(-rozm,-rozm, rozm);
      glVertex3f( rozm,-rozm, rozm);
      glVertex3f( rozm, rozm, rozm);
    glEnd;
    // Obrót na kolejną ścianę
    if odd(i) then glRotatef(90, 0, 1, 0) else glRotatef(90, 1, 0, 0);
  end;
  glPopMatrix;
end;

procedure TForm1.UstawOswietlenie;
const
  // światło tła
  ambient: TGLArrayf4 = ( 0.3, 0.3, 0.3, 1.0);
  // światło 0
  l0amb  : TGLArrayf4 = ( 0.0, 0.0, 0.0, 1.0);
  l0dif  : TGLArrayf4 = ( 0.4, 0.4, 0.4, 1.0);
  l0spec : TGLArrayf4 = ( 0.4, 0.5, 0.6, 1.0);
  l0pos  : TGLArrayf4 = ( 0.0, 0.0,-100, 1.0);
  // światlo 1
  l1amb  : TGLArrayf4 = ( 0.0, 0.0, 0.0, 1.0);
  l1dif  : TGLArrayf4 = ( 0.2, 0.2, 0.2, 1.0);
  l1spec : TGLArrayf4 = ( 0.5, 0.2, 0.5, 1.0);
  l1pos  : TGLArrayf4 = (-150,-100,-100, 1.0);
  // światlo 2
  l2amb  : TGLArrayf4 = ( 0.0, 0.0, 0.0, 1.0);
  l2dif  : TGLArrayf4 = ( 0.5, 0.5, 0.5, 1.0);
  l2spec : TGLArrayf4 = ( 0.7, 0.4, 0.1, 1.0);
  l2pos  : TGLArrayf4 = ( 100, 150,-100, 1.0);
begin
  // światło tła
  glLightModelfv(GL_LIGHT_MODEL_AMBIENT, @ambient);
  // światlo 0
  glLightfv(GL_LIGHT0,  GL_AMBIENT,  @l0amb);
  glLightfv(GL_LIGHT0,  GL_DIFFUSE,  @l0dif);
  glLightfv(GL_LIGHT0, GL_SPECULAR, @l0spec);
  glLightfv(GL_LIGHT0, GL_POSITION,  @l0pos);
  glEnable (GL_LIGHT0);
  // światlo 1
  glLightfv(GL_LIGHT1,  GL_AMBIENT,  @l1amb);
  glLightfv(GL_LIGHT1,  GL_DIFFUSE,  @l1dif);
  glLightfv(GL_LIGHT1, GL_SPECULAR, @l1spec);
  glLightfv(GL_LIGHT1, GL_POSITION,  @l1pos);
  glEnable (GL_LIGHT1);
  // światlo 2
  glLightfv(GL_LIGHT2,  GL_AMBIENT,  @l2amb);
  glLightfv(GL_LIGHT2,  GL_DIFFUSE,  @l2dif);
  glLightfv(GL_LIGHT2, GL_SPECULAR, @l2spec);
  glLightfv(GL_LIGHT2, GL_POSITION,  @l2pos);
  glEnable (GL_LIGHT2);
end;

procedure TForm1.UstalRozmiar;
var
  w, h: integer;
begin
  // Ustalenie widoku perspektywicznego
  w := gl.Width;
  h := gl.Height;
  if h = 0 then h := 1;
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity;
  gluPerspective(60, w/h, 1, 400);
  glMatrixMode(GL_MODELVIEW);
end;

procedure TForm1.GLRender(Sender: TObject);
var
  i: integer;
const
  kat: real = 0;
  amb_dif1: TGLArrayf4 = (0.8, 0.8, 0.2, 1.0);
  amb_dif2: TGLArrayf4 = (0.2, 0.2, 0.9, 1.0);
  spec1   : TGLArrayf4 = (0.0, 0.0, 0.0, 1.0);
  spec2   : TGLArrayf4 = (0.6, 0.6, 0.6, 1.0);
begin
  glClear (GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  // Załadowanie przekształcenia tożsamościowego
  glLoadIdentity;
  // Oświetlenie
  UstawOswietlenie;
  glTranslatef(0, 0,-150);
  // Rysowanie figur
  glRotatef(-60, 1, 0, 0);
  glRotatef(-kat, 0, 0, 1);
  for i := 0 to 11 do begin
    if i<2 then glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, @amb_dif1)
    else glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, @amb_dif2);
    if i<4 then glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, @spec1)
    else glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, @spec2);
    glPushMatrix;
    glRotatef(i*30, 0, 0, 1);
    glTranslatef(0,-50, 0);
    glRotatef(3*kat+i*30, 0.7, 1, 0.45);
    Szescian(20);
    glPopMatrix;
  end;
  kat := kat+1;
end;

procedure TForm1.glSetupRC(Sender: TObject);
begin
  // Wartości początkowe
  glClearColor(0.0, 0.0, 0.0, 1.0);
  UstalRozmiar;
  glEnable(GL_LIGHTING);
  glEnable(GL_DEPTH_TEST);
end;

procedure TForm1.glResize(Sender: TObject);
begin
  UstalRozmiar;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  // Następna klatka
  gl.Invalidate;
end;

end.
