Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Presentacion Y -> ¿a Donde Se Me Va La Luz?

Iniciado por The-Force, 24 de Mayo de 2005, 11:27:44 PM

« anterior - próximo »

The-Force

 Antes que nada saludaros a todos ya que es mi primer post aqui... Hola XD
Soy principiante en esto de la programacion grafica y en principio me he puesto a aprender algo de OpenGL que por alguna razon prefiero antes que Direct3D.

Para ir aprendiendo he partido de un  tutorial en c++ de SDL y le he ido añadiendo cosas. Unas librerias con clases para objetos y la clase mundo, un cargador de objetos desde ficheros .ac (el primero que vi facil de exportar desde el blender), fisica imitacion de gravedad y poco mas. Lo unico para lo que usaba opengl de momento era para dibujar los objetos en su posicion.

El problema viene cuando meto una luz y el objeto o la escena rota.  La luz desaparece y aparece y no como deberia.
Esta claro ke alguna chorrada estare haciendo pero...cual?

Sospecho que el problema esta aqui y en que ni idea de como posicionar una luz
//----------------------------------------------
glMatrixMode( GL_MODELVIEW );

  for(int i = 0; i < Mundo.NumObjetos; i++)                // pa todos los objetos de la escena....
  {
      glLoadIdentity( );

      glTranslatef( 0.0, 0.0, dist );                                 // translado la escena

      glRotatef(angle,0.0f,1.0f,0.0f);                             // roto la escena (si es ke tiene ke rotar)

      glTranslatef(Mundo.LObjetos.Pos.x,                 //  translado a la posicion del objeto
                          Mundo.LObjetos.Pos.y,
                          Mundo.LObjetos.Pos.z);

      glRotatef(Mundo.LObjetos.Rot.x,1.0f,0.0f,0.0f);     // roto el objeto (si es ke tiene ke rotar)
      glRotatef(Mundo.LObjetos.Rot.y,0.0f,1.0f,0.0f);
      glRotatef(Mundo.LObjetos.Rot.z,0.0f,0.0f,1.0f);

      // pintar triangulitos del objeto a saco
 }
//----------------------------------------------

Si yo defino una posicion para la luz, cuando translado, roto, translado.... el eje de coordenadas para dibujar un objeto, La posicion de la luz (que he definido mucho antes) sera desde este nuevo eje movido o desde el identidad? o que?
y ya de paso... como hago para cambiar la posicion de una luz?

Pido perdon por ser tan patetico ^^

BeRSeRKeR

 Teniendo en cuenta que hace muuuuuuuuchos años que no programo en OpenGL...

La primera pregunta obligada es si especificas las normales del modelo y si es así, ¿están normalizadas?. Si no están normalizadas siempre puedes activar la normalización automática de OpenGL (no recuerdo cuál es el flag).

Por otra parte, las transformaciones que apliques a los objetos no afectan a la luz. Además se supone que la posición de la luz ya la especificas en world-space.

Saludos.
¡Si te buscan en nombre de la ley, huye en nombre de la libertad!!

The-Force

 No aun no especifico las normales. Es algo ke hare dentro de poco ^^.

