フォントを表示してみる

OpenGLプログラミングガイドの8章の例をpythonで書いてみた。
ディスプレイリストとおを使うらしい。
ASCII全文字をカバーすればビットマップフォントを用意するのが面倒な時には使い手があるかも。
フォントはどこまで対応するか微妙に悩ましい。
ビットマップフォント、
ビットマップフォントをテクスチャで表示、
TrueTypeフォントをオブジェクト化する・・・
とどんどんエスカレートしていくのだが。

あと、glWindowPosを試してみようかと思ったのだがpyOpenGLでは無かった。
OpenGL1.4は未対応。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *

# window idを記憶しておく
window=0

space=[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
letters=[
    [0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xff, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18], 
    [0x00, 0x00, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe], 
    [0x00, 0x00, 0x7e, 0xe7, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xe7, 0x7e], 
    [0x00, 0x00, 0xfc, 0xce, 0xc7, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc7, 0xce, 0xfc], 
    [0x00, 0x00, 0xff, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xff], 
    [0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0, 0xff], 
    [0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xcf, 0xc0, 0xc0, 0xc0, 0xc0, 0xe7, 0x7e], 
    [0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xff, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3], 
    [0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e], 
    [0x00, 0x00, 0x7c, 0xee, 0xc6, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06], 
    [0x00, 0x00, 0xc3, 0xc6, 0xcc, 0xd8, 0xf0, 0xe0, 0xf0, 0xd8, 0xcc, 0xc6, 0xc3], 
    [0x00, 0x00, 0xff, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0], 
    [0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xff, 0xff, 0xe7, 0xc3], 
    [0x00, 0x00, 0xc7, 0xc7, 0xcf, 0xcf, 0xdf, 0xdb, 0xfb, 0xf3, 0xf3, 0xe3, 0xe3], 
    [0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xe7, 0x7e], 
    [0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe], 
    [0x00, 0x00, 0x3f, 0x6e, 0xdf, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c], 
    [0x00, 0x00, 0xc3, 0xc6, 0xcc, 0xd8, 0xf0, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe], 
    [0x00, 0x00, 0x7e, 0xe7, 0x03, 0x03, 0x07, 0x7e, 0xe0, 0xc0, 0xc0, 0xe7, 0x7e], 
    [0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff], 
    [0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3], 
    [0x00, 0x00, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3], 
    [0x00, 0x00, 0xc3, 0xe7, 0xff, 0xff, 0xdb, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3], 
    [0x00, 0x00, 0xc3, 0x66, 0x66, 0x3c, 0x3c, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3], 
    [0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3], 
    [0x00, 0x00, 0xff, 0xc0, 0xc0, 0x60, 0x30, 0x7e, 0x0c, 0x06, 0x03, 0x03, 0xff]
    ]

fontOffset=0

def makeRasterFont():
  global fontOffset

  glPixelStorei(GL_UNPACK_ALIGNMENT, 1)

  # DisplayList
  fontOffset=glGenLists(128)
  # Alphabet
  for i in range(26):
    glNewList(fontOffset+i+65, GL_COMPILE)
    glBitmap(8, 13, 0.0, 2.0, 10.0, 0.0, letters[i])
    glEndList()
  # Space
  glNewList(fontOffset+0x20, GL_COMPILE)
  glBitmap(8, 13, 0.0, 2.0, 10.0, 0.0, space)
  glEndList()

# 初期化とWindow生成
def init(width, height, title):
  global window
  # initialize glut
  glutInit("")
  glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB)

  # create window
  glutInitWindowSize(width, height)
  glutInitWindowPosition(100, 100)
  window = glutCreateWindow(title)

  glClearColor(0.0, 0.0, 0.0, 0.0)
  glShadeModel(GL_FLAT)

  # set callbacks
  glutDisplayFunc(display)
  glutReshapeFunc(reshape)
  glutKeyboardFunc(keyPressed)

def printString(text):
  global fontOffset 
  glPushAttrib(GL_LIST_BIT)
  glListBase(fontOffset)
  glCallLists(text)
  glPopAttrib()

def display():
  print 'display'
  glClear(GL_COLOR_BUFFER_BIT)
  glColor(1.0, 1.0, 1.0)
  glRasterPos2i(20, 60)
  printString("THE QUICK BROWN FOX JUMPS")
  glRasterPos2i(20, 40)
  printString("OVER A LAZY DOG")
  glFlush()

# ウィンドウリサイズ
def reshape(width, height):
  print 'reshape'
  glViewport(0, 0, width, height)
  glMatrixMode(GL_PROJECTION)
  glLoadIdentity()
  gluOrtho2D(0, 80, 0, 80)
  glMatrixMode(GL_MODELVIEW)

def keyPressed(*args):
  global window
  if args[0] == ESCAPE or args[0] == "q":
    glutDestroyWindow(window)
    sys.exit()

def main():
  init(500, 500, 'glut sample')
  makeRasterFont()
  glutMainLoop()

if __name__ == '__main__':
  print "Hit ESC key to quit."
  main()