- {
 - --==## VCL Template ##==--
 - Source by: BlueToby
 - Visit us: http://www.delphigl.com/
 - }
 - unit Unit1;
 - interface
 - uses
 -  Windows, Messages, ExtCtrls, Classes, AppEvnts, Graphics, Controls, Forms, Dialogs,
 -  OpenGL12, Glaux, Glu, Textures, Math, SysUtils;
 - type
 -  TDemoForm = class(TForm)
 -    ApplicationEvents: TApplicationEvents;
 -    FramesTimer: TTimer;
 -    procedure FormCreate(Sender: TObject);
 -    procedure SetPixelFormat;
 -    procedure StartGl;
 -    procedure SetupGL;
 -    procedure FormShow(Sender: TObject);
 -    procedure FormDestroy(Sender: TObject);
 -    procedure FormResize(Sender: TObject);
 -    procedure ApplicationEventsIdle(Sender: TObject; var Done: Boolean);
 -    procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,
 -      Y: Integer);
 -    procedure FramesTimerTimer(Sender: TObject);
 -  private
 -    { Private-Deklarationen }
 -  public
 -    { Public-Deklarationen }
 -  end;
 - const
 -  WinCaption = 'VCL Template '; // Der Titel unseres Fensters
 -  NearClipping = 1; // Sollte immer >= 1 sein
 -  FarClipping = 256; // Ab diesem Entfernung, werden deine Objekte nicht mehr dargestellt
 - var
 -  DemoForm: TDemoForm;
 -  IsOpenGLInit: Boolean;  // Fürs Init von OpenGL
 -  RenderContext: HGLRC;   // OpenGL Rendering Context
 -  Frames, Frame: Integer; // Frames fürs durchzählen, Fame zum Speichern
 -  rx, ry, rz: integer;    // Rotationsvariablen
 -  taste: char;            // tastendruck
 - implementation
 - {$R *.DFM}
 - // Zeichenprozedur
 - procedure TDemoForm.ApplicationEventsIdle(Sender: TObject;
 -  var Done: Boolean);
 -  var x:integer;
 -      outrot:integer;
 -      texture1: PTAUX_RGBImageRec;
 -      tex: TGLuint;
 - begin
 -  if not IsOpenGLInit then
 -   exit;                        // Falls OpenGL noch nicht initialisiert ist, erstmal garnix tun
 -  Done := false;                // Wichtig, damit immer was getan wird
 -  inc(Frames, 1);               // Frames zählen
 -  glClearColor(0, 0, 0, 0.5);   // Löschen der Farbe
 -  glClear(GL_DEPTH_BUFFER_BIT or GL_COLOR_BUFFER_BIT); // Leeren des Speichers
 - BEGIN;
 -  texture1 := auxDIBImageLoadA('./texture/wall.bmp');
 -    glGenTextures(1, @tex);
 -    glBindTexture(GL_TEXTURE_2D, tex);
 -    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_Linear);
 -    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_Linear);
 -    glTexImage2D(GL_TEXTURE_2D, 0, 3,
 -                        texture1^.sizeX, texture1^.sizeY, 0,
 -                        GL_RGB, GL_UNSIGNED_BYTE, texture1^.data);
 -        IF NOT Assigned( texture1 ) THEN
 -        BEGIN;
 -         MessageBox(0,'Texturenpfad oder Dateiname falsch!',
 -                        'Fehler beim Laden der Textur!',MB_OK or MB_ICONERROR);
 -            Halt;
 - END;
 - glloadidentity;
 - gltranslatef(0,0,-20);
 - glBindTexture(GL_TEXTURE_2D, tex);
 -  x:=x+1;
 -  outrot:=outrot+2;
 - glPushMatrix;
 -     glTranslatef(0,sin(x/50),0);
 -     glRotatef(x,0,1,0);
 -     glMatrixMode(GL_TEXTURE);
 -     glloadidentity;
 -     glColor3f(1,1,1);
 -     glTranslatef(0,-(x/100),0);
 -     glMatrixMode(GL_MODELVIEW);
 -    glBegin(GL_TRIANGLES);
 -     glVertex3f(-1,-1,1);
 -     glVertex3f(0,1,0);
 -     glVertex3f(1,-1,1);
 -     glEnd();
 -     glBegin(GL_TRIANGLES);
 -     glTexCoord2f(0,0);glVertex3f(1,-1,1);
 -     glTexCoord2f(0.5,1);glVertex3f(0,1,0);
 -     glTexCoord2f(1,0);glVertex3f(1,-1,-1);
 -     glEnd();
 -     glBegin(GL_TRIANGLES);
 -     glTexCoord2f(0,0);glVertex3f(1,-1,-1);
 -     glTexCoord2f(0.5,1);glVertex3f(0,1,0);
 -     glTexCoord2f(1,0);glVertex3f(-1,-1,-1);
 -     glEnd();
 -     glBegin(GL_TRIANGLES);
 -     glTexCoord2f(0,0);glVertex3f(-1,-1,-1);
 -     glTexCoord2f(0.5,1);glVertex3f(0,1,0);
 -     glTexCoord2f(1,0);glVertex3f(-1,-1,1);
 -     glEnd();
 -     glbegin(GL_QUADS);
 -      glvertex3f(-1,-1,1);
 -      glvertex3f(1,-1,1);
 -      glvertex3f(1,-1,-1);
 -      glvertex3f(-1,-1,-1);
 -     glend();
 - glPopMatrix;
 - glEnable(GL_BLEND);
 - glBlendFunc(GL_SRC_ALPHA,GL_ONE);
 - glDisable(GL_DEPTH_TEST);
 - glPushMatrix;
 -    glRotatef(x,0,1,0);
 -    glScalef(2,2,2);
 -    IF Sin(x/50)<0.9 THEN glColor4f(1,1,1,0.4)
 -    ELSE glColor4f(1,0.3,0.3,0.5);
 -    glBegin(GL_TRIANGLES);
 -     glTexCoord2f(0,0);glVertex3f(-1,-1,1);
 -     glTexCoord2f(0.5,1);glVertex3f(0,1,0);
 -     glTexCoord2f(1,0);glVertex3f(1,-1,1);
 -     glEnd();
 -     glBegin(GL_TRIANGLES);
 -     glTexCoord2f(0,0);glVertex3f(1,-1,1);
 -     glTexCoord2f(0.5,1);glVertex3f(0,1,0);
 -     glTexCoord2f(1,0);glVertex3f(1,-1,-1);
 -     glEnd();
 -     glBegin(GL_TRIANGLES);
 -     glTexCoord2f(0,0);glVertex3f(1,-1,-1);
 -     glTexCoord2f(0.5,1);glVertex3f(0,1,0);
 -     glTexCoord2f(1,0);glVertex3f(-1,-1,-1);
 -     glEnd();
 -     glBegin(GL_TRIANGLES);
 -     glTexCoord2f(0,0);glVertex3f(-1,-1,-1);
 -     glTexCoord2f(0.5,1);glVertex3f(0,1,0);
 -     glTexCoord2f(1,0);glVertex3f(-1,-1,1);
 -     glEnd();
 -     glbegin(GL_QUADS);
 -      glvertex3f(-1,-1,1);
 -      glvertex3f(1,-1,1);
 -      glvertex3f(1,-1,-1);
 -      glvertex3f(-1,-1,-1);
 -     glend();
 - glPopMatrix;
 -    // Blaue äußere Pyramide
 -    glPushMatrix;
 -         glColor4f(0.3,0.3,0.8,0.8);
 -         glRotatef(outrot,0,1,0);
 -         glTranslatef(5,0,0);
 -         glRotatef(outRot,-0.5,1,0);
 -                 glBegin(GL_TRIANGLES);
 -     glVertex3f(-1,-1,1);
 -     glVertex3f(0,1,0);
 -     glVertex3f(1,-1,1);
 -     glEnd();
 -     glBegin(GL_TRIANGLES);
 -     glTexCoord2f(0,0);glVertex3f(1,-1,1);
 -     glTexCoord2f(0.5,1);glVertex3f(0,1,0);
 -     glTexCoord2f(1,0);glVertex3f(1,-1,-1);
 -     glEnd();
 -     glBegin(GL_TRIANGLES);
 -     glTexCoord2f(0,0);glVertex3f(1,-1,-1);
 -     glTexCoord2f(0.5,1);glVertex3f(0,1,0);
 -     glTexCoord2f(1,0);glVertex3f(-1,-1,-1);
 -     glEnd();
 -     glBegin(GL_TRIANGLES);
 -     glTexCoord2f(0,0);glVertex3f(-1,-1,-1);
 -     glTexCoord2f(0.5,1);glVertex3f(0,1,0);
 -     glTexCoord2f(1,0);glVertex3f(-1,-1,1);
 -     glEnd();
 -     glbegin(GL_QUADS);
 -      glvertex3f(-1,-1,1);
 -      glvertex3f(1,-1,1);
 -      glvertex3f(1,-1,-1);
 -      glvertex3f(-1,-1,-1);
 -     glend();
 -    glPopMatrix;
 -    // Grüne äußere Pyramide
 -    glPushMatrix;
 -         glColor4f(0.3,0.8,0.3,0.8);
 -         glRotatef(outrot,0,1,0);
 -         glTranslatef(-5,0,0);
 -         glRotatef(OutRot,0.5,1,0);
 -     glBegin(GL_TRIANGLES);
 -     glTexCoord2f(0,0);glVertex3f(-1,-1,1);
 -     glTexCoord2f(0.5,1);glVertex3f(0,1,0);
 -     glTexCoord2f(1,0);glVertex3f(1,-1,1);
 -     glEnd();
 -     glBegin(GL_TRIANGLES);
 -     glTexCoord2f(0,0);glVertex3f(1,-1,1);
 -     glTexCoord2f(0.5,1);glVertex3f(0,1,0);
 -     glTexCoord2f(1,0);glVertex3f(1,-1,-1);
 -     glEnd();
 -     glBegin(GL_TRIANGLES);
 -     glTexCoord2f(0,0);glVertex3f(1,-1,-1);
 -     glTexCoord2f(0.5,1);glVertex3f(0,1,0);
 -     glTexCoord2f(1,0);glVertex3f(-1,-1,-1);
 -     glEnd();
 -     glBegin(GL_TRIANGLES);
 -     glTexCoord2f(0,0);glVertex3f(-1,-1,-1);
 -     glTexCoord2f(0.5,1);glVertex3f(0,1,0);
 -     glTexCoord2f(1,0);glVertex3f(-1,-1,1);
 -     glEnd();
 -     glbegin(GL_QUADS);
 -      glvertex3f(-1,-1,1);
 -      glvertex3f(1,-1,1);
 -      glvertex3f(1,-1,-1);
 -      glvertex3f(-1,-1,-1);
 -     glend();
 -    glPopMatrix;
 -  x:=x+1;
 -  outrot:=outrot+2;
 -  SwapBuffers(Canvas.Handle); // Und anzeigen
 - end;
 - end;
 - procedure glBindTexture(Target: TGLenum; Texture: TGLuint);
 - external opengl32; // Funktion für Texturen
 - procedure TDemoForm.FormCreate(Sender: TObject);
 - begin
 - if not InitOpenGL then    // Wichtig für OpenGL >= 1.2
 -  Halt(100);
 - IsOpenGLInit := false;    // OpenGL ist noch nicht initialisiert
 - end;
 - procedure TDemoForm.SetPixelFormat;
 - var
 -  PixelFormat: TGLuint; // Das PixelFormat
 -  PFD: PIXELFORMATDESCRIPTOR; // Die "Beschreibung" dazu
 - begin
 - with PFD do // Für die "Beschreibung" verändern wir:
 - begin
 -  nSize := SizeOf(PIXELFORMATDESCRIPTOR); // Die Größe ist die eines PIXELFORMATDESCRIPTORS
 -  nVersion := 1;                         // Version ist 1
 -  dwFlags := PFD_DRAW_TO_WINDOW          // Einige wichtige Einstellungen
 -   or PFD_SUPPORT_OPENGL
 -   or PFD_DOUBLEBUFFER;
 -  iPixelType := PFD_TYPE_RGBA; // Pixeltyp
 -  cColorBits := 32;   // Farbtiefe
 -  cRedBits := 0;      // Einige Einstellungen zu den Farben. Bei 0 belassen
 -  cRedShift := 0;
 -  cGreenBits := 0;
 -  cBlueBits := 0;
 -  cBlueShift := 0;
 -  cAlphaBits := 0;    // Das gleiche mit der Transparenz
 -  cAlphaShift := 0;
 -  cAccumBits := 0;       // Nochmal mit dem AccumBuffer
 -  cAccumRedBits := 0;
 -  cAccumGreenBits := 0;
 -  cAccumBlueBits := 0;
 -  cAccumAlphaBits := 0;
 -  cDepthBits := 16;       // Z-Buffer Tiefe, 16bit ist GraKa Standard
 -  cStencilBits := 0;      // Stencil Bits, bei 0 belassen
 -  cAuxBuffers := 0;       // Anzahl der AuxBuffers, auch 0 lassen
 -  iLayerType := PFD_MAIN_PLANE;  // Layertyp, so lassen, wie es ist
 -  bReserved := 0;               // Einfach 0 lassen
 -  dwLayerMask := 0;            // Verschiedene Masken, auch bei 0 lassen
 -  dwVisibleMask := 0;
 -  dwDamageMask := 0
 - end;
 - PixelFormat := ChoosePixelFormat(Canvas.Handle, @pfd); // Das Pixelformat übergeben
 - if PixelFormat = 0 then // Bei Fehler Fehlermeldungen ausgeben
 -  Application.MessageBox('Kein passendes PixelFormat gefunden!', 'Fehler', MB_ICONERROR or MB_OK);
 - if not Windows.SetPixelFormat(Canvas.Handle,PixelFormat,@pfd) then
 -  Application.MessageBox('Pixelformat kann nicht gesetzt werden!', 'Fehler', MB_ICONERROR or MB_OK);
 - end;
 - procedure TDemoForm.StartGl;
 - begin
 - RenderContext := wglCreateContext(Canvas.Handle); // Den RenderContext erstellen
 - if RenderContext = 0 then // Wenn er doch nicht erstellt wurde, Fehlermeldungen
 - begin
 -  Application.MessageBox('RenderContext kann nicht erstellt werden!', 'Fehler', MB_ICONERROR or MB_OK);
 -  Halt(100);
 - end;
 - if not wglMakeCurrent(Canvas.Handle, RenderContext) then
 - begin
 -  Application.MessageBox('RenderContext kann nicht aktiviert werden!', 'Fehler', MB_ICONERROR or MB_OK);
 -  Halt(100);
 - end;
 - end;
 - procedure TDemoForm.SetupGL;
 - begin
 - glEnable(GL_DEPTH_TEST);  // Den Z-Buffer-Test aktivieren (3D)
 - glDepthFunc(GL_LESS);     // Typ des Z-Buffers festlegen    
 - glEnable(GL_TEXTURE_2D);  // Texturen aktivieren
 - glShadeModel(GL_SMOOTH)   // Die Modelle weich zeichnen
 - end;
 - procedure TDemoForm.FormShow(Sender: TObject);
 - begin
 -  RenderContext := 0; // RenderContext erst mal auf Null setzten
 -  SetPixelFormat; // Das Format setzen
 -  StartGL;        // OpenGL starten
 -  ClearExtensions; // OpenGL Extensions löschen ...
 -  ReadExtensions;  // Und auslesen
 -  SetupGL;         // Letzte Einstellungen
 -  IsOpenGLInit := true; // Initalisierung komplett
 - end;
 - procedure TDemoForm.FormDestroy(Sender: TObject);
 - begin
 - IsOpenGLInit := False; // OpenGL ist nicht mehr initialisiert
 - if RenderContext <> 0 then // Wenn der RenderContext gesetzt werden konnte
 - begin  // Jetzt versuchen wir, ihn zu löschen
 -  if not wglMakeCurrent(Canvas.Handle, 0) then
 -   Application.MessageBox('Fehler beim Leeren der Contexts!','Fehler', MB_ICONERROR or MB_OK);
 -  if not wglDeleteContext(RenderContext) then
 -   Application.MessageBox('Fehler beim Leeren des RenderContexts!','Fehler', MB_ICONERROR or MB_OK);
 -  end;
 -  RenderContext := 0; // Und jetzt noch leeren
 - end;
 - procedure TDemoForm.FormResize(Sender: TObject);
 - begin
 - glViewport(0, 0, ClientWidth, ClientHeight); // Blickfeld für das Fenster einstellen
 - glMatrixMode(GL_PROJECTION);                 // In Projektionsmodus wechseln
 - glLoadIdentity;                              // Nullpunkt laden                      
 - gluPerspective(45, ClientWidth/ClientHeight, NearClipping, FarClipping);
 -  // Berechnung der Relation zwischen Breite und Höhe
 - glMatrixMode(GL_MODELVIEW); // Zurück zum ModelviewMatrixMode
 - glLoadIdentity;             // Und den Nullpunkt wieder laden
 - end;
 - procedure TDemoForm.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
 -  Y: Integer);
 - begin
 - // Wenn der Cursor im Fenster ist ...
 - if (X > DemoForm.Left) and (Y > DemoForm.Top) and (X < DemoForm.Left + DemoForm.Width) and (Y < DemoForm.Top + DemoForm.Height) then
 -  ShowCursor(true) // Zeige ihn nicht
 - else
 -  ShowCursor(True); // Ist er nicht im Fenster, zeige ihn
 - end;
 - procedure TDemoForm.FramesTimerTimer(Sender: TObject);
 - begin
 - Frame := Frames; // Speichern der aktuellen Anzahl Renderdurchläufen
 - Frames := 0; // Wieder auf 0 setzten
 - DemoForm.Caption := WinCaption + '[' + IntToStr(Frame) + ' fps]'; // Und ausgeben
 - end;
 - end.
 

