Teksture marmorja

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

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:

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

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:

- Borland Turbo Assembler 3.0 Quick Reference Guide

- PCGPE (PC Game Programmer`s Encyclopedia)