First you get the uniform's location:
GLint location = glGetUniformLocation(programId, "uniform name");
Once you have the location you can send the entire value of the matrix via glUniformMatrix4fv
:
const GLFloat matrix[] = { ...16 values of the matrix here... };
glUniformMatrix4fv(location, 1, GL_FALSE, matrix);
Thus, to change a single element, change it in the CPU-side representation of the matrix (for example, set matrix[4] = 1.0f
) and re-send the entire matrix uniform, leaving the rest of the elements unchanged.
If, for some reason, you no longer have a CPU-side copy of the matrix value, you can use glGetUniformfv
to query the current value of a uniform based on its location. Note that you should generally keep a CPU-side copy of the matrix around because modifying it and sending it via glUniformMatrix4fv
alone is going to be faster than first querying it via glGetUniformfv
, modifying the queried data, and resending it.
(You cannot directly query and modify a single element of a matrix via OpenGL, you can only query and send the 16 elements all at once; you can modify a single element of the 16-element array on the CPU however.)