Supongamos que tengo una escena 3D dibujada glDrawArrays(...)
y quiero renderizar algo simple, como una superposición 2D. ¿Sería una mala idea usar el modo inmediato para tal cosa, en lugar de configurar un renderizador 2D con modo retenido?
Ejemplo:
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();
}
Respuestas:
Es una mala idea en la medida en que no tiene sentido. No hay nada que "configurar" que aún no haya hecho, excepto una matriz de proyección ortopédica (que deberá hacer en cualquier caso).
La portabilidad probablemente no sea un problema, aunque debería serlo. Los IHV parecen ser muy reacios a abandonar el soporte para el modo inmediato en el futuro previsible (parece "funcionar bien" incluso en los perfiles principales), por lo que aunque el modo inmediato debería haberse extinguido hace mucho tiempo, probablemente se quedará para siempre. El rendimiento es otra historia. ¿Realmente desea que algo que represente el 0.1% de la complejidad de la escena consuma el 15-20% del tiempo de la CPU? Las llamadas GL son relativamente ligeras, en comparación con, por ejemplo, DX, pero no son gratuitas, y el 15-20% de tiempo de fotograma real debido al estancamiento de la tubería? ¿Incluso puede permitirse eso con su presupuesto de tiempo? La mayoría de los juegos no pueden.
Y luego, por supuesto, las peculiaridades. Oh las peculiaridades. La aparente belleza del modo inmediato es que es (aparentemente) fácil y directo hacer algo como dibujar un par de quads rápidamente. En realidad, el modo inmediato puede ser una molestia en la parte trasera, está lleno de trampas no obvias.
Por otro lado, es igual de fácil (¡y más sencillo si me preguntas!) Solo escribir una pequeña función de 5 LOC
DrawQuad
que cuando se llama agrega coordenadas e índices de vértice a un búfer de memoria e incrementa un contador. Con lo cual, sorprende, puedes dibujarglDrawArrays/Elements
y reutilizar (¡la copia de la GPU, no solo la copia del usuario!) El siguiente marco tal cual, siempre que no se cambie nada.El modo inmediato debe, no hay otra manera, asignar un búfer y hacer una transferencia PCIe cada vez. O, algo equivalente en latencia (GPU leyendo la memoria principal a través del bus, lo que sea). El controlador no puede saber (o suponer) que los datos permanecieron exactamente igual que el marco anterior.
Llevar datos a la GPU es una operación de alta velocidad, pero también de alta latencia . No sólo es el traslado en autobús de por sí complicado protocolo de latencia a, alta (varias capas de protocolo, en paquetes, reconocimientos, etc.), sino que además no todas las GPU son incluso capaces de transferir y dibujar al mismo tiempo, o si ellos pueden hacerlo , es posible que no siempre puedan cambiar o iniciar nuevas operaciones libremente mientras hacen algo diferente. Lea como: No transferirás en vano .
fuente
intel
controlador), pero también chips NVidia y AMD cuando se utilizan controladores de código abierto (nouveau
yamdgpu
respectivamente). Del mismo modo, en MacOS tampoco tiene el perfil de compatibilidad con OpenGL> 2.1.glDrawArrays
. Entonces, hay todo lo que se necesita para hacer otra llamada aglDrawElements
(o Array, lo que sea) para dibujar todos los quads para la GUI (después de escribir los vértices en un búfer). Se cargan las funciones, tiene un marco para asignar buffers, etc. Nada especial que hacer para agrupar la GUI, realmente. Simplemente vincule (o no, si le quedan suficientes UT para dejarla unida) la textura de la GUI, configure la matriz orto y realice una llamada de sorteo adicional. ¿Cómo quieres lotes mejor?Personalmente solo lo veo como malo por dos razones:
Pero, si está funcionando, y el rendimiento no va a ser un problema, y si no es un problema para usted usar funciones OpenGL obsoletas en su programa, entonces creo que podría hacerlo. Será más lento tener TONELADAS y TONELADAS de GUI, pero si no son tantas, de nuevo, adelante.
Sin embargo, comprenda esto. Que al final del día, OpenGL está haciendo lo mismo; dibujando a la pantalla. El modo inmediato es mucho más lento si se procesan muchas cosas. Por lo tanto, debe elegir qué es lo más útil para la tarea que tiene en mente. ¡Espero que esto te ayude!
fuente
Otra desventaja es que hace que su código sea menos portátil. Ciertas variantes de OpenGL no admiten el modo inmediato en absoluto, por ejemplo, OpenGL ES. (y a medida que los dispositivos basados en Android de mayor calibre, como las tabletas, ganan más tracción, podría ser importante)
fuente
Usar el modo inmediato es completamente innecesario para el trabajo relacionado con la interfaz gráfica de usuario.
Para crear un elemento gui simple, digamos, un botón:
De esta manera, puede escribir un sombreador de paso simple que ignore las consideraciones de iluminación, y simplemente escale el elemento gui a una escala de píxeles, o algún porcentaje de la ventana, y luego haga un algoritmo de pintores para renderizar.
De esta manera, puede hacer un sistema de interfaz de usuario completo con todos los beneficios de rendimiento del modo retenido.
fuente