4

我正在寻找一种从着色器访问 OpenGL 状态的方法。GLSL 快速参考指南,一个很棒的资源,在这方面帮不上我的忙。

在我正在处理的示例中,我有以下两个着色器:

顶点:

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,我可以设置什么条件检查,以便在禁用vec4(1.0, 1.0, 1.0, 1.0)时设置变量“texel”而不是从纹理中采样?GL_TEXTURE_2D

2,如果我为不同的纹理模式编写不同的着色器并在我将使用glEnable/ glDisable( GL_TEXTURE_2D) 的位置在它们之间切换,处理会更快吗?

4

2 回答 2

8

抱歉,您不能从 GLSL 访问那种状态,期间。

事实上,在未来的 GLSL 中,你必须自己发送所有的 unforms/attributes,即没有自动的 gl_ModelViewMatrix、gl_LightPosition、gl_Normal 等。只有 gl_Position 和 gl_FragColor 等基本内容可用。

这种方式使您的第二个问题无效,但是如果您发现这比为不同的纹理模式编写单独的着色器更方便,您总是可以使用#ifdef 来启用/禁用着色器中的部分。

相关的,请注意分支通常相当慢,因此如果您需要速度,请尽可能避免它。(这尤其重要,因为片段在 SIMD 块中处理,并且块中的所有片段必须计算相同的指令,即使它们只适用于一个或几个片段。)

于 2009-05-19T19:59:05.673 回答
3

One method I've seen is to bind a 1x1 texture with a single texel of (1.0, 1.0, 1.0, 1.0) when rendering polygons that are not textured. A texture switch should be less expensive than a shader switch and a 1x1 texture will fit entirely inside the texture cache.

于 2012-02-03T18:38:10.637 回答