Programiranje pomoću opengl biblioteke

Čitate moj prvi OpenGL vodič!

Prije nego počnete učiti sam OpenGL, čini mi se da je bolje reći vam kako kompajlirati kod, pokrenuti ga i što je najvažnije, kako eksperimentirati s izvornim kodovima danim u ovim lekcijama.

Što trebaš znati

Ove lekcije namijenjene su čitateljima bez posebnih znanja o programiranju. Naravno, poznavanje bilo kojeg programskog jezika (C, Java, Lisp, JavaSript) bit će veliki plus, ali to nije obavezno, samo morate učiti dva predmeta istovremeno - 3D grafiku i programiranje.

Sav kod u ovim lekcijama napisan je u C++ u najjednostavnijem mogućem stilu. Nema predložaka, klasa ili aritmetike pokazivača. Stoga, gledajući kod, možete razumjeti što radi, čak i ako ste upoznati samo s JavaSriptom.

Zaboravite sve što ste znali o OpenGL 1/2

Ove lekcije pretpostavljaju da ne znate ništa o 3D grafici. Ali ako ste čitali vodiče za OpenGL i naišli na nešto poput glBegin(), onda to zaboravite. Ovdje ćemo proučavati OpenGL 3 i 4, a ono što ste pročitali odnosi se na OpenGL 1 ili 2. Stoga vam preporučujem da zaboravite sve što ste prije znali, inače će vam se mozak početi topiti od nedosljednosti.

Izgradnja projekta

Kod iz ovih lekcija može se kompajlirati za Windows i Linux. Za početak kompajliranja koda za bilo koju od platformi morate učiniti sljedeće:

  1. Ažurirajte upravljačke programe za svoju video karticu!! Upozorio sam te :)
  2. Preuzmite kompajler ako ga već nemate.
  3. Instalirajte CMake
  4. Preuzmite gotove izvore lekcija.
  5. Generirajte projekt koristeći CMake
  6. Sastavite projekt.
  7. Eksperimentirajte s kodom kako biste bolje razumjeli što se tamo događa.

U nastavku sam dao detaljniji opis projekata sklapanja za svaku platformu. Ali ovisno o verziji OS-a, snimke zaslona mogu se malo razlikovati od onoga što će se pojaviti na vašem zaslonu, ali općenito bi sve trebalo biti približno isto.

Izrada za Windows


Izrada za Linux

U svijetu postoji ogroman broj različitih varijanti Linuxa, tako da ne želim davati primjere sastavljanja projekta za svaku. Ako nešto ne uspije kako je opisano u nastavku, pročitajte dokumentaciju ili pretražite Internet.

  1. Instalirati najnoviji drajveri na svoju video karticu. Toplo preporučujem upravljačke programe koji nisu otvorenog koda. Nisu uključeni u GNU, ali često rade mnogo bolje. Ako vaša verzija Linuxa ne pruža automatski instalater, pokušajte pročitati vodič za Ubuntu.
  2. Instalirajte kompajler sa svim potrebne knjižnice i alata. Evo popisa onoga što vam je potrebno: cmake make g++ libx11-dev libgl1-mesa-dev libglu1-mesa-dev libxrandr-dev libxext-dev. Koristite sudo apt-get install ***** ili su /yum install ******
  3. Preuzmite primjere izvora i raspakirajte ih u mapu, na primjer ~/Projects/OpenGLTutorials/
  4. Idite na ~/Projects/OpenGLTutorials/ i unesite sljedeće naredbe:
  • mkdir build
  • cd build
  • cmake..
  1. Ako su prethodne naredbe uspješno izvršene, makefile će biti kreiran u mapi build/
  2. unesite “make all” i nakon toga će svi primjeri i njihove ovisnosti biti kompilirani. Ako nema grešaka, onda ste spremni izvršne datoteke bit će smješten u mapu ~/Projects/OpenGLTutorials/

Stvarno volim koristiti QtCreator IDE. Ovaj IDE može raditi s CMakeom izvan kutije i pruža hrpu drugih pogodnosti, kao što su otklanjanje pogrešaka, automatsko dovršavanje itd.

Upute za izradu projekta u QtCreatoru:

1. U QtCreatoru kliknite File->Tools->Options->Compile&Execute->CMake

2. Navedite put do CMake. Ovo će najvjerojatnije biti /usr/bin/cmake

3. File->Open Project i odaberite tutorials/CMakeLists.txt

4. Navedite mapu za izradu, mapa bi po mogućnosti trebala biti izvan mape tutoriala.

5. Opcionalno postavite –DCMAKE_BUILD_TYPE=Debug u polju opcija.

6. Klik na čekiću ispod. Nakon toga, primjeri se mogu pokrenuti iz mape tutorials/

7. Da biste pokrenuli primjere iz QtCreatora, odaberite Projekti -> Parametri izvršenja -> Radni direktorij i odaberite direktorij u kojem se nalaze tekstura i osjenčivači modela. Za vodič 2 to će biti ~/opengl -tutorial /tutorial02_red_triangle/

Trčanje primjera

Nakon što je projekt sastavljen, aplikacije se mogu pokrenuti izravno iz imenika.
Ako trebate pokrenuti primjere izravno iz IDE-a, upotrijebite gornje upute za ispravno postavljanje radnog direktorija.

Kako uzeti ove lekcije

