Difference between revisions of "OpenGL Object"

From OpenGL.org
Jump to: navigation, search
(Object Types: Sync objects do not conform to the standard for OpenGL objects.)
(Object Creation and Destruction)
(25 intermediate revisions by 3 users not shown)
Line 1: Line 1:
'''OpenGL Objects''' are defined in terms of the context state that they contain. When they are bound to the context, the state that they contain is mapped into the context's state. Changes to the context state will then be stored in the object.
+
{{object float}}
 
+
'''OpenGL Objects''' are defined in terms of the context state that they contain. When they are bound to the context, the state that they contain is mapped into the context's state. Thus, changes to context state will be stored in this object, and functions that act on this context state will use the state stored in the object.
GL Objects.
+
  
 
== State and Objects ==
 
== State and Objects ==
Line 13: Line 12:
 
== Object Creation and Destruction ==
 
== Object Creation and Destruction ==
  
To create an object, you generate the object's name. This creates an empty object of the given type. The state that the empty objects have is well-defined by the specification for each object's type. So these objects are not created with undefined state.
+
To create an object, you generate the object's ''name'' (an integer). This creates a reference to the object. The object will only contain its default state when it is first bound to the context.
  
The functions to do this are of the form <code>glGen*</code>, where * is the object's type. All functions of this type have the same signature:
+
The functions to generate the object's name are of the form {{code|glGen*}}, where * is the object's type in plural form. All functions of this type have the same signature:
  
<code>
+
  void glGen*(GLsizei {{param|n}}, GLuint *{{param|objects}});
void glGen*(GLsizei ''n'', GLuint *''objects'');
+
</code>
+
  
This function generates <code>n</code> objects of the given type, storing them in the array given by the <code>objects</code> parameter. This allows you to create multiple objects with one call.
+
This function generates {{param|n}} objects of the given type, storing them in the array given by the {{param|objects}} parameter. This allows you to create multiple objects with one call.
  
An object name is always a GLuint. These names are not pointers, nor should you assume that they are. They are names, numbers that identify an object. They can be any 32-bit unsigned integer except 0. The object number 0 is never a valid object; it is how you specify that you don't want to use an object.
+
An object name is always a GLuint. These names are not pointers, nor should you assume that they are. They are references, numbers that identify an object. They can be any 32-bit unsigned integer except 0. The object number 0 is reserved for special use cases; see below for details.
  
: '''Legacy Note:''' In OpenGL versions before 3.0, the user was allowed to ignore the generation step entirely. The user could just decide that "3" is a valid object name, and start using it like an object. The implementation would then have to accept that and create the object behind the scenes when you first start using it. In GL 3.0, this behavior was deprecated. In core GL 3.1 and above, this is no longer allowed. Regardless of the version of OpenGL, it is always good practice to use <code>glGen*</code>.
+
: '''Legacy Note:''' In OpenGL versions before 3.0, the user was allowed to ignore the generation step entirely. The user could just decide that "3" is a valid object name, and start using it like an object. The implementation would then have to accept that and create the object behind the scenes when you first start using it. In GL 3.0, this behavior was deprecated. In core GL 3.1 and above, this is no longer allowed. Regardless of the version of OpenGL, it is always good practice to use {{code|glGen*}} rather than making up your own object names.
  
Once you are finished with an object, you should delete it. The functions for this are of the form <code>glDelete*</code>, using the same object type as before. These functions have this signature:
+
Once you are finished with an object, you should delete it. The functions for this are of the form {{code|glDelete*}}, using the same object type as before. These functions have this signature:
  
<code>
+
void glDelete*(GLsizei {{param|n}}, const GLuint *{{param|objects}});
void glDelete*(GLsizei ''n'', const GLuint *''objects'');
+
</code>
+
  
This works like the <code>glGen</code> functions, only it deletes the objects instead of creating them.
+
This works like the {{code|glGen*}} functions, only it deletes the objects instead of creating them.
 +
 
 +
After an object is deleted, its name is no longer valid. A subsequent {{code|glGen*}} call may or may not reuse a previously-deleted name; you should not make assumptions either way.
  
 
=== Object Attachment and Orphaning ===
 
=== Object Attachment and Orphaning ===
  
