diff options
| -rw-r--r-- | progs/directfb/Makefile | 36 | ||||
| -rw-r--r-- | progs/directfb/df_gears.c | 480 | ||||
| -rw-r--r-- | progs/directfb/df_morph3d.c | 1013 | ||||
| -rw-r--r-- | progs/directfb/df_reflect.c | 489 | ||||
| -rw-r--r-- | progs/directfb/multi_window.c | 240 | 
5 files changed, 2258 insertions, 0 deletions
diff --git a/progs/directfb/Makefile b/progs/directfb/Makefile new file mode 100644 index 0000000000..a541c8ff9a --- /dev/null +++ b/progs/directfb/Makefile @@ -0,0 +1,36 @@ +# progs/directfb/Makefile + +TOP = ../.. +include $(TOP)/configs/current + + +INCDIR = $(TOP)/include -I$(TOP)/progs + +LIB_DEP = $(LIB_DIR)/$(GL_LIB_NAME) $(LIB_DIR)/$(GLU_LIB_NAME) + +CFLAGS += $(shell pkg-config --cflags directfb) +APP_LIB_DEPS += $(shell pkg-config --libs directfb) + +PROGS = df_gears \ +	   df_reflect \ +	   df_morph3d \ +	   multi_window + +##### RULES ##### + +.SUFFIXES: +.SUFFIXES: .c + +.c: $(LIB_DEP) +	$(CC) -I$(INCDIR) $(CFLAGS) $< $(APP_LIB_DEPS) -o $@ + + +##### TARGETS ##### + +default: $(PROGS) + + +clean: +	-rm -f $(PROGS) +	-rm -f *.o *~ + diff --git a/progs/directfb/df_gears.c b/progs/directfb/df_gears.c new file mode 100644 index 0000000000..27df900115 --- /dev/null +++ b/progs/directfb/df_gears.c @@ -0,0 +1,480 @@ +/* +   (c) Copyright 2001  convergence integrated media GmbH. +   All rights reserved. + +   Written by Denis Oliver Kropp <dok@convergence.de> and +              Andreas Hundt <andi@convergence.de>. + +   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/gl.h> +#include <GL/directfbgl.h> + + +/* 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); +} + + +#ifndef M_PI +#define M_PI 3.14159265 +#endif + +/** + +  Draw a gear wheel.  You'll probably want to call this function when +  building a display list since we do a lot of trig here. + +  Input:  inner_radius - radius of hole at center +          outer_radius - radius at center of teeth +          width - width of gear +          teeth - number of teeth +          tooth_depth - depth of tooth + + **/ + +static void +gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width, +  GLint teeth, GLfloat tooth_depth) +{ +  GLint i; +  GLfloat r0, r1, r2; +  GLfloat angle, da; +  GLfloat u, v, len; + +  r0 = inner_radius; +  r1 = outer_radius - tooth_depth / 2.0; +  r2 = outer_radius + tooth_depth / 2.0; + +  da = 2.0 * M_PI / teeth / 4.0; + +  glShadeModel(GL_FLAT); + +  glNormal3f(0.0, 0.0, 1.0); + +  /* draw front face */ +  glBegin(GL_QUAD_STRIP); +  for (i = 0; i <= teeth; i++) { +    angle = i * 2.0 * M_PI / teeth; +    glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5); +    glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5); +    if (i < teeth) { +      glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5); +      glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5); +    } +  } +  glEnd(); + +  /* draw front sides of teeth */ +  glBegin(GL_QUADS); +  da = 2.0 * M_PI / teeth / 4.0; +  for (i = 0; i < teeth; i++) { +    angle = i * 2.0 * M_PI / teeth; + +    glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5); +    glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5); +    glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), width * 0.5); +    glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5); +  } +  glEnd(); + +  glNormal3f(0.0, 0.0, -1.0); + +  /* draw back face */ +  glBegin(GL_QUAD_STRIP); +  for (i = 0; i <= teeth; i++) { +    angle = i * 2.0 * M_PI / teeth; +    glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5); +    glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5); +    if (i < teeth) { +      glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5); +      glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5); +    } +  } +  glEnd(); + +  /* draw back sides of teeth */ +  glBegin(GL_QUADS); +  da = 2.0 * M_PI / teeth / 4.0; +  for (i = 0; i < teeth; i++) { +    angle = i * 2.0 * M_PI / teeth; + +    glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5); +    glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), -width * 0.5); +    glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5); +    glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5); +  } +  glEnd(); + +  /* draw outward faces of teeth */ +  glBegin(GL_QUAD_STRIP); +  for (i = 0; i < teeth; i++) { +    angle = i * 2.0 * M_PI / teeth; + +    glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5); +    glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5); +    u = r2 * cos(angle + da) - r1 * cos(angle); +    v = r2 * sin(angle + da) - r1 * sin(angle); +    len = sqrt(u * u + v * v); +    u /= len; +    v /= len; +    glNormal3f(v, -u, 0.0); +    glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5); +    glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5); +    glNormal3f(cos(angle), sin(angle), 0.0); +    glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), width * 0.5); +    glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), -width * 0.5); +    u = r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da); +    v = r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da); +    glNormal3f(v, -u, 0.0); +    glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5); +    glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5); +    glNormal3f(cos(angle), sin(angle), 0.0); +  } + +  glVertex3f(r1 * cos(0), r1 * sin(0), width * 0.5); +  glVertex3f(r1 * cos(0), r1 * sin(0), -width * 0.5); + +  glEnd(); + +  glShadeModel(GL_SMOOTH); + +  /* draw inside radius cylinder */ +  glBegin(GL_QUAD_STRIP); +  for (i = 0; i <= teeth; i++) { +    angle = i * 2.0 * M_PI / teeth; +    glNormal3f(-cos(angle), -sin(angle), 0.0); +    glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5); +    glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5); +  } +  glEnd(); + +} + +static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0; +static GLfloat inc_rotx = 0, inc_roty = 0, inc_rotz = 0; +static GLint gear1, gear2, gear3; +static GLfloat angle = 0.0; + +static void +draw(void) +{ +  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + +  glPushMatrix(); +    glRotatef(view_rotx, 1.0, 0.0, 0.0); +    glRotatef(view_roty, 0.0, 1.0, 0.0); +    glRotatef(view_rotz, 0.0, 0.0, 1.0); + +    glPushMatrix(); +      glTranslatef(-3.0, -2.0, 0.0); +      glRotatef(angle, 0.0, 0.0, 1.0); +      glCallList(gear1); +    glPopMatrix(); + +    glPushMatrix(); +      glTranslatef(3.1, -2.0, 0.0); +      glRotatef(-2.0 * angle - 9.0, 0.0, 0.0, 1.0); +      glCallList(gear2); +    glPopMatrix(); + +    glPushMatrix(); +      glTranslatef(-3.1, 4.2, 0.0); +      glRotatef(-2.0 * angle - 25.0, 0.0, 0.0, 1.0); +      glCallList(gear3); +    glPopMatrix(); + +  glPopMatrix(); +} + +/* new window size or exposure */ +static void +reshape(int width, int height) +{ +  GLfloat h = (GLfloat) height / (GLfloat) width; + +  glViewport(0, 0, (GLint) width, (GLint) height); +  glMatrixMode(GL_PROJECTION); +  glLoadIdentity(); +  glFrustum(-1.0, 1.0, -h, h, 5.0, 60.0); +  glMatrixMode(GL_MODELVIEW); +  glLoadIdentity(); +  glTranslatef(0.0, 0.0, -40.0); +} + +static void +init(int argc, char *argv[]) +{ +  static GLfloat pos[4] = {5.0, 5.0, 10.0, 0.0}; +  static GLfloat red[4] = {0.8, 0.1, 0.0, 1.0}; +  static GLfloat green[4] = {0.0, 0.8, 0.2, 1.0}; +  static GLfloat blue[4] = {0.2, 0.2, 1.0, 1.0}; +  GLint i; + +  glLightfv(GL_LIGHT0, GL_POSITION, pos); +  glEnable(GL_CULL_FACE); +  glEnable(GL_LIGHTING); +  glEnable(GL_LIGHT0); +  glEnable(GL_DEPTH_TEST); + +  /* make the gears */ +  gear1 = glGenLists(1); +  glNewList(gear1, GL_COMPILE); +  glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red); +  gear(1.0, 4.0, 1.0, 20, 0.7); +  glEndList(); + +  gear2 = glGenLists(1); +  glNewList(gear2, GL_COMPILE); +  glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green); +  gear(0.5, 2.0, 2.0, 10, 0.7); +  glEndList(); + +  gear3 = glGenLists(1); +  glNewList(gear3, GL_COMPILE); +  glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue); +  gear(1.3, 2.0, 0.5, 10, 0.7); +  glEndList(); + +  glEnable(GL_NORMALIZE); + +  for ( i=1; i<argc; i++ ) { +    if (strcmp(argv[i], "-info")==0) { +      printf("GL_RENDERER   = %s\n", (char *) glGetString(GL_RENDERER)); +      printf("GL_VERSION    = %s\n", (char *) glGetString(GL_VERSION)); +      printf("GL_VENDOR     = %s\n", (char *) glGetString(GL_VENDOR)); +      printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS)); +    } +  } +} + +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_KEYS | DICAPS_AXES, +                                           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  = 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 )); +     primary->Flip( primary, NULL, 0 ); + +     /* 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(argc, argv); +     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]; + +               snprintf(buf, 64, "%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, 0 ); +          Frames++; + + +          t = get_millis(); +          if (t - T0 >= 2000) { +               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 (evt.key_symbol) { +                              case DIKS_ESCAPE: +                                   quit = 1; +                                   break; +                              case DIKS_CURSOR_UP: +                                   inc_rotx = 5.0; +                                   break; +                              case DIKS_CURSOR_DOWN: +                                   inc_rotx = -5.0; +                                   break; +                              case DIKS_CURSOR_LEFT: +                                   inc_roty = 5.0; +                                   break; +                              case DIKS_CURSOR_RIGHT: +                                   inc_roty = -5.0; +                                   break; +                              case DIKS_PAGE_UP: +                                   inc_rotz = 5.0; +                                   break; +                              case DIKS_PAGE_DOWN: +                                   inc_rotz = -5.0; +                                   break; +                              default: +                                   ; +                         } +                         break; +                    case DIET_KEYRELEASE: +                         switch (evt.key_symbol) { +                              case DIKS_CURSOR_UP: +                                   inc_rotx = 0; +                                   break; +                              case DIKS_CURSOR_DOWN: +                                   inc_rotx = 0; +                                   break; +                              case DIKS_CURSOR_LEFT: +                                   inc_roty = 0; +                                   break; +                              case DIKS_CURSOR_RIGHT: +                                   inc_roty = 0; +                                   break; +                              case DIKS_PAGE_UP: +                                   inc_rotz = 0; +                                   break; +                              case DIKS_PAGE_DOWN: +                                   inc_rotz = 0; +                                   break; +                              default: +                                   ; +                         } +                         break; +                    case DIET_AXISMOTION: +                         if (evt.flags & DIEF_AXISREL) { +                              switch (evt.axis) { +                                   case DIAI_X: +                                        view_roty += evt.axisrel / 2.0; +                                        break; +                                   case DIAI_Y: +                                        view_rotx += evt.axisrel / 2.0; +                                        break; +                                   case DIAI_Z: +                                        view_rotz += evt.axisrel / 2.0; +                                        break; +                                   default: +                                        ; +                              } +                         } +                         break; +                    default: +                         ; +               } +          } + +          angle += 2.0; + +          view_rotx += inc_rotx; +          view_roty += inc_roty; +          view_rotz += inc_rotz; +     } + +     /* 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; +} + diff --git a/progs/directfb/df_morph3d.c b/progs/directfb/df_morph3d.c new file mode 100644 index 0000000000..f7f143447f --- /dev/null +++ b/progs/directfb/df_morph3d.c @@ -0,0 +1,1013 @@ +/* +   (c) Copyright 2001  convergence integrated media GmbH. +   All rights reserved. + +   Written by Denis Oliver Kropp <dok@convergence.de> and +              Andreas Hundt <andi@convergence.de>. + +   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. +*/ + +/*- + * morph3d.c - Shows 3D morphing objects + * + * Converted to GLUT by brianp on 1/1/98 + * + * This program was inspired on a WindowsNT(R)'s screen saver. It was written + * from scratch and it was not based on any other source code. + * + * Porting it to xlock (the final objective of this code since the moment I + * decided to create it) was possible by comparing the original Mesa's gear + * demo with it's ported version, so thanks for Danny Sung for his indirect + * help (look at gear.c in xlock source tree). NOTE: At the moment this code + * was sent to Brian Paul for package inclusion, the XLock Version was not + * available. In fact, I'll wait it to appear on the next Mesa release (If you + * are reading this, it means THIS release) to send it for xlock package + * inclusion). It will probably there be a GLUT version too. + * + * Thanks goes also to Brian Paul for making it possible and inexpensive + * to use OpenGL at home. + * + * Since I'm not a native english speaker, my apologies for any gramatical + * mistake. + * + * My e-mail addresses are + * + * vianna@cat.cbpf.br + *         and + * marcelo@venus.rdc.puc-rio.br + * + * Marcelo F. Vianna (Feb-13-1997) + */ + +/* +This document is VERY incomplete, but tries to describe the mathematics used +in the program. At this moment it just describes how the polyhedra are +generated. On futhurer versions, this document will be probabbly improved. + +Since I'm not a native english speaker, my apologies for any gramatical +mistake. + +Marcelo Fernandes Vianna +- Undergraduate in Computer Engeneering at Catholic Pontifical University +- of Rio de Janeiro (PUC-Rio) Brasil. +- e-mail: vianna@cat.cbpf.br or marcelo@venus.rdc.puc-rio.br +- Feb-13-1997 + +POLYHEDRA GENERATION + +For the purpose of this program it's not sufficient to know the polyhedra +vertexes coordinates. Since the morphing algorithm applies a nonlinear +transformation over the surfaces (faces) of the polyhedron, each face has +to be divided into smaller ones. The morphing algorithm needs to transform +each vertex of these smaller faces individually. It's a very time consoming +task. + +In order to reduce calculation overload, and since all the macro faces of +the polyhedron are transformed by the same way, the generation is made by +creating only one face of the polyhedron, morphing it and then rotating it +around the polyhedron center. + +What we need to know is the face radius of the polyhedron (the radius of +the inscribed sphere) and the angle between the center of two adjacent +faces using the center of the sphere as the angle's vertex. + +The face radius of the regular polyhedra are known values which I decided +to not waste my time calculating. Following is a table of face radius for +the regular polyhedra with edge length = 1: + +    TETRAHEDRON  : 1/(2*sqrt(2))/sqrt(3) +    CUBE     : 1/2 +    OCTAHEDRON   : 1/sqrt(6) +    DODECAHEDRON : T^2 * sqrt((T+2)/5) / 2     -> where T=(sqrt(5)+1)/2 +    ICOSAHEDRON  : (3*sqrt(3)+sqrt(15))/12 + +I've not found any reference about the mentioned angles, so I needed to +calculate them, not a trivial task until I figured out how :) +Curiously these angles are the same for the tetrahedron and octahedron. +A way to obtain this value is inscribing the tetrahedron inside the cube +by matching their vertexes. So you'll notice that the remaining unmatched +vertexes are in the same straight line starting in the cube/tetrahedron +center and crossing the center of each tetrahedron's face. At this point +it's easy to obtain the bigger angle of the isosceles triangle formed by +the center of the cube and two opposite vertexes on the same cube face. +The edges of this triangle have the following lenghts: sqrt(2) for the base +and sqrt(3)/2 for the other two other edges. So the angle we want is: +     +-----------------------------------------------------------+ +     | 2*ARCSIN(sqrt(2)/sqrt(3)) = 109.47122063449069174 degrees | +     +-----------------------------------------------------------+ +For the cube this angle is obvious, but just for formality it can be +easily obtained because we also know it's isosceles edge lenghts: +sqrt(2)/2 for the base and 1/2 for the other two edges. So the angle we +want is: +     +-----------------------------------------------------------+ +     | 2*ARCSIN((sqrt(2)/2)/1)   = 90.000000000000000000 degrees | +     +-----------------------------------------------------------+ +For the octahedron we use the same idea used for the tetrahedron, but now +we inscribe the cube inside the octahedron so that all cubes's vertexes +matches excatly the center of each octahedron's face. It's now clear that +this angle is the same of the thetrahedron one: +     +-----------------------------------------------------------+ +     | 2*ARCSIN(sqrt(2)/sqrt(3)) = 109.47122063449069174 degrees | +     +-----------------------------------------------------------+ +For the dodecahedron it's a little bit harder because it's only relationship +with the cube is useless to us. So we need to solve the problem by another +way. The concept of Face radius also exists on 2D polygons with the name +Edge radius: +  Edge Radius For Pentagon (ERp) +  ERp = (1/2)/TAN(36 degrees) * VRp = 0.6881909602355867905 +  (VRp is the pentagon's vertex radio). +  Face Radius For Dodecahedron +  FRd = T^2 * sqrt((T+2)/5) / 2 = 1.1135163644116068404 +Why we need ERp? Well, ERp and FRd segments forms a 90 degrees angle, +completing this triangle, the lesser angle is a half of the angle we are +looking for, so this angle is: +     +-----------------------------------------------------------+ +     | 2*ARCTAN(ERp/FRd)     = 63.434948822922009981 degrees | +     +-----------------------------------------------------------+ +For the icosahedron we can use the same method used for dodecahedron (well +the method used for dodecahedron may be used for all regular polyhedra) +  Edge Radius For Triangle (this one is well known: 1/3 of the triangle height) +  ERt = sin(60)/3 = sqrt(3)/6 = 0.2886751345948128655 +  Face Radius For Icosahedron +  FRi= (3*sqrt(3)+sqrt(15))/12 = 0.7557613140761707538 +So the angle is: +     +-----------------------------------------------------------+ +     | 2*ARCTAN(ERt/FRi)     = 41.810314895778596167 degrees | +     +-----------------------------------------------------------+ + +*/ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <math.h> +#include <unistd.h> + +#include <directfb.h> + +#include <GL/gl.h> +#include <GL/directfbgl.h> + + +/* 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 Scale                      0.3 + +#define VectMul(X1,Y1,Z1,X2,Y2,Z2) (Y1)*(Z2)-(Z1)*(Y2),(Z1)*(X2)-(X1)*(Z2),(X1)*(Y2)-(Y1)*(X2) +#define sqr(A)                     ((A)*(A)) + +/* Increasing this values produces better image quality, the price is speed. */ +/* Very low values produces erroneous/incorrect plotting */ +#define tetradivisions             23 +#define cubedivisions              20 +#define octadivisions              21 +#define dodecadivisions            10 +#define icodivisions               15 + +#define tetraangle                 109.47122063449069174 +#define cubeangle                  90.000000000000000000 +#define octaangle                  109.47122063449069174 +#define dodecaangle                63.434948822922009981 +#define icoangle                   41.810314895778596167 + +#ifndef Pi +#define Pi                         3.1415926535897932385 +#endif +#define SQRT2                      1.4142135623730951455 +#define SQRT3                      1.7320508075688771932 +#define SQRT5                      2.2360679774997898051 +#define SQRT6                      2.4494897427831778813 +#define SQRT15                     3.8729833462074170214 +#define cossec36_2                 0.8506508083520399322 +#define cos72                      0.3090169943749474241 +#define sin72                      0.9510565162951535721 +#define cos36                      0.8090169943749474241 +#define sin36                      0.5877852522924731292 + +/*************************************************************************/ + +static int       mono=0; +static int       smooth=1; +static GLint     WindH, WindW; +static GLfloat   step=0; +static GLfloat   seno; +static int       object; +static int       edgedivisions; +static void      (*draw_object)( void ); +static float     Magnitude; +static float     *MaterialColor[20]; + +static float front_shininess[] =   {60.0}; +static float front_specular[]  =   { 0.7, 0.7, 0.7, 1.0 }; +static float ambient[]         =   { 0.0, 0.0, 0.0, 1.0 }; +static float diffuse[]         =   { 1.0, 1.0, 1.0, 1.0 }; +static float position0[]       =   { 1.0, 1.0, 1.0, 0.0 }; +static float position1[]       =   {-1.0,-1.0, 1.0, 0.0 }; +static float lmodel_ambient[]  =   { 0.5, 0.5, 0.5, 1.0 }; +static float lmodel_twoside[]  =   {GL_TRUE}; + +static float MaterialRed[]     =   { 0.7, 0.0, 0.0, 1.0 }; +static float MaterialGreen[]   =   { 0.1, 0.5, 0.2, 1.0 }; +static float MaterialBlue[]    =   { 0.0, 0.0, 0.7, 1.0 }; +static float MaterialCyan[]    =   { 0.2, 0.5, 0.7, 1.0 }; +static float MaterialYellow[]  =   { 0.7, 0.7, 0.0, 1.0 }; +static float MaterialMagenta[] =   { 0.6, 0.2, 0.5, 1.0 }; +static float MaterialWhite[]   =   { 0.7, 0.7, 0.7, 1.0 }; +static float MaterialGray[]    =   { 0.2, 0.2, 0.2, 1.0 }; + +#define TRIANGLE(Edge, Amp, Divisions, Z)                                                                        \ +{                                                                                                                \ +  GLfloat   Xf,Yf,Xa,Yb,Xf2,Yf2;                                                                                 \ +  GLfloat   Factor,Factor1,Factor2;                                                                              \ +  GLfloat   VertX,VertY,VertZ,NeiAX,NeiAY,NeiAZ,NeiBX,NeiBY,NeiBZ;                                               \ +  GLfloat   Ax,Ay,Bx;                                                                                            \ +  int       Ri,Ti;                                                                                               \ +  GLfloat   Vr=(Edge)*SQRT3/3;                                                                                   \ +  GLfloat   AmpVr2=(Amp)/sqr(Vr);                                                                                \ +  GLfloat   Zf=(Edge)*(Z);                                                                                       \ +                                                                                                                 \ +  Ax=(Edge)*(+0.5/(Divisions)), Ay=(Edge)*(-SQRT3/(2*Divisions));                                                \ +  Bx=(Edge)*(-0.5/(Divisions));                                                                                  \ +                                                                                                                 \ +  for (Ri=1; Ri<=(Divisions); Ri++) {                                                                            \ +    glBegin(GL_TRIANGLE_STRIP);                                                                                  \ +    for (Ti=0; Ti<Ri; Ti++) {                                                                                    \ +      Xf=(float)(Ri-Ti)*Ax + (float)Ti*Bx;                                                                       \ +      Yf=Vr+(float)(Ri-Ti)*Ay + (float)Ti*Ay;                                                                    \ +      Xa=Xf+0.001; Yb=Yf+0.001;                                                                                  \ +      Factor=1-(((Xf2=sqr(Xf))+(Yf2=sqr(Yf)))*AmpVr2);                                                           \ +      Factor1=1-((sqr(Xa)+Yf2)*AmpVr2);                                                                          \ +      Factor2=1-((Xf2+sqr(Yb))*AmpVr2);                                                                          \ +      VertX=Factor*Xf;        VertY=Factor*Yf;        VertZ=Factor*Zf;                                           \ +      NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Yf-VertY; NeiAZ=Factor1*Zf-VertZ;                                    \ +      NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ;                                    \ +      glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ));                                             \ +      glVertex3f(VertX, VertY, VertZ);                                                                           \ +                                                                                                                 \ +      Xf=(float)(Ri-Ti-1)*Ax + (float)Ti*Bx;                                                                     \ +      Yf=Vr+(float)(Ri-Ti-1)*Ay + (float)Ti*Ay;                                                                  \ +      Xa=Xf+0.001; Yb=Yf+0.001;                                                                                  \ +      Factor=1-(((Xf2=sqr(Xf))+(Yf2=sqr(Yf)))*AmpVr2);                                                           \ +      Factor1=1-((sqr(Xa)+Yf2)*AmpVr2);                                                                          \ +      Factor2=1-((Xf2+sqr(Yb))*AmpVr2);                                                                          \ +      VertX=Factor*Xf;        VertY=Factor*Yf;        VertZ=Factor*Zf;                                           \ +      NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Yf-VertY; NeiAZ=Factor1*Zf-VertZ;                                    \ +      NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ;                                    \ +      glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ));                                             \ +      glVertex3f(VertX, VertY, VertZ);                                                                           \ +                                                                                                                 \ +    }                                                                                                            \ +    Xf=(float)Ri*Bx;                                                                                             \ +    Yf=Vr+(float)Ri*Ay;                                                                                          \ +    Xa=Xf+0.001; Yb=Yf+0.001;                                                                                    \ +    Factor=1-(((Xf2=sqr(Xf))+(Yf2=sqr(Yf)))*AmpVr2);                                                             \ +    Factor1=1-((sqr(Xa)+Yf2)*AmpVr2);                                                                            \ +    Factor2=1-((Xf2+sqr(Yb))*AmpVr2);                                                                            \ +    VertX=Factor*Xf;        VertY=Factor*Yf;        VertZ=Factor*Zf;                                             \ +    NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Yf-VertY; NeiAZ=Factor1*Zf-VertZ;                                      \ +    NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ;                                      \ +    glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ));                                               \ +    glVertex3f(VertX, VertY, VertZ);                                                                             \ +    glEnd();                                                                                                     \ +  }                                                                                                              \ +} + +#define SQUARE(Edge, Amp, Divisions, Z)                                                                          \ +{                                                                                                                \ +  int       Xi,Yi;                                                                                               \ +  GLfloat   Xf,Yf,Y,Xf2,Yf2,Y2,Xa,Yb;                                                                            \ +  GLfloat   Factor,Factor1,Factor2;                                                                              \ +  GLfloat   VertX,VertY,VertZ,NeiAX,NeiAY,NeiAZ,NeiBX,NeiBY,NeiBZ;                                               \ +  GLfloat   Zf=(Edge)*(Z);                                                                                       \ +  GLfloat   AmpVr2=(Amp)/sqr((Edge)*SQRT2/2);                                                                    \ +                                                                                                                 \ +  for (Yi=0; Yi<(Divisions); Yi++) {                                                                             \ +    Yf=-((Edge)/2.0) + ((float)Yi)/(Divisions)*(Edge);                                                           \ +    Yf2=sqr(Yf);                                                                                                 \ +    Y=Yf+1.0/(Divisions)*(Edge);                                                                                 \ +    Y2=sqr(Y);                                                                                                   \ +    glBegin(GL_QUAD_STRIP);                                                                                      \ +    for (Xi=0; Xi<=(Divisions); Xi++) {                                                                          \ +      Xf=-((Edge)/2.0) + ((float)Xi)/(Divisions)*(Edge);                                                         \ +      Xf2=sqr(Xf);                                                                                               \ +                                                                                                                 \ +      Xa=Xf+0.001; Yb=Y+0.001;                                                                                   \ +      Factor=1-((Xf2+Y2)*AmpVr2);                                                                                \ +      Factor1=1-((sqr(Xa)+Y2)*AmpVr2);                                                                           \ +      Factor2=1-((Xf2+sqr(Yb))*AmpVr2);                                                                          \ +      VertX=Factor*Xf;        VertY=Factor*Y;         VertZ=Factor*Zf;                                           \ +      NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Y-VertY;  NeiAZ=Factor1*Zf-VertZ;                                    \ +      NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ;                                    \ +      glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ));                                             \ +      glVertex3f(VertX, VertY, VertZ);                                                                           \ +                                                                                                                 \ +      Xa=Xf+0.001; Yb=Yf+0.001;                                                                                  \ +      Factor=1-((Xf2+Yf2)*AmpVr2);                                                                               \ +      Factor1=1-((sqr(Xa)+Yf2)*AmpVr2);                                                                          \ +      Factor2=1-((Xf2+sqr(Yb))*AmpVr2);                                                                          \ +      VertX=Factor*Xf;        VertY=Factor*Yf;        VertZ=Factor*Zf;                                           \ +      NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Yf-VertY; NeiAZ=Factor1*Zf-VertZ;                                    \ +      NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ;                                    \ +      glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ));                                             \ +      glVertex3f(VertX, VertY, VertZ);                                                                           \ +    }                                                                                                            \ +    glEnd();                                                                                                     \ +  }                                                                                                              \ +} + +#define PENTAGON(Edge, Amp, Divisions, Z)                                                                        \ +{                                                                                                                \ +  int       Ri,Ti,Fi;                                                                                            \ +  GLfloat   Xf,Yf,Xa,Yb,Xf2,Yf2;                                                                                 \ +  GLfloat   x[6],y[6];                                                                                           \ +  GLfloat   Factor,Factor1,Factor2;                                                                              \ +  GLfloat   VertX,VertY,VertZ,NeiAX,NeiAY,NeiAZ,NeiBX,NeiBY,NeiBZ;                                               \ +  GLfloat   Zf=(Edge)*(Z);                                                                                       \ +  GLfloat   AmpVr2=(Amp)/sqr((Edge)*cossec36_2);                                                                 \ +                                                                                                                 \ +  for(Fi=0;Fi<6;Fi++) {                                                                                          \ +    x[Fi]=-cos( Fi*2*Pi/5 + Pi/10 )/(Divisions)*cossec36_2*(Edge);                                                \ +    y[Fi]=sin( Fi*2*Pi/5 + Pi/10 )/(Divisions)*cossec36_2*(Edge);                                                \ +  }                                                                                                              \ +                                                                                                                 \ +  for (Ri=1; Ri<=(Divisions); Ri++) {                                                                            \ +    for (Fi=0; Fi<5; Fi++) {                                                                                     \ +      glBegin(GL_TRIANGLE_STRIP);                                                                                \ +      for (Ti=0; Ti<Ri; Ti++) {                                                                                  \ +        Xf=(float)(Ri-Ti)*x[Fi] + (float)Ti*x[Fi+1];                                                             \ +        Yf=(float)(Ri-Ti)*y[Fi] + (float)Ti*y[Fi+1];                                                             \ +        Xa=Xf+0.001; Yb=Yf+0.001;                                                                                \ +    Factor=1-(((Xf2=sqr(Xf))+(Yf2=sqr(Yf)))*AmpVr2);                                                         \ +    Factor1=1-((sqr(Xa)+Yf2)*AmpVr2);                                                                        \ +    Factor2=1-((Xf2+sqr(Yb))*AmpVr2);                                                                        \ +        VertX=Factor*Xf;        VertY=Factor*Yf;        VertZ=Factor*Zf;                                         \ +        NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Yf-VertY; NeiAZ=Factor1*Zf-VertZ;                                  \ +        NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ;                                  \ +        glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ));                                           \ +    glVertex3f(VertX, VertY, VertZ);                                                                         \ +                                                                                                                 \ +        Xf=(float)(Ri-Ti-1)*x[Fi] + (float)Ti*x[Fi+1];                                                           \ +        Yf=(float)(Ri-Ti-1)*y[Fi] + (float)Ti*y[Fi+1];                                                           \ +        Xa=Xf+0.001; Yb=Yf+0.001;                                                                                \ +    Factor=1-(((Xf2=sqr(Xf))+(Yf2=sqr(Yf)))*AmpVr2);                                                         \ +    Factor1=1-((sqr(Xa)+Yf2)*AmpVr2);                                                                        \ +    Factor2=1-((Xf2+sqr(Yb))*AmpVr2);                                                                        \ +        VertX=Factor*Xf;        VertY=Factor*Yf;        VertZ=Factor*Zf;                                         \ +        NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Yf-VertY; NeiAZ=Factor1*Zf-VertZ;                                  \ +        NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ;                                  \ +        glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ));                                           \ +    glVertex3f(VertX, VertY, VertZ);                                                                         \ +                                                                                                                 \ +      }                                                                                                          \ +      Xf=(float)Ri*x[Fi+1];                                                                                      \ +      Yf=(float)Ri*y[Fi+1];                                                                                      \ +      Xa=Xf+0.001; Yb=Yf+0.001;                                                                                  \ +      Factor=1-(((Xf2=sqr(Xf))+(Yf2=sqr(Yf)))*AmpVr2);                                                           \ +      Factor1=1-((sqr(Xa)+Yf2)*AmpVr2);                                                                          \ +      Factor2=1-((Xf2+sqr(Yb))*AmpVr2);                                                                          \ +      VertX=Factor*Xf;        VertY=Factor*Yf;        VertZ=Factor*Zf;                                           \ +      NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Yf-VertY; NeiAZ=Factor1*Zf-VertZ;                                    \ +      NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ;                                    \ +      glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ));                                             \ +      glVertex3f(VertX, VertY, VertZ);                                                                           \ +      glEnd();                                                                                                   \ +    }                                                                                                            \ +  }                                                                                                              \ +} + +static void draw_tetra( void ) +{ +  GLuint list; + +  list = glGenLists( 1 ); +  glNewList( list, GL_COMPILE ); +  TRIANGLE(2,seno,edgedivisions,0.5/SQRT6); +  glEndList(); + +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[0]); +  glCallList(list); +  glPushMatrix(); +  glRotatef(180,0,0,1); +  glRotatef(-tetraangle,1,0,0); +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[1]); +  glCallList(list); +  glPopMatrix(); +  glPushMatrix(); +  glRotatef(180,0,1,0); +  glRotatef(-180+tetraangle,0.5,SQRT3/2,0); +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[2]); +  glCallList(list); +  glPopMatrix(); +  glRotatef(180,0,1,0); +  glRotatef(-180+tetraangle,0.5,-SQRT3/2,0); +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[3]); +  glCallList(list); + +  glDeleteLists(list,1); +} + +static void draw_cube( void ) +{ +  GLuint list; + +  list = glGenLists( 1 ); +  glNewList( list, GL_COMPILE ); +  SQUARE(2, seno, edgedivisions, 0.5) +  glEndList(); + +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[0]); +  glCallList(list); +  glRotatef(cubeangle,1,0,0); +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[1]); +  glCallList(list); +  glRotatef(cubeangle,1,0,0); +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[2]); +  glCallList(list); +  glRotatef(cubeangle,1,0,0); +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[3]); +  glCallList(list); +  glRotatef(cubeangle,0,1,0); +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[4]); +  glCallList(list); +  glRotatef(2*cubeangle,0,1,0); +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[5]); +  glCallList(list); + +  glDeleteLists(list,1); +} + +static void draw_octa( void ) +{ +  GLuint list; + +  list = glGenLists( 1 ); +  glNewList( list, GL_COMPILE ); +  TRIANGLE(2,seno,edgedivisions,1/SQRT6); +  glEndList(); + +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[0]); +  glCallList(list); +  glPushMatrix(); +  glRotatef(180,0,0,1); +  glRotatef(-180+octaangle,1,0,0); +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[1]); +  glCallList(list); +  glPopMatrix(); +  glPushMatrix(); +  glRotatef(180,0,1,0); +  glRotatef(-octaangle,0.5,SQRT3/2,0); +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[2]); +  glCallList(list); +  glPopMatrix(); +  glPushMatrix(); +  glRotatef(180,0,1,0); +  glRotatef(-octaangle,0.5,-SQRT3/2,0); +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[3]); +  glCallList(list); +  glPopMatrix(); +  glRotatef(180,1,0,0); +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[4]); +  glCallList(list); +  glPushMatrix(); +  glRotatef(180,0,0,1); +  glRotatef(-180+octaangle,1,0,0); +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[5]); +  glCallList(list); +  glPopMatrix(); +  glPushMatrix(); +  glRotatef(180,0,1,0); +  glRotatef(-octaangle,0.5,SQRT3/2,0); +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[6]); +  glCallList(list); +  glPopMatrix(); +  glRotatef(180,0,1,0); +  glRotatef(-octaangle,0.5,-SQRT3/2,0); +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[7]); +  glCallList(list); + +  glDeleteLists(list,1); +} + +static void draw_dodeca( void ) +{ +  GLuint list; + +#define TAU ((SQRT5+1)/2) + +  list = glGenLists( 1 ); +  glNewList( list, GL_COMPILE ); +  PENTAGON(1,seno,edgedivisions,sqr(TAU) * sqrt((TAU+2)/5) / 2); +  glEndList(); + +  glPushMatrix(); +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[0]); +  glCallList(list); +  glRotatef(180,0,0,1); +  glPushMatrix(); +  glRotatef(-dodecaangle,1,0,0); +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[1]); +  glCallList(list); +  glPopMatrix(); +  glPushMatrix(); +  glRotatef(-dodecaangle,cos72,sin72,0); +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[2]); +  glCallList(list); +  glPopMatrix(); +  glPushMatrix(); +  glRotatef(-dodecaangle,cos72,-sin72,0); +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[3]); +  glCallList(list); +  glPopMatrix(); +  glPushMatrix(); +  glRotatef(dodecaangle,cos36,-sin36,0); +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[4]); +  glCallList(list); +  glPopMatrix(); +  glRotatef(dodecaangle,cos36,sin36,0); +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[5]); +  glCallList(list); +  glPopMatrix(); +  glRotatef(180,1,0,0); +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[6]); +  glCallList(list); +  glRotatef(180,0,0,1); +  glPushMatrix(); +  glRotatef(-dodecaangle,1,0,0); +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[7]); +  glCallList(list); +  glPopMatrix(); +  glPushMatrix(); +  glRotatef(-dodecaangle,cos72,sin72,0); +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[8]); +  glCallList(list); +  glPopMatrix(); +  glPushMatrix(); +  glRotatef(-dodecaangle,cos72,-sin72,0); +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[9]); +  glCallList(list); +  glPopMatrix(); +  glPushMatrix(); +  glRotatef(dodecaangle,cos36,-sin36,0); +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[10]); +  glCallList(list); +  glPopMatrix(); +  glRotatef(dodecaangle,cos36,sin36,0); +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[11]); +  glCallList(list); + +  glDeleteLists(list,1); +} + +static void draw_ico( void ) +{ +  GLuint list; + +  list = glGenLists( 1 ); +  glNewList( list, GL_COMPILE ); +  TRIANGLE(1.5,seno,edgedivisions,(3*SQRT3+SQRT15)/12); +  glEndList(); + +  glPushMatrix(); + +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[0]); +  glCallList(list); +  glPushMatrix(); +  glRotatef(180,0,0,1); +  glRotatef(-icoangle,1,0,0); +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[1]); +  glCallList(list); +  glPushMatrix(); +  glRotatef(180,0,1,0); +  glRotatef(-180+icoangle,0.5,SQRT3/2,0); +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[2]); +  glCallList(list); +  glPopMatrix(); +  glRotatef(180,0,1,0); +  glRotatef(-180+icoangle,0.5,-SQRT3/2,0); +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[3]); +  glCallList(list); +  glPopMatrix(); +  glPushMatrix(); +  glRotatef(180,0,1,0); +  glRotatef(-180+icoangle,0.5,SQRT3/2,0); +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[4]); +  glCallList(list); +  glPushMatrix(); +  glRotatef(180,0,1,0); +  glRotatef(-180+icoangle,0.5,SQRT3/2,0); +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[5]); +  glCallList(list); +  glPopMatrix(); +  glRotatef(180,0,0,1); +  glRotatef(-icoangle,1,0,0); +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[6]); +  glCallList(list); +  glPopMatrix(); +  glRotatef(180,0,1,0); +  glRotatef(-180+icoangle,0.5,-SQRT3/2,0); +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[7]); +  glCallList(list); +  glPushMatrix(); +  glRotatef(180,0,1,0); +  glRotatef(-180+icoangle,0.5,-SQRT3/2,0); +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[8]); +  glCallList(list); +  glPopMatrix(); +  glRotatef(180,0,0,1); +  glRotatef(-icoangle,1,0,0); +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[9]); +  glCallList(list); +  glPopMatrix(); +  glRotatef(180,1,0,0); +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[10]); +  glCallList(list); +  glPushMatrix(); +  glRotatef(180,0,0,1); +  glRotatef(-icoangle,1,0,0); +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[11]); +  glCallList(list); +  glPushMatrix(); +  glRotatef(180,0,1,0); +  glRotatef(-180+icoangle,0.5,SQRT3/2,0); +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[12]); +  glCallList(list); +  glPopMatrix(); +  glRotatef(180,0,1,0); +  glRotatef(-180+icoangle,0.5,-SQRT3/2,0); +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[13]); +  glCallList(list); +  glPopMatrix(); +  glPushMatrix(); +  glRotatef(180,0,1,0); +  glRotatef(-180+icoangle,0.5,SQRT3/2,0); +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[14]); +  glCallList(list); +  glPushMatrix(); +  glRotatef(180,0,1,0); +  glRotatef(-180+icoangle,0.5,SQRT3/2,0); +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[15]); +  glCallList(list); +  glPopMatrix(); +  glRotatef(180,0,0,1); +  glRotatef(-icoangle,1,0,0); +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[16]); +  glCallList(list); +  glPopMatrix(); +  glRotatef(180,0,1,0); +  glRotatef(-180+icoangle,0.5,-SQRT3/2,0); +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[17]); +  glCallList(list); +  glPushMatrix(); +  glRotatef(180,0,1,0); +  glRotatef(-180+icoangle,0.5,-SQRT3/2,0); +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[18]); +  glCallList(list); +  glPopMatrix(); +  glRotatef(180,0,0,1); +  glRotatef(-icoangle,1,0,0); +  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[19]); +  glCallList(list); + +  glDeleteLists(list,1); +} + +static void draw ( void ) { +  glClear( /*GL_COLOR_BUFFER_BIT |*/ GL_DEPTH_BUFFER_BIT ); + +  glPushMatrix(); + +    glTranslatef( 0.0, 0.0, -10.0 ); +    glScalef( Scale*WindH/WindW, Scale, Scale ); +    glTranslatef(2.5*WindW/WindH*sin(step*1.11),2.5*cos(step*1.25*1.11),0); +    glRotatef(step*100,1,0,0); +    glRotatef(step*95,0,1,0); +    glRotatef(step*90,0,0,1); + +  seno=(sin(step)+1.0/3.0)*(4.0/5.0)*Magnitude; + +  draw_object(); + +  glPopMatrix(); + +  glFlush(); + +  step+=0.05; +} + +static void reshape( int width, int height ) +{ +  glViewport(0, 0, WindW=(GLint)width, WindH=(GLint)height); +  glMatrixMode(GL_PROJECTION); +  glLoadIdentity(); +  glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 15.0 ); +  glMatrixMode(GL_MODELVIEW); +} + +static void pinit(void) +{ +  switch(object) { +    case 1: +      draw_object=draw_tetra; +      MaterialColor[0]=MaterialRed; +      MaterialColor[1]=MaterialGreen; +      MaterialColor[2]=MaterialBlue; +      MaterialColor[3]=MaterialWhite; +      edgedivisions=tetradivisions; +      Magnitude=2.5; +      break; +    case 2: +      draw_object=draw_cube; +      MaterialColor[0]=MaterialRed; +      MaterialColor[1]=MaterialGreen; +      MaterialColor[2]=MaterialCyan; +      MaterialColor[3]=MaterialMagenta; +      MaterialColor[4]=MaterialYellow; +      MaterialColor[5]=MaterialBlue; +      edgedivisions=cubedivisions; +      Magnitude=2.0; +      break; +    case 3: +      draw_object=draw_octa; +      MaterialColor[0]=MaterialRed; +      MaterialColor[1]=MaterialGreen; +      MaterialColor[2]=MaterialBlue; +      MaterialColor[3]=MaterialWhite; +      MaterialColor[4]=MaterialCyan; +      MaterialColor[5]=MaterialMagenta; +      MaterialColor[6]=MaterialGray; +      MaterialColor[7]=MaterialYellow; +      edgedivisions=octadivisions; +      Magnitude=2.5; +      break; +    case 4: +      draw_object=draw_dodeca; +      MaterialColor[ 0]=MaterialRed; +      MaterialColor[ 1]=MaterialGreen; +      MaterialColor[ 2]=MaterialCyan; +      MaterialColor[ 3]=MaterialBlue; +      MaterialColor[ 4]=MaterialMagenta; +      MaterialColor[ 5]=MaterialYellow; +      MaterialColor[ 6]=MaterialGreen; +      MaterialColor[ 7]=MaterialCyan; +      MaterialColor[ 8]=MaterialRed; +      MaterialColor[ 9]=MaterialMagenta; +      MaterialColor[10]=MaterialBlue; +      MaterialColor[11]=MaterialYellow; +      edgedivisions=dodecadivisions; +      Magnitude=2.0; +      break; +    case 5: +      draw_object=draw_ico; +      MaterialColor[ 0]=MaterialRed; +      MaterialColor[ 1]=MaterialGreen; +      MaterialColor[ 2]=MaterialBlue; +      MaterialColor[ 3]=MaterialCyan; +      MaterialColor[ 4]=MaterialYellow; +      MaterialColor[ 5]=MaterialMagenta; +      MaterialColor[ 6]=MaterialRed; +      MaterialColor[ 7]=MaterialGreen; +      MaterialColor[ 8]=MaterialBlue; +      MaterialColor[ 9]=MaterialWhite; +      MaterialColor[10]=MaterialCyan; +      MaterialColor[11]=MaterialYellow; +      MaterialColor[12]=MaterialMagenta; +      MaterialColor[13]=MaterialRed; +      MaterialColor[14]=MaterialGreen; +      MaterialColor[15]=MaterialBlue; +      MaterialColor[16]=MaterialCyan; +      MaterialColor[17]=MaterialYellow; +      MaterialColor[18]=MaterialMagenta; +      MaterialColor[19]=MaterialGray; +      edgedivisions=icodivisions; +      Magnitude=2.5; +      break; +  } +  if (mono) { +    int loop; +    for (loop=0; loop<20; loop++) MaterialColor[loop]=MaterialGray; +  } +  if (smooth) { +    glShadeModel( GL_SMOOTH ); +  } else { +    glShadeModel( GL_FLAT ); +  } + +} + +static void init(void) +{ +  printf("Morph 3D - Shows morphing platonic polyhedra\n"); +  printf("Author: Marcelo Fernandes Vianna (vianna@cat.cbpf.br)\n\n"); +  printf("  [1]    - Tetrahedron\n"); +  printf("  [2]    - Hexahedron (Cube)\n"); +  printf("  [3]    - Octahedron\n"); +  printf("  [4]    - Dodecahedron\n"); +  printf("  [5]    - Icosahedron\n"); +  printf("[SPACE]  - Toggle colored faces\n"); +  printf("[RETURN] - Toggle smooth/flat shading\n"); +  printf(" [ESC]   - Quit\n"); + +  object=1; + +  glClearDepth(1.0); +  glClearColor( 0.0, 0.0, 0.0, 0.0 ); +  glColor3f( 1.0, 1.0, 1.0 ); + +  glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); +  glFlush(); +  primary->Flip( primary, NULL, 0 ); + +  glLightfv(GL_LIGHT0, GL_AMBIENT, ambient); +  glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse); +  glLightfv(GL_LIGHT0, GL_POSITION, position0); +  glLightfv(GL_LIGHT1, GL_AMBIENT, ambient); +  glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse); +  glLightfv(GL_LIGHT1, GL_POSITION, position1); +  glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient); +  glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside); +  glEnable(GL_LIGHTING); +  glEnable(GL_LIGHT0); +  glEnable(GL_LIGHT1); +  glEnable(GL_DEPTH_TEST); +  glEnable(GL_NORMALIZE); + +  glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, front_shininess); +  glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, front_specular); + +  glHint(GL_FOG_HINT, GL_FASTEST); +  glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); +  glHint(GL_POLYGON_SMOOTH_HINT, GL_FASTEST); + +  pinit(); +} + +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_KEYS, 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  = 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; + +          primary->Clear( primary, 0, 0, 0, 0 ); +           +          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, 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 (evt.key_symbol) { +                              case DIKS_ESCAPE: +                                   quit = 1; +                                   break; +                              case DIKS_1: object=1; break; +                              case DIKS_2: object=2; break; +                              case DIKS_3: object=3; break; +                              case DIKS_4: object=4; break; +                              case DIKS_5: object=5; break; +                              case DIKS_SPACE: mono^=1; break; +                              case DIKS_ENTER: smooth^=1; break; +                              default: +                                   ; +                         } +                         pinit(); +                         break; +                    default: +                         ; +               } +          } +     } + +     /* 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; +} + diff --git a/progs/directfb/df_reflect.c b/progs/directfb/df_reflect.c new file mode 100644 index 0000000000..ce4d12f749 --- /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 <dok@convergence.de> and +              Andreas Hundt <andi@convergence.de>. + +   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; +} + diff --git a/progs/directfb/multi_window.c b/progs/directfb/multi_window.c new file mode 100644 index 0000000000..9bb0e4be8e --- /dev/null +++ b/progs/directfb/multi_window.c @@ -0,0 +1,240 @@ +/* +   (c) Copyright 2001  convergence integrated media GmbH. +   All rights reserved. + +   Written by Denis Oliver Kropp <dok@convergence.de> and +              Andreas Hundt <andi@convergence.de>. + +   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 <GL/gl.h> +#include <GL/glu.h> + +#include <directfb.h> +#include <directfbgl.h> + + +typedef struct { +     IDirectFBWindow  *window; +     IDirectFBSurface *surface; +     IDirectFBGL      *gl; + +     int               width; +     int               height; +      +     unsigned long     last_time; +     int               frames; +     float             fps; +} Context; + +static const GLfloat blue[4] = {0.2, 0.2, 1.0, 1.0}; + +static IDirectFB             *dfb; +static IDirectFBDisplayLayer *layer; +static IDirectFBFont         *font; +static IDirectFBEventBuffer  *events = NULL; + +/* macro for a safe call to DirectFB functions */ +#define DFBCHECK(x...) \ +        do {                                                                   \ +           ret = x;                                                            \ +           if (ret != DFB_OK) {                                                \ +              fprintf( stderr, "%s <%d>:\n\t", __FILE__, __LINE__ );           \ +              DirectFBErrorFatal( #x, ret );                                   \ +           }                                                                   \ +        } while (0) + + +static inline unsigned long get_millis() +{ +  struct timeval tv; + +  gettimeofday (&tv, NULL); +  return (tv.tv_sec * 1000 + tv.tv_usec / 1000); +} + + +static void +setup( Context *context ) +{ +     GLfloat pos[4] = {5.0, 5.0, 10.0, 0.0}; + +     context->surface->GetSize( context->surface, +                                &context->width, &context->height ); + +     context->gl->Lock( context->gl ); + +     glLightfv(GL_LIGHT0, GL_POSITION, pos); +     glEnable(GL_CULL_FACE); +     glEnable(GL_LIGHTING); +     glEnable(GL_LIGHT0); +     glEnable(GL_DEPTH_TEST); +      +     glViewport(0, 0, context->width, context->height); +      +     glMatrixMode(GL_PROJECTION); +     glLoadIdentity(); +     gluPerspective(70.0, context->width / (float) context->height, 1.0, 80.0); +      +     glMatrixMode(GL_MODELVIEW); +     glLoadIdentity(); +     glTranslatef(0.0, 0.0, -40.0); +      +     context->gl->Unlock( context->gl ); +} + +static void +update( Context *context ) +{ +     unsigned long     t; +     IDirectFBSurface *surface = context->surface; +     static __u8  r = 0, g = 0, b = 0; +     +      +     context->gl->Lock( context->gl ); + +     glClearColor( r++/255.0, g++/255.0, b++/255.0, 1.0 ); +     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); +      +     context->gl->Unlock( context->gl ); +      +     if (context->fps) { +          char buf[16]; + +          snprintf(buf, sizeof(buf), "%.1f FPS\n", context->fps); + +          surface->SetColor( surface, 0xff, 0x00, 0x00, 0xff ); +          surface->DrawString( surface, buf, -1, +                               context->width - 5, 5, DSTF_TOPRIGHT ); +     } +      +     surface->Flip( surface, NULL, 0 ); + +     context->frames++; + +     t = get_millis(); +     if (t - context->last_time >= 2000) { +          float seconds = (t - context->last_time) / 1000.0f; + +          context->fps = context->frames / seconds; + +          context->last_time = t; +          context->frames    = 0; +     } +} + +int +main( int argc, char *argv[] ) +{ +     DFBResult ret; +     int       i; +     int       quit = 0; +     const int num = 2; +     Context   contexts[num]; + +     DFBCHECK(DirectFBInit( &argc, &argv )); + +     /* create the super interface */ +     DFBCHECK(DirectFBCreate( &dfb )); + +     DFBCHECK(dfb->GetDisplayLayer( dfb, DLID_PRIMARY, &layer )); + +     /* create the default font */ +     DFBCHECK(dfb->CreateFont( dfb, NULL, NULL, &font )); + +     for (i=0; i<num; i++) { +          IDirectFBWindow      *window; +          IDirectFBSurface     *surface; +          IDirectFBGL          *gl; +          DFBWindowDescription  desc; + +          desc.flags  = DWDESC_POSX | DWDESC_POSY | +                        DWDESC_WIDTH | DWDESC_HEIGHT; +          desc.posx   = (i%3) * 200 + 10; +          desc.posy   = (i/3) * 200 + 10; +          desc.width  = 180; +          desc.height = 180; + +          DFBCHECK(layer->CreateWindow( layer, &desc, &window )); +          DFBCHECK(window->GetSurface( window, &surface )); +          DFBCHECK(surface->GetGL( surface, &gl )); + +          contexts[i].window    = window; +          contexts[i].surface   = surface; +          contexts[i].gl        = gl; + +          contexts[i].last_time = get_millis(); +          contexts[i].frames    = 0; +          contexts[i].fps       = 0; + +          setup( &contexts[i] ); + +          if (events) +               DFBCHECK(window->AttachEventBuffer( window, events )); +          else +               DFBCHECK(window->CreateEventBuffer( window, &events )); +           +          DFBCHECK(surface->SetFont( surface, font )); + +          window->SetOpacity( window, 0xff ); +     } +      +     while (!quit) { +          DFBWindowEvent evt; + +          for (i=0; i<num; i++) +               update( &contexts[i] ); +           +          while (events->GetEvent( events, DFB_EVENT(&evt) ) == DFB_OK) { +               switch (evt.type) { +                    case DWET_KEYDOWN: +                         switch (evt.key_symbol) { +                              case DIKS_ESCAPE: +                                   quit = 1; +                                   break; + +                              default: +                                   break; +                         } +                         break; + +                    default: +                         break; +               } +          } +     } + +     events->Release( events ); + +     for (i=0; i<num; i++) { +          contexts[i].gl->Release( contexts[i].gl ); +          contexts[i].surface->Release( contexts[i].surface ); +          contexts[i].window->Release( contexts[i].window ); +     } + +     font->Release( font ); +     layer->Release( layer ); +     dfb->Release( dfb ); + +     return 0; +} +  | 
