Kaasaegne OpenGL-02 – Textures

Link: https://www.tomdalling.com/blog/modern-opengl/02-textures/

<väike class=”meta”> Kategooria: Kaasaegne OpenGL-Seeria

Käesolevas artiklis, me lisada tekstuuri kolmnurk. See hõlmab, lisades uusi muutujaid, et tipp ja fragment varjutajad, luua ja kasutada tekstuur objektid ja õppe natuke tekstuuri üksused ja tekstuuri koordinaadid.

Selles artiklis nähakse ette kahe uue liigi tdogl nimeruum: tdogl::Bitmap ja tdogl::Tekstuur. Need võimaldavad meil laadi pilt on jpg, png või bmp faili video mälu, kasutamiseks varjutajad. Ka tdogl::Programm klass on mõned uued meetodid, millega shader muutujad.

Juurdepääsu Kood

Lae alla kogu kood zip-ina siit: https://github.com/tomdalling/opengl-series/archive/master.zip

Kõik koodi selle sarja tooted on saadaval github: https://github.com/tomdalling/opengl-series. Võite alla laadida zip-kõik failid sellest lehekülg, või saab kloonida hoidla kui te olete tuttav git.

See artikkel põhineb kood varasemat artiklit.

Kood käesoleva artikli võib leida source/02_textures kaust. OS X, avatud opengl-seeria.xcodeproj – faili root kausta ja valige siht, mis vastab käesoleva artikli. Windows, avage opengl-seeria.sln – faili Visual Studio 2013, ja avatud projekt, mis vastab käesoleva artikli.

Projekt hõlmab kõiki oma sõltuvusi, nii et teil pole õigust paigaldada või seadistada midagi ekstra. Palun andke mulle teada, kui teil on mingeid küsimusi koostada ja käivitada koodi.

Ühtne vs Atribuut Shader Muutujad

Kõik muutujad, mis eelmises artiklis olid atribuut muutujad. Käesolevas artiklis me ei kasutusele muud tüüpi muutuja: ühtne muutujad.

Atribuut muutujad võivad on erinev väärtus iga tipu. Ühtne muutujate hoida sama raha eest mitu tippu.

On kahte tüüpi shader muutujad: ühtne muutujate ja atribuut muutujad. Atribuut muutujad võivad on erinev väärtus iga tipu. Ühtne muutujate hoida sama raha eest mitu tipud. Näiteks, kui soovite valida värvi kogu kolmnurk, mida sa kasutad ühtlane muutuv. Kui soovite iga välisnurk, kolmnurga olla erinevat värvi, siis oleks kasutage atribuudi muutuja. Ma lihtsalt viidata neile kui “vormirõivad” ja “atribuudid” nüüd.

Vormirõivad, saab kasutada igas shader, kuid atribuudid tuleb sisestada vertex shader esiteks ei ole fragment shader. Ka vertex shader liigu väärtust arvesse fragment shader kui vaja.

Vormiriietuse pääseb igast shader, kuid atribuudid tuleb sisestada vertex shader esiteks ei ole fragment shader. Ka vertex shader liigu väärtust arvesse fragment shader kui vaja. See on sellepärast, et vormiriietus on nagu konstandid – nad ei muuda, nii et neid saab kasutada igas shader. Siiski omadused ei ole muutumatud. Ka vertex shader on võimalik muuta väärtus atribuudi enne, kui see jõuab fragment shader. Väljund vertex shader on sisend fragment shader.

Väärtuse määramiseks ühtne, me kasutada üks glUniform*funktsioonid. Et määrata väärtus atribuudi, me salvestada väärtusi VBO ja saata need shader koos VAO ja glVertexAttribPointer nagu me nägime eelmises artiklis. Samuti on võimalik, et määrata väärtus atribuudi kasutamine on üks glVertexAttrib* funktsioonid, kui te ei ole hoidmine väärtusi VBO.

Tekstuurid

Tekstuurid on põhimõtteliselt 2D-pilte, mida saab rakendada oma 3D-objekte.

