简体   繁体   中英

Why is bitmap image not showing with opengl on glfw window? Problem reading bitmap image file in C++

#include<GLFW/glfw3.h>
#include<stdio.h>
#include<GL/glu.h>
#include<vector>
using namespace std;

typedef struct __attribute__((__packed__)) { 
    unsigned short type; 
    unsigned long size; 
    unsigned short reserved1; 
    unsigned short reserved2; 
    unsigned long offsetbits; 
} BITMAPFILEHEADER1;

typedef struct __attribute__((__packed__)) {
    unsigned long size; 
    unsigned long width; 
    unsigned long height; 
    unsigned short planes; 
    unsigned short bitcount;
    unsigned long compression; 
    unsigned long sizeimage; 
    long xpelspermeter; 
    long ypelspermeter; 
    unsigned long colorsused; 
    unsigned long colorsimportant; 
} BITMAPINFOHEADER1;
 
typedef struct { 
    unsigned char blue; 
    unsigned char green; 
    unsigned char red; 
} SINGLE_PIXEL1;


void draw_all() {
    FILE *fp;
    unsigned char p;
    int x=0,y=0,c=0;
    float r,g,b;
    float rowsize,pixelarraysize;
    
    int datasize;
    
    BITMAPFILEHEADER1 bitmp;    
    BITMAPINFOHEADER1 bitm; 
    
    glClearColor(1.0,1.0,1.0,0.0);
    glClear(GL_COLOR_BUFFER_BIT);
    
    fp = fopen("free.bmp","rb");//Filename is given 
    
    //fread(&bitmp,14,1,fp);    
    
    //fread(&bitm,40,1,fp);
    printf("sizeheader: %d\n", sizeof(BITMAPFILEHEADER1));  
    fread(&bitmp,sizeof(BITMAPFILEHEADER1),1,fp);   
    
    fread(&bitm,sizeof(BITMAPINFOHEADER1),1,fp);
    
    printf("Type in hexadecimal: %x\n",bitmp.type);
    printf("Size in hexadecimal: %x\n",bitmp.size);
    printf("Reserved1 in hexadecimal: %x\n",bitmp.reserved1);
    printf("Reserved2 in hexadecimal: %x\n",bitmp.reserved2);
    printf("Offsetbits in hexadecimal: %x\n",bitmp.offsetbits); 

    //printf("Width: %x, Height: %x\n",bitm.width,bitm.height);
    printf("Width: %d, Height: %d\n",bitm.width,bitm.height);
    
    printf("Bitcount: %d\n",bitm.bitcount);
    
    glViewport(0,0,bitm.width,bitm.height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0.0,bitm.width,0.0,bitm.height);
            
    vector<float> v_data;
    int width,height;
    
    width=bitm.width;
    height=bitm.height;
    
    //width=800;
    //height=600;
    
    //rowsize=((24*734+31)/32)*4;
    rowsize=((24*800+31)/32)*4;
    //rowsize=((bitm.bitcount*bitm.width+31)/32)*4;
    pixelarraysize=rowsize*bitm.height;
    
    printf("Rowsize: %f\n",rowsize);
    printf("pixelarraysize: %f\n",pixelarraysize);
    
    //datasize=3*734;
    //datasize=3*800;
    //datasize=3*bitm.width;
    datasize=(bitm.bitcount/8.0)*bitm.width;
    printf("Datasize: %d\n",datasize);
    
    int padding;
    padding = rowsize - (width * 3); 
    //glBegin(GL_POINTS);
    while(!feof(fp))
    {
        fread(&p,1,1,fp);
        b = p/255.0;
        fread(&p,1,1,fp);
        g = p/255.0;    
        fread(&p,1,1,fp);
        r = p/255.0;
        
        v_data.push_back(r);
        v_data.push_back(g);
        v_data.push_back(b);
        /*
        glColor3f(r,g,b);       
        glVertex2i(x++,y);
        */
        x++;
        if(x == bitm.width)
        {
            //fseek(fp,2,SEEK_CUR);
            fseek(fp,padding,SEEK_CUR);
            x = 0;
            y++;
        }
        
    }   
    //glEnd();
    
    unsigned int texture;
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    
    glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,width,height,0,GL_RGB,GL_FLOAT,&v_data[0]);
        
    glEnable(GL_TEXTURE_2D);
    glActiveTexture(GL_TEXTURE);

    glBegin(GL_QUADS);

    glTexCoord2i(0,0);
    glVertex2i(0,0);
    
    glTexCoord2i(0,1);
    glVertex2i(0,height);
    
    glTexCoord2i(1,1);
    glVertex2i(width,height);
    
    glTexCoord2i(1,0);
    glVertex2i(width,0);

    glEnd();
           
    glFlush();
    fclose(fp); 
}

