GLSL ERROR: No vertex attrib is enabled in a draw call

GLSL ERROR: No vertex attrib is enabled in a draw call

我正在 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;

每次我想画东西时,我都会启用和禁用顶点属性数组。在我画之前我称之为:GLES20.glEnableVertexAttribArray(sPosition); 在我画之后我称之为 GLES20.glDisableVertexAttribArray(sPosition);

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

编辑:

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

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

虽然行得通,但为什么我不能用一个数字减去?

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

这在规范的第4章"Variables and Types"的介绍中指定:

The OpenGL ES Shading Language is type safe. There are no implicit conversions between types.

在第 5.9 节 "Expressions" 中更详细地介绍了这种情况,其中定义了 + 运算符:

The two operands must be the same type, or one can be a scalar float and the other a float vector or matrix, or one can be a scalar integer and the other an integer vector.

因此,在操作浮点数时需要使用浮点数常量:

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 节 "Vector and Matrix Constructors" 指定:

If the basic type (bool, int, or float) of a parameter to a constructor does not match the basic type of the object being constructed, the scalar construction rules (above) are used to convert the parameters.

这意味着您可以使用 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 中,存在隐式类型转换。我个人觉得这很不幸,因为我相信类型安全是一个有用的原则。