OpenGL paleidimas


Įvadas:

Ši pamoka skirta norintiems pradėti dirbti su OpenGL. Taip pat siūlyčiau paskaityti ir tiems, kurie nori dirbti su 3D grafika, bet niekaip neapsisprendžia nuo ko pradėti.
Taip jau yra, kad pradedantiesiems dažnai būna labai sunku išsirinkti tokius dalykus kaip programavimo kalba, 3D API. Visi ieško geriausio. Aš ir pats praleidau nemažai laiko lygindamas DirectX su OpenGL, norėjau pradėti nuo geriausio, kad paskui netektų pereidinėt prie kito. Kai išbandžiau abu, supratau, kad geriausio nėra. Ir nereikia jo ieškoti, reikia imti tą, kuris atrodo paprastesnis/labiau suprantamas, ir pirmyn į darbą. Nepatiks - paimsi kitą. Perėjimas prie kito nėra toks baisus kaip atrodo, o įgytos žinios netampa bevertėmis - jos praverčia ateityje. Taigi jeigu esi vienas iš tokių žmonių, niekaip neapsisprendžiančių nuo ko pradėti - pradėk dabar.


Ką ši pamoka duos:

Šioje pamokoje parodysiu, kaip susikonfigūruoti sistemą, parašyti ir sukompiliuoti paprastą OpenGL programą (C++ kalba). Mano nuomone, tai pradedančiąjam yra svarbiausia - sukurti kažką veikiančio, o tada jau galima mokintis patį OpenGL. Šioje pamokoje naudojama: C++ kalba, OpenGL + GLUT API, Dev-C++ programavimo aplinka, Windows OS. Skaitytojui rekomenduojama (bet nebūtina) turėti C++ programavimo pagrindus.



1) Sistemos paruošimas

Pirmiausia atsisiųskite Dev-C++ paketą. Jį rasite šiuo adresu:
http://www.bloodshed.net/dev/devcpp.html (Dev-C++ 5.0 beta 9.2 4.9.9.2, 9.0 MB)
Įdiekite jį į savo kompiuterį. Jei nesate tikri, ką reiškia įdiegimo metu prašomi įvesti parametrai, naudokite standartinius.

OpenGL yra tik grafikos biblioteka, todėl tokiais dalykais kaip lango sukūrimas, OpenGL inicializavimas turime pasirūpinti atskirai. Tai galima padaryti standartinėmis Win32 funkcijomis, arba naudoti papildomas bibliotekas, pvz. GLUT. Pasirinkus pirmą būdą, vien lango sukūrimo kodas sudarytų kelis šimtus eilučių. Tai pradedantiesiems tikrai nepriimtina, todėl naudosime antrąjį būdą - GLUT. GLUT (OpenGL Utility Toolkit) - tai funkcijų rinkinys, apimantis:
    ● lango sukūrimą;
    ● pagrindinio programos ciklo (main loop) valdymą;
    ● įvedimą (klaviatūra, pelė);
    ● ir dar kai ką...
Jis žymiai palengvina darbą, patogus kurti mažas programėles. Nereikia rašyti gremėzdiško kodo - viską atlieka kelios eilutės.
Yra kelios GLUT alternatyvos:
    ● GLUT - standartinė biblioteka. Deja jos kūrimas sustabdytas 1998 m., todėl prastas suderinamumas su dabartiniais kompiliatoriais. Norint ja naudotis, reikia nemažai pavargti.
    ● freeglut - atviro kodo GLUT perdirbimas.
    ● OpenGLUT - dar vienas perdirbimas, kuriamas freeglut pagrindu.
Visomis trimis distribucijomis parašytas kodas bus toks pat, todėl nėra svarbu, kurią naudoti. Mūsų atveju bus naudojama freeglut. Jos įdiegimas labai paprastas, o visi reikalingi failai pateikti archyve "freeglut.zip". Išarchyvuokite "freeglut.zip", jame esančius .h failus perkelkite į "Dev-Cpp\include\GL", "libfreeglut.a" - į "Dev-Cpp\lib", "freeglut.dll" - į "WINDOWS\system32". Čia "Dev-Cpp\" - katalogas, į kurį idiegėte Dev-C++.




2) Projekto sukūrimas

Dabar sukursime nedidelę programėlę, kuri piešia ekrane kvadratą. Programos projektas su kodu pateiktas "Hello_World.zip" archyve.

Projekto sukūrimas:

Paleiskite Dev-C++. Susikurkite naują projektą: File->New->Project... Pasirinkite Empty Project ir išsaugokite norimoje vietoje:



Tada įterpkite kodo failą: File->New->Source File:



Norint, kad veiktų OpenGL ir GLUT, reikia nurodyti bibliotekas (libraries). Tai galima padaryti taip: eikite į Project->Project Options. Pasirinkite Parameters ir Linker laukelyje įrašykite:
-lfreeglut -lopengl32:





3) OpenGL "Hello World"

Beliko parašyti patį programos kodą ir įsitikinti, kad viskas atlikta gerai:

#include <GL\glut.h>
Pati pirma eilutė - freeglut kodo įterpimas.

void KeistiDydi(int w, int h){
    glViewport (0, 0, w, h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-100.0, 100.0, -100.0, 100.0, -1.0, 1.0);
}

Ši funkcija kviečiama, kai pasikeičia lango dydis. Gaunami parametrai w ir h - tai naujas lango plotis ir aukštis. Funkcija glViewport() nustato stačiakampį plotą, kuriame vyksta piešimas. Pirmi du perduodami parametrai - to stačiakampio apatinio kairiojo kampo x ir y koordinatės, kiti du - viršutinio dešiniojo. Įsidėmėkite, kad OpenGL koordinatės skaičiuojamos nuo apatinio kairiojo kampo. Taigi šiuo atveju perduodant reikšmes (0, 0, w, h) nustatoma, kad būtų piešiama visame lange.
Paskutinės trys funkcijos nustato ortografinę projekciją.


