Home > Software design >  How to zoom in and out of a figure in Qt 5.0.2 OpenGL(QOpenGLWidget)?
How to zoom in and out of a figure in Qt 5.0.2 OpenGL(QOpenGLWidget)?

Time:08-13

I'm trying to make the zoom in and out of, say, two lines at an angle (like a tick(/)). I have looked through a lot of options on the Internet, but did not find anything useful. If you have an example in Qt which shows how to add zoom in and out of a shape, with a wheel, mouse, or you know how to do it, I will be very grateful if you can share it with me.

I just recently started to learn Qt and OpenGl. It would be cool if you could tell me how to move by x and y coordinates, i.e. the usual movement of a figure left, right, up and down.

Here is the code I use, maybe it will be useful for solving my question.

This code was taken from one guide, it would be cool if you could point out the mistakes in it (if there are any)

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void on_actionSalir_triggered();

private:
    Ui::MainWindow *ui;

};
#endif // MAINWINDOW_H

myqopenglwidget.h

#ifndef MYQOPENGLWIDGET_H
#define MYQOPENGLWIDGET_H

#include <QOpenGLFunctions>
#include <QColor>
#include <GL/gl.h>
#include <GL/glu.h>
#include <QTimer>
#include <QOpenGLWidget>
#include <QOpenGLFunctions>
#include <QQuaternion>
#include <QVector2D>
#include <QVector>
#include <functional>

#define RGB_MIN 1
#define RGB_MAX 255

class MyQOpenGLWidget : public QOpenGLWidget, public QOpenGLFunctions
{
public:
    MyQOpenGLWidget(QWidget *parent = nullptr);

protected:
    void initializeGL() override;
    void paintGL() override;
    void resizeGL(int w, int h) override;

private:
    void qColorToRGB(const QColor &C, float &r, float &g, float &b) const;
    float normaliza_0_1(float val, float min, float max) const;

protected:
};

#endif // MYQOPENGLWIDGET_H

myqopenglwidget.cpp


#include "myqopenglwidget.h"
#include <QOpenGLFunctions>
#include <QOpenGLFunctions_4_1_Compatibility>
#include <cmath>
#include <QOpenGLVertexArrayObject>
#include <QOpenGLFunctions>
#include <QOpenGLShaderProgram>
#include <QGLFramebufferObject>
#include <QOpenGLFramebufferObject>
#include <GL/gl.h>
#include <iostream>
#include <vector>
#include <cmath>
#include <iomanip>
#include <fstream>
#include <QGLWidget>
#include <QMouseEvent>

MyQOpenGLWidget::MyQOpenGLWidget(QWidget *parent) : QOpenGLWidget {parent}
{

}

void MyQOpenGLWidget::initializeGL()
{
    float r,g,b,a = normaliza_0_1(255.0f, RGB_MIN, RGB_MAX);
    initializeOpenGLFunctions();
    qColorToRGB(Qt::black,r,g,b);
    glClearColor(r,g,b,a);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_LIGHT0);
    glEnable(GL_LIGHTING);
    glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
    glEnable(GL_COLOR_MATERIAL);

}

void MyQOpenGLWidget::paintGL()
{
    float r,g,b;
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

//x
    glBegin(GL_LINES);
    qColorToRGB(Qt::yellow,r,g,b);
    glColor3f(r,g,b);
    glVertex3f(-1.0f, 0.0f,0.0f);
    glVertex3f(1.0f, 0.0f,0.0f);
    glEnd();
//y
    glBegin(GL_LINES);
    qColorToRGB(Qt::yellow,r,g,b);
    glColor3f(r,g,b);
    glVertex3f(0.0f, -1.0f,0.0f);
    glVertex3f(0.0f, 1.0f,0.0f);
    glEnd();

    glBegin(GL_LINES);
    qColorToRGB(Qt::green,r,g,b);
    glColor3f(r,g,b);
    glVertex3f(0.0f, 0.0f,0.0f);
    glVertex3f(0.835f, 0.69f,0.0f);
    glEnd();


    glBegin(GL_LINES);
    qColorToRGB(Qt::green,r,g,b);
    glColor3f(r,g,b);
    glVertex3f(-0.835f, 0.69f,0.0f);
    glVertex3f(0.0f, 0.0f,0.0f);
    glEnd();

}

