Baigiam žiūrėti į juodą langą ir pradedam dailės pamokas.
programose galima piešti tik kelias figūras: tašką, tiesę, keturkampį ir trikampį. Šios figūros vadinamos primityvais (kadangi jos primityvios :) ). Ką reiškia primityvios? Tai reiškia, kad visos sudėtingos figūros, visi sudėtingi modeliai (žmonės, technika) sudaryti iš šių paprastų figūrų (dažniausiai iš trikampių). Keturkampis yra vartojamas retai, kadangi tai iš tikrųjų du trikampiai, tačiau kūrėjai truputį palengvino darbą. Bet pradėsime nuo taško.

Ką mes žinome apie tašką? Tik tai, kad jis turi kažkokias savo koordinates. Na, jis taip pat gali būti skirtingų dydžių (didelis taškas jau yra dėmė). Pakeiskit šiek tiek jau esamą DrawGL funkciją ir pridėkit dar vieną procedūrą.

procedure Render; // Patogumui visas piešimas vyks naujoje procedūroje
begin
glTranslatef(0.0, 0.0, -3.0); // Pastumiam sceną 3 vienetais prieš Z ašį
  glBegin(GL_POINTS); // Pradedame piešti tašką
    glVertex2f(0.0, 0.0); // Taško koordinatės (0, 0)
  glEnd; // Baigiam taškų piešimą
end;
 
function DrawGL(): Bool;
begin
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
 
Render; // Iškviečiame piešimo procedūrą
 
glLoadIdentity;
DrawGL:= True;
end;

Paaiškinti, manau, reikia tik naujos procedūros turinį. glTranslate procedūra transformuoja matricą. Rezultatas – postūmio matrica, t.y. visa scena kažkiek pasislenka. Šiuo atveju aš ją pastūmiau trim vienetais į ekrano vidų, kad taškas būtų matomas (kitaip jis būtų prieš langą ir jo nematytumėt). Štai pavyzdys, kada naudojama gale raidelė „f“. Tai reiškia, kad argumentai – glFloat tipo (trupmeniniai). Šis tipas naudojamas dažniausiai.

Aš minėjau komandinius skliaustus glBegin ir glEnd. Tarp jų dažniausiai vykdomos piešimo funkcijos. Tačiau glBegin turi vieną parametrą – piešiamą objektą. Šiuo atveju tai GL_POINTS (taškai). Funkcija glVertex reiškia viršūnę. Kadangi taškas turi tik vieną viršūnę, patį save, tai šiuo atveju ši procedūra piešia vieną tašką nurodytomis koordinatėmis. Tokių taškų galima pridėti begalę.

procedure Render;
begin
glTranslatef(0.0, 0.0, -3.0);
  glBegin(GL_POINTS);
 
    glVertex2f(0.0, 0.0);
    glVertex2f(1.0, 1.0);
    glVertex2f(1.0, 0.0);
    glVertex2f(0.0, 1.0);
    glVertex2f(-1.0, 0.0);
    glVertex2f(-1.0, 1.0);
    glVertex2f(-1.0, -1.0);
    glVertex2f(1.0, -1.0);
    glVertex2f(0.0, -1.0);
 
  glEnd;
end;

Dabar ekrane bus daug mažyčių taškelių. Juos galima padidinti prieš glBegin pridėjus glPointSize(7). Galite išmėginti. Iš pradžių taškas buvo vieno pikselio dydžio, o dabar 7×7. Kaip matote, tokių išmatavimų objektas negali būti apvalus, todėl šie taškai yra kvadratiniai. Tai galima pakeisti įjungus funkciją GL_POINT_SMOOTH.

procedure Render;
begin
glTranslatef(0.0, 0.0, -3.0);
glPointSize(7);
glEnable(GL_POINT_SMOOTH);
  glBegin(GL_POINTS);
    glVertex2f(0.0, 0.0);
  glEnd;
glDisable(GL_POINT_SMOOTH);
end;

Taskas pic

Įvairūs įjungimai vykdomi glEnable pagalba, o išjungimai – glDisable (su tuo pačiu parametru). Išjunginėti gale patartina, norint atlaisvinti papildomai užimamus resursus.

Kaip matot, viskas labai paprasta ir nesunku. Noriu, kad atkreiptumėt dėmesį į tai, kad koordinačių vienetai nėra sutartiniai. Tai ne centimetrai, tai ne piksleliai ir t.t. Vienetai priklauso nuo jūsų fantazijos. Jei norit, tebūnie tai kilometrai. Jei norit – milimetrai. Vis tiek figūros bus tokio pačio dydžio.

