Da Delphis eigene Version von OpenGL.pas Version 1.0 ist und derzeit tatsächlich mindestens Version 1.1 verwendet wird und die reine Softwaresimulationsmethode von Windows ebenfalls Version 1.1 ist, müssen Sie einige notwendige Funktionen selbst importieren. Einige kostenlose Open-Source-Einheiten sind ebenfalls verfügbar, beispielsweise OpenGL12.pas von Mike Lischke. Wenn Sie es selbst schreiben, kann das Design natürlich prägnanter werden, und Sie müssen keine Fehler in einem riesigen Code finden, der zu fortgeschritten und vollständig ist.
Stellen Sie zunächst die erforderlichen Einheiten Windows, Nachrichten und OpenGL vor
Um einige notwendige Erweiterungen hinzuzufügen.
const
//GL_EXT_bgra
GL_BGR_EXT = $80E0;
GL_BGRA_EXT = $80E1;
// Polygon-Offset
GL_POLYGON_OFFSET_UNITS = $2A00;
GL_POLYGON_OFFSET_POINT = $2A01;
GL_POLYGON_OFFSET_LINE = $2A02;
GL_POLYGON_OFFSET_FILL = $8037;
GL_POLYGON_OFFSET_FACTOR = $8038;
PROcedure glBindTexture(target: GLEnum; texture: GLuint);
procedure glDeleteTextures(n: GLsizei; Textures: PGLuint);
procedure glGenTextures(n: GLsizei; Textures: PGLuint);
function glIsTexture(texture: GLuint): GLboolean;
procedure glPolygonOffset(Faktor, Einheiten: GLfloat);
// Diese Anweisung wird verwendet, um einen Fehler in OpenGL.pas zu beheben
function gluBuild2DMipmaps(target: GLEnum; Components, width, height: GLint; format, atype: GLint; Data: Pointer): GLint external opengl32;
Nun wurde die Schnittstelle grundsätzlich auf Version 1.1 aktualisiert. Wenn weitere Erweiterungen benötigt werden, können diese auf ähnliche Weise hinzugefügt werden.
Als nächstes müssen Sie den OpenGL-Zeichnungskontext RC erstellen, für den Sie den Gerätekontext-DC des GDI-Fensters benötigen. Die TForm.Handle-Eigenschaft oder andere Handle-Eigenschaften von TWinControl sind DC. Mit der folgenden Funktion können Sie RC aus DC erstellen. Der Rückgabewert ist das Handle von RC. Anschließend können Sie mit OpenGL zeichnen. Kann im Allgemeinen innerhalb des OnCreate-Ereignisses des Formulars verwendet werden. Die Optionen dieser Funktion bedeuten Tiefenpuffer, Vorlagenpuffer, Akkumulationspuffer und die Erzeugung eines Alpha-Kanalwerts.
Typ
TRCOptions = set of (roDepth, roStencil, roAccum, roAlpha);
function CreateRC(dc: HDC; opt: TRCOptions): HGLRC;
var
PFDescriptor: TPixelFormatDescriptor;
PixelFormat: Integer;
beginnen
FillChar(PFDescriptor, SizeOf(PFDescriptor), 0);
mit PFDescriptor tun
beginnen
nSize := SizeOf(PFDescriptor);
nVersion := 1;
dwFlags := PFD_SUPPORT_OPENGL oder PFD_DRAW_TO_WINDOW oder PFD_DOUBLEBUFFER;
iPixelType := PFD_TYPE_RGBA;
cColorBits := GetDeviceCaps(DC, BITSPIXEL) * GetDeviceCaps(DC, PLANES);
wenn roDepth in opt then cDepthBits := 24;
wenn roStencil in opt then cStencilBits := 8;
wenn roAccum in opt then cAccumBits := 64;
iLayerType := PFD_MAIN_PLANE;
Ende;
PixelFormat := ChoosePixelFormat(DC, @PFDescriptor);
Assert(PixelFormat <> 0);
Assert(SetPixelFormat(DC, PixelFormat, @PFDescriptor));
Ergebnis := wglCreateContext(DC);
Assert(Ergebnis <> 0);
wglMakeCurrent(dc, Ergebnis);
Ende;
Zeichnen Sie das OnPaint-Ereignis des Formulars ein. Denken Sie daran, dass nach Abschluss der Zeichnung SwapBuffers (dc: HDC) verwendet werden muss, um den Zeichnungspuffer und den Anzeigepuffer auszutauschen, damit das Bild angezeigt wird. Denken Sie auch daran, glViewport(0, 0, ClientWidth, ClientHeight); im OnResize-Ereignis des Formulars aufzurufen, damit RC und DC synchronisiert werden können.
Zerstöre RC im OnDestroy-Ereignis des Formulars.
Prozedur DestroyRC(rc: HGLRC);
beginnen
wenn rc = 0 dann Exit;
wglMakeCurrent(0, 0);
wglDeleteContext(rc);
Ende;
Zu diesem Zeitpunkt hat der Rahmen eines OpenGL-Programms ungefähr Gestalt angenommen. Aber es gibt immer noch Probleme, die gelöst werden müssen.
Verhindern Sie zunächst, dass Windows den Hintergrund löscht und die Geschwindigkeit beeinträchtigt. Fügen Sie dem Formular Mitgliedsfunktionen hinzu
Privat
procedure WMEraseBkgnd(var Message: TWmEraseBkgnd); message WM_ERASEBKGND;
procedure TGLWindow.WMEraseBkgnd(var Message: TWmEraseBkgnd);
beginnen
Message.Result := 1;
Ende;
Zweitens, um sicherer zu sein. Fügen Sie die folgenden Mitgliedsfunktionen hinzu.
geschützt
procedure CreateParams(var Params: TCreateParams); override;
procedure TGLWindow.CreateParams(var Params: TCreateParams);
beginnen
geerbt;
mit Params tun
beginnen
Stil := Stil oder WS_CLIPCHILDREN oder WS_CLIPSIBLINGS;
WindowClass.Style := CS_VREDRAW oder CS_HREDRAW oder CS_OWNDC;
Ende;
Ende;
Okay, jetzt können Sie diese lästigen Dinge vergessen und Ihre wundervolle 3D-Anzeige schreiben :)
Ich muss ein paar Worte sagen: Erstellen Sie nicht mehrere RCs in einem Thread, da dies die Leistung ernsthaft beeinträchtigt. Einige persönliche Demonstrationen von OpenGL-Fenstersteuerungen fügen mehrere Steuerelemente in ein Formular ein, was eigentlich keine gute Idee ist. Mehrere Ansichten sollten mit einem OpenGL-Fenster angezeigt werden. Greifen Sie außerdem nicht threadübergreifend auf OpenGL-Funktionen zu.
Wenn Windows den Grafikkartentreiber automatisch installiert, wird die OpenGL-Hardwarebeschleunigung nicht installiert. Sie müssen den Treiber des Grafikkartenherstellers selbst installieren!
Darüber hinaus steht eine kostenlose Vollbild-Anzeigefunktion zur Verfügung:)
Funktion FullScreen(win: TWinControl; Breite, Höhe, Bittiefe: Ganzzahl): boolean;
var displaymode: DEVMODE;
beginnen
FillChar(displaymode, sizeof(displaymode), 0);
mit displaymode tun
beginnen
dmSize := sizeof(displaymode);
dmPelsWidth:= width;
dmPelsHeight := height;
dmBitsPerPel := Bittiefe;
dmFields := DM_BITSPERPEL oder DM_PELSWIDTH oder DM_PELSHEIGHT;
Ende;
wenn ChangeDisplaySettings(displaymode, CDS_FULLSCREEN) = DISP_CHANGE_SUCCESSFUL
dann fang an
ShowWindow(win.Handle, WS_MAXIMIZE);
Ergebnis := wahr;
Ende
sonst Ergebnis := false;
Ende;
Prozedur RestoreDisplay(win: TWinControl);
beginnen
ChangeDisplaySettings(PDEVMODE(0)^, 0);
ShowWindow(win.Handle, SW_RESTORE);
Ende;