OpenGL has a particular Nomenclature, a system for naming functions that is followed consistently (mostly).
Because OpenGL is cross-platform, it does not require a language that has function overloading. However, it does have many functions that conceptually do the same thing (so they have the same name), yet they have variations that take different parameter types. These functions are given unique names by adding type-based suffixes. OpenGL has a specific scheme for defining these suffixes.
Function type suffixes are typically defined in the following pattern:
The first set of braces is an optional number from 1 to 4. This defines the number of parameters of those types that the function takes. The number is specified only if different variations of the function take different numbers of arguments.
The second set of braces defines the types themselves, as defined by this table:
Therefore, the function glVertexAttrib3ub is the version of glVertexAttrib that takes 3 values, all of type GLubyte.
The v suffix means that the function takes a "vector". That is, the function takes an array of values, defined by a pointer. If this suffix is used in conjunction with a number, then the array is expected to be exactly that many values. For example, glVertexAttrib3fv takes a GLfloat* that is expected to be an array of 3 floats.
When it is not used in conjunction with a number, the array's size will be based on some other parameter. In the case of glCreateShaderProgramv, the size is an explicit parameter. In the case of glSamplerParameterfv, the size is implicit based on the nature of the pname parameter. Different pname enumerators take different numbers of arguments.
v can also be used for output values. For example, glGetProgramResourceiv will write its results to the given array of integers. The size of the array that the user allocates is given to the function as a parameter, to help prevent buffer overruns.
There are a few oddball type suffixes, particularly around querying common state data from the context. The glGet family of functions rather than using the standard type suffixes, they use a spelled typename. So there is glGetBooleanv, glGetIntegerv and so forth.
More unusual still is the use of the i_v suffix. This is used for querying indexed state, typically set by glEnablei/glDisablei. These function take an array of values (hence the v part), but they also take an integer index in addition to the enumerator (hence the i part. The underscore is there because it doesn't take an array of integer indices; it takes an array of the particular type. So glGetFloati_v takes an array of floats, using an integer index.
There are some things which will look like type suffixes but are not. For example, there is the function glVertexAttribI4i. The I part is not a type suffix; the proper name for this function is glVertexAttribI, because it has different behavior from the glVertexAttrib family than simply what type of data it takes. It doesn't merely take a different type; it treats the value in a very different way.
Function names and objects
The OpenGL object model is build around objects as containers of state. To access such objects, you first bind some state to a location in the context, then call functions that modify or read the bound state. As such, there are OpenGL functions that are closely associated with various objects.
OpenGL function names therefore tend to follow a specific convention:
Verb represents actions like "Get", "Delete", and other such things. Object is a name that specifies which OpenGL object the function acts upon. And Command defines the particulars of what is being done.
Some functions names lack one or more of these features. Generally speaking, if a function lacks a Verb, then the function will be setting some kind of state or modifying the nature of some object. If a function lacks Object, then it is generally not accessing an object; it's modifying global context state. Functions that lack Command are meta-functions like glGenTextures, which manage objects and such.
Unfortunately, OpenGL does not consistently follow this scheme, particularly as it relates to Object names. There are many OpenGL functions that act on an OpenGL object without naming that object. Fortunately the reverse case never happens. If a function names an Object, it certainly acts on an object of that type. So while glDrawBuffers modifies Framebuffer state without mentioning Framebuffer, glFramebufferTexture certainly modifies framebuffer object state.
OpenGL does try to remain consistent about the names of these Objects. For most OpenGL object types, there will be a single, name used exclusively for them. Here are the object and their common Object names:
|OpenGL Object Type||Function Name|
|Transform Feedback Objects||"TransformFeedback"|
Objects not on this list do not have an Object name (or are otherwise inconsistently named). Functions still exist to manipulate them, but none of them use a consistent Object name.
In addition to the above inconsistency, not all state for an object is accessible through functions of the form glGetObject* functions. OpenGL is more consistent about these, but there are still exceptions. For example, the current read and draw buffers cannot be queried with a glGetFramebuffer* call; you must use the generic glGetIntegerv for them.
Most of these cases are due to legacy issues. The read and draw buffers predates framebuffer objects entirely; originally, they were ordinary context state, not bound to an object. So to maintain backwards compatibility with existing code, they simply stated that the old functions modify object state rather than context state. Thus, they could avoid having two sets of functions.
Direct state access
|Core in version||4.5|
|Core since version||4.5|
|Core ARB extension||ARB_direct_state_access|
The Nomenclature for Direct State Access is a bit more consistent than the non-DSA naming. As with non-DSA functions, they follow the standard Verb-Object-Command syntax. However, there were several non-DSA functions that affected some object's state without naming the Object type in its function. In the case of DSA, all DSA functions consistently use this nomenclature (even if it makes the function name unwieldy).
The difference is that DSA functions use a different Object name from the non-DSA functions. What is inconsistent is that some DSA functions will prefix the Object name with Named, while others do not. Fortunately, all functions that act on an object will consistently use the same Object name:
|OpenGL Object Type||Context Object Name||DSA Object Name|
|Transform Feedback Object||"TransformFeedback"1||"TransformFeedback"|
|Vertex Array Object||N/A2||"VertexArray"|
- 1: Transform feedback objects have a lot of functions that use TF objects in rendering operations. But the actual state in them consists only of the buffers attached to GL_TRANSFORM_FEEDBACK_BUFFER via glBindBufferRange, as well as a captured primitive count. As such, while they had a formal Object name, it was only used for functions that used the object for feedback operations rather than state-accessing functions. So the existing name could be appropriated for DSA functions (to attach buffers to the feedback object).
- 2: The functions that manipulate this object were so inconsistently named that there was never really a consistent object name for them.
- 3: These object types already used DSA-style functions.
There are some functions which were introduced before full DSA that work in a DSA style, but use the old Object name. For example, glClearTexImage takes the texture object to be cleared as a parameter, rather than acting on context state.