【问题标题】:Mouse position on (OpenGL) scene(OpenGL)场景上的鼠标位置
【发布时间】:2018-09-30 17:49:11
【问题描述】:

我正在尝试在 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() 

它会给我鼠标在窗口上的位置。

当我这样做时:

print self.mapToGlobal(event.pos())

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

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

【问题讨论】:

    标签: python-2.7 pyside pyopengl


    【解决方案1】:

    我不认为有一个方便的内置函数,但计算起来应该很简单,特别是考虑到这是一个 2D 正交场景。您知道窗口的大小(以像素为单位),并且您知道用户在该窗口中单击的位置,给定event.pos() 返回的任何内容(也以像素为单位)。然后需要发生的是,您需要将该范围(以像素为单位)映射到您在 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 坐标比较棘手。我建议为此阅读“鼠标选择”的概念。您需要获取深度缓冲区,将其结果存储在纹理中,并在该纹理中的适当位置对鼠标坐标进行采样以获得 z 坐标。您可以将这两个答案(12)结合起来,我之前已经为其他问题写过,以使某些事情发挥作用。让我知道这是否有帮助!

    【讨论】:

    • 我明白了...是的,这很完美,只是在划分mouse_pos[0] / window_size[0] 时,我将其更改为float(mouse_pos[0]) / float(self.width())float(mouse_pos[1]) / float(self.height())
    • 还有,是啊,我看到了一篇关于Mouse Picking with Ray Casting的文章,但是我现在还不需要3维,可能我以后有时会考虑。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-03
    • 1970-01-01
    • 2011-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多