{*******************************************************}
{                                                       }
{       Napisy w OpenGL - Delphi                        }
{       Wykorzystanie komponentu GlBox i OpenGL         }
{                                                       }
{       autor: Waldemara Pokuta - 2003                  }
{                                                       }
{*******************************************************}

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, OpenGL, Dialogs,
  GLBox, ExtCtrls;

type
  TForm1 = class(TForm)
    GL: TGLBox;
    Timer1: TTimer;
    procedure UstalRozmiar;
    procedure GLRender(Sender: TObject);
    procedure GLResize(Sender: TObject);
    procedure GLSetupRC(Sender: TObject);
    procedure UstawOswietlenie;
    procedure Timer1Timer(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  Czcionki, Czcionki2, Czcionki3, Czcionki4: Integer;
  procedure Tekst(t: pchar; baza: Integer);

implementation

{$R *.DFM}
procedure Tekst(t: pchar; baza:integer);
begin
  glPushMatrix;
  glPushAttrib(GL_LIST_BIT);
  glListBase(Baza);
  glCallLists(length(t), GL_UNSIGNED_BYTE, t);
  glPopAttrib;
  glPopMatrix;
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;

procedure TForm1.UstalRozmiar;
var
  w, h: integer;
begin
  // Ustalenie widoku perspektywicznego
  w := gl.Width;
  h := gl.Height;
  glViewport(0, 0, w, h);
  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);
const
  t: real = 0;
var
  x, y: real;
begin
  glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  glLoadIdentity;   // Przekształcenie tożsamościowe
  // Ustawienie kamery
  gluLookAt(0, 0, 200, 0, 0, 0, 0, 1, 0);
  // Rysowanie sceny
  glScalef(50, 50, 50);
  UstawOswietlenie;
  // FontBitmaps
  x := sin(t/17);
  y := sin(t/21);
  glColor3f(1, 0, 0);
  glRasterPos2f(x-0.2, y);
  Tekst('To są czcionki bitmapowe', Czcionki);
  glColor3f(0, 0, 1);
  glRasterPos2f(y, -x);
  Tekst(Pchar(TimeToStr(Now)), Czcionki2);
  glTranslatef(-2, 0, 0);
  // FontOutlines
  glRotatef(t, 1, 1, 1);
  Tekst('To kontury', Czcionki3);
  glRotatef(-90, 1, 1, 1);
  Tekst('To czcionka 3D', Czcionki4);
  // Inkrementacja parametru t
  t:=t+1;
end;

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

procedure TForm1.GLSetupRC(Sender: TObject);
const
  amb_dif: TGLArrayf4 = (1.0, 1.0, 1.0, 1);
  spec   : TGLArrayf4 = (1.0, 1.0, 1.0, 1);
  emis   : TGLArrayf4 = (0.1, 0.1, 0.1, 1);
begin
  // 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);
  // Wartości początkowe
  glClearColor(0, 0, 0, 1);
  UstalRozmiar;
  glEnable(GL_LIGHTING);
  glEnable(GL_DEPTH_TEST);
  glEnable(GL_NORMALIZE);
  glEnable(GL_COLOR_MATERIAL);
  // Budowanie list czcionek bitmapowych
  Czcionki      := glGenLists(256);
  GL.BuildBitmapFont(0, 256, Czcionki);
  GL.Font.Size  := -20;
  GL.Font.Name  := 'Courier New';
  GL.Font.Style := [fsItalic, fsBold];
  Czcionki2     := glGenLists(256);
  GL.BuildBitmapFont(0, 256, Czcionki2);
  // Budowanie czcionek 3D
  GL.Font.Name  := 'Times New Roman';
  GL.Font.Style := [fsBold];
  Czcionki3     := glGenLists(256);
  GL.BuildFont(0, 256, Czcionki3, 0, 0, WGL_FONT_LINES, nil);
  Czcionki4     := glGenLists(256);
  GL.BuildFont(0, 256, Czcionki4, 0, 0.2, WGL_FONT_POLYGONS, nil);
  // Włączenie zegara
  Timer1.Enabled := true;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  gl.Invalidate;
end;

end.
