我写了一个非常基本的测试,看看SDL是否能在我的系统上正常工作。我认为它会非常流畅地运行,因为绘图代码非常简单,但它根本不光滑,并且根据我指定的帧速率以不同的方式看起来很糟糕。
我希望我做了些傻话。我担心代码很好,但我的Windows 7机器不能很好地与SDL一起使用。我已经过度修改和google了,但我无法弄清楚发生了什么。更有知识的人能看到问题吗?代码如下:
#include "SDL.h"
static int g_width = 1024;
static int g_height = 768;
static int g_frameWaitInterval = 20; // 50fps
static int g_lastFrameTime = 0;
static int g_ballx = 200;
static int g_bally = 200;
static int g_ballSize = 20;
static int g_ballxVelocity = 5;
void Step();
void Draw();
// Main application loop
void Run(){
while(true){
if(SDL_GetTicks() - g_lastFrameTime >= g_frameWaitInterval){
g_lastFrameTime = SDL_GetTicks();
Step();
Draw();
}
}
}
// Bounces the ball back and forth across the screen
void Step(){
g_ballx += g_ballxVelocity;
if(g_ballx+g_ballSize>=g_width){
g_ballx = g_width - (g_ballSize+1);
g_ballxVelocity = -g_ballxVelocity;
}
if(g_ballx<0){
g_ballx = 0;
g_ballxVelocity = -g_ballxVelocity;
}
}
// Draws the ball as a square
void Draw(){
SDL_Surface* p_screen = SDL_GetVideoSurface();
SDL_FillRect(p_screen, NULL, 0xff000000);
SDL_Rect rect;
rect.x = g_ballx; rect.y = g_bally;
rect.w = rect.h = g_ballSize;
SDL_FillRect(SDL_GetVideoSurface(), &rect, 0xffff00ff);
SDL_UpdateRect(p_screen,0,0,0,0);
}
// Initialises SDL, etc (checking removed for brevity)
int main(int argc, char *argv[]){
SDL_Init(SDL_INIT_VIDEO);
SDL_SetVideoMode(g_width, g_height, 0, SDL_SWSURFACE);
Run();
return 0;
}
编辑:我在10秒的时间内进行了帧率测试,获得了49.76,这非常接近我所期待的50fps。我还打印出大量单独的帧时序,发现每帧都需要20毫秒,正如预期的那样。这告诉我,问题在于配置的某些方面,而不是我的渲染循环。
答案 0 :(得分:1)
您可能只需要设置双缓冲。没有它,你可以获得一点点闪烁,即使在简单的程序上也是如此。
答案 1 :(得分:1)
我认为问题在于您正在使用繁忙的循环,而Windows可能会限制您的流程,或类似的东西。
此外,如果您希望动画顺利运行,则应将g_frameWaitInterval
添加到g_lastFrameTime,而不是将其更新为返回SDL_GetTicks()。否则,您可能会积累差异并使动画不均匀。
尝试以下方法:
void Run(){
while(true){
Uint32 now = SDL_GetTicks();
Uint32 dif = now - g_lastFrameTime;
if (now >= g_lastFrameTime + g_frameWaitInterval){
g_lastFrameTime += g_frameWaitInterval;
Step();
Draw();
if (now >= g_lastFrameTime + g_frameWaitInterval){
//You are losing time! Correct it!
g_lastFrameTime = now;
}
}
else {
//Play nice with CPU time
SDL_Delay(g_frameWaitInterval - dif);
}
}
}
答案 2 :(得分:1)
要获得完美平滑的图像序列,您需要设置双缓冲(在此处绘制一个图像,而另一个在屏幕上显示,并在绘制过程完成后交换它们)和vsync,其中您将帧速率限制为显示器的刷新率,从而避免撕裂效果。在现代系统中,这两种效应是我能想到的唯一可能导致波动,动画效果的因素。