Hi Leute!
Ich weiß, dieses ist normalerweise ein Delphi-Forum, aber da ja in dem OpenGl-Tutorial-thread schon ein paar mal die Frage nach Kylix aufkam und nun entlich eine Lösung gefunden wurde, OpenGl unter Kylix zum laufen zu bekommen (Big THX @ DelphiC von der DGL), poste ich hier mal mein OpenGl-Kylix-Init-Tut.
Es ist im übrigen vollkommen identisch mit der Version auf meiner Homepage (
www.dcw-group.net), so dass ihr euch über einige Äußerungen bezüglich anderer Kursteile nicht wundern braucht.
Nun also los:
Wie Initialisiert man OpenGl in Kylix
Einleitung
Hi Leute!
So, nachdem der Kurs nun schon ganze 13 Teile stark ist, kommt nun endlich ein Kursteil, mit
dem sicherlich kaum einer Gerechnet hat: Teil 2b: Initialisieren von Open Gl unter Kylix!
Es war ein wirklich langer weg hier her, denn das Umsetzen von Teilen des Kurses nach
Kylix war schon vor einer halben Ewigkeit geplant, konnte aber leider nicht umgesetzt
werden, weil trotzt Crossplatform – Libary (opengl12.pas) die Initialisierung immer wieder
fehlschlug. Nun aber endlich ist es gelungen Open Gl unter Kylix zum laufen zu bekommen
und das nicht nur mit der OpenGl12.pas, sondern auch mit der neusten Ausgabe der
Opengl1.5-Unit der DGL (dglopengl.pas). Ein großer Dank geht denn nochmals von mir hier
aus an DelphiC aus dem DGL-Team, der dieses Möglich gemacht hat. Von ihm stammen
auch viele Teile vom Quelltext aus diesem Kursteil.
Bevor wir anfangen möchte ich noch ein paar Voraussetzungen für das Entwickeln von Open
Gl – Anwendungen unter Linux hier aufführen:
Das wohl wichtigste ist zunächst mal eine funktionierende 3D – Unterstützung, d.h. ein
geeigneter Treiber für die Grafikkarte. NVidia macht es hier den meisten Leuten mit ihrem
Installer ziemlich einfach: RPM installieren und los geht’s (meistens).
Bei ATI ist die Sache noch recht kompliziert (aber nicht unmöglich), evtl. auch, weil ATI
momentan an sich nur Treiber für FireGl-Karten rausgibt, die aber auch mit allen anderen
Radeon-Karten der 8xxx und 9xxx – Reihe laufen.
Weiterhin wichtig ist natürlich noch Kylix. Absolut ausreichend für unsere zwecke ist auf
jeden Fall mal Kylix 3 Open Edition ... zumindest für unsere Demos reicht das vollkommen.
Man kann es kostenlos auf der Borland – HP runterladen.
Ich selbst habe das ganze hier auf einem Athlon XP 2600+, einer Radeon 9600 Pro und unter
Fedora Core 1 (Kernel 2.4.x, XFree 4.3.X, KDE 3) entwickelt.
Los geht’s!
So, genug geschwafelt, ran ans Werk!
Das erste was wir in unserer frisch erzeugten Kylixanwendung machen müssen (solltet ihr
keine lehre vor euch finden, denn erzeugt eine!) ist, ein Panel auf das Form zu ziehen. Dieses
müssen wir leider machen, weil unter Kylix man aus irgendeinem mir nicht erdenklichen
Grunde nicht direkt aufs Form, sondern nur auf Panels rendern kann. Nur damit Klarheit
besteht: ich nenne dieses Panel immer „render_panel“ .... nur damit ihr wisst, was abgeht.
So, nachdem das Panel da ist, brauchen wir erstmal noch einen Timer. Dieser soll für uns den
Taktgeber spielen (Timer auf „1“ setzen). Zunächst hatte ich noch gehofft, evtl. das Onidle-
Event verwenden zu können, dies ging aber nicht, da es unter Linux offensichtlich anders
gehandhabt wird als unter Windows und damit selbst bei Standszene die Framerates stark
schwanke. So, damit haben wir die CLX-Arbeiten (also den visuellen Teil) abgeschlossen.
Nun müssen wir erstmal unsere Open Gl-Unit und die nötige Hilfsunit, welche die GLXFunktionen
kapselt einbinden. (GLX ist etwas das, was für die Windowsler WGL ist ... also
eine Hilfe, Open Gl auf den Schirm zu bringen):
Delphi-Quelltext
1:
| uses .... , dglGLX, dglOpenGl; |
Als nächstes brauchen wir nun ein paar Variablen, welche wie unter Windows als private
Eigenschaft der Form deklariert werden und alle Eigenschaften bezüglich dem Render-
Context des Forms beinhalten:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| private OpenGlInitialized : Boolean; dpy : PDisplay; cx : ^integer; vi : PXVisualInfo; glwin : XID; public end; ... |
Nun kann es richtig losgehen!
Nun kommt nämlich das Grauen der Windows-Benutzer dran: die OnCreate-Funktion! Diese
bearbeiten wir nun also:
Delphi-Quelltext
1: 2: 3: 4:
| procedure TForm1.FormCreate(Sender: TObject); begin OpenGlInitialized := false; end; |
Nanu? Was soll das denn werden? Ist das alles?
Na ja: unter Kylix läuft halt alles ein wenig anders. Irgendwie scheint es Kylix nicht so gut zu
bekommen, wenn man direkt im OnCreate initialisiert. Deshalb verschieben wir dieses auf die
OnShow-Prozedur:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44:
| procedure TForm1.FormShow(Sender: TObject); var Screen : Integer; Attributes : TAttributes; begin if not OpenGlInitialized then begin try InitOpengl; ReadExtensions; ReadImplementationProperties;
dpy := XOpenDisplay(#0); Screen := XDefaultScreen(dpy); Attributes:= GetAttributes(); vi := glXChooseVisual(dpy, Screen, @attributes[0]); cx := glXCreateContext(dpy, vi, nil, true); glwin := QWidget_winId(render_panel.Handle); if not glXMakeCurrent(dpy, glwin, cx) then begin WriteLn('OpenGl Initialisierung schlug fehl!'); Exit; end;
glShadeModel(GL_SMOOTH); glClearColor(0.3, 0.4, 0.6, 1.0); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); FormResize(nil); glLoadIdentity; Caption := Caption + ' @ ' + glGetString(GL_RENDERER); OpenGlInitialized := true; except WriteLn('OpenGl Initialisierung schlug fehl!') end end; end; |
So, das war eigentlich schon der größte Teil dieses ganzen Tuts. Nachdem wir das geschafft
haben müssen wir an sich nur noch ein paar Kleinigkeiten erledigen.
So muss natürlich noch die altbekannte OnDestroy-Prozedur her, welche ja den OpenGl-
Kontext wieder schließt:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| procedure TForm1.FormDestroy(Sender: TObject); begin if dpy <> nil then begin glXMakeCurrent(dpy,0,0); if cx <> nil then glXDestroyContext(dpy,cx); XCloseDisplay(dpy); end; end; |
Und was natürlich auch noch fehlt ist die Onresize-Prozedur (kennt man ja alles aus Teil
2(a)):
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| procedure TForm1.FormResize(Sender: TObject); var Width, Height : Integer; begin Width := render_panel.Width; Height := render_panel.Height; glViewport(0, 0, Width, Height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0, Width/Height, 1, 100.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); end; |
Nun sind es nur noch zwei kleine Schritte zu vollständigen OpenGl-Initalisierung unter Kylix.
Zunächst muss nämlich noch das Timer-Event eingefügt werden, da wir sonst ja keinen
Taktgeber für die Render-Prozedur haben:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7:
| procedure TForm1.Timer1Timer(Sender: TObject); begin if OpenGlInitialized then begin render; end; end; |
Und zu guter letzt muss noch die Render-Prozedur selbst her (man sollte sie im Quelltext über
das Timer-Event schreiben, da ansonsten der Timer evtl. die Render-Prozedur nicht finden
kann:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7:
| procedure render; begin glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); glLoadIdentity;
glXSwapBuffers(form1.dpy, form1.glwin); end; |
Hier kommt nun die erste (und letzte kleine Überaschung). Leider funktioniert der alte
Swapbuffers-Befehl nämlich unter Linux nicht, was aber nicht Tragisch ist, das die GLXFunktionen
einen passenden Ersatz parat haben.
So, damit ist unsere Initialisierung unter Kylix auch schon fertig und wir können fröhlich auch
unter Linux in die Welt von OGL einsteigen.
Nachwort
So, und schon ist es vollbracht!
Ich hoffe es hat euch allen soviel Spaß gemacht wie mir und wird euch soviel Spaß wie mir
machen, endlich auch unter Linux mit OGl runspielen zu können. Zumindest solltet ihr mit
diesem Kursteil die nötigen Voraussetzungen haben, auch wenn ich zugeben muss, dass ich
mich hier sehr kurz gehalten habe (dieser Kursteil ist in 4 Tagen und das während der
Facharbeits-Zeit entstanden ... mehr Zeit war leider nicht...).
Ein kleines Versprechen habe ich noch: Demnächst gibt es für Teil 5 noch ein kleines
Anhängsel, welches meine selbst geschriebene Texturen-Unit näher erklärt. Bis dahin könnt
ihr euch ja aber schon mal die Demo zu Teil 5 ansehen... normalerweise sollte es echt nicht
schwer sein zu erfassen, wie man unter Linux mit dieser Unit Texturen lädt, besonders weil
ich mir viel Mühe gemacht habe die Bedienung einfach zu gestalten.
Also hoffe ich, dass ihr noch viel Spaß mit OpenGL unter Linux habenwerdet und das ihr
auch nächstes Mal wieder reinschaut.
Eurer
Mr_T