GLEW & GL3W Undefined reference

Hello, I want to learn OpenGL 4. I tried to use GLEW and GL3W, then I got similar error. The GLEW program’s:

#include <stdlib.h>#include <stdio.h>
#include <string.h>
#include <GL/glew.h>
#include <GL/freeglut.h>
#define WINDOW_TITLE_PREFIX "Chapter 2"


int
  CurrentWidth = 800,
  CurrentHeight = 600,
  WindowHandle = 0;


unsigned FrameCount = 0;


GLuint
  VertexShaderId,
  FragmentShaderId,
  ProgramId,
  VaoId,
  VboId,
  ColorBufferId;


const GLchar* VertexShader =
{
  "#version 400
"\


  "layout(location=0) in vec4 in_Position;
"\
  "layout(location=1) in vec4 in_Color;
"\
  "out vec4 ex_Color;
"\


  "void main(void)
"\
  "{
"\
  "  gl_Position = in_Position;
"\
  "  ex_Color = in_Color;
"\
  "}
"
};


const GLchar* FragmentShader =
{
  "#version 400
"\


  "in vec4 ex_Color;
"\
  "out vec4 out_Color;
"\


  "void main(void)
"\
  "{
"\
  "  out_Color = ex_Color;
"\
  "}
"
};


void Initialize(int, char*]);
void InitWindow(int, char*]);
void ResizeFunction(int, int);
void RenderFunction(void);
void TimerFunction(int);
void IdleFunction(void);
void Cleanup(void);
void CreateVBO(void);
void DestroyVBO(void);
void CreateShaders(void);
void DestroyShaders(void);


int main(int argc, char* argv])
{
  Initialize(argc, argv);


  glutMainLoop();


  exit(EXIT_SUCCESS);
}


void Initialize(int argc, char* argv])
{
  GLenum GlewInitResult;


  InitWindow(argc, argv);


  glewExperimental = GL_TRUE;
  GlewInitResult = glewInit();


  if (GLEW_OK != GlewInitResult) {
    fprintf(
      stderr,
      "ERROR: %s
",
      glewGetErrorString(GlewInitResult)
    );
    exit(EXIT_FAILURE);
  }


  fprintf(
    stdout,
    "INFO: OpenGL Version: %s
",
    glGetString(GL_VERSION)
  );


  CreateShaders();
  CreateVBO();


  glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
}


void InitWindow(int argc, char* argv])
{
  glutInit(&argc, argv);


  glutInitContextVersion(4, 0);
  glutInitContextFlags(GLUT_FORWARD_COMPATIBLE);
  glutInitContextProfile(GLUT_CORE_PROFILE);


  glutSetOption(
    GLUT_ACTION_ON_WINDOW_CLOSE,
    GLUT_ACTION_GLUTMAINLOOP_RETURNS
  );


  glutInitWindowSize(CurrentWidth, CurrentHeight);


  glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);


  WindowHandle = glutCreateWindow(WINDOW_TITLE_PREFIX);


  if(WindowHandle < 1) {
    fprintf(
      stderr,
      "ERROR: Could not create a new rendering window.
"
    );
    exit(EXIT_FAILURE);
  }


  glutReshapeFunc(ResizeFunction);
  glutDisplayFunc(RenderFunction);
  glutIdleFunc(IdleFunction);
  glutTimerFunc(0, TimerFunction, 0);
  glutCloseFunc(Cleanup);
}


void ResizeFunction(int Width, int Height)
{
  CurrentWidth = Width;
  CurrentHeight = Height;
  glViewport(0, 0, CurrentWidth, CurrentHeight);
}


void RenderFunction(void)
{
  ++FrameCount;


  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


  glDrawArrays(GL_TRIANGLES, 0, 6);


  glutSwapBuffers();
}


void IdleFunction(void)
{
  glutPostRedisplay();
}


void TimerFunction(int Value)
{
  if (0 != Value) {
    char* TempString = (char*)
      malloc(512 + strlen(WINDOW_TITLE_PREFIX));


    sprintf(
      TempString,
      "%s: %d Frames Per Second @ %d x %d",
      WINDOW_TITLE_PREFIX,
      FrameCount * 4,
      CurrentWidth,
      CurrentHeight
    );


    glutSetWindowTitle(TempString);
    free(TempString);
  }


  FrameCount = 0;
  glutTimerFunc(250, TimerFunction, 1);
}


