2009-10-28 19 views
16

Tengo un poco de experiencia escribiendo aplicaciones OpenGL 2 y quiero aprender usando OpenGL 3. Para esto he comprado Addison Wesley "Red-book" y "Orange-book" (GLSL) que descirbe la desaprobación de lo fijo funcionalidad y la nueva tubería programable (sombreadores). Pero lo que no puedo entender es cómo construir una escena con múltiples objetos sin usar las funciones depreciadas de traducir *, rotar * y escalar *.¿Cómo puedo traducir objetos individuales en OpenGL 3.x?

Lo que solía hacer en OGL2 era "moverme" en el espacio tridimensional utilizando las funciones de trasladar y rotar, y crear los objetos en coordenadas locales donde los quería usando glBegin ... glEnd. En OGL3, estas funciones están obsoletas y, según tengo entendido, reemplazadas por sombreadores. Pero no puedo llamar a un programa shader para cada objeto que hago, ¿verdad? ¿No afectaría esto a todos los otros objetos también?

No estoy seguro de haber explicado satisfactoriamente mi problema, pero el meollo de todo es cómo programar una escena con múltiples objetos definidos en coordenadas locales en OpenGL 3.1. Todos los tutoriales para principiantes que he encontrado solo usan un solo objeto y no tienen/resuelven este problema.

Editar: Imagina que quieres dos cubos giratorios. Sería una molestia modificar manualmente cada coordenada de vértice, y no se puede simplemente modificar la matriz de vista de modelo, porque eso sería más bien girar la cámara alrededor de dos cubos estáticos ...

Respuesta

20

Comencemos con lo básico.

Por lo general, desea transformar sus vértices del triángulo locales a través de los siguientes pasos:

local-space coords-> world-space coords -> view-space coords -> clip-space coords

en la norma GL, las 2 primeras transformaciones se realizan a través GL_MODELVIEW_MATRIX, el tercero se realiza a través GL_PROJECTION_MATRIX

Estas transformaciones de vista de modelo, para las muchas transformaciones interesantes que generalmente queremos aplicar (por ejemplo, traducir, escalar y rotar, por ejemplo), se pueden expresar como multiplicación de matriz de vectores cuando representamos vértices en homogeneous coordinates. Normalmente, el vértice V = (x, y, z) se representa en este sistema como (x, y, z, 1).

Ok. Digamos que queremos transformar un vértice V_local a través de una traducción, luego una rotación, luego una traducción. Cada transformada se puede representar como una matriz *, llamémoslos T1, R1, T2. Queremos aplicar la transformación a cada vértice: V_view = V_local * T1 * R1 * T2.La multiplicación de la matriz es asociativa, podemos calcular de una vez por todas M = T1 * R1 * T2.

De esta manera, solo tenemos que pasar M al programa de vértices y calcular V_view = V_local * M. Al final, un sombreador de vértices típico multiplica la posición del vértice por una sola matriz. Todo el trabajo para calcular esa matriz es cómo mueve su objeto del espacio local al espacio del clip.

Ok ... Eché un vistazo a una serie de detalles importantes.

En primer lugar, lo que describí hasta ahora solo cubre la transformación que generalmente queremos hacer hasta el espacio de visualización, no el espacio de clip. Sin embargo, el hardware espera que la posición de salida del sombreador de vértices se represente en ese espacio de clips especial. Es difícil explicar las coordenadas de espacio de clip sin matemática significativa, así que lo dejo fuera, pero lo importante es que la transformación que trae los vértices a ese espacio de clip usualmente se puede expresar como el mismo tipo de multiplicación de matriz. Esto es lo que calculan los antiguos gluPerspective, glFrustum y glOrtho.

En segundo lugar, esto es lo que aplica a las posiciones de los vértices. La matemática para transformar las normales es algo diferente. Esto se debe a que desea que la normal permanezca perpendicular a la superficie después de la transformación (para referencia, requiere una multiplicación por la transposición inversa de la vista de modelo en el caso general, pero eso se puede simplificar en muchos casos)

Tercero, nunca se envían coordenadas 4-D al sombreador de vértices. En general, pasas los 3-D. OpenGL transformará esas coordenadas 3-D (o 2-D, btw) en 4-D para que el sombreado de vértices no tenga que agregar la coordenada extra. expande cada vértice para agregar el 1 como la coordenada w.

Entonces ... para volver a unir todo eso, para cada objeto, necesita calcular esas matrices M mágicas basadas en todas las transformaciones que desea aplicar al objeto. Dentro del sombreador, debes multiplicar cada posición de vértice por esa matriz y pasarla a la salida de posición del sombreador de vértices. código típico es más o menos (esto es utilizando la nomenclatura antigua):

mat4 MVP; 
gl_Position=MVP * gl_Vertex; 

* las matrices reales se pueden encontrar en la web, sobre todo en las páginas del manual para cada una de esas funciones: rotate, translate, scale, perspective , ortho

+1

¡Gracias por la gran respuesta! Un detalle que me había perdido fue que puedes cambiar la matriz MVP (por ejemplo, declararla uniforme) entre llamadas a glDrawElements ... Extraño cambio de khronos para dejar la especificación de estas matrices muy comunes para el programador. Espero que encuentren su camino hacia el glu o similares pronto ... – Wonko

+0

Para eso es el middleware. GL3.2 es menos expresivo para una codificación rápida. Pero las versiones anteriores eran el nivel incorrecto de abstracción para la aplicación real de todos modos. Requería un marco de gestión estatal además. Además, supongamos que quieres mantener matrices. Eso significa que el controlador tiene que mantener todas las pilas de la matriz, cómo pasarlas solo a _all_ shaders que lo requieren (no solo el vértice), descubrir qué sabor necesita - M, MV, MVP, IT (MV), IT (M) La peor parte ? la aplicación es la única que puede hacer que las matemáticas sean eficientes al ejecutar muchas operaciones matriciales a la vez. GL no puede hacer eso de manera eficiente. – Bahbar

1

Esas funciones están aparentemente obsoletas, pero son técnicamente todavía perfectamente funcional y de hecho compilará. Entonces todavía puedes usar las funciones translate3f (...) etc.

SIN EMBARGO, this tutorial tiene una buena explicación de cómo funcionan los nuevos sombreadores y demás, Y para múltiples objetos en el espacio.

Puede crear x matrices de vértices y unirlas en x objetos VAO, y renderizar la escena desde allí con sombreadores, etc ... meh, es más fácil para usted simplemente leerlo - es una muy buena lectura para captar los nuevos conceptos.

Además, OpenGL 'Red Book' como se le llama tiene una nueva versión - The Official Guide to Learning OpenGL, Versions 3.0 and 3.1. Incluye 'Discusión del mecanismo de desaprobación de OpenGL y cómo verificar sus programas para versiones futuras de OpenGL'.

Espero que sea de alguna ayuda!

+0

Gracias de nuevo por la respuesta rápida. He leído el tutorial que mencionas, pero a pesar de que crea dos triángulos, los crea en coordenadas globales, no a nivel local, como yo quiero. El problema es que cuando tienes un modelo más complicado, puede ser engorroso usar coordenadas globales, especialmente si el modelo se mueve. Además, quiero cargar un objeto prefabricado de un archivo .obj y colocarlo en algún lugar del espacio tridimensional. – Wonko

+8

@Mark El primer enlace está roto. – Jeff

Cuestiones relacionadas