OpenGL Learning Notes (vi)

Source: Internet
Author: User
Tags bind valid server memory

Buffer Object

Many OpenGL operations send a large chunk of data to OpenGL, such as passing the vertex array data that needs to be processed. Transferring this data can be very simple, such as copying data from the system's memory to a graphics card. However, since OpenGL is designed according to the client-server pattern, data must be transferred from client memory to the server at any time when OpenGL needs data. If the data is not modified, or if the client and server are on different computers (distributed rendering), the data transfer may be slow or redundant.

OpenGL version 1.5 Adds a buffer object, which allows the application to specify which data to store in the graphics server.

The current version of OpenGL uses a number of different types of buffer objects:

1. Starting with OpenGL 1.5, the vertex data in the array can be stored in the server-side buffer object.

2. In OpenGL 2.1, support for storing pixel data (for example, texture map or block of pixels) in a buffer object is added.

3. OpenGL 3.1 adds unified buffered objects (uniform buffer object) to store a block of uniform variable data for shaders.

creating a Buffer object

Any non-zero unsigned integer can be used as the identifier for the buffer object. You can choose a representative value arbitrarily, or let OpenGL be responsible for assigning and managing these identifiers. The difference between the two approaches is that having OpenGL assign identifiers ensures that you avoid reusing the buffer object identifiers that have been used, thereby eliminating the risk of unintentionally modifying the data.

In order for OpenGL to allocate buffer object identifiers, the following functions can be called:

void Glgenbuffers (Glsizei n,gluint *buffers);

Returns the n currently unused buffer object identifier in the buffers array. Note the identity names returned in the buffers array do not need to be consecutive integers. 0 is a reserved buffer object name that is never returned by Glgenbuffers () as a buffer object identifier.

Call to determine whether an identifier is a buffer object identifier that is currently being used :

Glboolean Glisbuffer (gluint buffer);

If buffer is the name of a buffer object that has already been bound, and if it has not yet been deleted, returns GL_TRUE, otherwise returns GL_FALSE.

activating the Buffer object

In order to activate the buffer object you first need to bind it. The bind buffer object indicates which buffer object will be affected by the selection of future operations. If your application has more than one buffer object, you need to call the Glbindbuffer () function multiple times: once to initialize the buffer object and its data, and subsequent calls either select the buffer object for rendering or update the data for the buffer object.

To disable a buffer object, you can call the Glbindbuffer () function with 0 as the identifier for the buffer object. This will switch OpenGL to the default mode that does not use a buffer object.

void Glbindbuffer (glenum target,gluint buffer);

The current active buffer object is specified. The parameter target must be set to Gl_array_buffer, Gl_element_array_buffer, Gl_pixel_pack_buffer, Gl_pixel_unpack_buffer, GL_COPY_READ_ BUFFER, Gl_copy_write_buffer, Gl_transform_feedback_buffer, or Gl_uniform_buffer. The parameter buffer specifies the buffer object that will be bound.

Glbindbuffer () completes one of 3 tasks:

1. When buffer is a non-0 unsigned integer that is first used, it creates a new buffer object and assigns buffer to the buffer object as its name

2. When binding to a previously created buffer object, the buffer object becomes the active buffer object

3. OpenGL stops using the buffer object when it is bound to a buffer with a value of zero

allocating and initializing buffer objects with data

Once a buffer object is bound, it is necessary to reserve space to store the data.

void Glbufferdata (Glenum target,glsizeiptr size,const glvoid *data,glenum usage);

An OpenGL server memory that allocates size storage units (typically bytes) for storing vertex data or indexes. All data previously associated with the current bound object will be deleted.

The parameter target must be Gl_array_buffer (representing vertex data), Gl_element_array_buffer (representing the index data), Gl_pixel_pack_buffer (representing the data passed to OpenGL pixels), Gl_ Pixel_unpack_buffer (represents the pixel data obtained from OpenGL), Gl_copy_read_buffer, and gl_copy_write_buffer (which means copying data between buffers), Gl_texture_buffer (represents texture data stored as a texture buffer), gl_transform_feedback_buffer (representing the result of performing a transform feedback shader), or Gl_uniform_buffer (representing a uniform variable value).

The parameter size is the amount of memory required to store the related data. This value is usually the number of data elements multiplied by their respective storage lengths.

The parameter data is a pointer to the client memory (used to initialize the buffer object), or it can be null. If it passes a valid pointer, the storage space for a size unit is copied from the client to the server. If NULL is passed, the function preserves the storage space for a size unit for later use, but does not initialize it.

The parameter usage provides a hint as to how the data will be read and written after it is allocated. Valid values include Gl_stream_draw (stream mode), Gl_stream_read (stream mode), Gl_stream_copy (stream mode), Gl_static_draw (static mode), Gl_static_read (static mode), GL _static_copy (static mode), Gl_dynamic_draw (dynamic mode), Gl_dynamic_read (dynamic mode), Gl_dynamic_copy (dynamic mode).

Stream mode: Data in a buffer object often needs to be updated, but it is used less frequently in drawings or other operations

Static mode: The data for the buffer object is specified only 1 times, but the data is used very frequently

Dynamic mode: The data of a buffer object is not only often updated, but also used very frequently

