从 BMP 纹理创建在 OpenGL 2.1 中有多余的像素

Created from BMP texture has excess pixels in OpenGL 2.1

我在学术工作中使用 OpenGL 2.1 来创建 3D 场景。我有一个 24 位 BMP 文件,一个立方体侧面的纹理,手动加载到内存中。

直奔问题:显示的纹理在左下角有一些多余的像素。 BMP 文件当然没有这些像素,它有一个全黑的边框。结果如下:



似乎从文件加载的数据没问题 - 超出一次后的一行中的像素与文件中的相同,用另一个杂色 BMP 检查。这是我用来从 BMP 创建纹理的函数:

GLuint CreateTextureFromBMP (const char path [])
{
    unsigned char header [54];
    unsigned int  data_position, width, height, image_size;
    unsigned char * data;

    FILE * file = fopen (path, "rb");
    fread (header, sizeof (char), 54, file);

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

    if (image_size == 0)
        image_size = width * height * 3;
    if (data_position == 0)
        data_position = 54;

    data = (unsigned char *) malloc (sizeof (unsigned char) * image_size);
    fread (data, sizeof (char), image_size, file);
    free (data);
    fclose (file);

    GLuint texture_id;
    glGenTextures (1, &texture_id);
    glBindTexture (GL_TEXTURE_2D, texture_id);

    glTexImage2D (GL_TEXTURE_2D, 0, 3, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, data);
    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    return texture_id;
}

我尝试在 glTexImage2DglTexParameteri 函数中使用不同的参数,但仍然没有任何改变。这是渲染场景函数:

void RenderScene (int arg)
{
    static GLuint texture_id = CreateTextureFromBMP ("cube_blue.bmp");

    glEnable (GL_TEXTURE_2D);
    glEnableClientState (GL_TEXTURE_COORD_ARRAY);
    glEnableClientState (GL_VERTEX_ARRAY);
    glActiveTexture (GL_TEXTURE0);

    GLfloat vertices  [] = { ... };
    GLfloat texcoords [] = { ... };
    GLubyte indices   [] = { ... };

    glVertexPointer   (3, GL_FLOAT, 0, vertices);
    glTexCoordPointer (2, GL_FLOAT, 0, texcoords);

    glPushMatrix ();
        glBindTexture   (GL_TEXTURE_2D, texture_id);
        glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

        glColor3f (1.0f, 1.0f, 1.0f);
        glDrawElements (GL_QUADS, 24, GL_UNSIGNED_BYTE, indices);
    glPopMatrix ();

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

知道在哪里查找错误吗?

我发现您的代码中有一个错误可能会导致您遇到的问题。

data = (unsigned char *) malloc (sizeof (unsigned char) * image_size);
fread (data, sizeof (char), image_size, file);
free (data);

您正在分配一个缓冲区,读入它,然后立即释放它。这意味着 free() 和 glTexImage2D() 之间的任何代码都可以自由覆盖堆中的这个缓冲区。

尝试将对 free() 的调用移动到对 glTexImage2D() 的调用之后,看看会发生什么。