Capitolul 5 al bazei opengl, cartea lui Igor Tarasov, un tutorial, exemple

5.4 Crearea unei texturi în memorie

O singură ieșire de imagini nu este suficientă pentru a crea scene tridimensionale cu drepturi depline. Deseori, este nevoie să se suprapună o imagine pe obiecte tridimensionale și să se rotească / să se schimbe. În aceste scopuri, există o textură. De asemenea, texturile vă vor ajuta să acoperiți întregul obiect sub forma unui mozaic. Spuneți, atunci când aveți un zid de cărămidă, atunci nu este nevoie să încărcați o imagine cu o grămadă de cărămizi. Este suficient să încărcați o cărămidă și să indicați că această textură trebuie multiplicată pe întregul plan.






Mai întâi vom analiza crearea și suprapunerea texturilor pe un avion. Apoi, luați în considerare cartografierea texturilor la obiectele descrise în secțiunea 4.1. Și în final, pentru toți ceilalți creați din poligoane; în special, un torus și un ceainic.

Pentru a aplica o textura unui obiect, trebuie:
  • Încărcați fișierul imagine în memorie
  • Creați un nume de identificator pentru textură
  • Faceți-l activ
  • Creați textura însăși în memorie
  • Setați opțiunile de textură
  • Setați parametrii de interacțiune a texturii cu obiectul
  • Asociați coordonatele texturii cu obiectul
  • Primul pe care l-ați învățat deja în secțiunea anterioară. Creați un proiect numit Textură. Declarați următoarele variabile globale:

    Variabilele photo_tex și space_tex vor servi drept identificatori de textură. Și în photos_image și space_image vom încărca fișierele bmp. Aici trebuie remarcat faptul că texturile din OpenGL ar trebui să aibă o dimensiune de 2 n x 2 m. unde n și m sunt numere întregi. Acest lucru este făcut pentru a accelera munca, pentru că comprimați sau întindeți aceste texturi mai rapid și mai convenabil. Desigur, puteți încărca o imagine de orice altă dimensiune, dar va trebui să fie redimensionată. În opinia mea, acest lucru este greșit. Rezultatul scalării poate să nu vi se potrivească. Deci, folosesc fișiere grafice cu o dimensiune care este un multiplu al puterii a două. Este mai convenabil pentru mine să editez o imagine într-un pachet grafic, să o taie sau, dimpotrivă, să o completez decât să aflu de ce este distorsionată. Cu toate acestea, depinde mult de cazul specific. Artistul care face texturi nu are grijă ce dimensiune să facă, deci este mai ușor să-l rogi să facă o imagine cu dimensiunile corespunzătoare. Lipiți următorul cod în funcția principală.

    Luați fotografiile din programul meu - Textură. Puteți face o fotografie proprie ;-) Numai dimensiunea acesteia ar trebui să rămână 512x512.
    Acum trebuie să creați un nume de identificator al texturii. Ar trebui să fie creat atunci când aveți mai multe texturi în aplicația dvs., astfel încât să puteți distinge cumva între ele. În caz contrar, atunci când textura este una singură, nu are nevoie de un identificator. În exemplul următor, atunci când aplicați o textură unei sfere, vom avea exact o textură și vom arăta care sunt apelurile funcționale opționale. Pentru moment, presupun că trebuie să utilizați mai multe texturi. Apropo, m-am uitat la multe exemple când scriu o carte. Printre acestea s-au numărat exemple din Cartea Roșie cunoscută, exemple din MSDN, Internet și alte surse, dar tot ceea ce sa referit la texturi a lucrat cu o singură textură. Pentru un program de exemplu elementar, desigur, o textura este potrivita, dar pentru aplicatii serioase, este putin probabil. Vrem să scriem aplicații serioase, așa că va trebui să folosim mai multe texturi. Funcția glGenTextures are două parametri în intrare. Primul specifică numărul de nume de identificatori de texturi pe care doriți să le creați. Al doilea parametru este un pointer la o serie de elemente int nesemnate. Numărul elementelor din matrice trebuie să se potrivească cu numărul specificat ca primul parametru. De exemplu, următorul cod creează zece nume de textură.

    Păstrați identificatorii texturilor într-o matrice nu este întotdeauna convenabilă. Această metodă este potrivită pentru stocarea fundalurilor sau tipurilor de pereți: caramida, piatră etc. În general, matricele stochează acele elemente, între care există ceva în comun. În cazul nostru, două imagini sunt conectate, deoarece Îl folosesc într-o singură aplicație, așa că am creat două identificatoare diferite. Deci, adăugați următorul cod la funcția principală.







    Acum suntem atașați de textura fotografiei, adică face activ. Pentru aceasta, utilizați funcția glBindTexture. Primul parametru trebuie să fie GL_TEXTURE_2D sau GL_TEXTURE_1D. Arată dacă o imagine unidimensională sau bidimensională va funcționa. Toate exemplele se referă aici la texturi bidimensionale. Pentru o textură unidimensională, pur și simplu nu am găsit un exemplu frumos. Cu toate acestea, în Cartea Roșie există un exemplu cu textura unidimensională. Acolo fierbătorul este decorat cu o panglică roșie. Unde să luați aceste exemple și mai multe, consultați apendicele "A". Al doilea parametru glBindTexture este identificatorul pe care l-am creat mai sus cu glGenTextures. Acum adăugați apelul la această funcție în principal.

    Acum trebuie să creăm textura în memorie. matrice octet structura AUX_RGBImageRec nu este chiar textura, deoarece textura o mulțime de opțiuni diferite. După ce am creat o textură, îi vom împărți anumite proprietăți. Printre parametrii texturii, specificați nivelul de detaliere, modul de a scala și de a lega textura de obiect. Nivelul de detaliu este necesar pentru a aplica textura obiectelor mai mici, adică Când zona de pe ecran este mai mică decât dimensiunea imaginii. Nivelul zero al detaliilor corespunde imaginii originale cu dimensiunea 2 n x 2 m. primul nivel este de 2 n-1 x2 m-1. Nivelul k este de 2 n-k x2 m-k. Numărul de niveluri corespunde cu min (n, m). Pentru a crea textura are două funcții glTexImage [1/2] D și DMipmaps gluBuild [1/2].

    Principala diferență este că prima funcție creează o textura de un anumit nivel de detaliu și percepe doar imagini. a cărui mărime este un multiplu de gradul doi. A doua funcție este mai flexibilă. Acesta generează texturi la toate nivelele de detalii. De asemenea, această funcție nu necesită ca dimensiunea imaginii să fie mai mare decât puterea a două. Aceasta va comprima / întinde imaginea într-un mod adecvat, deși se poate dovedi că nu este în întregime adecvată. Voi folosi funcția glTexImage2D. Primul parametru al acestei funcții trebuie să fie GL_TEXTURE_2D. Al doilea este nivelul de detaliu. Avem nevoie de imaginea originală, deci nivelul de detaliere este zero. Al treilea parametru indică numărul de componente de culoare. Imaginea noastră este stocată în format RGB. Prin urmare, valoarea acestui parametru este de trei. Al patrulea și al cincilea parametru sunt lățimea și înălțimea imaginii. A șasea este lățimea graniței; nu vom avea un hangout, deci valoarea acestui parametru este zero. În continuare, al șaptelea parametru este formatul pentru stocarea pixelilor în matrice - GL_RGB și tipul - GL_UNSIGNED_BYTE. În sfârșit, al optulea parametru este un indicator pentru o serie de date. De asemenea, trebuie să apelați funcția glPixelStorei și să specificați că alinierea în matricea de date este byte. Adăugați următorul cod la funcția principală.

    Un rezultat similar poate fi obținut prin introducerea unui apel la gluBuild2DMipmaps cu parametrii enumerați mai jos.

    Acum trebuie să setați parametrii texturii. În acest scop, funcția

    Primul parametru are valoarea GL_TEXTURE_1D sau GL_TEXTURE_2D. Al doilea - pname - definește parametrul textură, pe care îl veți schimba. Și al treilea parametru este valoarea de setare. Dacă ați folosit gluBuild2DMipmaps în loc de glTexImage2D, atunci nu este necesar să setați următorii parametri, deoarece texturi de toate nivelele de detaliu sunt deja formate, iar OpenGL va putea sa adune textura la nivelul dorit daca zona obiectului nu coincide cu zona texturii. În caz contrar, trebuie să adăugați următoarele linii:

    Ați indicat că algoritmul GL_NEAREST este utilizat pentru a reduce și a mări textura. Aceasta înseamnă că culoarea celui mai apropiat pixel al elementului de textura devine culoarea pixelului obiectului pe care este aplicată textura. În loc de GL_NEAREST, puteți specifica GL_LINEAR, adică culoarea elementului obiectului va fi calculată ca media aritmetică a celor patru elemente ale texturii. Există patru alți algoritmi pentru calcularea culorii unui element obiect. Ele pot fi stabilite atunci când creați o textură cu toate nivelele de detaliu, deoarece Aplicați algoritmii GL_NEAREST și GL_LINEAR la unul sau două dintre cele mai apropiate nivele de detaliu.
    De asemenea, puteți seta interacțiunea texturii cu obiectul. Există două moduri aici când utilizați cele trei componente color. Primul mod este implicit atunci când ia în considerare culoarea culoarea obiectului și textura. Culoarea rezultată se obține prin înmulțirea componentelor de culoare la textura componentelor de culoare obiect. De exemplu, în cazul în care textura de culoare - (r, g, b) și culoarea obiectului căruia i se aplică, - (r0, G0, b0), culoarea rezultată va - (r * r0, g * g0, b * b0) . În cazul în care culoarea obiectului negru - (0,0,0), atunci nu vei vedea pe textura, asa ca va fi totul negru. Al doilea mod de interacțiune, atunci când culoarea obiectului nu este luată în considerare. Culoarea rezultată este culoarea texturii. Acești parametri pot fi setați după cum urmează.

    În mod implicit, așa cum am spus, este modul GL_MODULATE. Acum faceți textura activă a space_tex. Și repetă pentru ea același lucru. Aceasta finalizează crearea texturii. Rămâne să asociați coordonatele texturii cu coordonatele obiectului. Editați funcția de afișare astfel:

    După cum probabil ați ghicit, glTexCoord2d compară coordonatele texturii cu vârfurile patrulaterului. Voi spune doar că colțul din stânga jos al texturii are coordonate (0,0), iar colțul din dreapta sus (1,1).

    Capitolul 5 al bazei opengl, cartea lui Igor Tarasov, un tutorial, exemple

    Fișierul sursă poate fi găsit aici. Executivul este aici.
    Fotografia mea e aici. Cerul înstelat este aici.







    Trimiteți-le prietenilor: