Na FreeHostingu Endora běží desítky tisíc webů. Přidejte se ještě dnes!

Vytvořit web zdarma

Na FreeHostingu Endora běží desítky tisíc webů. Přidejte se ještě dnes!

Vytvořit web zdarma

int21h

Grafika pod Free Pascalem

Mme tu nov dl serilu, kter navazuje na tradici serilu o grafice v TP7, kter navazuje na tradici mch kec o programovn. Tentokrt ns ek mlo samostatnho programovn, kter bude zahrnovat vyuit Linear Frame Bufferu, ale spe vyuvn cizch jednotek, mezi kter zahrneme Graph (z FP, ne tu ubohou z TP7), WinGraph a velmi okrajov tak SD, Direct Draw (z Direct X 7) a spol.

Ne ale zaneme, rd bych doplnil nkter z pedchozch dl, kde jsme se nauili provdt rotace ve 2D. Pokud budete nkdy dlat 3D hru, tak budete potebovat rotovat ve 3D. A nejen to, u objekt, kter budou popsny pomoc 3D, budete muset provdt rzn transformace pi jejich oten, zrcadlen nebo pesouvn (a u po map (na co vm ale sta pouh INC a DEC funkce), nebo ped kameru). Vtinu z nich najdete v asopisu Vhe v lncch Vektorov grafika a 3D engine. Pro rotace uvedu vzoreek zde:

Chcete-li otoit pixel se souadnicemi XYZ, muste provst toto:

	Y1 = Y*cos(a)+Z*sin(a)
	Z1 = -Y*sin(a)+Z*cos(a)
	X1 = X*cos(b)+Z1*sin(b)


	X' = X1*cos(c)+Y1*sin(c)
	Y' = -X1*sin(c)+Y1*cos(c)
	Z' = -X*sin(b)+Z1*cos(b)

Kde nov souadnice budou X'Y'Z'. ABC jsou hly, o kter chcete rotovat v osch XYZ (tedy se nejedn jen o 1 hel, jako v ppad 2D). Pokud si pamatujete na n pepoet z 3D na 2D, tak se vlastn jedn o vpoet perspektivy. Ta vypad pro XYZ na X'Y' takto:


	X' = (X SHL ShiftFactor) div (Z+ZDelta)
	Y' = (Y SHL ShiftFactor) div (Z+ZDelta)

Kde ShiftFactor je mra zkreslen a ZDelta je relativn prodlouen na ose Z. To jsou zkladn vpoty, kter budete ve 3D potebovat. Ale ono jich asem pibyde vc. Toto by Vm ale mlo pomoci hlavn do zatku. Pro zajmavost jet pikldm tabulku grafickch reim pod nativnm Linuxem (abyste vidli, jak je moc "nebezpen" se dret statickch sel, kter Vm nap. poskytne ATHelp):

Colours   640x400 640x480 800x600 1024x768 1152x864 1280x1024 1600x1200
--------+--------------------------------------------------------------
 4 bits |    ?       ?     0x302      ?        ?        ?         ?
 8 bits |  0x300   0x301   0x303    0x305    0x161    0x307     0x31C
15 bits |    ?     0x310   0x313    0x316    0x162    0x319     0x31D
16 bits |    ?     0x311   0x314    0x317    0x163    0x31A     0x31E
24 bits |    ?     0x312   0x315    0x318      ?      0x31B     0x31F
32 bits |    ?       ?       ?        ?      0x164      ?

Te se na chvli odmlme od Turbo Pascalu 7. Vrtme se k nmu na chvli jen u zvukovch karet a st IPX (nebo jet sriovho kabelu). Pravda, d se v nm uit, a je i celkem snadn, ale nedaj se v nm dlat profesionln aplikace (daj, pokud oelte rychlost). Stejn tak v nm mete udlat i Dooma, pokud Vm nebude vadit, e si ho na 486 a nich moc nezahrajete. Chce to u nco lepho a kdy u umme Pascal, pro se moit s uenm njakho Visual Basicu, Delphi (a je Pascalu velmi podobn) nebo C (C++, Java (u existuje i kompiltor, kter Vae programy z Pascalu zkompiluje do Javy pro mobiln telefony!), atd.), kdy tu mme Free Pascal. J jen podotknu, e jeliko jsem zaal v jedn firm zavdt Linux pes server, a programovat databzov sov software, asi u nebudu mt as (a nladu) pst lnky kad tden (nkomu tm udlm mon radost). Jde o to, e lovk mus mt nladu po 10 hodinch prce s PC v prci jet nco pst o vkendu. Ale tm Vs nechci zatovat (navc se bhem prce mohu nco nauit a urit o tom pozdji napu).

