Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Ayuda con Transformaciones en openGL

Iniciado por kronos, 31 de Enero de 2008, 11:36:45 PM

« anterior - próximo »

kronos

Hola a todos.

Mi nombre es moisés y soy nuevo en esto de los gráficos, así que espero que mi pregunta no sea algo tonta.

Estoy tratando de aplicarle las transformaciones a una línea de la siguiente forma


glPushMatrix();
glMultMatrixf(&caja.m[0][0]);
glRotated(90,0,1,0);
glBegin(GL_LINES);
glVertex3f(0,0,0);
glVertex3f(100,0,0);
glEnd();
glPopMatrix();


Hasta aquí todo va bien, el problema es cuando yo quiero aplicarle directamente las transformaciones a los puntos para saber donde se encuentran y luego dibujar la línea.

Lo primero que hago es realizar las transformaciones obtener la matriz de transformaciones y aplicársela a cada punto individualmente:



float m[4][4];

glPushMatrix();
glMultMatrixf(&caja.m[0][0]);
glRotated(90,0,1,0);
glGetFloatv(GL_MODELVIEW_MATRIX,&m[0][0]);
glPopMatrix();

v1[0]=0;
v1[1]=0;
v1[2]=0;

v2[0]=100;
v2[1]=0;
v2[2]=0;

//Para el v1:

r[0]=v1[0]*m[0][0]+v1[1]*m[0][1]+v1[2]*m[0][2];
r[1]=v1[0]*m[1][0]+v1[1]*m[1][1]+v1[2]*m[1][2];
r[2]=v1[0]*m[2][0]+v1[1]*m[2][1]+v1[2]*m[2][2];

r[0]=r[0]+m[3][0];
r[1]=r[1]+m[3][1];
r[2]=r[2]+m[3][2];

v1[0]=r[0];
v1[1]=r[1];
v1[2]=r[2];

//Para el v2:

r[0]=v2[0]*m[0][0]+v2[1]*m[0][1]+v2[2]*m[0][2];
r[1]=v2[0]*m[1][0]+v2[1]*m[1][1]+v2[2]*m[1][2];
r[2]=v2[0]*m[2][0]+v2[1]*m[2][1]+v2[2]*m[2][2];

r[0]=r[0]+m[3][0];
r[1]=r[1]+m[3][1];
r[2]=r[2]+m[3][2];

v2[0]=r[0];
v2[1]=r[1];
v2[2]=r[2];

//Dibujamos la linea

glPushMatrix();
       glBegin(GL_LINES);
glVertex3f(v1[0],v1[1],v1[2]);
glVertex3f(v2[0],v2[1],v2[2]);
glEnd();
glPopMatrix();



Pero le resultado no es el mismo, la línea la dibuja en otro lado y realmente no se donde esta el problema, alguien me podría ayudar?

Martinez

Las multiplicaciones hay que hacerlas con la matrix transpuesta. Te pongo un codigo de ejemplo

Nota: otra forma de hacerlo en mi segundo post. Esta forma necesita glext.h

void MultMatrix(GLdouble *m, GLdouble *v)
{
   GLdouble r[4];
   for(int i=0; i<12; i+=4)
       r[i/4]=   v[0]*m[i]
               + v[1]*m[i+1]
               + v[2]*m[i+2]
               + v[3]*m[i+3];
   r[3]=1; // Este componente tiene que valer 1 sino esta mal si se usa en
              // en glVertex4dv(r);

   memcpy(v,r,sizeof(r));

}

//........

glLoadIdentity();
GLdouble matrix[16];
glGetDoublev(GL_TRANSPOSE_MODELVIEW_MATRIX,matrix1);
// .......

glPushMatrix();
  glLoadTransposeMatrixd(matrix);
  glRotatef(180,0,1,0);
  glGetDoublev(GL_TRANSPOSE_MODELVIEW_MATRIX,matrix1);
glPopMatrix();

GLdouble v1[]={-2,-1,0,1};

MultMatrix(matrix1,v1);
//....
glVertex3dv(v1);
//.....




