Foros - Stratos

Programadores => Programación gráfica => Mensaje iniciado por: angelfmarcos en 25 de Mayo de 2006, 03:33:17 PM

Título: Camara En Opengl
Publicado por: angelfmarcos en 25 de Mayo de 2006, 03:33:17 PM
 Hola. Tengo un problema al implementar la camara en openGL para un pequeño motor que estoy desarrollando. La cámara debería funcionar indicandole un punto (posicion) y una orientacion (respecto al eje local de la propia camara y dado en angulos). Ahora mismo estoy usando el siguiente código:

 //Rota sobre el eje de la cámara
 glRotated (ang_c, 0.0f, 0.0f, 1.0f);
 glRotated (ang_b, 0.0f, 1.0f, 0.0f);
 glRotated (ang_a, 1.0f, 0.0f, 0.0f);
 glTranslated (-pos_x, -pos_y, -pos_z);


hasta ahora habia funcionando sin problemas pero he comenzado a detectarlos,

¿Cual sería la forma más correcta de implementar la cámara?

Un saludo.
Título: Camara En Opengl
Publicado por: ajmendoza en 25 de Mayo de 2006, 03:42:52 PM
 hay una función que es:

glulookAt( posicionCamara_x, posicionCamara_y, posicionCamara_z,
                punto_donde_miraCamara_x,punto_donde_miraCamara_y,punto_donde_miraCamara_z,                  
                vectorhaciaArribaCamara_x,vectorhaciaArribaCamara_y,vectorhaciaArribaCamara_z )


No necesita mas explicaciones  ¿no? :P.

Create una clase que tenga todos esos datos de la camara (y mas que te harán falta). Cuando utilices el teclado o el ratón haz que varie esos valores de clase y en cada pasada actualiza la camara utilizando esta función y los atributos de la clase.

Saludos!


Título: Camara En Opengl
Publicado por: angelfmarcos en 25 de Mayo de 2006, 03:46:33 PM
 Si, ya la había visto. Pero no consigo sacar el punto al que miro y el vector up a partir de la orientacion de la camara.
Título: Camara En Opengl
Publicado por: Lord Trancos 2 en 25 de Mayo de 2006, 07:27:54 PM
 Lo ideal es que pases de los "euler angles" y uses "quaternions".

Despues tan solo tienes que convertir la quaternion en una matriz, aplicarle la translacion y cargarla con glLoadMatrixf
Título: Camara En Opengl
Publicado por: angelfmarcos en 25 de Mayo de 2006, 07:39:22 PM
 Lo he hecho asi, pero sigo teniendo los mismos problemas. Si la escena esta de frente,  todo va bien y la camara rota perfectamente sobre cualquier eje. el problema viene cuando tengo una vista lateral, en la que cuando rota la camara sobre el eje x, no me hace ni caso y en su lugar lo hace sobre el z (el y y el z los rota correctamente)
Título: Camara En Opengl
Publicado por: tamat en 25 de Mayo de 2006, 07:46:48 PM
 Sobre camaras te puedo decir que el método que usabas tú es muy problematico, ya que si alteras el orden de las rotaciones el resultado no es el mismo con lo que esos valores no son absolutos. Ademas si tienes que hacer calculos con ellos te volveras loco.

Lo mejor es usar algun sistema en el que la orientación se guarde como un todo. Los más usados son las matrices de Euler (que es lo mismo que usa OpenGL para guardar las rotaciones) y los quaterniones.

Yo uso lo segundo pero te recomiendo que empieces por lo primero ya que es ligeramente más asequible.

En OPENGL existe una función que te permite extraer la matriz de rotación que se le aplicará a los vertices que pintes a continuación, dicha matriz se llama Modelview y la puedes sacar mediante la funcion glGetMatrix.

Te aconsejo que le eches una ojeada al tema de las matrices para transformaciones (rotacion, traslacion y escalado), aquí hay informacion.

Si todo esto no te gusta puedes usar glLookat como bien te han dicho, aunque para mantener el vector UP y TARGET actualizado tendras que aplicarles las rotaciones y para eso necesitaras o matrices o quaterniones así que tampoco ganas demasiado.

Si te vas a meter con tema 3D a fondo no te va a quedar más remedio que empollar estos temas, es lo que todos hemos hecho.

