Seriál OpenGL - 1. díl
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Seriál OpenGL - 1. dílSeriál OpenGL - 1. díl

 

Seriál OpenGL - 1. díl

Google       Google       6. 11. 2007       61 817×

Dneškem začínáme seriál o programování s knihovnou OpenGL.

Úvod

Ve zkratce řečeno je OpenGL (zkr. OGL) jednou z knihoven, které jsou schopny komunikovat s hardwarem grafické karty a donutit ji, aby poslala sestavu barevných bodů do monitoru. Takovýchto knihoven je samozřejmě více. My jsme ovšem zvolili OGL a dobře jsme udělali. Proč? To nechám do různých diskusí, kde se neustále řeší problémy typu: Je lepší PC nebo Mac? DirectX nebo OpenGL? Housky nebo rohlíky?

S OGL se dá zacházet prostřednictvím takřka všech programovacích jazyků. Já jsem zvolil C++. Poté, co si osvojíte základní funkce a příkazy, budete schopni s ní ale pracovat i ve svém oblíbeném Delphi, Pythonu či čemkoli jiném. OGL není sama osobě API (tedy Application Interface), tzn. potřebujeme ještě nějakou chytrou knihovnu, které nám umožní, abychom k tomu, co jsme naprogramovali, dokázali přistupovat. Budeme používat GLUT, má sice spoustu omezení, ale učíme se OGL a ne nějaké API. GLUT je knihovna na používání velice jednoduchá, zejména v začátcích a i pro těch několik prvních hrách případně programů, které vytvoříte, bude stačit. I když je jasné, že až budete chtít vyrobit něco jako Oblivion případně 3Ds Max, bude se muset naučit např. WinApi.

Takže s chutí do toho a půl je hotovo!


Instalace

V dnešní části se naučíme zinicializovat GLUT okno a vykreslíme si do něj první objekt. Nenechte se odradit tím, že to na vás bude spousta informací najednou, klidně si prostě zkopírujte kód, jelikož ten se v zásadě měnit nebude a budeme pořád pracovat ve dvou funkcích, jedné pro inicializaci, druhé pro vykreslení. Doporučuji si ale GLUT nastudovat, jelikož později se bude hodit (třeba na Root.cz). Sami uvidíte, že za tři dny to máte v hlavě. Navíc posléze přijdou i věci typu ovládání myši, klávesnice, případně časování. Pokusím se je sice trochu vysvětlit, ale v zásadě se budu tvářit, jakože je znáte.

Nejdřív je potřeba nainstalovat jak GLUT, tak OpenGL do vašeho oblíbeného kompilátoru… tím mám samozřejmě na mysli DevC++. Pomocí volby Nástroje → Zjistit updaty si stáhněte instalační balíčky pro GLUT a OGL. V DevC++ se proklikejte skrz Nástroje → Package manager, tam dejte Install, vyberte balíček a nainstalujete (pokud se balíček nenainstaluje automaticky při stažení). Tak se vám bez větší námahy dostanou tam, kam mají, ty knihovny, které mají. Pokud se vše podařilo nainstalovat, v Soubory → Nový → Projekt pod záložkou Multimédia by se vám měl objevit projekt v GLUT. Ten si otevřete. Pokud se na něj podíváte, uvidíte tam spoustu písmenek nedávajících absolutně žádný smysl, ale to je v pořádku, za chvíli tohle bude vaše abeceda. Jestli jste se už pokochali, tak to všechno s klidem smažte (to myslím vážně)!

Začínáme

Vytvoříme si vlastní šablonu, se kterou budeme posléze pracovat.

Nejdřív je třeba includovat knihovnu GLUT (měli byste ji mít v adresáři ../include/GL/).

#include <gl/glut.h>

Teď si postupně ve zkratce projedeme funkci main, ve které se vše v zásadě odehrává.

