ArticleDirectory
- Ii. API Introduction
- 5. Running Effect
[OpenGL ES 06] Using VBO: vertex Cache
Luo chaohui (http://www.cnblogs.com/kesalin)
This article follows the "signature-non-commercial use-consistency" creation public agreement
This is the sixth article in OpenGL ES tutorial. For the first five articles, see the following link:
[OpenGL ES 01] early experience of OpenGL ES on iOS
[OpenGL ES 02] OpenGL ES rendering pipeline and shader
[OpenGL ES 03] 3D Transformation: model, view, projection, and viewport
[OpenGL ES 04] 3D Transformation Practices: translation, rotation, scaling
[OpenGL ES 05] relative space transformation and color
I. Introduction to VBO
In the previous examplesCodeThe vertex data is directly transferred from the master memory of the CPU to the GPU for calculation and rendering.
Glvertexattrib4f(_ Colorslot, color [0], color [1], color [2], color [3]);Glvertexattribpointer(_ Positionslot, 3, gl_float, gl_false, 0, vertices );Glenablevertexattribarray(_ Positionslot );Gldrawelements(Gl_lines, sizeof (indices)/sizeof (glubyte), gl_unsigned_byte, indices );
In the above Code, both vertices and indices are allocated memory space in the primary storage. When rendering is required, the data is copied from the master memory of the CPU to the GPU for calculation and rendering through gldrawelements or gldrawarrays. This method requires frequent data transfer between the CPU and GPU, Which is inefficient. Therefore, VBO (vertex buffer object), that is, vertex cache, appears, it directly opens a cache area in the GPU to store vertex data. Because it is used to store vertex data, it is called vertex cache. We only need to write the buffer when initializing the buffer and when the vertex data changes. Using the vertex cache can significantly reduce the overhead of Data Copying between CPU-GPU, thus significantly improvingProgramEfficiency.
Today, we will be able to learn how to use VBO in OpenGL ES. The example program demonstrates six programming implementation objects. The source code of this article is as follows:
Ii. API Introduction
1. Overview
In OpenGL ES, the following functions are used to implement VBO:
Vertex cache object API
| Glgenbuffers |
Create vertex cache object |
| Glbindbuffer |
Sets the vertex cache object to the current array cache object (Array Buffer object) or the current element buffer object) |
| Glbufferdata |
Apply for memory space for vertex cache objects and initialize them (depending on the input parameters) |
| Glbuffersubdata |
Initialize or update vertex cache objects |
| Gldeletebuffers |
Delete vertex cache objects |
2. Create a vertex cache object
Void glgenbuffers (glsizei N, gluint * buffers );
Parameter N: Number of vertex cache objects to be created;
Buffers: used to store the processed vertex cache object;
The same as the render buffer object handle in the first article [OpenGL ES 01] OpenGL ES first experience ". Here, the vertex cache object handle is always a positive integer greater than 0, 0 is reserved by OpenGL ES. This function can generate multiple vertex cache objects at a time.
3. Set the vertex cache object to (or bound to) the current array cache object or element cache object.
Void glbindbuffer (glenum target, gluint buffer );
Target: Specify the bound target. The value is gl_array_buffer (used for vertex data) or gl_element_array_buffer (used to index data );
Parameter Buffer: vertex cache object handle;
4. Allocate space for vertex cache objects
Void glbufferdata (glenum target, glsizeiptr size, const glvoid * data, glenum usage );
Target: Same as the target parameter in glbindbuffer;
Parameter size: Specifies the size of the vertex cache area, measured in bytes;
Data: used to initialize the data in the vertex cache. The value can be null, indicating that only space is allocated and then initialized by glbuffersubdata;
Usage: indicates how the cache area will be used. The main purpose of usage is to prompt OpenGL to optimize the cache area. The parameters are one of the following:
Gl_static_draw: indicates that the cache is not modified;
Gl_dynamic_draw: indicates that the cache area will be changed periodically;
Gl_stream_draw: indicates that the cache area is frequently changed;
If vertex data is not modified once initialized, use gl_static_draw whenever possible to achieve better performance.
5. Update vertex buffer data
Void glbuffersubdata (glenum target, glintptr offset, glsizeiptr size, const glvoid * data );
Parameter: Offset indicates the starting offset of the data to be updated;
Parameter: size indicates the number of data to be updated, also measured in bytes;
Data: The data to be updated;
6. Release vertex Cache
Void gldeletebuffers (glsizei N, const gluint * buffers );
Similar to glgenbuffers, this function is used to delete vertex cache objects and release vertex cache.
3. Versatile: glvertexattribpointer and gldrawelements
Before introducing how to use VBO for rendering, let's review the functions used for rendering using Vertex Arrays:
Void glvertexattribpointer (gluint index, glint size, glenum type, glboolean normalized, glsizei stride, const glvoid * PTR );
Index: the slot position of vertex data (such as vertex, color, normal, texture, or vertex sprite size) in the shader program;
Parameter size: specify the size of each data type. For example, the vertex consists of three parts: X, Y, and Z, and the texture consists of U and V;
Parameter type: indicates the data format of each component;
The normalized parameter indicates whether to normalize the normal value to the unit length when the data is normal. You can set other vertex data to gl_false. If the normal vector is set to gl_false in unit length, unnecessary computation can be avoided to improve efficiency;
Stride: The interval between the previous data and the next data (also in bytes ), based on this interval, OpenGL ES can skip to read the corresponding vertex data from a data block composed of multiple vertex data;
PTR: It is worth noting that this parameter is a versatile operator. If VBO is not used, it points to the vertex data array in the CPU memory. If VBO is bound to gl_array_buffer, it indicates the starting offset of this type of vertex data in the vertex cache.
What about the index data represented by gl_element_array_buffer? This is used by the following functions:
Void gldrawelements (glenum mode, glsizei count, glenum type, const glvoid * indices );
The mode parameter indicates the type of the depicted elements, such as gl_triangles, gl_lines, and gl_points;
The Count parameter indicates the number of index data;
Parameter type: the format of the index data, which must be an unsigned integer value;
Indices: this parameter is also a versatile parameter. If VBO is not used, it points to the index data array in the CPU memory. If VBO is used to bind to gl_element_array_buffer, it indicates the offset of the index data in VBO.
4. Example
In today's example, I borrowed some code from the iPhone 3D programming to create the vertex and index of a three-dimensional object, this section is omitted here. If you are interested in the study, you can view the source code. Here we will only talk about part of the Code related to the vertex cache.
First, create a vertex cache object, allocate space, and initialize it:
// Create the vbo for the vertice. // gluint vertexbuffer; glgenbuffers (1, & vertexbuffer); buffers (gl_array_buffer, vertexbuffer); glbufferdata (gl_array_buffer, vbufsize * sizeof (glfloat), vbuf, callback ); // create the VBO for the line indice // gluint lineindexbuffer; glgenbuffers (1, & lineindexbuffer); buffers (buffers, lineindexbuffer); glbufferdata (buffers, lineindexcount * sizeof (glushort ), linebuf, callback); // create the VBO for the triangle indice // gluint triangleindexbuffer; glgenbuffers (1, & triangleindexbuffer); glbindbuffer (callback, triangleindexbuffer); glbufferdata (callback, triangleindexcount * sizeof (glushort), trianglebuf, gl_static_draw );
Then, use VBO for rendering:
-(Void) drawsurface {If (_ currentvbo = nil) return; glbindbuffer (gl_array_buffer, [_ currentvbo vertexbuffer]); terminate (_ positionslot, 3, gl_float, gl_false, [_ currentvbo vertexsize] * sizeof (glfloat), 0); glablevertexattribarray (_ positionslot); // draw the red triangles. // glvertexattrib4f (_ colorslot, 1.0, 0.0, 0.0, 1.0); reverse (partial, [_ currentvbo triangleindexbuffer]); gldrawelements (gl_triangles, [_ currentvbo triangleindexcount], partial, 0); // draw the black lines. // glvertexattrib4f (_ colorslot, 0.0, 0.0, 0.0, 1.0); glbindbuffer (latency, [_ currentvbo lineindexbuffer]); gldrawelements (gl_lines, [_ currentvbo lineindexcount], latency, 0); gldisablevertexattribarray (_ positionslot );}
Since this example can depict six three-dimensional geometric objects, _ currentvbo indicates the currently depicted geometric object, which is a drawablevbo object. The drawablevbo class declaration is as follows:
@ Interface drawablevbo: nsobject @ property (nonatomic, assign) gluint vertexbuffer; @ property (nonatomic, assign) gluint lineindexbuffer; @ property (nonatomic, assign) gluint triangleindexbuffer; @ Property, assign) int vertexsize; @ property (nonatomic, assign) int lineindexcount; @ property (nonatomic, assign) int triangleindexcount;-(void) cleanup; @ end
It contains a vertex cache object for vertex data vertexbuffer and two vertex cache objects for index data lineindexbuffer and triangleindexbuffer. These objects are generated through the Code part of the previously created vertex cache object. Vertexsize indicates the vertex data size, while lineindexcount and triangleindexcount indicate the number of index data. Cleanup is used to clear vertex cache objects. Its implementation is as follows:
-(Void) Cleanup {If (vertexbuffer! = 0) {gldeletebuffers (1, & vertexbuffer); vertexbuffer = 0;} If (lineindexbuffer! = 0) {gldeletebuffers (1, & lineindexbuffer); lineindexbuffer = 0;} If (triangleindexbuffer) {gldeletebuffers (1, & triangleindexbuffer); triangleindexbuffer = 0 ;}}
5. Running Effect
This example demonstrates programmable ry objects of different shapes in 6 and uses Quaternion to respond to the rotation Operation formed by finger sliding. Example running effect:
6. Exercise homework
In this example, vertex data and index data are generated by programming. What should I do if I want to use VBO with existing vertex data and index data? The following providesCubeYou can modify the vertex data and index data of the cube to see if you can modify it. In this example, the seventh ry will be added. This job will leave you alone.
// Cube vertex data and index data const glfloat vertices [] = {-1.5f,-1.5f, 1.5f,-0.577350,-0.577350, 0.577350,-1.5f, 1.5f, 1.5f, -0.577350, 0.577350, 0.577350, 1.5f, 1.5f, 1.5f, 0.577350, 0.577350, 0.577350, 1.5f,-1.5f, 1.5f, 0.577350,-0.577350, 0.577350, 1.5f,-1.5f, -1.5f, 0.577350,-0.577350,-0.577350, 1.5f, 1.5f,-1.5f, 0.577350, 0.577350,-0.577350,-1.5f, 1.5f,-1.5f,-0.577350, 0.577350, -0.577350,-1.5f,-1.5f,-1.5f,-0.577350,-0.577350,-0.577350}; const glushort indices [] = {// front face 3, 2, 1, 3, 1, 0, // back face 7, 5, 4, 7, 6, 5, // left face 0, 1, 7, 7, 1, 6, // right face 3, 4, 5, 3, 5, 2, // up face 1, 2, 5, 1, 5, 6, // down face 0, 7, 3, 3, 7, 4 };