首页 > 代码库 > PyOpenGL利用文泉驿正黑字体显示中文字体

PyOpenGL利用文泉驿正黑字体显示中文字体

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

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

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

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

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

python代码:

glFreeType.py

  1 #! /usr/bin/env python  2 #coding=utf-8  3 #    A quick and simple opengl font library that uses GNU freetype2, written  4 #    and distributed as part of a tutorial for nehe.gamedev.net.  5 #    Sven Olsen, 2003  6 #    Translated to PyOpenGL by Brian Leair, 2004  7 #   8 #  9  10  11  12 # import freetype 13 # We are going to use Python Image Library‘s font handling 14 # From PIL 1.1.4: 15 import ImageFont 16 from OpenGL.GL import * 17 from OpenGL.GLU import * 18  19  20 # Python 2.2 defines these directly 21 try: 22     True 23 except NameError: 24     True = 1==1 25     False = 1==0 26  27 def is_chinese(uchar): 28     ‘‘‘ 29     ‘‘‘ 30 #    if uchar>=u‘\u4e00‘ and uchar<=u‘\u9fa5‘: 31     if uchar>=u\u2e80 and uchar<=u\ufe4f: 32         return True 33     else: 34         return False 35 def is_number(uchar): 36     """判断一个unicode是否是数字""" 37     if uchar >= u\u0030 and uchar<=u\u0039: 38         return True 39     else: 40         return False 41       42 def is_alphabet(uchar): 43     """判断一个unicode是否是英文字母""" 44     if (uchar >= u\u0041 and uchar<=u\u005a) or (uchar >= u\u0061 and uchar<=u\u007a): 45         return True 46     else: 47         return False 48  49 def is_other(uchar): 50     """判断是否非汉字,数字和英文字符""" 51     if not (is_chinese(uchar) or is_number(uchar) or is_alphabet(uchar)): 52         return True 53     else: 54         return False     55 def string2List(ustring): 56     """将ustring按照中文,字母,数字分开""" 57     retList=[] 58     utmp=[] 59     for uchar in ustring: 60         if is_other(uchar): 61             if len(utmp)==0: 62                 continue 63             else: 64                 retList.append("".join(utmp)) 65                 utmp=[] 66         else: 67             utmp.append(uchar) 68     if len(utmp)!=0: 69         retList.append("".join(utmp)) 70     return retList 71  72 def is_font_available (ft, facename): 73     """ Returns true if FreeType can find the requested face name  74         Pass the basname of the font e.g. "arial" or "times new roman" 75     """ 76     if (facename in ft.available_fonts ()): 77         return True 78     return False 79  80  81 def next_p2 (num): 82     """ If num isn‘t a power of 2, will return the next higher power of two """ 83     rval = 1 84     while (rval<num): 85         rval <<= 1 86     return rval 87  88 def dispChinese(ft,ch): 89     ‘‘‘ 90     ‘‘‘ 91     glyph = ft.getmask(ch) 92     glyph_width,glyph_height = glyph.size 93     width = next_p2 (glyph_width + 1) 94     height = next_p2 (glyph_height + 1)     95     expanded_data = http://www.mamicode.com/"" 96     for j in xrange (height): 97         for i in xrange (width): 98             if (i >= glyph_width) or (j >= glyph_height): 99                 value =http://www.mamicode.com/ chr (0)100                 expanded_data += value101                 expanded_data += value102             else:103                 value =http://www.mamicode.com/ chr (glyph.getpixel ((i, j)))104                 expanded_data += value105                 expanded_data += value106     # -------------- Build the gl texture ------------107     108     # Now we just setup some texture paramaters.109     ID = glGenTextures (1)110     glBindTexture (GL_TEXTURE_2D, ID)111     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)112     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)113     114     border = 0115     # Here we actually create the texture itself, notice116     # that we are using GL_LUMINANCE_ALPHA to indicate that117     # we are using 2 channel data.118     glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, width, height,119         border, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, expanded_data )120     121     # With the texture created, we don‘t need to expanded data anymore122     expanded_data =http://www.mamicode.com/ None123     glBindTexture (GL_TEXTURE_2D, ID)124     125     glPushMatrix()126     127             # // first we need to move over a little so that128             # // the character has the right amount of space129             # // between it and the one before it.130             # glyph_left = glyph.bbox [0]131             # glTranslatef(glyph_left, 0, 0)132     133             # // Now we move down a little in the case that the134             # // bitmap extends past the bottom of the line 135             # // this is only true for characters like ‘g‘ or ‘y‘.136             # glyph_descent = glyph.decent137             # glTranslatef(0, glyph_descent, 0)138     139             # //Now we need to account for the fact that many of140             # //our textures are filled with empty padding space.141             # //We figure what portion of the texture is used by 142             # //the actual character and store that information in 143             # //the x and y variables, then when we draw the144             # //quad, we will only reference the parts of the texture145             # //that we contain the character itself.146     x=float (glyph_width) / float (width)147     y=float (glyph_height) / float (height)148     149             # //Here we draw the texturemaped quads.150             # //The bitmap that we got from FreeType was not 151             # //oriented quite like we would like it to be,152             # //so we need to link the texture to the quad153             # //so that the result will be properly aligned.154     glBegin(GL_QUADS)155     glColor3f(1,1,0)156     glTexCoord2f(0,0), glVertex2f(0,glyph_height)157     glTexCoord2f(0,y), glVertex2f(0,0)158     glTexCoord2f(x,y), glVertex2f(glyph_width,0)159     glTexCoord2f(x,0), glVertex2f(glyph_width, glyph_height)160     glEnd()161     glPopMatrix()162     163             # Note, PIL‘s FreeType interface hides the advance from us.164             # Normal PIL clients are rendering an entire string through FreeType, not165             # a single character at a time like we are doing here.166             # Because the advance value is hidden from we will advance167             # the "pen" based upon the rendered glyph‘s width. This is imperfect.168     glTranslatef(glyph_width + 0.75, 0, 0)169     170 def make_dlist (ft, ch, list_base, tex_base_list):171     """ Given an integer char code, build a GL texture into texture_array,172         build a GL display list for display list number display_list_base + ch.173         Populate the glTexture for the integer ch and construct a display174         list that renders the texture for ch.175         Note, that display_list_base and texture_base are supposed176         to be preallocated for 128 consecutive display lists and and 177         array of textures.178     """179 180     # //The first thing we do is get FreeType to render our character181     # //into a bitmap.  This actually requires a couple of FreeType commands:182     # //Load the Glyph for our character.183     # //Move the face‘s glyph into a Glyph object.184     # //Convert the glyph to a bitmap.185     # //This reference will make accessing the bitmap easier186     # - This is the 2 dimensional Numeric array187 188     # Use our helper function to get the widths of189     # the bitmap data that we will need in order to create190     # our texture.191     192     glyph = ft.getmask (chr (ch))193     glyph_width, glyph_height = glyph.size 194     # We are using PIL‘s wrapping for FreeType. As a result, we don‘t have 195     # direct access to glyph.advance or other attributes, so we add a 1 pixel pad.196     width = next_p2 (glyph_width + 1)197     height = next_p2 (glyph_height + 1)198 199 200     # python GL will accept lists of integers or strings, but not Numeric arrays201     # so, we buildup a string for our glyph‘s texture from the Numeric bitmap 202 203     # Here we fill in the data for the expanded bitmap.204     # Notice that we are using two channel bitmap (one for205     # luminocity and one for alpha), but we assign206     # both luminocity and alpha to the value that we207     # find in the FreeType bitmap. 208     # We use the ?: operator so that value which we use209     # will be 0 if we are in the padding zone, and whatever210     # is the the Freetype bitmap otherwise.211     expanded_data = http://www.mamicode.com/""212     for j in xrange (height):213         for i in xrange (width):214             if (i >= glyph_width) or (j >= glyph_height):215                 value =http://www.mamicode.com/ chr (0)216                 expanded_data += value217                 expanded_data += value218             else:219                 value =http://www.mamicode.com/ chr (glyph.getpixel ((i, j)))220                 expanded_data += value221                 expanded_data += value222 223     # -------------- Build the gl texture ------------224 225     # Now we just setup some texture paramaters.226     ID = glGenTextures (1)227     tex_base_list [ch] = ID228     glBindTexture (GL_TEXTURE_2D, ID)229     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)230     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)231 232     border = 0233     # Here we actually create the texture itself, notice234     # that we are using GL_LUMINANCE_ALPHA to indicate that235     # we are using 2 channel data.236     glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, width, height,237         border, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, expanded_data )238 239     # With the texture created, we don‘t need to expanded data anymore240     expanded_data =http://www.mamicode.com/ None241 242 243 244     # --- Build the gl display list that draws the texture for this character ---245 246     # So now we can create the display list247     glNewList (list_base + ch, GL_COMPILE)248 249     if (ch == ord (" ")):250         glyph_advance = glyph_width251         glTranslatef(glyph_advance, 0, 0)252         glEndList()253     else:254 255         glBindTexture (GL_TEXTURE_2D, ID)256 257         glPushMatrix()258 259         # // first we need to move over a little so that260         # // the character has the right amount of space261         # // between it and the one before it.262         # glyph_left = glyph.bbox [0]263         # glTranslatef(glyph_left, 0, 0)264 265         # // Now we move down a little in the case that the266         # // bitmap extends past the bottom of the line 267         # // this is only true for characters like ‘g‘ or ‘y‘.268         # glyph_descent = glyph.decent269         # glTranslatef(0, glyph_descent, 0)270 271         # //Now we need to account for the fact that many of272         # //our textures are filled with empty padding space.273         # //We figure what portion of the texture is used by 274         # //the actual character and store that information in 275         # //the x and y variables, then when we draw the276         # //quad, we will only reference the parts of the texture277         # //that we contain the character itself.278         x=float (glyph_width) / float (width)279         y=float (glyph_height) / float (height)280 281         # //Here we draw the texturemaped quads.282         # //The bitmap that we got from FreeType was not 283         # //oriented quite like we would like it to be,284         # //so we need to link the texture to the quad285         # //so that the result will be properly aligned.286         glBegin(GL_QUADS)287         glColor3f(0,1,0)288         glTexCoord2f(0,0), glVertex2f(0,glyph_height)289         glTexCoord2f(0,y), glVertex2f(0,0)290         glTexCoord2f(x,y), glVertex2f(glyph_width,0)291         glTexCoord2f(x,0), glVertex2f(glyph_width, glyph_height)292         glEnd()293         glPopMatrix()294 295         # Note, PIL‘s FreeType interface hides the advance from us.296         # Normal PIL clients are rendering an entire string through FreeType, not297         # a single character at a time like we are doing here.298         # Because the advance value is hidden from we will advance299         # the "pen" based upon the rendered glyph‘s width. This is imperfect.300         glTranslatef(glyph_width + 0.75, 0, 0)301 302         # //increment the raster position as if we were a bitmap font.303         # //(only needed if you want to calculate text length)304         # //glBitmap(0,0,0,0,face->glyph->advance.x >> 6,0,NULL)305 306         # //Finnish the display list307         glEndList()308 309     return310 311 # /// A fairly straight forward function that pushes312 # /// a projection matrix that will make object world 313 # /// coordinates identical to window coordinates.314 def pushScreenCoordinateMatrix():315     glPushAttrib(GL_TRANSFORM_BIT)316     viewport = glGetIntegerv(GL_VIEWPORT)317     glMatrixMode(GL_PROJECTION)318     glPushMatrix()319     glLoadIdentity()320     gluOrtho2D(viewport[0],viewport[2],viewport[1],viewport[3])321     glPopAttrib()322     return323 324 325 # Pops the projection matrix without changing the current326 # MatrixMode.327 def pop_projection_matrix():328     glPushAttrib(GL_TRANSFORM_BIT)329     glMatrixMode(GL_PROJECTION)330     glPopMatrix()331     glPopAttrib()332     return333 334 335 class font_data:336     def __init__ (self, facename, pixel_height):337         # We haven‘t yet allocated textures or display lists338         self.m_allocated = False339         self.m_font_height = pixel_height340         self.m_facename = facename341 342         # Try to obtain the FreeType font343         try:344             ft = ImageFont.truetype (facename, pixel_height)345         except:346             raise ValueError, "Unable to locate true type font ‘%s‘" % (facename)347         self.ft = ft348         # Here we ask opengl to allocate resources for349         # all the textures and displays lists which we350         # are about to create.  351         n = 128*2352         self.m_list_base = glGenLists (n)353 354         # Consturct a list of 128 elements. This355         # list will be assigned the texture IDs we create for each glyph356         self.textures = [None] * n357 358         # This is where we actually create each of the fonts display lists.359         for i in xrange (n):360             make_dlist (ft, i, self.m_list_base, self.textures);361 362         self.m_allocated = True363 364 365         # //We don‘t need the face information now that the display366         # //lists have been created, so we free the assosiated resources.367         # Note: Don‘t need this, as python will decref and dealloc the ft for us.368 #        ft = None369         return370 371     def glPrint (self, x, y, string):372         """373         # ///Much like Nehe‘s glPrint function, but modified to work374         # ///with freetype fonts.375         """376         # We want a coordinate system where things coresponding to window pixels.377         pushScreenCoordinateMatrix()378     379         # //We make the height about 1.5* that of380         h = float (self.m_font_height) / 0.63        381     382         # If There‘s No Text383         # Do Nothing384         if (string == None):385             pop_projection_matrix()386             return387         if (string == ""):388             pop_projection_matrix()389             return390 391         # //Here is some code to split the text that we have been392         # //given into a set of lines.  393         # //This could be made much neater by using394         # //a regular expression library such as the one avliable from395         # //boost.org (I‘ve only done it out by hand to avoid complicating396         # //this tutorial with unnecessary library dependencies).397         # //Note: python string object has convenience method for this :)398         lines = string.split ("\n")399         400         glPushAttrib(GL_LIST_BIT | GL_CURRENT_BIT  | GL_ENABLE_BIT | GL_TRANSFORM_BIT)401         glMatrixMode(GL_MODELVIEW)402         glDisable(GL_LIGHTING)403         glEnable(GL_TEXTURE_2D)404         glDisable(GL_DEPTH_TEST)405         glEnable(GL_BLEND)406         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)407 408         glListBase(self.m_list_base)409         modelview_matrix = glGetFloatv(GL_MODELVIEW_MATRIX)410 411         # //This is where the text display actually happens.412         # //For each line of text we reset the modelview matrix413         # //so that the line‘s text will start in the correct position.414         # //Notice that we need to reset the matrix, rather than just translating415         # //down by h. This is because when each character is416         # //draw it modifies the current matrix so that the next character417         # //will be drawn immediatly after it.  418         for i in xrange (len (lines)):419             line = lines [i]420             glPushMatrix ()421             glLoadIdentity ()422             glTranslatef (x,y-h*i,0);423             glMultMatrixf (modelview_matrix);424 425             # //  The commented out raster position stuff can be useful if you need to426             # //  know the length of the text that you are creating.427             # //  If you decide to use it make sure to also uncomment the glBitmap command428             # //  in make_dlist().429             # //    glRasterPos2f(0,0);430 #            glCallLists (line)431             for tt in line:432                 if is_chinese(tt):433                     dispChinese(self.ft,tt)434                 else:435                     glCallList(ord(tt)+1)436             # //    rpos = glGetFloatv (GL_CURRENT_RASTER_POSITION)437             # //    float len=x-rpos[0];438             glPopMatrix()439 440         glPopAttrib()441         pop_projection_matrix()442         return443 444     def release (self):445         """ Release the gl resources for this Face.446             (This provides the functionality of KillFont () and font_data::clean ()447         """448         if (self.m_allocated):449             # Free up the glTextures and the display lists for our face450             glDeleteLists ( self.m_list_base, 256);451             for ID in self.textures:452                 glDeleteTextures (ID);453             # Extra defensive. Clients that continue to try and use this object454             # will now trigger exceptions.455             self.list_base = None456             self.m_allocated = False457         return458 459     def __del__ (self):460         """ Python destructor for when no more refs to this Face object """461         self.release ()462         return463 464 465 # Unit Test harness if this python module is run directly.466 if __name__=="__main__":467     print "testing availability of freetype font arial\n"468     ft = ImageFont.truetype ("Test.ttf", 15)469     if ft:470         print "Found the TrueType font ‘Test.ttf‘"471     else:472         print "faild to find the TrueTYpe font ‘arial‘\n"473     ft2 = ImageFont.truetype("wqy-zenhei.ttc",15)474     if ft2:475         print "Found the TrueType font ‘wqy-zenhei.ttc‘"476     else:477         print "Failed to find the TrueType font ‘wqy-zenhei.ttc‘\n"478     ss = u"ceatefed中文你125中文addb测试"479     ret = string2List(ss)480     print len(ret),len(ret[0]),ret[0][1],ret[0][12]481     print482     for tt in ss:483         print tt484         if not is_chinese(tt):print ord(tt)

 

