pascalabcnet/bin/Lib/OpenGLABC.pas

111 lines
4.3 KiB
ObjectPascal
Raw Normal View History

2022-03-25 14:27:17 +03:00

//*****************************************************************************************************\\
// Copyright (©) Sergey Latchenko ( github.com/SunSerega | forum.mmcs.sfedu.ru/u/sun_serega )
// This code is distributed under the Unlicense
// For details see LICENSE file or this:
// https://github.com/SunSerega/POCGL/blob/master/LICENSE
//*****************************************************************************************************\\
// Copyright (©) Сергей Латченко ( github.com/SunSerega | forum.mmcs.sfedu.ru/u/sun_serega )
// Данный код распространяется с лицензией Unlicense
// Подробнее в файле LICENSE или тут:
// https://github.com/SunSerega/POCGL/blob/master/LICENSE
//*****************************************************************************************************\\
///
2019-09-09 21:04:21 +03:00
///Модуль, зарезервированный для высокоуровневой оболочки модуля OpenGL
2022-03-25 14:27:17 +03:00
///Все текущие элементы модуля являются временными
2019-09-09 21:04:21 +03:00
///
unit OpenGLABC;
2019-07-18 03:47:28 +03:00
2022-03-25 14:27:17 +03:00
uses System;
2019-07-18 03:47:28 +03:00
uses OpenGL;
2022-03-25 14:27:17 +03:00
type
///Методы для интеграции с gdi
gl_gdi = static class
{$reference System.Windows.Forms.dll}
///Создаёт новый контекст устройства GDI для дескриптора элемента управления
public static function GetControlDC(hwnd: IntPtr): gdi_device_context;
external 'user32.dll' name 'GetDC';
///Создаёт и настраивает контекст устройства GDI элемента управления WF
///hwnd - дескриптор элемента управления
public static function InitControl(hwnd: IntPtr): gdi_device_context;
begin
Result := gl_gdi.GetControlDC(hwnd);
var pfd: gdi_pixel_format_descriptor;
pfd.nVersion := 1;
pfd.dwFlags :=
GDI_PixelFormatFlags.DRAW_TO_WINDOW or
GDI_PixelFormatFlags.SUPPORT_OPENGL or
GDI_PixelFormatFlags.DOUBLEBUFFER
;
pfd.cColorBits := 24;
pfd.cDepthBits := 16;
if not gdi.SetPixelFormat(
Result,
gdi.ChoosePixelFormat(Result, pfd),
pfd
) then raise new InvalidOperationException;
end;
///Создаёт и настраивает контекст устройства GDI элемента управления WF
public static function InitControl(c: System.Windows.Forms.Control) := InitControl(c.Handle);
end;
RedrawThreadProc = procedure(pl: PlatformLoader; EndFrame: ()->());
RedrawHelper = static class
///Создаёт новый поток выполнения, который:
///1. Создаёт контекст OpenGL из контекста устройства GDI (hdc)
///2. Запускает перерисовку (RedrawThreadProc)
public static procedure SetupRedrawThread(hdc: gdi_device_context; RedrawThreadProc: OpenGLABC.RedrawThreadProc; vsync_fps: integer := 65);
begin
System.Threading.Thread.Create(()->
begin
var pl := new PlWin;
var context := wgl.CreateContext(hdc);
if not wgl.MakeCurrent(hdc, context) then raise new InvalidOperationException('Не удалось применить контекст');
var EndFrame: ()->();
if vsync_fps<=0 then
EndFrame := ()->gdi.SwapBuffers(hdc) else
begin
var LastRedr := DateTime.UtcNow;
var FrameDuration := new TimeSpan(Trunc(TimeSpan.TicksPerSecond/vsync_fps));
var MaxSlowDown := FrameDuration.Ticks*3;
EndFrame := ()->
begin
gdi.SwapBuffers(hdc);
LastRedr := LastRedr+FrameDuration;
var time_left := LastRedr-DateTime.UtcNow;
if time_left.Ticks>0 then
System.Threading.Thread.Sleep(time_left) else
if -time_left.Ticks > MaxSlowDown then
LastRedr := LastRedr.AddTicks(-time_left.Ticks - MaxSlowDown);
end;
end;
RedrawThreadProc(pl, EndFrame);
end).Start;
end;
end;
2019-07-18 03:47:28 +03:00
end.