DRC | 2ff39b8 | 2011-07-28 08:38:59 +0000 | [diff] [blame^] | 1 | // |
| 2 | // "$Id: Fl_Gl_Window.H 8157 2011-01-01 14:01:53Z AlbrechtS $" |
| 3 | // |
| 4 | // OpenGL header file for the Fast Light Tool Kit (FLTK). |
| 5 | // |
| 6 | // Copyright 1998-2010 by Bill Spitzak and others. |
| 7 | // |
| 8 | // This library is free software; you can redistribute it and/or |
| 9 | // modify it under the terms of the GNU Library General Public |
| 10 | // License as published by the Free Software Foundation; either |
| 11 | // version 2 of the License, or (at your option) any later version. |
| 12 | // |
| 13 | // This library is distributed in the hope that it will be useful, |
| 14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 16 | // Library General Public License for more details. |
| 17 | // |
| 18 | // You should have received a copy of the GNU Library General Public |
| 19 | // License along with this library; if not, write to the Free Software |
| 20 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 |
| 21 | // USA. |
| 22 | // |
| 23 | // Please report all bugs and problems on the following page: |
| 24 | // |
| 25 | // http://www.fltk.org/str.php |
| 26 | // |
| 27 | |
| 28 | /* \file |
| 29 | Fl_Gl_Window widget . */ |
| 30 | |
| 31 | #ifndef Fl_Gl_Window_H |
| 32 | #define Fl_Gl_Window_H |
| 33 | |
| 34 | #include "Fl_Window.H" |
| 35 | |
| 36 | #ifndef GLContext |
| 37 | /** |
| 38 | Opaque pointer type to hide system specific implementation. |
| 39 | */ |
| 40 | typedef void* GLContext; // actually a GLXContext or HGLDC |
| 41 | #endif |
| 42 | |
| 43 | class Fl_Gl_Choice; // structure to hold result of glXChooseVisual |
| 44 | |
| 45 | /** |
| 46 | The Fl_Gl_Window widget sets things up so OpenGL works. |
| 47 | |
| 48 | It also keeps an OpenGL "context" for that window, so that changes to the |
| 49 | lighting and projection may be reused between redraws. Fl_Gl_Window |
| 50 | also flushes the OpenGL streams and swaps buffers after draw() returns. |
| 51 | |
| 52 | OpenGL hardware typically provides some overlay bit planes, which |
| 53 | are very useful for drawing UI controls atop your 3D graphics. If the |
| 54 | overlay hardware is not provided, FLTK tries to simulate the overlay. |
| 55 | This works pretty well if your graphics are double buffered, but not |
| 56 | very well for single-buffered. |
| 57 | |
| 58 | Please note that the FLTK drawing and clipping functions |
| 59 | will not work inside an Fl_Gl_Window. All drawing |
| 60 | should be done using OpenGL calls exclusively. |
| 61 | Even though Fl_Gl_Window is derived from Fl_Group, |
| 62 | it is not useful to add other FLTK Widgets as children, |
| 63 | unless those widgets are modified to draw using OpenGL calls. |
| 64 | */ |
| 65 | class FL_EXPORT Fl_Gl_Window : public Fl_Window { |
| 66 | |
| 67 | int mode_; |
| 68 | const int *alist; |
| 69 | Fl_Gl_Choice *g; |
| 70 | GLContext context_; |
| 71 | char valid_f_; |
| 72 | char damage1_; // damage() of back buffer |
| 73 | virtual void draw_overlay(); |
| 74 | void init(); |
| 75 | |
| 76 | void *overlay; |
| 77 | void make_overlay(); |
| 78 | friend class _Fl_Gl_Overlay; |
| 79 | |
| 80 | static int can_do(int, const int *); |
| 81 | int mode(int, const int *); |
| 82 | |
| 83 | public: |
| 84 | |
| 85 | void show(); |
| 86 | void show(int a, char **b) {Fl_Window::show(a,b);} |
| 87 | void flush(); |
| 88 | void hide(); |
| 89 | void resize(int,int,int,int); |
| 90 | int handle(int); |
| 91 | |
| 92 | /** |
| 93 | Is turned off when FLTK creates a new context for this window or |
| 94 | when the window resizes, and is turned on \e after draw() is called. |
| 95 | You can use this inside your draw() method to avoid unnecessarily |
| 96 | initializing the OpenGL context. Just do this: |
| 97 | \code |
| 98 | void mywindow::draw() { |
| 99 | if (!valid()) { |
| 100 | glViewport(0,0,w(),h()); |
| 101 | glFrustum(...); |
| 102 | ...other initialization... |
| 103 | } |
| 104 | if (!context_valid()) { |
| 105 | ...load textures, etc. ... |
| 106 | } |
| 107 | ... draw your geometry here ... |
| 108 | } |
| 109 | \endcode |
| 110 | |
| 111 | You can turn valid() on by calling valid(1). You |
| 112 | should only do this after fixing the transformation inside a draw() |
| 113 | or after make_current(). This is done automatically after |
| 114 | draw() returns. |
| 115 | */ |
| 116 | char valid() const {return valid_f_ & 1;} |
| 117 | /** |
| 118 | See char Fl_Gl_Window::valid() const |
| 119 | */ |
| 120 | void valid(char v) {if (v) valid_f_ |= 1; else valid_f_ &= 0xfe;} |
| 121 | void invalidate(); |
| 122 | |
| 123 | /** |
| 124 | Will only be set if the |
| 125 | OpenGL context is created or recreated. It differs from |
| 126 | Fl_Gl_Window::valid() which is also set whenever the context |
| 127 | changes size. |
| 128 | */ |
| 129 | char context_valid() const {return valid_f_ & 2;} |
| 130 | /** |
| 131 | See char Fl_Gl_Window::context_valid() const |
| 132 | */ |
| 133 | void context_valid(char v) {if (v) valid_f_ |= 2; else valid_f_ &= 0xfd;} |
| 134 | |
| 135 | /** Returns non-zero if the hardware supports the given or current OpenGL mode. */ |
| 136 | static int can_do(int m) {return can_do(m,0);} |
| 137 | /** Returns non-zero if the hardware supports the given or current OpenGL mode. */ |
| 138 | static int can_do(const int *m) {return can_do(0, m);} |
| 139 | /** Returns non-zero if the hardware supports the given or current OpenGL mode. */ |
| 140 | int can_do() {return can_do(mode_,alist);} |
| 141 | /** |
| 142 | Set or change the OpenGL capabilites of the window. The value can be |
| 143 | any of the following OR'd together: |
| 144 | |
| 145 | - \c FL_RGB - RGB color (not indexed) |
| 146 | - \c FL_RGB8 - RGB color with at least 8 bits of each color |
| 147 | - \c FL_INDEX - Indexed mode |
| 148 | - \c FL_SINGLE - not double buffered |
| 149 | - \c FL_DOUBLE - double buffered |
| 150 | - \c FL_ACCUM - accumulation buffer |
| 151 | - \c FL_ALPHA - alpha channel in color |
| 152 | - \c FL_DEPTH - depth buffer |
| 153 | - \c FL_STENCIL - stencil buffer |
| 154 | - \c FL_MULTISAMPLE - multisample antialiasing |
| 155 | |
| 156 | FL_RGB and FL_SINGLE have a value of zero, so they |
| 157 | are "on" unless you give FL_INDEX or FL_DOUBLE. |
| 158 | |
| 159 | If the desired combination cannot be done, FLTK will try turning off |
| 160 | FL_MULTISAMPLE. If this also fails the show() will call |
| 161 | Fl::error() and not show the window. |
| 162 | |
| 163 | You can change the mode while the window is displayed. This is most |
| 164 | useful for turning double-buffering on and off. Under X this will |
| 165 | cause the old X window to be destroyed and a new one to be created. If |
| 166 | this is a top-level window this will unfortunately also cause the |
| 167 | window to blink, raise to the top, and be de-iconized, and the xid() |
| 168 | will change, possibly breaking other code. It is best to make the GL |
| 169 | window a child of another window if you wish to do this! |
| 170 | |
| 171 | mode() must not be called within draw() since it |
| 172 | changes the current context. |
| 173 | */ |
| 174 | Fl_Mode mode() const {return (Fl_Mode)mode_;} |
| 175 | /** See Fl_Mode mode() const */ |
| 176 | int mode(int a) {return mode(a,0);} |
| 177 | /** See Fl_Mode mode() const */ |
| 178 | int mode(const int *a) {return mode(0, a);} |
| 179 | /** void See void context(void* v, int destroy_flag) */ |
| 180 | void* context() const {return context_;} |
| 181 | void context(void*, int destroy_flag = 0); |
| 182 | void make_current(); |
| 183 | void swap_buffers(); |
| 184 | void ortho(); |
| 185 | |
| 186 | /** |
| 187 | Returns true if the hardware overlay is possible. If this is false, |
| 188 | FLTK will try to simulate the overlay, with significant loss of update |
| 189 | speed. Calling this will cause FLTK to open the display. |
| 190 | */ |
| 191 | int can_do_overlay(); |
| 192 | /** |
| 193 | This method causes draw_overlay() to be called at a later time. |
| 194 | Initially the overlay is clear. If you want the window to display |
| 195 | something in the overlay when it first appears, you must call this |
| 196 | immediately after you show() your window. |
| 197 | */ |
| 198 | void redraw_overlay(); |
| 199 | void hide_overlay(); |
| 200 | /** |
| 201 | The make_overlay_current() method selects the OpenGL context |
| 202 | for the widget's overlay. It is called automatically prior to the |
| 203 | draw_overlay() method being called and can also be used to |
| 204 | implement feedback and/or selection within the handle() |
| 205 | method. |
| 206 | */ |
| 207 | void make_overlay_current(); |
| 208 | |
| 209 | // Note: Doxygen docs in Fl_Widget.H to avoid redundancy. |
| 210 | virtual Fl_Gl_Window* as_gl_window() {return this;} |
| 211 | |
| 212 | ~Fl_Gl_Window(); |
| 213 | /** |
| 214 | Creates a new Fl_Gl_Window widget using the given size, and label string. |
| 215 | The default boxtype is FL_NO_BOX. The default mode is FL_RGB|FL_DOUBLE|FL_DEPTH. |
| 216 | */ |
| 217 | Fl_Gl_Window(int W, int H, const char *l=0) : Fl_Window(W,H,l) {init();} |
| 218 | /** |
| 219 | Creates a new Fl_Gl_Window widget using the given position, |
| 220 | size, and label string. The default boxtype is FL_NO_BOX. The |
| 221 | default mode is FL_RGB|FL_DOUBLE|FL_DEPTH. |
| 222 | */ |
| 223 | |
| 224 | Fl_Gl_Window(int X, int Y, int W, int H, const char *l=0) |
| 225 | : Fl_Window(X,Y,W,H,l) {init();} |
| 226 | |
| 227 | protected: |
| 228 | /** |
| 229 | Draws the Fl_Gl_Window. |
| 230 | |
| 231 | You \e \b must override the draw() method. |
| 232 | */ |
| 233 | virtual void draw(); |
| 234 | }; |
| 235 | |
| 236 | #endif |
| 237 | |
| 238 | // |
| 239 | // End of "$Id: Fl_Gl_Window.H 8157 2011-01-01 14:01:53Z AlbrechtS $". |
| 240 | // |