- {
- --==## 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.