lesson43.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 from math import cos 43  44 import sys 45  46 # Python 2.2 defines these directly 47 try: 48     True 49 except NameError: 50     True = 1==1 51     False = 1==0 52  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  82  83 # The function called when our window is resized (which shouldn‘t happen if you enable fullscreen, below) 84 def ReSizeGLScene(Width, Height): 85     if Height == 0:                        # Prevent A Divide By Zero If The Window Is Too Small  86         Height = 1 87  88     glViewport(0, 0, Width, Height)        # Reset The Current Viewport And Perspective Transformation 89     glMatrixMode(GL_PROJECTION) 90     glLoadIdentity() 91     # // field of view, aspect ratio, near and far 92     # This will squash and stretch our objects as the window is resized. 93     gluPerspective(45.0, float(Width)/float(Height), 0.1, 100.0) 94  95     glMatrixMode(GL_MODELVIEW) 96     glLoadIdentity() 97  98 cnt1 = 0 99 # The main drawing function. 100 def DrawGLScene():101     global cnt1102     global our_font103 104     # Clear The Screen And The Depth Buffer105     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)106     glLoadIdentity()                    # Reset The View 107     # Step back (away from objects)108     glTranslatef (0.0, 0.0, -1.0)109 110     # Currently - NYI - No WGL text111     # Blue Text112     # glColor3ub(0, 0, 0xff)113     #114     # // Position The WGL Text On The Screen115     # glRasterPos2f(-0.40f, 0.35f);116      # glPrint("Active WGL Bitmap Text With NeHe - %7.2f", cnt1);    117 118     # Red Text119     glColor3ub (0xff, 0, 0)120 121     glPushMatrix ()122     glLoadIdentity ()123     # Spin the text, rotation around z axe == will appears as a 2d rotation of the text on our screen124     glRotatef (cnt1, 0, 0, 1)125     glScalef (1, 0.8 + 0.3* cos (cnt1/5), 1)126     glTranslatef (-180, 0, 0)127     our_font.glPrint(320, 240, u"Active123中文 \nFreeType Text 汉字- %7.2f\n{【丯丱丳丵饕餮】}、\n今日はとてもいい天気です。空は靑く" % (cnt1))128     glPopMatrix ()129 130     # //Uncomment this to test out print‘s ability to handle newlines.131     # our_font.glPrint (320, 240, "Here\nthere\nbe\n\nnewlines %f\n." % (cnt1))132 133     cnt1 += 0.091134     # cnt2 += 0.005135 136     glutSwapBuffers()137     return138 139 140 # The function called whenever a key is pressed. Note the use of Python tuples to pass in: (key, x, y)  141 def keyPressed(*args):142     global window143     global our_font144     # If escape is pressed, kill everything.145     if args[0] == ESCAPE:146         our_font.release ()147         sys.exit()148 149 def main():150     global window151     # pass arguments to init152     glutInit(sys.argv)153 154     # Select type of Display mode:   155     #  Double buffer 156     #  RGBA color157     # Alpha components supported 158     # Depth buffer159     glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH)160     161     # get a 640 x 480 window 162     glutInitWindowSize(640, 480)163     164     # the window starts at the upper left corner of the screen 165     glutInitWindowPosition(0, 0)166     167     # Okay, like the C version we retain the window id to use when closing, but for those of you new168     # to Python (like myself), remember this assignment would make the variable local and not global169     # if it weren‘t for the global declaration at the start of main.170     window = glutCreateWindow("NeHe & Sven Olsen‘s TrueType Font Tutorial")171 172        # Register the drawing function with glut, BUT in Python land, at least using PyOpenGL, we need to173     # set the function pointer and invoke a function to actually register the callback, otherwise it174     # would be very much like the C version of the code.    175     glutDisplayFunc(DrawGLScene)176     177     # Uncomment this line to get full screen.178     #glutFullScreen()179 180     # When we are doing nothing, redraw the scene.181     glutIdleFunc(DrawGLScene)182     183     # Register the function called when our window is resized.184     glutReshapeFunc(ReSizeGLScene)185     186     # Register the function called when the keyboard is pressed.  187     glutKeyboardFunc(keyPressed)188 189     # Initialize our window. 190     InitGL(640, 480)191 192     # Start Event Processing Engine    193     glutMainLoop()194 195 # Print message to console, and kick off the main to get it rolling.196 print "Hit ESC key to quit."197 main()

 

PyOpenGL利用文泉驿正黑字体显示中文字体