我有一个简单的平原(正方形),上面有灯光和材料,我想在上面放一个地球纹理。但是什么都没有出现。我检查过,认为它正确加载了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*时)我会得到一个红色的材料覆盖所有内容,但不知道到底是什么导致了它
更新:必须更改几行才能正常工作(对于bmp24文件):
1-编辑此行:fread(data,1, ImageSize, file);
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,(GLval*)data);
4-添加UV坐标(查找glTexCoord)
你必须告诉OpenGL UV坐标在哪里以及如何放置纹理。这可以在渲染函数中完成。
UV坐标范围在0.0到1.0之间,告诉OpenGL如何将纹理放置到渲染器上。
这是一张很好的图片,很好地说明了uv坐标
像这样的方法应该有用:
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
设置纹理参数。
如果不生成mipmap(通过glGenerateMipmap
),则设置GL_纹理_MIN_过滤器
很重要。由于默认过滤器是GL_NEAREST\u MIPMAP\u 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);
当然,在指定顶点坐标(glVertex
)之前,必须通过glTexCoord
设置纹理参数,如另一个答案中所述:
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);
我正在尝试使用类来构建小行星类型的翻拍,我在这里有一个制作飞船的类: } 但是当它使用我的主类绘制时,精灵上的纹理是正常绘制的,但是当我按下w向前移动时,它会将我移动到右边。当我旋转它的时候,好像我的船的顶部在一边,这怎么可能呢? 编辑:似乎只是旋转图像90度顺时针固定它,但不幸的是,它默认为该角度。
我有一对着色器程序,如果我的DataTextures是正方形(1:1),那么一切都很好,但是如果其中一个或两个都是2:1(宽度:高度)的比例,那么行为就会变得混乱。我可以使用未使用的填充来扩展每个缓冲区,以确保它们始终是方形的,但从长远来看,这似乎是不必要的昂贵(内存方面的),因为两个缓冲区中的一个在启动时非常大。在这种情况下,有没有办法处理2:1的缓冲区? 我有两个着色器程序: 第一个是单个fr
我正在尝试同时渲染背景和我的角色动画和我的角色工具。这件事看起来很琐碎,但我还是搞不懂。这里是我现在为我的呈现所提供的代码。 现在,当我运行以下代码时(将切换到底部): 这是结果 我就是找不到一个模式,总是一个凌驾于另一个之上。我会非常感激我的失落。谢谢!!
我有一个OpenGL纹理,我想在运行中更改纹理中像素的RGBA值。我想在CPU端做修改。我想创建一个函数,将纹理中选定坐标中的像素更改为选定的RGBA值。 我尝试了以下方法: 其中,和是修改像素的坐标,是红色、绿色、蓝色和阿尔法的整数数组。但是,我不确定我是否使用了正确的参数,因为当我使用此参数时,纹理不会改变。我想创建一个函数,使用将指定坐标中纹理中的像素颜色更改为指定颜色。
有人能给我解释一下,我如何在OpenGL中渲染多个不同纹理的物体吗? 我认为我接近最终结果,但目前我被困在这里,我不知道下一步需要做什么。真的需要一些帮助! 目前,这就是我所拥有的: > < li> drawSphere():根据经度和纬度的数量绘制UV球体 int numberOfVerices = 0; SetupGeometry():该方法用于绑定顶点和纹理坐标。 DrawSphere(30