void Cleanup(void)
{
  DestroyShaders();
  DestroyVBO();
}


void CreateVBO(void)
{
  GLfloat Vertices] = {
    -0.8f,  0.8f, 0.0f, 1.0f,
     0.8f,  0.8f, 0.0f, 1.0f,
    -0.8f, -0.8f, 0.0f, 1.0f,


    -0.8f, -0.8f, 0.0f, 1.0f,
     0.8f,  0.8f, 0.0f, 1.0f,
     0.8f, -0.8f, 0.0f, 1.0f
  };


  GLfloat Colors] = {
    1.0f, 0.0f, 0.0f, 1.0f,
    0.0f, 1.0f, 0.0f, 1.0f,
    0.0f, 0.0f, 1.0f, 1.0f,


    0.0f, 0.0f, 1.0f, 1.0f,
    0.0f, 1.0f, 0.0f, 1.0f,
    1.0f, 1.0f, 1.0f, 1.0f
  };


  GLenum ErrorCheckValue = glGetError();


  glGenVertexArrays(1, &VaoId);
  glBindVertexArray(VaoId);


  glGenBuffers(1, &VboId);
  glBindBuffer(GL_ARRAY_BUFFER, VboId);
  glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
  glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
  glEnableVertexAttribArray(0);


  glGenBuffers(1, &ColorBufferId);
  glBindBuffer(GL_ARRAY_BUFFER, ColorBufferId);
  glBufferData(GL_ARRAY_BUFFER, sizeof(Colors), Colors, GL_STATIC_DRAW);
  glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, 0);
  glEnableVertexAttribArray(1);


  ErrorCheckValue = glGetError();
  if (ErrorCheckValue != GL_NO_ERROR)
  {
    fprintf(
      stderr,
      "ERROR: Could not create a VBO: %s 
",
      gluErrorString(ErrorCheckValue)
    );


    exit(-1);
  }
}


void DestroyVBO(void)
{
  GLenum ErrorCheckValue = glGetError();


  glDisableVertexAttribArray(1);
  glDisableVertexAttribArray(0);


  glBindBuffer(GL_ARRAY_BUFFER, 0);


  glDeleteBuffers(1, &ColorBufferId);
  glDeleteBuffers(1, &VboId);


  glBindVertexArray(0);
  glDeleteVertexArrays(1, &VaoId);


  ErrorCheckValue = glGetError();
  if (ErrorCheckValue != GL_NO_ERROR)
  {
    fprintf(
      stderr,
      "ERROR: Could not destroy the VBO: %s 
",
      gluErrorString(ErrorCheckValue)
    );


    exit(-1);
  }
}


void CreateShaders(void)
{
  GLenum ErrorCheckValue = glGetError();


  VertexShaderId = glCreateShader(GL_VERTEX_SHADER);
  glShaderSource(VertexShaderId, 1, &VertexShader, NULL);
  glCompileShader(VertexShaderId);


  FragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER);
  glShaderSource(FragmentShaderId, 1, &FragmentShader, NULL);
  glCompileShader(FragmentShaderId);


  ProgramId = glCreateProgram();
    glAttachShader(ProgramId, VertexShaderId);
    glAttachShader(ProgramId, FragmentShaderId);
  glLinkProgram(ProgramId);
  glUseProgram(ProgramId);


  ErrorCheckValue = glGetError();
  if (ErrorCheckValue != GL_NO_ERROR)
  {
    fprintf(
      stderr,
      "ERROR: Could not create the shaders: %s 
",
      gluErrorString(ErrorCheckValue)
    );


    exit(-1);
  }
}


void DestroyShaders(void)
{
  GLenum ErrorCheckValue = glGetError();


  glUseProgram(0);


  glDetachShader(ProgramId, VertexShaderId);
  glDetachShader(ProgramId, FragmentShaderId);


  glDeleteShader(FragmentShaderId);
  glDeleteShader(VertexShaderId);


  glDeleteProgram(ProgramId);


  ErrorCheckValue = glGetError();
  if (ErrorCheckValue != GL_NO_ERROR)
  {
    fprintf(
      stderr,
      "ERROR: Could not destroy the shaders: %s 
",
      gluErrorString(ErrorCheckValue)
    );


    exit(-1);
  }
}

The used command’s:

g++ -o the_program -lGLEW -lglut file.cpp

