在之前的文章中讲到了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. mysql的基本查询(等于,不等于,between...and...,)

    单个字段多个字段查询 查询员工姓名 *注:在SQL语句中不区分大小写:SQL语句以“:”分号结束 select ename from emp; 注:select询句后面跟的是字段名称,select是关 ...

  2. oval-and-rectangle

    oval-and-rectangle Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

  3. Java基础知识--内存管理

    Java语言中 的垃圾收集器相对于以前的其他语言优势是什么? 过去的语言需要程序员显示的进行分配内存.释放内存.这种做法可能会引起“内存泄漏”,即由于某种原因是分配给程序的内存无法释放,如果该任务不断 ...

  4. react-native 报错 RawText "" must be wrapped in an explicit <Text> component

    刚才又遇到了一个坑,找了好久,问题如下: 开始以为是Text标签怎么有问题了,结果是下面的原因影响的: 上图第二行,标签和注释中间多了一个空格,就会报这个错误. 解决办法 1.将空格删掉 <Re ...

  5. ngClass指令3种使用

    CSS代码:1 .strike { text-decoration: line-through; } .bold { font-weight: bold; } .red { color: red; } ...

  6. pygame 笔记-9 图片旋转及边界反弹

    h5或flash中,可以直接对矢量对象,比如line, rectange旋转,但是pygame中,仅支持对image旋转,本以为这个是很简单的事情,但是发现还是有很多小猫腻的,记录一下: 先看一个错误 ...

  7. Spring源码分析 之浅谈设计模式

    一直想专门写个Spring源码的博客,工作了,可以全身性的投入到互联网行业中.虽然加班很严重,但是依然很开心.趁着凌晨有时间,总结总结. 首先spring,相信大家都很熟悉了. 1.轻量级  零配置, ...

  8. poi 升级至4.x 的问题总结(POI Excel 单元格内容类型判断并取值)

    POI Excel 单元格内容类型判断并取值 以前用 cell.getCachedFormulaResultType() 得到 type 升级到4后获取不到了 换为:cell.getCellType( ...

  9. 【性能提升神器】STRAIGHT_JOIN

    今天给大家下另一个性能提升神器-STRAIGHT_JOIN,在数据量大的联表查询中灵活运用的话,能大大缩短查询时间. 首先来解释下STRAIGHT_JOIN到底是用做什么的: STRAIGHT_JOI ...

  10. mac双系统下ubuntu卡在开机密码登录界面卡死

    背景:开机黑屏卡在,dev/sda1: clean, 552599/6111232 files, 7119295/24414464 blocks,修复完这个问题之后,出现桌面卡死,光标鼠标键盘全部失灵 ...