He probado a meter dos objetos en la escena y la luz mantenerla en un punto fijo (30,0,0) a la derecha de ambos objetos.  Uno de los obejetos no rota y se ilumina correctamente por mucho que se mueva. El otro objeto rota en sentido antihorario sobre el eje 'Y' y el reflejo de la luz se mueve  de derecha a izq y al rato vuelve a aparecer por la derecha.
no lo entiendo
:(

BeRSeRKeR

 Pues sin normales lo raro es que se ilumine bien alguno de los objetos. Ten en cuenta que la normal es primordial en el cálculo de la iluminación. Así que si quieres iluminación, tendrás que especificar antes las normales de tus modelos.

Saludos.
¡Si te buscan en nombre de la ley, huye en nombre de la libertad!!

The-Force

 Ok pues manos a la obra. Ya te contare ke tal  

O2

 Yo tambien hace tiempo que me pasé al lado oscuro de D3D y no uso GL, pero si no recuerdo mal, podias activar la normalización automática con:

glEnable(GL_NORMALIZE);

Aunque si las normalizas tú antes de dibujar, eso que le ahorras...

Saludos.

The-Force

 Arreglado! Calcule las normales, las normalize (pase de usar el GL_NORMALIZE) y  :blink:  funciona!
Tambien comprobe que la luz la podia colocar donde quisiera de igual manera que cualquier objeto. Vamos que las transformaciones del eje de coordenadas le afectaban.

Muchas gracias a BeRSeRKeR y O2 por ayudarme.

Buffon

Cita de: "The-Force"Antes que nada saludaros a todos ya que es mi primer post aqui... Hola XD
Soy principiante en esto de la programacion grafica y en principio me he puesto a aprender algo de OpenGL que por alguna razon prefiero antes que Direct3D.

Para ir aprendiendo he partido de un  tutorial en c++ de SDL y le he ido añadiendo cosas. Unas librerias con clases para objetos y la clase mundo, un cargador de objetos desde ficheros .ac (el primero que vi facil de exportar desde el blender), fisica imitacion de gravedad y poco mas. Lo unico para lo que usaba opengl de momento era para dibujar los objetos en su posicion.

El problema viene cuando meto una luz y el objeto o la escena rota.  La luz desaparece y aparece y no como deberia.
Esta claro ke alguna chorrada estare haciendo pero...cual?

Sospecho que el problema esta aqui y en que ni idea de como posicionar una luz
//----------------------------------------------
glMatrixMode( GL_MODELVIEW );

  for(int i = 0; i < Mundo.NumObjetos; i++)                // pa todos los objetos de la escena....
  {
      glLoadIdentity( );

      glTranslatef( 0.0, 0.0, dist );                                 // translado la escena

      glRotatef(angle,0.0f,1.0f,0.0f);                             // roto la escena (si es ke tiene ke rotar)

      glTranslatef(Mundo.LObjetos.Pos.x,                 //  translado a la posicion del objeto
                          Mundo.LObjetos.Pos.y,
                          Mundo.LObjetos.Pos.z);

      glRotatef(Mundo.LObjetos.Rot.x,1.0f,0.0f,0.0f);     // roto el objeto (si es ke tiene ke rotar)
      glRotatef(Mundo.LObjetos.Rot.y,0.0f,1.0f,0.0f);
      glRotatef(Mundo.LObjetos.Rot.z,0.0f,0.0f,1.0f);

      // pintar triangulitos del objeto a saco
 }
//----------------------------------------------

Si yo defino una posicion para la luz, cuando translado, roto, translado.... el eje de coordenadas para dibujar un objeto, La posicion de la luz (que he definido mucho antes) sera desde este nuevo eje movido o desde el identidad? o que?
y ya de paso... como hago para cambiar la posicion de una luz?

Pido perdon por ser tan patetico ^^
como bien has hecho, no uses nunca glEnable(GL_NORMALIZE)

te va a ralentizar muchisimo tu código.

----------------------

otra cosa que me ha hecho daño y que se haría bien de optimización a la hora de tener mucho objetos en el mundo.

piensa que tu haces una cuantas rotaciones totalmente iguales para todos los objetos o meshes de tu escena, con lo cuál eso podría hacerse al principio.

//----------------------------------------------
glMatrixMode( GL_MODELVIEW );

glLoadIdentity( );

glTranslatef( 0.0, 0.0, dist );                                 // translado la escena

glRotatef(angle,0.0f,1.0f,0.0f);                             // roto la escena (si es ke tiene ke rotar)

  for(int i = 0; i < Mundo.NumObjetos; i++)                // pa todos los objetos de la escena....
  {
      glPushMatrix();
      glTranslatef(Mundo.LObjetos[i].Pos.x,                 //  translado a la posicion del objeto
                          Mundo.LObjetos[i].Pos.y,
                          Mundo.LObjetos[i].Pos.z);

      glRotatef(Mundo.LObjetos[i].Rot.x,1.0f,0.0f,0.0f);     // roto el objeto (si es ke tiene ke rotar)
      glRotatef(Mundo.LObjetos[i].Rot.y,0.0f,1.0f,0.0f);
      glRotatef(Mundo.LObjetos[i].Rot.z,0.0f,0.0f,1.0f);

      // pintar triangulitos del objeto a saco
      glPopMatrix();
 }
//----------------------------------------------


zupervaca

 como dice buffon gl_normalize hace que opengl calcule siempre que pintas un triangulo su normal, lo mejor es tenerlo precalculado, si quieres mas info descargate mi clase vector (tiene tiempo y es muy simple) en la que tengo una funcion para realizar los calculos necesarios para calcular las normales y normalizarlas

http://www.davidib.com/codigofuente/cpp/vector.rar

saludos

The-Force

 Cambios sugeridos aplicados y funcionando ^^.
Mola eso de la pila de matrices. No lo conocia

La funcion que habia implementado para calcular las normales , calculaba la normal a las caras.
He implementado otra que calcula las normales promediadas de cada vertice. El resultado es mucho mas bonito ^^


The-Force

 Aqui van dos capturas de lo que estoy haciendo para comentaros algo sobre las normales.

Usando normales a cara:



Usando normales a vertices con promedio:


Diria que el problema es ese y que antes de promediar habria que fijarse si el angulo entre las dos normales es muy grande.
¿Estoy en lo correcto? si es asi ¿Como?

(Aclaro que esas pequeñas rayitas que se ven saliendo de los planetitas no son ningun fallo. Solo indican la direccion en la que se mueve el objeto)

BeRSeRKeR

 Así a simple vista es complicado saber la causa pero ten en cuenta que estás haciendo iluminación per-vertex y si la malla no es lo suficientemente densa, la iluminación no será todo lo suave que quisieras.

Por otro lado, lo de calcular el ángulo entre las normales para saber si debes promediar o no....yo no sé si lo haría. Ten en cuenta que normalmente tus modelos los harás en un programa de modelado y ahí tendrás acceso a los smoothing groups que sirven precisamente para eso, para saber si un vértice se tiene que duplicar de forma que a la hora de calcular las normales, no se promedie con las caras contiguas.

Saludos.
¡Si te buscan en nombre de la ley, huye en nombre de la libertad!!

_Grey

 
CitarDiría que el problema es ese y que antes de promediar habría que fijarse si el ángulo entre las dos normales es muy grande.
¿Estoy en lo correcto? si es así ¿Como?

Esto es normal, con el gouraud se interpolan los valores de la luz por todo el polígono, y si tienes un polígono muy largo puede terminar viéndose feo por que parece que influyen "demasiado" los valores de unos extremos que coinciden con polígonos mas pequeños, simplemente parece "no muy correcto".

De todas formas puedes hacer que las normales de los polígonos mas grandes "pesen" mas que las normales de los polígonos mas pequeños; esto lo digo de memoria, igual no es del todo correcto, pero cuando calcules la normal que es el promedio de las normales de los polígonos circundantes hazlo con las normales SIN normalizar, LUEGO normalizas esa normal que has obtenido, deveria ser así mas o menos, pero eso de lo que preguntas es "normal" en un principio.

Ya nos contaras, saludos.






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.