摘要:在NeHe的OpenGL教程第43课源代码基础上,调用文泉驿正黑字体实现中文字体的显示

在OpenGL中显示汉字一直是个麻烦的事情,很多中文书籍的文抄公乐此不疲地介绍各种方法及其在windows下的代码实现。此处不在赘述,有兴趣的可以参考下面的文章:

OpenGL点阵字体绘制终极解决方案!哈!

下面的代码是在NeHe教程第43课的基础上,添加了中文字体显示功能,原则上只要字体库支持,任何unicode字符串都是可以显示的

btw,unbutu下字体库文件位置:/usr/share/fonts/


16/09/14 晚补注:

在Windos下请安装PIL的替代产品pillow并相应修改

  1. import ImageFont

  1. from PIL import ImageFont

python代码:

  1. #! /usr/bin/env python
  2. #coding=utf-8
  3. # Modified from following code by T.Q. 2014
  4. # A quick and simple opengl font library that uses GNU freetype2, written
  5. # and distributed as part of a tutorial for nehe.gamedev.net.
  6. # Sven Olsen, 2003
  7. # Translated to PyOpenGL by Brian Leair, 2004
  8. #
  9. #
  10. import ImageFont
  11. import numpy as np
  12. from OpenGL import GL,GLU
  13.  
  14. def is_cjk(uchar):
  15. '''
  16. Checks for an unicode whether a CJK character
  17. '''
  18. # cjk = (u'\u4e00',u'\u9fa5')
  19. cjk = (u'\u2e80',u'\ufe4f')
  20. if cjk[0]<=uchar<=cjk[1]:
  21. return True
  22. else:
  23. return False
  24.  
  25. def is_ascii(uchar):
  26. '''
  27. Checks for an unicode whether a ASCII character
  28. '''
  29. ascii = (u'\u0000',u'\u00ff')
  30. if ascii[0]<=uchar<=ascii[1]:
  31. return True
  32. else:
  33. return False
  34.  
  35. def is_other(uchar):
  36. '''
  37. Checks for an unicode whether an ASCII or CJK character
  38. '''
  39. if not (is_cjk(uchar) or is_ascii(uchar)):
  40. return True
  41. else:
  42. return False
  43.  
  44. def nextpow2(x):
  45. '''
  46. If num isn't a power of 2, will return the next higher power of two
  47. '''
  48. if x>=1.0:
  49. return np.int(2**np.ceil(np.log2(x)))
  50. else:
  51. print "cannot convert negetive float to integer:",x
  52.  
  53. def getCharData(ft,uchar):
  54. '''
  55. '''
  56. # Use our helper function to get the widths of
  57. # the bitmap data that we will need in order to create
  58. # our texture.
  59.  
  60. if isinstance(uchar,int):
  61. glyph = ft.getmask(chr(uchar))
  62. elif isinstance(uchar,unicode):
  63. if is_other(uchar):
  64. return [None]*5
  65. else:
  66. glyph = ft.getmask(uchar)
  67. elif isinstance(uchar,str):
  68. uchar = unicode(uchar)
  69. if is_other(uchar):
  70. return [None]*5
  71. else:
  72. glyph = ft.getmask(uchar)
  73. else:
  74. return [None]*5
  75. glyph_width,glyph_height = glyph.size
  76. # We are using PIL's wrapping for FreeType. As a result, we don't have
  77. # direct access to glyph.advance or other attributes, so we add a 1 pixel pad.
  78. width = nextpow2(glyph_width + 1)
  79. height = nextpow2(glyph_height + 1)
  80. # python GL will accept lists of integers or strings, but not Numeric arrays
  81. # so, we buildup a string for our glyph's texture from the Numeric bitmap
  82.  
  83. # Here we fill in the data for the expanded bitmap.
  84. # Notice that we are using two channel bitmap (one for
  85. # luminocity and one for alpha), but we assign
  86. # both luminocity and alpha to the value that we
  87. # find in the FreeType bitmap.
  88. # We use the ?: operator so that value which we use
  89. # will be 0 if we are in the padding zone, and whatever
  90. # is the the Freetype bitmap otherwise.
  91. expanded_data = ""
  92. for j in xrange (height):
  93. for i in xrange (width):
  94. if (i >= glyph_width) or (j >= glyph_height):
  95. value = chr(0)
  96. expanded_data += value
  97. expanded_data += value
  98. else:
  99. value = chr(glyph.getpixel((i, j)))
  100. expanded_data += value
  101. expanded_data += value
  102.  
  103. return glyph_width,glyph_height,width,height,expanded_data
  104.  
  105. def make_dlist(ft,ch,list_base,tex_base_list,color=[0,1,0]):
  106. '''
  107. Given an integer char code, build a GL texture into texture_array,
  108. build a GL display list for display list number display_list_base + ch.
  109. Populate the glTexture for the integer ch and construct a display
  110. list that renders the texture for ch.
  111. Note, that display_list_base and texture_base are supposed
  112. to be preallocated for 256 consecutive display lists and and
  113. array of textures.
  114. '''
  115. # Load char data
  116. glyph_width,glyph_height,width,height,expanded_data = getCharData(ft,ch)
  117. if not glyph_width:
  118. return
  119. # -------------- Build the gl texture ------------
  120.  
  121. # Now we just setup some texture paramaters.
  122. ID = GL.glGenTextures(1)
  123. tex_base_list[ch] = ID
  124. GL.glBindTexture(GL.GL_TEXTURE_2D, ID)
  125. GL.glTexParameterf(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_MAG_FILTER,GL.GL_LINEAR)
  126. GL.glTexParameterf(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_MIN_FILTER,GL.GL_LINEAR)
  127.  
  128. border = 0
  129. # Here we actually create the texture itself, notice
  130. # that we are using GL_LUMINANCE_ALPHA to indicate that
  131. # we are using 2 channel data.
  132. GL.glTexImage2D(GL.GL_TEXTURE_2D,0,GL.GL_RGBA,width,height,border,
  133. GL.GL_LUMINANCE_ALPHA,GL.GL_UNSIGNED_BYTE,expanded_data)
  134.  
  135. # With the texture created, we don't need to expanded data anymore
  136. expanded_data = None
  137.  
  138. # --- Build the gl display list that draws the texture for this character ---
  139.  
  140. # So now we can create the display list
  141. GL.glNewList(list_base+ch,GL.GL_COMPILE)
  142.  
  143. if ch == ord(" "):
  144. glyph_advance = glyph_width
  145. GL.glTranslatef(glyph_advance, 0, 0)
  146. GL.glEndList()
  147. else:
  148. GL.glBindTexture(GL.GL_TEXTURE_2D, ID)
  149. GL.glPushMatrix()
  150.  
  151. # // first we need to move over a little so that
  152. # // the character has the right amount of space
  153. # // between it and the one before it.
  154. # glyph_left = glyph.bbox [0]
  155. # glTranslatef(glyph_left, 0, 0)
  156.  
  157. # // Now we move down a little in the case that the
  158. # // bitmap extends past the bottom of the line
  159. # // this is only true for characters like 'g' or 'y'.
  160. # glyph_descent = glyph.decent
  161. # glTranslatef(0, glyph_descent, 0)
  162.  
  163. # //Now we need to account for the fact that many of
  164. # //our textures are filled with empty padding space.
  165. # //We figure what portion of the texture is used by
  166. # //the actual character and store that information in
  167. # //the x and y variables, then when we draw the
  168. # //quad, we will only reference the parts of the texture
  169. # //that we contain the character itself.
  170. x = np.float(glyph_width)/np.float(width)
  171. y = np.float(glyph_height)/np.float(height)
  172.  
  173. # //Here we draw the texturemaped quads.
  174. # //The bitmap that we got from FreeType was not
  175. # //oriented quite like we would like it to be,
  176. # //so we need to link the texture to the quad
  177. # //so that the result will be properly aligned.
  178. GL.glBegin(GL.GL_QUADS)
  179. GL.glColor3fv(color)
  180. GL.glTexCoord2f(0,0), GL.glVertex2f(0,glyph_height)
  181. GL.glTexCoord2f(0,y), GL.glVertex2f(0,0)
  182. GL.glTexCoord2f(x,y), GL.glVertex2f(glyph_width,0)
  183. GL.glTexCoord2f(x,0), GL.glVertex2f(glyph_width, glyph_height)
  184. GL.glEnd()
  185. GL.glPopMatrix()
  186.  
  187. # Note, PIL's FreeType interface hides the advance from us.
  188. # Normal PIL clients are rendering an entire string through FreeType, not
  189. # a single character at a time like we are doing here.
  190. # Because the advance value is hidden from we will advance
  191. # the "pen" based upon the rendered glyph's width. This is imperfect.
  192. GL.glTranslatef(glyph_width + 0.75, 0, 0)
  193.  
  194. # //increment the raster position as if we were a bitmap font.
  195. # //(only needed if you want to calculate text length)
  196. # //glBitmap(0,0,0,0,face->glyph->advance.x >> 6,0,NULL)
  197.  
  198. # //Finnish the display list
  199. GL.glEndList()
  200. return
  201.  
  202. def dispCJK(ft,uchar,tex_base_list,color=[1,1,0]):
  203. '''
  204. '''
  205. # Load char data
  206. glyph_width,glyph_height,width,height,expanded_data = getCharData(ft,uchar)
  207. if glyph_width == None:
  208. return
  209. # -------------- Build the gl texture ------------
  210.  
  211. # Now we just setup some texture paramaters.
  212. ID = GL.glGenTextures(1)
  213. tex_base_list.append(ID)
  214. GL.glBindTexture(GL.GL_TEXTURE_2D, ID)
  215. GL.glTexParameterf(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_MAG_FILTER,GL.GL_LINEAR)
  216. GL.glTexParameterf(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_MIN_FILTER,GL.GL_LINEAR)
  217.  
  218. border = 0
  219. # Here we actually create the texture itself, notice
  220. # that we are using GL_LUMINANCE_ALPHA to indicate that
  221. # we are using 2 channel data.
  222. GL.glTexImage2D(GL.GL_TEXTURE_2D,0,GL.GL_RGBA,width,height,border,
  223. GL.GL_LUMINANCE_ALPHA,GL.GL_UNSIGNED_BYTE,expanded_data)
  224.  
  225. # With the texture created, we don't need to expanded data anymore
  226. expanded_data = None
  227. GL.glBindTexture(GL.GL_TEXTURE_2D, ID)
  228. GL.glPushMatrix()
  229. x = np.float(glyph_width)/np.float(width)
  230. y = np.float(glyph_height)/np.float(height)
  231. GL.glBegin(GL.GL_QUADS)
  232. GL.glColor3fv(color)
  233. GL.glTexCoord2f(0,0), GL.glVertex2f(0,glyph_height)
  234. GL.glTexCoord2f(0,y), GL.glVertex2f(0,0)
  235. GL.glTexCoord2f(x,y), GL.glVertex2f(glyph_width,0)
  236. GL.glTexCoord2f(x,0), GL.glVertex2f(glyph_width, glyph_height)
  237. GL.glEnd()
  238. GL.glPopMatrix()
  239. GL.glTranslatef(glyph_width + 0.75, 0, 0)
  240. return
  241.  
  242. def pushScreenCoordinateMatrix():
  243. # A fairly straight forward function that pushes
  244. # a projection matrix that will make object world
  245. # coordinates identical to window coordinates.
  246. GL.glPushAttrib(GL.GL_TRANSFORM_BIT)
  247. viewport = GL.glGetIntegerv(GL.GL_VIEWPORT)
  248. GL.glMatrixMode(GL.GL_PROJECTION)
  249. GL.glPushMatrix()
  250. GL.glLoadIdentity()
  251. GLU.gluOrtho2D(viewport[0],viewport[2],viewport[1],viewport[3])
  252. GL.glPopAttrib()
  253. return
  254.  
  255. def pop_projection_matrix():
  256. # Pops the projection matrix without changing the current
  257. # MatrixMode.
  258. GL.glPushAttrib(GL.GL_TRANSFORM_BIT)
  259. GL.glMatrixMode(GL.GL_PROJECTION)
  260. GL.glPopMatrix()
  261. GL.glPopAttrib()
  262. return
  263.  
  264. class font_data(object):
  265. '''
  266. '''
  267. def __init__(self, facename, pixel_height):
  268. # We haven't yet allocated textures or display lists
  269. self.m_allocated = False
  270. self.m_font_height = pixel_height
  271. self.m_facename = facename
  272.  
  273. # Try to obtain the FreeType font
  274. try:
  275. self.ft = ImageFont.truetype (facename, pixel_height)
  276. except:
  277. raise ValueError, "Unable to locate true type font '%s'" % (facename)
  278. # Here we ask opengl to allocate resources for
  279. # all the textures and displays lists which we
  280. # are about to create.
  281. # Note: only ASCII character
  282. n = 256
  283. self.m_list_base = GL.glGenLists(n)
  284.  
  285. # Consturct a list of 256 elements. This
  286. # list will be assigned the texture IDs we create for each glyph
  287. self.textures = [None] * n
  288. self.cjk_textures = []
  289. # This is where we actually create each of the fonts display lists.
  290. for i in xrange(n):
  291. make_dlist(self.ft, i, self.m_list_base, self.textures)
  292.  
  293. self.m_allocated = True
  294.  
  295. def glPrint(self,x,y,string,color=[1,0,0]):
  296. '''
  297. '''
  298. # We want a coordinate system where things coresponding to window pixels.
  299.  
  300. pushScreenCoordinateMatrix()
  301. # //We make the height about 1.5* that of
  302. h = np.float(self.m_font_height)/0.63
  303.  
  304. if not string:
  305. pop_projection_matrix()
  306. return
  307. else:
  308. if not isinstance(string,unicode):
  309. try:
  310. string = unicode(string)
  311. except:
  312. raise ValueError,"Can not convert to unicode",string
  313. # //Here is some code to split the text that we have been
  314. # //given into a set of lines.
  315. # //This could be made much neater by using
  316. # //a regular expression library such as the one avliable from
  317. # //boost.org (I've only done it out by hand to avoid complicating
  318. # //this tutorial with unnecessary library dependencies).
  319. # //Note: python string object has convenience method for this :)
  320. lines = string.split("\n")
  321. GL.glPushAttrib(GL.GL_LIST_BIT|GL.GL_CURRENT_BIT |GL.GL_ENABLE_BIT|GL.GL_TRANSFORM_BIT)
  322. GL.glMatrixMode(GL.GL_MODELVIEW)
  323. # GL.glDisable(GL.GL_LIGHTING)
  324. # GL.glEnable(GL.GL_TEXTURE_2D)
  325. # GL.glDisable(GL.GL_DEPTH_TEST)
  326. # GL.glEnable(GL.GL_BLEND)
  327. # GL.glBlendFunc(GL.GL_SRC_ALPHA,GL.GL_ONE_MINUS_SRC_ALPHA)
  328.  
  329. GL.glListBase(self.m_list_base)
  330. modelview_matrix = GL.glGetFloatv(GL.GL_MODELVIEW_MATRIX)
  331.  
  332. # //This is where the text display actually happens.
  333. # //For each line of text we reset the modelview matrix
  334. # //so that the line's text will start in the correct position.
  335. # //Notice that we need to reset the matrix, rather than just translating
  336. # //down by h. This is because when each character is
  337. # //draw it modifies the current matrix so that the next character
  338. # //will be drawn immediatly after it.
  339. for i in xrange(len(lines)):
  340. line = lines[i]
  341. GL.glPushMatrix()
  342. GL.glLoadIdentity ()
  343. GL.glTranslatef(x,y-h*i,0);
  344. GL.glMultMatrixf(modelview_matrix);
  345.  
  346. # // The commented out raster position stuff can be useful if you need to
  347. # // know the length of the text that you are creating.
  348. # // If you decide to use it make sure to also uncomment the glBitmap command
  349. # // in make_dlist().
  350. # // glRasterPos2f(0,0);
  351. # glCallLists (line)
  352. for tt in line:
  353. if is_cjk(tt):
  354. dispCJK(self.ft,tt,self.cjk_textures)
  355. else:
  356. # print 'ascii',tt
  357. GL.glCallList(ord(tt)+1)
  358. # // rpos = glGetFloatv (GL_CURRENT_RASTER_POSITION)
  359. # // float len=x-rpos[0];
  360. GL.glPopMatrix()
  361. GL.glPopAttrib()
  362. pop_projection_matrix()
  363.  
  364. def release(self):
  365. """ Release the gl resources for this Face.
  366. (This provides the functionality of KillFont () and font_data::clean ()
  367. """
  368. if self.m_allocated:
  369. # Free up the glTextures and the display lists for our face
  370. GL.glDeleteLists( self.m_list_base, 256);
  371. for ID in self.textures:
  372. GL.glDeleteTextures(ID)
  373. if self.cjk_textures:
  374. for ID in self.cjk_textures:
  375. GL.glDeleteTextures(ID)
  376. # Extra defensive. Clients that continue to try and use this object
  377. # will now trigger exceptions.
  378. self.list_base = None
  379. self.m_allocated = False
  380.  
  381. def __del__ (self):
  382. """ Python destructor for when no more refs to this Face object """
  383. self.release()
  384.  
  385. # Unit Test harness if this python module is run directly.
  386. if __name__=="__main__":
  387. print "testing availability of freetype font arial\n"
  388. ft = ImageFont.truetype ("Test.ttf", 15)
  389. if ft:
  390. print "Found the TrueType font 'Test.ttf'"
  391. else:
  392. print "faild to find the TrueTYpe font 'arial'\n"

