Suponha que eu tenha uma cena 3D sendo desenhada glDrawArrays(...)
e que queira tornar algo simples, como uma sobreposição 2D. Seria uma má idéia usar o modo imediato para isso, em vez de configurar um renderizador 2D com o modo retido?
Exemplo:
void Draw()
{
// Draw the 3D scene:
// *does stuff*
glDrawArrays(...);
// *some other stuff*
// Setup a quad with immediate mode (for something like a vignette overlay)
glBegin(GL_QUADS);
glTexCoord2f(...); glVertex2f(...);
glEnd();
}
Respostas:
É uma péssima idéia, na medida em que não faz sentido. Não há nada para "configurar" que você ainda não tenha feito, exceto uma matriz de projeção orto (que você terá que fazer em qualquer caso).
A portabilidade provavelmente não é um problema, embora deva ser. IHVs parecem ser muito relutantes em perder o suporte para modo imediato para o futuro previsível (parece "bom trabalho" mesmo em perfis de núcleo), portanto, embora modo imediato deveria ter morrido há muito tempo, ele provavelmente vai ficar para sempre. O desempenho é outra história. Deseja realmente que algo que represente 0,1% da complexidade da cena consuma 15 a 20% do tempo da CPU - as chamadas GL são relativamente leves, em comparação com, por exemplo, o DX, mas não são gratuitas - e 15 a 20% tempo de quadro real devido ao bloqueio do pipeline? Você pode pagar isso com seu orçamento de tempo? A maioria dos jogos não pode.
E então, claro, as peculiaridades. Oh, as peculiaridades. A beleza aparente do modo imediato é que é (aparentemente) fácil e direto fazer algo como desenhar dois quadríceps rapidamente. Na realidade, o modo imediato pode ser uma dor na parte traseira, é tão cheio de armadilhas não óbvias.
Por outro lado, é tão fácil (e mais direto, se você me perguntar!) Escrever apenas uma pequena função 5-LOC
DrawQuad
que, quando chamada, adiciona coordenadas e índices de vértices a um buffer de memória e incrementa um contador. Com surpresa, você pode desenharglDrawArrays/Elements
e reutilizar (a cópia da GPU, não apenas a cópia da terra do usuário!) O próximo quadro, como está, desde que nada seja alterado.O modo imediato deve, de nenhuma outra maneira, alocar um buffer e fazer uma transferência PCIe sempre. Ou, algo equivalente em latência (GPU lendo a memória principal no barramento, qualquer que seja). O motorista não pode saber (ou assumir) que os dados permaneceram exatamente os mesmos do quadro anterior.
A obtenção de dados na GPU é uma operação de alta velocidade, mas também de alta latência . Não é só a transferência de ônibus per se um complicado protocolo, alta latência (várias camadas de protocolo, empacotamento, agradecimentos, etc.), mas também nem todas as GPUs são mesmo capazes de transferir e desenhar ao mesmo tempo, ou se eles podem fazê-lo , eles podem não ser capazes de alternar o tempo todo ou iniciar novas operações livremente enquanto fazem algo diferente. Leia como: Você não deve transferir em vão .
fonte
intel
driver), mas também chips NVidia e AMD ao usar drivers de código aberto (nouveau
eamdgpu
respectivamente). Da mesma forma, no MacOS você também não possui um Perfil de Compatibilidade com o OpenGL> 2.1.glDrawArrays
. Portanto, há tudo o que é necessário para fazer outra chamadaglDrawElements
(ou matriz, o que for) para desenhar todos os quadríceps da GUI (depois de gravar os vértices em um buffer). As funções são carregadas, você tem uma estrutura para alocar buffers, etc. Nada de especial para fazer em lotes da GUI, realmente. Apenas vincule (ou não, se você tiver TUs suficientes para deixá-lo vinculado) a textura da GUI, defina a matriz orto e faça uma chamada de desenho adicional. Como você deseja melhorar o lote?Pessoalmente, só vejo isso como ruim por duas razões:
Mas, se estiver funcionando, e o desempenho não for um problema, e se não for um problema para você usar funções obsoletas do OpenGL em seu programa, acredito que você poderia fazê-lo. Será mais lento o número de Toneladas e Toneladas de GUIs, mas se não forem tantas, novamente, faça isso.
Entenda isso, no entanto. Que, no final das contas, o OpenGL está fazendo a mesma coisa; desenho para a tela. O modo imediato é muito mais lento se você tiver muitas coisas sendo processadas. Portanto, você deve escolher o que é mais útil para a tarefa que tem em mente. Espero que isto te ajude!
fonte
Outra desvantagem é que isso torna seu código menos portátil. Certas variantes do OpenGL não suportam o modo imediato, por exemplo, o OpenGL ES. (e, à medida que dispositivos baseados em Android de maior calibre, como tablets, ganham mais força, isso pode se tornar importante)
fonte
Usar o modo imediato é completamente desnecessário para trabalhos relacionados à GUI.
Para criar um item simples da GUI, digamos, um botão:
Dessa forma, você pode simplesmente escrever um sombreador de passagem simples que ignore as considerações de iluminação e apenas escalar o item da GUI para uma escala de pixels ou alguma porcentagem da janela e, em seguida, executar um algoritmo de pintores para renderização.
Dessa forma, você pode fazer um sistema de interface do usuário completo com todos os benefícios de desempenho do modo retido.
fonte