- unit lesson2_1_vcl_main;
- {******************************************************************************}
- { }
- { OpenGl Tutorial 2 - VCL }
- { }
- { Copyright (C) 2002 Delphi OpenGl Community }
- { 11/03/2002: ported from API to VCL by Delphic }
- { All Rights Reserved. }
- { }
- { Obtained through: }
- { Delphi OpenGL Community(DGL) }
- { }
- { You may retrieve the latest version of this file at the Delphi OpenGL }
- { Community home page, located at http://dgl.quellcodes.de/ }
- { }
- { The contents of this file are used with permission, subject to }
- { the Mozilla Public License Version 1.1 (the "License"); you may }
- { not use this file except in compliance with the License. You may }
- { obtain a copy of the License at }
- { http://www.mozilla.org/MPL/MPL-1.1.html }
- { }
- { Software distributed under the License is distributed on an }
- { "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or }
- { implied. See the License for the specific language governing }
- { rights and limitations under the License. }
- { }
- {******************************************************************************}
- interface
- uses
- Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
- dglopengl, Geometry, StdCtrls, ExtCtrls;
- const
- //Entfernung der Clipping planes
- FarClipping = 100.0;
- NearClipping = 1.0;
- AppTitle = 'http://dgl.quellcodes.de/ - OpenGL Tutorial 2';
- type
- TMainForm = class(TForm)
- procedure FormCreate(Sender: TObject);
- procedure FormShow(Sender: TObject);
- procedure FormDestroy(Sender: TObject);
- procedure FormResize(Sender: TObject);
- procedure ApplicationEventsIdle(Sender: TObject; var Done: Boolean);
- private
- { Private-Deklarationen }
- OpenGLInitialized : Boolean; //Ist true, wenn OpenGL bereit zum zeichnen ist
- RC : HGLRC; //OpenGL Rendering Context
- //Daten, für den Framecounter
- StartTick : Cardinal;
- Frames : LongInt;
- public
- { Public-Deklarationen }
- end;
- var
- MainForm: TMainForm;
- implementation
- {$R *.DFM}
- procedure TMainForm.FormCreate(Sender: TObject);
- begin
- //OpenGL ist noch nicht bereit
- OpenGLInitialized := False;
- //Nur starten, wenn die Bibliotheken auch geladen sind
- if not LoadOpenGL then
- Halt(100)
- end; (*FormCreate*)
- procedure TMainForm.FormShow(Sender: TObject);
- procedure SetPixelFormat;
- var
- PixelFormat : TGLuint;
- PFD : pixelformatdescriptor;
- begin
- with pfd do
- begin
- nSize:= SizeOf( PIXELFORMATDESCRIPTOR );
- nVersion:= 1;
- dwFlags:= PFD_DRAW_TO_WINDOW
- or PFD_SUPPORT_OPENGL
- or PFD_DOUBLEBUFFER;
- iPixelType:= PFD_TYPE_RGBA;
- cColorBits:= 16; //Farbtiefe
- cRedBits:= 0;
- cRedShift:= 0;
- cGreenBits:= 0;
- cBlueBits:= 0;
- cBlueShift:= 0;
- cAlphaBits:= 0;
- cAlphaShift:= 0;
- cAccumBits:= 0; //Accumulation Buffer
- cAccumRedBits:= 0;
- cAccumGreenBits:= 0;
- cAccumBlueBits:= 0;
- cAccumAlphaBits:= 0;
- cDepthBits:= 16; //Z-Buffer Tiefe
- cStencilBits:= 0; //Stencil Buffer
- cAuxBuffers:= 0;
- iLayerType:= PFD_MAIN_PLANE;
- bReserved:= 0;
- dwLayerMask:= 0;
- dwVisibleMask:= 0;
- dwDamageMask:= 0
- end;
- //Pixel Format setzten
- PixelFormat := ChoosePixelFormat(Canvas.Handle, @pfd);
- if (PixelFormat=0) then
- MessageDlg('Es konnte kein passendes PixelFormat gefunden werden.', mtError, [mbOk], 0);
- if (not Windows.SetPixelFormat(Canvas.Handle,PixelFormat,@pfd)) then
- MessageDlg('PixelFormat konnte nicht gesetzt werden.', mtError, [mbOk], 0)
- end; (*SetPixelFormat*)
- procedure StartGl;
- begin
- //Rendering Context initialisieren
- RC := wglCreateContext(Canvas.Handle);
- if (RC=0) then
- begin
- MessageDlg('Rendering Context kann nicht erstellt werden.', mtError, [mbOk], 0);
- Halt(100)
- end;
- if (not wglMakeCurrent(Canvas.Handle, RC)) then
- begin
- MessageDlg('Rendering Context kann nicht aktiviert werden.', mtError, [mbOk], 0);
- Halt(100)
- end
- end; (*StartGl*)
- procedure SetupGL;
- begin
- glShadeModel(GL_SMOOTH); // Aktiviert weiches Shading
- glClearColor(0.0, 0.0, 0.0, 0.5); // Bildschirm löschen (schwarz)
- glClearDepth(1.0); // Depth Buffer Setup
- glEnable(GL_DEPTH_TEST); // Aktiviert Depth Testing
- glDepthFunc(GL_LEQUAL); // Bestimmt den Typ des Depth Testing
- glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
- // Qualitativ bessere Koordinaten Interpolation
- end; (*SetupGL*)
- begin
- RC := 0;
- SetPixelFormat;
- StartGL;
- //GL Extensions neu auslesen
- ClearExtensions;
- ReadExtensions;
- SetupGL;
- //Kleinkram initialisieren
- Frames := 0;
- StartTick := GetTickCount;
- //OnIdle setzen
- Application.OnIdle := ApplicationEventsIdle;
- //OpenGL ist nun bereit
- OpenGLInitialized := True
- end; (*FormShow*)
- procedure TMainForm.FormDestroy(Sender: TObject);
- begin
- OpenGLInitialized := False;
- if RC<>0 then
- begin
- if (not wglMakeCurrent(Canvas.Handle,0)) then
- MessageDlg('Rendering Context konnte nicht abgewählt werden.', mtError, [mbOk], 0);
- if (not wglDeleteContext(RC)) then
- MessageDlg('Rendering Context konnte nicht freigegeben werden.', mtError, [mbOk], 0)
- end;
- RC:=0
- end; (*Form Destroy*)
- procedure TMainForm.FormResize(Sender: TObject);
- begin
- glViewport(0, 0, ClientWidth, ClientHeight);
- //Projektionsmatrix resetten
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- //Perspektivische Darstellung
- gluPerspective(45.0,ClientWidth/ClientHeight,NearClipping,FarClipping);// Calculate The Aspect Ratio Of The Window
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity
- end; (*FormResize*)
- procedure TMainForm.ApplicationEventsIdle(Sender: TObject;
- var Done: Boolean);
- var
- Error : LongInt; //Fehler?
- begin
- //Abbrechen, wenn OpenGL noch nicht initialisiert ist
- if not OpenGLInitialized then Exit;
- //Immer schön neu zeichnen
- Done := False;
- glClearColor(0,0,0,0);
- glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
- glLoadIdentity;
- glTranslatef( -1.5, 0, -6);
- {TIP: Entferne die beiden oberen glColor3f. Das Dreieck wird dann "blau" gezeichnet
- werden! Wenn Sie beim starten ganz schnell gucken, wirst du feststellen, dass das
- Dreieck kurz weiß zu flackern scheint. Der Grund dafür ist, dass beim ersten Durchgang
- die beiden ersten Eckpunkte weiß gezeichnet werden und erst beim nächsten Durchgang
- blau gefärbt werden. Um dies zu vermeiden müßte man bereits vor dem Zeichnen dieser
- beiden Eckpunkte die Farbe auf blau setzen!}
- glBegin(GL_TRIANGLES);
- glColor3f(1,0,0); // alle weiteren Vertice werden rot gezeichnet
- glVertex3f(-1.0,-1.0, 0.0);
- glColor3f(0,1,0); // alle weiteren Verticen werden grün gezeichnet
- glVertex3f( 0.0, 1.0, 0.0);
- glColor3f(0,0,1); // alle weiteren Verticen werden blau gezeichnet
- glVertex3f( 1.0,-1.0, 0.0);
- glEnd();
- //Error Handler
- Error := glgetError;
- if Error <> GL_NO_ERROR then
- begin
- Caption := gluErrorString(Error);
- //Rendering kurz anhalten
- Done := True;
- FlashWindow(Handle, True)
- end;
- //Frame Counter
- Inc(Frames);
- if GetTickCount - StartTick >=500 then
- begin
- Caption := Format('%s [%f FPS]', [AppTitle, Frames/(GetTickCount - StartTick)*1000]);
- Frames := 0;
- StartTick := GetTickCount
- end;
- //Und anzeigen
- SwapBuffers(Canvas.Handle)
- end; (*ApplicationEventsIdle*)
- end.