freeTypeFont.py

  1. #! /usr/bin/env python
  2. #coding=utf-8
  3. # NeHe Tutorial Lesson: 43 - FreeType fonts in OpenGL
  4. #
  5. # Ported to PyOpenGL 2.0 by Brian Leair 18 Jan 2004
  6. #
  7. # This code was created by Jeff Molofee 2000
  8. #
  9. # The port was based on the PyOpenGL tutorials and from
  10. # PyOpenGLContext (tests/glprint.py)
  11. #
  12. # If you've found this code useful, feel free to let me know
  13. # at (Brian Leair telcom_sage@yahoo.com).
  14. #
  15. # See original source and C based tutorial at http://nehe.gamedev.net
  16. #
  17. # Note:
  18. # -----
  19. # This code is not an ideal example of Pythonic coding or use of OO
  20. # techniques. It is a simple and direct exposition of how to use the
  21. # Open GL API in Python via the PyOpenGL package. It also uses GLUT,
  22. # a high quality platform independent library. Due to using these APIs,
  23. # this code is more like a C program using procedural programming.
  24. #
  25. # To run this example you will need:
  26. # Python - www.python.org (v 2.3 as of 1/2004)
  27. # PyOpenGL - pyopengl.sourceforge.net (v 2.0.1.07 as of 1/2004)
  28. # Numeric Python - (v.22 of "numpy" as of 1/2004) numpy.sourceforge.net
  29. # Python Image Library - http://www.pythonware.com/products/pil/ (v1.1.4 or later)
  30. #
  31. # Make sure to get versions of Numeric, PyOpenGL, and PIL to match your
  32. # version of python.
  33. #
  34. #
  35.  
  36. from OpenGL.GL import *
  37. from OpenGL.GLUT import *
  38. from OpenGL.GLU import *
  39.  
  40. # Imports specific to Lesson 43
  41. #import glFreeType
  42. import freeTypeFont as glFreeType
  43. from math import cos
  44.  
  45. import sys
  46.  
  47. # Python 2.2 defines these directly
  48. try:
  49. True
  50. except NameError:
  51. True = 1==1
  52. False = 1==0
  53.  
  54. # Some api in the chain is translating the keystrokes to this octal string
  55. # so instead of saying: ESCAPE = 27, we use the following.
  56. ESCAPE = '\033'
  57.  
  58. # Number of the glut window.
  59. window = 0
  60.  
  61. our_font = None
  62.  
  63. # A general OpenGL initialization function. Sets all of the initial parameters.
  64. def InitGL(Width, Height): # We call this right after our OpenGL window is created.
  65. global our_font
  66. glShadeModel(GL_SMOOTH) # Enables Smooth Color Shading
  67. glClearColor(0.0, 0.0, 0.0, 0.5) # This Will Clear The Background Color To Black
  68. glClearDepth(1.0) # Enables Clearing Of The Depth Buffer
  69. glEnable(GL_DEPTH_TEST) # Enables Depth Testing
  70. glEnable(GL_TEXTURE_2D) # Enables texture mapping
  71. glDepthFunc(GL_LEQUAL) # The Type Of Depth Test To Do
  72. glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST) # Really Nice Perspective Calculations
  73.  
  74. # Currently omitting the wgl based font. See lesson13.py for example use of wgl font.
  75. # FYI, the ttf font file "Test.ttf" in lesson43 is the typeface "Arial Black Italic".
  76. # our_font = glFreeType.font_data ("ARBLI___.ttf", 16)
  77. # our_font = glFreeType.font_data ("Test.ttf", 16)
  78. our_font = glFreeType.font_data("wqy-zenhei.ttc",20)
  79. return True
  80.  
  81. # The function called when our window is resized (which shouldn't happen if you enable fullscreen, below)
  82. def ReSizeGLScene(Width, Height):
  83. if Height == 0: # Prevent A Divide By Zero If The Window Is Too Small
  84. Height = 1
  85.  
  86. glViewport(0, 0, Width, Height) # Reset The Current Viewport And Perspective Transformation
  87. glMatrixMode(GL_PROJECTION)
  88. glLoadIdentity()
  89. # // field of view, aspect ratio, near and far
  90. # This will squash and stretch our objects as the window is resized.
  91. gluPerspective(45.0, float(Width)/float(Height), 0.1, 100.0)
  92.  
  93. glMatrixMode(GL_MODELVIEW)
  94. glLoadIdentity()
  95.  
  96. cnt1 = 0
  97. # The main drawing function.
  98. def DrawGLScene():
  99. global cnt1
  100. global our_font
  101.  
  102. # Clear The Screen And The Depth Buffer
  103. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
  104. glLoadIdentity() # Reset The View
  105. # Step back (away from objects)
  106. glTranslatef (0.0, 0.0, -1.0)
  107.  
  108. # Currently - NYI - No WGL text
  109. # Blue Text
  110. # glColor3ub(0, 0, 0xff)
  111. #
  112. # // Position The WGL Text On The Screen
  113. # glRasterPos2f(-0.40f, 0.35f);
  114. # glPrint("Active WGL Bitmap Text With NeHe - %7.2f", cnt1);
  115.  
  116. # Red Text
  117. glColor3ub (0xff, 0, 0)
  118.  
  119. glPushMatrix ()
  120. glLoadIdentity ()
  121. # Spin the text, rotation around z axe == will appears as a 2d rotation of the text on our screen
  122. glRotatef (cnt1, 0, 0, 1)
  123. glScalef (1, 0.8 + 0.3* cos (cnt1/5), 1)
  124. glTranslatef (-180, 0, 0)
  125. our_font.glPrint(320, 240, u"Active123中文 \nFreeType Text 汉字- %7.2f\n{【丯丱丳丵饕餮】}、\n今日はとてもいい天気です。空は靑く" % (cnt1))
  126. glPopMatrix ()
  127.  
  128. # //Uncomment this to test out print's ability to handle newlines.
  129. # our_font.glPrint (320, 240, "Here\nthere\nbe\n\nnewlines %f\n." % (cnt1))
  130.  
  131. cnt1 += 0.091
  132. # cnt2 += 0.005
  133.  
  134. glutSwapBuffers()
  135. return
  136.  
  137. # The function called whenever a key is pressed. Note the use of Python tuples to pass in: (key, x, y)
  138. def keyPressed(*args):
  139. global window
  140. global our_font
  141. # If escape is pressed, kill everything.
  142. if args[0] == ESCAPE:
  143. our_font.release ()
  144. sys.exit()
  145.  
  146. def main():
  147. global window
  148. # pass arguments to init
  149. glutInit(sys.argv)
  150.  
  151. # Select type of Display mode:
  152. # Double buffer
  153. # RGBA color
  154. # Alpha components supported
  155. # Depth buffer
  156. glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH)
  157.  
  158. # get a 640 x 480 window
  159. glutInitWindowSize(640, 480)
  160.  
  161. # the window starts at the upper left corner of the screen
  162. glutInitWindowPosition(0, 0)
  163.  
  164. # Okay, like the C version we retain the window id to use when closing, but for those of you new
  165. # to Python (like myself), remember this assignment would make the variable local and not global
  166. # if it weren't for the global declaration at the start of main.
  167. window = glutCreateWindow("NeHe & Sven Olsen's TrueType Font Tutorial")
  168.  
  169. # Register the drawing function with glut, BUT in Python land, at least using PyOpenGL, we need to
  170. # set the function pointer and invoke a function to actually register the callback, otherwise it
  171. # would be very much like the C version of the code.
  172. glutDisplayFunc(DrawGLScene)
  173.  
  174. # Uncomment this line to get full screen.
  175. #glutFullScreen()
  176.  
  177. # When we are doing nothing, redraw the scene.
  178. glutIdleFunc(DrawGLScene)
  179.  
  180. # Register the function called when our window is resized.
  181. glutReshapeFunc(ReSizeGLScene)
  182.  
  183. # Register the function called when the keyboard is pressed.
  184. glutKeyboardFunc(keyPressed)
  185.  
  186. # Initialize our window.
  187. InitGL(640, 480)
  188.  
  189. # Start Event Processing Engine
  190. glutMainLoop()
  191.  
  192. # Print message to console, and kick off the main to get it rolling.
  193. print "Hit ESC key to quit."
  194. main()

