2017-03-13 61 views
0

我使用NV路徑已經呈現由馬克·基爾加德閱讀Getting Started with NV Path RenderingNV路徑渲染字體最優實現

我的實現是基於在NVidia Graphics Samples的Tiger3DES項目render_font例子。

這個實現看起來比普通的基於紋理的字體解決方案慢,所以我想知道它是否有缺陷? NVidia state NV路徑渲染是faster than alternatives,但是我的性能極限比我預期的要快得多。

我有一個1000'消息'的場景。我的FPS在Quadro K4200上非常差。如果我將文本合併爲一條消息,則不存在性能問題,但單獨格式化消息是不可能的。如果我將郵件數量減少到100個,我可以獲得體面的幀率(解鎖200+)。

電話模板,covertroke和coverfill昂貴嗎?

這裏有一個代碼片段...

初始化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

我找到了緩慢的原因,它與上述引用的功能無關。一旦違規代碼被刪除,這些功能就可以很好地執行。完全披露 - 我對場景中使用的矩陣使用std :: stack,並且在棧上調用push和pop是很昂貴的。因此,在回答NVidia文本渲染路徑的問題時,它的渲染速度非常快,而且模板,覆蓋和覆蓋都很便宜。