X11 + OpenGL: new procedure to create OpenGL3+ contexts giving access to the highest OpenGL version supported by GLX.
The ABI compatibility was checked with the abi-compliance-checker tool. The same code has already been committed in the 1.4 branch. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@13043 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
parent
121abf4ca9
commit
226b64e9bd
@ -149,7 +149,7 @@ public:
|
||||
- \c FL_DEPTH - depth buffer
|
||||
- \c FL_STENCIL - stencil buffer
|
||||
- \c FL_MULTISAMPLE - multisample antialiasing
|
||||
- \c FL_OPENGL3 - use OpenGL version 3.0 or more when running Mac OS.
|
||||
- \c FL_OPENGL3 - use OpenGL version 3.0 or more.
|
||||
|
||||
FL_RGB and FL_SINGLE have a value of zero, so they
|
||||
are "on" unless you give FL_INDEX or FL_DOUBLE.
|
||||
@ -169,16 +169,9 @@ public:
|
||||
mode() must not be called within draw() since it
|
||||
changes the current context.
|
||||
|
||||
\note On the <b>MSWindows and Unix/Linux platforms</b>, FLTK produces
|
||||
contexts for the highest OpenGL version supported by the hardware. Such contexts
|
||||
are also compatible with lower OpenGL versions. On the <b>Apple OS X
|
||||
platform</b>, it is necessary to decide whether the source code targets
|
||||
OpenGL versions higher or lower than 3.0. By default, FLTK
|
||||
creates contexts adequate for OpenGL versions 1 and 2. To get contexts
|
||||
for OpenGL 3.0 or higher, the <tt>FL_OPENGL3</tt> flag and Mac OS
|
||||
version 10.7 or higher are required (in that case the context is NOT
|
||||
compatible with OpenGL versions 1 or 2). The <tt>FL_OPENGL3</tt> flag has no
|
||||
effect on non-Apple platforms.
|
||||
The FL_OPENGL3 flag is required to access OpenGL version 3 or more
|
||||
under the X11 and MacOS platforms; it's optional under Windows.
|
||||
See more details in \ref opengl3.
|
||||
|
||||
\version the <tt>FL_OPENGL3</tt> flag appeared in version 1.3.4
|
||||
*/
|
||||
|
||||
@ -456,14 +456,21 @@ showing how to use OpenGL 3.0 (or higher versions) with FLTK in a cross-platform
|
||||
It contains also OpenGL3-glut-test.cxx which shows how to use FLTK's GLUT compatibility
|
||||
and OpenGL 3.
|
||||
|
||||
<b>On the MSWindows and Unix/Linux platforms</b>, FLTK creates contexts implementing
|
||||
the highest OpenGL version supported by the hardware,
|
||||
which are also compatible with lower OpenGL versions. Thus, FLTK allows
|
||||
source code targeting any version of OpenGL. Access to functions from OpenGL versions above 1.1 requires to load function pointers at runtime on these platforms. FLTK recommends to use the GLEW library to perform this. It is therefore
|
||||
necessary to install the GLEW library (see below). <b>On the Mac OS X platform</b>,
|
||||
FLTK creates by default contexts implementing OpenGL versions 1 or 2.
|
||||
To access OpenGL 3.0 (or higher versions), use the <tt>FL_OPENGL3</tt> flag (see below).
|
||||
Mac OS 10.7 or above is required; GLEW is possible but not necessary.
|
||||
To access OpenGL 3.0 (or higher versions), use the <tt>FL_OPENGL3</tt> flag
|
||||
when calling Fl_Gl_Window::mode(int a) or glutInitDisplayMode().
|
||||
|
||||
<b>On the Windows and Unix/Linux platforms</b>, FLTK creates contexts
|
||||
implementing the highest OpenGL version supported by the hardware.
|
||||
Such contexts may also be compatible with lower OpenGL versions.
|
||||
Access to functions from OpenGL
|
||||
versions above 1.1 requires to load function pointers at runtime on these platforms.
|
||||
FLTK recommends to use the GLEW library to perform this. It is therefore
|
||||
necessary to install the GLEW library (see below).
|
||||
|
||||
<b>On the macOS platform</b>, MacOS 10.7 or above is required;
|
||||
GLEW is possible but not necessary. FLTK creates contexts for OpenGL
|
||||
versions 1 and 2 without the FL_OPENGL3
|
||||
flag and for OpenGL versions 3.2 and above with it.
|
||||
|
||||
\par GLEW installation (Unix/Linux and MSWindows platforms)
|
||||
GLEW is available as a package for most Linux distributions and in source form at http://glew.sourceforge.net/.
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
//
|
||||
// OpenGL definitions for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 1998-2010 by Bill Spitzak and others.
|
||||
// Copyright 1998-2018 by Bill Spitzak and others.
|
||||
//
|
||||
// This library is free software. Distribution and use rights are outlined in
|
||||
// the file "COPYING" which should have been included with this file. If this
|
||||
@ -64,6 +64,9 @@ typedef NSOpenGLContext* FLOpenGLContextPtr;
|
||||
#else
|
||||
# include <GL/glx.h>
|
||||
# define GLContext GLXContext
|
||||
# if ! defined(GLX_VERSION_1_3)
|
||||
# typedef void *GLXFBConfig;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// Describes crap needed to create a GLContext.
|
||||
@ -80,6 +83,7 @@ public:
|
||||
#else
|
||||
XVisualInfo *vis; // the visual to use
|
||||
Colormap colormap; // a colormap for that visual
|
||||
GLXFBConfig best_fb;
|
||||
#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
|
||||
@ -101,10 +105,10 @@ GLContext fl_create_gl_context(Fl_Window*, const Fl_Gl_Choice*, int layer=0);
|
||||
|
||||
GLContext fl_create_gl_context(XVisualInfo* vis);
|
||||
|
||||
static inline
|
||||
GLContext fl_create_gl_context(Fl_Window*, const Fl_Gl_Choice* g) {
|
||||
//static inline
|
||||
GLContext fl_create_gl_context(Fl_Window*, const Fl_Gl_Choice* g);/* {
|
||||
return fl_create_gl_context(g->vis);
|
||||
}
|
||||
}*/
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
//
|
||||
// OpenGL visual selection code for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 1998-2010 by Bill Spitzak and others.
|
||||
// Copyright 1998-2018 by Bill Spitzak and others.
|
||||
//
|
||||
// This library is free software. Distribution and use rights are outlined in
|
||||
// the file "COPYING" which should have been included with this file. If this
|
||||
@ -33,6 +33,63 @@ void fl_save_dc(HWND, HDC);
|
||||
extern void gl_texture_reset();
|
||||
#endif
|
||||
|
||||
#if defined(USE_X11)
|
||||
static XVisualInfo *gl3_getvisual(const int *blist, GLXFBConfig *pbestFB)
|
||||
{
|
||||
int glx_major, glx_minor;
|
||||
|
||||
// FBConfigs were added in GLX version 1.3.
|
||||
if ( !glXQueryVersion( fl_display, &glx_major, &glx_minor ) ||
|
||||
( ( glx_major == 1 ) && ( glx_minor < 3 ) ) || ( glx_major < 1 ) )
|
||||
{
|
||||
//printf("Invalid GLX version");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//printf( "Getting matching framebuffer configs\n" );
|
||||
int fbcount;
|
||||
GLXFBConfig* fbc = glXChooseFBConfig(fl_display, DefaultScreen(fl_display), blist, &fbcount);
|
||||
if (!fbc)
|
||||
{
|
||||
//printf( "Failed to retrieve a framebuffer config\n" );
|
||||
return NULL;
|
||||
}
|
||||
//printf( "Found %d matching FB configs.\n", fbcount );
|
||||
|
||||
// Pick the FB config/visual with the most samples per pixel
|
||||
int best_fbc = -1, worst_fbc = -1, best_num_samp = -1, worst_num_samp = 999;
|
||||
|
||||
int i;
|
||||
for (i=0; i<fbcount; ++i)
|
||||
{
|
||||
XVisualInfo *vi = glXGetVisualFromFBConfig( fl_display, fbc[i] );
|
||||
if ( vi )
|
||||
{
|
||||
int samp_buf, samples;
|
||||
glXGetFBConfigAttrib( fl_display, fbc[i], GLX_SAMPLE_BUFFERS, &samp_buf );
|
||||
glXGetFBConfigAttrib( fl_display, fbc[i], GLX_SAMPLES , &samples );
|
||||
/*printf( " Matching fbconfig %d, visual ID 0x%2lx: SAMPLE_BUFFERS = %d, SAMPLES = %d\n",
|
||||
i, vi -> visualid, samp_buf, samples );*/
|
||||
if ( best_fbc < 0 || (samp_buf && samples > best_num_samp) )
|
||||
best_fbc = i, best_num_samp = samples;
|
||||
if ( worst_fbc < 0 || !samp_buf || samples < worst_num_samp )
|
||||
worst_fbc = i, worst_num_samp = samples;
|
||||
}
|
||||
XFree( vi );
|
||||
}
|
||||
|
||||
GLXFBConfig bestFbc = fbc[ best_fbc ];
|
||||
|
||||
// Be sure to free the FBConfig list allocated by glXChooseFBConfig()
|
||||
XFree( fbc );
|
||||
|
||||
// Get a visual
|
||||
XVisualInfo *vi = glXGetVisualFromFBConfig( fl_display, bestFbc );
|
||||
*pbestFB = bestFbc;
|
||||
return vi;
|
||||
}
|
||||
#endif
|
||||
|
||||
static Fl_Gl_Choice *first;
|
||||
|
||||
// this assumes one of the two arguments is zero:
|
||||
@ -96,12 +153,19 @@ Fl_Gl_Choice *Fl_Gl_Choice::find(int m, const int *alistp) {
|
||||
}
|
||||
|
||||
fl_open_display();
|
||||
XVisualInfo *visp = glXChooseVisual(fl_display, fl_screen, (int *)blist);
|
||||
XVisualInfo *visp = NULL;
|
||||
GLXFBConfig best_fb = NULL;
|
||||
if (m & FL_OPENGL3) {
|
||||
visp = gl3_getvisual((const int *)blist, &best_fb);
|
||||
}
|
||||
if (!visp) {
|
||||
visp = glXChooseVisual(fl_display, fl_screen, (int *)blist);
|
||||
if (!visp) {
|
||||
# if defined(GLX_VERSION_1_1) && defined(GLX_SGIS_multisample)
|
||||
if (m&FL_MULTISAMPLE) return find(m&~FL_MULTISAMPLE,0);
|
||||
if (m&FL_MULTISAMPLE) return find(m&~FL_MULTISAMPLE,0);
|
||||
# endif
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(__APPLE_QUARTZ__)
|
||||
@ -155,6 +219,7 @@ Fl_Gl_Choice *Fl_Gl_Choice::find(int m, const int *alistp) {
|
||||
|
||||
#if defined(USE_X11)
|
||||
g->vis = visp;
|
||||
g->best_fb = best_fb;
|
||||
|
||||
if (/*MaxCmapsOfScreen(ScreenOfDisplay(fl_display,fl_screen))==1 && */
|
||||
visp->visualid == fl_visual->visualid &&
|
||||
@ -204,6 +269,56 @@ static void del_context(GLContext ctx) {
|
||||
|
||||
#if defined(USE_X11)
|
||||
|
||||
static bool ctxErrorOccurred = false;
|
||||
static int ctxErrorHandler( Display *dpy, XErrorEvent *ev )
|
||||
{
|
||||
ctxErrorOccurred = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
GLContext fl_create_gl_context(Fl_Window *window, const Fl_Gl_Choice* g) {
|
||||
GLContext shared_ctx = 0;
|
||||
if (context_list && nContext) shared_ctx = context_list[0];
|
||||
|
||||
typedef GLContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLContext, Bool, const int*);
|
||||
|
||||
// It is not necessary to create or make current to a context before calling glXGetProcAddressARB
|
||||
static glXCreateContextAttribsARBProc glXCreateContextAttribsARB =
|
||||
(glXCreateContextAttribsARBProc)glXGetProcAddressARB((const GLubyte *)"glXCreateContextAttribsARB");
|
||||
|
||||
GLContext ctx = 0;
|
||||
|
||||
// Check for the GLX_ARB_create_context extension string and the function.
|
||||
// If either is not present, use GLX 1.3 context creation method.
|
||||
const char *glxExts = glXQueryExtensionsString(fl_display, fl_screen);
|
||||
if (g->best_fb && strstr(glxExts, "GLX_ARB_create_context") && glXCreateContextAttribsARB ) {
|
||||
int context_attribs[] =
|
||||
{
|
||||
GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
|
||||
GLX_CONTEXT_MINOR_VERSION_ARB, 2,
|
||||
//GLX_CONTEXT_FLAGS_ARB , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
|
||||
//GLX_CONTEXT_PROFILE_MASK_ARB , GLX_CONTEXT_CORE_PROFILE_BIT_ARB ,
|
||||
None
|
||||
};
|
||||
ctxErrorOccurred = false;
|
||||
XErrorHandler oldHandler = XSetErrorHandler(&ctxErrorHandler);
|
||||
ctx = glXCreateContextAttribsARB( fl_display, g->best_fb, shared_ctx, True, context_attribs );
|
||||
// Sync to ensure any errors generated are processed.
|
||||
XSync( fl_display, False );
|
||||
if (ctxErrorOccurred) ctx = 0;
|
||||
XSetErrorHandler(oldHandler);
|
||||
}
|
||||
if (!ctx) { // use OpenGL 1-style context creation
|
||||
ctx = glXCreateContext(fl_display, g->vis, shared_ctx, true);
|
||||
}
|
||||
if (ctx)
|
||||
add_context(ctx);
|
||||
//glXMakeCurrent(fl_display, fl_xid(window), ctx);printf("%s\n", glGetString(GL_VERSION));
|
||||
return ctx;
|
||||
}
|
||||
|
||||
|
||||
GLContext fl_create_gl_context(XVisualInfo* vis) {
|
||||
GLContext shared_ctx = 0;
|
||||
if (context_list && nContext) shared_ctx = context_list[0];
|
||||
|
||||
Loading…
Reference in New Issue
Block a user