 |
Teksture
marmorja |
|
1. Definicija naloge
2. Potek resevanja
2.1 Simulacija marmorja
3. Zajem slike
4. Upravljanje s programom
4.1 Zapis slike
5. Detajli programa
5.1 Inicializacija grafike
5.2 Komunikacija z uporabnikom
5.3 Nastavitev barvne palete,
zajem in prenos slike
6. Zakljucek
7. Reference
Definicija naloge
Izdelati je treba program za generacijo teksture marmorja,
in zapis slike v uporaben slikovni format.
Potek resevanja
Simulacija marmorja
Iz opazovanja marmorja lahko povem, da jih je veliko vrst. Poznamo marmor
-
kjer se barva enakomerno preliva iz elipsoidnih struktur iz srednje
sive v umazano belo, z enakomernimi kamencki brez necistoc
-
marmorje violicnih barv
-
marmorje s prosto razporejenimi vkljucki razlicnih odtenkov crne do
bele barve razlicnih velikosti
Odlocil sem se za prvo varianto. Program generira nakljucno stevilo
elipsoidov (40 do 127), z nakljucno pozicijo XYZ (0 do 1m) in jakostjo
F (0 do 1). Poleg tega se generira tri-dimenzionalno polje tock (128 x
128 x 128), s celostevilcnimi jakostmi (0 do 255). Preracun za kamen se
bo vrsil med koordinatnimi dolzinami XY (-0.5 do 1.5m) in Z (0 do 1m).
Zajem slike
Sliko zajamemo na presecni ravnini kvadra. Ravnina je popisana s tocko
[XYZ], to je koordinato centra ekrana, ter z normalnim vektorjem ravnine.
Le ta je dolocen s kotom [j]
med projekcijo normale na ravnino XY in osjo X ter s kotom [J]
med ravnino XY (oz. projekcijo normale) ter normalnim vektorjem (horizontalni
kot normale ravnine ter elevacijski kot normale ravnine). Poleg tega s
povecevalnim parametrom [Zoom] dolocimo ogljisca ekrana.
Zajem slike poteka za vsak piksel ekrana posebej. Skeniramo
vrstice od vrha proti dnu in piksle od leve proti desni. Koordinate vsakega
piksla [ij] posebej preracunamo v koordinate marmornega sistema [xyz] po
formuli:
I = (i-320) J = (j-240)
x = X + (sin(j)*I
+ sin(J)*J* cos(j))*Zoom/320
y = Y - (cos(j)*I
- sin(J)*J* sin(j))*Zoom/320
z = Z - (cos(J)*J)*Zoom/320
Stevilke 320 in 240 veljajo za graficni nacin 640x480.
Ko se dolocijo koordinate posameznega piksla, se poisce barva le
tega. Paleta barv marmorja se nahaja linearno razporejena med RGB tockama
[00 00 00] in [FF FF FF] hex. Robni barvi sem dolocil vizualno ob primerjavi
marmorja. (Velja za paleto StonPal0.COL) Glede na to, da najnatancnejsi
graficni nacini delujejo v RGB direktnem nacinu 8:8:8, se da v RGB prostoru
koordinatne osi R,G in B razdeliti na najvec 256 delov. Ce v to RGB kocko
postavimo daljico, bo ta daljica imela svojo dolzino glede na koordinatne
osi Dr Dg in Db. Le v redkih primerih bo katera od dolzin Dr Dg Db dolga
256 enot. Palete cistih barv rdece, zelene, modre, rumene, turkizne, violicne
ter sive bodo imele eno dve ali vse tri stranice dolge 256 enot. V nasem
primeru pa je razpon Dr Dg Db [+255 +255 +255] dec. Ker je koordinatni
sistem RGB celostevilcen sledi, da nam lahko daljica priskrbi le toliko
razlicnih barv, kot je dolga njena najdaljsa diferenca plus ena, v nasem
primeru je to 256 barv. Zapis slike, katere paleta se nahaja le na daljici,
s komponentami RGB bi bil zato potraten iz razlogov velikosti, kompresibilnosti
ter hitrosti izrisovanja. Zato sem se odlocil za graficni nacin z 256 fiksnimi
barvami 640x480x256.
Barva posameznega piksla se torej doloci glede na njegove koordinate
[xyz]. Preverjamo oddaljenost centra vseh elipsoidov od koordinat piksla.
Glede na oddaljenost in jakost elipsoid (aditivno) prispeva vrednost, glede
na vsoto katerih se na koncu doloci barva (0 = nevtralna barva, 1 = barva
elipsoida).
r2 = ((x-Stone.DotX[u])/View.RX)2 + ((y-Stone.DotY[u])/View.RY)2
+ ((z-Stone.DotZ[u])/View.RZ)2
P = (P + e-0.001 * Stone.DotF[u] * r10)
kjer so parametri RX, RY in RZ deformacije krogle v elipsoid.
Poleg tega moramo generirati se vpliv razdrobitve na kamencke.
Le ti naj bi bili veliki cca. 1 cm. Uporabil sem pristop iz mehanike fluidov.
Tri-dimenzionalno polje tock, je polje izvorov. Glede na koordinate piksla
dolocimo 25 sosednjih izvorov. Glede na to, da so si izvori 10 mm narazen,
lahko z njimi sestavimo le kocko s stranico 1280 mm, v prvem oktantu koordinatnega
sistema z ohljiscem v izhodiscu. Za vsa morebitna preverjanja izven te
kocke, se koordinate preracunavajo po modulu 128. 25 sosednjih izvorov
ima torej vsak svojo zacetno hitrost. Glede na oddaljenost piksla od izvora
se izracunajo tri komponente hitrosti na koordinatah piksla, celotna hitrost
pa je
dv = (Stone.P[a][b][c] * e-0.125* r4)
Modificirana absolutna hitrost v preiskovani tocki nam posvetli
barvo tocke, tocke na nicelni tokovnici pa ne spreminjajo ozadja.
Upravljanje programa
Program deluje v okolju DOS in potrebuje en vhodni parameter:
Za paleto barv se smatra, da so barve podane v 6-bitni globini, zaporedje
RGB (zaradi programa s katerim sem generiral paleto), program pa inicializira
grafiko 640x480x256 na standardno SVGA 6-bitno globino palete.
Pri zaganjanju programa le ta zapisuje mozne probleme v datoteko
TREE.ERR. Med tekom programa se da spreminjati parametre ravnine:
-
Povecanje X : Rt
-
Zmanjsanje X : Lt
-
Povecanje Y : Up
-
Zmanjsanje Y : Dn
-
Povecanje Z : LAlt Up
-
Zmanjsanje Z : LAlt Dn
-
Povecanje j
: LCtrl Lt
-
Zmanjsanje j
:
LCtrl Rt
-
Povecanje J
: LCtrl Dn
-
Zmanjsanje J
:
LCtrl Up
-
Zoom In : RCtrl
-
Zoom Out : RAlt Gr
Za zajem slike 640x480 potrebuje program na 80486 33MHz cca. 70 minut.
Zaradi tega takoj po spremembi zgornjih parametrov opravimo preliminarno
risanje 80 x 60 pikslov, ki se razmazejo na povrsino 8x8. Slika je zato
grda, vendar se kalkulacija na Pentiumu opravi tako rekoc takoj. Ko zaslutimo,
da smo nasli zeljeni prerez, sliko fino spoliramo.
Poliranje : Enter
Ko je slika spolirana, jo shranimo v nekompresiran format TarGA 640x480x256
pod vpisano ime. Vse shranjene slike bodo nosile inkrementirane indekse.
Shranjevanje : F10
Kot receno traja poliranje eno minuto. Medtem, ko procesor opravlja
idealni loop in preverja tipke, lahko izstopimo v DOS po regularni poti.
Ta pot ne bo delovala med preracunavanjem. Normalni izhod : ESC
Ce iz katerega koli razloga program obvisi ali ne zelimo cakati konca
izracuna, lahko prisilno izstopimo v DOS pod pogojem, da ni prislo do napake
med klicanjem interrupta tipkovnice. Prisilni izhod : Ctrl-Alt-Del
Zapis slike
Sliko sem se odlocil zapisati v format TarGA, ker sem ga ze prej poznal.
Format targa je nekompresiran graficni format z 256 barvnim in dirketnim
RGB nacinom zapisa.
Zgradba:
Velikost Stevilo Opis
Velikost
|
Stevilo
|
Opis
|
byte
|
12
|
glava
|
word
|
1
|
sirina X
|
word
|
1
|
visina Y
|
byte
|
2
|
glava
|
3byte RGB
|
256
|
paleta
|
byte
|
X * Y
|
slika
|
Detajli Programa
Inicializacija grafike
Grafiko sem inicializiral preko VESA BIOS interrupta. Zaradi napredka
racunalniske tehnologije smatram, da imajo vsi racunalniki graficno kartico,
ki podpira zeljeni graficni nacin, zato sem preverjanje oklestil iz procedure.
Komunikacija z uporabnikom
Komunikacija poteka preko tipkovnice. Zaradi enostavnejsega zaznavanja
pritisnjenih tipk sem ze pred casom napisal proceduro, ki se izvede vsakic,
ko tipkovnica generira interrupt (sprememba stanja na tipkovnici). Sprva
je procedura shranjevala do 5 tipk, vendar sem zaradi nesmotrnosti proces
poenostavil na dve katerikoli tipki. Dokler je neka tipka pritisnjena,
bo njena modificirana koda shranjena v Command.Keys[0/1]. Pazljivost velja
za tipko Pause, ki se obnasa drugace in jo je treba po uporabi "rocno"
izbrisati iz spremenljivke - oznaciti prosto mesto. Procedura zaznava posebej
status tipk Ctrl, Alt in Del, in sicer v spremenljivki Command.Release[2]
oznacuje bit 0 stisnjen Ctrl, bit 1 Alt in bit 2 Del.
Nastavitev barvne palete, zajem in prenos slike
Nastavitev palete poteka preko VGA portov 0x3C8 in 0x3C9. Da bi se izognil
pogostemu preklapljanju bank graficne kartice ter kasneje olajsal proces
shranjevanja, sem se odlocil sliko izrisovati na virtualni zaslon (VGA.Virtual[i][j]),
od koder se po koncu zajema z operacijo premika bloka prekopira v spomin
graficne kartice ter nastavi novo 64 kb banko.
Zakljucek
Program sem prevedel z Watcom-ovim C/C++/Asm prevajalnikom. Program
uporablja DOS4GW extender, ki preklopi procesor iz realnega nacina v zasciteni
(proteceted) nacin. Posledica tega je, da se zacnejo namesto 16-bitnih
registrov v procesorju uporabljati celotni (32-bitni) registri. Tako se
za naslavljanje spomina ne uporabljajo vec 20-bitne kombinacije segmentnih
in offsetnih registrov, ki nam lahko zagotovijo le 1 Mb spomina, ampak
32-bitni offsetni registri v kombinaciji s 16-bitnim selektorjem, s katerimi
lahko naslovimo najmanj 4 Gb spomina.
Reference:
Miran Klemenc
Ljubljana, 21. avg. 1998