在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的符号。符号在标头中像往常一样定义,由库实现。
以下是我添加到项目中的所有库:
所有项目都运行良好,直到我添加了类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;
}
由于所有库都在那里并且包含了标题我不知道链接时出了什么问题。 也许有人会在几个小时内看到我忽略的问题。
提前致谢!
答案 0 :(得分:1)
您的问题出在transform.cpp
中的此声明中inline glm::mat4 Transform::getModel() const {...}
删除inline
,因为它强制只在编译单元内看到该函数。