summaryrefslogtreecommitdiff
path: root/src/Fl_Gl_Choice.cxx
diff options
context:
space:
mode:
authorManolo Gouy <Manolo>2016-05-08 06:42:57 +0000
committerManolo Gouy <Manolo>2016-05-08 06:42:57 +0000
commit300747225ca2de6db483287fa44ed24d18765b99 (patch)
tree6fb63553203032bc98f4dd84b3162c8e306ffc32 /src/Fl_Gl_Choice.cxx
parent048bb2b0f6ea49d0a88eee879017949bbd1ac83d (diff)
Rewrite OpenGL-related code under the driver model.
Class Fl_Gl_Window_Driver, with its platform-specific derived classes, is created to hold platform-specific, OpenGL code. File gl_draw.cxx still needs to be converted to the driver model. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3-porting@11716 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src/Fl_Gl_Choice.cxx')
-rw-r--r--src/Fl_Gl_Choice.cxx414
1 files changed, 219 insertions, 195 deletions
diff --git a/src/Fl_Gl_Choice.cxx b/src/Fl_Gl_Choice.cxx
index 6d5e8f6e4..5eb55cac5 100644
--- a/src/Fl_Gl_Choice.cxx
+++ b/src/Fl_Gl_Choice.cxx
@@ -16,49 +16,221 @@
// http://www.fltk.org/str.php
//
-#include <config.h>
+#include "config_lib.h"
#if HAVE_GL
# include <FL/Fl.H>
-# include <FL/x.H>
# include <FL/Fl_Graphics_Driver.H>
# include <stdlib.h>
# include "Fl_Gl_Choice.H"
+# include <FL/Fl_Gl_Window.H>
+# include <FL/Fl_Gl_Window_Driver.H>
# include <FL/gl_draw.H>
# include "flstring.h"
# include <FL/fl_utf8.h>
-#if defined(WIN32)
-#include "drivers/WinAPI/Fl_WinAPI_Window_Driver.H"
-#elif defined(__APPLE__) // PORTME: platform OpenGL management
-#include "drivers/Cocoa/Fl_Cocoa_Screen_Driver.H"
-#elif defined(FL_PORTING)
-# pragma message "FL_PORTING: add code to list and select OpenGL drawing contexts"
-#else
-#endif
-
-# ifdef WIN32
-void fl_save_dc(HWND, HDC);
-#elif defined(__APPLE__) // PORTME: platform OpenGL management
-extern void gl_texture_reset();
-#endif
+
+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();
+}
static Fl_Gl_Choice *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...
-Fl_Gl_Choice *Fl_Gl_Choice::find(int m, const int *alistp) {
+Fl_Gl_Choice *Fl_Gl_Window_Driver::find_begin(int m, const int *alistp) {
Fl_Gl_Choice *g;
-
for (g = first; g; g = g->next)
- if (g->mode == m && g->alist == alistp)
+ if (g->mode == m && g->alist == alistp)
return g;
+ return NULL;
+}
+
+
+static GLContext cached_context;
+static Fl_Window* cached_window;
+
+
+#ifdef FL_CFG_GFX_QUARTZ
+#include "drivers/Cocoa/Fl_Cocoa_Screen_Driver.H"
+extern void gl_texture_reset();
+
+Fl_Gl_Choice *Fl_Cocoa_Gl_Window_Driver::find(int m, const int *alistp)
+{
+ Fl_Gl_Choice *g = Fl_Gl_Window_Driver::find_begin(m, alistp);
+ if (g) return g;
+ NSOpenGLPixelFormat* fmt = Fl_Cocoa_Screen_Driver::mode_to_NSOpenGLPixelFormat(m, alistp);
+ if (!fmt) return 0;
+ g = new Fl_Gl_Choice(m, alistp, first);
+ first = g;
+ g->pixelformat = fmt;
+ return g;
+}
+
+GLContext Fl_Cocoa_Gl_Window_Driver::create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g, int layer) {
+ GLContext context, shared_ctx = 0;
+ if (context_list && nContext) shared_ctx = context_list[0];
+ // resets the pile of string textures used to draw strings
+ // necessary before the first context is created
+ if (!shared_ctx) gl_texture_reset();
+ context = Fl_Cocoa_Screen_Driver::create_GLcontext_for_window(g->pixelformat, shared_ctx, window);
+ if (!context) return 0;
+ add_context((GLContext)context);
+ return (context);
+}
+
+void Fl_Cocoa_Gl_Window_Driver::set_gl_context(Fl_Window* w, GLContext context) {
+ if (context != cached_context || w != cached_window) {
+ cached_context = context;
+ cached_window = w;
+ Fl_Cocoa_Screen_Driver::GLcontext_makecurrent(context);
+ }
+}
+
+void Fl_Cocoa_Gl_Window_Driver::delete_gl_context(GLContext context) {
+ if (cached_context == context) {
+ cached_context = 0;
+ cached_window = 0;
+ Fl_Cocoa_Screen_Driver::GL_cleardrawable();
+ }
+ Fl_Cocoa_Screen_Driver::GLcontext_release(context);
+ del_context(context);
+}
+
+#endif // FL_CFG_GFX_QUARTZ
+
+#ifdef FL_CFG_GFX_GDI
+# include <FL/x.H>
+#include "drivers/WinAPI/Fl_WinAPI_Window_Driver.H"
+extern void fl_save_dc(HWND, HDC);
+
+Fl_Gl_Choice *Fl_WinAPI_Gl_Window_Driver::find(int m, const int *alistp)
+{
+ Fl_Gl_Choice *g = Fl_Gl_Window_Driver::find_begin(m, alistp);
+ if (g) return g;
+
+ // Replacement for ChoosePixelFormat() that finds one with an overlay
+ // if possible:
+ HDC gc = (HDC)fl_graphics_driver->gc();
+ if (!gc) gc = fl_GetDC(0);
+ int pixelformat = 0;
+ PIXELFORMATDESCRIPTOR chosen_pfd;
+ for (int i = 1; ; i++) {
+ PIXELFORMATDESCRIPTOR pfd;
+ if (!DescribePixelFormat(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&FL_INDEX)?PFD_TYPE_COLORINDEX:PFD_TYPE_RGBA)) continue;
+ if ((m & FL_ALPHA) && !pfd.cAlphaBits) continue;
+ if ((m & FL_ACCUM) && !pfd.cAccumBits) continue;
+ if ((!(m & FL_DOUBLE)) != (!(pfd.dwFlags & PFD_DOUBLEBUFFER))) continue;
+ if ((!(m & FL_STEREO)) != (!(pfd.dwFlags & PFD_STEREO))) continue;
+ if ((m & FL_DEPTH) && !pfd.cDepthBits) continue;
+ if ((m & FL_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;
+
+ g = new Fl_Gl_Choice(m, alistp, first);
+ first = g;
+
+ g->pixelformat = pixelformat;
+ g->pfd = chosen_pfd;
+
+ return g;
+}
+
+
+GLContext Fl_WinAPI_Gl_Window_Driver::create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g, int layer)
+{
+ Fl_X* i = Fl_X::i(window);
+ HDC hdc = Fl_WinAPI_Window_Driver::driver(window)->private_dc;
+ if (!hdc) {
+ hdc = Fl_WinAPI_Window_Driver::driver(window)->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;
+}
+
+
+void Fl_WinAPI_Gl_Window_Driver::set_gl_context(Fl_Window* w, GLContext context) {
+ if (context != cached_context || w != cached_window) {
+ cached_context = context;
+ cached_window = w;
+ wglMakeCurrent(Fl_WinAPI_Window_Driver::driver(w)->private_dc, context);
+ }
+}
+
+void Fl_WinAPI_Gl_Window_Driver::delete_gl_context(GLContext context) {
+ if (cached_context == context) {
+ cached_context = 0;
+ cached_window = 0;
+ wglMakeCurrent(0, 0);
+ }
+ wglDeleteContext(context);
+ del_context(context);
+}
+
+#endif // FL_CFG_GFX_GDI
+
+#ifdef FL_CFG_GFX_XLIB
+# include <FL/x.H>
-#if defined(USE_X11)
+Fl_Gl_Choice *Fl_X11_Gl_Window_Driver::find(int m, const int *alistp)
+{
+ Fl_Gl_Choice *g = Fl_Gl_Window_Driver::find_begin(m, alistp);
+ if (g) return g;
+
const int *blist;
int list[32];
-
+
if (alistp)
blist = alistp;
else {
@@ -71,16 +243,16 @@ Fl_Gl_Choice *Fl_Gl_Choice::find(int m, const int *alistp) {
list[n++] = GLX_GREEN_SIZE;
list[n++] = (m & FL_RGB8) ? 8 : 1;
if (m & FL_ALPHA) {
- list[n++] = GLX_ALPHA_SIZE;
- list[n++] = (m & FL_RGB8) ? 8 : 1;
+ list[n++] = GLX_ALPHA_SIZE;
+ list[n++] = (m & FL_RGB8) ? 8 : 1;
}
if (m & FL_ACCUM) {
- list[n++] = GLX_ACCUM_GREEN_SIZE;
- list[n++] = 1;
- if (m & FL_ALPHA) {
- list[n++] = GLX_ACCUM_ALPHA_SIZE;
- list[n++] = 1;
- }
+ list[n++] = GLX_ACCUM_GREEN_SIZE;
+ list[n++] = 1;
+ if (m & FL_ALPHA) {
+ list[n++] = GLX_ACCUM_ALPHA_SIZE;
+ list[n++] = 1;
+ }
}
}
if (m & FL_DOUBLE) {
@@ -104,7 +276,7 @@ Fl_Gl_Choice *Fl_Gl_Choice::find(int m, const int *alistp) {
list[n] = 0;
blist = list;
}
-
+
fl_open_display();
XVisualInfo *visp = glXChooseVisual(fl_display, fl_screen, (int *)blist);
if (!visp) {
@@ -113,109 +285,29 @@ Fl_Gl_Choice *Fl_Gl_Choice::find(int m, const int *alistp) {
# endif
return 0;
}
-
-#elif defined(__APPLE__) // PORTME: platform OpenGL management
- NSOpenGLPixelFormat* fmt = Fl_Cocoa_Screen_Driver::mode_to_NSOpenGLPixelFormat(m, alistp);
- if (!fmt) return 0;
-#elif defined(WIN32)
-
- // Replacement for ChoosePixelFormat() that finds one with an overlay
- // if possible:
- HDC gc = (HDC)fl_graphics_driver->gc();
- if (!gc) gc = fl_GetDC(0);
- int pixelformat = 0;
- PIXELFORMATDESCRIPTOR chosen_pfd;
- for (int i = 1; ; i++) {
- PIXELFORMATDESCRIPTOR pfd;
- if (!DescribePixelFormat(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&FL_INDEX)?PFD_TYPE_COLORINDEX:PFD_TYPE_RGBA)) continue;
- if ((m & FL_ALPHA) && !pfd.cAlphaBits) continue;
- if ((m & FL_ACCUM) && !pfd.cAccumBits) continue;
- if ((!(m & FL_DOUBLE)) != (!(pfd.dwFlags & PFD_DOUBLEBUFFER))) continue;
- if ((!(m & FL_STEREO)) != (!(pfd.dwFlags & PFD_STEREO))) continue;
- if ((m & FL_DEPTH) && !pfd.cDepthBits) continue;
- if ((m & FL_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 Fl_Gl_Choice;
- g->mode = m;
- g->alist = alistp;
- g->next = first;
+ g = new Fl_Gl_Choice(m, alistp, first);
first = g;
-
-#if defined(USE_X11)
+
g->vis = visp;
-
+
if (/*MaxCmapsOfScreen(ScreenOfDisplay(fl_display,fl_screen))==1 && */
visp->visualid == fl_visual->visualid &&
!fl_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__) // PORTME: platform OpenGL management
- g->pixelformat = fmt;
-# else
-# error unsupported platform
-# endif
-
+ visp->visual, AllocNone);
+
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();
+GLContext Fl_X11_Gl_Window_Driver::create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g, int layer) {
+ return create_gl_context(g->vis);
}
-#if defined(USE_X11)
-
-GLContext fl_create_gl_context(XVisualInfo* vis) {
+GLContext Fl_X11_Gl_Window_Driver::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);
@@ -224,95 +316,27 @@ GLContext fl_create_gl_context(XVisualInfo* vis) {
return context;
}
-#elif defined(WIN32)
-
-GLContext fl_create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g, int layer) {
- Fl_X* i = Fl_X::i(window);
- HDC hdc = Fl_WinAPI_Window_Driver::driver(window)->private_dc;
- if (!hdc) {
- hdc = Fl_WinAPI_Window_Driver::driver(window)->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__) // PORTME: platform OpenGL management
-
-GLContext fl_create_gl_context(Fl_Window* window, const Fl_Gl_Choice* g, int layer) {
- GLContext context, shared_ctx = 0;
- if (context_list && nContext) shared_ctx = context_list[0];
- // resets the pile of string textures used to draw strings
- // necessary before the first context is created
- if (!shared_ctx) gl_texture_reset();
- context = Fl_Cocoa_Screen_Driver::create_GLcontext_for_window(g->pixelformat, shared_ctx, window);
- if (!context) return 0;
- add_context((GLContext)context);
- return (context);
-}
-# else
-# error unsupported platform
-# endif
-
-static GLContext cached_context;
-static Fl_Window* cached_window;
-
-void fl_set_gl_context(Fl_Window* w, GLContext context) {
+void Fl_X11_Gl_Window_Driver::set_gl_context(Fl_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_WinAPI_Window_Driver::driver(w)->private_dc, context);
-# elif defined(__APPLE__) // PORTME: platform OpenGL management
- Fl_Cocoa_Screen_Driver::GLcontext_makecurrent(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__) // PORTME: platform OpenGL management
- Fl_Cocoa_Screen_Driver::GL_cleardrawable();
-# else
-# error unsupported platform
-# endif
-}
-
-void fl_delete_gl_context(GLContext context) {
- if (cached_context == context) fl_no_gl_context();
-# if defined(USE_X11)
+void Fl_X11_Gl_Window_Driver::delete_gl_context(GLContext context) {
+ if (cached_context == context) {
+ cached_context = 0;
+ cached_window = 0;
+ glXMakeCurrent(fl_display, 0, 0);
+ }
glXDestroyContext(fl_display, context);
-# elif defined(WIN32)
- wglDeleteContext(context);
-# elif defined(__APPLE__) // PORTME: platform OpenGL management
- Fl_Cocoa_Screen_Driver::GLcontext_release(context);
-# else
-# error unsupported platform
-# endif
del_context(context);
}
-#endif // HAVE_GL
+#endif // FL_CFG_GFX_XLIB
+#endif // HAVE_GL
//
// End of "$Id$".