fltk::GlWindow Class Reference

Inherits fltk::Window.

Inherited by fltk::GlutWindow.

List of all members.

Public Member Functions

bool can_do () const
bool can_do_overlay ()
GLContext context () const
void context (GLContext v, bool destroy_flag=false)
void create ()
void destroy ()
virtual void draw ()=0
virtual void draw_overlay ()
void flush ()
 GlWindow (int X, int Y, int W, int H, const char *l=0)
virtual int handle (int event)
void invalidate ()
void layout ()
void make_current ()
void make_overlay_current ()
bool mode (int a)
void ortho ()
void redraw_overlay ()
void swap_buffers ()
char valid () const
 ~GlWindow ()

Static Public Member Functions

static bool can_do (int)

Detailed Description

Provides an area in which the draw() method can use OpenGL to draw. This widget sets things up so OpenGL works, and also keeps an OpenGL "context" for that window, so that changes to the lighting and projection may be reused between redraws. GlWindow also flushes the OpenGL streams and swaps buffers after draw() returns.

draw() is a pure virtual method. You must subclass GlWindow and provide an implementation for draw(). You can avoid reinitializing the viewport and lights and other things by checking valid() at the start of draw() and only doing the initialization if it is false.

draw() can only use OpenGL calls. Do not attempt to call any of the functions in <fltk/draw.h>, or X or GDI32 or any other drawing api. Do not call glstart() or glfinish().

Double Buffering

Normally double-buffering is enabled. You can disable it by chaning the mode() to turn off the DOUBLE_BUFFER bit.

If double-buffering is enabled, the back buffer is made current before draw() is called, and the back and front buffers are automatically swapped after draw() is completed.

Some tricks using the front buffer require you to control the swapping. You can call swap_buffers() to swap them (OpenGL does not provide a portable function for this, so we provide it). But you will need to turn off the auto-swap, you do this by adding the NO_AUTO_SWAP bit to the mode().

Overlays

The method draw_overlay() is a second drawing operation that is put atop the main image. You can implement this, and call redraw_overlay() to indicate that the image in this overlay has changed and that draw_overlay() must be called.

Originally this was written to support hardware overlays, but FLTK emulated it if the hardware was missing so programs were portable. FLTK 2.0 is not normally compiled to support hardware overlays, but the emulation still remains, so you can use these functions. (Modern hardware typically has no overlays, and besides it is fast enough that the original purpose of them is moot)

By default the emulation is to call draw_overlay() after draw() and before swapping the buffers, so the overlay is just part of the normal image and does not blink. You can get some of the advantages of overlay hardware by setting the GL_SWAP_TYPE environment variable, which will cause the front buffer to be used for the draw_overlay() method, and not call draw() each time the overlay changes. This will be faster if draw() is very complex, but the overlay will blink. GL_SWAP_TYPE can be set to:

  • "USE_COPY" use glCopyPixels to copy the back buffer to the front. This should always work.
  • "COPY" indicates that the swap_buffers() function actually copies the back to the front buffer, rather than swapping them. If your card does this (most do) then this is best.
  • "NODAMAGE" indicates that behavior is like "COPY" but nothing changes the back buffer, including overlapping it with another OpenGL window. This is true of software OpenGL emulation, and may be true of some modern cards with lots of memory.

Constructor & Destructor Documentation

GlWindow::~GlWindow ( )

The destructor will destroy the context() if it belongs to the window.

GlWindow::GlWindow ( int  x,
int  y,
int  w,
int  h,
const char *  label = 0 
) [inline]

The constructor sets the mode() to RGB_COLOR|DEPTH_BUFFER|DOUBLE_BUFFER which is probably all that is needed for most 3D OpenGL graphics.


Member Function Documentation

bool GlWindow::can_do ( ) const [inline]

Returns true if the hardware supports the current value of mode(). If false, attempts to show or draw this window will cause an fltk::error().

bool GlWindow::can_do ( int  mode) [static]

Returns true if the hardware supports mode, see mode() for the meaning of the bits.

bool GlWindow::can_do_overlay ( )

