Read "Computer Graphics Programming (Using OpenGL and C++)" 2 - Drawing Dots

OpenGL can draw points, lines, and triangles. These simple things are called primitives. Most 3D models are usually composed of many triangular primitives. Primitives are composed of vertices. Vertices can be read from a file and loaded into a buffer by a C++/OpenGL application or hardcoded strings directly in a C++ file or directly in GLSL code. Before loading vertices, a C++/OpenGL application must compile and link the appropriate GLSL vertex shader and fragment shader programs, and then load them into the pipeline.

The C++/OpenGL application is also responsible for notifying OpenGL to construct the triangle. By calling the function glDrawArrays(), the GLSL code in the pipeline starts executing. All vertices are passed to the vertex shader. Shaders are executed once for each vertex, and these executions are usually performed in parallel.

glDrawArrays (GLenum mode, GLint first, GLsizei count);

The mode parameter is the type of primitive - for triangles use GL_TRIANGLES. The First parameter indicates which vertex to start drawing from (usually vertex 0, the first vertex), and count is the total number of vertices to be drawn.

Load the GLSL program into the shader
1. Use C++ to obtain the GLSL shader code and read it from a file or string
2. Create an OpenGL shader object and load the GLSL shader code into the shader object
3. Use OpenGL commands to compile and Connect the shader object and install it into the GPU

The default size of OpenGL midpoints is 1 pixel.

The code for a blue dot in the center of the window is as follows.

main.cpp

(The #include list is the same as before)
#define numVAOs 1

GLuint renderingProgram;
GLuint vao[numVAOs];

GLuint createShaderProgram()
{
    const char* vshaderSource = 
        "#version 460 \n"
        "void main(void) \n"
        "{ gl_Position = vec4(0.0, 0.0, 0.0, 1.0); }";

    const char* fshaderSource =
        "#version 460 \n"
        "out vec4 color; \n"
        "void main(void) \n"
        "{ color = vec4(0.0, 0.0, 1.0, 1.0); }";

    GLuint vShader = glCreateShader(GL_VERTEX_SHADER); // 创建类型 GL_VERTEX_SHADER 的着色器,返回引用它的序号
    GLuint fShader = glCreateShader(GL_FRAGMENT_SHADER); // 创建类型 GL_FRAGMENT_SHADER 的着色器,返回引用它的序号

    glShaderSource(vShader, 1, &vshaderSource, NULL); // 将GLSL代码从字符串载入空着色器对象中 
    glShaderSource(fShader, 1, &fshaderSource, NULL);
    glCompileShader(vShader); // 编译各着色器
    glCompileShader(fShader);

    GLuint vfProgram = glCreateProgram(); // 创建程序对象,并储存指向它的整数ID
    glAttachShader(vfProgram, vShader); // 将着色器加入程序对象
    glAttachShader(vfProgram, fShader);
    glLinkProgram(vfProgram); // 让GLSL编译器确保它们的兼容性

    return vfProgram;
}

void init(GLFWwindow* window){
    renderingProgram = createShaderProgram();
    glGenVertexArrays(numVAOs, vao);
    glBindVertexArray(vao[0]);
}

void display(GLFWwindow* window, double currentTime)
{
    glUseProgram(renderingProgram); // 将含有两个已编译着色器的程序载入OpenGL管线阶段(在GPU上),没有运行着色器,只是将着色器加载进硬件
    glDrawArrays(GL_POINTS, 0, 1); // 启动管线处理过程
}
(The main function is the same as before)

The string vshaderSource is a vertex hardcoded in the vertex shader. The main goal of the vertex shader is to send vertices to the pipeline. The built-in variable gl_Position is used to set the coordinate position of the vertex in 3D space and send it to the next pipeline stage. The GLSL data type vec4 is used to store 4-tuples.

The vertices next move along the pipeline to the raster shader, where they are converted into pixel positions. Eventually these pixels reach the fragment shader fshaderSource . The purpose of the fragment shader is to give RGB colors to the pixels that will be displayed. In this case it's blue. The "out" tag indicates that the color variable is an output variable. gl_Position is a predefined output variable in the vertex shader, so it is not necessary to specify an "out" tag for it.

When preparing to send the data set to the pipeline, it is sent in the form of buffers. These buffers will eventually be stored in vertex array objects (VAO). Even if the application does not use any buffers, OpenGL still needs There is at least one created VAO when using a shader, so the last two lines of init() are used to create the VAO required by OpenGL.

glShaderSource() has 4 parameters:

1. Shader object; 2. The number of strings in the shader source code; 3. A string pointer containing the source code; 4. Specify an array of length that contains the number of strings for each line of code in the given shader program. Integer length. If set to NULL, OpenGL will automatically build this array from NULL-terminated strings.

glShaderSource(GLuint shader, GLsizei count, const GLchar *const* string, const GLint* length);

The result is as follows:

 Add the following code to display() and place it before glDrawArrays()

glPointSize(30.0f);

When the rasterization stage receives a vertex from the vertex shader, it sets the pixel color value for a point of size 30 pixels.

The result is as follows:

Guess you like

Origin blog.csdn.net/ttod/article/details/135343075