In my last article I wrote about the 3Dfx and how well it
did at providing Mesa hardware acceleration capabilities. I
touched upon the advantages and disadvantages of using Mesa+3Dfx,
and this time I would like to go into detail about some of these
disadvantages and how a developer can get around them.
To begin with, Miguel's informative article explains how to
use the GLUT library to render into subwindows within the main
window. When you use subwindows, a new context is created
separately from the context of the main window. Unfortunately,
the 3Dfx driver for Mesa only supports one context at the moment.
If you try to use subwindows on the 3Dfx you will see that
instead of rendering the subwindow into the main window, the
subwindow is rendered over top of the main window. This produces
a quick flashing effect as the main window and subwindow are
alternately rendered very fast. This is obviously not the effect
we want from subwindows so you will have to wait for Miguel's
future explanation of how to get around using subwindows by
manipulating matrix stacks.
Second, I would like to show how one can overcome the
problem with keeping the mouse focus when using fullscreen
rendering with the 3Dfx. When using fullscreen rendering with
the 3Dfx, the rendering is done to the 3Dfx's framebuffer instead
of your 2D video adapter's framebuffer. The result is that a
window is created for the program on your 2D desktop, but all of
the rendering for the program is done fullscreen to the 3Dfx. On
a single headed system, the 3Dfx takes over the monitor and
you will not be able to see the window on the 2D desktop, but on
a dual headed system, one monitor will show your 2D desktop and
the window created for the program, and on the other monitor you
will see fullscreen rendering of the program.
On single headed systems it can often be tricky to have the
program's window keep the window focus on the 2D desktop because
you wont be able to see the window. If the program's window on
the 2D desktop loses focus, it will be unable to accept input.
If the program cant accept input to detect when the user presses
a designated exit key, and the user can't see the 2D desktop to
be able to locate the exit button on the window and close the
program, the user might not be able to shutdown the program!
A trick you can use to work around this is to use the
glutFullScreen() and glViewport() functions. The
glutFullScreen() function resizes the program's window to the
dimensions of the 2D desktop so that the window becomes
fullscreen on the 2D desktop. What you can do is call
glutFullScreen() after creating a window to make the window
fullscreen on the 2D desktop. When the window is fullscreen,
there is not way for the mouse to leave the window, so the window
can not lose focus.
The glViewport() function tells the program how big the
viewport will be for the program. When you specify a viewport,
all of the rendering is done into that viewport. For the 3Dfx,
where you would normally call glViewport() in a reshape callback
function to set the viewport to the new dimensions of the window,
make a call to glViewport() with the dimensions of the resolution
of the 3Dfx. If you were running the 3Dfx at 640x480 you would
call glViewport(0,0,640,480) and if you were running at 800x600
you would call glViewport(0,0,800,600). This will make the
program render to the viewport dimensions that you specified as
the resolution of your 3Dfx card even though the window is
fullscreen.
I've included a version of Miguel's smooth-shaded triangle
modified to work on the 3Dfx (../../common/March1998/example3.c,
../../common/March1998/Makefile). I simply excluded the subwindows,
added glutFullscreen() in the proper place (after window
creation), and changed glViewport() in the reshape callback
function to force the viewport to 640x480 (the resolution of my
3Dfx carx). You will notice if you run without the 3D (by not
setting MESA_GLX_FX environment variable) the program's window
will open to the full dimensions of your desktop, but rendering
is only done to a 640x480 area within that window. If you run
the program with the 3Dfx, you will see the rendering is done to
the full size of the 3dfx and the program will now lose focus.
Something else to note, when you run the program without the
3Dfx, the program may run really slow due to the fact that the
full window is being updated instead of just the viewport. This
is quite a performance hit when rendering to your 2D desktop but
it's fine for fullscreen 3Dfx. For this reason, you may want to
write your programs to detect whether or not the 3Dfx is being
used (by detecting and reading the MESA_GLX_FX environment
variable) and either using glutFullScreen() force glViewport()
trick if the 3Dfx detected or not use the trick if the 3Dfx is
not detected.
|