Why glBegin is not defined & undefined identifier using new API (LearnOpenGL P2)

Article directory

    • Deprecated glBegin & amp; glEnd
    • Examples of using the new API

Deprecated glBegin & amp; glEnd

Environment: glfw 3.3.8 + glad core

When OpenGL beginners try to use the glBegin and glEnd functions to draw triangles, they may find articles and code documents that use these functions.

But many of these functions have been deprecated in the core OpenGL specification

New API should be used to draw graphics

  • Vertex Buffer Objects: Vertex Buffer Objects, VBOs
  • Vertex Array Objects: Vertex Array Objects, VAOs
glBegin(GL_TRIANGLES);
glColor3f(1.0f, 0.0f, 0.0f); //Set the color to red
glVertex2f(-0.6f, -0.4f); // Vertex 1
glColor3f(0.0f, 1.0f, 0.0f); //Set the color to green
glVertex2f(0.6f, -0.4f); // Vertex 2
glColor3f(0.0f, 0.0f, 1.0f); //Set the color to blue
glVertex2f(0.0f, 0.6f); // Vertex 3
glEnd();

Examples of using the new API

#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>

// window size
const int WINDOW_WIDTH = 800;
const int WINDOW_HEIGHT = 600;

//Vertex shader source code
const char* vertexShaderSource = R"(
    #version 330 core
    layout (location = 0) in vec3 aPos;
    uniform float rotation;

    mat3 getRotationMatrix(float angle) {
        float s = sin(angle);
        float c = cos(angle);
        return mat3(
            c, -s, 0.0,
            s, c, 0.0,
            0.0, 0.0, 1.0
        );
    }

    void main()
    {
        mat3 rotationMatrix = getRotationMatrix(rotation);
        gl_Position = vec4(rotationMatrix * aPos, 1.0);
    }
)";

// Fragment shader source code
const char* fragmentShaderSource = R"(
    #version 330 core
    out vec4 FragColor;
    uniform float time;
    void main()
    {
        float red = sin(time);
        float green = cos(time);
        float blue = 0.5 + 0.5 * sin(2.0 * time);

        FragColor = vec4(red, green, blue, 1.0);
    }
)";

int main() {<!-- -->
    //Initialize GLFW
    if (!glfwInit()) {<!-- -->
        std::cout << "GLFW initialization failed" << std::endl;
        return -1;
    }

    // Configure GLFW
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    //Create window object
    GLFWwindow* window = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "Triangle", nullptr, nullptr);
    if (window == nullptr) {<!-- -->
        std::cout << "Failed to create GLFW window" << std::endl;
        glfwTerminate();
        return -1;
    }

    //Set the window's context to the main context of the current thread
    glfwMakeContextCurrent(window);

    //Initialize GLAD
    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {<!-- -->
        std::cout << "Failed to initialize GLAD" << std::endl;
        return -1;
    }

    //Create a vertex shader object
    unsigned int vertexShader;
    vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, & amp;vertexShaderSource, nullptr);
    glCompileShader(vertexShader);

    // Check whether the vertex shader was compiled successfully
    int success;
    char infoLog[512];
    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, & amp;success);
    if (!success) {<!-- -->
        glGetShaderInfoLog(vertexShader, 512, nullptr, infoLog);
        std::cout << "Failed to compile vertex shader:\
" << infoLog << std::endl;
        return -1;
    }

    // Create fragment shader object
    unsigned int fragmentShader;
    fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, & amp;fragmentShaderSource, nullptr);
    glCompileShader(fragmentShader);

    // Check whether the fragment shader compiled successfully
    glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, & amp;success);
    if (!success) {<!-- -->
        glGetShaderInfoLog(fragmentShader, 512, nullptr, infoLog);
        std::cout << "Failed to compile fragment shader:\
" << infoLog << std::endl;
        return -1;
    }

    // Create shader program object
    unsigned int shaderProgram;
    shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);

    // Check whether the shader program is linked successfully
    glGetProgramiv(shaderProgram, GL_LINK_STATUS, & amp;success);
    if (!success) {<!-- -->
        glGetProgramInfoLog(shaderProgram, 512, nullptr, infoLog);
        std::cout << "Failed to link shader program:\
" << infoLog << std::endl;
        return -1;
    }

    //Delete shader object
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);

    //Set vertex data
    float vertices[] = {<!-- -->
        -0.5f, -0.5f, 0.0f,
        0.5f, -0.5f, 0.0f,
        0.0f, 0.5f, 0.0f,
        0.0f, 0.0f, 0.0f //Origin coordinates
    };

    //Create a vertex buffer object (VBO) and a vertex array object (VAO)
    unsigned int VBO, VAO;
    glGenVertexArrays(1, & amp;VAO);
    glGenBuffers(1, & amp;VBO);

    // Bind VAO and VBO
    glBindVertexArray(VAO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    //Set the vertex attribute pointer
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);

    // Unbind VAO and VBO
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);

    // Rendering loop
    while (!glfwWindowShouldClose(window)) {<!-- -->
        // Handle input events
        glfwPollEvents();

        // Clear the color buffer
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        //Use shader program
        glUseProgram(shaderProgram);

        // Get the current time
        float time = glfwGetTime();
        float rotation = time;
        int rotationLocation = glGetUniformLocation(shaderProgram, "rotation");
        glUniform1f(rotationLocation, rotation);
        
        int timeLoadtion = glGetUniformLocation(shaderProgram, "time");
        glUniform1f(timeLoadtion, time);

        // Bind VAO
        glBindVertexArray(VAO);
        glDrawArrays(GL_POINTS, 3, 1); // Draw a point starting from index 3

        // draw triangle
        glDrawArrays(GL_TRIANGLES, 0, 3);

        // Unbind VAO
        glBindVertexArray(0);

        // swap buffers
        glfwSwapBuffers(window);
    }

    // Delete VAO and VBO
    glDeleteVertexArrays(1, & amp;VAO);
    glDeleteBuffers(1, & amp;VBO);

    // Terminate GLFW
    glfwTerminate();

    return 0;
}