Когда модель нарисована, убедитесь, что установлен режим матрицы GL_MODELVIEW
:
def draw(self, mode):
for i, p in enumerate(self.coord):
glMatrixMode(GL_MODELVIEW) # <------
glPushMatrix()
glTranslatef(p[0], p[1], p[2])
if mode == GL_SELECT:
glLoadName(i+1)
glColor3f(0,0,0)
glutSolidSphere(0.1, 30, 30)
glPopMatrix()
Параметры комплектации gluPickMatrix
регион вроде бы большой.Уменьшите его (например, 10);
gluPickMatrix(event.x(), viewport[3] - event.y(), 10.0, 10.0, viewport)
Модель должна быть нарисована с одинаковой матрицей вида модели и матрицей проекции в обеих моделях (GL_RENDER
/ GL_SELECT
).Создайте функцию, которая умножает матрицу проекции:
def setProjection(self):
gluPerspective(45.0, self.ratio, 0.1, 100.0)
и метод, который очищает набор матрицы вида:
def setView(self):
glLoadIdentity()
self.xCam = self.radialD*cos(self.xzAngle*pi/180)*cos(self.xAngle*pi/180)
self.yCam = self.radialD*sin(self.xzAngle*pi/180)
self.zCam = self.radialD*cos(self.xzAngle*pi/180)*sin(self.xAngle*pi/180)
gluLookAt(self.xCam, self.yCam, self.zCam, 0, 0, 0, 0.0, 1.0, 0.0)
, так как gluPickMatrix
умножаетсядля текущей матрицы установите режим GL_PROJECTION
и очистите текущую матрицу перед вызовом gluPickMatrix
.Умножьте матрицу проекции (setProjection
) и установите матрицу вида (setView
) после вызова gluPickMatrix
:
def mousePressEvent(self, event):
self.makeCurrent()
# store and cleare projection matrix
glMatrixMode(GL_PROJECTION)
glPushMatrix()
glLoadIdentity()
# s4t render mode and pick matrix
selectBuf = glSelectBuffer(100)
glRenderMode(GL_SELECT)
glInitNames()
glPushName(-1)
viewport = glGetIntegerv(GL_VIEWPORT)
gluPickMatrix(event.x(), viewport[3] - event.y(), 10.0, 10.0, viewport)
# multiply projection matrix
self.setProjection()
# store and set current view matrix
glMatrixMode(GL_MODELVIEW)
glPushMatrix()
self.setView()
# draw
self.draw(GL_SELECT)
# restore current matrices
glMatrixMode(GL_PROJECTION)
glPopMatrix()
glMatrixMode(GL_MODELVIEW)
glPopMatrix()
glFlush()
hits = glRenderMode(GL_RENDER)
if hits:
print([x.names for x in hits])
self.doneCurrent()
Класс MyGL
:
class MyGL(QtWidgets.QOpenGLWidget):
def __init__(self, *args):
super().__init__(*args)
self.ratio = 1
self.width, self.height = 1, 1
self.coord = [
[0,0,0], [1,0,0], [2,0,0],
[0,1,0], [1,1,0], [2,1,0],
[0,2,0], [1,2,0], [2,2,0]
]
self.radialD, self.xzAngle, self.xAngle = 30, 0, 90
self.xCam = self.radialD*cos(self.xzAngle*pi/180)*cos(self.xAngle*pi/180)
self.yCam = self.radialD*sin(self.xzAngle*pi/180)
self.zCam = self.radialD*cos(self.xzAngle*pi/180)*sin(self.xAngle*pi/180)
def initializeGL(self):
self.setFocusPolicy(Qt.StrongFocus)
glutInit()
def resizeGL(self, w, h):
if h==0:
h=1
self.ratio = w * 1.0 / h
self.width, self.height = w, h
glViewport(0, 0, w, h)
def setProjection(self):
gluPerspective(45.0, self.ratio, 0.1, 100.0)
def setView(self):
glLoadIdentity()
self.xCam = self.radialD*cos(self.xzAngle*pi/180)*cos(self.xAngle*pi/180)
self.yCam = self.radialD*sin(self.xzAngle*pi/180)
self.zCam = self.radialD*cos(self.xzAngle*pi/180)*sin(self.xAngle*pi/180)
gluLookAt(self.xCam, self.yCam, self.zCam, 0, 0, 0, 0.0, 1.0, 0.0)
def paintGL(self):
glClearDepth(1)
glClearColor(1.0,1.0,1.0,1.0)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
self.setProjection()
glMatrixMode(GL_MODELVIEW)
self.setView()
self.draw(GL_RENDER)
def draw(self, mode):
for i, p in enumerate(self.coord):
glMatrixMode(GL_MODELVIEW)
glPushMatrix()
glTranslatef(p[0], p[1], p[2])
if mode == GL_SELECT:
glLoadName(i+1)
glColor3f(0,0,0)
glutSolidSphere(0.1, 30, 30)
glPopMatrix()
def mousePressEvent(self, event):
self.makeCurrent()
# store and cleare projection matrix
glMatrixMode(GL_PROJECTION)
glPushMatrix()
glLoadIdentity()
# s4t render mode and pick matrix
selectBuf = glSelectBuffer(100)
glRenderMode(GL_SELECT)
glInitNames()
glPushName(-1)
viewport = glGetIntegerv(GL_VIEWPORT)
gluPickMatrix(event.x(), viewport[3] - event.y(), 10.0, 10.0, viewport)
# multiply projection matrix
self.setProjection()
# store and set current view matrix
glMatrixMode(GL_MODELVIEW)
glPushMatrix()
self.setView()
# draw
self.draw(GL_SELECT)
# restore current matrices
glMatrixMode(GL_PROJECTION)
glPopMatrix()
glMatrixMode(GL_MODELVIEW)
glPopMatrix()
glFlush()
hits = glRenderMode(GL_RENDER)
if hits:
print([x.names for x in hits])
self.doneCurrent()
def mouseReleaseEvent(self, event):
pass
def keyPressEvent(self, event):
if event.key() == Qt.Key_Down:
self.xzAngle -= 1
if self.xzAngle < 0:
self.xzAngle = 359
if event.key() == Qt.Key_Up:
self.xzAngle += 1
if self.xzAngle > 360:
self.xzAngle = 1
if event.key() == Qt.Key_Left:
self.xAngle += 1
if self.xAngle > 360:
self.xAngle = 1
if event.key() == Qt.Key_Right:
self.xAngle -= 1
if self.xAngle < 0:
self.xAngle = 359
if event.key() == Qt.Key_Plus:
self.radialD -= 0.3
if event.key() == Qt.Key_Minus:
self.radialD += 0.3
self.update()