GLSL错误:在绘制调用中未启用顶点属性

时间:2015-03-21 06:27:47

标签: android glsl opengl-es-2.0 vertex-shader glsles

我正在为OpenGL ES 2.0编写一个Android应用程序,我有一些着色器代码的问题。这是:

attribute vec4 vPosition;
vec4 tempPosition;

void main() {
    tempPosition = vPosition;
    tempPosition.x = 2 - tempPosition.x;
    gl_Position = tempPosition.yxzw;
}

导致错误的行是这一行:

tempPosition.x = 2 - tempPosition.x;

每次我想要画一些东西时,我都在启用和禁用顶点atrrib数组。在我画之前我称之为:GLES20.glEnableVertexAttribArray(sPosition);并在我画完之后我称之为 GLES20.glDisableVertexAttribArray(sPosition);

我做错了什么?如何从2减去x?

修改

如果我将导致错误的行更改为:

tempPosition.xz = vec2(2,0) - tempPosition.xz;

比它有效,但为什么我不能用一个数字减去?

1 个答案:

答案 0 :(得分:4)

在与ES 2.0一起使用的GLSL版本中(有点神秘的是版本1.00),没有隐式类型转换。您不能将类型int的值添加到类型float的值或浮点数的向量中。

这在规范第4章“变量和类型”的介绍中有详细说明:

  

OpenGL ES着色语言是类型安全的。类型之间没有隐式转换。

并在第5.9节“表达式”中针对此案例进行了更详细的说明,其中定义了+运算符:

  

两个操作数必须是相同的类型,或者一个可以是标量浮点数,另一个可以是浮点矢量或矩阵,或者一个可以是标量整数,另一个可以是整数向量。

因此,在使用浮点运算时需要使用浮点常量:

tempPosition.x = 2.0 - tempPosition.x;

更有趣的案例是为什么你的第二次尝试有效,因为你也混合了不同的类型:

tempPosition.xz = vec2(2,0) - tempPosition.xz;

这是合法的,因为构造函数可以用于转换类型,并且是执行此操作的主要机制。例如,您可以将原始表达式编写为:

tempPosition.x = float(2) - tempPosition.x;

这对于常量值看起来很尴尬,但如果整数值在变量中会更有意义:

int foo = ...;
tempPosition.x = float(foo) - tempPosition.x;

回到矢量案例,第5.4.2节“矢量和矩阵构造函数”指定:

  

如果构造函数的参数的基本类型(bool,int或float)与正在构造的对象的基本类型不匹配,则使用标量构造规则(上面)来转换参数。

这意味着您可以使用int值作为vec2的构造函数的参数,即使它包含float值。在这种情况下,该值会自动转换。换句话说,您的第二个陈述相当于:

tempPosition.xz = vec2(float(2), float(0)) - tempPosition.xz;

恕我直言,不依赖隐式转换仍然更加清晰,并写道:

tempPosition.xz = vec2(2.0, 0.0) - tempPosition.xz;

请注意,在这方面,完整的OpenGL与OpenGL ES不同。在完整的GLSL中,存在隐式类型转换。我个人认为这是不幸的,因为我认为类型安全是一个有用的原则。