void MyQOpenGLWidget::resizeGL(int w, int h)
{
    glViewport(0,0,w,h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

}

void MyQOpenGLWidget::qColorToRGB(const QColor &C, float &r, float &g, float &b) const
{
    r = normaliza_0_1(C.red(),RGB_MIN, RGB_MAX);
    g = normaliza_0_1(C.green(),RGB_MIN, RGB_MAX);
    b = normaliza_0_1(C.blue(),RGB_MIN, RGB_MAX);
}

float MyQOpenGLWidget::normaliza_0_1(float val, float min, float max) const
{
    return (val-min)/(max-min);
}

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

main.cpp

#include "mainwindow.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

CodePudding user response:

If you have an example in Qt which shows how to add zoom in and out of a shape, with a wheel

My example shows how to zoom with the wheel button and pan with the right button: enter image description here

main.cpp

#ifdef _WIN32
#include <windows.h>
extern "C" __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
extern "C" __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001;
#endif

#include "Widget.h"

#include <QtGui/QSurfaceFormat>
#include <QtWidgets/QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QSurfaceFormat format;
    format.setSamples(8);

    Widget w;
    w.setFormat(format);
    w.show();
    return a.exec();
}

Widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QtGui/QOpenGLFunctions>
#include <QtGui/QMatrix4x4>
#include <QtGui/QWheelEvent>
#include <QtOpenGLWidgets/QOpenGLWidget>
#include <QtOpenGL/QOpenGLBuffer>
#include <QtOpenGL/QOpenGLShaderProgram>

class Widget : public QOpenGLWidget, QOpenGLFunctions
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private:
    void initializeGL() override;
    void paintGL() override;
    void resizeGL(int w, int h) override;

    void mousePressEvent (QMouseEvent *event) override;
    void mouseMoveEvent (QMouseEvent *event) override;
    void mouseReleaseEvent (QMouseEvent *event) override;
    void wheelEvent(QWheelEvent *event) override;

private:
    QOpenGLShaderProgram m_program;
    QOpenGLBuffer m_vertPosBuffer;
    QMatrix4x4 m_projMatrix;
    QMatrix4x4 m_viewMatrix;
    QMatrix4x4 m_modelMatrix;
    QMatrix4x4 m_mvpMatrix;
    int m_uMvpMatrixLocation;

    bool m_panning = false;
    float m_panX = 0;
    float m_panY = 0;
    float m_prevXForPan;
    float m_prevYForPan;
};
#endif // WIDGET_H

Widget.cpp

#include "Widget.h"

#include <QtMath>
#include <QtGui/QOffscreenSurface>
#include <QtGui/QOpenGLContext>

Widget::Widget(QWidget *parent)
    : QOpenGLWidget(parent)
{
    setWindowTitle("OpenGL3, Qt6, C  ");
    setFixedSize(QSize(400, 400));
}

Widget::~Widget()
{
}

