|
|
SPACEHAWKS
WORLDNEWS
ISSUE 17 |
|
|
|
MysticView
- GuiGFX - Render
|
Az elmúlt
időben egyre több új program igényli a címben szereplő library-t. Az ember
jóihszeműen töltögeti le a dolgokat aminetről, mire a programok installálás
után kiírják "Cúl dont open guigfx.library" etc -- mire program letörlődik...
Így járt volna nálam a guigfx, ha nem nekem kellene beszerezni a haveroknak
az internetről a különböző stuffok új verzióit. Jó szokásomhoz híven most
is leszedtem a readme filéját is, és nyomban megbántam, hogy nem szenteltem
neki komolyabb figyelmet...
A guigfx
és társai egy komplett hardverfüggetlen grafikus rendszert alkotnak, amely
rendkívül megkönnyíti bármilyen grafikus fájlokat kezelő alkalmazás elkészítését.
A három library három absztrakciós réteget képez:
A render.library
a grafikus feldolgozó mag (kernel), de ez csak chunky (8 - 32 bites) formátummal
foglalkozik. Tud alfa csatorna kezelést, akár 24 bites histogramokat, truecolor
<-> palettás konverziót akár dithereléssel, képes nagyítani, kicsinyíteni
vagy textúrázni, és még a HAM módokat is ismeri... Egyszóval egy csomó olyan
funkciót ismer, amely jól jön egy képfeldolgozó programnak.
A guigfx.library
erre a magra épülve lehetővé teszi a reá írt alkalmazás számára, hogy a grafikákat
a lehető legjobb minőségben jelenítse meg tetszőleges grafikus rendszeren.
A guigfx-nek mindegy, hogy a kép 24 bites képen CGFX vagy P96 alatt, vagy
ECS/AGA-n 2 bites vagy akár HAM8 módban jelenik meg... A képeket a V43-as
picture.datatype-pal tölti be (persze képes bármely verzióval együttműködni,
de ezzel a leghatékonyabb -- AGA felhasználóknak a P96-os V43 pic.dt ajánlott).
A mysticview.library
a legfelső, éppen ezért igen specializált réteg, szinte kifejezetten csak
képek megjelenítésére használatos. (Épp ezt teszi egy hasonló nevű képnéző
program.)
Én itt a
GuiGFX-re koncentrálok, hiszen egy hétköznapi programozó, ki némi grafikát
kíván varázsolni programja felhasználói interfészébe, ezt a réteget választja.
Ha programunk megnyitja a GuiGFX-et, a GuiGFX megnyitja magának a renderlibet,
nekünk ezzel nem kell foglalkozni (illetve annyit azért kell, hogy a LIBS:-ben
ott egy kuksoljon a render.library nevű file...). Épp ezért célszerű a program
doksijában a júzer orrára kötni, hogy a programnak a GuiGFX és a Render.lib
is kell, mert különben szegény letölti a legújabbat GuiGFX-et, és a program
mégsem tudja megnyitni. Ja, az egész cuccos ma 3.0-át igényel, amely ma már
amúgy is elfogadott minimumnak tekinthető... (Bár az AI szerint már ez is
elavult.)
GuiGFX-ből
elérhető persze az összes renderlib funkció is (mert hiszen a libek egymásra
épülnek), az összes ilyen funkciót a DoPictureMethod() függvénnyel érhetjük
el. (Én ezt még nem használtam, hiszen nem volt rá szükségem.)
A GuiGFX
egyik fő funkciója tetszőleges számú, színmélységű és (fájl)formátumú kép
megjelenítése bármilyen képernyőn, másik fő funkciója pedig a c2p konverzió.
Utóbbira három igen látványos példa is található a GuiGFX archívumban, én
főként az előbbi miatt ragadtam most billentyűzetet.
Mivel 16
vagy 24 bites képernyőformátumnál a libnek nincs sok dolga, így a megjegyzéseim
AGA-ra, vagy max 8 bites chunky képernyőmódra vonatkoznak.
Három objektummal
kell megismerkednünk:
PenShareMap:
ez tulajdonképpen egy histogram. A histogram arra jó, hogy megszámolja, milyen
színek vannak egy képen. Készülhet egy vagy több képről, vagy képrészletekről,
ezek GuiGFX-nél súlyozhatók is, azaz egy "fontosabb" képet nagyobb súllyal
a histogramhoz adva a majdani palettában ez a kép több színt foglalhat, a
megjelenített kép színei közelebb lesznek az eredetihez.
DrawHandle:
ez az objektum írja le, hogyan kell tetszőleges képet egy adott RastPort/ColorMap
kombináción megjeleníteni.
Így képek
megjelenítése a következőképpen történik:
struct Screen *screen;
struct Window *window;
APTR pic;
APTR psm;
APTR drawhandle;
...
screen = OpenScreenTags(...);
pic = LoadPicture("valami.pic", TAG_DONE);
psm = CreatePenShareMap(TAG_DONE);
if (pic && psm)
{
AddPicture(psm, pic, TAG_DONE);
drawhandle = ObtainDrawHandle(psm, window->RPort, screen->ViewPort.ColorMap,
TAG_DONE);
}
DeletePenShareMap(psm);
if (drawhandle)
{
DrawPicture(drawhandle, pic, XPOS, YPOS, TAG_DONE);
}
...
ReleaseDrawHandle(drawhande);
DeletePicture(pic);
Most jöjjön egy kissé
bővebb példa: (itt a "tilepic" pl. egy stratégiajáték grafikus elemeit tartalmazza).
Inicializálás:
APTR tilepic, pic1, pic2;
APTR psm;
APRT drawhandle;
tilepic = LoadPicture("tiles.ilbm", GGFX_UseMask, TRUE, TAG_DONE);
pic1 = LoadPicture("pic1.ilbm", TAG_DONE);
pic2 = LoadPicture("pic2.ilbm", TAG_DONE);
psm = CreatePenShareMap(TAG_DONE);
if (!(mainpic && pic1 && pic2 && psm))
{
/* error */
}
AddPicture(psm, pic1, TAG_DONE);
AddPicture(psm, pic2, TAG_DONE);
AddPicture(psm, tilepic, GGFX_Weight, 5, TAG_DONE);
drawhandle = ObtainDrawHandle(psm, &screen->RastPort, screen->ViewPort.ColorMap,
TAG_DONE);
/* ez már nem kell */
DeletePenShareMap(psm);
Az ObtainDrawHandle()
hívásakor opcionálisan megadhatjuk a célképernyő módját is a GGFX_ModeID,
taggal, hiszen a GuiGFX csak így "veheti észre" a spéci HAM, HAM8 vagy EHB
módokat.
Ennél a pontnál el kell
döntenünk, hogy érdemes-e BitMap-et gyártani a képekből. A példánkban feltételezzük,
hogy a tilepic elemei gyakran kerülnek megjelenítésre, míg a pic1 és pic2
csak ritkább eseményeknél (pl. új kör esetén stratégiajátéknál). Így előbbiből
készítünk bittérképet, utóbbiakból nem:
struct BitMap *tilebm;
tilebm = CreatePictureBitMap(drawhandle, tilepic,
GGFX_DitherMode, DITHERMODE_NONE,
TAG_DONE);
if (!tilebm)
{
/* error */
}
Szükségünk lehet egy kép
"maszkjára" is, ha az bizonyos helyeken átlátszó:
ULONG picwidth, picheight;
PLANEPTR tilemask;
GetPictureAttrs(tilepic,
PICATTR_Width, &picwidth,
PICATTR_Height, &picheight,
TAG_DONE);
tilemask = AllocRaster(picwidth, picheight);
if (!tilemask)
{
/* error */
}
CreatePictureMask(picture, tilemask, ((picwidth+15)/8) & 0xFFFE, TAG_DONE);
Ezután a BitMap-pé alakított
képet törölhetjük is:
DeletePicture(tilepic);
Persze a pic1 és a pic2
még kell, hiszen ezekből nem csináltunk BitMap-et. Így végére is értünk az
inicializálásnak. Ha ezután egy elemet ki akarunk rakni a tilepic-ből a képre,
a BltMaskBitMapRastPort() függvénnyel tehetjük meg, a tilebm a forrás BitMap,
tilemask pedig a maszk. Akkor sincs gond, ha a betöltött képnek nem volt maszkja
(vagy alfa csatornája), ilyenkor egy teljesen kitöltött maszkot kapunk, azaz
semmi sem lesz átlátszó. A másik két picet a következőképpen tehetjük ki:
success = DrawPicture(drawhandle, pic1, 0, 0, TAG_DONE);
Kissé egyszerűbb, ugye?
Napersze nem olyan hatékony (főként ECS vagy AGA rendszeren) mint a CreateBitMap()-os
megoldás, de CHIP RAM-ot sem igényel, "röptében" alakítódik a kép a megfelelő
formátumra.
Ezek után a felszabadítás:
ReleaseDrawHandle(drawhandle);
FreeBitMap(tilebm);
FreeRaster(tilemask, picwidth, picheight);
DeletePicture(pic1);
DeletePicture(pic2);
Persze mindezeket csak
az ablakaink bezárása vagy törlése után illik megtenni, mert a GuiGFX rendszer
által lefoglalt színek ReleaseDrawHandle() után felszabadulnak, és a style
guide szerint ekkor már nem lehet a képernyőn a képekből egyetlen pixel sem.
A GuiGFX rendszer kiválóan
használható Custom screen-en is, csak a kép nyitásakor meg kell mondanunk
az Intuition-nek, hogy "shared" palettát szeretnénk:
OpenScreenTags(NULL,
...
SA_Type, CUSTOMSCREEN,
SA_SharePens, TRUE,
TAG_DONE);
Ennyi. Jó GuiGFX-elést
mindenkinek!
Att1s^SH
|