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

raylib文本绘制数量受限?超阈值后画面消失问题排查

Raylib绘制带文本圆形时画面消失的原因分析

问题现象

  • 使用Raylib开发时,绘制带有>_<文本的黄色圆形,当数量达到390个时,画面完全变黑消失
  • 若仅绘制单个字符>,则可绘制到430个圆形才出现同样问题

附问题代码:

#include <stdio.h>
#include <raylib.h>

#define SCREEN_WIDTH  800
#define SCREEN_HEIGHT 600

#define CIRCLES_CAPACITY 1024

// why??
#define CIRCLES_MAX 390

int main(void)
{
    Vector2 circles[CIRCLES_CAPACITY] = {0};

    for (int i = 0; i < CIRCLES_MAX - 2; i++) {
        // coordinates does not matter
        circles[i] = (Vector2){SCREEN_WIDTH * 0.5f, SCREEN_HEIGHT * 0.5f};
    }
    size_t circles_len = CIRCLES_MAX - 2;

    InitWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "test");
    //SetTargetFPS(60);

    while (!WindowShouldClose()) {
        BeginDrawing();
        DrawFPS(10, 10);

        // add new circle when user left click
        if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) {
            if (circles_len + 1 < CIRCLES_CAPACITY) {
                circles[circles_len++] = (Vector2){GetMouseX(), GetMouseY()};
            }
        }
        // render circles
        for (size_t i = 0; i < circles_len; i++) {

            // draw a circle
            DrawCircleV(circles[i], 25, YELLOW);

            // >_<
            const char* smile_str = ">_<";
            Vector2 smile_size = MeasureTextEx(GetFontDefault(), smile_str, 32, 0);

            // this line causes strange behaviour i think
            // draw a text on the circle
            DrawText(smile_str, (int)(circles[i].x - smile_size.x*0.5f - 3), (int)(circles[i].y - smile_size.y*0.5f), 32, BLACK);
        }

        // print count of circles
        if (IsKeyPressed(KEY_C)) {
            printf("Count of circles: %zu\n", circles_len);
        }

        ClearBackground(BLACK);
        EndDrawing();
    }
    CloseWindow();
    return 0;
}

核心原因

1. 渲染顺序完全错误

你的代码中ClearBackground(BLACK);被放在了所有绘制操作之后,这违背了Raylib的基本渲染流程:

  • 正确流程:BeginDrawing() → 清屏(ClearBackground) → 绘制所有内容 → EndDrawing()
  • 当前错误流程会导致:绘制的内容本应被后续清屏操作覆盖,但Raylib的批处理机制会延迟提交绘制命令,当缓冲区未填满时,绘制命令会在EndDrawing()时才提交,刚好覆盖清屏结果,所以你能看到内容;当缓冲区满了之后,Raylib会自动提交缓冲区内容,随后执行清屏,最终画面只剩下黑色。

2. Raylib默认批处理缓冲区耗尽

Raylib使用顶点批处理优化2D绘制性能,所有DrawCircleV、DrawText这类操作都会把顶点数据打包到一个内部缓冲区中,缓冲区有固定容量(默认对应32768个顶点):

  • 每个带>_<的圆形:1个圆形(4个顶点,Raylib用四边形模拟圆) + 3个字符(每个字符对应1个四边形,4个顶点),总共16个顶点
  • 单个>的圆形:1个圆形(4顶点) + 1个字符(4顶点),总共8个顶点
  • 前者的顶点消耗是后者的2倍,会更快耗尽缓冲区。当缓冲区满时,新的绘制命令无法被添加,后续内容无法渲染,加上错误的清屏顺序,就会出现画面全黑的现象。

解决办法

  1. 修正渲染顺序:把ClearBackground(BLACK);移到BeginDrawing()之后、所有绘制操作之前,这是最基础的修复。
  2. 增大批处理缓冲区:在InitWindow前调用SetBatchLimit(16384);(新版本Raylib支持),或者修改Raylib编译时的MAX_BATCH_ELEMENTS宏定义,提升缓冲区容量。
  3. 优化绘制操作:
    • 预渲染表情为纹理,用DrawTexture代替DrawText,减少每个圆形的顶点消耗
    • 合并绘制逻辑,减少绘制调用次数,降低批处理压力
  4. 分批渲染:当绘制元素数量接近缓冲区上限时,手动调用EndDrawing()和BeginDrawing()刷新缓冲区,不过会增加一定性能开销。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 07:19:53