unit uglcContext; { Package: OpenGLCore Prefix: glc - OpenGL Core Beschreibung: diese Unit enthält eine abstrakte Klassen-Kapselung für OpenGL Kontexte Abstrakte Contextklasse zum Erstellen von Renderkontexten auf Windows & Linux(bzw X11/Gtk2) Für aktuelle Plattform passende Klasse kann per GetPlatformClass gefunden werden. Bsp.: //muss im GUI/Main-Thread aufgerufen werden: pf := TglcContext.GetPlatformClass().MakePF(); fContext := TglcContext.GetPlatformClass().Create(MyTWinControl, PF); //_kann_ in Background Thread abgerufen werden: fContext.BuildContext(); [Arbeit mit dem Context] fContext.CloseContext(); //im MainThread FreeAndNil(fContext) weitere Funktionen: MakePF() erzeugt PixelFormatDescriptor mit Defaults BuildContext() baut Kontext (kann in BackgrounThread aufgerufen werden) CloseContext() gibt den Kontext frei (muss im selben Thread aufgerufen werden wie BuildContext; wird der Kontext nur im MainThread genutzt, muss CloseContext nicht explizit aufgerufen werden und wird beim zerstören des Kontext-Objekts ausgeführt) Activate/Deactiveate Kontext aktiv schalten oder nicht SwapBuffers DoubleBuffering SetSwapInterval VSync Share ShareLists EnableDebugOutput GL-Debug via ARB_debug_output oder AMD_debug_output de/aktivieren } interface uses SysUtils, Controls, dglOpenGL; const GLC_CONTEXT_VERSION_UNKNOWN = -1; type TMultiSample = 1..high(byte); TglcContextPixelFormatSettings = packed record DoubleBuffered: boolean; Stereo: boolean; MultiSampling: TMultiSample; ColorBits: Integer; DepthBits: Integer; StencilBits: Integer; AccumBits: Integer; AuxBuffers: Integer; Layer: Integer; end; TglcContextVersionSettings = packed record Major: Integer; Minor: Integer; ForwardCompatible: Boolean; end; TglcDisplayFlag = ( dfFullscreen); TglcDisplayFlags = set of TglcDisplayFlag; EGLError = class(Exception); { TglcContext } TglcContextClass = class of TglcContext; TglcContext = class private fControl: TWinControl; fThreadID: TThreadID; fEnableVsync: Boolean; function GetEnableVSync: Boolean; procedure SetEnableVSync(aValue: Boolean); protected fUseVersion: Boolean; fPixelFormatSettings: TglcContextPixelFormatSettings; fVersionSettings: TglcContextVersionSettings; procedure OpenContext; virtual; public property PixelFormatSettings: TglcContextPixelFormatSettings read fPixelFormatSettings; property VersionSettings: TglcContextVersionSettings read fVersionSettings; constructor Create(const aControl: TWinControl; const aPixelFormatSettings: TglcContextPixelFormatSettings); virtual; overload; constructor Create(const aControl: TWinControl; const aPixelFormatSettings: TglcContextPixelFormatSettings; const aVersionSettings: TglcContextVersionSettings); virtual; overload; destructor Destroy; override; property ThreadID: TThreadID read fThreadID; property EnableVSync: Boolean read GetEnableVSync write SetEnableVSync; procedure BuildContext; procedure CloseContext; virtual; procedure Activate; virtual; abstract; procedure Deactivate; virtual; abstract; function IsActive: boolean; virtual; abstract; procedure SwapBuffers; virtual; abstract; procedure SetSwapInterval(const aInterval: GLint); virtual; abstract; function GetSwapInterval: GLint; virtual; abstract; procedure Share(const aContext: TglcContext); virtual; abstract; private class var fMainContextThreadID: TThreadID; public class property MainContextThreadID: TThreadID read fMainContextThreadID; class function MakePF(DoubleBuffered: boolean = true; Stereo: boolean=false; MultiSampling: TMultiSample=1; ColorBits: Integer=32; DepthBits: Integer=24; StencilBits: Integer=0; AccumBits: Integer=0; AuxBuffers: Integer=0; Layer: Integer=0): TglcContextPixelFormatSettings; class function MakeVersion(const aMajor, aMinor: Integer; const aForwardCompatible: Boolean): TglcContextVersionSettings; class function GetPlatformClass: TglcContextClass; class function ChangeDisplaySettings(const aWidth, aHeight, aBitPerPixel, aFreq: Integer; const aFlags: TglcDisplayFlags): Boolean; virtual; abstract; class function IsAnyContextActive: boolean; virtual; end; implementation uses {$IFDEF WINDOWS} uglcContextWGL {$ENDIF} {$IFDEF LINUX} uglcContextGtk2GLX {$ENDIF} ; function TglcContext.GetEnableVSync: Boolean; begin result := fEnableVsync; end; procedure TglcContext.SetEnableVSync(aValue: Boolean); begin fEnableVsync := aValue; if IsActive then begin if fEnableVsync then SetSwapInterval(1) else SetSwapInterval(0); end; end; procedure TglcContext.OpenContext; begin fThreadID := GetCurrentThreadId; if fMainContextThreadID = 0 then fMainContextThreadID := fThreadID; end; class function TglcContext.MakePF(DoubleBuffered: boolean; Stereo: boolean; MultiSampling: TMultiSample; ColorBits: Integer; DepthBits: Integer; StencilBits: Integer; AccumBits: Integer; AuxBuffers: Integer; Layer: Integer): TglcContextPixelFormatSettings; begin Result.DoubleBuffered:= DoubleBuffered; Result.Stereo:= Stereo; Result.MultiSampling:= MultiSampling; Result.ColorBits:= ColorBits; Result.DepthBits:= DepthBits; Result.StencilBits:= StencilBits; Result.AccumBits:= AccumBits; Result.AuxBuffers:= AuxBuffers; Result.Layer:= Layer; end; class function TglcContext.MakeVersion(const aMajor, aMinor: Integer; const aForwardCompatible: Boolean): TglcContextVersionSettings; begin result.Major := aMajor; result.Minor := aMinor; result.ForwardCompatible := aForwardCompatible; end; class function TglcContext.GetPlatformClass: TglcContextClass; begin {$IFDEF WINDOWS} Result:= TglcContextWGL; {$ENDIF} {$IFDEF LINUX} Result:= TglcContextGtk2GLX; {$ENDIF} end; class function TglcContext.IsAnyContextActive: boolean; begin Result:= GetPlatformClass.IsAnyContextActive; end; constructor TglcContext.Create(const aControl: TWinControl; const aPixelFormatSettings: TglcContextPixelFormatSettings); begin inherited Create; fPixelFormatSettings := aPixelFormatSettings; FControl := aControl; fThreadID := 0; fEnableVsync := false; fUseVersion := false; InitOpenGL(); end; constructor TglcContext.Create(const aControl: TWinControl; const aPixelFormatSettings: TglcContextPixelFormatSettings; const aVersionSettings: TglcContextVersionSettings); begin Create(aControl, aPixelFormatSettings); fVersionSettings := aVersionSettings; fUseVersion := true; end; destructor TglcContext.Destroy; begin if (GetCurrentThreadId = fMainContextThreadID) then fMainContextThreadID := 0; CloseContext; inherited Destroy; end; procedure TglcContext.BuildContext; begin OpenContext; Activate; ReadImplementationProperties; ReadExtensions; SetEnableVSync(fEnableVsync); end; procedure TglcContext.CloseContext; begin if fMainContextThreadID = fThreadID then fMainContextThreadID := 0; end; initialization TglcContext.fMainContextThreadID := 0; end.