FAQ

Aus DGL Wiki
Wechseln zu: Navigation, Suche

FAQ (Frequently asked Questions)

Hier wird auf einige, sehr häufige Fragen eingegangen. Ein solches FAQ soll vor allem verhindern, dass häufig angefragte Themen im Forum wieder und wieder angefragt werden. Ein Großteil dieses FAQs stammt aus unserem alten Foren-FAQ.


Hinweis

Dies ist kein Wiki-FAQ! Fragen bzgl. des Wikis oder dessen Benutzung werden hier also nicht beantwortet.


OpenGL

Fragen und Antworten im Bezug auf häufig angesprochene OpenGL-Themen/Problematiken :

OpenGL-Header (Unit)

F : Wo gibt es den aktuellsten OpenGL-Header für Delphi?
A : Das DGL-Interne OpenGL2-Portteam kümmert sich um die aktuellsten OpenGL-Header (momentan bis v1.5), welche hier zu beziehen sind. In diesem Forenthread gibt es immer die neuste Version, so wie Informationen zu Änderungen/Neuerungen.


F : Warum heisst euer Header inzwischen dglOpenGL.pas statt wie früher OpenGl15.pas?
A : Das liegt daran, dass wir uns auch weiterhin um die zur Verfügungstellung der aktuellsten GL-Funktionalität für Delphinutzer kümmern wollen. Und da es ja nach OpenGL 1.5 weitergeht, hätten wir mit jeder neuen GL-Version einen neuen, anders benannten, Header rausbringen müssen. Dadurch würde die Umstellung unnötig komplizierter, weshalb wir uns dazu entschieden haben den Header umzubenennen, so dass man bei einer Aktualisierung nichts am Programm ändern muss.


F : In manchen Anwendungen/Tutorials die euren Header benutzen, steht manchmal ein GLint statt eines TGLint, oder umgekehrt. Welche Schreibvariante ist korrekt?
A : Das spielt keine Rolle. In unserem Header sind GLint und TGLint beide vom gleichen Datentyp. In älteren Headern (z.B. Mike Lischkes OpenGL12.pas) begannen alle OpenGL-Typen mit einem T, was zwar den Programmierstandards für Object Pascal entspricht, aber nicht denen für OpenGL. Deshalb haben wir in unserem Header beide Varianten, also GL-Standard und OP-Standard (mit T als Präfix) untergebracht.


F : Ich habe früher den mit Delphi gelieferten OpenGL-Header (OpenGL.pas) benutzt, und bin auf euren Header umgestiegen. Die Programme lassen sich dann zwar ohne Änderungen kompilieren, aber beim Start erhalte ich eine Zugriffsverletzung an Adresse 0.
A : Um unseren Header flexibler zu machen, haben wir in Sachen Initialisierung etwas geändert. Vor dem Aufruf (am besten direkt nach Programmstart) des ersten GL-Befehles, muss erstmal InitOpenGL() aufgerufen werden, so dass die OpenGL-Funktionszeiger zugewiesen werden. Desweiteren sollte darauf geachtet werden, dass vor dem Aufruf eines glBefehls der Context aktiviert wird. Danach kann ganz normal weitergearbeitet werden. Diese Änderung wurde deshalb getätigt, weil wir mit unserem Header auch das dynamische Laden anderer OpenGL-Implementationen (z.B. MESA) ermöglichen wollten.


Diverse

F : Wie arbeiten Delphi und OpenGL eigentlich zusammen?
A : OpenGL ist eine API. Um sie zu benutzen muss auf dem Computer ein OpenGL fähiger Grafikkartentreiber oder zumindest ein Softwareemulator installiert sein (dies ist heutzutage immer der Fall). Um Befehle von Delphi aus an die OpenGL API zu senden benötigt ihr den Oben angesprochenen Header, die DGLOpenGL.pas. Diesen Header bindet ihr, wie jede Unit auch, über eure uses Klausel in eurem Programm ein und plötzlich spricht Delphi auch OpenGL.


