#ifndef MYOPENGLWIDGET_H
#define MYOPENGLWIDGET_H
#include <QOpenGLWidget>
#include <QOpenGLFunctions>
#include <QVector3D>
#include <QOpenGLShaderProgram>
#include <QMatrix4x4>
#include <QMouseEvent>
class MyOpenGLWidget : public QOpenGLWidget, protected QOpenGLFunctions {
Q_OBJECT
public:
MyOpenGLWidget(QWidget *parent = nullptr);
void setPointData(const QVector<QVector3D>& points);
void setRotation(float x, float y);
void setScaling(float scale);
QPoint lastMousePos;
void mousePressEvent(QMouseEvent *event) override;
void mouseMoveEvent(QMouseEvent *event) override;
void wheelEvent(QWheelEvent *event) override;
protected:
void initializeGL() override;
void resizeGL(int w, int h) override;
void paintGL() override;
private:
void drawPoints(const QMatrix4x4& mvpMatrix);
QQuaternion rotationQuaternion;
private:
float rotationX;
float rotationY;
float scaling;
QVector<QVector3D> pointData;
QMatrix4x4 projection;
};
#endif // MYOPENGLWIDGET_H
#include "mygl.h"
MyOpenGLWidget::MyOpenGLWidget(QWidget *parent)
: QOpenGLWidget(parent),
rotationX(0.0f),
rotationY(0.0f),
scaling(1.0f) {
}
void MyOpenGLWidget::initializeGL() {
initializeOpenGLFunctions();
glEnable(GL_DEPTH_TEST);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
}
void MyOpenGLWidget::resizeGL(int w, int h) {
glViewport(0, 0, w, h);
projection.setToIdentity();
projection.perspective(45.0f, (float)w / h, 0.1f, 100.0f);
}
void MyOpenGLWidget::paintGL() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
QMatrix4x4 modelView;
modelView.setToIdentity();
modelView.translate(0.0f, 0.0f, -5.0f);
modelView.rotate(rotationQuaternion);
modelView.scale(scaling);
QMatrix4x4 mvpMatrix = projection * modelView;
drawPoints(mvpMatrix);
}
void MyOpenGLWidget::drawPoints(const QMatrix4x4& mvpMatrix) {
QOpenGLShaderProgram program;
program.addShaderFromSourceCode(QOpenGLShader::Vertex,
"attribute highp vec4 vertex;\n"
"uniform highp mat4 mvpMatrix;\n"
"void main(void)\n"
"{\n"
" gl_Position = mvpMatrix * vertex;\n"
" gl_PointSize = 5.0;\n"
"}");
program.addShaderFromSourceCode(QOpenGLShader::Fragment,
"void main(void)\n"
"{\n"
" gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);\n"
"}");
program.link();
program.bind();
program.enableAttributeArray("vertex");
program.setAttributeArray("vertex", pointData.constData());
program.setUniformValue("mvpMatrix", mvpMatrix);
glDrawArrays(GL_POINTS, 0, pointData.size());
program.disableAttributeArray("vertex");
program.release();
}
void MyOpenGLWidget::setPointData(const QVector<QVector3D>& points) {
pointData = points;
update(); // Trigger repaint
}
void MyOpenGLWidget::setRotation(float x, float y) {
rotationX = x;
rotationY = y;
update(); // Trigger repaint
}
void MyOpenGLWidget::setScaling(float scale) {
scaling = scale;
update(); // Trigger repaint
}
void MyOpenGLWidget::mousePressEvent(QMouseEvent *event)
{
lastMousePos = event->pos();
}
void MyOpenGLWidget::mouseMoveEvent(QMouseEvent *event)
{
// 计算鼠标的移动距离
float deltaX = event->x() - lastMousePos.x();
float deltaY = event->y() - lastMousePos.y();
// 更新旋转
QQuaternion deltaRotation = QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, deltaX) *
QQuaternion::fromAxisAndAngle(1.0f, 0.0f, 0.0f, deltaY);
rotationQuaternion = deltaRotation * rotationQuaternion;
// 保存当前鼠标位置
lastMousePos = event->pos();
// 重新绘制
update();
}
void MyOpenGLWidget::wheelEvent(QWheelEvent *event)
{
// 根据滚轮旋转进行缩放
scaling += event->delta() / 1200.0f;
// 防止缩放过小或过大
scaling = qMax(0.1f, qMin(scaling, 5.0f));
// 重新绘制
update();
}
QVector<QVector3D> points;
points << QVector3D(0.0, 0.0, 0.0)
<< QVector3D(1.0, 0.0, 0.0)
<< QVector3D(0.0, 1.0, 0.0)
<< QVector3D(0.0, 0.0, 1.0);
ui->openGLWidget->setPointData(points);