1 // 2 // "$Id$" 3 // 4 // OpenGL header file for the Fast Light Tool Kit (FLTK). 5 // 6 // Copyright 1998-2015 by Bill Spitzak and others. 7 // 8 // This library is free software. Distribution and use rights are outlined in 9 // the file "COPYING" which should have been included with this file. If this 10 // file is missing or damaged, see the license at: 11 // 12 // http://www.fltk.org/COPYING.php 13 // 14 // Please report all bugs and problems on the following page: 15 // 16 // http://www.fltk.org/str.php 17 // 18 19 /* \file 20 Fl_Gl_Window widget . */ 21 22 #ifndef Fl_Gl_Window_H 23 #define Fl_Gl_Window_H 24 25 #include "Fl_Window.H" 26 27 #ifndef GLContext 28 /** 29 Opaque pointer type to hide system specific implementation. 30 */ 31 typedef void* GLContext; // actually a GLXContext or HGLDC 32 #endif 33 34 class Fl_Gl_Choice; // structure to hold result of glXChooseVisual 35 36 /** 37 The Fl_Gl_Window widget sets things up so OpenGL works. 38 39 It also keeps an OpenGL "context" for that window, so that changes to the 40 lighting and projection may be reused between redraws. Fl_Gl_Window 41 also flushes the OpenGL streams and swaps buffers after draw() returns. 42 43 OpenGL hardware typically provides some overlay bit planes, which 44 are very useful for drawing UI controls atop your 3D graphics. If the 45 overlay hardware is not provided, FLTK tries to simulate the overlay. 46 This works pretty well if your graphics are double buffered, but not 47 very well for single-buffered. 48 49 Please note that the FLTK drawing and clipping functions 50 will not work inside an Fl_Gl_Window. All drawing 51 should be done using OpenGL calls exclusively. 52 Even though Fl_Gl_Window is derived from Fl_Group, 53 it is not useful to add other FLTK Widgets as children, 54 unless those widgets are modified to draw using OpenGL calls. 55 */ 56 class FL_EXPORT Fl_Gl_Window : public Fl_Window { 57 58 int mode_; 59 const int *alist; 60 Fl_Gl_Choice *g; 61 GLContext context_; 62 char valid_f_; 63 char damage1_; // damage() of back buffer 64 virtual void draw_overlay(); 65 void init(); 66 67 void *overlay; 68 void make_overlay(); 69 friend class _Fl_Gl_Overlay; 70 71 static int can_do(int, const int *); 72 int mode(int, const int *); 73 static int gl_plugin_linkage(); 74 75 public: 76 77 void show(); show(int a,char ** b)78 void show(int a, char **b) {Fl_Window::show(a,b);} 79 void flush(); 80 void hide(); 81 void resize(int,int,int,int); 82 int handle(int); 83 84 /** 85 Is turned off when FLTK creates a new context for this window or 86 when the window resizes, and is turned on \e after draw() is called. 87 You can use this inside your draw() method to avoid unnecessarily 88 initializing the OpenGL context. Just do this: 89 \code 90 void mywindow::draw() { 91 if (!valid()) { 92 glViewport(0,0,pixel_w(),pixel_h()); 93 glFrustum(...); 94 ...other initialization... 95 } 96 if (!context_valid()) { 97 ...load textures, etc. ... 98 } 99 ... draw your geometry here ... 100 } 101 \endcode 102 103 You can turn valid() on by calling valid(1). You 104 should only do this after fixing the transformation inside a draw() 105 or after make_current(). This is done automatically after 106 draw() returns. 107 */ valid()108 char valid() const {return valid_f_ & 1;} 109 /** 110 See char Fl_Gl_Window::valid() const 111 */ valid(char v)112 void valid(char v) {if (v) valid_f_ |= 1; else valid_f_ &= 0xfe;} 113 void invalidate(); 114 115 /** 116 Will only be set if the 117 OpenGL context is created or recreated. It differs from 118 Fl_Gl_Window::valid() which is also set whenever the context 119 changes size. 120 */ context_valid()121 char context_valid() const {return valid_f_ & 2;} 122 /** 123 See char Fl_Gl_Window::context_valid() const 124 */ context_valid(char v)125 void context_valid(char v) {if (v) valid_f_ |= 2; else valid_f_ &= 0xfd;} 126 127 /** Returns non-zero if the hardware supports the given OpenGL mode. */ can_do(int m)128 static int can_do(int m) {return can_do(m,0);} 129 /** Returns non-zero if the hardware supports the given OpenGL mode. 130 \see Fl_Gl_Window::mode(const int *a) */ can_do(const int * m)131 static int can_do(const int *m) {return can_do(0, m);} 132 /** Returns non-zero if the hardware supports the current OpenGL mode. */ can_do()133 int can_do() {return can_do(mode_,alist);} 134 /** Returns the current OpenGL capabilites of the window. 135 Don't use this if capabilities were set through Fl_Gl_Window::mode(const int *a). 136 */ mode()137 Fl_Mode mode() const {return (Fl_Mode)mode_;} 138 /** 139 Set or change the OpenGL capabilites of the window. The value can be 140 any of the following OR'd together: 141 142 - \c FL_RGB - RGB color (not indexed) 143 - \c FL_RGB8 - RGB color with at least 8 bits of each color 144 - \c FL_INDEX - Indexed mode 145 - \c FL_SINGLE - not double buffered 146 - \c FL_DOUBLE - double buffered 147 - \c FL_ACCUM - accumulation buffer 148 - \c FL_ALPHA - alpha channel in color 149 - \c FL_DEPTH - depth buffer 150 - \c FL_STENCIL - stencil buffer 151 - \c FL_MULTISAMPLE - multisample antialiasing 152 - \c FL_OPENGL3 - use OpenGL version 3.0 or more. 153 154 FL_RGB and FL_SINGLE have a value of zero, so they 155 are "on" unless you give FL_INDEX or FL_DOUBLE. 156 157 If the desired combination cannot be done, FLTK will try turning off 158 FL_MULTISAMPLE. If this also fails the show() will call 159 Fl::error() and not show the window. 160 161 You can change the mode while the window is displayed. This is most 162 useful for turning double-buffering on and off. Under X this will 163 cause the old X window to be destroyed and a new one to be created. If 164 this is a top-level window this will unfortunately also cause the 165 window to blink, raise to the top, and be de-iconized, and the xid() 166 will change, possibly breaking other code. It is best to make the GL 167 window a child of another window if you wish to do this! 168 169 mode() must not be called within draw() since it 170 changes the current context. 171 172 The FL_OPENGL3 flag is required to access OpenGL version 3 or more 173 under the X11 and MacOS platforms; it's optional under Windows. 174 See more details in \ref opengl3. 175 176 \version the <tt>FL_OPENGL3</tt> flag appeared in version 1.3.4 177 */ mode(int a)178 int mode(int a) {return mode(a,0);} 179 /** Set the OpenGL capabilites of the window using platform-specific data. 180 \param a zero-ending array of platform-specific attributes and attribute values 181 <p><b>Unix/Linux platform</b>: attributes are GLX attributes adequate for the 3rd argument of 182 the <tt>glXChooseVisual()</tt> function (e.g., <tt>GLX_DOUBLEBUFFER</tt>, defined by including <GL/glx.h>). 183 \note What attributes are adequate here is subject to change. 184 The preferred, stable public API is Fl_Gl_Window::mode(int a). 185 <p><b>MSWindows platform</b>: this member function is of no use. 186 <p><b>Mac OS X platform</b>: attributes belong to the <tt>CGLPixelFormatAttribute</tt> enumeration 187 (defined by including <tt><OpenGL/OpenGL.h></tt>, e.g., <tt>kCGLPFADoubleBuffer</tt>) 188 and may be followed by adequate attribute values. 189 */ mode(const int * a)190 int mode(const int *a) {return mode(0, a);} 191 /** Returns a pointer to the GLContext that this window is using. 192 \see void context(void* v, int destroy_flag) */ context()193 void* context() const {return context_;} 194 void context(void*, int destroy_flag = 0); 195 void make_current(); 196 void swap_buffers(); 197 void ortho(); 198 199 /** 200 Returns true if the hardware overlay is possible. If this is false, 201 FLTK will try to simulate the overlay, with significant loss of update 202 speed. Calling this will cause FLTK to open the display. 203 */ 204 int can_do_overlay(); 205 /** 206 This method causes draw_overlay() to be called at a later time. 207 Initially the overlay is clear. If you want the window to display 208 something in the overlay when it first appears, you must call this 209 immediately after you show() your window. 210 */ 211 void redraw_overlay(); 212 void hide_overlay(); 213 /** 214 The make_overlay_current() method selects the OpenGL context 215 for the widget's overlay. It is called automatically prior to the 216 draw_overlay() method being called and can also be used to 217 implement feedback and/or selection within the handle() 218 method. 219 */ 220 void make_overlay_current(); 221 222 // Note: Doxygen docs in Fl_Widget.H to avoid redundancy. as_gl_window()223 virtual Fl_Gl_Window* as_gl_window() {return this;} 224 225 /** The number of pixels per FLTK unit of length for the window. 226 Returns 1, except for a window mapped to 227 an Apple 'retina' display, and if Fl::use_high_res_GL(bool) is set to true, 228 when it returns 2. This method dynamically adjusts its value when the window 229 is moved to/from a retina display. This method is useful, e.g., to convert, 230 in a window's handle() method, the FLTK units returned by Fl::event_x() and 231 Fl::event_y() to the pixel units used by the OpenGL source code. 232 \version 1.3.4 233 */ 234 #ifdef __APPLE__ 235 float pixels_per_unit(); 236 #else pixels_per_unit()237 float pixels_per_unit() { return 1; } 238 #endif 239 /** Gives the window width in OpenGL pixels. 240 Generally identical with the result of the w() function, but for a window mapped to 241 an Apple 'retina' display, and if Fl::use_high_res_GL(bool) is set to true, 242 pixel_w() returns 2 * w(). This method detects when the window has been moved 243 between low and high resolution displays and automatically adjusts the returned value. 244 \version 1.3.4 245 */ pixel_w()246 int pixel_w() { return int(pixels_per_unit() * w() + 0.5); } 247 /** Gives the window height in OpenGL pixels. 248 Generally identical with the result of the h() function, but for a window mapped to 249 an Apple 'retina' display, and if Fl::use_high_res_GL(bool) is set to true, 250 pixel_h() returns 2 * h(). This method detects when the window has been moved 251 between low and high resolution displays and automatically adjusts the returned value. 252 \version 1.3.4 253 */ pixel_h()254 int pixel_h() { return int(pixels_per_unit() * h() + 0.5); } 255 256 ~Fl_Gl_Window(); 257 /** 258 Creates a new Fl_Gl_Window widget using the given size, and label string. 259 The default boxtype is FL_NO_BOX. The default mode is FL_RGB|FL_DOUBLE|FL_DEPTH. 260 */ Fl_Window(W,H,l)261 Fl_Gl_Window(int W, int H, const char *l=0) : Fl_Window(W,H,l) {init();} 262 /** 263 Creates a new Fl_Gl_Window widget using the given position, 264 size, and label string. The default boxtype is FL_NO_BOX. The 265 default mode is FL_RGB|FL_DOUBLE|FL_DEPTH. 266 */ 267 268 Fl_Gl_Window(int X, int Y, int W, int H, const char *l=0) Fl_Window(X,Y,W,H,l)269 : Fl_Window(X,Y,W,H,l) {init();} 270 271 protected: 272 /** 273 Draws the Fl_Gl_Window. 274 275 You \e \b must override the draw() method. 276 */ 277 virtual void draw(); 278 }; 279 280 #endif 281 282 // 283 // End of "$Id$". 284 // 285