Meph
Meph

Reputation: 372

OpenGL unresolved External Symbol VS 2013

A Linker error popped up on Visual Studio 2013 i don't get why it is thrown on me.

I've seen a lot of Questions already asked about this, but none seem to fit here.

Background: I'm working on a little Triangle drawing with OpenGl.

The Error:

Fehler 1 error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""public: struct glm::tmat4x4 __thiscall Transform::getModel(void)const " (?getModel@Transform@@QBE?AU?$tmat4x4@M$0A@@glm@@XZ)" in Funktion ""public: void __thiscall Shader::Update(class Transform const &)" (?Update@Shader@@QAEXABVTransform@@@Z)". D:\Arbeit\Prog\CPPprojects \OpenGLTutorial\OpenGlTut\OpenGlTut\Shader.obj

So as I see it there is the Symbol of glm::mat4 the linker does not find. The Symbol is defined in headers as usual and is implemented by libraries.

Here are all the libraries i added to the Project :

all of the project worked fine until i added the class Transform and edited the class Shader to take it in.

Here's Code:

Shader.h

#ifndef SHADER_H
#define SHADER_H

#include <string>
#include <glew\GL\glew.h>
#include "Transform.h"

class Shader
{
    enum
    {
        TRANSFORM_U,

        NUM_UNIFORM
    };

    static const unsigned int NUM_SHADER = 2;
    GLuint program;
    GLuint shaders[NUM_SHADER];
    GLuint uniforms[NUM_UNIFORM];

public:
    Shader(const std::string& filename);
    ~Shader();
    void Bind();
    void Update(const Transform& transform);
};
#endif

Shader.cpp:

#include "Shader.h"
#include <iostream>
#include <fstream>
#include <exception>


static void CheckShaderError(GLuint shader, GLuint flag, bool isProgram, const std::string& errorMessage);
static std::string LoadShader(const std::string& filename);
static GLuint CreateShader(const std::string& text, GLenum shaderType);


Shader::Shader(const std::string& filename)
{
    program = glCreateProgram();
    shaders[0] = CreateShader(LoadShader(filename+".vs") , GL_VERTEX_SHADER);
    shaders[1] = CreateShader(LoadShader(filename+".fs"), GL_FRAGMENT_SHADER);

    for (unsigned int i = 0; i < NUM_SHADER; i++)
    {
        glAttachShader(program, shaders[i]);
    }

    glBindAttribLocation(program, 0, "position");
    glBindAttribLocation(program, 1, "texCoord");

    glLinkProgram(program);
    CheckShaderError(program, GL_LINK_STATUS, true, "Error: Program linking failed :");

    glValidateProgram(program);
    CheckShaderError(program, GL_VALIDATE_STATUS, true, "Error: Program is invalid :");

    uniforms[TRANSFORM_U] = glGetUniformLocation(program, "transform");
}


Shader::~Shader()
{

    for (unsigned int i = 0; i < NUM_SHADER; i++)
    {
        glDetachShader(program, shaders[i]);
        glDeleteShader(shaders[i]);
    }

    glDeleteProgram(program);
}

void Shader::Bind()
{
    glUseProgram(program);
}

void Shader::Update(const Transform& transform)
{
    glm::mat4 model = transform.getModel();

    glUniformMatrix4fv(uniforms[TRANSFORM_U], 1, GL_FALSE, &model[0][0]);
}



static GLuint CreateShader(const std::string& text, GLenum shaderType)
{
    GLuint shader = glCreateShader(shaderType);
    if (shader == 0)
    {
        throw std::runtime_error("Error: Shader creation failed !");
    }
    const GLchar* shaderSourceStrings[1];
    GLint shaderSourceStringLengths[1];

    shaderSourceStrings[0] = text.c_str();
    shaderSourceStringLengths[0] = text.length();

    glShaderSource(shader, 1 ,shaderSourceStrings, shaderSourceStringLengths);
    glCompileShader(shader);

    CheckShaderError(shader, GL_COMPILE_STATUS, false, "Error: Shader compilation failed: ");

    return shader;
}

static std::string LoadShader(const std::string& filename)
{
    std::ifstream file;
    file.open((filename).c_str());

    std::string output;
    std::string line;

    if (file.is_open())
    {
        while (file.good())
        {
            getline(file, line);
            output.append(line + "\n");
        }
    }
    else
    {
        throw std::runtime_error("Unable to load Shader :" + filename);
    }

    return output;
}

