widget.h:
#ifndef WIDGET_H
#define WIDGET_H
#include <QtOpenGL/QtOpenGL>
class Widget : public QGLWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = 0);
void draw();
int faceAtPosition(const QPoint &pos);
protected:
void initializeGL();
void resizeGL(int width, int height);
void paintGL();
void mouseDoubleClickEvent(QMouseEvent *event);
};
#endif // WIDGET_H
widget.cpp:
#include "widget.h"
#include <QMouseEvent>
#include <GL/glu.h>
Widget::Widget(QWidget *parent)
: QGLWidget(parent)
{
setFormat(QGLFormat(QGL::DoubleBuffer | QGL::DepthBuffer));
}
void Widget::initializeGL()
{
qglClearColor(Qt::black);
glShadeModel(GL_FLAT);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
}
void Widget::resizeGL(int width, int height)
{
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
GLfloat x = GLfloat(width) / height;
glFrustum(-x,+x,-1.0,+1.0,4.0,15.0);
glMatrixMode(GL_MODELVIEW);
}
void Widget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
draw();
}
void Widget::draw()
{
GLfloat P1[2][3] = {0.0, -1.0, +2.0, +1.73205081, -1.0, -1.0};
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -10.0);
int i;
for (i = 0; i < 2; i++)
{
glLoadName(i);
glBegin(GL_POINTS);
glVertex3f(P1[i][0], P1[i][1], P1[i][2]);
glEnd();
}
glLoadName(2);
glBegin(GL_LINES);
glVertex3f(P1[0][0], P1[0][1], P1[0][2]);
glVertex3f(P1[1][0], P1[1][1], P1[1][2]);
glEnd();
}
void Widget::mouseDoubleClickEvent(QMouseEvent *event)
{
int name = faceAtPosition(event->pos());
qDebug("selected: %d", name);
}
int Widget::faceAtPosition(const QPoint &pos)
{
const int MaxSize = 512;
GLuint buffer[MaxSize];
GLint viewport[4];
makeCurrent();
glGetIntegerv(GL_VIEWPORT, viewport);
glSelectBuffer(MaxSize, buffer);
glRenderMode(GL_SELECT);
glInitNames();
glPushName(0);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluPickMatrix(GLdouble(pos.x()), GLdouble(viewport[3] - pos.y()), 15.0, 15.0, viewport);
GLfloat x = GLfloat(width()) / height();
glFrustum(-x, x, -1.0, 1.0, 4.0, 15.0);
draw();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
if(!glRenderMode(GL_RENDER))
return -1;
return buffer[3];
}
main.cpp:
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
testPick.pro文件:
QT += core gui opengl
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = testPick
TEMPLATE = app
DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += main.cpp\
widget.cpp
HEADERS += widget.h
FORMS += widget.ui
LIBS += -lglut -lGLU
我们在两个顶点和画线的时候分别 glLoadName(i),最后在双击的时候就可以找到端点和线的标识:
测试结果: