[英]Pyglet HUD text location / scaling
我有一個基於這個例子的HUD游戲
我有一個帶有兩個gluOrtho2D
視圖的pyglet應用程序。 一個被映射到屏幕的1/1,作為我的HUD。 一個映射到游戲世界的,所以它可以擴展。
當游戲世界中的玩家在某個位置渲染時,我想在HUD中顯示該玩家的名字。 但是HUD對世界物體渲染位置一無所知,世界對屏幕的縮放一無所知。
有沒有辦法找出屏幕上呈現的內容,或者是否有可能找出或只是反作用於上下文中的當前縮放集?
from pyglet import clock, window, font
from pyglet.gl import *
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)
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世界的投影矩陣。 獲得2D位置是矩陣乘法的簡單問題。
假設我的球員位置為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)
最后你的x
和y
將包含3D點的2D投影。
注意:確保在設置矩陣后定位glGetDoublev()
調用。 將它們存儲在變量中並使用它投影到2D。
希望這可以幫助
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.