static void CheckShaderError(GLuint shader, GLuint flag, bool isProgram, const std::string& errorMessage)
{
    GLint success = 0;
    GLchar error[1024] = { 0 };

    if (isProgram)
        glGetProgramiv(shader, flag, &success);
    else
        glGetShaderiv(shader, flag, &success);

    if (success == GL_FALSE)
    {
        if (isProgram)
        {
            glGetProgramInfoLog(shader, sizeof(error), NULL, error);
        }
        else glGetShaderInfoLog(shader, sizeof(error), NULL, error);

        throw std::runtime_error(errorMessage + ": " + error + "\n");
    }

}

Transform.h:

#ifndef TRANSFORM_H
#define TRANSFORM_H


#include <glm\gtx\transform.hpp>
#include <glm\glm.hpp>


class Transform
{
    glm::vec3 pos, rot, scale;

public: 
    inline const glm::vec3& getPos() const;
    inline const glm::vec3& getRot() const;
    inline const glm::vec3& getScale() const;

    inline void setPos(glm::vec3& pos);
    inline void setRot(glm::vec3& rot);
    inline void setScale(glm::vec3& Scale);

    Transform(const glm::vec3& pos = glm::vec3(), const glm::vec3& rot = glm::vec3(), const glm::vec3& scale = glm::vec3(1.0f, 1.0f, 1.0f));
    ~Transform();

    inline glm::mat4 getModel() const;
};

#endif

Transform.cpp:

#include "Transform.h"


Transform::Transform(const glm::vec3& pos, const glm::vec3& rot, const glm::vec3& scale) :
pos(pos),
rot(rot),
scale(scale)
{
}


Transform::~Transform()
{
}


inline const glm::vec3& Transform::getPos() const { return pos; }
inline const glm::vec3& Transform::getRot() const { return rot; }
inline const glm::vec3& Transform::getScale() const { return scale; }

inline void Transform::setPos(glm::vec3& pos){ this->pos = pos; }
inline void Transform::setRot(glm::vec3& rot){ this->rot = rot; }
inline void Transform::setScale(glm::vec3& Scale){ this->scale = scale; }


inline glm::mat4 Transform::getModel() const 
{
    glm::mat4 posMatrix = glm::translate(pos);
    glm::mat4 rotXMatrix = glm::rotate(rot.x, glm::vec3(1, 0, 0));
    glm::mat4 rotYMatrix = glm::rotate(rot.y, glm::vec3(0, 1, 0));
    glm::mat4 rotZMatrix = glm::rotate(rot.z, glm::vec3(0, 0, 1));
    glm::mat4 scaleMatrix = glm::scale(scale);

    glm::mat4 rotMatrix = rotZMatrix * rotYMatrix * rotXMatrix;             //multiply them in reverse order

    return posMatrix * rotMatrix * scaleMatrix;                             // first scale them right , then turn them, then move them the right spot
}   

main.cpp:

#include <iostream>

#include "SDLGuard.h"
#include "Display.h"
#include <glew\GL\glew.h>
#include "Mesh.h"
#include "Shader.h"
#include "Texture.h"
#include "Transform.h"


#undef main

void run()
{
    Display display(800, 600, "HelloWorld !");

    Vertex vertices[] = { 
        Vertex(glm::vec3(-0.5, -0.5, 0.0), glm::vec2(0.0,0.0)),
        Vertex(glm::vec3(0.0, 0.5, 0.0),   glm::vec2(0.5, 1.0)),
        Vertex(glm::vec3(0.5, -0.5, 0.0),  glm::vec2(1.0, 0.0)),
    };

    Mesh mesh(vertices, sizeof(vertices) / sizeof(vertices[0]));

    Shader shader("./res/basicShader");

    Texture texture("./res/testTexture.jpg");

    Transform transform;


    while (!display.isClosed())
    {
        display.clear(0.30f, 0.0f, 0.05f, 1.0f);
        shader.Bind();
        texture.bind();
        shader.Update(transform);
        mesh.draw();
        display.update();
    }
}

int main(int argc, char *argv[])
{
    SDLGuard sdlguard;          //initialize SDL and quit it before quiting program throoug self written guard
    try{
        run();
    }
    catch (std::runtime_error &re)
    {
        std::cout << re.what() << std::endl;
        getchar();
    }
    return 0;
}

Since all the libraries are there and the headers included i have no idea what went wrong while linking. Maybe someone sees the issues i overlooked for a few hours now.

Thanks in advance !

Upvotes: 0

Views: 393

Answers (1)

c-smile
c-smile

Reputation: 27460

Your problem is in this declaration inside transform.cpp

inline glm::mat4 Transform::getModel() const {...}

remove that inline as it forces the function to be seen only inside that compilation unit.

Upvotes: 1

Related Questions