我正在寻找一种从着色器访问OpenGL状态的方法。 GLSL Quick Reference Guide,一个很棒的资源,无法真正帮助我解决这个问题。
在我正在研究的示例中,我有以下两个着色器:
顶点:
void main()
{
gl_FrontColor = gl_Color;
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform();
}
片段:
uniform sampler2D tex;
uniform float flattening;
void main( void )
{
vec4 texel;
texel = texture2D(tex, gl_TexCoord[0].st);
texel.r *= gl_Color.r;
texel.g *= gl_Color.g;
texel.b *= gl_Color.b;
texel.a *= gl_Color.a;
gl_FragColor = texel;
}
当我渲染没有纹理的多边形时,它们的alpha值是正确的,但是它们被指定为黑色。
1,我可以设置哪种条件检查,以便将变量'texel'设置为vec4(1.0, 1.0, 1.0, 1.0)
,而不是在GL_TEXTURE_2D
被禁用时从纹理中采样?
2,如果我为不同的纹理模式编写不同的着色器并在它们之间进行切换,我会使用glEnable
/ glDisable
(GL_TEXTURE_2D
),处理会更快吗?
答案 0 :(得分:8)
很抱歉,但您无法从GLSL期间访问此类状态。
事实上,在未来的GLSL中你必须自己发送所有的unforms /属性,即没有自动的gl_ModelViewMatrix,gl_LightPosition,gl_Normal等。只有像gl_Position和gl_FragColor这样的基本内容才可用。
这样会使你的第二个问题无效,但如果你发现为不同的纹理模式编写单独的着色器更方便,你总是可以使用#ifdef来启用/禁用着色器中的部件。
相关,请注意分支通常相当慢,因此如果您需要速度,请尽可能避免使用。 (这尤其是不规则的动态分支,因为片段在SIMD块中处理,并且块中的所有片段必须计算相同的指令,即使它们仅适用于一个或几个片段。)
答案 1 :(得分:3)
我看到的一种方法是在渲染未纹理化的多边形时将1x1纹理与单个纹素(1.0,1.0,1.0,1.0)绑定。纹理开关应该比着色器开关便宜,并且1x1纹理将完全适合纹理缓存。