In this tutorial, you have learned about the following:
Buffer object contents can be updated partially with the
glBufferSubData
function. This function performs the
equivalent of a memcpy
operation.
Uniform variables in shaders are variables that are set by code outside of GLSL. They only change between rendering calls, so they are uniform over the surface of any particular triangle.
Uniform variable values are stored with the program object. This state is preserved until it is explicitly changed.
Uniform variables defined in two GLSL stages that have the same name and type are considered the same uniform. Setting this uniform in the program object will change its value for both stages.
There are several things you can test to see what happens with these tutorials.
With VertCalcOffset.cpp
, change it so that it draws
two triangles moving in a circle, with one a half
loopDuration
ahead of the other. Simply change the
uniforms after the glDrawArrays
call and then make the
glDrawArrays
call again. Add half of the loop
duration to the time before setting it the second time.
In FragChangeColor.cpp
, change it so that the
fragment program bounces between firstColor
and
secondColor
, rather than popping from
secondColor
back to first at the end of a loop. The
first-to-second-to-first transition should all happen within a single
fragLoopDuration
time interval. In case you are
wondering, GLSL supports the if
statement, as well as the
?: operator. For bonus points however, do it without an explicit conditional
statement; feel free to use a sin or cos function to do this.
Using our knowledge of uniforms, go back to Tutorial 2's FragPosition tutorial. Modify the code so that it
takes a uniform that describes the window's height, rather than using a
hard-coded value. Change the reshape
function to bind
the program and modify the uniform with the new height.
This function copies memory from the user's memory address into a buffer object. This function takes a byte offset into the buffer object to begin copying, as well as a number of bytes to copy.
When this function returns control to the user, you are free to immediately deallocate the memory you owned. So you can allocate and fill a piece of memory, call this function, and immediately free that memory with no hazardous side effects. OpenGL will not store the pointer or make use of it later.
This function retrieves the location of a uniform of the given name from the given program object. If that uniform does not exist or was not considered in use by GLSL, then this function returns -1, which is not a valid uniform location.
Sets the given uniform in the program currently in use (set by
glUseProgram
) to the given value. This is not
merely one function, but an entire suite of functions that take
different types.
vec mod( | vec numerator, |
float denominator) ; |
The mod
function takes the modulus of the
numerator
by the denominator
. The
modulus can be thought of as a way of causing a loop; the return value will be on
the range [0, denominator
) in a looping fashion.
Mathematically, it is defined as numerator
-
(denominator
*
FLOOR
(numerator
/
denominator
)), where FLOOR
rounds a
floating-point value down towards the smallest whole number.
The type vec can be either float or any vector type. It
must be the same type for all parameters. If a vector denominator is used, then the
modulus is taken for each corresponding component. The function returns a vector of
the same size as its numerator
type.
vec cos( | vec angle) ; |
vec sin( | vec angle) ; |
Returns the trigonometric cosine
or sine, respectively, of the given angle.
The
angle
is given in units of radians. If the
angle
is a vector, then the returned vector will be of
the same size, and will be the cosine or sine of each component of the
angle
vector.