FLTK 1.3.3
|
This chapter discusses using FLTK for your OpenGL applications.
The easiest way to make an OpenGL display is to subclass Fl_Gl_Window. Your subclass must implement a draw()
method which uses OpenGL calls to draw the display. Your main program should call redraw()
when the display needs to change, and (somewhat later) FLTK will call draw()
.
With a bit of care you can also use OpenGL to draw into normal FLTK windows. This allows you to use Gouraud shading for drawing your widgets. To do this you use the gl_start() and gl_finish() functions around your OpenGL code.
You must include FLTK's <FL/gl.h>
header file. It will include the file <GL/gl.h>
, define some extra drawing functions provided by FLTK, and include the <windows.h>
header file needed by WIN32 applications.
To make a subclass of Fl_Gl_Window, you must provide:
draw()
method. handle()
method if you need to receive input from the user.If your subclass provides static controls in the window, they must be redrawn whenever the FL_DAMAGE_ALL
bit is set in the value returned by damage()
. For double-buffered windows you will need to surround the drawing code with the following code to make sure that both buffers are redrawn:
Note: If you are using the Mesa graphics library, the call to |
To define the subclass you just subclass the Fl_Gl_Window class:
The draw()
and handle()
methods are described below. Like any widget, you can include additional private and public data in your class (such as scene graph information, etc.)
The draw()
method is where you actually do your OpenGL drawing:
The handle()
method handles mouse and keyboard events for the window:
When handle()
is called, the OpenGL context is not set up! If your display changes, you should call redraw()
and let draw()
do the work. Don't call any OpenGL drawing functions from inside handle()!
You can call some OpenGL stuff like hit detection and texture loading functions by doing:
Your main program can now create one of your windows by doing new MyWindow(...)
.
You can also use your new window class in FLUID by:
MyWindow.H
file.MyWindow
. This will make FLUID produce constructors for your new class.#include "MyWindow.H"
, so that the FLUID output file will compile.You must put glwindow->show()
in your main code after calling show()
on the window containing the OpenGL window.
You can put OpenGL code into the draw()
method, as described in Drawing the Widget in the previous chapter, or into the code for a boxtype or other places with some care.
Most importantly, before you show any windows, including those that don't have OpenGL drawing, you must initialize FLTK so that it knows it is going to use OpenGL. You may use any of the symbols described for Fl_Gl_Window::mode()
to describe how you intend to use OpenGL:
You can then put OpenGL drawing code anywhere you can draw normally by surrounding it with gl_start() and gl_finish() to set up, and later release, an OpenGL context with an orthographic projection so that 0,0 is the lower-left corner of the window and each pixel is one unit. The current clipping is reproduced with OpenGL glScissor()
commands. These functions also synchronize the OpenGL graphics stream with the drawing done by other X, WIN32, or FLTK functions.
The same context is reused each time. If your code changes the projection transformation or anything else you should use glPushMatrix()
and glPopMatrix()
functions to put the state back before calling gl_finish()
.
You may want to use Fl_Window::current()->h()
to get the drawable height so that you can flip the Y coordinates.
Unfortunately, there are a bunch of limitations you must adhere to for maximum portability:
FL_DOUBLE
to Fl::gl_visual().Do not call gl_start()
or gl_finish()
when drawing into an Fl_Gl_Window !
FLTK provides some useful OpenGL drawing functions. They can be freely mixed with any OpenGL calls, and are defined by including <FL/gl.h>
which you should include instead of the OpenGL header <GL/gl.h>
.
void gl_color(Fl_Color)
fl_xpixel(c)
, which is only right if this window uses the default colormap!void gl_rect(int x, int y, int w, int h)
void gl_rectf(int x, int y, int w, int h)
void gl_font(Fl_Font fontid, int size)
int gl_height()
int gl_descent()
float gl_width(const char *s)
float gl_width(const char *s, int n)
float gl_width(uchar c)
void gl_draw(const char *s)
void gl_draw(const char *s, int n)
n
characters in the current OpenGL font at the current raster position.void gl_draw(const char *s, int x, int y)
void gl_draw(const char *s, int n, int x, int y)
void gl_draw(const char *s, float x, float y)
void gl_draw(const char *s, int n, float x, float y)
n
characters in the current OpenGL font at the given position.void gl_draw(const char *s, int x, int y, int w, int h, Fl_Align)
Performance of Fl_Gl_Window may be improved on some types of OpenGL implementations, in particular MESA and other software emulators, by setting the GL_SWAP_TYPE
environment variable. This variable declares what is in the backbuffer after you do a swapbuffers.
setenv GL_SWAP_TYPE COPY
damage()
will not be cleared to -1.setenv GL_SWAP_TYPE NODAMAGE
GL_SWAP_TYPE
, and not setting the variable, cause FLTK to assume that the back buffer must be completely redrawn after a swap.This is easily tested by running the gl_overlay demo program and seeing if the display is correct when you drag another window over it or if you drag the window off the screen and back on. You have to exit and run the program again for it to see any changes to the environment variable.
OpenGL Optimizer is a scene graph toolkit for OpenGL available from Silicon Graphics for IRIX and Microsoft Windows. It allows you to view large scenes without writing a lot of OpenGL code.
camera()
method sets the camera (projection and viewpoint) to use when drawing the scene. The scene is redrawn after this call.draw()
method performs the needed initialization and does the actual drawing:scene()
method sets the scene to be drawn. The scene is a collection of 3D objects in a csGroup
. The scene is redrawn after this call.[Prev] Adding and Extending Widgets | [Index] | Programming with FLUID [Next] |