QT、OpenGLWidget鼠标控制旋转缩放

#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);

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
可以使用QOpenGLWidget和QMatrix4x4类来实现旋转缩放和移动操作。具体实现可以参考以下代码: ```python from PyQt5.QtWidgets import QApplication, QOpenGLWidget from PyQt5.QtGui import QMatrix4x4, QVector3D from PyQt5.QtCore import Qt class MyOpenGLWidget(QOpenGLWidget): def __init__(self, parent=None): super().__init__(parent) self.rotation = QVector3D(0.0, 0.0, 0.0) self.scale = 1.0 self.translation = QVector3D(0.0, 0.0, 0.0) def initializeGL(self): # 初始化OpenGL环境 ... def paintGL(self): # 绘制OpenGL场景 ... def resizeGL(self, width, height): # 处理窗口大小变化 ... def mousePressEvent(self, event): # 处理鼠标按下事件 ... def mouseMoveEvent(self, event): # 处理鼠标移动事件 ... def wheelEvent(self, event): # 处理鼠标滚轮事件 ... def keyPressEvent(self, event): # 处理键盘按下事件 ... def updateMatrix(self): # 更新变换矩阵 matrix = QMatrix4x4() matrix.translate(self.translation) matrix.rotate(self.rotation.x(), QVector3D(1.0, 0.0, 0.0)) matrix.rotate(self.rotation.y(), QVector3D(0.0, 1.0, 0.0)) matrix.rotate(self.rotation.z(), QVector3D(0.0, 0.0, 1.0)) matrix.scale(self.scale) self.setMatrix(matrix) def setRotation(self, x, y, z): self.rotation = QVector3D(x, y, z) self.updateMatrix() def setScale(self, scale): self.scale = scale self.updateMatrix() def setTranslation(self, x, y, z): self.translation = QVector3D(x, y, z) self.updateMatrix() ``` 其中,updateMatrix()方法用于更新变换矩阵,setRotation()、setScale()和setTranslation()方法用于设置旋转缩放和移动参数。在鼠标和键盘事件处理方法中,可以根据用户的操作来调用这些方法,从而实现旋转缩放和移动操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值