1

语境

我正在使用 SDL 和 OpenGL 制作游戏引擎。我正在尝试找到使用精美的真字体将文本输出到屏幕的最佳方式,但我遇到了 FTGL。(如果您有更好/更简单的解决方案,请随时分享。)

编译 FTGL

它需要 FreeType2 才能工作,所以我得到了它,编译它(使用 Code::Block),然后我也使用 Code::Block 编译了 FTGL 库。

我正在使用带有 CDT 插件的 Eclipse Indigo。我不确定要采用哪个库,因为有一个.lib和一个.dll文件。我都试过了,但这似乎根本没有改变我的问题,目前就在这条线上:

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

错误是:

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

如果我使用另一个 FTfont 子类,例如 FTPixmapFont 构造函数,它不会改变。

这是我尝试过的链接器标志:

-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

我正在使用 Eclipse 和 MinGW。

我已经复制粘贴了

  • src/FTGL文件夹和
  • Includefreetype 库文件夹的内容

includeMinGW 目录的文件夹。

freetype2(有freetype.lib,freetype248_D.libfreetype-bcc.lib, 不确定在项目属性中链接)和 ftgl ( ftgl.dll, ftgl_D.lib, ftgl_static_D.lib) lib 文件到 MinGW 目录的相应 lib 文件夹中。

如果我单击有错误的行并使用 Open Declaration 选项,eclipse 会将我带到FTTextureFontFTTextureFont(char const*)定义的头文件和定义的MakeGlyph函数。

如果您想查看更多内容或作为参考,您可以在GetRandomGame 项目页面上找到完整代码。

这是编译器版本

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)

编辑

类似的问题:FTGL undefined references everywere?,但是那个问题的答案并没有解决我的问题,我仍然得到这两个错误。


编辑 2

当我第一次尝试使用 FTGL 并出现两个错误时,我正在使用 MSVC 进行编译。

我最终使用 code::block 来导入两个库提供的 MSVC 项目。两个错误之一得到了解决!但是,我还是得到了这个:

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

编辑 3

我尝试用 freetype 2.3.4 编译 FTGL 2.1.2,但这并没有解决我的问题。我已经尝试过使用 freetype 2.3.4 的 FTGL 2.1.3 rc5,同样的事情。可以肯定的是,我也尝试过 freetype 2.3.5 和 2.4.8(第一次已经是 2.4.8)。

我已经尝试将MakeGlyph代码移动到头文件中,但这并没有解决问题。

这是我找到的一些有用的链接,但它们还没有解决问题。


编辑 4

当我删除ftgl链接器标志时,编译器会抱怨这个:

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

而且我仍然得到纯虚拟方法MakeGlyph错误。

使用ftgl链接器标志,我得到的唯一错误是“必须实现继承的纯虚拟方法 MakeGlyph”。编译器可以很好地构建项目(但在启动时崩溃):

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

所以我认为 FTGL 库没有正确编译,因为它应该FTPixmapFont.cpp定义纯虚拟方法MakeGlyph。我对 C++ 中的所有这些 lib 东西有点陌生,我可能在构建 lib 时做错了什么。


编辑 5

我已经阅读并在一个示例中看到我需要一个config.h文件,因此我添加了一个正确配置的config.h文件,该文件随 FTGL 一起提供。

然后我在目录中提供的示例中找到了以下代码,ftgl并将其添加到我的Font课程中。

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

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

即使我MakeGlyph在那里定义,Eclipse 也会抱怨未实现的纯虚拟方法FTFont::MakeGlyph


编辑 6

我尝试使用 gdb 从命令行进行调试,它告诉我找不到 freetype6.dll。我现在正在努力寻找解决方案。

4

3 回答 3

1

编译器告诉您该方法FTTextureFont::MakeGlyph尚未编写。

您必须:

  1. 继承FTTextureFont并编写MakeGlyph方法。
  2. 找到一个可以满足您需求的子类FTTextureFont

根据 FTGL 文档,任何派生自FTFontFTTextureFont作为父级)的类都必须实现MakeGlyph.

我会在网上寻找代码,看看其他人做了什么。

于 2012-02-21T11:33:30.297 回答
1

你使用了错误的类。

要使用的正确类是 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;
}

另外,阅读教程


从我的源代码来看,我使用的版本是 2.1.2(因为 2.1.3 是 rc5,它是“候选版本”,不是“稳定”)。看起来您正在尝试使用 2.1.3 - rc5。降级到 2.1.2 并重试。另外,请记住在下次遇到此类问题时告诉您正在使用的库版本。

或者,您可以尝试修复 FTGL(这很痛苦,并且项目似乎被放弃了)。或者您可以尝试制作自己的基于 freetype2 的字体渲染器(这也很痛苦,但从长远来看可能会有所回报)。

于 2012-02-21T11:40:27.793 回答
1

编辑 6

我尝试使用gdb从命令行进行调试,它告诉我freetype6.dll找不到。

我已经将freetype6.dll我的可执行文件放在debug文件夹中并且它有效。

这些是让我变慢或在寻找解决方案时学到的东西:

  • 使用我正在使用的相同编译器进行编译
  • 学习使用 code::block 导入 Visual Studio 项目
  • 实际上能够在没有任何警告的情况下在 code::block 中编译库
  • 使用链接器标志(删除一个并查看发生了什么)以帮助解决错误和发现问题
  • 学习阅读提供的示例以查找必要的文件
  • 并从命令行使用 gdb

我在重命名项目的某些文件时遇到了另一个问题,我不得不在 Eclipse 中重新配置我的整个项目(从字面上删除所有文件并再次签出 SVN)。之后,纯虚的错误就消失了!所以我试图调试项目,我得到了这个错误:

gdb: unknown target exception 0xc0000135 at 0x7724f52f

Eclipse 对我的帮助不大,所以我尝试了命令行调试器,它告诉我 freetype6.dll 丢失了。就是这样!

于 2012-02-27T07:31:35.293 回答