gpt4 book ai didi

python - Pyglet HUD 文本位置/缩放

转载 作者:太空狗 更新时间:2023-10-29 21:52:15 25 4
gpt4 key购买 nike

背景

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

我有一个带有两个 gluOrtho2D View 的 pyglet 应用程序。一个以 1/1 的比例映射到屏幕,用作我的 HUD。一个映射到游戏世界,因此它可以扩展。

问题

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

问题

有没有办法找出在屏幕上渲染某些内容的位置,或者是否有可能找出或简单地抵消上下文中的当前缩放设置?

最简单的示例代码

导入

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

梳理HUD和2D世界区别的相机类

class Camera(object):

def __init__(self, win):
self.win = win

def project_world(self):
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluOrtho2D(-500, 1000, -500, 500)

def project_hud(self):
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluOrtho2D(0, self.win.width, 0, self.win.height)

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 就可以读取属性并计算文本本身的位置。

这当然是我不想要的 Spaghetti 代码反模式。

最佳答案

我不是 python 程序员,但我认为我对问题的 opengl 部分了解得足够多,所以我会尝试回答。请原谅我的语法。

我相信您想要一个代表场景中 3D 点的 2D 位置。您想知道 2D 中的位置,以便可以在那里绘制一些文本。您拥有 3D 世界的模型 View 和投影矩阵。获取二维位置是一个简单的矩阵乘法问题。

假设我的玩家位置是 p(1.0, 1.0, 1.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)

最后,您的 xy 将包含 3D 点的 2D 投影。

注意:确保在设置矩阵后定位 glGetDoublev() 调用。将它们存储在一个变量中并使用它投影到 2D。

希望对你有帮助

关于python - Pyglet HUD 文本位置/缩放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38414995/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com