Uz svaku lekciju dolazi izvorni kod i podataka. Sve ove datoteke mogu se pronaći u odgovarajućem direktoriju tutorialXX/.

Ali preporučujem da ne mijenjate ništa u ovim datotekama, one su samo za referencu. Bolje je igrati u playground/playground.cpp i tamo mijenjati što god želiš. Ako nešto pokvarite i ne možete vratiti, ovu datoteku možete vratiti jednostavnim kopiranjem iz bilo koje druge lekcije.

Dok budete čitali ove vodiče, posvuda ćete vidjeti dijelove koda. Slobodno ih kopirajte u playground.cpp da biste ih vidjeli na djelu - eksperimentiranje je uvijek dobro. Opet ću reći, nemojte samo čitati. spreman kod i pokušajte ga pokrenuti. Nećete puno naučiti samo čitajući izvorni kod. Čak i uz jednostavno kopiranje i lijepljenje, dobit ćete vlastitu kantu problema, rješavanjem kojih ćete steći potrebno iskustvo.

Otvaranje prozora

Konačno! OpenGL!

Iako, morat ćete pričekati još malo. U svim lekcijama 3D operacije izvodit će se na vrlo niskoj razini, tako da za vas neće biti magije. Međutim, rad sa sistemskim prozorima i porukama je nezanimljiv i dosadan, pa ćemo GLFW knjižnici odraditi prljavi posao umjesto nas. Ako stvarno želite, možete koristiti Win32 API za Windows ili X11 API za Linux, ili koristiti nešto drugo poput SFML, FreeGLUT, SDL, ... pročitajte stranicu s poveznicama.

U redu, počnimo već jednom. Počnimo s činjenicom da moramo povezati ovisnosti. Budući da moramo poslati poruke na konzolu, napisat ćemo sljedeće:

// Povezivanje standardnih zaglavlja

#uključi

#uključi

Zatim spajamo GLEW

// To ne smijemo zaboraviti GLEW moraju biti povezani prije gl . h ili glfw . h

#uključi

Zatim povezujemo GLFW. Ova biblioteka će učiniti svu magiju upravljanja prozorima.

#uključi

Na u ovoj fazi ne trebamo ovu knjižnicu, ali sadrži matematičke funkcije i trebat će nam uskoro. U GLM-u nema magije, a ako baš želite, možete koristiti bilo koju drugu biblioteku za rad s matricama i vektorima. Uključujemo "upotrebu imenskog prostora" kako bismo napisali "vec3", a ne "glm::vec3"

#uključi

korištenje imenskog prostora glm;

Ako kopirate ove dijelove koda u playground.cpp, kompajler će se početi žaliti da nije glavne funkcije(). Pa dodajmo:

int main())(

Bilo bi bolje prvo inicijalizirati GLFW:

// Inicijaliziraj GLFW

ako(!glfwInit())

{

fprintf(stderr, "Nije uspjelo inicijaliziranje GLFW\n");

povratak -1;

}

Kreirajmo sada naš OpenGL prozor:

glfwOpenWindowHint( GLFW_ FSAA_ UZORCI, 4); // 4 xzaglađivanje

glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 3); //nas potrebna OpenGL 3.3

glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 3);

glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // nas Ne potrebna star OpenGL

// Otvorimo prozor i stvorimo kontekst

if(!glfwOpenWindow(1024, 768, 0,0,0,0, 32,0, GLFW_WINDOW))

