1

I installed GLWF succesfully. I can prove that since this program compiles:

#include <GLFW/glfw3.h>

int main(void)
{
    GLFWwindow* window;

    /* Initialize the library */
    if (!glfwInit())
        return -1;

    /* Create a windowed mode window and its OpenGL context */
    window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
    if (!window)
    {
        glfwTerminate();
        return -1;
    }

    /* Make the window's context current */
    glfwMakeContextCurrent(window);

    /* Loop until the user closes the window */
    while (!glfwWindowShouldClose(window))
    {
        /* Render here */
        glClear(GL_COLOR_BUFFER_BIT);

        /* Swap front and back buffers */
        glfwSwapBuffers(window);

        /* Poll for and process events */
        glfwPollEvents();
    }

    glfwTerminate();
    return 0;
}

Then i used these commands in order to install glad:

git clone https://github.com/Dav1dde/glad.git
cd glad
cmake ./
make
sudo cp -a include /usr/local/

When i tried to execute this program:

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

#include <iostream>

void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow *window);

// settings
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;

const char *vertexShaderSource = "#version 330 core\n"
    "layout (location = 0) in vec3 aPos;\n"
    "void main()\n"
    "{\n"
    "   gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
    "}\0";
const char *fragmentShaderSource = "#version 330 core\n"
    "out vec4 FragColor;\n"
    "void main()\n"
    "{\n"
    "   FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
    "}\n\0";

int main()
{
    // glfw: initialize and configure
    // ------------------------------
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

#ifdef __APPLE__
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif

    // glfw window creation
    // --------------------
    GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);
    if (window == NULL)
    {
        std::cout << "Failed to create GLFW window" << std::endl;
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);
    glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);

    // glad: load all OpenGL function pointers
    // ---------------------------------------
    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
    {
        std::cout << "Failed to initialize GLAD" << std::endl;
        return -1;
    }


    // build and compile our shader program
    // ------------------------------------
    // vertex shader
    unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
    glCompileShader(vertexShader);
    // check for shader compile errors
    int success;
    char infoLog[512];
    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
    if (!success)
    {
        glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
        std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
    }
    // fragment shader
    unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
    glCompileShader(fragmentShader);
    // check for shader compile errors
    glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
    if (!success)
    {
        glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
        std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
    }
    // link shaders
    unsigned int shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);
    // check for linking errors
    glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
    if (!success) {
        glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
        std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;
    }
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);

    // set up vertex data (and buffer(s)) and configure vertex attributes
    // ------------------------------------------------------------------
    float vertices[] = {
         0.5f,  0.5f, 0.0f,  // top right
         0.5f, -0.5f, 0.0f,  // bottom right
        -0.5f, -0.5f, 0.0f,  // bottom left
        -0.5f,  0.5f, 0.0f   // top left 
    };
    unsigned int indices[] = {  // note that we start from 0!
        0, 1, 3,  // first Triangle
        1, 2, 3   // second Triangle
    };
    unsigned int VBO, VAO, EBO;
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
    glGenBuffers(1, &EBO);
    // bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s).
    glBindVertexArray(VAO);

    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);

    // note that this is allowed, the call to glVertexAttribPointer registered VBO as the vertex attribute's bound vertex buffer object so afterwards we can safely unbind
    glBindBuffer(GL_ARRAY_BUFFER, 0); 

    // remember: do NOT unbind the EBO while a VAO is active as the bound element buffer object IS stored in the VAO; keep the EBO bound.
    //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

    // You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this rarely happens. Modifying other
    // VAOs requires a call to glBindVertexArray anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary.
    glBindVertexArray(0); 


    // uncomment this call to draw in wireframe polygons.
    //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

    // render loop
    // -----------
    while (!glfwWindowShouldClose(window))
    {
        // input
        // -----
        processInput(window);

        // render
        // ------
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        // draw our first triangle
        glUseProgram(shaderProgram);
        glBindVertexArray(VAO); // seeing as we only have a single VAO there's no need to bind it every time, but we'll do so to keep things a bit more organized
        //glDrawArrays(GL_TRIANGLES, 0, 6);
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
        // glBindVertexArray(0); // no need to unbind it every time 
 
        // glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
        // -------------------------------------------------------------------------------
        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    // optional: de-allocate all resources once they've outlived their purpose:
    // ------------------------------------------------------------------------
    glDeleteVertexArrays(1, &VAO);
    glDeleteBuffers(1, &VBO);
    glDeleteBuffers(1, &EBO);
    glDeleteProgram(shaderProgram);

    // glfw: terminate, clearing all previously allocated GLFW resources.
    // ------------------------------------------------------------------
    glfwTerminate();
    return 0;
}

// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
// ---------------------------------------------------------------------------------------------------------
void processInput(GLFWwindow *window)
{
    if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
        glfwSetWindowShouldClose(window, true);
}

// glfw: whenever the window size changed (by OS or user resize) this callback function executes
// ---------------------------------------------------------------------------------------------
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
    // make sure the viewport matches the new window dimensions; note that width and 
    // height will be significantly larger than specified on retina displays.
    glViewport(0, 0, width, height);
}

