Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Menu

Mostrar Mensajes

Esta sección te permite ver todos los posts escritos por este usuario. Ten en cuenta que sólo puedes ver los posts escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menu

Mensajes - habier

#1
hola,

muchas gracias :) se nota la mejora de rendimiento.

Lo he hecho tal como me deciais, acabo de terminar de implementarlo. Ha sido un poco lio hasta que sacas los arrays como se necesitan, al menos respecto a como lo tenía yo antes, pero ha merecido la pena.

Ahora tengo el array de vertices. Primero quito duplicados, y luego duplico los vértices por cada smoothing group al que pertenezcan (cambiando los índices de los triángulos para apuntar al vértice con mismo smoothing group). Y las normales igual, una para cada vértice (contando los duplicados).

Luego paso estos arrays a opengl y uso glDrawElements con los triangulos de índices. Para medir cuanto mejoraba lo he hecho en plan rápido: he puesto un trozo de código que cuenta cuantas veces se pasa por la función de Display (la aplicación con la que pruebo apenas consume tiempo en otro sitio) en aproximadamente 15 segundos. Con la manera nueva pasa al menos el triple de veces que con glBegin...glEnd.
#2
hola,

muchas gracias otra vez :) no tenía ni idea de que se podía hacer esto. Ahora mismo estoy implementandolo.

Para los vértices no tengo ningún problema para pasarlo a esta nueva manera. Tengo un array de vértices y otro de triángulos (cada posición son 3 indices al array de vértices), así que podría usar glDrawElements.

Pero para las normales sí que me ha surgido un problema. Con lo de los smoothing groups tengo varias normales para cada vértice, dependiendo de la cara que se dibuje. En realidad lo tengo almacenado como un array de posiciones igual al número de caras totales y cada posición del array almacena otro sub-array de tres normales (las de los tres vértices de ese triángulo para ese triángulo).

¿Teniéndolo así que podría hacer? Había pensado que los triángulos en vez de como array de índices los guardo directamente como array de vértices y uso glDrawArrays, para poder tener diferentes normales para los vértices dependiendo de la cara en la que esté. Pero si esto no se puede hacer creo que directamente pasaré de los smoothing groups y tendré una única normal para cada vértice.
#3
CitarSobre lo de pintar por materiales, pues es lo más normal, no se como haras tu el render pero no creo que vayas cambiando el material para cada poligono que pintas (si haces algo así entonces que sepas que eso es super-ineficiente).

Hola Tamat, ahora mismo tengo una clase que representa un objeto, que contiene sus vertices, triangulos, normales, material de cada cara, etc.. Para los materiales lo que tengo es un array de tamaño igual al numero de caras del objeto que contiene indices al array de materiales, de manera que para cada cara en esa posicion del array tengo un indice al material que tiene. En el fichero 3ds las caras vienen ordenadas por material, asi que me parece que no voy cambiando de material todo el rato, pero si que es verdad que cada vez que voy a pintar un triangulo previamente hago la llamada a glMaterialfv para configurar el material de la cara, aunque este no haya cambiado y sea el mismo que el de la cara que dibuje justo antes. Esto puede ser ineficiente?

CitarLo normal es tener empaquetados los modelos por materiales, si hay el mas ligera cambio de material entonces ese va a otro objeto, si luego empaquetas los vertices/normales/uvs en streams y los subes a la tarjeta pues ya tienes el 90% de eficiencia de tu tarjeta.

He estado buscando sobre esto, pero no he encontrado nada. Como se puede subir toda esa informacion de golpe a la tarjeta con un stream? Es de otra manera distinta a glBegin(GL_TRIANGLES), glNormal3f, glVertex, etc..?

Gracias por vuestras respuestas, me hay ayudado muchisimo :)
#4
hola Tamat,

perdona, estaba respondiendo cuando entro tu respuesta. Tambien de lejos a cerca? :S eso si que me supone varios cambios, pero bueno. Supongo que eso, si no lo hago asi, dará problemas cuando tenga varios objetos trasparentes seguidos verdad?

Gracias!
#5
muchas gracias Shaitan, me has resuelto el problema :) ahora se me esta viendo perfecto:



Los cristales del coche son objetos trasparentes, y se ve perfecto lo de dentro.