lesson43.py

Ubuntu 14.04

Win7

PyOpenGL利用文泉驿正黑字体显示中文字体的更多相关文章

  1. Ubuntu安装文泉驿-微米黑字体

    sudo apt-get install ttf-wqy-microhei #文泉驿-微米黑

  2. fedora 下安装 文泉驿正黑体

    1. 可以到文泉驿正黑体的 主页 http://wenq.org/wqy2/index.cgi?%E9%A6%96%E9%A1%B5 最好能去官网表示一下支持 2. 也可以直接使用命令 :  sudo ...

  3. LinuxMint(Ubuntu)安装文泉驿家族黑体字

    文泉驿黑体字家族在Ubuntu上很有用,可以解决系统字体发虚的问题. 通过下面的三条命令安装: sudo apt-get install ttf-wqy-microhei #文泉驿-微米黑 sudo ...

  4. Ubuntu 14.04 64位字体美化(使用黑文泉驿)

    Ubuntu 14.04安装和升级后,,斜体字体变得很难看,昨天,我得到一个晚上,最终,管理一个线索,这里整洁. 在线调研后,.一致的观点是,,使用开源字体库文泉驿理想的黑色字体效果,效果甚至没有丢失 ...

  5. Ubuntu 12.04 设置终端字体为文泉驿(转载)

    转自:http://my.oschina.net/uniquejava/blog/98480 0.说明      在gnome-terminal终端中看习惯了文泉驿微米黑字体,没想到从11.10升级到 ...

  6. Centos 下安装 文泉驿 字体 Odoo

    刚装完centos下的odoo的字体 文泉驿 ,一万头草泥马呼啸而过.....劝君如非必要,千万别再centos下折腾odoo..... 正题,文泉驿官网 只提供 deb包和源码包的字体安装 ,想在c ...

  7. Kali安装使用文泉驿字体

    安装文泉驿字体 Kali选择"简体中文"安装后,在终端等地方发现字体总有重叠,只要安装中文字体即可,这里推荐文泉驿字体.文泉驿是一个以开发开源.免费中文电子资源--如汉字字体.词库 ...

  8. QT程序中显示中文字体解决办法

    Qt4.7.1 默认没有中文字体库,迅为给用户提供“文泉驿”字体和配置方法.本节需要的 文件在网盘: 用一个简单测试程序说明“文泉驿”字体的配置方法. 在 Qt Creater 新建工程“nihao” ...

  9. 如何制作prezi swf格式字体(prezi 中文字体)

    如何制作prezi swf格式字体(prezi 中文字体) 文/玄魂 前言 Prezi软件虽然没有正式进入中国,但是中国的Prezi爱好者却在不遗余力的推广着Prezi.我接触这款软件比较晚,但是从接 ...

