fysxasteroids/engine/libraries/oglft/tests/demo3.cpp

1583 lines
42 KiB
C++
Raw Normal View History

2010-04-05 23:38:59 +02:00
/*
* demo3.cpp: Third Demo of the OGLFT library
* Copyright (C) 2002 lignum Computing, Inc. <oglft@lignumcomputing.com>
* $Id$
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <iostream>
#include <algorithm>
#include <qapplication.h>
#include <qimage.h>
#include "OGLFT.h"
#include "vignette.h"
#include "vignette.moc"
#include "Demo3UnicodeExample.h"
#include "Demo3UnicodeExample2.h"
class Vignette0 : public Vignette {
static const unsigned int FRAME_COUNT = 32;
static const unsigned int FRAME_RATE = 16;
const char* text_;
OGLFT::Filled* face_;
public:
Vignette0 ( const char* text, const char* fontfile ) : text_( text )
{
face_ = new OGLFT::Filled( fontfile, 288, 75 );
face_->setForegroundColor( 0., .5, .75 );
face_->setHorizontalJustification( OGLFT::Face::CENTER );
}
~Vignette0 ( void )
{
// std::cout << "destructing Vignette 0" << std::endl;
delete face_;
}
unsigned int frame_count ( void ) { return FRAME_COUNT; }
unsigned int frame_rate ( void ) { return FRAME_RATE; }
void init ( void )
{
std::cout << "Vignette 0" << std::endl;
}
void draw ( unsigned int frame_number )
{
glPushMatrix();
glTranslatef( 0., 0.,
- 1. - ( FRAME_COUNT - frame_number ) );
face_->draw( 0., 0., text_ );
glPopMatrix();
}
void finish ( void )
{
}
};
class Vignette1 : public Vignette {
static const unsigned int FRAME_COUNT = 49;
static const unsigned int FRAME_RATE = 16;
const char* text_;
OGLFT::Filled* face_;
public:
Vignette1 ( const char* text, const char* fontfile ) : text_( text )
{
face_ = new OGLFT::Filled( fontfile, 288, 75 );
face_->setForegroundColor( 0., .5, .75 );
face_->setHorizontalJustification( OGLFT::Face::CENTER );
}
~Vignette1 ( void )
{
// std::cout << "destructing Vignette 1" << std::endl;
delete face_;
}
unsigned int frame_count ( void ) { return FRAME_COUNT; }
unsigned int frame_rate ( void ) { return FRAME_RATE; }
void init ( void )
{
std::cout << "Vignette 1" << std::endl;
}
void draw ( unsigned int frame_number )
{
glPushMatrix();
glTranslatef( 0., 0.,
- 1. - ( FRAME_COUNT - frame_number ) );
glRotatef( frame_number * 15., 0., 0., 1. );
face_->draw( 0., 0., text_ );
glPopMatrix();
}
void finish ( void )
{
}
};
class Vignette2 : public Vignette {
static const unsigned int FRAME_COUNT = 60;
static const unsigned int FRAME_RATE = 12;
const char* text_;
OGLFT::Filled* face_;
GLfloat x_;
public:
Vignette2 ( const char* text, const char* fontfile ) : text_( text )
{
face_ = new OGLFT::Filled( fontfile, 32, 75 );
face_->setCompileMode( OGLFT::Face::IMMEDIATE );
face_->setForegroundColor( 0., .5, .75 );
face_->setHorizontalJustification( OGLFT::Face::RIGHT );
face_->setCharacterRotationZ( 30. );
x_ = -250.;
}
~Vignette2 ( void )
{
// std::cout << "destructing Vignette 2" << std::endl;
delete face_;
}
unsigned int frame_count ( void ) { return FRAME_COUNT; }
unsigned int frame_rate ( void ) { return FRAME_RATE; }
void init ( void )
{
std::cout << "Vignette 2" << std::endl;
}
void draw ( unsigned int frame_number )
{
glPushMatrix();
if ( frame_number <= 48 ) {
x_ += 10.;
face_->setCharacterRotationZ( face_->characterRotationZ() - 30. );
}
else
x_ = 250.;
glTranslatef( x_, 0., 0. );
face_->draw( 0., 0., text_ );
glPopMatrix();
}
void view ( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top )
{
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( left, right, bottom, top, -250., 250. );
glMatrixMode( GL_MODELVIEW );
}
void finish ( void )
{
}
};
class Vignette3 : public Vignette {
static const unsigned int FRAME_COUNT = 36;
static const unsigned int FRAME_RATE = 16;
const char* text_;
OGLFT::Filled* face_;
public:
Vignette3 ( const char* text, const char* fontfile ) : text_( text )
{
face_ = new OGLFT::Filled( fontfile, 32, 75 );
face_->setCompileMode( OGLFT::Face::IMMEDIATE );
face_->setForegroundColor( 0., .5, .75 );
face_->setHorizontalJustification( OGLFT::Face::CENTER );
face_->setCharacterRotationY( 90. );
}
~Vignette3 ( void )
{
// std::cout << "destructing Vignette 3" << std::endl;
delete face_;
}
unsigned int frame_count ( void ) { return FRAME_COUNT; }
unsigned int frame_rate ( void ) { return FRAME_RATE; }
void init ( void )
{
std::cout << "Vignette 3" << std::endl;
}
void view ( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top )
{
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( left, right, bottom, top, -250., 250. );
glMatrixMode( GL_MODELVIEW );
}
void draw ( unsigned int frame_number )
{
glPushMatrix();
glTranslatef( 0., 0.,
- 1. - ( FRAME_COUNT - frame_number ) );
face_->setCharacterRotationY( face_->characterRotationY() + 10. );
face_->draw( 0., 0., text_ );
glPopMatrix();
}
void finish ( void )
{
}
};
class Vignette4 : public Vignette {
static const unsigned int FRAME_COUNT = 82;
static const unsigned int FRAME_RATE = 10;
const char* text_;
#ifndef OGLFT_NO_SOLID
OGLFT::Solid* face_;
#else
OGLFT::Filled* face_;
#endif
OGLFT::Translucent* annotation_;
QImage* bg00b;
QImage* bg01;
QImage* bg10b;
QImage* bg11;
GLuint bg_textures_[6];
public:
Vignette4 ( const char* text, const char* fontfile ) : text_( text )
{
#ifndef OGLFT_NO_SOLID
face_ = new OGLFT::Solid( fontfile, 120, 75 );
face_->setDepth( 24. );
#else
face_ = new OGLFT::Filled( fontfile, 120, 75 );
#endif
face_->setCompileMode( OGLFT::Face::IMMEDIATE );
face_->setForegroundColor( 1., 1., 0. );
face_->setHorizontalJustification( OGLFT::Face::CENTER );
face_->setVerticalJustification( OGLFT::Face::MIDDLE );
face_->setCharacterRotationY( 0. );
face_->setCharacterRotationZ( 0. );
annotation_ = new OGLFT::Translucent( fontfile, 10, 75 );
annotation_->setForegroundColor( 1., 1., 0., 0.5 );
annotation_->setHorizontalJustification( OGLFT::Face::RIGHT );
annotation_->setVerticalJustification( OGLFT::Face::BOTTOM );
bg00b = new QImage( "background00b.png" );
bg01 = new QImage( "background01.png" );
bg10b = new QImage( "background10b.png" );
bg11 = new QImage( "background11.png" );
}
~Vignette4 ( void )
{
// std::cout << "destructing Vignette 4" << std::endl;
glDeleteTextures( 6, bg_textures_ );
delete bg00b;
delete bg01;
delete bg10b;
delete bg11;
delete face_;
}
unsigned int frame_count ( void ) { return FRAME_COUNT; }
unsigned int frame_rate ( void ) { return FRAME_RATE; }
void init ( void )
{
std::cout << "Vignette 4" << std::endl;
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
glGenTextures( 6, bg_textures_ );
glBindTexture( GL_TEXTURE_2D, bg_textures_[1] );
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_MAG_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, bg01->width(), bg01->height(),
0, GL_BGRA, GL_UNSIGNED_BYTE, bg01->bits() );
glBindTexture( GL_TEXTURE_2D, bg_textures_[3] );
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_MAG_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, bg11->width(), bg11->height(),
0, GL_BGRA, GL_UNSIGNED_BYTE, bg11->bits() );
glBindTexture( GL_TEXTURE_2D, bg_textures_[4] );
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_MAG_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, bg00b->width(), bg00b->height(),
0, GL_BGRA, GL_UNSIGNED_BYTE, bg00b->bits() );
glBindTexture( GL_TEXTURE_2D, bg_textures_[5] );
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_MAG_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, bg10b->width(), bg10b->height(),
0, GL_BGRA, GL_UNSIGNED_BYTE, bg10b->bits() );
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
glEnable( GL_LIGHT0 );
}
void view ( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top )
{
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( left, right, bottom, top, -250., 250. );
glMatrixMode( GL_MODELVIEW );
GLint viewport[4];
GLdouble matrix[16];
glGetIntegerv( GL_VIEWPORT, viewport );
glGetDoublev( GL_PROJECTION_MATRIX, matrix );
glGetDoublev( GL_MODELVIEW_MATRIX, matrix );
}
void draw ( unsigned int frame_number )
{
glPushMatrix();
GLubyte alpha = 255;
if ( frame_number < FRAME_COUNT )
alpha = (GLubyte)( 255. * (GLfloat)frame_number/(FRAME_COUNT) );
glEnable( GL_BLEND );
glBegin( GL_QUADS );
glColor4ub( 128, 164, 212, alpha );
glVertex2f( -250., 0. );
glVertex2f( 250., 0. );
glColor4ub( 101, 142, 198, alpha );
glVertex2f( 250., 250. );
glVertex2f( -250., 250. );
glEnd();
glDisable( GL_BLEND );
glEnable( GL_LIGHTING );
glEnable( GL_DEPTH_TEST );
glEnable( GL_COLOR_MATERIAL );
GLfloat y;
if ( frame_number <= 72 ) {
face_->setCharacterRotationX( face_->characterRotationX() + 25. );
face_->setCharacterRotationY( face_->characterRotationY() + 25. );
#if 0
face_->setCharacterRotationZ( face_->characterRotationZ() - 12.5 );
#endif
y = 3.5*frame_number - 55.;
}
else
y = 3.5*72 - 55.;
face_->draw( 0., y, text_ );
if ( frame_number < FRAME_COUNT ) {
// Fade in the background
GLdouble f = (GLfloat)frame_number/(FRAME_COUNT);
glColor4f( f, f, f, 1. );
}
else
glColor4f( 1., 1., 1., 1. );
glDisable( GL_LIGHTING );
glDisable( GL_DEPTH_TEST );
glDisable( GL_COLOR_MATERIAL );
glEnable( GL_TEXTURE_2D );
glEnable( GL_BLEND );
glBindTexture( GL_TEXTURE_2D, bg_textures_[1] );
glBegin( GL_QUADS );
glTexCoord2f( 0., 1. ); glVertex2f( -250., -250. );
glTexCoord2f( 1., 1. ); glVertex2f( 0., -250. );
glTexCoord2f( 1., 0. ); glVertex2f( 0., 0. );
glTexCoord2f( 0., 0. ); glVertex2f( -250., 0. );
glEnd();
glBindTexture( GL_TEXTURE_2D, bg_textures_[3] );
glBegin( GL_QUADS );
glTexCoord2f( 0., 1. ); glVertex2f( 0., -250. );
glTexCoord2f( 1., 1. ); glVertex2f( 250., -250. );
glTexCoord2f( 1., 0. ); glVertex2f( 250., 0. );
glTexCoord2f( 0., 0. ); glVertex2f( 0., 0. );
glEnd();
glBindTexture( GL_TEXTURE_2D, bg_textures_[4] );
glBegin( GL_QUADS );
glTexCoord2f( 0., 1. ); glVertex2f( -250., 0. );
glTexCoord2f( 1., 1. ); glVertex2f( 0., 0. );
glTexCoord2f( 1., 0. ); glVertex2f( 0., 250. );
glTexCoord2f( 0., 0. ); glVertex2f( -250., 250. );
glEnd();
glBindTexture( GL_TEXTURE_2D, bg_textures_[5] );
glBegin( GL_QUADS );
glTexCoord2f( 0., 1. ); glVertex2f( 0., 0. );
glTexCoord2f( 1., 1. ); glVertex2f( 250., 0. );
glTexCoord2f( 1., 0. ); glVertex2f( 250., 250. );
glTexCoord2f( 0., 0. ); glVertex2f( 0., 250. );
glEnd();
glDisable( GL_TEXTURE_2D );
glDisable( GL_BLEND );
glEnable( GL_BLEND );
annotation_->draw( 250., -250., "Hoodoos @ Bryce Canyon National Park, Utah, USA" );
glDisable( GL_BLEND );
glPopMatrix();
}
void finish ( void )
{
}
};
class Vignette5 : public Vignette {
static const unsigned int FRAME_COUNT = 124;
static const unsigned int FRAME_RATE = 8;
const char* text_;
OGLFT::Monochrome* monochrome_;
OGLFT::Grayscale* grayscale_;
OGLFT::Translucent* translucent_;
OGLFT::Outline* outline_;
OGLFT::Filled* filled_;
#ifndef OGLFT_NO_SOLID
OGLFT::Solid* solid_;
#else
OGLFT::Monochrome* solid_;
#endif
OGLFT::MonochromeTexture* monochrome_texture_;
OGLFT::GrayscaleTexture* grayscale_texture_;
OGLFT::TranslucentTexture* translucent_texture_;
public:
Vignette5 ( const char* text, const char* fontfile ) : text_( text )
{
int point_size = 20;
monochrome_ = new OGLFT::Monochrome( fontfile, point_size, 75 );
monochrome_->setHorizontalJustification( OGLFT::Face::CENTER );
monochrome_->setForegroundColor( 1., 0., 0., 1. );
grayscale_ = new OGLFT::Grayscale( fontfile, point_size, 75 );
grayscale_->setHorizontalJustification( OGLFT::Face::CENTER );
grayscale_->setForegroundColor( 0., 0., .5, 1. );
grayscale_->setBackgroundColor( 0., 1., 1., 1. );
translucent_ = new OGLFT::Translucent( fontfile, point_size, 75 );
translucent_->setHorizontalJustification( OGLFT::Face::CENTER );
translucent_->setForegroundColor( 0., .5, 0., 1. );
outline_ = new OGLFT::Outline( fontfile, point_size, 75 );
outline_->setForegroundColor( 1., 1., 0., 1. );
outline_->setHorizontalJustification( OGLFT::Face::CENTER );
filled_ = new OGLFT::Filled( fontfile, point_size, 75 );
filled_->setForegroundColor( .5, 0., 1., 1. );
filled_->setHorizontalJustification( OGLFT::Face::CENTER );
#ifndef OGLFT_NO_SOLID
solid_ = new OGLFT::Solid( fontfile, point_size, 75 );
solid_->setDepth( 10. );
solid_->setCharacterRotationX( 25. );
solid_->setCharacterRotationY( 25. );
solid_->setTessellationSteps( 3 );
#else
solid_ = new OGLFT::Monochrome( fontfile, point_size, 75 );
#endif
solid_->setHorizontalJustification( OGLFT::Face::CENTER );
solid_->setForegroundColor( 1., .5, 0., 1. );
monochrome_texture_ = new OGLFT::MonochromeTexture( fontfile, point_size, 75 );
monochrome_texture_->setHorizontalJustification( OGLFT::Face::CENTER );
monochrome_texture_->setForegroundColor( 0., .5, .75, 1. );
grayscale_texture_ = new OGLFT::GrayscaleTexture( fontfile, point_size, 75 );
grayscale_texture_->setHorizontalJustification( OGLFT::Face::CENTER );
grayscale_texture_->setForegroundColor( 0.9, .65, .9, 1. );
grayscale_texture_->setBackgroundColor( 0.5, .5, .75, 0.3 );
translucent_texture_ = new OGLFT::TranslucentTexture( fontfile, point_size, 75 );
translucent_texture_->setHorizontalJustification( OGLFT::Face::CENTER );
translucent_texture_->setForegroundColor( 0.75, 1., .75, 1. );
}
~Vignette5 ( void )
{
// std::cout << "destructing Vignette 5" << std::endl;
delete monochrome_;
delete grayscale_;
delete translucent_;
delete outline_;
delete filled_;
delete solid_;
delete monochrome_texture_;
delete grayscale_texture_;
delete translucent_texture_;
}
unsigned int frame_count ( void ) { return FRAME_COUNT; }
unsigned int frame_rate ( void ) { return FRAME_RATE; }
void init ( void )
{
std::cout << "Vignette 5" << std::endl;
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
glEnable( GL_RASTER_POSITION_UNCLIPPED_IBM );
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
glEnable( GL_LIGHT0 );
}
void view ( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top )
{
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( left, right, bottom, top, -250., 250. );
glMatrixMode( GL_MODELVIEW );
}
void draw ( unsigned int frame_number )
{
GLdouble y;
glPushMatrix();
if ( frame_number <= 12 )
y = -240. + 490. * ( 12 - frame_number ) / 12;
else
y = -240.;
monochrome_->draw( 0., y, "Draw text as monochrome bitmaps" );
if ( frame_number >= 12 ) {
if ( frame_number <= 24 )
y = -190. + 440. * ( 24 - frame_number ) / 12;
else
y = -190.;
grayscale_->draw( 0., y, "Draw text as antialiased, grayscale pixmaps" );
}
if ( frame_number >= 24 ) {
if ( frame_number <= 36 )
y = -140. + 390. * ( 36 - frame_number ) / 12;
else
y = -140.;
glEnable( GL_BLEND );
translucent_->draw( 0., y, "Draw text as antialiased, blended pixmaps" );
glDisable( GL_BLEND );
}
if ( frame_number >= 36 ) {
if ( frame_number <= 48 )
y = -90. + 340. * ( 48 - frame_number ) / 12;
else
y = -90.;
outline_->draw( 0., y, "Draw text as line segments" );
}
if ( frame_number >= 48 ) {
if ( frame_number <= 60 )
y = -40. + 290. * ( 60 - frame_number ) / 12;
else
y = -40.;
filled_->draw( 0., y, "Draw text as filled polygons" );
}
if ( frame_number >= 60 ) {
if ( frame_number <= 72 )
y = 10. + 240. * ( 72 - frame_number ) / 12;
else
y = 10.;
#ifndef OGLFT_NO_SOLID
glEnable( GL_LIGHTING );
glEnable( GL_DEPTH_TEST );
glEnable( GL_COLOR_MATERIAL );
solid_->draw( 0., y, "Draw text as solid with GLE" );
glDisable( GL_COLOR_MATERIAL );
glDisable( GL_DEPTH_TEST );
glDisable( GL_LIGHTING );
#else
solid_->draw( 0., y, "<Solid not available in library>" );
#endif
}
glEnable( GL_TEXTURE_2D );
glEnable( GL_BLEND );
if ( frame_number >= 72 ) {
if ( frame_number <= 84 )
y = 60. + 190. * ( 84 - frame_number ) / 12;
else
y = 60.;
monochrome_texture_->draw( 0., y, "Draw text as monochrome texture maps" );
}
if ( frame_number >= 84 ) {
if ( frame_number <= 96 )
y = 110. + 140. * ( 96 - frame_number ) / 12;
else
y = 110.;
grayscale_texture_->draw( 0., y, "Draw text as antialiased, grayscale texture maps" );
}
if ( frame_number >= 96 ) {
if ( frame_number <= 108 )
y = 160. + 90. * ( 108 - frame_number ) / 12;
else
y = 160.;
translucent_texture_->draw( 0., y, "Draw text as antialiased, blended texture maps" );
}
glDisable( GL_BLEND );
glDisable( GL_TEXTURE_2D );
glPopMatrix();
}
void finish ( void )
{
}
};
class Vignette6 : public Vignette {
static const unsigned int FRAME_COUNT = 48;
static const unsigned int FRAME_RATE = 12;
const char* text_;
OGLFT::Filled* face_;
class MyColorTess : public OGLFT::ColorTess {
public:
QColor hsv_;
GLfloat colors_[4];
int phase_;
MyColorTess ()
{
hsv_.setHsv( 0, 255, 255 );
colors_[OGLFT::R] = hsv_.red() / 255.;
colors_[OGLFT::G] = hsv_.green() / 255.;
colors_[OGLFT::B] = hsv_.blue() / 255.;
colors_[OGLFT::A] = 1.;
phase_ = 0;
}
void setPhase ( int phase ) { phase_ = phase; }
int phase ( void ) const { return phase_; }
};
class MyColorTessVertical : public MyColorTess
{
public:
GLfloat* color ( GLdouble* p )
{
int hue = (int)( 360. * p[OGLFT::Y] / 36. + phase_ ) % 360;
if ( hue < 0 ) hue += 360;
hsv_.setHsv( hue, 255, 255 );
colors_[OGLFT::R] = hsv_.red() / 255.;
colors_[OGLFT::G] = hsv_.green() / 255.;
colors_[OGLFT::B] = hsv_.blue() / 255.;
return colors_;
}
};
class MyColorTessHorizontal : public MyColorTess
{
public:
GLfloat* color ( GLdouble* p )
{
int hue = (int)( 360. * p[OGLFT::X] / 36. + phase_ ) % 360;
if ( hue < 0 ) hue += 360;
hsv_.setHsv( hue, 255, 255 );
colors_[OGLFT::R] = hsv_.red() / 255.;
colors_[OGLFT::G] = hsv_.green() / 255.;
colors_[OGLFT::B] = hsv_.blue() / 255.;
return colors_;
}
};
MyColorTessVertical color_tess_v_;
MyColorTessHorizontal color_tess_h_;
public:
Vignette6 ( const char* text, const char* fontfile ) : text_( text )
{
face_ = new OGLFT::Filled( fontfile, 72, 75 );
face_->setForegroundColor( 0., .5, .75 );
face_->setHorizontalJustification( OGLFT::Face::CENTER );
face_->setVerticalJustification( OGLFT::Face::MIDDLE );
face_->setTessellationSteps( 3 );
face_->setCompileMode( OGLFT::Face::IMMEDIATE );
}
~Vignette6 ( void )
{
// std::cout << "destructing Vignette 6" << std::endl;
delete face_;
}
unsigned int frame_count ( void ) { return FRAME_COUNT; }
unsigned int frame_rate ( void ) { return FRAME_RATE; }
void init ( void )
{
std::cout << "Vignette 6" << std::endl;
}
void view ( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top )
{
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( left, right, bottom, top, -250., 250. );
glMatrixMode( GL_MODELVIEW );
}
void draw ( unsigned int /*frame_number*/ )
{
glPushMatrix();
face_->setColorTess( &color_tess_h_ );
face_->draw( 0., 72., "Apply a per" );
face_->draw( 0., 0., "vertex color" );
face_->draw( 0., -72., "function" );
glPopMatrix();
color_tess_h_.setPhase( color_tess_h_.phase() + 15 );
color_tess_v_.setPhase( color_tess_v_.phase() + 15 );
}
void finish ( void )
{
}
};
class Vignette7 : public Vignette {
static const unsigned int FRAME_COUNT = 48;
static const unsigned int FRAME_RATE = 12;
const char* text_;
OGLFT::Filled* face_;
QImage* image_;
GLuint texture_;
class MyTextureTess : public OGLFT::TextureTess {
int phase_;
GLfloat texCoords_[2];
public:
MyTextureTess ()
{
texCoords_[0] = texCoords_[1] = 0.;
phase_ = 0;
}
GLfloat* texCoord ( GLdouble* p ) {
texCoords_[0] = ( p[OGLFT::X] + phase_ ) / 18.;
texCoords_[1] = ( p[OGLFT::Y] + phase_ ) / 18.;
return texCoords_;
}
void setPhase ( int phase ) { phase_ = phase; }
int phase ( void ) const { return phase_; }
};
MyTextureTess texture_tess_;
public:
Vignette7 ( const char* text, const char* fontfile ) : text_( text )
{
face_ = new OGLFT::Filled( fontfile, 72, 75 );
face_->setForegroundColor( 0., .5, .75 );
face_->setHorizontalJustification( OGLFT::Face::CENTER );
face_->setVerticalJustification( OGLFT::Face::MIDDLE );
face_->setTessellationSteps( 3 );
face_->setCompileMode( OGLFT::Face::IMMEDIATE );
face_->setTextureTess( &texture_tess_ );
image_ = new QImage( "texture.png" );
}
~Vignette7 ( void )
{
// std::cout << "destructing Vignette 7" << std::endl;
glDeleteTextures( 1, &texture_ );
delete image_;
delete face_;
}
unsigned int frame_count ( void ) { return FRAME_COUNT; }
unsigned int frame_rate ( void ) { return FRAME_RATE; }
void init ( void )
{
std::cout << "Vignette 7" << std::endl;
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
glGenTextures( 1, &texture_ );
glBindTexture( GL_TEXTURE_2D, texture_ );
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_MAG_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, image_->width(), image_->height(),
0, GL_BGRA, GL_UNSIGNED_BYTE, image_->bits() );
glEnable( GL_TEXTURE_2D );
}
void view ( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top )
{
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( left, right, bottom, top, -250., 250. );
glMatrixMode( GL_MODELVIEW );
}
void draw ( unsigned int frame_number )
{
glPushMatrix();
face_->draw( 0., 144., "Apply a" );
face_->draw( 0., 72., "per vertex" );
face_->draw( 0., 0., "texture" );
face_->draw( 0., -72., "function" );
texture_tess_.setPhase( frame_number );
glPopMatrix();
}
void finish ( void )
{
glDisable( GL_TEXTURE_2D );
}
};
class Vignette8 : public Vignette {
static const unsigned int FRAME_COUNT = 48;
static const unsigned int FRAME_RATE = 3;
char* text_;
unsigned int text_length_;
OGLFT::Monochrome* face_;
static const int N_SIZES = 8;
static const int sizes_[N_SIZES];
public:
Vignette8 ( const char* text, const char* fontfile )
{
face_ = new OGLFT::Monochrome( fontfile, 36, 75 );
face_->setForegroundColor( 1., 0., 0. );
text_ = strdup( text );
text_length_ = strlen( text_ );
}
~Vignette8 ( void )
{
// std::cout << "destructing Vignette 8" << std::endl;
delete face_;
free( text_ );
}
unsigned int frame_count ( void ) { return text_length_ + 3; }
unsigned int frame_rate ( void ) { return FRAME_RATE; }
void init ( void )
{
std::cout << "Vignette 8" << std::endl;
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
glEnable( GL_RASTER_POSITION_UNCLIPPED_IBM );
glPushAttrib( GL_POLYGON_BIT );
}
void draw ( unsigned int frame_number )
{
char save_char = '\0';
if ( frame_number < text_length_ ) {
save_char = text_[frame_number];
text_[frame_number] = '\0';
}
glPushMatrix();
glTranslatef( -225., 250., 0. );
for ( int i = 0; i < N_SIZES; i++ ) {
glTranslatef( 0., -2. * sizes_[i], 0. );
face_->setPointSize( sizes_[i] );
OGLFT::BBox size = face_->measure( text_ );
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
glColor3f( 1., 1., 1. );
glRectf( size.x_min_, size.y_min_, size.x_max_, size.y_max_ );
face_->draw( 0., 0., text_ );
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
glColor3f( 0., 0., 1. );
glRectf( size.x_min_, 0., size.x_max_, size.y_max_ );
}
if ( frame_number < text_length_ )
text_[frame_number] = save_char;
glPopMatrix();
}
void view ( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top )
{
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( left, right, bottom, top, -250., 250. );
glMatrixMode( GL_MODELVIEW );
}
void finish ( void )
{
glPopAttrib();
}
};
const int Vignette8::sizes_[8] = { 64, 48, 32, 24, 18, 12, 10, 6 };
class Vignette9 : public Vignette {
static const unsigned int FRAME_COUNT = 32;
static const unsigned int FRAME_RATE = 8;
const char* text_;
OGLFT::Filled* face_;
public:
Vignette9 ( const char* text, const char* fontfile ) : text_( text )
{
face_ = new OGLFT::Filled( fontfile, 288, 75 );
face_->setForegroundColor( 0., .5, .75 );
face_->setHorizontalJustification( OGLFT::Face::CENTER );
face_->setCharacterRotationX( 12. );
}
~Vignette9 ( void )
{
// std::cout << "destructing Vignette 9" << std::endl;
delete face_;
}
unsigned int frame_count ( void ) { return FRAME_COUNT; }
unsigned int frame_rate ( void ) { return FRAME_RATE; }
void init ( void )
{
std::cout << "Vignette 9" << std::endl;
}
void draw ( unsigned int /*frame_number*/ )
{
glPushMatrix();
glTranslatef( 0., 0., -8. );
face_->draw( 0., 0., text_ );
face_->setCharacterRotationX( face_->characterRotationX() - 0.5 );
glPopMatrix();
}
void finish ( void )
{
}
};
class Vignette10 : public Vignette {
static const unsigned int FRAME_COUNT = 108;
static const unsigned int FRAME_RATE = 8;
const char* text_;
unsigned int text_length_;
OGLFT::Filled* face_;
GLuint glyph_dl_;
OGLFT::DisplayLists dlists;
GLfloat x_;
public:
Vignette10 ( const char* text, const char* fontfile ) : text_( text )
{
face_ = new OGLFT::Filled( fontfile, 24, 75 );
face_->setForegroundColor( 0., .5, .75 );
face_->setHorizontalJustification( OGLFT::Face::LEFT );
text_length_ = strlen( text_ );
x_ = 250.;
}
~Vignette10 ( void )
{
// std::cout << "destructing Vignette 10" << std::endl;
delete face_;
}
unsigned int frame_count ( void ) { return FRAME_COUNT; }
unsigned int frame_rate ( void ) { return FRAME_RATE; }
void init ( void )
{
std::cout << "Vignette 10" << std::endl;
glyph_dl_ = glGenLists( 2 * text_length_ );
dlists.push_back( 0 );
QColor hsv;
for ( unsigned int i = 0; i < text_length_; i++ ) {
float dy = 50. * ( + sin( M_PI + (i+1) * 4 * M_PI / text_length_ )
- sin( M_PI + i * 4 * M_PI / text_length_ ) );
hsv.setHsv( (int)(360. * i / text_length_), 255, 255 );
glNewList( glyph_dl_ + i, GL_COMPILE );
glTranslatef( 0., dy, 0. );
glColor3ub( hsv.red(), hsv.green(), hsv.blue() );
glEndList();
dlists.push_back( glyph_dl_ + i );
}
for ( unsigned int i = 0; i < text_length_; i++ ) {
float y = 50. * sin( M_PI - i * 4 * M_PI / text_length_ );
hsv.setHsv( (int)(360. * (text_length_ - i) / text_length_), 255, 255 );
glNewList( glyph_dl_ + text_length_ + i, GL_COMPILE );
glTranslatef( 0., y, 0. );
glColor3ub( hsv.red(), hsv.green(), hsv.blue() );
glEndList();
dlists.push_back( glyph_dl_ + text_length_ + i );
}
dlists[0] = dlists[text_length_];
face_->setCharacterDisplayLists( dlists );
}
void view ( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top )
{
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( left, right, bottom, top, -250., 250. );
glMatrixMode( GL_MODELVIEW );
}
void draw ( unsigned int /*frame_number*/ )
{
OGLFT::DLI first = face_->characterDisplayLists().begin() + 1;
OGLFT::DLI next = first + text_length_ - 1;
OGLFT::DLI last = first + text_length_;
rotate( first, next, last );
first = face_->characterDisplayLists().begin() + text_length_ + 1;
next = first + 1;
last = first + text_length_;
rotate( first, next, last );
face_->characterDisplayLists()[0] =
face_->characterDisplayLists()[text_length_+1];
face_->draw( x_, 0., text_ );
x_ -= 10.;
}
void finish ( void )
{
glDeleteLists( glyph_dl_, 2 * text_length_ );
}
};
class Vignette11 : public Vignette {
static const unsigned int FRAME_COUNT = 10;
static const unsigned int FRAME_RATE = 1;
const QString text_;
QString equation_;
OGLFT::Translucent* face_;
public:
Vignette11 ( const char* text, const char* fontfile ) : text_( text )
{
// First, open a face in the usual way.
face_ = new OGLFT::Translucent( fontfile, 18, 75 );
// Now, create a second face, in this case, using a built-in font.
#if 0
FT_Library library = OGLFT::Library::instance();
FT_Face ft_face;
FT_New_Memory_Face( library, Demo3UnicodeExample_ttf,
Demo3UnicodeExample_ttf_size, 0, &ft_face );
face_->addAuxiliaryFace( ft_face );
#else
// Somewhat simpler with new interface.
face_->addAuxiliaryFace( Demo3UnicodeExample_ttf,
Demo3UnicodeExample_ttf_size );
#endif
face_->setForegroundColor( 0., .5, .75 );
// Manually create the equation in UNICODE points
equation_ = QChar( 0x2207 );//Nabla
equation_ += QChar( 0x2219 );//Dot
equation_ += QChar( 0x03a9 );//Omega
equation_ += QChar( 0x03c8 );//psi
equation_ += QChar( ' ' );
equation_ += QChar( '+' );
equation_ += QChar( ' ' );
equation_ += QChar( 0x03c3 );//sigma
equation_ += QChar( 0x03c8 );//psi
equation_ += QChar( ' ' );
equation_ += QChar( '=' );
equation_ += QChar( ' ' );
equation_ += QChar( 0x222b );//integral
equation_ += QChar( 'd' );
equation_ += QChar( 0x03a9 );//Omega
equation_ += QChar( '\'' );
equation_ += QChar( 0x03c3 );//sigma
equation_ += QChar( '(' );
equation_ += QChar( 0x03a9 );//Omega
equation_ += QChar( '\'' );
equation_ += QChar( 0x2192 );//right arrow
equation_ += QChar( 0x03a9 );//Omega
equation_ += QChar( ')' );
equation_ += QChar( 0x03c8 );//psi
equation_ += QChar( '(' );
equation_ += QChar( 0x03a9 );//Omega
equation_ += QChar( '\'' );
equation_ += QChar( ')' );
}
~Vignette11 ( void )
{
// std::cout << "destructing Vignette 11" << std::endl;
delete face_;
}
unsigned int frame_count ( void ) { return FRAME_COUNT; }
unsigned int frame_rate ( void ) { return FRAME_RATE; }
void init ( void )
{
std::cout << "Vignette 11" << std::endl;
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
glEnable( GL_RASTER_POSITION_UNCLIPPED_IBM );
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
glEnable( GL_BLEND );
}
void view ( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top )
{
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( left, right, bottom, top, -250., 250. );
glMatrixMode( GL_MODELVIEW );
glTranslated( left, 0, 0 );
}
void draw ( unsigned int /*frame_number*/ )
{
face_->setHorizontalJustification( OGLFT::Face::LEFT );
face_->draw( 2., 128., "This frame demonstrates two...no three...features:" );
face_->draw( 2., 96., "1. Drawing a UNICODE string (using Qt's QString)." );
face_->draw( 2., 64., "2. Combining two fonts to cover more UNICODE points." );
face_->draw( 2., 32., "3. Embedding a font in the program." );
face_->setHorizontalJustification( OGLFT::Face::CENTER );
face_->draw( 250., 0., equation_ );
face_->setHorizontalJustification( OGLFT::Face::LEFT );
face_->draw( 2., -32., "Thanks to Oliver Bock for the font-in-memory code!" );
}
void finish ( void )
{
glDisable( GL_BLEND );
}
};
class Vignette12 : public Vignette {
static const unsigned int FRAME_COUNT = 10;
static const unsigned int FRAME_RATE = 1;
const QString text_;
QString equation_;
#if 1
OGLFT::Monochrome* face_;
#else
OGLFT::Filled* face_;
#endif
public:
Vignette12 ( const char* text, const char* fontfile ) : text_( text )
{
// First, open a face in the usual way.
#if 1
face_ = new OGLFT::Monochrome( fontfile, 18, 75 );
#else
face_ = new OGLFT::Filled( fontfile, 18, 75 );
#endif
face_->setForegroundColor( 0., .75, .75 );
// Now, create a second face, in this case, using a built-in font.
FT_Library library = OGLFT::Library::instance();
FT_Face ft_face;
FT_New_Memory_Face( library, lCSymbols_ttf,
lCSymbols_ttf_size, 0, &ft_face );
face_->addAuxiliaryFace( ft_face );
}
~Vignette12 ( void )
{
// cout << "destructing Vignette 12" << endl;
delete face_;
}
unsigned int frame_count ( void ) { return FRAME_COUNT; }
unsigned int frame_rate ( void ) { return FRAME_RATE; }
void init ( void )
{
std::cout << "Vignette 12" << std::endl;
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
glEnable( GL_RASTER_POSITION_UNCLIPPED_IBM );
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
glEnable( GL_BLEND );
}
void view ( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top )
{
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( left, right, bottom, top, -250., 250. );
glMatrixMode( GL_MODELVIEW );
glTranslated( left, 0, 0 );
}
void draw ( unsigned int /*frame_number*/ )
{
face_->setVerticalJustification( OGLFT::Face::TOP );
face_->setHorizontalJustification( OGLFT::Face::CENTER );
face_->draw( 250., 250., "Example of numeric formatting" );
face_->setVerticalJustification( OGLFT::Face::BASELINE );
face_->setHorizontalJustification( OGLFT::Face::ORIGIN );
face_->draw( 0., 128., "%.6f", 100.123456789 );
face_->draw( 0., 96., "%12.6e", 100.123456789 );
face_->draw( 0., 64., "%12.6g", 100.123456789 );
for ( int i = 1; i <= 8; ++i ) {
for ( int j = 1; j <= i; j++ ) {
double a = i + (double)j / ( 1 << i );
OGLFT::BBox bbox = face_->measure( "%p\"", a );
glPushMatrix();
glTranslated( j*42, -i * 18, 0 );
glColor3f( .25, .25, .25 );
glRectd( bbox.x_min_, bbox.y_min_, bbox.x_max_, bbox.y_max_ );
face_->draw( 0, 0, "%p\"", a );
glPopMatrix();
}
}
for ( int r = 0; r < 360; r += 45 ) {
double sinr = sin( (double)r/180 * M_PI );
double cosr = cos( (double)r/180 * M_PI );
face_->setStringRotation( r );
OGLFT::BBox bbox = face_->measure( "%p\"", 1.015625 );
glPushMatrix();
glTranslated( 250.+cosr*24, 96.+sinr*24, 0 );
glColor3f( .25, .25, .25 );
glRectd( bbox.x_min_, bbox.y_min_, bbox.x_max_, bbox.y_max_ );
face_->draw( 0, 0, "%p\"", 1.015625 );
glPopMatrix();
}
face_->setStringRotation( 0 );
}
void finish ( void )
{
glDisable( GL_BLEND );
}
};
CharacterView::CharacterView ( bool flank_speed, const char* fontfile,
QWidget* parent, const char* name )
: QGLWidget( ), flank_speed_( flank_speed )
{
vignettes.enqueue( new Vignette0( "Welcome to OGLFT!", fontfile ) );
vignettes.enqueue( new Vignette1( "The OpenGL/FreeType library", fontfile ) );
vignettes.enqueue( new Vignette2( "Featuring a mind numbing", fontfile ) );
vignettes.enqueue( new Vignette3( "collection of rendering options", fontfile ) );
vignettes.enqueue( new Vignette9( "and other text effects.", fontfile ) );
vignettes.enqueue( new Vignette5( "Sampler", fontfile ) );
vignettes.enqueue( new Vignette8( "Measuring the text.", fontfile ) );
vignettes.enqueue( new Vignette6( "Per vertex color", fontfile ) );
vignettes.enqueue( new Vignette7( "Per vertex texture coord", fontfile ) );
vignettes.enqueue( new Vignette10( "Each glyph can have it's own display list", fontfile ) );
vignettes.enqueue( new Vignette11( "QString Example", fontfile ) );
vignettes.enqueue( new Vignette12( "Formatting Numbers", fontfile ) );
vignettes.enqueue( new Vignette4( "OGLFT", fontfile ) );
frame_counter_ = 0;
counter_snapshot_ = 0;
animation_frame_counter_ = 0;
animation_frame_count_ = vignettes.current()->frame_count();
animation_frame_rate_ = 1000 / vignettes.current()->frame_rate();
connect( &redraw_timer_, SIGNAL(timeout()), SLOT(redraw()) );
connect( &performance_timer_, SIGNAL(timeout()), SLOT(measure_performance()) );
if ( flank_speed_ )
redraw_timer_.start( 0 );
else
redraw_timer_.start( animation_frame_rate_ );
performance_timer_.start( PERFORMANCE_SAMPLE_RATE_HZ * 1000 );
}
void CharacterView::redraw ( void )
{
updateGL();
frame_counter_++;
animation_frame_counter_++;
if ( animation_frame_counter_ >= animation_frame_count_ ) {
redraw_timer_.stop();
vignettes.current()->finish();
delete vignettes.dequeue();
if ( !vignettes.isEmpty() ) {
counter_snapshot_ = frame_counter_;
animation_frame_counter_ = 0;
vignettes.current()->init();
resetView();
animation_frame_count_ = vignettes.current()->frame_count();
animation_frame_rate_ = 1000 / vignettes.current()->frame_rate();
if ( flank_speed_ )
redraw_timer_.start( 0 );
else
redraw_timer_.start( animation_frame_rate_ );
}
else {
// Evidently, events may be processed during exiting, so...
redraw_timer_.stop();
performance_timer_.stop();
qApp->exit( 0 );
}
}
}
void CharacterView::measure_performance ( void )
{
int delta_count = frame_counter_ - counter_snapshot_;
std::cout << delta_count << " FPS" << std::endl;
counter_snapshot_ = frame_counter_;
}
void CharacterView::initializeGL ( void )
{
std::cout << glGetString( GL_VENDOR ) << " " << glGetString( GL_RENDERER ) << " "
<< glGetString( GL_VERSION ) << std::endl;
glClearColor( 0., 0., 0., 1. );
// Let the first vignette do any initialization it wants (though this
// should probably be called by the animation controller).
vignettes.current()->init();
}
void CharacterView::resizeGL ( int w, int h )
{
window_width_ = w;
window_height_ = h;
glViewport( 0, 0, window_width_, window_height_ );
view_width_ = window_width_;
view_height_ = window_height_;
view_left_ = -view_width_ / 2.;
view_right_ = view_width_ / 2.;
view_bottom_ = -view_height_ / 2.;
view_top_ = view_height_ / 2.;
resetView();
}
void CharacterView::paintGL ( void )
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
vignettes.current()->draw( animation_frame_counter_ % animation_frame_count_ );
}
void CharacterView::keyPressEvent ( QKeyEvent* e )
{
switch ( e->key() ) {
case Key_Q:
case Key_Escape:
qApp->exit( 0 );
case Key_Return:
// "Speed up the harvest." L, Skywalker
animation_frame_counter_ = animation_frame_count_;
updateGL();
}
}
void CharacterView::resetView ( void )
{
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glFrustum( view_left_, view_right_, view_bottom_, view_top_,
1., 100. );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
vignettes.current()->view( view_left_, view_right_, view_bottom_, view_top_ );
}
int main ( int argc, char* argv[] )
{
QApplication app( argc, argv );
if ( argc < 2 ) {
std::cerr << "usage: " << argv[0] << " [-f] fontfile" << std::endl;
std::cerr << " -f ignore the animation timings and run as fast as possible"
<< std::endl;
return 1;
}
int argn = 1;
bool flank_speed = false;
if ( !strcmp( argv[argn], "-f" ) ) {
flank_speed = true;
argn++;
}
if ( argc <= argn ) {
std::cerr << "usage: " << argv[0] << " [-f] fontfile" << std::endl;
std::cerr << " -f ignore the animation timings and run as fast as possible"
<< std::endl;
return 1;
}
// Test the supplied face to make sure it will work OK
OGLFT::Monochrome* test_face = new OGLFT::Monochrome( argv[argn] );
if ( !test_face->isValid() ) {
std::cerr << "Freetype did not recognize \"" << argv[1] << "\" as a font file"
<< std::endl;
return 1;
}
delete test_face;
CharacterView cv( flank_speed, argv[argn] );
cv.resize( 500, 500 );
app.setMainWidget( &cv );
cv.show();
return app.exec();
}