# Attributes: pass additional vertex information

We may need more than just plain coordinates in our program. For instance: colors. Let's pass RGB color information to OpenGL.
We passed the coordinates using an attribute, so we can add a new attribute for colors. Let's modify our globals:
And our init_resources:
Now in the render procedure, we can pass 1 RGB color for each of our 3 vertices. I chose yellow, blue and red, but feel free to use your favorite colors :)
Let's tell OpenGL once we're done with the attribute, at the end of the function:
Last, we declare it also in our vertex shader:
At this point, if we run the program, we'll get:
This is because we didn't use v_color yet.
Problem is: we want to color in the fragment shader, not in the vertex shader! Let's now see how to...

# Varyings: pass information from the vertex shader to the fragment shader

Instead of using an attribute, we'll use a varying variable. It's:
* An output variable for the vertex shader
* An input variable for the fragment shader
* It's interpolated.
So it's a communication channel between the two shaders. To understand why it's interpolated, let's see an example.
We need to declare our new varying, say f_color, in both shaders.
In triangle.v.glsl:
and in triangle.f.glsl:
(Note: if you're using GLES2, check the section on portability below.)
Let's see the result:
Wow, there's actually more than 3 colors!
OpenGL interpolates the vertex value for each pixel. This explains the varying name: it varies for each vertex, and then it varies even more for each fragment.
We didn't need to declare the varying in the C code - that's because there's no interface between the C code and the varying.

# Interweaving coordinates and colors

To better understand the glVertexAttribPointer function, let's mix both attributes in a single C array:
glVertexAttribPointer's 5th element is the stride, to tell OpenGL how long each set of attributes is - in our case 5 floats:
It works just the same!
Note that for colors, we start at the 3rd element (2 * sizeof(GLfloat)) of the array, where the first color is - that's the offset of the first element.
Why (GLvoid*)? We saw that, in early versions of OpenGL, it was possible to pass a pointer to a C array directly (rather than a buffer object). This is now deprecated, but the glVertexAttribPointer prototype remained unchanged, so we do as if we passed a pointer, but we pass an offset really.
An alternative for sport:
Note the use of offsetof to specify the first color offset.

# Uniforms: pass global information

The opposite of attribute variables are uniform variables: they are the same for all the vertices. Note that we can change them on a regular basis from the C code - but each time a set of vertices is displayed on screen, the uniform will be constant.
Let's say that we want to define the triangle's global transparency from our C code. As with attributes, we need to declare it. A global in the C code:
Then we declare it in the C code (still after the program linking):
Note: we could even target a specific array element in the shader code with uniform_name, e.g. "my_array[1]"!
In addition, for uniform, we also explicitly set its non-varying value. Let's request, in render, that the triangle be very little opaque:
We now can use this variable in our fragment shader:
Note: if you don't use the uniform in your code, glGetUniformLocation will not see it, and fail.

# OpenGL ES 2 portability

In the previous section, we mentioned that GLES2 requires precision hints. These hints tells OpenGL how much precision we want for our data. The precision can be:
* lowp
* mediump
* highp
For instance, lowp can often be used for colors, and it is recommended to use highp for vertices.
We can specify the precision on each variable:
or, we can declare a default precision:
Sadly these precision hints do not work on traditional OpenGL 2.1, so we need to include them only if we're on GLES2.
GLSL includes a preprocessor, similar to the C preprocessor. We can use directive such as #define or #ifdef.
Only the fragment shader requires an explicit precision for floats. The precision is implicitly highp for vertex shaders. For fragment shaders, highp might not be available, which can be tested using the GL_FRAGMENT_PRECISION_HIGH macro.
We can improve our shader loader so it defines a default precision on GLES2, and ignore precision identifiers on OpenGL 2.1 (so we can still set the precision for a specific variable if needed):
Keep in mind that the GLSL compiler will count these prepended lines in its line count when displaying error messages. Setting #line 0 sadly does not reset this compiler line count.

# Refreshing the display

Now it would be quite nice if the transparency could vary back and forth. To achieve this,
* we can check the number of seconds since the user started the application; SDL_GetTicks/1000 gives that
* apply the maths sin function on it (the sin function goes back on forth between -1 and +1 every 2.PI=~6.28 units of time)
* before rending the scene, prepare a logic function to update its state.
In mainLoop, let's call the logic function, before the render:
Let's add a new logic function
Also remove the call to glUniform1f in render.
Compile and run...
We've got our first animation!
It is common that OpenGL implementation wait for the screen's vertical refresh before updating the physical screen's buffer - this is called vertical sync. In that case, the triangle will be rendered around 60 times per second (60 FPS). If you disable vertical sync, the program will keep updating the triangle continuously, resulting in a higher CPU usage. We'll meet again the vertical sync when we create applications with perspective changes.

# Notes

* ↑ It's a bit confusing to have a single example across the two differents concepts of attribute and varying. We'll try to find two separate examples to better explain them.
* ↑ Cf. "OpenGL ES Shading Language 1.0.17 Specification" (PDF). Khronos.org. 2009-05-12. Retrieved 2011-09-10., section 4.5.3 Default Precision Qualifiers
- Recent stats
< OpenGL Programming