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

如何通过类渲染SDL_Texture?类封装后无文字显示排查

解决SDL Text类无法显示文字的问题

我帮你排查一下代码里的几个关键问题,这些大概率就是文字不显示的核心原因:

1. 缺失错误检查,无法定位资源加载失败

你的setText函数完全没对TTF和SDL的API返回值做校验——如果字体路径写错、字体文件损坏、渲染Surface失败,都会导致最终的textTexture变成nullptr,但调试时不会主动抛出错误,自然看不到文字。

修改setText函数,补上错误判断:

SDL_Texture* Text::setText(const std::string & fontPath, int fontSize, const std::string & message, const SDL_Color & color, const std::shared_ptr<SDL_Renderer>& renderer) {
    TTF_Font* font = TTF_OpenFont(fontPath.c_str(), fontSize);
    if (!font) {
        std::cerr << "字体加载失败: " << TTF_GetError() << std::endl;
        return nullptr;
    }

    auto textSurface = TTF_RenderText_Solid(font, message.c_str() , color);
    if (!textSurface) {
        std::cerr << "文字Surface渲染失败: " << TTF_GetError() << std::endl;
        TTF_CloseFont(font);
        return nullptr;
    }

    auto tempTexture = SDL_CreateTextureFromSurface(renderer.get(), textSurface);
    if (!tempTexture) {
        std::cerr << "Surface转Texture失败: " << SDL_GetError() << std::endl;
        SDL_FreeSurface(textSurface);
        TTF_CloseFont(font);
        return nullptr;
    }

    SDL_FreeSurface(textSurface);
    TTF_CloseFont(font);
    return tempTexture;
}

同时在init函数里也要检查setText的返回值,避免后续操作空指针:

void Text::init(const std::string & fontPath, int fontSize, const std::string & message, const SDL_Color & color, const std::shared_ptr<SDL_Renderer>& renderer) {
    textTexture = setText(fontPath, fontSize, message, color, renderer);
    if (!textTexture) {
        std::cerr << "文字Texture初始化失败!" << std::endl;
        return;
    }
    SDL_QueryTexture(textTexture, nullptr, nullptr, &textRect.w, &textRect.h);
}

2. 指针传递的冗余写法可能引发问题

你代码里用&*textTexture和&*renderer的写法完全没必要,还容易混淆指针层级:

  • textTexture本身就是SDL_Texture*,直接传给SDL_QueryTexture和SDL_RenderCopy即可
  • renderer是shared_ptr<SDL_Renderer>,用renderer.get()获取原始指针更清晰直观

修改init和display函数:

// init里的QueryTexture调用
SDL_QueryTexture(textTexture, nullptr, nullptr, &textRect.w, &textRect.h);

// display函数
void Text::display(const std::shared_ptr<SDL_Renderer>& renderer) {
    SDL_RenderCopy(renderer.get(), textTexture, nullptr, &textRect);
}

3. 确认setPosition被正确调用,且位置在屏幕可见范围内

如果你的代码没调用过setPosition,textRect.x和textRect.y默认是0(全局变量默认初始化),这时候文字应该在左上角显示;但如果调用了setPosition,要检查计算后的textRect.x和textRect.y是否在屏幕范围内——比如如果position.x小于textRect.w/2,会导致textRect.x为负数,文字会被移出屏幕左侧。

另外,textRect.x和textRect.y是int类型,你用float计算后直接赋值会被截断,虽然一般不影响,但如果需要更精确的位置,可以显式转成int:

void Text::setPosition(const Vector2<float>& position) {
    textRect.x = static_cast<int>(position.x - textRect.w / 2.f);
    textRect.y = static_cast<int>(position.y - textRect.h / 2.f);
}

4. 确认主渲染流程的正确性

最后,要确保主循环里的渲染顺序完全正确:

  • 先调用SDL_RenderClear(renderer.get())清空渲染器
  • 调用text.display(renderer)绘制文字
  • 最后调用SDL_RenderPresent(renderer.get())提交渲染结果

如果跳过了SDL_RenderPresent,或者文字被其他后绘制的元素覆盖,也会出现看不到文字的情况。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:43:57