问题
From section 5.8 of The OpenGL® ES Shading Language (v1.00, r17) [PDF] (emphasis mine):
The assignment operator stores the value of the rvalue-expression into the l-value and returns an r-value with the type and precision of the lvalue-expression. The lvalue-expression and rvalue-expression must have the same type. All desired type-conversions must be specified explicitly via a constructor.
So it sounds like doing something like this would not be legal:
vec3 my_vec3 = vec3(1, 2, 3);
vec4 my_vec4 = my_vec3;
And to make it legal the second line would have to be something like:
vec4 my_vec4 = vec4(my_vec3, 1); // add 4th component
I assumed that glVertexAttribPointer had similar requirements. That is, if you were assigning to a vec4
that the size
parameter would have to be equal to 4.
Then I came across the GLES20TriangleRenderer sample for Android. Some relevant snippets:
attribute vec4 aPosition;
maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false,
TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);
So aPosition
is a vec4
, but the call to glVertexAttribPointer
that's used to set it has a size
of 3. Is this code correct, is GLES20TriangleRenderer
relying on unspecified behavior, or is there something else I'm missing?
回答1:
The size of the attribute data passed to the shader does not have to match the size of the attribute in that shader. You can pass 2 values (from glVertexAttribPointer
) to an attribute defined as a vec4
; the leftover two values are zero, except for the W component which is 1. And similarly, you can pass 4 values to a vec2
attribute; the extra values are discarded.
So you can mix and match vertex attributes with uploaded values all you want.
来源:https://stackoverflow.com/questions/7747566/can-you-use-glvertexattribpointer-to-assign-a-smaller-vector-to-a-larger-one