如何通过类渲染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
相关产品推荐
相关产品推荐

