Question

Context

I'm making a game engine using SDL and OpenGL. I'm trying to find the best way to output text to the screen with fancy true type font and I came across FTGL. (If you have better/easier solution, feel free to share it.)

Compiling FTGL

It requires FreeType2 in order to work so I got it, compiled it (using Code::Block) and then I compiled the FTGL lib using Code::Block too.

I'm using Eclipse Indigo with the CDT plugin. I'm not sure which lib to take, since there are a .lib and a .dll file. I tried both, but this doesn't seem to change my problem at all, which curently is on this line:

FTfont* m_Font = new FTTextureFont(filename.c_str());

The error is:

The type 'FTTextureFont' must implement the inherited pure virtual method 'FTFont::MakeGlyph'

It doesn't change if I use another FTfont subclass, e.g. FTPixmapFont constructor.

Here are the linker flags which I tried:

-lmingw32 -lSDLmain -lSDL -lSDL_image -lSDL_net -lSDL_ttf -lftgl -lfreetype234_D -lopengl32 -lglu32

-lmingw32 -lSDLmain -lSDL -lSDL_image -lSDL_net -lSDL_ttf -lftgl -llibfreetype -lopengl32 -lglu32

I'm using eclipse with MinGW.

I have copied and pasted

  • the src/FTGL folder and
  • the content of the Include folder of the freetype library

to the include folder of the MinGW directory.

Both freetype2 (there a are freetype.lib, freetype248_D.lib and freetype-bcc.lib, not sure wich to link in the project properties) and ftgl (ftgl.dll, ftgl_D.lib, ftgl_static_D.lib) lib files into the corresponding lib folder of the MinGW directory.

If I click on the line that has the error and uses the Open Declaration option, eclipse takes me to the FTTextureFont header file which has FTTextureFont(char const*) defined and the MakeGlyph function defined too.

You can find the full code on the GetRandomGame project page if you want to see more, or as a reference.

Here's the Compiler version

Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=c:/mingw/bin/../libexec/gcc/mingw32/4.6.1/lto-wrapper.exe
Target: mingw32
Configured with: ../gcc-4.6.1/configure --enable-languages=c,c++,fortran,objc,ob
j-c++ --disable-sjlj-exceptions --with-dwarf2 --enable-shared --enable-libgomp -
-disable-win32-registry --enable-libstdcxx-debug --enable-version-specific-runti
me-libs --build=mingw32 --prefix=/mingw
Thread model: win32
gcc version 4.6.1 (GCC)

EDIT

Similar question: FTGL undefined references everywere?, but the answer of that question doesn't solve my problem, I still get these two errors.


EDIT 2

I was compiling using MSVC when I first tried to use FTGL and had two errors.

I finally used code::block to import the MSVC project provided with both libraries. One of the two errors got solved! But, I still got this one:

The type 'FTTextureFont' must implement the inherited pure virtual method 'FTFont::MakeGlyph'

EDIT 3

I've tried to compile FTGL 2.1.2 with freetype 2.3.4 and that hasn't solved my problem. I've tried FTGL 2.1.3 rc5 with freetype 2.3.4, same thing. Just to be sure, I've also tried freetype 2.3.5 and 2.4.8 (the first time was already 2.4.8).

I've tried moving the MakeGlyph code into the header file, but that hasn't solved the problem.

Here are some useful links i've found, but they haven't solved the problem yet.


EDIT 4

When I remove the ftgl linker flag, the compiler complains about this:

undefined reference to FTPixmapFont::FTPixmapFont(char const*)'
collect2: ld returned 1 exit status
Build error occurred, build is stopped

And I still get the pure virtual method MakeGlyph error.

With the ftgl linker flag, the only error I get is the "must implement the inherited Pure Virtual method MakeGlyph". The compiler builds the project fine (but crashes at start up):

-lmingw32 -lSDLmain -lSDL -lSDL_image -lSDL_net -lSDL_ttf -lfreetype -lftgl -lopengl32 -lglu32
Build complete for project GetRandomGame

So I'm thinking that the FTGL lib isn't compiled correctly since it should have the FTPixmapFont.cpp defining the pure virtual method MakeGlyph. I'm kind of new with all those lib things in c++ and I might be doing something wrong building the lib.


EDIT 5

I have read and seen in an example that I needed to have a config.h file, so I added a properly configured config.h file that comes with FTGL.

Then I found the following code in an example provided in the ftgl directory and I added that to my Font class.

class FTHaloFont : public FTFont
{
    public:
        FTHaloFont(char const *fontFilePath) : FTFont(fontFilePath) {}

