QT使用openglWidget时遇到闪退问题,敬请各位指导!
pathViewer.h
#ifndef PATHVIEWER_H
#define PATHVIEWER_H
#include <QWidget>
#include <QOpenGLWidget>
//#include <QOpenGLFunctions_3_3_Core>
#include <QOpenGLFunctions>
#include <QOpenGLShaderProgram>
#include <QOpenGLVertexArrayObject>
#include <QOpenGLBuffer>
#include <QMatrix4x4>
#include <QVector3D>
class PathViewer : public QOpenGLWidget, protected QOpenGLFunctions
{
Q_OBJECT
public:
explicit PathViewer(QWidget *parent = nullptr);
void setPath(const QList<QVector3D> &points);
void setShowPath(bool show);
void setToolPath(const QList<QVector3D> &points);
protected:
void initializeGL() override;
void resizeGL(int w, int h) override;
void paintGL() override;
private:
void setupShaders();
QMatrix4x4 createFANUCViewMatrix() const;
QMatrix4x4 createProjectionMatrix(int w, int h) const;
// Shader
QOpenGLShaderProgram m_program;
// Path VAO/VBO
QOpenGLVertexArrayObject m_pathVAO;
QOpenGLBuffer m_pathVBO{QOpenGLBuffer::VertexBuffer};
// Axis VAO/VBO
QOpenGLVertexArrayObject m_axisVAO;
QOpenGLBuffer m_axisVBO{QOpenGLBuffer::VertexBuffer};
// Data
QList<QVector3D> m_pathPoints;
bool m_showPath = false;
int m_pathVertexCount = 0;
// Uniform locations
GLuint m_projLoc = 0;
GLuint m_viewLoc = 0;
GLuint m_colorLoc = 0;
};
#endif // PATHVIEWER_H
pathViewer.cpp
#include "pathViewer.h"
#include <QtMath>
// ===== Vertex Shader =====
static const char* vertShaderSrc = R"(
#version 330 core
layout (location = 0) in vec3 aPos;
uniform mat4 uProjection;
uniform mat4 uView;
void main() {
gl_Position = uProjection * uView * vec4(aPos, 1.0);
}
)";
// ===== Fragment Shader =====
static const char* fragShaderSrc = R"(
#version 330 core
out vec4 FragColor;
uniform vec3 uColor;
void main() {
FragColor = vec4(uColor, 1.0);
}
)";
PathViewer::PathViewer(QWidget *parent)
: QOpenGLWidget(parent)
{
// setMinimumSize(400, 300);
}
void PathViewer::setPath(const QList<QVector3D> &points)
{
m_pathPoints = points;
m_pathVertexCount = points.size();
if (m_pathVertexCount > 0) {
makeCurrent();
m_pathVBO.bind();
m_pathVBO.allocate(m_pathPoints.data(), m_pathPoints.size() * static_cast<int>(sizeof(QVector3D)));
m_pathVBO.release();
doneCurrent();
}
update();
}
void PathViewer::setShowPath(bool show)
{
m_showPath = show;
update();
}
void PathViewer::initializeGL()
{
initializeOpenGLFunctions();
// 编译着色器
setupShaders();
// 获取 uniform 位置
m_projLoc = m_program.uniformLocation("uProjection");
m_viewLoc = m_program.uniformLocation("uView");
m_colorLoc = m_program.uniformLocation("uColor");
// 初始化 Path VAO/VBO
m_pathVAO.create();
m_pathVBO.create();
m_pathVAO.bind();
m_pathVBO.bind();
m_program.enableAttributeArray(0);
m_program.setAttributeBuffer(0, GL_FLOAT, 0, 3);
m_pathVBO.release();
m_pathVAO.release();
// 初始化坐标轴数据(6个点:3条线 × 2端点)
QVector3D axisVertices[] = {
// X axis (red)
QVector3D(0, 0, 0), QVector3D(30, 0, 0),
// Y axis (green)
QVector3D(0, 0, 0), QVector3D(0, 30, 0),
// Z axis (blue)
QVector3D(0, 0, 0), QVector3D(0, 0, 30)
};
m_axisVAO.create();
m_axisVBO.create();
m_axisVBO.bind();
m_axisVBO.allocate(axisVertices, sizeof(axisVertices));
m_axisVBO.release();
m_axisVAO.bind();
m_axisVBO.bind();
m_program.enableAttributeArray(0);
m_program.setAttributeBuffer(0, GL_FLOAT, 0, 3);
m_axisVBO.release();
m_axisVAO.release();
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // 黑色背景(FANUC 风格)
glEnable(GL_DEPTH_TEST);
glEnable(GL_LINE_SMOOTH);
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
}
void PathViewer::setupShaders()
{
m_program.addShaderFromSourceCode(QOpenGLShader::Vertex, vertShaderSrc);
m_program.addShaderFromSourceCode(QOpenGLShader::Fragment, fragShaderSrc);
m_program.link();
}
QMatrix4x4 PathViewer::createFANUCViewMatrix() const
{
QMatrix4x4 view;
// 相机位置:右前上方(FANUC标准视角)
// eye = (50, -40, 40), center = (0,0,0), up = (0,0,1)
view.lookAt(
QVector3D(50.0f, -40.0f, 40.0f),
QVector3D(0.0f, 0.0f, 0.0f),
QVector3D(0.0f, 0.0f, 1.0f)
);
return view;
}
QMatrix4x4 PathViewer::createProjectionMatrix(int w, int h) const
{
QMatrix4x4 proj;
proj.perspective(45.0f, float(w) / float(h ? h : 1), 0.1f, 200.0f);
return proj;
}
void PathViewer::resizeGL(int w, int h)
{
glViewport(0, 0, w, h);
}
void PathViewer::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
QMatrix4x4 projection = createProjectionMatrix(width(), height());
QMatrix4x4 view = createFANUCViewMatrix();
m_program.bind();
m_program.setUniformValue(m_projLoc, projection);
m_program.setUniformValue(m_viewLoc, view);
// === 绘制坐标轴 ===
glLineWidth(2.5f);
m_axisVAO.bind();
// X - Red
m_program.setUniformValue(m_colorLoc, QVector3D(1.0f, 0.0f, 0.0f));
glDrawArrays(GL_LINES, 0, 2);
// Y - Green
m_program.setUniformValue(m_colorLoc, QVector3D(0.0f, 1.0f, 0.0f));
glDrawArrays(GL_LINES, 2, 2);
// Z - Blue
m_program.setUniformValue(m_colorLoc, QVector3D(0.0f, 0.0f, 1.0f));
glDrawArrays(GL_LINES, 4, 2);
m_axisVAO.release();
// === 绘制路径(白色)===
if (m_showPath && m_pathVertexCount > 0) {
glLineWidth(2.0f);
m_program.setUniformValue(m_colorLoc, QVector3D(1.0f, 1.0f, 1.0f)); // White
m_pathVAO.bind();
glDrawArrays(GL_LINE_STRIP, 0, m_pathVertexCount);
m_pathVAO.release();
}
m_program.release();
}
我在widget.h中添加:
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include "pathViewer.h"
QT_BEGIN_NAMESPACE
namespace Ui {
class Widget;
}
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_pushButton_clicked();
private:
Ui::Widget *ui;
PathViewer *pv;
};
#endif // WIDGET_H
widget.cpp中添加:
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_pushButton_clicked()
{
// QVector<QVector3D> path;
QList<QVector3D> path;
path << QVector3D(0, 0, 0)
<< QVector3D(10, 0, 0)
<< QVector3D(10, 10, 0)
<< QVector3D(5, 15, -2)
<< QVector3D(0, 10, -2);
pv->setPath(path);
}
openglTest.pro中添加:
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++17
QT += core gui openglwidgets
LIBS += -lopengl32 -lglu32
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
pathViewer.cpp \
widget.cpp
HEADERS += \
pathViewer.h \
widget.h
FORMS += \
widget.ui
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

openglWidget也作了提升 ,运行时界面出来了,一旦点击按钮,就闪退了,百思不得其解,请各位指导