2013-03-07 51 views
2

在我的程序中,我使用了2种纹理:t0和t1。 T1是额外的,只是在某些情况下需要:在OpenGL中绑定零纹理

..... 
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)return(0,0 ,0,1)纹理。

我进行了一些测试: 的Shader

.... 
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纹理)?

回答

6

以下所有内容都涉及核心配置文件3.2,但通常适用于所有版本的GL。

名称0对应于默认纹理对象(每个纹理目标一个:1d,2d,...见3.8.14,最后一段)。

所以glBindtexture(2D, 0);让你获得默认的纹理对象。它确实是而不是意味着禁用纹理。现在,默认对象的纹理会导致通常的操作,只是在您自己没有创建的纹理对象上。最初的纹理对象最初是不完整的,所以除非你修改它,否则它将遵循“不完整”的规则。

现在规范说(3.9.2,纹理访问段落),从不完整纹理抽样将返回(0,0,0,1)。

所以你的老司机没有按照规范行事。

+0

太棒了!这是合乎逻辑的使用(0,0,0,0)作为“零”纹理;(我没有找到有什么办法来定义默认纹理? – Jeka 2013-03-07 16:06:50

+1

@Jeka:这是一个像任何其他纹理,所以如果你设置它为1x1 RGBA纹理,其内容为0,0,0,0的单一纹素,它将完成你以后的工作,通常这样使用它,所以你可能会混淆任何人阅读你的代码(哦,并可能发现更多驱动程序错误) – Bahbar 2013-03-07 16:12:13

+0

看起来很有趣;)1x1 RGBA纹理是我当前的解决方案,但我不尝试将它与0绑定 – Jeka 2013-03-11 07:57:43