Documentation

  
  FLTK Apps      FLTK Library      Forums      Links     Login 
 Home  |  Articles & FAQs  |  Bugs & Features  |  Documentation  |  Download  ]
 

class Fl_Gl_Window


Class Hierarchy

Include Files

    #include <FL/Fl_Gl_Window.H>
    

Additional Libraries

    -lfltk_gl  /  fltkgl.lib
    

Description

The Fl_Gl_Window 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. Fl_Gl_Window also flushes the OpenGL streams and swaps buffers after draw() returns.

OpenGL hardware typically provides some overlay bit planes, which are very useful for drawing UI controls atop your 3D graphics. If the overlay hardware is not provided, FLTK tries to simulate the overlay, This works pretty well if your graphics are double buffered, but not very well for single-buffered.

Please note that the FLTK drawing and clipping functions will not work inside an Fl_Gl_Window. All drawing should be done using OpenGL calls exclusively. Even though Fl_Gl_Window is derived from Fl_Group, it is not useful to add other FLTK Widgets as children, unless those Widgets are modified to draw using OpenGL calls.

Methods

Fl_Gl_Window::Fl_Gl_Window(int x, int y, int w, int h, const char *label = 0)

Creates a new Fl_Gl_Window widget using the given position, size, and label string. The default boxtype is FL_NO_BOX. The default mode is FL_RGB|FL_DOUBLE|FL_DEPTH.

virtual Fl_Gl_Window::~Fl_Gl_Window()

The destructor removes the widget and destroys the OpenGL context associated with it.

virtual void Fl_Gl_Window::draw(void)

Fl_Gl_Window::draw() is a pure virtual method. You must subclass Fl_Gl_Window and provide an implementation for draw(). You may also provide an implementation of draw_overlay() if you want to draw into the overlay planes. 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.

The draw() method can only use OpenGL calls. Do not attempt to call X, any of the functions in <FL/fl_draw.H>, or glX directly. Do not call gl_start() or gl_finish().

If double-buffering is enabled in the window, the back and front buffers are swapped after this function is completed.

const int Fl_Gl_Window::mode() const
int Fl_Gl_Window::mode(int m)

Set or change the OpenGL capabilites of the window. The value can be any of the following OR'd together:
  • FL_RGB - RGB color (not indexed)
  • FL_RGB8 - RGB color with at least 8 bits of each color
  • FL_INDEX - Indexed mode
  • FL_SINGLE - not double buffered
  • FL_DOUBLE - double buffered
  • FL_ACCUM - accumulation buffer
  • FL_ALPHA - alpha channel in color
  • FL_DEPTH - depth buffer
  • FL_STENCIL - stencil buffer
  • FL_MULTISAMPLE - multisample antialiasing
FL_RGB and FL_SINGLE have a value of zero, so they are "on" unless you give FL_INDEX or FL_DOUBLE.

If the desired combination cannot be done, FLTK will try turning off FL_MULTISAMPLE. If this also fails the show() will call Fl::error() and not show the window.

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 xid() 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!

mode() must not be called within draw() since it changes the current context.

static int Fl_Gl_Window::can_do(int)
int Fl_Gl_Window::can_do() const

Returns non-zero if the hardware supports the given or current OpenGL mode.

void* Fl_Gl_Window::context() const;
void Fl_Gl_Window::context(void*, int destroy_flag = false);

Return or set a pointer to the GLContext that this window is using. This is a system-dependent structure, 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.

If destroy_flag is true the context will be destroyed by fltk when the window is destroyed, or when the mode() is changed, or the next time context(x) is called.

char Fl_Gl_Window::valid() const
void Fl_Gl_Window::valid(char i)

Fl_Gl_Window::valid() is turned off when FLTK creates a new context for this window or when the window resizes, and is turned on after draw() is called. You can use this inside your draw() method to avoid unneccessarily initializing the OpenGL context. Just do this:
    void mywindow::draw() {
      if (!valid()) {
        glViewport(0,0,w(),h());
        glFrustum(...);
        ...other initialization...
      }
      if (!context_valid()) {
        ...load textures, etc. ...
      }
      ... draw your geometry here ...
    }
    
You can turn valid() on by calling valid(1). You should only do this after fixing the transformation inside a draw() or after make_current(). This is done automatically after draw() returns.

void Fl_Gl_Window::invalidate()

The invalidate() method turns off valid() and is equivalent to calling value(0).

char Fl_Gl_Window::context_valid() const
void Fl_Gl_Window::context_valid(char i)

