在之前的文章中讲到了OpenGL鼠标拾取操作的例子,工作中需要在Qt中实现,下面的程序演示了QT中opengl的拾取例子。

本例子在Qt5.12和Qt Creator4.8.0上测试,使用的是QOpenGLWidget类,在窗口的正中央有红绿两个三角形组成一个正方形,分别点击不同的三角形部分进行对象拾取。

相关代码如下:

opengl_widget.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
 
#ifdef _MSC_VER
#pragma once
#endif

#ifndef _OPENGL_WIDGET_H_
#define _OPENGL_WIDGET_H_

#include <vector>

#include <QtWidgets/qopenglwidget.h>

class OpenGLWidget : public QOpenGLWidget
{
    Q_OBJECT

public:
    explicit OpenGLWidget(QWidget *parent = nullptr);
    virtual ~OpenGLWidget();

protected:
    virtual void initializeGL() override;
    virtual void paintGL() override;
    virtual void resizeGL(int w, int h) override;
    virtual void mousePressEvent(QMouseEvent *ev) override;
    virtual void mouseMoveEvent(QMouseEvent *ev) override;
    virtual void mouseReleaseEvent(QMouseEvent *ev) override;

private:
    void drawObjects() const;

using uint = unsigned int;
    ;
    std::vector<uint> selectBuffer = std::vector<uint>(selectBufferSize);

};  // class OpenGLWidget

#endif  // _OPENGL_WIDGET_H_

opengl_widget.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
 
#include "opengl_widget.h"

#include <gl/GLU.h>

#include <QtGui/qevent.h>

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

OpenGLWidget::~OpenGLWidget()
{
}

void OpenGLWidget::initializeGL()
{
    glEnable(GL_DEPTH_TEST);
    glClearColor(.0f);
}

void OpenGLWidget::resizeGL(int w, int h)
{
    glViewport(, w, h);
}

void OpenGLWidget::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

int renderMode;
    glGetIntegerv(GL_RENDER_MODE, &renderMode);

if (renderMode != GL_SELECT)
    {
        // Matrix setting
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        const float aspect = static_cast<float>(width()) / height();
        gluPerspective();
    }

glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt();

drawObjects();
}

void OpenGLWidget::mousePressEvent(QMouseEvent *ev)
{
    // Selection buffer
);
    glSelectBuffer(selectBufferSize, &selectBuffer[]);

// Draw for selection buffer
    glRenderMode(GL_SELECT);

// Matrix setting
    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();

];
    glGetIntegerv(GL_VIEWPORT, viewport);
    gluPickMatrix(ev->x(), height() - ev->y(), , viewport);
    ];
    gluPerspective();

// Draw
    paintGL();

// Reset matrix setting
    glMatrixMode(GL_PROJECTION);
    glPopMatrix();

// Revert render mode
    int hits = glRenderMode(GL_RENDER);

// Show selection
    printf("%d hits\n", hits);
    )
    {
        ;
        ; i < hits; i++)
        {
            printf(]);
            printf(] / UINT_MAX);
            printf(] / UINT_MAX);
            printf(]);
            id += ;
        }
    }
}

void OpenGLWidget::mouseMoveEvent(QMouseEvent *ev)
{
}

void OpenGLWidget::mouseReleaseEvent(QMouseEvent *ev)
{
}

void OpenGLWidget::drawObjects() const
{
    // Prepare for selection
    glInitNames();
    glPushName();

// First
.0f);
    glLoadName();
    glBegin(GL_TRIANGLES);
    glVertex3f(-.0f);
    glVertex3f(-.0f);
    glVertex3f( .0f);
    glEnd();

// Second
.0f);
    glLoadName();
    glBegin(GL_TRIANGLES);
    glVertex3f(-.0f);
    glVertex3f( .0f);
    glVertex3f( .0f);
    glEnd();
}

运行测试:

程序中使用了printf作为输出,但是其不能直接打印在Qt的应用程序输出窗口,需要进程结束后才会打印,可以使用qDebug来替代printf。

在测试过程中,我遇到了无论点击屏幕哪里,都会将所有的对象选中的情况,查找一些资料对比试验后,提醒要注意gluLookAt、gluPerspective的调用位置。

仅供参考,出自github:https://github.com/tatsy/QtOpenGLMousePick

