OpenGL: VBO o glBegin () + glEnd ()?

16

Recientemente recibí este enlace a un sitio de tutoría de alguien a quien le di el Redbook OGL original. El tercer encabezado hacia abajo dice claramente que debe olvidar glBegin () y glEnd () como el método típico de renderizado. Aprendí a través del método del Redbook, pero veo algún beneficio en los VBO. ¿Es este realmente el camino a seguir, y si es así, hay una manera de convertir fácilmente el código de renderizado y los sombreadores posteriores en VBO y tipos de datos posteriores?

S. Fitzgerald
fuente

Respuestas:

27

Con los VBO de OpenGL modernos, las cosas de funciones fijas (incluyendo glBegin / glEnd y las cosas intermedias) han quedado en desuso desde 3.0 y se han eliminado desde 3.1.

Con OpenGL Core Profile, OpenGL ES 2.0+ y WebGL, ni siquiera tiene acceso a las cosas antiguas.

Algunas personas piensan que aprender las cosas viejas primero es mejor porque es un poco más fácil, pero esas cosas que aprendes son en su mayoría inútiles y luego cosas que tienes que desaprender.

Sin embargo, no se trata solo de VBO, debe usar sombreadores para todo y hacer transformaciones matriciales usted mismo (o usar GLM).

La única razón para usar las cosas antiguas sería si quisieras apuntar a OpenGL antes de 2.0. que se lanzó nuevamente en 2003. Hay algunos conjuntos de chips de netbook integrados realmente malos que son 1.5, pero incluso 1.5 deberían admitir VBO, no sombreadores. O OpenGL ES 1.x que se basa en la canalización de funciones fijas (por ejemplo, se usa en iPhones más antiguos). O OpenGL SC (para sistemas críticos de seguridad).

Las siguientes funciones de uso común están en desuso:

  • glBegin
  • deslumbramiento
  • glVertex *
  • glNormal *
  • glTextCoord *
  • glTranslate *
  • glRotate *
  • glScale *
  • glLoadIdenity
  • glModelViewMatrix

Los tutoriales de opengl-tutorial.org tienen lo que creo que es la mejor manera de aprender OpenGL. Confían en algunas de las cosas de compatibilidad heredadas, pero en realidad no te lo enseñan. Por ejemplo, se supone que no debe renderizar nada sin un sombreador, pero funciona. Y debe manejar las operaciones de matrices (rotar, traducir, etc.) usted mismo, pero de forma predeterminada obtendrá una vista gráfica 2D plana básica.

Además de evitar las cosas obsoletas, hay un montón de funciones que hacen que la codificación de OpenGL sea mucho más agradable, pero con muchas de ellas tienes que decidir si estás de acuerdo con requerir versiones 3.x + más nuevas de OpenGL y hardware compatible.

Hay más información en una publicación que hice aquí .

Si, por algún motivo, necesita admitir OpenGL más antiguos, puede usar VBO cuando sea posible y, cuando no lo sea, proporcionar un respaldo que use glBegin / glEnd y recorra los datos de vértices.

Por otro lado, no hay una forma 'fácil' real de convertir el antiguo código de renderizado. Quizás podría implementar su propia versión de las funciones que agregan los vértices a una matriz / vector que luego lo descarga en un VBO y lo dibuja cuando se llama a glEnd falso. pero eso sería muy ineficiente, ya que lo haría cada cuadro (a menos que marque una casilla para hacerlo solo una vez, pero eso no funciona para objetos animados) y probablemente sería más trabajo que simplemente cambiar a VBO. Supongo que si tuvieras mucho código, ese enfoque podría funcionar.

David C. Bishop
fuente
7

Con los VBO generalmente tiene dos ventajas principales.

La ventaja 1 se relaciona con datos totalmente estáticos y proviene de poder mantener sus datos de vértice en la memoria que es más óptima para la GPU.

