Nomenclature: Difference between revisions

From OpenGL Wiki
Jump to navigation Jump to search
(More complete nomenclature.)
(→‎Function suffixes: Clarifications)
 
(15 intermediate revisions by the same user not shown)
Line 3: Line 3:
== Function suffixes ==
== Function suffixes ==


Because OpenGL is cross-platform, it does not require a language that has [http://en.wikipedia.org/wiki/Function_overloading 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.
There are a number of OpenGL functions that all perform the same task, with the only variation between these functions being that they take different [[OpenGL Type|parameter types]]. Because OpenGL is cross-platform, it does not require a language that provides [http://en.wikipedia.org/wiki/Function_overloading function overloading]. As such, these families of functions use name suffixes to specify what types they take. OpenGL has a specific scheme for defining these suffixes.


Function type suffixes are typically defined in the following pattern:
Function type suffixes are typically defined in the following pattern:
Line 9: Line 9:
{{funcdef|FunctionName{'''1234'''}{'''b s i i64 f d ub us ui ui64'''}{'''v'''} }}
{{funcdef|FunctionName{'''1234'''}{'''b s i i64 f d ub us ui ui64'''}{'''v'''} }}


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 second set of braces defines the types themselves, as defined by this table:
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.


{|class="wikitable"
The second set of braces defines the types themselves, as defined by the table to the left.
 
{|class="wikitable" style="float: left; margin-right: 10px;"
!Suffix
!Suffix
![[OpenGL Type]]
![[OpenGL Type]]
Line 48: Line 50:
Therefore, the function {{code|glVertexAttrib3ub}} is the version of {{apifunc|glVertexAttrib}} that takes 3 values, all of type {{code|GLubyte}}.
Therefore, the function {{code|glVertexAttrib3ub}} is the version of {{apifunc|glVertexAttrib}} that takes 3 values, all of type {{code|GLubyte}}.


The {{param|v}} suffix is an optional suffix. It instead means a "vector". That is, the function takes an array of values, defined by a pointer. If it is used in conjunction with a number, then the array is expected to be exactly that many values. For example, {{apifunc|glVertexAttrib|3fv}} takes a {{code|GLfloat*}} that is expected to be an array of 3 floats.
If the optional {{param|v}} suffix is provided, this means the function takes a "vector": a pointer to an array of some number of values. If this suffix is used in conjunction with a number, then the array is expected to be exactly that many values. For example, {{apifunc|glVertexAttrib|3fv}} takes a {{code|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 {{apifunc|glCreateShaderProgram|v}}, the size is an explicit parameter. In the case of {{apifunc|glSamplerParameter|fv}}, the size is implicit based on the nature of the {{param|pname}} parameter. Different {{param|pname}} enumerators take different numbers of arguments.
 
When it is not used in conjunction with a number, the array will be restricted to an expected size based on some other parameter. In the case of {{apifunc|glCreateShaderProgram|v}}, the size is an explicit parameter. In the case of {{apifunc|glSamplerParameter|fv}}, the size is implicit based on the nature of the {{param|pname}} parameter. Different {{param|pname}} enumerators will yield different results.


{{param|v}} can also be used for output values. For example, {{apifunc|glGetProgramResource|iv}} will write its results to the given array of integers. The size of the array is provided as a parameter, to help prevent buffer overruns.
The {{param|v}} suffix can also be used for output values. For example, {{apifunc|glGetProgramResource|iv}} 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.


=== Unusual suffixes ===
=== Unusual suffixes ===


There are a few oddball type suffixes, particularly around querying common state data from the context. The {{apifunc|glGet}} family of functions is very strange. Rather than using the standard type suffixes, they use a spelled typename. So there is {{apifunc|glGet|Booleanv}}, {{apifunc|glGet|Integerv}} and so forth.
There are a few oddball type suffixes, particularly around querying common state data from the context. The {{apifunc|glGet}} family of functions use a spelled typename, rather than using the standard type suffixes. So there are {{apifunc|glGet|Booleanv}}, {{apifunc|glGet|Integerv}} and so forth. Note that the {{param|v}} suffix retains the usual meaning, as these functions can return multiple values.


More unusual still is the use of the {{param|i_v}} suffix. This is used for querying indexed state, typically set by {{apifunc|glEnable|i/glDisablei}}. These function take an array of values (hence the {{param|v}} part), but they also take an integer index in addition to the enumerator (hence the {{param|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 {{apifunc|glGet|Floati_v}} takes an array of ''floats'', using an integer index.
More unusual still is the use of the {{param|i_v}} suffix. This is used for querying indexed state, typically set by {{apifunc|glEnable|i/glDisablei}}. Normally, state is specified simply by an enumerator, but indexed state specifies the state to set/query using both an enumerator and an integer index. So the {{param|i_}} in the suffix refers to the fact that the function takes an integer index, not that the function takes integers. The {{param|v}} part has the usual meaning: that the function sets/queries an array of values. So {{apifunc|glGet|Floati_v}} takes an array of ''floats'', but it uses an integer index along with the enumerator to specify which array of floats is being accessed.


=== Not suffixes ===
=== Not suffixes ===


There are some things which will look like type suffixes but are not. For example, there is the function {{apifunc|glVertexAttrib|I4i}}. The {{param|I}} part is ''not a type suffix''; the proper name for this function is {{code|glVertexAttribI}}, because it has different behavior from {{code|glVertexAttrib}} 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.
There are some things which will look like type suffixes but are not. For example, there is the function {{apifunc|glVertexAttrib|I4i}}. The {{param|4i}} is a type suffix, but the {{param|I}} part is ''not a type suffix''. The base name for this function is {{code|glVertexAttribI}}, because it has different behavior from the {{code|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 ==
== Function names and objects ==
Line 68: Line 68:
The [[OpenGL Object|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.
The [[OpenGL Object|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 uses a semi-consistent naming convention for functions in this regard. Functions which modify the state of a bound object are of the form {{code|gl{{param|OBJECT_NAME}}*}}, where {{param|OBJECT_NAME}} represents that object. Functions which read data from those objects are of the form {{code|glGet{{param|OBJECT_NAME}}*}}. Here are the object names and their common object types:
OpenGL function names therefore tend to follow a specific convention:
 
  Verb-Object-Command.
 
{{param|Verb}} represents actions that describe what the {{param|Command}} does to the {{param|Object}} or OpenGL context. There are quite a few verbs in use, from the common {{code|Get}}, {{code|Draw/MultiDraw}}, and {{code|Enable/Disable}} to the infrequent {{code|Blit}}.
 
{{param|Object}} is a name that specifies which OpenGL object the function acts upon. And {{param|Command}} defines the particulars of what is being done.
 
Many functions lack one or more of these features. Generally speaking, if a function lacks a {{param|Verb}}, then the function sets state in the context or in the given {{param|Object}}. If a function lacks {{param|Object}}, then it is generally not accessing an object; it's accessing global context state. Functions that lack {{param|Command}} tend to deal with object lifetimes, such as {{apifunc|glGenTextures}}/{{apifunc|glIsTexture}} and the like.
 
Unfortunately, OpenGL does not consistently follow this scheme, particularly as it relates to having a consistent {{param|Object}} name. 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 {{param|Object}}, it certainly acts on an object of that type. So while {{apifunc|glDrawBuffers}} modifies [[Framebuffer]] state without mentioning {{code|Framebuffer}}, the function {{apifunc|glFramebufferTexture}} undeniably modifies framebuffer object state.
 
OpenGL does try to remain consistent about the names of these {{param|Object}}s. For most OpenGL object types, there will be a specific name used exclusively for them. Here are the objects that have common {{param|Object}} names:


{|class="wikitable"
{|class="wikitable"
Line 74: Line 86:
!Function Name
!Function Name
|-
|-
|[[Texture Object]]
|[[Texture|Texture Object]]
|"Tex"
|"Tex"
|-
|-
Line 93: Line 105:
|}
|}


However, OpenGL is only semi-consistent about this. OpenGL is consistent in that all functions of the form {{code|gl{{param|OBJECT_NAME}}*}} do indeed modify that object type's state, most objects will have ''other'' functions not of that form which modify the object's state too. For example, {{apifunc|glDrawBuffers}} and {{apifunc|glReadBuffers}} both set framebuffer state, despite not being named {{code|glFramebufferDrawBuffers}} and {{code|glFramebufferReadBuffers}}.
Objects not on this list do not have an {{param|Object}} name or are inconsistently named. Functions still exist to manipulate them, but none of them use a consistent {{param|Object}} name.
 
In addition to the above inconsistency, not all state for an object is accessible through functions of the form {{code|glGet{{param|Object}}*}} 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 {{code|glGetFramebuffer*}} call; you must use the generic {{apifunc|glGet|Integerv}} 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.


Similarly, not all state for an object is accessible through {{code|glGet{{param|OBJECT_NAME}}*}} functions. OpenGL is more consistent about these, but there are still exceptions. For example, the current read and draw buffers cannot be queries with a {{code|glGetFramebuffer*}} call; you must use the generic {{apifunc|glGet|Integerv}} for them.
=== Direct state access ===
{{infobox feature
| name = Direct State Access
| core = 4.5
| core_extension = {{extref|direct_state_access}}
| ext_extension = {{extref|direct_state_access|EXT}}
}}
{{snippet|:Nomenclature/Direct State Access}}


Most of these cases are due to legacy issues. Having read and draw buffers predates framebuffer objects entirely. So to maintain backwards compatibility with existing code, they simply stated that the old functions modify objects rather than global state.


[[Category:General OpenGL]]
[[Category:General OpenGL]]

Latest revision as of 03:15, 18 October 2019

OpenGL has a particular Nomenclature, a system for naming functions that is followed consistently (mostly).

Function suffixes

There are a number of OpenGL functions that all perform the same task, with the only variation between these functions being that they take different parameter types. Because OpenGL is cross-platform, it does not require a language that provides function overloading. As such, these families of functions use name suffixes to specify what types they take. OpenGL has a specific scheme for defining these suffixes.

Function type suffixes are typically defined in the following pattern:

FunctionName{1234}{b s i i64 f d ub us ui ui64}{v}

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 the table to the left.

Suffix OpenGL Type
b GLbyte
s GLshort
i GLint
i64 GLint64
ub GLubyte
us GLushort
ui GLuint
ui64 GLuint64
f GLfloat
d GLdouble

Therefore, the function glVertexAttrib3ub is the version of glVertexAttrib that takes 3 values, all of type GLubyte.

If the optional v​ suffix is provided, this means the function takes a "vector": a pointer to an array of some number of values. 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.

The v​ suffix 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.

Unusual suffixes

There are a few oddball type suffixes, particularly around querying common state data from the context. The glGet family of functions use a spelled typename, rather than using the standard type suffixes. So there are glGetBooleanv, glGetIntegerv and so forth. Note that the v​ suffix retains the usual meaning, as these functions can return multiple values.

More unusual still is the use of the i_v​ suffix. This is used for querying indexed state, typically set by glEnablei/glDisablei. Normally, state is specified simply by an enumerator, but indexed state specifies the state to set/query using both an enumerator and an integer index. So the i_​ in the suffix refers to the fact that the function takes an integer index, not that the function takes integers. The v​ part has the usual meaning: that the function sets/queries an array of values. So glGetFloati_v takes an array of floats, but it uses an integer index along with the enumerator to specify which array of floats is being accessed.

Not suffixes

There are some things which will look like type suffixes but are not. For example, there is the function glVertexAttribI4i. The 4i​ is a type suffix, but the I​ part is not a type suffix. The base 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-Object-Command.

Verb​ represents actions that describe what the Command​ does to the Object​ or OpenGL context. There are quite a few verbs in use, from the common Get, Draw/MultiDraw, and Enable/Disable to the infrequent Blit.

Object​ is a name that specifies which OpenGL object the function acts upon. And Command​ defines the particulars of what is being done.

Many functions lack one or more of these features. Generally speaking, if a function lacks a Verb​, then the function sets state in the context or in the given Object​. If a function lacks Object​, then it is generally not accessing an object; it's accessing global context state. Functions that lack Command​ tend to deal with object lifetimes, such as glGenTextures/glIsTexture and the like.

Unfortunately, OpenGL does not consistently follow this scheme, particularly as it relates to having a consistent Object​ name. 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, the function glFramebufferTexture undeniably modifies framebuffer object state.

OpenGL does try to remain consistent about the names of these Object​s. For most OpenGL object types, there will be a specific name used exclusively for them. Here are the objects that have common Object​ names:

OpenGL Object Type Function Name
Texture Object "Tex"
Framebuffer Object "Framebuffer"
Buffer Object "Buffer"
Sampler Object "Sampler"
Query Object "Query"
Transform Feedback Objects "TransformFeedback"

Objects not on this list do not have an Object​ name or are 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

Direct State Access
Core in version 4.6
Core since version 4.5
Core ARB extension ARB_direct_state_access
EXT extension EXT_direct_state_access
V · E

The Nomenclature for Direct State Access's functions 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 specify the Object, even if it makes the function name unwieldy.

The difference is that DSA functions use a different Object​ name from the non-DSA functions. Because OpenGL is defined to be implemented in C, function overloading cannot be used. So DSA functions are differentiated from their non-DSA versions by using a different Object​ name.

There is an inconsistency in how this new Object​ name was chosen. For some object types, the new Object​ name is the old Object​ name prefixed with "Named". Others objects use a longer version of the original, non-DSA Object​ name. Fortunately, all functions that act on a particular object will consistently use the same Object​ name:

OpenGL Object Type Context Object Name DSA Object Name
Texture Object "Tex" "Texture"
Framebuffer Object "Framebuffer" "NamedFramebuffer"
Buffer Object "Buffer" "NamedBuffer"
Transform Feedback Object "TransformFeedback"1 "TransformFeedback"
Vertex Array Object N/A2 "VertexArray"
Sampler Object N/A3 "Sampler"
Query Object N/A3 "Query"
Program Object N/A3 "Program"
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. For program objects, DSA-style uniform setting (e.g. glProgramUniform) was added with separable programs in GL 4.2.

There are some functions which were introduced before OpenGL 4.5. These functions 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. The DSA feature did not add variations on these that use the DSA-Object​ name.