1. The GPU is short for graphic processing unit ". GPU (graphics core chip) is the "brain" of the display card. It determines the level and performance of the video card.
Ii. Background
With the removal of OpenGL status and fixed pipeline mode, we do not use any glable function call, nor do we have function calls such as glvertex and glcolor. This means we need a new way to transfer data to the graphics card to render the image.
III,Vertex array object (VAO)
1. Background
Every time we draw a ry, we need to repeat the same work (first bind the buffer and then set the vertex attribute ). This process is time-consuming when many objects need to be drawn. Is there a way to simplify this process? This is what VAO does. It stores these settings in the process of drawing all vertices together with the binding process. When we need them, we only need to use the corresponding VAO.
This method of VAO is a bit like an intermediary. It puts all the tedious binding and vertex settings together for processing. When we need to plot it, just look for this intermediary.
2. Introduction
First, VAO is not a buffer-object, so it does not need to store data. Second, it is for "vertex", that is, it is closely related to "vertex painting" and has no relationship with the vertex array, VAO can be understood as a status container that records the status of VBO. With VAO, you can quickly access the VBO status and VBO data. VAO records the information required in a drawing. This includes "where is the data glbindbuffer", "what is the data format glvertexattribpointer", and "How is the shader-attribute location enabled glablevertexattribarray.
Note:
1> the core mode of OpenGL requires us to use VAO. If we fail to bind VAO, OpenGL in the core mode will refuse to draw anything;
2> considering the performance, the attribute variable of the vertex coloring tool is disabled by default. Therefore, the attribute data of the vertex is invisible in the vertex coloring tool, even if the data has been uploaded to the GPU. After you call glenablevertexattribarray, you can only access the attribute data of the vertex in the vertex coloring er. Calling glvertexattribpointer only establishes a logical connection between the CPU and the GPU, and uploads data from the CPU to the GPU. However, whether or not the vertex coloring er can read and use data is determined by calling the glenablevertexattribarray (allowing the vertex coloring er to read GPU (server-side) data.
After VAO is used, the GPU can directly find the status of the VBO recorded by the GPU and the corresponding VBO data during painting, which can be quickly drawn and avoids frequent data operations, thus improving performance.
3. The content stored in the VAO object includes
1. VAO enabled or disabled status (glenablevertexattribarray and gldisablevertexattribarray)
2. Use glvertexattribpointer to set vertex attributes
3. VBO object for storing vertex data
4. Use of VAO
1> Create VAO:glGenVertexArrays
2> bind and set VAO
After creating a VAO, you need to use glbindvertexarray to set it as the VAO of the current operation. Then we set the vertex data (including the VBO object used for data, vertex attribute settings are stored in VAO ). After the settings are complete, the VAO object is usually unbound, and the corresponding VAO object is enabled as needed.
Generate VAO
Bytes
Bind VAO
Bytes
Bind VBO handle (VBO data handle) (BIND vertex buffer object)
Bytes
Enable the corresponding attribute information in the shader. glenablevertexattribarray () uses the vertex attribute position value as the parameter to enable the vertex attribute. The vertex attribute is disabled by default. Therefore, you need to open these (CPU to GPU) communication ports.
Bytes
Specifies the data format and position of the vertex attribute array during rendering. Use the glvertexattribpointer function to specify
Bytes
Bind to the next VBO
Bytes
VAO save ended
The Code is as follows:
1 // create VAO 2 gluint VAO; 3 glgenvertexarrays (1, & VAO); 4 // set the current VAO and all subsequent operations (note: these operations must be called as stated in the above VAO content. Other non-VAO stored content will not affect VAO even if it is called) 5 glbindvertexarray (VAO); 6 Gbit/s (gl_array_buffer, VBO); // set VBO 7 glbufferdata (gl_array_buffer, sizeof (vertices), vertices, buffers ); // set the data in VBO to 8 glvertexattribpointer (0, 3, gl_float, gl_false, 3 * sizeof (glfloat), (glvoid *) 0 ); // set the vertex attribute (the attribute with an index of 0, which interacts with the content in the shader) 9. glenablevertexattribarray (0); // set the Enable vertex attribute (the attribute with an index of 0, interact with the content in the shader) 10 glbindvertexarray (0); // unbind VAO (unbind mainly to avoid affecting subsequent VAO settings, a bit similar to the null behind the delete pointer in C ++, is a good habit)
The above code completes the VAO settings. When we need to draw, the code used is similar:
1 gluseprogram (shaderprogram); 2 glbindvertexarray (VAO); // binding the VAO we need will automatically complete the settings saved by all VAO above. 3 someopenglfunctionthatdrawsourtriangle (); 4 glbindvertexarray (0); // unbind VAO
4. VBO (vertex buffer object) vertex buffer object
1. Introduction
VBO places vertex information in the GPU, And the GPU caches data during rendering. the bridge between the two is Gl-context. Generally, there is only one Gl-context program, so if there are two different drawing codes in a rendering process, GL-context is responsible for switching between them. This is why glbindbuffer, glablevertexattribarray, and glvertexattribpointer are included in each rendering code. The optimization method is to put all of these into initialization. VAO records all VBO information required for this drawing, saves it to a specific position of VAO, and draws information directly at this position.
2,Procedure of using VBO
Create VBO
Three steps are required to create a VBO:
- Use glgenbuffers () to generate a new cache object and return the identifier of the cached object. It requires two parameters: the first is the number of caches to be created, and the second is the address of the gluint variable or array used to store a single ID or multiple IDs.
1 void glGenBuffers(GLsizei n, GLuint* buffers)
- Use glbindbuffer () to bind a cache object. After a cache object is created, we need to connect the cached object to the corresponding cache before using the cached object. Glbindbuffer () has two parameters: Target and buffer.
void
glBindBuffer(GLenum target, GLuint buffer)
Target tells VBO whether the cached object will save the vertex array data or index array data: gl_array_buffer or gl_element_array. Gl_array_buffer is used for any vertex attributes, such as vertex coordinates, texture coordinates, normal and color component arrays. Use gl_element_array to bind the index data used for gldraw [range] elements. Note: The target flag helps VBO determine the most effective position of the cache object. For example, some systems save the index to the AGP or system memory and store the vertex in the graphics card memory.
When glbindbuffer () is called for the first time, VBO initializes the cache with a memory cache of 0 and sets the initial status of VBO, such as purpose and access attributes.
- Use glbufferdata () to copy vertex data to the cache object.
void
glBufferData(GLenum target,GLsizeiptr size,
const
Glvoid * data, glenum usage); the first target parameter can be gl_array_buffer or gl_element_array. Size indicates the number of bytes of data to be transferred. The third parameter is the source data array pointer. If data is null, VBO only reserves the memory space of the given data size. Another performance prompt of the last parameter usage flag VBO, which provides how the cache object will use static, dynamic or stream, and read, copy, or draw.
"Static" indicates that the data in the VBO will not be changed (used multiple times at a time), and "dynamic" indicates that the data will be frequently changed (specified and used repeatedly ). each rendering call remains unchanged, so its usage type is best gl_static_draw. If, for example, the data in a buffer is frequently changed, the type used is gl_dynamic_draw or gl_stream_draw. This ensures that the video card stores the data in the memory that can be written at a high speed.
5. EBO/Ibo (index buffer object)
1. Introduction
Like the vertex buffer object, EBO is also a buffer that stores indexes. OpenGL calls the indexes of These vertices to determine which vertex to draw. Used for indexing.
2. Procedure
Define an index array in addition to the vertex array and store the subscript of the vertex to be drawn.
Float vertices [] = {unsigned int indices [] = {// note that the index starts from 0!
0.5f, 0.5f, 0.0f, // 0, 1, 3 in the upper right corner, // The first triangle
0.5f,-0.5f, 0.0f, // bottom right corner 1, 2, 3 // second triangle
-0.5f,-0.5f, 0.0f, // lower left corner };
-0.5f, 0.5f, 0.0f // upper left corner
};
Bytes
Create an index buffer object
Unsigned int EBO;
Glgenbuffers (1, & EBO );
Bytes
Similar to VBO, we first bind EBO and then use glbufferdata to copy the index to the buffer. Similarly, like VBO, we will place these function calls between binding and unbinding function calls, but this time we define the buffer typeGl_element_array_buffer.
Glbindbuffer (gl_element_array_buffer, EBO );
Glbufferdata (gl_element_array_buffer, sizeof (indices), indices, gl_static_draw );
Bytes
Note thatGl_element_array_bufferAs a buffer target. The last thing to do is to use gldrawelements to replace the gldrawarrays function to specify the buffer rendering from the index. When using gldrawelements, we will use the indexes in the currently bound index buffer object for rendering.
Glbindbuffer (gl_element_array_buffer, EBO );
Gldrawelements (gl_triangles, 6, gl_unsigned_int, 0)
The gldrawelements function is bound from the currentGl_element_array_bufferObtain the index from the target EBO. This means that the corresponding EBO must be bound every time an object is rendered using an index. This process is cumbersome. However, VAO can also save the binding status of EBO. When VAO is bound, the EBO being bound will be saved as an element buffer object of VAO. When VAO is bound, EBO is automatically bound.
3. Example
The final initialization and drawing code now looks like this:
// ..: Initialization code ::..//
1. Bind the vertex array object
Glbindvertexarray (VAO );
// 2. copy our vertex array to a vertex buffer for OpenGL
Glbindbuffer (gl_array_buffer, VBO );
Glbufferdata (gl_array_buffer, sizeof (vertices), vertices, gl_static_draw );
// 3. copy our index array to an index buffer for OpenGL
Glbindbuffer (gl_element_array_buffer, EBO );
Glbufferdata (gl_element_array_buffer, sizeof (indices), indices, gl_static_draw );
// 4. Set the vertex property pointer
Glvertexattribpointer (0, 3, gl_float, gl_false, 3 * sizeof (float), (void *) 0 );
Glenablevertexattribarray (0 );
[...]
//...: Draw the code (in the rendering loop )::..
Gluseprogram (shaderprogram );
Glbindvertexarray (VAO );
Gldrawelements (gl_triangles, 6, gl_unsigned_int, 0 );
Glbindvertexarray (0); // This line of code usually does not need to be placed in a rendering loop, because it is not necessary to bind and unbind each loop. This is only for normalization, so this line of code is added.
Create and use common OpenGL objects