root/trunk/luigi/examples/example1_sdl.d

Revision 57, 15.3 kB (checked in by baxissimo, 1 year ago)

Steal gui focus on mousedown that that GUI doesn't handle.

Line 
1 /* $Id: gears.c,v 1.2 1999/10/21 16:39:06 brianp Exp $ */
2
3 /*
4  * 3-D gear wheels.  This program is in the public domain.
5  *
6  * Command line options:
7  *    -info      print GL implementation information
8  *
9  *
10  * Brian Paul
11  */
12
13 /* Conversion to GLUT by Mark J. Kilgard */
14
15 /*
16  * $Log: gears.c,v $
17  * Revision 1.2  1999/10/21 16:39:06  brianp
18  * added -info command line option
19  *
20  * Revision 1.1.1.1  1999/08/19 00:55:40  jtg
21  * Imported sources
22  *
23  * Revision 3.2  1999/06/03 17:07:36  brianp
24  * an extra quad was being drawn in front and back faces
25  *
26  * Revision 3.1  1998/11/03 02:49:10  brianp
27  * added fps output
28  *
29  * Revision 3.0  1998/02/14 18:42:29  brianp
30  * initial rev
31  *
32  */
33
34
35 module sdl_gears;
36
37 import luigui = luigi.gui;
38 import luigi.adapters.sdl;
39 static import luigi.themes.std;
40 static import luigi.themes.dxut;
41
42 import derelict.sdl.sdl;
43 import derelict.opengl.gl;
44 import std.math;
45 import std.stdio;
46 import std.string;
47
48 static GLint T0 = 0;
49 static GLint Frames = 0;
50
51 static this()
52 {
53     // load the SDL shared library
54     DerelictSDL.load();
55     DerelictGL.load();
56
57     SDL_Init(SDL_INIT_VIDEO);
58 }
59
60 static ~this()
61 {
62     // Close OpenGL window and terminate GLFW
63     SDL_Quit();
64 }
65
66
67 luigui.Overlay create_gui(SDL_Surface *win, char[][] argv)
68 {
69     char[] theme = "dx";
70
71     //---------------- PARSE ARGS -----------------------
72     for( int i=1; i<argv.length; i++ ) {
73         auto a = argv[i];
74         if (a == "-theme") {
75             theme = argv[++i];
76         }
77     }
78    
79     luigui.Overlay gui;
80     with(luigui) {
81         Luigi().adapter = SDLAdapter();
82         if (theme == "dxut" || theme == "dx") {
83             Luigi().add_resource_location("..");
84             Luigi().theme = new luigi.themes.dxut.DXUTTheme();
85         }
86         gui = new Overlay(cast(WindowHandle)win);
87    
88         gui.arranger = new BorderArranger(Gaps(5));
89
90         alias BorderArranger.Region Region;
91         alias Alignment A;
92
93         auto eastGroup = gui.add_arranged(new GridPanel(1,0, Gaps(2)), Region.East);
94         auto westGroup = gui.add_arranged(new GridPanel(2,0, Gaps(2)), Region.West);
95         auto northGroup = gui.add_arranged(new FlowPanel, Region.North);
96         auto southGroup = gui.add_arranged(new FlowPanel, Region.South);
97
98         auto rgrp = new RadioGroup;
99
100         with (westGroup) {
101             auto b20 = add_arranged(new Button("Tool0"));
102             auto b21 = add_arranged(new Button("Tool1"));
103             auto b22 = add_arranged(new Button("Tool2"));
104             auto b23 = add_arranged(new Button("Tool3"));
105             auto b24 = add_arranged(new Button("LongNameTool4"));
106             auto b25 = add_arranged(new Button("Tool5"));
107             auto b26 = add_arranged(new Button("Tool6"));
108             auto b27 = add_arranged(new Button("Tool7"));
109             auto b28 = add_arranged(new Button("Tool8"));
110             auto b29 = add_arranged(new Button("Tool9"));
111
112             rgrp.multiadd(b20,b21,b22,b23,b24,b25,b26,b27,b28,b29);
113             rgrp.value = 0;
114             rgrp.selection_changed ~= (int t) {
115                 writefln("Tool %s now selected", t);
116             };
117
118             auto s01 = add_arranged(new Slider);
119             auto s02 = add_arranged(new Slider);
120             s02.vertical = true;
121             s01.precision = 0.1;
122             s02.precision = 0.1;
123
124             s01.value_changed.connect2nd( (double d){ writefln("Slider now %s",d); } );
125             s02.value_changed.connect2nd( (double d){ writefln("Slider now %s",d); } );
126             s02.value_changed.connect2nd(&s01.value);
127             s01.value_changed.connect2nd(&s02.value);
128         }
129
130         with(eastGroup) {
131             auto b0 = add_widget(new Button("Luigi"));  b0.disable();
132             auto b1 = add_widget(new Button("Is")); rgrp.add(b1,5);
133             auto b2 = add_widget(new Button("My")); rgrp.add(b2,7);
134             auto b3 = add_widget(new Button("Pal"));rgrp.add(b3,9);
135             auto b4 = add_widget(new Button("Hide West"));
136             b4.is_toggle = true;
137             b4.clicked.connect( &westGroup.toggle_shown );
138             b4.value_changed ~= (Widget w, bool v){
139                 Button b = cast(Button)w; assert(b);
140                 if (v) b.label = "Show West";
141                 else   b.label = "Hide West";
142                 b.get_root.arrange();
143             };
144         }
145
146         with(southGroup) {
147             auto l0 = add_widget(new Label( "First Name:"));
148             auto t0 = add_widget(new TextField("Hello"));
149             auto l1 = add_widget(new Label( "Last Name:"));
150             auto t1 = add_widget(new TextField("Rumpelstiltskin"));
151             auto b4 = add_widget(new Button("Click me!"));
152             auto l2 = add_widget(new Label("Disabled label"));
153             l2.disable;
154             b4.clicked ~= (Widget w){ writefln("Ouch! Not so hard!"); };
155         }
156
157         with (northGroup) {
158             auto b10 =   add_widget(new Button("File"));
159             auto b11 =   add_widget(new Button("Edit"));
160             auto b12 =   add_widget(new Button("View"));
161             auto b13 =   add_widget(new Button("Favorites"));
162             auto b14 =   add_widget(new Button("Tools"));
163             auto b15 =   add_widget(new Button("Options"));
164             auto c15 =   add_widget(new Checkbox("Check it out!"));
165             auto b16 =   add_widget(new Button("Help"));
166
167             c15.value_changed ~= (Widget w, bool onoff) {
168                 writefln(onoff?"checked!":"unchecked!");
169             };
170         }
171     }
172     return gui;
173 }
174
175
176 /**
177
178   Draw a gear wheel.  You'll probably want to call this function when
179   building a display list since we do a lot of trig here.
180  
181   Input:  inner_radius - radius of hole at center
182           outer_radius - radius at center of teeth
183           width - width of gear
184           teeth - number of teeth
185           tooth_depth - depth of tooth
186
187  **/
188
189 static void
190 gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
191   GLint teeth, GLfloat tooth_depth)
192 {
193     GLint i;
194     GLfloat r0, r1, r2;
195     GLfloat angle, da;
196     GLfloat u, v, len;
197
198     r0 = inner_radius;
199     r1 = outer_radius - tooth_depth / 2.0;
200     r2 = outer_radius + tooth_depth / 2.0;
201
202     da = 2.0 * PI / teeth / 4.0;
203
204     glShadeModel(GL_FLAT);
205
206     glNormal3f(0.0, 0.0, 1.0);
207
208     /* draw front face */
209     glBegin(GL_QUAD_STRIP);
210     for (i = 0; i <= teeth; i++) {
211         angle = i * 2.0 * PI / teeth;
212         glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
213         glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
214         if (i < teeth) {
215             glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
216             glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5);
217         }
218     }
219     glEnd();
220
221     /* draw front sides of teeth */
222     glBegin(GL_QUADS);
223     da = 2.0 * PI / teeth / 4.0;
224     for (i = 0; i < teeth; i++) {
225         angle = i * 2.0 * PI / teeth;
226
227         glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
228         glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
229         glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), width * 0.5);
230         glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5);
231     }
232     glEnd();
233
234     glNormal3f(0.0, 0.0, -1.0);
235
236     /* draw back face */
237     glBegin(GL_QUAD_STRIP);
238     for (i = 0; i <= teeth; i++) {
239         angle = i * 2.0 * PI / teeth;
240         glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
241         glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
242         if (i < teeth) {
243             glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5);
244             glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
245         }
246     }
247     glEnd();
248
249     /* draw back sides of teeth */
250     glBegin(GL_QUADS);
251     da = 2.0 * PI / teeth / 4.0;
252     for (i = 0; i < teeth; i++) {
253         angle = i * 2.0 * PI / teeth;
254
255         glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5);
256         glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), -width * 0.5);
257         glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
258         glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
259     }
260     glEnd();
261
262     /* draw outward faces of teeth */
263     glBegin(GL_QUAD_STRIP);
264     for (i = 0; i < teeth; i++) {
265         angle = i * 2.0 * PI / teeth;
266
267         glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
268         glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
269         u = r2 * cos(angle + da) - r1 * cos(angle);
270         v = r2 * sin(angle + da) - r1 * sin(angle);
271         len = sqrt(u * u + v * v);
272         u /= len;
273         v /= len;
274         glNormal3f(v, -u, 0.0);
275         glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
276         glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
277         glNormal3f(cos(angle), sin(angle), 0.0);
278         glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), width * 0.5);
279         glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), -width * 0.5);
280         u = r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da);
281         v = r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da);
282         glNormal3f(v, -u, 0.0);
283         glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5);
284         glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5);
285         glNormal3f(cos(angle), sin(angle), 0.0);
286     }
287
288     glVertex3f(r1 * cos(0), r1 * sin(0), width * 0.5);
289     glVertex3f(r1 * cos(0), r1 * sin(0), -width * 0.5);
290
291     glEnd();
292
293     glShadeModel(GL_SMOOTH);
294
295     /* draw inside radius cylinder */
296     glBegin(GL_QUAD_STRIP);
297     for (i = 0; i <= teeth; i++) {
298         angle = i * 2.0 * PI / teeth;
299         glNormal3f(-cos(angle), -sin(angle), 0.0);
300         glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
301         glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
302     }
303     glEnd();
304
305 }
306
307 static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0;
308 static GLint gear1, gear2, gear3;
309 static GLfloat angle = 0.0;
310 static luigui.Overlay gui;
311
312 static void
313 draw()
314 {
315   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
316
317   glPushMatrix();
318   glRotatef(view_rotx, 1.0, 0.0, 0.0);
319   glRotatef(view_roty, 0.0, 1.0, 0.0);
320   glRotatef(view_rotz, 0.0, 0.0, 1.0);
321
322   glPushMatrix();
323   glTranslatef(-3.0, -2.0, 0.0);
324   glRotatef(angle, 0.0, 0.0, 1.0);
325   glCallList(gear1);
326   glPopMatrix();
327
328   glPushMatrix();
329   glTranslatef(3.1, -2.0, 0.0);
330   glRotatef(-2.0 * angle - 9.0, 0.0, 0.0, 1.0);
331   glCallList(gear2);
332   glPopMatrix();
333
334   glPushMatrix();
335   glTranslatef(-3.1, 4.2, 0.0);
336   glRotatef(-2.0 * angle - 25.0, 0.0, 0.0, 1.0);
337   glCallList(gear3);
338   glPopMatrix();
339
340   glPopMatrix();
341
342   gui.draw();
343
344   SDL_GL_SwapBuffers();
345
346   Frames++;
347   {
348      GLint t = SDL_GetTicks();
349      if (t - T0 >= 5000) {
350         GLfloat seconds = (t - T0) / 1000.0;
351         GLfloat fps = Frames / seconds;
352         printf("%d frames in %g seconds = %g FPS\n", Frames, seconds, fps);
353         T0 = t;
354         Frames = 0;
355      }
356   }
357 }
358
359
360 static void
361 idle()
362 {
363   angle += 2.0;
364 }
365
366 /* new window size or exposure */
367 static void
368 reshape(int width, int height)
369 {
370   GLfloat h = cast(GLfloat) height / cast(GLfloat) width;
371
372   glViewport(0, 0, cast(GLint) width, cast(GLint) height);
373   glMatrixMode(GL_PROJECTION);
374   glLoadIdentity();
375   glFrustum(-1.0, 1.0, -h, h, 5.0, 100.0);
376   glMatrixMode(GL_MODELVIEW);
377   glLoadIdentity();
378   glTranslatef(0.0, 0.0, -60.0);
379 }
380
381 static void
382 init(char[][] args)
383 {
384   static GLfloat[4] pos =   [5.0, 5.0, 10.0, 0.0];
385   static GLfloat[4] red =   [0.8, 0.1, 0.0, 1.0];
386   static GLfloat[4] green = [0.0, 0.8, 0.2, 1.0];
387   static GLfloat[4] blue =  [0.2, 0.2, 1.0, 1.0];
388
389   glLightfv(GL_LIGHT0, GL_POSITION, pos.ptr);
390   glEnable(GL_CULL_FACE);
391   glEnable(GL_LIGHTING);
392   glEnable(GL_LIGHT0);
393   glEnable(GL_DEPTH_TEST);
394
395   /* make the gears */
396   gear1 = glGenLists(1);
397   glNewList(gear1, GL_COMPILE);
398   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red.ptr);
399   gear(1.0, 4.0, 1.0, 20, 0.7);
400   glEndList();
401
402   gear2 = glGenLists(1);
403   glNewList(gear2, GL_COMPILE);
404   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green.ptr);
405   gear(0.5, 2.0, 2.0, 10, 0.7);
406   glEndList();
407
408   gear3 = glGenLists(1);
409   glNewList(gear3, GL_COMPILE);
410   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue.ptr);
411   gear(1.3, 2.0, 0.5, 10, 0.7);
412   glEndList();
413
414   glEnable(GL_NORMALIZE);
415
416   glClearColor(0.13, 0.27, 0.22, 0);
417
418   if (args.length > 1 && args[1]=="-info") {
419       writefln("GL_RENDERER   = ", toString(glGetString(GL_RENDERER)));
420       writefln("GL_VERSION    = ", toString(glGetString(GL_VERSION)));
421       writefln("GL_VENDOR     = ", toString(glGetString(GL_VENDOR)));
422       writefln("GL_EXTENSIONS = ", toString(glGetString(GL_EXTENSIONS)));
423   }
424 }
425
426 int main(char[][] args)
427 {
428     SDL_Surface *screen = SDL_SetVideoMode(640, 480, 32, SDL_OPENGL|SDL_RESIZABLE);
429
430     if ( ! screen ) {
431         fprintf(stderr, "Couldn't set 300x300 GL video mode: %s\n", SDL_GetError());
432         SDL_Quit();
433         return 2;
434     }
435     SDL_WM_SetCaption("Gears", "gears");
436     SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
437     SDL_EnableUNICODE(1);
438
439     init(args);
440     gui = create_gui(screen, args);
441     SDLAdapter adapter = cast(SDLAdapter)gui.adapter;
442
443     reshape(screen.w, screen.h);
444     int done = 0;
445     while ( ! done ) {
446         SDL_Event event;
447
448         idle();
449         while ( SDL_PollEvent(&event) ) {
450             if (adapter.dispatchEvent(event)) {
451                 continue;
452             }
453
454             switch(event.type) {
455             case SDL_VIDEORESIZE:
456                 screen.w = event.resize.w;
457                 screen.h = event.resize.h;
458                 reshape(screen.w,screen.h);
459                 break;
460
461             case SDL_QUIT:
462                 done = 1;
463                 break;
464
465             case SDL_KEYDOWN:
466                 with (event.key) {
467                     if (keysym.sym == SDLK_ESCAPE ||
468                         (keysym.sym == SDLK_q && (keysym.mod & KMOD_CTRL)))
469                     {
470                         done = 1;
471                     }
472                 }
473                 break;
474
475             case SDL_MOUSEBUTTONDOWN:
476                 // Click on the non-gui area -- steal focus from gui.
477                 gui.set_focus(null);
478                 break;
479
480             default:
481                 // do nothing
482                 break;
483             }
484         }
485
486         if (!gui.get_focus())
487         {
488             Uint8 *keys = SDL_GetKeyState(null);
489             if ( keys[SDLK_UP] ) {
490                 view_rotx += 5.0;
491             }
492             if ( keys[SDLK_DOWN] ) {
493                 view_rotx -= 5.0;
494             }
495             if ( keys[SDLK_LEFT] ) {
496                 view_roty += 5.0;
497             }
498             if ( keys[SDLK_RIGHT] ) {
499                 view_roty -= 5.0;
500             }
501             if ( keys[SDLK_z] ) {
502                 if ( SDL_GetModState() & KMOD_SHIFT ) {
503                     view_rotz -= 5.0;
504                 } else {
505                     view_rotz += 5.0;
506                 }
507             }
508         }
509         draw();
510     }
511     return 0;
512 }
Note: See TracBrowser for help on using the browser.