mesa/progs/directfb/multi_window.c

241 lines
6.6 KiB
C

/*
(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;
}