Calling <code>glDelete*</code> on an object does not guarantee its ''immediate'' deletion. Because OpenGL is allowed to execute rendering commands well after you issue them (for maximum parallelism and performance), it is entirely possible for an object to remain with the OpenGL server for some time before it actually deletes it.
+
Calling {{code|glDelete*}} on an object does not guarantee its ''immediate'' deletion. Because OpenGL is allowed to execute rendering commands well after you issue them (for maximum parallelism and performance), it is entirely possible for an object to remain with the OpenGL server for some time before it actually deletes it.
  
Note that this is an implementation detail. Once you call <code>glDelete*</code> on the object, the object name becomes useless. You can no longer refer to that object, even if the object is still being used by the rendering pipeline.
+
Note that this is an implementation detail. Once you call {{code|glDelete*}} on the object, the object name becomes useless. You can no longer refer to that object, even if the object is still being used by the rendering pipeline.
  
This is not the case for objects that can become attached to other objects. If you delete an object that is attached to another object, the object will continue to exist until all objects it is attached to are deleted, or the object becomes unattached. This is different from the orphaning described above; you can still refer to the object through normal commands. You should n't, because the object can be deleted later by commands that normally would not delete objects, but you still can.
+
This is not the case for objects that can become attached to other objects. If you delete an object that is attached to another object, the object will continue to exist until all objects it is attached to are deleted, or the object becomes unattached. This is different from the orphaning described above; you can still refer to the object through normal commands. You shouldn't, because the object can be deleted later by commands that normally would not delete objects, but you still can.
  
If you have bound an object to the current GL context, and you call <code>glDelete*</code> on it, this will also cause that binding to be terminated. The context will be as though you had bound object name "0" (not an object) to the context. If you have bound the object to another context (though object sharing, see below), then the object will not be deleted.
+
If you have bound an object to the current GL context, and you call {{code|glDelete*}} on it, this will also cause that binding to be terminated. The context will be as though you had bound object name 0 to the context. If you have bound the object to another context (though object sharing, see below), then the object will not be deleted.
  
 
== Object Usage ==
 
== Object Usage ==
  
Because objects in OpenGL are defined as a collections of state, to modify objects, you must first bind them to the OpenGL context. Binding objects to the context causes the state in them to be set to be the current context's state. This also means that any functions that change the encapsulated state will simply change the state within the object, thus preserving that state.
+
Because objects in OpenGL are defined as a collections of state, to modify objects, you must first bind them to the OpenGL context. Binding objects to the context causes the state in them to be set to be the current context's state. This means that any functions that change the state governed by that object will simply change the state within the object, thus preserving that state.
 +
 
 +
Binding a newly generated object name will create new state for that object. In some cases, the target to which it is first bound (see below) will affect properties of the newly created state for the object.
  
 
Different objects have different binding functions. They do share a naming convention and general parameters:
 
Different objects have different binding functions. They do share a naming convention and general parameters:
  
<code>
+
void '''glBind*'''({{param|location}}, GLuint {{param|object}});
void glBind*(''location'', GLuint ''object'');
+
</code>
+
  
The * is the type of object, and <code>object</code> is the object to be bound.
+
The * is the type of object, and {{param|object}} is the object to be bound.
  
The ''location'' is where different object types differ. Some objects can be bound to multiple locations in the context, while others can only be bound to a specific place. For example, a buffer object can be bound as an array buffer, index buffer, pixel buffer, transform buffer, or various other possibilities. If an object can be bound to multiple locations, then there will be some kind of parameter to define where the binding happens. Buffer objects take an enumeration, for example.
+
The {{param|location}} is where different object types differ. Some objects can be bound to multiple locations in the context, while others can only be bound to a single specific place. For example, a buffer object can be bound as an array buffer, index buffer, pixel buffer, transform buffer, or various other possibilities. If an object can be bound to multiple locations, then there will be some kind of parameter to define where the binding happens. {{apifunc|glBindBuffer}} takes an enumeration, for example.
  
 
Different locations have separate bindings. So you can bind a buffer object as an array, and a different buffer object as an index buffer without having any crosstalk between them.
 
Different locations have separate bindings. So you can bind a buffer object as an array, and a different buffer object as an index buffer without having any crosstalk between them.
  
If an object is bound to a location where another object is also bound, the previously bound object will be unbound. If the <code>object</code> parameter is object 0 (not an object), then the currently bound object to that will be unbound, but no new object will be bound.
+
If an object is bound to a location where another object is also bound, the previously bound object will be unbound.
 +
 
 +
