pygame + opengl = 显示文本

问题描述

我需要在窗口中显示文本,我找到了这样的解决方案,但它什么也不画

def drawText(x,y,text):                                                
    position = (x,0)
    font = pygame.font.SysFont('arial',64)
    textSurface = font.render(text,True,(255,255,66,255),(0,255))
    textData = pygame.image.tostring(textSurface,"RGBA",True)
    glrasterPos3d(*position)
    glDrawPixels(textSurface.get_width(),textSurface.get_height(),GL_RGBA,GL_UNSIGNED_BYTE,textData)

有没有办法只在 pygame 窗口中显示文本?

解决方法

使用 glWindowPos 而不是 glRasterPosglRasterPos 的坐标由当前模型视图和投影矩阵转换,glWindowPos 直接更新当前光栅位置的 x 和 y 坐标。

另见PyGame and OpenGL immediate mode (Legacy OpenGL) - Text


最小示例:

import pygame
from pygame.locals import *
from OpenGL.GL import *
from OpenGL.GLU import *

verticies = ((1,-1,-1),(1,1,(-1,1),1))
edges = ((0,(0,3),4),(2,7),(6,(5,7))

def drawCube():
    global edges
    glBegin(GL_LINES)
    for edge in edges:
        for vertex in edge:
            glVertex3fv(verticies[vertex])
    glEnd()

def drawText(x,y,text):                                                
    textSurface = font.render(text,True,(255,255,66,255),255))
    textData = pygame.image.tostring(textSurface,"RGBA",True)
    glWindowPos2d(x,y)
    glDrawPixels(textSurface.get_width(),textSurface.get_height(),GL_RGBA,GL_UNSIGNED_BYTE,textData)

pygame.init()
clock = pygame.time.Clock()

display = (400,300)
pygame.display.set_mode(display,DOUBLEBUF | OPENGL)
font = pygame.font.SysFont('arial',64)

gluPerspective(45,(display[0]/display[1]),0.1,50.0)
glTranslatef(0.0,0.0,-5)
run = True
while run:
    clock.tick(100)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    glRotatef(1,3,1)
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
    drawCube()
    drawText(140,120,"cube")
    pygame.display.flip()

pygame.quit()
exit()

对于具有透明背景的文本,您需要使用 convert_alpha() 将文本表面转换为每像素格式:

textSurface = font.render(text,255)).convert_alpha()

此外,您必须启用 Blending

glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA)

最小示例:

import pygame
from pygame.locals import *
from OpenGL.GL import *
from OpenGL.GLU import *

verticies = ((1,255)).convert_alpha()
    textData = pygame.image.tostring(textSurface,64)

glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA)

gluPerspective(45,-5)
run = True
while run:
    clock.tick(100)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
    glRotatef(1,"cube")
    pygame.display.flip()

pygame.quit()
exit()