从 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;
}
我尝试在 glTexImage2D
和 glTexParameteri
函数中使用不同的参数,但仍然没有任何改变。这是渲染场景函数:
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() 的调用之后,看看会发生什么。
我在学术工作中使用 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;
}
我尝试在 glTexImage2D
和 glTexParameteri
函数中使用不同的参数,但仍然没有任何改变。这是渲染场景函数:
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() 的调用之后,看看会发生什么。