|
@@ -1,836 +0,0 @@
|
|
|
-{
|
|
|
- * 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.
|
|
|
-
|