Espero haber sido de ayuda.
Título: Camara En Opengl
Publicado por: vicho en 25 de Mayo de 2006, 09:21:22 PM
 yo la solucion que tenia era usar cordenadas esfericas y glulookat  :rolleyes:  
Título: Camara En Opengl
Publicado por: angelfmarcos en 26 de Mayo de 2006, 11:10:33 AM
 He usado quaterniones (a partir de un ejemplo que he visto por ahi) y parece que la navegacion con el ratón va mejor (aunque no del todo perfecta). Sin embargo cuando trato de posicionar la camara en un punto en concreto y con una orientación determinada ahi puede pasar cualquier cosa :(
Título: Camara En Opengl
Publicado por: Buffon en 26 de Mayo de 2006, 01:53:29 PM
 Como han dicho create una clase llamada Camara y en la cuál guardes toda la información y luego usas gluLookAt sino va a ser una putada.

Nosotros recurrimos a otra táctica, teniamos que guardar sucesivas transformaciones geométricas y que cada render de la camara se guardara bien y l oque haciamos era ir multiplicando la matriz antigua con la nueva generada y cargandola antes de las nuevas rotaciones que haciamos, así vas guardando el estado anterior pero no puedes hacer pasos atrás.

También puedes ir apilando las matrices y luego multiplicarlas para poder hacer pasos hacia atrás por si no te interesa el cambio efectuado.

La camara de OpenGL en si no es tan difícil una vez la entiendes, la putada es entenderla :)

Título: Camara En Opengl
Publicado por: killrazor en 26 de Mayo de 2006, 04:21:36 PM
 gluLookAt es poco eficiente, ademas de que tendras problemas. Lo mejor es usar quaterniones. Basicamente fabricamos un quaternion por rotacion, los multiplicamos, los convertimos en matriz y los subimos con glMultMatrix.

A saco!!!!
Título: Camara En Opengl
Publicado por: ethernet en 26 de Mayo de 2006, 05:49:49 PM
Cita de: "killrazor"gluLookAt es poco eficiente, ademas de que tendras problemas. Lo mejor es usar quaterniones. Basicamente fabricamos un quaternion por rotacion, los multiplicamos, los convertimos en matriz y los subimos con glMultMatrix.

A saco!!!!
Será todo lo ineficiente que quieras, pero para hacer 4 movimientos de cámara es muchísimo más que suficiente y en cuestión de minutos la tienes funcionando. Con quaternios todo es fantastico... después de haber estado unos días entendiendo el porqué o haciendo en una tarde un copy&paste de la virgen.
Título: Camara En Opengl
Publicado por: vicho en 26 de Mayo de 2006, 06:53:31 PM
 si quieres algo rapido te recomiendo el siguiente link http://www.gamedev.net/reference/articles/...article2160.asp

killrazor segun tu que hace ineficiente al glulookat???
Título: Camara En Opengl
Publicado por: tamat en 26 de Mayo de 2006, 07:20:52 PM
Cita de: "killrazor"gluLookAt es poco eficiente, ademas de que tendras problemas. Lo mejor es usar quaterniones. Basicamente fabricamos un quaternion por rotacion, los multiplicamos, los convertimos en matriz y los subimos con glMultMatrix.

A saco!!!!
qué coño importa que una función que se llama como máximo UNA VEZ por frame sea ineficiente?!?!
Título: Camara En Opengl
Publicado por: angelfmarcos en 26 de Mayo de 2006, 08:36:27 PM
 La camara la he probado a hacer por varios métodos, pero no encuentro el que encaje del todo con lo que me hace falta. por ejemplo, con quaterniones iba genial la navegacion, pero al posicionar la camara con una orientacion concreta fallaba.

