Soluços em OpenGL ES. O que é a aplicação correcta?
-
08-07-2019 - |
Pergunta
Eu estou usando OpenGL ES para fazer um jogo no iPhone. Infelizmente, vejo pequenos (e irregulares) soluços.
Eu uso um temporizador com um sono, chamando a função de sorteio a cada 60 de um segundo, a fim de garantee uma taxa de quadros sólida. Eu tentei mudar o momento em meus desperta temporizador de seu sono, dando a função mais tempo sorteio para executar. Os soluços que recebem menos uma vez a função empate tem sido dado mais tempo. Com 8 milissegundos, as animações são quase fluido. Meus resultados são:
- Aparentemente, dando a GPU mais tempo para executar o desenho real, resulta em um (quase) perfeito animação fluida.
- Desenho no final exata do meu quadro resulta em gaguejar, soluços e quais não.
Agora que eu sei que, Eu não tenho certeza de como proceder . Eu tenho duas idéias contraditórias sobre a causa deste comportamento:
- Em primeiro lugar, pode ser que os comandos OpenGL interferir com o desenho do quadro anterior? Tanto quanto eu entendo que isso não pode ser o caso, já que os comandos são armazenados e só será executada quando o comando sorteio é dado.
- Em segundo lugar, poderia o tempo flutuação dos comandos sorteio fazer com que o temporizador para pular um carrapato?
Então, qual explicação é mais provável? Ou não é nem? É claro que eu poderia apenas tentar colocar a função de empate em um segmento separado e ver se isso resolve o meu problema. Mas eu espero compreender mais de OpenGL.
Esta é a função que está sendo chamado e explica o que eu estou tomando sobre: ??
- (void) drawView
{
// measure time with mach_absolute_time
// gameEngine update
// OpenGL commands (translate, rotate, drawArrays etc.)
// end measure time with mach_absolute_time
// usleep(animationInterval - duration - constant)
// constant is the time to start executing
// draw
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER_OES];
}
Solução
Você pode querer ler este artigo sobre loops jogo , o que explica muita coisa. Em geral, a melhor solução consiste em chamar a rotina sorteio num ciclo infinito dentro de um segmento separado (ver esta questão ) e atualizar o modelo de jogo subjacente de acordo com a quantidade de tempo decorrido desde a última atualização. Isto lhe dará suave movimento.
Edit: Como para a fonte dos “soluços”, eles provavelmente não têm nada a ver com OpenGL. Aos 60 fps estamos a falar 1/60 seg ˜ 17 ms por quadro. Este é um calendário apertado que é fácil de perder, porque existem outros processos em execução no dispositivo. Safari ou Mail.app acordar no fundo, o dispositivo pensa por um tempo e agora o seu quadro leva 30 ms ou mesmo muito mais. Isto é muito fácil de detectar se o seu modelo de espera framerate perfeitamente estável. A solução é atualizar o modelo de acordo com o tempo real decorrido, como escrevi acima. O artigo ligado explica tudo isso completamente.