2010. február 3., szerda

Tao Start 02 - Color Quad

Legutóbb ott hagytuk abba az ismerkedést a Tao-val, hogy beüzemeltük a framework-öt és elkészítettük az első háromszögünket. Ez is már valami, de ideje tovább lépni. De előtte még felhívnám a figyelmet arra, hogy az OpeGL a C nyelvre épül ezért minden utasítást az eredeti szintaxisban érdemes megismerni, mert így később bármilyen OpenGL forrást könnyedén megérthetünk. Ahány wrapper annyiféle megvalósítás, de amint ráhangolódunk magára az OpenGL-re könnyedén fog menni minden menedzselt környezetben is. Ok, akkor folytassuk ott ahol abbahagytuk, de még mindig csak aprókat lépünk.
Tudjuk, hogy egy 3d-s objektumnak vannak csúcspontjai, a csúcspontok összekötéséből poligonok (sokszögek) állnak elő. Több polygon alkothat egy testet, ezek lesznek a test oldallapjai. Rajzoló utasításokat az OGL-ben a glBegin(mitrajzoljon); és glEnd; közé lehet tenni. Tehát az említett megjegyzéses részbe be is írhatjuk ezt az utasítás párt. Persze glBegin és glEnd párból bármennyi lehet egymás után (egymásba ágyazva nem!). Amint látható a glBegin-nek van még egy paramétere is. Ez határozza meg, hogy a glBegin és glEnd közötti részben megadott pontokat miként kezelje az OpenGL. Először leírom, milyen értékeket kaphat:
  1. GL_POINTS - Egyedülálló pontokat rajzol
  2. GL_LINES - Egyenest rajzol úgy, hogy a megadott pontokat párosával összeköti
  3. GL_POLYGON - A megadott pontokat mind egy sokszög pontjainak tekinti az utoljára megadott pontot a legelsővel összeköti a végén. A poligon lehetőleg konvex legyen!
  4. GL_TRIANGLES - A megadott pontokból hármasával háromszögeket rajzol.
  5. GL_QUADS - A pontokból négyesével négyszögeket rajzol
  6. GL_LINE_STRIP - Vonalat rajzol, tehát az egymást követő pontokat összeköti
  7. GL_LINE_LOOP - Hasonló az előzőhöz, csak az utolsó és első pontot is összeköti így gyakorlatilag egy hurkot rajzol.
  8. GL_TRIANGLE_STRIP - 3szög szalagot rajzol: Az első három pont lesz egy háromszög, ezután minden egyes pont egy újabb háromszöget határoz meg úgy, hogy az előző két pont és az aktuális pont lesznek a háromszög pontjai.
  9. GL_TRIANGLE_FAN - Legyező szerűen összekapcsolódó háromszögeket rajzol.
  10. GL_QUAD_STRIP - Négyszögekből álló szalagot rajzol.
Egy kép többet ér ezer szónál
Akkor most rajzoljunk valami:

glBegin(GL_QUADS);
glVertex3f(-0.5, +0.5, 0.0);
glVertex3f(+0.5, +0.5, 0.0);
glVertex3f(+0.5, -0.5, 0.0);
glVertex3f(-0.5, -0.5, 0.0);
glEnd;