Zaneme metodou zobrazovn, kter se nazv linear frame buffer. Podotkm pr vc: pod Windows XP to nemus fungovat, pokud jedete v DOSovm programu. A tak nejprve trochu teorie: LFB podporuj hlavn novj karty (tm myslm cca. 10 let a vce), hlavn na to mus bt VESA verze 2.0 a vy, pokud se nepletu. Nejprve se tedy pepnete do reimu, kter bude vyuvat LFB. To provedete tak, e k slu reimu pitete do registru BX hodnotu $4000:


function VESA_LFB(rezim : word) : word; assembler;
asm  
	mov	eax,$4f02
	mov	ebx,rezim
	or	ebx,$4000
	int	10h  
end;  

Podle vstupu funkce pak poznte, zda dan reim jde nastavit, nebo zda je vbec podporovan funkce LFB (a pokud ne, ale dan reim ano, budete ho muset nastavit jet jednou, ale viz. minule). Adresa VRAM nyn nele na $a000 (i kdy by jet stle mohla leet), ale nkde nad 1. MB pamti. Pokud si nechte zjistit informace o tomto reimu (viz. minule), tak v LFB najdete fyzickou adresu VRAM pro tento reim (nezapomete, e tento blok informac MUS leet v konvenn pamti, take nejprve muste alokovat pes "global_dos_alloc" funkci doln pam, tam zjistit informace a pak tuto pam uvolnit (nen j zase tolik, aby se s n mohlo pltvat). Budeme tak potebovat velikost tto pamti, a tu najdeme v poloce PAMET v informacch o cel kart. Tyto dva daje si ulote nkam stranou (nazvu je nap. _LFB a _PAMET) do normlnch VAR promnnch.

Tuto adresu vak nemete pmo pout. Muste nejprve namapovat fyzickou adresu do linern pomoc DPMI, najt zkladn adresu DS selektoru, kter pouvte pro data, a odest tuto bzovou adresu od linern, abyste dostali blzk offset VRAM, kam mete pst pixely:


function ZjistiAdrLFB(Fyzicka : longint) : longint;
var	Linear : longint;
begin
 Linear := get_linear_addr(_LFB,_PAMET);
 Set_Segment_Limit(get_ds,$FFFFFFFF);
 lock_linear_region(_LFB,_PAMET);
 Linear:=Linear-get_segment_base_address(get_ds);
 ZjistiAdrLFB := Linear;
end;  

Nyn u vte, kam mete zapisovat svoje data (_LFBlin). Velikost X,Y,BPP a poet byt na dku (_BYTESLINE) mte uloeno opt v informacch o mdu. Nyn je adresovn u velmi jednoduch. Cel VRAM je toti pstupn bez njakho pepnn bank, take adresa Vaeho pixelu je (X+Y*MaxX)*BPP. Zjednoduen (bez optimalizac, kter jsou zvisl prv na tom MaxX) se to d napsat takto (pklady pro 8, 15/16 a 24/32 bit):


procedure PutPixel8(x,y : longint; barva : byte); assembler;
asm  
	mov	eax,y
	mul	_bytesline
	add	eax,x
	mov	bl,barva
	add	eax,_lfblin
	mov	[eax],bl  
end;


procedure PutPixel16(x,y : longint; barva : word); assembler;
asm  
	mov	eax,y
	mul	_bytesline
	add	eax,x
	mov	bx,barva
	add	eax,_lfblin
	mov	[eax],bx  
end;


procedure PutPixel32(x,y : longint; barva : longint); assembler;
asm  
	mov	eax,y
	mul	_bytesline
	add	eax,x
	mov	ebx,barva
	add	eax,_lfblin
	mov	[eax],ebx  
end;  

Vechno ostatn zstv stejn. Jen nezapomete pi pepnn reimu (ukonovn VESA) provst jet toto (INLINE pouvm proto, aby FP tuto proceduru vloil na msto jejho voln jako makro a ne jako voln procedury, m je urychl vykonn jejho kdu (za cenu, e kd bude velk jako jej pkazy a ne jako CALL)):


procedure KonecLFB; inline;
begin
 unlock_linear_region(_LFB,_PAMET);
end;  

Tak, te se trochu zaneme spolhat na ciz jednotky. Vhoda je jasn: pokud chcete programovat pro Windows (nebo i Linux), tak tam to, co jsme se doposud nauili, nemete pout (tm myslm, e budete vytvet nativn WIN32 aplikace: DOSov aplikace sputn pod WIN se bude chovat naprosto stejn jako pod DOSem, za pedpokladu, e je Windows dobe napsn - kdy ne, pouijte emultor, nap. DOSbox (s tm mete spustit Vae DOSovky i pod Linuxem)).

Free Pascal nm pro zklad poskytuje jednotku GRAPH. Je sice pomalej ne to, co si meme napsat vlastnmi silami, nebo za pouit dalch jednotek (budeme brt dle alespo co se te Windows), ale m dv vhody: a) podporuje i VESA reimy, jako 800x600/TC, b) b pod DOSem, Windows a i Linuxem (zkrtka je urena pro vechny platformy, kter FP podporuje). Pokud nepotebujete pst nron 3D hry, ale jen nap. grafick etn/databzov/grafov aplikace, jist Vm pijde vhod, e V program budete moci zkompilovat pro 3 systmy souasn. Protoe jednotka GRAPH je dobe popsan v Turbo Pascalu 7 (navc i v npovd pro FP) a pouv stejn funkce (OutText,SetColor,atd.), nebudu j rozebrat do hloubky. Uku Vm jen pklad, jak jednodue zapnout rozlien 800x600 v 8bitovch barvch:


