|
fltk 1.3.0rc3
About: FLTK (Fast Light Tool Kit) is a cross-platform C++ GUI toolkit for UNIX/Linux (X11), Microsoft Windows, and MacOS X. Release candidate.
SfR Fresh Dox: fltk-1.3.0rc3-source.tar.gz ("inofficial" and yet experimental doxygen-generated source code documentation) ![]() |
00001 // 00002 // "$Id: Fl_Gl_Overlay.cxx 7903 2010-11-28 21:06:39Z matt $" 00003 // 00004 // OpenGL overlay code for the Fast Light Tool Kit (FLTK). 00005 // 00006 // Copyright 1998-2010 by Bill Spitzak and others. 00007 // 00008 // This library is free software; you can redistribute it and/or 00009 // modify it under the terms of the GNU Library General Public 00010 // License as published by the Free Software Foundation; either 00011 // version 2 of the License, or (at your option) any later version. 00012 // 00013 // This library is distributed in the hope that it will be useful, 00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 // Library General Public License for more details. 00017 // 00018 // You should have received a copy of the GNU Library General Public 00019 // License along with this library; if not, write to the Free Software 00020 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00021 // USA. 00022 // 00023 // Please report all bugs and problems on the following page: 00024 // 00025 // http://www.fltk.org/str.php 00026 // 00027 00028 #include <config.h> 00029 #if HAVE_GL 00030 00031 #include <FL/Fl.H> 00032 #include <FL/x.H> 00033 #include "Fl_Gl_Choice.H" 00034 #include <FL/Fl_Gl_Window.H> 00035 #include <stdlib.h> 00036 00037 #if !HAVE_GL_OVERLAY 00038 00039 int Fl_Gl_Window::can_do_overlay() {return 0;} 00040 00041 void Fl_Gl_Window::make_overlay() {overlay = this;} 00042 00043 #else 00044 00045 // Methods on Fl_Gl_Window that create an overlay window. Because 00046 // many programs don't need the overlay, this is separated into this 00047 // source file so it is not linked in if not used. 00048 00049 // Under X this is done by creating another window, of class _Fl_Gl_Overlay 00050 // which is a subclass of Fl_Gl_Window except it uses the overlay planes. 00051 // A pointer to this is stored in the "overlay" pointer of the Fl_Gl_Window. 00052 00053 // Under win32 another GLX context is created to draw into the overlay 00054 // and it is stored in the "overlay" pointer. 00055 00056 // In both cases if overlay hardware is unavailable, the overlay is 00057 // "faked" by drawing into the main layers. This is indicated by 00058 // setting overlay == this. 00059 00060 #ifndef WIN32 00061 00062 // X version 00063 00064 extern XVisualInfo *fl_find_overlay_visual(); 00065 extern XVisualInfo *fl_overlay_visual; 00066 extern Colormap fl_overlay_colormap; 00067 extern unsigned long fl_transparent_pixel; 00068 extern uchar fl_overlay; 00069 00070 class _Fl_Gl_Overlay : public Fl_Gl_Window { 00071 void flush(); 00072 void draw(); 00073 public: 00074 void show(); 00075 _Fl_Gl_Overlay(int x, int y, int w, int h) : 00076 Fl_Gl_Window(x,y,w,h) { 00077 set_flag(INACTIVE); 00078 } 00079 }; 00080 00081 void _Fl_Gl_Overlay::flush() { 00082 make_current(); 00083 #ifdef BOXX_BUGS 00084 // The BoXX overlay is broken and you must not call swap-buffers. This 00085 // code will make it work, but we lose because machines that do support 00086 // double-buffered overlays will blink when they don't have to 00087 glDrawBuffer(GL_FRONT); 00088 draw(); 00089 #else 00090 draw(); 00091 swap_buffers(); 00092 #endif 00093 glFlush(); 00094 valid(1); 00095 } 00096 00097 void _Fl_Gl_Overlay::draw() { 00098 if (!valid()) glClearIndex((GLfloat)fl_transparent_pixel); 00099 if (damage() != FL_DAMAGE_EXPOSE) glClear(GL_COLOR_BUFFER_BIT); 00100 Fl_Gl_Window *w = (Fl_Gl_Window *)parent(); 00101 uchar save_valid = w->valid(); 00102 w->valid(valid()); 00103 fl_overlay = 1; 00104 w->draw_overlay(); 00105 fl_overlay = 0; 00106 valid(w->valid()); 00107 w->valid(save_valid); 00108 } 00109 00110 void _Fl_Gl_Overlay::show() { 00111 if (!shown()) { 00112 fl_background_pixel = int(fl_transparent_pixel); 00113 Fl_X::make_xid(this, fl_overlay_visual, fl_overlay_colormap); 00114 fl_background_pixel = -1; 00115 // find the outermost window to tell wm about the colormap: 00116 Fl_Window *w = window(); 00117 for (;;) {Fl_Window *w1 = w->window(); if (!w1) break; w = w1;} 00118 XSetWMColormapWindows(fl_display, fl_xid(w), &(Fl_X::i(this)->xid), 1); 00119 context(fl_create_gl_context(fl_overlay_visual), 1); 00120 valid(0); 00121 } 00122 Fl_Gl_Window::show(); 00123 } 00124 00125 int Fl_Gl_Window::can_do_overlay() { 00126 return fl_find_overlay_visual() != 0; 00127 } 00128 00129 void Fl_Gl_Window::make_overlay() { 00130 if (overlay) return; 00131 if (can_do_overlay()) { 00132 _Fl_Gl_Overlay* o = new _Fl_Gl_Overlay(0,0,w(),h()); 00133 overlay = o; 00134 add(*o); 00135 o->show(); 00136 } else { 00137 overlay = this; // fake the overlay 00138 } 00139 } 00140 00141 #else 00142 00143 // WIN32 version: 00144 00145 //static COLORREF *palette; 00146 extern int fl_overlay_depth; 00147 00148 void Fl_Gl_Window::make_overlay() { 00149 if (overlay) return; 00150 00151 GLContext context = fl_create_gl_context(this, g, 1); 00152 if (!context) {overlay = this; return;} // fake the overlay 00153 00154 HDC hdc = Fl_X::i(this)->private_dc; 00155 overlay = context; 00156 LAYERPLANEDESCRIPTOR pfd; 00157 wglDescribeLayerPlane(hdc, g->pixelformat, 1, sizeof(pfd), &pfd); 00158 if (!pfd.iPixelType) { 00159 ; // full-color overlay 00160 } else { 00161 fl_overlay_depth = pfd.cColorBits; // used by gl_color() 00162 if (fl_overlay_depth > 8) fl_overlay_depth = 8; 00163 COLORREF palette[256]; 00164 int n = (1<<fl_overlay_depth)-1; 00165 // copy all colors except #0 into the overlay palette: 00166 for (int i = 0; i <= n; i++) { 00167 uchar r,g,b; Fl::get_color((Fl_Color)i,r,g,b); 00168 palette[i] = RGB(r,g,b); 00169 } 00170 // always provide black & white in the last 2 pixels: 00171 if (fl_overlay_depth < 8) { 00172 palette[n-1] = RGB(0,0,0); 00173 palette[n] = RGB(255,255,255); 00174 } 00175 // and use it: 00176 wglSetLayerPaletteEntries(hdc, 1, 1, n, palette+1); 00177 wglRealizeLayerPalette(hdc, 1, TRUE); 00178 } 00179 valid(0); 00180 return; 00181 } 00182 00183 int Fl_Gl_Window::can_do_overlay() { 00184 if (!g) { 00185 g = Fl_Gl_Choice::find(mode_,alist); 00186 if (!g) return 0; 00187 } 00188 return (g->pfd.bReserved & 15) != 0; 00189 } 00190 00192 #endif 00193 00194 #endif 00195 00196 void Fl_Gl_Window::redraw_overlay() { 00197 if (!shown()) return; 00198 make_overlay(); 00199 #ifdef __APPLE__ 00200 redraw(); 00201 #else 00202 #ifndef WIN32 00203 if (overlay != this) 00204 ((Fl_Gl_Window*)overlay)->redraw(); 00205 else 00206 #endif 00207 damage(FL_DAMAGE_OVERLAY); 00208 #endif 00209 } 00210 00211 void Fl_Gl_Window::make_overlay_current() { 00212 make_overlay(); 00213 #ifdef __APPLE__ 00214 // this is not very useful, but unfortunately, Apple decided 00215 // that front buffer drawing can no longer (OS X 10.4) be 00216 // supported on their platforms. 00217 make_current(); 00218 #else 00219 #if HAVE_GL_OVERLAY 00220 if (overlay != this) { 00221 #ifdef WIN32 00222 fl_set_gl_context(this, (GLContext)overlay); 00223 // if (fl_overlay_depth) 00224 // wglRealizeLayerPalette(Fl_X::i(this)->private_dc, 1, TRUE); 00225 #else 00226 ((Fl_Gl_Window*)overlay)->make_current(); 00227 #endif 00228 } else 00229 #endif 00230 glDrawBuffer(GL_FRONT); 00231 #endif 00232 } 00234 void Fl_Gl_Window::hide_overlay() { 00235 #if HAVE_GL_OVERLAY 00236 #ifdef WIN32 00237 // nothing needs to be done? Or should it be erased? 00238 #else 00239 if (overlay && overlay!=this) ((Fl_Gl_Window*)overlay)->hide(); 00240 #endif 00241 #endif 00242 } 00243 00244 #endif 00245 00246 // 00247 // End of "$Id: Fl_Gl_Overlay.cxx 7903 2010-11-28 21:06:39Z matt $". 00248 //