Search code examples
c++opengltexturestexture2d

Opening bmp image to texture in OpenGL


I'm having problems opening a bmp image to a texture using OpenGl Here is the loadTexture func:

GLuint loadTexture() {
FILE *f;
int imageSize,rd;
f = fopen(filename, "rb");
if(f == 0){
    printf("Couldn't open file\n");
    exit(-1);
}
GLubyte header[54];
fread(header, 54,1,f);
if(header[0] != 'B' || header[1] != 'M'){
    printf("File not bitmap\n");
    exit(1);
}
dataPos    = *(int*)&(header[0x0A]);
imageSize  = *(int*)&(header[0x22]);
width      = *(int*)&(header[0x12]);
height     = *(int*)&(header[0x16]);
if (imageSize==0)    imageSize=width*height*3;
if (dataPos==0)      dataPos=54;
data = new unsigned char [imageSize];
fread(data,1,imageSize,f);
fclose(f);
GLuint textureID;
glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_2D, textureID);
glTexImage2D(GL_TEXTURE_2D, 0,GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, data);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);  return textureID;

}

The function always returns 0, but there is no error (I looked at glGetError() as well)

When trying to load the texture anyway:

    glClear(GL_COLOR_BUFFER_BIT);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,GL_REPLACE);
//BOTTOM LEFT - red
glBindTexture(GL_TEXTURE_2D,texture);
glViewport(0,0,256,256);
glBegin(GL_QUADS);
glTexCoord2f(0,0);
glVertex2f(-1,1);
glTexCoord2f(1,0);
glVertex2f(-1,-1);
glTexCoord2f(0,1);
glVertex2f(1,-1);
glTexCoord2f(1,1);
glVertex2f(1,1);
glEnd();

I get a white square and not the picture.. This is my init func:

glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(512, 512);
glutCreateWindow("Sample");
glEnable(GL_TEXTURE_2D);
glOrtho(-1.0,1.0,-1.0,1.0,2.0,-2.0);
glClearColor(0,0,0,0);
texture = loadTexture();
printf("Texture: %d\n",texture);
glutDisplayFunc(mydisplay);
glutMainLoop();

Any thoughts?


Solution

  • You don't get a current GL context with GLUT until glutCreateWindow() successfully returns. glutInitDisplayMode() is not sufficient.

    All the GL functions you call in loadTexture() require a current GL context to function.

    Move texture = loadTexture(); to somewhere after glutCreateWindow() and before glutMainLoop();.

    Also, if you're going to be using 3-component BGR/RGB make sure to use glPixelStorei() to set GL_UNPACK_ALIGNMENT to 1 (instead of the default 4) before your glTexImage2D() call.

    Here's the simplest thing that works on my system:

    // http://glew.sourceforge.net/
    #include <GL/glew.h>
    #include <GL/glut.h>
    
    GLuint loadTexture()
    {
        const unsigned char data[] =
        {
            255,   0,   0,    0, 255,   0,
              0,   0, 255,  255, 255, 255,
        };
        const GLsizei width = 2;
        const GLsizei height = 2;
    
        GLuint textureID = 0;
        glGenTextures(1, &textureID);
        glBindTexture(GL_TEXTURE_2D, textureID);
        glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, data);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
        return textureID;
    }
    
    GLuint texture = 0;
    void display()
    {
        glClearColor( 0, 0, 0, 1 );
        glClear( GL_COLOR_BUFFER_BIT );
    
        glMatrixMode( GL_PROJECTION );
        glLoadIdentity();
        glOrtho( -2, 2, -2, 2, 2, -2 );
    
        glMatrixMode( GL_MODELVIEW );
        glLoadIdentity();
    
        glEnable(GL_TEXTURE_2D);
        glBindTexture(GL_TEXTURE_2D,texture);
        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,GL_REPLACE);
    
        glBegin(GL_QUADS);
        glTexCoord2f( 0, 0 );
        glVertex2i( -1, -1 );
        glTexCoord2f( 1, 0 );
        glVertex2i(  1, -1 );
        glTexCoord2f( 1, 1 );
        glVertex2i(  1,  1 );
        glTexCoord2f( 0, 1 );
        glVertex2i( -1,  1 );
        glEnd();
    
        glutSwapBuffers();
    }
    
    int main( int argc, char **argv )
    {
        glutInit( &argc, argv );
        glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE );
        glutInitWindowSize( 640, 480 );
        glutCreateWindow( "GLUT" );
        glewInit();
        texture = loadTexture();
        glutDisplayFunc( display );
        glutMainLoop();
        return 0;
    }