Aprovechando el hilo queria hacer otra pregunta relacionada: merece la pena implementarlo de tal manera que en caso de que un objeto algunas caras las tenga con materiales trasparentes y otras no, se pinte por partes las caras, para que las solidas se pinten con todo lo solido y lo trasparente despues? Osea, que pasaria si tengo un objeto solido y trasparante a trozos? es frecuentes esto? Tal como lo tengo implementado seria bastante coñazo tener que soportar ese caso, si no se suele dar casi que lo dejo asi, pero si es frecuente encontrar modelos asi lo tendre que hacer.

Un saludo y gracias otra vez.
#6
hola a todos,

estoy cargando un modelo a partir de un fichero .3ds, cargo los colores del material y la trasparencia (y el shininess, y todo eso), y luego se los aplico. El problema que tengo es que la trasparencia parece que funciona, al menos le da un aspecto como traslucido al objeto, pero no va bien del todo, no se ve nada de lo que hay detras, solo un poco la parte de atras del mismo objeto. Pongo una captura:



Lo de arriba es el modelo como es. Lo de abajo es lo que veo cuando cargo yo el modelo. A parte de los colores que se van diferentes por las luces y todo eso, al menos si lo estuviera haciendo bien se veria algo de la pelota.

El codigo donde hago esto lo pongo abajo, mas o menos se ve en que orden llamo a las funciones de opengl y eso. Pongo las luces, calculo el material y le doy los vertices del trianglo y sus normales.

Antes de usar materiales usaba la funcion gColor4f y entonces si que se hacia bien la trasparencia, se veia lo de tras y eso.

Sabeis por que puede ser esto?

Un saludo y muchas gracias.


