OpenGL define la posición del vértice en píxeles

He estado escribiendo un motor de juego básico 2D en OpenGL / C ++ y aprendiendo todo sobre la marcha. Todavía estoy bastante confundido sobre la definición de vértices y su “posición”. Es decir, todavía estoy intentando comprender el mecanismo de conversión de vértices a píxeles de OpenGL. ¿Puede explicarse brevemente o alguien puede señalar un artículo o algo que lo explique? ¡Gracias!

Este es un conocimiento bastante básico de que su recurso favorito de aprendizaje de OpenGL debería enseñarle como una de las primeras cosas. Pero de todos modos la tubería estándar de OpenGL es la siguiente:

  1. La posición del vértice se transforma del espacio del objeto (local a algún objeto) en el espacio del mundo (con respecto a algún sistema de coordenadas global). Esta transformación especifica dónde se encuentra el objeto (al que pertenecen los vértices) en el mundo

  2. Ahora la posición del espacio-mundo se transforma en cámara / espacio de visión. Esta transformación está determinada por la posición y la orientación de la cámara virtual mediante la cual se ve la escena. En OpenGL, estas dos transformaciones se combinan en una, la matriz de vista de modelo, que transforma directamente sus vértices del espacio de objetos al espacio de vista.

  3. A continuación, se aplica la transformación de proyección. Mientras que la transformación de modelview debe consistir solo en transformaciones afines (rotación, traducción, escalado), la transformación de proyección puede ser una perspectiva, que básicamente distorsiona los objetos para realizar una vista en perspectiva real (con los objetos más alejados siendo más pequeños). Pero en su caso de una vista 2D, probablemente será una proyección ortográfica, que no hace más que una traducción y escalado. Esta transformación está representada en OpenGL por la matriz de proyección.

  4. Después de estas 3 (o 2) transformaciones (y luego siguiendo la división de perspectiva por el componente w, que en realidad se da cuenta de la distorsión de la perspectiva, si hay alguna) lo que tienes son coordenadas del dispositivo normalizadas. Esto significa que después de estas transformaciones, las coordenadas de los objetos visibles deberían estar en el rango [-1,1] . Todo lo que está fuera de este rango está recortado.

  5. En un paso final, se aplica la transformación de la ventana gráfica y las coordenadas se transforman del rango [-1,1] en el cubo [0,w]x[0,h]x[0,1] (suponiendo un glViewport(0, w, 0, h) call), que son las posiciones finales del vértice en el framebuffer y, por lo tanto, sus coordenadas de píxel.

Cuando se utiliza un sombreador de vértices, los pasos 1 a 3 se realizan realmente en el sombreador y, por lo tanto, se pueden hacer de la manera que se desee, pero generalmente uno se ajusta a esta vista de modelo estándar -> tubería de proyección también.

Lo más importante a tener en cuenta es que, después de que la vista de modelo y la proyección se transformen, cada vértice con coordenadas fuera del rango [-1,1] se recortará. Entonces, la casilla [-1,1] determina su escena visible después de estas dos transformaciones.

Entonces, a partir de su pregunta, supongo que desea utilizar un sistema de coordenadas 2D con unidades de píxeles para las coordenadas y transformaciones de sus vértices. En este caso, esto se hace mejor usando glOrtho(0.0, w, 0.0, h, -1.0, 1.0) con w y h siendo las dimensiones de su ventana gráfica. Básicamente, esto contrarresta la transformación de la ventana gráfica y, por lo tanto, transforma los vértices de la casilla [0,w]x[0,h]x[-1,1] en la casilla [-1,1] , que luego transforma la transformación de la ventana gráfica. volver a la [0,w]x[0,h]x[0,1] -box.

