首页 > 解决方案 > 如何在pyglet/opengl中获取相对于矩阵比例的光标坐标?

问题描述

我正在 pyglet 中制作 2D 游戏并同时使用 glTranslatef 和 glScalef:

def background_motion(dt):
    if stars.left:
        pyglet.gl.glTranslatef(stars.speed, 0, 0)
        stars.translation[0] += stars.speed
    if stars.right:
        pyglet.gl.glTranslatef(-stars.speed, 0, 0)
        stars.translation[0] -= stars.speed
    if stars.up:
        pyglet.gl.glTranslatef(0, -stars.speed, 0)
        stars.translation[1] -= stars.speed
    if stars.down:
        pyglet.gl.glTranslatef(0, stars.speed, 0)
        stars.translation[1] += stars.speed 
pyglet.clock.schedule_interval(background_motion, 0.05)

@window.event
def on_mouse_scroll(x, y, scroll_x, scroll_y):
    if scroll_y > 0:
        stars.scale += 0.01

    elif scroll_y < 0:
        stars.scale -= 0.01
@window.event
def on_draw():
    window.clear()

    pyglet.gl.glScalef(stars.scale,stars.scale, 1, 1)

    stars.image.draw()
    for s in game.ships:
        s.draw()

    pyglet.gl.glPushMatrix()
    pyglet.gl.glLoadIdentity()

    #HUD Start
    overlay.draw(stars.image.x,stars.image.y,game.ships,stars.scale,stars.image.width)
    if game.pause:
        pause_text.draw()
    #HUD End

    pyglet.gl.glPopMatrix()
    stars.scale = 1

但是我还需要相对于背景的光标坐标。对于运动,我只是将平移添加到 xy 坐标上,但仅当我不缩放矩阵时才有效:

@window.event
def on_mouse_motion(x, y, dx, dy):
    if player.course_setting:
        player.projected_heading = (x - stars.translation[0],y -stars.translation[1])

如何让光标坐标占比例?

标签: python-3.xopenglpyglet

解决方案


您必须取消投影指针位置。投影发生如下:

p_eye = M · p
p_clip = P · p_eye

此时图元被剪裁,但我们暂时可以忽略它。裁剪之后是齐次分割,将坐标带入 NDC 空间,即视口被视为尺寸为 [-1,1]×[-1,1]×[0,1] 的长方体

p_NDC = p_clip / p_clip.w

从那里它被映射到像素尺寸。我将在这里省略这一步。

Unprojecting 是反向执行这些操作。不过,关于同质鸿沟,这里有一个小技巧。这是一种“反对称”(不是这个的正确术语,但它跨越了要点)操作,并在最后发生,对于每个投影和非投影。因此,非投影是

p_NDC.w = 1
p_eye' = inv(P)·p_NDC
p' = inv(M)·p_eye'
p = p' / p'.w

为了您的方便,所有这些都被 GLU(如果您坚持使用固定函数矩阵堆栈)或 GLM 包装到 unproject 函数中,但我的linmath.h没有。


推荐阅读