    protected:
        virtual FTGlyph* MakeGlyph(FT_GlyphSlot slot)
        {
            return new FTHaloGlyph(slot);
        }
};

Even if I define MakeGlyph there, Eclipse complains about an unimplemented pure virtual method FTFont::MakeGlyph.


EDIT 6

I've tried debugging from command line with gdb and it tells me that freetype6.dll can't be found. I'm trying right now to find a solution.

Was it helpful?

Solution 3

EDIT 6

I've tried debugging from command line with gdb and it tells me that freetype6.dll can't be found.

I have placed freetype6.dll besides my executable file in the debug folder and it worked.

These are things that have slowed me or that I have learn while searching a solution:

  • Compiling with the same Compiler that I'm using
  • Learn to use code::block to import Visual Studio project
  • Actually be able to compile libraries in code::block without any warnings
  • Playing with linker flag (remove one and see what's going on) to help solve error and find problems
  • Learn to read provided example to find files that are necessary
  • And use gdb from command line

I got another problem while renaming some file of the project and I had to reconfigure my whole project in Eclipse (literally delete all files and checkout the SVN again). After that, the pure virtual error had disappeared! So I tried to debug the project and I got this error:

gdb: unknown target exception 0xc0000135 at 0x7724f52f

Eclipse wasn't helping me that much, so I tried the command line debugger and it told me that freetype6.dll was missing. And that was it!

OTHER TIPS

The compiler is telling you that the method FTTextureFont::MakeGlyph has not been written.

You have to either:

  1. Inherit from FTTextureFont and write the MakeGlyph method.
  2. Find a child class of FTTextureFont that does what you want.

According to the FTGL docs, any class derived from FTFont (which FTTextureFont has as a parent) has to implement MakeGlyph.

I'd look for code on the 'net to see what others have done were I you.

You're using wrong class.

The correct class to use is FTGLPixmapFont.

#include <SDL/SDL.h>
#include <GL/glew.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <common/timer.h>
#include <common/keyboard.h>
#include <FTGL/FTGL.h>
#include <FTGL/FTGLPixmapFont.h>
#include <wchar.h>
#include <math.h>

using Keyboard::keyPressed;

static Timer timer;
static int scrWidth = 640;
static int scrHeight = 480;

int main(int argc, char** argv){
    SDL_Init(SDL_INIT_VIDEO);

    SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 0);

    Keyboard::init();
    timer.reset();
    timer.setMaxFps(100);
    timer.setMinFps(5);

    if (SDL_SetVideoMode(scrWidth, scrHeight, 32, SDL_OPENGL) == 0){
        fprintf(stderr, "couldn't set mode %dx%d!\n", 640, 480);
        SDL_Quit();
        return -1;
    }
    glewInit();

    FTGLPixmapFont font("DejaVuSans.ttf");
    font.CharMap(ft_encoding_unicode);
    font.FaceSize(10);
    SDL_ShowCursor(SDL_DISABLE);

    glClearColor(0.2, 0.2, 0.2, 0.2);
    glClearDepth(1.0);

    glEnable(GL_DEPTH_TEST);

    bool running = true;
    while (running){
        SDL_Event event;
        if (SDL_PollEvent(&event)){
            switch(event.type){
                case SDL_QUIT:
                    running = false;
                    break;
            };
        }
        timer.update();
        Keyboard::update();

        if (keyPressed(SDLK_ESCAPE))
            running = false;

        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        gluOrtho2D(-scrWidth/2.0f, scrWidth/2.0f, scrHeight/2.0f, -scrHeight/2.0f);

        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();

        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

        glDisable(GL_DEPTH_TEST);
        wchar_t buf[256];
        swprintf(buf, 256, L"fps: %0.2f", timer.getFps());
        glRasterPos2i(10-scrWidth/2, 20-scrHeight/2);
        font.Render(buf);

        glFlush();
        SDL_GL_SwapBuffers();       
    }   

    SDL_Quit();
    return 0;
}

Also, read the tutorial.


Judging by my source code, the version I'm using is 2.1.2 (since 2.1.3 is rc5 which is "release candidate", which is not "stable"). It looks like you're trying to use 2.1.3 - rc5. Downgrade to 2.1.2 and try again. Also, remember to tell what library version you're using next time you run into problem like this.

Alternatively you could try to fix FTGL (which is pain, and project seems to be abandoned). Or you could try to make your own freetype2-based font renderer (which is also pain, but might pay off in the long run).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top