【问题标题】:Visualize a single character in an OpenGL window (python)在 OpenGL 窗口中可视化单个字符 (python)
【发布时间】:2020-06-29 11:55:32
【问题描述】:

使用下面的代码,我想在 opengl 窗口中显示单个字符,但是如果字符在较小的尺寸中横向和垂直打印多次到一个空间中,我想,我想,我得到的只是性格应该是。谢谢。

代码(几乎全部):

import numpy
from freetype import *
import OpenGL.GL as gl
import OpenGL.GLUT as glut

text  = 'H'

def makefont(filename, size):
    face = Face(filename)
    face.set_char_size( size*64 )
    face.load_char(text, FT_LOAD_RENDER | FT_LOAD_FORCE_AUTOHINT)
    bitmap = face.glyph.bitmap

    data = bitmap.buffer
    rows = bitmap.rows
    width = bitmap.width
    ascender  = face.glyph.bitmap_top
    descender = bitmap.rows-face.glyph.bitmap_top
    height = ascender+descender
    imageData = numpy.array(bitmap.buffer, numpy.uint8).reshape(rows,width)
    imageData = imageData[::-1,:]
    #########

    textureID = gl.glGenTextures(1)
    gl.glBindTexture( gl.GL_TEXTURE_2D, textureID )
    gl.glTexParameterf( gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR )
    gl.glTexParameterf( gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR )
    gl.glTexImage2D( gl.GL_TEXTURE_2D, 0, gl.GL_RGBA, width, height, 0,
                     gl.GL_RGBA, gl.GL_UNSIGNED_BYTE, imageData )
    #
    gl.glBindTexture(gl.GL_TEXTURE_2D, textureID)
    gl.glBegin(gl.GL_QUADS)
    gl.glTexCoord2f(0, 0)
    x = 0
    y = 0
    w = width
    h = height
    gl.glVertex2f(x, y)
    gl.glTexCoord2f(1, 0)
    gl.glVertex2f(x + w, y)
    gl.glTexCoord2f(1, 1)
    gl.glVertex2f(x + w, y + h)
    gl.glTexCoord2f(0, 1)
    gl.glVertex2f( x, y + h) 
    gl.glEnd()


def on_display( ):
    gl.glClearColor(1,1,1,1)
    gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
    gl.glColor(0,0,0,1)
    makefont( './VeraMono.ttf', 64 )
    glut.glutSwapBuffers( )

def on_reshape( width, height ):
    #

if __name__ == '__main__':
    import sys
    glut.glutInitDisplayMode( glut.GLUT_DOUBLE | glut.GLUT_RGB | glut.GLUT_DEPTH )

    gl.glTexEnvf( gl.GL_TEXTURE_ENV, gl.GL_TEXTURE_ENV_MODE, gl.GL_MODULATE )
    gl.glEnable( gl.GL_DEPTH_TEST )
    gl.glEnable( gl.GL_BLEND )
    gl.glEnable( gl.GL_COLOR_MATERIAL )
    gl.glColorMaterial( gl.GL_FRONT_AND_BACK, gl.GL_AMBIENT_AND_DIFFUSE )
    gl.glBlendFunc( gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA )
    gl.glEnable( gl.GL_TEXTURE_2D )
    glut.glutMainLoop( )