F : Wie bekomme ich den Gerätekontext (der zum Erstellen eines Renderkontextes nötig ist) eines Windowsobjektes?
A : Generell kann man den Gerätekontext eines Windowsobjektes anhand der Funktion GetDC, mit dem Handle des Objektes als Argument ermitteln. Bei VCL-Objekten geht dies meist noch bequemer, nämlich (falls dieses Objekt eine solche Eigenschaft besitzt) über die Eigenschaft Objekt.Canvas.Handle. Hinweise : Wenn man den Gerätekontext mittels GetDC ermittelt hat, sollte man diesen bei Programmende wieder mit ReleaseDC freigeben. Ausserdem gibt es einige Objekte (z.B. TPaintBox) auf die nicht gerendert werden kann.


F : Wie kann ich bereits erzeugte Texturen wieder freigeben?
A : Möchte man Texturen während der Laufzeit aus dem Texturenspeicher entfernen, so ist dies über den Befehl glDeleteTextures möglich. Man beachte allerdings, dass dies beim Beenden eines Programmes nicht nötig ist, denn sobald ein Renderkontext zerstört wird, werden auch alle zugehörigen Objekte (Texturen, Displayliste, Shader, etc.) gelöscht.


F : Warum verschwinden meine Objekte, sobald ich sie auch nur ein wenig nach hinten oder vorne verschiebe, aus meiner 3D-Szene?
A : Wahrscheinlich ist die nahe- oder ferne Schnittfläche falsch eingestellt. Diese lassen sich über die letzten beiden Parameter (zNear und zFar) der beiden Funktionen glOrtho und gluPerspective setzen, die beide eine Projektionsmatrix erstellen. Fällt nun eines der Objekte hinter die ferne bzw. vor die nahe Schnittfläche, wird es entweder abgeschnitten oder verschwindet komplett. Sollte dies der Fall sein, muss man obige Parameter entsprechend anpassen. Hinweis : zNear muss immer größer 0 sein, im Normalfall versucht man die nahe Schnittfläche allerdings so weit wie möglich hinauszuschieben, um die Auflösung des Tiefenpuffers besser nutzen zu können.


F : Warum seh ich meine Szene nicht?
A : Es gibt verschiedene Fehler die daran schuld sein könnten.
  1. Die Kamera befindet sich zu nah/im Objekt. -> Vorm zeichnen der Objekte Szene per glTranslate nach hinten verschieben.
  2. Die Flächen wurden bei aktivierten Backfaceculling verkehrt herum definiert. -> Deaktivieren des Backfacecullings. Wenn Objekte sichtbar, Eckpunkte in anderer Reihenfolge übergeben.
  3. Die Farbe ist gleich der Hintergrundfarbe und Beleuchtung ist aus. -> Ändern der Farbe mittels glColor.


F :Wie kann ich die ALT- und F10-Taste abfangen, da diese meien GL-Anwendung pausieren?
A : Ein Blick in die MS-SDK verrät uns, dass die Tasten ALT und F10 (wie bereits bekannt) für die Aktivierung des Menüs stehen. Windows sendet also bei Betätigung der Taste(n) eine System-Nachricht, in welcher per Parameter definiert ist, dass es um einen Menu-Key handelt.
Nachricht: WM_SYSCOMMAND, Parameter: SC_KEYMENU.
Nun habe es die Progger, welche ein API-Fenster verwenden, leicht. Denn hier wird einfach die Nachricht abgefangen. Aber wie läuft das mit der VCL? Ich bin ja nicht in der Message-Loop drinnen, also was soll ich tun? Ganz einfach! Delphi bietet eine Möglichkeit an, Prozeduren in die Message-Loop einzubinden. Die Prozedur muss dann folgendermaßen innerhalb der Form definiert sein:
procedure [Name](var TheMsg: [Typ Abhängig von der Nachricht]); message [gewünschte Nachricht]
Damit wird die [gewünschte Nachricht] angegebene Message an das Fenster weitergeleitet, in welcher die Prozedur definiert wurde. Nähere infos gibt's in der Delphi-Hilfe.
In unserem Fall bedeutet dass (zuerst die Funktion deklarieren)
procedure WMSysCommand(var SysCmd: TWMSysCommand); message WM_SYSCOMMAND;
Ein weiterer Blick in die SDK verrät uns, dass Windows als Result 0 erwartet, wenn die System-Nachricht von der Anwenung verarbeitet wurde. Also müssen wird folgender maßen unsere Funktion implementieren:
      procedure TMainForm.WMSysCommand(var SysCmd: TWMSysCommand);
         begin
         if SysCmd.CmdType = SC_KEYMENU then
          SysCmd.Result := 0
         else
          inherited;
         end;