Ez a kis kódocska ha beírjátok egy szép fehér téglalapot fog rajzolni a képernyő közepére. Aki programozott már raszteres grafikusan annak ez igen furcsán hat. Mint látjuk glBegin-nek paraméterben GL_QUADS van megadva, tehát legalább 4 pont kell, hogy legyen megadva, hogy rajzolni tudjon. Mint nyilván kitaláltad a glVertex3f eljárással lehet 3D-s pontot rajzolni. Ennek a vertexes eljárásnak több fajtája is van az eljárás nevében a szám (jelen példánál 3) azt jelenti, hogy hány koordinátát adsz meg az f pedig, hogy milyen típusú adatot használsz. Mindegy, egyenlőre használjuk a glVertex3f-et, hisz így 3 koordinátát adhatunk meg, tehát "3d-s" lesz a pont. A glVertex3f paraméterei értelemszerűen a pont x, y és z koordinátái. A koordináták [-1,1] tartományban esnek a képernyőre (alapértelmezett vetítésnél). A koordináta-rendszer tehát teljesen olyan, mint az általános iskolában tanult Descartes-féle koordináta rendszer (felfele nő az y, balra nő az x, z pedig "kifele" nő és a z tengely negatív iránya felé nézünk a (0,0,1) pontból). Ez persze az alapértelmezés. Ja és alapértelmezés szerint csak minden koordináta [-1,1] tartományba eső pontja látszik a képernyőn (tehát egy origó középpontú 2x2x2-es kocka tartalma). Most, hogy már tudunk rajzolni ideje színt vinni a programunkba. Ezt a glColor3f(r,g,b); eljárás segítségével tehetjük (ennek is van több változata, de erről majd később). Itt paraméterben értelemszerűen a szín piros, zöld és kék összetevőit állíthatjuk be, melynek már említett okok miatt [0,1] tartományba kell esniük. Ezt a glBegin-glEnd közt akárhányszor meghívhatjuk. Ha beállítunk egy színt pl. pirosat:
glBegin(GL_QUADS);
glColor3f(1,0,0);
glVertex3f(-0.5, +0.5, 0.0);
glVertex3f(+0.5, +0.5, 0.0);
glVertex3f(+0.5, -0.5, 0.0);
glVertex3f(-0.5, -0.5, 0.0);
glEnd;

Akkor onnantól kezdve a pontok és így a poligon is piros lesz. De mi van, ha minden pontnál külön átállítjuk a színt?
glBegin(GL_QUADS);
glColor3f(1,0,0);
glVertex3f(-0.5, +0.5, 0.0);
glColor3f(0,1,0);
glVertex3f(+0.5, +0.5, 0.0);
glColor3f(0,0,1);
glVertex3f(+0.5, -0.5, 0.0);
glColor3f(1,1,1);
glVertex3f(-0.5, -0.5, 0.0);
glEnd;

Ha ezt így lefuttatjátok egy szépen színezett téglalapot láthattok. A csúcspontok között az OpenGL ugyanis színátmenetet képez lineáris interpolációval, amit most itt nem írok le, hogy működik, de ha valakit érdekel, akkor szívesen elmagyarázom. A fenti példa a Tao-val a következőképpen néz ki:
public partial class MainForm : Form
{
    public MainForm()
    {
        InitializeComponent();
        {
            this.ClientSize = new Size(800, 600);
            this.Text = "TaoGL - Color Quad";
            this.glControl.InitializeContexts();
            this.Focus();
        }
    }

    private void glControl_Paint(object sender, PaintEventArgs e)
    {
        Gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        Gl.glClear(Gl.GL_COLOR_BUFFER_BIT);

        Gl.glBegin(Gl.GL_QUADS);
        {
            Gl.glColor3f(1f, 0f, 0f);
            Gl.glVertex3f(-0.5f, +0.5f, 0.0f);
            Gl.glColor3f(0f, 1f, 0f);
            Gl.glVertex3f(+0.5f, +0.5f, 0.0f);
            Gl.glColor3f(0f, 0f, 1f);
            Gl.glVertex3f(+0.5f, -0.5f, 0.0f);
            Gl.glColor3f(1f, 1f, 1f);
            Gl.glVertex3f(-0.5f, -0.5f, 0.0f);
        }
        Gl.glEnd();
    }
}

A kód futtatása után a következő képet kapjuk:


A mai lecke ennyi. Próbáljátok ki a GL_QUADS-on kívül a többi rajzolási módot is. A példa teljes forrása itt tölthető le:


A fenti tutorial PowR által írt a http://free-pascal.extra.hu/ oldalon megtalálható OGL tutorial alapján készült el. Köszönet érte PowR-nek!

0 megjegyzés :

Megjegyzés küldése