El método que tengo ahora va bien excepto para rotaciones sobre el eje z, que hace un poco lo que le da la gana :(


y aun que queda la parte complicada, localizar un objeto y centrarlo en la pantalla :(

Título: Camara En Opengl
Publicado por: Lord Trancos 2 en 26 de Mayo de 2006, 09:01:19 PM
Cita de: "angelfmarcos"... pero al posicionar la camara con una orientacion concreta fallaba....
Si te explicas un poco mejor o pones algo de codigo tal vez podamos ayudarte.  
Título: Camara En Opengl
Publicado por: marcode en 26 de Mayo de 2006, 09:08:15 PM
 si sabes el punto donde está la cámara, y el punto al que quieres mirar, no necesitas nada más para usar gluLookAt, el vector up por lo general será 0,1,0.
Título: Camara En Opengl
Publicado por: angelfmarcos en 26 de Mayo de 2006, 09:18:26 PM
 Fallaba al ponerme en la posicion (20, 0, 0) y mirar hacia el centro. giraba sobre el eje Y para orientarme hacia el centro y eso lo hacia bien, pero luego el girar sobre el eje Z o X daba el mismo resultado, girando siempre sobre el mismo eje.

El código que estoy usando es


Quaternion ra, rb, rc, r;
Matrix m;
ra.EulerToQuat (ang_a, 0, 0);
rb.EulerToQuat (0, ang_b, 0);
rc.EulerToQuat (0, 0, ang_c);
r = r * rc;
r = r * rb;
r = r * ra;
r.GetMatrix (m);
float m_vals[16];
m.GetValues (m_vals);
glMultMatrixf (m_vals);
glTranslatef (-pos_x, -pos_y, -pos_z);


donde ang_a, ang_b y ang_c son la orientacion de la camara.


El problema de localizar asi el objeto es que necesito en todo momento saber los ángulo de orientación de la cámara. Además debo o acercarme para que se muestre completo en pantalla. Tambíen pensaba hacer la localización por densidad de puntos y no por el centro del objeto (pero bueno, eso para otra version xD)
Título: Camara En Opengl
Publicado por: tamat en 26 de Mayo de 2006, 09:35:44 PM
 Creo que sigues sin comprender el concepto de rotación tridimensional.

Te equivocas al seguir guardando los tres angulos por separado en floats y luego hacer tres rotaciones hasta tener la rotacion deseada, no es esa la idea.

Un quaternion es ya de por sí una rotación que contempla los tres ejes y por lo tanto es ese el unico dato que tienes que guardar, ese y nada más. Si luego durante el transcurso de tu aplicación quieres alterar esa rotación (por ejemplo el usuario quiere rotar haciendo roll sobre su propio eje Z) pues construyes el quaternion que rota en Z y lo multiplicas por el quaternion de la rotación de tu camara que ya tienes, el resultado será la rotación de la camara una vez aplicada la rotación.

Lo que tu haces es simplemente usar los quaterniones para aplicar tres rotaciones por separado, exactamente lo mismo que si haces tres glRotates, solo que ahora en lugar de hacerlo a traves del API lo haces a traves de tu codigo. No has ganado nada aunque en algunos contextos pueda parecerte que si.

Una rotación 3D tiene que contener la información necesaria para pasar de un sistema a otro sistema de coordenadas en el que solo hay un cambio de orientación. No necesitas las famosas tres variables porque estas modelan algo que el quaternion ya tiene (y para colmo no lo hacen del todo bien).

El sistema debería ser:
- Mi camara tiene un quaternion que me indica como se ha de rotar todo el sistema.
- Si en algun momento mi camara cambia de rotación le aplico unicamente esa rotación a mi camara, ninguna más. Normalmente cualquier acción del usuario se puede resolver con una unica rotación, obviamente puedes aplicar muchas sucesivas pero eso sería si realmente se han producido varias acciones que impliquen rotaciones en diferentes ejes.
- No puedo tener directamente el angulo de pitch, roll o yaw porque estos valores son conceptos de percepción personal sobre las rotaciones, pero puedo aplicar trigonometria basica para obtener esos angulos si se el vector FRONT o el vector UP, que los puedo sacar facilmente de mi quaternion.

Estas pecando en lo mismo que pequé yo en su momento y que me llevó a perder un mes de desarrollo de mi juego de naves espaciales.

Lo que me llevó a ver la luz fué que me di cuenta de que es imposible guardar la rotación como tres angulos ya que no es lo mismo rotar 90 grados en Z y luego 90 en Y que rotar 90 en Y y luego 90 en Z. El resultado cambia.
Título: Camara En Opengl
Publicado por: angelfmarcos en 26 de Mayo de 2006, 11:36:33 PM
 Tambien lo había hecho asi. Y la navegación iba perfectamente, pero luego no sabía obtener la orientacion ni posicionar la camara con una orientacion concreta como punto de partida.

La aplicacion que estoy desarrollando es un editor de escenarios en el que vamos añadiendo primitivas, etc.. bastante sencillote, pero una de las cosas que debe poder hacer es manejar la camara mediante la posicion y la orientacion, para poder guardarlo en un fichero y recuperarlo posteriormente.

Estoy pensando que si en lugar de estos 3 valores guardo el x,y,z,w del quaternion podria volver a restaurar la camara sin problemas ¿es correcto?
Título: Camara En Opengl
Publicado por: tamat en 27 de Mayo de 2006, 12:38:41 AM
 Es correcto, sino mal contenedor de rotaciones sería.

Cualquier operacion que quieras para camaras seguro que la encuentras con quaterniones, yo de hecho para serte sincero no se como funcionan internamente los quaterniones, me limité a buscar una implementación y los metodos que no tenía los saqué tambien de internet.
Título: Camara En Opengl
Publicado por: killrazor en 27 de Mayo de 2006, 12:59:17 AM
 A ver, por partes. Es ineficiente por que todo el trabajo lo mandamos a la tarjeta mientras que con cuaterniones o camaras basadas en Euler la matriz la obtenemos directamente de un calculo hecho por el procesador, mucho mas eficiente y rapido. El quaternion hay que comprenderlo para saberle sacar el juguillo. La idea es que en general "volamos" con la camara asi que al final usamos los angulos tipicos de un avion (headin, pitch y roll). Eso implica los movimientos de los tres ejes. Con las camaras basadas en angulos Euler puedes tener un problema de gimbal lock y eso me hizo definitivamente decidirme por los quaterniones, pero eso es otra historia. Ademas es mas eficiente por que solo calculas una vez la matriz. Realmente juntar varias rotaciones es tan facil como multiplicar vectores. Eso lo hace un metodo muy potente, y lo unico que mandamos a la targeta es la matriz de rotacion.

Con cuaterniones lo unico que has de hacer para posicionar la camara es decidir donde miras, y el vector de la direccion a la que quieres mirar. Asi que no es dificil....
Título: Camara En Opengl
Publicado por: ethernet en 27 de Mayo de 2006, 10:11:37 AM
Cita de: "killrazor"A ver, por partes. Es ineficiente por que todo el trabajo lo mandamos a la tarjeta mientras que con cuaterniones o camaras basadas en Euler la matriz la obtenemos directamente de un calculo hecho por el procesador, mucho mas eficiente y rapido.
Umh? gluLookAt se calcula en CPU al igual que si tu lo haces con quaternion. Siguiendo tu política es mejor que calculemos las rotaciones, la iluminación, el blend e incluso los shaders en la CPU que es más rápida y eficiente. En cualquiera caso lee lo que te ha dicho tamat.

Nadie ha dicho que los quaternions sean fáciles o difíciles, pero para un desarrollo normal con gluLookAt es muchísimo más que suficiente. Nada impide usar quaternion junto con gluLookAt en cualquier caso.
Título: Camara En Opengl
Publicado por: senior wapo en 27 de Mayo de 2006, 04:42:09 PM
 Me da pereza buscar overengineering en wikipedia.

Si estás haciendo un editor 3D para poner entidades, lo normal no es que te muevas como en una nave espacial. Un control tipo FPS en la vista 3D es lo más común, que es la manera en que los mortales de a pie nos orientamos. ¿ Seguro que con eso no te vale ?

Con un par de operaciones de seno y coseno puedes orientar la cámara guardando sólo en ángulo de deriva (yaw) y el de cabeceo (pitch). Eso te da los vectores lookat, up y right a la hora de dibujar.

Tanto tiempo gastado en complicarse con super cámaras y al final le faltará el sistema de Undo (deshacer) :P

Edit: Si trabajas simplemente con ángulos, te basta restarle a la posición del objeto observado la de la cámara para obtener el vector lookat (normaliza...). Con un par de arcotangentes sacas los ángulos (que además te sirven para calcular los vectores up y right con sin() y cos() ).
Título: Camara En Opengl
Publicado por: angelfmarcos en 28 de Mayo de 2006, 12:01:50 PM
 Es un control ActiveX que sirve tanto para el editor de escenarios como para poder visualizar escenas y navegar en ellas.
Título: Alguien puede poner un codigo de ejemplo???
Publicado por: josette en 08 de Junio de 2006, 11:14:14 AM
Yo obtuve un codigo extraido de www.gametutorials.com en el apartado opengl pero tambien tengo algunos problemas. Alguien puede validar si esta clase funciona o si se puede adapar a lo que en este 'topic' se comenta?