mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-17 13:39:36 +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;
|
||||
|
||||
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;
|
||||
cm: TColormap;
|
||||
winAttr: TXSetWindowAttributes;
|
||||
@ -64,22 +82,52 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure Error(const S: string);
|
||||
begin
|
||||
Writeln(ErrOutput, 'Error: ', S);
|
||||
Halt(1);
|
||||
end;
|
||||
|
||||
var
|
||||
errorBase,eventBase: integer;
|
||||
window_title_property: TXTextProperty;
|
||||
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
|
||||
initGlx();
|
||||
dpy := XOpenDisplay(nil);
|
||||
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
|
||||
writeLn('Error: GLX extension not supported');
|
||||
if not GLX_version_1_0(dpy) then
|
||||
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
|
||||
writeLn('Error: Could not find visual');
|
||||
Error('Could not find visual');
|
||||
|
||||
//Create a new colormap
|
||||
cm := XCreateColormap(dpy,RootWindow(dpy,visinfo.screen),visinfo.visual,AllocNone);
|
||||
@ -96,9 +144,32 @@ begin
|
||||
XSetWMName(dpy,win,@window_title_property);
|
||||
|
||||
//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
|
||||
writeLn('Error: Could not create an OpenGL rendering context');
|
||||
Error('Could not create an OpenGL rendering context');
|
||||
|
||||
//Make it current
|
||||
glXMakeCurrent(dpy,win,glXCont);
|
||||
|
@ -84,16 +84,6 @@ const
|
||||
GLX_ACCUM_BLUE_SIZE = 16;
|
||||
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:
|
||||
GLX_BAD_SCREEN = 1;
|
||||
GLX_BAD_ATTRIBUTE = 2;
|
||||
@ -108,7 +98,105 @@ const
|
||||
GLX_VERSION = 2;
|
||||
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_DIRECT_COLOR_EXT = $8003;
|
||||
GLX_PSEUDO_COLOR_EXT = $8004;
|
||||
@ -129,7 +217,7 @@ type
|
||||
GLXPixmap = TXID;
|
||||
GLXDrawable = TXID;
|
||||
GLXContextID = TXID;
|
||||
|
||||
|
||||
TXPixmap = XPixmap;
|
||||
TXFont = XFont;
|
||||
TXColormap = XColormap;
|
||||
@ -137,7 +225,16 @@ type
|
||||
TGLXContext = GLXContext;
|
||||
TGLXPixmap = GLXPixmap;
|
||||
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;
|
||||
TGLXWindow = TXID;
|
||||
TGLXPbuffer = TXID;
|
||||
|
||||
var
|
||||
glXChooseVisual: function(dpy: PDisplay; screen: Integer; attribList: PInteger): PXVisualInfo; cdecl;
|
||||
@ -163,24 +260,320 @@ var
|
||||
glXQueryServerString: function(dpy: PDisplay; screen, 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;
|
||||
|
||||
// Unknown Mesa GLX extension (undocumented in current GLX C headers?)
|
||||
glXReleaseBufferMESA: function(dpy: PDisplay; d: GLXDrawable): Boolean; cdecl;
|
||||
glXCopySubBufferMESA: procedure(dpy: PDisplay; drawbale: GLXDrawable; x, y, width, height: Integer); cdecl;
|
||||
|
||||
// GLX_SGI_video_sync
|
||||
glXGetVideoSyncSGI: function(var counter: 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
|
||||
|
||||
uses GL, dynlibs;
|
||||
uses GL, dynlibs, GLExt { for glext_ExtensionSupported utility };
|
||||
|
||||
{$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;
|
||||
begin
|
||||
Result := GetProcAddress(handle, name);
|
||||
@ -224,10 +617,39 @@ begin
|
||||
glXQueryExtensionsString := GetProc(OurLibGL, 'glXQueryExtensionsString');
|
||||
glXQueryServerString := GetProc(OurLibGL, 'glXQueryServerString');
|
||||
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');
|
||||
// Unknown Mesa GLX extension
|
||||
glXReleaseBufferMESA := GetProc(OurLibGL, 'glXReleaseBufferMESA');
|
||||
glXCopySubBufferMESA := GetProc(OurLibGL, 'glXCopySubBufferMESA');
|
||||
// GLX_SGI_video_sync
|
||||
glXGetVideoSyncSGI := GetProc(OurLibGL, 'glXGetVideoSyncSGI');
|
||||
glXWaitVideoSyncSGI := GetProc(OurLibGL, 'glXWaitVideoSyncSGI');
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user