В Интернет нашёл код на Delphi + GDI (Ссылка), перевёл этот код на Delphi + OpenGL. Вышел интересный визуальный эффект.
Рисунок 1. Результат работы программы
Код проекта:
unit ogl_p1_u1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, OpenGL, ExtCtrls;
type
TForm1 = class(TForm)
tmr1: TTimer;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure tmr1Timer(Sender: TObject);
procedure FormResize(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
type
TRGB = record
B, G, R: Byte;
end;
ARGB = array[0..0] of TRGB;
PARGB = ^ARGB;
var
Form1: TForm1;
MyBmp: TBitmap;
i: Byte = 0;
hrc: HGLRC; // Контекст OpenGL
FHDC: HDC; // Контекст устройства
implementation
{$R *.dfm}
const
pfd: TPixelFormatDescriptor = (
nSize: SizeOf(TPixelFormatDescriptor);
nVersion: 1;
dwFlags: PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER;
iPixelType: PFD_TYPE_RGBA;
cColorBits: 24;
cDepthBits: 16;
iLayerType: PFD_MAIN_PLANE;
);
procedure SetupOrthoProjection;
begin
glViewport(0, 0, Form1.ClientWidth, Form1.ClientHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
glOrtho(0, Form1.ClientWidth, 0, Form1.ClientHeight, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity;
glDisable(GL_DEPTH_TEST);
end;
procedure InitOpenGL;
begin
// Настройка OpenGL
glClearColor(0.0, 0.0, 0.0, 0.0);
SetupOrthoProjection;
end;
procedure CreateOpenGLContext;
begin
FHDC := GetDC(Form1.Handle); // Получаем контекст устройства
if FHDC = 0 then
raise Exception.Create('Не удалось получить контекст устройства.');
// Устанавливаем формат пикселей
if not SetPixelFormat(FHDC, ChoosePixelFormat(FHDC, @pfd), @pfd) then
raise Exception.Create('Не удалось установить формат пикселей.');
// Создаем контекст OpenGL
hrc := wglCreateContext(FHDC);
if hrc = 0 then
raise Exception.Create('Не удалось создать контекст OpenGL.');
// Активируем контекст OpenGL
if not wglMakeCurrent(FHDC, hrc) then
raise Exception.Create('Не удалось активировать контекст OpenGL.');
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
// Задаем фиксированные размеры для Bitmap
MyBmp := TBitmap.Create;
MyBmp.PixelFormat := pf24bit;
MyBmp.Width := Form1.ClientWidth; // Фиксированная ширина
MyBmp.Height := Form1.ClientHeight; // Фиксированная высота
// Настраиваем таймер
tmr1.Interval := 50;
tmr1.Enabled := True;
CreateOpenGLContext;
// Инициализация OpenGL
InitOpenGL;
end;
procedure Draw;
var
LinePointer: PARGB;
a, b: Real;
x, y: Integer;
xPos, yPos: GLfloat;
begin
// Заполняем Bitmap данными
for y := 0 to (MyBmp.Height - 1) do
begin
LinePointer := MyBmp.ScanLine[y];
for x := 0 to (MyBmp.Width - 1) do
begin
a := x * x + i;
b := y * y + i;
LinePointer[x].R := Trunc(Abs(b));
LinePointer[x].G := Trunc(Abs(a + b));
LinePointer[x].B := Trunc(Abs(a));
end;
end;
// Очищаем буфер и отрисовываем Bitmap
glClear(GL_COLOR_BUFFER_BIT);
// Вычисляем позицию для центрирования
xPos := Abs(Form1.ClientWidth - MyBmp.Width) div 2;
yPos := Abs(Form1.ClientHeight - MyBmp.Height) div 2;
//glRasterPos2f(-1, -1);
glRasterPos2f(xPos, yPos);
glDrawPixels(MyBmp.Width, MyBmp.Height, GL_RGB, GL_UNSIGNED_BYTE, LinePointer);
SwapBuffers(FHDC); // Обмениваем буферы
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
// Освобождаем ресурсы
if Assigned(MyBmp) then
MyBmp.Free;
if hrc <> 0 then
begin
wglMakeCurrent(0, 0);
wglDeleteContext(hrc);
end;
if FHDC <> 0 then
ReleaseDC(Form1.Handle, FHDC);
end;
procedure TForm1.tmr1Timer(Sender: TObject);
begin
Draw;
Inc(i);
end;
procedure TForm1.FormResize(Sender: TObject);
begin
if (Form1.ClientWidth < 640) or (Form1.ClientHeight < 480) then
begin
MyBmp.Width := Form1.ClientWidth; // Фиксированная ширина
MyBmp.Height := Form1.ClientHeight; // Фиксированная высота
end
else
begin
MyBmp.Width := 640; // Фиксированная ширина
MyBmp.Height := 480; // Фиксированная высота
end;
SetupOrthoProjection;
end;
end.

Комментариев нет:
Отправить комментарий