gpt4 book ai didi

c++ - 使用 glTexImage2D 的奇怪结果

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:55:37 24 4
gpt4 key购买 nike

我一直在努力弄清楚 glTexImage2D 是如何工作的,并从一些非常清晰的代码中看到了一些奇怪的结果。我的代码只是将一个粗略的圆画成一个 256*256 长度的无符号数组,然后将该数据发送出去成为一个纹理。然而,无论我在图像创建循环中选择什么组合,显示的纹理都会变成红色和橙色的变化:

unsigned* data = new unsigned[256*256];
for (int y = 0; y < 256; ++y)
for (int x = 0; x < 256; ++x)
if ((x - 100)*(x - 100) + (y - 156)*(y - 156) < 75*75)
data[256*y + x] = ((156 << 24) | (256 << 16) | (156 << 8) | (200 << 0));
else
data[256*y + x] = 0; // I'd expect this to be transparent and the above to be slightly transparent and green, but it's red somehow.

glBindTexture(GL_TEXTURE_2D, texid);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)data);

OpenGL 选项:

    glEnable(GL_TEXTURE_2D);
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
//glBlendFunc(GL_SRC_ALPHA, GL_ONE);
//glEnable(GL_BLEND);
//glDisable(GL_CULL_FACE);

glGenTextures(1, &leaf[0]);
createLeaf(leaf[0]); // createLeaf(GLuint& texid) is posted entirely above

其余代码只在窗口中的单个四边形上显示纹理。 (x64 win7)

编辑:我完全尝试了 Rickard 的解决方案,但我仍然得到一个紫色圆圈。

最佳答案

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)data);

首先是积极的事情。您使用大小的内部格式(GL_RGBA8,而不是 GL_RGBA)。这是非常好的;继续这样做。您清楚地了解内部格式(GL_RGBA8)和像素传输格式(GL_RGBA)之间的区别。这也不错。

问题是这样的。您告诉 OpenGL 您的数据是无符号字节流。但它不是无符号字节流;它是一个无符号的整数流。这就是您声明 data 的方式,这就是您填充 data 的方式。那你为什么要对 OpenGL 撒谎?

问题出在你的颜色上。这是您的颜色值之一:

 ((156 << 24) | (256 << 16) | (156 << 8) | (200 << 0))

首先,256 不是有效的颜色。 256的十六进制是0x100,是两个字节,不是一个字节。

您将从中得到的无符号整数是:

 0x9D009CC8

如果这些按顺序是 RGBA 颜色,则红色为 0x9D,绿色为 0x00,蓝色为 0x9C,alpha 为 0xC8。

现在,因为您可能在一台小端计算机上工作,所以这 4 个字节被翻转存储,如下所示:

 0xC89C009D

当您告诉 OpenGL 假装这是一个字节数组(实际上它不是)时,您将丢失小尾数法转换。所以 OpenGL 看到字节数组以 0xC8 开头,所以这是红色值。等等。

您需要告诉 OpenGL 您实际在做什么:您将四个 8 位无符号值存储在一个无符号 32 位整数中。为此,请使用以下内容:

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, (GLvoid*)data);

GL_UNSIGNED_INT_8_8_8_8 表示您正在向 OpenGL 提供一个无符号 32 位整数数组(您就是)。 32位整数的前8位是红色,第二位是绿色,第三位是蓝色,第四位是alpha。

因此,要完全修复您的代码,您需要:

GLuint* data = new GLuint[256*256]; //Use OpenGL's types
for (int y = 0; y < 256; ++y)
for (int x = 0; x < 256; ++x)
if ((x - 100)*(x - 100) + (y - 156)*(y - 156) < 75*75)
data[256*y + x] = ((0x9C << 24) | (0xFF << 16) | (0x9C << 8) | (0xC8 << 0));
else
data[256*y + x] = 0; // I'd expect this to be transparent and the above to be slightly transparent and green, but it's red somehow.

glBindTexture(GL_TEXTURE_2D, texid);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); //Always set the base and max mipmap levels of a texture.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, (GLvoid*)data);

// I'd expect this to be transparent and the above to be slightly transparent and green, but it's red somehow.

Alpha 并不意味着透明;除非你赋予它意义,否则它毫无意义。如果您使用混合并设置导致低 alpha 使事物透明的混合模式,则 Alpha 仅表示透明度。否则,它根本没有任何意义。

关于c++ - 使用 glTexImage2D 的奇怪结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6636847/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com