In meinem letzten Artikel ging es um die
3Dfx-Karte und welche Performance-Gewinne sie bringt
bei Verwendung der Programmbibliothek Mesa. Ich habe dort kurz �ber die Vor- und
Nachteile der Kombination von Mesa und 3Dfx
geschrieben. Diesmal will ich etwas detaillierter
�ber diese Nachteile berichten und Tips zu ihrer
Umgehung geben
Miguels Artikel
erkl�rt, wie man mit Hilfe der GLUT-Library in
Teilfenster des Hauptwindows zeichnen kann. F�r
jedes Subwindow wird ein neuer, vom Hauptfenster
separater Kontext erzeugt. Leider unterst�tzt der
Mesa-3Dfx-Treiber nur einen aktuellen Kontext. Will
man mit einer 3Dfx Teilfenster benutzen, stellt man
fest, da� sie nicht innerhalb des Hauptfensters
erzeugt werden, sondern dieses verdecken. Das f�hrt
zu einem schnellen Blinken, wenn Haupt- und
Teilfenster abwechselnd gezeichnet werden. Klar, da�
dieser Effekt nicht erw�nscht ist. Wer Teilfenster
benutzen will, mu� auf den Artikel von Miguel
warten, in dem er erkl�ren will, wie man sie durch
Manipulation des Matrix-Stacks einsetzen kann.
Ich m�chte hier jetzt gerne zeigen, wie man den
Fokus behalten kann, wenn man mit der 3Dfx
Fullscreen zeichnet. In diesem Fall wird der
3Dfx-Framebuffer anstelle der 2D-Grafikkarte
benutzt. Dadurch wird ein Fenster f�r das Programm
auf dem 2D-Desktop erzeugt, die gesamte Grafik aber
Fullscreen von der 3Dfx erstellt. Bei einem System mit einem
Bildschirm �bernimmt die 3Dfx diesen, so da� man das
Fenster auf dem 2D-Desktop nicht sehen kann. Ist ein
zweiter Monitor angeschlossen, zeigt einer das
Fullscreen-Bild der 3Dfx und der andere den
2D-Desktop mit dem Programm-Fenster.
Wenn nur ein Monitor angeschlossen ist, gibt es
h�ufig Schwierigkeiten den Fokus auf dem 2D-Desktop zu
behalten, weil dieser ja unsichtbar ist. Verliert das
Programm auf diesem Desktop den Fokus, kann es keine
Eingaben mehr verarbeiten. Dann kann es nat�rlich auch
nicht feststellen, wenn der Anwender die "Ende"-Taste
dr�ckt, und er kann andererseits nicht den Men�eintrag
anklicken -- denn das Programmfenster ist unsichtbar.
In dieser Situation ist es also nicht m�glich, das
Programm zu beenden.
Ein bi�chen Trickserei mit glutFullScreen() und
glViewport() hilft aus diesem Dilemma.
glutFullScreen() vergr��ert das Programmfenster so,
da� es den ganzen 2D-Desktop einnimmt. Ruft man
glutFullScreen() nach dem Erzeugen eines Fensters
auf, kann die Maus es nicht mehr verlassen, denn es
ist ja genauso gro� wie der Desktop. So kann das
Fenster den Fokus nicht mehr verlieren.
Die Funktion glViewport() legt den Viewport des
Programms fest, in dem die
ganze Grafik erscheint. Normalerweise ruft man
glViewport() w�hrend einer Resize-Operation auf, um
den Viewport an die neuen Fensterabmessungen
anzupassen. Hier sollte man glViewport() mit den
Gr��en aufrufen, mit denen man die 3Dfx betreibt:
bei 640x480 also glViewport(0,0,640,480) und bei
800x600 entsprechend glViewport(0,0,800,600).
Dadurch benutzt das Programm nur diesen Teil des
Fensters, das eigentlich den ganzen Bildschirm
einnimmt.
Eine f�r die 3Dfx modifizierte Version von
Miguels schattiertem Dreieck liegt hier: (../../common/March1998/example3.c, ../../common/March1998/Makefile). Ich habe einfach die
Teilfenster weggelassen, glutFullscreen() an der
richtigen Stelle eingetragen (nach dem Erzeugen der
Fenster) und glViewport() im Reshape-Callback so
ge�ndert, da� der Viewport den 640x480 Pixeln meiner
3Dfx-Karte entspricht. L��t man das Programm ohne
die 3D-Karte laufen l��t (also MESA_GLX_FX nicht
gesetzt ist), kann man sehen, da� das
Programm-Fenster den ganzen Bildschirm einnimmt, zum
Zeichnen aber nur eine 640x480 Pixel gro�e Fl�che
benutzt wird. L�uft das Programm mit der 3Dfx,
zeichnet es auf den ganzen Bildschirm.
Au�erdem f�llt auf, da� das Programm ohne 3Dfx
sehr langsam ist. Das liegt daran, da� das ganze
Fenster neu gezeichnet werden mu� anstelle des
kleineren Viewports. Dadurch gibt es
Performance-Einbu�en beim Zeichen in den 2D-Desktop.
Es ist also sinnvoll, in Applikationen die An-
oder Abwesenheit der 3Dfx durch Pr�fen von
MESA_GLX_FX festzustellen. Dann kann man entweder
die Kombination glutFullScreen()/glViewport()
benutzen, wenn die Karte vorhanden ist, oder eben
darauf verzichten.
|