在 OpenGL window (python) 中可视化单个字符
Visualize a single character in an OpenGL window (python)
使用以下代码,我想在 opengl window 中显示单个字符,但如果字符在较小的 sizer 中多次水平和垂直打印成 space,我只能得到也就是说,我认为,角色应有的大小。谢谢。
代码(几乎全部):
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( )
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)
由于您没有设置任何投影矩阵,因此您必须在归一化设备中绘制几何图形space。在标准化设备 space 中,所有坐标都在 [-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()
如果你想使用 window 坐标,你必须通过 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()
完成函数makefont
和on_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)
使用以下代码,我想在 opengl window 中显示单个字符,但如果字符在较小的 sizer 中多次水平和垂直打印成 space,我只能得到也就是说,我认为,角色应有的大小。谢谢。
代码(几乎全部):
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( )
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)
由于您没有设置任何投影矩阵,因此您必须在归一化设备中绘制几何图形space。在标准化设备 space 中,所有坐标都在 [-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()
如果你想使用 window 坐标,你必须通过 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()
完成函数makefont
和on_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)