Puedes trabajar con floats, solo tienes que cambiar los tipos y las funciones por glGetDoublef, glVertex3fv.

kronos

Gracias por la respuesta "Martines"

Solo que tengo el mismo problema, primero no puedo utilizar "GL_TRANSPOSE_MODELVIEW_MATRIX" ya que estoy utilizando visul studio 2003, pero me dice que no esta definido:

pero eso no importa ya que es la transpuesta asi que solo se mueve el indice y tengo lo siguiente:



void MultMatrix(float *m, float *v){
   float r[4];
for(int i=0; i<4; i+=1)
       r[i/4]=v[0]*m[i] + v[1]*m[i+4] + v[2]*m[i+8] + v[3]*m[i+12];

   r[3]=1;

   memcpy(v,r,sizeof(r));
}


pero aun no dibuja la linea correctamente la dibuja en otro lugar.

Martinez

Esta definido en glext.h, pero mejor usa esta forma:



void MultMatrix(GLdouble *m, GLdouble *v)
{
   GLdouble r[4];
   for(int i=0; i<12; i+=4)
       r[i]=   v[0]*m[i]
               + v[1]*m[i+1]
               + v[2]*m[i+2]
               + v[3]*m[i+3];
   r[3]=1; // Este componente tiene que valer 1 sino esta mal si se usa en
              // en glVertex4dv(r);

   memcpy(v,r,sizeof(r));

}

.........
glPushMatrix();
       glLoadIdentity();
       glRotatef(90,0,0,1);

       glGetDoublev(GL_MODELVIEW_MATRIX,matrix1);
glPopMatrix();

.....


El error lo tenias en  for(int i=0; i<4; i+=1) r[i/4]....

Si cambias el for cambia el r. XDXD.

Nos vemos, Matrinez.

kronos

Aquí molestando nuevamente con lo mismo

Para no errar utilice el codigo de "Martinez"

Para obtener la matriz y dibujar una linea amarilla de referencia tengo lo siguiente



GLdouble v1[]={0,0,0,1};
GLdouble v2[]={100,0,0,1};
GLdouble m[16];

glPushMatrix();
  glColor3f(1,1,0);
  glMultMatrixf(&caja.m[0][0]);
  glRotated(90,0,1,0);
  glGetDoublev(GL_TRANSPOSE_MODELVIEW_MATRIX,&m[0]);
  glBegin(GL_LINES);
      glVertex3dv(v1);
      glVertex3dv(v2);
  glEnd();
glPopMatrix();



Luego le aplicamos la matriz a los puntos y los dibujamos


MultMatrix(m,v1);
MultMatrix(m,v2);

glPushMatrix();
  glColor3f(1,1,1);
  glBegin(GL_LINES);
      glVertex3dv(v1);
      glVertex3dv(v2);
  glEnd();
glPopMatrix();



Donde MulMatrix es:



void MultMatrix(GLdouble *m, GLdouble *v){
   GLdouble r[4];
   for(int i=0; i<12; i+=4)
       r[i/4]= v[0]*m[i] + v[1]*m[i+1]+v[2]*m[i+2]+ v[3]*m[i+3];
   r[3]=1;
   memcpy(v,r,sizeof(r));
}



pero tengo lo siguinte

//http://kronos2008.blogspot.com/

Como pueden ver en los videos, si dibuja la línea pero no en el lugar donde debería (en el lugar de la línea amarilla), y lo extraño es que cambia la posición de la línea según el observador

alguna sugerencia

kronos

Finalmente encontré el problema, lo que sucedía es que cuando le aplicaba las transformaciones a los puntos y los dibujaba, le aplicaba nuevamente la matriz MODELVIEW.

Entonces para solucionar el problema simplemente tengo que cargar la identidad y dibujar los puntos.



glPushMatrix();
     glLoadIdentity();
     glBegin(GL_LINES);
          glVertex3f(v1[0],v1[1],v1[2]);
          glVertex3f(v2[0],v2[1],v2[2]);
     glEnd();
glPopMatrix()


Perdon por la molestia






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.