4

是否可以禁用纹理颜色,只使用白色作为颜色?它仍然会读取纹理,所以我不能使用 glDisable(GL_TEXTURE_2D) 因为我也想渲染 alpha 通道。

我现在能想到的就是制作所有颜色数据都是白色的新纹理,保持原样。

我需要在没有 shaders的情况下做到这一点,所以这甚至可能吗?

编辑:澄清:我想同时使用两种纹理:白色和正常颜色。

编辑:显然这是不可能的

4

2 回答 2

5

我仍然不完全确定我是否正确理解您想要什么,但我会试一试。我想到的是,当您调用 时glTexImage2D,您指定正在加载的纹素的格式,指定您从这些纹素创建的纹理的“内部格式”。在典型情况下,您为两者指定(大致)相同的格式——例如,您通常会GL_RGBA为两者使用。

指定两者是有原因的:(format靠近列表末尾的参数)指定您要从中加载的纹素的格式但是internal format(靠近参数列表开头的那个)指定格式对于您从这些纹素创建的实际纹理。

如果你想加载一些纹素,但实际上只使用它们的 alpha 通道,你可以GL_ALPHA指定internal format不是颜色。这不仅避免了制作额外的纹素副本,而且(至少通常)还减少了纹理本身消耗的内存,因为它只包括一个 alpha 通道,而不是三个颜色通道。

编辑:好的,再想一想,有一种方法可以做(我认为)你想要的,只使用一个纹理。首先,您将混合功能设置为只使用 alpha 通道,然后当您想要复制纹理的颜色时,您使用 调用glTextureEnvfGL_REPLACE但是当您只想使用 alpha 通道时,您使用 调用它GL_BLEND。例如,让我们创建一个绿色纹理,并在蓝色四边形上绘制(两次),一次使用 GL_REPLACE,一次使用 GL_BLEND。为简单起见,我们将使用纯绿色纹理,alpha 从顶部 (0) 到底部 (1) 线性增加:

static GLubyte Image[128][128][4];

for (int i=0; i<128; i++)
    for (int j=0; j<128; j++) {
        Image[i][j][0] = 0;
        Image[i][j][1] = 255;
        Image[i][j][2] = 0;
        Image[i][j][3] = i;
    }

我将跳过创建和绑定纹理、设置参数等的大部分内容,直接使用纹理绘制几个四边形:

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

glBegin(GL_QUADS);
    glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
    glTexCoord2f(0.0, 0.0); glVertex3f(-1.0f, 1.0f, 0.0f);
    glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
    glTexCoord2f(1.0, 0.0); glVertex3f(0.0f, 1.0f, 0.0f);
    glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
    glTexCoord2f(1.0, 1.0); glVertex3f(0.0f, -1.0f, 0.0f);
    glColor4f(0.0, 0.0f, 1.0f, 1.0f);
    glTexCoord2f(0.0, 1.0); glVertex3f(-1.0f, -1.0f, 0.0f);
glEnd();

glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);

glBegin(GL_QUADS);
    glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
    glTexCoord2f(0.0, 0.0); glVertex3f(0.0f, 1.0f, 0.0f);
    glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
    glTexCoord2f(1.0, 0.0); glVertex3f(1.0f, 1.0f, 0.0f);
    glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
    glTexCoord2f(1.0, 1.0); glVertex3f(1.0f, -1.0f, 0.0f);
    glColor4f(0.0, 0.0f, 1.0f, 1.0f);
    glTexCoord2f(0.0, 1.0); glVertex3f(0.0f, -1.0f, 0.0f);
glEnd();

这会产生:

混合纹理

因此,在使用 GL_REPLACE 绘制的左侧,我们得到了纹理的绿色,但在使用 GL_BLEND 绘制的右侧(并且 glBlendFunc 设置为仅使用 alpha 通道),我们得到了蓝色四边形,但它的Alpha 取自纹理——但我们对两者使用完全相同的纹理。

编辑 2:如果您确定确实需要全白的纹理,我只需创建一个 1 像素纹理,并将 GL_TEXTURE_WRAP_S 和 GL_TEXTURE_WRAP_T 设置为 GL_REPEAT。尽管这仍然使用额外的纹理,但额外的纹理将非常小,因为它只有一个像素。加载它的时间和消耗的内存都非常小——像素的数据基本上是“噪音”。我没有尝试测试,但你可能会更好地使用 8x8 或 16x16 像素块。这仍然很小,几乎无关紧要,但它们分别是 JPEG 和 MPEG 中使用的尺寸,我可以看到卡和(特别是)驱动程序可能针对它们进行优化的地方。它可能会有所帮助,并且不会受到伤害(无论如何都足以关心)。

于 2010-03-24T03:39:33.777 回答
1

在加载后和在 OpenGL 中使用它们之前将所有纹理颜色(除了 alpha )更改为白色怎么样?如果您在某个时候将它们作为位图保存在内存中,这应该很容易,并且您不需要单独的纹理文件。

于 2010-03-22T14:32:14.383 回答