{

fprintf(stderr, "Nije uspjelo otvaranje GLFW prozora\n");

U ovom poglavlju ćemo pogledati renderiranje 3D grafika koristeći OpenGL biblioteku, proučavat ćemo GLU i GLUT biblioteke (umjesto potonje, Linux koristi FreeGLUT biblioteku), analizirat ćemo proces učitavanja tekstura pomoću SOIL i DevIL biblioteka.

Kao što je već navedeno u Pogl. 9, Grafički programeri obično ne rade izravno s GPU-om. To je zbog činjenice da postoji mnogo različitih GPU-a i zato što je rad na niskoj razini s GPU-ima prilično složen i obično ga rade programeri upravljačkih programa. Umjesto toga, koriste razne API-je koji pružaju nešto više sučelja visoka razina za rad s GPU-om. Ovo sučelje apstrahira određeni GPU (kojim se upravlja kroz upravljački program, koji obično isporučuje proizvođač GPU-a), što vam omogućuje pisanje prijenosnog koda koji će raditi na različitim GPU-ovima. Također, takav API skriva niz detalja niske razine rada s GPU-om od programera.

Glavni API-ji za programiranje 3D grafike u ovaj trenutak su OpenGL i Dircct3D. Potonji je specifičan samo za platformu Microsoft Windows. Ova knjiga pokriva osnove rada s OpenGL-om. Ovo je višeplatformski API koji podržava sve glavne operativne sustave (Windows, Linux, Mac OS X) i omogućuje vam rad s veliki iznos razni GPU-ovi.

Postoji verzija API-ja - OpenGL ES, dizajnirana za rad Mobilni uredaji. Uz njegovu pomoć možete stvoriti trodimenzionalnu grafiku za iOS platforme i Android. Uz to, tu je i WebGL, biblioteka koja vam omogućuje korištenje OpenGL ES izravno u prozoru preglednika pomoću javascripta. Postoje i povezivanja za OpenGL koja rade sa svim glavnim programskim jezicima, što olakšava korištenje OpenGL-a iz gotovo bilo kojeg programskog jezika.

Glavni zadatak OpenGL-a je renderiranje dvo- i trodimenzionalne grafike. pri čemu ovaj API općenito se ne bavi stvaranjem prozora za renderiranje, čitanjem unosa korisnika i drugim sličnim poslovima koji uvelike ovise o specifičnom operativnom sustavu, pa ćemo za te svrhe koristiti biblioteku GLUT za više platformi. Ova knjižnica pruža jednostavne i prikladan način za stvaranje prozora, njihovo renderiranje pomoću OpenGL-a i primanje poruka s miša i tipkovnice.

S gledišta OpenGL arhitekture izgrađena po modelu klijent-poslužitelj. U ovom slučaju sam program, koji koristi OpenGL, djeluje kao klijent, a GPU i njegov upravljački program djeluju kao poslužitelj. Obično se program izvodi na istom računalu na kojem je instaliran GPU, ali to nije nužno.

U praksi, sve OpenGL naredbe koje se izvode spremaju se u međuspremnik i zatim stavljaju u red za prijenos na GPU. Dakle, izvršenje CPU naredbe samo to ukazuje ovu naredbu je ušao u međuspremnik ili je dodan u red čekanja; sasvim je moguće da ga GPU još nije počeo izvršavati. U isto vrijeme, OpenGL se može smatrati državni stroj- ima svoje bogatstvo. Jedini način promijeniti ovo stanje - koristiti OpenGL naredbe. OpenGL stanje se ne mijenja između naredbi.

Važan koncept u OpenGL-u su međuspremnici (slika 10.1). Za renderiranje moraju se stvoriti potrebni međuspremnici. Međuspremnik boja uvijek se koristi i za svaki piksel pohranjuje njegovu boju kao 24-bitni broj RGB format(8 bita za svaku od osnovnih boja - crvenu, zelenu i plavu) ili kao 32-bitni in RGBA format(na standardne tri komponente dodaje se četvrta komponenta - alpha, koja postavlja neprozirnost).

Kada koristite metodu r-buffer za uklanjanje nevidljivih površina, trebate pohraniti odgovarajuću vrijednost dubine za svaki piksel (obično se vrijednost dubine pohranjuje kao 16-, 24- i 32-bitni cijeli broj). U skladu s tim, sve vrijednosti dubine uzete zajedno tampon dubine. Također možete koristiti tampon za šablone, akumulacijski međuspremnik.

Kada stvarate prozor za renderiranje, morate stvoriti OpenGL kontekst i odgovarajuće međuspremnike. Sam kontekst obično je vezan za trenutnu nit, tako da ako aplikacija koristi više niti, kreirani kontekst se stvarno može koristiti samo iz niti u kojoj je stvoren.

Obrada podataka u OpenGL-u temelji se na cjevovodu renderiranja (vidi sliku 9.1). Cjevovod definira glavne faze obrade ulaznih podataka. Kako će točno podaci biti obrađeni ovisi o parametrima stanja OpenGL-a, ali same te faze i redoslijed kojim se pojavljuju strogo su fiksni.

Riža. 10.1.

Za moderne GPU-e, dva dijela ovog cjevovoda predstavljaju programi koji se pokreću na GPU-u, a nazivaju se shaderi. Zatim ćemo razmotriti OpenGL verziju 2, u kojoj ti programi ne moraju biti eksplicitno specificirani: postoje shaderi koji rade prema zadanim postavkama (to jest, u slučaju kada programer nije eksplicitno specificirao odgovarajuće shadere). Počevši od verzije 3, OpenGL zahtijeva specificiranje shadera i djelomično prekida kompatibilnost s njima prethodne verzije, zbog čega ćemo gledati verziju OpenGL 2.

Geometrija se definira kao skup vrhova koji tvore različite primitive (točke, segmente, trokute). Na svakom vrhu, osim njegovih koordinata, također možete postaviti niz dodatnih atributa, kao što su boje, normale, koordinate teksture. Podaci na svakom vrhu su ulaz za sjenčilo vrhova: za svaki vrh, sjenčilo za vrhove izvršava i generira neke izlazne vrijednosti. Tražena izlazna vrijednost su jedinstvene koordinate vrhova nakon što su sve transformacije obavljene.

OpenGL koristi 4x4 matrice za verteksnu transformaciju - model-view design matricu (Slika 10.2). Ako verteks shader nije eksplicitno naveden, koristi se zadani verteks shader, koji množi koordinate vrhova (kao vektor u homogenim koordinatama) prvo s matricom pogleda modela, a zatim s matricom dizajna.

Nakon toga se primitive sastavljaju i odsijecaju: svi dijelovi svake primitive koji izlaze izvan vidljivog područja (gledanje frustum) se automatski skraćuju tako da se primitive koje su u cijelosti sadržane u opsegu prosljeđuju u sljedeću fazu cjevovoda. Zatim fiksni dio cjevovoda izvodi perspektivnu podjelu - vektor u homogenim koordinatama dijeli se na svoju četvrtu komponentu.


Riža. 10.2.

Ako su koordinate inicijalno navedene u vlastitom koordinatnom sustavu, tada ih množenje s matricom pogleda modela prenosi u koordinatni sustav kamere. Daljnje množenje s matricom projekcije dovodi koordinate do prostor isječka. Nakon izvršene perspektivne diobe dobivamo normalizirane koordinate uređaja (normalizirane koordinate uređaja).

Posljednji korak je pretvaranje normaliziranih koordinata u koordinate prozora izražene u pikselima.

Prije perspektivne podjele primitivi se sklapaju i naknadno odsijecaju: odsijeca se sve što ne ulazi u okvir vidljivosti. Zatim se svaka primitiva rasterizira, tj. prevodi se u skup fragmenata. Niz vrijednosti navedenih u vrhovima se interpolira, a svakom fragmentu se daje vrijednost koja mu odgovara. Nakon toga se za svaki fragment izvršava shader fragmenta, čija je zadaća izračunati boju za svaki fragment. U ovom slučaju koriste se interpolirane vrijednosti, moguće je pristupiti teksturama - unaprijed pripremljenim slikama koje se superponiraju na izlazne primitive. Imajte na umu da svaki fragment ima vlastite koordinate na ekranu i vrijednost dubine dobivenu interpolacijom. Također, shader fragmenta, umjesto da izračuna boju fragmenta, može eksplicitno odbaciti cijeli fragment.

U sljedećem koraku cjevovoda izvodi se grupa provjera za svaki fragment, od kojih svaka može odbaciti dati fragment. Prva od ovih provjera ispituje odgovara li određeni piksel vidljivom dijelu prozora. Ako nije, onda se ovaj fragment odmah odbacuje. Sljedeći test provjerava nalazi li se fragment unutar zadanog pravokutnika (u koordinatama prozora). Tu su i testovi šablona i dubine. Test matrice dohvaća grupu bitova koji odgovaraju danom fragmentu iz međuspremnika matrice i provjerava je li uvjet za te bitove ispunjen. Test dubine uspoređuje dubinu fragmenta s odgovarajućom vrijednošću iz međuspremnika dubine. Svaki od ovih testova može rezultirati odbacivanjem odgovarajućeg fragmenta. Osim toga, postoji alfa test koji vam omogućuje odbacivanje fragmenata na temelju vrijednosti alfa komponente njegove boje.

Nakon toga se izvodi korak miješanja boje fragmenta s bojom koja odgovara ovom fragmentu u međuspremniku boja. Ova operacija potreban za podršku translucent™.

Izračun vrijednosti boje može se napraviti s mnogo većom preciznošću nego što se može pohraniti u međuspremnik boja. Obično je u ovom slučaju boja jednostavno zaokružena. Korištenje rasterizacija (dithering) pruža drugu opciju: boja se mijenja tako da prosjek susjednih piksela daje željenu vrijednost.

Posljednji korak je izvršavanje zadanog po bitovima logična operacija između sadržaja međuspremnika boja i rezultirajuće vrijednosti boje. Imajte na umu da se mnogi od ovih testova i operacija mogu isključiti ako nisu potrebni - to obično poboljšava izvedbu.

Ako pišete program koristeći OpenGL u C (ili C++), prva stvar koju trebate učiniti je uključiti sljedeću datoteku zaglavlja:

Kako bi se osigurala kompatibilnost koda i prenosivost, OpenGL uvodi nekoliko vlastitih tipova podataka, ime svakog od ovih tipova počinje s prefiksom GL. GLint odgovara standardni tip cijeli brojevi, GLuint tip je standardni nepredznačeni cijeli broj, a GLfloat je float tip. OpenGL također koristi nekoliko posebnih tipova, kao što je GLsizei, koji označava tip koji se koristi za određivanje veličine, i GLclampf, koji se koristi za određivanje vrijednosti pomičnog zareza koje leže na liniji.

Također je uveden poseban tip GLenum za označavanje vrste vrijednosti koje odgovaraju različitim konstantama.

OpenGL biblioteka (kao i GLU i GLUT biblioteke koje dolaze s njom) obično koriste prilično jednostavnu konvenciju imenovanja za konstante i funkcije. Imena svih OpenGL naredbi (funkcija) počinju s prefiksom gl (za funkcije iz biblioteka GLU i GLUT - s glu odnosno glut).

Imena svih konstanti počinju s GL_ (odnosno s GLU_ i GLUTJ.

Mnoge OpenGL naredbe imaju višestruke razne opcije, koji se razlikuju po broju proslijeđenih argumenata i njihovim vrstama. U ovom slučaju naziv naredbe također uključuje poseban sufiks koji sadrži broj parametara i sufiks koji specificira njihovu vrstu. Dakle, naziv naredbe u OpenGL-u obično izgleda ovako:

glCommand(1 2 3 4)(b s i f d ub us ui)(v)

Neobavezni broj koristi se za određivanje broja proslijeđenih argumenata (u slučaju kada postoje verzije ove naredbe s drugačiji broj argumenti). Zatim dolazi izborni sufiks od jednog ili dva slova koji specificira vrstu proslijeđenih argumenata (u slučaju kada postoje verzije ove naredbe koje prihvaćaju ulazne vrijednosti različite vrste). Sufiks v označava da se niz parametara (obično skup zadnjih parametara) prosljeđuje kao niz - u stvarnosti, funkcija prima pokazivač na ovaj niz umjesto ovih parametara.

Dakle, naredba glVertex2i ima dva argumenta cijelog broja, naredba glColor3f ima tri argumenta tip plovka, a naredba glColor4ubv ima četiri argumenta nepotpisani tip bajt, proslijeđen kao niz (tj. kada se pozove, funkcija prima samo jedan argument - adresu niza).

OpenGL je trenutno jedno od najpopularnijih programskih sučelja (API) za razvoj aplikacija u području dvodimenzionalne i trodimenzionalne grafike. Standard OpenGL razvijen je i odobren 1992. od strane vodećih tvrtki za razvoj softvera, a temelji se na biblioteci IRIS GL koju je razvio Silicon Graphics.

Trenutno implementacija OpenGL-a uključuje nekoliko biblioteka (opis osnovnih funkcija OpenGL-a, GLU, GLUT, GLAUX i drugih), čija će svrha biti opisana u nastavku.

Karakteristične značajke OpenGL-a koje su osigurale širenje i razvoj ovog grafičkog standarda su:

Stabilnost - dodaci i izmjene standarda implementiraju se na način da se održi kompatibilnost s prethodno razvijenim softverom.

Pouzdanost i prenosivost - aplikacije koje koriste OpenGL jamče isti vizualni rezultat bez obzira na vrstu operativnog sustava koji se koristi i organizaciju prikaza informacija. Osim toga, te se aplikacije mogu izvoditi na osobnim računalima, radnim stanicama i superračunalima.

Jednostavnost korištenja - OpenGL standard ima dobro promišljenu strukturu i intuitivno sučelje, koje vam omogućuje stvaranje učinkovitih aplikacija s manje redaka koda nego korištenjem drugih grafičkih biblioteka po nižoj cijeni. Potrebne funkcije za osiguranje kompatibilnosti s različitom opremom implementirane su na razini knjižnice i uvelike pojednostavljuju razvoj aplikacija.

Osnovne OpenGL značajke

    Skup osnovnih primitiva: točke, linije, poligoni itd.

    Pregledajte i koordinirajte transformacije

    Uklanjanje nevidljivih linija i površina (z-buffer)

    Korištenje splajnova za konstruiranje linija i površina

    Mapiranje teksture i primjena osvjetljenja

    Dodavanje specijalnih efekata: magla, promjena prozirnosti, miješanje boja, uklanjanje aliasinga (anti-aliasing).

Kao što je već spomenuto, postoji OpenGL implementacija za različite platforme, za što je bilo zgodno razdvojiti osnovne funkcije grafičkog sustava i funkcije za prikaz grafičke informacije i interakcija s korisnikom. Biblioteke su stvorene za prikaz informacija pomoću podsustava prozora za operativne sustave Windows sustavi i Unix (WGL odnosno GLX), kao i biblioteke GLAUX i GLUT, koje se koriste za izradu tzv. konzolnih aplikacija.

Biblioteka GLAUX je inferiorna u popularnosti od biblioteke GLUT napisane nešto kasnije, iako pružaju približno iste mogućnosti. GLU biblioteka uključuje implementaciju složenijih funkcija, kao što je skup popularnih geometrijskih primitiva (kocka, lopta, cilindar, disk), funkcije za konstruiranje splineova, implementaciju dodatnih operacija na matricama itd. Svi su oni implementirani kroz osnovne OpenGL funkcije.

Značajke arhitekture i sintakse

S arhitektonskog gledišta, OpenGL grafički sustav je cjevovod koji se sastoji od nekoliko faza obrade podataka:

    Aproksimacija krivulja i površina

    Vertex obrada i primitivno sklapanje

    Rasterizacija i obrada fragmenata

    Operacije nad pikselima

    Priprema teksture

    Prijenos podataka u međuspremnik okvira

Općenito, OpenGL se može usporediti s automatom stanja čije je stanje određeno skupom vrijednosti posebnih varijabli (njihova imena obično počinju znakovima GL_) i vrijednostima trenutne normale, boje i koordinate teksture. Sve ove informacije koristit će se prilikom unosa vrhnog koordinatnog sustava za konstrukciju figure u koju su uključene. Promjene stanja događaju se korištenjem naredbi, koje se izdaju kao pozivi funkcija.

INICIJALIZIRANJE OpenGL BIBLIOTEKE U C++

Prije svega, trebate uključiti datoteke zaglavlja:

#uključi

#uključi

#uključi

· gl.h i glu.h sadrže prototipove glavnih OpenGL funkcija definiranih u opengl32.dll i glu32.dll.

· glaux.h sadrži pomoćne funkcije (glaux.dll).

Nakon povezivanja datoteka zaglavlja, trebate postaviti format piksela. U tu svrhu koristi se sljedeća funkcija:

BOOL bSetupPixelFormat(HDC hdc)

DESKRIPTOR PIXELFORMATA pfd, *ppfd;

int pixelformat;

ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR);

ppfd->nVerzija = 1;

ppfd->dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;

ppfd->dwLayerMask = PFD_MAIN_PLANE;

ppfd->iPixelType = PFD_TYPE_RGBA;

ppfd->cColorBits = 16;

ppfd->cDepthBits = 16;

ppfd->cAccumBits = 0;

ppfd->cStencilBits = 0;

if ((pixelformat = ChoosePixelFormat(hdc, ppfd)) == 0)

MessageBox(NULL, "ChoosePixelFormat failed", "Error", MB_OK);

if (SetPixelFormat(hdc, pixelformat, ppfd) == FALSE)

MessageBox(NULL, "SetPixelFormat nije uspio", "Greška", MB_OK);

Mora se spomenuti struktura PIXELFORMATDESCRIPTOR-a.

cColorBits - dubina boje

cDepthBits - veličina međuspremnika dubine (Z-Buffer)

cStencilBits - veličina međuspremnika šablone (još je ne koristimo)

iPixelType - format specifikacije boje. Može uzeti vrijednosti PFD_TYPE_RGBA (boja je označena s četiri RGBA parametra - crvena, zelena, plava i alfa) i PFD_TYPE_COLORINDEX (boja je označena indeksom u paleti).

Funkcija ChoosePixelFormat() odabire format piksela i vraća njegovu oznaku, a SetPixelFormat() ga postavlja u kontekstu uređaja (dc).

Nakon što je format piksela postavljen u kontekstu uređaja, trebate stvoriti kontekst reprodukcije (kontekst prikazivanja) za to, sljedeće su funkcije definirane u OpenGL-u:

HGLRC wglCreateContext(HDC hdc);

BOOL wglMakeCurrent(HDC hdc, HGLRC hglrc);

U deklaraciji klase obrasca, u privatnom području, trebate dodati sljedeće:

ghRC - pokazivač na kontekst prikazivanja (Rendering Context)

ghDC je ručica uređaja (za nas je to samo pokazivač na prozor)

Postupak izvlačenja bit će odgovoran za izvlačenje.

void __fastcall TForm1::FormCreate(TObject *Sender)

ghDC = GetDC(Handle);

if (!bSetupPixelFormat(ghDC))

ghRC = wglCreateContext(ghDC);

wglMakeCurrent(ghDC, ghRC);

glClearColor(0.0, 0.0, 0.0, 0.0);

Promjena veličine obrasca (pošiljatelj);

glEnable(GL_COLOR_MATERIAL);

glEnable(GL_DEPTH_TEST);

glEnable(GL_LIGHTING);

glEnable(GL_LIGHT0);

float p=(3,3,3,1),

glLightfv(GL_SVJETLO0,GL_POZICIJA,p);

glLightfv(GL_SVJETLO0,GL_TOČKA_SMJER,d);

glViewport(0, 0, širina, visina);

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

glOrtho(-5,5, -5,5, 2,12);

gluLookAt(0,0,5, 0,0,0, 0,1,0);

glMatrixMode(GL_MODELVIEW);

glClearColor() postavlja boju koja će ispuniti zaslon prilikom brisanja. Ova procedura ima 4 parametra, što odgovara RGBA. Umjesto toga, možete napisati glClearIndex(0.0) . Ovaj postupak postavlja indeks boja u paleti.

glViewport() postavlja izlazno područje - područje u koje će OpenGL ispisati sliku.

glMatrixMode() postavlja način matrice transformacije pogleda.

glLoadIdentity() zamjenjuje trenutnu matricu transformacije pogleda s matricom identiteta.

glOrtho() postavlja način ortogonalne (pravokutne) projekcije. To znači da će slika biti nacrtana kao u izometriji. 6 parametara tipa GLdouble (ili jednostavno dvostruko): lijevo, desno, dolje, gore, blizu, daleko određuju koordinate lijeve, desne, donje, gornje, blizu i daleko ravnine odsijecanja, redom, tj. sve što je izvan ovih granica neće biti nacrtano. Zapravo, ovaj postupak jednostavno postavlja mjerilo koordinatnih osi. Za postavljanje perspektivne projekcije koriste se procedure glFrustum() i gluPerspective().

gluLookAt() postavlja parametre kamere: prve tri su njene koordinate, druga je vektor smjera, treća je smjer Y osi.

U OpenGL-u sve se uključuje i isključuje (omogućava i onemogućuje) procedurama glEnable() i glDisable().

glLightfv() postavlja svojstva "žarulja": položaj i smjer svjetla.

Nakon što završite s radom s OpenGL-om, trebate osloboditi zauzete resurse oslobađanjem konteksta pozivanjem wglMakeCurrent s null parametrom za identifikator OpenGL konteksta i uništavanjem tog konteksta s wglDeleteContext. Osim toga, trebate ukloniti ghDC ručku. Budući da rad s OpenGL-om obično završava kada aplikacija izađe, odgovarajući kod treba staviti u FormClose:

void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)