Taškas yra taškas, todėl jam tereikia nurodyti koordinates vieną kartą. Tiesei – du kartus. Pirmas kartas – pradžios taškas, antras – pabaigos, kitaip tiesė nebus pavaizduota. glBegin parametras bus GL_LINES. Trikampiui – trys taškai ir GL_TRIANGLES parametras. Keturkampiui atitinkamai keturi taškai ir parametras GL_QUADS. Yra ir dar keli variantai, bet jų neliesime.

Norint sutalpinti dvi dideles figūras reikia porą kartų atitinkamai transformuoti matricas. Vienai figūrai matricą paslinkti į kairę, kitai – į dešinę (nuo paskutinio sustojimo vietos).

procedure Render;
begin
// Trikampis
glTranslatef(-1.5, 0.0, -6.0);
glBegin(GL_TRIANGLES);
 glVertex2f(0.0, 1.0);
 glVertex2f(-1.0, -1.0);
 glVertex2f(1.0, -1.0);
glEnd;
 
// Kvadratas
glTranslatef(3.0, 0.0, 0.0);
glBegin(GL_QUADS);
 glVertex2f(-1.0, 1.0);
 glVertex2f(-1.0, -1.0);
 glVertex2f(1.0, -1.0);
 glVertex2f(1.0, 1.0);
glEnd;
end;

Trikampis vs Kvadratas

Taigi porą kartų panaudojau glTranslate. Pridėkime dar ir spalvas. Jas galima nustatyti kaip prieš, taip ir glBegin viduje. Prieš trikampio piešimą pridėkite eilutę glColor3f(0.0, 1.0, 1.0), o prieš kvadrato - glColor3f(0.0, 1.0, 0.0). Dabar figūros spalvotos. Pakaitaliokit argumentus, pažiūrėkite kaip viskas keičiasi. Atsiminkite, kad šiuo atveju didžiausias argumetas yra 1.0, o mažiausias – 0.0, kadangi spalvų nėra begalybė. O dabar pažiūrėkit į šį variantą.

procedure Render;
begin
// Trikampis
glTranslatef(-1.5, 0.0, -6.0);
glBegin(GL_TRIANGLES);
 glColor3f(1.0, 1.0, 0.0);
 glVertex2f(0.0, 1.0);
 glColor3f(0.0, 1.0, 0.0);
 glVertex2f(-1.0, -1.0);
 glColor3f(0.0, 1.0, 1.0);
 glVertex2f(1.0, -1.0);
glEnd;
 
glTranslatef(3.0, 0.0, 0.0);
glRotatef(45.0, 0.0, 0.0, 1.0);
glBegin(GL_QUADS);
 glColor3f(1.0, 0.0, 0.0);
 glVertex2f(-1.0, 1.0);
 glColor3f(0.0, 1.0, 0.0);
 glVertex2f(-1.0, -1.0);
 glColor3f(0.0, 0.0, 1.0);
 glVertex2f(1.0, -1.0);
 glColor3f(1.0, 0.0, 1.0);
 glVertex2f(1.0, 1.0);
glEnd;
end;

Spalvos

Spalva kiekvienai viršūnei nustatoma atskirai ir to rezultatas – švelnus spalvų susiliejimas. Naujoji funkcija glRotatef pasuka matricą. Iš pradžių nurodomas kampas, o po to ašis, pagal kurią reikia sukti. Pasukinėkime abi figūras. Visų pirma prie globaliųjų kintamųjų pridėkite dar vieną: Rot: glFloat = 0.0. Tada pakeiskite savo funkciją.

procedure Render;
begin
glTranslatef(-1.5, 0.0, -10.0);
glRotatef(Rot, 1.0, -1.0, 0.0);
glBegin(GL_TRIANGLES);
 glColor3f(1.0, 1.0, 0.0);
 glVertex2f(0.0, 1.0);
 glColor3f(0.0, 1.0, 0.0);
 glVertex2f(-1.0, -1.0);
 glColor3f(0.0, 1.0, 1.0);
 glVertex2f(1.0, -1.0);
glEnd;
 
glTranslatef(3.0, 0.0, 0.0);
glRotatef(Rot, 0.0, 0.0, 1.0);
glRotatef(45.0, 0.0, 0.0, 1.0);
glBegin(GL_QUADS);
 glColor3f(1.0, 0.0, 0.0);
 glVertex2f(-1.0, 1.0);
 glColor3f(0.0, 1.0, 0.0);
 glVertex2f(-1.0, -1.0);
 glColor3f(0.0, 0.0, 1.0);
 glVertex2f(1.0, -1.0);
 glColor3f(1.0, 0.0, 1.0);
 glVertex2f(1.0, 1.0);