uses Graph;
begin
 initgraph(d8bit,m800x600,'');	(* nepotebujeme dn BGI *)
 if error = grOk then
 begin
  (* zde si nakreslete nco na obrazovku, atd. *)
  closegraph;
 end;
end;  

Jak vidte, je to velice snadn. Mon ne tak rychl, ale pro vykreslen neho jako je Windows 3.11 bez nroku na pehrvn videa a animac dostaujc. Pokud je Vaim primrnm clem hlavn Windows, mete vyut jednotku WinGRAPH. Ta pistupuje pmo pes Direct Draw a umon Vm pouvat i Open GL, take tedy i 3D objekty! Pouv tm stejn funkce jako jednotka GRAPH.

Mete zde vyut pr novch funkc (jako nap. reagovat na zaven aplikace vynucen uivatelem, podpora bzeriovch kivek a jaktak i animac). Nevhoda je, e Vae aplikace me bet bu v okn, kde si rozmry mete nadefinovat sami, nebo ve Full Screen, kde jsou ovem rozmry obrazovky zvisl na aktulnm nastaven plochy Windows. Reimy, kter mete vyuvat se zadvaj podobn jako v FP. Zde mte 2,16 a 256 barevn palety, nebo True Color (ovem pravdpodobn 24 bitov). Rozlien v okn sah od m320x200 a po m1280x1024. Pokud pracujete na Full Screen (mFullSc), muste se pizpsobovat podle MaxX a MaxY. Podporovany jsou i pvodn zastaral reimy, jako nap. m640x350. Navc si mete pojmenovat titulek okna, pokud v nm bete. Mete pouvat tak vechny fonty, kter jsou instalovan ve Windows! Jednotka podporuje a 4 grafick strnky, do kterch mete kreslit. Vbrem aktivn si urte, kter se ale bude zobrazovat. Jednotka podporuje obnovovn VRAM podle uritch pravidel. Standardn se kresl pmo do VRAM. Mete si ale zapnout, abyste kreslili nejprve do Vaich strnek (UpdateOff), a teprve po kompletnm dokreslen je zobrazte (UpdateNow). To provd funkce UpdateGraph. K jednotce se dodvaj i jednotky pro prci s my, zvukem (pp) a klvesnic. Zde je njak ten pklad (k jednotce se dodv dost dobe popsan dokumentace a spousta pklad):


