PageRenderTime 27ms CodeModel.GetById 11ms app.highlight 7ms RepoModel.GetById 1ms app.codeStats 1ms

/examples/glcubes.winxed

http://github.com/NotFound/winxed
Unknown | 402 lines | 349 code | 53 blank | 0 comment | 0 complexity | 3df784f736f5332ce323019a2b2d894d MD5 | raw file
  1#! winxed
  2
  3// glcubes.winxed
  4// Opengl demo
  5
  6//**********************************************************************
  7
  8const float PI = 3.1415926;
  9const float ToRad = PI / 180.0;
 10
 11const int
 12  GLUT_RGBA           = 0x0000,
 13  GLUT_DOUBLE         = 0x0002,
 14  GLUT_DEPTH          = 0x0010,
 15  GLUT_KEY_LEFT       = 0x0064,
 16  GLUT_KEY_RIGHT      = 0x0066,
 17  GLUT_KEY_UP         = 0x0065,
 18  GLUT_KEY_DOWN       = 0x0067,
 19  GL_COLOR_BUFFER_BIT = 0x00004000,
 20  GL_DEPTH_BUFFER_BIT = 0x00000100,
 21  GL_TRIANGLES        = 0x0004,
 22  GL_QUADS            = 0x0007,
 23  GL_BACK             = 0x0405,
 24  GL_DEPTH_TEST       = 0x0B71,
 25  GL_MODELVIEW        = 0x1700,
 26  GL_PROJECTION       = 0x1701;
 27
 28/***********************************************************************
 29                           Callbacks
 30    OpenGL callbacks take no parameters, work around that by creating
 31funtion objects for each callback that forward to the corresponding
 32methods in a OpenGlWindow object.
 33
 34***********************************************************************/
 35
 36class OpenGlCallback
 37{
 38    var w; // The window this callback refers
 39
 40    // The callback mechanics checks 'does invokable',
 41    // overriding does takes care of that requisite.
 42    function does[vtable](string doname)
 43    {
 44        return doname == 'invokable';
 45    }
 46
 47    // Initialize
 48    function set(var w)
 49    {
 50        self.w = w;
 51    }
 52}
 53
 54class Reshape : OpenGlCallback
 55{
 56    function invoke[vtable](int w, int h)
 57    {
 58        self.w.reshape(w, h);
 59    }
 60}
 61
 62class Draw : OpenGlCallback
 63{
 64    function invoke[vtable]()
 65    {
 66        self.w.draw();
 67    }
 68}
 69
 70class Idle : OpenGlCallback
 71{
 72    function invoke[vtable]()
 73    {
 74        self.w.idle();
 75    }
 76}
 77
 78class Keyboard : OpenGlCallback
 79{
 80    function invoke[vtable](int key, int x, int y)
 81    {
 82        self.w.keyboard(key, x, y);
 83    }
 84}
 85
 86class Special : OpenGlCallback
 87{
 88    function invoke[vtable](int key, int x, int y)
 89    {
 90        self.w.specialKey(key, x, y);
 91    }
 92}
 93
 94//**********************************************************************
 95
 96class Cube
 97{
 98    var r;
 99    var g;
100    var b;
101    var x;
102    var y;
103    var z;
104
105    function Cube(float r, float g, float b, float x, float y, float z)
106    {
107        self.r = r;
108        self.g = g;
109        self.b = b;
110        self.x = x;
111        self.y = y;
112        self.z = z;
113    }
114    function quad()
115    {
116        glBegin(GL_QUADS);
117        glVertex3f( 0.5,  0.5, 0.0);
118        glVertex3f( 0.5, -0.5, 0.0);
119        glVertex3f(-0.5, -0.5, 0.0);
120        glVertex3f(-0.5,  0.5, 0.0);
121        glEnd();
122    }
123    function wire()
124    {
125        float x = self.x;
126        float y = self.y;
127        float z = self.z;
128        glPushMatrix();
129        glTranslatef(x, y, z);
130        glColor4f(1.0, 1.0, 1.0, 0.2);
131        glutWireCube(1.3);
132        glPopMatrix();
133    }
134    function draw()
135    {
136        float r = self.r;
137        float g = self.g;
138        float b = self.b;
139        float x = self.x;
140        float y = self.y;
141        float z = self.z;
142
143        float f = 0.8;
144        glColor3f(r * f, g * f, b * f);
145
146        glPushMatrix();
147        glTranslatef(x, y, z);
148
149        glTranslatef(0.0, 0.0, -0.5);
150        self.quad();
151
152        f = 0.4;
153        glColor3f(r * f, g * f, b * f);
154        glPushMatrix();
155        glTranslatef(0.0, 0.0, 1.0);
156        glRotatef(180.0, 0.0, 1.0, 0.0);
157        self.quad();
158        glPopMatrix();
159
160        f = 0.7;
161        glColor3f(r * f, g * f, b * f);
162        glPushMatrix();
163        glRotatef(90.0, 0.0, 1.0, 0.0);
164        glTranslatef(-0.5, 0.0, -0.5);
165        self.quad();
166        f = 0.6;
167        glColor3f(r * f, g * f, b * f);
168        glTranslatef(0.0, 0.0, 1.0);
169        self.quad();
170        glPopMatrix();
171
172        f = 1.0;
173        glColor3f(r * f, g * f, b * f);
174        glPushMatrix();
175        glRotatef(90.0, 1.0, 0.0, 0.0);
176        glTranslatef( 0.0,  0.5, -0.5);
177        self.quad();
178        f = 0.3;
179        glColor3f(r * f, g * f, b * f);
180        glTranslatef(0.0, 0.0, 1.0);
181        self.quad();
182        glPopMatrix();
183
184        glPopMatrix();
185    }
186}
187
188//**********************************************************************
189
190class OpenGlWindow
191{
192    const float basestepvangle = 1.0;
193    const float basestephangle = 0.1;
194
195    var savecb;
196    var w;
197    var init;
198    var withwires;
199    var aspect;
200    var ipos;
201    var vangle;
202    var angle;
203    var stephangle;
204    var distance;
205    var cubes;
206
207    function create(string title)
208    {
209        int w = glutCreateWindow(title);
210        self.w = w;
211        self.withwires = true;
212        self.aspect = 1.0;
213        self.vangle = 20.0;
214        self.angle = 0.0;
215        self.stephangle = basestephangle;
216        self.ipos = 0;
217        self.distance = 6.0;
218
219        var cubes = [];
220        self.cubes = cubes;
221
222        cubes.push(new Cube(0.0, 1.0, 0.0,  0.0, 0.0,  0.0));
223        cubes.push(new Cube(0.5, 0.7, 0.5,  2.0, 0.0,  0.0));
224        cubes.push(new Cube(1.0, 1.0, 0.0, -2.0, 0.0,  0.0));
225        cubes.push(new Cube(0.0, 1.0, 1.0,  0.0, 0.0,  2.0));
226        cubes.push(new Cube(1.0, 0.0, 1.0,  0.0, 0.0, -2.0));
227        cubes.push(new Cube(1.0, 1.0, 1.0, -2.0, 0.0, -2.0));
228        cubes.push(new Cube(0.5, 0.5, 1.0, -2.0, 0.0,  2.0));
229        cubes.push(new Cube(0.5, 0.8, 0.7,  2.0, 0.0, -2.0));
230        cubes.push(new Cube(1.0, 0.8, 0.8,  2.0, 0.0,  2.0));
231        cubes.push(new Cube(1.0, 0.0, 0.0,  0.0, 2.0,  0.0));
232
233        var savecb = [];
234        self.savecb = savecb;
235
236        var d = new Reshape; d.set(self);
237        savecb.push(d);
238        glutReshapeFunc(d);
239        d = new Draw; d.set(self);
240        savecb.push(d);
241        glutDisplayFunc(d);
242        d = new Keyboard; d.set(self);
243        savecb.push(d);
244        glutKeyboardFunc(d);
245        d = new Special; d.set(self);
246        savecb.push(d);
247        glutSpecialFunc(d);
248
249        float now;
250        ${ time now };
251        self.init = now;
252        d = new Idle; d.set(self);
253        savecb.push(d);
254        glutIdleFunc(d);
255    }
256
257    function idle()
258    {
259        float init = self.init;
260        float now;
261        ${ time now };
262        float dt = (now - init) * 100.0;
263        int it = dt;
264        int ipos = self.ipos;
265        if (it != ipos) {
266            self.ipos =: it;
267            self.angle += self.stephangle;
268            glutPostRedisplay();
269        }
270    }
271
272    function reshape(int w, int h)
273    {
274        float aspect = w;
275        aspect = aspect / h;
276        self.aspect =: aspect;
277        glViewport(0, 0, w, h);
278    }
279
280    function draw()
281    {
282        int buffers = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT;
283        glClear(buffers);
284
285        glMatrixMode(GL_PROJECTION);
286        glLoadIdentity();
287        gluPerspective(60.0, self.aspect, 0.1, 60.0);
288
289        float angle = self.angle;
290        float hangle = angle * ToRad;
291        float distance = self.distance;
292        float vangle = self.vangle;
293        vangle = vangle * ToRad;
294        float ypos = distance * sin(vangle);
295
296        float hdistance = distance * cos(vangle);
297        float xpos = hdistance * sin(hangle);
298        float zpos = hdistance * cos(hangle);
299
300        glMatrixMode(GL_MODELVIEW);
301        glLoadIdentity();
302        gluLookAt(
303             xpos, ypos, zpos,
304             0.0, 0.0, 0.0,
305             0.0, 1.0, 0.0);
306
307        var withwires = self.withwires;
308        if (distance < 20.0 && withwires)
309            for (var cube in self.cubes)
310                cube.wire();
311        for (var cube in self.cubes)
312            cube.draw();
313
314        glutSwapBuffers();
315
316        // Without this sweep it leaks memory continuously.
317        // Don't know if it's a problem with the opengl module
318        // or in parrot internals.
319        ${ sweep 1 };
320    }
321
322    function keyboard(int key, int x, int y)
323    {
324        float distance = self.distance;
325        const float step = 0.1;
326        switch (key) {
327          case ord(' '):
328            self.withwires =: ! self.withwires;
329            break;
330          case ord("\e"):
331            glutDestroyWindow(self.w);
332            break;
333          case ord("+"):
334            distance = distance - step;
335            self.distance =: distance;
336            break;
337          case ord("-"):
338            distance = distance + step;
339            self.distance =: distance;
340            break;
341        }
342    }
343
344    function specialKey(int key, int x, int y)
345    {
346        float vangle = self.vangle;
347        float stephangle = self.stephangle;
348        const float step = 0.1;
349        switch (key) {
350          case GLUT_KEY_LEFT:
351            if (stephangle < 0)
352                stephangle = basestephangle;
353            else
354                stephangle += basestephangle;
355            self.stephangle =: stephangle;
356            break;
357          case GLUT_KEY_RIGHT:
358            if (stephangle > 0)
359                stephangle = -basestephangle;
360            else
361                stephangle -= basestephangle;
362            self.stephangle =: stephangle;
363            break;
364          case GLUT_KEY_UP:
365            vangle = vangle + basestepvangle;
366            if (vangle < 90.0)
367                self.vangle =: vangle;
368            break;
369          case GLUT_KEY_DOWN:
370            vangle = vangle - basestepvangle;
371            if (vangle > -90.0)
372                self.vangle =: vangle;
373            break;
374        }
375    }
376}
377
378//**********************************************************************
379
380function main(var argv)
381{
382    using extern OpenGL;
383    using OpenGL._export_all_functions;
384    _export_all_functions();
385
386    using extern NCI.Utils;
387    using NCI.Utils.call_toolkit_init;
388    using OpenGL.glutInit;
389    call_toolkit_init(glutInit, argv);
390
391    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
392
393    var window = new OpenGlWindow;
394    window.create('glcubes - Winxed OpenGL demo');
395
396    glCullFace(GL_BACK);
397    glEnable(GL_DEPTH_TEST);
398
399    glutMainLoop();
400}
401
402// End