int main (int argc, char **argv) {

Inicializujeme okno.

    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
    glutInitWindowSize(640,480);
    glutInitWindowPosition(10,10);
    glutCreateWindow("Moje prvni glut okno");  

V prvním řádku se inicializuje samotná knihovna GLUT. Druhý řádek nastavuje tzv. framebuffer. Framebuffer si lze představit jako dvourozměrné pole o velikosti šířka okna krát výška okna. Jsou v něm obsaženy barevné informace jednotlivých pixelů, které jsou posléze poslány do monitoru. Všechno, co se v OGL vypočítá a vykreslí během jednoho průchodu, se uloží do framebufferu a pokud je vykreslování dokončeno, barevné hodnoty se najednou „nalejí“ do výstupu grafické karty.

Prvním parametrem GLUT_RGBA tedy GLUTu říkáme aby inicializoval framebuffer, do kterého se budou ukládat RGBA informace (Red, Blue, Green, Alpha).

Mimo barevného bufferu je zde ještě tzv. depth buffer GLUT_DEPTH (někdy z-buffer), tedy paměť hloubky; v ní se ukládá hloubka jednotlivých pixelů. V zásadě se jedná také o barevnou hodnotu ve stupních šedi s tím, že nejtmavší znamená nejbližší k pozorovateli. Vzdálenější pixely jsou automaticky přepsány pixely, které je překrývají a jsou blíže k pozorovateli (jak uvidíme v některé z dalších lekcí, toto chování se dá změnit). Díky depth bufferu ví grafická karta, které barevné informace má zahodit a které je třeba zobrazit, jelikož jsou vidět.

Posledním parametr – GLUT_DOUBLE – inicializuje tzv. double buffering. To znamená, že není pouze jeden framebuffer, který se vytvoří a „naleje“ do monitoru, to by totiž znamenalo prodlevu mezi jednotlivými vykresleními, nýbrž jsou dva. Tedy, zatímco jeden se zobrazuje v monitoru, druhý se zpracovává.

K bufferům si ještě někdy povíme více. Zatím to je spíše o tom, abyste věděli, co píšete do okna kompilátoru.

Nyní následuje registrace tzv. callback funkcí.

    glutDisplayFunc(onDisplay);
    glutIdleFunc(onDisplay);
    glutReshapeFunc(onResize);

Tyto funkce mají za parametr ukazatel na jinou funkci, kterou pak vykonávají. Jsou volány znovu a znovu při každém průchodu smyčky funkce main (f-ce main je v zásadě nekonečný cyklus, který vykonává tyhle f-ce dokud není zastaven).

void glutDisplayFunc(void (*func)(void));
Registruje funkci pro zobrazení. Já jsem si ji pojmenoval onDisplay, ale pojmenujte si ji jak chcete. To je tedy jedna ze dvou funkcí, které budeme tvořit celý tento seriál, odehrávají se v ní všechny OGL příkazy.
void glutIdleFunc (void (*func)());
Tento příkaz registruje f-ci, která se provádí, když nejsou přijímány žádné povely (např. pohyb myší atd). Všimněte si, že je v ní opět zaregistrována funkce onDisplay. To je logické, jelikož když zrovna není počítač zaměstnán něčím jiným, tak vykresluje, proto vám na obrazovce neuhnije jediný obraz, ale mění se v průběhu.
void glutReshapeFunc (void (*func)(int width, int height));
Tato funkce se volá při každé změně velikosti okna. Zajišťuje to, aby se nám obraz nedeformoval při roztažení okna (v našem případě), na druhou stranu se ale může starat i o to, aby se naopak deformoval. Touto funkcí se zatím nebudeme moc zabývat. Probereme si ji později.

Teď už zbývá jenom:

init();
glutMainLoop();   
return 0; 	

Init() je funkce, ve které budeme provádět inicializaci OpenGL, opět se může jmenovat jakkoli. Vlastně zde ani nemusí být, ale to by znamenalo, že příkazy, které jsou v ní, by se musely provádět ve vykreslovací funkci každý frame a to by dost zpomalovalo chod programu. Proto je třeba si vždy promyslet, co budeme v průběhu programu měnit a co stačí, aby bylo určeno jenom jednou na začátku.

GlutMainLoop() pak spouští a udržuje v chodu onu nekonečnou smyčku, jež byla zmíněna v souvislosti s callback funkcemi.

Zbytek je doufám jasný.

Teď se podívejme na funkce init() a onDisplay() a onResize(). Nebudu je zatím vysvětlovat, pouze je stručně okomentuji, jelikož věci, které jsou v nich obsaženy, si probereme postupně v následujících dílech.

Tato funkce probíhá vždy při změně velikosti okna:

void onResize(int w, int h) {
	 glMatrixMode(GL_PROJECTION); // bude se upravovat projekční matice
	 glLoadIdentity(); // nastaví se na jednotkovou matici 
         glViewport(0, 0, w, h); // nastaví se vlastnosti viewportu
	 gluPerspective(45,(double)w/(double)h,1,100);
	 glMatrixMode(GL_MODELVIEW); // přepne se na modelview matici
}

Následující funkce se spustí jenom jednou, a to při startu programu:

void init() {
     glEnable(GL_DEPTH_TEST); // povolí se testování hloubky
     glClearColor(1.0,1.0,1.0,1.0); // nastaví se barva pozadí
     glEnable(GL_LIGHTING);// zapnou se světla
     glEnable(GL_LIGHT0); // zapne se světlo 0	
}

Tato funkce probíhá každý frame znovu a znovu:

void onDisplay(void){
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); // vymaže se frame buffer a depth buffer, aby se do něj mohlo začít znovu kreslit
     glLoadIdentity(); // modelview matice se nastaví na jednotkovou
     glTranslatef(0.0, 0.0, -4.0); // provede se posun
     glutSolidTeapot(1); // vykreslí se konvice (to je jeden ze tvarů, které má GLUT přednastavené)
     glutSwapBuffers(); // prohodí se buffery (jeden se pošle na výstup a do druhého se začne znovu vykreslovat).                         
}

