Pergunta

Estou trabalhando em um aplicativo que precisa desenhar com OpengGL a uma taxa de atualização pelo menos igual à taxa de atualização do monitor.E preciso realizar o desenho em um thread separado para que o desenho nunca seja bloqueado por ações intensas da interface do usuário.

Na verdade estou usando um NSOpenGLView em combinação com CVDisplayLink e consigo atingir 60-80FPS sem nenhum problema.

Como também preciso exibir alguns controles de cacau no topo desta visualização, tentei subclassificar NSOpenGLView e torná-lo apoiado em camadas, seguindo LayerBackedOpenGLView Exemplo da maçã.

O resultado não é satisfatório e recebo muitos artefatos.

Portanto, resolvi o problema usando um separado NSWindow para hospedar os controles cacau e adicionar esta janela como uma janela filha da janela principal contendo o NSOpenGLView.Funciona bem e consigo obter o mesmo FPS da implementação inicial.

Como considero esta solução um hack sujo, estou procurando uma maneira alternativa e mais limpa de conseguir o que preciso.

Há poucos dias me deparei NSOpenGLLayer e pensei que poderia ser usado como uma solução viável para o meu problema.

Então, finalmente, depois de todo esse preâmbulo, aqui vem a minha pergunta:é possível desenhar para um NSOpenGLLayer de um thread separado usando CVDisplayLink ligar de volta?.

Até agora tentei implementar isso, mas não consigo extrair do CVDisplayLink ligar de volta.Eu posso apenas -setNeedsDisplay:TRUE no NSOpenGLLayer de CVDisplayLink retorno de chamada e, em seguida, execute o desenho em -drawInOpenGLContext:pixelFormat:forLayerTime:displayTime: quando é chamado automaticamente pelo cacau.Mas suponho que assim estou desenhando a partir do fio principal, não é?

Depois de pesquisar isso no Google, eu até encontrei esse postagem em que o usuário afirma que sob Leão o sorteio só pode ocorrer dentro -drawInOpenGLContext:pixelFormat:forLayerTime:displayTime:.

Estou no Snow Leopard no momento, mas o aplicativo deve funcionar perfeitamente mesmo no Lion.

Estou esquecendo de algo?

Foi útil?

Solução

Sim, é possível, embora não seja recomendado.Chamar display na camada de dentro do seu CVDisplayLink.Isto causará canDrawInContext:... a ser chamado e se retornar SIM, drawInContext:... será chamado e tudo isso em qualquer thread chamado display.Para tornar a imagem renderizada visível na tela, você deve chamar [CATransaction flush].Este método foi sugerido na lista de discussão da Apple, embora não seja completamente isento de problemas (o método de exibição de outra visualização também pode ser chamado em seu thread de segundo plano e nem todas as visualizações suportam a renderização de um thread de segundo plano).

A maneira recomendada é tornar a camada assíncrona e renderizar o contexto OpenGL no thread principal.Se você não conseguir obter uma boa taxa de quadros dessa maneira, já que seu thread principal está ocupado em outro lugar, é recomendável mover todo o resto (praticamente toda a lógica do seu aplicativo) para outros threads (por exemplo,usando Grand Central Dispatch) e manter apenas a entrada do usuário e o código de desenho no thread principal.Se sua janela for muito grande, você ainda pode não conseguir nada melhor do que 30 FPS (um quadro a cada duas atualizações de tela), mas isso vem do fato de que a composição do CALayer parece um processo bastante caro e foi otimizado para mais ou menos camadas estáticas (por ex.camadas contendo uma imagem) e não para camadas que se atualizam em 60 FPS.

Por exemplo.se você estiver escrevendo um jogo 3D, é aconselhável não misturar CALayers com conteúdo OpenGL.Se você precisar de elementos Cocoa UI, mantenha-os separados do conteúdo OpenGL (por exemplo,divida a janela horizontalmente em uma parte que exibe apenas OpenGL e uma parte que exibe apenas controles) ou desenhe você mesmo todos os controles (o que é bastante comum em jogos).

Por último, mas não menos importante, a abordagem de duas janelas não é tão exótica quanto você imagina, é assim que o VLC (o reprodutor de vídeo) desenha seus controles sobre a imagem do vídeo (que também é renderizada pelo OpenGL no Mac).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top