GLWindowsContext.pas 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222
  1. //
  2. // This unit is part of the GLScene Engine, http://glscene.org
  3. //
  4. unit GLWindowsContext;
  5. (* Windows specific Context *)
  6. interface
  7. {$I GLScene.inc}
  8. uses
  9. Winapi.OpenGL,
  10. Winapi.OpenGLext,
  11. Winapi.Windows,
  12. Winapi.Messages,
  13. System.SysUtils,
  14. System.Classes,
  15. Vcl.Forms,
  16. OpenGLTokens,
  17. OpenGLAdapter,
  18. GLPipelineTransformation,
  19. GLContext,
  20. GLState,
  21. GLS.Logger,
  22. GLS.Strings,
  23. GLVectorGeometry;
  24. type
  25. // A context driver for standard Windows OpenGL (via MS OpenGL).
  26. TGLWindowsContext = class(TGLContext)
  27. protected
  28. FDC: NativeUInt;
  29. FRC: NativeUInt;
  30. FShareContext: TGLWindowsContext;
  31. FHPBUFFER: Integer;
  32. FiAttribs: packed array of Integer;
  33. FfAttribs: packed array of Single;
  34. FLegacyContextsOnly: Boolean;
  35. FSwapBufferSupported: Boolean;
  36. procedure SpawnLegacyContext(aDC: HDC); // used for WGL_pixel_format soup
  37. procedure CreateOldContext(aDC: HDC); virtual;
  38. procedure CreateNewContext(aDC: HDC); virtual;
  39. procedure ClearIAttribs;
  40. procedure AddIAttrib(attrib, value: Integer);
  41. procedure ChangeIAttrib(attrib, newValue: Integer);
  42. procedure DropIAttrib(attrib: Integer);
  43. procedure ClearFAttribs;
  44. procedure AddFAttrib(attrib, value: Single);
  45. procedure DestructionEarlyWarning(sender: TObject);
  46. procedure ChooseWGLFormat(DC: HDC; nMaxFormats: Cardinal; piFormats: PInteger; var nNumFormats: Integer;
  47. BufferCount: Integer = 1);
  48. procedure DoCreateContext(ADeviceHandle: HDC); override;
  49. procedure DoCreateMemoryContext(outputDevice: HWND; width, height: Integer; BufferCount: Integer); override;
  50. function DoShareLists(aContext: TGLContext): Boolean; override;
  51. procedure DoDestroyContext; override;
  52. procedure DoActivate; override;
  53. procedure DoDeactivate; override;
  54. // DoGetHandles must be implemented in child classes, and return the display+window
  55. public
  56. constructor Create; override;
  57. destructor Destroy; override;
  58. function IsValid: Boolean; override;
  59. procedure SwapBuffers; override;
  60. function RenderOutputDevice: Pointer; override;
  61. property DC: NativeUInt read FDC;
  62. property RC: NativeUInt read FRC;
  63. end;
  64. function CreateTempWnd: NativeUInt;
  65. var
  66. (* This boolean controls a hook-based tracking of top-level forms destruction,
  67. with the purpose of being able to properly release OpenGL contexts before
  68. they are (improperly) released by some drivers upon top-level form
  69. destruction *)
  70. vUseWindowTrackingHook: Boolean = True;
  71. // ------------------------------------------------------------------
  72. implementation
  73. // ------------------------------------------------------------------
  74. var
  75. vTrackingCount: Integer;
  76. vTrackedHwnd: array of NativeUInt;
  77. vTrackedEvents: array of TNotifyEvent;
  78. vTrackingHook: HHOOK;
  79. function TrackHookProc(nCode: Integer; wParam: wParam; lParam: lParam): Integer; stdcall;
  80. var
  81. i: Integer;
  82. p: PCWPStruct;
  83. begin
  84. if nCode = HC_ACTION then
  85. begin
  86. p := PCWPStruct(lParam);
  87. // if (p.message=WM_DESTROY) or (p.message=WM_CLOSE) then begin
  88. if p.message = WM_DESTROY then
  89. begin
  90. // special care must be taken by this loop, items may go away unexpectedly
  91. i := vTrackingCount - 1;
  92. while (i >= 0) and (length(vTrackedHwnd) >= (i+1)) do // earlier was while i >= 0 do
  93. begin
  94. if IsChild(p.HWND, vTrackedHwnd[i]) then
  95. begin
  96. // got one, send notification
  97. vTrackedEvents[i](nil);
  98. end;
  99. Dec(i);
  100. while i >= vTrackingCount do
  101. Dec(i);
  102. end;
  103. end;
  104. CallNextHookEx(vTrackingHook, nCode, wParam, lParam);
  105. Result := 0;
  106. end
  107. else
  108. Result := CallNextHookEx(vTrackingHook, nCode, wParam, lParam);
  109. end;
  110. procedure TrackWindow(h: HWND; notifyEvent: TNotifyEvent); inline;
  111. begin
  112. if not IsWindow(h) then
  113. Exit;
  114. if vTrackingCount = 0 then
  115. vTrackingHook := SetWindowsHookEx(WH_CALLWNDPROC, @TrackHookProc, 0, GetCurrentThreadID);
  116. Inc(vTrackingCount);
  117. SetLength(vTrackedHwnd, vTrackingCount);
  118. vTrackedHwnd[vTrackingCount - 1] := h;
  119. SetLength(vTrackedEvents, vTrackingCount);
  120. vTrackedEvents[vTrackingCount - 1] := notifyEvent;
  121. end;
  122. procedure UnTrackWindow(h: HWND);
  123. var
  124. i, k: Integer;
  125. begin
  126. if not IsWindow(h) then
  127. Exit;
  128. if vTrackingCount = 0 then
  129. Exit;
  130. k := 0;
  131. for i := 0 to MinInteger(vTrackingCount, Length(vTrackedHwnd)) - 1 do
  132. begin
  133. if vTrackedHwnd[i] <> h then
  134. begin
  135. if (k <> i) then
  136. begin
  137. vTrackedHwnd[k] := vTrackedHwnd[i];
  138. vTrackedEvents[k] := vTrackedEvents[i];
  139. end;
  140. Inc(k);
  141. end
  142. end;
  143. if (k >= vTrackingCount) then
  144. Exit;
  145. Dec(vTrackingCount);
  146. SetLength(vTrackedHwnd, vTrackingCount);
  147. SetLength(vTrackedEvents, vTrackingCount);
  148. if vTrackingCount = 0 then
  149. UnhookWindowsHookEx(vTrackingHook);
  150. end;
  151. var
  152. vUtilWindowClass: TWndClass = (style: 0;
  153. lpfnWndProc: @DefWindowProc;
  154. cbClsExtra: 0;
  155. cbWndExtra: 0;
  156. hInstance: 0;
  157. hIcon: 0;
  158. hCursor: 0;
  159. hbrBackground: 0;
  160. lpszMenuName: nil;
  161. lpszClassName: 'GLSUtilWindow');
  162. function CreateTempWnd: NativeUInt;
  163. var
  164. classRegistered: Boolean;
  165. tempClass: TWndClass;
  166. begin
  167. vUtilWindowClass.hInstance := hInstance;
  168. classRegistered := GetClassInfo(hInstance, vUtilWindowClass.lpszClassName, tempClass);
  169. if not classRegistered then
  170. Winapi.Windows.RegisterClass(vUtilWindowClass);
  171. Result := CreateWindowEx(WS_EX_TOOLWINDOW, vUtilWindowClass.lpszClassName,
  172. '', WS_POPUP, 0, 0, 0, 0, 0, 0, hInstance, nil);
  173. end;
  174. // ------------------
  175. // ------------------ TGLWindowsContext ------------------
  176. // ------------------
  177. constructor TGLWindowsContext.Create;
  178. begin
  179. inherited Create;
  180. ClearIAttribs;
  181. ClearFAttribs;
  182. end;
  183. destructor TGLWindowsContext.Destroy;
  184. begin
  185. inherited Destroy;
  186. end;
  187. function SetupPalette(DC: HDC; const PFD: TPixelFormatDescriptor): HPalette;
  188. var
  189. nColors, i: Integer;
  190. LogPalette: TMaxLogPalette;
  191. RedMask, GreenMask, BlueMask: Byte;
  192. begin
  193. nColors := 1 shl PFD.cColorBits;
  194. LogPalette.palVersion := $300;
  195. LogPalette.palNumEntries := nColors;
  196. RedMask := (1 shl PFD.cRedBits) - 1;
  197. GreenMask := (1 shl PFD.cGreenBits) - 1;
  198. BlueMask := (1 shl PFD.cBlueBits) - 1;
  199. with LogPalette, PFD do
  200. for i := 0 to nColors - 1 do
  201. begin
  202. palPalEntry[i].peRed := (((i shr cRedShift) and RedMask) * 255) div RedMask;
  203. palPalEntry[i].peGreen := (((i shr cGreenShift) and GreenMask) * 255) div GreenMask;
  204. palPalEntry[i].peBlue := (((i shr cBlueShift) and BlueMask) * 255) div BlueMask;
  205. palPalEntry[i].peFlags := 0;
  206. end;
  207. Result := CreatePalette(PLogPalette(@LogPalette)^);
  208. if Result <> 0 then
  209. begin
  210. SelectPalette(DC, Result, False);
  211. RealizePalette(DC);
  212. end
  213. else
  214. RaiseLastOSError;
  215. end;
  216. procedure TGLWindowsContext.ClearIAttribs;
  217. begin
  218. SetLength(FiAttribs, 1);
  219. FiAttribs[0] := 0;
  220. end;
  221. procedure TGLWindowsContext.AddIAttrib(attrib, value: Integer);
  222. var
  223. n: Integer;
  224. begin
  225. n := Length(FiAttribs);
  226. SetLength(FiAttribs, n + 2);
  227. FiAttribs[n - 1] := attrib;
  228. FiAttribs[n] := value;
  229. FiAttribs[n + 1] := 0;
  230. end;
  231. procedure TGLWindowsContext.ChangeIAttrib(attrib, newValue: Integer);
  232. var
  233. i: Integer;
  234. begin
  235. i := 0;
  236. while i < Length(FiAttribs) do
  237. begin
  238. if FiAttribs[i] = attrib then
  239. begin
  240. FiAttribs[i + 1] := newValue;
  241. Exit;
  242. end;
  243. Inc(i, 2);
  244. end;
  245. AddIAttrib(attrib, newValue);
  246. end;
  247. procedure TGLWindowsContext.DropIAttrib(attrib: Integer);
  248. var
  249. i: Integer;
  250. begin
  251. i := 0;
  252. while i < Length(FiAttribs) do
  253. begin
  254. if FiAttribs[i] = attrib then
  255. begin
  256. Inc(i, 2);
  257. while i < Length(FiAttribs) do
  258. begin
  259. FiAttribs[i - 2] := FiAttribs[i];
  260. Inc(i);
  261. end;
  262. SetLength(FiAttribs, Length(FiAttribs) - 2);
  263. Exit;
  264. end;
  265. Inc(i, 2);
  266. end;
  267. end;
  268. procedure TGLWindowsContext.ClearFAttribs;
  269. begin
  270. SetLength(FfAttribs, 1);
  271. FfAttribs[0] := 0;
  272. end;
  273. procedure TGLWindowsContext.AddFAttrib(attrib, value: Single);
  274. var
  275. n: Integer;
  276. begin
  277. n := Length(FfAttribs);
  278. SetLength(FfAttribs, n + 2);
  279. FfAttribs[n - 1] := attrib;
  280. FfAttribs[n] := value;
  281. FfAttribs[n + 1] := 0;
  282. end;
  283. procedure TGLWindowsContext.DestructionEarlyWarning(sender: TObject);
  284. begin
  285. if IsValid then
  286. DestroyContext;
  287. end;
  288. procedure TGLWindowsContext.ChooseWGLFormat(DC: HDC; nMaxFormats: Cardinal; piFormats: PInteger; var nNumFormats: Integer;
  289. BufferCount: Integer);
  290. const
  291. cAAToSamples: array [aaNone .. csa16xHQ] of Integer = (1, 2, 2, 4, 4, 6, 8, 16, 8, 8, 16, 16);
  292. cCSAAToSamples: array [csa8x .. csa16xHQ] of Integer = (4, 8, 4, 8);
  293. procedure ChoosePixelFormat;
  294. begin
  295. if not FGL.WChoosePixelFormatARB(DC, @FiAttribs[0], @FfAttribs[0],
  296. 32, PGLint(piFormats), @nNumFormats) then
  297. nNumFormats := 0;
  298. end;
  299. var
  300. float: Boolean;
  301. aa: TGLAntiAliasing;
  302. begin
  303. // request hardware acceleration
  304. case FAcceleration of
  305. chaUnknown:
  306. AddIAttrib(WGL_ACCELERATION_ARB, WGL_GENERIC_ACCELERATION_ARB);
  307. chaHardware:
  308. AddIAttrib(WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB);
  309. chaSoftware:
  310. AddIAttrib(WGL_ACCELERATION_ARB, WGL_NO_ACCELERATION_ARB);
  311. end;
  312. float := (ColorBits = 64) or (ColorBits = 128); // float_type
  313. if float then
  314. begin // float_type
  315. if gl.W_ATI_pixel_format_float then
  316. begin // NV40 uses ATI_float, with linear filtering
  317. AddIAttrib(WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_FLOAT_ATI);
  318. end
  319. else
  320. begin
  321. AddIAttrib(WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB);
  322. AddIAttrib(WGL_FLOAT_COMPONENTS_NV, GL_TRUE);
  323. end;
  324. end;
  325. if BufferCount > 1 then
  326. // 1 front buffer + (BufferCount-1) aux buffers
  327. AddIAttrib(WGL_AUX_BUFFERS_ARB, BufferCount - 1);
  328. AddIAttrib(WGL_COLOR_BITS_ARB, ColorBits);
  329. if AlphaBits > 0 then
  330. AddIAttrib(WGL_ALPHA_BITS_ARB, AlphaBits);
  331. AddIAttrib(WGL_DEPTH_BITS_ARB, DepthBits);
  332. if StencilBits > 0 then
  333. AddIAttrib(WGL_STENCIL_BITS_ARB, StencilBits);
  334. if AccumBits > 0 then
  335. AddIAttrib(WGL_ACCUM_BITS_ARB, AccumBits);
  336. if AuxBuffers > 0 then
  337. AddIAttrib(WGL_AUX_BUFFERS_ARB, AuxBuffers);
  338. if (AntiAliasing <> aaDefault) and FGL.W_ARB_multisample then
  339. begin
  340. if AntiAliasing = aaNone then
  341. AddIAttrib(WGL_SAMPLE_BUFFERS_ARB, GL_FALSE)
  342. else
  343. begin
  344. AddIAttrib(WGL_SAMPLE_BUFFERS_ARB, GL_TRUE);
  345. AddIAttrib(WGL_SAMPLES_ARB, cAAToSamples[AntiAliasing]);
  346. if (AntiAliasing >= csa8x) and (AntiAliasing <= csa16xHQ) then
  347. AddIAttrib(WGL_COLOR_SAMPLES_NV, cCSAAToSamples[AntiAliasing]);
  348. end;
  349. end;
  350. ClearFAttribs;
  351. ChoosePixelFormat;
  352. if (nNumFormats = 0) and (DepthBits >= 32) then
  353. begin
  354. // couldn't find 32+ bits depth buffer, 24 bits one available?
  355. ChangeIAttrib(WGL_DEPTH_BITS_ARB, 24);
  356. ChoosePixelFormat;
  357. end;
  358. if (nNumFormats = 0) and (DepthBits >= 24) then
  359. begin
  360. // couldn't find 24+ bits depth buffer, 16 bits one available?
  361. ChangeIAttrib(WGL_DEPTH_BITS_ARB, 16);
  362. ChoosePixelFormat;
  363. end;
  364. if (nNumFormats = 0) and (ColorBits >= 24) then
  365. begin
  366. // couldn't find 24+ bits color buffer, 16 bits one available?
  367. ChangeIAttrib(WGL_COLOR_BITS_ARB, 16);
  368. ChoosePixelFormat;
  369. end;
  370. if (nNumFormats = 0) and (AntiAliasing <> aaDefault) then
  371. begin
  372. // Restore DepthBits
  373. ChangeIAttrib(WGL_DEPTH_BITS_ARB, DepthBits);
  374. if (AntiAliasing >= csa8x) and (AntiAliasing <= csa16xHQ) then
  375. begin
  376. DropIAttrib(WGL_COLOR_SAMPLES_NV);
  377. case AntiAliasing of
  378. csa8x, csa8xHQ:
  379. AntiAliasing := aa8x;
  380. csa16x, csa16xHQ:
  381. AntiAliasing := aa16x;
  382. end;
  383. ChangeIAttrib(WGL_SAMPLES_ARB, cAAToSamples[AntiAliasing]);
  384. end;
  385. ChoosePixelFormat;
  386. if nNumFormats = 0 then
  387. begin
  388. aa := AntiAliasing;
  389. repeat
  390. Dec(aa);
  391. if aa = aaNone then
  392. begin
  393. // couldn't find AA buffer, try without
  394. DropIAttrib(WGL_SAMPLE_BUFFERS_ARB);
  395. DropIAttrib(WGL_SAMPLES_ARB);
  396. ChoosePixelFormat;
  397. break;
  398. end;
  399. ChangeIAttrib(WGL_SAMPLES_ARB, cAAToSamples[aa]);
  400. ChoosePixelFormat;
  401. until nNumFormats <> 0;
  402. AntiAliasing := aa;
  403. end;
  404. end;
  405. // Check DepthBits again
  406. if (nNumFormats = 0) and (DepthBits >= 32) then
  407. begin
  408. // couldn't find 32+ bits depth buffer, 24 bits one available?
  409. ChangeIAttrib(WGL_DEPTH_BITS_ARB, 24);
  410. ChoosePixelFormat;
  411. end;
  412. if (nNumFormats = 0) and (DepthBits >= 24) then
  413. begin
  414. // couldn't find 24+ bits depth buffer, 16 bits one available?
  415. ChangeIAttrib(WGL_DEPTH_BITS_ARB, 16);
  416. ChoosePixelFormat;
  417. end;
  418. if (nNumFormats = 0) and (ColorBits >= 24) then
  419. begin
  420. // couldn't find 24+ bits color buffer, 16 bits one available?
  421. ChangeIAttrib(WGL_COLOR_BITS_ARB, 16);
  422. ChoosePixelFormat;
  423. end;
  424. if nNumFormats = 0 then
  425. begin
  426. // ok, last attempt: no AA, restored depth and color,
  427. // relaxed hardware-acceleration request
  428. ChangeIAttrib(WGL_COLOR_BITS_ARB, ColorBits);
  429. ChangeIAttrib(WGL_DEPTH_BITS_ARB, DepthBits);
  430. DropIAttrib(WGL_ACCELERATION_ARB);
  431. ChoosePixelFormat;
  432. end;
  433. end;
  434. procedure TGLWindowsContext.CreateOldContext(aDC: HDC);
  435. begin
  436. if not FLegacyContextsOnly then
  437. begin
  438. case Layer of
  439. clUnderlay2: FRC := wglCreateLayerContext(aDC, -2);
  440. clUnderlay1: FRC := wglCreateLayerContext(aDC, -1);
  441. clMainPlane: FRC := wglCreateContext(aDC);
  442. clOverlay1: FRC := wglCreateLayerContext(aDC, 1);
  443. clOverlay2: FRC := wglCreateLayerContext(aDC, 2);
  444. end;
  445. end
  446. else
  447. FRC := wglCreateContext(aDC);
  448. if FRC = 0 then
  449. RaiseLastOSError;
  450. FDC := aDC;
  451. if not wglMakeCurrent(FDC, FRC) then
  452. raise EGLContext.Create(Format(strContextActivationFailed, [GetLastError, SysErrorMessage(GetLastError)]));
  453. if not FLegacyContextsOnly then
  454. begin
  455. if Assigned(FShareContext) and (FShareContext.RC <> 0) then
  456. begin
  457. if not wglShareLists(FShareContext.RC, FRC) then
  458. {$IFDEF USE_LOGGING}
  459. LogWarning(strFailedToShare)
  460. {$ENDIF}
  461. else
  462. begin
  463. FSharedContexts.Add(FShareContext);
  464. PropagateSharedContext;
  465. end;
  466. end;
  467. FGL.DebugMode := False;
  468. FGL.Initialize;
  469. MakeGLCurrent;
  470. // If we are using AntiAliasing, adjust filtering hints
  471. if AntiAliasing in [aa2xHQ, aa4xHQ, csa8xHQ, csa16xHQ] then
  472. // Hint for nVidia HQ modes (Quincunx etc.)
  473. GLStates.MultisampleFilterHint := hintNicest
  474. else
  475. GLStates.MultisampleFilterHint := hintDontCare;
  476. if rcoDebug in Options then
  477. GLSLogger.LogWarning(strDriverNotSupportDebugRC);
  478. if rcoOGL_ES in Options then
  479. GLSLogger.LogWarning(strDriverNotSupportOESRC);
  480. (* if ForwardContext then
  481. LogWarning(strDriverNotSupportFRC);
  482. ForwardContext := False; *)
  483. end
  484. else
  485. GLSLogger.LogInfo(strTmpRC_Created);
  486. end;
  487. procedure TGLWindowsContext.CreateNewContext(aDC: HDC);
  488. var
  489. bSuccess, bOES: Boolean;
  490. begin
  491. bSuccess := False;
  492. bOES := False;
  493. try
  494. ClearIAttribs;
  495. // Initialize forward context
  496. if False (* GLStates.ForwardContext *) then
  497. begin
  498. if FGL.VERSION_4_2 then
  499. begin
  500. AddIAttrib(WGL_CONTEXT_MAJOR_VERSION_ARB, 4);
  501. AddIAttrib(WGL_CONTEXT_MINOR_VERSION_ARB, 2);
  502. end
  503. else if FGL.VERSION_4_1 then
  504. begin
  505. AddIAttrib(WGL_CONTEXT_MAJOR_VERSION_ARB, 4);
  506. AddIAttrib(WGL_CONTEXT_MINOR_VERSION_ARB, 1);
  507. end
  508. else if FGL.VERSION_4_0 then
  509. begin
  510. AddIAttrib(WGL_CONTEXT_MAJOR_VERSION_ARB, 4);
  511. AddIAttrib(WGL_CONTEXT_MINOR_VERSION_ARB, 0);
  512. end
  513. else if FGL.VERSION_3_3 then
  514. begin
  515. AddIAttrib(WGL_CONTEXT_MAJOR_VERSION_ARB, 3);
  516. AddIAttrib(WGL_CONTEXT_MINOR_VERSION_ARB, 3);
  517. end
  518. else if FGL.VERSION_3_2 then
  519. begin
  520. AddIAttrib(WGL_CONTEXT_MAJOR_VERSION_ARB, 3);
  521. AddIAttrib(WGL_CONTEXT_MINOR_VERSION_ARB, 2);
  522. end
  523. else if FGL.VERSION_3_1 then
  524. begin
  525. AddIAttrib(WGL_CONTEXT_MAJOR_VERSION_ARB, 3);
  526. AddIAttrib(WGL_CONTEXT_MINOR_VERSION_ARB, 1);
  527. end
  528. else if FGL.VERSION_3_0 then
  529. begin
  530. AddIAttrib(WGL_CONTEXT_MAJOR_VERSION_ARB, 3);
  531. AddIAttrib(WGL_CONTEXT_MINOR_VERSION_ARB, 0);
  532. end
  533. else
  534. Abort;
  535. AddIAttrib(WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB);
  536. if rcoOGL_ES in Options then
  537. GLSLogger.LogWarning(strOESvsForwardRC);
  538. end
  539. else if rcoOGL_ES in Options then
  540. begin
  541. if FGL.W_EXT_create_context_es2_profile then
  542. begin
  543. AddIAttrib(WGL_CONTEXT_MAJOR_VERSION_ARB, 2);
  544. AddIAttrib(WGL_CONTEXT_MINOR_VERSION_ARB, 0);
  545. AddIAttrib(WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_ES2_PROFILE_BIT_EXT);
  546. bOES := True;
  547. end
  548. else
  549. GLSLogger.LogError(strDriverNotSupportOESRC);
  550. end;
  551. if rcoDebug in Options then
  552. begin
  553. AddIAttrib(WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_DEBUG_BIT_ARB);
  554. FGL.DebugMode := True;
  555. end;
  556. case Layer of
  557. clUnderlay2: AddIAttrib(WGL_CONTEXT_LAYER_PLANE_ARB, -2);
  558. clUnderlay1: AddIAttrib(WGL_CONTEXT_LAYER_PLANE_ARB, -1);
  559. clOverlay1: AddIAttrib(WGL_CONTEXT_LAYER_PLANE_ARB, 1);
  560. clOverlay2: AddIAttrib(WGL_CONTEXT_LAYER_PLANE_ARB, 2);
  561. end;
  562. FRC := 0;
  563. if Assigned(FShareContext) then
  564. begin
  565. FRC := FGL.WCreateContextAttribsARB(aDC, FShareContext.RC, @FiAttribs[0]);
  566. if FRC <> 0 then
  567. begin
  568. FSharedContexts.Add(FShareContext);
  569. PropagateSharedContext;
  570. end
  571. else
  572. GLSLogger.LogWarning(strFailedToShare)
  573. end;
  574. if FRC = 0 then
  575. begin
  576. FRC := FGL.WCreateContextAttribsARB(aDC, 0, @FiAttribs[0]);
  577. if FRC = 0 then
  578. begin
  579. if False (* GLStates.ForwardContext *) then
  580. GLSLogger.LogErrorFmt(strForwardContextFailed, [GetLastError, SysErrorMessage(GetLastError)])
  581. else
  582. GLSLogger.LogErrorFmt(strBackwardContextFailed, [GetLastError, SysErrorMessage(GetLastError)]);
  583. Abort;
  584. end;
  585. end;
  586. FDC := aDC;
  587. if not wglMakeCurrent(FDC, FRC) then
  588. begin
  589. GLSLogger.LogErrorFmt(strContextActivationFailed, [GetLastError, SysErrorMessage(GetLastError)]);
  590. Abort;
  591. end;
  592. FGL.Initialize;
  593. MakeGLCurrent;
  594. // If we are using AntiAliasing, adjust filtering hints
  595. if AntiAliasing in [aa2xHQ, aa4xHQ, csa8xHQ, csa16xHQ] then
  596. // Hint for nVidia HQ modes (Quincunx etc.)
  597. GLStates.MultisampleFilterHint := hintNicest
  598. else
  599. GLStates.MultisampleFilterHint := hintDontCare;
  600. (* if GLStates.ForwardContext then
  601. GLSLogger.LogInfo(strFRC_created); *)
  602. if bOES then
  603. GLSLogger.LogInfo(strOESRC_created);
  604. bSuccess := True;
  605. finally
  606. /// GLStates.ForwardContext := GLStates.ForwardContext and bSuccess;
  607. PipelineTransformation.LoadMatricesEnabled := True { not GLStates.ForwardContext };
  608. end;
  609. end;
  610. procedure TGLWindowsContext.DoCreateContext(ADeviceHandle: HDC);
  611. const
  612. cMemoryDCs = [OBJ_MEMDC, OBJ_METADC, OBJ_ENHMETADC];
  613. cBoolToInt: array [False .. True] of Integer = (GL_FALSE, GL_TRUE);
  614. cLayerToSet: array [TGLContextLayer] of Byte = (32, 16, 0, 1, 2);
  615. var
  616. pfDescriptor: TPixelFormatDescriptor;
  617. pixelFormat, nbFormats, softwarePixelFormat: Integer;
  618. aType: DWORD;
  619. iFormats: array [0 .. 31] of Integer;
  620. tempWnd: HWND;
  621. tempDC: HDC;
  622. localDC: HDC;
  623. localRC: HGLRC;
  624. sharedRC: TGLWindowsContext;
  625. function CurrentPixelFormatIsHardwareAccelerated: Boolean;
  626. var
  627. localPFD: TPixelFormatDescriptor;
  628. begin
  629. Result := False;
  630. if pixelFormat = 0 then
  631. Exit;
  632. with localPFD do
  633. begin
  634. nSize := SizeOf(localPFD);
  635. nVersion := 1;
  636. end;
  637. DescribePixelFormat(ADeviceHandle, pixelFormat, SizeOf(localPFD), localPFD);
  638. Result := ((localPFD.dwFlags and PFD_GENERIC_FORMAT) = 0);
  639. end;
  640. var
  641. i, iAttrib, iValue: Integer;
  642. begin
  643. if vUseWindowTrackingHook and not FLegacyContextsOnly then
  644. TrackWindow(WindowFromDC(ADeviceHandle), DestructionEarlyWarning);
  645. // Just in case it didn't happen already.
  646. if not InitOpenGL then
  647. RaiseLastOSError;
  648. // Prepare PFD
  649. FillChar(pfDescriptor, SizeOf(pfDescriptor), 0);
  650. with pfDescriptor do
  651. begin
  652. nSize := SizeOf(pfDescriptor);
  653. nVersion := 1;
  654. dwFlags := PFD_SUPPORT_OPENGL;
  655. aType := GetObjectType(ADeviceHandle);
  656. if aType = 0 then
  657. RaiseLastOSError;
  658. if aType in cMemoryDCs then
  659. dwFlags := dwFlags or PFD_DRAW_TO_BITMAP
  660. else
  661. dwFlags := dwFlags or PFD_DRAW_TO_WINDOW;
  662. if rcoDoubleBuffered in Options then
  663. dwFlags := dwFlags or PFD_DOUBLEBUFFER;
  664. if rcoStereo in Options then
  665. dwFlags := dwFlags or PFD_STEREO;
  666. iPixelType := PFD_TYPE_RGBA;
  667. cColorBits := ColorBits;
  668. cDepthBits := DepthBits;
  669. cStencilBits := StencilBits;
  670. cAccumBits := AccumBits;
  671. cAlphaBits := AlphaBits;
  672. cAuxBuffers := AuxBuffers;
  673. case Layer of
  674. clUnderlay2, clUnderlay1: iLayerType := Byte(PFD_UNDERLAY_PLANE);
  675. clMainPlane: iLayerType := PFD_MAIN_PLANE;
  676. clOverlay1, clOverlay2: iLayerType := PFD_OVERLAY_PLANE;
  677. end;
  678. bReserved := cLayerToSet[Layer];
  679. if Layer <> clMainPlane then
  680. dwFlags := dwFlags or PFD_SWAP_LAYER_BUFFERS;
  681. end;
  682. pixelFormat := 0;
  683. // WGL_ARB_pixel_format is used if available
  684. //
  685. if not(IsMesaGL or FLegacyContextsOnly or (aType in cMemoryDCs)) then
  686. begin
  687. // the WGL mechanism is a little awkward: we first create a dummy context
  688. // on the TOP-level DC (ie. screen), to retrieve our pixelformat, create
  689. // our stuff, etc.
  690. tempWnd := CreateTempWnd;
  691. tempDC := GetDC(tempWnd);
  692. localDC := 0;
  693. localRC := 0;
  694. try
  695. SpawnLegacyContext(tempDC);
  696. try
  697. DoActivate;
  698. try
  699. FGL.ClearError;
  700. if FGL.W_ARB_pixel_format then
  701. begin
  702. // New pixel format selection via wglChoosePixelFormatARB
  703. ClearIAttribs;
  704. AddIAttrib(WGL_DRAW_TO_WINDOW_ARB, GL_TRUE);
  705. AddIAttrib(WGL_STEREO_ARB, cBoolToInt[rcoStereo in Options]);
  706. AddIAttrib(WGL_DOUBLE_BUFFER_ARB, cBoolToInt[rcoDoubleBuffered in Options]);
  707. ChooseWGLFormat(ADeviceHandle, 32, @iFormats, nbFormats);
  708. if nbFormats > 0 then
  709. begin
  710. if FGL.W_ARB_multisample and (AntiAliasing in [aaNone, aaDefault]) then
  711. begin
  712. // Pick first non AntiAliased for aaDefault and aaNone modes
  713. iAttrib := WGL_SAMPLE_BUFFERS_ARB;
  714. for i := 0 to nbFormats - 1 do
  715. begin
  716. pixelFormat := iFormats[i];
  717. iValue := GL_FALSE;
  718. FGL.WGetPixelFormatAttribivARB(ADeviceHandle, pixelFormat, 0, 1, @iAttrib, @iValue);
  719. if iValue = GL_FALSE then
  720. break;
  721. end;
  722. end
  723. else
  724. pixelFormat := iFormats[0];
  725. if GetPixelFormat(ADeviceHandle) <> pixelFormat then
  726. begin
  727. if not SetPixelFormat(ADeviceHandle, pixelFormat, @pfDescriptor) then
  728. RaiseLastOSError;
  729. end;
  730. end;
  731. end;
  732. finally
  733. DoDeactivate;
  734. end;
  735. finally
  736. sharedRC := FShareContext;
  737. DoDestroyContext;
  738. FShareContext := sharedRC;
  739. GLSLogger.LogInfo('Temporary rendering context destroyed');
  740. end;
  741. finally
  742. ReleaseDC(0, tempDC);
  743. DestroyWindow(tempWnd);
  744. FDC := localDC;
  745. FRC := localRC;
  746. end;
  747. end;
  748. if pixelFormat = 0 then
  749. begin
  750. // Legacy pixel format selection
  751. pixelFormat := ChoosePixelFormat(ADeviceHandle, @pfDescriptor);
  752. if (not(aType in cMemoryDCs)) and (not CurrentPixelFormatIsHardwareAccelerated) then
  753. begin
  754. softwarePixelFormat := pixelFormat;
  755. pixelFormat := 0;
  756. end
  757. else
  758. softwarePixelFormat := 0;
  759. if pixelFormat = 0 then
  760. begin
  761. // Failed on default params, try with 16 bits depth buffer
  762. pfDescriptor.cDepthBits := 16;
  763. pixelFormat := ChoosePixelFormat(ADeviceHandle, @pfDescriptor);
  764. if not CurrentPixelFormatIsHardwareAccelerated then
  765. pixelFormat := 0;
  766. if pixelFormat = 0 then
  767. begin
  768. // Failed, try with 16 bits color buffer
  769. pfDescriptor.cColorBits := 16;
  770. pixelFormat := ChoosePixelFormat(ADeviceHandle, @pfDescriptor);
  771. end;
  772. if not CurrentPixelFormatIsHardwareAccelerated then
  773. begin
  774. // Fallback to original, should be supported by software
  775. pixelFormat := softwarePixelFormat;
  776. end;
  777. if pixelFormat = 0 then
  778. RaiseLastOSError;
  779. end;
  780. end;
  781. if GetPixelFormat(ADeviceHandle) <> pixelFormat then
  782. begin
  783. if not SetPixelFormat(ADeviceHandle, pixelFormat, @pfDescriptor) then
  784. RaiseLastOSError;
  785. end;
  786. // Check the properties we just set.
  787. DescribePixelFormat(ADeviceHandle, pixelFormat, SizeOf(pfDescriptor), pfDescriptor);
  788. with pfDescriptor do
  789. begin
  790. if (dwFlags and PFD_NEED_PALETTE) <> 0 then
  791. SetupPalette(ADeviceHandle, pfDescriptor);
  792. FSwapBufferSupported := (dwFlags and PFD_SWAP_LAYER_BUFFERS) <> 0;
  793. if bReserved = 0 then
  794. FLayer := clMainPlane;
  795. end;
  796. if not FLegacyContextsOnly then
  797. begin
  798. if ((pfDescriptor.dwFlags and PFD_GENERIC_FORMAT) > 0)
  799. and (FAcceleration = chaHardware) then
  800. begin
  801. FAcceleration := chaSoftware;
  802. GLSLogger.LogWarning(strFailHWRC);
  803. end;
  804. end;
  805. if not FLegacyContextsOnly and FGL.W_ARB_create_context
  806. and (FAcceleration = chaHardware) then
  807. CreateNewContext(ADeviceHandle)
  808. else
  809. CreateOldContext(ADeviceHandle);
  810. if not FLegacyContextsOnly then
  811. begin
  812. // Share identifiers with other context if it deffined
  813. if (ServiceContext <> nil) and (Self <> ServiceContext) then
  814. begin
  815. if wglShareLists(TGLWindowsContext(ServiceContext).FRC, FRC) then
  816. begin
  817. FSharedContexts.Add(ServiceContext);
  818. PropagateSharedContext;
  819. end
  820. else
  821. GLSLogger.LogWarning('DoCreateContext - Failed to share contexts with resource context');
  822. end;
  823. end;
  824. end;
  825. procedure TGLWindowsContext.SpawnLegacyContext(aDC: HDC);
  826. begin
  827. try
  828. FLegacyContextsOnly := True;
  829. try
  830. DoCreateContext(aDC);
  831. finally
  832. FLegacyContextsOnly := False;
  833. end;
  834. except
  835. on E: Exception do
  836. begin
  837. raise Exception.Create(strUnableToCreateLegacyContext + #13#10 + E.ClassName + ': ' + E.message);
  838. end;
  839. end;
  840. end;
  841. procedure TGLWindowsContext.DoCreateMemoryContext(outputDevice: HWND; width, height: Integer; BufferCount: Integer);
  842. var
  843. nbFormats: Integer;
  844. iFormats: array [0 .. 31] of Integer;
  845. iPBufferAttribs: array [0 .. 0] of Integer;
  846. localHPBuffer: Integer;
  847. localRC: HGLRC;
  848. localDC, tempDC: HDC;
  849. tempWnd: HWND;
  850. shareRC: TGLWindowsContext;
  851. pfDescriptor: TPixelFormatDescriptor;
  852. bOES: Boolean;
  853. begin
  854. localHPBuffer := 0;
  855. localDC := 0;
  856. localRC := 0;
  857. bOES := False;
  858. // the WGL mechanism is a little awkward: we first create a dummy context
  859. // on the TOP-level DC (ie. screen), to retrieve our pixelformat, create
  860. // our stuff, etc.
  861. tempWnd := CreateTempWnd;
  862. tempDC := GetDC(tempWnd);
  863. try
  864. SpawnLegacyContext(tempDC);
  865. try
  866. DoActivate;
  867. try
  868. FGL.ClearError;
  869. if FGL.W_ARB_pixel_format and FGL.W_ARB_pbuffer then
  870. begin
  871. ClearIAttribs;
  872. AddIAttrib(WGL_DRAW_TO_PBUFFER_ARB, 1);
  873. ChooseWGLFormat(tempDC, 32, @iFormats, nbFormats, BufferCount);
  874. if nbFormats = 0 then
  875. raise EPBuffer.Create('Format not supported for pbuffer operation.');
  876. iPBufferAttribs[0] := 0;
  877. localHPBuffer := FGL.WCreatePbufferARB(tempDC, iFormats[0], width, height, @iPBufferAttribs[0]);
  878. if localHPBuffer = 0 then
  879. raise EPBuffer.Create('Unabled to create pbuffer.');
  880. try
  881. localDC := FGL.WGetPbufferDCARB(localHPBuffer);
  882. if localDC = 0 then
  883. raise EPBuffer.Create('Unabled to create pbuffer''s DC.');
  884. try
  885. if FGL.W_ARB_create_context then
  886. begin
  887. // Modern creation style
  888. ClearIAttribs;
  889. // Initialize forward context
  890. if False { GLStates.ForwardContext } then
  891. begin
  892. if FGL.VERSION_4_2 then
  893. begin
  894. AddIAttrib(WGL_CONTEXT_MAJOR_VERSION_ARB, 4);
  895. AddIAttrib(WGL_CONTEXT_MINOR_VERSION_ARB, 2);
  896. end
  897. else if FGL.VERSION_4_1 then
  898. begin
  899. AddIAttrib(WGL_CONTEXT_MAJOR_VERSION_ARB, 4);
  900. AddIAttrib(WGL_CONTEXT_MINOR_VERSION_ARB, 1);
  901. end
  902. else if FGL.VERSION_4_0 then
  903. begin
  904. AddIAttrib(WGL_CONTEXT_MAJOR_VERSION_ARB, 4);
  905. AddIAttrib(WGL_CONTEXT_MINOR_VERSION_ARB, 0);
  906. end
  907. else if FGL.VERSION_3_3 then
  908. begin
  909. AddIAttrib(WGL_CONTEXT_MAJOR_VERSION_ARB, 3);
  910. AddIAttrib(WGL_CONTEXT_MINOR_VERSION_ARB, 3);
  911. end
  912. else if FGL.VERSION_3_2 then
  913. begin
  914. AddIAttrib(WGL_CONTEXT_MAJOR_VERSION_ARB, 3);
  915. AddIAttrib(WGL_CONTEXT_MINOR_VERSION_ARB, 2);
  916. end
  917. else if FGL.VERSION_3_1 then
  918. begin
  919. AddIAttrib(WGL_CONTEXT_MAJOR_VERSION_ARB, 3);
  920. AddIAttrib(WGL_CONTEXT_MINOR_VERSION_ARB, 1);
  921. end
  922. else if FGL.VERSION_3_0 then
  923. begin
  924. AddIAttrib(WGL_CONTEXT_MAJOR_VERSION_ARB, 3);
  925. AddIAttrib(WGL_CONTEXT_MINOR_VERSION_ARB, 0);
  926. end
  927. else
  928. Abort;
  929. AddIAttrib(WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB);
  930. if rcoOGL_ES in Options then
  931. GLSLogger.LogWarning(strOESvsForwardRC);
  932. end
  933. else if rcoOGL_ES in Options then
  934. begin
  935. if FGL.W_EXT_create_context_es2_profile then
  936. begin
  937. AddIAttrib(WGL_CONTEXT_MAJOR_VERSION_ARB, 2);
  938. AddIAttrib(WGL_CONTEXT_MINOR_VERSION_ARB, 0);
  939. AddIAttrib(WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_ES2_PROFILE_BIT_EXT);
  940. end
  941. else
  942. GLSLogger.LogError(strDriverNotSupportOESRC);
  943. end;
  944. if rcoDebug in Options then
  945. begin
  946. AddIAttrib(WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_DEBUG_BIT_ARB);
  947. FGL.DebugMode := True;
  948. end;
  949. case Layer of
  950. clUnderlay2: AddIAttrib(WGL_CONTEXT_LAYER_PLANE_ARB, -2);
  951. clUnderlay1: AddIAttrib(WGL_CONTEXT_LAYER_PLANE_ARB, -1);
  952. clOverlay1: AddIAttrib(WGL_CONTEXT_LAYER_PLANE_ARB, 1);
  953. clOverlay2: AddIAttrib(WGL_CONTEXT_LAYER_PLANE_ARB, 2);
  954. end;
  955. localRC := FGL.WCreateContextAttribsARB(localDC, 0, @FiAttribs[0]);
  956. if localRC = 0 then
  957. {$IFDEF USE_LOGGING}
  958. begin
  959. if False { GLStates.ForwardContext } then
  960. GLSLogger.LogErrorFmt(strForwardContextFailed, [GetLastError, SysErrorMessage(GetLastError)])
  961. else
  962. GLSLogger.LogErrorFmt(strBackwardContextFailed, [GetLastError, SysErrorMessage(GetLastError)]);
  963. Abort;
  964. end;
  965. {$ELSE}
  966. raise Exception.Create('Unabled to create pbuffer''s RC.');
  967. {$ENDIF}
  968. end
  969. else
  970. begin
  971. // Old creation style
  972. localRC := wglCreateContext(localDC);
  973. if localRC = 0 then
  974. begin
  975. GLSLogger.LogErrorFmt(strBackwardContextFailed, [GetLastError, SysErrorMessage(GetLastError)]);
  976. Abort;
  977. end;
  978. end;
  979. except
  980. FGL.WReleasePBufferDCARB(localHPBuffer, localDC);
  981. raise;
  982. end;
  983. except
  984. FGL.WDestroyPBufferARB(localHPBuffer);
  985. raise;
  986. end;
  987. end
  988. else
  989. raise EPBuffer.Create('WGL_ARB_pbuffer support required.');
  990. FGL.CheckError;
  991. finally
  992. DoDeactivate;
  993. end;
  994. finally
  995. shareRC := FShareContext;
  996. DoDestroyContext;
  997. FShareContext := shareRC;
  998. end;
  999. finally
  1000. ReleaseDC(0, tempDC);
  1001. DestroyWindow(tempWnd);
  1002. FHPBUFFER := localHPBuffer;
  1003. FDC := localDC;
  1004. FRC := localRC;
  1005. end;
  1006. DescribePixelFormat(FDC, GetPixelFormat(FDC), SizeOf(pfDescriptor), pfDescriptor);
  1007. if ((pfDescriptor.dwFlags and PFD_GENERIC_FORMAT) > 0) and (FAcceleration = chaHardware) then
  1008. begin
  1009. FAcceleration := chaSoftware;
  1010. GLSLogger.LogWarning(strFailHWRC);
  1011. end;
  1012. Activate;
  1013. FGL.Initialize;
  1014. // If we are using AntiAliasing, adjust filtering hints
  1015. if AntiAliasing in [aa2xHQ, aa4xHQ, csa8xHQ, csa16xHQ] then
  1016. GLStates.MultisampleFilterHint := hintNicest
  1017. else if AntiAliasing in [aa2x, aa4x, csa8x, csa16x] then
  1018. GLStates.MultisampleFilterHint := hintFastest
  1019. else
  1020. GLStates.MultisampleFilterHint := hintDontCare;
  1021. // Specific which color buffers are to be drawn into
  1022. if BufferCount > 1 then
  1023. FGL.DrawBuffers(BufferCount, @MRT_BUFFERS);
  1024. if (ServiceContext <> nil) and (Self <> ServiceContext) then
  1025. begin
  1026. if wglShareLists(TGLWindowsContext(ServiceContext).FRC, FRC) then
  1027. begin
  1028. FSharedContexts.Add(ServiceContext);
  1029. PropagateSharedContext;
  1030. end
  1031. else
  1032. GLSLogger.LogWarning('DoCreateContext - Failed to share contexts with resource context');
  1033. end;
  1034. if Assigned(FShareContext) and (FShareContext.RC <> 0) then
  1035. begin
  1036. if not wglShareLists(FShareContext.RC, FRC) then
  1037. GLSLogger.LogWarning(strFailedToShare)
  1038. else
  1039. begin
  1040. FSharedContexts.Add(FShareContext);
  1041. PropagateSharedContext;
  1042. end;
  1043. end;
  1044. Deactivate;
  1045. { if GLStates.ForwardContext then
  1046. GLSLogger.LogInfo('PBuffer ' + strFRC_created);
  1047. if bOES then
  1048. GLSLogger.LogInfo('PBuffer ' + strOESRC_created);
  1049. if not (GLStates.ForwardContext or bOES) then
  1050. GLSLogger.LogInfo(strPBufferRC_created); }
  1051. end;
  1052. function TGLWindowsContext.DoShareLists(aContext: TGLContext): Boolean;
  1053. begin
  1054. if aContext is TGLWindowsContext then
  1055. begin
  1056. FShareContext := TGLWindowsContext(aContext);
  1057. if FShareContext.RC <> 0 then
  1058. Result := wglShareLists(FShareContext.RC, RC)
  1059. else
  1060. Result := False;
  1061. end
  1062. else
  1063. raise Exception.Create(strIncompatibleContexts);
  1064. end;
  1065. procedure TGLWindowsContext.DoDestroyContext;
  1066. begin
  1067. if vUseWindowTrackingHook then
  1068. UnTrackWindow(WindowFromDC(FDC));
  1069. if FHPBUFFER <> 0 then
  1070. begin
  1071. FGL.WReleasePBufferDCARB(FHPBUFFER, FDC);
  1072. FGL.WDestroyPBufferARB(FHPBUFFER);
  1073. FHPBUFFER := 0;
  1074. end;
  1075. if FRC <> 0 then
  1076. if not wglDeleteContext(FRC) then
  1077. GLSLogger.LogErrorFmt(strDeleteContextFailed, [GetLastError, SysErrorMessage(GetLastError)]);
  1078. FRC := 0;
  1079. FDC := 0;
  1080. FShareContext := nil;
  1081. end;
  1082. procedure TGLWindowsContext.DoActivate;
  1083. begin
  1084. if not wglMakeCurrent(FDC, FRC) then
  1085. begin
  1086. GLSLogger.LogErrorFmt(strContextActivationFailed, [GetLastError, SysErrorMessage(GetLastError)]);
  1087. Abort;
  1088. end;
  1089. if not FGL.IsInitialized then
  1090. FGL.Initialize(CurrentGLContext = nil);
  1091. end;
  1092. procedure TGLWindowsContext.DoDeactivate;
  1093. begin
  1094. if not wglMakeCurrent(0, 0) then
  1095. begin
  1096. GLSLogger.LogErrorFmt(strContextDeactivationFailed, [GetLastError, SysErrorMessage(GetLastError)]);
  1097. Abort;
  1098. end;
  1099. end;
  1100. function TGLWindowsContext.IsValid: Boolean;
  1101. begin
  1102. Result := (FRC <> 0);
  1103. end;
  1104. procedure TGLWindowsContext.SwapBuffers;
  1105. begin
  1106. if (FDC <> 0) and (rcoDoubleBuffered in Options) then
  1107. if FSwapBufferSupported then
  1108. begin
  1109. case Layer of
  1110. clUnderlay2: wglSwapLayerBuffers(FDC, WGL_SWAP_UNDERLAY2);
  1111. clUnderlay1: wglSwapLayerBuffers(FDC, WGL_SWAP_UNDERLAY1);
  1112. clMainPlane: Winapi.Windows.SwapBuffers(FDC);
  1113. clOverlay1: wglSwapLayerBuffers(FDC, WGL_SWAP_OVERLAY1);
  1114. clOverlay2: wglSwapLayerBuffers(FDC, WGL_SWAP_OVERLAY2);
  1115. end;
  1116. end
  1117. else
  1118. Winapi.Windows.SwapBuffers(FDC);
  1119. end;
  1120. function TGLWindowsContext.RenderOutputDevice: Pointer;
  1121. begin
  1122. Result := Pointer(FDC);
  1123. end;
  1124. // ------------------------------------------------------------------
  1125. initialization
  1126. // ------------------------------------------------------------------
  1127. RegisterGLContextClass(TGLWindowsContext);
  1128. end.