wglMakeCurrent(ghDC,0);

wglDeleteContext(ghRC);

OtpuštanjeDC(Ručka, ghDC);

ZAKLJUČAK

Tijekom stažiranja od 5. do 31. srpnja 2011. u JSC Transas, Aviation Division u odjelu za programiranje, upoznao sam se s radom odjela za programiranje. Upoznao sam dizajn i funkcioniranje složenih simulatora letenja razvijenih u JSC Transas. Saznao sam za sustav za vizualizaciju krajolika i raznih objekata koji se zove Aurora. Stekao sam početne praktične vještine i sposobnosti potrebne za razvoj aplikacija i softvera koristeći suvremeni programski jezik visoke razine i grafičku biblioteku.

Tipično, područje u kojem je potrebno utvrditi prisutnost objekata (područje odabira objekta) definira se kao fragment projekcije scene. Na primjer, korisnik odabire pravokutno područje na projekcijskoj slici koristeći manipulator (npr. pokazivač miša) ili jednostavno klikne tipku miša, definirajući tako područje odabira.

Budući da se u ovim slučajevima područje odabira određuje na projekciji trodimenzionalne scene, potrebno je odrediti odgovarajuće područje trodimenzionalne scene (scena odabira). Scena koju odaberete ovisit će o nekoliko čimbenika: korištenoj projekciji, veličini scene i izlaznom području.