La ventaja 2 se relaciona con los datos dinámicos y proviene de poder especificar sus datos de vértice en cualquier momento antes de usarlos para la representación, lo que puede canalizar mejor.

Una tercera ventaja proviene del procesamiento por lotes de llamadas de extracción, pero también se comparte con las matrices de vértices de la vieja escuela, por lo que no lo llamo específicamente para VBO. El envío de datos a una GPU (o el uso de datos que ya están en la GPU) es similar en muchos aspectos al disco de E / S y el tráfico de red; si tiene algunos lotes grandes, es más eficiente que muchos lotes pequeños.

Una buena analogía (no 100% precisa pero suficiente para ayudarte a entender la idea) es si eres un conductor de autobús que tiene que llevar a 50 personas de una ciudad a otra. Puede cargarlos uno a la vez y hacer 50 viajes separados, eso es glBegin / glEnd. Alternativamente, puede poner los 50 en el autobús y simplemente hacer un solo viaje, que es agrupar con conjuntos de vértices o VBO (en el caso de VBO, las 50 personas ya estarían en el autobús;)).

Sin embargo, esto tiene un precio, y aquí el precio es que pierde la capacidad de especificar datos de vértice cuando lo necesite. Bueno, está bien, puede hacerlo (con algo de trabajo adicional), pero no obtendrá el rendimiento completo de su código. En cambio, debe pensar más en sus datos de vértices, cómo se usan, cómo (y si) deben actualizarse, si se pueden realizar animaciones en un sombreador (permitiendo así que los datos permanezcan estáticos; los VBO realmente necesitan sombreadores para un muchos casos de animación para que funcionen bien) o si necesita respetar los datos de vértice de cada cuadro, estrategias de actualización eficientes si es el último, etc. Si no hace esto y solo implementa una conversión ingenua, tiene un riesgo muy alto de poner ¡en un montón de trabajo solo para que el resultado final sea más lento!

Esto puede parecer mucho trabajo cuando lo encuentras por primera vez, pero en realidad no lo es. Una vez que entres en el modo de pensar así, en realidad encontrarás que es increíblemente fácil y casi es algo natural. Pero puede arruinar sus primeros intentos y no debería desanimarse si es así: arruinarlo es una oportunidad para aprender de lo que hizo mal.

Algunas reflexiones finales.

Tener los datos de su modelo en un formato que pueda cargarse fácilmente en un VBO puede ayudarlo a facilitar todo este proceso. Eso significa que debe evitar formatos más complejos o exóticos, al menos al principio (y hasta que se sienta más cómodo con el proceso); mantenga las cosas tan simples y básicas como sea posible cuando aprenda y habrá menos cosas que saldrán mal, y menos lugares donde buscar errores si (¡o cuándo!) las cosas salen mal.

Las personas a veces se desaniman si ven una implementación de VBO que usa más memoria que una implementación optimizada / comprimida de glBegin / glEnd (incluso pueden referirse a ella como "desperdicio"). No seas así. Excepto en casos extremos, el uso de memoria es realmente no que importante. Aquí es una compensación clara: está aceptando un uso de memoria potencialmente mayor a cambio de un rendimiento sustancialmente mayor. También ayuda a desarrollar la mentalidad de que la memoria es un recurso barato y abundante que está ahí para ser utilizado; El rendimiento no lo es.

Y, finalmente, el viejo castaño: si ya es lo suficientemente rápido, entonces su trabajo está hecho. Si está alcanzando su velocidad de fotogramas objetivo, si tiene espacio libre para condiciones transitorias, entonces es lo suficientemente bueno y puede pasar al siguiente paso. Puede perder mucho tiempo y energía exprimiendo un 10% extra de algo que realmente no lo necesita (estado allí, hecho, aún caer en la trampa), así que siempre considere cuál es el uso más óptimo de su propio tiempo ¡Porque el tiempo del programador es aún menos barato y menos abundante que el rendimiento!

Maximus Minimus
fuente