I got these errors:

/usr/bin/ld: /tmp/ccDMX5H7.o: in function `main':
triangle.c:(.text+0xe9): undefined reference to `gladLoadGLLoader'
/usr/bin/ld: triangle.c:(.text+0x12b): undefined reference to `glad_glCreateShader'
/usr/bin/ld: triangle.c:(.text+0x13f): undefined reference to `glad_glShaderSource'
/usr/bin/ld: triangle.c:(.text+0x162): undefined reference to `glad_glCompileShader'
/usr/bin/ld: triangle.c:(.text+0x173): undefined reference to `glad_glGetShaderiv'
/usr/bin/ld: triangle.c:(.text+0x19a): undefined reference to `glad_glGetShaderInfoLog'
/usr/bin/ld: triangle.c:(.text+0x1fd): undefined reference to `glad_glCreateShader'
/usr/bin/ld: triangle.c:(.text+0x211): undefined reference to `glad_glShaderSource'
/usr/bin/ld: triangle.c:(.text+0x234): undefined reference to `glad_glCompileShader'
/usr/bin/ld: triangle.c:(.text+0x245): undefined reference to `glad_glGetShaderiv'
/usr/bin/ld: triangle.c:(.text+0x26c): undefined reference to `glad_glGetShaderInfoLog'
/usr/bin/ld: triangle.c:(.text+0x2cf): undefined reference to `glad_glCreateProgram'
/usr/bin/ld: triangle.c:(.text+0x2de): undefined reference to `glad_glAttachShader'
/usr/bin/ld: triangle.c:(.text+0x2f7): undefined reference to `glad_glAttachShader'
/usr/bin/ld: triangle.c:(.text+0x310): undefined reference to `glad_glLinkProgram'
/usr/bin/ld: triangle.c:(.text+0x321): undefined reference to `glad_glGetProgramiv'
/usr/bin/ld: triangle.c:(.text+0x348): undefined reference to `glad_glGetProgramInfoLog'
/usr/bin/ld: triangle.c:(.text+0x3ab): undefined reference to `glad_glDeleteShader'
/usr/bin/ld: triangle.c:(.text+0x3bc): undefined reference to `glad_glDeleteShader'
/usr/bin/ld: triangle.c:(.text+0x4b9): undefined reference to `glad_glGenVertexArrays'
/usr/bin/ld: triangle.c:(.text+0x4d1): undefined reference to `glad_glGenBuffers'
/usr/bin/ld: triangle.c:(.text+0x4e9): undefined reference to `glad_glGenBuffers'
/usr/bin/ld: triangle.c:(.text+0x501): undefined reference to `glad_glBindVertexArray'
/usr/bin/ld: triangle.c:(.text+0x512): undefined reference to `glad_glBindBuffer'
/usr/bin/ld: triangle.c:(.text+0x528): undefined reference to `glad_glBufferData'
/usr/bin/ld: triangle.c:(.text+0x54b): undefined reference to `glad_glBindBuffer'
/usr/bin/ld: triangle.c:(.text+0x561): undefined reference to `glad_glBufferData'
/usr/bin/ld: triangle.c:(.text+0x584): undefined reference to `glad_glVertexAttribPointer'
/usr/bin/ld: triangle.c:(.text+0x5ad): undefined reference to `glad_glEnableVertexAttribArray'
/usr/bin/ld: triangle.c:(.text+0x5bb): undefined reference to `glad_glBindBuffer'
/usr/bin/ld: triangle.c:(.text+0x5ce): undefined reference to `glad_glBindVertexArray'
/usr/bin/ld: triangle.c:(.text+0x607): undefined reference to `glad_glClearColor'
/usr/bin/ld: triangle.c:(.text+0x630): undefined reference to `glad_glClear'
/usr/bin/ld: triangle.c:(.text+0x63e): undefined reference to `glad_glUseProgram'
/usr/bin/ld: triangle.c:(.text+0x64f): undefined reference to `glad_glBindVertexArray'
/usr/bin/ld: triangle.c:(.text+0x660): undefined reference to `glad_glDrawElements'
/usr/bin/ld: triangle.c:(.text+0x696): undefined reference to `glad_glDeleteVertexArrays'
/usr/bin/ld: triangle.c:(.text+0x6ae): undefined reference to `glad_glDeleteBuffers'
/usr/bin/ld: triangle.c:(.text+0x6c6): undefined reference to `glad_glDeleteBuffers'
/usr/bin/ld: triangle.c:(.text+0x6de): undefined reference to `glad_glDeleteProgram'
/usr/bin/ld: /tmp/ccDMX5H7.o: in function `framebuffer_size_callback(GLFWwindow*, int, int)':
triangle.c:(.text+0x764): undefined reference to `glad_glViewport'
collect2: error: ld returned 1 exit status

I compiled the program with this command:

g++ triangle.c -o triangle -Wall -lGL -lGLU -lglut -lGLEW -lglfw -lX11 -lXxf86vm -lXrandr -lpthread -lXi -ldl -lXinerama -lXcursor

EDIT: I used these two resources to perform the installation of the libraries: https://www.youtube.com/watch?v=ZwaHQ6c-ma0

https://shnoh171.github.io/gpu%20and%20gpu%20programming/2019/08/26/installing-glfw-on-ubuntu.html

EDIT 2: Because resources come and go, i will list the steps here:

GLEW/GLFW setup:

sudo apt update
sudo apt install build-essential
sudo apt install cmake
sudo apt install xorg-dev

download glfw source package https://www.glfw.org/download.html
unpack it in Desktop
go to unpacked directory

cmake -G "Unix Makefiles"
make
sudo make install

sudo apt-get install libx11-dev libglu1-mesa-dev freeglut3-dev libglew1.5 libglew1.5-dev libglu1-mesa libgl1-mesa-glx libgl1-mesa-dev libglfw3-dev libglfw3

make your own code and name it with extension .c
and then

gcc "source filename".c -o "filename" -Wall -lGL -lGLU -lglut -lGLEW -lglfw -lX11 -lXxf86vm -lXrandr -lpthread -lXi -ldl -lXinerama -lXcursor

also works with c++:

g++ "source filename".cpp -o "filename" -std=c++11 -Wall -lGL -lGLU -lglut -lGLEW -lglfw -lX11 -lXxf86vm -lXrandr -lpthread -lXi -ldl -lXinerama -lXcursor

And to install GLFW:

sudo apt-get install libglfw3
sudo apt-get install libglfw3-dev

Addition: GLAD can be installed with the following commands:

git clone https://github.com/Dav1dde/glad.git
cd glad
cmake ./
make
sudo cp -a include /usr/local/
user1584421
  • 3,499
  • 11
  • 46
  • 86

2 Answers2

4

Glad consists of multiple files:

  • A glad.h header file, which you have to include into your files
  • A glad.c source file which you have to compile together with your own source files.

Judging from your error message, you forgot to also compile the glad.c source file. You can adapt your command line to something like:

g++ triangle.c <GLADPATH>/glad.c -o triangle -Wall -lGL -lGLU -lglut -lGLEW -lglfw -lX11 -lXxf86vm -lXrandr -lpthread -lXi -ldl -lXinerama -lXcursor

Replace <GLADPATH> with the path to the glad directory

BDL
  • 21,052
  • 22
  • 49
  • 55
  • Thank you. I tried you command and i got `g++: error: glad/glad.c: No such file or directory` – user1584421 Jul 15 '21 at 10:49
  • @user1584421 Where is your glad.c file located? – BDL Jul 15 '21 at 11:05
  • /Desktop/glfw-3.3.4/glad/src – user1584421 Jul 15 '21 at 11:10
  • Then try `g++ triangle.c /Desktop/glfw-3.3.4/glad/src/glad.c` ....` – BDL Jul 15 '21 at 11:14
  • This command `g++ triangle.c /Desktop/glfw-3.3.4/glad/src/glad.c -o triangle -Wall -lGL -lGLU -lglut -lGLEW -lglfw -lX11 -lXxf86vm -lXrandr -lpthread -lXi -ldl -lXinerama -lXcursor` gives me the same error `g++: error: /Desktop/glfw-3.3.4/glad/src/glad.c: No such file or directory`. – user1584421 Jul 15 '21 at 11:15
  • Why is that since the file IS there? – user1584421 Jul 15 '21 at 11:26
  • This worked though! `g++ triangle.c glad/src/glad.c -o triangle -Wall -lGL -lGLU -lglut -lGLEW -lglfw -lX11 -lXxf86vm -lXrandr -lpthread -lXi -ldl -lXinerama -lXcursor` – user1584421 Jul 15 '21 at 11:28
