@@ -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 *~ | |||
@@ -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; | |||
} | |||
@@ -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; | |||
} | |||
@@ -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; | |||
} | |||