You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DirectX 11中使用FreeType渲染文本异常:重复绘制最后一个字符

Troubleshooting Duplicate Last Character in DirectX 11 + FreeType Text Rendering

It sounds like you're hitting a classic case where all your draw calls are reusing the final character's data instead of updating for each glyph. Let's walk through the most likely culprits and how to fix them:

1. Texture/SRV Not Updated Per Character

If you're reusing the same ID3D11Texture2D and ID3D11ShaderResourceView for all characters, you need to ensure you're properly updating the texture's data before each draw call. Common mistakes here:

  • Immutable Texture: If your texture was created with D3D11_USAGE_IMMUTABLE, you can't modify its data after creation. Switch to D3D11_USAGE_DYNAMIC (for mapping) or D3D11_USAGE_DEFAULT (for UpdateSubresource).
  • Incorrect Data Copy: FreeType's bitmap uses a pitch value (row length in bytes) that might be padded for alignment. Don't just do a single memcpy—copy row-by-row to match the texture's pitch:
    FT_Bitmap* bitmap = &face->glyph->bitmap;
    D3D11_MAPPED_SUBRESOURCE mapped;
    devCon->Map(texture, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped);
    
    // Copy each row to account for pitch differences
    for (int y = 0; y < bitmap->rows; y++) {
        memcpy(
            static_cast<BYTE*>(mapped.pData) + y * mapped.RowPitch,
            bitmap->buffer + y * bitmap->pitch,
            bitmap->width // Assumes 1 byte per pixel (grayscale from FT_RENDER_MODE_NORMAL)
        );
    }
    devCon->Unmap(texture, 0);
    
  • SRV Binding: Ensure you're re-binding the SRV to the shader before each draw call (though if you're updating the same texture, this shouldn't be necessary unless you switched it for another render task).

2. Vertex/Index Buffer Data Stale

If your vertex buffer holds position and UV data for each character, you need to update it for every glyph. Check:

  • Dynamic Buffer Usage: Static vertex buffers can't be modified mid-render. Use D3D11_USAGE_DYNAMIC with D3D11_CPU_ACCESS_WRITE so you can map and update it per character.
  • Incorrect Vertex Values: Make sure you're calculating the correct position (using face->glyph->bitmap_left and bitmap_top for baseline alignment) and UVs (for per-glyph textures, UVs are 0-1, but position should offset by the glyph's advance width each time).
  • Loop Variable Mistake: Double-check that you're using the current loop index (e.g., text[i]) instead of always referencing the last character (e.g., text[textLength-1]) when loading glyphs or setting vertex data.

3. Draw Call Parameters

  • Reusing Stale Draw Data: If you're not updating the vertex buffer content between draw calls, you'll keep rendering the same quad. For example, calling Draw(4, 0) every time without updating the buffer will repeat the last character's geometry.
  • Advance Width Calculation: After drawing each character, advance the pen position using face->glyph->advance.x >> 6 (FreeType uses 1/64 pixel units). If you're not advancing, characters will overlap, but in your case, it suggests you're advancing but using the wrong glyph data.

Debugging Steps to Pinpoint the Issue

  1. Log Glyph Data: For each character in your loop, print the character code, bitmap width/height, and advance width. Verify each iteration processes a unique character.
  2. Inspect Texture Data: After updating the texture, map it again and check a few pixels to confirm it's the current character's glyph, not the previous one.
  3. Check Vertex Buffer: Map the vertex buffer before each draw call to ensure position and UV values match the current character's expected values.
  4. Isolate Draw Calls: Temporarily modify your loop to draw only the first character, then the second, etc., to confirm each individual glyph renders correctly on its own.

内容的提问来源于stack exchange,提问作者aqwerty

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:41:22