1

There are two essential components while using gpp compiler, that allow to run OpenGL programs:

  1. LINKER FILE (for example glad.c) THE FILE THAT HAS TO BE COMPILED APART FROM YOUR MAIN PROGRAM. The easiest way to handle the linker file is to move it to the folder where your main.cpp is located. Then compile the program in a following way:

    g++ main.cpp glad.c -lglfw -lGL -ldl


  1. HEADER FILE (for example glad.h)

A file which is defined in the curly brackets <> of the #include directive. The path that is placed in curly brackets <> needs to be continuation of the directory that is placed in one of the following paths:

$ cpp -v

#include <...> search starts here:
 /usr/lib/gcc/x86_64-linux-gnu/9/include
 /usr/local/include
 /usr/include/x86_64-linux-gnu
 /usr/include

For example, when #include <glad/glad.h> is specified in your code, glad.h should be located in:

/usr/include/glad/glad.h


Apart from that, you don't need to use the libraries like : -lGLU -lglut -lGLEW -lX11 -lXxf86vm -lXrandr -lpthread -lXi -lXinerama -lXcursor. Use the minimum amount of "-l's" and once you compile linker file with main file, there's no need to define glad in the form of static library (-lglad). Thus, the answer is:

g++ triangle.c glad.c -lglfw -lGL -ldl 

and you should get orange square on the green background (if you don't forget about header and linker files located in the right folders)

JacobTheKnitter
  • 415
  • 5
  • 7