OpenGL未解析外部符号VS 2013

时间:2016-05-08 16:07:08

标签: c++ opengl linker-errors

在Visual Studio 2013上弹出一个链接器错误我不明白为什么它会被抛到我身上。

我已经看过很多关于此问题的问题,但似乎没有一个适合这里。

背景:我正在使用OpenGl进行一个小小的三角形绘图。

错误:

  

Fehler 1错误LNK2019:Verweis aufnichtaufgelöstesexternesSymbol   “”public:struct glm :: tmat4x4 __thiscall   Transform :: getModel(void)const“   (?getModel @ Transform @@ QBE?AU?$ tmat4x4 @ M $ 0A @@ glm @@ XZ)“在Funktion   “”public:void __thiscall Shader :: Update(类Transform const&)“   (?更新@ Shader @@ QAEXABVTransform @@@ Z)“。D:\ Arbeit \ Prog \ CPPprojects   \ OpenGLTutorial \ OpenGlTut \ OpenGlTut \ Shader.obj

因为我看到它有链接器找不到的glm :: mat4的符号。符号在标头中像往常一样定义,由库实现。

以下是我添加到项目中的所有库:

  • glew32.lib
  • glew32s.lib
  • SDL2.lib
  • SDL2test.lib
  • OpenGL32.lib

所有项目都运行良好,直到我添加了类Transform并编辑了Shader类来接受它。

这是代码:

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;
}

由于所有库都在那里并且包含了标题我不知道链接时出了什么问题。 也许有人会在几个小时内看到我忽略的问题。

提前致谢!

1 个答案:

答案 0 :(得分:1)

您的问题出在transform.cpp

中的此声明中
inline glm::mat4 Transform::getModel() const {...}

删除inline,因为它强制只在编译单元内看到该函数。