void Piesti(void){
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(1.0, 1.0, 1.0);
    glRectf(-50.0, -50.0, 50.0, 50.0);
    glutSwapBuffers();
}

Funkcija Piesti() kviečiama, kai reikia perpiešti sceną. glClear() parametras GL_COLOR_BUFFER_BIT reiškia, kad išvalomas spalvų buferis. Buferio valymas reikalingas, kad neliktų fragmentų iš praeito kadro. glColor3f funkcija nustato naudojamą spalvą. Kiekvienas parametras atitinka vieną spalvos komponentą - raudoną, žalią ir mėlyną. Kartais naudojamas ir ketvirtas parametras, jis reiškia permatomumą (opacity). Reikšmė gali būti nuo 0,0 iki 1,0. Kuo reikšmė didesnė, tuo daugiau tos spalvos imama. Šiuo atveju imami visų trijų komponentų maksimumai ir gaunama balta spalva. glRectf() piešia stačiakampį. Pirmi du parametrai - apatinio kairiojo kampo koordinatės, kiti du - viršutinio dešiniojo. glutSwapBuffers() sukeičia buferius. Buferis - tai ta dalis, į kurią piešiama. Iš viso yra 2 buferiai - į vieną piešiama, kitas vaizduojamas ekrane. Kai piešimas baigtas, buferiai sukeičiami vietomis. Tada ekrane matomas naujai nupieštas buferis, o senas išvalomas ir naudojamas piešimui.

void Atnaujinti(){
    glutPostRedisplay();
}

Ši funkcija kviečiama, kai baigiamas kadro piešimas. glutPostRedisplay() liepia pakartoti piešimą.

int main(int argc, char **argv){
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);

    glutInitWindowSize(250, 250);
    glutInitWindowPosition(100, 100);
    glutCreateWindow("GLUT");

    glClearColor(0.0, 0.0, 0.0, 1.0);
    glutReshapeFunc(KeistiDydi);
    glutDisplayFunc(Piesti);
    glutIdleFunc(Atnaujinti);
    glutMainLoop();
    return 0;
}

Tikriausiai žinote, kad main() yra pagrindinė funkcija, kuri vykdoma paleidus programą.
glutInit inicializuoja GLUT. Su funkcija glutInitDisplayMode() nustatomi parametrai:
GLUT_DOUBLE - naudoti du piešimo buferius;
GLUT_RGB - naudoti RGB (raudona, žalia, mėlyna) spalvas.
Kitų funkcijų paskirtis aiški vien iš pavadinimo:
glutInitWindowSize() - kuriamo lango dydis;
glutInitWindowPosition() - kuriamo lango pozicija (čia naudojamos ne OpenGL, o Windows koordinatės - jos skaičiuojamos nuo kairiojo viršutinio kampo);
glutCreateWindow() - sukuriamas langas; perduodamas parametras - lango pavadinimas;
glClearColor() - nustatoma spalva (šiuo atveju juoda), kuria užpiešiamas buferis jį valant;
glutReshapeFunc() - nurodoma, kuri funkcija turi būti kviečiama pakeitus lango dydį;
glutDisplayFunc() - nurodoma, kuri funkcija atlieka piešimą;
glutIdleFunc() - nurodoma, kuri funkcija vykdoma tarp kadrų piešimo;
glutMainLoop() - pradedamas programos pagrindinis ciklas (main loop);
return 0 - baigiama programa.


Išsaugokite kodo failą (File->Save) ir galite kompiliuoti: Execute->Compile & Run. Gausite tokį vaizdą:



YEAH! Argi ne paprasta?




4) Ką veikti toliau?

Patarčiau parsisiųsti knygą "OpenGL Programming Guide" (dar žinoma kaip "OpenGL Redbook"), kurią privalo perskaityti kiekvienas OpenGL programuotojas. Knygoje pateikiamuose pavyzdžiuose naudojama GLUT biblioteka, todėl su kompiliavimu neturėtų kilti problemų. Taip pat yra neblogas "OpenGL įvadas" lietuvių kalba, parašytas Andriaus Davidsono. Jame pateikiama medžiaga apima pirmus keturis "OpenGL Redbook" skyrius. Šį dokumentą galite parsisiųsti iš GameDev.LT:
http://www.gamedev.lt/files/tutorials/OpenGL_ivadas.rar


Šiaip:

● Kad veiktų freeglut biblioteką naudojanti programa, būtinas "freeglut.dll" failas. Kai jis nukopijuotas į "WINDOWS\system32" - viskas tvarkoj, Windows'ai jį randa. Bet kituose kompiuteriuose šio failo gali ir nebūti, taigi jei pvz. norėtumėt savo sukurtą programėlę duoti draugui, nepamirškite prie jos (į tą patį katalogą) pridėti "freeglut.dll".
● Su šia pamoka pateikti jau sukompiliuoti freeglut failai ("libfreeglut.a" ir "freeglut.dll"). Originalią freeglut biblioteką sudaro tik source kodas, o šiuos failus reikia susikompiliuoti pačiam. Aišku pradedančiąjam tai būtų didelis vargas (gal netgi neįveikiamas), taigi neišsiplėčiau į bibliotekų kompiliavimą, o tik pateikiau savo sukompiliuotą versiją.


-----------------------------------------------------------------------------------

Apie autorių:

Esu Arvydas Burdulis (A-E), studijuoju informatiką, su OpenGL dirbu dvejus metus.
Jei ši pamoka Jums buvo naudinga - praneškit :)
Kontaktai:
http://ae.gamedev.lt aab@auto.lt

© 2008 A-E Software ®