OpenGL:禁用纹理颜色?

时间:2010-03-22 14:29:52

标签: c++ opengl texture-mapping

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

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

我需要这样做没有着色器,所以这甚至可能吗?

编辑澄清:我想使用两种纹理:白色和普通颜色。

编辑:显然这是不可能的

2 个答案:

答案 0 :(得分:5)

我仍然完全确定我理解你想要的东西,但我会试一试。我的想法是,当你致电glTexImage2D时,你指定你正在加载的纹素的格式你指定你正在创建的纹理的“内部格式”那些纹素。在典型情况下,您为两者指定(大致)相同的格式 - 例如你通常会使用GL_RGBA

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

如果你想加载一些纹素,但实际只是使用来自它们的alpha通道,你可以为GL_ALPHA指定internal format,这就是你要做的一切get - 当您将该纹理映射到曲面时,它只会影响alpha,而不会影响颜色。这不仅可以避免制作纹素的额外副本,而且(至少通常)会减少纹理本身消耗的内存,因为它只包含一个alpha通道,而不是三个颜色通道。

编辑:好的,考虑一下,有一种方法可以做你想要的(我认为),只使用一个纹理。首先,您将混合函数设置为仅使用Alpha通道,然后当您想要复制纹理的颜色时,使用glTextureEnvf调用GL_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();

这会产生:

Blended Textures

所以,在用GL_REPLACE绘制的左边,我们得到纹理的绿色,但在右边,用GL_BLEND绘制的地方(并且glBlendFunc设置为仅使用alpha通道),我们得到蓝色四边形,但是从纹理中取出Alpha - 但我们对两者使用完全相同的纹理。

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

答案 1 :(得分:1)

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