2 (c) Copyright 2001 convergence integrated media GmbH.
5 Written by Denis Oliver Kropp <dok@convergence.de> and
6 Andreas Hundt <andi@convergence.de>.
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public
19 License along with this library; if not, write to the
20 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA.
30 #include <directfbgl.h>
35 /* the super interface */
38 /* the primary surface (surface of primary layer) */
39 IDirectFBSurface
*primary
;
42 IDirectFBGL
*primary_gl
;
48 IDirectFBEventBuffer
*events
;
50 /* macro for a safe call to DirectFB functions */
51 #define DFBCHECK(x...) \
54 if (err != DFB_OK) { \
55 fprintf( stderr, "%s <%d>:\n\t", __FILE__, __LINE__ ); \
56 DirectFBErrorFatal( #x, err ); \
60 static int screen_width
, screen_height
;
62 static unsigned long T0
= 0;
63 static GLint Frames
= 0;
64 static GLfloat fps
= 0;
66 static inline unsigned long get_millis()
70 gettimeofday (&tv
, NULL
);
71 return (tv
.tv_sec
* 1000 + tv
.tv_usec
/ 1000);
76 #define M_PI 3.14159265
81 Draw a gear wheel. You'll probably want to call this function when
82 building a display list since we do a lot of trig here.
84 Input: inner_radius - radius of hole at center
85 outer_radius - radius at center of teeth
87 teeth - number of teeth
88 tooth_depth - depth of tooth
93 gear(GLfloat inner_radius
, GLfloat outer_radius
, GLfloat width
,
94 GLint teeth
, GLfloat tooth_depth
)
102 r1
= outer_radius
- tooth_depth
/ 2.0;
103 r2
= outer_radius
+ tooth_depth
/ 2.0;
105 da
= 2.0 * M_PI
/ teeth
/ 4.0;
107 glShadeModel(GL_FLAT
);
109 glNormal3f(0.0, 0.0, 1.0);
111 /* draw front face */
112 glBegin(GL_QUAD_STRIP
);
113 for (i
= 0; i
<= teeth
; i
++) {
114 angle
= i
* 2.0 * M_PI
/ teeth
;
115 glVertex3f(r0
* cos(angle
), r0
* sin(angle
), width
* 0.5);
116 glVertex3f(r1
* cos(angle
), r1
* sin(angle
), width
* 0.5);
118 glVertex3f(r0
* cos(angle
), r0
* sin(angle
), width
* 0.5);
119 glVertex3f(r1
* cos(angle
+ 3 * da
), r1
* sin(angle
+ 3 * da
), width
* 0.5);
124 /* draw front sides of teeth */
126 da
= 2.0 * M_PI
/ teeth
/ 4.0;
127 for (i
= 0; i
< teeth
; i
++) {
128 angle
= i
* 2.0 * M_PI
/ teeth
;
130 glVertex3f(r1
* cos(angle
), r1
* sin(angle
), width
* 0.5);
131 glVertex3f(r2
* cos(angle
+ da
), r2
* sin(angle
+ da
), width
* 0.5);
132 glVertex3f(r2
* cos(angle
+ 2 * da
), r2
* sin(angle
+ 2 * da
), width
* 0.5);
133 glVertex3f(r1
* cos(angle
+ 3 * da
), r1
* sin(angle
+ 3 * da
), width
* 0.5);
137 glNormal3f(0.0, 0.0, -1.0);
140 glBegin(GL_QUAD_STRIP
);
141 for (i
= 0; i
<= teeth
; i
++) {
142 angle
= i
* 2.0 * M_PI
/ teeth
;
143 glVertex3f(r1
* cos(angle
), r1
* sin(angle
), -width
* 0.5);
144 glVertex3f(r0
* cos(angle
), r0
* sin(angle
), -width
* 0.5);
146 glVertex3f(r1
* cos(angle
+ 3 * da
), r1
* sin(angle
+ 3 * da
), -width
* 0.5);
147 glVertex3f(r0
* cos(angle
), r0
* sin(angle
), -width
* 0.5);
152 /* draw back sides of teeth */
154 da
= 2.0 * M_PI
/ teeth
/ 4.0;
155 for (i
= 0; i
< teeth
; i
++) {
156 angle
= i
* 2.0 * M_PI
/ teeth
;
158 glVertex3f(r1
* cos(angle
+ 3 * da
), r1
* sin(angle
+ 3 * da
), -width
* 0.5);
159 glVertex3f(r2
* cos(angle
+ 2 * da
), r2
* sin(angle
+ 2 * da
), -width
* 0.5);
160 glVertex3f(r2
* cos(angle
+ da
), r2
* sin(angle
+ da
), -width
* 0.5);
161 glVertex3f(r1
* cos(angle
), r1
* sin(angle
), -width
* 0.5);
165 /* draw outward faces of teeth */
166 glBegin(GL_QUAD_STRIP
);
167 for (i
= 0; i
< teeth
; i
++) {
168 angle
= i
* 2.0 * M_PI
/ teeth
;
170 glVertex3f(r1
* cos(angle
), r1
* sin(angle
), width
* 0.5);
171 glVertex3f(r1
* cos(angle
), r1
* sin(angle
), -width
* 0.5);
172 u
= r2
* cos(angle
+ da
) - r1
* cos(angle
);
173 v
= r2
* sin(angle
+ da
) - r1
* sin(angle
);
174 len
= sqrt(u
* u
+ v
* v
);
177 glNormal3f(v
, -u
, 0.0);
178 glVertex3f(r2
* cos(angle
+ da
), r2
* sin(angle
+ da
), width
* 0.5);
179 glVertex3f(r2
* cos(angle
+ da
), r2
* sin(angle
+ da
), -width
* 0.5);
180 glNormal3f(cos(angle
), sin(angle
), 0.0);
181 glVertex3f(r2
* cos(angle
+ 2 * da
), r2
* sin(angle
+ 2 * da
), width
* 0.5);
182 glVertex3f(r2
* cos(angle
+ 2 * da
), r2
* sin(angle
+ 2 * da
), -width
* 0.5);
183 u
= r1
* cos(angle
+ 3 * da
) - r2
* cos(angle
+ 2 * da
);
184 v
= r1
* sin(angle
+ 3 * da
) - r2
* sin(angle
+ 2 * da
);
185 glNormal3f(v
, -u
, 0.0);
186 glVertex3f(r1
* cos(angle
+ 3 * da
), r1
* sin(angle
+ 3 * da
), width
* 0.5);
187 glVertex3f(r1
* cos(angle
+ 3 * da
), r1
* sin(angle
+ 3 * da
), -width
* 0.5);
188 glNormal3f(cos(angle
), sin(angle
), 0.0);
191 glVertex3f(r1
* cos(0), r1
* sin(0), width
* 0.5);
192 glVertex3f(r1
* cos(0), r1
* sin(0), -width
* 0.5);
196 glShadeModel(GL_SMOOTH
);
198 /* draw inside radius cylinder */
199 glBegin(GL_QUAD_STRIP
);
200 for (i
= 0; i
<= teeth
; i
++) {
201 angle
= i
* 2.0 * M_PI
/ teeth
;
202 glNormal3f(-cos(angle
), -sin(angle
), 0.0);
203 glVertex3f(r0
* cos(angle
), r0
* sin(angle
), -width
* 0.5);
204 glVertex3f(r0
* cos(angle
), r0
* sin(angle
), width
* 0.5);
210 static GLfloat view_rotx
= 20.0, view_roty
= 30.0, view_rotz
= 0.0;
211 static GLfloat inc_rotx
= 0, inc_roty
= 0, inc_rotz
= 0;
212 static GLint gear1
, gear2
, gear3
;
213 static GLfloat angle
= 0.0;
218 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
221 glRotatef(view_rotx
, 1.0, 0.0, 0.0);
222 glRotatef(view_roty
, 0.0, 1.0, 0.0);
223 glRotatef(view_rotz
, 0.0, 0.0, 1.0);
226 glTranslatef(-3.0, -2.0, 0.0);
227 glRotatef(angle
, 0.0, 0.0, 1.0);
232 glTranslatef(3.1, -2.0, 0.0);
233 glRotatef(-2.0 * angle
- 9.0, 0.0, 0.0, 1.0);
238 glTranslatef(-3.1, 4.2, 0.0);
239 glRotatef(-2.0 * angle
- 25.0, 0.0, 0.0, 1.0);
246 /* new window size or exposure */
248 reshape(int width
, int height
)
250 GLfloat h
= (GLfloat
) height
/ (GLfloat
) width
;
252 glViewport(0, 0, (GLint
) width
, (GLint
) height
);
253 glMatrixMode(GL_PROJECTION
);
255 glFrustum(-1.0, 1.0, -h
, h
, 5.0, 60.0);
256 glMatrixMode(GL_MODELVIEW
);
258 glTranslatef(0.0, 0.0, -40.0);
262 init(int argc
, char *argv
[])
264 static GLfloat pos
[4] = {5.0, 5.0, 10.0, 0.0};
265 static GLfloat red
[4] = {0.8, 0.1, 0.0, 1.0};
266 static GLfloat green
[4] = {0.0, 0.8, 0.2, 1.0};
267 static GLfloat blue
[4] = {0.2, 0.2, 1.0, 1.0};
270 glLightfv(GL_LIGHT0
, GL_POSITION
, pos
);
271 glEnable(GL_CULL_FACE
);
272 glEnable(GL_LIGHTING
);
274 glEnable(GL_DEPTH_TEST
);
277 gear1
= glGenLists(1);
278 glNewList(gear1
, GL_COMPILE
);
279 glMaterialfv(GL_FRONT
, GL_AMBIENT_AND_DIFFUSE
, red
);
280 gear(1.0, 4.0, 1.0, 20, 0.7);
283 gear2
= glGenLists(1);
284 glNewList(gear2
, GL_COMPILE
);
285 glMaterialfv(GL_FRONT
, GL_AMBIENT_AND_DIFFUSE
, green
);
286 gear(0.5, 2.0, 2.0, 10, 0.7);
289 gear3
= glGenLists(1);
290 glNewList(gear3
, GL_COMPILE
);
291 glMaterialfv(GL_FRONT
, GL_AMBIENT_AND_DIFFUSE
, blue
);
292 gear(1.3, 2.0, 0.5, 10, 0.7);
295 glEnable(GL_NORMALIZE
);
297 for ( i
=1; i
<argc
; i
++ ) {
298 if (strcmp(argv
[i
], "-info")==0) {
299 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER
));
300 printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION
));
301 printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR
));
302 printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS
));
307 int main( int argc
, char *argv
[] )
311 DFBSurfaceDescription dsc
;
313 DFBCHECK(DirectFBInit( &argc
, &argv
));
315 /* create the super interface */
316 DFBCHECK(DirectFBCreate( &dfb
));
318 /* create an event buffer for all devices with these caps */
319 DFBCHECK(dfb
->CreateInputEventBuffer( dfb
, DICAPS_KEYS
| DICAPS_AXES
,
320 DFB_FALSE
, &events
));
322 /* set our cooperative level to DFSCL_FULLSCREEN
323 for exclusive access to the primary layer */
324 dfb
->SetCooperativeLevel( dfb
, DFSCL_FULLSCREEN
);
326 /* get the primary surface, i.e. the surface of the
327 primary layer we have exclusive access to */
328 dsc
.flags
= DSDESC_CAPS
;
329 dsc
.caps
= DSCAPS_PRIMARY
| DSCAPS_DOUBLE
;
331 DFBCHECK(dfb
->CreateSurface( dfb
, &dsc
, &primary
));
333 /* get the size of the surface and fill it */
334 DFBCHECK(primary
->GetSize( primary
, &screen_width
, &screen_height
));
335 DFBCHECK(primary
->FillRectangle( primary
, 0, 0,
336 screen_width
, screen_height
));
337 primary
->Flip( primary
, NULL
, 0 );
339 /* create the default font and set it */
340 DFBCHECK(dfb
->CreateFont( dfb
, NULL
, NULL
, &font
));
341 DFBCHECK(primary
->SetFont( primary
, font
));
343 /* get the GL context */
344 DFBCHECK(primary
->GetGL( primary
, &primary_gl
));
346 DFBCHECK(primary_gl
->Lock( primary_gl
));
349 reshape(screen_width
, screen_height
);
351 DFBCHECK(primary_gl
->Unlock( primary_gl
));
359 DFBCHECK(primary_gl
->Lock( primary_gl
));
363 DFBCHECK(primary_gl
->Unlock( primary_gl
));
368 snprintf(buf
, 64, "%4.1f FPS\n", fps
);
370 primary
->SetColor( primary
, 0xff, 0, 0, 0xff );
371 primary
->DrawString( primary
, buf
, -1, screen_width
- 5, 5, DSTF_TOPRIGHT
);
374 primary
->Flip( primary
, NULL
, 0 );
379 if (t
- T0
>= 2000) {
380 GLfloat seconds
= (t
- T0
) / 1000.0;
382 fps
= Frames
/ seconds
;
389 while (events
->GetEvent( events
, DFB_EVENT(&evt
) ) == DFB_OK
) {
392 switch (evt
.key_symbol
) {
399 case DIKS_CURSOR_DOWN
:
402 case DIKS_CURSOR_LEFT
:
405 case DIKS_CURSOR_RIGHT
:
418 case DIET_KEYRELEASE
:
419 switch (evt
.key_symbol
) {
423 case DIKS_CURSOR_DOWN
:
426 case DIKS_CURSOR_LEFT
:
429 case DIKS_CURSOR_RIGHT
:
442 case DIET_AXISMOTION
:
443 if (evt
.flags
& DIEF_AXISREL
) {
446 view_roty
+= evt
.axisrel
/ 2.0;
449 view_rotx
+= evt
.axisrel
/ 2.0;
452 view_rotz
+= evt
.axisrel
/ 2.0;
466 view_rotx
+= inc_rotx
;
467 view_roty
+= inc_roty
;
468 view_rotz
+= inc_rotz
;
471 /* release our interfaces to shutdown DirectFB */
472 primary_gl
->Release( primary_gl
);
473 primary
->Release( primary
);
474 font
->Release( font
);
475 events
->Release( events
);