Ylfaue
Ylfaue

Reputation: 131

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.

Upvotes: 2

Views: 8766

Answers (1)

Mateusz Grzejek
Mateusz Grzejek

Reputation: 12058

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.

Upvotes: 5

Related Questions