1998-10-20 01:39:29 +04:00
|
|
|
//
|
2005-02-25 00:55:12 +03:00
|
|
|
// "$Id$"
|
1998-10-20 01:39:29 +04:00
|
|
|
//
|
|
|
|
// OpenGL header file for the Fast Light Tool Kit (FLTK).
|
|
|
|
//
|
2010-11-29 00:06:39 +03:00
|
|
|
// Copyright 1998-2010 by Bill Spitzak and others.
|
1998-10-20 01:39:29 +04:00
|
|
|
//
|
2011-07-19 08:49:30 +04:00
|
|
|
// This library is free software. Distribution and use rights are outlined in
|
|
|
|
// the file "COPYING" which should have been included with this file. If this
|
|
|
|
// file is missing or damaged, see the license at:
|
1998-10-20 01:39:29 +04:00
|
|
|
//
|
2011-07-19 08:49:30 +04:00
|
|
|
// http://www.fltk.org/COPYING.php
|
1998-10-20 01:39:29 +04:00
|
|
|
//
|
2005-04-16 04:13:17 +04:00
|
|
|
// Please report all bugs and problems on the following page:
|
|
|
|
//
|
|
|
|
// http://www.fltk.org/str.php
|
1998-10-20 01:39:29 +04:00
|
|
|
//
|
2008-09-16 11:26:22 +04:00
|
|
|
|
2008-10-15 17:46:06 +04:00
|
|
|
/* \file
|
2008-09-16 11:26:22 +04:00
|
|
|
Fl_Gl_Window widget . */
|
|
|
|
|
1998-10-06 22:21:25 +04:00
|
|
|
#ifndef Fl_Gl_Window_H
|
|
|
|
#define Fl_Gl_Window_H
|
|
|
|
|
|
|
|
#include "Fl_Window.H"
|
|
|
|
|
2001-03-14 20:20:02 +03:00
|
|
|
#ifndef GLContext
|
2008-10-04 19:54:15 +04:00
|
|
|
/**
|
2009-02-18 12:27:54 +03:00
|
|
|
Opaque pointer type to hide system specific implementation.
|
2008-10-04 19:54:15 +04:00
|
|
|
*/
|
2001-03-14 20:20:02 +03:00
|
|
|
typedef void* GLContext; // actually a GLXContext or HGLDC
|
|
|
|
#endif
|
|
|
|
|
1998-10-06 22:21:25 +04:00
|
|
|
class Fl_Gl_Choice; // structure to hold result of glXChooseVisual
|
|
|
|
|
2008-09-14 02:33:03 +04:00
|
|
|
/**
|
2009-02-18 12:27:54 +03:00
|
|
|
The Fl_Gl_Window widget sets things up so OpenGL works.
|
|
|
|
|
|
|
|
It also keeps an OpenGL "context" for that window, so that changes to the
|
2008-09-14 02:33:03 +04:00
|
|
|
lighting and projection may be reused between redraws. Fl_Gl_Window
|
2009-02-18 12:27:54 +03:00
|
|
|
also flushes the OpenGL streams and swaps buffers after draw() returns.
|
|
|
|
|
|
|
|
OpenGL hardware typically provides some overlay bit planes, which
|
2008-09-14 02:33:03 +04:00
|
|
|
are very useful for drawing UI controls atop your 3D graphics. If the
|
2009-02-18 12:27:54 +03:00
|
|
|
overlay hardware is not provided, FLTK tries to simulate the overlay.
|
2008-09-14 02:33:03 +04:00
|
|
|
This works pretty well if your graphics are double buffered, but not
|
2009-02-18 12:27:54 +03:00
|
|
|
very well for single-buffered.
|
|
|
|
|
|
|
|
Please note that the FLTK drawing and clipping functions
|
2008-09-14 02:33:03 +04:00
|
|
|
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,
|
2009-02-18 12:27:54 +03:00
|
|
|
unless those widgets are modified to draw using OpenGL calls.
|
2008-09-14 02:33:03 +04:00
|
|
|
*/
|
2002-08-14 20:49:38 +04:00
|
|
|
class FL_EXPORT Fl_Gl_Window : public Fl_Window {
|
1998-10-06 22:21:25 +04:00
|
|
|
|
|
|
|
int mode_;
|
|
|
|
const int *alist;
|
|
|
|
Fl_Gl_Choice *g;
|
2001-03-14 20:20:02 +03:00
|
|
|
GLContext context_;
|
2006-08-17 13:49:43 +04:00
|
|
|
char valid_f_;
|
1998-10-06 22:21:25 +04:00
|
|
|
char damage1_; // damage() of back buffer
|
2002-08-14 20:49:38 +04:00
|
|
|
virtual void draw_overlay();
|
|
|
|
void init();
|
1998-10-06 22:21:25 +04:00
|
|
|
|
|
|
|
void *overlay;
|
2002-08-14 20:49:38 +04:00
|
|
|
void make_overlay();
|
1998-10-06 22:21:25 +04:00
|
|
|
friend class _Fl_Gl_Overlay;
|
|
|
|
|
2002-08-14 20:49:38 +04:00
|
|
|
static int can_do(int, const int *);
|
|
|
|
int mode(int, const int *);
|
1998-10-06 22:21:25 +04:00
|
|
|
|
|
|
|
public:
|
|
|
|
|
2002-08-14 20:49:38 +04:00
|
|
|
void show();
|
1998-10-06 22:21:25 +04:00
|
|
|
void show(int a, char **b) {Fl_Window::show(a,b);}
|
2002-08-14 20:49:38 +04:00
|
|
|
void flush();
|
|
|
|
void hide();
|
|
|
|
void resize(int,int,int,int);
|
2010-11-14 20:28:48 +03:00
|
|
|
int handle(int);
|
|
|
|
|
2008-09-14 02:33:03 +04:00
|
|
|
/**
|
2009-02-18 12:27:54 +03:00
|
|
|
Is turned off when FLTK creates a new context for this window or
|
|
|
|
when the window resizes, and is turned on \e after draw() is called.
|
|
|
|
You can use this inside your draw() method to avoid unnecessarily
|
|
|
|
initializing the OpenGL context. Just do this:
|
2008-09-15 23:21:20 +04:00
|
|
|
\code
|
2008-09-14 02:33:03 +04:00
|
|
|
void mywindow::draw() {
|
|
|
|
if (!valid()) {
|
|
|
|
glViewport(0,0,w(),h());
|
|
|
|
glFrustum(...);
|
|
|
|
...other initialization...
|
|
|
|
}
|
|
|
|
if (!context_valid()) {
|
|
|
|
...load textures, etc. ...
|
|
|
|
}
|
|
|
|
... draw your geometry here ...
|
|
|
|
}
|
2008-09-15 23:21:20 +04:00
|
|
|
\endcode
|
2008-09-14 02:33:03 +04:00
|
|
|
|
|
|
|
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.
|
|
|
|
*/
|
2006-08-17 13:49:43 +04:00
|
|
|
char valid() const {return valid_f_ & 1;}
|
2008-09-14 02:33:03 +04:00
|
|
|
/**
|
|
|
|
See char Fl_Gl_Window::valid() const
|
|
|
|
*/
|
2006-08-17 13:49:43 +04:00
|
|
|
void valid(char v) {if (v) valid_f_ |= 1; else valid_f_ &= 0xfe;}
|
2002-08-14 20:49:38 +04:00
|
|
|
void invalidate();
|
1998-10-06 22:21:25 +04:00
|
|
|
|
2008-09-14 02:33:03 +04:00
|
|
|
/**
|
|
|
|
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.
|
|
|
|
*/
|
2006-08-17 13:49:43 +04:00
|
|
|
char context_valid() const {return valid_f_ & 2;}
|
2008-09-14 02:33:03 +04:00
|
|
|
/**
|
|
|
|
See char Fl_Gl_Window::context_valid() const
|
|
|
|
*/
|
2006-08-17 13:49:43 +04:00
|
|
|
void context_valid(char v) {if (v) valid_f_ |= 2; else valid_f_ &= 0xfd;}
|
|
|
|
|
2009-02-18 12:27:54 +03:00
|
|
|
/** Returns non-zero if the hardware supports the given or current OpenGL mode. */
|
2002-08-09 07:17:30 +04:00
|
|
|
static int can_do(int m) {return can_do(m,0);}
|
2009-02-18 12:27:54 +03:00
|
|
|
/** Returns non-zero if the hardware supports the given or current OpenGL mode. */
|
2002-08-09 07:17:30 +04:00
|
|
|
static int can_do(const int *m) {return can_do(0, m);}
|
2009-02-18 12:27:54 +03:00
|
|
|
/** Returns non-zero if the hardware supports the given or current OpenGL mode. */
|
1998-10-06 22:21:25 +04:00
|
|
|
int can_do() {return can_do(mode_,alist);}
|
2008-09-14 02:33:03 +04:00
|
|
|
/**
|
|
|
|
Set or change the OpenGL capabilites of the window. The value can be
|
|
|
|
any of the following OR'd together:
|
2008-10-19 00:01:04 +04:00
|
|
|
|
|
|
|
- \c FL_RGB - RGB color (not indexed)
|
|
|
|
- \c FL_RGB8 - RGB color with at least 8 bits of each color
|
|
|
|
- \c FL_INDEX - Indexed mode
|
|
|
|
- \c FL_SINGLE - not double buffered
|
|
|
|
- \c FL_DOUBLE - double buffered
|
|
|
|
- \c FL_ACCUM - accumulation buffer
|
|
|
|
- \c FL_ALPHA - alpha channel in color
|
|
|
|
- \c FL_DEPTH - depth buffer
|
|
|
|
- \c FL_STENCIL - stencil buffer
|
|
|
|
- \c FL_MULTISAMPLE - multisample antialiasing
|
|
|
|
|
2008-09-14 02:33:03 +04:00
|
|
|
FL_RGB and FL_SINGLE have a value of zero, so they
|
2008-09-17 19:44:43 +04:00
|
|
|
are "on" unless you give FL_INDEX or FL_DOUBLE.
|
2008-10-19 00:01:04 +04:00
|
|
|
|
|
|
|
If the desired combination cannot be done, FLTK will try turning off
|
2008-09-14 02:33:03 +04:00
|
|
|
FL_MULTISAMPLE. If this also fails the show() will call
|
2008-10-19 00:01:04 +04:00
|
|
|
Fl::error() and not show the window.
|
|
|
|
|
|
|
|
You can change the mode while the window is displayed. This is most
|
2008-09-14 02:33:03 +04:00
|
|
|
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!
|
2008-10-19 00:01:04 +04:00
|
|
|
|
|
|
|
mode() must not be called within draw() since it
|
|
|
|
changes the current context.
|
2008-09-14 02:33:03 +04:00
|
|
|
*/
|
1998-10-06 22:21:25 +04:00
|
|
|
Fl_Mode mode() const {return (Fl_Mode)mode_;}
|
2008-09-18 04:15:35 +04:00
|
|
|
/** See Fl_Mode mode() const */
|
1998-10-06 22:21:25 +04:00
|
|
|
int mode(int a) {return mode(a,0);}
|
2008-09-18 04:15:35 +04:00
|
|
|
/** See Fl_Mode mode() const */
|
1998-10-06 22:21:25 +04:00
|
|
|
int mode(const int *a) {return mode(0, a);}
|
2008-09-18 04:15:35 +04:00
|
|
|
/** void See void context(void* v, int destroy_flag) */
|
2001-03-14 20:20:02 +03:00
|
|
|
void* context() const {return context_;}
|
2002-08-14 20:49:38 +04:00
|
|
|
void context(void*, int destroy_flag = 0);
|
|
|
|
void make_current();
|
|
|
|
void swap_buffers();
|
|
|
|
void ortho();
|
2001-03-14 20:20:02 +03:00
|
|
|
|
2008-09-14 02:33:03 +04:00
|
|
|
/**
|
|
|
|
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.
|
|
|
|
*/
|
2002-08-14 20:49:38 +04:00
|
|
|
int can_do_overlay();
|
2008-09-14 02:33:03 +04:00
|
|
|
/**
|
2009-02-18 12:27:54 +03:00
|
|
|
This method causes draw_overlay() to be called at a later time.
|
|
|
|
Initially the overlay is clear. If you want the window to display
|
2008-09-14 02:33:03 +04:00
|
|
|
something in the overlay when it first appears, you must call this
|
|
|
|
immediately after you show() your window.
|
|
|
|
*/
|
2002-08-14 20:49:38 +04:00
|
|
|
void redraw_overlay();
|
|
|
|
void hide_overlay();
|
2008-09-14 02:33:03 +04:00
|
|
|
/**
|
|
|
|
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.
|
|
|
|
*/
|
2002-08-14 20:49:38 +04:00
|
|
|
void make_overlay_current();
|
1998-10-06 22:21:25 +04:00
|
|
|
|
2011-01-01 17:01:53 +03:00
|
|
|
// Note: Doxygen docs in Fl_Widget.H to avoid redundancy.
|
2010-03-17 01:51:31 +03:00
|
|
|
virtual Fl_Gl_Window* as_gl_window() {return this;}
|
|
|
|
|
2002-08-14 20:49:38 +04:00
|
|
|
~Fl_Gl_Window();
|
2008-09-18 04:15:35 +04:00
|
|
|
/**
|
|
|
|
Creates a new Fl_Gl_Window widget using the given size, and label string.
|
|
|
|
The default boxtype is FL_NO_BOX. The default mode is FL_RGB|FL_DOUBLE|FL_DEPTH.
|
|
|
|
*/
|
|
|
|
Fl_Gl_Window(int W, int H, const char *l=0) : Fl_Window(W,H,l) {init();}
|
2008-09-14 02:33:03 +04:00
|
|
|
/**
|
|
|
|
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.
|
|
|
|
*/
|
2008-09-18 04:15:35 +04:00
|
|
|
|
1998-10-06 22:21:25 +04:00
|
|
|
Fl_Gl_Window(int X, int Y, int W, int H, const char *l=0)
|
|
|
|
: Fl_Window(X,Y,W,H,l) {init();}
|
2008-09-18 00:30:37 +04:00
|
|
|
|
2009-02-18 12:27:54 +03:00
|
|
|
protected:
|
|
|
|
/**
|
|
|
|
Draws the Fl_Gl_Window.
|
|
|
|
|
|
|
|
You \e \b must override the draw() method.
|
|
|
|
*/
|
2008-09-18 00:30:37 +04:00
|
|
|
virtual void draw();
|
1998-10-06 22:21:25 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|
1998-10-20 01:39:29 +04:00
|
|
|
|
|
|
|
//
|
2005-02-25 00:55:12 +03:00
|
|
|
// End of "$Id$".
|
1998-10-20 01:39:29 +04:00
|
|
|
//
|