Return true if the hardware supports OpenGL overlay planes, and FLTK has been compiled to use them. If true, draw_overlay() will be called with OpenGL setup to draw these overlay planes, and redraw_overlay() will not cause the main draw() to be called.

GLContext GlWindow::context ( ) const [inline]

Return the current OpenGL context object being used by this window, or 0 if there is none.

void GlWindow::context ( GLContext  v,
bool  destroy_flag = false 
) [inline]

Set the OpenGL context object to use to draw this window.

This is a system-dependent structure (HGLRC on Windows,GLXContext on X, and AGLContext (may change) on OS/X), but it is portable to copy the context from one window to another. You can also set it to NULL, which will force FLTK to recreate the context the next time make_current() is called, this is useful for getting around bugs in OpenGL implementations.

destroy_flag indicates that the context belongs to this window and should be destroyed by it when no longer needed. It will be destroyed when the window is destroyed, or when the mode() is changed, or if the context is changed to a new value with this call.

void GlWindow::create ( ) [virtual]

This virtual function may be overridden to use something other than FLTK's default code to create the system's window. This must call either CreatedWindow::create() or CreatedWindow::set_xid().

An example for Xlib (include x.h to make this work):

void MyWindow::create() {
  fltk::open_display(); // necessary if this is first window
  // we only calcualte the necessary visual & colormap once:
  static XVisualInfo* visual;
  static Colormap colormap;
  static int background;
  if (!visual) {
    visual = figure_out_visual();
    colormap = XCreateColormap(xdisplay, RootWindow(xdisplay,xscreen),
                                vis->visual, AllocNone);
    XColor xcol; xcol.red = 1; xcol.green = 2; xcol.blue = 3;
    XAllocColor(fltk::display, colormap, &xcol);
    background = xcol.pixel;
  }
  CreatedWindow::create(this, visual, colormap, background);
}

Reimplemented from fltk::Window.

void GlWindow::destroy ( ) [virtual]

Besides getting rid of the window, this will destroy the context if it belongs to the window.

Reimplemented from fltk::Window.

virtual void fltk::GlWindow::draw ( void  ) [pure virtual]

Fltk calls this virtual function to draw the widget, after setting up the graphics (current window, xy translation, etc) so that any drawing functions will go into this widget.

User code should not call this! You probably want to call redraw().

The default version calls draw_box() and draw_label(), thus drawing the box() to fill the widget and putting the label() and image() inside it to fill it, unless the align() flags are set to put it outside.

Information on how to write your own version is here.

Reimplemented from fltk::Window.

Implemented in fltk::GlutWindow.

void GlWindow::draw_overlay ( ) [virtual]

You must implement this virtual function if you want to draw into the overlay. The overlay is cleared before this is called (unless the NO_ERASE_OVERLAY bit is set in the mode and hardware overlay is supported). You should draw anything that is not clear using OpenGL.

If the hardware overlay is being used it will probably be color indexed. You must use glsetcolor() to choose colors (it allocates them from the colormap using system-specific calls), and remember that you are in an indexed OpenGL mode and drawing anything other than flat-shaded will probably not work.

Depending on the OS and whether or not the overlay is being simulated, the context may be shared with the main window. This means if you check valid() in draw() to avoid initialization, you must do so here and initialize to exactly the same setting.

Reimplemented from fltk::Window.

Reimplemented in fltk::GlutWindow.

void GlWindow::flush ( ) [virtual]

This virtual function is called by fltk::flush() to update the window. You can override it for special window subclasses to change how they draw.

For FLTK's normal windows this calls Window::make_current(), then perhaps sets up the clipping if the only damage is expose events, and then draw(), and then does some extra work to get the back buffer copied or swapped into the front buffer.

For your own windows you might just want to put all the drawing code in here.

Reimplemented from fltk::Window.

int GlWindow::handle ( int  event) [virtual]

Calls send() on some or all of the children widgets.

Reimplemented from fltk::Window.

Reimplemented in fltk::GlutWindow.

void GlWindow::invalidate ( )

Turn off valid().

void GlWindow::layout ( ) [virtual]

