Write in front
From this point on, there are a lot of basic concepts that I have read many times over and over again to understand the meaning and the relationship between them.
Concept
Vertex Array object: VAO
Vertex Buffer object: VBO
Index Buffer object: ebo| IBO
OpenGL is a 3D space, and the screen and window are 2D, so most of OpenGL's work is to convert the coordinates to 2D pixels
The process of conversion is managed by a graphical rendering pipeline.
The image rendering pipeline is divided into two parts: 1. Convert 3D coordinates to 2D coordinates. 2. Turn 2D coordinates into colored pixels
Several stages of rendering:
Test and blend, fragment shader----vertex shader, geometry shader
Each stage of the rendering has its own program, which is written using the OpenGL shader language, which is called a shader (shader)
Vertex shader: Converts 3D coordinates to another 3d coordinate, while some basic processing of vertex properties
Entity assembly: Assemble all points into a specified entity shape
Geometry shader: Create a shape by generating new points and new elements
Rasterization: Maps an element to the corresponding pixel on the final screen, generates a fragment used by the fragment shader, and cuts the lift beyond the view's pixels
Fragment shader: Calculates the final color of a pixel
Test and Blend: detects the depth value of the fragment to determine whether the pixel is in front of or behind other objects and decides if it is discarded
Code creation
First, we declare the following shader source code to be used.
With these concepts, we know that shaders are small programs that run on the image rendering pipeline, and the code style is similar to the C language
1 //vertex shader Source code2 Const Char*vertexshadersource =3 "#version core\n"4 "Layout (location = 0) in VEC3 apos;\n"5 "void Main () {\ n"6 "gl_position = VEC4 (apos.x, Apos.y, Apos.z, 1.0f); \ n"7 "}\n\0";8 9 //fragment shader source codeTen Const Char*fragmentshadersource = One "#version core\n" A "Out vec4 fragcolor;\n" - "void Main () {\ n" - "Fragcolor = VEC4 (1.0f, 0.5f, 0.2f, 1.0f); \ n" the "}\n\0";
Below we use the above two shaders to build a rendering pipeline that can render
//creating a vertex shader intVertexShader =Glcreateshader (Gl_vertex_shader); //The first parameter shader object, the second argument passes the source string, and the third parameter is the source of the vertex shaderGlshadersource (VertexShader,1, &Vertexshadersource, NULL); Glcompileshader (vertexshader); //determine if the compilation was successful intsucess; Charinfolog[ +]; Glgetshaderiv (VertexShader, Gl_compile_status,&sucess); if(!sucess) {Glgetshaderinfolog (vertexshader, +, NULL, InfoLog); Std::cout<<"error::shader::vertex::compilation_failed\n"<< InfoLog << Std::endl; }
// fragment shader, create and compile int fragmentshader = Glcreateshader (Gl_fragment_shader); Glshadersource (Fragmentshader, 1 , & Fragmentshadersource, NULL); Glcompileshader (Fragmentshader); Glgetshaderiv (Fragmentshader, Gl_compile_status, & sucess); if (! 512 << " error::shader:: fragment::compilation_failed\n " << infolog<<STD::ENDL; }
Two shaders are created, and after compilation, connections are required
//link two shader objects to a shader program for rendering//Creating a shader program intShaderprogram =Glcreateprogram (); //linksGlattachshader (Shaderprogram, vertexshader); Glattachshader (Shaderprogram, Fragmentshader); Gllinkprogram (Shaderprogram); Glgetshaderiv (Shaderprogram, Gl_compile_status,&sucess); if(!sucess) {Glgetshaderinfolog (Shaderprogram, +, NULL, InfoLog); Std::cout<<"error::shader::P rogram::compilation_failed\n"<< infolog<<Std::endl; }
Linking two shaders to the shader program we just created, and compiled, this time, the two shaders above us are already in Shaderprogram.
1 // 2gldeleteshader (vertexshader); 3 Gldeleteshader (Fragmentshader);
We know that there are several stages of rendering, so now we just need to create the vertex data and then render it using the shader program above
1 // define three vertices 2 float vertices[] = {3 -0.5f,-0.5f0.0f, 4 0.5f,-0.5f0.0f,5 0.0f, 0.5f 0.0f6 };
For vertex management, we use vertex-buffered objects and vertex array objects for management. The basic concept has been explained at the beginning of the article
// Caching using vertex buffer objects int VBO, VAO; Glgenvertexarrays (1, &VAO); Glgenbuffers (1, &VBO); // buffering objects for binding Glbindvertexarray (VAO); Glbindbuffer (Gl_array_buffer, VBO);
Use of Buffered objects
1 //Copy the defined vertex data into buffered memory2 //The first parameter, the buffer type, the second parameter data size, the third parameter sends the data, the fourth parameter, the graphics card how to manage the given data3Glbufferdata (Gl_array_buffer,sizeof(vertices), vertices, gl_static_draw);4 5 //parsing vertex Data6Glvertexattribpointer (0,3, Gl_float, Gl_false,3*sizeof(float), (void*)0);7 //Start vertex data8Glenablevertexattribarray (0);9 TenGlbindbuffer (Gl_array_buffer,0); OneGlbindvertexarray (0); A -Gldrawarrays (Gl_triangles,0,3);
Now our vertex array object is already in memory.
The following is a call to the shader program to start
1 //Enable Triangles2Glclearcolor (0.2f,0.3f,0.3f,1.0f);3 glclear (gl_color_buffer_bit);4 //Activating the program5 Gluseprogram (shaderprogram);6 Glbindvertexarray (VAO);7Gldrawarrays (Gl_triangles,0,3);8Glfwswapbuffers (window);
Finally, don't forget to understand the Vao and Vbo objects we use
// Clear Objects Gldeletevertexarrays (1, &VAO); Gldeletebuffers (1, &VBO);
Summarize
Through the above process, it should be possible to run up a triangle. OpenGL Road Long, we continue to refuel