Qt OpenGL 鼠标拾取实现的更多相关文章

  1. CSharpGL(21)用鼠标拾取、拖拽VBO图元内的点、线或本身

    CSharpGL(21)用鼠标拾取.拖拽VBO图元内的点.线或本身 效果图 以最常见的三角形网格(用GL_TRIANGLES方式进行渲染)为例. 在拾取模式为GeometryType.Point时,你 ...

  2. OpenGL 3D拾取文章(转)

    参考文章 深入探索3D拾取技术 OpenGL 3D拾取 射线和三角形的相交检测(ray triangle intersection test) 3D拾取的方法有两种 1.基于几何计算的射线-三角形相交 ...

  3. Qt OpenGL三维绘图

     简介 OpenGL是为三维绘图提供的标准应用编程接口. OpenGL处理的仅仅是三维绘图方面,而很少或是根本不提供图形用户界面编程方面的支持.OpenGL*应用程序的用户界面必须由其它工具包创建,比 ...

  4. ubuntu下配置qt+opengl+opencv

    原地址:http://www.cnblogs.com/aleny-liu/archive/2011/12/16/aleny-Qtnote1.html http://blog.csdn.net/jdh9 ...

  5. qt 窗口鼠标穿透

    Qt 不规则窗体 – 鼠标点击穿透 qt实现鼠标穿透,如果要被穿透窗口只有一层,也即没有嵌套窗口,直接只用对子窗口使用setAttribute (Qt::WA_TransparentForMouseE ...

  6. DirectX11 With Windows SDK--21 鼠标拾取

    前言 拾取是一项非常重要的技术,不论是电脑上用鼠标操作,还是手机的触屏操作,只要涉及到UI控件的选取则必然要用到该项技术.除此之外,一些类似魔兽争霸3.星际争霸2这样的3D即时战略游戏也需要通过拾取技 ...

  7. QT 11 鼠标键盘事件添加

    鼠标事件 void mousePressEvent(QMouseEvent *event); //单击 void mouseReleaseEvent(QMouseEvent *event); //释放 ...

  8. Qt532.【转】Qt创建鼠标右键菜单

    ZC:可以通过 设置  (QWebView*)->setContextMenuPolicy(NoContextMenu); 来关闭 QWebView的默认右键菜单 Qt创建鼠标右键菜单_疯华正茂 ...

  9. Qt判断鼠标在控件上

    QT判断鼠标是否在某子窗口控件上方 需要注意的是,子窗口获取geometry,是相对于父窗口的相对位置,QCursor::pos()获取的是鼠标绝对位置,要不将父窗口的相对位置进行换算,要不将鼠标的绝 ...

随机推荐

  1. CSharp遗传算法求解背包问题

    断断续续写了四天,感觉背包问题是最适合了解遗传算法的问题模型 using System; using System.Collections.Generic; using System.Linq; us ...

  2. Qt控制台例子

    功能:实现通过命令行方式保存文件 #include <QCoreApplication> #include <iostream> #include <QString> ...

  3. mysql命令(command)

    连接mysql命令: -uuserName -pPassword 显示表的索引: SHOW INDDEX FROM table_name 查看mysql的超时时间:SHOW GLOBAL VARIAB ...

  4. SourceTree安装教程和破解教程

    SourceTree破解版是一款非常实用的编程工具,这是一款专业的Git和Hg客户端,界面简洁,操作简单易上手,是开发者的必备工具,欢迎大家来绿色资源网下载体验!SourceTree是一款免费的Git ...

  5. 3ds max学习笔记(七)-- 实例操作(桌子)

    首先[自定义]/[单位设置],将公制和系统的单位都设置成mm(毫米) 若软件右侧无[标准基本体]那么可以选择[创建]/标准基本体/扩展基本体.... 1.创建一个长方体(作为桌面)完成后,点击菜单栏[ ...

  6. javaScript系列 [06]-javaScript和this

    在javaScript系列 [01]-javaScript函数基础这篇文章中我已经简单介绍了JavaScript语言在函数使用中this的指向问题,虽然篇幅不长,但其实最重要的部分已经讲清楚了,这篇文 ...

  7. 登录页面和FORM的职责不对称,处理方法,刷新工作流程

    登录页面和FORM的职责不对称,处理方法,刷新工作流程:

  8. YUV420、YUV422、RGB24转换

      //平面YUV422转平面RGB24static void YUV422p_to_RGB24(unsigned char *yuv422[3], unsigned char *rgb24, int ...

  9. tensorflow由于未初始化变量所导致的错误

     版权声明:本文为博主原创文章,如需转载请注明出处,谢谢. https://blog.csdn.net/qq_38542085/article/details/78742295 初始代码 import ...

  10. Eclipse预编译的include路径与宏定义