uses WinGraph;
begin
 InitGraph(D8bit,_m640x480,'Test rozlien 640x480');
 UpdateGraph(UpdateOff);
 {nastavme jeden z pedvolench font na tun a velikost 16 pixel}
 {cokoliv pod 6 nen vel.v pixelech, ale nsobi 8 pixel}
 SetTextStyle(TimesNewRomanFont or BoldFont,HorizDir,16);
 (* tady si nco vykreslete (pouvme strnku 0) *)
 UpdateGraph(UpdateNow);
 (* tady meme teba chvli pokat *)
 CloseGraph;
end;  

Pokud Vm toto nevyhovuje, mete pout rovnou Direct Draw. Budete potebovat jednotku (z balku "gx106") DXCommon a DirectDrawFPC spolen se souborem Switches.inc (ve si zkompilujete). Zde jsou implementovny vechny funkce, kter byste mohli volat ve Windows programovacch jazycch. Jednotky u sebe obsahuj velkou spoustu pkaz. Nejhor na vysvtlen je asi to, e ten nejblbj pklad ukazujc metodu PageFlipp m 10 kB zdrojovho textu! Natst ale mete vyut i tutorialy Direct X, kter jsou nap. na adrese www.CeskeHry.cz, ale i v tch pkladech pmo u jednotky je popsn kd celkem pehledn. Problm je v tom, e ne v Direct Draw vbec inicializujete reim, trochu se zapotte. Pokud chcete pracovat s grafikou o trochu lpe, ne Vm nabz nap. WinGraph, budete se do toho muset ponoit (pod Linuxem Vm pob takov programy samozejm tak, pokud pouijete WINE). Strun byste mohli potebovat informace o tchto vcech:


	IDirectDraw4			objekty
	IDirectDrawSurface4		obrazovka


	IDirectDrawSurface4_Blt		vykresl obrazovku
	IDirectDrawSurface4_GetDC	?
	IDirectDrawSurface4_ReleaseDC	?
	PostMessage			zprvy
	SetCursor			kurzor
	IDirectDrawSurface4_Flip	pesune obrazovku do VRAM
	IDirectDrawSurface4__Restore	?
	LoadIcon			nahraje ikonu
	LoadCursor			nahraje kurzor myi
	GetSystemMetrics		informace o XY obrazovky
	ShowWindow			zobraz okno
	UpdateWindow, SetFocus		?
	IDirectDraw_QueryInterface	?
	IDirectDraw4_SetCooperativeLevel
	IDirectDraw4_SetDisplayMode	mn rozlien
	IDirectDraw4_CreateSurface	vytvo "obrazovku"
	IDirectDrawSurface4_GetAttachedSurface
	SetTimer			nastavuje asova  

