You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

245 line
7.3 KiB

  1. unit uglcContext;
  2. { Package: OpenGLCore
  3. Prefix: glc - OpenGL Core
  4. Beschreibung: diese Unit enthält eine abstrakte Klassen-Kapselung für OpenGL Kontexte
  5. Abstrakte Contextklasse zum Erstellen von Renderkontexten auf Windows & Linux(bzw X11/Gtk2)
  6. Für aktuelle Plattform passende Klasse kann per GetPlatformClass gefunden werden.
  7. Bsp.:
  8. //muss im GUI/Main-Thread aufgerufen werden:
  9. pf := TglcContext.GetPlatformClass().MakePF();
  10. fContext := TglcContext.GetPlatformClass().Create(MyTWinControl, PF);
  11. //_kann_ in Background Thread abgerufen werden:
  12. fContext.BuildContext();
  13. [Arbeit mit dem Context]
  14. fContext.CloseContext();
  15. //im MainThread
  16. FreeAndNil(fContext)
  17. weitere Funktionen:
  18. MakePF() erzeugt PixelFormatDescriptor mit Defaults
  19. BuildContext() baut Kontext (kann in BackgrounThread aufgerufen werden)
  20. CloseContext() gibt den Kontext frei (muss im selben Thread aufgerufen werden wie BuildContext;
  21. wird der Kontext nur im MainThread genutzt, muss CloseContext nicht explizit aufgerufen
  22. werden und wird beim zerstören des Kontext-Objekts ausgeführt)
  23. Activate/Deactiveate Kontext aktiv schalten oder nicht
  24. SwapBuffers DoubleBuffering
  25. SetSwapInterval VSync
  26. Share ShareLists
  27. EnableDebugOutput GL-Debug via ARB_debug_output oder AMD_debug_output de/aktivieren
  28. }
  29. interface
  30. uses
  31. SysUtils, Controls, dglOpenGL;
  32. const
  33. GLC_CONTEXT_VERSION_UNKNOWN = -1;
  34. type
  35. TMultiSample = 1..high(byte);
  36. TglcContextPixelFormatSettings = packed record
  37. DoubleBuffered: boolean;
  38. Stereo: boolean;
  39. MultiSampling: TMultiSample;
  40. ColorBits: Integer;
  41. DepthBits: Integer;
  42. StencilBits: Integer;
  43. AccumBits: Integer;
  44. AuxBuffers: Integer;
  45. Layer: Integer;
  46. end;
  47. TglcContextVersionSettings = packed record
  48. Major: Integer;
  49. Minor: Integer;
  50. ForwardCompatible: Boolean;
  51. end;
  52. TglcDisplayFlag = (
  53. dfFullscreen);
  54. TglcDisplayFlags = set of TglcDisplayFlag;
  55. EGLError = class(Exception);
  56. { TglcContext }
  57. TglcContextClass = class of TglcContext;
  58. TglcContext = class
  59. private
  60. fControl: TWinControl;
  61. fThreadID: TThreadID;
  62. fEnableVsync: Boolean;
  63. function GetEnableVSync: Boolean;
  64. procedure SetEnableVSync(aValue: Boolean);
  65. protected
  66. fUseVersion: Boolean;
  67. fPixelFormatSettings: TglcContextPixelFormatSettings;
  68. fVersionSettings: TglcContextVersionSettings;
  69. procedure OpenContext; virtual;
  70. public
  71. property PixelFormatSettings: TglcContextPixelFormatSettings read fPixelFormatSettings;
  72. property VersionSettings: TglcContextVersionSettings read fVersionSettings;
  73. constructor Create(const aControl: TWinControl; const aPixelFormatSettings: TglcContextPixelFormatSettings); virtual; overload;
  74. constructor Create(const aControl: TWinControl; const aPixelFormatSettings: TglcContextPixelFormatSettings; const aVersionSettings: TglcContextVersionSettings); virtual; overload;
  75. destructor Destroy; override;
  76. property ThreadID: TThreadID read fThreadID;
  77. property EnableVSync: Boolean read GetEnableVSync write SetEnableVSync;
  78. procedure BuildContext;
  79. procedure CloseContext; virtual;
  80. procedure Activate; virtual; abstract;
  81. procedure Deactivate; virtual; abstract;
  82. function IsActive: boolean; virtual; abstract;
  83. procedure SwapBuffers; virtual; abstract;
  84. procedure SetSwapInterval(const aInterval: GLint); virtual; abstract;
  85. function GetSwapInterval: GLint; virtual; abstract;
  86. procedure Share(const aContext: TglcContext); virtual; abstract;
  87. private class var
  88. fMainContextThreadID: TThreadID;
  89. public
  90. class property MainContextThreadID: TThreadID read fMainContextThreadID;
  91. class function MakePF(DoubleBuffered: boolean = true;
  92. Stereo: boolean=false;
  93. MultiSampling: TMultiSample=1;
  94. ColorBits: Integer=32;
  95. DepthBits: Integer=24;
  96. StencilBits: Integer=0;
  97. AccumBits: Integer=0;
  98. AuxBuffers: Integer=0;
  99. Layer: Integer=0): TglcContextPixelFormatSettings;
  100. class function MakeVersion(const aMajor, aMinor: Integer; const aForwardCompatible: Boolean): TglcContextVersionSettings;
  101. class function GetPlatformClass: TglcContextClass;
  102. class function ChangeDisplaySettings(const aWidth, aHeight,
  103. aBitPerPixel, aFreq: Integer; const aFlags: TglcDisplayFlags): Boolean; virtual; abstract;
  104. class function IsAnyContextActive: boolean; virtual;
  105. end;
  106. implementation
  107. uses
  108. {$IFDEF WINDOWS}
  109. uglcContextWGL
  110. {$ENDIF}
  111. {$IFDEF LINUX}
  112. uglcContextGtk2GLX
  113. {$ENDIF}
  114. ;
  115. function TglcContext.GetEnableVSync: Boolean;
  116. begin
  117. result := fEnableVsync;
  118. end;
  119. procedure TglcContext.SetEnableVSync(aValue: Boolean);
  120. begin
  121. fEnableVsync := aValue;
  122. if IsActive then begin
  123. if fEnableVsync then
  124. SetSwapInterval(1)
  125. else
  126. SetSwapInterval(0);
  127. end;
  128. end;
  129. procedure TglcContext.OpenContext;
  130. begin
  131. fThreadID := GetCurrentThreadId;
  132. if fMainContextThreadID = 0 then
  133. fMainContextThreadID := fThreadID;
  134. end;
  135. class function TglcContext.MakePF(DoubleBuffered: boolean; Stereo: boolean; MultiSampling: TMultiSample; ColorBits: Integer;
  136. DepthBits: Integer; StencilBits: Integer; AccumBits: Integer; AuxBuffers: Integer; Layer: Integer): TglcContextPixelFormatSettings;
  137. begin
  138. Result.DoubleBuffered:= DoubleBuffered;
  139. Result.Stereo:= Stereo;
  140. Result.MultiSampling:= MultiSampling;
  141. Result.ColorBits:= ColorBits;
  142. Result.DepthBits:= DepthBits;
  143. Result.StencilBits:= StencilBits;
  144. Result.AccumBits:= AccumBits;
  145. Result.AuxBuffers:= AuxBuffers;
  146. Result.Layer:= Layer;
  147. end;
  148. class function TglcContext.MakeVersion(const aMajor, aMinor: Integer; const aForwardCompatible: Boolean): TglcContextVersionSettings;
  149. begin
  150. result.Major := aMajor;
  151. result.Minor := aMinor;
  152. result.ForwardCompatible := aForwardCompatible;
  153. end;
  154. class function TglcContext.GetPlatformClass: TglcContextClass;
  155. begin
  156. {$IFDEF WINDOWS}
  157. Result:= TglcContextWGL;
  158. {$ENDIF}
  159. {$IFDEF LINUX}
  160. Result:= TglcContextGtk2GLX;
  161. {$ENDIF}
  162. end;
  163. class function TglcContext.IsAnyContextActive: boolean;
  164. begin
  165. Result:= GetPlatformClass.IsAnyContextActive;
  166. end;
  167. constructor TglcContext.Create(const aControl: TWinControl; const aPixelFormatSettings: TglcContextPixelFormatSettings);
  168. begin
  169. inherited Create;
  170. fPixelFormatSettings := aPixelFormatSettings;
  171. FControl := aControl;
  172. fThreadID := 0;
  173. fEnableVsync := false;
  174. fUseVersion := false;
  175. InitOpenGL();
  176. end;
  177. constructor TglcContext.Create(const aControl: TWinControl; const aPixelFormatSettings: TglcContextPixelFormatSettings; const aVersionSettings: TglcContextVersionSettings);
  178. begin
  179. Create(aControl, aPixelFormatSettings);
  180. fVersionSettings := aVersionSettings;
  181. fUseVersion := true;
  182. end;
  183. destructor TglcContext.Destroy;
  184. begin
  185. if (GetCurrentThreadId = fMainContextThreadID) then
  186. fMainContextThreadID := 0;
  187. CloseContext;
  188. inherited Destroy;
  189. end;
  190. procedure TglcContext.BuildContext;
  191. begin
  192. OpenContext;
  193. Activate;
  194. ReadImplementationProperties;
  195. ReadExtensions;
  196. SetEnableVSync(fEnableVsync);
  197. end;
  198. procedure TglcContext.CloseContext;
  199. begin
  200. if fMainContextThreadID = fThreadID then
  201. fMainContextThreadID := 0;
  202. end;
  203. initialization
  204. TglcContext.fMainContextThreadID := 0;
  205. end.