{
вы знаете что такое карта высот?
можно создать супер эффект на простом Canvas
к сожалению мой код моргает при перерисовке,
но вы уж поковыряйтесь.... :)
}unit Unit1;
interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls, StdCtrls, ExtDlgs, math, ComCtrls, ShellApi;
type
TForm1 = class(TForm)
Image1: TImage;
OpenDialog1: TOpenDialog;
Timer1: TTimer;
PageControl1: TPageControl;
Specular: TTabSheet;
sRed: TEdit;
Label1: TLabel;
ScrollBar1: TScrollBar;
Label2: TLabel;
sGreen: TEdit;
ScrollBar2: TScrollBar;
ScrollBar3: TScrollBar;
sBlue: TEdit;
Label3: TLabel;
Label4: TLabel;
Edit1: TEdit;
ScrollBar4: TScrollBar;
Diffuse: TTabSheet;
Ambient: TTabSheet;
Label5: TLabel;
Label6: TLabel;
Label7: TLabel;
dGreen: TEdit;
dBlue: TEdit;
dRed: TEdit;
ScrollBar5: TScrollBar;
ScrollBar6: TScrollBar;
ScrollBar7: TScrollBar;
Label8: TLabel;
Label9: TLabel;
Label10: TLabel;
aBlue: TEdit;
aGreen: TEdit;
aRed: TEdit;
ScrollBar8: TScrollBar;
ScrollBar9: TScrollBar;
ScrollBar10: TScrollBar;
Label11: TLabel;
Label12: TLabel;
Edit2: TEdit;
Label13: TLabel;
procedure FormCreate(Sender: TObject);
procedure Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure ScrollBarChange(Sender: TObject);
procedure Label11Click(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private{ Private declarations }public{ Public declarations }end;
type
normal = record
x: integer;
y: integer;
end;
type
rgb32 = record
b: byte;
g: byte;
r: byte;
t: byte;
end;
type
rgb24 = record
r: integer;
g: integer;
b: integer;
end;
var
Form1: TForm1;
bumpimage: tbitmap;
current_X, Current_Y: integer;
var
Bump_Map: array[0..255, 0..255] of normal;
Environment_map: array[0..255, 0..255] of integer;
Palette: array[0..256] of rgb24;
implementation{$R *.DFM}procedure TForm1.FormCreate(Sender: TObject);
type
image_array = array[0..255, 0..255] of byte;
var
x, y: integer;
Buffer: image_array;
bump_file: fileof image_array;
ny2, nx, nz: double;
c: integer;
ca, cap: double;
begin
assignfile(bump_File, 'bump.raw');
reset(Bump_File);
Read(Bump_File, buffer);
for y := 1 to 254 dobeginfor x := 1 to 254 dobegin
Bump_Map[x, y].x := buffer[y + 1, x] - buffer[y + 1, x + 2];
bump_map[x, y].y := buffer[y, x + 1] - buffer[y + 2, x + 1];
end;
end;
closefile(bump_File);
for y := -128 to 127 dobegin
nY2 := y / 128;
nY2 := nY2 * nY2;
for X := -128 to 127 dobegin
nX := X / 128;
nz := 1 - SQRT(nX * nX + nY2);
c := trunc(nz * 255);
if c < = 0 then
c := 0;
Environment_Map[x + 128, y + 128] := c;
end;
end;
nx := pi / 2;
ny2 := nx / 256;
for y := 0 to 255 dobegin
ca := cos(nx);
cap := power(ca, 35);
nx := nx - ny2;
palette[y].r := trunc((128 * ca) + (235 * cap));
if palette[y].r > 255 then
palette[y].r := 255;
palette[y].G := trunc((128 * ca) + (245 * cap));
if palette[y].g > 255 then
palette[y].g := 255;
palette[y].B := trunc(5 + (170 * ca) + (255 * cap));
;
if palette[y].b > 255 then
palette[y].b := 255;
end;
bumpimage := TBitmap.create;
bumpimage.width := 255;
bumpimage.height := 255;
bumpimage.PixelFormat := pf32bit;
Image1.Picture.Bitmap := bumpimage;
image1mousemove(self, [], 128, 128);
application.ProcessMessages;
end;
procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
Current_X := x;
Current_Y := y;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
var
x, y, x2, y2, y3: integer;
Scan: ^Scanline;
bx, by: longint;
c: byte;
begin
x := Current_X;
y := Current_Y;
for y2 := 0 to 253 dobegin
scan := image1.Picture.Bitmap.ScanLine[y2];
y3 := 128 + y2 - y;
for x2 := 0 to 253 dobegin
bx := bump_Map[x2, y2].x + 128 + x2 - x;
by := bump_Map[x2, y2].y + y3;
if (bx < 255) and (bx > 0) and (by < 255) and (by > 0) thenbegin
c := Environment_Map[bx, by];
scan^[x2].r := palette[c].r;
scan^[x2].g := palette[c].g;
scan^[x2].b := palette[c].b;
endelsebegin
scan^[x2].r := palette[0].r;
scan^[x2].g := palette[0].g;
scan^[x2].b := palette[0].b;
end;
{image1.Canvas.Pixels[x,y] := rgb(r,g,b);}end;
end;
image1.Refresh;
end;
procedure TForm1.ScrollBarChange(Sender: TObject);
var
ny2, nx: double;
c: integer;
ca, cap: double;
begin
sRed.Text := inttostr(scrollbar1.position);
sGreen.Text := inttostr(scrollbar2.position);
sBlue.Text := inttostr(scrollbar3.position);
edit1.Text := inttostr(scrollbar4.position);
dRed.Text := inttostr(scrollbar5.position);
dGreen.Text := inttostr(scrollbar6.position);
dBlue.Text := inttostr(scrollbar7.position);
aRed.Text := inttostr(scrollbar8.position);
aGreen.Text := inttostr(scrollbar9.position);
aBlue.Text := inttostr(scrollbar10.position);
nx := pi / 2;
ny2 := nx / 256;
for C := 0 to 255 dobegin
ca := cos(nx);
cap := power(ca, scrollbar4.position);
nx := nx - ny2;
palette[c].r := trunc(scrollbar8.position + (scrollbar5.position * ca) +
(scrollbar1.position * cap));
if palette[c].r > 255 then
palette[c].r := 255;
palette[c].G := trunc(scrollbar9.position + (scrollbar6.position * ca) +
(scrollbar2.position * cap));
if palette[c].g > 255 then
palette[c].g := 255;
palette[c].B := trunc(scrollbar10.position + (scrollbar7.position * ca) +
(scrollbar3.position * cap));
;
if palette[c].b > 255 then
palette[c].b := 255;
end;
image1mousemove(self, [], Current_X, Current_Y);
application.ProcessMessages;
end;
procedure TForm1.Label11Click(Sender: TObject);
begin
ShellExecute(handle, 'open', 'http://wkweb5.cableinet.co.uk/daniel.davies/',
nil, nil, SW_SHOWNORMAL);
end;
end.
Here is a translation of the content into Russian:
Вот код Delphi, который создает графическое интерфейсе с различными компонентами, такими как изображения, полосы прокрутки и поля ввода. Цель программы - создать интерактивный генератор высотной карты для 3D-графики.
Распределение кода:
Первая часть объявляет единицу Unit1, которая содержит основную форму приложения.
Она определяет несколько типов, таких как normal, rgb32 и rgb24, которые используются для представления различных данных.
Программа затем инициализирует несколько переменных, включая массивы для хранения карт высот, окружающих карт и палеток цветов.
В процедуре FormCreate она загружает карту высот из файла "bump.raw" и использует эту карту для генерации окружающей карты.
Она также генерирует палету цветов на основе функции косинуса и хранит их в массиве Palette.
Программа создает битмап-изображение с помощью класса TBitmap и присваивает его компоненту изображения (Image1) на форме.
В процедуре Image1MouseMove она обновляет текущую позицию мыши (Current_X и Current_Y) при перемещении мыши над изображением.
Процедура Timer1Timer вызывается каждый раз, когда таймер (Timer1) срабатывает. Она использует текущую позицию мыши для генерации новой высотной карты путем интерполяции между значениями карт высот.
В процедуре ScrollBarChange она обновляет палету цветов на основе положений нескольких полос прокрутки.
Вот обновленная версия кода с более подробными комментариями:
unitUnit1;interfaceusesWindows,Messages,SysUtils,Classes,Graphics,Controls,Forms,Dialogs,ExtCtrls,StdCtrls,ExtDlgs,Math,ComCtrls,ShellApi;typeTForm1=class(TForm)Image1:TImage;OpenDialog1:TOpenDialog;Timer1:TTimer;PageControl1:TPageControl;Specular:TTabSheet;sRed:TEdit;Label1:TLabel;ScrollBar1:TScrollBar;Label2:TLabel;sGreen:TEdit;ScrollBar2:TScrollBar;ScrollBar3:TScrollBar;sBlue:TEdit;Label3:TLabel;Label4:TLabel;Edit1:TEdit;ScrollBar4:TScrollBar;Diffuse:TTabSheet;Ambient:TTabSheet;Label5:TLabel;Label6:TLabel;Label7:TLabel;dGreen:TEdit;dBlue:TEdit;dRed:TEdit;ScrollBar5:TScrollBar;ScrollBar6:TScrollBar;ScrollBar7:TScrollBar;Label8:TLabel;Label9:TLabel;Label10:TLabel;aBlue:TEdit;aGreen:TEdit;aRed:TEdit;ScrollBar8:TScrollBar;ScrollBar9:TScrollBar;ScrollBar10:TScrollBar;Label11:TLabel;procedureFormCreate(Sender:TObject);procedureImage1MouseMove(Sender:TObject;Shift:TShiftState;X,Y:Integer);procedureScrollBarChange(Sender:TObject);procedureTimer1Timer(Sender:TObject);private{ Private declarations }public{ Public declarations }end;varForm1:TForm1;bumpimage:TBitmap;current_X,Current_Y:integer;Bump_Map:array[0..255,0..255]ofnormal;Environment_map:array[0..255,0..255]ofinteger;Palette:array[0..256]ofrgb24;implementation{$R *.DFM}procedureTForm1.FormCreate(Sender:TObject);typeimage_array=array[0..255,0..255]ofbyte;varx,y:integer;Buffer:image_array;bump_file:fileofimage_array;ny2,nx,nz:double;c:integer;ca,cap:double;beginassignfile(bump_file,'bump.raw');reset(bump_file);read(bump_file,buffer);fory:=1to254dobeginforx:=1to254dobeginBump_Map[x,y].x:=buffer[y+1,x]-buffer[y+1,x+2];bump_map[x,y].y:=buffer[y,x+1]-buffer[y+2,x+1];end;end;closefile(bump_file);fory:=-128to127dobeginny2:=y/128;ny2:=ny2*ny2;forX:=-128to127dobeginnX:=X/128;nz:=1-sqrt(nX*nX+ny2);c:=trunc(nz*255);ifc<=0thenc:=0;Environment_Map[x+128,y+128]:=c;end;end;nx:=pi/2;ny2:=nx/256;forc:=0to255dobeginca:=cos(nx);cap:=power(ca,35);nx:=nx-ny2;palette[c].r:=trunc((128*ca)+(235*cap));ifpalette[c].r>255thenpalette[c].r:=255;palette[c].G:=trunc((128*ca)+(245*cap));ifpalette[c].g>255thenpalette[c].g:=255;palette[c].B:=trunc(5+(170*ca)+(255*cap));// Ensure that the color value does not exceed 255ifpalette[c].b>255thenpalette[c].b:=255;end;bumpimage:=TBitmap.create;bumpimage.width:=255;bumpimage.height:=255;bumpimage.PixelFormat:=pf32bit;Image1.Picture.Bitmap:=bumpimage;image1mousemove(self,[],128,128);application.ProcessMessages;end;procedureTForm1.Image1MouseMove(Sender:TObject;Shift:TShiftState;X,Y:Integer);beginCurrent_X:=x;Current_Y:=y;end;procedureTForm1.Timer1Timer(Sender:TObject);varx,y,x2,y2,y3:integer;Scan:^Scanline;bx,by:longint;c:byte;beginx:=Current_X;y:=Current_Y;fory2:=0to253dobeginscan:=image1.Picture.Bitmap.ScanLine[y2];y3:=128+y2-y;forx2:=0to253dobeginbx:=bump_Map[x2,y2].x+128+x2-x;by:=bump_Map[x2,y2].y+y3;if(bx<255)and(bx>0)and(by<255)and(by>0)thenbeginc:=Environment_Map[bx,by];scan^[x2].r:=palette[c].r;scan^[x2].g:=palette[c].g;scan^[x2].b:=palette[c].b;endelsebeginscan^[x2].r:=palette[0].r;scan^[x2].g:=palette[0].g;scan^[x2].b:=palette[0].b;end;end;image1.Refresh;end;procedureTForm1.ScrollBarChange(Sender:TObject);varny2,nx:double;c:integer;ca,cap:double;beginsRed.Text:=inttostr(ScrollBar1.Position);sGreen.Text:=inttostr(ScrollBar2.Position);sBlue.Text:=inttostr(ScrollBar3.Position);Edit1.Text:=inttostr(ScrollBar4.Position);dRed.Text:=inttostr(ScrollBar5.Position);dGreen.Text:=inttostr(ScrollBar6.Position);dBlue.Text:=inttostr(ScrollBar7.Position);aRed.Text:=inttostr(ScrollBar8.Position);aGreen.Text:=inttostr(ScrollBar9.Position);aBlue.Text:=inttostr(ScrollBar10.Position);nx:=pi/2;ny2:=nx/256;forc:=0to255dobeginca:=cos(nx);cap:=power(ca,ScrollBar4.Position);nx:=nx-ny2;palette[c].r:=trunc(ScrollBar8.Position+(ScrollBar5.Position*ca)+(ScrollBar1.Position*cap));ifpalette[c].r>255thenpalette[c].r:=255;palette[c].G:=trunc(ScrollBar9.Position+(ScrollBar6.Position*ca)+(ScrollBar2.Position*cap));ifpalette[c].g>255thenpalette[c].g:=255;palette[c].B:=trunc(ScrollBar10.Position+(ScrollBar7.Position*ca)+(ScrollBar3.Position*cap));// Ensure that the color value does not exceed 255ifpalette[c].b>255thenpalette[c].b:=255;end;image1mousemove(self,[],Current_X,Current_Y);application.ProcessMessages;end;procedureTForm1.Label11Click(Sender:TObject);beginShellExecute(handle,'open','http://wkweb5.cableinet.co.uk/daniel.davies/',nil,nil,SW_SHOWNORMAL);end;end.
I hope this helps! Let me know if you have any further questions.
В статье описывается создание карты высот для простого Canvas с помощью Delphi и использования таймера для перерисовки изображения в реальном времени.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.