Texturing a vertex array with a bitmap.

I’m currently trying to texture a quad that has been spilt up into smaller quads (for torch lighting effect) but it’s giving bizarre results. I’m working in windows and using the LoadImage function so perhaps I’m not using the handle it returns correctly or maybe I’m not using the right OpenGL calls but here’s what I’m doing. Perhaps also my texture coordinates are wrong… I’m drawing a quad that extends from +0.5 to -0.5 in the z direction, with a height of 0.7 and positioned at x=0.5. This is shifted around later but for rotational purposes it’s drawn there. The loadTexture and setUpWallArray functions are called earlier. I know the wall is drawn in the right place since when I turn off the texture a white wall is there. Whatever bitmap I upload, the following texture is shown.

Which is mental really. Below is the code that does the uploading, fills the vertex array and should do the drawing… I’m not sure where the error lies here… The image appears to be uploaded succesfully and I am able to retrieve the height of it using cout << BM.bmHeight for example.


GLuint textures[1];

static GLfloat wallVertices[(sizeG+1)*(sizeG+1)][3];
static GLfloat wallNormals[(sizeG+1)*(sizeG+1)][3];
static GLfloat texCoords[(sizeG+1)*(sizeG+1)][2];
unsigned int wallIndex[sizeG*sizeG*4];


void loadTexture()
{
    HBITMAP hBmp = NULL;

    hBmp = (HBITMAP) ::LoadImage
    (
        NULL,
        "C:\\Documents and Settings\\B\\Desktop\\Game Textures\\Wall.bmp",
        IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE
    );

    BITMAP BM;
    ::GetObject(hBmp, sizeof(BM), &BM);

    //glPixelStorei(GL_UNPACK_ALIGNMENT, 4); ???

    glGenTextures( 1, textures );

    glBindTexture(GL_TEXTURE_2D, textures[0]);

    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,     GL_REPEAT);
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,     GL_REPEAT);

    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, BM.bmWidth, BM.bmHeight,
                 0, GL_RGB, GL_UNSIGNED_BYTE, BM.bmBits);

    DeleteObject((HGDIOBJ) hBmp);
}


void setUpWallArray()
{
    for (int i = 0; i <= sizeG; i++)
    {
        for (int j = 0; j <= sizeG; j++)
        {
            wallVertices[(sizeG+1)*i + j][0] = 0.5;
            wallVertices[(sizeG+1)*i + j][1] = (i*0.7)/(1.0*sizeG);
            wallVertices[(sizeG+1)*i + j][2] = (j*1.0)/(1.0*sizeG) - 0.5;

            wallNormals[(sizeG+1)*i + j][0] = 1.0;
            wallNormals[(sizeG+1)*i + j][1] = 0.0;
            wallNormals[(sizeG+1)*i + j][2] = 0.0;

            texCoords[(sizeG+1)*i + j][0] = (1.0*j)/(1.0*sizeG);
            texCoords[(sizeG+1)*i + j][1] = (1.0*i)/(1.0*sizeG);
        }
    }

    int i = 0;
    for (unsigned int column = 0; column < sizeG; column++)
    {
        for (unsigned int row = 0; row < sizeG; row++)
        {
            wallIndex[i] = (sizeG+1)*column + row;
            i += 1;
            wallIndex[i] = (sizeG+1)*column + row + 1;
            i += 1;
            wallIndex[i] = (sizeG+1)*(column + 1) + row + 1;
            i += 1;
            wallIndex[i] = (sizeG+1)*(column + 1) + row;
            i += 1;
        }
    }
}


void drawWall()
{
        glPushMatrix();
            glColor3f(0.9,0.9,0.9);
            glEnable(GL_TEXTURE_2D);

            glBindTexture(GL_TEXTURE_2D, textures[0]);

            glEnableClientState(GL_VERTEX_ARRAY);
            glEnableClientState(GL_NORMAL_ARRAY);
            glEnableClientState(GL_TEXTURE_COORD_ARRAY);

            glVertexPointer(3, GL_FLOAT, 0, wallVertices);
            glNormalPointer(GL_FLOAT, 0, wallNormals);
            glTexCoordPointer(2, GL_FLOAT, 0, texCoords);

            glDrawElements(GL_QUADS, sizeG*sizeG*4, GL_UNSIGNED_INT, wallIndex);

            glDisableClientState(GL_VERTEX_ARRAY);
            glDisableClientState(GL_NORMAL_ARRAY);
            glDisableClientState(GL_TEXTURE_COORD_ARRAY);
            glDisable(GL_TEXTURE_2D);
        glPopMatrix();
}

As for the image itself it’s 256x128 pixels with 24 bit depth. Any more information or code needed?

You need to include

[LEFT]glPixelStorei(GL_UNPACK_ALIGNMENT, 1);[/LEFT]

see http://www.opengl.org/wiki/Common_Mistakes#Texture_upload_and_pixel_reads for details.

Ok I tried that and still get pretty much the same result…

Right came back to it today and solved it.

I just replaced LR_LOADFROMFILE with LR_LOADFROMFILE | LR_CREATEDIBSECTION.

Bit odd tho since I thought the LR_CREATEDIBSECTION was related to resource files…