diff options
author | Claudio Ciccani <[email protected]> | 2006-05-31 17:05:11 +0000 |
---|---|---|
committer | Claudio Ciccani <[email protected]> | 2006-05-31 17:05:11 +0000 |
commit | fe94d0b33508560f7b42dacd457f9eedcaf1a210 (patch) | |
tree | 34c49ab4e01eafaf4d308c0d80e9c8d4c9b409be /progs/directfb/df_reflect.c | |
parent | b18191cf306c255fe5eff7762fc8e419e043a621 (diff) |
Added some example progs using DirectFBGL.
Diffstat (limited to 'progs/directfb/df_reflect.c')
-rw-r--r-- | progs/directfb/df_reflect.c | 489 |
1 files changed, 489 insertions, 0 deletions
diff --git a/progs/directfb/df_reflect.c b/progs/directfb/df_reflect.c new file mode 100644 index 00000000000..ce4d12f749f --- /dev/null +++ b/progs/directfb/df_reflect.c @@ -0,0 +1,489 @@ +/* + (c) Copyright 2001 convergence integrated media GmbH. + All rights reserved. + + Written by Denis Oliver Kropp <[email protected]> and + Andreas Hundt <[email protected]>. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <math.h> + +#include <directfb.h> + +#include <GL/glu.h> +#include <GL/directfbgl.h> + +#include "util/showbuffer.c" +#include "util/readtex.c" + + +/* the super interface */ +IDirectFB *dfb; + +/* the primary surface (surface of primary layer) */ +IDirectFBSurface *primary; + +/* the GL context */ +IDirectFBGL *primary_gl; + +/* our font */ +IDirectFBFont *font; + +/* event buffer */ +IDirectFBEventBuffer *events; + +/* macro for a safe call to DirectFB functions */ +#define DFBCHECK(x...) \ + { \ + err = x; \ + if (err != DFB_OK) { \ + fprintf( stderr, "%s <%d>:\n\t", __FILE__, __LINE__ ); \ + DirectFBErrorFatal( #x, err ); \ + } \ + } + +static int screen_width, screen_height; + +static unsigned long T0 = 0; +static GLint Frames = 0; +static GLfloat fps = 0; + +static inline unsigned long get_millis() +{ + struct timeval tv; + + gettimeofday (&tv, NULL); + return (tv.tv_sec * 1000 + tv.tv_usec / 1000); +} + +/*******************************/ + +#define DEG2RAD (3.14159/180.0) + +#define TABLE_TEXTURE "../images/tile.rgb" + +static GLint ImgWidth, ImgHeight; +static GLenum ImgFormat; +static GLubyte *Image = NULL; + +#define MAX_OBJECTS 2 +static GLint table_list; +static GLint objects_list[MAX_OBJECTS]; + +static GLfloat xrot, yrot; +static GLfloat spin; + +static GLint Width = 400, Height = 300; +static GLenum ShowBuffer = GL_NONE; + + +static void make_table( void ) +{ + static GLfloat table_mat[] = { 1.0, 1.0, 1.0, 0.6 }; + static GLfloat gray[] = { 0.4, 0.4, 0.4, 1.0 }; + + table_list = glGenLists(1); + glNewList( table_list, GL_COMPILE ); + + /* load table's texture */ + glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, table_mat ); +/* glMaterialfv( GL_FRONT, GL_EMISSION, gray );*/ + glMaterialfv( GL_FRONT, GL_DIFFUSE, table_mat ); + glMaterialfv( GL_FRONT, GL_AMBIENT, gray ); + + /* draw textured square for the table */ + glPushMatrix(); + glScalef( 4.0, 4.0, 4.0 ); + glBegin( GL_POLYGON ); + glNormal3f( 0.0, 1.0, 0.0 ); + glTexCoord2f( 0.0, 0.0 ); glVertex3f( -1.0, 0.0, 1.0 ); + glTexCoord2f( 1.0, 0.0 ); glVertex3f( 1.0, 0.0, 1.0 ); + glTexCoord2f( 1.0, 1.0 ); glVertex3f( 1.0, 0.0, -1.0 ); + glTexCoord2f( 0.0, 1.0 ); glVertex3f( -1.0, 0.0, -1.0 ); + glEnd(); + glPopMatrix(); + + glDisable( GL_TEXTURE_2D ); + + glEndList(); +} + + +static void make_objects( void ) +{ + GLUquadricObj *q; + + static GLfloat cyan[] = { 0.0, 1.0, 1.0, 1.0 }; + static GLfloat green[] = { 0.2, 1.0, 0.2, 1.0 }; + static GLfloat black[] = { 0.0, 0.0, 0.0, 0.0 }; + + q = gluNewQuadric(); + gluQuadricDrawStyle( q, GLU_FILL ); + gluQuadricNormals( q, GLU_SMOOTH ); + + objects_list[0] = glGenLists(1); + glNewList( objects_list[0], GL_COMPILE ); + glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cyan ); + glMaterialfv( GL_FRONT, GL_EMISSION, black ); + gluCylinder( q, 0.5, 0.5, 1.0, 15, 1 ); + glEndList(); + + objects_list[1] = glGenLists(1); + glNewList( objects_list[1], GL_COMPILE ); + glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green ); + glMaterialfv( GL_FRONT, GL_EMISSION, black ); + gluCylinder( q, 1.5, 0.0, 2.5, 15, 1 ); + glEndList(); +} + + +static void init( void ) +{ + make_table(); + make_objects(); + + Image = LoadRGBImage( TABLE_TEXTURE, &ImgWidth, &ImgHeight, &ImgFormat ); + if (!Image) { + printf("Couldn't read %s\n", TABLE_TEXTURE); + exit(0); + } + + gluBuild2DMipmaps(GL_TEXTURE_2D, 3, ImgWidth, ImgHeight, + ImgFormat, GL_UNSIGNED_BYTE, Image); + + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); + + xrot = 30.0; + yrot = 50.0; + spin = 0.0; + + glShadeModel( GL_FLAT ); + + glEnable( GL_LIGHT0 ); + glEnable( GL_LIGHTING ); + + glClearColor( 0.5, 0.5, 0.9, 0.0 ); + + glEnable( GL_NORMALIZE ); +} + + + +static void reshape(int w, int h) +{ + GLfloat yAspect = 2.5; + GLfloat xAspect = yAspect * (float) w / (float) h; + Width = w; + Height = h; + glViewport(0, 0, w, h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum( -xAspect, xAspect, -yAspect, yAspect, 10.0, 30.0 ); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + + + +static void draw_objects( GLfloat eyex, GLfloat eyey, GLfloat eyez ) +{ + (void) eyex; + (void) eyey; + (void) eyez; +#ifndef USE_ZBUFFER + if (eyex<0.5) { +#endif + glPushMatrix(); + glTranslatef( 1.0, 1.5, 0.0 ); + glRotatef( spin, 1.0, 0.5, 0.0 ); + glRotatef( 0.5*spin, 0.0, 0.5, 1.0 ); + glCallList( objects_list[0] ); + glPopMatrix(); + + glPushMatrix(); + glTranslatef( -1.0, 0.85+3.0*fabs( cos(0.01*spin) ), 0.0 ); + glRotatef( 0.5*spin, 0.0, 0.5, 1.0 ); + glRotatef( spin, 1.0, 0.5, 0.0 ); + glScalef( 0.5, 0.5, 0.5 ); + glCallList( objects_list[1] ); + glPopMatrix(); +#ifndef USE_ZBUFFER + } + else { + glPushMatrix(); + glTranslatef( -1.0, 0.85+3.0*fabs( cos(0.01*spin) ), 0.0 ); + glRotatef( 0.5*spin, 0.0, 0.5, 1.0 ); + glRotatef( spin, 1.0, 0.5, 0.0 ); + glScalef( 0.5, 0.5, 0.5 ); + glCallList( objects_list[1] ); + glPopMatrix(); + + glPushMatrix(); + glTranslatef( 1.0, 1.5, 0.0 ); + glRotatef( spin, 1.0, 0.5, 0.0 ); + glRotatef( 0.5*spin, 0.0, 0.5, 1.0 ); + glCallList( objects_list[0] ); + glPopMatrix(); + } +#endif +} + + + +static void draw_table( void ) +{ + glCallList( table_list ); +} + + + +static void draw( void ) +{ + static GLfloat light_pos[] = { 0.0, 20.0, 0.0, 1.0 }; + GLfloat dist = 20.0; + GLfloat eyex, eyey, eyez; + + glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + + eyex = dist * cos(yrot*DEG2RAD) * cos(xrot*DEG2RAD); + eyez = dist * sin(yrot*DEG2RAD) * cos(xrot*DEG2RAD); + eyey = dist * sin(xrot*DEG2RAD); + + /* view from top */ + glPushMatrix(); + gluLookAt( eyex, eyey, eyez, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0 ); + + glLightfv( GL_LIGHT0, GL_POSITION, light_pos ); + + /* draw table into stencil planes */ + glDisable( GL_DEPTH_TEST ); + glEnable( GL_STENCIL_TEST ); + glStencilFunc( GL_ALWAYS, 1, 0xffffffff ); + glStencilOp( GL_REPLACE, GL_REPLACE, GL_REPLACE ); + glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE ); + draw_table(); + glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE ); + + glEnable( GL_DEPTH_TEST ); + + /* render view from below (reflected viewport) */ + /* only draw where stencil==1 */ + if (eyey>0.0) { + glPushMatrix(); + + glStencilFunc( GL_EQUAL, 1, 0xffffffff ); /* draw if ==1 */ + glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP ); + glScalef( 1.0, -1.0, 1.0 ); + + /* Reposition light in reflected space. */ + glLightfv(GL_LIGHT0, GL_POSITION, light_pos); + + draw_objects(eyex, eyey, eyez); + glPopMatrix(); + + /* Restore light's original unreflected position. */ + glLightfv(GL_LIGHT0, GL_POSITION, light_pos); + } + + glDisable( GL_STENCIL_TEST ); + + glEnable( GL_BLEND ); + glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + + glEnable( GL_TEXTURE_2D ); + draw_table(); + glDisable( GL_TEXTURE_2D ); + glDisable( GL_BLEND ); + + /* view from top */ + glPushMatrix(); + + draw_objects(eyex, eyey, eyez); + + glPopMatrix(); + + glPopMatrix(); + + if (ShowBuffer == GL_DEPTH) { + ShowDepthBuffer(Width, Height, 1.0, 0.0); + } + else if (ShowBuffer == GL_STENCIL) { + ShowStencilBuffer(Width, Height, 255.0, 0.0); + } + else if (ShowBuffer == GL_ALPHA) { + ShowAlphaBuffer(Width, Height); + } +} + +/*******************************/ + +int main( int argc, char *argv[] ) +{ + int quit = 0; + DFBResult err; + DFBSurfaceDescription dsc; + + DFBCHECK(DirectFBInit( &argc, &argv )); + + /* create the super interface */ + DFBCHECK(DirectFBCreate( &dfb )); + + /* create an event buffer for all devices with these caps */ + DFBCHECK(dfb->CreateInputEventBuffer( dfb, DICAPS_ALL, DFB_FALSE, &events )); + + /* set our cooperative level to DFSCL_FULLSCREEN + for exclusive access to the primary layer */ + dfb->SetCooperativeLevel( dfb, DFSCL_FULLSCREEN ); + + /* get the primary surface, i.e. the surface of the + primary layer we have exclusive access to */ + dsc.flags = DSDESC_CAPS; + dsc.caps = (DFBSurfaceCapabilities)(DSCAPS_PRIMARY | DSCAPS_DOUBLE); + + DFBCHECK(dfb->CreateSurface( dfb, &dsc, &primary )); + + /* get the size of the surface and fill it */ + DFBCHECK(primary->GetSize( primary, &screen_width, &screen_height )); + DFBCHECK(primary->FillRectangle( primary, 0, 0, + screen_width, screen_height )); + + /* create the default font and set it */ + DFBCHECK(dfb->CreateFont( dfb, NULL, NULL, &font )); + DFBCHECK(primary->SetFont( primary, font )); + + /* get the GL context */ + DFBCHECK(primary->GetGL( primary, &primary_gl )); + + DFBCHECK(primary_gl->Lock( primary_gl )); + + init(); + reshape(screen_width, screen_height); + + DFBCHECK(primary_gl->Unlock( primary_gl )); + + T0 = get_millis(); + + while (!quit) { + DFBInputEvent evt; + unsigned long t; + + DFBCHECK(primary_gl->Lock( primary_gl )); + + draw(); + + DFBCHECK(primary_gl->Unlock( primary_gl )); + + if (fps) { + char buf[64]; + + sprintf(buf, "%4.1f FPS\n", fps); + primary->SetColor( primary, 0xff, 0, 0, 0xff ); + primary->DrawString( primary, buf, -1, screen_width - 5, 5, DSTF_TOPRIGHT ); + } + + primary->Flip( primary, NULL, (DFBSurfaceFlipFlags)0 ); + Frames++; + + + t = get_millis(); + if (t - T0 >= 1000) { + GLfloat seconds = (t - T0) / 1000.0; + + fps = Frames / seconds; + + T0 = t; + Frames = 0; + } + + + while (events->GetEvent( events, DFB_EVENT(&evt) ) == DFB_OK) { + switch (evt.type) { + case DIET_KEYPRESS: + switch (DFB_LOWER_CASE(evt.key_symbol)) { + case DIKS_ESCAPE: + quit = 1; + break; + case DIKS_CURSOR_UP: + xrot += 3.0; + if ( xrot > 85 ) + xrot = 85; + break; + case DIKS_CURSOR_DOWN: + xrot -= 3.0; + if ( xrot < 5 ) + xrot = 5; + break; + case DIKS_CURSOR_LEFT: + yrot += 3.0; + break; + case DIKS_CURSOR_RIGHT: + yrot -= 3.0; + break; + case DIKS_SMALL_D: + ShowBuffer = GL_DEPTH; + break; + case DIKS_SMALL_S: + ShowBuffer = GL_STENCIL; + break; + case DIKS_SMALL_A: + ShowBuffer = GL_ALPHA; + break; + default: + ShowBuffer = GL_NONE; + } + break; + case DIET_AXISMOTION: + if (evt.flags & DIEF_AXISREL) { + switch (evt.axis) { + case DIAI_X: + yrot += evt.axisrel / 2.0; + break; + case DIAI_Y: + xrot += evt.axisrel / 2.0; + break; + default: + ; + } + } + break; + default: + ; + } + } + + spin += 2.0; + yrot += 3.0; + } + + /* release our interfaces to shutdown DirectFB */ + primary_gl->Release( primary_gl ); + primary->Release( primary ); + font->Release( font ); + events->Release( events ); + dfb->Release( dfb ); + + return 0; +} + |