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>
34 #include "util/showbuffer.c"
35 #include "util/readtex.c"
38 /* the super interface */
41 /* the primary surface (surface of primary layer) */
42 IDirectFBSurface
*primary
;
45 IDirectFBGL
*primary_gl
;
51 IDirectFBEventBuffer
*events
;
53 /* macro for a safe call to DirectFB functions */
54 #define DFBCHECK(x...) \
57 if (err != DFB_OK) { \
58 fprintf( stderr, "%s <%d>:\n\t", __FILE__, __LINE__ ); \
59 DirectFBErrorFatal( #x, err ); \
63 static int screen_width
, screen_height
;
65 static unsigned long T0
= 0;
66 static GLint Frames
= 0;
67 static GLfloat fps
= 0;
69 static inline unsigned long get_millis()
73 gettimeofday (&tv
, NULL
);
74 return (tv
.tv_sec
* 1000 + tv
.tv_usec
/ 1000);
77 /*******************************/
79 #define DEG2RAD (3.14159/180.0)
81 #define TABLE_TEXTURE "../images/tile.rgb"
83 static GLint ImgWidth
, ImgHeight
;
84 static GLenum ImgFormat
;
85 static GLubyte
*Image
= NULL
;
88 static GLint table_list
;
89 static GLint objects_list
[MAX_OBJECTS
];
91 static GLfloat xrot
, yrot
;
94 static GLint Width
= 400, Height
= 300;
95 static GLenum ShowBuffer
= GL_NONE
;
98 static void make_table( void )
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 };
103 table_list
= glGenLists(1);
104 glNewList( table_list
, GL_COMPILE
);
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
);
112 /* draw textured square for the table */
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 );
124 glDisable( GL_TEXTURE_2D
);
130 static void make_objects( void )
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 };
139 gluQuadricDrawStyle( q
, GLU_FILL
);
140 gluQuadricNormals( q
, GLU_SMOOTH
);
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 );
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 );
158 static void init( void )
163 Image
= LoadRGBImage( TABLE_TEXTURE
, &ImgWidth
, &ImgHeight
, &ImgFormat
);
165 printf("Couldn't read %s\n", TABLE_TEXTURE
);
169 gluBuild2DMipmaps(GL_TEXTURE_2D
, 3, ImgWidth
, ImgHeight
,
170 ImgFormat
, GL_UNSIGNED_BYTE
, Image
);
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
);
181 glShadeModel( GL_FLAT
);
183 glEnable( GL_LIGHT0
);
184 glEnable( GL_LIGHTING
);
186 glClearColor( 0.5, 0.5, 0.9, 0.0 );
188 glEnable( GL_NORMALIZE
);
193 static void reshape(int w
, int h
)
195 GLfloat yAspect
= 2.5;
196 GLfloat xAspect
= yAspect
* (float) w
/ (float) h
;
199 glViewport(0, 0, w
, h
);
200 glMatrixMode(GL_PROJECTION
);
202 glFrustum( -xAspect
, xAspect
, -yAspect
, yAspect
, 10.0, 30.0 );
203 glMatrixMode(GL_MODELVIEW
);
209 static void draw_objects( GLfloat eyex
, GLfloat eyey
, GLfloat eyez
)
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] );
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] );
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] );
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] );
254 static void draw_table( void )
256 glCallList( table_list
);
261 static void draw( void )
263 static GLfloat light_pos
[] = { 0.0, 20.0, 0.0, 1.0 };
265 GLfloat eyex
, eyey
, eyez
;
267 glClear( GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
| GL_STENCIL_BUFFER_BIT
);
270 eyex
= dist
* cos(yrot
*DEG2RAD
) * cos(xrot
*DEG2RAD
);
271 eyez
= dist
* sin(yrot
*DEG2RAD
) * cos(xrot
*DEG2RAD
);
272 eyey
= dist
* sin(xrot
*DEG2RAD
);
276 gluLookAt( eyex
, eyey
, eyez
, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0 );
278 glLightfv( GL_LIGHT0
, GL_POSITION
, light_pos
);
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
);
287 glColorMask( GL_TRUE
, GL_TRUE
, GL_TRUE
, GL_TRUE
);
289 glEnable( GL_DEPTH_TEST
);
291 /* render view from below (reflected viewport) */
292 /* only draw where stencil==1 */
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 );
300 /* Reposition light in reflected space. */
301 glLightfv(GL_LIGHT0
, GL_POSITION
, light_pos
);
303 draw_objects(eyex
, eyey
, eyez
);
306 /* Restore light's original unreflected position. */
307 glLightfv(GL_LIGHT0
, GL_POSITION
, light_pos
);
310 glDisable( GL_STENCIL_TEST
);
312 glEnable( GL_BLEND
);
313 glBlendFunc( GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
315 glEnable( GL_TEXTURE_2D
);
317 glDisable( GL_TEXTURE_2D
);
318 glDisable( GL_BLEND
);
323 draw_objects(eyex
, eyey
, eyez
);
329 if (ShowBuffer
== GL_DEPTH
) {
330 ShowDepthBuffer(Width
, Height
, 1.0, 0.0);
332 else if (ShowBuffer
== GL_STENCIL
) {
333 ShowStencilBuffer(Width
, Height
, 255.0, 0.0);
335 else if (ShowBuffer
== GL_ALPHA
) {
336 ShowAlphaBuffer(Width
, Height
);
340 /*******************************/
342 int main( int argc
, char *argv
[] )
346 DFBSurfaceDescription dsc
;
348 DFBCHECK(DirectFBInit( &argc
, &argv
));
350 /* create the super interface */
351 DFBCHECK(DirectFBCreate( &dfb
));
353 /* create an event buffer for all devices with these caps */
354 DFBCHECK(dfb
->CreateInputEventBuffer( dfb
, DICAPS_ALL
, DFB_FALSE
, &events
));
356 /* set our cooperative level to DFSCL_FULLSCREEN
357 for exclusive access to the primary layer */
358 dfb
->SetCooperativeLevel( dfb
, DFSCL_FULLSCREEN
);
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
);
365 DFBCHECK(dfb
->CreateSurface( dfb
, &dsc
, &primary
));
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
));
372 /* create the default font and set it */
373 DFBCHECK(dfb
->CreateFont( dfb
, NULL
, NULL
, &font
));
374 DFBCHECK(primary
->SetFont( primary
, font
));
376 /* get the GL context */
377 DFBCHECK(primary
->GetGL( primary
, &primary_gl
));
379 DFBCHECK(primary_gl
->Lock( primary_gl
));
382 reshape(screen_width
, screen_height
);
384 DFBCHECK(primary_gl
->Unlock( primary_gl
));
392 DFBCHECK(primary_gl
->Lock( primary_gl
));
396 DFBCHECK(primary_gl
->Unlock( primary_gl
));
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
);
406 primary
->Flip( primary
, NULL
, (DFBSurfaceFlipFlags
)0 );
411 if (t
- T0
>= 1000) {
412 GLfloat seconds
= (t
- T0
) / 1000.0;
414 fps
= Frames
/ seconds
;
421 while (events
->GetEvent( events
, DFB_EVENT(&evt
) ) == DFB_OK
) {
424 switch (DFB_LOWER_CASE(evt
.key_symbol
)) {
433 case DIKS_CURSOR_DOWN
:
438 case DIKS_CURSOR_LEFT
:
441 case DIKS_CURSOR_RIGHT
:
445 ShowBuffer
= GL_DEPTH
;
448 ShowBuffer
= GL_STENCIL
;
451 ShowBuffer
= GL_ALPHA
;
454 ShowBuffer
= GL_NONE
;
457 case DIET_AXISMOTION
:
458 if (evt
.flags
& DIEF_AXISREL
) {
461 yrot
+= evt
.axisrel
/ 2.0;
464 xrot
+= evt
.axisrel
/ 2.0;
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
);