glLightfv (GL_LIGHT0, GL_AMBIENT, Light->ambient);
glLightfv (GL_LIGHT0, GL_DIFFUSE, Light->diffuse);
glLightfv (GL_LIGHT0, GL_SPECULAR, Light->specular);
glLightfv (GL_LIGHT0, GL_POSITION, TempLightPos);
glEnable (GL_LIGHTING);
glEnable (GL_LIGHT0);
   
   for (i=0;i<Obj->nObjectTriangles;i++)
   {
     glEnable(GL_BLEND);
     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

     Camera->VertexFromCamera(&Obj->WorldObjectVertexes[Obj->ObjectTriangles[i].a],&CameraVertexa);
     Camera->VertexFromCamera(&Obj->WorldObjectVertexes[Obj->ObjectTriangles[i].b],&CameraVertexb);
     Camera->VertexFromCamera(&Obj->WorldObjectVertexes[Obj->ObjectTriangles[i].c],&CameraVertexc);

     float mat_ambient[]=
     {((float)Obj->ObjectInfo3ds->Materials[Obj->ObjectInfo3ds->FaceMaterial[i]]->AmbientColorRgba.r)/0xff,
      ((float)Obj->ObjectInfo3ds->Materials[Obj->ObjectInfo3ds->FaceMaterial[i]]->AmbientColorRgba.g)/0xff,
      ((float)Obj->ObjectInfo3ds->Materials[Obj->ObjectInfo3ds->FaceMaterial[i]]->AmbientColorRgba.b)/0xff,
      ((float)(100-((float)Obj->ObjectInfo3ds->Materials[Obj->ObjectInfo3ds->FaceMaterial[i]]->Transparency)))/100};
     float mat_diffuse[]=
     {((float)Obj->ObjectInfo3ds->Materials[Obj->ObjectInfo3ds->FaceMaterial[i]]->DiffuseColorRgba.r)/0xff,
      ((float)Obj->ObjectInfo3ds->Materials[Obj->ObjectInfo3ds->FaceMaterial[i]]->DiffuseColorRgba.g)/0xff,
      ((float)Obj->ObjectInfo3ds->Materials[Obj->ObjectInfo3ds->FaceMaterial[i]]->DiffuseColorRgba.b)/0xff,
      ((float)(100-((float)Obj->ObjectInfo3ds->Materials[Obj->ObjectInfo3ds->FaceMaterial[i]]->Transparency)))/100};  
     float mat_specular[]=
     {((float)Obj->ObjectInfo3ds->Materials[Obj->ObjectInfo3ds->FaceMaterial[i]]->SpecularColorRgba.r)/0xff,
      ((float)Obj->ObjectInfo3ds->Materials[Obj->ObjectInfo3ds->FaceMaterial[i]]->SpecularColorRgba.g)/0xff,
      ((float)Obj->ObjectInfo3ds->Materials[Obj->ObjectInfo3ds->FaceMaterial[i]]->SpecularColorRgba.b)/0xff,
      ((float)(100-((float)Obj->ObjectInfo3ds->Materials[Obj->ObjectInfo3ds->FaceMaterial[i]]->Transparency)))/100};
     float mat_selfillum[]=
     {((float)Obj->ObjectInfo3ds->Materials[Obj->ObjectInfo3ds->FaceMaterial[i]]->SelfIllumColorRgba.r)/0xff,
      ((float)Obj->ObjectInfo3ds->Materials[Obj->ObjectInfo3ds->FaceMaterial[i]]->SelfIllumColorRgba.g)/0xff,
      ((float)Obj->ObjectInfo3ds->Materials[Obj->ObjectInfo3ds->FaceMaterial[i]]->SelfIllumColorRgba.b)/0xff,
      ((float)(100-((float)Obj->ObjectInfo3ds->Materials[Obj->ObjectInfo3ds->FaceMaterial[i]]->Transparency)))/100};

       glMaterialfv (GL_FRONT, GL_AMBIENT, mat_ambient);
       glMaterialfv (GL_FRONT, GL_DIFFUSE, mat_diffuse);
       glMaterialfv (GL_FRONT, GL_SPECULAR, mat_specular);
       glMaterialf (GL_FRONT, GL_SHININESS,1.28*((float)Obj->ObjectInfo3ds->Materials[Obj->ObjectInfo3ds->FaceMaterial[i]]->Shininess));

     glBegin(GL_TRIANGLES);

     Obj->GetWorldVertexNormal(i,0,&Normal);
     Normal.x+=Obj->WorldObjectVertexes[Obj->ObjectTriangles[i].a].x;
     Normal.y+=Obj->WorldObjectVertexes[Obj->ObjectTriangles[i].a].y;
     Normal.z+=Obj->WorldObjectVertexes[Obj->ObjectTriangles[i].a].z;
     Camera->VertexFromCamera(&Normal,&Normal);
     Normal.x-=CameraVertexa.x;
     Normal.y-=CameraVertexa.y;
     Normal.z-=CameraVertexa.z;
     glNormal3f(Normal.x,Normal.y,Normal.z);

     glVertex3f( CameraVertexa.x,    
                 CameraVertexa.y,    
                 CameraVertexa.z );

     Obj->GetWorldVertexNormal(i,1,&Normal);
     Normal.x+=Obj->WorldObjectVertexes[Obj->ObjectTriangles[i].b].x;
     Normal.y+=Obj->WorldObjectVertexes[Obj->ObjectTriangles[i].b].y;
     Normal.z+=Obj->WorldObjectVertexes[Obj->ObjectTriangles[i].b].z;
     Camera->VertexFromCamera(&Normal,&Normal);
     Normal.x-=CameraVertexb.x;
     Normal.y-=CameraVertexb.y;
     Normal.z-=CameraVertexb.z;
     glNormal3f(Normal.x,Normal.y,Normal.z);

     glVertex3f( CameraVertexb.x,    
                 CameraVertexb.y,    
                 CameraVertexb.z );

     Obj->GetWorldVertexNormal(i,2,&Normal);
     Normal.x+=Obj->WorldObjectVertexes[Obj->ObjectTriangles[i].c].x;
     Normal.y+=Obj->WorldObjectVertexes[Obj->ObjectTriangles[i].c].y;
     Normal.z+=Obj->WorldObjectVertexes[Obj->ObjectTriangles[i].c].z;
     Camera->VertexFromCamera(&Normal,&Normal);
     Normal.x-=CameraVertexc.x;
     Normal.y-=CameraVertexc.y;
     Normal.z-=CameraVertexc.z;
     glNormal3f(Normal.x,Normal.y,Normal.z);

     glVertex3f( CameraVertexc.x,    
                 CameraVertexc.y,    
                 CameraVertexc.z );
     
     glEnd();
     glDisable(GL_BLEND);
#7
Programación gráfica / obtener normales de un terreno
15 de Junio de 2007, 02:27:39 PM
hola,

yo para calcular las normales de los vertices (por si te vale de algo) he usado lo del smoothing group del fichero 3ds, pero en tu caso que creo que no tienes smoothing group vi por ahi que lo q se hacia es lo que se llama average normals, que no se si es lo mismo que comentabais atras.. pero es bastante sencillo.. seria esto nada mas:

for each vertex {
  vertex normal = zero
}
for each face {
  calculate face normal
  add face normal to all 3 vertex normals of face
}
for each vertex {
  noramlize vertex normal
}

osea, tienes un array de normales con N normales, y N es el numero de vertices, y cada vez q pasas por un triangulo sumas a la vertex normal de los 3 vertices del triangulo la face normal de ese triangulo. Y al final normalizas.
#8
Si pones el modo ese GL_LINE (creo que es ese, el que no es GL_FILL me refiero) igual pasara lo que quieres tu? O igual las texturas tampoco se veran.. ni idea, pero por probar..
#9
hola,

estoy haciendo un trozo de codigo para cargar objectos a partir de archivos 3ds. Estoy teniendo problemas con un campo. Seria el chunkid 0xa080, que se supone que es el color de la autoiluminación del objeto. El caso es que creo un material en 3d studio, le pongo autoiluminación y se lo asigno a un objeto, pero luego a parsear el fichero 3ds no encuentro el campo 0xa080, solamente encuentro el 0xa084, que es la intensidad de la autoiluminación.

Habia pensado que a lo mejor cambiara los colores ambiente, diffuse o specular pero no cambia nada de eso. De que parte se lee el color de la iluminacion? Deberia ser de ese campo, pero ya digo, solo mete el 0xa084.
#10
hola de nuevo,

pongo este post para cerrar lo que preguntaba en el anterior. Ya encontre el problema asi que os lo comento, mas que nada por si alguien necesita este mismo codigo que he usado yo quizas le venga bien.

A mi me estaba fallando porque estaba calculando mal las extents. Estaba restando el vertice 5 del cubo menos el vertice 3. Pero el problemas es que lo hacia asi incluso aunque el cubo no estuviera alineado con los ejes. Entonces me salia mal las extents.

El codigo funciona perfecto, por si alguien mas lo esta usando o lo piensa usar.

Un saludo.
#11
hola,

soy nuevo por aquí (así como en el mundillo del 3d) así que aprovecho este post para presentarme también.

me gustaría hacer una pregunta sobre una pieza de código que he encontrado que implementa un test de colisión entre dos oriented bounding boxes. El código lo saqué de aquí:

http://www.gamasutra.com/features/19991018/Gomez_5.htm

El autor es Miguel Gómez. Me da la impresión que es un tutorial y trozo de código bastante conocido, por ejemplo un motor (opcode 1.2) lo usa, y lo he visto comentado en distintos foros.

El problema que tengo es llamando a la función OBBOverlap. Varias veces funciona y me devuelve correctamente si colisiona o no, pero cuando las dos boxes están en algunos ángulos y posiciones entre ellas lo que me devuelve es erroneo. Se ve claramente que no colisionan, pero me devuelven que sí.

Mi pregunta es si alguien por aquí ha usado esta función y en este caso de que manera le pasa los parámetros. A mi me parecía que estaba haciendo bien, y intentando seguir el código de la función me lo sigue pareciendo, pero en algunos casos me dice que colisionan cuando no es así.

La función tiene este prototipo:

//check if two oriented bounding boxes overlap
const bool OBBOverlap
(
//A
VECTOR& a, //extents
VECTOR& Pa, //position
VECTOR* A, //orthonormal basis
//B
VECTOR& b, //extents
VECTOR& Pb, //position
VECTOR* B //orthonormal basis
)

Teniendo las caras mas alta y mas baja de la caja así:

  v7 - v6
 /       /
v4 - v5

v3 - v2
/      /
v0 - v1

El extent (a) lo calculo así:

 Extents.x = fabs((v5->x - v3->x)/2);
 Extents.y = fabs((v5->y - v3->y)/2);
 Extents.z = fabs((v5->z - v3->z)/2);

La posición (Pa):

 Position.x = ((v5->x - v3->x)/2) + v3->x;
 Position.y = ((v5->y - v3->y)/2) + v3->y;
 Position.z = ((v5->z - v3->z)/2) + v3->z;

La base ortonormal (A) así:

 OrthoBasis[0].x = v2->x - v3->x;
 OrthoBasis[0].y = v2->y - v3->y;
 OrthoBasis[0].z = v2->z - v3->z;

 normalize(OrthoBasis[0]);

 OrthoBasis[1].x = v7->x - v3->x;
 OrthoBasis[1].y = v7->y - v3->y;
 OrthoBasis[1].z = v7->z - v3->z;
 
 normalize(OrthoBasis[1]);

 OrthoBasis[2].x = v0->x - v3->x;
 OrthoBasis[2].y = v0->y - v3->y;
 OrthoBasis[2].z = v0->z - v3->z;

 normalize(OrthoBasis[2]);

Veis algo mal?

Si no habeis usado esta, teneis alguna otra implementación de este test de colisiones?

Un saludo y gracias.





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.