私はC++、OpenGLアプリケーションでテキストをレンダリングするのにFTGLライブラリを使用していますが、これは高速かつ効率的なライブラリであると言われていますが、テキストレンダリングがひどく遅い
でもテキストの少量のため、パフォーマンスの低下が表示されているが、私は、テキストの数行をレンダリングしようとすると、FPSが30〜350〜から落ちる:
はい、私はすでに知っています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;
}
テキストをテクスチャにレンダリングし、テキストが変更された場合にのみテクスチャを更新してください。もちろん、テキストがフレームごとに変更されても、これは役に立ちません。 – didierc
@didierc私はそれがFTGLが既にしていると思います。 –
私たちはFTGLと 'FTTextureFont'を使用し、良いパフォーマンスを得ています。あなたは間違ったことをしているに違いない。 – user763305