* implemented functions to create, destroy, active and deactivate a rendering context
authorBergmann89 <bergmann89@muo-game.de>
Tue, 18 Nov 2014 20:13:35 +0000 (21:13 +0100)
committerBergmann89 <bergmann89@muo-game.de>
Tue, 18 Nov 2014 20:14:00 +0000 (21:14 +0100)
dglOpenGLES.pas

index 7630ae5..4f05259 100644 (file)
@@ -49,10 +49,14 @@ interface
 {$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';
@@ -1550,7 +1554,7 @@ type
   EGLNativeDisplayType  = Pointer;
   EGLNativePixmapType   = Pointer;
   EGLNativeWindowType   = packed record
-     element: Cardinal { DispManXElementHandle };
+     element: Cardinal;
      width: Integer;
      height: Integer;
   end;
@@ -1816,7 +1820,30 @@ var
 
   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
@@ -1915,6 +1942,72 @@ begin
     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');
@@ -2237,5 +2330,11 @@ begin
   glVertexBindingDivisor                    := dglGetProcAddress('glVertexBindingDivisor');
 end;
 
+constructor EeglError.Create(const msg: string; const aErrorCode: EGLint);
+begin
+  inherited Create(msg);
+  ErrorCode := aErrorCode;
+end;
+
 end.