在OpenGL中绑定零纹理

4
在我的程序中,我使用了2个纹理:t0和t1。 t1是额外的,只在某些情况下需要使用:
.....
glActiveTexture ( GL_TEXTURE1 );
if ( mDisplayMode == EDM_DEFAULT ){
    glBindTexture( GL_TEXTURE_2D, 0 ); // In this case I don't need t1
}else{
    glBindTexture( GL_TEXTURE_2D, mglDegreeTexture ); // In this case t1 will overlap t0
}
shader->setUniformValue( "textureId1", 1 );

绘制所需的着色器:

.....
vec4 c1 = texture( textureId0, uv );
vec4 c2 = texture( textureId1, gridUV );
float a = c2.a;
gl_FragColor = ( 1.0 - a )*c1 + a*c2;

它的工作很好:第二个纹理在需要时重叠在第一个上。假设使用glBindTexture(.., 0)返回零纹理(0,0,0,0),但在更新NVidia驱动程序到314.07后,我的代码产生黑屏,就像glBindTexture(.., 0)返回(0,0,0,1)纹理一样。

我进行了一些测试: 使用着色器

....
vec4 c1 = texture( textureId0, uv );
vec4 c2 = texture( textureId1, gridUV );
float a = c2.a;
if (a == 1){
    gl_FragColor = vec4(1,0,0,0);
    return;
}
if ( a == 0){
    gl_FragColor = vec4(0,1,0,0);
    return;
}
gl_FragColor = ( 1.0 - a )*c1 + a*c2;

我在旧的驱动程序(296,306)上遇到了绿屏,而在新的驱动程序上则是红屏。我在两台电脑上进行了测试,一台是Win 7(GeForce 210),另一台是win XP(GTX 260)。

因此我的问题是:使用glBindTexture和0作为第二个参数是否正确,并且如何在新驱动程序中实现相同的结果(0000纹理)?

1个回答

9
下面的内容都是针对核心3.2版本,但一般适用于所有GL版本。
编号0代表默认纹理对象(每个纹理目标一个:1d、2d等。请参阅3.8.14中的最后一段)。因此,glBindtexture(2D, 0); 可以获取默认纹理对象。这并不意味着禁用纹理。现在从默认对象进行纹理处理会导致通常的操作,只是针对你没有自己创建的纹理对象。初始纹理对象最初是不完整的,因此除非你进行修改,否则它将按照“不完整”的规则运行。
规范指出(3.9.2,纹理访问段落),从不完整的纹理采样将返回 (0,0,0,1)。因此,您的旧驱动程序未按照规范进行处理。

太好了!使用(0,0,0,0)作为“零”纹理是如此合乎逻辑;我无法找到定义默认纹理的方法,你知道吗? - Jeka
1
@Jeka:它就像任何其他纹理一样,所以如果您将其设置为例如1x1 RGBA纹理,并将其内容设置为0,0,0,0的单个像素,则可以实现您想要的效果。只是通常不会以这种方式使用它,因此您可能会使阅读您代码的任何人感到困惑(哦,还可能发现更多驱动程序错误)。 - Bahbar
看起来很有趣 ;) 1x1 RGBA纹理是我的当前解决方案,但我不尝试将其绑定为0。 - Jeka

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接