Estas han sido explicaciones bastante generales sin mencionar que las transformaciones reales se realizan mediante multiplicaciones vectoriales de matriz y sin hablar de coordenadas homogéneas, pero deberían haber explicado lo esencial. Esta documentación de gluProject también podría proporcionarle una idea, ya que en realidad modela la tubería de transformación para un solo vértice. Pero en esta documentación se olvidaron de mencionar la división por la componente w ( v" = v' / v'(3) ) después del paso v' = P x M xv .

EDITAR: No te olvides de mirar el primer enlace en la respuesta de epatel, que explica el proceso de transformación un poco más práctico y detallado.

Se llama transformación.

Los vértices se configuran en coordenadas 3D que se transforman en coordenadas de ventana gráfica (en la vista de la ventana). Esta transformación se puede establecer de varias maneras. La transformación ortogonal puede ser más fácil de entender como un iniciador.

http://www.songho.ca/opengl/gl_transform.html

http://www.opengl.org/wiki/Vertex_Transformation

http://www.falloutsoftware.com/tutorials/gl/gl5.htm

En primer lugar, tenga en cuenta que OpenGL no utiliza coordenadas de píxeles estándar. Quiero decir con eso para una resolución particular, es decir. 800×600 no tiene coordenadas horizontales en el rango 0-799 o 1-800 paso por uno. Prefiere tener coordenadas que vayan de -1 a 1 y luego enviar a la unidad rasterizadora de tarjetas gráficas y después de eso se corresponde con una resolución particular.

Omití un paso aquí, antes de todo lo que tienes es una matriz ModelViewProjection (o una matriz de proyección de vista en algunos casos simples) que antes de todo arroja las coordenadas que usas para un plano de proyección. El uso predeterminado de esto es implementar una cámara que convierta el espacio 3D del mundo (Ver para colocar una cámara en posición correcta y Proyección para proyectar coordenadas 3D en el plano de pantalla. En ModelViewProjection también es el paso de colocar un modelo en el lugar correcto en el mundo).

Otro caso (y puede usar la matriz de proyección de esta manera para lograr lo que desea) es usar estas matrices para convertir un rango de resoluciones en otro.

Y hay un truco que necesitarás. Debería leer sobre la matriz y la cámara modelViewProjection en OpenGL si quiere hacerlo en serio. Pero, por ahora, les diré que con la matriz adecuada, pueden simplemente proyectar su propio sistema de coordenadas (es decir, usar rangos 0-799 horizontaly y 0-599 verticalmente) para un rango estandarizado -1: 1. De esta forma, no verá que la API subyacente utiliza su propio sistema -1 a 1.

La forma más fácil de lograr esto es la función glOrtho. Aquí está el enlace a la documentación: http://www.opengl.org/sdk/docs/man/xhtml/glOrtho.xml

Este es un ejemplo de uso adecuado: glMatrixMode (GL_PROJECTION) glLoadIdentity (); glOrtho (0, 800, 600, 0, 0, 1) glMatrixMode (GL_MODELVIEW)

Ahora puede usar su propia matriz modelView, es decir. para objetos de traducción (movimiento) pero no toques tu ejemplo de proyección. Este código debe ejecutarse antes de cualquier comando de dibujo. (Puede ser después de inicializar opengl, de hecho, si no usará gráficos en 3D).

Y aquí está el ejemplo de trabajo: http://nehe.gamedev.net/tutorial/2d_texture_font/18002/

Solo dibuje sus figuras en lugar de dibujar texto. Y hay otra cosa: glPushMatrix y glPopMatrix para la matriz elegida (en este ejemplo, matriz de proyección); no la usarás hasta que combines 3D con representación 2d.

Y aún puedes usar la matriz modelo (es decir, para colocar fichas en algún lugar del mundo) y ver la matriz (en el ejemplo para ampliar o desplazarte por el mundo; en este caso, tu mundo puede ser mayor que la resolución y puedes recortar vistas mediante traducciones simples) )

Después de mirar mi respuesta, veo que es un poco caótico, pero si te confundiste, solo lee sobre maquetas de modelos, vistas y proyecciones y prueba con glOrtho. Si todavía está confundido, siéntase libre de preguntar.

MSDN tiene una gran explicación . Puede ser en términos de DirectX pero OpenGL es más o menos lo mismo.

Google para “OpenGL rendering pipeline”. Los primeros cinco artículos proporcionan buenas exposiciones.

La transición de clave de vértices a píxeles (en realidad, fragmentos, pero no estará demasiado lejos si piensa “píxeles”) se encuentra en la etapa de rasterización, que ocurre después de que todos los vértices se hayan transformado de coordenadas mundiales a coordenadas de pantalla y cortado.