纹理不会出现 FreeGLUT
Texture wont appear FreeGLUT
我有一个带照明的简单平面(方形)和 material,我想在上面放一个地球纹理。但什么也没有出现。我检查过,认为它正确加载了 RGB 数据,所以我猜测这条线有问题(数据是 *char,图像是 BMP24)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, outWidth, outHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, (GLvoid*)data);
这里是一个 .bmp 加载函数:
GLuint LoadTexture(const char* imagepath) {
printf("Reading image %s\n", imagepath);
unsigned int outWidth = -1;
unsigned int outHeight = -1;
unsigned char header[54];
unsigned int dataPos;
unsigned int imageSize;
FILE* file;
if (errno_t err = fopen_s(&file, imagepath, "rb") != 0) {
perror("Can't Open file");
return 0;
}
// If less than 54 byes are read, problem
if (fread(header, 1, 54, file) != 54) {
printf("Not a correct BMP file\n");
return NULL;
}
// A BMP files always begins with "BM"
if (header[0] != 'B' || header[1] != 'M') {
printf("Not a correct BMP file\n");
return NULL;
}
// Make sure this is a 24bpp file
if (*(int*)&(header[0x1E]) != 0) { printf("Not a correct BMP file\n"); return NULL; }
if (*(int*)&(header[0x1C]) != 24) { printf("Not a correct BMP file\n"); return NULL; }
// Read the information about the image
dataPos = *(int*)&(header[0x0A]);
outWidth = *(int*)&(header[0x12]);
outHeight = *(int*)&(header[0x16]);
imageSize = *(int*)&(header[0x22]);
// Some BMP files are misformatted, guess missing information
if (imageSize == 0) imageSize = outWidth * outHeight * 3; // 3 : one byte for each Red, Green and Blue component
if (dataPos == 0) dataPos = 54; // The BMP header is done that way
// Read the actual data from the file into the buffer
unsigned char* data = new unsigned char[imageSize];
fread(data, 3, imageSize, file);
// Everything is in memory now, the file wan be closed
fclose(file);
GLuint tex;
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, outWidth, outHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, (GLvoid*)data);
return tex;
}
这里是主要和显示功能:
void render(void) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
float ratio = 0.75;
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, earthTextureData);
glBegin(GL_QUADS);
glVertex3f(-0.5, -0.5, 0);
glVertex3f(-0.5, 0.5, 0);
glVertex3f(0.5, 0.5, 0);
glVertex3f(0.5, -0.5, 0);
glEnd();
glDisable(GL_TEXTURE_2D);
glutSwapBuffers();
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(100, 100);
glutInitWindowSize(1200, 800);
glutCreateWindow("app");
init(); // custome initilizing
initLighting();
earthTextureData = LoadTexture("Texture/globe.bmp");
glutDisplayFunc(render);
glutReshapeFunc(reshape);
glutMotionFunc(mouseMove);
glutKeyboardFunc(keyboard);
glutIdleFunc(idle);
glutMainLoop();
}
我试过代码,有时(当我使用 int 而不是 char* 时)我得到一个红色 material 覆盖所有内容但不知道到底是什么原因造成的
更新:必须更改几行才能使其正常工作(对于 bmp24 文件):
1-编辑此行:
fread(数据, 1, imageSize, 文件);
2- 添加这一行:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
3- 编辑这一行(为了正确显示颜色):
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, outWidth, outHeight, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, (GLvoid*)data);
4-添加UV坐标(查找glTexCoord)
您必须将 UV 坐标告知 OpenGL,以了解放置该纹理的位置和方式。这可以在您的渲染函数中完成。
UV 坐标范围为 0.0 - 1.0,并告诉 OpenGL 如何将纹理放置到渲染器上。
Here is a good picture that illustrates uv coordinates well
像这样的东西应该可以工作:
void render(void) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
float ratio = 0.75;
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, earthTextureData);
glBegin(GL_QUADS);
glTexCoord3f(0.0, 0.0, 0.0);
glVertex3f(-0.5, -0.5, 0);
glTexCoord3f(0.0, 1.0, 0.0);
glVertex3f(-0.5, 0.5, 0);
glTexCoord3f(1.0, 1.0, 0.0);
glVertex3f(0.5, 0.5, 0);
glTexCoord3f(1.0, 0.0, 0);
glVertex3f(0.5, -0.5, 0);
glEnd();
glDisable(GL_TEXTURE_2D);
glutSwapBuffers();
}
您错过了通过 glTexParameter
设置纹理参数的设置。
如果不生成mipmaps (by glGenerateMipmap
),那么设置GL_TEXTURE_MIN_FILTER
很重要。由于默认过滤器是 GL_NEAREST_MIPMAP_LINEAR
如果您不将缩小功能更改为 GL_NEAREST
或 GL_LINEAR
.
,纹理将是不完整的 mipmap
当图像加载到纹理对象时,GL_UNPACK_ALIGNMENT
必须设置为 1。
默认情况下 GL_UNPACK_ALIGNMENT
为 4,因此假定图像的每一行对齐到 4 个字节。一个BMP文件的像素一般都是3个字节大小,而且是紧密排列的,这样会造成错位。
GLuint tex;
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, outWidth, outHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, (GLvoid*)data);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
当然你必须通过 glTexCoord
, before specifying the vertex coordinate (glVertex
) 设置纹理参数,如另一个答案中所述:
glBindTexture(GL_TEXTURE_2D, earthTextureData);
glEnable(GL_TEXTURE_2D);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0);
glVertex3f(-0.5, -0.5, 0);
glTexCoord2f(0.0, 1.0);
glVertex3f(-0.5, 0.5, 0);
glTexCoord2f(1.0, 1.0);
glVertex3f(0.5, 0.5, 0);
glTexCoord2f(1.0, 0.0);
glVertex3f(0.5, -0.5, 0);
glEnd();
glDisable(GL_TEXTURE_2D);
我有一个带照明的简单平面(方形)和 material,我想在上面放一个地球纹理。但什么也没有出现。我检查过,认为它正确加载了 RGB 数据,所以我猜测这条线有问题(数据是 *char,图像是 BMP24)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, outWidth, outHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, (GLvoid*)data);
这里是一个 .bmp 加载函数:
GLuint LoadTexture(const char* imagepath) {
printf("Reading image %s\n", imagepath);
unsigned int outWidth = -1;
unsigned int outHeight = -1;
unsigned char header[54];
unsigned int dataPos;
unsigned int imageSize;
FILE* file;
if (errno_t err = fopen_s(&file, imagepath, "rb") != 0) {
perror("Can't Open file");
return 0;
}
// If less than 54 byes are read, problem
if (fread(header, 1, 54, file) != 54) {
printf("Not a correct BMP file\n");
return NULL;
}
// A BMP files always begins with "BM"
if (header[0] != 'B' || header[1] != 'M') {
printf("Not a correct BMP file\n");
return NULL;
}
// Make sure this is a 24bpp file
if (*(int*)&(header[0x1E]) != 0) { printf("Not a correct BMP file\n"); return NULL; }
if (*(int*)&(header[0x1C]) != 24) { printf("Not a correct BMP file\n"); return NULL; }
// Read the information about the image
dataPos = *(int*)&(header[0x0A]);
outWidth = *(int*)&(header[0x12]);
outHeight = *(int*)&(header[0x16]);
imageSize = *(int*)&(header[0x22]);
// Some BMP files are misformatted, guess missing information
if (imageSize == 0) imageSize = outWidth * outHeight * 3; // 3 : one byte for each Red, Green and Blue component
if (dataPos == 0) dataPos = 54; // The BMP header is done that way
// Read the actual data from the file into the buffer
unsigned char* data = new unsigned char[imageSize];
fread(data, 3, imageSize, file);
// Everything is in memory now, the file wan be closed
fclose(file);
GLuint tex;
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, outWidth, outHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, (GLvoid*)data);
return tex;
}
这里是主要和显示功能:
void render(void) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
float ratio = 0.75;
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, earthTextureData);
glBegin(GL_QUADS);
glVertex3f(-0.5, -0.5, 0);
glVertex3f(-0.5, 0.5, 0);
glVertex3f(0.5, 0.5, 0);
glVertex3f(0.5, -0.5, 0);
glEnd();
glDisable(GL_TEXTURE_2D);
glutSwapBuffers();
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(100, 100);
glutInitWindowSize(1200, 800);
glutCreateWindow("app");
init(); // custome initilizing
initLighting();
earthTextureData = LoadTexture("Texture/globe.bmp");
glutDisplayFunc(render);
glutReshapeFunc(reshape);
glutMotionFunc(mouseMove);
glutKeyboardFunc(keyboard);
glutIdleFunc(idle);
glutMainLoop();
}
我试过代码,有时(当我使用 int 而不是 char* 时)我得到一个红色 material 覆盖所有内容但不知道到底是什么原因造成的
更新:必须更改几行才能使其正常工作(对于 bmp24 文件):
1-编辑此行: fread(数据, 1, imageSize, 文件);
2- 添加这一行: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
3- 编辑这一行(为了正确显示颜色): glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, outWidth, outHeight, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, (GLvoid*)data);
4-添加UV坐标(查找glTexCoord)
您必须将 UV 坐标告知 OpenGL,以了解放置该纹理的位置和方式。这可以在您的渲染函数中完成。
UV 坐标范围为 0.0 - 1.0,并告诉 OpenGL 如何将纹理放置到渲染器上。
Here is a good picture that illustrates uv coordinates well
像这样的东西应该可以工作:
void render(void) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
float ratio = 0.75;
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, earthTextureData);
glBegin(GL_QUADS);
glTexCoord3f(0.0, 0.0, 0.0);
glVertex3f(-0.5, -0.5, 0);
glTexCoord3f(0.0, 1.0, 0.0);
glVertex3f(-0.5, 0.5, 0);
glTexCoord3f(1.0, 1.0, 0.0);
glVertex3f(0.5, 0.5, 0);
glTexCoord3f(1.0, 0.0, 0);
glVertex3f(0.5, -0.5, 0);
glEnd();
glDisable(GL_TEXTURE_2D);
glutSwapBuffers();
}
您错过了通过 glTexParameter
设置纹理参数的设置。
如果不生成mipmaps (by glGenerateMipmap
),那么设置GL_TEXTURE_MIN_FILTER
很重要。由于默认过滤器是 GL_NEAREST_MIPMAP_LINEAR
如果您不将缩小功能更改为 GL_NEAREST
或 GL_LINEAR
.
当图像加载到纹理对象时,GL_UNPACK_ALIGNMENT
必须设置为 1。
默认情况下 GL_UNPACK_ALIGNMENT
为 4,因此假定图像的每一行对齐到 4 个字节。一个BMP文件的像素一般都是3个字节大小,而且是紧密排列的,这样会造成错位。
GLuint tex;
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, outWidth, outHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, (GLvoid*)data);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
当然你必须通过 glTexCoord
, before specifying the vertex coordinate (glVertex
) 设置纹理参数,如另一个答案中所述:
glBindTexture(GL_TEXTURE_2D, earthTextureData);
glEnable(GL_TEXTURE_2D);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0);
glVertex3f(-0.5, -0.5, 0);
glTexCoord2f(0.0, 1.0);
glVertex3f(-0.5, 0.5, 0);
glTexCoord2f(1.0, 1.0);
glVertex3f(0.5, 0.5, 0);
glTexCoord2f(1.0, 0.0);
glVertex3f(0.5, -0.5, 0);
glEnd();
glDisable(GL_TEXTURE_2D);