{*******************************************************}
{                                                       }
{       Macierze przekształceń - Delphi                 }
{       Wykorzystanie komponentu GlBox i OpenGL         }
{                                                       }
{       autor: Waldemara Pokuta - 2003                  }
{                                                       }
{*******************************************************}

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  GLBox, OpenGL, ExtCtrls, StdCtrls, Buttons, ComCtrls, Grids;

type
  TForm1 = class(TForm)
    Timer1: TTimer;
    Panel1: TPanel;
    GL1: TGLBox;
    Button1: TButton;
    GL2: TGLBox;
    Panel2: TPanel;
    StringGrid1: TStringGrid;
    StringGrid2: TStringGrid;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    StringGrid3: TStringGrid;
    ScrollBar1: TScrollBar;
    ScrollBar2: TScrollBar;
    ScrollBar3: TScrollBar;
    ScrollBar4: TScrollBar;
    ScrollBar5: TScrollBar;
    ScrollBar6: TScrollBar;
    GL3: TGLBox;
    ScrollBar7: TScrollBar;
    ScrollBar8: TScrollBar;
    ScrollBar9: TScrollBar;
    StringGrid4: TStringGrid;
    Label4: TLabel;
    StringGrid5: TStringGrid;
    GL4: TGLBox;
    procedure UstawOswietlenie;
    procedure UstalRozmiar(Sender: TObject);
    procedure GLSetupRC(Sender: TObject);
    procedure GLResize(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  kw: gluQuadricObj;
  procedure figury;
implementation

{$R *.DFM}

procedure TForm1.UstalRozmiar(Sender: TObject);
var
  w, h: integer;
begin
  // Ustalenie widoku perspektywicznego
  w := (Sender as TGLBox).Width;
  h := (Sender as TGLBox).Height;
  if h = 0 then h := 1;
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity;
  gluPerspective(80, w/h, 1, 600);
  glMatrixMode(GL_MODELVIEW);
end;

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

procedure TForm1.GLSetupRC(Sender: TObject);
const
  amb_dif: TGLArrayf4 = (0.8, 0.8, 0.8, 0.2);
  spec   : TGLArrayf4 = (0.5, 0.5, 0.5, 0.2);
  emis   : TGLArrayf4 = (0.0, 0.0, 0.0, 0.2);
begin
  // Wartości początkowe
  glClearColor(0, 0, 0, 1);
  UstalRozmiar(Sender);
  glEnable(GL_LIGHTING);
  glEnable(GL_DEPTH_TEST);
  glEnable(GL_COLOR_MATERIAL);
  glEnable(GL_NORMALIZE);
  // Materiał figur
  glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, @amb_dif);
  glMaterialfv(GL_FRONT_AND_BACK,            GL_SPECULAR,    @spec);
  glMaterialf (GL_FRONT_AND_BACK,           GL_SHININESS,       80);
  glMaterialfv(GL_FRONT_AND_BACK,            GL_EMISSION,    @emis);
  // Kwadryki
  kw := gluNewQuadric;
  gluQuadricDrawStyle(kw, GLU_FILL);
  gluQuadricNormals(kw, GLU_SMOOTH);
  gluQuadricOrientation(kw, GLU_OUTSIDE);
  Timer1.Enabled := TRUE;
end;

procedure figury;
var
  i: integer;
begin
  // powierzchnia
  glColor3f(0.0, 0.5, 0.0);
  glBegin(GL_TRIANGLES);
    glNormal3f(0, 0, 1);
    for i := 0 to 2 do
      glVertex3f(sin(i*2*pi/3)*100,     0, cos(i*2*pi/3)*100);
  glEnd;
  // kula
  glColor3f(1, 0, 0);
  glTranslatef(30, 20, -20);
  gluSphere(kw, 20, 50, 50);
  // walec
  glColor3f(0, 0, 1);
  glTranslatef(-60, -20, 0);
  glRotatef(-90, 1, 0, 0);
  gluCylinder(kw, 20, 20, 40, 50, 50);
  // stożek
  glColor3f(1, 1, 0);
  glTranslatef(30, -60, 0);
  gluCylinder(kw, 20, 0, 40, 50, 50);
end;

procedure TForm1.UstawOswietlenie;
const
  ambient: TGLArrayf4 = ( 0.3, 0.3, 0.3, 1.0);
  swiatla: array[0..3] of record
    dif, spec, pos: TGLArrayf4
  end =
  ((dif:( 0.9, 0.9, 0.1, 1.0); spec:( 0.9, 0.9, 0.1, 1.0); pos:(-200,-100,   0, 1.0)),
   (dif:( 0.1, 0.9, 0.9, 1.0); spec:( 0.1, 0.9, 0.9, 1.0); pos:(-100, 200,   0, 1.0)),
   (dif:( 0.9, 0.1, 0.9, 1.0); spec:( 0.9, 0.1, 0.9, 1.0); pos:( 200,   0,-200, 1.0)),
   (dif:( 0.5, 0.5, 0.9, 1.0); spec:( 0.5, 0.5, 0.9, 1.0); pos:(   0, 100, 200, 1.0)));
var i:integer;
begin
  glLightModelfv(GL_LIGHT_MODEL_AMBIENT, @ambient);
  for i := 0 to 3 do begin
    glLightfv(GL_LIGHT0+i, GL_DIFFUSE , @swiatla[i].dif );
    glLightfv(GL_LIGHT0+i, GL_SPECULAR, @swiatla[i].spec);
    glLightfv(GL_LIGHT0+i, GL_POSITION, @swiatla[i].pos );
    glEnable (GL_LIGHT0+i);
  end;
end;

var
  ds: char;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  gluDeleteQuadric(kw);
end;

initialization
  ds := DecimalSeparator;
  DecimalSeparator := '.';
finalization
  DecimalSeparator := ds;
end.
