Pyglet HUD文本位置/缩放

2024-06-26 14:19:34 发布

您现在位置:Python中文网/ 问答频道 /正文

背景

我有一个基于this example的HUD游戏

我有一个带有两个gluOrtho2D视图的pyglet应用程序。一个是1/1映射到屏幕上,作为我的HUD。它被映射到游戏世界,所以它可以缩放。在

问题

当游戏世界中的玩家被渲染到某个位置时,我想在HUD中显示这个玩家的名字。但是HUD对世界对象渲染位置一无所知,世界对屏幕的缩放一无所知。在

问题

有没有一种方法可以找出在屏幕上呈现的东西,或者可以找出或者简单地反作用上下文中设置的当前缩放比例?在

最小示例代码

进口

from pyglet import clock, window, font
from pyglet.gl import *

分类HUD和2D世界差异的Camera类

^{pr2}$

包含无视点渲染的所有内容的HUD。

class Hud(object):

    def __init__(self, win: window.Window):
        self.fps = clock.ClockDisplay()
        self.helv = font.load('Helvetica', 12.0)
        self.text = font.Text(self.helv, "This text does not scale", \
                              x=0, y=0, color=(1, 1, 1, 0.5))

    def draw(self):
        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()
        self.text.draw()

包含从玩家视角渲染的一切的世界

class World(object):

    def __init__(self):
        self.helv = font.load('Helvetica', 12.0)
        self.text = font.Text(self.helv, "This text should not scale", \
                              x=0, y=0, color=(1, 1, 1, 0.5))

    def draw(self):
        glClear(GL_COLOR_BUFFER_BIT)
        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()
        self.text.draw()

运行整个交易的应用程序

class App(object):

    def __init__(self):
        self.win = window.Window(fullscreen=False, vsync=True, width=800, height=600)
        self.world = World()
        self.camera = Camera(self.win)
        self.hud = Hud(self.win)
        clock.set_fps_limit(60)

    def run(self):
        while not self.win.has_exit:
            self.win.dispatch_events()

            self.camera.project_world()
            self.world.draw()

            self.camera.project_hud()
            self.hud.draw()

            clock.tick()
            self.win.flip()

app = App()
app.run()

丑八怪

现在,我已经通过丑陋的黑客攻击解决了这个问题。敏感读者请不要继续阅读。在

我现在计算出摄像机在世界上的比例和猎户座,然后把世界链接到HUD,这样HUD就可以读取属性并计算文本本身的位置。在

这当然是我不想要的意大利面代码反模式。在


Tags: textself游戏屏幕def玩家世界window
1条回答
网友
1楼 · 发布于 2024-06-26 14:19:34

我不是一个python程序员,但我认为我对opengl的问题有足够的理解,所以我将尝试回答。请原谅我的语法。在

我相信你想要一个二维的位置来代表你场景中的一个3D点。你想知道二维的位置,这样你就可以在那里画一些文字。您有三维世界的模型视图和投影矩阵。得到二维位置是一个简单的矩阵乘法问题。在

假设我的位置是1.0.0

import numpy as np
import pyglet 

#transform point to camera or eye space
posV = np.array([1.0,1.0,1.0,1.0])
pyglet.gl.glMatrixMode(pyglet.gl.GL_MODELVIEW)
mvmat = (pyglet.gl.GLdouble * 16)()
pyglet.gl.glGetDoublev(pyglet.gl.GL_MODELVIEW_MATRIX, mvmat)
pyglet.gl.glLoadIdentity()
npmvmat = np.array( mvmat ).reshape((4,4))
eyeV = np.dot(npmvmat, posV)

#transform point to NDC
pyglet.gl.glMatrixMode(pyglet.gl.GL_PROJECTION)
projmat = (pyglet.gl.GLdouble * 16)()
pyglet.gl.glGetDoublev(pyglet.gl.GL_PROJECTION_MATRIX, projmat )
pyglet.gl.glLoadIdentity()
npprojmat = np.array( projmat ).reshape((4,4))
screenV = np.dot(npprojmat, eyeV)

#w-divide - convert from NDC
screenV[0] = screenV[0] / screenV[3]
screenV[1] = screenV[1] / screenV[3]

#[-1,1] shift to [0,1]
x = 0.5 + (0.5 * screenV[0])
y = 0.5 + (0.5 * screenV[1])    

#get a position on the viewport change to your viewport size
width = 1920
height = 1080
x = x * width
y = y * height

print (x,y)

最后,x和{}将包含3D点的2D投影。在

注意:请确保在矩阵设置完成后放置glGetDoublev()调用。将它们存储在一个变量中并使用它投影到二维

希望这有帮助

相关问题 更多 >