int main(void)
{
    GLFWwindow* window;
    /* Initialize the library */
    if (!glfwInit())
        return -1;
    /* Create a windowed mode window and its OpenGL context */
    window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
    if (!window)
    {
        glfwTerminate();
        return -1;
    }
    /* Make the window's context current */
    glfwMakeContextCurrent(window);
    /* Loop until the user closes the window */
    draw_all();
    while (!glfwWindowShouldClose(window))
    {
        //gladLoadGL();
        /* Render here */
        //draw_all();
        /* Swap front and back buffers */
        glfwSwapBuffers(window);        
        /* Poll for and process events */
        glfwPollEvents();
    }
    glfwTerminate();
    return 0;
}
g++ glfw.cpp -o glfw -lglfw -lGL -lGLU
./glfw

Can anyone fix the problem of reading bitmap file (free.bmp)? It is not getting width and height of image.

The computation of rowsize is definitely wrong. The number of lines in a line is aligned to 4:

rowsize=((24*64+31)/32)*4;

rowsize = (bitm.width*3*4+3)/4;

I recommend to use the STB library to load bitmaps. Different solutions can be found in the answers to the question How to load a bmp on GLUT to use it as a texture? .


Anyway it is no necessary to convert the texture image to floating pint data. The texture can be loaded directly:

vector<unsigned char> v_data(pixelarraysize);
fread(v_data.data(), 1, pixelarraysize, fp);

// [...]

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, &v_data[0]);

Do not continuously load the texture per frame. Load the texture once before the application loop:

int width, height;

unsigned int load_texture(const char *filename)
{
    FILE *fp;
    float rowsize,pixelarraysize;
    BITMAPFILEHEADER1 bitmp;    
    BITMAPINFOHEADER1 bitm; 

    fp = fopen(filename,"rb");//Filename is given 
    printf("sizeheader: %d\n", sizeof(BITMAPFILEHEADER1));  
    fread(&bitmp,sizeof(BITMAPFILEHEADER1),1,fp);   
    fread(&bitm,sizeof(BITMAPINFOHEADER1),1,fp);
    
    printf("Type in hexadecimal: %x\n",bitmp.type);
    printf("Size in hexadecimal: %x\n",bitmp.size);
    printf("Reserved1 in hexadecimal: %x\n",bitmp.reserved1);
    printf("Reserved2 in hexadecimal: %x\n",bitmp.reserved2);
    printf("Offsetbits in hexadecimal: %x\n",bitmp.offsetbits); 

    printf("Width: %d, Height: %d\n",bitm.width,bitm.height);
    printf("Bitcount: %d\n",bitm.bitcount);

    rowsize = (bitm.width*3*4+3)/4;
    pixelarraysize = rowsize*bitm.height;
    
    printf("Rowsize: %f\n",rowsize);
    printf("pixelarraysize: %f\n",pixelarraysize);

    vector<unsigned char> v_data(pixelarraysize);
    fread(v_data.data(), 1, pixelarraysize, fp);
    fclose(fp); 

    width = bitm.width;
    height = bitm.height;

    unsigned int texture;
    glGenTextures(1, &texture);
    
    glActiveTexture(GL_TEXTURE);
    glBindTexture(GL_TEXTURE_2D, texture);
    
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, &v_data[0]);
        
    return texture;
}
void draw_all()
{
    glClearColor(1.0,1.0,1.0,0.0);
    glClear(GL_COLOR_BUFFER_BIT);
    
    glViewport(0,0,640, 480);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0.0,640,0.0,480);
             
    glEnable(GL_TEXTURE_2D);
    glBegin(GL_QUADS);

    glTexCoord2i(0,0);
    glVertex2i(0,0);
    
    glTexCoord2i(0,1);
    glVertex2i(0,height);
    
    glTexCoord2i(1,1);
    glVertex2i(width,height);
    
    glTexCoord2i(1,0);
    glVertex2i(width,0);

    glEnd();
           
    glFlush();
}
int main(void)
{
    // [...]

    int textureobject = load_texture("free.bmp");
    while (!glfwWindowShouldClose(window))
    {
        /* Render here */
        draw_all();
        /* Swap front and back buffers */
        glfwSwapBuffers(window);        
        /* Poll for and process events */
        glfwPollEvents();
    }

    // [...]
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM