gpt4 book ai didi

c++ - 文本渲染非常慢

转载 作者:可可西里 更新时间:2023-11-01 16:46:22 26 4
gpt4 key购买 nike

我正在使用 FTGL 库在我的 C++、OpenGL 应用程序中呈现文本,但我发现它非常慢,尽管据说它是一个快速高效的库。

即使对于少量文本,性能下降也是可见的,但是当我尝试渲染几行文本时,FPS 从 350~ 下降到 30~:

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

我在 Debug模式下检查了断点 - 它只创建一次显示列表,之后它只调用之前创建的一个。

渲染如此缓慢的原因可能是什么?我怎样才能加快速度?

编辑:我正在使用 FTTextureFont(每个字形使用一个纹理)。根据this FTGL 教程,我宁愿使用 FTBufferFont,因为它每行只使用一个纹理。缓冲区字体应该更快,但在我尝试之后它变得更丑甚至更慢(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;
}

最佳答案

从普通字体文件渲染排版是一项计算密集型操作。字体字形被读取为一组样条线,用于生成字符边界,这些边界被 segmentation 并送入图形管道。我对 FreeType2 不是很熟悉,但我使用过 FTGL。您应该使用 FontAtlas 来呈现类型。 FontAtlas 是一个常规的纹理图集(很像 Sprite 表),它为每个字体大小渲染一次,然后存储以供将来的字形渲染。

查看此链接以获取有关该过程的更多信息: http://antongerdelan.net/opengl4/freetypefonts.html

这应该会大大提高性能。尽管您可能会失去一些字体渲染的灵 active 。

关于c++ - 文本渲染非常慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15544742/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com