Nv Path Rendering字体最佳实现

时间:2017-03-13 15:50:44

标签: opengl

我使用Mark Kilgard读过Getting Started with NV Path Rendering的NV路径渲染

我的实施基于NVidia Graphics Samples中Tiger3DES项目中的render_font示例。

这个实现看起来比普通的基于纹理的字体解决方案慢,所以我想知道它有缺陷吗? NVidia state NV路径渲染为faster than alternatives,但我的性能限制比我预期的要快得多。

我有一个包含1000条消息的场景'。我的FPS在Quadro K4200上非常差。如果我将文本合并为单个消息,则不会出现性能问题,但无法单独格式化消息。如果我将消息数量减少到100,我会得到一个不错的帧率(200+解锁)。

对模板,限幅和覆盖填料的调用是否昂贵?

这是一个代码段......

Init FontFace:

/* Create a range of path objects corresponding to Latin-1 character codes. */
m_glyphBase = glGenPathsNV(numChars);

glPathGlyphRangeNV(m_glyphBase,
    target,
    name.c_str(),
    style,
    0,
    numChars,
    GL_USE_MISSING_GLYPH_NV,
    pathParamTemplate,
    GLfloat(emScale)
);
/* Load base character set for unsupported glyphs. */
glPathGlyphRangeNV(m_glyphBase,
    GL_STANDARD_FONT_NAME_NV,
    "Sans",
    style,
    0,
    numChars,
    GL_USE_MISSING_GLYPH_NV,
    pathParamTemplate,
    GLfloat(emScale)
);

/* Query font and glyph metrics. */
GLfloat fontData[4];
glGetPathMetricRangeNV(GL_FONT_Y_MIN_BOUNDS_BIT_NV | GL_FONT_Y_MAX_BOUNDS_BIT_NV |
    GL_FONT_UNDERLINE_POSITION_BIT_NV | GL_FONT_UNDERLINE_THICKNESS_BIT_NV,
    m_glyphBase + ' ',
    /*count*/1,
    4 * sizeof(GLfloat),
    fontData
);

m_yMin = fontData[0];
m_yMax = fontData[1];
m_underlinePosition = fontData[2];
m_underlineThickness = fontData[3];
glGetPathMetricRangeNV(GL_GLYPH_HORIZONTAL_BEARING_ADVANCE_BIT_NV,
    m_glyphBase,
    numChars,
    0, /* stride of zero means sizeof(GLfloat) since 1 bit in mask */
    &m_horizontalAdvance[0]
);

初始讯息:

glGetPathSpacingNV(GL_ACCUM_ADJACENT_PAIRS_NV,
    (GLsizei)message.size(),
    GL_UNSIGNED_BYTE,
    message.c_str(),
    m_font->glyphBase(),
    1.0, 1.0,
    GL_TRANSLATE_X_NV,
    &m_xtranslate[1]
);

/* Total advance is accumulated spacing plus horizontal advance of
the last glyph */
m_totalAdvance = m_xtranslate[m_messageLength - 1] +
    m_font->horizontalAdvance(uint32(message[m_messageLength - 1]));

绘制消息:

glStencilStrokePathInstancedNV((GLsizei)m_messageLength,
        GL_UNSIGNED_BYTE,
        message().c_str(),
        font()->glyphBase(),
        1, ~0U,  /* Use all stencil bits */
        GL_TRANSLATE_X_NV,
        &m_xtranslate[0]
    );
glColor3f(m_colour.r, m_colour.g, m_colour.b);

glCoverStrokePathInstancedNV((GLsizei)m_messageLength,
        GL_UNSIGNED_BYTE,
        message().c_str(),
        font()->glyphBase(),
        GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV,
        GL_TRANSLATE_X_NV,
        &m_xtranslate[0]
    );

glStencilFillPathInstancedNV((GLsizei)m_messageLength,
        GL_UNSIGNED_BYTE,
        message().c_str(),
        font()->glyphBase(),
        GL_PATH_FILL_MODE_NV,
        ~0U,  /* Use all stencil bits */
        GL_TRANSLATE_X_NV,
        &m_xtranslate[0]
    );

glCoverFillPathInstancedNV((GLsizei)m_messageLength,
        GL_UNSIGNED_BYTE,
        message().c_str(),
        font()->glyphBase(),
        GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV,
        GL_TRANSLATE_X_NV,
        &m_xtranslate[0]
    );

1 个答案:

答案 0 :(得分:2)

我找到了缓慢的原因并且它与上面提到的功能没有关系。一旦删除了违规代码,这些功能就能很好地运行。完全公开 - 我使用std :: stack作为场景中使用的矩阵,并且在栈上调用push和pop是很昂贵的。因此,在回答问题时,NVidia文本路径渲染的速度非常快,模板,覆盖和覆盖填充都很便宜。