mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-11 21:29:42 +02:00
+ patch by Michalis Kamburelis to add GLX 1.4 support and new GLX extensions, resolves #19953
git-svn-id: trunk@18207 -
This commit is contained in:
parent
8308b46a94
commit
c45222cd17
@ -13,7 +13,25 @@ program glxTest;
|
|||||||
uses glx,unix,x,xlib,xutil,gl,glu;
|
uses glx,unix,x,xlib,xutil,gl,glu;
|
||||||
|
|
||||||
var
|
var
|
||||||
attr: Array[0..8] of integer = (GLX_RGBA,GLX_RED_SIZE,1,GLX_GREEN_SIZE,1,GLX_BLUE_SIZE,1,GLX_DOUBLEBUFFER,none);
|
{ Attributes to choose context with glXChooseVisual }
|
||||||
|
Attr: Array[0..8] of integer = (
|
||||||
|
GLX_RGBA,
|
||||||
|
GLX_RED_SIZE, 1,
|
||||||
|
GLX_GREEN_SIZE, 1,
|
||||||
|
GLX_BLUE_SIZE, 1,
|
||||||
|
GLX_DOUBLEBUFFER,
|
||||||
|
none);
|
||||||
|
|
||||||
|
{ Attributes to choose context with glXChooseFBConfig.
|
||||||
|
Similar to Attr, but not exactly compatible. }
|
||||||
|
AttrFB: Array[0..10] of integer = (
|
||||||
|
GLX_X_RENDERABLE, 1 { true },
|
||||||
|
GLX_RED_SIZE, 1,
|
||||||
|
GLX_GREEN_SIZE, 1,
|
||||||
|
GLX_BLUE_SIZE, 1,
|
||||||
|
GLX_DOUBLEBUFFER, 1 { true },
|
||||||
|
none);
|
||||||
|
|
||||||
visinfo: PXVisualInfo;
|
visinfo: PXVisualInfo;
|
||||||
cm: TColormap;
|
cm: TColormap;
|
||||||
winAttr: TXSetWindowAttributes;
|
winAttr: TXSetWindowAttributes;
|
||||||
@ -64,22 +82,52 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure Error(const S: string);
|
||||||
|
begin
|
||||||
|
Writeln(ErrOutput, 'Error: ', S);
|
||||||
|
Halt(1);
|
||||||
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
errorBase,eventBase: integer;
|
|
||||||
window_title_property: TXTextProperty;
|
window_title_property: TXTextProperty;
|
||||||
title: String;
|
title: String;
|
||||||
|
FBConfig: TGLXFBConfig;
|
||||||
|
FBConfigs: PGLXFBConfig;
|
||||||
|
FBConfigsCount: Integer;
|
||||||
|
|
||||||
|
{ Used with glXCreateContextAttribsARB to select 3.0 forward-compatible context }
|
||||||
|
Context30Forward: array [0..6] of Integer =
|
||||||
|
( GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
|
||||||
|
GLX_CONTEXT_MINOR_VERSION_ARB, 0,
|
||||||
|
GLX_CONTEXT_FLAGS_ARB , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
|
||||||
|
None
|
||||||
|
);
|
||||||
begin
|
begin
|
||||||
initGlx();
|
|
||||||
dpy := XOpenDisplay(nil);
|
dpy := XOpenDisplay(nil);
|
||||||
if(dpy = nil) then
|
if(dpy = nil) then
|
||||||
writeLn('Error: Could not connect to X server');
|
Error('Could not connect to X server');
|
||||||
|
|
||||||
if not (glXQueryExtension(dpy,errorBase,eventBase)) then
|
if not GLX_version_1_0(dpy) then
|
||||||
writeLn('Error: GLX extension not supported');
|
Error('GLX extension not supported');
|
||||||
|
|
||||||
|
if GLX_version_1_3(dpy) then
|
||||||
|
begin
|
||||||
|
{ use approach recommended since glX 1.3 }
|
||||||
|
FBConfigs := glXChooseFBConfig(dpy, DefaultScreen(dpy), AttrFB, FBConfigsCount);
|
||||||
|
if FBConfigsCount = 0 then
|
||||||
|
Error('Could not find FB config');
|
||||||
|
|
||||||
|
{ just choose the first FB config from the FBConfigs list.
|
||||||
|
More involved selection possible. }
|
||||||
|
FBConfig := FBConfigs^;
|
||||||
|
visinfo := glXGetVisualFromFBConfig(dpy, FBConfig);
|
||||||
|
end else
|
||||||
|
begin
|
||||||
|
visinfo := glXChooseVisual(dpy, DefaultScreen(dpy), Attr);
|
||||||
|
end;
|
||||||
|
|
||||||
visinfo := glXChooseVisual(dpy,DefaultScreen(dpy), Attr);
|
|
||||||
if(visinfo = nil) then
|
if(visinfo = nil) then
|
||||||
writeLn('Error: Could not find visual');
|
Error('Could not find visual');
|
||||||
|
|
||||||
//Create a new colormap
|
//Create a new colormap
|
||||||
cm := XCreateColormap(dpy,RootWindow(dpy,visinfo.screen),visinfo.visual,AllocNone);
|
cm := XCreateColormap(dpy,RootWindow(dpy,visinfo.screen),visinfo.visual,AllocNone);
|
||||||
@ -96,9 +144,32 @@ begin
|
|||||||
XSetWMName(dpy,win,@window_title_property);
|
XSetWMName(dpy,win,@window_title_property);
|
||||||
|
|
||||||
//Create an OpenGL rendering context
|
//Create an OpenGL rendering context
|
||||||
glXCont := glXCreateContext(dpy,visinfo,none,true);
|
if GLX_version_1_3(dpy) then
|
||||||
|
begin
|
||||||
|
writeln('Using GLX 1.3 code path');
|
||||||
|
{ Uncomment two lines below to use GLX_ARB_create_context extension
|
||||||
|
to request OpenGL 3.0 forward-compatible context. This is just
|
||||||
|
a simple example, be aware of some shortcomings:
|
||||||
|
|
||||||
|
- In case of failure, glXCreateContextAttribsARB not only returns nil,
|
||||||
|
it also raises X error that by default simply breaks your program.
|
||||||
|
In a real program, you probably want to catch it (use XSetErrorHandler
|
||||||
|
to assign custom error handler) and retry glXCreateContextAttribsARB
|
||||||
|
with less restrictive attributes.
|
||||||
|
|
||||||
|
- In case of success, you will just see a black screen.
|
||||||
|
That's because the Redraw and Resize procedures defined in this program
|
||||||
|
actually use deprecated OpenGL calls, that are *not* available in
|
||||||
|
a forward-compatible context (glGetError would show actual errors). }
|
||||||
|
// if GLX_ARB_create_context(dpy, DefaultScreen(dpy)) then
|
||||||
|
// glXCont := glXCreateContextAttribsARB(dpy, FBConfig, 0, true, Context30Forward) else
|
||||||
|
{ use approach recommended since glX 1.3 }
|
||||||
|
glXCont := glXCreateNewContext(dpy, FBConfig, GLX_RGBA_TYPE, 0, true);
|
||||||
|
end else
|
||||||
|
glXCont := glXCreateContext(dpy, visinfo, none, true);
|
||||||
|
|
||||||
if(glXCont = nil) then
|
if(glXCont = nil) then
|
||||||
writeLn('Error: Could not create an OpenGL rendering context');
|
Error('Could not create an OpenGL rendering context');
|
||||||
|
|
||||||
//Make it current
|
//Make it current
|
||||||
glXMakeCurrent(dpy,win,glXCont);
|
glXMakeCurrent(dpy,win,glXCont);
|
||||||
|
@ -84,16 +84,6 @@ const
|
|||||||
GLX_ACCUM_BLUE_SIZE = 16;
|
GLX_ACCUM_BLUE_SIZE = 16;
|
||||||
GLX_ACCUM_ALPHA_SIZE = 17;
|
GLX_ACCUM_ALPHA_SIZE = 17;
|
||||||
|
|
||||||
// GLX_EXT_visual_info extension
|
|
||||||
GLX_X_VISUAL_TYPE_EXT = $22;
|
|
||||||
GLX_TRANSPARENT_TYPE_EXT = $23;
|
|
||||||
GLX_TRANSPARENT_INDEX_VALUE_EXT = $24;
|
|
||||||
GLX_TRANSPARENT_RED_VALUE_EXT = $25;
|
|
||||||
GLX_TRANSPARENT_GREEN_VALUE_EXT = $26;
|
|
||||||
GLX_TRANSPARENT_BLUE_VALUE_EXT = $27;
|
|
||||||
GLX_TRANSPARENT_ALPHA_VALUE_EXT = $28;
|
|
||||||
|
|
||||||
|
|
||||||
// Error codes returned by glXGetConfig:
|
// Error codes returned by glXGetConfig:
|
||||||
GLX_BAD_SCREEN = 1;
|
GLX_BAD_SCREEN = 1;
|
||||||
GLX_BAD_ATTRIBUTE = 2;
|
GLX_BAD_ATTRIBUTE = 2;
|
||||||
@ -108,7 +98,105 @@ const
|
|||||||
GLX_VERSION = 2;
|
GLX_VERSION = 2;
|
||||||
GLX_EXTENSIONS = 3;
|
GLX_EXTENSIONS = 3;
|
||||||
|
|
||||||
// GLX_visual_info extension
|
// GLX 1.3 and later:
|
||||||
|
GLX_CONFIG_CAVEAT = $20;
|
||||||
|
GLX_DONT_CARE = $FFFFFFFF;
|
||||||
|
GLX_X_VISUAL_TYPE = $22;
|
||||||
|
GLX_TRANSPARENT_TYPE = $23;
|
||||||
|
GLX_TRANSPARENT_INDEX_VALUE = $24;
|
||||||
|
GLX_TRANSPARENT_RED_VALUE = $25;
|
||||||
|
GLX_TRANSPARENT_GREEN_VALUE = $26;
|
||||||
|
GLX_TRANSPARENT_BLUE_VALUE = $27;
|
||||||
|
GLX_TRANSPARENT_ALPHA_VALUE = $28;
|
||||||
|
GLX_WINDOW_BIT = $00000001;
|
||||||
|
GLX_PIXMAP_BIT = $00000002;
|
||||||
|
GLX_PBUFFER_BIT = $00000004;
|
||||||
|
GLX_AUX_BUFFERS_BIT = $00000010;
|
||||||
|
GLX_FRONT_LEFT_BUFFER_BIT = $00000001;
|
||||||
|
GLX_FRONT_RIGHT_BUFFER_BIT = $00000002;
|
||||||
|
GLX_BACK_LEFT_BUFFER_BIT = $00000004;
|
||||||
|
GLX_BACK_RIGHT_BUFFER_BIT = $00000008;
|
||||||
|
GLX_DEPTH_BUFFER_BIT = $00000020;
|
||||||
|
GLX_STENCIL_BUFFER_BIT = $00000040;
|
||||||
|
GLX_ACCUM_BUFFER_BIT = $00000080;
|
||||||
|
GLX_NONE = $8000;
|
||||||
|
GLX_SLOW_CONFIG = $8001;
|
||||||
|
GLX_TRUE_COLOR = $8002;
|
||||||
|
GLX_DIRECT_COLOR = $8003;
|
||||||
|
GLX_PSEUDO_COLOR = $8004;
|
||||||
|
GLX_STATIC_COLOR = $8005;
|
||||||
|
GLX_GRAY_SCALE = $8006;
|
||||||
|
GLX_STATIC_GRAY = $8007;
|
||||||
|
GLX_TRANSPARENT_RGB = $8008;
|
||||||
|
GLX_TRANSPARENT_INDEX = $8009;
|
||||||
|
GLX_VISUAL_ID = $800B;
|
||||||
|
GLX_SCREEN = $800C;
|
||||||
|
GLX_NON_CONFORMANT_CONFIG = $800D;
|
||||||
|
GLX_DRAWABLE_TYPE = $8010;
|
||||||
|
GLX_RENDER_TYPE = $8011;
|
||||||
|
GLX_X_RENDERABLE = $8012;
|
||||||
|
GLX_FBCONFIG_ID = $8013;
|
||||||
|
GLX_RGBA_TYPE = $8014;
|
||||||
|
GLX_COLOR_INDEX_TYPE = $8015;
|
||||||
|
GLX_MAX_PBUFFER_WIDTH = $8016;
|
||||||
|
GLX_MAX_PBUFFER_HEIGHT = $8017;
|
||||||
|
GLX_MAX_PBUFFER_PIXELS = $8018;
|
||||||
|
GLX_PRESERVED_CONTENTS = $801B;
|
||||||
|
GLX_LARGEST_PBUFFER = $801C;
|
||||||
|
GLX_WIDTH = $801D;
|
||||||
|
GLX_HEIGHT = $801E;
|
||||||
|
GLX_EVENT_MASK = $801F;
|
||||||
|
GLX_DAMAGED = $8020;
|
||||||
|
GLX_SAVED = $8021;
|
||||||
|
GLX_WINDOW = $8022;
|
||||||
|
GLX_PBUFFER = $8023;
|
||||||
|
GLX_PBUFFER_HEIGHT = $8040;
|
||||||
|
GLX_PBUFFER_WIDTH = $8041;
|
||||||
|
GLX_RGBA_BIT = $00000001;
|
||||||
|
GLX_COLOR_INDEX_BIT = $00000002;
|
||||||
|
GLX_PBUFFER_CLOBBER_MASK = $08000000;
|
||||||
|
|
||||||
|
// GLX 1.4 and later:
|
||||||
|
GLX_SAMPLE_BUFFERS = $186a0; // 100000
|
||||||
|
GLX_SAMPLES = $186a1; // 100001
|
||||||
|
|
||||||
|
// Extensions:
|
||||||
|
|
||||||
|
// GLX_ARB_multisample
|
||||||
|
GLX_SAMPLE_BUFFERS_ARB = 100000;
|
||||||
|
GLX_SAMPLES_ARB = 100001;
|
||||||
|
|
||||||
|
// GLX_ARB_create_context (http://www.opengl.org/registry/specs/ARB/glx_create_context.txt)
|
||||||
|
GLX_CONTEXT_DEBUG_BIT_ARB = $00000001;
|
||||||
|
GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB = $00000002;
|
||||||
|
GLX_CONTEXT_MAJOR_VERSION_ARB = $2091;
|
||||||
|
GLX_CONTEXT_MINOR_VERSION_ARB = $2092;
|
||||||
|
GLX_CONTEXT_FLAGS_ARB = $2094;
|
||||||
|
|
||||||
|
// GLX_ARB_create_context_profile
|
||||||
|
GLX_CONTEXT_CORE_PROFILE_BIT_ARB = $00000001;
|
||||||
|
GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB = $00000002;
|
||||||
|
GLX_CONTEXT_PROFILE_MASK_ARB = $9126;
|
||||||
|
|
||||||
|
// GLX_ARB_create_context_robustness
|
||||||
|
GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB = $00000004;
|
||||||
|
GLX_LOSE_CONTEXT_ON_RESET_ARB = $8252;
|
||||||
|
GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB = $8256;
|
||||||
|
GLX_NO_RESET_NOTIFICATION_ARB = $8261;
|
||||||
|
|
||||||
|
// GLX_SGIS_multisample
|
||||||
|
GLX_SAMPLE_BUFFERS_SGIS = 100000;
|
||||||
|
GLX_SAMPLES_SGIS = 100001;
|
||||||
|
|
||||||
|
// GLX_EXT_visual_info
|
||||||
|
GLX_X_VISUAL_TYPE_EXT = $22;
|
||||||
|
GLX_TRANSPARENT_TYPE_EXT = $23;
|
||||||
|
GLX_TRANSPARENT_INDEX_VALUE_EXT = $24;
|
||||||
|
GLX_TRANSPARENT_RED_VALUE_EXT = $25;
|
||||||
|
GLX_TRANSPARENT_GREEN_VALUE_EXT = $26;
|
||||||
|
GLX_TRANSPARENT_BLUE_VALUE_EXT = $27;
|
||||||
|
GLX_TRANSPARENT_ALPHA_VALUE_EXT = $28;
|
||||||
|
|
||||||
GLX_TRUE_COLOR_EXT = $8002;
|
GLX_TRUE_COLOR_EXT = $8002;
|
||||||
GLX_DIRECT_COLOR_EXT = $8003;
|
GLX_DIRECT_COLOR_EXT = $8003;
|
||||||
GLX_PSEUDO_COLOR_EXT = $8004;
|
GLX_PSEUDO_COLOR_EXT = $8004;
|
||||||
@ -129,7 +217,7 @@ type
|
|||||||
GLXPixmap = TXID;
|
GLXPixmap = TXID;
|
||||||
GLXDrawable = TXID;
|
GLXDrawable = TXID;
|
||||||
GLXContextID = TXID;
|
GLXContextID = TXID;
|
||||||
|
|
||||||
TXPixmap = XPixmap;
|
TXPixmap = XPixmap;
|
||||||
TXFont = XFont;
|
TXFont = XFont;
|
||||||
TXColormap = XColormap;
|
TXColormap = XColormap;
|
||||||
@ -137,7 +225,16 @@ type
|
|||||||
TGLXContext = GLXContext;
|
TGLXContext = GLXContext;
|
||||||
TGLXPixmap = GLXPixmap;
|
TGLXPixmap = GLXPixmap;
|
||||||
TGLXDrawable = GLXDrawable;
|
TGLXDrawable = GLXDrawable;
|
||||||
|
// GLX 1.3 and later
|
||||||
|
TGLXFBConfigRec = record { internal, use only a pointer to this } end;
|
||||||
|
TGLXFBConfig = ^TGLXFBConfigRec;
|
||||||
|
{ PGLXFBConfig is a pointer to TGLXFBConfig (which is also a pointer).
|
||||||
|
glX uses this to represent an array of FB configs. }
|
||||||
|
PGLXFBConfig = ^TGLXFBConfig;
|
||||||
|
TGLXFBConfigID = TXID;
|
||||||
TGLXContextID = GLXContextID;
|
TGLXContextID = GLXContextID;
|
||||||
|
TGLXWindow = TXID;
|
||||||
|
TGLXPbuffer = TXID;
|
||||||
|
|
||||||
var
|
var
|
||||||
glXChooseVisual: function(dpy: PDisplay; screen: Integer; attribList: PInteger): PXVisualInfo; cdecl;
|
glXChooseVisual: function(dpy: PDisplay; screen: Integer; attribList: PInteger): PXVisualInfo; cdecl;
|
||||||
@ -163,24 +260,320 @@ var
|
|||||||
glXQueryServerString: function(dpy: PDisplay; screen, name: Integer): PChar; cdecl;
|
glXQueryServerString: function(dpy: PDisplay; screen, name: Integer): PChar; cdecl;
|
||||||
glXGetClientString: function(dpy: PDisplay; name: Integer): PChar; cdecl;
|
glXGetClientString: function(dpy: PDisplay; name: Integer): PChar; cdecl;
|
||||||
|
|
||||||
// Mesa GLX Extensions
|
// GLX 1.2 and later
|
||||||
|
glXGetCurrentDisplay: function: PDisplay; cdecl;
|
||||||
|
|
||||||
|
// GLX 1.3 and later
|
||||||
|
glXChooseFBConfig: function(dpy: PDisplay; screen: Integer; attribList: PInteger; var nitems: Integer): PGLXFBConfig; cdecl;
|
||||||
|
glXGetFBConfigAttrib: function(dpy: PDisplay; config: TGLXFBConfig; attribute: Integer; var value: Integer): Integer; cdecl;
|
||||||
|
glXGetFBConfigs: function(dpy: PDisplay; screen: Integer; var nelements: Integer): PGLXFBConfig; cdecl;
|
||||||
|
glXGetVisualFromFBConfig: function(dpy: PDisplay; config: TGLXFBConfig): PXVisualInfo; cdecl;
|
||||||
|
glXCreateWindow: function(dpy: PDisplay; config: TGLXFBConfig; win: X.TWindow; attribList: PInteger): TGLXWindow; cdecl;
|
||||||
|
glXDestroyWindow: procedure (dpy: PDisplay; window: TGLXWindow); cdecl;
|
||||||
|
glXCreatePixmap: function(dpy: PDisplay; config: TGLXFBConfig; pixmap: TXPixmap; attribList: PInteger): TGLXPixmap; cdecl;
|
||||||
|
glXDestroyPixmap: procedure (dpy: PDisplay; pixmap: TGLXPixmap); cdecl;
|
||||||
|
glXCreatePbuffer: function(dpy: PDisplay; config: TGLXFBConfig; attribList: PInteger): TGLXPbuffer; cdecl;
|
||||||
|
glXDestroyPbuffer: procedure (dpy: PDisplay; pbuf: TGLXPbuffer); cdecl;
|
||||||
|
glXQueryDrawable: procedure (dpy: PDisplay; draw: TGLXDrawable; attribute: Integer; value: PLongWord); cdecl;
|
||||||
|
glXCreateNewContext: function(dpy: PDisplay; config: TGLXFBConfig; renderType: Integer; shareList: TGLXContext; direct: boolean): TGLXContext; cdecl;
|
||||||
|
glXMakeContextCurrent: function(dpy: PDisplay; draw: TGLXDrawable; read: GLXDrawable; ctx: TGLXContext): boolean; cdecl;
|
||||||
|
glXGetCurrentReadDrawable: function: TGLXDrawable; cdecl;
|
||||||
|
glXQueryContext: function(dpy: PDisplay; ctx: TGLXContext; attribute: Integer; var value: Integer): Integer; cdecl;
|
||||||
|
glXSelectEvent: procedure (dpy: PDisplay; drawable: TGLXDrawable; mask: LongWord); cdecl;
|
||||||
|
glXGetSelectedEvent: procedure (dpy: PDisplay; drawable: TGLXDrawable; mask: PLongWord); cdecl;
|
||||||
|
|
||||||
|
// GLX 1.4 and later
|
||||||
|
glXGetProcAddress: function(procname: PChar): Pointer; cdecl;
|
||||||
|
|
||||||
|
// Extensions:
|
||||||
|
|
||||||
|
// GLX_ARB_get_proc_address
|
||||||
|
glXGetProcAddressARB: function(procname: PChar): Pointer; cdecl;
|
||||||
|
|
||||||
|
// GLX_ARB_create_context
|
||||||
|
glXCreateContextAttribsARB: function (dpy: PDisplay; config: TGLXFBConfig; share_context: TGLXContext; direct: boolean; attrib_list: PInteger): TGLXContext; cdecl;
|
||||||
|
|
||||||
|
// GLX_MESA_pixmap_colormap
|
||||||
glXCreateGLXPixmapMESA: function(dpy: PDisplay; visual: PXVisualInfo; pixmap: XPixmap; cmap: XColormap): GLXPixmap; cdecl;
|
glXCreateGLXPixmapMESA: function(dpy: PDisplay; visual: PXVisualInfo; pixmap: XPixmap; cmap: XColormap): GLXPixmap; cdecl;
|
||||||
|
|
||||||
|
// Unknown Mesa GLX extension (undocumented in current GLX C headers?)
|
||||||
glXReleaseBufferMESA: function(dpy: PDisplay; d: GLXDrawable): Boolean; cdecl;
|
glXReleaseBufferMESA: function(dpy: PDisplay; d: GLXDrawable): Boolean; cdecl;
|
||||||
glXCopySubBufferMESA: procedure(dpy: PDisplay; drawbale: GLXDrawable; x, y, width, height: Integer); cdecl;
|
glXCopySubBufferMESA: procedure(dpy: PDisplay; drawbale: GLXDrawable; x, y, width, height: Integer); cdecl;
|
||||||
|
|
||||||
|
// GLX_SGI_video_sync
|
||||||
glXGetVideoSyncSGI: function(var counter: LongWord): Integer; cdecl;
|
glXGetVideoSyncSGI: function(var counter: LongWord): Integer; cdecl;
|
||||||
glXWaitVideoSyncSGI: function(divisor, remainder: Integer; var count: LongWord): Integer; cdecl;
|
glXWaitVideoSyncSGI: function(divisor, remainder: Integer; var count: LongWord): Integer; cdecl;
|
||||||
|
|
||||||
|
|
||||||
// =======================================================
|
// =======================================================
|
||||||
//
|
//
|
||||||
// =======================================================
|
// =======================================================
|
||||||
|
|
||||||
|
{
|
||||||
|
Safe checking of glX version and extension presence.
|
||||||
|
|
||||||
|
For each glX version, these functions check that
|
||||||
|
- glXQueryExtension indicates that glX extension is present at all on this display.
|
||||||
|
- glXQueryVersion indicates that (at least) this version is supported.
|
||||||
|
- all the entry points defined for this glX version were
|
||||||
|
successfully loaded from the library.
|
||||||
|
For now, all glX versions are fully backward-compatible,
|
||||||
|
so e.g. if GLX_version_1_3 is true, you know that also GLX_version_1_2
|
||||||
|
and GLX_version_1_1 etc. are true,
|
||||||
|
and all entry points up to glX 1.3 are assigned.
|
||||||
|
|
||||||
|
For each extension, these functions check that
|
||||||
|
- it is declared within glXQueryExtensionsString (which in turn means
|
||||||
|
that glXQueryExtensionsString must be available, which requires glX 1.1)
|
||||||
|
- all it's entry points were successfully loaded from library
|
||||||
|
|
||||||
|
As such, these functions are the safest way to check if given
|
||||||
|
extension/glX version is available.
|
||||||
|
|
||||||
|
Note that the availability of glX version and extension may depend
|
||||||
|
on the X display and (in case of extension) even screen number.
|
||||||
|
}
|
||||||
|
|
||||||
|
function GLX_version_1_0(Display: PDisplay): boolean;
|
||||||
|
function GLX_version_1_1(Display: PDisplay): boolean;
|
||||||
|
function GLX_version_1_2(Display: PDisplay): boolean;
|
||||||
|
function GLX_version_1_3(Display: PDisplay): boolean;
|
||||||
|
function GLX_version_1_4(Display: PDisplay): boolean;
|
||||||
|
|
||||||
|
function GLX_ARB_get_proc_address(Display: PDisplay; Screen: Integer): boolean;
|
||||||
|
function GLX_ARB_create_context(Display: PDisplay; Screen: Integer): boolean;
|
||||||
|
function GLX_ARB_create_context_profile(Display: PDisplay; Screen: Integer): boolean;
|
||||||
|
function GLX_ARB_create_context_robustness(Display: PDisplay; Screen: Integer): boolean;
|
||||||
|
function GLX_ARB_multisample(Display: PDisplay; Screen: Integer): boolean;
|
||||||
|
function GLX_EXT_visual_info(Display: PDisplay; Screen: Integer): boolean;
|
||||||
|
function GLX_MESA_pixmap_colormap(Display: PDisplay; Screen: Integer): boolean;
|
||||||
|
function GLX_SGI_video_sync(Display: PDisplay; Screen: Integer): boolean;
|
||||||
|
function GLX_SGIS_multisample(Display: PDisplay; Screen: Integer): boolean;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses GL, dynlibs;
|
uses GL, dynlibs, GLExt { for glext_ExtensionSupported utility };
|
||||||
|
|
||||||
{$LINKLIB m}
|
{$LINKLIB m}
|
||||||
|
|
||||||
|
function GLX_version_1_0(Display: PDisplay): boolean;
|
||||||
|
var
|
||||||
|
IgnoredErrorb, IgnoredEvent, Major, Minor: Integer;
|
||||||
|
begin
|
||||||
|
Result :=
|
||||||
|
{ check is glX present at all for this display }
|
||||||
|
Assigned(glXQueryExtension) and
|
||||||
|
glXQueryExtension(Display, IgnoredErrorb, IgnoredEvent) and
|
||||||
|
{ check glXQueryVersion, although there is no glX with version < 1 }
|
||||||
|
Assigned(glXQueryVersion) and
|
||||||
|
glXQueryVersion(Display, Major, Minor) and
|
||||||
|
(Major >= 1) and
|
||||||
|
{ check entry points assigned }
|
||||||
|
Assigned(glXChooseVisual) and
|
||||||
|
Assigned(glXCreateContext) and
|
||||||
|
Assigned(glXDestroyContext) and
|
||||||
|
Assigned(glXMakeCurrent) and
|
||||||
|
Assigned(glXCopyContext) and
|
||||||
|
Assigned(glXSwapBuffers) and
|
||||||
|
Assigned(glXCreateGLXPixmap) and
|
||||||
|
Assigned(glXDestroyGLXPixmap) and
|
||||||
|
{ Assigned(glXQueryExtension) and } { (already checked) }
|
||||||
|
{ Assigned(glXQueryVersion) and } { (already checked) }
|
||||||
|
Assigned(glXIsDirect) and
|
||||||
|
Assigned(glXGetConfig) and
|
||||||
|
Assigned(glXGetCurrentContext) and
|
||||||
|
Assigned(glXGetCurrentDrawable) and
|
||||||
|
Assigned(glXWaitGL) and
|
||||||
|
Assigned(glXWaitX) and
|
||||||
|
Assigned(glXUseXFont)
|
||||||
|
end;
|
||||||
|
|
||||||
|
function GLX_version_1_1(Display: PDisplay): boolean;
|
||||||
|
var
|
||||||
|
Major, Minor: Integer;
|
||||||
|
begin
|
||||||
|
Result :=
|
||||||
|
{ check previous version Ok }
|
||||||
|
GLX_version_1_0(Display) and
|
||||||
|
{ check glXQueryVersion }
|
||||||
|
glXQueryVersion(Display, Major, Minor) and
|
||||||
|
( (Major > 1) or ((Major = 1) and (Minor >= 1)) ) and
|
||||||
|
{ check entry points assigned }
|
||||||
|
Assigned(glXQueryExtensionsString) and
|
||||||
|
Assigned(glXQueryServerString) and
|
||||||
|
Assigned(glXGetClientString);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function GLX_version_1_2(Display: PDisplay): boolean;
|
||||||
|
var
|
||||||
|
Major, Minor: Integer;
|
||||||
|
begin
|
||||||
|
Result :=
|
||||||
|
{ check previous version Ok }
|
||||||
|
GLX_version_1_1(Display) and
|
||||||
|
{ check glXQueryVersion }
|
||||||
|
glXQueryVersion(Display, Major, Minor) and
|
||||||
|
( (Major > 1) or ((Major = 1) and (Minor >= 2)) ) and
|
||||||
|
{ check entry points assigned }
|
||||||
|
Assigned(glXGetCurrentDisplay);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function GLX_version_1_3(Display: PDisplay): boolean;
|
||||||
|
var
|
||||||
|
Major, Minor: Integer;
|
||||||
|
begin
|
||||||
|
Result :=
|
||||||
|
{ check previous version Ok }
|
||||||
|
GLX_version_1_2(Display) and
|
||||||
|
{ check glXQueryVersion }
|
||||||
|
glXQueryVersion(Display, Major, Minor) and
|
||||||
|
( (Major > 1) or ((Major = 1) and (Minor >= 3)) ) and
|
||||||
|
{ check entry points assigned }
|
||||||
|
Assigned(glXChooseFBConfig) and
|
||||||
|
Assigned(glXGetFBConfigAttrib) and
|
||||||
|
Assigned(glXGetFBConfigs) and
|
||||||
|
Assigned(glXGetVisualFromFBConfig) and
|
||||||
|
Assigned(glXCreateWindow) and
|
||||||
|
Assigned(glXDestroyWindow) and
|
||||||
|
Assigned(glXCreatePixmap) and
|
||||||
|
Assigned(glXDestroyPixmap) and
|
||||||
|
Assigned(glXCreatePbuffer) and
|
||||||
|
Assigned(glXDestroyPbuffer) and
|
||||||
|
Assigned(glXQueryDrawable) and
|
||||||
|
Assigned(glXCreateNewContext) and
|
||||||
|
Assigned(glXMakeContextCurrent) and
|
||||||
|
Assigned(glXGetCurrentReadDrawable) and
|
||||||
|
Assigned(glXQueryContext) and
|
||||||
|
Assigned(glXSelectEvent) and
|
||||||
|
Assigned(glXGetSelectedEvent);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function GLX_version_1_4(Display: PDisplay): boolean;
|
||||||
|
var
|
||||||
|
Major, Minor: Integer;
|
||||||
|
begin
|
||||||
|
Result :=
|
||||||
|
{ check previous version Ok }
|
||||||
|
GLX_version_1_3(Display) and
|
||||||
|
{ check glXQueryVersion }
|
||||||
|
glXQueryVersion(Display, Major, Minor) and
|
||||||
|
( (Major > 1) or ((Major = 1) and (Minor >= 4)) ) and
|
||||||
|
{ check entry points assigned }
|
||||||
|
Assigned(glXGetProcAddress);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function GLX_ARB_get_proc_address(Display: PDisplay; Screen: Integer): boolean;
|
||||||
|
var
|
||||||
|
GlxExtensions: PChar;
|
||||||
|
begin
|
||||||
|
Result := GLX_version_1_1(Display);
|
||||||
|
if Result then
|
||||||
|
begin
|
||||||
|
GlxExtensions := glXQueryExtensionsString(Display, Screen);
|
||||||
|
Result := glext_ExtensionSupported('GLX_ARB_get_proc_address', GlxExtensions) and
|
||||||
|
Assigned(glXGetProcAddressARB);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function GLX_ARB_create_context(Display: PDisplay; Screen: Integer): boolean;
|
||||||
|
var
|
||||||
|
GlxExtensions: PChar;
|
||||||
|
begin
|
||||||
|
Result := GLX_version_1_1(Display);
|
||||||
|
if Result then
|
||||||
|
begin
|
||||||
|
GlxExtensions := glXQueryExtensionsString(Display, Screen);
|
||||||
|
Result := glext_ExtensionSupported('GLX_ARB_create_context', GlxExtensions) and
|
||||||
|
Assigned(glXCreateContextAttribsARB);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function GLX_ARB_create_context_profile(Display: PDisplay; Screen: Integer): boolean;
|
||||||
|
var
|
||||||
|
GlxExtensions: PChar;
|
||||||
|
begin
|
||||||
|
Result := GLX_version_1_1(Display);
|
||||||
|
if Result then
|
||||||
|
begin
|
||||||
|
GlxExtensions := glXQueryExtensionsString(Display, Screen);
|
||||||
|
Result := glext_ExtensionSupported('GLX_ARB_create_context_profile', GlxExtensions);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function GLX_ARB_create_context_robustness(Display: PDisplay; Screen: Integer): boolean;
|
||||||
|
var
|
||||||
|
GlxExtensions: PChar;
|
||||||
|
begin
|
||||||
|
Result := GLX_version_1_1(Display);
|
||||||
|
if Result then
|
||||||
|
begin
|
||||||
|
GlxExtensions := glXQueryExtensionsString(Display, Screen);
|
||||||
|
Result := glext_ExtensionSupported('GLX_ARB_create_context_robustness', GlxExtensions);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function GLX_ARB_multisample(Display: PDisplay; Screen: Integer): boolean;
|
||||||
|
var
|
||||||
|
GlxExtensions: PChar;
|
||||||
|
begin
|
||||||
|
Result := GLX_version_1_1(Display);
|
||||||
|
if Result then
|
||||||
|
begin
|
||||||
|
GlxExtensions := glXQueryExtensionsString(Display, Screen);
|
||||||
|
Result := glext_ExtensionSupported('GLX_ARB_multisample', GlxExtensions);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function GLX_EXT_visual_info(Display: PDisplay; Screen: Integer): boolean;
|
||||||
|
var
|
||||||
|
GlxExtensions: PChar;
|
||||||
|
begin
|
||||||
|
Result := GLX_version_1_1(Display);
|
||||||
|
if Result then
|
||||||
|
begin
|
||||||
|
GlxExtensions := glXQueryExtensionsString(Display, Screen);
|
||||||
|
Result := glext_ExtensionSupported('GLX_EXT_visual_info', GlxExtensions);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function GLX_MESA_pixmap_colormap(Display: PDisplay; Screen: Integer): boolean;
|
||||||
|
var
|
||||||
|
GlxExtensions: PChar;
|
||||||
|
begin
|
||||||
|
Result := GLX_version_1_1(Display);
|
||||||
|
if Result then
|
||||||
|
begin
|
||||||
|
GlxExtensions := glXQueryExtensionsString(Display, Screen);
|
||||||
|
Result := glext_ExtensionSupported('GLX_MESA_pixmap_colormap', GlxExtensions) and
|
||||||
|
Assigned(glXCreateGLXPixmapMESA);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function GLX_SGI_video_sync(Display: PDisplay; Screen: Integer): boolean;
|
||||||
|
var
|
||||||
|
GlxExtensions: PChar;
|
||||||
|
begin
|
||||||
|
Result := GLX_version_1_1(Display);
|
||||||
|
if Result then
|
||||||
|
begin
|
||||||
|
GlxExtensions := glXQueryExtensionsString(Display, Screen);
|
||||||
|
Result := glext_ExtensionSupported('GLX_SGI_video_sync', GlxExtensions) and
|
||||||
|
Assigned(glXGetVideoSyncSGI) and
|
||||||
|
Assigned(glXWaitVideoSyncSGI);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function GLX_SGIS_multisample(Display: PDisplay; Screen: Integer): boolean;
|
||||||
|
var
|
||||||
|
GlxExtensions: PChar;
|
||||||
|
begin
|
||||||
|
Result := GLX_version_1_1(Display);
|
||||||
|
if Result then
|
||||||
|
begin
|
||||||
|
GlxExtensions := glXQueryExtensionsString(Display, Screen);
|
||||||
|
Result := glext_ExtensionSupported('GLX_SGIS_multisample', GlxExtensions);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
function GetProc(handle: PtrInt; name: PChar): Pointer;
|
function GetProc(handle: PtrInt; name: PChar): Pointer;
|
||||||
begin
|
begin
|
||||||
Result := GetProcAddress(handle, name);
|
Result := GetProcAddress(handle, name);
|
||||||
@ -224,10 +617,39 @@ begin
|
|||||||
glXQueryExtensionsString := GetProc(OurLibGL, 'glXQueryExtensionsString');
|
glXQueryExtensionsString := GetProc(OurLibGL, 'glXQueryExtensionsString');
|
||||||
glXQueryServerString := GetProc(OurLibGL, 'glXQueryServerString');
|
glXQueryServerString := GetProc(OurLibGL, 'glXQueryServerString');
|
||||||
glXGetClientString := GetProc(OurLibGL, 'glXGetClientString');
|
glXGetClientString := GetProc(OurLibGL, 'glXGetClientString');
|
||||||
// Mesa GLX Extensions
|
// GLX 1.2 and later
|
||||||
|
glXGetCurrentDisplay := GetProc(OurLibGL, 'glXGetCurrentDisplay');
|
||||||
|
// GLX 1.3 and later
|
||||||
|
glXChooseFBConfig := GetProc(OurLibGL, 'glXChooseFBConfig');
|
||||||
|
glXGetFBConfigAttrib := GetProc(OurLibGL, 'glXGetFBConfigAttrib');
|
||||||
|
glXGetFBConfigs := GetProc(OurLibGL, 'glXGetFBConfigs');
|
||||||
|
glXGetVisualFromFBConfig := GetProc(OurLibGL, 'glXGetVisualFromFBConfig');
|
||||||
|
glXCreateWindow := GetProc(OurLibGL, 'glXCreateWindow');
|
||||||
|
glXDestroyWindow := GetProc(OurLibGL, 'glXDestroyWindow');
|
||||||
|
glXCreatePixmap := GetProc(OurLibGL, 'glXCreatePixmap');
|
||||||
|
glXDestroyPixmap := GetProc(OurLibGL, 'glXDestroyPixmap');
|
||||||
|
glXCreatePbuffer := GetProc(OurLibGL, 'glXCreatePbuffer');
|
||||||
|
glXDestroyPbuffer := GetProc(OurLibGL, 'glXDestroyPbuffer');
|
||||||
|
glXQueryDrawable := GetProc(OurLibGL, 'glXQueryDrawable');
|
||||||
|
glXCreateNewContext := GetProc(OurLibGL, 'glXCreateNewContext');
|
||||||
|
glXMakeContextCurrent := GetProc(OurLibGL, 'glXMakeContextCurrent');
|
||||||
|
glXGetCurrentReadDrawable := GetProc(OurLibGL, 'glXGetCurrentReadDrawable');
|
||||||
|
glXQueryContext := GetProc(OurLibGL, 'glXQueryContext');
|
||||||
|
glXSelectEvent := GetProc(OurLibGL, 'glXSelectEvent');
|
||||||
|
glXGetSelectedEvent := GetProc(OurLibGL, 'glXGetSelectedEvent');
|
||||||
|
// GLX 1.4 and later
|
||||||
|
glXGetProcAddress := GetProc(OurLibGL, 'glXGetProcAddress');
|
||||||
|
// Extensions
|
||||||
|
// GLX_ARB_get_proc_address
|
||||||
|
glXGetProcAddressARB := GetProc(OurLibGL, 'glXGetProcAddressARB');
|
||||||
|
// GLX_ARB_create_context
|
||||||
|
glXCreateContextAttribsARB := GetProc(OurLibGL, 'glXCreateContextAttribsARB');
|
||||||
|
// GLX_MESA_pixmap_colormap
|
||||||
glXCreateGLXPixmapMESA := GetProc(OurLibGL, 'glXCreateGLXPixmapMESA');
|
glXCreateGLXPixmapMESA := GetProc(OurLibGL, 'glXCreateGLXPixmapMESA');
|
||||||
|
// Unknown Mesa GLX extension
|
||||||
glXReleaseBufferMESA := GetProc(OurLibGL, 'glXReleaseBufferMESA');
|
glXReleaseBufferMESA := GetProc(OurLibGL, 'glXReleaseBufferMESA');
|
||||||
glXCopySubBufferMESA := GetProc(OurLibGL, 'glXCopySubBufferMESA');
|
glXCopySubBufferMESA := GetProc(OurLibGL, 'glXCopySubBufferMESA');
|
||||||
|
// GLX_SGI_video_sync
|
||||||
glXGetVideoSyncSGI := GetProc(OurLibGL, 'glXGetVideoSyncSGI');
|
glXGetVideoSyncSGI := GetProc(OurLibGL, 'glXGetVideoSyncSGI');
|
||||||
glXWaitVideoSyncSGI := GetProc(OurLibGL, 'glXWaitVideoSyncSGI');
|
glXWaitVideoSyncSGI := GetProc(OurLibGL, 'glXWaitVideoSyncSGI');
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user