|
Author: matt
Date: 2011-08-25 03:53:58 -0700 (Thu, 25 Aug 2011)
New Revision: 9009
Log:
More OpenGL renaming
Added:
branches/branch-3.0/include/fltk3gl/GL_Window.h
branches/branch-3.0/src/fltk3gl/GL_Choice.cxx
branches/branch-3.0/src/fltk3gl/GL_Choice.h
branches/branch-3.0/src/fltk3gl/GL_DevicePlugin.cxx
branches/branch-3.0/src/fltk3gl/GL_Overlay.cxx
branches/branch-3.0/src/fltk3gl/GL_Window.cxx
Removed:
branches/branch-3.0/include/fltk3gl/GlWindow.h
branches/branch-3.0/src/fltk3gl/GlChoice.cxx
branches/branch-3.0/src/fltk3gl/GlChoice.h
branches/branch-3.0/src/fltk3gl/GlDevicePlugin.cxx
branches/branch-3.0/src/fltk3gl/GlOverlay.cxx
branches/branch-3.0/src/fltk3gl/GlWindow.cxx
Copied: branches/branch-3.0/include/fltk3gl/GL_Window.h (from rev 9008, branches/branch-3.0/include/fltk3gl/GlWindow.h)
===================================================================
--- branches/branch-3.0/include/fltk3gl/GL_Window.h (rev 0)
+++ branches/branch-3.0/include/fltk3gl/GL_Window.h 2011-08-25 10:53:58 UTC (rev 9009)
@@ -0,0 +1,248 @@
+//
+// "$Id: GlWindow.h 8157 2011-01-01 14:01:53Z AlbrechtS $"
+//
+// OpenGL header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2010 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+// http://www.fltk.org/str.php
+//
+
+/* \file
+ fltk3::GlWindow widget . */
+
+#ifndef Fltk3_Gl_Window_H
+#define Fltk3_Gl_Window_H
+
+#include "Window.h"
+
+#ifndef GLContext
+/**
+ Opaque pointer type to hide system specific implementation.
+ */
+typedef void* GLContext; // actually a GLXContext or HGLDC
+#endif
+
+class Fl_Gl_Window;
+
+namespace fltk3 {
+
+ class GlChoice; // structure to hold result of glXChooseVisual
+
+ /**
+ The fltk3::GlWindow widget sets things up so OpenGL works.
+
+ It also keeps an OpenGL "context" for that window, so that changes to the
+ lighting and projection may be reused between redraws. fltk3::GlWindow
+ also flushes the OpenGL streams and swaps buffers after draw() returns.
+
+ OpenGL hardware typically provides some overlay bit planes, which
+ are very useful for drawing UI controls atop your 3D graphics. If the
+ overlay hardware is not provided, FLTK tries to simulate the overlay.
+ This works pretty well if your graphics are double buffered, but not
+ very well for single-buffered.
+
+ Please note that the FLTK drawing and clipping functions
+ will not work inside an fltk3::GlWindow. All drawing
+ should be done using OpenGL calls exclusively.
+ Even though fltk3::GlWindow is derived from fltk3::Group,
+ it is not useful to add other FLTK Widgets as children,
+ unless those widgets are modified to draw using OpenGL calls.
+ */
+ class FLTK3_EXPORT GlWindow : public fltk3::Window {
+
+ friend class ::Fl_Gl_Window;
+
+ int mode_;
+ const int *alist;
+ GlChoice *g;
+ GLContext context_;
+ char valid_f_;
+ char damage1_; // damage() of back buffer
+ virtual void draw_overlay();
+ void init();
+
+ void *overlay;
+ void make_overlay();
+ friend class _Fl_Gl_Overlay;
+
+ static int can_do(int, const int *);
+ int mode(int, const int *);
+
+ public:
+
+ void show();
+ void show(int a, char **b) {Window::show(a,b);}
+ void flush();
+ void hide();
+ void resize(int,int,int,int);
+ int handle(int);
+
+ /**
+ 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:
+ \code
+ void mywindow::draw() {
+ if (!valid()) {
+ glViewport(0,0,w(),h());
+ glFrustum(...);
+ ...other initialization...
+ }
+ if (!context_valid()) {
+ ...load textures, etc. ...
+ }
+ ... draw your geometry here ...
+ }
+ \endcode
+
+ 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.
+ */
+ char valid() const {return valid_f_ & 1;}
+ /**
+ See char fltk3::GlWindow::valid() const
+ */
+ void valid(char v) {if (v) valid_f_ |= 1; else valid_f_ &= 0xfe;}
+ void invalidate();
+
+ /**
+ Will only be set if the
+ OpenGL context is created or recreated. It differs from
+ fltk3::GlWindow::valid() which is also set whenever the context
+ changes size.
+ */
+ char context_valid() const {return valid_f_ & 2;}
+ /**
+ See char fltk3::GlWindow::context_valid() const
+ */
+ void context_valid(char v) {if (v) valid_f_ |= 2; else valid_f_ &= 0xfd;}
+
+ /** Returns non-zero if the hardware supports the given or current OpenGL mode. */
+ static int can_do(int m) {return can_do(m,0);}
+ /** Returns non-zero if the hardware supports the given or current OpenGL mode. */
+ static int can_do(const int *m) {return can_do(0, m);}
+ /** Returns non-zero if the hardware supports the given or current OpenGL mode. */
+ int can_do() {return can_do(mode_,alist);}
+ /**
+ Set or change the OpenGL capabilites of the window. The value can be
+ any of the following OR'd together:
+
+ - \c fltk3::RGB - RGB color (not indexed)
+ - \c fltk3::RGB8 - RGB color with at least 8 bits of each color
+ - \c fltk3::INDEX - Indexed mode
+ - \c fltk3::SINGLE - not double buffered
+ - \c fltk3::DOUBLE - double buffered
+ - \c fltk3::ACCUM - accumulation buffer
+ - \c fltk3::ALPHA - alpha channel in color
+ - \c fltk3::DEPTH - depth buffer
+ - \c fltk3::STENCIL - stencil buffer
+ - \c fltk3::MULTISAMPLE - multisample antialiasing
+
+ fltk3::RGB and fltk3::SINGLE have a value of zero, so they
+ are "on" unless you give fltk3::INDEX or fltk3::DOUBLE.
+
+ If the desired combination cannot be done, FLTK will try turning off
+ fltk3::MULTISAMPLE. If this also fails the show() will call
+ fltk3::error() and not show the window.
+
+ You can change the mode while the window is displayed. This is most
+ 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!
+
+ mode() must not be called within draw() since it
+ changes the current context.
+ */
+ fltk3::Mode mode() const {return (fltk3::Mode)mode_;}
+ /** See fltk3::Mode mode() const */
+ int mode(int a) {return mode(a,0);}
+ /** See fltk3::Mode mode() const */
+ int mode(const int *a) {return mode(0, a);}
+ /** void See void context(void* v, int destroy_flag) */
+ void* context() const {return context_;}
+ void context(void*, int destroy_flag = 0);
+ void make_current();
+ void swap_buffers();
+ void ortho();
+
+ /**
+ 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.
+ */
+ int can_do_overlay();
+ /**
+ This method causes draw_overlay() to be called at a later time.
+ Initially the overlay is clear. If you want the window to display
+ something in the overlay when it first appears, you must call this
+ immediately after you show() your window.
+ */
+ void redraw_overlay();
+ void hide_overlay();
+ /**
+ 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.
+ */
+ void make_overlay_current();
+
+ // Note: Doxygen docs in Widget.h to avoid redundancy.
+ virtual fltk3::GlWindow* as_gl_window() {return this;}
+
+ ~GlWindow();
+ /**
+ Creates a new fltk3::GlWindow widget using the given size, and label string.
+ The default boxtype is fltk3::NO_BOX. The default mode is fltk3::RGB|fltk3::DOUBLE|fltk3::DEPTH.
+ */
+ GlWindow(int W, int H, const char *l=0) : fltk3::Window(W,H,l) {init();}
+ /**
+ Creates a new fltk3::GlWindow widget using the given position,
+ size, and label string. The default boxtype is fltk3::NO_BOX. The
+ default mode is fltk3::RGB|fltk3::DOUBLE|fltk3::DEPTH.
+ */
+
+ GlWindow(int X, int Y, int W, int H, const char *l=0)
+ : fltk3::Window(X,Y,W,H,l) {init();}
+
+ protected:
+ /**
+ Draws the fltk3::GlWindow.
+
+ You \e \b must override the draw() method.
+ */
+ virtual void draw();
+ };
+
+}
+
+#endif
+
+//
+// End of "$Id: GlWindow.h 8157 2011-01-01 14:01:53Z AlbrechtS $".
+//
Deleted: branches/branch-3.0/include/fltk3gl/GlWindow.h
Copied: branches/branch-3.0/src/fltk3gl/GL_Choice.cxx (from rev 9008, branches/branch-3.0/src/fltk3gl/GlChoice.cxx)
===================================================================
--- branches/branch-3.0/src/fltk3gl/GL_Choice.cxx (rev 0)
+++ branches/branch-3.0/src/fltk3gl/GL_Choice.cxx 2011-08-25 10:53:58 UTC (rev 9009)
@@ -0,0 +1,426 @@
+//
+// "$Id$"
+//
+// OpenGL visual selection code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2010 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+// http://www.fltk.org/str.php
+//
+
+#include <config.h>
+#if HAVE_GL
+
+# include <fltk3/run.h>
+# include <fltk3/x.h>
+# include <stdlib.h>
+# include "Fl_Gl_Choice.H"
+# include <fltk3/glDraw.h>
+# include "flstring.h"
+# include <fltk3/utf8.h>
+
+# ifdef __APPLE__
+# include <ApplicationServices/ApplicationServices.h>
+# include <fltk3/Window.h>
+# endif
+
+# ifdef WIN32
+void fl_save_dc(HWND, HDC);
+# endif
+
+static fltk3::GlChoice *first;
+
+// this assumes one of the two arguments is zero:
+// We keep the list system in Win32 to stay compatible and interpret
+// the list later...
+fltk3::GlChoice *fltk3::GlChoice::find(int m, const int *alistp) {
+ fltk3::GlChoice *g;
+
+ for (g = first; g; g = g->next)
+ if (g->mode == m && g->alist == alistp)
+ return g;
+
+#if defined(USE_X11)
+ const int *blist;
+ int list[32];
+
+ if (alistp)
+ blist = alistp;
+ else {
+ int n = 0;
+ if (m & fltk3::INDEX) {
+ list[n++] = GLX_BUFFER_SIZE;
+ list[n++] = 8; // glut tries many sizes, but this should work...
+ } else {
+ list[n++] = GLX_RGBA;
+ list[n++] = GLX_GREEN_SIZE;
+ list[n++] = (m & fltk3::RGB8) ? 8 : 1;
+ if (m & fltk3::ALPHA) {
+ list[n++] = GLX_ALPHA_SIZE;
+ list[n++] = (m & fltk3::RGB8) ? 8 : 1;
+ }
+ if (m & fltk3::ACCUM) {
+ list[n++] = GLX_ACCUM_GREEN_SIZE;
+ list[n++] = 1;
+ if (m & fltk3::ALPHA) {
+ list[n++] = GLX_ACCUM_ALPHA_SIZE;
+ list[n++] = 1;
+ }
+ }
+ }
+ if (m & fltk3::DOUBLE) {
+ list[n++] = GLX_DOUBLEBUFFER;
+ }
+ if (m & fltk3::DEPTH) {
+ list[n++] = GLX_DEPTH_SIZE; list[n++] = 1;
+ }
+ if (m & fltk3::STENCIL) {
+ list[n++] = GLX_STENCIL_SIZE; list[n++] = 1;
+ }
+ if (m & fltk3::STEREO) {
+ list[n++] = GLX_STEREO;
+ }
+# if defined(GLX_VERSION_1_1) && defined(GLX_SGIS_multisample)
+ if (m & fltk3::MULTISAMPLE) {
+ list[n++] = GLX_SAMPLES_SGIS;
+ list[n++] = 4; // value Glut uses
+ }
+# endif
+ list[n] = 0;
+ blist = list;
+ }
+
+ fl_open_display();
+ XVisualInfo *visp = glXChooseVisual(fl_display, fl_screen, (int *)blist);
+ if (!visp) {
+# if defined(GLX_VERSION_1_1) && defined(GLX_SGIS_multisample)
+ if (m&fltk3::MULTISAMPLE) return find(m&~fltk3::MULTISAMPLE,0);
+# endif
+ return 0;
+ }
+
+#elif defined(__APPLE_QUARTZ__)
+ // warning: the Quartz version should probably use Core GL (CGL) instead of AGL
+ const int *blist;
+ int list[32];
+
+ if (alistp)
+ blist = alistp;
+ else {
+ int n = 0;
+ if (m & fltk3::INDEX) {
+ list[n++] = AGL_BUFFER_SIZE;
+ list[n++] = 8; // glut tries many sizes, but this should work...
+ } else {
+ list[n++] = AGL_RGBA;
+ list[n++] = AGL_GREEN_SIZE;
+ list[n++] = (m & fltk3::RGB8) ? 8 : 1;
+ if (m & fltk3::ALPHA) {
+ list[n++] = AGL_ALPHA_SIZE;
+ list[n++] = (m & fltk3::RGB8) ? 8 : 1;
+ }
+ if (m & fltk3::ACCUM) {
+ list[n++] = AGL_ACCUM_GREEN_SIZE;
+ list[n++] = 1;
+ if (m & fltk3::ALPHA) {
+ list[n++] = AGL_ACCUM_ALPHA_SIZE;
+ list[n++] = 1;
+ }
+ }
+ }
+ if (m & fltk3::DOUBLE) {
+ list[n++] = AGL_DOUBLEBUFFER;
+ }
+ if (m & fltk3::DEPTH) {
+ list[n++] = AGL_DEPTH_SIZE; list[n++] = 24;
+ }
+ if (m & fltk3::STENCIL) {
+ list[n++] = AGL_STENCIL_SIZE; list[n++] = 1;
+ }
+# ifdef AGL_STEREO
+ if (m & fltk3::STEREO) {
+ list[n++] = AGL_STEREO;
+ }
+# endif
+ list[n] = AGL_NONE;
+ blist = list;
+ }
+ fl_open_display();
+ AGLPixelFormat fmt = aglChoosePixelFormat(NULL, 0, (GLint*)blist);
+ if (!fmt) return 0;
+
+#elif defined(WIN32)
+
+ // Replacement for ChoosePixelFormat() that finds one with an overlay
+ // if possible:
+ if (!fl_gc) fl_GetDC(0);
+ int pixelformat = 0;
+ PIXELFORMATDESCRIPTOR chosen_pfd;
+ for (int i = 1; ; i++) {
+ PIXELFORMATDESCRIPTOR pfd;
+ if (!DescribePixelFormat(fl_gc, i, sizeof(pfd), &pfd)) break;
+ // continue if it does not satisfy our requirements:
+ if (~pfd.dwFlags & (PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL)) continue;
+ if (pfd.iPixelType != ((m&fltk3::INDEX)?PFD_TYPE_COLORINDEX:PFD_TYPE_RGBA)) continue;
+ if ((m & fltk3::ALPHA) && !pfd.cAlphaBits) continue;
+ if ((m & fltk3::ACCUM) && !pfd.cAccumBits) continue;
+ if ((!(m & fltk3::DOUBLE)) != (!(pfd.dwFlags & PFD_DOUBLEBUFFER))) continue;
+ if ((!(m & fltk3::STEREO)) != (!(pfd.dwFlags & PFD_STEREO))) continue;
+ if ((m & fltk3::DEPTH) && !pfd.cDepthBits) continue;
+ if ((m & fltk3::STENCIL) && !pfd.cStencilBits) continue;
+ // see if better than the one we have already:
+ if (pixelformat) {
+ // offering non-generic rendering is better (read: hardware accelleration)
+ if (!(chosen_pfd.dwFlags & PFD_GENERIC_FORMAT) &&
+ (pfd.dwFlags & PFD_GENERIC_FORMAT)) continue;
+ // offering overlay is better:
+ else if (!(chosen_pfd.bReserved & 15) && (pfd.bReserved & 15)) {}
+ // otherwise more bit planes is better:
+ else if (chosen_pfd.cColorBits > pfd.cColorBits) continue;
+ else if (chosen_pfd.cDepthBits > pfd.cDepthBits) continue;
+ }
+ pixelformat = i;
+ chosen_pfd = pfd;
+ }
+ //printf("Chosen pixel format is %d\n", pixelformat);
+ if (!pixelformat) return 0;
+#else
+# error platform unsupported
+#endif
+
+ g = new fltk3::GlChoice;
+ g->mode = m;
+ g->alist = alistp;
+ g->next = first;
+ first = g;
+
+#if defined(USE_X11)
+ g->vis = visp;
+
+ if (/*MaxCmapsOfScreen(ScreenOfDisplay(fl_display,fl_screen))==1 && */
+ visp->visualid == fl_visual->visualid &&
+ !fltk3::getenv("MESA_PRIVATE_CMAP"))
+ g->colormap = fl_colormap;
+ else
+ g->colormap = XCreateColormap(fl_display, RootWindow(fl_display,fl_screen),
+ visp->visual, AllocNone);
+# elif defined(WIN32)
+ g->pixelformat = pixelformat;
+ g->pfd = chosen_pfd;
+# elif defined(__APPLE_QUARTZ__)
+ // warning: the Quartz version should probably use Core GL (CGL) instead of AGL
+ g->pixelformat = fmt;
+# else
+# error unsupported platform
+# endif
+
+ return g;
+}
+
+static GLContext *context_list = 0;
+static int nContext = 0, NContext = 0;
+
+static void add_context(GLContext ctx) {
+ if (!ctx) return;
+ if (nContext==NContext) {
+ if (!NContext) NContext = 8;
+ NContext *= 2;
+ context_list = (GLContext*)realloc(
+ context_list, NContext*sizeof(GLContext));
+ }
+ context_list[nContext++] = ctx;
+}
+
+static void del_context(GLContext ctx) {
+ int i;
+ for (i=0; i<nContext; i++) {
+ if (context_list[i]==ctx) {
+ memmove(context_list+i, context_list+i+1,
+ (nContext-i-1) * sizeof(GLContext));
+ context_list[--nContext] = 0;
+ break;
+ }
+ }
+ if (!nContext) gl_remove_displaylist_fonts();
+}
+
+#if defined(USE_X11)
+
+GLContext fl_create_gl_context(XVisualInfo* vis) {
+ GLContext shared_ctx = 0;
+ if (context_list && nContext) shared_ctx = context_list[0];
+ GLContext context = glXCreateContext(fl_display, vis, shared_ctx, 1);
+ if (context)
+ add_context(context);
+ return context;
+}
+
+#elif defined(WIN32)
+
+GLContext fl_create_gl_context(fltk3::Window* window, const fltk3::GlChoice* g, int layer) {
+ Fl_X* i = Fl_X::i(window);
+ HDC hdc = i->private_dc;
+ if (!hdc) {
+ hdc = i->private_dc = GetDCEx(i->xid, 0, DCX_CACHE);
+ fl_save_dc(i->xid, hdc);
+ SetPixelFormat(hdc, g->pixelformat, (PIXELFORMATDESCRIPTOR*)(&g->pfd));
+# if USE_COLORMAP
+ if (fl_palette) SelectPalette(hdc, fl_palette, FALSE);
+# endif
+ }
+ GLContext context =
+ layer ? wglCreateLayerContext(hdc, layer) : wglCreateContext(hdc);
+ if (context) {
+ if (context_list && nContext)
+ wglShareLists(context_list[0], context);
+ add_context(context);
+ }
+ return context;
+}
+
+# elif defined(__APPLE_QUARTZ__)
+#if !(MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 && __LP64__)
+static CGrafPtr fl_GetWindowPort(WindowRef window)
+{
+ typedef CGrafPtr (*wf)(WindowRef);
+ static wf f = NULL;
+ if ( ! f) f = (wf)Fl_X::get_carbon_function("GetWindowPort");
+ return (*f)(window);
+}
+#endif
+
+// warning: the Quartz version should probably use Core GL (CGL) instead of AGL
+GLContext fl_create_gl_context(fltk3::Window* window, const fltk3::GlChoice* g, int layer) {
+ GLContext context, shared_ctx = 0;
+ if (context_list && nContext) shared_ctx = context_list[0];
+ context = aglCreateContext( g->pixelformat, shared_ctx);
+ if (!context) return 0;
+ add_context((GLContext)context);
+ if ( window->parent() ) {
+ int H = window->window()->h();
+ GLint rect[] = { window->x(), H-window->h()-window->y(), window->w(), window->h() };
+ aglSetInteger( (GLContext)context, AGL_BUFFER_RECT, rect );
+ aglEnable( (GLContext)context, AGL_BUFFER_RECT );
+ }
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+#if __LP64__
+ // 64 bit version
+ aglSetWindowRef(context, Fl_X::i(window)->window_ref() );
+#else
+ // 32 bit version >= 10.5
+ if (aglSetWindowRef != NULL)
+ aglSetWindowRef(context, Fl_X::i(window)->window_ref() );
+ else
+ aglSetDrawable( context, fl_GetWindowPort( Fl_X::i(window)->window_ref() ) );
+#endif
+#else
+ // 32 bit version < 10.5
+ aglSetDrawable( context, fl_GetWindowPort( Fl_X::i(window)->window_ref() ) );
+#endif
+ return (context);
+}
+# else
+# error unsupported platform
+# endif
+
+static GLContext cached_context;
+static fltk3::Window* cached_window;
+
+void fl_set_gl_context(fltk3::Window* w, GLContext context) {
+ if (context != cached_context || w != cached_window) {
+ cached_context = context;
+ cached_window = w;
+# if defined(USE_X11)
+ glXMakeCurrent(fl_display, fl_xid(w), context);
+# elif defined(WIN32)
+ wglMakeCurrent(Fl_X::i(w)->private_dc, context);
+# elif defined(__APPLE_QUARTZ__)
+ // warning: the Quartz version should probably use Core GL (CGL) instead of AGL
+ if ( w->parent() ) { //: resize our GL buffer rectangle
+ int H = w->window()->h();
+ GLint rect[] = { w->x(), H-w->h()-w->y(), w->w(), w->h() };
+ aglSetInteger( context, AGL_BUFFER_RECT, rect );
+ aglEnable( context, AGL_BUFFER_RECT );
+ }
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+#if __LP64__
+ // 64 bit version
+ aglSetWindowRef(context, Fl_X::i(w)->window_ref() );
+#else
+ // 32 bit version >= 10.5
+ if (aglSetWindowRef != NULL)
+ aglSetWindowRef(context, Fl_X::i(w)->window_ref() );
+ else
+ aglSetDrawable( context, fl_GetWindowPort( Fl_X::i(w)->window_ref() ) );
+#endif
+#else
+ // 32 bit version < 10.5
+ aglSetDrawable( context, fl_GetWindowPort( Fl_X::i(w)->window_ref() ) );
+#endif
+ aglSetCurrentContext(context);
+# else
+# error unsupported platform
+# endif
+ }
+}
+
+void fl_no_gl_context() {
+ cached_context = 0;
+ cached_window = 0;
+# if defined(USE_X11)
+ glXMakeCurrent(fl_display, 0, 0);
+# elif defined(WIN32)
+ wglMakeCurrent(0, 0);
+# elif defined(__APPLE_QUARTZ__)
+ // warning: the Quartz version should probably use Core GL (CGL) instead of AGL
+ AGLContext ctx = aglGetCurrentContext();
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+ if (aglSetWindowRef != NULL)
+ { if(ctx) aglSetWindowRef(ctx, NULL ); }
+ else
+#endif
+ if(ctx) aglSetDrawable( ctx, NULL );
+ aglSetCurrentContext(0);
+# else
+# error unsupported platform
+# endif
+}
+
+void fl_delete_gl_context(GLContext context) {
+ if (cached_context == context) fl_no_gl_context();
+# if defined(USE_X11)
+ glXDestroyContext(fl_display, context);
+# elif defined(WIN32)
+ wglDeleteContext(context);
+# elif defined(__APPLE_QUARTZ__)
+ // warning: the Quartz version should probably use Core GL (CGL) instead of AGL
+ aglDestroyContext( context );
+# else
+# error unsupported platform
+# endif
+ del_context(context);
+}
+
+#endif // HAVE_GL
+
+
+//
+// End of "$Id$".
+//
Copied: branches/branch-3.0/src/fltk3gl/GL_Choice.h (from rev 9008, branches/branch-3.0/src/fltk3gl/GlChoice.h)
===================================================================
--- branches/branch-3.0/src/fltk3gl/GL_Choice.h (rev 0)
+++ branches/branch-3.0/src/fltk3gl/GL_Choice.h 2011-08-25 10:53:58 UTC (rev 9009)
@@ -0,0 +1,129 @@
+//
+// "$Id$"
+//
+// OpenGL definitions for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2010 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+// http://www.fltk.org/str.php
+//
+
+// Internal interface to set up OpenGL.
+//
+// A "fltk3::GlChoice" is created from an OpenGL mode and holds information
+// necessary to create a window (on X) and to create an OpenGL "context"
+// (on both X and Win32).
+//
+// fl_create_gl_context takes a window (necessary only on Win32) and an
+// fltk3::GlChoice and returns a new OpenGL context. All contexts share
+// display lists with each other.
+//
+// On X another fl_create_gl_context is provided to create it for any
+// X visual.
+//
+// fl_set_gl_context makes the given OpenGL context current and makes
+// it draw into the passed window. It tracks the current one context
+// to avoid calling the context switching code when the same context
+// is used, though it is a mystery to me why the GLX/WGL libraries
+// don't do this themselves...
+//
+// fl_no_gl_context clears that cache so the next fl_set_gl_context is
+// guaranteed to work.
+//
+// fl_delete_gl_context destroys the context.
+//
+// This code is used by fltk3::GlWindow, gl_start(), and gl_visual()
+
+#ifndef Fl_Gl_Choice_H
+#define Fl_Gl_Choice_H
+
+// Warning: whatever GLContext is defined to must take exactly the same
+// space in a structure as a void*!!!
+#ifdef WIN32
+# include <fltk3/gl.h>
+# define GLContext HGLRC
+#elif defined(__APPLE_QUARTZ__)
+// warning: the Quartz version should probably use Core GL (CGL) instead of AGL
+# include <OpenGL/gl.h>
+# include <AGL/agl.h>
+# define GLContext AGLContext
+#else
+# include <GL/glx.h>
+# define GLContext GLXContext
+#endif
+
+namespace fltk3 {
+
+ // Describes crap needed to create a GLContext.
+ class GlChoice {
+ int mode;
+ const int *alist;
+ fltk3::GlChoice *next;
+ public:
+#ifdef WIN32
+ int pixelformat; // the visual to use
+ PIXELFORMATDESCRIPTOR pfd; // some wgl calls need this thing
+#elif defined(__APPLE_QUARTZ__)
+ // warning: the Quartz version should probably use Core GL (CGL) instead of AGL
+ AGLPixelFormat pixelformat;
+#else
+ XVisualInfo *vis; // the visual to use
+ Colormap colormap; // a colormap for that visual
+#endif
+ // Return one of these structures for a given gl mode.
+ // The second argument is a glX attribute list, and is used if mode is
+ // zero. This is not supported on Win32:
+ static fltk3::GlChoice *find(int mode, const int *);
+ };
+
+ class Window;
+
+} // namespace
+
+
+#ifdef WIN32
+
+ GLContext fl_create_gl_context(fltk3::Window*, const fltk3::GlChoice*, int layer=0);
+
+#elif defined(__APPLE_QUARTZ__)
+ // warning: the Quartz version should probably use Core GL (CGL) instead of AGL
+
+ GLContext fl_create_gl_context(fltk3::Window*, const fltk3::GlChoice*, int layer=0);
+
+#else
+
+ GLContext fl_create_gl_context(XVisualInfo* vis);
+
+ static inline
+ GLContext fl_create_gl_context(fltk3::Window*, const fltk3::GlChoice* g) {
+ return fl_create_gl_context(g->vis);
+ }
+
+#endif
+
+ void fl_set_gl_context(fltk3::Window*, GLContext);
+ void fl_no_gl_context();
+ void fl_delete_gl_context(GLContext);
+
+#endif
+
+//
+// End of "$Id$".
+//
Copied: branches/branch-3.0/src/fltk3gl/GL_DevicePlugin.cxx (from rev 9008, branches/branch-3.0/src/fltk3gl/GlDevicePlugin.cxx)
===================================================================
--- branches/branch-3.0/src/fltk3gl/GL_DevicePlugin.cxx (rev 0)
+++ branches/branch-3.0/src/fltk3gl/GL_DevicePlugin.cxx 2011-08-25 10:53:58 UTC (rev 9009)
@@ -0,0 +1,156 @@
+//
+// "$Id$"
+//
+// implementation of class Fl_Gl_Device_Plugin for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 2010 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems to:
+//
+// http://www.fltk.org/str.php
+//
+
+#include <config.h>
+#include <fltk3/Printer.h>
+#include <fltk3/GlWindow.h>
+#include "Fl_Gl_Choice.H"
+#include <fltk3/run.h>
+#ifndef __APPLE__
+#include <fltk3/draw.h>
+#endif
+
+#if defined(__APPLE__)
+static void imgProviderReleaseData (void *info, const void *data, size_t size)
+{
+ free((void *)data);
+}
+#endif
+
+static void print_gl_window(fltk3::GlWindow *glw, int x, int y, int height)
+{
+#ifdef WIN32
+ HDC save_gc = fl_gc;
+ const int bytesperpixel = 3;
+#elif defined(__APPLE__)
+ CGContextRef save_gc = fl_gc;
+ const int bytesperpixel = 4;
+#else
+ _XGC *save_gc = fl_gc;
+ const int bytesperpixel = 3;
+#endif
+ fltk3::SurfaceDevice *save_surface = fltk3::SurfaceDevice::surface();
+ fl_gc = NULL;
+ fltk3::DisplayDevice::display_device()->set_current();
+#ifdef WIN32
+ fltk3::check();
+ fltk3::Window *win = (fltk3::Window*)glw;
+ while( win->window() ) win = win->window();
+ win->redraw();
+ fltk3::check();
+ glw->make_current();
+#else
+ glw->make_current();
+ glw->redraw();
+ glFlush();
+ fltk3::check();
+ glFinish();
+#endif
+ // Read OpenGL context pixels directly.
+ // For extra safety, save & restore OpenGL states that are changed
+ glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
+ glPixelStorei(GL_PACK_ALIGNMENT, 4); /* Force 4-byte alignment */
+ glPixelStorei(GL_PACK_ROW_LENGTH, 0);
+ glPixelStorei(GL_PACK_SKIP_ROWS, 0);
+ glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
+ // Read a block of pixels from the frame buffer
+ int mByteWidth = glw->w() * bytesperpixel;
+ mByteWidth = (mByteWidth + 3) & ~3; // Align to 4 bytes
+ uchar *baseAddress = (uchar*)malloc(mByteWidth * glw->h());
+ glReadPixels(0, 0, glw->w(), glw->h(),
+#ifdef WIN32
+ GL_RGB, GL_UNSIGNED_BYTE,
+#elif defined(__APPLE__)
+ GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
+#else // FIXME Linux/Unix
+ GL_RGB, GL_UNSIGNED_BYTE,
+#endif
+ baseAddress);
+ glPopClientAttrib();
+ save_surface->set_current();
+ fl_gc = save_gc;
+#if defined(__APPLE__)
+// kCGBitmapByteOrder32Host and CGBitmapInfo are supposed to arrive with 10.4
+// but some 10.4 don't have kCGBitmapByteOrder32Host, so we play a little #define game
+#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_4
+#define kCGBitmapByteOrder32Host 0
+#define CGBitmapInfo CGImageAlphaInfo
+#elif ! defined(kCGBitmapByteOrder32Host)
+#ifdef __BIG_ENDIAN__
+#define kCGBitmapByteOrder32Host (4 << 12)
+#else /* Little endian. */
+#define kCGBitmapByteOrder32Host (2 << 12)
+#endif
+#endif
+ CGColorSpaceRef cSpace = CGColorSpaceCreateDeviceRGB();
+ CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, baseAddress, mByteWidth * glw->h(), imgProviderReleaseData);
+ CGImageRef image = CGImageCreate(glw->w(), glw->h(), 8, 8*bytesperpixel, mByteWidth, cSpace,
+ (CGBitmapInfo)(kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host),
+ provider, NULL, false, kCGRenderingIntentDefault);
+ if(image == NULL) return;
+ CGContextSaveGState(fl_gc);
+ CGContextTranslateCTM(fl_gc, 0, height);
+ CGContextScaleCTM(fl_gc, 1.0f, -1.0f);
+ CGRect rect = { { x, height - y - glw->h() }, { glw->w(), glw->h() } };
+ Fl_X::q_begin_image(rect, 0, 0, glw->w(), glw->h());
+ CGContextDrawImage(fl_gc, rect, image);
+ Fl_X::q_end_image();
+ CGContextRestoreGState(fl_gc);
+ CGImageRelease(image);
+ CGColorSpaceRelease(cSpace);
+ CGDataProviderRelease(provider);
+#else
+ fltk3::draw_image(baseAddress + (glw->h() - 1) * mByteWidth, x, y , glw->w(), glw->h(), bytesperpixel, - mByteWidth);
+ free(baseAddress);
+#endif // __APPLE__
+}
+
+/**
+ This class will make sure that OpenGL printing is available if fltk_gl
+ was linked to the program.
+ */
+class Fl_Gl_Device_Plugin : public fltk3::DevicePlugin {
+public:
+ Fl_Gl_Device_Plugin() : fltk3::DevicePlugin(name()) { }
+ virtual const char *name() { return "opengl.device.fltk.org"; }
+ virtual int print(fltk3::Widget *w, int x, int y, int height) {
+ fltk3::GlWindow *glw = w->as_gl_window();
+ if (!glw) return 0;
+ print_gl_window(glw, x, y, height);
+ return 1;
+ }
+};
+
+static Fl_Gl_Device_Plugin Gl_Device_Plugin;
+
+// The purpose of this variable, used in fltk3::GlWindow.cxx, is only to force this file to be loaded
+// whenever fltk3::GlWindow.cxx is loaded, that is, whenever fltk_gl is.
+FLTK3_EXPORT int fl_gl_load_plugin = 0;
+
+//
+// End of "$Id$".
+//
Copied: branches/branch-3.0/src/fltk3gl/GL_Overlay.cxx (from rev 9008, branches/branch-3.0/src/fltk3gl/GlOverlay.cxx)
===================================================================
--- branches/branch-3.0/src/fltk3gl/GL_Overlay.cxx (rev 0)
+++ branches/branch-3.0/src/fltk3gl/GL_Overlay.cxx 2011-08-25 10:53:58 UTC (rev 9009)
@@ -0,0 +1,248 @@
+//
+// "$Id$"
+//
+// OpenGL overlay code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2010 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+// http://www.fltk.org/str.php
+//
+
+#include <config.h>
+#if HAVE_GL
+
+#include <fltk3/run.h>
+#include <fltk3/x.h>
+#include "Fl_Gl_Choice.H"
+#include <fltk3/GlWindow.h>
+#include <stdlib.h>
+
+#if !HAVE_GL_OVERLAY
+
+int fltk3::GlWindow::can_do_overlay() {return 0;}
+
+void fltk3::GlWindow::make_overlay() {overlay = this;}
+
+#else
+
+// Methods on fltk3::GlWindow that create an overlay window. Because
+// many programs don't need the overlay, this is separated into this
+// source file so it is not linked in if not used.
+
+// Under X this is done by creating another window, of class _Fl_Gl_Overlay
+// which is a subclass of fltk3::GlWindow except it uses the overlay planes.
+// A pointer to this is stored in the "overlay" pointer of the fltk3::GlWindow.
+
+// Under win32 another GLX context is created to draw into the overlay
+// and it is stored in the "overlay" pointer.
+
+// In both cases if overlay hardware is unavailable, the overlay is
+// "faked" by drawing into the main layers. This is indicated by
+// setting overlay == this.
+
+#ifndef WIN32
+////////////////////////////////////////////////////////////////
+// X version
+
+extern XVisualInfo *fl_find_overlay_visual();
+extern XVisualInfo *fl_overlay_visual;
+extern Colormap fl_overlay_colormap;
+extern unsigned long fl_transparent_pixel;
+extern uchar fl_overlay;
+
+class _Fl_Gl_Overlay : public fltk3::GlWindow {
+ void flush();
+ void draw();
+public:
+ void show();
+ _Fl_Gl_Overlay(int x, int y, int w, int h) :
+ fltk3::GlWindow(x,y,w,h) {
+ set_flag(INACTIVE);
+ }
+};
+
+void _Fl_Gl_Overlay::flush() {
+ make_current();
+#ifdef BOXX_BUGS
+ // The BoXX overlay is broken and you must not call swap-buffers. This
+ // code will make it work, but we lose because machines that do support
+ // double-buffered overlays will blink when they don't have to
+ glDrawBuffer(GL_FRONT);
+ draw();
+#else
+ draw();
+ swap_buffers();
+#endif
+ glFlush();
+ valid(1);
+}
+
+void _Fl_Gl_Overlay::draw() {
+ if (!valid()) glClearIndex((GLfloat)fl_transparent_pixel);
+ if (damage() != fltk3::DAMAGE_EXPOSE) glClear(GL_COLOR_BUFFER_BIT);
+ fltk3::GlWindow *w = (fltk3::GlWindow *)parent();
+ uchar save_valid = w->valid();
+ w->valid(valid());
+ fl_overlay = 1;
+ w->draw_overlay();
+ fl_overlay = 0;
+ valid(w->valid());
+ w->valid(save_valid);
+}
+
+void _Fl_Gl_Overlay::show() {
+ if (!shown()) {
+ fl_background_pixel = int(fl_transparent_pixel);
+ Fl_X::make_xid(this, fl_overlay_visual, fl_overlay_colormap);
+ fl_background_pixel = -1;
+ // find the outermost window to tell wm about the colormap:
+ fltk3::Window *w = window();
+ for (;;) {fltk3::Window *w1 = w->window(); if (!w1) break; w = w1;}
+ XSetWMColormapWindows(fl_display, fl_xid(w), &(Fl_X::i(this)->xid), 1);
+ context(fl_create_gl_context(fl_overlay_visual), 1);
+ valid(0);
+ }
+ fltk3::GlWindow::show();
+}
+
+int fltk3::GlWindow::can_do_overlay() {
+ return fl_find_overlay_visual() != 0;
+}
+
+void fltk3::GlWindow::make_overlay() {
+ if (overlay) return;
+ if (can_do_overlay()) {
+ _Fl_Gl_Overlay* o = new _Fl_Gl_Overlay(0,0,w(),h());
+ overlay = o;
+ add(*o);
+ o->show();
+ } else {
+ overlay = this; // fake the overlay
+ }
+}
+
+#else
+////////////////////////////////////////////////////////////////
+// WIN32 version:
+
+//static COLORREF *palette;
+extern int fl_overlay_depth;
+
+void fltk3::GlWindow::make_overlay() {
+ if (overlay) return;
+
+ GLContext context = fl_create_gl_context(this, g, 1);
+ if (!context) {overlay = this; return;} // fake the overlay
+
+ HDC hdc = Fl_X::i(this)->private_dc;
+ overlay = context;
+ LAYERPLANEDESCRIPTOR pfd;
+ wglDescribeLayerPlane(hdc, g->pixelformat, 1, sizeof(pfd), &pfd);
+ if (!pfd.iPixelType) {
+ ; // full-color overlay
+ } else {
+ fl_overlay_depth = pfd.cColorBits; // used by gl_color()
+ if (fl_overlay_depth > 8) fl_overlay_depth = 8;
+ COLORREF palette[256];
+ int n = (1<<fl_overlay_depth)-1;
+ // copy all colors except #0 into the overlay palette:
+ for (int i = 0; i <= n; i++) {
+ uchar r,g,b; fltk3::get_color((fltk3::Color)i,r,g,b);
+ palette[i] = RGB(r,g,b);
+ }
+ // always provide black & white in the last 2 pixels:
+ if (fl_overlay_depth < 8) {
+ palette[n-1] = RGB(0,0,0);
+ palette[n] = RGB(255,255,255);
+ }
+ // and use it:
+ wglSetLayerPaletteEntries(hdc, 1, 1, n, palette+1);
+ wglRealizeLayerPalette(hdc, 1, TRUE);
+ }
+ valid(0);
+ return;
+}
+
+int fltk3::GlWindow::can_do_overlay() {
+ if (!g) {
+ g = fltk3::GlChoice::find(mode_,alist);
+ if (!g) return 0;
+ }
+ return (g->pfd.bReserved & 15) != 0;
+}
+
+////////////////////////////////////////////////////////////////
+#endif
+
+#endif
+
+void fltk3::GlWindow::redraw_overlay() {
+ if (!shown()) return;
+ make_overlay();
+#ifdef __APPLE__
+ redraw();
+#else
+#ifndef WIN32
+ if (overlay != this)
+ ((fltk3::GlWindow*)overlay)->redraw();
+ else
+#endif
+ damage(fltk3::DAMAGE_OVERLAY);
+#endif
+}
+
+void fltk3::GlWindow::make_overlay_current() {
+ make_overlay();
+#ifdef __APPLE__
+ // this is not very useful, but unfortunately, Apple decided
+ // that front buffer drawing can no longer (OS X 10.4) be
+ // supported on their platforms.
+ make_current();
+#else
+#if HAVE_GL_OVERLAY
+ if (overlay != this) {
+#ifdef WIN32
+ fl_set_gl_context(this, (GLContext)overlay);
+// if (fl_overlay_depth)
+// wglRealizeLayerPalette(Fl_X::i(this)->private_dc, 1, TRUE);
+#else
+ ((fltk3::GlWindow*)overlay)->make_current();
+#endif
+ } else
+#endif
+ glDrawBuffer(GL_FRONT);
+#endif
+}
+/** Hides the window if it is not this window, does nothing in WIN32. */
+void fltk3::GlWindow::hide_overlay() {
+#if HAVE_GL_OVERLAY
+#ifdef WIN32
+ // nothing needs to be done? Or should it be erased?
+#else
+ if (overlay && overlay!=this) ((fltk3::GlWindow*)overlay)->hide();
+#endif
+#endif
+}
+
+#endif
+
+//
+// End of "$Id$".
+//
Copied: branches/branch-3.0/src/fltk3gl/GL_Window.cxx (from rev 9008, branches/branch-3.0/src/fltk3gl/GlWindow.cxx)
===================================================================
--- branches/branch-3.0/src/fltk3gl/GL_Window.cxx (rev 0)
+++ branches/branch-3.0/src/fltk3gl/GL_Window.cxx 2011-08-25 10:53:58 UTC (rev 9009)
@@ -0,0 +1,554 @@
+//
+// "$Id$"
+//
+// OpenGL window code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2010 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+// http://www.fltk.org/str.php
+//
+
+#include "flstring.h"
+#if HAVE_GL
+
+extern int fl_gl_load_plugin;
+
+static int temp = fl_gl_load_plugin;
+
+#include <fltk3/Wrapper.h>
+#include <fltk3/run.h>
+#include <fltk3/x.h>
+#ifdef __APPLE__
+#include <fltk3/gl.h>
+#endif
+#include "Fl_Gl_Choice.H"
+#include <fltk3/GlWindow.h>
+#include <stdlib.h>
+#include <fltk3/utf8.h>
+
+////////////////////////////////////////////////////////////////
+
+// The symbol SWAP_TYPE defines what is in the back buffer after doing
+// a glXSwapBuffers().
+
+// The OpenGl documentation says that the contents of the backbuffer
+// are "undefined" after glXSwapBuffers(). However, if we know what
+// is in the backbuffers then we can save a good deal of time. For
+// this reason you can define some symbols to describe what is left in
+// the back buffer.
+
+// Having not found any way to determine this from glx (or wgl) I have
+// resorted to letting the user specify it with an environment variable,
+// GL_SWAP_TYPE, it should be equal to one of these symbols:
+
+// contents of back buffer after glXSwapBuffers():
+#define UNDEFINED 1 // anything
+#define SWAP 2 // former front buffer (same as unknown)
+#define COPY 3 // unchanged
+#define NODAMAGE 4 // unchanged even by X expose() events
+
+static char SWAP_TYPE = 0 ; // 0 = determine it from environment variable
+
+////////////////////////////////////////////////////////////////
+
+/** Returns non-zero if the hardware supports the given or current OpenGL mode. */
+int fltk3::GlWindow::can_do(int a, const int *b) {
+ return fltk3::GlChoice::find(a,b) != 0;
+}
+
+void fltk3::GlWindow::show() {
+#if defined(__APPLE__)
+ int need_redraw = 0;
+#endif
+ if (!shown()) {
+ if (!g) {
+ g = fltk3::GlChoice::find(mode_,alist);
+
+ if (!g && (mode_ & fltk3::DOUBLE) == fltk3::SINGLE) {
+ g = fltk3::GlChoice::find(mode_ | fltk3::DOUBLE,alist);
+ if (g) mode_ |= fltk3::FAKE_SINGLE;
+ }
+
+ if (!g) {
+ fltk3::error("Insufficient GL support");
+ return;
+ }
+ }
+#if !defined(WIN32) && !defined(__APPLE__)
+ Fl_X::make_xid(this, g->vis, g->colormap);
+ if (overlay && overlay != this) ((fltk3::GlWindow*)overlay)->show();
+#elif defined(__APPLE__)
+ if( ! parent() ) need_redraw=1;
+#endif
+ }
+ Window::show();
+
+#ifdef __APPLE__
+ set_visible();
+ if(need_redraw) redraw();//necessary only after creation of a top-level GL window
+#endif /* __APPLE__ */
+}
+
+/**
+ The invalidate() method turns off valid() and is
+ equivalent to calling value(0).
+*/
+void fltk3::GlWindow::invalidate() {
+ valid(0);
+ context_valid(0);
+#ifndef WIN32
+ if (overlay) {
+ ((fltk3::GlWindow*)overlay)->valid(0);
+ ((fltk3::GlWindow*)overlay)->context_valid(0);
+ }
+#endif
+}
+
+/**
+ See const int fltk3::GlWindow::mode() const
+*/
+int fltk3::GlWindow::mode(int m, const int *a) {
+ if (m == mode_ && a == alist) return 0;
+#ifndef __APPLE__
+ int oldmode = mode_;
+#endif // !__APPLE__
+#if !defined(WIN32) && !defined(__APPLE__)
+ fltk3::GlChoice* oldg = g;
+#endif // !WIN32 && !__APPLE__
+ context(0);
+ mode_ = m; alist = a;
+ if (shown()) {
+ g = fltk3::GlChoice::find(m, a);
+
+#if defined(USE_X11)
+ // under X, if the visual changes we must make a new X window (yuck!):
+ if (!g || g->vis->visualid!=oldg->vis->visualid || (oldmode^m)&fltk3::DOUBLE) {
+ hide();
+ show();
+ }
+#elif defined(WIN32)
+ if (!g || (oldmode^m)&(fltk3::DOUBLE|fltk3::STEREO)) {
+ hide();
+ show();
+ }
+#elif defined(__APPLE_QUARTZ__)
+ // warning: the Quartz version should probably use Core GL (CGL) instead of AGL
+ redraw();
+#else
+# error unsupported platform
+#endif
+ } else {
+ g = 0;
+ }
+ return 1;
+}
+
+#define NON_LOCAL_CONTEXT 0x80000000
+
+/**
+ The make_current() method selects the OpenGL context for the
+ widget. It is called automatically prior to the draw() method
+ being called and can also be used to implement feedback and/or
+ selection within the handle() method.
+*/
+
+void fltk3::GlWindow::make_current() {
+// puts("fltk3::GlWindow::make_current()");
+// printf("make_current: context_=%p\n", context_);
+ if (!context_) {
+ mode_ &= ~NON_LOCAL_CONTEXT;
+ context_ = fl_create_gl_context(this, g);
+ valid(0);
+ context_valid(0);
+ }
+ fl_set_gl_context(this, context_);
+
+#ifdef __APPLE__
+ // Set the buffer rectangle here, since in resize() we won't have the
+ // correct parent window size to work with...
+ GLint xywh[4];
+
+ if (window()) {
+ xywh[0] = x();
+ xywh[1] = window()->h() - y() - h();
+ } else {
+ xywh[0] = 0;
+ xywh[1] = 0;
+ }
+
+ xywh[2] = w();
+ xywh[3] = h();
+
+ aglSetInteger(context_, AGL_BUFFER_RECT, xywh);
+ aglEnable(context_, AGL_BUFFER_RECT);
+// printf("make_current: xywh=[%d %d %d %d]\n", xywh[0], xywh[1], xywh[2], xywh[3]);
+#endif // __APPLE__
+
+#if defined(WIN32) && USE_COLORMAP
+ if (fl_palette) {
+ fl_GetDC(fl_xid(this));
+ SelectPalette(fl_gc, fl_palette, FALSE);
+ RealizePalette(fl_gc);
+ }
+#endif // USE_COLORMAP
+ if (mode_ & fltk3::FAKE_SINGLE) {
+ glDrawBuffer(GL_FRONT);
+ glReadBuffer(GL_FRONT);
+ }
+ current_ = this;
+}
+
+/**
+ Sets the projection so 0,0 is in the lower left of the window and each
+ pixel is 1 unit wide/tall. If you are drawing 2D images, your
+ draw() method may want to call this if valid() is false.
+*/
+void fltk3::GlWindow::ortho() {
+// Alpha NT seems to have a broken OpenGL that does not like negative coords:
+#ifdef _M_ALPHA
+ glLoadIdentity();
+ glViewport(0, 0, w(), h());
+ glOrtho(0, w(), 0, h(), -1, 1);
+#else
+ GLint v[2];
+ glGetIntegerv(GL_MAX_VIEWPORT_DIMS, v);
+ glLoadIdentity();
+ glViewport(w()-v[0], h()-v[1], v[0], v[1]);
+ glOrtho(w()-v[0], w(), h()-v[1], h(), -1, 1);
+#endif
+}
+
+/**
+ The swap_buffers() method swaps the back and front buffers.
+ It is called automatically after the draw() method is called.
+*/
+void fltk3::GlWindow::swap_buffers() {
+#if defined(USE_X11)
+ glXSwapBuffers(fl_display, fl_xid(this));
+#elif defined(WIN32)
+# if HAVE_GL_OVERLAY
+ // Do not swap the overlay, to match GLX:
+ BOOL ret = wglSwapLayerBuffers(Fl_X::i(this)->private_dc, WGL_SWAP_MAIN_PLANE);
+ DWORD err = GetLastError();;
+# else
+ SwapBuffers(Fl_X::i(this)->private_dc);
+# endif
+#elif defined(__APPLE_QUARTZ__)
+ if(overlay != NULL) {
+ //aglSwapBuffers does not work well with overlays under cocoa
+ glReadBuffer(GL_BACK);
+ glDrawBuffer(GL_FRONT);
+ glCopyPixels(0,0,w(),h(),GL_COLOR);
+ }
+ else
+ aglSwapBuffers((AGLContext)context_);
+#else
+# error unsupported platform
+#endif
+}
+
+#if HAVE_GL_OVERLAY && defined(WIN32)
+uchar fl_overlay; // changes how fltk3::color() works
+int fl_overlay_depth = 0;
+#endif
+
+
+void fltk3::GlWindow::flush() {
+ uchar save_valid = valid_f_ & 1;
+#if HAVE_GL_OVERLAY && defined(WIN32)
+ uchar save_valid_f = valid_f_;
+#endif
+
+#if defined(__APPLE_QUARTZ__)
+ // warning: the Quartz version should probably use Core GL (CGL) instead of AGL
+ //: clear previous clipping in this shared port
+#if ! __LP64__
+/*GrafPtr port = GetWindowPort( Fl_X::i(this)->window_ref() );
+ Rect rect; SetRect( &rect, 0, 0, 0x7fff, 0x7fff );
+ GrafPtr old; GetPort( &old );
+ SetPort( port );
+ ClipRect( &rect );
+ SetPort( old );*/
+#endif
+#endif
+
+#if HAVE_GL_OVERLAY && defined(WIN32)
+
+ bool fixcursor = false; // for fixing the SGI 320 bug
+
+ // Draw into hardware overlay planes if they are damaged:
+ if (overlay && overlay != this
+ && (damage()&(fltk3::DAMAGE_OVERLAY|fltk3::DAMAGE_EXPOSE) || !save_valid)) {
+ // SGI 320 messes up overlay with user-defined cursors:
+ if (Fl_X::i(this)->cursor && Fl_X::i(this)->cursor != fl_default_cursor) {
+ fixcursor = true; // make it restore cursor later
+ SetCursor(0);
+ }
+ fl_set_gl_context(this, (GLContext)overlay);
+ if (fl_overlay_depth)
+ wglRealizeLayerPalette(Fl_X::i(this)->private_dc, 1, TRUE);
+ glDisable(GL_SCISSOR_TEST);
+ glClear(GL_COLOR_BUFFER_BIT);
+ fl_overlay = 1;
+ draw_overlay();
+ fl_overlay = 0;
+ valid_f_ = save_valid_f;
+ wglSwapLayerBuffers(Fl_X::i(this)->private_dc, WGL_SWAP_OVERLAY1);
+ // if only the overlay was damaged we are done, leave main layer alone:
+ if (damage() == fltk3::DAMAGE_OVERLAY) {
+ if (fixcursor) SetCursor(Fl_X::i(this)->cursor);
+ return;
+ }
+ }
+#endif
+
+ make_current();
+
+ if (mode_ & fltk3::DOUBLE) {
+
+ glDrawBuffer(GL_BACK);
+
+ if (!SWAP_TYPE) {
+#if defined (__APPLE_QUARTZ__) || defined (USE_X11)
+ SWAP_TYPE = COPY;
+#else
+ SWAP_TYPE = UNDEFINED;
+#endif
+ const char* c = fltk3::getenv("GL_SWAP_TYPE");
+ if (c) {
+ if (!strcmp(c,"COPY")) SWAP_TYPE = COPY;
+ else if (!strcmp(c, "NODAMAGE")) SWAP_TYPE = NODAMAGE;
+ else if (!strcmp(c, "SWAP")) SWAP_TYPE = SWAP;
+ else SWAP_TYPE = UNDEFINED;
+ }
+ }
+
+ if (SWAP_TYPE == NODAMAGE) {
+
+ // don't draw if only overlay damage or expose events:
+ if ((damage()&~(fltk3::DAMAGE_OVERLAY|fltk3::DAMAGE_EXPOSE)) || !save_valid)
+ draw();
+ swap_buffers();
+
+ } else if (SWAP_TYPE == COPY) {
+
+ // don't draw if only the overlay is damaged:
+ if (damage() != fltk3::DAMAGE_OVERLAY || !save_valid) draw();
+ swap_buffers();
+
+ } else if (SWAP_TYPE == SWAP){
+ damage(fltk3::DAMAGE_ALL);
+ draw();
+ if (overlay == this) draw_overlay();
+ swap_buffers();
+ } else if (SWAP_TYPE == UNDEFINED){ // SWAP_TYPE == UNDEFINED
+
+ // If we are faking the overlay, use CopyPixels to act like
+ // SWAP_TYPE == COPY. Otherwise overlay redraw is way too slow.
+ if (overlay == this) {
+ // don't draw if only the overlay is damaged:
+ if (damage1_ || damage() != fltk3::DAMAGE_OVERLAY || !save_valid) draw();
+ // we use a separate context for the copy because rasterpos must be 0
+ // and depth test needs to be off:
+ static GLContext ortho_context = 0;
+ static fltk3::GlWindow* ortho_window = 0;
+ int orthoinit = !ortho_context;
+ if (orthoinit) ortho_context = fl_create_gl_context(this, g);
+ fl_set_gl_context(this, ortho_context);
+ if (orthoinit || !save_valid || ortho_window != this) {
+ glDisable(GL_DEPTH_TEST);
+ glReadBuffer(GL_BACK);
+ glDrawBuffer(GL_FRONT);
+ glLoadIdentity();
+ glViewport(0, 0, w(), h());
+ glOrtho(0, w(), 0, h(), -1, 1);
+ glRasterPos2i(0,0);
+ ortho_window = this;
+ }
+ glCopyPixels(0,0,w(),h(),GL_COLOR);
+ make_current(); // set current context back to draw overlay
+ damage1_ = 0;
+
+ } else {
+ damage1_ = damage();
+ clear_damage(0xff); draw();
+ swap_buffers();
+ }
+
+ }
+
+ if (overlay==this && SWAP_TYPE != SWAP) { // fake overlay in front buffer
+ glDrawBuffer(GL_FRONT);
+ draw_overlay();
+ glDrawBuffer(GL_BACK);
+ glFlush();
+ }
+
+ } else { // single-buffered context is simpler:
+
+ draw();
+ if (overlay == this) draw_overlay();
+ glFlush();
+
+ }
+
+#if HAVE_GL_OVERLAY && defined(WIN32)
+ if (fixcursor) SetCursor(Fl_X::i(this)->cursor);
+#endif
+ valid(1);
+ context_valid(1);
+}
+
+void fltk3::GlWindow::resize(int X,int Y,int W,int H) {
+// printf("fltk3::GlWindow::resize(X=%d, Y=%d, W=%d, H=%d)\n", X, Y, W, H);
+// printf("current: x()=%d, y()=%d, w()=%d, h()=%d\n", x(), y(), w(), h());
+
+ if (W != w() || H != h()) valid(0);
+
+#ifdef __APPLE__
+ if (X != x() || Y != y() || W != w() || H != h()) aglUpdateContext(context_);
+#elif !defined(WIN32)
+ if ((W != w() || H != h()) && !resizable() && overlay && overlay != this) {
+ ((fltk3::GlWindow*)overlay)->resize(0,0,W,H);
+ }
+#endif
+
+ Window::resize(X,Y,W,H);
+}
+
+/**
+ Returns or sets a pointer to the GLContext that this window is
+ using. This is a system-dependent structure, but it is portable to copy
+ the context from one window to another. You can also set it to NULL,
+ which will force FLTK to recreate the context the next time make_current()
+ is called, this is useful for getting around bugs in OpenGL implementations.
+
+ If <i>destroy_flag</i> is true the context will be destroyed by
+ fltk when the window is destroyed, or when the mode() is changed,
+ or the next time context(x) is called.
+*/
+void fltk3::GlWindow::context(void* v, int destroy_flag) {
+ if (context_ && !(mode_&NON_LOCAL_CONTEXT)) fl_delete_gl_context(context_);
+ context_ = (GLContext)v;
+ if (destroy_flag) mode_ &= ~NON_LOCAL_CONTEXT;
+ else mode_ |= NON_LOCAL_CONTEXT;
+}
+
+/**
+ Hides the window and destroys the OpenGL context.
+*/
+void fltk3::GlWindow::hide() {
+ context(0);
+#if HAVE_GL_OVERLAY && defined(WIN32)
+ if (overlay && overlay != this) {
+ fl_delete_gl_context((GLContext)overlay);
+ overlay = 0;
+ }
+#endif
+ Window::hide();
+}
+
+/**
+ The destructor removes the widget and destroys the OpenGL context
+ associated with it.
+*/
+fltk3::GlWindow::~GlWindow() {
+ hide();
+// delete overlay; this is done by ~Fl_Group
+#ifdef __APPLE__
+ // resets the pile of string textures used to draw strings
+ extern void gl_texture_reset();
+ gl_texture_reset();
+#endif
+}
+
+void fltk3::GlWindow::init() {
+ end(); // we probably don't want any children
+ box(fltk3::NO_BOX);
+
+ mode_ = fltk3::RGB | fltk3::DEPTH | fltk3::DOUBLE;
+ alist = 0;
+ context_ = 0;
+ g = 0;
+ overlay = 0;
+ valid_f_ = 0;
+ damage1_ = 0;
+
+#if 0 // This breaks resizing on Linux/X11
+ int H = h();
+ h(1); // Make sure we actually do something in resize()...
+ resize(x(), y(), w(), H);
+#endif // 0
+}
+
+/**
+ You must implement this virtual function if you want to draw into the
+ overlay. The overlay is cleared before this is called. You should
+ draw anything that is not clear using OpenGL. You must use
+ gl_color(i) to choose colors (it allocates them from the colormap
+ using system-specific calls), and remember that you are in an indexed
+ OpenGL mode and drawing anything other than flat-shaded will probably
+ not work.
+
+ Both this function and fltk3::GlWindow::draw() should check
+ fltk3::GlWindow::valid() and set the same transformation. If you
+ don't your code may not work on other systems. Depending on the OS,
+ and on whether overlays are real or simulated, the OpenGL context may
+ be the same or different between the overlay and main window.
+*/
+void fltk3::GlWindow::draw_overlay() {
+ FLTK3_OBJECT_VCALLS_WRAPPER(draw_overlay(), DrawOverlay)
+}
+
+#endif
+
+ /**
+ You \e \b must subclass fltk3::GlWindow and provide an implementation for
+ draw(). You may also provide an implementation of draw_overlay()
+ if you want to draw into the overlay planes. You can avoid
+ reinitializing the viewport and lights and other things by checking
+ valid() at the start of draw() and only doing the
+ initialization if it is false.
+
+ The draw() method can <I>only</I> use OpenGL calls. Do not
+ attempt to call X, any of the functions in <fltk3/draw.h>, or glX
+ directly. Do not call gl_start() or gl_finish().
+
+ If double-buffering is enabled in the window, the back and front
+ buffers are swapped after this function is completed.
+*/
+void fltk3::GlWindow::draw() {
+ FLTK3_OBJECT_VCALLS_WRAPPER(draw(), Draw)
+ fltk3::fatal("fltk3::GlWindow::draw() *must* be overriden. Please refer to the documentation.");
+}
+
+
+/**
+ Handle some FLTK events as needed.
+ */
+int fltk3::GlWindow::handle(int event)
+{
+ FLTK3_OBJECT_VCALLS_WRAPPER_RET(int, handle(event), Handle)
+ return Window::handle(event);
+}
+
+//
+// End of "$Id$".
+//
Deleted: branches/branch-3.0/src/fltk3gl/GlChoice.cxx
Deleted: branches/branch-3.0/src/fltk3gl/GlChoice.h
Deleted: branches/branch-3.0/src/fltk3gl/GlDevicePlugin.cxx
Deleted: branches/branch-3.0/src/fltk3gl/GlOverlay.cxx
Deleted: branches/branch-3.0/src/fltk3gl/GlWindow.cxx
[ Direct Link to Message ] | |