Remove DirectFBGL header from Mesa bacause since 1.0.0 DirectFB installs its own...
[mesa.git] / progs / directfb / df_reflect.c
1 /*
2 (c) Copyright 2001 convergence integrated media GmbH.
3 All rights reserved.
4
5 Written by Denis Oliver Kropp <dok@convergence.de> and
6 Andreas Hundt <andi@convergence.de>.
7
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.
12
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.
17
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.
22 */
23
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <string.h>
27 #include <math.h>
28
29 #include <directfb.h>
30 #include <directfbgl.h>
31
32 #include <GL/glu.h>
33
34 #include "util/showbuffer.c"
35 #include "util/readtex.c"
36
37
38 /* the super interface */
39 IDirectFB *dfb;
40
41 /* the primary surface (surface of primary layer) */
42 IDirectFBSurface *primary;
43
44 /* the GL context */
45 IDirectFBGL *primary_gl;
46
47 /* our font */
48 IDirectFBFont *font;
49
50 /* event buffer */
51 IDirectFBEventBuffer *events;
52
53 /* macro for a safe call to DirectFB functions */
54 #define DFBCHECK(x...) \
55 { \
56 err = x; \
57 if (err != DFB_OK) { \
58 fprintf( stderr, "%s <%d>:\n\t", __FILE__, __LINE__ ); \
59 DirectFBErrorFatal( #x, err ); \
60 } \
61 }
62
63 static int screen_width, screen_height;
64
65 static unsigned long T0 = 0;
66 static GLint Frames = 0;
67 static GLfloat fps = 0;
68
69 static inline unsigned long get_millis()
70 {
71 struct timeval tv;
72
73 gettimeofday (&tv, NULL);
74 return (tv.tv_sec * 1000 + tv.tv_usec / 1000);
75 }
76
77 /*******************************/
78
79 #define DEG2RAD (3.14159/180.0)
80
81 #define TABLE_TEXTURE "../images/tile.rgb"
82
83 static GLint ImgWidth, ImgHeight;
84 static GLenum ImgFormat;
85 static GLubyte *Image = NULL;
86
87 #define MAX_OBJECTS 2
88 static GLint table_list;
89 static GLint objects_list[MAX_OBJECTS];
90
91 static GLfloat xrot, yrot;
92 static GLfloat spin;
93
94 static GLint Width = 400, Height = 300;
95 static GLenum ShowBuffer = GL_NONE;
96
97
98 static void make_table( void )
99 {
100 static GLfloat table_mat[] = { 1.0, 1.0, 1.0, 0.6 };
101 static GLfloat gray[] = { 0.4, 0.4, 0.4, 1.0 };
102
103 table_list = glGenLists(1);
104 glNewList( table_list, GL_COMPILE );
105
106 /* load table's texture */
107 glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, table_mat );
108 /* glMaterialfv( GL_FRONT, GL_EMISSION, gray );*/
109 glMaterialfv( GL_FRONT, GL_DIFFUSE, table_mat );
110 glMaterialfv( GL_FRONT, GL_AMBIENT, gray );
111
112 /* draw textured square for the table */
113 glPushMatrix();
114 glScalef( 4.0, 4.0, 4.0 );
115 glBegin( GL_POLYGON );
116 glNormal3f( 0.0, 1.0, 0.0 );
117 glTexCoord2f( 0.0, 0.0 ); glVertex3f( -1.0, 0.0, 1.0 );
118 glTexCoord2f( 1.0, 0.0 ); glVertex3f( 1.0, 0.0, 1.0 );
119 glTexCoord2f( 1.0, 1.0 ); glVertex3f( 1.0, 0.0, -1.0 );
120 glTexCoord2f( 0.0, 1.0 ); glVertex3f( -1.0, 0.0, -1.0 );
121 glEnd();
122 glPopMatrix();
123
124 glDisable( GL_TEXTURE_2D );
125
126 glEndList();
127 }
128
129
130 static void make_objects( void )
131 {
132 GLUquadricObj *q;
133
134 static GLfloat cyan[] = { 0.0, 1.0, 1.0, 1.0 };
135 static GLfloat green[] = { 0.2, 1.0, 0.2, 1.0 };
136 static GLfloat black[] = { 0.0, 0.0, 0.0, 0.0 };
137
138 q = gluNewQuadric();
139 gluQuadricDrawStyle( q, GLU_FILL );
140 gluQuadricNormals( q, GLU_SMOOTH );
141
142 objects_list[0] = glGenLists(1);
143 glNewList( objects_list[0], GL_COMPILE );
144 glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cyan );
145 glMaterialfv( GL_FRONT, GL_EMISSION, black );
146 gluCylinder( q, 0.5, 0.5, 1.0, 15, 1 );
147 glEndList();
148
149 objects_list[1] = glGenLists(1);
150 glNewList( objects_list[1], GL_COMPILE );
151 glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green );
152 glMaterialfv( GL_FRONT, GL_EMISSION, black );
153 gluCylinder( q, 1.5, 0.0, 2.5, 15, 1 );
154 glEndList();
155 }
156
157
158 static void init( void )
159 {
160 make_table();
161 make_objects();
162
163 Image = LoadRGBImage( TABLE_TEXTURE, &ImgWidth, &ImgHeight, &ImgFormat );
164 if (!Image) {
165 printf("Couldn't read %s\n", TABLE_TEXTURE);
166 exit(0);
167 }
168
169 gluBuild2DMipmaps(GL_TEXTURE_2D, 3, ImgWidth, ImgHeight,
170 ImgFormat, GL_UNSIGNED_BYTE, Image);
171
172 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
173 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
174 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
175 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
176
177 xrot = 30.0;
178 yrot = 50.0;
179 spin = 0.0;
180
181 glShadeModel( GL_FLAT );
182
183 glEnable( GL_LIGHT0 );
184 glEnable( GL_LIGHTING );
185
186 glClearColor( 0.5, 0.5, 0.9, 0.0 );
187
188 glEnable( GL_NORMALIZE );
189 }
190
191
192
193 static void reshape(int w, int h)
194 {
195 GLfloat yAspect = 2.5;
196 GLfloat xAspect = yAspect * (float) w / (float) h;
197 Width = w;
198 Height = h;
199 glViewport(0, 0, w, h);
200 glMatrixMode(GL_PROJECTION);
201 glLoadIdentity();
202 glFrustum( -xAspect, xAspect, -yAspect, yAspect, 10.0, 30.0 );
203 glMatrixMode(GL_MODELVIEW);
204 glLoadIdentity();
205 }
206
207
208
209 static void draw_objects( GLfloat eyex, GLfloat eyey, GLfloat eyez )
210 {
211 (void) eyex;
212 (void) eyey;
213 (void) eyez;
214 #ifndef USE_ZBUFFER
215 if (eyex<0.5) {
216 #endif
217 glPushMatrix();
218 glTranslatef( 1.0, 1.5, 0.0 );
219 glRotatef( spin, 1.0, 0.5, 0.0 );
220 glRotatef( 0.5*spin, 0.0, 0.5, 1.0 );
221 glCallList( objects_list[0] );
222 glPopMatrix();
223
224 glPushMatrix();
225 glTranslatef( -1.0, 0.85+3.0*fabs( cos(0.01*spin) ), 0.0 );
226 glRotatef( 0.5*spin, 0.0, 0.5, 1.0 );
227 glRotatef( spin, 1.0, 0.5, 0.0 );
228 glScalef( 0.5, 0.5, 0.5 );
229 glCallList( objects_list[1] );
230 glPopMatrix();
231 #ifndef USE_ZBUFFER
232 }
233 else {
234 glPushMatrix();
235 glTranslatef( -1.0, 0.85+3.0*fabs( cos(0.01*spin) ), 0.0 );
236 glRotatef( 0.5*spin, 0.0, 0.5, 1.0 );
237 glRotatef( spin, 1.0, 0.5, 0.0 );
238 glScalef( 0.5, 0.5, 0.5 );
239 glCallList( objects_list[1] );
240 glPopMatrix();
241
242 glPushMatrix();
243 glTranslatef( 1.0, 1.5, 0.0 );
244 glRotatef( spin, 1.0, 0.5, 0.0 );
245 glRotatef( 0.5*spin, 0.0, 0.5, 1.0 );
246 glCallList( objects_list[0] );
247 glPopMatrix();
248 }
249 #endif
250 }
251
252
253
254 static void draw_table( void )
255 {
256 glCallList( table_list );
257 }
258
259
260
261 static void draw( void )
262 {
263 static GLfloat light_pos[] = { 0.0, 20.0, 0.0, 1.0 };
264 GLfloat dist = 20.0;
265 GLfloat eyex, eyey, eyez;
266
267 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
268
269
270 eyex = dist * cos(yrot*DEG2RAD) * cos(xrot*DEG2RAD);
271 eyez = dist * sin(yrot*DEG2RAD) * cos(xrot*DEG2RAD);
272 eyey = dist * sin(xrot*DEG2RAD);
273
274 /* view from top */
275 glPushMatrix();
276 gluLookAt( eyex, eyey, eyez, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0 );
277
278 glLightfv( GL_LIGHT0, GL_POSITION, light_pos );
279
280 /* draw table into stencil planes */
281 glDisable( GL_DEPTH_TEST );
282 glEnable( GL_STENCIL_TEST );
283 glStencilFunc( GL_ALWAYS, 1, 0xffffffff );
284 glStencilOp( GL_REPLACE, GL_REPLACE, GL_REPLACE );
285 glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
286 draw_table();
287 glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
288
289 glEnable( GL_DEPTH_TEST );
290
291 /* render view from below (reflected viewport) */
292 /* only draw where stencil==1 */
293 if (eyey>0.0) {
294 glPushMatrix();
295
296 glStencilFunc( GL_EQUAL, 1, 0xffffffff ); /* draw if ==1 */
297 glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
298 glScalef( 1.0, -1.0, 1.0 );
299
300 /* Reposition light in reflected space. */
301 glLightfv(GL_LIGHT0, GL_POSITION, light_pos);
302
303 draw_objects(eyex, eyey, eyez);
304 glPopMatrix();
305
306 /* Restore light's original unreflected position. */
307 glLightfv(GL_LIGHT0, GL_POSITION, light_pos);
308 }
309
310 glDisable( GL_STENCIL_TEST );
311
312 glEnable( GL_BLEND );
313 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
314
315 glEnable( GL_TEXTURE_2D );
316 draw_table();
317 glDisable( GL_TEXTURE_2D );
318 glDisable( GL_BLEND );
319
320 /* view from top */
321 glPushMatrix();
322
323 draw_objects(eyex, eyey, eyez);
324
325 glPopMatrix();
326
327 glPopMatrix();
328
329 if (ShowBuffer == GL_DEPTH) {
330 ShowDepthBuffer(Width, Height, 1.0, 0.0);
331 }
332 else if (ShowBuffer == GL_STENCIL) {
333 ShowStencilBuffer(Width, Height, 255.0, 0.0);
334 }
335 else if (ShowBuffer == GL_ALPHA) {
336 ShowAlphaBuffer(Width, Height);
337 }
338 }
339
340 /*******************************/
341
342 int main( int argc, char *argv[] )
343 {
344 int quit = 0;
345 DFBResult err;
346 DFBSurfaceDescription dsc;
347
348 DFBCHECK(DirectFBInit( &argc, &argv ));
349
350 /* create the super interface */
351 DFBCHECK(DirectFBCreate( &dfb ));
352
353 /* create an event buffer for all devices with these caps */
354 DFBCHECK(dfb->CreateInputEventBuffer( dfb, DICAPS_ALL, DFB_FALSE, &events ));
355
356 /* set our cooperative level to DFSCL_FULLSCREEN
357 for exclusive access to the primary layer */
358 dfb->SetCooperativeLevel( dfb, DFSCL_FULLSCREEN );
359
360 /* get the primary surface, i.e. the surface of the
361 primary layer we have exclusive access to */
362 dsc.flags = DSDESC_CAPS;
363 dsc.caps = (DFBSurfaceCapabilities)(DSCAPS_PRIMARY | DSCAPS_DOUBLE);
364
365 DFBCHECK(dfb->CreateSurface( dfb, &dsc, &primary ));
366
367 /* get the size of the surface and fill it */
368 DFBCHECK(primary->GetSize( primary, &screen_width, &screen_height ));
369 DFBCHECK(primary->FillRectangle( primary, 0, 0,
370 screen_width, screen_height ));
371
372 /* create the default font and set it */
373 DFBCHECK(dfb->CreateFont( dfb, NULL, NULL, &font ));
374 DFBCHECK(primary->SetFont( primary, font ));
375
376 /* get the GL context */
377 DFBCHECK(primary->GetGL( primary, &primary_gl ));
378
379 DFBCHECK(primary_gl->Lock( primary_gl ));
380
381 init();
382 reshape(screen_width, screen_height);
383
384 DFBCHECK(primary_gl->Unlock( primary_gl ));
385
386 T0 = get_millis();
387
388 while (!quit) {
389 DFBInputEvent evt;
390 unsigned long t;
391
392 DFBCHECK(primary_gl->Lock( primary_gl ));
393
394 draw();
395
396 DFBCHECK(primary_gl->Unlock( primary_gl ));
397
398 if (fps) {
399 char buf[64];
400
401 sprintf(buf, "%4.1f FPS\n", fps);
402 primary->SetColor( primary, 0xff, 0, 0, 0xff );
403 primary->DrawString( primary, buf, -1, screen_width - 5, 5, DSTF_TOPRIGHT );
404 }
405
406 primary->Flip( primary, NULL, (DFBSurfaceFlipFlags)0 );
407 Frames++;
408
409
410 t = get_millis();
411 if (t - T0 >= 1000) {
412 GLfloat seconds = (t - T0) / 1000.0;
413
414 fps = Frames / seconds;
415
416 T0 = t;
417 Frames = 0;
418 }
419
420
421 while (events->GetEvent( events, DFB_EVENT(&evt) ) == DFB_OK) {
422 switch (evt.type) {
423 case DIET_KEYPRESS:
424 switch (DFB_LOWER_CASE(evt.key_symbol)) {
425 case DIKS_ESCAPE:
426 quit = 1;
427 break;
428 case DIKS_CURSOR_UP:
429 xrot += 3.0;
430 if ( xrot > 85 )
431 xrot = 85;
432 break;
433 case DIKS_CURSOR_DOWN:
434 xrot -= 3.0;
435 if ( xrot < 5 )
436 xrot = 5;
437 break;
438 case DIKS_CURSOR_LEFT:
439 yrot += 3.0;
440 break;
441 case DIKS_CURSOR_RIGHT:
442 yrot -= 3.0;
443 break;
444 case DIKS_SMALL_D:
445 ShowBuffer = GL_DEPTH;
446 break;
447 case DIKS_SMALL_S:
448 ShowBuffer = GL_STENCIL;
449 break;
450 case DIKS_SMALL_A:
451 ShowBuffer = GL_ALPHA;
452 break;
453 default:
454 ShowBuffer = GL_NONE;
455 }
456 break;
457 case DIET_AXISMOTION:
458 if (evt.flags & DIEF_AXISREL) {
459 switch (evt.axis) {
460 case DIAI_X:
461 yrot += evt.axisrel / 2.0;
462 break;
463 case DIAI_Y:
464 xrot += evt.axisrel / 2.0;
465 break;
466 default:
467 ;
468 }
469 }
470 break;
471 default:
472 ;
473 }
474 }
475
476 spin += 2.0;
477 yrot += 3.0;
478 }
479
480 /* release our interfaces to shutdown DirectFB */
481 primary_gl->Release( primary_gl );
482 primary->Release( primary );
483 font->Release( font );
484 events->Release( events );
485 dfb->Release( dfb );
486
487 return 0;
488 }
489