Es ist dabei sehr wichtig, zu überprüften, ob es sich wirklich um SC_KEYMENU handelt. Denn WM_SYSCOMMAND wird auch bei sämtlichen Fenster-Nachrichten aufgerufen. Wenn wir also einfach alle Nachrichten als verarbeitet definieren, kann das Fenster nicht mehr verschoben, in der Größe verändert oder gar geschlossen werden. Deswegen SysCmd.Result NUR DANN auf 0 setzen wenn es sich wirklich um die SC_KEYMENU Nachricht handelt. Ansonsten den Vorgänger aufrufen (per inherited) und somit die Nachricht and die VCL weiterleiten.


DGL

Fragen und Antworten im Bezug auf unsere Delphi-OpenGL-Community :

F : Ich möchte ein Tutorial für die DGL schreiben, was muss ich tun?
A : Tutorials von "externen" Leuten nehmen wir natürlich gerne (und haben wir auch schon getan), allerdings solltet ihr einige Sachen beachten, bevor ihr euch dran macht ein Tutorial für uns zu schreiben :
    1. Setze dich zuerst mit einem unserer [Teammitglieder] in Verbindung, und frag an ob ein Tutorial zum von dir gewählten Thema überhaupt nützlich/interessant ist.
    2. Sollte dies der Fall sein, dann schreibe dein Tutorial, und sende es an das Teammitglied dem du es vorgeschlagen hast. Da wir unsere Tutorials in Zukunft im XML-Format veröffentlichen werden, schickt es uns bitte nicht als formatiertes HTML-Dokument zu, sondern entweder als einfachen TXT (nicht so toll), oder gleich als Open-Office-Dokument (MS-Office geht auch, nutzen im Team allerdings eher wenige Leute). Wenn du ein Beispielprogramm hast, dann schicke es uns bitte mit komplettem Quellcode (mit ALLEN Units die gebraucht werden), sowie vorkompiliert zu. Der Quellcode sollte nach Borland-Standards geschrieben und formatiert sein, und auch ausführlich kommentiert.
    3. Wenn sich das Teammitglied die Sache angesehen hat, wird das Tutorial in einem eigens dafür eingerichtetem, internem Forum hochgeladen. Dort hat der Rest des Teams dann ein bis zwei Wochen Zeit es sich auch anzuschauen.
    4. Danach gibts dann vom Team her bescheid. Entweder ne Bestätigung dass es hochgeladen wird, oder Verbesserungsvorschläge. Bei letzterem springe wieder zu dem Punkt eins drüber.
    5. Wenn das Tutorial gut und vom Team abgesegnet ist, wird es von einem Teammitglied ins passende Format gebracht und veröffentlicht.
    6. Dann gibts natürlich auch Bescheid (per Mail), und nen Newseintrag.

Mathematik

F : Wie berechne ich Schnittpunkte zwischen [...]?
A : Auf unserer Seite findet ihr unter Links -> General -> CompGeo ein Script von Herrn Dr. Pester (TU Chemnitz) als PDF welches sich mit der Mathematik die 3D APIs zu Grunde liegt beschäftigt.In diesem Script findet ihr verständlich erklärt, wie alle Schnittpunktberechnungen funktionieren. (Als Nachschlagewerk sehr zu empfehlen)