Note that if the requested amount of memory exceeds the memory that the server can allocate, Glbufferdata () will return a gl_out_of_memory error. Returns Gl_invalid_value if usage is not one of the allowed values.

updating the data of a buffer object

There are two ways to update the data stored in the buffer object.

Method One, replace some data subsets of the bound buffer object with the supplied data

void Glbuffersubdata (Glenum target,glintptr ofsset,glsizeiptr size,const glvoid *data);

Updates the size byte data from offset (in bytes) in the current bound buffer object associated with the target with data pointing to the database. The target parameter is consistent with the target parameter of the Glbufferdata.

Note that if size is less than 0 or size+offset is greater than the size specified when the buffer object is created, Glbuffersubdata () produces a gl_invalid_value error.

Method Two, select the bound buffer object, and then write the new value as needed (or simply read the data, depending on the access rights of the memory), as if the array is assigned a value

Glvoid * Glmapbuffer (glenum target,glenum access);

Returns a pointer to the data store of the current bound buffer object associated with target. The target parameter is consistent with the target parameter of the Glbufferdata. Parameter access must be one of gl_read_only, gl_write_only, or gl_read_write to represent what the customer can do with the data.

Note that this is useful if you need to modify most of the data in the buffer, but it is inefficient if there is a large buffer and only a small portion of the value needs to be updated. The use of Glmapbufferrange () is now more efficient. It allows you to modify only the data values within the range you want.

Glvoid * Glmapbufferrange (glenum target,glintptr offset,glsizeiptr length,glbitfield access);

After the data update of the buffer object is completed, you can call Glunmapbuffer () to cancel the mapping of this buffer:

Glboolean Glunmapbuffer (glenum target);

Indicates that an update to the current bound buffer object has completed and that the buffer can be disposed.

copying data between buffer objects

How to copy data one buffer object to another buffer object.

In previous versions of OpenGL 3.1, this process was in two steps:

1. Copy the data from the buffer object into the application's memory.

2. Bind to the new buffer object, and then update the data for the buffer object.

In OpenGL 3.1, Glcopybuffersubdata () is used to replicate data without forcing the data to stay in the application's memory for a short time.

void Glcopybuffersubdata (Glenum readbuffer,glenum writebuffer,glintptr readoffset,glintptr writeoffset,GLsizeiptr size);

Copies data from a buffer object associated with Readbuffer to a buffer object bound to WriteBuffer. The parameters Readbuffer and WriteBuffer are identical to the target parameters of the Glbufferdata. Readoffset, Writeoffset is the offset, and size is the amount copied to the data.

Clear Buffer Object

After you have finished manipulating the buffer object, you can free its resources and make its identity available to other buffer objects.

void Gldeletebuffers (Glsizei n,const gluint *buffers);

Deletes n buffer objects whose identity name is the element of the buffers array.

Note that if you attempt to delete a nonexistent buffer object or a buffer object that is identified as 0, the operation is ignored and no error is generated.

Example: Use a Buffer object to store vertex array data and draw

#define Buffer_offset (bytes) ((Glubyte *) null+ (bytes))

Gluint buffers[2];

Glfloat vertices[][3]={//contains vertex data

{-1.0,-1.0,-1.0},

{1.0,-1.0,-1.0},

{1.0, 1.0,-1.0},

{-1.0, 1.0,-1.0},

{-1.0,-1.0, 1.0},

{1.0,-1.0, 1.0},

{1.0, 1.0, 1.0},

{-1.0, 1.0, 1.0}

};

Glbyte indices[][4]={//INCLUDE index data

{0,1,2,3},

{4,7,6,5},

{0,4,5,1},

{3,2,6,7},

{0,3,7,4},

{1,5,6,2}

};

Glgenbuffers (2,buffers); Generate Buffer Object identifiers

Glbindbuffer (Gl_array_buffer,buffers[0]); Binding Vertex Buffer objects

Glbufferdata (gl_array_buffer,sizeof (vertices), vertices,gl_static_draw); Requests the storage space of the data and initializes it with the specified data

Glbindbuffer (Gl_element_array_buffer,buffers[1]); Binding an index Buffer object

Glbufferdata (gl_element_array_buffer,sizeof (indices), indices,gl_static_draw);

Glenableclientstate (Gl_vertex_array); Enable array of vertices

Glvertexpointer (3,gl_float,0,buffer_offset (0)); specifying vertex array data

Gldrawelements (Gl_quads,24,gl_unsigned_byte,buffer_offset (0)); Drawing based on index (note: Vertex data and indexes each use different buffer zones)

If the buffer object is not used, the above code snippet

Glvertexpointer (3,gl_float,0,buffer_offset (0));

Gldrawelements (Gl_quads,24,gl_unsigned_byte,buffer_offset (0));

It should be written like this.

Glvertexpointer (3,gl_float,0, vertices);

Gldrawelements (gl_quads,24, indices);

After using the buffer object, like the Glvertexpointer (), this OpenGL function with a pointer parameter no longer takes data from the pointer position, the function converts the pointer to an integer, assuming that the converted result is k, the data is taken from the first K bytes of the current buffer ( When NULL is converted to an integer, it is usually 0, which is where the buffer begins.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.