2009-11-13 9 views
9

Aunque parece que hay muy pocas referencias actualizadas para OpenGL 3.x, la manipulación real de bajo nivel de OpenGL es relativamente sencilla. Sin embargo, estoy teniendo serios problemas para intentar siquiera conceptualizar cómo se manipularían las VBO para generar un mundo dinámico.¿Cómo uso OpenGL 3.x VBOs para renderizar un mundo dinámico?

Obviamente, las formas de modo inmediato de la antigüedad no son aplicables, pero desde allí, ¿a dónde voy? ¿Escribo algún tipo de estructura de escena y luego la convierto en un conjunto de vértices y la transmito a la VBO, cómo almacenaría los datos de traducción? Si es así, ¿qué aspecto tendría el código?

Básicamente, realmente no sé cómo continuar.

Respuesta

9

Si todo tu mundo es verdaderamente dinámica, puede utilizar la bandera GL_STREAM_DRAW_ARB uso y restablecer los datos en cada cuadro. No se moleste en manipularlo, solo intente transmitir lo más eficiente posible.

Sin embargo, supongo que tiene una escena que consiste en múltiples objetos rígidos que se mueven entre sí. En este caso, use un VBO para cada objeto y especifique el indicador de uso GL_STATIC_DRAW_ARB. Luego puede establecer la transformación de la vista de modelo para cada instancia de un objeto y renderizarlas usando una llamada de extracción por instancia.

Una regla de oro (en la PC) es emitir no más de una llamada de extracción por MHz de su CPU. Esta es una estimación cruda, pero hay algo de cierto en ello. No se preocupe por poner múltiples objetos independientes en un solo VBO u otros trucos de rendimiento si se mantiene por debajo de este límite.

+1

+1 para reconocer el procesamiento por lotes como el mayor problema con la codificación de gráficos en estos días. 1 llamada de sorteo por Mhz me parece optimista después de algunos códigos de OpenGL ES iPhone - ¡He encontrado que estoy limitado a 30-40 lotes para mantener una tasa de fotogramas decente! – tsalter

+0

Ok, debería haber agregado que esta regla puede no aplicarse directamente a los dispositivos móviles. Lo he visto primero en algunas diapositivas de GDC hace unos años, y me ha sido útil en PC con Windows. –

+0

Por cierto, acabo de encontrar las diapositivas aquí: http://ati.amd.com/developer/gdc/D3DTutorial3_Pipeline_Performance.pdf (principalmente D3D9, OpenGL en la página 28) –

5

El uso de VBO no significa que deba renderizar toda su escena con solo una llamada de un solo dibujo. Todavía puede emitir varias llamadas de sorteo y configurar diferentes matrices de transformación a lo largo del camino.

Por ejemplo, si está utilizando un gráfico de escenas, cada modelo en el gráfico de escenas puede corresponder a una sola llamada a dibujo. En tal caso, la forma más fácil de usar VBO es crear un VBO separado para cada modelo.

Como optimización, puede combinar varios modelos en un solo VBO, y luego pasar compensaciones distintas de cero al hacer sus llamadas; esto saca el modelo correcto de la VBO. También es deseable combinar llamadas de sorteo múltiples en una sola llamada de sorteo, pero eso no es posible si necesitan tener transformaciones independientes. (En realidad, es posible en ciertas situaciones si utiliza la creación de instancias o mezcla vértice, pero yo sugeriría conseguir los fundamentos fuera del camino primero.)

9

Respuesta corta:

Uso glMapBufferRange y sólo actualizar el subrango que necesita modificación.

Respuesta larga:

El truco consiste en trazar el buffer ya existente con glMapBufferRange, y sólo asignar el rango que necesita. Teniendo en cuenta estos supuestos:

  • Su geometría utiliza la animación por vértice morphing
  • El recuento de vértices para los modelos es constante durante la animación.

continuación, puede utilizar glMapBufferRange para actualizar sólo las partes que cambian, y dejar el resto de los datos por sí solos. Las cargas completas que usan glBufferData son lentas como una tortuga, ya que eliminan el almacén de memoria antiguo y asignan uno nuevo. Eso es además de cargar los nuevos datos. glMapBufferRange solo le permite leer/escribir datos existentes, no asigna ni cancela la asignación.

Sin embargo, si usa animación de esqueleto, pase las transformaciones de vértices como matrices 4x4 por vértice al sombreado de vértices y realice los cálculos allí. Por supuesto, los datos por vértice se especifican con glVertexAttribPointer.

Además, recuerde que puede leer datos de textura en el sombreado de vértices, y que OpenGL 3.1 introdujo algunas llamadas a nuevas instancias; glDrawArraysInstanced y glDrawElementsInstanced. Los combinados se pueden usar para búsquedas específicas de instancia. Es decir, puede hacer llamadas de instancia con los mismos datos de geometría encuadernados, pero enviar posiciones o cualquier dato por vértice que necesite como texturas o matrices de texturas. Esto puede evitar que mezcle y haga coincidir diferentes conjuntos de datos de matriz de vértices.

Imagine si desea representar 100 instancias del mismo modelo, pero con diferentes posiciones o combinaciones de colores. O incluso mapas de texturas.

Cuestiones relacionadas