Search code examples
c++eclipseopenglglew

Undefined reference when using glew and mingw?


I am using Eclipse, I had originally downloaded the binary from the website until someone pointed out that I needed to build it from source to make it work with mingw, so I did and I got these files: glew32.dll, libglew32.a, and libglew32.dll.a

I dropped the glew32.dll into the debug folder, and linked the libraries but it did not work.

The weird part: GLenum status = glewInit(); works but glClearColorand glClear do not work and I get a undefined reference to error when I try to call them.

Please see these screenshots: https://i.sstatic.net/yfkrG.jpg and https://i.sstatic.net/Mg8VR.jpg

C++.cpp

#include <iostream>
#include "classHeaders\display.h"
#include "GL\glew.h"


int main(int argv, char** args){
  display x(800,600,"something");

  while(!x.isClosed()){
    glClearColor(0.0f,0.15f,0.3f,1.0f); //undefined reference to ERROR here
    glClear(GL_COLOR_BUFFER_BIT); //undefined reference to ERROR here
    x.Update();
  }
  return 0;
}

display.cpp

#include "classHeaders\display.h"
#include "GL\glew.h"
#include <iostream>
display::display(int width, int height, const std::string& title){

     SDL_Init(SDL_INIT_EVERYTHING);

     SDL_GL_SetAttribute(SDL_GL_RED_SIZE,8);
     SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE,8);
     SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE,8);
     SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE,8);
     SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE,32);
     SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,1);

     m_window = SDL_CreateWindow(title.c_str(),SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED,width,height, SDL_WINDOW_OPENGL);

     m_glContext = SDL_GL_CreateContext(m_window);

     GLenum status = glewInit(); //NO ERRORS OCCUR

     if(status != GLEW_OK){
         std::cerr << "glew failed to initialize" << std::endl;
     }

     m_isClosed = false;
}

display::~display(){
     SDL_GL_DeleteContext(m_glContext);
     SDL_DestroyWindow(m_window);
     SDL_Quit();
}

bool display::isClosed(){
     return m_isClosed;
}

void display::Update(){
     SDL_GL_SwapWindow(m_window);
     SDL_Event e;

    while(SDL_PollEvent(&e)){
        if(e.type == SDL_QUIT){
           m_isClosed = true;
         }
    }
}

display.h

#ifndef DISPLAY_H_
#define DISPLAY_H_

#include <string>
#include "SDL2\SDL.h"
#undef main /*need to put this in or else it gives me "undefined reference to WinMain" ERROR*/

class display{

    public:
        display(int width, int height, const std::string& title);
        void Update();
        bool isClosed();
        virtual ~display();

    private:
        display(const display& other){}
        display& operator=(const display& other){}
        SDL_Window* m_window;
        SDL_GLContext m_glContext;
        bool m_isClosed;

  };

  #endif /* DISPLAY_H_ */

Solution

  • To set up GLEW, a current OpenGL Context is needed (see Creating an OpenGL Context (WGL) for more information).

    Create OpenGL context and window

    A OpenGL Context and a window can easily created by SDL, GLFW or GLUT (see Initializing GLEW for more information).

    Initilize SDL

    If you are using SDL you have to create the window and you have to create the OpenGL context.

    SDL_Window *window = SDL_CreateWindow(""OGL window", SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL );
    SDL_GLContext glContext = SDL_GL_CreateContext( window );
    

    Note, you should check for errors with SDL_GetError.

    The OpenGL context has to become the current context before you use it. Use SDL_GL_MakeCurrent therefor.

    SDL_GL_MakeCurrent( window, glContext );
    

    Initilize GLUT

    To set up GLUT you have to use glutInit and can follow the instructions of initializing glew.

    glutInit(&argc, argv);
    glutCreateWindow("OGL window");
    

    Initilize GLFW

    Note, glfwInit returns GLFW_TRUE if succeded:

    if ( glfwInit() != GLFW_TRUE )
        return;
    
    GLFWwindow *wnd = glfwCreateWindow( width, height, "OGL window", nullptr, nullptr );
    if ( wnd == nullptr )
    {
        glfwTerminate();
        return;
    }
    
    glfwMakeContextCurrent( wnd );
    

    After you have created an OpenGL Context and you have made it become the current context, you have to initialize glew.

    Set up GLEW

    Note that glewInit returns GLEW_OK if succeded:

    if ( glewInit() != GLEW_OK )
        return;
    

    To link the GLEW library correctly you have to set up proper preprocessor definitions:

    On Windows, you also need to define the GLEW_STATIC preprocessor token when building a static library or executable, and the GLEW_BUILD preprocessor token when building a dll

    See also the answer to GLEW Linker Errors (undefined reference to `__glewBindVertexArray')