Как получить координаты курсора относительно масштаба матрицы в pyglet / opengl? - PullRequest
0 голосов
/ 01 января 2019

Я делаю 2D-игру в pyglet и использую 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])

Как я могу получить координаты курсора, учитывающие масштаб?

1 Ответ

0 голосов
/ 01 января 2019

Вам придется отменить проекцию положение указателя.Проекция происходит следующим образом:

p_eye = M · p
p_clip = P · p_eye

, в этот момент примитив обрезается, но мы можем пока игнорировать это.После отсечения происходит однородное деление, которое переносит координаты в пространство НДЦ, то есть область просмотра обрабатывается как кубоид с размерами [-1,1] × [-1,1] × [0,1]

p_NDC = p_clip / p_clip.w

Оттуда он отображается в пиксельных измерениях.Я собираюсь пропустить этот шаг здесь.

Непроектирование делает эти операции в обратном порядке.Там есть небольшая хитрость относительно однородного разделения;это своего рода «антисимметричная» (не совсем подходящий для этого термин, но она подходит к сути) операция, которая выполняется в конце для каждого проецирования и снятия проекции.Следовательно, для непроецирования это

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

Все это для удобства было обернуто в непроектированные функции с помощью GLU (если вы настаиваете на использовании стека с фиксированной матрицей функций) или GLM - но не мой linmath.h, хотя.

...