【问题讨论】:

    标签: python opengl pyopengl freetype opengl-compat


    【解决方案1】:

    由 freetype 库渲染的字形图像只有 1 个颜色通道。纹理的格式和内部格式使用GL_ALPHA。见glTexImage2D
    此外,您还必须更改 GL_UNPACK_ALIGNMENT 参数。 GL_UNPACK_ALIGNMENT 参数定义从缓冲区读取图像时图像每行(行)中第一个像素的对齐方式。默认情况下,此参数为 4。
    字形图像的每个像素都以一个字节编码,并且图像被紧密打包。所以字形图像的对齐方式为1,在读取图像并指定纹理之前必须更改参数:

    gl.glPixelStorei(gl.GL_UNPACK_ALIGNMENT, 1)
    gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_ALPHA, width, height, 0,
                    gl.GL_ALPHA, gl.GL_UNSIGNED_BYTE, imageData)
    

    由于您没有设置任何投影矩阵,因此您必须在标准化设备空间中绘制几何图形。在规范化的设备空间中,所有坐标都在范围内 [-1.0, 1.0]:

    x, y, w, h = -1, -1, 2, 2
    gl.glBegin(gl.GL_QUADS)
    gl.glTexCoord2f(0, 0)
    gl.glVertex2f(x, y)
    gl.glTexCoord2f(1, 0)
    gl.glVertex2f(x + w, y)
    gl.glTexCoord2f(1, 1)
    gl.glVertex2f(x + w, y + h)
    gl.glTexCoord2f(0, 1)
    gl.glVertex2f( x, y + h) 
    gl.glEnd()
    

    如果你想使用窗口坐标,你必须通过glOrtho设置一个正交投影:

    gl.glMatrixMode(gl.GL_PROJECTION)
    gl.glLoadIdentity()
    gl.glOrtho(0, width, height, 0, -1, 1)
    gl.glMatrixMode(gl.GL_MODELVIEW)
    
    x, y, w, h = 0, 0, width, height
    gl.glBegin(gl.GL_QUADS)
    gl.glTexCoord2f(0, 0)
    gl.glVertex2f(x, y)
    gl.glTexCoord2f(1, 0)
    gl.glVertex2f(x + w, y)
    gl.glTexCoord2f(1, 1)
    gl.glVertex2f(x + w, y + h)
    gl.glTexCoord2f(0, 1)
    gl.glVertex2f( x, y + h) 
    gl.glEnd()
    

    完整的函数makefonton_reshape

    def makefont(filename, size):
        face = Face(filename)
        face.set_char_size( size*64 )
        face.load_char(text, FT_LOAD_RENDER | FT_LOAD_FORCE_AUTOHINT)
        bitmap = face.glyph.bitmap
    
        data = bitmap.buffer
        rows = bitmap.rows
        width = bitmap.width
        ascender  = face.glyph.bitmap_top
        descender = bitmap.rows-face.glyph.bitmap_top
        height = ascender+descender
        imageData = numpy.array(bitmap.buffer, numpy.uint8).reshape(rows,width)
        imageData = imageData[::-1,:]
    
        textureID = gl.glGenTextures(1)
        gl.glBindTexture( gl.GL_TEXTURE_2D, textureID )
        gl.glTexParameterf( gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR )
        gl.glTexParameterf( gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR )
        gl.glPixelStorei(gl.GL_UNPACK_ALIGNMENT, 1)
        gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_ALPHA, width, height, 0,
                    gl.GL_ALPHA, gl.GL_UNSIGNED_BYTE, imageData)
    
        x, y, w, h = 0, 0, width, height
        gl.glBindTexture(gl.GL_TEXTURE_2D, textureID)
        gl.glBegin(gl.GL_QUADS)
        gl.glTexCoord2f(0, 0)
        gl.glVertex2f(x, y)
        gl.glTexCoord2f(1, 0)
        gl.glVertex2f(x + w, y)
        gl.glTexCoord2f(1, 1)
        gl.glVertex2f(x + w, y + h)
        gl.glTexCoord2f(0, 1)
        gl.glVertex2f( x, y + h) 
        gl.glEnd()
    
    def on_reshape( width, height ):
        gl.glViewport(0, 0, width, height)
        gl.glMatrixMode(gl.GL_PROJECTION)
        gl.glLoadIdentity()
        gl.glOrtho(0, width, height, 0, -1, 1)
        gl.glMatrixMode(gl.GL_MODELVIEW)
    

    另见Immediate mode and legacy OpenGL

    【讨论】:

    • 在 gl.glTexImage2D 中使用 GL_ALPHA 只会改变显示的内容:从前面描述的多个小字符到剥离的图片。您建议的其余代码是相同的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-04
    • 1970-01-01
    • 1970-01-01
    • 2010-09-14
    • 2012-12-13
    • 1970-01-01
    • 2012-08-22
    相关资源
    最近更新 更多