随机推荐

  1. 分页pagination实现及其应用

    1.分页jquery.page.js //分页插件 /** 2014-08-05 ch **/ (function ($) { var ms = { init: function (obj, args ...

  2. Java学习笔记(六)——google java编程风格指南(下)

    [前面的话] 年后开始正式上班,计划着想做很多事情,但是总会有这样那样的打扰,不知道是自己要求太高还是自我的奋斗意识不够?接下来好好加油.好好学学技术,好好学习英语,好好学习做点自己喜欢的事情,趁着自 ...

  3. 图片百分百问题 z-index问题

    遇到的问题:     1.图片设置宽高都为100%,为什么高度没有100%呢?  我日了狗了!         答:因为图片默认高度大于包含框, 此时元素的高度100%将不会参照父元素? 继承出现了问 ...

  4. RAID 磁盘状态为foreign,怎么变成ready

    我们在关掉电源,插入三块硬盘,打开电源 这时候: 首先启动服务器,出现[Press<ctrl><R>to Run Configuration Utility]提示时,按下ctr ...

  5. Html-input文本框只能输入数字

    onKeyPress="if ((event.keyCode < 48 || event.keyCode > 57)) event.returnValue = false;&qu ...

  6. Spring-如何实现事物管理的

    事务的实现方式 实现方式共有两种:编码方式:声明式事务管理方式.基于AOP技术实现的声明式事务管理,实质就是:在方法执行前后进行拦截,然后在目标方法开始之前创建并加入事务,执行完目标方法后根据执行情况 ...

  7. 【POJ 2923】Relocation(状压DP+DP)

    题意是给你n个物品,每次两辆车运,容量分别是c1,c2,求最少运送次数.好像不是很好想,我看了网上的题解才做出来.先用状压DP计算i状态下,第一辆可以运送的重量,用该状态的重量总和-第一辆可以运送的, ...

  8. 【ZOJ 1221】Risk

    题 题意 给你20个城市的相邻关系,求给定任意两个城市的最短距离 分析 求任意两个城市最短距离,就是用floyd算法,我脑残忘记了k是写在最外层的. 代码 #include<stdio.h> ...

  9. 【BZOJ-2223】PATULJCI 可持久化线段树

    2223: [Coci 2009]PATULJCI Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 728  Solved: 292[Submit][S ...

  10. codevs3031 最富有的人

    题目描述 Description 在你的面前有n堆金子,你只能取走其中的两堆,且总价值为这两堆金子的xor值,你想成为最富有的人,你就要有所选择. 输入描述 Input Description 第一行 ...