Browse Source

Create zgl_opengl.pas

Seenkao 3 years ago
parent
commit
96e1446cfa
1 changed files with 834 additions and 0 deletions
  1. 834 0
      Zengl_SRC/src/zgl_opengl.pas

+ 834 - 0
Zengl_SRC/src/zgl_opengl.pas

@@ -0,0 +1,834 @@
+{
+ *  Copyright (c) 2012 Andrey Kemka
+ *
+ *  This software is provided 'as-is', without any express or
+ *  implied warranty. In no event will the authors be held
+ *  liable for any damages arising from the use of this software.
+ *
+ *  Permission is granted to anyone to use this software for any purpose,
+ *  including commercial applications, and to alter it and redistribute
+ *  it freely, subject to the following restrictions:
+ *
+ *  1. The origin of this software must not be misrepresented;
+ *     you must not claim that you wrote the original software.
+ *     If you use this software in a product, an acknowledgment
+ *     in the product documentation would be appreciated but
+ *     is not required.
+ *
+ *  2. Altered source versions must be plainly marked as such,
+ *     and must not be misrepresented as being the original software.
+ *
+ *  3. This notice may not be removed or altered from any
+ *     source distribution.
+ !!! modification from Serge 26.02.2022
+}
+unit zgl_opengl;
+
+{$I zgl_config.cfg}
+{$I GLdefine.cfg}
+{$IfDef MAC_COCOA}
+  {$modeswitch objectivec1}
+{$EndIf}
+{$IFDEF UNIX}
+  {$DEFINE stdcall := cdecl}
+{$ENDIF}
+
+interface
+uses
+  zgl_opengl_all,
+  zgl_pasOpenGL,
+  zgl_gltypeconst,
+  {$IFDEF LINUX}
+  X, XUtil, xlib,
+  zgl_glx_wgl
+  {$ENDIF}
+  {$IFDEF WINDOWS}
+  Windows,
+  zgl_glx_wgl
+  {$ENDIF}
+  {$IFDEF MACOSX}{$IfDef MAC_COCOA}
+  CocoaAll,
+  {$EndIf}
+  MacOSAll
+  {$ENDIF}
+  ;
+
+const
+  TARGET_SCREEN  = 1;                    // цель - экран
+  TARGET_TEXTURE = 2;                    // цель - часть экрана
+
+// Rus: инициализация OpenGL и подготовка формата пиксела.
+// Eng:
+function  gl_Create: Boolean;
+{$IfNDef MAC_COCOA}
+// Rus: уничтожение контекста.
+// Eng:
+procedure gl_Destroy;
+{$EndIf}
+// Rus: создание контекста.
+// Eng:
+function  gl_Initialize: Boolean;
+// Rus: возвращение к первоначальным заданным данным.
+// Eng:
+procedure gl_ResetState;
+// Rus: проверка и загрузка расширений.
+// Eng:
+procedure gl_LoadEx;
+
+var
+  oglzDepth    : LongWord;
+  oglStencil   : LongWord;
+  oglFSAA      : LongWord;
+  oglAnisotropy: LongWord;
+  oglFOVY      : Single = 45;
+  oglzNear     : Single = 0.1;
+  oglzFar      : Single = 100;
+
+  oglMode   : Integer = 2; // 2D/3D Modes
+  oglTarget : Integer = TARGET_SCREEN;
+  oglTargetW: Integer;
+  oglTargetH: Integer;
+  oglWidth  : Integer;
+  oglHeight : Integer;
+
+  oglVRAMUsed: LongWord;
+
+  oglRenderer     : UTF8String;
+  oglExtensions   : UTF8String;
+  ogl3DAccelerator: Boolean;
+  oglCanVSync     : Boolean;
+  oglCanFBO       : Boolean;
+  oglCanPBuffer   : Boolean;               // для MacOS доделать!!!
+  oglMaxTexSize   : Integer;
+  oglMaxFBOSize   : Integer;
+  oglMaxAnisotropy: Integer;
+  oglMaxTexUnits  : Integer;
+  oglSeparate     : Boolean;
+
+  maxGLVerMajor   : Integer = 2;
+  maxGLVerMinor   : Integer = 1;
+
+  // переделать
+  contextAttr     : array[0..9] of Integer;
+  contextFlags    : LongWord = 2;
+  contextMask     : LongWord = 2;
+  oldContext      : Boolean = true;
+
+  {$IFDEF LINUX}
+  oglXExtensions: UTF8String;
+  oglPBufferMode: Integer;
+  oglContext    : GLXContext;
+  oglVisualInfo : PXVisualInfo;
+  oglFBConfig   : GLXFBConfig;
+  oglAttr       : array[0..31] of Integer = (GLX_RGBA, GL_TRUE, GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, GLX_ALPHA_SIZE, 8,
+                                    GLX_DOUBLEBUFFER, GL_TRUE, GLX_DEPTH_SIZE, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+  {$IfDef GL_VERSION_3_0}
+  glxAttr       : array[0..26] of GLint = (GLX_X_RENDERABLE, GL_TRUE,
+                                      GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
+                                      GLX_RENDER_TYPE, GLX_RGBA_BIT,
+                                      GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR,
+                                      GLX_RED_SIZE, 8,
+                                      GLX_GREEN_SIZE, 8,
+                                      GLX_BLUE_SIZE, 8,
+                                      GLX_ALPHA_SIZE, 8,
+                                      GLX_DEPTH_SIZE, 24,
+                                      GLX_DOUBLEBUFFER, GL_TRUE,
+                                      0, 0, 0, 0, 0, 0, 0);
+  {$ENDIF}{$EndIf}
+
+  {$IFDEF WINDOWS}
+  oWGLExtensions: UTF8String;
+  oglContext   : HGLRC;
+  oglfAttr     : array[0..1 ] of Single = (0, 0);
+  ogliAttr     : array[0..31] of Integer = (WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB, WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
+                                    WGL_SUPPORT_OPENGL_ARB, GL_TRUE, WGL_DOUBLE_BUFFER_ARB, GL_TRUE, WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
+                                    WGL_COLOR_BITS_ARB, 24, WGL_RED_BITS_ARB, 8, WGL_GREEN_BITS_ARB, 8, WGL_BLUE_BITS_ARB, 8,
+                                    WGL_ALPHA_BITS_ARB, 8, WGL_DEPTH_BITS_ARB, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+  oglFormat    : Integer;
+  oglFormats   : LongWord;
+  oglFormatDesc: TPixelFormatDescriptor;
+  {$ENDIF}
+
+  {$IFDEF MACOSX}{$IfDef MAC_COCOA}
+  oglContext : NSOpenGLContext;
+  oglCoreGL  : Integer;
+  oglAttr    : array[0..9] of NSOpenGLPixelFormatAttribute = (NSOpenGLPFADoubleBuffer, NSOpenGLPFAColorSize, 32, NSOpenGLPFADepthSize, 32,
+                        NSOpenGLPFAStencilSize, 8, NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersionLegacy, 0);
+  {$Else}
+  oglDevice  : GDHandle;
+  oglContext : TAGLContext;
+  oglFormat  : TAGLPixelFormat;
+  oglAttr    : array[0..31] of LongWord;
+  {$ENDIF}{$EndIf}
+
+implementation
+uses
+  zgl_screen,
+  zgl_window,
+  zgl_log,
+  zgl_utils;
+
+function gl_Create: Boolean;
+var
+  i, j: Integer;
+  {$IfDef LINUX}
+  FBConfig: GLXFBConfig;
+  PFBConfig: PGLXFBConfig;
+  fbcount: Integer = 0;
+  samp_buf: Integer = 0;
+  samples: Integer = 0;
+  best_FBconf: Integer = -1;
+  worst_FBconf: Integer = -1;
+  best_num_samp: Integer = -1;
+  worst_num_samp: Integer = 9999;
+  {$EndIf}
+  {$IFDEF WINDOWS}
+  pixelFormat: Integer;
+  {$ENDIF}
+begin
+  Result := FALSE;
+
+  if not InitGL() Then
+  begin
+    log_Add('Cannot load GL library');
+    exit;
+  end;
+
+{$IFDEF LINUX}
+  glXGetProcAddressARB := gl_GetProc('glXGetProcAddress');
+  Init_GLX_WGL;
+
+  if not glXQueryExtension(scrDisplay, i, j) Then
+  begin
+    u_Error('GLX Extension not found');
+    exit;
+  end
+  else
+    log_Add('GLX Extension - ok');
+
+  // PBUFFER or OpenGL 3+
+  if GLX_VERSION_1_4 or GLX_VERSION_1_3 then
+    oglPBufferMode := 1
+  else
+    if GLX_SGIX_fbconfig and GLX_SGIX_pbuffer Then
+        oglPBufferMode := 2
+    else
+      oglPBufferMode := 0;
+  oglCanPBuffer := oglPBufferMode <> 0;
+  if oglPBufferMode = 2 Then
+    log_Add('GLX_SGIX_PBUFFER: TRUE')
+  else
+    log_Add('GLX_PBUFFER: ' + u_BoolToStr(oglCanPBuffer));
+
+  case oglPBufferMode of
+    1:
+      begin
+        glXGetVisualFromFBConfig := gl_GetProc('glXGetVisualFromFBConfig');
+        glXChooseFBConfig        := gl_GetProc('glXChooseFBConfig');
+        glXCreatePbuffer         := gl_GetProc('glXCreatePbuffer');
+        glXDestroyPbuffer        := gl_GetProc('glXDestroyPbuffer');
+      end;
+    2:
+      begin
+        glXGetVisualFromFBConfig := gl_GetProc('glXGetVisualFromFBConfigSGIX');
+        glXChooseFBConfig        := gl_GetProc('glXChooseFBConfigSGIX');
+        glXCreateGLXPbufferSGIX  := gl_GetProc('glXCreateGLXPbufferSGIX');
+        glXDestroyGLXPbufferSGIX := gl_GetProc('glXDestroyGLXPbufferSGIX');
+      end;
+  end;
+
+  {$IfDef GL_VERSION_3_0}
+  if maxGLVerMajor >= 3 then
+  begin
+    oldContext := False;
+    i := 20;
+    FillChar(glxAttr[20], 5 * 4, None);
+    if oglStencil > 0 then
+    begin
+      glxAttr[i] := GLX_STENCIL_SIZE;
+      glxAttr[i + 1] := oglStencil;
+      inc(i, 2);
+    end;
+    if oglFSAA > 0 then
+    begin
+      glxAttr[i] := GLX_SAMPLES_SGIS;
+      glxAttr[i + 1] := oglFSAA;
+    end;
+    PFBConfig := @FBConfig;
+    PFBConfig := glXChooseFBConfig(scrDisplay, scrDefault, @glxAttr[0], fbcount);
+    if not Assigned(PFBConfig) or (fbcount = 0) then
+    begin
+      log_Add('Attribs for OpenGL 3+ not used.');
+      //exit;  //????
+    end;
+    for i := 0 to fbcount - 1 do
+    begin
+      oglVisualInfo := glXGetVisualFromFBConfig(scrDisplay, PFBConfig[i]);
+      if Assigned(oglVisualInfo) then
+      begin
+        glXGetFBConfigAttrib(scrDisplay, PFBConfig[i], GLX_SAMPLE_BUFFERS, samp_buf);
+        glXGetFBConfigAttrib(scrDisplay, PFBConfig[i], GLX_SAMPLES, samples);
+        if (best_FBconf < 0) or ((samp_buf and samples) > best_num_samp) then
+        begin
+          best_FBconf := i;
+          best_num_samp := samples;
+        end;
+        if (worst_FBconf < 0) or ((not samp_buf or samples) < worst_num_samp) then
+        begin
+          worst_FBconf := i;
+          worst_num_samp := samples;
+        end;
+      end;
+      XFree(oglVisualInfo);
+    end;
+    oglFBConfig := PFBConfig[best_FBconf];
+    XFree(PFBConfig);
+    oglVisualInfo := glXGetVisualFromFBConfig(scrDisplay, oglFBConfig);
+    if not Assigned(oglVisualInfo) then
+    begin
+      log_Add('Could not create correct visual window fo OpenGL 3+.');
+      oldContext := true;
+    end;
+    if scrDefault <> oglVisualInfo^.screen then
+    begin
+      log_Add('screenID(' + u_IntToStr(scrDefault) + ') does not match visual->screen(' + u_IntToStr(oglVisualInfo^.screen) + ').');
+      oldContext := true;
+    end;
+  end;
+  {$EndIf}
+
+  if oldContext then
+  begin
+    // for old context
+    oglzDepth := 24;
+    repeat
+      FillChar(oglAttr[14], (32 - 14) * 4, None);
+      i := 14;
+      if oglStencil > 0 Then
+      begin
+        oglAttr[i] := GLX_STENCIL_SIZE;
+        oglAttr[i + 1] := oglStencil;
+        INC(i, 2);
+      end;
+      if oglFSAA > 0 Then
+      begin
+        oglAttr[i] := GLX_SAMPLES_SGIS;
+        oglAttr[i + 1] := oglFSAA;
+      end;
+
+      log_Add('glXChooseVisual: zDepth = ' + u_IntToStr(oglzDepth) + '; ' + 'stencil = ' + u_IntToStr(oglStencil) + '; ' + 'fsaa = ' + u_IntToStr(oglFSAA));
+      oglVisualInfo := glXChooseVisual(scrDisplay, scrDefault, @oglAttr[0]);
+      if (not Assigned(oglVisualInfo) and (oglzDepth = 1)) Then
+      begin
+        if oglFSAA = 0 Then
+          break
+        else
+        begin
+          oglzDepth := 24;
+          DEC(oglFSAA, 2);
+        end;
+      end else
+        if not Assigned(oglVisualInfo) Then
+          DEC(oglzDepth, 8);
+    if oglzDepth = 0 Then
+      oglzDepth := 1;
+    until Assigned(oglVisualInfo);
+  end;
+
+  if not Assigned(oglVisualInfo) Then
+  begin
+    u_Error('Cannot choose visual info.');
+    exit;
+  end;
+{$ENDIF}
+{$IFDEF WINDOWS}
+  wnd_Create();
+
+  FillChar(oglFormatDesc, SizeOf(TPixelFormatDescriptor), 0);
+  with oglFormatDesc do
+  begin
+    nSize        := SizeOf(TPIXELFORMATDESCRIPTOR);
+    nVersion     := 1;
+    dwFlags      := PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER;
+    iPixelType   := PFD_TYPE_RGBA;
+    cColorBits   := 24;
+    cAlphabits   := 8;
+    cDepthBits   := 24;
+    cStencilBits := oglStencil;
+    iLayerType   := PFD_MAIN_PLANE;
+  end;
+
+  pixelFormat := ChoosePixelFormat(wndDC, @oglFormatDesc);
+  if pixelFormat = 0 Then
+  begin
+    u_Error('Cannot choose pixel format');
+    exit;
+  end;
+
+  if not SetPixelFormat(wndDC, pixelFormat, @oglFormatDesc) Then
+  begin
+    u_Error('Cannot set pixel format');
+    exit;
+  end;
+
+  oglContext := wglCreateContext(wndDC);
+  if (oglContext = 0) Then
+  begin
+    u_Error('Cannot create OpenGL context');
+    exit;
+  end;
+
+  if not wglMakeCurrent(wndDC, oglContext) Then
+  begin
+    u_Error('Cannot set current OpenGL context');
+    exit;
+  end;
+
+  wglGetExtensionsStringARB := gl_GetProc('wglGetExtensionsString');
+  if Assigned(wglGetExtensionsStringARB) then
+  begin
+    oWGLExtensions := wglGetExtensionsStringARB(wndDC);
+    log_Add('All extensions: ' + oWGLExtensions);
+  end;
+  CheckGLVersion;
+  log_Add(u_IntToStr(use_glMajorVer) + '.' + u_IntToStr(use_glMinorVer));
+  oglExtensions := '';
+  {$IfDef GL_VERSION_3_0}
+  if use_glMajorVer >= 3 then
+  begin
+    if not Assigned(glGetStringi) then
+      glGetStringi := gl_GetProc('glGetStringi');
+    if Assigned(glGetStringi) then
+    begin
+      glGetIntegerv(GL_NUM_EXTENSIONS, @j);
+      for i := 0 to j - 1 do
+        oglExtensions := oglExtensions + PAnsiChar(glGetStringi(GL_EXTENSIONS, i)) + #32;
+    end;
+  end;
+  {$EndIf}
+  if oglExtensions = '' then
+    oglExtensions := glGetString(GL_EXTENSIONS);
+  log_Add(oglExtensions);
+  Init_GLX_WGL;
+  LoadOpenGL;
+
+  wglChoosePixelFormatARB := gl_GetProc('wglChoosePixelFormat');
+  if Assigned(wglChoosePixelFormatARB) Then
+  begin
+    oglzDepth := 24;
+    repeat
+      FillChar(ogliAttr[22], (32 - 22) * 4, 0);
+      i := 22;
+      if oglStencil > 0 Then
+      begin
+        ogliAttr[i] := WGL_STENCIL_BITS_ARB;
+        ogliAttr[i + 1] := oglStencil;
+        inc(i, 2);
+      end;
+      if oglFSAA > 0 Then
+      begin
+        ogliAttr[i] := WGL_SAMPLE_BUFFERS_ARB;
+        ogliAttr[i + 1] := GL_TRUE;
+        ogliAttr[i + 2] := WGL_SAMPLES_ARB;
+        ogliAttr[i + 3] := oglFSAA;
+      end;
+
+      log_Add('wglChoosePixelFormatARB: zDepth = ' + u_IntToStr(oglzDepth) + '; ' + 'stencil = ' + u_IntToStr(oglStencil) + '; ' + 'fsaa = ' + u_IntToStr(oglFSAA));
+      wglChoosePixelFormatARB(wndDC, @ogliAttr, @oglfAttr, 1, @oglFormat, @oglFormats);
+      if (oglFormat = 0) and (oglzDepth < 16) Then
+      begin
+        if oglFSAA <= 0 Then
+          break
+        else
+        begin
+          oglzDepth := 24;
+          DEC(oglFSAA, 2);
+        end;
+      end else
+        DEC(oglzDepth, 8);
+    until oglFormat <> 0;
+  end;
+
+  if oglFormat = 0 Then
+  begin
+    oglzDepth := 24;
+    oglFSAA   := 0;
+    oglFormat := pixelFormat;
+    log_Add('ChoosePixelFormat: zDepth = ' + u_IntToStr(oglzDepth) + '; ' + 'stencil = ' + u_IntToStr(oglStencil));
+  end;
+
+  wglMakeCurrent(wndDC, 0);
+  wglDeleteContext(oglContext);
+  wnd_Destroy();
+//  wndFirst := FALSE;
+{$ENDIF}
+{$IFDEF MACOSX}{$IfDef MAC_COCOA}
+
+{$Else}
+  if not InitAGL() Then
+  begin
+    log_Add('Cannot load AGL library');
+    exit;
+  end;
+
+  oglzDepth := 24;
+  repeat
+    FillChar(oglAttr[0], Length(oglAttr) * 4, AGL_NONE);
+    oglAttr[0] := AGL_RGBA;
+    oglAttr[1] := AGL_RED_SIZE;
+    oglAttr[2] := 8;
+    oglAttr[3] := AGL_GREEN_SIZE;
+    oglAttr[4] := 8;
+    oglAttr[5] := AGL_BLUE_SIZE;
+    oglAttr[6] := 8;
+    oglAttr[7] := AGL_ALPHA_SIZE;
+    oglAttr[8] := 8;
+    oglAttr[9] := AGL_DOUBLEBUFFER;
+    oglAttr[10] := AGL_DEPTH_SIZE;
+    oglAttr[11] := oglzDepth;
+    i := 12;
+    if oglStencil > 0 Then
+    begin
+      oglAttr[i] := AGL_STENCIL_SIZE;
+      oglAttr[i + 1] := oglStencil;
+      inc(i, 2);
+    end;
+    if oglFSAA > 0 Then
+    begin
+      oglAttr[i] := AGL_SAMPLE_BUFFERS_ARB;
+      oglAttr[i + 1] := 1;
+      oglAttr[i + 2] := AGL_SAMPLES_ARB;
+      oglAttr[i + 3] := oglFSAA;
+    end;
+
+    log_Add('aglChoosePixelFormat: zDepth = ' + u_IntToStr(oglzDepth) + '; ' + 'stencil = ' + u_IntToStr(oglStencil) + '; ' + 'fsaa = ' + u_IntToStr(oglFSAA));
+    DMGetGDeviceByDisplayID(DisplayIDType(scrDisplay), oglDevice, FALSE);
+    oglFormat := aglChoosePixelFormat(@oglDevice, 1, @oglAttr[0]);
+    if (not Assigned(oglFormat) and (oglzDepth = 1)) Then
+    begin
+      if oglFSAA = 0 Then
+        break
+      else
+      begin
+        oglzDepth := 24;
+        DEC(oglFSAA, 2);
+      end;
+    end else
+      if not Assigned(oglFormat) Then
+        DEC(oglzDepth, 8);
+    if oglzDepth = 0 Then
+      oglzDepth := 1;
+  until Assigned(oglFormat);
+
+  if not Assigned(oglFormat) Then
+  begin
+    u_Error('Cannot choose pixel format.');
+    exit;
+  end;
+{$ENDIF}{$EndIf}
+  Result := TRUE;
+end;
+
+{$IfNDef MAC_COCOA}
+procedure gl_Destroy;
+begin
+{$IFDEF LINUX}
+  if not glXMakeCurrent(scrDisplay, None, nil) Then
+    u_Error('Cannot release current OpenGL context');
+
+  glXDestroyContext(scrDisplay, oglContext);
+{$ENDIF}
+{$IFDEF WINDOWS}
+  if not wglMakeCurrent(wndDC, 0) Then
+    u_Error('Cannot release current OpenGL context');
+
+  wglDeleteContext(oglContext);
+{$ENDIF}
+{$IFDEF MACOSX}
+  aglDestroyPixelFormat(oglFormat);
+  if aglSetCurrentContext(nil) = GL_FALSE Then
+    u_Error('Cannot release current OpenGL context');
+
+  aglDestroyContext(oglContext);
+  FreeAGL();
+{$ENDIF}
+
+  FreeGL();
+end;
+{$EndIf}
+
+function gl_Initialize: Boolean;
+{$IfDef MAC_COCOA}
+var
+  pixfmt: NSOpenGLPixelFormat;
+{$EndIf}
+begin
+  Result := FALSE;
+{$IFDEF LINUX}
+  if oldContext then
+  begin
+    oglContext := glXCreateContext(scrDisplay, oglVisualInfo, nil, GL_TRUE);
+    if not Assigned(oglContext) Then
+    begin
+      oglContext := glXCreateContext(scrDisplay, oglVisualInfo, nil, GL_FALSE);
+      if not Assigned(oglContext) Then
+      begin
+        u_Error('Cannot create OpenGL context');
+        exit;
+      end;
+    end;
+  end {$IfDef GL_VERSION_3_0}
+  else begin
+    contextAttr[0] := GLX_CONTEXT_MAJOR_VERSION_ARB;
+    contextAttr[1] := maxGLVerMajor;
+    contextAttr[2] := GLX_CONTEXT_MINOR_VERSION_ARB;
+    contextAttr[3] := maxGLVerMinor;
+    contextAttr[4] := GLX_CONTEXT_FLAGS_ARB;
+    contextAttr[5] := contextFlags;
+    contextAttr[6] := GLX_CONTEXT_PROFILE_MASK_ARB;
+    contextAttr[7] := contextMask;
+    contextAttr[8] := 0;
+    if GLX_ARB_create_context then
+    begin
+      oglContext := glXCreateContextAttribsARB(scrDisplay, oglFBConfig, nil, true, @contextAttr[0]);
+      if not Assigned(oglContext) then
+        oglContext := glXCreateContextAttribsARB(scrDisplay, oglFBConfig, nil, false, @contextAttr[0]);
+      if not Assigned(oglContext) Then
+      begin
+        u_Error('Cannot create OpenGL context');
+        exit;
+      end;
+    end
+    else begin
+      oglContext := glXCreateNewContext(scrDisplay, oglFBConfig, GLX_RGBA_TYPE, nil, GL_TRUE);
+      if not Assigned(oglContext) then
+        oglContext := glXCreateNewContext(scrDisplay, oglFBConfig, GLX_RGBA_TYPE, nil, GL_FALSE);
+      if not Assigned(oglContext) Then
+      begin
+        u_Error('Cannot create OpenGL context');
+        exit;
+      end;
+    end;
+  end{$EndIf};
+  if not glXMakeCurrent(scrDisplay, wndHandle, oglContext) Then
+  begin
+    u_Error('Cannot set current OpenGL context');
+    exit;
+  end;
+  CheckGLVersion;
+  LoadOpenGL;
+{$ENDIF}
+{$IFDEF WINDOWS}
+  if not SetPixelFormat(wndDC, oglFormat, @oglFormatDesc) Then
+  begin
+    u_Error('Cannot set pixel format');
+    exit;
+  end;
+  oglContext := 0;
+  {$IfDef GL_VERSION_3_0}
+  if GL_VERSION_3_0 and Assigned(wglCreateContextAttribsARB) then
+  begin
+    contextAttr[0] := WGL_CONTEXT_MAJOR_VERSION_ARB;
+    contextAttr[1] := use_glMajorVer;
+    contextAttr[2] := WGL_CONTEXT_MINOR_VERSION_ARB;
+    contextAttr[3] := use_glMinorVer;
+    contextAttr[4] := WGL_CONTEXT_PROFILE_MASK_ARB;
+    contextAttr[5] := contextMask;
+    contextAttr[6] := WGL_CONTEXT_FLAGS_ARB;
+    contextAttr[7] := contextFlags;
+    contextAttr[8] := 0;
+    oglContext := wglCreateContextAttribsARB(wndDC, 0, @contextAttr[0]);
+  end;
+  if oglContext = 0 then
+  begin
+    if (GL_ARB_compatibility and (use_glMajorVer >= 3)) or (use_glMajorVer <= 2) then
+      oglContext := wglCreateContext(wndDC)
+    else begin
+      u_Error('Cannot create OpenGL context 3+');
+      Exit;
+    end;
+  end;
+  {$Else}
+  oglContext := wglCreateContext(wndDC);
+  {$EndIf}
+  if (oglContext = 0) Then
+  begin
+    u_Error('Cannot create OpenGL context');
+    exit;
+  end;
+  if not wglMakeCurrent(wndDC, oglContext) Then
+  begin
+    u_Error('Cannot set current OpenGL context');
+    exit;
+  end;
+{$ENDIF}
+{$IFDEF MACOSX}{$IfDef MAC_COCOA}
+  pixfmt := NSOpenGLPixelFormat.alloc.initWithAttributes(@oglAttr);
+  oglContext := NSOpenGLContext.alloc.initWithFormat_shareContext(pixfmt, nil);
+  pixfmt.release;
+  oglContext.makeCurrentContext;
+
+  oglContext.setView(zglView);
+{$Else}
+  oglContext := aglCreateContext(oglFormat, nil);
+  if not Assigned(oglContext) Then
+    begin
+      u_Error('Cannot create OpenGL context');
+      exit;
+    end;
+  if aglSetDrawable(oglContext, GetWindowPort(wndHandle)) = GL_FALSE Then
+    begin
+      u_Error('Cannot set Drawable');
+      exit;
+    end;
+  if aglSetCurrentContext(oglContext) = GL_FALSE Then
+    begin
+      u_Error('Cannot set current OpenGL context');
+      exit;
+    end;
+{$ENDIF}{$EndIf}
+
+  oglRenderer := glGetString(GL_RENDERER);
+  log_Add('GL_VERSION: ' + glGetString(GL_VERSION));
+  log_Add('GL_RENDERER: ' + oglRenderer);
+
+{$IFDEF LINUX}
+  ogl3DAccelerator := oglRenderer <> 'Software Rasterizer';
+{$ENDIF}
+{$IFDEF WINDOWS}
+  ogl3DAccelerator := oglRenderer <> 'GDI Generic';
+{$ENDIF}
+{$IFDEF MACOSX}
+  ogl3DAccelerator := oglRenderer <> 'Apple Software Renderer';
+{$ENDIF}
+  if not ogl3DAccelerator Then
+    u_Warning('Cannot find 3D-accelerator! Application run in software-mode, it''s very slow');
+
+  gl_LoadEx();
+  gl_ResetState();
+
+  Result := TRUE;
+end;
+
+procedure gl_ResetState;
+begin
+  glHint(GL_LINE_SMOOTH_HINT,            GL_NICEST);
+  glHint(GL_POLYGON_SMOOTH_HINT,         GL_NICEST);
+  glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
+  glHint(GL_FOG_HINT,                    GL_DONT_CARE);
+  glShadeModel(GL_SMOOTH);
+
+  glClearColor(0, 0, 0, 0);
+
+  glDepthFunc (GL_LEQUAL);
+  glClearDepth(1.0);
+
+  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+  glAlphaFunc(GL_GREATER, 0);
+
+  if oglSeparate Then
+    begin
+      glBlendEquation(GL_FUNC_ADD_EXT);
+      glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+    end;
+
+  glDisable(GL_BLEND);
+  glDisable(GL_ALPHA_TEST);
+  glDisable(GL_DEPTH_TEST);
+  glDisable(GL_TEXTURE_2D);
+  glEnable (GL_NORMALIZE);
+end;
+
+procedure gl_LoadEx;
+begin
+  // Texture size
+  glGetIntegerv(GL_MAX_TEXTURE_SIZE, @oglMaxTexSize);
+  log_Add('GL_MAX_TEXTURE_SIZE: ' + u_IntToStr(oglMaxTexSize));
+
+  glCompressedTexImage2D := gl_GetProc('glCompressedTexImage2D');
+  log_Add('GL_EXT_TEXTURE_COMPRESSION_S3TC: ' + u_BoolToStr(GL_EXT_texture_compression_s3tc));
+
+  log_Add('GL_SGIS_GENERATE_MIPMAP: ' + u_BoolToStr(GL_SGIS_generate_mipmap));
+
+  // Multitexturing
+  glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, @oglMaxTexUnits);
+  log_Add('GL_MAX_TEXTURE_UNITS_ARB: ' + u_IntToStr(oglMaxTexUnits));
+
+  // Anisotropy
+  if GL_EXT_texture_filter_anisotropic Then
+  begin
+    glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, @oglMaxAnisotropy);
+    oglAnisotropy := oglMaxAnisotropy;
+  end else
+    oglAnisotropy := 0;
+  log_Add('GL_EXT_TEXTURE_FILTER_ANISOTROPIC: ' + u_BoolToStr(GL_EXT_texture_filter_anisotropic));
+  log_Add('GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: ' + u_IntToStr(oglMaxAnisotropy));
+
+  glBlendEquation     := gl_GetProc('glBlendEquation');
+  glBlendFuncSeparate := gl_GetProc('glBlendFuncSeparate');
+  // separator
+  oglSeparate := Assigned(glBlendEquation) and Assigned(glBlendFuncSeparate) and GL_EXT_blend_func_separate;
+  log_Add('GL_EXT_BLEND_FUNC_SEPARATE: ' + u_BoolToStr(oglSeparate));
+
+  // FBO
+  glBindRenderbuffer := gl_GetProc('glBindRenderbuffer');
+  if Assigned(glBindRenderbuffer) Then
+  begin
+    oglCanFBO                 := TRUE;
+    glIsRenderbuffer          := gl_GetProc('glIsRenderbuffer'         );
+    glDeleteRenderbuffers     := gl_GetProc('glDeleteRenderbuffers'    );
+    glGenRenderbuffers        := gl_GetProc('glGenRenderbuffers'       );
+    glRenderbufferStorage     := gl_GetProc('glRenderbufferStorage'    );
+    glIsFramebuffer           := gl_GetProc('glIsFramebuffer'          );
+    glBindFramebuffer         := gl_GetProc('glBindFramebuffer'        );
+    glDeleteFramebuffers      := gl_GetProc('glDeleteFramebuffers'     );
+    glGenFramebuffers         := gl_GetProc('glGenFramebuffers'        );
+    glCheckFramebufferStatus  := gl_GetProc('glCheckFramebufferStatus' );
+    glFramebufferTexture2D    := gl_GetProc('glFramebufferTexture2D'   );
+    glFramebufferRenderbuffer := gl_GetProc('glFramebufferRenderbuffer');
+
+    glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, @oglMaxFBOSize);
+    log_Add('GL_MAX_RENDERBUFFER_SIZE: ' + u_IntToStr(oglMaxFBOSize));
+  end else
+    oglCanFBO := FALSE;
+   log_Add('GL_EXT_FRAMEBUFFER_OBJECT: ' + u_BoolToStr(oglCanFBO));
+
+{$IFDEF WINDOWS}
+  if Assigned(wglCreatePbufferARB) and Assigned(wglChoosePixelFormatARB) Then
+  begin
+    oglCanPBuffer          := TRUE;
+    wglGetPbufferDCARB     := gl_GetProc('wglGetPbufferDC'    );
+    wglReleasePbufferDCARB := gl_GetProc('wglReleasePbufferDC');
+    wglDestroyPbufferARB   := gl_GetProc('wglDestroyPbuffer'  );
+    wglQueryPbufferARB     := gl_GetProc('wglQueryPbuffer');
+  end else
+    oglCanPBuffer := FALSE;
+  log_Add('WGL_PBUFFER: ' + u_BoolToStr(oglCanPBuffer));
+{$ENDIF}
+{$IFDEF MACOSX}{$IfNDef MAC_COCOA}
+  oglCanPBuffer := Assigned(aglCreatePBuffer);
+  log_Add('AGL_PBUFFER: ' + u_BoolToStr(oglCanPBuffer));
+{$ENDIF}{$EndIf}
+
+  // WaitVSync
+{$IFDEF LINUX}
+  glXSwapIntervalSGI := gl_GetProc('glXSwapIntervalSGI');
+  oglCanVSync        := Assigned(glXSwapIntervalSGI);
+{$ENDIF}
+{$IFDEF WINDOWS}
+  wglSwapIntervalEXT := gl_GetProc('wglSwapInterval');
+  oglCanVSync     := Assigned(wglSwapIntervalEXT);
+{$ENDIF}
+{$IFDEF MACOSX}{$IfNDef MAC_COCOA}
+  if aglSetInt(oglContext, AGL_SWAP_INTERVAL, 1) = GL_TRUE Then
+    oglCanVSync := TRUE
+  else
+    oglCanVSync := FALSE;
+  aglSetInt(oglContext, AGL_SWAP_INTERVAL, Byte(scrVSync));
+{$ENDIF}{$EndIf}
+  if oglCanVSync Then
+    scr_VSync;
+  log_Add('Support WaitVSync: ' + u_BoolToStr(oglCanVSync));
+end;
+
+end.