Edit

kc3-lang/ftgl/demo/simple.cpp

Branch :

  • Show log

    Commit

  • Author : sammy
    Date : 2010-05-23 16:30:54
    Hash : b066d782
    Message : Add query functions to request FTGL configuration information: - C version: ftglGetString(); - C++ version: FTGL::GetString(); Currently supported strings are: - FTGL_CONFIG_VERSION: FTGL version information

  • demo/simple.cpp
  • /*
     * simple.cpp - simple demo for FTGL, the OpenGL font library
     *
     * Copyright (c) 2008 Sam Hocevar <sam@hocevar.net>
     *
     * Permission is hereby granted, free of charge, to any person obtaining
     * a copy of this software and associated documentation files (the
     * "Software"), to deal in the Software without restriction, including
     * without limitation the rights to use, copy, modify, merge, publish,
     * distribute, sublicense, and/or sell copies of the Software, and to
     * permit persons to whom the Software is furnished to do so, subject to
     * the following conditions:
     *
     * The above copyright notice and this permission notice shall be
     * included in all copies or substantial portions of the Software.
     *
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
     * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
     * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
     * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
     * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     */
    
    #include "config.h"
    
    #include <math.h> // sin(), cos()
    #include <stdlib.h> // exit()
    
    #if defined HAVE_GL_GLUT_H
    #   include <GL/glut.h>
    #elif defined HAVE_GLUT_GLUT_H
    #   include <GLUT/glut.h>
    #else
    #   error GLUT headers not present
    #endif
    
    #include <FTGL/ftgl.h>
    
    static FTFont *font[3];
    static int fontindex = 0;
    static int lastfps = 0;
    static int frames = 0;
    
    //
    //  FTHaloGlyph is a derivation of FTPolygonGlyph that also displays a
    //  halo of FTOutlineGlyph objects at varying positions and with varying
    //  outset values.
    //
    class FTHaloGlyph : public FTPolygonGlyph
    {
        public:
            FTHaloGlyph(FT_GlyphSlot glyph) : FTPolygonGlyph(glyph, 0, true)
            {
                for(int i = 0; i < 5; i++)
                {
                    subglyph[i] = new FTOutlineGlyph(glyph, i, true);
                }
            }
    
        private:
            const FTPoint& Render(const FTPoint& pen, int renderMode)
            {
                glPushMatrix();
                for(int i = 0; i < 5; i++)
                {
                    glTranslatef(0.0, 0.0, -2.0);
                    subglyph[i]->Render(pen, renderMode);
                }
                glPopMatrix();
    
                return FTPolygonGlyph::Render(pen, renderMode);
            }
    
            FTGlyph *subglyph[5];
    };
    
    //
    //  FTHaloFont is a simple FTFont derivation that builds FTHaloGlyph
    //  objects.
    //
    class FTHaloFont : public FTFont
    {
        public:
            FTHaloFont(char const *fontFilePath) : FTFont(fontFilePath) {}
    
        private:
            virtual FTGlyph* MakeGlyph(FT_GlyphSlot slot)
            {
                return new FTHaloGlyph(slot);
            }
    };
    
    //
    //  Main OpenGL loop: set up lights, apply a few rotation effects, and
    //  render text using the current FTGL object.
    //
    static void RenderScene(void)
    {
        int now = glutGet(GLUT_ELAPSED_TIME);
    
        float n = (float)now / 20.;
        float t1 = sin(n / 80);
        float t2 = sin(n / 50 + 1);
        float t3 = sin(n / 30 + 2);
    
        float ambient[4]  = { (t1 + 2.0) / 3,
                              (t2 + 2.0) / 3,
                              (t3 + 2.0) / 3, 0.3 };
        float diffuse[4]  = { 1.0, 0.9, 0.9, 1.0 };
        float specular[4] = { 1.0, 0.7, 0.7, 1.0 };
        float position[4] = { 100.0, 100.0, 0.0, 1.0 };
    
        float front_ambient[4]  = { 0.7, 0.7, 0.7, 0.0 };
    
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
        glEnable(GL_LIGHTING);
        glEnable(GL_DEPTH_TEST);
        glEnable(GL_LINE_SMOOTH);
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE);
    
        glPushMatrix();
            glTranslatef(-0.9, -0.2, -10.0);
            glLightfv(GL_LIGHT1, GL_AMBIENT,  ambient);
            glLightfv(GL_LIGHT1, GL_DIFFUSE,  diffuse);
            glLightfv(GL_LIGHT1, GL_SPECULAR, specular);
            glLightfv(GL_LIGHT1, GL_POSITION, position);
            glEnable(GL_LIGHT1);
        glPopMatrix();
    
        glPushMatrix();
            glMaterialfv(GL_FRONT, GL_AMBIENT, front_ambient);
            glColorMaterial(GL_FRONT, GL_DIFFUSE);
            glTranslatef(0.0, 0.0, 20.0);
            glRotatef(n / 1.11, 0.0, 1.0, 0.0);
            glRotatef(n / 2.23, 1.0, 0.0, 0.0);
            glRotatef(n / 3.17, 0.0, 0.0, 1.0);
            glTranslatef(-260.0, -0.2, 0.0);
            glColor3f(1.0, 1.0, 1.0);
            font[fontindex]->Render("Hello FTGL!");
        glPopMatrix();
    
        glutSwapBuffers();
    
        frames++;
    
        if(now - lastfps > 5000)
        {
            fprintf(stderr, "%i frames in 5.0 seconds = %g FPS\n",
                    frames, frames * 1000. / (now - lastfps));
            lastfps += 5000;
            frames = 0;
        }
    }
    
    //
    //  GLUT key processing function: <esc> quits, <tab> cycles across fonts.
    //
    static void ProcessKeys(unsigned char key, int x, int y)
    {
        switch(key)
        {
        case 27:
            delete font[0];
            delete font[1];
            delete font[2];
            exit(EXIT_SUCCESS);
            break;
        case '\t':
            fontindex = (fontindex + 1) % 3;
            break;
        }
    }
    
    //
    //  Main program entry point: set up GLUT window, load fonts, run GLUT loop.
    //
    int main(int argc, char **argv)
    {
        char const *file = NULL;
    
    #ifdef FONT_FILE
        file = FONT_FILE;
    #else
        if(argc < 2)
        {
            fprintf(stderr, "Usage: %s <font_name.ttf>\n", argv[0]);
            return EXIT_FAILURE;
        }
    #endif
    
        if(argc > 1)
        {
            file = argv[1];
        }
    
        // Initialise GLUT stuff
        glutInit(&argc, argv);
        glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
        glutInitWindowPosition(100, 100);
        glutInitWindowSize(640, 480);
        glutCreateWindow("simple FTGL C++ demo");
    
        glutDisplayFunc(RenderScene);
        glutIdleFunc(RenderScene);
        glutKeyboardFunc(ProcessKeys);
    
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        gluPerspective(90, 640.0f / 480.0f, 1, 1000);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        gluLookAt(0.0, 0.0, 640.0f / 2.0f, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
    
        // Initialise FTGL stuff
        font[0] = new FTExtrudeFont(file);
        font[1] = new FTBufferFont(file);
        font[2] = new FTHaloFont(file);
    
        if(font[0]->Error() || font[1]->Error() || font[2]->Error())
        {
            fprintf(stderr, "%s: could not load font `%s'\n", argv[0], file);
            return EXIT_FAILURE;
        }
    
        font[0]->FaceSize(80);
        font[0]->Depth(10);
        font[0]->Outset(0, 3);
        font[0]->CharMap(ft_encoding_unicode);
    
        font[1]->FaceSize(80);
        font[1]->CharMap(ft_encoding_unicode);
    
        font[2]->FaceSize(80);
        font[2]->CharMap(ft_encoding_unicode);
    
        fprintf(stderr, "Using FTGL version %s\n",
                FTGL::GetString(FTGL::CONFIG_VERSION));
    
        // Run GLUT loop
        glutMainLoop();
    
        return EXIT_SUCCESS;
    }