The error’s:

/usr/lib64/gcc/x86_64-suse-linux/4.8/…/…/…/…/x86_64-suse-linux/bin/ld: /tmp/ccrJgTa8.o: undefined reference to symbol ‘glClear’/usr/lib64/gcc/x86_64-suse-linux/4.8/…/…/…/…/x86_64-suse-linux/bin/ld: note: ‘glClear’ is defined in DSO /usr/X11R6/lib64/libGL.so.1 so try adding it to the linker command line
/usr/X11R6/lib64/libGL.so.1: could not read symbols: Invalid operation
collect2: error: ld returned 1 exit status

In case of GL3W, I hope I did it the right way. I moved gl3w.h and glcorearb.h to /usr/include/GL and the compiled the files test.c*, which comes with the GL3W source,* with:

g++ -o the_test -lglut -L/usr/include/GL/gl3w.h test.c

The error was:

/tmp/cc8zHajU.o: In function display()':test.c:(.text+0x3f): undefined reference to gl3wClearColor’
test.c:(.text+0x92): undefined reference to gl3wClear' /tmp/cc8zHajU.o: In function reshape(int, int)‘:
test.c:(.text+0xe9): undefined reference to gl3wViewport' test.c:(.text+0x108): undefined reference to gl3wClearDepth’
test.c:(.text+0x119): undefined reference to gl3wClearColor' test.c:(.text+0x12e): undefined reference to gl3wEnable’
/tmp/cc8zHajU.o: In function main': test.c:(.text+0x1a3): undefined reference to gl3wInit’
test.c:(.text+0x1e0): undefined reference to gl3wIsSupported' test.c:(.text+0x215): undefined reference to gl3wGetString’
test.c:(.text+0x226): undefined reference to `gl3wGetString’
collect2: error: ld returned 1 exit status

Just a forum technical remark. I would say that those error are also computer text. Thus why do you not post them using CODE tags? You know how to use them. And genraly token, best is of course to copy/paste all in one sweep: the prompt, the command, the output and the next prompt Then there is no need for explanations like “The used command’s” and “The error’s” because it is all there for us in one logical consistent piece of code text, the same as you saw it.

Sorry, I’m not used to post in forums and I thought the CODE tag’s used for programs only. Thanks.:slight_smile:

As general comment - libraries should be specified on command line after sources that reference them. And -L gives search path for libraries, so your usage of it makes no sense. I’m not sure what you intended to do.

Sorry, I thought it was the right way :slight_smile: . I tried:

g++ -o test file.cpp -lGLEW -lglut

I got the same error.

I presume, you need to add library which provides gl3* functions. I have no idea which though.

I could never compile any OpenGL program on OpenSUSE. :frowning:

Well, the code from the first post compiles fine here with the following command line:

g++ file.cpp -o the_program -lGLEW -lGL -lglut -lGLU

(the error message mentioned in that post actually tells you that -lGL is missing)

But it doesn’t run unfortunately:

./the_program
 X Error of failed request:  GLXBadFBConfig
  Major opcode of failed request:  154 (GLX)
  Minor opcode of failed request:  34 ()
  Serial number of failed request:  34
  Current serial number in output stream:  33

Although I installed fglrx, -lGL seems to be linking Mesa.

Well, I cannot tell anything about fglrx.
I’m only running the open source radeon driver here.

But linking against Mesa should work nonetheless I guess?

It’s said that Mesa doesn’t support OpenGL 4 here: http://www.mesa3d.org/intro.html.

Yeah, sorry.
But your example program does compile fine against Mesa… :wink:

Why couldn’t I compile it?

Because you didn’t specify “-lGL -lGLU”, as I already posted.

Sorry, I don’t have OpenSUSE now, but:

g++ file.cpp -o the_program -lGLEW -lGL -lglut -lGLU
g++ file.cpp -o the_program -lGLEW -lglut -lGL -lGLU

both worked on Ubuntu.
Why did it work? Will the same sequence work on OpenSUSE?

Surprise, surprise.
I already posted that exact line in http://forums.opensuse.org/showthread.php/499282-GLEW-amp-GL3W-Undefined-reference?p=2653135#post2653135 .

Why did it work?

As I already wrote two times:
You did not link against libGL and libGLU, but were using functions form those libraries. Now you did link against them. That’s why it worked now.

Will the same sequence work on OpenSUSE?

Read the thread again.