我正在为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;
比它有效,但为什么我不能用一个数字减去?
答案 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中,存在隐式类型转换。我个人认为这是不幸的,因为我认为类型安全是一个有用的原则。