|
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_Device_Plugin.cxx 7715 2010-10-11 18:10:32Z greg.ercolano $" 00003 // 00004 // implementation of class Fl_Gl_Device_Plugin for the Fast Light Tool Kit (FLTK). 00005 // 00006 // Copyright 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 to: 00024 // 00025 // http://www.fltk.org/str.php 00026 // 00027 00028 #include <config.h> 00029 #include <FL/Fl_Printer.H> 00030 #include <FL/Fl_Gl_Window.H> 00031 #include "Fl_Gl_Choice.H" 00032 #include "FL/Fl.H" 00033 #ifndef __APPLE__ 00034 #include "FL/fl_draw.H" 00035 #endif 00036 00037 #if defined(__APPLE__) 00038 static void imgProviderReleaseData (void *info, const void *data, size_t size) 00039 { 00040 free((void *)data); 00041 } 00042 #endif 00043 00044 static void print_gl_window(Fl_Gl_Window *glw, int x, int y, int height) 00045 { 00046 #ifdef WIN32 00047 HDC save_gc = fl_gc; 00048 const int bytesperpixel = 3; 00049 #elif defined(__APPLE__) 00050 CGContextRef save_gc = fl_gc; 00051 const int bytesperpixel = 4; 00052 #else 00053 _XGC *save_gc = fl_gc; 00054 const int bytesperpixel = 3; 00055 #endif 00056 fl_gc = NULL; 00057 #ifdef WIN32 00058 Fl::check(); 00059 Fl_Window *win = (Fl_Window*)glw; 00060 while( win->window() ) win = win->window(); 00061 win->redraw(); 00062 Fl::check(); 00063 glw->make_current(); 00064 #else 00065 glw->make_current(); 00066 glw->redraw(); 00067 glFlush(); 00068 Fl::check(); 00069 glFinish(); 00070 #endif 00071 // Read OpenGL context pixels directly. 00072 // For extra safety, save & restore OpenGL states that are changed 00073 glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT); 00074 glPixelStorei(GL_PACK_ALIGNMENT, 4); /* Force 4-byte alignment */ 00075 glPixelStorei(GL_PACK_ROW_LENGTH, 0); 00076 glPixelStorei(GL_PACK_SKIP_ROWS, 0); 00077 glPixelStorei(GL_PACK_SKIP_PIXELS, 0); 00078 // Read a block of pixels from the frame buffer 00079 int mByteWidth = glw->w() * bytesperpixel; 00080 mByteWidth = (mByteWidth + 3) & ~3; // Align to 4 bytes 00081 uchar *baseAddress = (uchar*)malloc(mByteWidth * glw->h()); 00082 glReadPixels(0, 0, glw->w(), glw->h(), 00083 #ifdef WIN32 00084 GL_RGB, GL_UNSIGNED_BYTE, 00085 #elif defined(__APPLE__) 00086 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 00087 #else // FIXME Linux/Unix 00088 GL_RGB, GL_UNSIGNED_BYTE, 00089 #endif 00090 baseAddress); 00091 glPopClientAttrib(); 00092 fl_gc = save_gc; 00093 #if defined(__APPLE__) 00094 // kCGBitmapByteOrder32Host and CGBitmapInfo are supposed to arrive with 10.4 00095 // but some 10.4 don't have kCGBitmapByteOrder32Host, so we play a little #define game 00096 #if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_4 00097 #define kCGBitmapByteOrder32Host 0 00098 #define CGBitmapInfo CGImageAlphaInfo 00099 #elif ! defined(kCGBitmapByteOrder32Host) 00100 #ifdef __BIG_ENDIAN__ 00101 #define kCGBitmapByteOrder32Host (4 << 12) 00102 #else /* Little endian. */ 00103 #define kCGBitmapByteOrder32Host (2 << 12) 00104 #endif 00105 #endif 00106 CGColorSpaceRef cSpace = CGColorSpaceCreateDeviceRGB(); 00107 CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, baseAddress, mByteWidth * glw->h(), imgProviderReleaseData); 00108 CGImageRef image = CGImageCreate(glw->w(), glw->h(), 8, 8*bytesperpixel, mByteWidth, cSpace, 00109 (CGBitmapInfo)(kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host), 00110 provider, NULL, false, kCGRenderingIntentDefault); 00111 if(image == NULL) return; 00112 CGContextSaveGState(fl_gc); 00113 CGContextTranslateCTM(fl_gc, 0, height); 00114 CGContextScaleCTM(fl_gc, 1.0f, -1.0f); 00115 CGRect rect = { { x, height - y - glw->h() }, { glw->w(), glw->h() } }; 00116 Fl_X::q_begin_image(rect, 0, 0, glw->w(), glw->h()); 00117 CGContextDrawImage(fl_gc, rect, image); 00118 Fl_X::q_end_image(); 00119 CGContextRestoreGState(fl_gc); 00120 CGImageRelease(image); 00121 CGColorSpaceRelease(cSpace); 00122 CGDataProviderRelease(provider); 00123 #else 00124 fl_draw_image(baseAddress + (glw->h() - 1) * mByteWidth, x, y , glw->w(), glw->h(), bytesperpixel, - mByteWidth); 00125 free(baseAddress); 00126 #endif // __APPLE__ 00127 } 00128 00133 class Fl_Gl_Device_Plugin : public Fl_Device_Plugin { 00134 public: 00135 Fl_Gl_Device_Plugin() : Fl_Device_Plugin(name()) { } 00136 virtual const char *name() { return "opengl.device.fltk.org"; } 00137 virtual int print(Fl_Widget *w, int x, int y, int height) { 00138 Fl_Gl_Window *glw = w->as_gl_window(); 00139 if (!glw) return 0; 00140 print_gl_window(glw, x, y, height); 00141 return 1; 00142 } 00143 }; 00144 00145 static Fl_Gl_Device_Plugin Gl_Device_Plugin; 00146 00147 // The purpose of this variable, used in Fl_Gl_Window.cxx, is only to force this file to be loaded 00148 // whenever Fl_Gl_Window.cxx is loaded, that is, whenever fltk_gl is. 00149 FL_EXPORT int fl_gl_load_plugin = 0; 00150 00151 // 00152 // End of "$Id: Fl_Gl_Device_Plugin.cxx 7715 2010-10-11 18:10:32Z greg.ercolano $". 00153 //