The IDLgrSurface::SetVertexAttributeData procedure method passes a set of per-vertex attribute data to a vertex shader program. When an IDLgrShader object is associated with the surface via the SHADER property, this attribute data is made available, a vertex's worth at a time, to the vertex shader program as it processes each vertex in the surface. If there are more vertices in the surface than there are vertex attributes, the list of vertex attributes is reused until all the vertices are drawn.
IDL stores the Name and Value of the vertex attribute data variable with this surface object the first time this method is called. When SetVertexAttributeData is called again using the same Name argument, the vertex attribute data variable is updated with the current contents of Value. Once a vertex attribute data variable is associated with this object, there is no way to remove the reference. The shader program ignores any vertex attribute data variable defined for this object but not declared in the shader program.
The attribute data may consist of 1 to 4 elements per vertex. The data is passed to the vertex shader program via a shader program variable with the attribute qualifier. The attribute variable may be of GLSL type float, vec2, vec3, vec4, mat2, mat3, or mat4. Internally, the mat2 type is treated as two vec2 attribute variables, mat3 as three vec3 attribute variables, and mat4 as four vec4 attribute variables.
If the attribute variable is larger than the data passed to it, the shader program pads the missing elements as follows. A missing second or third element is set to 0.0. A missing fourth element is set to 1.0.
For example, the IDL application has a set of vertex attribute data where there is an x‑offset and a y‑offset for each vertex. The vertex program defines an attribute variable using a vec4 type so that it can be used in 4x4 general transformations. The IDL program stores the x- and y-offset information in a [2, n] array and sets the value of the attribute variable to this array. As the shader program runs, for each vertex it assigns the two values from the corresponding row of the IDL array to the first two elements in the vec4 attribute variable. It also sets the third value to 0.0 and the fourth value to 1.0, thus expanding the 2-element data to a general 3-D point in homogenous coordinate space, suited for 4x4 general transforms.
Note: A minimum of 16 vertex attribute data variables can be passed to the shader vertex program (use IDLgrWindow::GetDeviceInfo to determine the exact number). IDL uses one vertex attribute variable, leaving the remainder for user programs. For maximum shader program portability, define 15 or fewer attribute variables.
Syntax
Obj->[IDLgrSurface::]SetVertexAttributeData, Name, Value
Arguments
Name
Specifies a case-sensitive string name of the attribute variable.
Value
Specifies an IDL array of any numeric type. The array must be of the form [n], [a,n], or [a,a,n] where a is 1,2,3, or 4 and n is the number of vertex attribute elements. IDL will halt with an error if you assign IDL strings, structures, pointers, object references, and undefined variables to Value. IDL converts all numeric types to 32-bit float when submitting the data to the shader program.
Keywords
None
Examples
Suppose there is large set of point sample data, along with a set of initial velocity vectors for each point. You want to display an animation of these points as each point moves along its own velocity vector as a function of time. Without a shader program, you would normally have to recalculate the position of each point and replace all the vertices in an IDLgrPolygon (STYLE=0) object with the recomputed values for each animation frame, which would be inefficient with a large number of points.
However, with a vertex shader program and vertex attribute data, you can move the points around using the graphics card's GPU instead of recalculating and moving a lot of data around on the system CPU.
The interesting parts of the IDL code are:
oPolygon->SetProperty, DATA=vertices
oPolygon->SetVertexAttributeData, 'velocity', velocities
FOR t=0.0, 100.0, 0.01 DO BEGIN
oShader->SetUniformVariable, 'time', t
oWindow->Draw
ENDFOR
And the interesting parts of the vertex shader program are:
attribute vec3 velocity
uniform float time
void main () {
vec4 vert
vert = gl_Vertex + vec4(velocity * time, 0.0)
gl_Position = gl_ModelViewProjectMatrix * vert
}
Version History
See Also
IDLgrSurface::GetVertexAttributeData