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

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

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

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

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

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

 


 

16/09/14 晚补注:

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

import ImageFont

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         
139         
140     # --- Build the gl display list that draws the texture for this character ---
141         
142     # So now we can create the display list
143     GL.glNewList(list_base+ch,GL.GL_COMPILE)
144         
145     if ch == ord(" "):
146         glyph_advance = glyph_width
147         GL.glTranslatef(glyph_advance, 0, 0)
148         GL.glEndList()
149     else:
150         GL.glBindTexture(GL.GL_TEXTURE_2D, ID)
151         GL.glPushMatrix()
152         
153         # // first we need to move over a little so that
154         # // the character has the right amount of space
155         # // between it and the one before it.
156         # glyph_left = glyph.bbox [0]
157         # glTranslatef(glyph_left, 0, 0)
158         
159         # // Now we move down a little in the case that the
160         # // bitmap extends past the bottom of the line 
161         # // this is only true for characters like 'g' or 'y'.
162         # glyph_descent = glyph.decent
163         # glTranslatef(0, glyph_descent, 0)
164         
165         # //Now we need to account for the fact that many of
166         # //our textures are filled with empty padding space.
167         # //We figure what portion of the texture is used by 
168         # //the actual character and store that information in 
169         # //the x and y variables, then when we draw the
170         # //quad, we will only reference the parts of the texture
171         # //that we contain the character itself.
172         x = np.float(glyph_width)/np.float(width)
173         y = np.float(glyph_height)/np.float(height)
174         
175         # //Here we draw the texturemaped quads.
176         # //The bitmap that we got from FreeType was not 
177         # //oriented quite like we would like it to be,
178         # //so we need to link the texture to the quad
179         # //so that the result will be properly aligned.
180         GL.glBegin(GL.GL_QUADS)
181         GL.glColor3fv(color)
182         GL.glTexCoord2f(0,0), GL.glVertex2f(0,glyph_height)
183         GL.glTexCoord2f(0,y), GL.glVertex2f(0,0)
184         GL.glTexCoord2f(x,y), GL.glVertex2f(glyph_width,0)
185         GL.glTexCoord2f(x,0), GL.glVertex2f(glyph_width, glyph_height)
186         GL.glEnd()
187         GL.glPopMatrix()
188         
189         # Note, PIL's FreeType interface hides the advance from us.
190         # Normal PIL clients are rendering an entire string through FreeType, not
191         # a single character at a time like we are doing here.
192         # Because the advance value is hidden from we will advance
193         # the "pen" based upon the rendered glyph's width. This is imperfect.
194         GL.glTranslatef(glyph_width + 0.75, 0, 0)
195         
196         # //increment the raster position as if we were a bitmap font.
197         # //(only needed if you want to calculate text length)
198         # //glBitmap(0,0,0,0,face->glyph->advance.x >> 6,0,NULL)
199         
200         # //Finnish the display list
201         GL.glEndList()
202     return
203 
204 def dispCJK(ft,uchar,tex_base_list,color=[1,1,0]):
205     '''
206     '''
207     # Load char data
208     glyph_width,glyph_height,width,height,expanded_data = getCharData(ft,uchar)
209     if glyph_width == None:
210         return            
211     # -------------- Build the gl texture ------------
212             
213     # Now we just setup some texture paramaters.
214     ID = GL.glGenTextures(1)
215     tex_base_list.append(ID)
216     GL.glBindTexture(GL.GL_TEXTURE_2D, ID)
217     GL.glTexParameterf(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_MAG_FILTER,GL.GL_LINEAR)
218     GL.glTexParameterf(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_MIN_FILTER,GL.GL_LINEAR)
219             
220     border = 0
221     # Here we actually create the texture itself, notice
222     # that we are using GL_LUMINANCE_ALPHA to indicate that
223     # we are using 2 channel data.
224     GL.glTexImage2D(GL.GL_TEXTURE_2D,0,GL.GL_RGBA,width,height,border,
225         GL.GL_LUMINANCE_ALPHA,GL.GL_UNSIGNED_BYTE,expanded_data)
226             
227     # With the texture created, we don't need to expanded data anymore
228     expanded_data = None    
229     GL.glBindTexture(GL.GL_TEXTURE_2D, ID)
230     GL.glPushMatrix()
231     x = np.float(glyph_width)/np.float(width)
232     y = np.float(glyph_height)/np.float(height)        
233     GL.glBegin(GL.GL_QUADS)
234     GL.glColor3fv(color)
235     GL.glTexCoord2f(0,0), GL.glVertex2f(0,glyph_height)
236     GL.glTexCoord2f(0,y), GL.glVertex2f(0,0)
237     GL.glTexCoord2f(x,y), GL.glVertex2f(glyph_width,0)
238     GL.glTexCoord2f(x,0), GL.glVertex2f(glyph_width, glyph_height)
239     GL.glEnd()
240     GL.glPopMatrix()
241     GL.glTranslatef(glyph_width + 0.75, 0, 0)
242     return
243 
244 
245 def pushScreenCoordinateMatrix():
246     # A fairly straight forward function that pushes
247     # a projection matrix that will make object world 
248     # coordinates identical to window coordinates.    
249     GL.glPushAttrib(GL.GL_TRANSFORM_BIT)
250     viewport = GL.glGetIntegerv(GL.GL_VIEWPORT)
251     GL.glMatrixMode(GL.GL_PROJECTION)
252     GL.glPushMatrix()
253     GL.glLoadIdentity()
254     GLU.gluOrtho2D(viewport[0],viewport[2],viewport[1],viewport[3])
255     GL.glPopAttrib()
256     return
257 
258 
259 
260 def pop_projection_matrix():
261     # Pops the projection matrix without changing the current
262     # MatrixMode.    
263     GL.glPushAttrib(GL.GL_TRANSFORM_BIT)
264     GL.glMatrixMode(GL.GL_PROJECTION)
265     GL.glPopMatrix()
266     GL.glPopAttrib()
267     return
268 
269     
270 class font_data(object):
271     '''
272     '''
273     def __init__(self, facename, pixel_height):
274         # We haven't yet allocated textures or display lists
275         self.m_allocated = False
276         self.m_font_height = pixel_height
277         self.m_facename = facename
278         
279         # Try to obtain the FreeType font
280         try:
281             self.ft = ImageFont.truetype (facename, pixel_height)
282         except:
283             raise ValueError, "Unable to locate true type font '%s'" % (facename)
284         # Here we ask opengl to allocate resources for
285         # all the textures and displays lists which we
286         # are about to create.  
287         # Note: only ASCII character
288         n = 256
289         self.m_list_base = GL.glGenLists(n)
290         
291         # Consturct a list of 256 elements. This
292         # list will be assigned the texture IDs we create for each glyph
293         self.textures = [None] * n
294         self.cjk_textures = []
295         # This is where we actually create each of the fonts display lists.
296         for i in xrange(n):
297             make_dlist(self.ft, i, self.m_list_base, self.textures)
298         
299         self.m_allocated = True
300     
301     def glPrint(self,x,y,string,color=[1,0,0]):
302         '''
303         '''
304         # We want a coordinate system where things coresponding to window pixels.
305         
306         pushScreenCoordinateMatrix()            
307         # //We make the height about 1.5* that of
308         h = np.float(self.m_font_height)/0.63
309         
310         if not string:
311             pop_projection_matrix()
312             return
313         else:
314             if not isinstance(string,unicode):
315                 try:
316                     string = unicode(string)
317                 except:
318                     raise ValueError,"Can not convert to unicode",string
319             # //Here is some code to split the text that we have been
320             # //given into a set of lines.  
321             # //This could be made much neater by using
322             # //a regular expression library such as the one avliable from
323             # //boost.org (I've only done it out by hand to avoid complicating
324             # //this tutorial with unnecessary library dependencies).
325             # //Note: python string object has convenience method for this :)
326             lines = string.split("\n")
327             GL.glPushAttrib(GL.GL_LIST_BIT|GL.GL_CURRENT_BIT |GL.GL_ENABLE_BIT|GL.GL_TRANSFORM_BIT)
328             GL.glMatrixMode(GL.GL_MODELVIEW)
329 #            GL.glDisable(GL.GL_LIGHTING)
330 #            GL.glEnable(GL.GL_TEXTURE_2D)
331 #            GL.glDisable(GL.GL_DEPTH_TEST)
332 #            GL.glEnable(GL.GL_BLEND)
333 #            GL.glBlendFunc(GL.GL_SRC_ALPHA,GL.GL_ONE_MINUS_SRC_ALPHA)
334             
335             GL.glListBase(self.m_list_base)
336             modelview_matrix = GL.glGetFloatv(GL.GL_MODELVIEW_MATRIX)
337             
338             # //This is where the text display actually happens.
339             # //For each line of text we reset the modelview matrix
340             # //so that the line's text will start in the correct position.
341             # //Notice that we need to reset the matrix, rather than just translating
342             # //down by h. This is because when each character is
343             # //draw it modifies the current matrix so that the next character
344             # //will be drawn immediatly after it.  
345             for i in xrange(len(lines)):
346                 line = lines[i]
347                 GL.glPushMatrix()
348                 GL.glLoadIdentity ()
349                 GL.glTranslatef(x,y-h*i,0);
350                 GL.glMultMatrixf(modelview_matrix);
351             
352                 # //  The commented out raster position stuff can be useful if you need to
353                 # //  know the length of the text that you are creating.
354                 # //  If you decide to use it make sure to also uncomment the glBitmap command
355                 # //  in make_dlist().
356                 # //    glRasterPos2f(0,0);
357                 #            glCallLists (line)
358                 for tt in line:
359                     if is_cjk(tt):
360                         dispCJK(self.ft,tt,self.cjk_textures)
361                     else:
362             #            print 'ascii',tt
363                         GL.glCallList(ord(tt)+1)
364                 # //    rpos = glGetFloatv (GL_CURRENT_RASTER_POSITION)
365                 # //    float len=x-rpos[0];
366                 GL.glPopMatrix()
367             GL.glPopAttrib()
368             pop_projection_matrix()
369             
370             
371         
372     def release(self):
373         """ Release the gl resources for this Face.
374             (This provides the functionality of KillFont () and font_data::clean ()
375         """
376         if self.m_allocated:
377             # Free up the glTextures and the display lists for our face
378             GL.glDeleteLists( self.m_list_base, 256);
379             for ID in self.textures:
380                 GL.glDeleteTextures(ID)
381             if self.cjk_textures:
382                 for ID in self.cjk_textures:
383                     GL.glDeleteTextures(ID)
384             # Extra defensive. Clients that continue to try and use this object
385             # will now trigger exceptions.
386             self.list_base = None
387             self.m_allocated = False
388     
389     def __del__ (self):
390         """ Python destructor for when no more refs to this Face object """
391         self.release()
392     
393 # Unit Test harness if this python module is run directly.
394 if __name__=="__main__":
395     print "testing availability of freetype font arial\n"
396     ft = ImageFont.truetype ("Test.ttf", 15)
397     if ft:
398         print "Found the TrueType font 'Test.ttf'"
399     else:
400         print "faild to find the TrueTYpe font 'arial'\n"
401 
402         
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 
 55 # Some api in the chain is translating the keystrokes to this octal string
 56 # so instead of saying: ESCAPE = 27, we use the following.
 57 ESCAPE = '\033'
 58 
 59 # Number of the glut window.
 60 window = 0
 61 
 62 our_font = None
 63 
 64 # A general OpenGL initialization function.  Sets all of the initial parameters. 
 65 def InitGL(Width, Height):                # We call this right after our OpenGL window is created.
 66     global our_font
 67     glShadeModel(GL_SMOOTH)                # Enables Smooth Color Shading
 68     glClearColor(0.0, 0.0, 0.0, 0.5)    # This Will Clear The Background Color To Black
 69     glClearDepth(1.0)                    # Enables Clearing Of The Depth Buffer
 70     glEnable(GL_DEPTH_TEST)                # Enables Depth Testing
 71     glEnable(GL_TEXTURE_2D)                # Enables texture mapping
 72     glDepthFunc(GL_LEQUAL)                # The Type Of Depth Test To Do
 73     glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST) # Really Nice Perspective Calculations
 74 
 75     # Currently omitting the wgl based font. See lesson13.py for example use of wgl font.
 76     # FYI, the ttf font file "Test.ttf" in lesson43 is the typeface "Arial Black Italic".
 77     # our_font = glFreeType.font_data ("ARBLI___.ttf", 16)
 78     # our_font = glFreeType.font_data ("Test.ttf", 16)
 79     our_font = glFreeType.font_data("wqy-zenhei.ttc",20)
 80     return True
 81     
 82 
 83 
 84 # The function called when our window is resized (which shouldn't happen if you enable fullscreen, below)
 85 def ReSizeGLScene(Width, Height):
 86     if Height == 0:                        # Prevent A Divide By Zero If The Window Is Too Small 
 87         Height = 1
 88 
 89     glViewport(0, 0, Width, Height)        # Reset The Current Viewport And Perspective Transformation
 90     glMatrixMode(GL_PROJECTION)
 91     glLoadIdentity()
 92     # // field of view, aspect ratio, near and far
 93     # This will squash and stretch our objects as the window is resized.
 94     gluPerspective(45.0, float(Width)/float(Height), 0.1, 100.0)
 95 
 96     glMatrixMode(GL_MODELVIEW)
 97     glLoadIdentity()
 98 
 99 cnt1 = 0
