# GLEW Linker-Problem!



## Diablokiller999 (1. Januar 2012)

Hi!
Habe hier ein Linker-Problem unter Codeblocks und momentan keine Ahnung wo ich anfangen soll das Problem zu suchen.
In den Build Options unter Link Libs sind folgende Libs gelistet:
glew32.lib
glew32mx.lib
glew32mxs.lib
glew32s.lib
libfreeglut.a
libfreeglut_static.a

sowie

-lOpengl32

Als Linker-Option...


Hier der Code:

```
#include <stdlib.h>
#include <iostream>
#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\n"\

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

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

const GLchar* FragmentShader =
{
    "#version 400\n"\
    "in vec4 ex_Color;\n"\
    "out vec4 out_Color;\n"\

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



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[])
{
/*Ruft Initialize mit den von Windows übergebenen Parametern auf*/
    Initialize(argc, argv);

    glutMainLoop();

    exit(EXIT_SUCCESS);
}

void Initialize(int argc, char* argv[])
{   /*Erstellt GLEW-Variable zur Überprüfung der Initialisierung*/
    GLenum GlewInitResult;
    /*Ruft InitWindow-Funktion mit den Windows-Parametern auf*/
    InitWindow(argc, argv);
    GlewInitResult = glewInit();

    if (GLEW_OK != GlewInitResult)
    {
        std::cout<<"ERROR:"<<glewGetErrorString(GlewInitResult)<<std::endl;
        exit(EXIT_FAILURE);
    }

    std::cout<<"INFO: OpenGL Version:"<<glGetString(GL_VERSION)<<std::endl;
    CreateShaders();
    CreateVBO();
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
}

void InitWindow(int argc, char* argv[])
{/*Initialisiert GLUT*/
    glutInit(&argc, argv);
/*Initialisiert GLUT auf OpenGL 4.0*/
    glutInitContextVersion(4, 0);
/*Initialisiert GLUT mit dem Flag Vorwärts-Kompatibel*/
    glutInitContextFlags(GLUT_FORWARD_COMPATIBLE);
/*Setzt das GLUT-Profil auf GLUT_CORE_PROFILE*/
    glutInitContextProfile(GLUT_CORE_PROFILE);
/*Optionen sorgen dafür, dass sich GlutMainLoop selbst wiederholt bis das Fenster schließt*/
    glutSetOption(
        GLUT_ACTION_ON_WINDOW_CLOSE,
        GLUT_ACTION_GLUTMAINLOOP_RETURNS
    );
/*Initialisiert das Fenster mit der gewünschten Größe*/
    glutInitWindowSize(CurrentWidth, CurrentHeight);
/*Aktiviert Z-Buffer, Double-Buffer und die RED-GREEN-BLUE-ALPHA Farbpalette*/
    glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
/*Übergibt Ergebnis der Fenster-Erstellung (Fenster-Titel) an WindowHandle*/
    WindowHandle = glutCreateWindow(WINDOW_TITLE_PREFIX);
/*Falls Fenster-Erstellung fehl schlägt, wird das Programm beendet*/
    if(WindowHandle < 1) {
        std::cout<<"ERROR: Could not create a new rendering window."<<std::endl;
        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, 3);

    glutSwapBuffers();
    glutPostRedisplay();
}

void IdleFunction(void)
{
    glutPostRedisplay();
}
/*TIMER-FUNKTION ZUM MESSEN DER FPS*/
void TimerFunction(int Value)
{
    if (0 != Value) {
        char* TempString = (char*)
            malloc(512 + strlen(WINDOW_TITLE_PREFIX));
/*KONSOLEN-AUSGABE DER FRAMES*/
        std::cout<<TempString<<WINDOW_TITLE_PREFIX<<": "<<FrameCount * 10<<" Frames Per Second @ "<<CurrentWidth<<" x "<<CurrentHeight<<std::endl;
/*FENSTER-HEADER-AUSGABE DER FPS
Speichert Text im Pointer TempString*/
        sprintf(TempString,"%s: %d Frames Per Second @ %d x %d",WINDOW_TITLE_PREFIX,FrameCount * 10,CurrentWidth,CurrentHeight);
/*Schreibt TempString ins Fenster*/
        glutSetWindowTitle(TempString);
        free(TempString);
    }
/*Frame-Zähler wieder auf 0 setzen*/
    FrameCount = 0;
/*Funktion ruft sich selbst mit 100ms Verzögerung auf und übergibt Wert 1 an TimerFunction*/
    glutTimerFunc(100, TimerFunction, 1);
}

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

void CreateVBO(void)
{
    GLfloat Vertices[] = {
        -0.8f, -0.8f, 0.0f, 1.0f,
         0.0f,  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
    };
    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 \n",
            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 \n",
            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 \n",
            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 \n",
            gluErrorString(ErrorCheckValue)
        );

        exit(-1);
    }
}
```
Hier die Fehlermeldung beim kompilieren:


```
...\GL\freeglut_std.h|60|warning: "NOMINMAX" redefined|
..\lib\gcc\mingw32\4.4.1\include\c++\mingw32\bits\os_defines.h|46|warning: this is the location of the previous definition|
obj\Release\main.o:main.cpp|| undefined reference to `_imp____glewUseProgram'|
obj\Release\main.o:main.cpp|| undefined reference to `_imp____glewDetachShader'|
obj\Release\main.o:main.cpp|| undefined reference to `_imp____glewDeleteShader'|
obj\Release\main.o:main.cpp|| undefined reference to `_imp____glewDeleteProgram'|
obj\Release\main.o:main.cpp|| undefined reference to `gluErrorString@4'|
obj\Release\main.o:main.cpp|| undefined reference to `_imp____glewCreateShader'|
obj\Release\main.o:main.cpp|| undefined reference to `_imp____glewShaderSource'|
obj\Release\main.o:main.cpp|| undefined reference to `_imp____glewCompileShader'|
obj\Release\main.o:main.cpp|| undefined reference to `_imp____glewCreateProgram'|
obj\Release\main.o:main.cpp|| undefined reference to `_imp____glewAttachShader'|
obj\Release\main.o:main.cpp|| undefined reference to `_imp____glewLinkProgram'|
obj\Release\main.o:main.cpp|| undefined reference to `_imp____glewUseProgram'|
obj\Release\main.o:main.cpp|| undefined reference to `gluErrorString@4'|
obj\Release\main.o:main.cpp|| undefined reference to `_imp____glewDisableVertexAttribArray'|
obj\Release\main.o:main.cpp|| undefined reference to `_imp____glewBindBuffer'|
obj\Release\main.o:main.cpp|| undefined reference to `_imp____glewDeleteBuffers'|
obj\Release\main.o:main.cpp|| undefined reference to `_imp____glewBindVertexArray'|
obj\Release\main.o:main.cpp|| undefined reference to `_imp____glewDeleteVertexArrays'|
obj\Release\main.o:main.cpp|| undefined reference to `gluErrorString@4'|
obj\Release\main.o:main.cpp|| undefined reference to `_imp____glewGenVertexArrays'|
obj\Release\main.o:main.cpp|| undefined reference to `_imp____glewBindVertexArray'|
obj\Release\main.o:main.cpp|| undefined reference to `_imp____glewGenBuffers'|
obj\Release\main.o:main.cpp|| undefined reference to `_imp____glewBindBuffer'|
obj\Release\main.o:main.cpp|| undefined reference to `_imp____glewBufferData'|
obj\Release\main.o:main.cpp|| undefined reference to `_imp____glewVertexAttribPointer'|
obj\Release\main.o:main.cpp|| undefined reference to `_imp____glewEnableVertexAttribArray'|
obj\Release\main.o:main.cpp|| undefined reference to `gluErrorString@4'|
||=== Build finished: 27 errors, 2 warnings ===|
```
Sollte doch alles richtig gelinkt sein so wie ich das sehe.
Nutze den GNU GCC Compiler unter Codeblocks. Eine ältere Version des Sourcecodes kompiliert ohne Probleme, hat aber auch nicht die Shader drin. Fehlt mir eine Lib?


----------



## AMD (2. Januar 2012)

Also wenn ich mir den Code so angucke, dann sollte die glew32.lib völlig ausreichend sein! Die anderen Lib's sind überflüssig.

Willst du das denn gerade unter Linux oder Windows compilen?
Weil bei deinen lib's sehe ich z.B. glew32.lib (Windows) und libfreeglut.a (freeglut).
*.a sind ja die Linux-Libs und *.lib für Windows.


----------



## Diablokiller999 (2. Januar 2012)

MinGW sollte damit eigentlich klar kommen, aber nur zum Spaß habe ich das Ganze auch unter Visual Studio 2010 mit Freeglut für VC und GLEW genutzt, gleiche Fehlermeldung...


----------



## AMD (2. Januar 2012)

Hattest du bei VS auch die Lib's eingetragen?
Projekt-Eigenschaften -> Konfigurationseigenschaften -> Linker -> Eingabe -> Zusätzliche Abhängigkeiten


Ich hatte damals das gleiche Problem mit glew. Der Eintrag von glew32.lib bei dem Linker hatte es dann bei mir behoben.


----------



## Diablokiller999 (2. Januar 2012)

Klar ^^


			Dieser Inhalt steht nur eingeloggten Mitgliedern zur Verfügung.


----------



## AMD (3. Januar 2012)

Hm okay, bei VS 2005 - was ich ja nehme, muss man nämlich die Libs noch einzeln beim Linker eintragen und nicht nur den Pfad angeben.



			Dieser Inhalt steht nur eingeloggten Mitgliedern zur Verfügung.
        



Hab mal bei VS2010 geschaut und da sieht das Fenster unwesentlich anders aus. Trag da mal die glew32.lib auch noch ein.


----------



## bingo88 (3. Januar 2012)

wenn man die Libs nicht mit irgendwelchen #pragma's im Code einbindet, muss man die in VS auf jeden Fall in dem Menü eintragen. Sonst findet der nix.


----------



## AMD (3. Januar 2012)

Stimmt. Bingo88 seine Möglichkeit über #pragma geht natürlich auch 

Daher könntest du auch das nehmen:

```
#pragma comment(lib, "glew32.lib")
```


----------



## Diablokiller999 (7. Januar 2012)

THX, hat geklappt. Endlich gehs weiter mit dem OpenGL Studium ^^


----------