Virtual function to respond to layout_damage(), it should calculate the correct size of this widget and all it's children. This function is called by fltk or by the layout() method in other widgets. User programs should not call it.

A widget is allowed to alter it's own size in a layout() method, to indicate a size that the data will fit in. A parent widget is then expected to rearrange itself to accomodate the new size. This may mean it will move the widget and thus layout() will be called again.

You can look at layout_damage() to find out why this is being called.

The base class redraws the widget.

Reimplemented from fltk::Window.

void GlWindow::make_current ( )

Selects the OpenGL context for the widget, creating it if necessary. It is called automatically prior to the draw() method being called. You can call it in handle() to set things up to do OpenGL hit detection, or call it other times to do incremental update of the window.

Reimplemented in fltk::GlutWindow.

void GlWindow::make_overlay_current ( )

Selects the OpenGL context for the widget's overlay. This can be used to do incremental OpenGL drawing into the overlay. If hardware overlay is not supported, this sets things to draw into the front buffer, which is probably not good enough emulation to be usable.

bool GlWindow::mode ( int  m)

Set or change the OpenGL capabilites of the window. The value can be any of the symbols from <fltk/visual.h> OR'd together:

  • fltk::INDEXED_COLOR indicates that a colormapped visual is ok. This call will normally fail if a TrueColor visual cannot be found.
  • fltk::RGB_COLOR this value is zero and may be passed to indicate that fltk::INDEXED_COLOR is not wanted.
  • fltk::RGB24_COLOR indicates that the visual must have at least 8 bits of red, green, and blue (Windows calls this "millions of colors").
  • fltk::DOUBLE_BUFFER indicates that double buffering is wanted.
  • fltk::SINGLE_BUFFER is zero and can be used to indicate that double buffering is not wanted.
  • fltk::ACCUM_BUFFER makes the accumulation buffer work
  • fltk::ALPHA_BUFFER makes an alpha buffer
  • fltk::DEPTH_BUFFER makes a depth/Z buffer
  • fltk::STENCIL_BUFFER makes a stencil buffer
  • fltk::MULTISAMPLE makes it multi-sample antialias if possible (X only)
  • fltk::STEREO stereo if possible
  • NO_AUTO_SWAP disables the automatic call to swap_buffers() after draw().
  • NO_ERASE_OVERLAY if overlay hardware is used, don't call glClear before calling draw_overlay().

If the desired combination cannot be done, FLTK will try turning off MULTISAMPLE and STERERO. If this also fails then attempts to create the context will cause fltk::error() to be called, aborting the program. Use can_do() to check for this and try other combinations.

You can change the mode while the window is displayed. This is most useful for turning double-buffering on and off. Under X this will cause the old X window to be destroyed and a new one to be created. If this is a top-level window this will unfortunately also cause the window to blink, raise to the top, and be de-iconized, and the ID will change, possibly breaking other code. It is best to make the GL window a child of another window if you wish to do this!

void GlWindow::ortho ( )

Set the projection so 0,0 is in the lower left of the window and each pixel is 1 unit wide/tall. If you are drawing 2D images, your draw() method may want to call this when valid() is false.

void GlWindow::redraw_overlay ( )

Causes draw_overlay() to be called at a later time. Initially the overlay is clear, if you want the window to display something in the overlay when it first appears, you must call this immediately after you show() your window.

Reimplemented from fltk::Window.

void GlWindow::swap_buffers ( )

Swap the front and back buffers of this window (or copy the back buffer to the front, possibly clearing or garbaging the back one, depending on your OpenGL implementation.

This is called automatically after draw() unless the NO_AUTO_SWAP flag is set in the mode().

char GlWindow::valid ( ) const [inline]

This flag is turned off on a new window or if the window is ever resized or the context is changed. It is turned on after draw() is called. draw() can use this to skip initializing the viewport, lights, or other pieces of the context.

void My_GlWindow_Subclass::draw() {
  if (!valid()) {
    glViewport(0,0,w(),h());
    glFrustum(...);
    glLight(...);
    glEnable(...);
    ...other initialization...
  }
  ... draw your geometry here ...
}

The documentation for this class was generated from the following files: