我写了一个简单的2d平铺游戏并在2台计算机上运行。在comp1上它非常慢,在comp2它的快速闪电。
Comp1的cpu有点慢,但它可以玩其他sdl游戏(甚至在emulaters中)和简单的3D游戏,足够快。
所以我只使用cpu渲染在两台计算机上运行游戏:两者都以相同的速度运行。 然后我切换到gpu渲染,第二台计算机运行速度非常快(200 + fps),但第一台计算机以相同的速度运行,大约20fps。
所以我假设hw加速不能在comp1上运行,或者cpu被我的计算阻塞了。
我记录了所有错误处理并且可以确认两台计算机都支持hw加速度和纹理大小(我知道这是因为游戏的cpu绑定版本没有翻转,因此角色总是面向相同的方式; )
那么它必须是第一台计算机上的慢CPU,对吧?但是当我检查cpu统计数据时,游戏只需要1,2%的cpu,整体负载大约是2%cpu
所以当我的游戏爬行时,cpu大部分处于空闲状态:(
游戏现在只有几千行代码,所以这里有一些我认为与这个问题有关的陈述:
主游戏循环:
while (!quit)
{
GameEngine_Tick(gameType->fps, false, 0);
if (SDL_PollEvent(&event) != 0))
{
int windowID = event.window.windowID;
if (event.window.event == SDL_WINDOWEVENT_CLOSE &&
event.window.windowID == screens[0].windowID) quit = true;
switch (event.type)
{
case SDL_KEYDOWN:
if (event.key.keysym.sym == SDLK_LEFT) { Key_Left(); }
if (event.key.keysym.sym == SDLK_RIGHT) { Key_Right();}
if (event.key.keysym.sym == SDLK_UP) { Key_Up(); }
if (event.key.keysym.sym == SDLK_DOWN) { Key_Down(); }
break; // end key_down.
} // switch event type
}
GameEngine_Render();
}
GameEngine_Tick中的帧速率限制:
void GameEngine_Tick(int fps, bool bIsRegTestStep, Uint8 TDir)
{
unsigned int frametime = 1000 / fps;
unsigned int currentTime;
const Uint8* keystates = SDL_GetKeyboardState(NULL); // do not free.
SDL_PumpEvents(); // upd keystates to get keyboard inputs.
// Get KB input - todo: later GetInputFromSelectedInputDevice (checks kb/xbox etc)
if (keystates[SDL_SCANCODE_LEFT]) GameLeft();
else if (keystates[SDL_SCANCODE_RIGHT]) GameRight();
Sprites_Tick();
// set framerate by waiting if needed.
currentTime = SDL_GetTicks();
if (currentTime - prevTime < (frametime))
{
//Sleep the remaining frame time
if (fps > 0) SDL_Delay((frametime)-(currentTime - prevTime)); /* fps-1 == MAX == no delay*/
}
prevTime = currentTime;
}
创建渲染器:
ren = nullptr;
if (bForceCPURender == false) ren = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);// | SDL_RENDERER_PRESENTVSYNC);
if (nullptr == ren)
{
if (bForceCPURender == false)
{
Log("Info: SDL_CreateRenderer with SDL_RENDERER_ACCELERATED failed. Trying default.");
}
bForceCPURender = true;
ren = SDL_CreateRenderer(window, -1, 0);
if (nullptr == ren)
{
Log("Info: SDL_CreateRenderer with default also failed.");
SDLDestroy();
return -1;
}
else Logs("Info: success using default renderer.");
}
else Logs("Info: success, using SDL_CreateRenderer with SDL_RENDERER_ACCELERATED.");
创建纹理或曲面:
spriteMapTexture = SDL_CreateTexture(ren, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET,
x_pixPerCharInStageMap * roomWidthInChars * gameRoomMatrix_w,
y_pixPerCharInStageMap * roomHeightInChars * gameRoomMatrix_h);
// If GPU cannot handle size of stage map: try to do CPU preRendering. (gpu is texture, cpu is surface).
if (NULL == spriteMapTexture || bForceCPUStageRenderAnyway == true)
{
spriteMapSurface = GameEngine_CreateRGBSurface(x_pixPerCharInStageMap * roomWidthInChars * gameRoomMatrix_w, y_pixPerCharInStageMap * roomHeightInChars * gameRoomMatrix_h);
}
答案 0 :(得分:2)
while (!quit)
{
GameEngine_Tick(gameType->fps, false, 0);
if (SDL_PollEvent(&event) != 0))
^^ wat
{
// process event
}
GameEngine_Render();
}
现在你只是每帧处理一个事件。以前SDL只能缓冲128个事件才能丢弃它们,现在我认为它们可以达到64k。因此,例如,如果你有一个高报告率的游戏鼠标(500-1000赫兹采样),你的事件队列将比常规鼠标(125赫兹)更快地备份。对于SDL可以生成的任何其他事件类型也是如此;某些系统的事件生成率与其他系统不同。
您希望在渲染帧之前处理队列中的每个事件:
while (!quit)
{
GameEngine_Tick(gameType->fps, false, 0);
// NOTE: if -> while
while( SDL_PollEvent(&event) )
{
// process event
}
GameEngine_Render();
}