Saturday, June 12, 2010

GL_TEXTURE_2D

GL_TEXTURE_2D

In this part, we continue with a convenient and powerful method for 2D OpenGL, 2D texture.
The strength of using OpenGL 2D texture over glDrawPixels is that linear filtering can be selected.
Moreover, the task is systematic and not tedious.

I, however, do not know if using RGBA is better in terms of performance or not, but I used it in this example.
Thus, we have to modify a way to create a texture image.  The A element can be set to 255, as shown below.

texImage[nColorBytes*(h*m_nWidth + w) + 3] = (GLubyte) 255;

To initialize 2D texture with linear filtering, the following code can be used to make a texImage an OpenGL texture.

void GLTexture2D::initializeGL()
{
    // Basic initialization
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glShadeModel(GL_FLAT);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

    // Texture initialization
    glGenTextures(1, &textureName);
    glBindTexture(GL_TEXTURE_2D, textureName);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);    // GL_NEAREST is another choice
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_nWidth, m_nHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, texImage);
}



To draw a 2D image as a texture, we have to map image coordinates to texture coordinates when we draw GL_QUADS.
In the following function, we map the texture created in initializeGL to rectangular coordinates -1.0 to 1.0.

void GLTexture2D::paintGL() {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glEnable(GL_TEXTURE_2D);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
    glBindTexture(GL_TEXTURE_2D, textureName);

    glBegin(GL_QUADS);
        glTexCoord2f(0.0, 0.0);    glVertex3f(-1.0, -1.0, 0.0);
        glTexCoord2f(0.0, 1.0);    glVertex3f(-1.0,  1.0, 0.0);
        glTexCoord2f(1.0, 1.0);    glVertex3f( 1.0,  1.0, 0.0);
        glTexCoord2f(1.0, 0.0);    glVertex3f( 1.0, -1.0, 0.0);
    glEnd();
    glDisable(GL_TEXTURE_2D);
}


===================================

An example project for Eclipse CDT / Qt on Linux is stored at a public folder here.
The project file is valid for Eclipse CDT on Linux with Qt integration (Ubuntu 9.04 Juanty), but the main part should be applicable to most C++ environment.


Pinyo Taeprasartsit
Octobor 2009

No comments: