2009-12-26 10 views
16

glLoadIdentity dice se genera¿Cuándo debe uno llamar a glGetError?

GL_INVALID_OPERATION si glLoadIdentity se ejecuta entre la ejecución de glBegin y la correspondiente ejecución de glEnd.

Pero GL_INVALID_OPERATION es una bandera que devuelve glGetError.

Mi pregunta es, ¿cuándo deberíamos llamar al glGetError (para saber si estamos llamando a OpenGL en la secuencia correcta)?

+1

Nota: 'glBegin' y' glEnd' [están en desuso] (http://gamedev.stackexchange.com/questions/34108/opengl-vbo-or-glbegin-glend). –

Respuesta

22

No estoy seguro si su pregunta es sobre cuándo puede llamar a glGetError si está dentro de glBegin/End o si se trata de una pregunta más general sobre el uso de glGetError en general. Entonces responderé a ambos.

Lo que puedes hacer entre glBegin y glEnd es muy limitado. Esto es a propósito, ya que pones el GL en un modo muy específico: en el medio de un Draw. Como tal, cualquier cosa que no se relacione directamente con los atributos por vértice es simplemente inválida. Incluso un glGetError no es válido en ese contexto. Pruebe y piense en glBegin + todas las llamadas de GL entre + glEnd como una sola llamada de Draw al GL, que ayuda a acercarse más a lo que realmente hace el GL de todos modos.

Ahora, usted debe nunca haber provocado un error de GL, mientras que en el interior del Begin/par Fin si se adhieren a la regla simple a métodos atributo sólo de llamadas (glNormal, glTexCoord, glColor, glSecondaryColor, glIndex, glMultiTexCoord, glVertexAttrib, glVertex y un par de otros). Cualquier otra cosa provocará un error. (err ... bueno, glMaterial es un poco una excepción. Funciona, pero se desaconseja su uso)

Si su pregunta es cuándo puede llamar a glGetError cuando se activó el error dentro de un par Begin/End, ChrisF respondió en un comentario: después de la llamada glEND.

Ahora, en un sentido más amplio, use glGetError solo como una herramienta de depuración. Mi preferencia personal es doble:

  • cheque glGetError una vez por cuadro para asegurarse de que no haya error
  • envoltura más GL llama con una macro que puede comprobar el código de error GL, y sólo encenderlo cuando el per la verificación del marco falla

Por supuesto, ya que los métodos de atributos pueden ser llamados fuera un Begin/par final, es un poco difícil de hacerlo bien. Pero en la práctica, esos métodos nunca fallan de todos modos, así que no me molesto en hacer una macrocomprobación.

Un tidbit de trivia: el GL API fue diseñado originalmente para que la implementación del cliente no supiera si había un error en el sitio de la llamada. P.ej. si el GL se implementó realmente en una máquina remota (como en los días SGI), una llamada a, digamos, glTexEnv con un objetivo no GL_TEXTURE_ENV podría simplemente agregarse al búfer de comando, y no se registraría ningún error en ese punto.

Si luego llamó a glGetError, el lado del cliente tendría que vaciar el búfer de comando al servidor GL, esperar a que se procesen los comandos que están en búfer, recuperar el código de error y devolver el código de error correspondiente a la aplicación.

Si esto suena pesado, es porque así fue. Esta fue la razón principal por la cual no cada llamada devolvía un código de error, por cierto, y por qué llamar a glGetError solo se consideraba correcto para la depuración. En la actualidad, la mayoría de las implementaciones GL están manejando toda la administración estatal en el mismo proceso, así que como dije, es realmente trivial para la mayoría de los usuarios.

Por último, cada vez que estoy hablando de Begin/End, siento que necesito decir que probablemente debería considerar no usarlo en absoluto. Es la peor forma de dibujar con GL.

4

Normalmente debe llamar glGetError después de cada dos gl... llamada como uno de los efectos de la llamada es para borrar el error de la pila (from the MSDN):

Cuando se produce un error, se establece el indicador de error al valor de código de error apropiado. No se registran otros errores hasta que se llame a glGetError, se devuelva el código de error y se restablezca el indicador a GL_NO_ERROR.

Sin embargo, si tiene llamadas envueltos en glBegin y glEnd llamada glError después de la glEnd. Esto debería devolverle el código de error correcto (si lo había) y borrar la pila de errores.

+0

Sin embargo, glGetError genera un error GL_INVALID_OPERATION si se llama entre un glBegin y una llamada glEnd. Entonces glGetError no se puede llamar después de cada gl ... llamada. –

+0

Ah - He entendido mal. Si tienes llamadas envueltas en 'glBegin' y' glEnd' llama a 'glError' después de' glEnd'. – ChrisF

3

Algunas filosofías de codificación esperan que cada programa verifique todos los errores posibles y que maneje adecuadamente esos errores. Sin embargo, seguir una de esas filosofías requiere mucho código adicional y puede ralentizar significativamente un programa. En la práctica, solo uso glGetError cuando estoy diagnosticando un problema, o escribo algún código que tiene una posibilidad significativa de falla y una acción apropiada después del error.

En el primer caso, al diagnosticar un problema, utilizo una de dos estrategias. Debido a que OpenGL no registra nuevos errores hasta que se llame a glGetError, puedo verificar si hay errores una vez cada vez a través de mi ciclo principal. Eso me dice el primer error, que luego rastrear, y con suerte corregir. La otra estrategia que uso cuando me reduzco a algún código problemático, pero no estoy seguro de qué llamada está causando el problema. Después de cada gl ... llame fuera de glBegin. . . Bloque glEnd Voy a llamar a glGetError e informar cualquier error. Esto me dirá exactamente qué gl ... llamada está causando el problema, y ​​espero que me inicie en el camino hacia una solución.

En el segundo caso, programando de forma defensiva un probable error, llamaré a glGetError para borrar el indicador de error, realizar mi otra gl ... llamada (s), luego llamar a glGetError. Luego, tomo las medidas necesarias para lidiar con los informes de glGetError.

Cuestiones relacionadas