OpenGL 未解析的外部符号 VS 2013
OpenGL unresolved External Symbol VS 2013
2013 年 Visual Studio 弹出一个链接器错误,我不明白为什么它会抛给我。
我已经看到很多关于此的问题,但 none 似乎适合这里。
背景:我正在使用 OpenGl 绘制一个小三角形。
错误:
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[=15=]A@@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
因此,正如我所见,链接器找不到 glm::mat4 的符号。 Symbol 像往常一样在 headers 中定义,并由库实现。
以下是我添加到项目中的所有库:
- glew32.lib
- glew32s.lib
- SDL2.lib
- SDL2test.lib
- OpenGL32.lib
在我添加 class 转换并编辑 class 着色器以将其纳入之前,所有项目都运行良好。
代码如下:
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;
}
因为所有库都在那里并且包含 headers 我不知道链接时出了什么问题。
也许现在有人看到了我忽略了几个小时的问题。
提前致谢!
你的问题出在这个声明里面transform.cpp
inline glm::mat4 Transform::getModel() const {...}
删除 inline
因为它强制该函数只能在该编译单元内看到。
2013 年 Visual Studio 弹出一个链接器错误,我不明白为什么它会抛给我。
我已经看到很多关于此的问题,但 none 似乎适合这里。
背景:我正在使用 OpenGl 绘制一个小三角形。
错误:
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[=15=]A@@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
因此,正如我所见,链接器找不到 glm::mat4 的符号。 Symbol 像往常一样在 headers 中定义,并由库实现。
以下是我添加到项目中的所有库:
- glew32.lib
- glew32s.lib
- SDL2.lib
- SDL2test.lib
- OpenGL32.lib
在我添加 class 转换并编辑 class 着色器以将其纳入之前,所有项目都运行良好。
代码如下:
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;
}
因为所有库都在那里并且包含 headers 我不知道链接时出了什么问题。 也许现在有人看到了我忽略了几个小时的问题。
提前致谢!
你的问题出在这个声明里面transform.cpp
inline glm::mat4 Transform::getModel() const {...}
删除 inline
因为它强制该函数只能在该编译单元内看到。