All OpenGL objects have the ''concept'' of an "object 0". But they don't all have an actual ''object'' that represents that concept. For example, with [[Framebuffer Object]]s, object 0 means the [[Default Framebuffer]], which is a special case. [[Buffer Object]]s do not have an object 0, so attempting to do something that requires a bound buffer object while 0 is bound is an error. [[Texture]] objects do have an object 0; this is effectively an un-deletable object that you could theoretically store data in (but you never should).
 +
 
 +
If you bind object 0 to a target, then the currently bound object will be unbound. If that object type has an object 0, then that object will be bound to the target. Otherwise, nothing will be bound to that target.
 +
 
 +
{{recommend|With the exception of [[Framebuffer Object]]s, you should completely ignore object 0. Even if an object type has an object 0, you should treat it as if it did not. Treat it as you would the NULL pointer in C/C++; you can store it in a pointer, but you can't ''use'' that pointer until you put a real object there.}}
  
 
== Object Sharing ==
 
== Object Sharing ==
Line 69: Line 72:
 
At context creation time however, you are able to create a context that shares objects with another context. This means you can use objects created in one context in another context.
 
At context creation time however, you are able to create a context that shares objects with another context. This means you can use objects created in one context in another context.
  
Not all object types can be shared across contexts. The unsharable objects tend to be ones made from simple state; objects that hold lots of data, like buffers or textures, are sharable.
+
Not all object types can be shared across contexts. Objects that contain references to other objects cannot be shared. These include [[Framebuffer Object]]s, Program Pipeline objects, [[Query Object]]s, [[Transform Feedback|Transform Feedback objects]], and [[Vertex Array Object]]s. All other object types can be shared. This includes [[GLSL Object]]s and [[Sync Object]]s, which do not follow the OpenGL Object model.
  
 
== Object Types ==
 
== Object Types ==
  
* [[Buffer Objects]], with a number of different uses:
+
* [[Buffer Object]]s, with a number of different uses:
** [[Vertex Buffer Objects]]
+
** [[Vertex Buffer Object]]s
** [[Pixel Buffer Objects]]
+
** [[Pixel Buffer Object]]s
** [[Uniform Buffer Objects]]
+
** [[Uniform Buffer Object]]s
* [[Vertex Array Objects]]
+
* [[Transform Feedback]] Objects
* [[Textures|Texture Objects]]
+
* [[Vertex Array Object]]s
* [[GLSL|Shader and Program Objects]]
+
* [[Texture|Texture Objects]]
* [[Framebuffer Objects]]
+
** [[Sampler Object]]s
 +
* [[Query Object]]s
 +
* [[Framebuffer Object]]s
 +
** [[Renderbuffer Object]]s
 +
 
 +
The following are ''not'' OpenGL Objects. They are called "objects" in the OpenGL API, but they do not follow the well-defined conventions specified above:
 +
 
 +
* [[Sync Object]]s
 +
* [[GLSL Object|GLSL Shader and Program Objects]]
 +
** Except for program pipeline objects, which ''do'' follow the OpenGL Object conventions.
  
 
[[Category:Objects]]
 
[[Category:Objects]]
 +
[[Category:General OpenGL]]

Revision as of 00:45, 8 November 2012

OpenGL Objects are defined in terms of the context state that they contain. When they are bound to the context, the state that they contain is mapped into the context's state. Thus, changes to context state will be stored in this object, and functions that act on this context state will use the state stored in the object.

State and Objects

OpenGL is defined as a state machine. The various API calls change the OpenGL state, query some part of that state, or cause OpenGL to use its current state to render something.

Objects are always containers for state. Each particular kind of object is defined by the particular state that it contains. An OpenGL object is a way to encapsulate a particular group of state and change all of it in one function call.

Remember: this is just how OpenGL is defined by its specification. How these objects are actually implemented in drivers is another matter. But that is nothing you need to worry about; what matters is how objects and state interact as defined by the specification.

Object Creation and Destruction

To create an object, you generate the object's name (an integer). This creates a reference to the object. The object will only contain its default state when it is first bound to the context.

The functions to generate the object's name are of the form glGen*​, where * is the object's type in plural form. All functions of this type have the same signature:

 void glGen*(GLsizei n​, GLuint *objects​);

This function generates n​ objects of the given type, storing them in the array given by the objects​ parameter. This allows you to create multiple objects with one call.

An object name is always a GLuint. These names are not pointers, nor should you assume that they are. They are references, numbers that identify an object. They can be any 32-bit unsigned integer except 0. The object number 0 is reserved for special use cases; see below for details.

Legacy Note: In OpenGL versions before 3.0, the user was allowed to ignore the generation step entirely. The user could just decide that "3" is a valid object name, and start using it like an object. The implementation would then have to accept that and create the object behind the scenes when you first start using it. In GL 3.0, this behavior was deprecated. In core GL 3.1 and above, this is no longer allowed. Regardless of the version of OpenGL, it is always good practice to use glGen*​ rather than making up your own object names.

Once you are finished with an object, you should delete it. The functions for this are of the form glDelete*​, using the same object type as before. These functions have this signature:

void glDelete*(GLsizei n​, const GLuint *objects​);

This works like the glGen*​ functions, only it deletes the objects instead of creating them.

After an object is deleted, its name is no longer valid. A subsequent glGen*​ call may or may not reuse a previously-deleted name; you should not make assumptions either way.

Object Attachment and Orphaning

Calling glDelete*​ on an object does not guarantee its immediate deletion. Because OpenGL is allowed to execute rendering commands well after you issue them (for maximum parallelism and performance), it is entirely possible for an object to remain with the OpenGL server for some time before it actually deletes it.

Note that this is an implementation detail. Once you call glDelete*​ on the object, the object name becomes useless. You can no longer refer to that object, even if the object is still being used by the rendering pipeline.

This is not the case for objects that can become attached to other objects. If you delete an object that is attached to another object, the object will continue to exist until all objects it is attached to are deleted, or the object becomes unattached. This is different from the orphaning described above; you can still refer to the object through normal commands. You shouldn't, because the object can be deleted later by commands that normally would not delete objects, but you still can.

If you have bound an object to the current GL context, and you call glDelete*​ on it, this will also cause that binding to be terminated. The context will be as though you had bound object name 0 to the context. If you have bound the object to another context (though object sharing, see below), then the object will not be deleted.

Object Usage

Because objects in OpenGL are defined as a collections of state, to modify objects, you must first bind them to the OpenGL context. Binding objects to the context causes the state in them to be set to be the current context's state. This means that any functions that change the state governed by that object will simply change the state within the object, thus preserving that state.

Binding a newly generated object name will create new state for that object. In some cases, the target to which it is first bound (see below) will affect properties of the newly created state for the object.

Different objects have different binding functions. They do share a naming convention and general parameters:

void glBind*(location​, GLuint object​);

The * is the type of object, and object​ is the object to be bound.

The location​ is where different object types differ. Some objects can be bound to multiple locations in the context, while others can only be bound to a single specific place. For example, a buffer object can be bound as an array buffer, index buffer, pixel buffer, transform buffer, or various other possibilities. If an object can be bound to multiple locations, then there will be some kind of parameter to define where the binding happens. glBindBuffer takes an enumeration, for example.

Different locations have separate bindings. So you can bind a buffer object as an array, and a different buffer object as an index buffer without having any crosstalk between them.

If an object is bound to a location where another object is also bound, the previously bound object will be unbound.

All OpenGL objects have the concept of an "object 0". But they don't all have an actual object that represents that concept. For example, with Framebuffer Objects, object 0 means the Default Framebuffer, which is a special case. Buffer Objects do not have an object 0, so attempting to do something that requires a bound buffer object while 0 is bound is an error. Texture objects do have an object 0; this is effectively an un-deletable object that you could theoretically store data in (but you never should).

If you bind object 0 to a target, then the currently bound object will be unbound. If that object type has an object 0, then that object will be bound to the target. Otherwise, nothing will be bound to that target.

Recommendation: With the exception of Framebuffer Objects, you should completely ignore object 0. Even if an object type has an object 0, you should treat it as if it did not. Treat it as you would the NULL pointer in C/C++; you can store it in a pointer, but you can't use that pointer until you put a real object there.

Object Sharing

You can create multiple OpenGL contexts. This is useful, as the current GL context is thread-specific. Normally, each context is entirely separate from the others; nothing done in one can affect the others.

At context creation time however, you are able to create a context that shares objects with another context. This means you can use objects created in one context in another context.

Not all object types can be shared across contexts. Objects that contain references to other objects cannot be shared. These include Framebuffer Objects, Program Pipeline objects, Query Objects, Transform Feedback objects, and Vertex Array Objects. All other object types can be shared. This includes GLSL Objects and Sync Objects, which do not follow the OpenGL Object model.

Object Types

The following are not OpenGL Objects. They are called "objects" in the OpenGL API, but they do not follow the well-defined conventions specified above: