使用glTexImage2D的奇怪结果 [英] Odd results using glTexImage2D

查看:201
本文介绍了使用glTexImage2D的奇怪结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在试图弄清楚 glTexImage2D 是如何工作的,并从一些漂亮的代码看到一些奇怪的结果。我的代码只是绘制一个粗糙的圆形到一个256 * 256长度的无符号数组,然后发送出来的数据成为一个纹理。然而,显示的纹理会变成红色和橙色的变化,无论我在图像创建循环中选择什么组合:

I've been trying to figure out how glTexImage2D works and an seeing some odd results from some pretty clear-cut code. My code simply draws a rough circle into a 256*256 length unsigned array and then sends that data out to become a texture. The texture displayed however is turning out as variations of red and orange no matter what combinations I select inside my image creation loop:

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)

The rest of the code does nothing but display the texture on a single quad in a window. (x64 win7)

编辑:我试过Rickard的解决方案,我还得到一个紫色的圆圈。

I tried Rickard's solution exactly and I'm still getting a purple circle.

推荐答案

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)之间的差异。这也很好。

First the positive things. You use a sized internal format (GL_RGBA8, rather than GL_RGBA). This is very good; keep doing that. You have a clear understanding of the difference between the internal format (GL_RGBA8) and the pixel transfer format (GL_RGBA). This is also good.

问题是这样的。你告诉OpenGL你的数据是一个无符号字节流。但它不是无符号字节流;它是一个无符号整数流。这是你如何声明 data ,这是你填写数据的方式。那么你为什么要说OpenGL?

The problem is this. You told OpenGL that your data was a stream of unsigned bytes. But it's not a stream of unsigned bytes; it's a stream of unsigned integers. That's how you declared data, that's how you filled data. So why are you lying to OpenGL?

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

The problem is with your colors. This is one of your color values:

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

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

First, 256 is not a valid color. 256 in hex is 0x100, which is two bytes, not one.

从这里得到的无符号整数是:

The unsigned integer you would get from this is:

 0x9D009CC8

如果这些都是RGBA颜色的顺序,那么红色是0x9D,绿色是0x00,蓝色是0x9C,alpha是0xC8。

If these are intended to be RGBA colors in that order, then the red is 0x9D, green is 0x00, blue is 0x9C, and alpha is 0xC8.

现在, -endian计算机,这4个字节存储翻转,如下:

Now, because you're probably working on a little-endian computer, that 4 bytes is stored flipped, like this:

 0xC89C009D

当你告诉OpenGL假设这是一个字节数组(它不是),你就失去了小端序转换。所以OpenGL看到以0xC8开头的字节数组,所以这是红色值。等等。

When you tell OpenGL to pretend that this is a byte array (which it is not), you are losing the little-endian conversion. So OpenGL sees the byte array starting with 0xC8, so that is the red value. And so on.

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

You need to tell OpenGL what you're actually doing: you're storing four 8-bit unsigned values in a single unsigned 32-bit integer. To do this, use the following:

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位是红色,第二个是绿色,第三个是蓝色,第四个是阿尔法。

The GL_UNSIGNED_INT_8_8_8_8 says that you're feeding OpenGL an array of unsigned 32-bit integers (which you are). The first 8-bits of the 32-bit integer is red, the second is green, the third is blue, and the fourth is alpha.

您的代码,您需要这样:

So, to completely fix your code, you need this:

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使事情透明。否则,它根本就没有。

Alpha doesn't mean transparent; it means nothing at all unless you give it a meaning. Alpha only represents transparency if you use blending and set up a blending mode that causes a low alpha to make things transparent. Otherwise, it means nothing at all.

这篇关于使用glTexImage2D的奇怪结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