|
1 # |
|
2 # simplecube.py |
|
3 # |
|
4 # Copyright (c) 2006-2007 Nokia Corporation |
|
5 # |
|
6 # Licensed under the Apache License, Version 2.0 (the "License"); |
|
7 # you may not use this file except in compliance with the License. |
|
8 # You may obtain a copy of the License at |
|
9 # |
|
10 # http://www.apache.org/licenses/LICENSE-2.0 |
|
11 # |
|
12 # Unless required by applicable law or agreed to in writing, software |
|
13 # distributed under the License is distributed on an "AS IS" BASIS, |
|
14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
15 # See the License for the specific language governing permissions and |
|
16 # limitations under the License. |
|
17 # |
|
18 |
|
19 import appuifw, sys, e32 |
|
20 from glcanvas import * |
|
21 from gles import * |
|
22 from key_codes import * |
|
23 |
|
24 class SimpleCube: |
|
25 vertices = array(GL_BYTE, 3, ( |
|
26 [-1, 1, 1.0], |
|
27 [ 1, 1, 1], |
|
28 [ 1, -1, 1], |
|
29 [-1, -1, 1], |
|
30 |
|
31 [-1, 1, -1], |
|
32 [ 1, 1, -1], |
|
33 [ 1, -1, -1], |
|
34 [-1, -1, -1] |
|
35 ) |
|
36 ) |
|
37 |
|
38 triangles = array(GL_UNSIGNED_BYTE, 3, ( |
|
39 # front |
|
40 [1,0,3], |
|
41 [1,3,2], |
|
42 |
|
43 # right |
|
44 [2,6,5], |
|
45 [2,5,1], |
|
46 |
|
47 # back |
|
48 [7,4,5], |
|
49 [7,5,6], |
|
50 |
|
51 # left |
|
52 [0,4,7], |
|
53 [0,7,3], |
|
54 |
|
55 # top |
|
56 [5,4,0], |
|
57 [5,0,1], |
|
58 |
|
59 # bottom |
|
60 [3,7,6], |
|
61 [3,6,2] |
|
62 ) |
|
63 ) |
|
64 |
|
65 fanOne = array(GL_UNSIGNED_BYTE, 3, ( |
|
66 [1,0,3], |
|
67 [1,3,2], |
|
68 [1,2,6], |
|
69 [1,6,5], |
|
70 [1,5,4], |
|
71 [1,4,0] |
|
72 ) |
|
73 ) |
|
74 fanTwo = array(GL_UNSIGNED_BYTE, 3, ( |
|
75 [7,4,5], |
|
76 [7,5,6], |
|
77 [7,6,2], |
|
78 [7,2,3], |
|
79 [7,3,0], |
|
80 [7,0,4] |
|
81 ) |
|
82 ) |
|
83 |
|
84 colors = array(GL_UNSIGNED_BYTE, 4, ( |
|
85 [0 ,255, 0,255], |
|
86 [0 , 0,255,255], |
|
87 [0 ,255, 0,255], |
|
88 [255, 0, 0,255], |
|
89 |
|
90 [0 , 0,255,255], |
|
91 [255, 0, 0,255], |
|
92 [0 , 0,255,255], |
|
93 [0 ,255, 0,255] |
|
94 )) |
|
95 |
|
96 ETriangles=0 |
|
97 ETriangleFans=1 |
|
98 |
|
99 def __init__(self): |
|
100 """Initializes OpenGL ES, sets the vertex and color arrays and pointers, |
|
101 and selects the shading mode.""" |
|
102 |
|
103 # It's best to set these before creating the GL Canvas |
|
104 self.iDrawingMode=self.ETriangles |
|
105 self.iFrame=0 |
|
106 self.exitflag = False |
|
107 self.render=0 |
|
108 self.canvas = None |
|
109 |
|
110 self.old_body=appuifw.app.body |
|
111 try: |
|
112 self.canvas=GLCanvas(redraw_callback=self.redraw, event_callback=self.event, resize_callback=self.resize) |
|
113 appuifw.app.body=self.canvas |
|
114 except Exception,e: |
|
115 appuifw.note(u"Exception: %s" % (e)) |
|
116 self.set_exit() |
|
117 return |
|
118 |
|
119 # binds are exactly same as with normal Canvas objects |
|
120 self.canvas.bind(EKey1,lambda:self.FullScreen(0)) |
|
121 self.canvas.bind(EKey2,lambda:self.FullScreen(1)) |
|
122 self.canvas.bind(EKey3,lambda:self.FullScreen(2)) |
|
123 |
|
124 appuifw.app.menu = [ |
|
125 ( |
|
126 u"Shading mode", |
|
127 ( |
|
128 (u"Flat", self.FlatShading), |
|
129 (u"Smooth", self.SmoothShading) |
|
130 ) |
|
131 ), |
|
132 ( |
|
133 u"Drawing mode", |
|
134 ( |
|
135 (u"Triangles", self.TriangleMode), |
|
136 (u"Triangle fans", self.TriangleFanMode) |
|
137 ) |
|
138 ), |
|
139 ( |
|
140 u"Screen", |
|
141 ( |
|
142 (u"Normal", lambda:self.FullScreen(0)), |
|
143 (u"Large", lambda:self.FullScreen(1)), |
|
144 (u"Full", lambda:self.FullScreen(2)), |
|
145 ) |
|
146 ), |
|
147 (u"Exit", self.set_exit) |
|
148 ] |
|
149 |
|
150 try: |
|
151 self.initgl() |
|
152 except Exception,e: |
|
153 appuifw.note(u"Exception: %s" % (e)) |
|
154 self.set_exit() |
|
155 |
|
156 def event(self, ev): |
|
157 """Event handler""" |
|
158 pass |
|
159 |
|
160 def resize(self): |
|
161 """Resize handler""" |
|
162 # This may get called before the canvas is created, so check that the canvas exists |
|
163 if self.canvas: |
|
164 glViewport(0, 0, self.canvas.size[0], self.canvas.size[1]) |
|
165 aspect = float(self.canvas.size[1]) / float(self.canvas.size[0]) |
|
166 glMatrixMode( GL_PROJECTION ) |
|
167 glLoadIdentity() |
|
168 glFrustumf( -1.0, 1.0, -1.0*aspect, 1.0*aspect, 3.0, 1000.0 ) |
|
169 |
|
170 def initgl(self): |
|
171 """Initializes OpenGL and sets up the rendering environment""" |
|
172 # Set the screen background color. |
|
173 glClearColor( 0.0, 0.0, 0.0, 1.0 ) |
|
174 |
|
175 # Enable back face culling. |
|
176 glEnable( GL_CULL_FACE ) |
|
177 |
|
178 # Initialize viewport and projection. |
|
179 self.resize() |
|
180 |
|
181 glMatrixMode( GL_MODELVIEW ) |
|
182 |
|
183 # Enable vertex arrays. |
|
184 glEnableClientState( GL_VERTEX_ARRAY ) |
|
185 |
|
186 # Set array pointers. |
|
187 glVertexPointerb(self.vertices) |
|
188 |
|
189 # Enable color arrays. |
|
190 glEnableClientState( GL_COLOR_ARRAY ) |
|
191 |
|
192 # Set color pointers. |
|
193 glColorPointerub(self.colors ) |
|
194 |
|
195 # Set the initial shading mode |
|
196 glShadeModel( GL_FLAT ) |
|
197 |
|
198 # Do not use perspective correction |
|
199 glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST ) |
|
200 self.render=1 |
|
201 |
|
202 def FlatShading(self): |
|
203 """Sets the GL shading model to flat.""" |
|
204 glShadeModel( GL_FLAT ) |
|
205 |
|
206 def SmoothShading(self): |
|
207 """Sets the GL shading model to smooth.""" |
|
208 glShadeModel( GL_SMOOTH ) |
|
209 |
|
210 def TriangleMode(self): |
|
211 """Sets the rendering mode to triangles.""" |
|
212 self.iDrawingMode = self.ETriangles |
|
213 |
|
214 def TriangleFanMode(self): |
|
215 """Sets the rendering mode to triangle fans.""" |
|
216 self.iDrawingMode = self.ETriangleFans |
|
217 |
|
218 def FullScreen(self,mode): |
|
219 if mode == 0: |
|
220 appuifw.app.screen = 'normal' |
|
221 elif mode == 1: |
|
222 appuifw.app.screen = 'large' |
|
223 elif mode == 2: |
|
224 appuifw.app.screen = 'full' |
|
225 |
|
226 def drawbox(self, aSizeX, aSizeY, aSizeZ): |
|
227 """Draws a box with triangles or triangle fans depending on the current rendering mode. |
|
228 Scales the box to the given size using glScalef.""" |
|
229 glScalef( aSizeX, aSizeY, aSizeZ ) |
|
230 |
|
231 if self.iDrawingMode == self.ETriangles: |
|
232 glDrawElementsub( GL_TRIANGLES, self.triangles ) |
|
233 elif self.iDrawingMode == self.ETriangleFans: |
|
234 glDrawElementsub( GL_TRIANGLE_FAN, self.fanOne ) |
|
235 glDrawElementsub( GL_TRIANGLE_FAN, self.fanTwo ) |
|
236 |
|
237 def redraw(self,frame): |
|
238 """Draws and animates the objects. |
|
239 The frame number determines the amount of rotation.""" |
|
240 self.iFrame = frame |
|
241 |
|
242 if self.render == 0: |
|
243 return |
|
244 glMatrixMode( GL_MODELVIEW ) |
|
245 |
|
246 cameraDistance = 100 |
|
247 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) |
|
248 |
|
249 # Animate and draw box |
|
250 glLoadIdentity() |
|
251 glTranslatex( 0 , 0 , -cameraDistance << 16 ) |
|
252 glRotatex( self.iFrame << 16, 1 << 16, 0 , 0 ) |
|
253 glRotatex( self.iFrame << 15, 0 , 1 << 16, 0 ) |
|
254 glRotatex( self.iFrame << 14, 0 , 0 , 1 << 16 ) |
|
255 self.drawbox( 15.0, 15.0, 15.0 ) |
|
256 |
|
257 def close_canvas(self): # break reference cycles |
|
258 appuifw.app.body=self.old_body |
|
259 self.canvas=None |
|
260 self.draw=None |
|
261 appuifw.app.exit_key_handler=None |
|
262 |
|
263 def set_exit(self): |
|
264 self.exitflag = True |
|
265 |
|
266 def run(self): |
|
267 appuifw.app.exit_key_handler=self.set_exit |
|
268 while not self.exitflag: |
|
269 self.canvas.drawNow() |
|
270 e32.ao_sleep(0.0001) |
|
271 self.close_canvas() |
|
272 |
|
273 appuifw.app.screen='full' |
|
274 try: |
|
275 app=SimpleCube() |
|
276 except Exception,e: |
|
277 appuifw.note(u'Exception: %s' % (e)) |
|
278 else: |
|
279 app.run() |
|
280 del app |
|
281 #sys.exit(0) |