나는 아직 다루지 않은 것들 중 하나이기 때문에 OpenGL 렌더링을 가르치기 위해 약간의 게임을 작성하고 있습니다. 이전에 SDL을 사용했는데 여전히 성능이 좋았지 만 지금과 똑같은 기능을 수행하지 못했습니다.이 기능을 어떻게 최적화 할 수 있습니까? (거의 모든 처리 능력을 사용합니다.)
기본적으로 내 게임에는 아직 많은 기본적인 움직임과 배경 그림이 없습니다. OpenGL로 전환했을 때, 마치 의 방식으로이 너무 빠릅니다. 초당 프레임 수는 2000을 초과하며이 기능은 대부분의 처리 능력을 사용합니다.
재미있는 점은 100 % CPU를 사용했지만 원활하게 실행되는 SDL 버전의 프로그램은 OpenGL 버전이 약 40-60 % CPU만을 사용하지만 내 그래픽 카드에 과세하는 것으로 보입니다. 바탕 화면이 응답하지 않게됩니다. 나쁜.
너무 복잡하지는 않지만 플레이어 그래픽 자체가 가운데에 고정되어있는 동안 플레이어의 X 및 Y 좌표에 따라 1024x1024 배경 타일을 렌더링하여 움직임이있는 느낌을줍니다. 더 큰 화면을위한 작은 타일이기 때문에 여러 번 타일을 엮어서 전체 배경을 만들어야합니다. 아래의 코드에서 두 개의 for 루프는 12 번 반복되어 반복되므로 초당 2000 회 호출 할 때 이것이 효과적이지 않은 이유를 알 수 있습니다.
그래서 지점에 도착, 이것은 악을 행하는 것입니다 : 내가 인위적으로 게임 루프에서 호출 SDL_Delay(1)
하여 속도를 제한하는 경우
void render_background(game_t *game)
{
int bgw;
int bgh;
int x, y;
glBindTexture(GL_TEXTURE_2D, game->art_background);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &bgw);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &bgh);
glBegin(GL_QUADS);
/*
* Start one background tile too early and end one too late
* so the player can not outrun the background
*/
for (x = -bgw; x < root->w + bgw; x += bgw)
{
for (y = -bgh; y < root->h + bgh; y += bgh)
{
/* Offsets */
int ox = x + (int)game->player->x % bgw;
int oy = y + (int)game->player->y % bgh;
/* Top Left */
glTexCoord2f(0, 0);
glVertex3f(ox, oy, 0);
/* Top Right */
glTexCoord2f(1, 0);
glVertex3f(ox + bgw, oy, 0);
/* Bottom Right */
glTexCoord2f(1, 1);
glVertex3f(ox + bgw, oy + bgh, 0);
/* Bottom Left */
glTexCoord2f(0, 1);
glVertex3f(ox, oy + bgh, 0);
}
}
glEnd();
}
, 나는 660 ~에 ± 20 아래로 FPS를 잘라, 나는 "과다한 성과"를 얻지 못한다. 그러나 이것이 그것이 올바른 방법인지 의심 스럽습니다. 완료를 위해서
이 내 일반 렌더링 및 게임 루프 기능은 다음과 같습니다void game_main()
{
long current_ticks = 0;
long elapsed_ticks;
long last_ticks = SDL_GetTicks();
game_t game;
object_t player;
if (init_game(&game) != 0)
return;
init_player(&player);
game.player = &player;
/* game_init() */
while (!game.quit)
{
/* Update number of ticks since last loop */
current_ticks = SDL_GetTicks();
elapsed_ticks = current_ticks - last_ticks;
last_ticks = current_ticks;
game_handle_inputs(elapsed_ticks, &game);
game_update(elapsed_ticks, &game);
game_render(elapsed_ticks, &game);
/* Lagging stops if I enable this */
/* SDL_Delay(1); */
}
cleanup_game(&game);
return;
}
void game_render(long elapsed_ticks, game_t *game)
{
game->tick_counter += elapsed_ticks;
if (game->tick_counter >= 1000)
{
game->fps = game->frame_counter;
game->tick_counter = 0;
game->frame_counter = 0;
printf("FPS: %d\n", game->fps);
}
render_background(game);
render_objects(game);
SDL_GL_SwapBuffers();
game->frame_counter++;
return;
}
gprof의 프로파일에 따르면, 내가 SDL_Delay()
과 실행을 제한하는 경우에도, 여전히 시간의 약 50 %를 지출 내 배경 렌더링.
프레임 속도를 제한하는 타이머를 만드십시오 ... – Jason
뭔가를 놓치지 않는 한이 전체 기능을 [glCallList]로 작성할 수 없습니다 (http://www.opengl.org/sdk/docs/). man/xhtml/glCallList.xml) 그런 다음 [glTranslatef] (http://www.opengl.org/sdk/docs/man/xhtml/glTransl.xml)에 대한 호출을 사용하여 그려지는 위치를 제어 할 수 있습니까? – Flexo
유휴 처리는 나쁜 것입니다. 더 나은 성능을 가지면 실제로 새로운 문제가 발생합니다. 유휴 처리 대신 멀티미디어 타이머를 사용하십시오. –