vs+qt中使用opengl及关键报错“无法打开包括文件: no such file or directory”与“error LNK2001: 无法解析的外部符号 "public: virtual struct QMetaObject const *... ”解决办法
参考链接
https://blog.csdn.net/qq_22533607/article/details/79792083
http://t.csdnimg.cn/T8II5
http://t.csdnimg.cn/JP8k7
基础准备:vs中配置qt插件(略)
关键步骤:
- 创建Qt Widget Application项目
- 将Base Class修改成QWidget,方框中的内容可以不勾,个人习惯
- ui文件中添加opengl控件并提升为OpenGLWidget(可以另外修改成其他的名字,与之后在文件中新建的类名一致即可),控件具体名称可以不管
- 添加新类,名称openglwidget(与刚才提升的类名一致,但小写)
- main.cpp, invisual.cpp, invisual.h文件全保持不变,对openglwidget.cpp和openglwidget.h进行修改(注意:根据功能变化main.cpp, invisual.cpp, invisual.h或许可以添加与opengl有关的代码,此处只是为了说明opengl在qt中不需要特别包含特别调用,直接重写一个新类也可以运行)
// openglwidget.cpp
#include "openglwidget.h"
const char* vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"
"void main()\n"
"{\n"
" gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
"}\0";
const char* fragmentShaderSource = "#version 330 core\n"
"out vec4 FragColor;\n"
"void main()\n"
"{\n"
" FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
"}\n\0";
OpenGLWidget::OpenGLWidget(QWidget* parent)
: QOpenGLWidget(parent) {}
OpenGLWidget::~OpenGLWidget() {
makeCurrent();
glDeleteBuffers(1, &VBO);
glDeleteVertexArrays(1, &VAO);
shaderProgram.release();
doneCurrent();
}
void OpenGLWidget::initializeGL() {
initializeOpenGLFunctions();
// link shaders
shaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource);
shaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource);
shaderProgram.link();
float vertices[] = {
-0.5f, -0.5f, 0.0f, // left
0.5f, -0.5f, 0.0f, // right
0.0f, 0.5f, 0.0f // top
};
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// position attribute
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
void OpenGLWidget::paintGL() {
glClearColor(0.2f, 0.3f, 0.2f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
shaderProgram.bind();
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
}
void OpenGLWidget::resizeGL(int w, int h) {
glViewport(0, 0, w, h);
}
//openglwidget.h
#pragma once
#include <QOpenGLWidget>
#include <QOpenGLFunctions_3_3_Core>
#include <QOpenGLShaderProgram>
#include <iostream>
class OpenGLWidget : public QOpenGLWidget, QOpenGLFunctions_3_3_Core {
Q_OBJECT
public:
OpenGLWidget(QWidget* parent);
~OpenGLWidget();
protected:
void initializeGL();
void resizeGL(int w, int h);
void paintGL();
private:
QOpenGLShaderProgram shaderProgram;
unsigned int VBO;
unsigned int VAO;
};
5.编译运行错误及解决办法:
错误1:报错“无法打开包括文件...”
解决办法:在项目属性中进行修改,包含目录中添加$(ProjectDir)
(或直接填写./
),表示当前工作目录,即“.vcxproj”及其类似文件所在目录
错误2:报错“无法解析的外部符号...”
解决办法:在头文件属性(此处是openglwidget.h)中进行修改,项类型中修改为Qt Meta-Object Compiler (moc)
- 编译成功
注意:
- 本次项目属性中并没有勾选OpenGL或OpenGL Extensions,可见vs+qt中使用opengl勾选这两个模块并不是必须的
- 上述两个报错在涉及vs与qt的项目中有类似错误可以继续参考。