1

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.

Community
  • 1
  • 1
Emile Bergeron
  • 17,074
  • 5
  • 83
  • 129
  • 1
    It's much quicker for you to get help if you make the smallest example possible that reproduces your problem, including parameters passed to a makefile, compiler and/or linker. There could be a number of problems with what you present here and there's no way to tell you what they are without complete info. FWIW, MSVC does not link to DLLs, a .lib file is required. There are a few exceptions to that rule, but not in your case. – JimR Feb 19 '12 at 10:50
  • 3
    Wait. You compiled FreeType2 and FTGL with VC2010, but you are using Eclipse as your IDE. How exactly does that work? – Nicol Bolas Feb 19 '12 at 15:20
  • @NicolBolas i'm going to try to compile both lib with eclipse using the MinGW to see if it can fix the problem. – Emile Bergeron Feb 19 '12 at 19:15
  • After compiling both lib with MinGW (in code::block) I still get that last error... – Emile Bergeron Feb 20 '12 at 21:14
  • 1
    Make simple test application that produces that problem, pack it into archive (along with build scripts/makefiles, ftgl and freetype) and upload somewhere. Somebody might take a look at it. Also add compiler/library version to the question. – SigTerm Feb 22 '12 at 10:22

3 Answers3

1

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.

JimR
  • 15,513
  • 2
  • 20
  • 26
  • Thanks for the answer, but I already know all of this. The compiler error message is fairly clear to me, and I have already check up the header file and there is a MakeGlyph function. I guess the code is in the lib and i'm probably doing something wrong while using the lib. – Emile Bergeron Feb 21 '12 at 17:09
  • @DawnUser: Sorry, but based on your response you do not already know all of this. You do not understand what pure virtual means in this context. – JimR Feb 21 '12 at 20:27
  • Yes i do understand, I'm actually using some pure virtual functions in my own project, but I do not want to implement the MakeGlyph Fonction myself since it's supposed to be implemented in the lib. – Emile Bergeron Feb 21 '12 at 22:53
  • @DawnUser: pure virtual functions have to be defined before you can instantiate an instance of a class. It does not work if you do not define the function. So, I still maintain that you do not understand. Read this: http://www.learncpp.com/cpp-tutorial/126-pure-virtual-functions-abstract-base-classes-and-interface-classes for a better explanation. – JimR Feb 22 '12 at 13:30
  • Yes I know that, the function is defined in the FTxxxx.cpp – Emile Bergeron Feb 22 '12 at 20:48
  • See Edit 5, I even tried defining a new class that defines MakeGlyph, but Eclipse still complains about that pure virtual method to be not implemented. The compiler builds the project without any errors or warnings though. – Emile Bergeron Feb 24 '12 at 03:42
1

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).

SigTerm
  • 26,089
  • 6
  • 66
  • 115
  • First of all, thanks for the answer! 1. Wrong class, not so sure, since all of the FTfont sub class give me the error, no matter if I use FTxxxxx or FTGLxxxx (eclipse only highlight the FTxxxx class but recognize both). 2. The lib version, great idea, I'm going to see if that can solve it today – Emile Bergeron Feb 21 '12 at 16:57
  • in the FTGLPixmapFont header file, you can see >`#define FTGLPixmapFont FTPixmapFont` – Emile Bergeron Feb 21 '12 at 23:40
  • @DawnUser: Nope. It is not present in 2.1.2. – SigTerm Feb 22 '12 at 10:19
1

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!

Emile Bergeron
  • 17,074
  • 5
  • 83
  • 129
  • 1
    I'm just having the same issue. Luckily it was just Eclipse who was complaining, but g++ ignored it. To get rid of the annoying errors messages in Eclipse I just disabled the "Abstract class cannot be instantiated" option under Project -> Properties -> C/C++ General -> Code Analysis – Dan Jun 05 '13 at 10:40
  • Good it worked for you but I guess disabling this isn't a good idea!? – Emile Bergeron Jul 28 '13 at 02:59