Textúrázás

1. Kezdjünk új OpenGL projektet, de üres main.cpp helyett ezzel a file-lal!

2. Először saját, memóriában létrehozott textúrával próbáljuk ki a textúrázást! Ehhez adjuk meg a következő függvényt és globális változót:

GLuint checker;

void loadGenTexture()
{
    unsigned char tex[256][256][3];
    for (int i=0; i<256; ++i)
        for (int j=0; j<256; ++j)
        {
            if ( i == 0 ) { // elso sor
                tex[i][j][0] = 0;
                tex[i][j][1] = 255;
                tex[i][j][2] = 0;
            } else if ( j == 0 ) { // elso oszlpo
                tex[i][j][0] = 0;
                tex[i][j][1] = 0;
                tex[i][j][2] = 255;
            } else
                tex[i][j][0] = tex[i][j][1] = tex[i][j][2] = ((i/16%2) ^ (j/16%2)) * 255;
        }

    glGenTextures(1, &checker);
    glBindTexture(GL_TEXTURE_2D, checker);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 256, 256, 0, GL_RGB, GL_UNSIGNED_BYTE, tex);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
}

A tex változóban hozunk létre egy 256x256-os képet, minden képponthoz három byte-nyi RGB adat tartozik. A kép egy 16x16-os sakktábla lesz, bal oldalán egy kék, tetején egy zöld csíkkal. A bal felső sarkot egy piros pont jelzi.

Ahhoz, hogy ezt a képet textúraként tudjuk használni, először egy új textúra nevet kell az OpenGL-től kérnünk (ami gyakorlatilag csak egy szám), amivel a továbbiakban erre a textúrára tudunk hivatkozni. Ezt fogjuk a checker változóban tárolni, és a glGenTextures függvény segítségével generáltatjuk. Ezzel egyszerre akár több textúra nevet is lehet generáltatni, amiket a paraméterként kapott címre menti.

Az aktuálisan használt textúrát a glBindTexture függvénnyel adhatjuk meg. Ennek első paramétere, hogy milyen cél textúráról van szó, mi csak a GL_TEXTURE_2D típust fogjuk használni. Második paramétere a használni kívánt textúra neve.

A képadatok betöltését a glTexImage2D függvény végzi. Itt a negyedik és az ötödik paraméter adja meg a kép szélességét és magasságát, amik régi OpenGL verziókban csak kettő-hatvány értékűek lehetnek.

 A glTexParameter az első paramétereként megadott cél textúra viselkedése állítható. A lehetséges paraméterek listája a függvény leírásánál megtalálható, a fontosabbak:

3. Ezt a függvényt hívjuk meg main-ben, és engedélyezzük a textúrák használatát:

//...
    glutMouseFunc(mouseClick);
    glutMotionFunc(mouseMove);

    loadGenTexture();
    glEnable(GL_TEXTURE_2D);

    glutMainLoop();
    return 0;
}

4. Ahhoz, hogy ez meg is jelenjen a modellen, a csúcspontokhoz textúra-koordinátákat kell megadnunk:

void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    cam.setView();

    glBegin(GL_QUADS);
        glTexCoord2f(0, 1);
        glVertex3f(-1,-1, 0);
        glTexCoord2f(0, 0);
        glVertex3f(-1, 1, 0);
        glTexCoord2f(1, 0);
        glVertex3f( 1, 1, 0);
        glTexCoord2f(1, 1);
        glVertex3f( 1,-1, 0);
    glEnd();

    glutSwapBuffers();
}

* Feladatok:

a) Próbáld ki a GL_TEXTURE_MIN_FILTER és a GL_TEXTURE_MAG_FILTER más beállításait is!

b) Különböző, 0-nál kisebb és 1-nél nagyobb textúra koordináták mellett próbáld ki a GL_TEXTURE_WRAP_S és GL_TEXTURE_WRAP_T változtatásának a hatását!


Képek betöltése file-ból

1. Se az OpenGL se a GLUT nem támogatja képfile-ok betöltését, ezért ehhez külön könyvtárra van szükségünk.

Az órán a FreeImage nevű könyvtárt fogjuk használni. Az ehhez szükséges file-ok letölthetők innen. Ezeket a projekt könyvtárába kell másolni. A projekt beállításoknál meg kell adni a következőt:

A programunkban pedig include-olni kell a FreeImage.h header-t.

2. A következő függvénnyel tölthetünk be egy képet textúrába, és a textúra nevét kapjuk meg visszatérési értékként:

GLuint textureFromFile(const char* filename)
{
    FREE_IMAGE_FORMAT fileFormat = FIF_UNKNOWN;
    FIBITMAP *image(0);
    BYTE* bits(0);
    unsigned int width(0), height(0);
    
    fileFormat = FreeImage_GetFileType(filename, 0);
    image = FreeImage_Load(fileFormat, filename);
    if(!image)
        return 0;

    FreeImage_FlipVertical(image);

    bits = FreeImage_GetBits(image);
    width = FreeImage_GetWidth(image);
    height = FreeImage_GetHeight(image);

    GLuint tex;
    glGenTextures(1, &tex);
    glBindTexture(GL_TEXTURE_2D, tex);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, bits);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

    FreeImage_Unload(image);

    return tex;
}

* Feladat:

a) A függvény segítségével tölts be egy képet file-ból!

b) Hozz létre újabb objektumokat vagy a meglévőt rajzold ki többször, és jelenítsd meg őket különböző textúrákkal!