使用Glut和C时纹理扭曲

时间:2017-10-17 08:01:23

标签: c opengl textures glut bmp

我正在尝试熟悉XCode 9中的GLUT框架,以用于我想要处理的未来项目,但现在我仍然坚持要正确显示纹理。

所以我的目标是将这个bmp图像显示为纹理:

bmp image

到这个红色方块的位置:

display window

结果如下:

error

应该如此:

goal

这是我用来初始化纹理的代码。

GLuint loadAndBufferImage(const char * filename){

    GLuint texture;
    unsigned char header[54];
    unsigned int dataPos;
    unsigned int width, height;
    unsigned int imageSize;

    unsigned char * data;

    FILE * file = fopen(filename, "rb");
    if(!file){printf("Image could not load\n"); exit(2);}

    if(fread(header, 1, 54, file) != 54){
        printf("Not a correct BMP file.\n");
        return -1;
    }

    if(header[0] != 'B' || header[1] != 'M'){
        printf("Not a correct BMP file.\n");
        return -1;
    }

    dataPos = *(int*)&(header[0x0A]);
    imageSize = *(int*)&(header[0x22]);
    width = *(int*)&(header[0x12]);
    height = *(int*)&(header[0x16]);

    if(imageSize == 0) imageSize = width * height * 4;
    if(dataPos==0) dataPos=54;

    data = malloc(imageSize);
    if(!data){printf("No more memory\n"); exit(1);}

    fread(data, 1, imageSize, file);
    fclose(file);

    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, data);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    free(data);
    return texture;    
}

这就是调用该函数的地方。

GameWindow *initializeGameWindow(){


    GameWindow *gw = malloc(sizeof(*gw));
    if(gw == NULL){
        printf("Error: no more memory");
        exit(1);
    }

    gw->render = render;
    gw->update = update;
    gw->isRunning = isRunning;
    gw->setRunning = setRunning;
    glClearColor(1.0, 1.0, 1.0, 1.0);

    glEnable(GL_TEXTURE_2D);

    glViewport(0.0f, 0.0f, _width, _height);
    glMatrixMode(GL_PROJECTION);
    gluOrtho2D(0, _width, 0, _height);
    glMatrixMode(GL_MODELVIEW);

    glGenBuffers(1, &_vertexBufferID);
    glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferID);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(3, GL_FLOAT, sizeof(VertexData), (GLvoid *)offsetof(VertexData, pos));


    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glTexCoordPointer(2, GL_FLOAT, sizeof(VertexData), (GLvoid *)offsetof(VertexData, tex));

    _textureBufferID = loadAndBufferImage("test.bmp");

    return gw;
}

我要猜测并说它与我如何从图像中获取数据以及可能的纹理参数有关。如果是这样,我该如何解决这个问题?否则我需要做些什么才能设置纹理?

修改 所以我按照建议在纹理初始化代码中的fseek(file, (long)dataPos, SEEK_SET);上方添加了fread(data, 1, imageSize, file);,与初始结果相比,它似乎将图像移动了一点点。

new results

我也尝试将GL_RGBA和GL_BGRA分别更改为GL_RGB和GL_BGR,就像在glTexImage2D函数中一样,这发生了。

change to GL_RGB and GL_BRG

编辑2: 所以经过一些研究和一些实验,结果证明另一个问题是因为当我将它保存为位图时,图像被设置为索引颜色模式而不是 RGB颜色模式文件。 (我正在使用Gimp编辑器。)它必须影响数据的存储方式,因为当我比较它们时,文件的像素数据部分中的十六进制值和总文件大小不同。但是在编辑器中将其切换到RBG颜色模式是解决这个问题的最后一个关键。

https://image.ibb.co/fC99Lm/Screen_Shot_2017_10_18_at_4_15_36_AM.png

感谢您的帮助。

资源:

https://en.wikipedia.org/wiki/BMP_file_format

http://fac.ksu.edu.sa/sites/default/files/lab08_6.pdf

1 个答案:

答案 0 :(得分:0)

您已阅读但忽略dataPos,即图像数据的偏移量。使用

fseek(file, (long)dataPos, SEEK_SET);
fread(data, 1, imageSize, file);

将文件指针定位到数据。原因是标题和图像数据之间可能有调色板数据。