Pregunta

¿Con qué frecuencia debo llamar a las funciones OpenGL como glEnable () o glEnableClientState () y sus correspondientes homólogos de glDisable ? ¿Están destinados a ser llamados una vez al principio de la aplicación, o debo mantenerlos deshabilitados y solo habilitar aquellas funciones que necesito de inmediato para dibujar algo? ¿Hay una diferencia de rendimiento?

¿Fue útil?

Solución

" Eso depende " ;.

Si toda la aplicación solo usa una combinación de estados de habilitación / inhabilitación, entonces, por todos los medios, simplemente configúrela al principio y listo.

La mayoría de las aplicaciones del mundo real se deben mezclar, y luego se ve obligado a llamar a glEnable () para habilitar algunos estados en particular, hacer llamadas, luego glDisable ( ) de nuevo cuando hayas terminado de " despejar el escenario " ;.

La clasificación de estados, el seguimiento de estados y muchos esquemas de optimización se derivan de esto, ya que el cambio de estado es a veces costoso.

Otros consejos

Si encuentra que está verificando el valor de las variables de estado con frecuencia y luego llama a glEnable / glDisable, puede limpiar un poco las cosas usando el atributo stack (glPushAttrib / glPopAttrib).

La pila de atributos le permite aislar áreas de su código y los cambios en los atributos de una sección no afectan el estado del atributo en otras secciones.

void drawObject1(){
  glPushAttrib(GL_ENABLE_BIT);

  glEnable(GL_DEPTH_TEST);
  glEnable(GL_LIGHTING);    

  /* Isolated Region 1 */

  glPopAttrib();
}        

void drawObject2(){
  glPushAttrib(GL_ENABLE_BIT);

  glEnable(GL_FOG);
  glEnable(GL_GL_POINT_SMOOTH);    

   /* Isolated Region 2 */

  glPopAttrib();
}    

void drawScene(){
  drawObject1();
  drawObject2();
}

Aunque GL_LIGHTING y GL_DEPTH_TEST están establecidos en drawObject1, su estado no se conserva en drawObject2. En ausencia de glPushAttrib este no sería el caso. Además, tenga en cuenta que no es necesario llamar a glDisable al final de las llamadas a funciones, glPopAttrib hace el trabajo.

En cuanto al rendimiento, la sobrecarga debida a las llamadas de función individuales a glEnable / glDisable es mínima. Si necesita manejar muchos estados, probablemente necesitará crear su propio administrador de estados o realizar numerosas llamadas a glGetInteger ... y luego actuar en consecuencia. La maquinaria agregada y el flujo de control podrían hacer que el código sea menos transparente, más difícil de depurar y más difícil de mantener. Estos problemas pueden dificultar otras optimizaciones más fructíferas.

La pila de atribución puede ayudar a mantener capas de abstracción y crear regiones de aislamiento.

página de manual de glPushAttrib

En primer lugar, ¿qué versión de OpenGL usas? ¿Y qué generación de hardware de gráficos tiene su grupo objetivo? Saber esto facilitaría dar una respuesta más correcta. Mi respuesta asume OpenGL 2.1.

OpenGL es una máquina de estados, lo que significa que cada vez que se cambia un estado, ese estado se convierte en "actual". hasta que el programador vuelva a cambiarlo explícitamente con una nueva llamada a la API de OpenGL. Existen excepciones a esta regla, como las llamadas a la matriz de estado del cliente que hacen que el color del vértice actual sea indefinido. Pero esas son las excepciones que definen la regla.

" una vez al comienzo de la aplicación " no tiene mucho sentido, porque hay veces que necesitas destruir tu contexto OpenGL mientras la aplicación aún se está ejecutando. Supongo que te refieres justo después de cada creación de ventana. Eso funciona para el estado que no necesita cambiar más tarde. Ejemplo: si todas sus llamadas de sorteo usan los mismos datos de matriz de vértices, no necesita deshabilitarlos con glDisableClientState después.

Hay muchos estados de habilitación / deshabilitación asociados con la tubería antigua de función fija. La redención fácil para esto es: ¡Usa sombreadores! Si apuntas a una generación de tarjetas a lo sumo de cinco años, probablemente imite la canalización de función fija con sombreadores de todos modos. Al usar sombreadores, usted tiene un control más o menos total de lo que sucede durante las etapas de transformación y rasterización, y puede crear sus propios "estados". con uniformes, que son muy baratos de cambiar / actualizar.

Saber que OpenGL es una máquina de estado como dije anteriormente debería dejar en claro que uno debe esforzarse por mantener los cambios de estado al mínimo, siempre que sea posible. Sin embargo, probablemente hay otras cosas que afectan el rendimiento mucho más que habilitar / deshabilitar llamadas de estado. Si quieres saber sobre ellos, lee.


El gasto del estado no asociado con las antiguas llamadas de estado de función fija y que no es simple habilitar / deshabilitar el estado puede variar ampliamente en costo. En particular, los sombreadores de enlace y los nombres de enlace (" nombres " de texturas, programas, objetos de búfer) suelen ser bastante caros. Es por eso que muchos juegos y aplicaciones solían clasificar el orden de dibujo de sus mallas de acuerdo con la textura. De esa manera, no tenían que unir la misma textura dos veces. Sin embargo, hoy en día, lo mismo se aplica a los programas de sombreado. No desea vincular el mismo programa de sombreado dos veces si no tiene que hacerlo. Además, no todas las características en una versión particular de OpenGL son aceleradas por hardware en todas las tarjetas, incluso si los proveedores de esas tarjetas afirman que son compatibles con OpenGL. Ser compatible significa que siguen la especificación, no que necesariamente ejecuten todas las funciones de manera eficiente. Algunas de las funciones como glHistogram y glMinMax de GL__ ARB __imaging deben recordarse a este respecto.


Conclusión: ¡A menos que haya una razón obvia para no hacerlo, use sombreadores! Le ahorra muchas llamadas estatales innecesarias, ya que puede usar uniformes en su lugar. Ya sabes, los sombreadores de OpenGL llevan alrededor de seis años. Además, la sobrecarga de habilitar / deshabilitar los cambios de estado puede puede ser un problema, pero generalmente hay mucho más que ganar al optimizar otros cambios de estado más costosos, como glUseProgram, glCompileShader, glLinkprogram, glBindBuffer y glBindTexture.

P.S: OpenGL 3.0 eliminó el estado del cliente habilitar / deshabilitar llamadas. Se habilitan de forma implícita, ya que las matrices de dibujo son la única forma de dibujar en esta versión. Se eliminó el modo inmediato. gl..Las llamadas de puntero también se eliminaron, ya que uno realmente solo necesita glVertexAttribPointer.

Una regla de oro que me enseñaron dice que casi siempre es más barato habilitar / deshabilitar a voluntad en lugar de verificar el estado actual y cambiar solo si es necesario.

Dicho esto, la respuesta de Marc es algo que definitivamente debería funcionar.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top