Building a 3D Engine in Perl, Part 4

Building a 3D Engine in Perl, Part 4
by Geoff Broadwell |

An FPS Counter

The measurements that dprofpp performs have enough overhead to significantly reduce the engine's apparent performance. (Even old hardware can do better than 80-100 FPS with this simple scene.) The overhead is necessary to get a detailed analysis, but when it comes time to show off, most users want to have a nice frame rate display showing the performance of the engine running as fast as it can.

Making a frame rate display requires the ability to render text in front of the scene. The necessary pieces of that are:

  1. A font containing glyphs for the characters to display (at least 0 through 9).
  2. A font reader to load the font from a file into memory as bitmaps.
  3. A converter from raw bitmaps to a format that OpenGL can readily display.
  4. A way to render the proper bitmaps for a given string.
  5. A way to calculate the current frame rate.

The Numbers Font

There are hundreds of freely available fonts, but most of them are available only in fairly complex font formats such as TrueType and Type 1. Some versions of SDL_perl support these complex font formats, but this support has historically been frustratingly buggy or incomplete.

Given the relatively simple requirement (render a single integer), I chose instead to create a very simple bitmapped font format just for this article. The font file is numbers-7x11.txt in the examples tarball. It begins as follows:

7x11



30

..000..

.0...0.

.0...0.

0.....0

0.....0

0.....0

0.....0

0.....0

.0...0.

.0...0.

..000..



31

...0...

..00...

00.0...

...0...

...0...

...0...

...0...

...0...

...0...

...0...

0000000

The first line indicates the size of each character cell in the font; in this case, seven columns and 11 rows. The remaining chunks each consist of the character's codepoint in hex followed by a bitmap represented as text--. represents a transparent pixel, and 0 represents a rendered pixel. Empty lines separate chunks.

The Font Reader

To read the glyph definitions into bitmaps, I first added read_font_file:

sub read_font_file

{

    my $self = shift;

    my $file = shift;



    open my $defs, '<', $file

        or die "Could not open '$file': $!";

    local $/ = '';



    my $header  = <$defs>;

    chomp($header);

    my ($w, $h) = split /x/ =& $header;



    my %bitmaps;

    while (my $def = <$defs>) {

        my ($hex, @rows) = grep /\S/ =& split /\n/ =& $def;



        @rows = map {tr/.0/01/; pack 'B*' =& $_} @rows;



        my $bitmap           = join '' =& reverse @rows;

        my $codepoint        = hex $hex;



        $bitmaps{$codepoint} = $bitmap;

    }



    return (\%bitmaps, $w, $h);

}

read_font_file begins by opening the font file for reading. It next requests paragraph slurping mode by setting $/ to ''. In this mode, Perl automatically breaks up the font file at empty lines, with the header first followed by each complete glyph definition as a single chunk. Next, the routine reads the header, chomps it, and splits the cell size definition into width and height.

With the preliminaries out of the way, read_font_file creates a hash to store the finished bitmaps and enters a while loop over the remaining chunks of the font file. Each glyph definition is split into a hex number and an array of bitmap rows; using grep /\S/ =& ignores any trailing blank lines.

The next line converts textual rows to real bitstrings. First, each transparent pixel (.) becomes 0, and each rendered pixel (0) turns into a 1. Feeding the resulting binary text string to pack 'B*' converts the binary into an actual bitstring, with the bits packed in starting from the high bit of each byte (as OpenGL prefers). The resulting bitstrings are stored back in @rows.

Because OpenGL prefers bitmaps to start at the bottom and go up, the code reverses @rows before joining to create the finished bitmap. The hex operator converts the hex number to decimal to be the key for the newly created bitmap in the %bitmaps hash.

After parsing the whole font file, the function returns the bitmaps to the caller, along with the cell size metrics.

Prev  [1] [2] [3] [4] [5] [6] [7] [8] Next

Close    To Top
  • Prev Article-Programming:
  • Next Article-Programming:
  • Now: Tutorial for Web and Software Design > Programming > Perl > Programming Content
    Photoshop Tutorial
     

    Special Effect

      3D Effect
      Photoshop Articles
    Programming Tutorial
     

    C/C++ Tutorial

      Visual Basic
      C# Tutorial
    Database Tutorial
     

    MySQL Tutorial

      MS SQL Tutorial
      Oracle Tutorial
    Geek Tutorial
     

    Blogging Tutorial

      RSS Tutorial
      Podcasting Tutorial
    Graphic Design Tutorial
      Coreldraw Tutorial
      Illustrator Tutorial
      3D Tutorials
    Webmaster Articles
     

    Domain Service

      Web Hosting
      Site Promotion
    Java Tutorial/ Articles
     

    Java Servlets

      JavaEE Tutorial
     

    JavaBeans Tutorial

    XML Tutorial/ Articles
     

    XML Style

      AJAX Tutorial
      XML Mobile
    Flash Tutorial/ Articles
     

    Flash Video

      Action Script
      Flash Articles
    OS Tutorial/ Articles
      Linux Tutorial
      Symbian Tutorial
      MacOS Tutorial
    Personal Tech
      Hardware Tutorial
      Software Tutorial
      Online Auction