鼠标在 (OpenGL) 场景中的位置

Mouse position on (OpenGL) scene

我正在尝试获取 OpenGL 场景中的鼠标坐标。 我的代码:

from PySide.QtGui import (QColor)
from PySide.QtCore import (Qt, QSize)
from PySide.QtOpenGL import (QGLWidget)
from OpenGL.GL import *
from OpenGL.GLU import *

class QGL(QGLWidget):
    def __init__(self, parent=None):
        self._pan_valid = False

        super(QGL, self).__init__(parent)
        self.setFocusPolicy(Qt.ClickFocus)

        self.local_translate = (0.0, 0.0, 0.0)
        self.zoomVal = 1.2

    def minimumSizeHint(self):
        return QSize(50, 50)

    def sizeHint(self):
        return QSize(800, 800)

    def initializeGL(self):
        self.qglClearColor(QColor.fromCmykF(0.0, 0.1, 0.0, 0.882))
        glViewport( 0, 0, self.width(), self.height())
        glEnable(GL_TEXTURE_2D)
        glEnable(GL_CULL_FACE)
        glEnable(GL_MULTISAMPLE)
        glEnable(GL_LINE_SMOOTH, GL_LINE_WIDTH, GL_ALIASED_LINE_WIDTH_RANGE)
        glShadeModel(GL_FLAT)
        glEnable(GL_DEPTH_TEST)
        glHint(GL_LINE_SMOOTH_HINT,  GL_NICEST)
        glDepthRange (0.1, 1.0)

    def paintGL(self):
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        gluOrtho2D(-self.zoomVal, +self.zoomVal, -self.zoomVal, +self.zoomVal)
        glLoadIdentity()

        genList = glGenLists(1)
        glNewList(genList, GL_COMPILE)

        vertices = [
            (0,0,0),
            (0.5,0,0),
            (0.5,0.5,0),
            (0,0.5,0)
        ]

        glBegin(GL_QUADS)
        self.qglColor(QColor(0,255,255))
        for vertex in vertices:
            glVertex3fv(vertex)
        glEnd()

        glEndList()
        glCallList(genList)

    def mousePressEvent(self, event):
        print event.pos()
        print self.mapToGlobal(event.pos())

当我这样做时:

print event.pos() 

它将给我鼠标在 window 上的位置。

当我这样做时:

print self.mapToGlobal(event.pos())

它会告诉我鼠标在显示器上的位置。

如何获取鼠标在场景中的位置? 我正在使用 2D 视口 (gluOrtho2D)。

我不认为为此有方便的内置函数,但计算起来应该很简单,尤其是考虑到这是一个 2D 正交场景。您知道 window 的大小(以像素为单位),并且您知道 window 中用户点击的位置,给定任何 event.pos() returns(也以像素为单位)。然后需要发生的是您需要将该范围(以像素为单位)映射到您在 gluOrtho2D 调用中指定的范围。您可以根据需要调整以下代码:

#specifying a bunch of example values
zoom_val = 1.2
window_size = (800, 600)
mouse_pos = (300, 150)
ortho_2d = (-zoom_val, +zoom_val, -zoom_val, +zoom_val)

#First, calculate the "normalized" mouse coordinates by dividing by window_size
mouse_norm_x = mouse_pos[0] / window_size[0]
mouse_norm_y = mouse_pos[1] / window_size[1]

#Now map those coordinates to your orthographic projection range
mouse_ortho_x = (mouse_norm_x * (ortho_2d[1] - ortho_2d[0])) + ortho_2d[0]
mouse_ortho_y = (mouse_norm_y * (ortho_2d[3] - ortho_2d[2])) + ortho_2d[2]
mouse_ortho = (mouse_ortho_x, mouse_ortho_y)
print(mouse_ortho)

获取 z 坐标比较棘手。我建议为此阅读 "mouse-picking" 的概念。您需要获取深度缓冲区,将其结果存储在纹理中,并在该纹理中的适当位置采样鼠标坐标以获得 z 坐标。您可以将我之前为其他问题撰写的这两个答案 (, ) 组合在一起,以得到一些有用的东西。让我知道这是否有帮助!