Tekstuurid on põhimõtteliselt 2D-pilte, mida saab rakendada oma 3D-objekte. Nad on muul otstarbel, kuid kuvamine 2D-pilt 3D geomeetria on kõige levinum kasutada. Seal on 1D, 2D ja 3D tekstuuride, kuid me saame olla ainult siis, vaadates 2D tekstuurid käesolevas artiklis. Senisest põhjalikum pilk tekstuurid, vt Tekstuurid ei ole Pildid peatükk Õppe Kaasaegne 3D Graafika Programmeerimine raamat.

Tekstuurid live video mälu. See tähendab, et teil laadida andmeid tekstuur graafika kaarti on vaja enne kasutamist vormindada. See on sarnane sellele, kuidas me nägime VBOs töö eelmises artiklis – VBOs kasutatakse andmete talletamiseks video mälu enne, et andmeid saab kasutada.

pixel laius ja kõrgus tekstuur peaks olema õigus kahe.

Sensori laius ja kõrgus tekstuur peaks olema õigus kahe, näiteks: 16, 32, 64, 128, 256, 512. Käesolevas artiklis me kasutame 256×256 image “ohtu.png”, nagu tekstuur, mis on näidatud allpool.

Me kasutame tdogl::Bitmap – klassi laadida raw pixel andmed “oht.png” mällu, abiga stb_image. Siis meil on kasutada tdogl::Tekstuur upload raw pikslite andmed sisse OpenGL tekstuur objekt. Õnneks tekstuur loomist toetab OpenGL-i ei ole tegelikult muutunud, kuna see võeti esmakordselt kasutusele, nii et seal on palju häid artikleid internetis, mis näitab teile, kuidas luua tekstuuri. Nii, et tekstuuri koordinaadid on saadetud graafika kaart on muutunud, kuid loomine tekstuur on sama.Allpool on ehitaja kood tdogl::Tekstuur, mis tegeleb loomine OpenGL tekstuuri.

Texture::Texture(const Bitmap& bitmap, GLint minMagFiler, GLint wrapMode) :
    _originalWidth((GLfloat)bitmap.width()),
    _originalHeight((GLfloat)bitmap.height())
{
    glGenTextures(1, &_object);
    glBindTexture(GL_TEXTURE_2D, _object);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minMagFiler);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, minMagFiler);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapMode);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapMode);
    glTexImage2D(GL_TEXTURE_2D,
                 0, 
                 TextureFormatForBitmapFormat(bitmap.format()),
                 (GLsizei)bitmap.width(), 
                 (GLsizei)bitmap.height(),
                 0, 
                 TextureFormatForBitmapFormat(bitmap.format()), 
                 GL_UNSIGNED_BYTE, 
                 bitmap.pixelBuffer());
    glBindTexture(GL_TEXTURE_2D, 0);
}

Tekstuuri Koordinaadid

kummaline asi tekstuuri koordinaadid on see, et nad ei ole pikslit. Nad vahemikku nullist kuni ühe, kus (0,0) on vasakul ja (1,1) on täiesti õigus.

Tekstuuri koordinaadid on, üllatav, koordinaatide järgi tekstuuri. Kummaline asi tekstuuri koordinaadid on see, et nad ei ole pikslit. Nad vahemikku nullist kuni ühe, kus (0,0) on vasakul ja (1,1) on üleval paremal. Kui laadid pildi OpenGL tagurpidi, siis (0,0) on üleval vasakul, mitte vasakul. Lülitada pixel koordinaadid arvesse tekstuuri koordinaadid, peate jagada kõrgus ja laius tekstuuri. Näiteks 256×256 pildi, pixel koordinaadid (128, 256) muutunud (0.5, 1) tekstuuri koordinaadid.

Tekstuuri koordinaadid on tavaliselt nimetatakse UV-koordinaadid. Sa võiksid helistada XY koordinaadid, kuid XYZ on tavaliselt kasutatakse, et esindada tipp, ja me ei taha ajada tekstuuri koordinaadid, mille tippude koordinaadid.

Texture Pildi Üksused

Sa ei saa lihtsalt saata tekstuur otse shader. Esimese saate siduda tekstuuri tekstuuri üksus, siis saadate indeks tekstuur ühik, et shader.

Tekstuur pildi üksused, või lihtsalt “tekstuur üksused” lühike, on veidi imelik osa OpenGL-i. Sa ei saa lihtsalt saata tekstuur otse shader. Esimese saate siduda tekstuuri tekstuuri üksus, siis saadate indeks tekstuur ühik, et shader.

Seal on piiratud arv tekstuur ühikut. Vähem-võimas seadmetega, näiteks telefonid, seal võib olla vaid kaks tekstuuri ühikut. Sellisel juhul, isegi kui me võiks olla kümneid tekstuurid, me võib kasutada ainult kaks neist samal ajal varjutajad. Me ainult kasutades ühte tekstuur käesolevas artiklis, nii et meil on vaja ainult üks tekstuur ühik, aga see on võimalik, et segu mitmest eri tekstuure koos sees fragment shader.

Rakendamisel Tekstuurid

Esimese, let ‘ s tegema uue ülemaailmse jaoks tekstuuri.

tdogl::Texture* gTexture = NULL;

Me teha uusi funktsioone koormus “ohtu.png” into the global. See saab helistas AppMainfunction.

static void LoadTexture() {
    tdogl::Bitmap bmp = tdogl::Bitmap::bitmapFromFile(ResourcePath("hazard.png"));
    bmp.flipVertically();
    gTexture = new tdogl::Texture(bmp);
}

Järgmine anname iga tipu kolmnurk tekstuuri kooskõlastada. Kui võrrelda UV coords, et pildi peal, siis näed, et koordinaadid esindada (middle,top), (vasakule,alt), ja (paremal,all) selles järjekorras.

GLfloat vertexData[] = {
    //  X     Y     Z       U     V
     0.0f, 0.8f, 0.0f,   0.5f, 1.0f,
    -0.8f,-0.8f, 0.0f,   0.0f, 0.0f,
     0.8f,-0.8f, 0.0f,   1.0f, 0.0f,
};

Nüüd peame muuta fragment shader nii, et see võtab faktuur ja tekstuur koordineerida sisendina. Uus fragment shader näeb välja selline:

#version 150
uniform sampler2D tex; //this is the texture
in vec2 fragTexCoord; //this is the texture coord
out vec4 finalColor; //this is the output color of the pixel

void main() {
    finalColor = texture(tex, fragTexCoord);
}

ühtne märksõna märke, et tex on ühtne muutuja. Tekstuur on ühtlane, sest kõik tipud kolmnurk on sama tekstuur. sampler2D on muutuja tüüp, mis näitab, et tal on 2D tekstuuri.

fragTexCoord on atribuut muutuja, sest iga tipu kolmnurk on erinev tekstuur kooskõlastada.

texture funktsioon leiab, värvi pixel antud tekstuur kooskõlastada. Vanemate versioonide GLSL, siis oleks kasutada texture2D funktsioon, et seda teha.

Me ei saa edasi atribuut otse fragment shader, sest atribuudid peavad kõigepealt läbima vertex shader. Siin on muudetud vertex shader:

#version 150
in vec3 vert;
in vec2 vertTexCoord;
out vec2 fragTexCoord;

void main() {
    // Pass the tex coord straight through to the fragment shader
    fragTexCoord = vertTexCoord;
    
    gl_Position = vec4(vert, 1);
}

See vertex shader võtab vertTexCoord sisendina, ja läheb seda otse fragTexCoordatribuut fragment shader muutmata.

Kui varjutajad nüüd on kaks muutujat on meil vaja, et määrata: vertTexCoord atribuudi ja tex ühtne. Alustame seadistamine tex muutuja. Avada main.cpp ja leida Render() function. Me määratud tex ühtne lihtsalt enne kui me joonesta kolmnurk:

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, gTexture->object());
gProgram->setUniform("tex", 0); //set to 0 because the texture is bound to GL_TEXTURE0

Tekstuur ei saa kasutada, kuni see on seotud tekstuur üksus. glActiveTexture ütleb OpenGL, mille tekstuur ühik me tahame kasutada. GL_TEXTURE0 on esimene tekstuur üksus, nii et me lihtsalt kasutada.

Järgmine, mida me kasutame glBindTexture koo meie tekstuur aktiivsesse tekstuur üksus.

Seejärel seadsime tex ühtne shaders indeks tekstuur ühik. Me kasutasime tekstuur ühik null, seega seadsime tex ühtne täisarvuline väärtus 0. setUniform meetod lihtsalt nõuab glUniform1ifunction.