Za određivanje 3D područja odabira na temelju pravokutnog dijela projekcije scene, potrebne su informacije o matrici projekcije. Da biste to učinili, možete koristiti neke funkcije iz biblioteke GLUT, koja je dodatak biblioteci OpenGL i pruža niz dodatnih mogućnosti.

U biblioteci OpenTK, funkcije biblioteke GLUT nalaze se u klasi Glu u prostoru imena Tao.OpenGL(C#). U Object Pascalu sve funkcije i procedure biblioteke GLUT imaju prefiks "glu" kako bi se razlikovale od OpenGL procedura i funkcija.

Za generiranje matrice projekcije na temelju odabranog fragmenta projekcije scene, možete koristiti naredbu PickMatrix biblioteke GLUT:

C#: void gluPickMatrix(double x, double y, double width, double height, int viewport); Object Pascal: procedure gluPickMatrix(x,y,width,height: GLdouble; viewport: PGLint);

Naredba PickMatrix biblioteke GLUT modificira trenutnu matricu tako da veličina regije scene odgovara regiji odabira definiranoj u koordinatama projekcije te scene. Naredba ima sljedeće parametre:

  • x, y – vodoravne i okomite koordinate područja odabira u koordinatama prozora u kojem se prikazuje projekcija 3D scene.
  • širina, visina – širina i visina odabranog pravokutnog područja projekcije 3D scene u koordinatama prozora.
  • okvir za prikaz je niz od četiri cjelobrojna elementa. U C# se polje prosljeđuje izravno kao parametar; u Object Pascalu se kao parametar prosljeđuje pokazivač na polje. Niz definira izlazno područje 3D projekcije scene. Vrijednosti niza moraju odgovarati koordinatama izlaznog područja definiranim pomoću naredbe ViewPort. Elementi ovog niza moraju imati sljedeće vrijednosti: 1. i 2. element – ​​x i y koordinate lijevo gornji kut odabrano područje u zaslonskim koordinatama, 3 i 4 elementa su širina i visina ovog područja.

Naredba se mora izvršiti prije izvršavanja naredbi Ortho ili Frushtum, koje generiraju matricu projekcije.

Stavljanje OpenGL biblioteke u način odabira

Da biste biblioteku stavili u način odabira, koristite naredbu RenderMode:

C#: int RenderMode(RenderingMode mode); Object Pascal: funkcija glRenderMode(mod: GLenum): GLint;

Parametar načina rada određuje način rada OpenGL biblioteke i može uzeti jednu od tri vrijednosti:

Tablica 10.1. Moguće vrijednosti za parametar moda naredbe RenderMode
Opis Značenje
OpenTK biblioteka, C# Object Pascal
Način odabira dana vrijednost koristi se za stavljanje knjižnice u način odabira. RenderingMode.Select GL_SELECT
Način snimanja scene. Ovaj se način rada koristi prema zadanim postavkama nakon pokretanja OpenGL biblioteke. U ovom načinu rada OpenGL biblioteka generira sliku. RenderingMode.Render GL_RENDER
Način povratne informacije. RenderingMode.Feedback GL_POVRATNA INFORMACIJA

Nakon prebacivanja u način odabira, OpenGL ne renderira sliku sve dok se način ne promijeni u način renderiranja scene pomoću naredbe RenderMode s vrijednošću RenderingMode.Render u C# i GL_RENDER u Object Pascalu.

Imenovanje i oblikovanje objekata scene

Kao što je gore objašnjeno, slika se ne generira u načinu odabira. Naredbe za slikanje u ovom načinu rada koriste se za definiranje objekata koji spadaju u područje odabira.

Budući da su objekti s kojima korisnik radi obično formirani od mnogo različitih primitiva, skup imena se koristi za određivanje odabranog objekta. Imena su cjelobrojne vrijednosti. Prije početka ispisa sljedećeg objekta, ime (broj) ovog objekta stavlja se na stog imena. Ako, prilikom formiranja objekta, biblioteka otkrije da primitive ovog objekta spadaju u područje odabira, tada se sadržaj stoga imena kopira u međuspremnik odabira (zajedno s nekim dodatne informacije) inicijaliziran naredbom SelectBuffer. Kada primitive drugog imenovanog objekta uđu u područje scene, sadržaj snopa naziva također će se kopirati u međuspremnik odabira. Tako se mogu dobiti nazivi (brojevi) objekata koji se u cijelosti ili djelomično nalaze unutar područja odabira. Mora se uzeti u obzir da je za ispravno određivanje odabranih objekata potrebno da se koordinatne transformacije objekata poklapaju s onima koje su izvršene pri formiranju slike scene.

Nekoliko naredbi koristi se za rad sa skupom naziva. Brisanje stoga imena vrši se pomoću naredbe InitNames:

C#: void InitNames(); Object Pascal: procedure glInitNames;

Guranje imena na stog vrši se pomoću naredbe PushName:

C#: void PushName(uint ime); Object Pascal: procedure glPushName(name: GLuint);

Ime se prosljeđuje kao parametar naredbe.

Prije nego što se snop imena može koristiti, mora se inicijalizirati pomoću naredbe InitNames. Zatim trebate gurnuti jedan element na stog pomoću naredbe PushName. Prije formiranja svakog objekta, jedan element stoga imena bit će zamijenjen imenom objekta koji se formira pomoću naredbe LoadName. Procedura zamjenjuje zadnji element u nizu naziva onim danim kao parametar. Stoga se inicijalizacija i upotreba stoga imena može shematski prikazati na sljedeći način:

InitNames; PushName(0); ...LoadName(1); //formiranje objekta br. 1 LoadName(2); //formiranje objekta br. 2 LoadName(3); //formiranje objekta br. 3 //itd. Listing 10.7. Dijagram za korištenje niza naziva za odabir objekata

U ovom odjeljku naučit ćemo kako izraditi 3D slike pomoću funkcija OpenGL biblioteke, tako da u sljedećem poglavlju možemo razviti Windows aplikaciju koja se može smatrati alatom za pregled rezultata znanstvenih izračuna. Materijal u ovom odjeljku omogućit će vam da postupno napredujete i svladate vrlo atraktivnu tehnologiju stvaranja i upravljanja trodimenzionalnim slikama. Prvo ćemo pogledati osnovne mogućnosti OpenGL biblioteke, a zatim ćemo naučiti kako kontrolirati OpenGL funkcije Na primjer jednostavne aplikacije konzolnog tipa i tek nakon toga ćemo krenuti u razvoj Windows aplikacije.

Čitatelj vjerojatno zna da je OpenGL optimiziran, visokoučinkovit grafička biblioteka funkcije i tipovi podataka za prikaz dvo- i trodimenzionalne grafike. Standard OpenGL odobren je 1992. godine. Temelji se na biblioteci IRIS GL koju je razvio Silicon Graphics (www.sgi.com). OpenGL je podržan na svim platformama. Osim toga, OpenGL je podržan u hardveru. Postoje video kartice s akceleratorima i specijalizirane SD kartice koje izvode OpenGL primitive u hardveru.

Materijal u prvom dijelu ove lekcije inspiriran je vrlo dobrom knjigom (dostupnom online) od Addison-Wesleya, "OpenGL Programming Guide, The Official Guide to Learning OpenGL". Ako čitatelj posjeduje Engleski jezik, onda preporučamo čitanje.

Povezane knjižnice

Microsoftova implementacija OpenGL-a uključuje cijeli set OpenGL naredbe, tj globalne funkcije, uključen u jezgru biblioteke OPENGL32.LIB i ima prefiks gl(npr. glLineWidth). Imajte na umu da osnovne funkcije biblioteke imaju više verzija, što vam omogućuje da odredite željeni parametar ili postavku na bilo koji način. Pogledajte pomoć za funkcije u obitelji glColor*. Ispada da trenutnu boju možete postaviti na 32 načina. Na primjer, funkcija:

Void glColorSb(GLbyte crvena, GLbyte zelena, GLbyte plava);

Definira boju koristeći tri komponente tipa GLbyte i funkciju:

Void glColor4dv (const GLdouble *v);

Određuje ga pomoću adrese niza od četiri komponente.

Uzimajući u obzir ove opcije, osnovna biblioteka sadrži više od 300 naredbi. Osim toga, možete povezati GLU32.LIB biblioteku uslužnih programa koji nadopunjuju glavni kernel. Postoje funkcije za kontrolu tekstura, transformaciju koordinata, generiranje sfera, cilindara i diskova, spline aproksimacije krivulja i površina ( NURBS - Neuniformni racionalni B-splin), kao i rukovanje greškama. Još jedan, dodatni ( pomoćni) dopušta biblioteka GLAUX.LIB na jednostavan način stvoriti Windows prozore, prikazati neke SD objekte, rukovati ulaznim događajima i upravljati pozadinski proces. Nažalost, ova knjižnica nije dokumentirana. Tvrtka Microsoft Ne preporuča se koristiti za razvoj komercijalnih projekata, jer sadrži kod petlje za obradu poruka u koji je nemoguće umetnuti obradu drugih proizvoljnih poruka.

Bilješka
Tip GLbyte je ekvivalentan tipu signed char, a GLdouble je ekvivalentan tipu double. Njihovi vlastiti tipovi koriste se za pojednostavljenje prenosivosti na druge platforme. U nastavku donosimo popis vrsta OpenGL-a. Četvrta komponenta boje određuje prozirnost boje, što je način na koji se boja pozadine stapa s bojom slike. Neke OpenGL naredbe imaju v na kraju, što označava da bi argument trebao biti adresa niza (vektora). Vektor u matematici je niz brojeva (koordinata) koji jednoznačno definiraju element vektorskog prostora. Mnoge naredbe imaju više verzija, što vam u konačnici omogućuje da navedete vektor na različite načine
.

Oko dvadeset Windows GDI funkcija stvoreno je posebno za rad s OpenGL-om. Većina ih ima prefiks wgl(akronim za Windows GL). Ove funkcije analogne su funkcijama s prefiksom glx, koje povezuju OpenGL s platformom X window sustava. Konačno, postoji nekoliko Win32 funkcija za kontrolu formata piksela i dvostruko međuspremnik. Primjenjivi su samo na specijalizirane OpenGL prozore.