Search code examples
c++gccopengl-3

OpenGL with GLFW and GLEW - compiling with gcc on windows


I'm trying to run an OpenGL program that uses GLFW and GLEW libraries I built myself. The starter code I use is

#include <iostream>

// GLEW
#define GLEW_STATIC
#include <glew.h>

// GLFW
#include <glfw3.h>


// Function prototypes
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode);

// Window dimensions
const GLuint WIDTH = 800, HEIGHT = 600;

// The MAIN function, from here we start the application and run the game loop
int main()
{
    std::cout << "Starting GLFW context, OpenGL 3.3" << std::endl;
    // Init GLFW
    glfwInit();
    // Set all the required options for GLFW
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);

    // Create a GLFWwindow object that we can use for GLFW's functions
    GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", 0, 0);
    glfwMakeContextCurrent(window);
    if (window == NULL)
    {
        std::cout << "Failed to create GLFW window" << std::endl;
        glfwTerminate();
        return -1;
    }

    // Set the required callback functions
    glfwSetKeyCallback(window, key_callback);

    // Set this to true so GLEW knows to use a modern approach to retrieving function pointers and extensions
    glewExperimental = GL_TRUE;
    // Initialize GLEW to setup the OpenGL Function pointers
    if (glewInit() != GLEW_OK)
    {
        std::cout << "Failed to initialize GLEW" << std::endl;
        return -1;
    }    

    // Define the viewport dimensions
    glViewport(0, 0, WIDTH, HEIGHT);

    // Game loop
    while (!glfwWindowShouldClose(window))
    {
        // Check if any events have been activated (key pressed, mouse moved etc.) and call corresponding response functions
        glfwPollEvents();

        // Render
        // Clear the colorbuffer
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        // Swap the screen buffers
        glfwSwapBuffers(window);
    }

    // Terminate GLFW, clearing any resources allocated by GLFW.
    glfwTerminate();
    return 0;
}

// Is called whenever a key is pressed/released via GLFW
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode)
{
    std::cout << key << std::endl;
    if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
        glfwSetWindowShouldClose(window, GL_TRUE);
}

Then I type

g++ -I<path to headers> Tma.cpp -L<path to libraries> -lglu32 -lopengl32 -lglfw3 -lglew32

Which yields a number of 'undefined reference to' errors.

The code should be OK, as I previously run it successfully in Visual Studio.


Solution

  • This command:

    g++ -I<path to headers> Tma.cpp -L<path to libraries> -lglu32 -lopengl32 -lglfw3 -lglew32

    will not be enough in Windows. You will need to link additional system libraries. For example, every project in Visual Studio 2012 have these attached by default:

    kernel32.lib
    user32.lib
    gdi32.lib
    winspool.lib
    comdlg32.lib
    advapi32.lib
    shell32.lib
    ole32.lib
    oleaut32.lib
    uuid.lib
    odbc32.lib
    odbccp32.lib
    

    That is why it compiled fine in VS.

    kernel32.lib and user32.lib should be always linked. gdi32.lib is required, when you do any graphic operations.

    First solution:

    Link these libraries manually:

    g++ -I<path to headers> Tma.cpp -L<path to libraries> -lglu32 -lopengl32 -lglfw3 -lglew32 -lkernel32 -luser32 -lgdi32 -lws2_32

    If I remember correctly, ws2_32.a is the name of WinSock2 library supplied with MinGW.

    Second solution:

    If you use MinGW, you can use -mwindows flag:

    g++ -I<path to headers> Tma.cpp -L<path to libraries> -lglu32 -lopengl32 -lglfw3 -lglew32 -mwindows

    This will link, among few others, gdi32.a, kernel32.a, user32.a and ws2_32.a.