Fl_Gl_Window::context_valid() will only be set if the OpenGL context is created or recreated. It differs from Fl_Gl_Window::valid() which is also set whenever the context changes size.

void Fl_Gl_Window::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 if valid() is false.

void Fl_Gl_Window::make_current()

The make_current() method selects the OpenGL context for the widget. It is called automatically prior to the draw() method being called and can also be used to implement feedback and/or selection within the handle() method.

void Fl_Gl_Window::make_overlay_current()

The make_overlay_current() method selects the OpenGL context for the widget's overlay. It is called automatically prior to the draw_overlay() method being called and can also be used to implement feedback and/or selection within the handle() method.

void Fl_Gl_Window::swap_buffers()

The swap_buffers() method swaps the back and front buffers. It is called automatically after the draw() method is called.

void Fl_Gl_Window::hide()

Hides the window and destroys the OpenGL context.

int Fl_Gl_Window::can_do_overlay()

Returns true if the hardware overlay is possible. If this is false, FLTK will try to simulate the overlay, with significant loss of update speed. Calling this will cause FLTK to open the display.

void Fl_Gl_Window::redraw_overlay()

This method 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.

virtual void Fl_Gl_Window::draw_overlay()

You must implement this virtual function if you want to draw into the overlay. The overlay is cleared before this is called. You should draw anything that is not clear using OpenGL. You must use gl_color(i) 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.

Both this function and Fl_Gl_Window::draw() should check Fl_Gl_Window::valid() and set the same transformation. If you don't your code may not work on other systems. Depending on the OS, and on whether overlays are real or simulated, the OpenGL context may be the same or different between the overlay and main window.


User Comments [ Add Comment ]

From Mark T., 12:08 Oct 06, 2004 (score=1)

There seem to be several restrictions on the Fl_Gl_Window class which are not in the documentation: 1. the Fl_Gl_Window may not contain widgets (Apparently the end() member fuction is automatically called after construction.  If begin() is called manually, the widgets then seem to be added but are never drawn.) 2. if the Fl_Gl_Window is on a parent window, apparently the Fl_Gl_Window is the last widget drawn regardless of whether it was added before or after the other widgets.  Any other widgets attached to the parent window which overlap the Fl_Gl_Window appear "under" the Fl_Gl_Window. 3.  I have a class derived from Fl_Double_Window which allows the drawing commands in Fl_Draw.H to be used over the top of any widgets added to the window.  However, if a Fl_Gl_Window is added, the additional drawing is done "under" the Fl_Gl_Window, but above all other widgets. 4.  It appears to be impossible to add two Fl_Gl_Windows to the same parent window (whether they overlap or not).  (Conjecture: both Fl_Gl_Windows need to be drawn last, and since they can't both be last, the system crashes.)

Testing of the above was done using Windows.
Reply ]

From matt, 07:08 Jun 23, 2006 (score=3)

Hi Mark.

Thanks for your additions. I updated the documentation accordingly.

Ad 1: Fl_Gl_Window is derived from Fl_Window, so it can stand alone as a top level window on a desktop. As a side efeect, it is also a group, so it may contain further widgets. This however works only with a little trickery, most importantly, all child widgets must be drawn using OpenGL commands.

Ad 2: stuff like this depends very much on how OpenGL is implemented on your machine in hardware. Some graphics boards use an entirely different area in memory to draw accelerated OpenGL, using something called a hardware overlay. As the name suggests, the OpenGL darwings are layered "over" regular drawings. FLTK has no influence on these things.

Ad 3: based on 2, OpenGL and native drawing command may or may not mix, depending on the hardware that you use. Again, this is nothing that FLTK could do different. It is purely a graphics driver and hardware issue. Yes, we could trick the fl_ drawing commands into using OpenGL commands, but that is a whole other can of worms. Nothing we will start in FLTK1.

Ad 4: it should be no problem to open 2 OpenGL contexts in a single windows. "test/cube.cxx" shows you how.


Reply ]

From greg.ercolano, 17:53 Jun 18, 2006 (score=3)

I've made an STR for this: http://fltk.org/str.php?L1329

But Mark's comment #4 can't be right; the cube.cxx demo implements two Fl_Gl_Window's next to each other, and it has been around forever.
Reply ]

 
 

Comments are owned by the poster. All other content is copyright 1998-2015 by Bill Spitzak and others. This project is hosted by Seriss Corporation. Please report site problems to 'erco@seriss.com'.