2013-03-21 16 views
9

私はC++、OpenGLアプリケーションでテキストをレンダリングするのにFTGLライブラリを使用していますが、これは高速かつ効率的なライブラリであると言われていますが、テキストレンダリングがひどく遅い

でもテキストの少量のため、パフォーマンスの低下が表示されているが、私は、テキストの数行をレンダリングしようとすると、FPSが30〜350〜から落ちる:

enter image description here

はい、私はすでに知っています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; 
} 

私はデバッグモードでブレークポイントでチェックしました。表示リストは1回だけ作成され、後で以前に作成されたものだけが呼び出されます。

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

編集: 私は(グリフごとにテクスチャを使用する)FTTextureFontを使用しています。 this FTGLチュートリアルによれば、1行に1つのテクスチャしか使用しないので、むしろFTBufferFontを使うべきです。バッファフォントは高速にする必要がありますが、試した後では、テクスチャフォントが30fpsの場合は6fpsですが、醜く、さらに遅くなります。

EDIT2:

は、これは私が私のフォントを作成する方法である:

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; 
} 

EDIT3:

これはFTTextureFontでグリフをレンダリングするFTGLライブラリのソースコードから取られた機能です。これは、別のグリフには同じテクスチャを使用し、他の座標と同じように使用するので、問題ではありません。

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; 
} 
+0

テキストをテクスチャにレンダリングし、テキストが変更された場合にのみテクスチャを更新してください。もちろん、テキストがフレームごとに変更されても、これは役に立ちません。 – didierc

+0

@didierc私はそれがFTGLが既にしていると思います。 –

+0

私たちはFTGLと 'FTTextureFont'を使用し、良いパフォーマンスを得ています。あなたは間違ったことをしているに違いない。 – user763305

答えて

2

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

は、プロセスの詳細については、このリンクをチェックアウト: http://antongerdelan.net/opengl4/freetypefonts.html

これは、パフォーマンスを大幅に向上させる必要があります。フォントレンダリングの柔軟性が失われることもありますが、

+0

回答とリンクの両方をありがとうございます - 非常に便利です。 FTGL機能が本当に好きだったので、私が聞きたい答えは間違いありませんが、他の選択肢がないようです。 –

関連する問題