glEnd;
 
Rot:= Rot + 0.1;
If Rot = 360
  then Rot:= 0;
end;

Posukis

Žinoma, gavosi kažkokia nesamonė, bet figūros sukasi! :) Kolkas figūros labai plokščios, bet tinkamai jas sujungus galima gauti ir trimatį vaizdą. Tam reikia pridėti Z ašį ir naudoti glVertex3f. Norint pavaizduoti kubą reikės nupiešti šešis kvadratus. O jei dar kiekvieno kvadrato kiekvienai aukštinei priskirsime vis kitą spalvą, kodo gausis nemažai.

procedure Render;
begin
glTranslatef(0.0, 0.0, -5.0);
glRotatef(Rot, 1.0, 1.0, 1.0);
glRotatef(Rot, 0.0, 1.0, 0.0);
glBegin(GL_QUADS);
    glColor3f(0.0,1.0,0.0);
    glVertex3f( 1.0, 1.0,-1.0);
    glColor3f(0.6, 0.1, 1.0);
    glVertex3f(-1.0, 1.0,-1.0);
    glColor3f(1.0, 1.0, 1.0);
    glVertex3f(-1.0, 1.0, 1.0);
    glColor3f(0.0, 0.6, 0.1);
    glVertex3f( 1.0, 1.0, 1.0);
 
    glColor3f(1.0,0.5,0.0);
    glVertex3f( 1.0,-1.0, 1.0);
    glColor3f(1.0, 0.5, 0.5);
    glVertex3f(-1.0,-1.0, 1.0);
    glColor3f(0.5, 0.0, 1.0);
    glVertex3f(-1.0,-1.0,-1.0);
    glColor3f(0.1, 0.5, 0.9);
    glVertex3f( 1.0,-1.0,-1.0);
 
    glColor3f(1.0,0.0,0.0);
    glVertex3f( 1.0, 1.0, 1.0);
    glColor3f(1.0, 0.25, 0.7);
    glVertex3f(-1.0, 1.0, 1.0);
    glColor3f(1.0, 1.0, 0.0);
    glVertex3f(-1.0,-1.0, 1.0);
    glColor3f(0.0, 1.0, 1.0);
    glVertex3f( 1.0,-1.0, 1.0);
 
    glColor3f(1.0,1.0,0.0);
    glVertex3f( 1.0,-1.0,-1.0);
    glColor3f(0.0, 1.0, 1.0);
    glVertex3f(-1.0,-1.0,-1.0);
    glColor3f(1.0, 1.0, 0.0);
    glVertex3f(-1.0, 1.0,-1.0);
    glColor3f(1.0, 0.5, 0.5);
    glVertex3f( 1.0, 1.0,-1.0);
 
    glColor3f(0.0,0.0,1.0);
    glVertex3f(-1.0, 1.0, 1.0);
    glColor3f(1.0, 1.0, 0.0);
    glVertex3f(-1.0, 1.0,-1.0);
    glColor3f(0.0, 1.0, 0.0);
    glVertex3f(-1.0,-1.0,-1.0);
    glColor3f(1.0, 0.0, 1.0);
    glVertex3f(-1.0,-1.0, 1.0);
 
    glColor3f(1.0,0.0,1.0);
    glVertex3f( 1.0, 1.0,-1.0);
    glColor3f(0.3, 0.5, 0.7);
    glVertex3f( 1.0, 1.0, 1.0);
    glColor3f(0.1, 0.3, 0.8);
    glVertex3f( 1.0,-1.0, 1.0);
    glColor3f(1.0, 1.0, 1.0);
    glVertex3f( 1.0,-1.0,-1.0);
  glEnd;
 
Rot:= Rot + 0.1;
If Rot = 360
  then Rot:= 0;
end;

Kubas

Na va, gavosi visai mielas kubas. Kuo sudėtingesnė figūra, tuo daugiau darbo, koordinačių ir kodo, todėl į pagalba ateina tokios programos, kaip 3D Studio Max, Milkshape, AutoCAD ir pan.

Panašūs straipsniai


“Žingsnis į kitą pasaulį (OpenGL II dalis)” komentarų: 3

  1. OggyH

    O tęsinys bus? Pvz kaip įkelti 3DS Max objektus ir pan… labai praverstų :)

  2. JudicatorMX

    Ne, apie tuos objektus ir pan nesu parases. Mano straipsniuose tik principai ;) Internete daug literaturos apie tai :)

  3. OggyH

    Vistiek aciu uz gerus straipsnius :)

Rašyti komentarą

Jūs privalote prisijungti jeigu norite rašyti komentarą.