{$ENDIF}
//check if system is supported and set system dependent constants
-{$IFDEF DGL_LINUX}
uses
- dl;
+ sysutils
+ {$IFDEF DGL_LINUX}
+ , dl
+ {$ENDIF}
+ ;
+{$IFDEF DGL_LINUX}
const
LIBNAME_OPENGLES = 'libGLESv2.so';
LIBNAME_EGL = 'libEGL.so';
EGLNativeDisplayType = Pointer;
EGLNativePixmapType = Pointer;
EGLNativeWindowType = packed record
- element: Cardinal { DispManXElementHandle };
+ element: Cardinal;
width: Integer;
height: Integer;
end;
eglGetProcAddress: TeglGetProcAddress;
+
+{ =================================================== DelphiGL ======================================================= }
+type
+ EdglOpenGLES = class(Exception);
+ EeglError = class(EdglOpenGLES)
+ public
+ ErrorCode: EGLint;
+ constructor Create(const msg: string; const aErrorCode: EGLint);
+ end;
+
+ TdglRenderContext = packed record
+ Display: EGLDisplay;
+ Surface: EGLSurface;
+ Context: EGLContext;
+ end;
+
function InitOpenGLES(const aOpenGLESLibName: String = LIBNAME_OPENGLES; aEGLLibName: String = LIBNAME_EGL): Boolean;
+
+function CreateRenderingContext(const aDisplayType: EGLNativeDisplayType; const aWindowType: PEGLNativeWindowType; const aAttributes: PEGLint): TdglRenderContext;
+procedure DestroyRenderingContext(const aContext: TdglRenderContext);
+function ActivateRenderingContext(const aContext: TdglRenderContext): Boolean;
+function DeactivateRenderingContext(const aContext: TdglRenderContext): Boolean;
+procedure SwapBuffers(const aContext: TdglRenderContext);
+
procedure ReadExtensions;
implementation
result := false;
end;
+procedure RaiseEglError(const aMsg: String);
+var err: EGLint;
+begin
+ err := eglGetError();
+ raise EeglError.Create(aMsg + ' ErrorCode: 0x' + IntToHex(err, 8), err);
+end;
+
+function CreateRenderingContext(const aDisplayType: EGLNativeDisplayType; const aWindowType: PEGLNativeWindowType; const aAttributes: PEGLint): TdglRenderContext;
+var
+ ConfigCount: EGLint;
+ Config: EGLConfig;
+begin
+ if (not Assigned(LibHandleOpenGLES) or not Assigned(LibHandleEGL)) and
+ not InitOpenGLES then
+ raise EdglOpenGLES.Create('unable to initialize OpenGL library');
+
+ result.Display := eglGetDisplay(aDisplayType);
+ if (result.Display = EGL_NO_DISPLAY) then
+ RaiseEglError('unable to get display.');
+
+ if (eglInitialize(result.Display, nil, nil) <> EGL_TRUE) then
+ RaiseEglError('unable to initialize egl.');
+
+ if (eglChooseConfig(result.Display, aAttributes, @Config, 1, @ConfigCount) <> EGL_TRUE) or
+ (ConfigCount <> 1) then
+ RaiseEglError('unable to get suitable config.');
+
+ result.Surface := eglCreateWindowSurface(result.Display, Config, aWindowType, nil);
+ if (result.Surface = EGL_NO_SURFACE) then
+ RaiseEglError('unable to create window surface.');
+
+ result.Context := eglCreateContext(result.Display, Config, EGL_NO_CONTEXT, nil);
+ if (result.Context = EGL_NO_CONTEXT) then begin
+ eglDestroySurface(result.Display, result.Surface);
+ RaiseEglError('unable to create context.');
+ end;
+end;
+
+procedure DestroyRenderingContext(const aContext: TdglRenderContext);
+begin
+ if (eglGetCurrentContext = aContext.Context) and
+ not DeactivateRenderingContext(aContext) then
+ RaiseEglError('unable to unbind context.');
+
+ if (eglDestroyContext(aContext.Display, aContext.Context) <> EGL_TRUE) then
+ RaiseEglError('unable to destory context.');
+
+ if (eglDestroySurface(aContext.Display, aContext.Surface) <> EGL_TRUE) then
+ RaiseEglError('unable to destroy surface.');
+end;
+
+function ActivateRenderingContext(const aContext: TdglRenderContext): Boolean;
+begin
+ result := (eglMakeCurrent(aContext.Display, aContext.Surface, aContext.Surface, aContext.Context) = GL_TRUE);
+end;
+
+function DeactivateRenderingContext(const aContext: TdglRenderContext): Boolean;
+begin
+ result := (eglMakeCurrent(aContext.Display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT) = EGL_TRUE);
+end;
+
+procedure SwapBuffers(const aContext: TdglRenderContext);
+begin
+ eglSwapBuffers(aContext.Display, aContext.Surface);
+end;
+
procedure ReadExtensions;
begin
glActiveTexture := dglGetProcAddress('glActiveTexture');
glVertexBindingDivisor := dglGetProcAddress('glVertexBindingDivisor');
end;
+constructor EeglError.Create(const msg: string; const aErrorCode: EGLint);
+begin
+ inherited Create(msg);
+ ErrorCode := aErrorCode;
+end;
+
end.