Pokud se nechcete moit s Direct X a chcete radji zkusit nco, co Vm nabz komfort, mete zkusit jednotky VGFX (obsahuje i tutorial), kter nabz celkem rychl zobrazovn efektn grafiky pod Windows; grafickou st jednotek lx5suite_0760, kter nabz opravdu kompletn ovldn potae (vetn zvuku (na ten Vm mohu jet doporuit nap. Bass20 nebo Fmod350)); Qgtk-Graphic; FPCx-dx (kter zjednodu pouvn Direct Draw); nebo vyut docela oblben JediSDL, kter obsahuje podporuje grafiky, st, ale i zvuk. Navc SDL b zrove jak pod Windows, tak i pod Linuxem, tedy pokud napete aplikaci chodc pod jednm, mete ji rovnou jen zmnou targetu pekompilovat pro druhou platformu. Samozejm, e nauit se pln vyuvat monost tchto jednotek nebude snadn, ale pokud to myslte s programovnm opravdu vn, mli byste s tm zat. Pokud se rozhodnete pro nkterou z tchto vc, asi budete potebovat nsledujc funkce a procedury:


	--- VGFX ---
	(viz. "VGFX - making first steps.doc")


	Window_RegisterClass		Window_CreateClass
	CheckWMCreate			Init_Graph
	Load_Fonts			Load_Pcx
	Init_VW				ScaleSprite
	CursorVisible			Flip_VW
	PutSprite			Flip_DD
	GETALLMESSAGES			HANDLEMINIMIZED
	ApplicationRunning : boolean
	Kill_VW				Kill_Graph
	CheckMemory			TERMINATE
	atd.




	--- LX5SUITE ---
	(dema jsou dostaten pehledn)


	video_open			video.hline
	LoadImage			tsprite.create_assign
	sprite.show			sprite.move
	video_update			sprite.hide
	lx5suite_process		keywaiting
	keyread				mouse.leftbutton
	sprite.free			video_close
	LoadAlpha			CreateImage
	backdrop.paste_area		workspace.alpha_tint
	video_lock			video_unlock
	video.cls			workspace.paste
	workspace.paste_region		backdrop.convert_depth
	video.putpixel			video.line
	video.box			video.bar
	video.ellipse			video.polygon
	video.circle			backdrop.paste_scale
	scalar.resize			scalar.paste_area


	- ovldn videa a grafiky
	- ovldn zvuk
	- prce s fonty TTF
	- vytven GUI (okna, tlatka, plochy)
	- efekty s grafikou
	- pstup na web




	--- SDL Jedi ---
	(obsahuje podrobnou HTML dokumentaci s pklady u kad funkce)


	- grafika a video
	- klvesnice
	- joystick
	- zvukov zazen (WAV)
	- ovldn CD-ROM
	- asova
	- Open GL
	- TCP pes sockety  

Protoe nm tento seril vyel tentokrt docela krtk (omlouvm se za to, e zde nejsou pklady pro pedchoz dva odstavce, ale to bych se to musel nejprve vechno nauit, co udlm, a to osobn budu potebovat), pidm sem jako bonbnek krtkou (!) informaci ovldn WinAPI, kter Vm s pomoc FP umon vytvet aplikace typu Poznmkov blok (bc ve Windows a s WINE i pod Linuxem). Pro tyto ely se nemuste shnt po dnch extra jednotkch. Pokud si sthnete FP pro Windows, tak v adresi DEMOS a WIN32 najdete pr ukzek, jak vytvoit DLL knihovnu, a pop. i njak ten jednodu program. Myslm, e je celkem zbyten vysvtlovat princip tchto program, nebo pokud se o n budete chvli zajmat, pochopte jej sami:


	SendMessage			GetOpenFileName
	GetSaveFileName			GetWindowTextLength
	GetWindowText			SetStatusText
	MessageBox			SetWindowText
	ChooseFont			PostQuitMessage
	SetFocus			GetClientRect
	MoveWindow			GetSysColorBrush
	DefWindowProc			GetStockObject
	LoadIcon			LoadCursor
	WndProc				RegisterClass
	CreateWindowEx			ShowWindow
	UpdateWindow			CreateMenu
	AppendMenu			SetMenu
	CreateStatusWindow		TranslateMessage
	DispatchMessage			DeleteObject  

Samozejm, budete-li mt zjem, napite na INT21H (nkomu jinmu ne m), zda-li by se nechtl ujmout njakho lnku, kter by vysvtloval nkterou konkrtn vc z poslednch tech a tyech odstavc (nap. grafika v SDL; pokud Vm nebudou stait dodvan efektn grafick dema a pklady); budu mezi tmi, kte si dan lnky rdi petou.


J tmto mj seril o grafice uzavu. Zrove konstatuji, e pokud chcete programovat pod DOSem, mete se nyn pln spolehnout na sv sly. Pokud byste ale chtli V program distribuovat a provozovat pod Windows (i Linuxem), vyuijte rozhodn radji njakou s cizch jednotek (pop. WinAPI). Doporuuji bu SDL nebo lx5suite_0760 i VGFX-vesa3 podle toho, co Vm pijde jednodu na nauen se (ideln je samozejm balk, kter podporuje zrove i zvuky, jako je lx5suite_0760 nebo JediSDL-Delphi, pokud se ovem nespolehnete na zvukov jednotky cizch stran - ale o tom snad nkdy pt).

2006-11-30 | Martin Lux
Reklamy: