9

C++、OpenGL アプリケーションでテキストをレンダリングするために FTGL ライブラリを使用していますが、高速で効率的なライブラリであると言われていますが、非常に遅いことがわかりました。

少量のテキストでもパフォーマンスの低下が見られますが、数行のテキストをレンダリングしようとすると、FPS が 350 ~ から 30 ~ に低下します。

ここに画像の説明を入力

はい、FPS が効率をチェックする良い方法ではないことは既に知っていますが、この場合、それほど大きな違いはないはずです。

FTGL内部で表示リストを使って高速化する機能を見つけたのですが、デフォルトでオンになっているようです。とにかく私はそれを使ってみましたが、何も得られませんでした。それで何か壊れているのか、よくわからないのではないかと思い、レンダリングテキストを自分のディスプレイリストに入れることにしましたが、違いが見えないほどわずかであるか、まったく違いがありません。違い。

bool TFontManager::renderWrappedText(font_ptr font, int lineLength, const TPoint& position, const std::string& text) {
    if(font == nullptr) {
        return false;
    }

    string key = sizeToString(font->FaceSize());    // key to look for it in map
    key.append(TUtil::intToString(lineLength));
    key.append(text);
    GLuint displayListId = getDisplayListId(key);   // get display list id from internal map

    if(displayListId != 0) {                        // if display list id was found in map, i can call it
        glCallList(displayListId);
        return true;
    }

    // if id was not found, i'm creating new display list 

    FTSimpleLayout simpleLayout;
    simpleLayout.SetLineLength((float)lineLength);

    simpleLayout.SetFont(font.get());

    displayListId = glGenLists(1);
    glNewList(displayListId, GL_COMPILE);

    glPushMatrix();
    glTranslatef(position.x, position.y, 0.0f);
    simpleLayout.Render(TUtil::stringToWString(text).c_str(), -1, FTPoint(), FTGL::RENDER_FRONT | FTGL::RENDER_BACK);        // according to visual studio's profiler, bottleneck is inside this function. more exactly in drawing textured quads when i looked into FTGL code.
    glPopMatrix();

    glEndList();

    m_textDisplayLists[key] = displayListId;

    glCallList(displayListId);

    return true;
}

デバッグモードでブレークポイントを確認しました-表示リストを一度だけ作成し、後で以前に作成したリストのみを呼び出します。

このような遅いレンダリングの理由は何でしょうか? どうすればスピードアップできますか?

編集: 私は使用してFTTextureFontいます(グリフごとに1つのテクスチャを使用します)。このFTGL チュートリアルによるとFTBufferFont、1 行に 1 つのテクスチャしか使用しないため、むしろ を使用する必要があります。バッファ フォントの方が速いはずですが、試してみると、見にくく、さらに遅くなりました (6 fps に対し、テクスチャ フォントでは 30 fps でした)。

編集2:

これが私のフォントの作成方法です。

font_ptr TFontManager::getFont(const std::string& filename, int size) {
    string fontKey = filename;
    fontKey.append(sizeToString(size));

    FontIter result = fonts.find(fontKey);
    if(result != fonts.end()) {
        return result->second;      // Found font in list
    }

    // If font wasn't found, create a new one and store it in list of fonts

    font_ptr font(new FTTextureFont(filename.c_str()));
    font->UseDisplayList(true);

    if(font->Error()) {
        string message = "Failed to open font";
        message.append(filename);
        TError::showMessage(message);
        return nullptr;
    }

    if(!font->FaceSize(size)) {
        string message = "Failed to set font size";
        TError::showMessage(message);
        return nullptr;
    }

    fonts[fontKey] = font;

    return font;
}

編集3:

これは、 でグリフをレンダリングする FTGL ライブラリ ソース コードから取得した関数ですFTTextureFont。別のグリフに同じテクスチャを使用し、他の座標だけを使用するため、これは問題になりません。

const FTPoint& FTTextureGlyphImpl::RenderImpl(const FTPoint& pen,
                                              int renderMode)
{
    float dx, dy;

    if(activeTextureID != glTextureID)
    {
        glBindTexture(GL_TEXTURE_2D, (GLuint)glTextureID);
        activeTextureID = glTextureID;
    }

    dx = floor(pen.Xf() + corner.Xf());
    dy = floor(pen.Yf() + corner.Yf());

    glBegin(GL_QUADS);
        glTexCoord2f(uv[0].Xf(), uv[0].Yf());
        glVertex2f(dx, dy);

        glTexCoord2f(uv[0].Xf(), uv[1].Yf());
        glVertex2f(dx, dy - destHeight);

        glTexCoord2f(uv[1].Xf(), uv[1].Yf());
        glVertex2f(dx + destWidth, dy - destHeight);

        glTexCoord2f(uv[1].Xf(), uv[0].Yf());
        glVertex2f(dx + destWidth, dy);
    glEnd();

    return advance;
}
4

1 に答える 1

3

通常の書体ファイルからタイポグラフィをレンダリングすることは、かなり計算量の多い操作です。フォント グリフは、テッセレーションされてグラフィックス パイプラインに供給される文字境界を生成するために使用される一連のスプラインとして読み取られます。私は FreeType2 にはあまり詳しくありませんが、FTGL を使用したことがあります。タイプをレンダリングするには、FontAtlas を使用する必要があります。FontAtlas は、通常のテクスチャ アトラス (スプライト シートによく似ています) であり、フォント サイズごとに 1 回レンダリングされ、その後のグリフ レンダリング用に保存されます。

プロセスの詳細については、このリンクを確認してください: http://antongerdelan.net/opengl4/freetypefonts.html

これにより、パフォーマンスが大幅に向上するはずです。ただし、フォント レンダリングの柔軟性が失われる可能性があります。

于 2013-03-24T22:19:47.717 に答える