diff --git a/FL/Fl_Gl_Window.H b/FL/Fl_Gl_Window.H index 0951f3a107dc174c0d6e53802db66e74dbfcabae..8a7a0af741f5fcfa09f7beb0b393ee7b5e8729fc 100644 --- a/FL/Fl_Gl_Window.H +++ b/FL/Fl_Gl_Window.H @@ -1,5 +1,5 @@ // -// "$Id: Fl_Gl_Window.H,v 1.7.2.3 2001/01/22 15:13:37 easysw Exp $" +// "$Id: Fl_Gl_Window.H,v 1.7.2.4 2001/03/14 17:20:01 spitzak Exp $" // // OpenGL header file for the Fast Light Tool Kit (FLTK). // @@ -27,6 +27,10 @@ #include "Fl_Window.H" +#ifndef GLContext +typedef void* GLContext; // actually a GLXContext or HGLDC +#endif + class Fl_Gl_Choice; // structure to hold result of glXChooseVisual class Fl_Gl_Window : public Fl_Window { @@ -34,7 +38,7 @@ class Fl_Gl_Window : public Fl_Window { int mode_; const int *alist; Fl_Gl_Choice *g; - void * context; // actually a GLXContext + GLContext context_; char valid_; char damage1_; // damage() of back buffer virtual FL_EXPORT void draw_overlay(); @@ -66,14 +70,16 @@ public: int mode(int a) {return mode(a,0);} int mode(const int *a) {return mode(0, a);} + void* context() const {return context_;} + FL_EXPORT void context(void*, int destroy_flag = false); + FL_EXPORT void make_current(); + FL_EXPORT void swap_buffers(); + FL_EXPORT void ortho(); + FL_EXPORT int can_do_overlay(); FL_EXPORT void redraw_overlay(); FL_EXPORT void hide_overlay(); - - FL_EXPORT void make_current(); FL_EXPORT void make_overlay_current(); - FL_EXPORT void swap_buffers(); - FL_EXPORT void ortho(); FL_EXPORT ~Fl_Gl_Window(); Fl_Gl_Window(int W, int H, const char *l=0) : Fl_Window(W,H,l) {init();} @@ -84,5 +90,5 @@ public: #endif // -// End of "$Id: Fl_Gl_Window.H,v 1.7.2.3 2001/01/22 15:13:37 easysw Exp $". +// End of "$Id: Fl_Gl_Window.H,v 1.7.2.4 2001/03/14 17:20:01 spitzak Exp $". // diff --git a/FL/glut.H b/FL/glut.H index 8f8b2b446e3155b432b488c4f4e6e49d6ff55bc7..193e6f498e1fc1a47dd4a693d36fdc55e2e7c25e 100644 --- a/FL/glut.H +++ b/FL/glut.H @@ -1,5 +1,5 @@ // -// "$Id: glut.H,v 1.6.2.9 2001/01/22 15:13:38 easysw Exp $" +// "$Id: glut.H,v 1.6.2.10 2001/03/14 17:20:01 spitzak Exp $" // // GLUT emulation header file for the Fast Light Tool Kit (FLTK). // @@ -45,7 +45,7 @@ #define __glut_h__ #include <FL/gl.h> -#include <GL/glu.h> +//#include <GL/glu.h> //////////////////////////////////////////////////////////////// // Glut is emulated using this window class and these static variables @@ -431,7 +431,7 @@ extern "C" { extern int APIENTRY glutExtensionSupported(char *name); /* Stroke font constants (use these in GLUT program). */ -#if defined(_WIN32) || defined(WIN32) +#ifdef WIN32 # define GLUT_STROKE_ROMAN ((void*)0) # define GLUT_STROKE_MONO_ROMAN ((void*)1) #else @@ -470,5 +470,5 @@ extern void APIENTRY glutSolidIcosahedron(); #endif /* __glut_h__ */ // -// End of "$Id: glut.H,v 1.6.2.9 2001/01/22 15:13:38 easysw Exp $". +// End of "$Id: glut.H,v 1.6.2.10 2001/03/14 17:20:01 spitzak Exp $". // diff --git a/Makefile b/Makefile index 27c9491b3e424f2c74a02bf1bd8a357f2f438f2f..3dd59520325909e11fe21eb337baad9f9eceeca1 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ # -# "$Id: Makefile,v 1.12.2.5 2001/01/22 15:13:37 easysw Exp $" +# "$Id: Makefile,v 1.12.2.6 2001/03/14 17:20:01 spitzak Exp $" # # Top-level makefile for the Fast Light Tool Kit (FLTK). # @@ -68,6 +68,9 @@ distclean: clean makeinclude: configure configh.in makeinclude.in ./configure +configure: configure.in + autoconf + # -# End of "$Id: Makefile,v 1.12.2.5 2001/01/22 15:13:37 easysw Exp $". +# End of "$Id: Makefile,v 1.12.2.6 2001/03/14 17:20:01 spitzak Exp $". # diff --git a/documentation/Fl_Gl_Window.html b/documentation/Fl_Gl_Window.html index 6e5ad96be8d326b7b1790d749eee64b25a6f555a..079fc5eecd517235fc7e8582140a9785c06ae96d 100644 --- a/documentation/Fl_Gl_Window.html +++ b/documentation/Fl_Gl_Window.html @@ -41,6 +41,7 @@ very well for single-buffered. </P> </UL> </TD><TD align=left valign=top> <UL> +<LI><A href=#Fl_Gl_Window.context>context</A></LI> <LI><A href=#Fl_Gl_Window.draw>draw</A></LI> <LI><A href=#Fl_Gl_Window.draw_overlay>draw_overlay</A></LI> <LI><A href=#Fl_Gl_Window.handle>handle</A></LI> @@ -120,6 +121,22 @@ window a child of another window if you wish to do this! </P> <BR> int Fl_Gl_Window::can_do() const</A></H4> Returns non-zero if the hardware supports the given or current OpenGL mode. + +<h4><a name=Fl_Gl_Window.context>void* Fl_Gl_Window::context() const; +<br>void Fl_Gl_Window::context(void*, int destroy_flag = false);</a></h4> + +Return or set 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 <a +href=#make_current><tt>make_current()</tt></a> is called, this is +useful for getting around bugs in OpenGL implementations. + +<p>If <i>destroy_flag</i> is true the context will be destroyed by +fltk when the window is destroyed, or when the <a +href=#mode><tt>mode()</tt></a> is changed, or the next time +<tt>context(x)</tt> is called. + <H4><A name=Fl_Gl_Window.valid>char Fl_Gl_Window::valid() const <BR> void Fl_Gl_Window::valid(char i)</A></H4> <TT>Fl_Gl_Window::valid()</TT> is turned off when FLTK creates a new diff --git a/src/Fl_Gl_Choice.H b/src/Fl_Gl_Choice.H index 986ee5d651ff95091d4ddfa4028f1ccc7387e808..2fd10c967f398801c0a2fd5d18225d7bb9759bd6 100644 --- a/src/Fl_Gl_Choice.H +++ b/src/Fl_Gl_Choice.H @@ -1,5 +1,5 @@ // -// "$Id: Fl_Gl_Choice.H,v 1.4.2.5 2001/01/22 15:13:39 easysw Exp $" +// "$Id: Fl_Gl_Choice.H,v 1.4.2.6 2001/03/14 17:20:01 spitzak Exp $" // // OpenGL definitions for the Fast Light Tool Kit (FLTK). // @@ -20,42 +20,49 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 // USA. // -// Please report all bugs and problems to "fltk-bugs@fltk.org". +// Please report all bugs and problems to "fltk-bugs@easysw.com". // // Internal interface to set up OpenGL. // -// A "Fl_Gl_Choice" is used to cache results of calling the -// OpenGL code for system-specific information needed to -// implement a "mode". -// For X this is a visual, and this must be called *before* -// the X window is created. -// For win32 this can be delayed to a more convienent time, -// as it only returns information for modifying a device -// context. -// This is used by Fl_Gl_Window, gl_start(), and gl_visual() +// A "Fl_Gl_Choice" 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 +// Fl_Gl_Choice 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 Fl_Gl_Window, 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 <windows.h> # include <FL/gl.h> -# define GLXContext HGLRC -# define GLX_BUFFER_SIZE 1 -# define GLX_RGBA 2 -# define GLX_GREEN_SIZE 3 -# define GLX_ALPHA_SIZE 4 -# define GLX_ACCUM_GREEN_SIZE 5 -# define GLX_ACCUM_ALPHA_SIZE 6 -# define GLX_DOUBLEBUFFER 7 -# define GLX_DEPTH_SIZE 8 -# define GLX_STENCIL_SIZE 9 +# define GLContext HGLRC #else # include <GL/glx.h> +# define GLContext GLXContext #endif -// one of these structures is returned: +// Describes crap needed to create a GLContext. class Fl_Gl_Choice { int mode; const int *alist; @@ -68,28 +75,35 @@ public: XVisualInfo *vis; // the visual to use Colormap colormap; // a colormap for that visual #endif - uchar r,d,o; // rgb mode, double buffered, overlay flags // 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 Fl_Gl_Choice *find(int mode, const int *); }; -extern GLXContext fl_first_context; // used to make all contexts share -extern GLXContext fl_current_context; - class Fl_Window; #ifdef WIN32 -// This must be called before fl_set_gl_context works: -HDC fl_private_dc(Fl_Window*, int, Fl_Gl_Choice **gp); + +GLContext fl_create_gl_context(Fl_Window*, const Fl_Gl_Choice*, int layer=0); + +#else + +GLContext fl_create_gl_context(XVisualInfo* vis); + +static inline +GLContext fl_create_gl_context(Fl_Window*, const Fl_Gl_Choice* g) { + return fl_create_gl_context(g->vis); +} + #endif -void fl_set_gl_context(Fl_Window*, GLXContext); +void fl_set_gl_context(Fl_Window*, GLContext); void fl_no_gl_context(); +void fl_delete_gl_context(GLContext); #endif // -// End of "$Id: Fl_Gl_Choice.H,v 1.4.2.5 2001/01/22 15:13:39 easysw Exp $". +// End of "$Id: Fl_Gl_Choice.H,v 1.4.2.6 2001/03/14 17:20:01 spitzak Exp $". // diff --git a/src/Fl_Gl_Choice.cxx b/src/Fl_Gl_Choice.cxx index 31285e9c6ce110b02e1b5a2221ca97e91f97b6a9..420367348f9a4e1572c54710e93d2daeac3af8e4 100644 --- a/src/Fl_Gl_Choice.cxx +++ b/src/Fl_Gl_Choice.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Gl_Choice.cxx,v 1.5.2.5 2001/01/22 15:13:39 easysw Exp $" +// "$Id: Fl_Gl_Choice.cxx,v 1.5.2.6 2001/03/14 17:20:01 spitzak Exp $" // // OpenGL visual selection code for the Fast Light Tool Kit (FLTK). // @@ -20,7 +20,7 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 // USA. // -// Please report all bugs and problems to "fltk-bugs@fltk.org". +// Please report all bugs and problems to "fltk-bugs@easysw.com". // #include <config.h> @@ -32,7 +32,6 @@ #include "Fl_Gl_Choice.H" static Fl_Gl_Choice *first; -GLXContext fl_first_context; // this assummes one of the two arguments is zero: // We keep the list system in Win32 to stay compatible and interpret @@ -143,16 +142,8 @@ Fl_Gl_Choice *Fl_Gl_Choice::find(int mode, const int *alist) { #ifdef WIN32 g->pixelformat = pixelformat; g->pfd = chosen_pfd; - g->d = ((mode&FL_DOUBLE) != 0); - g->r = (mode & FL_INDEX); - g->o = 0; // not an overlay #else g->vis = vis; - g->colormap = 0; - int i; - glXGetConfig(fl_display, vis, GLX_DOUBLEBUFFER, &i); g->d = i; - glXGetConfig(fl_display, vis, GLX_RGBA, &i); g->r = i; - glXGetConfig(fl_display, vis, GLX_LEVEL, &i); g->o = i; if (/*MaxCmapsOfScreen(ScreenOfDisplay(fl_display,fl_screen))==1 && */ vis->visualid == fl_visual->visualid && @@ -166,36 +157,50 @@ Fl_Gl_Choice *Fl_Gl_Choice::find(int mode, const int *alist) { return g; } +static GLContext first_context; + #ifdef WIN32 -HDC fl_private_dc(Fl_Window* w, int mode, Fl_Gl_Choice **gp) { - Fl_X* i = Fl_X::i(w); - if (!i->private_dc) { - i->private_dc = GetDCEx(i->xid, 0, DCX_CACHE); - Fl_Gl_Choice *g = Fl_Gl_Choice::find(mode, 0); - if (gp) *gp = g; +GLContext fl_create_gl_context(Fl_Window* window, const Fl_Gl_Choice* 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); SetPixelFormat(i->private_dc, g->pixelformat, &g->pfd); #if USE_COLORMAP if (fl_palette) SelectPalette(i->private_dc, fl_palette, FALSE); #endif } - return i->private_dc; + GLContext context = + layer ? wglCreateLayerContext(hdc, layer) : wglCreateContext(hdc); + if (context) { + if (first_context) wglShareLists(first_context, context); + else first_context = context; + } + return context; } -#endif +#else -static GLXContext cached_context; +GLContext fl_create_gl_context(XVisualInfo* vis) { + GLContext context = glXCreateContext(fl_display, vis, first_context, 1); + if (!first_context) first_context = context; + return context; +} + +#endif +static GLContext cached_context; static Fl_Window* cached_window; -void fl_set_gl_context(Fl_Window* w, GLXContext c) { - if (c != cached_context || w != cached_window) { - cached_context = c; +void fl_set_gl_context(Fl_Window* w, GLContext context) { + if (context != cached_context || w != cached_window) { + cached_context = context; cached_window = w; #ifdef WIN32 - wglMakeCurrent(Fl_X::i(w)->private_dc, c); + wglMakeCurrent(Fl_X::i(w)->private_dc, context); #else - glXMakeCurrent(fl_display, fl_xid(w), c); + glXMakeCurrent(fl_display, fl_xid(w), context); #endif } } @@ -210,8 +215,19 @@ void fl_no_gl_context() { #endif } +void fl_delete_gl_context(GLContext context) { + if (cached_context == context) fl_no_gl_context(); + if (context != first_context) { +#ifdef WIN32 + wglDeleteContext(context); +#else + glXDestroyContext(fl_display, context); +#endif + } +} + #endif // -// End of "$Id: Fl_Gl_Choice.cxx,v 1.5.2.5 2001/01/22 15:13:39 easysw Exp $". +// End of "$Id: Fl_Gl_Choice.cxx,v 1.5.2.6 2001/03/14 17:20:01 spitzak Exp $". // diff --git a/src/Fl_Gl_Overlay.cxx b/src/Fl_Gl_Overlay.cxx index fd040abb0e66ca7f944b82810f2472c01bb04eed..1272c11a2807f7f439d0a8bee7f7c27d6f6673d1 100644 --- a/src/Fl_Gl_Overlay.cxx +++ b/src/Fl_Gl_Overlay.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Gl_Overlay.cxx,v 1.5.2.14 2001/01/22 15:13:39 easysw Exp $" +// "$Id: Fl_Gl_Overlay.cxx,v 1.5.2.15 2001/03/14 17:20:01 spitzak Exp $" // // OpenGL overlay code for the Fast Light Tool Kit (FLTK). // @@ -20,21 +20,25 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 // USA. // -// Please report all bugs and problems to "fltk-bugs@fltk.org". +// Please report all bugs and problems to "fltk-bugs@easysw.com". // #include <config.h> #if HAVE_GL #include <FL/Fl.H> -#include <FL/Fl_Gl_Window.H> #include <FL/x.H> #include "Fl_Gl_Choice.H" +#include <FL/Fl_Gl_Window.H> #include <stdlib.h> -#if HAVE_GL_OVERLAY +#if !HAVE_GL_OVERLAY + +int Fl_Gl_Window::can_do_overlay() {return 0;} + +void Fl_Gl_Window::make_overlay() {overlay = this;} -#if !defined(_WIN32) && !defined(WIN32) +#else // Methods on Fl_Gl_Window that create an overlay window. Because // many programs don't need the overlay, this is seperated into this @@ -51,11 +55,14 @@ // "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; -static Fl_Gl_Choice overlay_choice; extern uchar fl_overlay; class _Fl_Gl_Overlay : public Fl_Gl_Window { @@ -65,12 +72,6 @@ public: _Fl_Gl_Overlay(int x, int y, int w, int h) : Fl_Gl_Window(x,y,w,h) { set_flag(INACTIVE); - overlay_choice.vis = fl_overlay_visual; - overlay_choice.colormap = fl_overlay_colormap; - overlay_choice.r = 0; - overlay_choice.d = 0; - overlay_choice.o = 1; - g = &overlay_choice; } }; @@ -88,91 +89,87 @@ void _Fl_Gl_Overlay::draw() { } void _Fl_Gl_Overlay::show() { - if (shown()) {Fl_Gl_Window::show(); return;} - fl_background_pixel = int(fl_transparent_pixel); + 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: + Fl_Window *w = window(); + for (;;) {Fl_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); + } Fl_Gl_Window::show(); - fl_background_pixel = -1; - // find the outermost window to tell wm about the colormap: - Fl_Window *w = window(); - for (;;) {Fl_Window *w1 = w->window(); if (!w1) break; w = w1;} - XSetWMColormapWindows(fl_display, fl_xid(w), &(Fl_X::i(this)->xid), 1); } int Fl_Gl_Window::can_do_overlay() { return fl_find_overlay_visual() != 0; } -#else // _WIN32: - -int Fl_Gl_Window::can_do_overlay() { - Fl_Gl_Choice* choice = Fl_Gl_Choice::find(0,0); - return (choice && (choice->pfd.bReserved & 15)); +void Fl_Gl_Window::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 + } } -extern int fl_overlay_depth; - -#endif - #else +//////////////////////////////////////////////////////////////// +// WIN32 version: -int Fl_Gl_Window::can_do_overlay() {return 0;} - -#endif +//static COLORREF *palette; +extern int fl_overlay_depth; void Fl_Gl_Window::make_overlay() { - if (!overlay) { -#if HAVE_GL_OVERLAY -#if defined(_WIN32) || defined(WIN32) - HDC hdc = fl_private_dc(this, mode_,&g); - GLXContext context = wglCreateLayerContext(hdc, 1); - if (context) { // we found a usable overlay context - if (fl_first_context) wglShareLists(fl_first_context, context); - else fl_first_context = context; - 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; Fl::get_color((Fl_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; + 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; Fl::get_color((Fl_Color)i,r,g,b); + palette[i] = RGB(r,g,b); } -#else - if (can_do_overlay()) { - _Fl_Gl_Overlay* o = new _Fl_Gl_Overlay(0,0,w(),h()); - overlay = o; - add(*o); - o->show(); - return; + // 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); } -#endif -#endif - overlay = this; // fake the overlay + // and use it: + wglSetLayerPaletteEntries(hdc, 1, 1, n, palette+1); + wglRealizeLayerPalette(hdc, 1, TRUE); } + valid(0); + return; } +//////////////////////////////////////////////////////////////// +#endif + +#endif + void Fl_Gl_Window::redraw_overlay() { if (!shown()) return; make_overlay(); -#if !defined(_WIN32) && !defined(WIN32) +#ifndef WIN32 if (overlay != this) ((Fl_Gl_Window*)overlay)->redraw(); else @@ -184,8 +181,8 @@ void Fl_Gl_Window::make_overlay_current() { make_overlay(); #if HAVE_GL_OVERLAY if (overlay != this) { -#if defined(_WIN32) || defined(WIN32) - fl_set_gl_context(this, (GLXContext)overlay); +#ifdef WIN32 + fl_set_gl_context(this, (GLContext)overlay); // if (fl_overlay_depth) // wglRealizeLayerPalette(Fl_X::i(this)->private_dc, 1, TRUE); #else @@ -198,7 +195,7 @@ void Fl_Gl_Window::make_overlay_current() { void Fl_Gl_Window::hide_overlay() { #if HAVE_GL_OVERLAY -#if defined(_WIN32) || defined(WIN32) +#ifdef WIN32 // nothing needs to be done? Or should it be erased? #else if (overlay && overlay!=this) ((Fl_Gl_Window*)overlay)->hide(); @@ -209,5 +206,5 @@ void Fl_Gl_Window::hide_overlay() { #endif // -// End of "$Id: Fl_Gl_Overlay.cxx,v 1.5.2.14 2001/01/22 15:13:39 easysw Exp $". +// End of "$Id: Fl_Gl_Overlay.cxx,v 1.5.2.15 2001/03/14 17:20:01 spitzak Exp $". // diff --git a/src/Fl_Gl_Window.cxx b/src/Fl_Gl_Window.cxx index 87806a54aa4030f8fdedc4967e18ae2d33498613..70d46ab68a144da517600546b963766775cf277c 100644 --- a/src/Fl_Gl_Window.cxx +++ b/src/Fl_Gl_Window.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Gl_Window.cxx,v 1.12.2.20 2001/01/22 15:13:39 easysw Exp $" +// "$Id: Fl_Gl_Window.cxx,v 1.12.2.21 2001/03/14 17:20:01 spitzak Exp $" // // OpenGL window code for the Fast Light Tool Kit (FLTK). // @@ -28,8 +28,8 @@ #include <FL/Fl.H> #include <FL/x.H> -#include <FL/Fl_Gl_Window.H> #include "Fl_Gl_Choice.H" +#include <FL/Fl_Gl_Window.H> #include <stdlib.h> #include <string.h> @@ -63,66 +63,65 @@ int Fl_Gl_Window::can_do(int a, const int *b) { } void Fl_Gl_Window::show() { -#if !defined(_WIN32) && !defined(WIN32) if (!shown()) { if (!g) { g = Fl_Gl_Choice::find(mode_,alist); if (!g) {Fl::error("Insufficient GL support"); return;} } +#ifndef WIN32 Fl_X::make_xid(this, g->vis, g->colormap); if (overlay && overlay != this) ((Fl_Gl_Window*)overlay)->show(); - } #endif + } Fl_Window::show(); } void Fl_Gl_Window::invalidate() { valid(0); -#if !defined(_WIN32) && !defined(WIN32) +#ifndef WIN32 if (overlay) ((Fl_Gl_Window*)overlay)->valid(0); #endif } int Fl_Gl_Window::mode(int m, const int *a) { if (m == mode_ && a == alist) return 0; +#ifndef WIN32 + int oldmode = mode_; + Fl_Gl_Choice* oldg = g; +#endif + context(0); mode_ = m; alist = a; -#if defined(_WIN32) || defined(WIN32) - // destroy context and g: - if (shown()) {hide(); show();} -#else - // under X, if the visual changes we must make a new X window (!): if (shown()) { - Fl_Gl_Choice *g1 = g; - g = Fl_Gl_Choice::find(mode_,alist); - if (!g || g->vis->visualid != g1->vis->visualid || g->d != g1->d) { - hide(); show(); + g = Fl_Gl_Choice::find(m, a); +#ifndef WIN32 + // under X, if the visual changes we must make a new X window (yuck!): + if (!g || g->vis->visualid!=oldg->vis->visualid || (oldmode^m)&FL_DOUBLE) { + hide(); + show(); } - } #endif + } else { + g = 0; + } return 1; } +#define NON_LOCAL_CONTEXT 0x80000000 + void Fl_Gl_Window::make_current() { - if (!context) { -#if defined(_WIN32) || defined(WIN32) - context = wglCreateContext(fl_private_dc(this, mode_,&g)); - if (fl_first_context) wglShareLists(fl_first_context, (GLXContext)context); - else fl_first_context = (GLXContext)context; -#else - context = glXCreateContext(fl_display, g->vis, fl_first_context, 1); - if (!fl_first_context) fl_first_context = (GLXContext)context; -#endif + if (!context_) { + mode_ &= ~NON_LOCAL_CONTEXT; + context_ = fl_create_gl_context(this, g); valid(0); } - fl_set_gl_context(this, (GLXContext)context); -#if (defined(_WIN32) || defined(WIN32)) && USE_COLORMAP + fl_set_gl_context(this, context_); +#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 (g->d) glDrawBuffer(GL_BACK); current_ = this; } @@ -142,7 +141,7 @@ void Fl_Gl_Window::ortho() { } void Fl_Gl_Window::swap_buffers() { -#if defined(_WIN32) || defined(WIN32) +#ifdef WIN32 #if HAVE_GL_OVERLAY // Do not swap the overlay, to match GLX: wglSwapLayerBuffers(Fl_X::i(this)->private_dc, WGL_SWAP_MAIN_PLANE); @@ -154,25 +153,25 @@ void Fl_Gl_Window::swap_buffers() { #endif } -#if HAVE_GL_OVERLAY && defined(_WIN32) +#if HAVE_GL_OVERLAY && defined(WIN32) uchar fl_overlay; // changes how fl_color() works int fl_overlay_depth = 0; #endif void Fl_Gl_Window::flush() { uchar save_valid = valid_; -#if defined(_WIN32) || defined(WIN32) + +#if HAVE_GL_OVERLAY && defined(WIN32) + // SGI 320 messes up overlay with user-defined cursors: bool fixcursor = Fl_X::i(this)->cursor && Fl_X::i(this)->cursor != fl_default_cursor; if (fixcursor) SetCursor(0); -#endif -#if HAVE_GL_OVERLAY && (defined(_WIN32) || defined(WIN32)) // Draw into hardware overlay planes: if (overlay && overlay != this && (damage()&(FL_DAMAGE_OVERLAY|FL_DAMAGE_EXPOSE) || !save_valid)) { - fl_set_gl_context(this, (GLXContext)overlay); + fl_set_gl_context(this, (GLContext)overlay); if (fl_overlay_depth) wglRealizeLayerPalette(Fl_X::i(this)->private_dc, 1, TRUE); glDisable(GL_SCISSOR_TEST); @@ -191,7 +190,9 @@ void Fl_Gl_Window::flush() { make_current(); - if (g->d) { + if (mode_ & FL_DOUBLE) { + + glDrawBuffer(GL_BACK); if (!SWAP_TYPE) { SWAP_TYPE = UNDEFINED; @@ -224,16 +225,10 @@ void Fl_Gl_Window::flush() { if (damage1_ || damage() != FL_DAMAGE_OVERLAY || !save_valid) draw(); // we use a seperate context for the copy because rasterpos must be 0 // and depth test needs to be off: - static GLXContext ortho_context = 0; + static GLContext ortho_context = 0; static Fl_Gl_Window* ortho_window = 0; int init = !ortho_context; - if (init) { -#if defined(_WIN32) || defined(WIN32) - ortho_context = wglCreateContext(Fl_X::i(this)->private_dc); -#else - ortho_context =glXCreateContext(fl_display,g->vis,fl_first_context,1); -#endif - } + if (init) ortho_context = fl_create_gl_context(this, g); fl_set_gl_context(this, ortho_context); if (init || !save_valid || ortho_window != this) { glDisable(GL_DEPTH_TEST); @@ -274,7 +269,7 @@ void Fl_Gl_Window::flush() { } -#if defined(_WIN32) || defined(WIN32) +#if HAVE_GL_OVERLAY && defined(WIN32) if (fixcursor) SetCursor(Fl_X::i(this)->cursor); #endif valid(1); @@ -283,7 +278,7 @@ void Fl_Gl_Window::flush() { void Fl_Gl_Window::resize(int X,int Y,int W,int H) { if (W != w() || H != h()) { valid(0); -#if !defined(_WIN32) && !defined(WIN32) +#ifndef WIN32 if (!resizable() && overlay && overlay != this) ((Fl_Gl_Window*)overlay)->resize(0,0,W,H); #endif @@ -291,26 +286,18 @@ void Fl_Gl_Window::resize(int X,int Y,int W,int H) { Fl_Window::resize(X,Y,W,H); } +void Fl_Gl_Window::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; +} + void Fl_Gl_Window::hide() { - if (context) { - fl_no_gl_context(); - if (context != fl_first_context) { -#if defined(_WIN32) || defined(WIN32) - wglDeleteContext((GLXContext)context); -#else - glXDestroyContext(fl_display, (GLXContext)context); -#endif - } -// This causes incompatibility with some OpenGL libraries -// I don't think this is not necessary in any case, right? -//#ifdef GLX_MESA_release_buffers -// glXReleaseBuffersMESA(fl_display, fl_xid(this)); -//#endif - context = 0; - } -#if HAVE_GL_OVERLAY && (defined(_WIN32) || defined(WIN32)) - if (overlay && overlay != this && (GLXContext)overlay != fl_first_context) { - wglDeleteContext((GLXContext)overlay); + context(0); +#if HAVE_GL_OVERLAY && defined(WIN32) + if (overlay && overlay != this) { + fl_delete_gl_context((GLContext)overlay); overlay = 0; } #endif @@ -327,7 +314,7 @@ void Fl_Gl_Window::init() { box(FL_NO_BOX); mode_ = FL_RGB | FL_DEPTH | FL_DOUBLE; alist = 0; - context = 0; + context_ = 0; g = 0; overlay = 0; } @@ -337,5 +324,5 @@ void Fl_Gl_Window::draw_overlay() {} #endif // -// End of "$Id: Fl_Gl_Window.cxx,v 1.12.2.20 2001/01/22 15:13:39 easysw Exp $". +// End of "$Id: Fl_Gl_Window.cxx,v 1.12.2.21 2001/03/14 17:20:01 spitzak Exp $". // diff --git a/src/Fl_compose.cxx b/src/Fl_compose.cxx index 8fa620be539817555424378726bd461bf187b504..5b9a9f619722913d1176d41645f2df9ffb5778f8 100644 --- a/src/Fl_compose.cxx +++ b/src/Fl_compose.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_compose.cxx,v 1.1.2.6 2001/01/22 15:13:40 easysw Exp $" +// "$Id: Fl_compose.cxx,v 1.1.2.7 2001/03/14 17:20:01 spitzak Exp $" // // Character compose processing for the Fast Light Tool Kit (FLTK). // @@ -30,7 +30,7 @@ static const char* const compose_pairs = "`A'A^A~A:A*AAE,C`E'E^E:E`I'I^I:I-D~N`O'O^O~O:Ox O/`U'U^U:U'YTHss" "`a'a^a~a:a*aae,c`e'e^e:e`i'i^i:i-d~n`o'o^o~o:o-:o/`u'u^u:u'yth:y"; -#if !defined(_WIN32) && !defined(WIN32) // X only +#ifndef WIN32 // X only // X dead-key lookup table. This turns a dead-key keysym into the // first of two characters for one of the compose sequences. These // keysyms start at 0xFE50. @@ -113,7 +113,7 @@ int Fl::compose(int& del) { return 1; } -#if !defined(_WIN32) && !defined(WIN32) // X only +#ifndef WIN32 // X only // See if they typed a dead key. This gets it into the same state as // typing prefix+accent: if (i >= 0xfe50 && i <= 0xfe5b) { diff --git a/src/fl_file_chooser.cxx b/src/fl_file_chooser.cxx index 70987668eb223b2b9af14cc93deb3b103cc760f3..1e6b463e3358827f8e391a57b068de8bd4f66ff2 100644 --- a/src/fl_file_chooser.cxx +++ b/src/fl_file_chooser.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_file_chooser.cxx,v 1.10.2.8 2001/01/22 15:13:41 easysw Exp $" +// "$Id: fl_file_chooser.cxx,v 1.10.2.9 2001/03/14 17:20:02 spitzak Exp $" // // File chooser widget for the Fast Light Tool Kit (FLTK). // @@ -231,7 +231,7 @@ int FCB::get(char* buf) { for (dirent** r = q+1; n && r < last; r++) { if (!item_height(*r, 0)) continue; int i; -#if defined(_WIN32) || defined(WIN32) +#ifdef WIN32 for (i=0; i<n && tolower((*q)->d_name[i])==tolower((*r)->d_name[i]); i++) {} #else for (i=0; i<n && (*q)->d_name[i]==(*r)->d_name[i]; i++) {} @@ -632,5 +632,5 @@ char* fl_file_chooser(const char* message, const char* pat, const char* fname) } // -// End of "$Id: fl_file_chooser.cxx,v 1.10.2.8 2001/01/22 15:13:41 easysw Exp $". +// End of "$Id: fl_file_chooser.cxx,v 1.10.2.9 2001/03/14 17:20:02 spitzak Exp $". // diff --git a/src/gl_draw.cxx b/src/gl_draw.cxx index c24463c5d11a00898d5dcbb3ced0a2ea66fb8048..2b0348c60e09d71f3d9af50ba70f489a60e0770c 100644 --- a/src/gl_draw.cxx +++ b/src/gl_draw.cxx @@ -1,5 +1,5 @@ // -// "$Id: gl_draw.cxx,v 1.7.2.4 2001/01/22 15:13:41 easysw Exp $" +// "$Id: gl_draw.cxx,v 1.7.2.5 2001/03/14 17:20:02 spitzak Exp $" // // OpenGL drawing support routines for the Fast Light Tool Kit (FLTK). // @@ -37,14 +37,14 @@ #include "Fl_Font.H" #include <string.h> -void gl_font(int fontid, int size) {fl_font(fontid, size);} int gl_height() {return fl_height();} int gl_descent() {return fl_descent();} double gl_width(const char* s) {return fl_width(s);} double gl_width(const char* s, int n) {return fl_width(s,n);} double gl_width(uchar c) {return fl_width(c);} -void gl_draw(const char* str, int n) { +void gl_font(int fontid, int size) { + fl_font(fontid, size); if (!fl_fontsize->listbase) { #ifdef WIN32 int base = fl_fontsize->metr.tmFirstChar; @@ -60,11 +60,11 @@ void gl_draw(const char* str, int n) { glXUseXFont(fl_xfont->fid, base, size, fl_fontsize->listbase+base); #endif } + glListBase(fl_fontsize->listbase); +} - glPushAttrib(GL_LIST_BIT); - glListBase(fl_fontsize->listbase); - glCallLists(n, GL_UNSIGNED_BYTE, str); - glPopAttrib(); +void gl_draw(const char* str, int n) { + glCallLists(n, GL_UNSIGNED_BYTE, str); } void gl_draw(const char* str, int n, int x, int y) { @@ -155,5 +155,5 @@ void gl_draw_image(const uchar* b, int x, int y, int w, int h, int d, int ld) { #endif // -// End of "$Id: gl_draw.cxx,v 1.7.2.4 2001/01/22 15:13:41 easysw Exp $". +// End of "$Id: gl_draw.cxx,v 1.7.2.5 2001/03/14 17:20:02 spitzak Exp $". // diff --git a/src/gl_start.cxx b/src/gl_start.cxx index 3438fc46411e4419c3910583fa22fb76ed03a4e0..f0274eaf473bc280505e413f34e9d02d7be89af1 100644 --- a/src/gl_start.cxx +++ b/src/gl_start.cxx @@ -1,5 +1,5 @@ // -// "$Id: gl_start.cxx,v 1.6.2.4 2001/01/22 15:13:41 easysw Exp $" +// "$Id: gl_start.cxx,v 1.6.2.5 2001/03/14 17:20:02 spitzak Exp $" // // OpenGL context routines for the Fast Light Tool Kit (FLTK). // @@ -20,7 +20,7 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 // USA. // -// Please report all bugs and problems to "fltk-bugs@fltk.org". +// Please report all bugs and problems to "fltk-bugs@easysw.com". // // You MUST use gl_visual() to select the default visual before doing @@ -42,35 +42,27 @@ #include <FL/Fl_Window.H> #include <FL/x.H> #include <FL/fl_draw.H> - #include "Fl_Gl_Choice.H" -extern GLXContext fl_first_context; // in Fl_Gl_Choice.C extern int fl_clip_state_number; // in fl_rect.C -static GLXContext context; +static GLContext context; static int clip_state_number=-1; static int pw, ph; #ifdef WIN32 -static int default_mode; +static Fl_Gl_Choice* gl_choice; #endif Region XRectangleRegion(int x, int y, int w, int h); // in fl_rect.C void gl_start() { -#ifdef WIN32 - HDC hdc = fl_private_dc(Fl_Window::current(), default_mode,0); -#endif if (!context) { #ifdef WIN32 - context = wglCreateContext(hdc); - if (!fl_first_context) fl_first_context = context; - else wglShareLists(fl_first_context, context); + if (!gl_choice) Fl::gl_visual(0); + context = fl_create_gl_context(Fl_Window::current(), gl_choice); #else - context = glXCreateContext(fl_display, fl_visual, fl_first_context, 1); - if (!context) Fl::fatal("OpenGL does not support this visual"); - if (!fl_first_context) fl_first_context = context; + context = fl_create_gl_context(fl_visual); #endif } fl_set_gl_context(Fl_Window::current(), context); @@ -100,19 +92,18 @@ void gl_start() { } void gl_finish() { -#ifdef WIN32 glFlush(); -#else +#ifndef WIN32 glXWaitGL(); #endif } int Fl::gl_visual(int mode, int *alist) { -#ifdef WIN32 - default_mode = mode; -#else Fl_Gl_Choice *c = Fl_Gl_Choice::find(mode,alist); if (!c) return 0; +#ifdef WIN32 + gl_choice = c; +#else fl_visual = c->vis; fl_colormap = c->colormap; #endif @@ -122,5 +113,5 @@ int Fl::gl_visual(int mode, int *alist) { #endif // -// End of "$Id: gl_start.cxx,v 1.6.2.4 2001/01/22 15:13:41 easysw Exp $". +// End of "$Id: gl_start.cxx,v 1.6.2.5 2001/03/14 17:20:02 spitzak Exp $". // diff --git a/test/cube.cxx b/test/cube.cxx index 0236b3ba72ae306d9709d6d00c7f3e9157404294..58d9d7579709f406f4d779d89a482b52ba4973ca 100644 --- a/test/cube.cxx +++ b/test/cube.cxx @@ -1,5 +1,5 @@ // -// "$Id: cube.cxx,v 1.4.2.4 2001/01/22 15:13:41 easysw Exp $" +// "$Id: cube.cxx,v 1.4.2.5 2001/03/14 17:20:02 spitzak Exp $" // // Another forms test program for the Fast Light Tool Kit (FLTK). // @@ -152,6 +152,16 @@ int main(int argc, char **argv) { form->show(argc,argv); cube->show(); cube2->show(); +#if 0 + // This demonstrates how to manipulate OpenGL contexts. + // In this case the same context is used by multiple windows (I'm not + // sure if this is allowed on Win32, can somebody check?). + // This fixes a bug on the XFree86 3.0 OpenGL where only one context + // per program seems to work, but there are probably better uses for + // this! + cube->make_current(); // causes context to be created + cube2->context(cube->context()); // share the contexts +#endif for (;;) { if (form->visible() && speed->value()) {if (!Fl::check()) break;} // returns immediately @@ -169,5 +179,5 @@ int main(int argc, char **argv) { } // -// End of "$Id: cube.cxx,v 1.4.2.4 2001/01/22 15:13:41 easysw Exp $". +// End of "$Id: cube.cxx,v 1.4.2.5 2001/03/14 17:20:02 spitzak Exp $". //