void Widget::initializeGL()
{
    initializeOpenGLFunctions();
    glClearColor(0.86f, 0.87f, 0.84f, 1.f);

    float vertPositions[] = {
        -0.5f, -0.5f, 0.f,
        -0.5f, 0.5f, 0.f,
        0.5f, -0.5f, 0.f,
        0.5f, -0.5f, 0.f,
        -0.5f, 0.5f, 0.f,
        0.5f, 0.5f, 0.f
    };
    m_vertPosBuffer.create();
    m_vertPosBuffer.bind();
    m_vertPosBuffer.allocate(vertPositions, sizeof(vertPositions));

    m_program.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/Assets/Shaders/default.vert");
    m_program.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/Assets/Shaders/default.frag");
    m_program.bindAttributeLocation("aPosition", 0);
    m_program.link();

    m_program.setAttributeBuffer(0, GL_FLOAT, 0, 3);
    m_program.enableAttributeArray(0);

    m_projMatrix.perspective(50.f, 1.f, 0.1f, 500.0f);
    m_viewMatrix.lookAt(QVector3D(0.f, 0.f, 20.f), QVector3D(0.f, 0.f, 0.f), QVector3D(0.f, 1.f, 0.f));

    m_modelMatrix.translate(0.f, 0.f);
    m_modelMatrix.rotate(30.f, QVector3D(0.f, 0.f, 1.f));
    m_modelMatrix.scale(7.f, 4.f);

    m_program.bind();

    m_uMvpMatrixLocation = m_program.uniformLocation("uMvpMatrix");

    int uColorLocation = m_program.uniformLocation("uColor");
    QVector3D color(0.34f, 0.73f, 0.73f);
    m_program.setUniformValue(uColorLocation, color);
}

void Widget::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT);
    m_program.bind();

    QMatrix4x4 projViewMatrix = m_projMatrix * m_viewMatrix;
    m_mvpMatrix = projViewMatrix * m_modelMatrix;
    m_program.setUniformValue(m_uMvpMatrixLocation, m_mvpMatrix);

    glDrawArrays(GL_TRIANGLES, 0, 6);
}

void Widget::resizeGL(int w, int h)
{

}

void Widget::mousePressEvent(QMouseEvent *event)
{
    switch(event->button())
    {
        case Qt::LeftButton:
        {
            break;
        }
        case Qt::MiddleButton:
        {
            break;
        }
        case Qt::RightButton:
        {
            if (m_panning)
            {
                return;
            }
            m_panning = true;
            m_prevXForPan = event->position().x();
            m_prevYForPan = event->position().y();
            break;
        }
        default:
        {
            break;
        }
    }
}

void Widget::mouseMoveEvent(QMouseEvent *event)
{
    if (!m_panning)
    {
        return;
    }

    float x = event->position().x();
    float y = event->position().y();

    float distance = m_viewMatrix.column(3).z();

    m_panX = (m_panX   (x - m_prevXForPan) * qFabs(distance) / 500.f);
    m_panY = (m_panY   (y - m_prevYForPan) * qFabs(distance) / 500.f);

    m_prevXForPan = x;
    m_prevYForPan = y;

    m_viewMatrix.setColumn(3, QVector4D(m_panX, -m_panY, distance, 1.f));

    update();
}

void Widget::mouseReleaseEvent(QMouseEvent *event)
{
    Q_UNUSED(event);

    if (!m_panning)
    {
        return;
    }
    m_panning = false;
}

void Widget::wheelEvent(QWheelEvent *event)
{
    float delta = event->angleDelta().y() / 100.f;
    float distance = m_viewMatrix.column(3).z();
    distance  = delta;
    m_viewMatrix.setColumn(3, QVector4D(m_panX, -m_panY, distance, 1.f));
    update();
}

Assets/Shader/default.vert

#version 130

in vec3 aPosition;
uniform mat4 uMvpMatrix;

void main()
{
    gl_Position = uMvpMatrix * vec4(aPosition, 1.0);
}

Assets/Shader/default.frag

#version 130

uniform vec3 uColor;

out vec4 fragColor;

void main()
{
    fragColor = vec4(uColor, 1.0);
}

.pro

QT        = core gui openglwidgets

win32: LIBS  = -lopengl32

greaterThan(QT_MAJOR_VERSION, 4): QT  = widgets

CONFIG  = c  11

# 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 \
    Widget.cpp

HEADERS  = \
    Widget.h

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS  = target

RESOURCES  = \
    Shaders.qrc
  • Related