Raylib双摆路径绘制仅显示1/4窗口问题求助
Raylib双摆模拟器RenderTexture2D轨迹仅显示1/4问题排查与解决
核心问题分析
你遇到的轨迹仅显示窗口1/4的问题,大概率是RenderTexture尺寸与窗口尺寸不匹配或坐标转换逻辑错误导致的,和rlTranslatef的使用直接相关。Raylib在创建RenderTexture时,会自动将纹理尺寸调整为最接近的2的幂次(比如窗口宽高是800x600,RenderTexture可能会被创建为1024x1024),如果你的坐标转换仍基于窗口尺寸,就会出现轨迹只绘制在RenderTexture的1/4区域,最终显示到窗口时也就只占1/4。
分步排查与修复
1. 确认RenderTexture实际尺寸
创建RenderTexture后,先打印其实际宽高,对比窗口尺寸:
RenderTexture2D renderTexture = LoadRenderTexture(GetScreenWidth(), GetScreenHeight()); printf("RT Width: %d, RT Height: %d\n", renderTexture.texture.width, renderTexture.texture.height); printf("Screen Width: %d, Screen Height: %d\n", GetScreenWidth(), GetScreenHeight());
如果两者不一致,说明Raylib自动调整了纹理尺寸,后续所有坐标计算都要基于RenderTexture的实际尺寸,而非窗口尺寸。
2. 修正rlTranslatef的基准坐标
在RenderTexture模式下绘制轨迹时,rlTranslatef的平移基准应该是RenderTexture的中心,而非窗口中心。比如之前你可能写的是:
// 错误:用窗口中心做平移基准 rlTranslatef(GetScreenWidth()/2, GetScreenHeight()/2);
要改成:
// 正确:用RenderTexture实际中心做平移基准 int rtWidth = renderTexture.texture.width; int rtHeight = renderTexture.texture.height; rlTranslatef(rtWidth/2.0f, rtHeight/2.0f);
同时记得用rlPushMatrix()和rlPopMatrix()包裹坐标变换,避免影响其他绘制逻辑。
3. 正确绘制RenderTexture到窗口
Raylib的RenderTexture是Y轴翻转的,绘制到窗口时必须处理翻转,同时确保纹理完整覆盖整个窗口:
DrawTexturePro(renderTexture.texture, // 源矩形:取整个RenderTexture,Y轴翻转 (Rectangle){0, 0, (float)rtWidth, -(float)rtHeight}, // 目标矩形:覆盖整个窗口 (Rectangle){0, 0, (float)GetScreenWidth(), (float)GetScreenHeight()}, (Vector2){0, 0}, 0.0f, WHITE);
如果直接用DrawTexture(),会因为Y轴翻转导致图像倒置,同时尺寸不匹配时会出现拉伸或裁剪。
完整修正示例
假设你的main.cpp中RenderTexture相关代码可以修改为:
#include "raylib.h" #include "pendulum.h" int main() { const int screenWidth = 800; const int screenHeight = 600; InitWindow(screenWidth, screenHeight, "Double Pendulum"); SetTargetFPS(60); // 创建RenderTexture,记录实际尺寸 RenderTexture2D renderTexture = LoadRenderTexture(screenWidth, screenHeight); int rtWidth = renderTexture.texture.width; int rtHeight = renderTexture.texture.height; Pendulum pendulum; // 你的双摆实例 Vector2 prevPos = pendulum.GetEndPos(); while (!WindowShouldClose()) { // 更新双摆 pendulum.Update(); Vector2 currentPos = pendulum.GetEndPos(); // 绘制轨迹到RenderTexture BeginTextureMode(renderTexture); rlPushMatrix(); rlTranslatef(rtWidth/2.0f, rtHeight/2.0f); // 修正平移基准 DrawLine(prevPos.x, prevPos.y, currentPos.x, currentPos.y, BLACK); rlPopMatrix(); EndTextureMode(); prevPos = currentPos; // 绘制到窗口 BeginDrawing(); ClearBackground(WHITE); // 正确绘制RenderTexture DrawTexturePro(renderTexture.texture, (Rectangle){0, 0, (float)rtWidth, -(float)rtHeight}, (Rectangle){0, 0, (float)screenWidth, (float)screenHeight}, (Vector2){0, 0}, 0.0f, WHITE); // 绘制当前双摆(可选,避免被轨迹覆盖) pendulum.Draw(); EndDrawing(); } UnloadRenderTexture(renderTexture); CloseWindow(); return 0; }
额外注意事项
- 如果你的双摆绘制逻辑中也用到了坐标变换,要确保所有坐标都基于RenderTexture的实际尺寸,或者统一用
Camera2D来管理坐标空间(比直接用rlTranslatef更不易出错)。 - 若窗口尺寸是2的幂次(比如512x512),RenderTexture尺寸会和窗口一致,此时之前的错误可能不会出现,但仍建议按实际尺寸处理以保证兼容性。
内容的提问来源于stack exchange,提问作者Cr3
相关产品推荐
相关产品推荐