Viimane samm on saada tekstuuri koordinaadid arvesse vertTexCoord atribuut. Et seda teha, me muuta VAO sees LoadTriangle() function. See on see, mida koodi kasutatakse, et välja nägema:

// Put the three triangle vertices into the VBO
GLfloat vertexData[] = {
    //  X     Y     Z
     0.0f, 0.8f, 0.0f,
    -0.8f,-0.8f, 0.0f,
     0.8f,-0.8f, 0.0f
};

// connect the xyz to the "vert" attribute of the vertex shader
glEnableVertexAttribArray(gProgram->attrib("vert"));
glVertexAttribPointer(gProgram->attrib("vert"), 3, GL_FLOAT, GL_FALSE, 0, NULL);

Ja see on see, mida me peame muutma seda, et:

// Put the three triangle vertices (XYZ) and texture coordinates (UV) into the VBO
GLfloat vertexData[] = {
    //  X     Y     Z       U     V
     0.0f, 0.8f, 0.0f,   0.5f, 1.0f,
    -0.8f,-0.8f, 0.0f,   0.0f, 0.0f,
     0.8f,-0.8f, 0.0f,   1.0f, 0.0f,
};

// connect the xyz to the "vert" attribute of the vertex shader
glEnableVertexAttribArray(gProgram->attrib("vert"));
glVertexAttribPointer(gProgram->attrib("vert"), 3, GL_FLOAT, GL_FALSE, 5*sizeof(GLfloat), NULL);
    
// connect the uv coords to the "vertTexCoord" attribute of the vertex shader
glEnableVertexAttribArray(gProgram->attrib("vertTexCoord"));
glVertexAttribPointer(gProgram->attrib("vertTexCoord"), 2, GL_FLOAT, GL_TRUE,  5*sizeof(GLfloat), (const GLvoid*)(3 * sizeof(GLfloat)));

Oleme lisanud teise kõne glVertexAttribPointer, kuid me oleme ka muudetud esimene kõne ka. Kõige olulisemad argumendid, et pilk on kaks viimast.

Teine viimane argument, et nii glVertexAttribPointer kõned on 5*sizeof(GLfloat). See on “stride” argument. See argument tahab teada, kui palju baite on vahel alustada ühe väärtuse, ja järgmise alguse väärtus. Mõlemal juhul on iga väärtus viie GLfloats eemale järgmise väärtus. Näiteks, kui me hakkame “X” väärtus ja loe edasi viis väärtused, me olema järgmine “X” väärtus. Sama kehtib ka juhul, kui me alustama “U” väärtus ja loe edasi viis. See väide on baiti, ei ujub, nii et me peame korrutama arv hõljub, mitu baiti per float.

Viimane argument, et glVertexAttribPointer on “nihe” argument. See argument tahab teada, mitu baiti algusest on esimene väärtus. Esimene XYZ väärtus on õigus alguses, nii et nihe on seatud NULL, mis tähendab “null baiti algusest”. Esimene UV – väärtus ei ole alguses – see on kolm hõljub ära algusest peale. Veelkord, see argument on baiti, ei ujub, nii et me peame korrutama arv hõljub, mitu baiti per float. Me peame loo baitide arv, et const GLvoid*, sest vanemad versioonid OpenGL see argument, mida kasutatakse, et tuleb midagi erinevat, “nihe”, et ta on praegu.

Nüüd, kui käivitate programmi, siis peaks näha reljeefne kolmnurk nagu üks ülaosas näidatakse käesoleva artikli.

Tulevik Artikli Sneak Peek

Järgmises artiklis me õpime natuke maatriks matemaatika ja kasutamise tabelite pöörlema kuubik, liigutage kaamerat, ja lisada perspektiivi projektsioon. Me ka õppida sügavus puhverdamine, ja kuidas tüüpiline programm ei aja põhinevad uuendused, nagu animatsioon.

Täiendavaid OpenGL Tekstuur Ressursid

<

  • Juhendaja 16 – Basic Texture Mapping poolt Etay Meiri
  • <

  • tekstureerimiseks näide kood poolt Jacob Progsch
  • Leave a Reply