Tady je ještě jednou celý zdrojový kód dnešního dílu vcelku:

#include <gl/glut.h>



void onResize(int w, int h) {
	 glMatrixMode(GL_PROJECTION);
	 glLoadIdentity();
     glViewport(0, 0, w, h);
	 gluPerspective(45,(double)w/(double)h,1,100);
	 glMatrixMode(GL_MODELVIEW);
}

void init() {
     glEnable(GL_DEPTH_TEST);
     glClearColor(1.0,1.0,1.0,1.0);
     glEnable(GL_LIGHTING);
     glEnable(GL_LIGHT0);	
}

void onDisplay(void){
	 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
	 glLoadIdentity();
     glTranslatef(0.0, 0.0, -4.0);
     glutSolidTeapot(1);
	 glutSwapBuffers();                          
} 

int main (int argc, char **argv) {
    
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
    glutInitWindowSize(640,480);
    glutInitWindowPosition(10,10);
    glutCreateWindow("okno");   
    
    glutDisplayFunc(init);
    glutIdleFunc(onDisplay);
    glutReshapeFunc(onResize);

    glutMainLoop();   
    return 0;
}

Závěr

Teď už zbývá jenom uložit to, co jsme dnes vytvořili, jako šablonu, která nám bude sloužit pro další používání. Proklikejte se k Soubor → Nový → Šablona, zde si šablonu nějak pojmenujte, jako kategorii zadejte Multimedia a vytvořte. Šablona bude k nalezení v Soubor → Nový → Projekt → Multimedia.

To je pro dnešek vše. V příštím díle i povíme o vykreslování. Jaké jsou základní způsoby vykreslování v OGL, řekneme si něco o normálách, vertexech a základních transformacích. Taky se dozvíte, co to znamená, že OGL je stavový automat. V dalších dílech pak budou následovat základní transformace a vysvětlíme si, jak je to s maticemi. Pak přijdou světla, textury a spousta dalších šíleností, které už začnou být opravdu zajímavé. A pokud vám i mně vydrží trpělivost, vrhneme se posléze i na různé OGL extenze a programování shaderů a to už začne být opravdu, ale opravdu zajímavé a věřte mi, že se nad tím potrápíte nejenom vy, ale i vaše grafické karty :-).

×Odeslání článku na tvůj Kindle

Zadej svůj Kindle e-mail a my ti pošleme článek na tvůj Kindle.
Musíš mít povolený příjem obsahu do svého Kindle z naší e-mailové adresy kindle@programujte.com.

E-mailová adresa (např. novak@kindle.com):

TIP: Pokud chceš dostávat naše články každé ráno do svého Kindle, koukni do sekce Články do Kindle.

Hlasování bylo ukončeno    
0 hlasů
Google
Autor programuje v OpenGL, C++, PHP.
Web    

Nové články

Obrázek ke článku Hybridní inteligentní systémy 2

Hybridní inteligentní systémy 2

V technické praxi využíváme často kombinaci různých disciplín umělé inteligence a klasických výpočtů. Takovým systémům říkáme hybridní systémy. V tomto článku se zmíním o určitém typu hybridního systému, který je užitečný ve velmi složitých výrobních procesech.

Obrázek ke článku Jak vést kvalitně tým v IT oboru: Naprogramujte si ty správné manažerské kvality

Jak vést kvalitně tým v IT oboru: Naprogramujte si ty správné manažerské kvality

Vedení týmu v oboru informačních technologií se nijak zvlášť neliší od jiných oborů. Přesto však IT manažeři čelí výzvě v podobě velmi rychlého rozvoje a tím i rostoucími nároky na své lidi. Udržet pozornost, motivaci a efektivitu týmu vyžaduje opravdu pevné manažerské základy a zároveň otevřenost a flexibilitu pro stále nové výzvy.

Obrázek ke článku Síla týmů se na home office může vytrácet. Odborníci radí, jak z pracovních omezení vytěžit maximum

Síla týmů se na home office může vytrácet. Odborníci radí, jak z pracovních omezení vytěžit maximum

Za poslední rok se podoba práce zaměstnanců změnila k nepoznání. Především plošné zavedení home office, které mělo být zpočátku jen dočasným opatřením, je pro mnohé už více než rok každodenní realitou. Co ale dělat, když se při práci z domova ztrácí motivace, zaměstnanci přestávají komunikovat a dříve fungující tým se rozpadá na skupinu solitérů? Odborníci na personalistiku dali dohromady několik rad, jak udržet tým v chodu, i když pracovní podmínky nejsou ideální.

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý