123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836 |
- {
- * 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.
|