100 # The main drawing function. 
101 def DrawGLScene():
102     global cnt1
103     global our_font
104 
105     # Clear The Screen And The Depth Buffer
106     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
107     glLoadIdentity()                    # Reset The View 
108     # Step back (away from objects)
109     glTranslatef (0.0, 0.0, -1.0)
110 
111     # Currently - NYI - No WGL text
112     # Blue Text
113     # glColor3ub(0, 0, 0xff)
114     #
115     # // Position The WGL Text On The Screen
116     # glRasterPos2f(-0.40f, 0.35f);
117      # glPrint("Active WGL Bitmap Text With NeHe - %7.2f", cnt1);    
118 
119     # Red Text
120     glColor3ub (0xff, 0, 0)
121 
122     glPushMatrix ()
123     glLoadIdentity ()
124     # Spin the text, rotation around z axe == will appears as a 2d rotation of the text on our screen
125     glRotatef (cnt1, 0, 0, 1)
126     glScalef (1, 0.8 + 0.3* cos (cnt1/5), 1)
127     glTranslatef (-180, 0, 0)
128     our_font.glPrint(320, 240, u"Active123中文 \nFreeType Text 汉字- %7.2f\n{【丯丱丳丵饕餮】}、\n今日はとてもいい天気です。空は靑く" % (cnt1))
129     glPopMatrix ()
130 
131     # //Uncomment this to test out print's ability to handle newlines.
132     # our_font.glPrint (320, 240, "Here\nthere\nbe\n\nnewlines %f\n." % (cnt1))
133 
134     cnt1 += 0.091
135     # cnt2 += 0.005
136 
137     glutSwapBuffers()
138     return
139 
140 
141 # The function called whenever a key is pressed. Note the use of Python tuples to pass in: (key, x, y)  
142 def keyPressed(*args):
143     global window
144     global our_font
145     # If escape is pressed, kill everything.
146     if args[0] == ESCAPE:
147         our_font.release ()
148         sys.exit()
149 
150 def main():
151     global window
152     # pass arguments to init
153     glutInit(sys.argv)
154 
155     # Select type of Display mode:   
156     #  Double buffer 
157     #  RGBA color
158     # Alpha components supported 
159     # Depth buffer
160     glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH)
161     
162     # get a 640 x 480 window 
163     glutInitWindowSize(640, 480)
164     
165     # the window starts at the upper left corner of the screen 
166     glutInitWindowPosition(0, 0)
167     
168     # Okay, like the C version we retain the window id to use when closing, but for those of you new
169     # to Python (like myself), remember this assignment would make the variable local and not global
170     # if it weren't for the global declaration at the start of main.
171     window = glutCreateWindow("NeHe & Sven Olsen's TrueType Font Tutorial")
172 
173        # Register the drawing function with glut, BUT in Python land, at least using PyOpenGL, we need to
174     # set the function pointer and invoke a function to actually register the callback, otherwise it
175     # would be very much like the C version of the code.    
176     glutDisplayFunc(DrawGLScene)
177     
178     # Uncomment this line to get full screen.
179     #glutFullScreen()
180 
181     # When we are doing nothing, redraw the scene.
182     glutIdleFunc(DrawGLScene)
183     
184     # Register the function called when our window is resized.
185     glutReshapeFunc(ReSizeGLScene)
186     
187     # Register the function called when the keyboard is pressed.  
188     glutKeyboardFunc(keyPressed)
189 
190     # Initialize our window. 
191     InitGL(640, 480)
192 
193     # Start Event Processing Engine    
194     glutMainLoop()
195 
196 # Print message to console, and kick off the main to get it rolling.
197 print "Hit ESC key to quit."
198 main()
lesson43.py

 

Ubuntu 14.04

 

Win7

posted @ 2014-09-16 14:58  pasuka  阅读(1708)  评论(0编辑  收藏  举报