Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





problema con transparencia en opengl

Iniciado por habier, 22 de Junio de 2007, 12:53:17 PM

« anterior - próximo »

habier

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.

tamat

Te toca descomprimir, es decir, crear los arrays de manera que los datos esten tal cual los usaría la tarjeta.

Esto significa que un vertice con dos posibles normales tiene que pasar a ser dos vertices, cada uno con su normal. Esto obviamente implica que tus arrays de vertices tendran muchas entradas repetidas, pero es la manera como se hace.

Un ejemplo sería el cubo, en teoria tienes 8 vertices y 24 normales, si descomprimes te quedan 24 vertices y 24 normales. Si ademas tienes UVs por vertice que pueden variar en funcion del triangulo al que pertenece el vertice pues aun crece más.

Esto se hace así porque es la manera más cómoda para el hardware de trabajar, ademas hoy en día las tarjetas tienen suficiente memoria para soportar ese overhead.
Por un stratos menos tenso

marcode

Está claro que donde más puedes ganar es indexando vértices.

Por ponerte un ejemplo, una malla de 10x10 tiene 200 triángulos, por lo que sin indexar serían 600 vértices e indexada se quedaría en 100, por lo que es un coste 6 veces mayor. En el caso de la chapa todos comparten la misma normal y casi se podría considerar como una malla deformada donde multitud de vértices de diferentes triángulos están repetidos.

Entonces para indexar:

- Creas una lista de índices del mismo tamaño que el número de triángulos x 3.

- Creas otras sin tamaño fijo (se desconoce) donde añadir las nuevas listas de vértices, normales, etc.

- Recorres la lista de triángulos a indexar y vas añadiendo cada componente de vértice a las nuevas listas, excepto si está en la misma posición o en una muy próxima que otro que se haya añadido ya, lo que significaría que está duplicado y se puede descartar.

- Si se ha agregado un nuevo vértice, añades a la de índices la posición en la lista a la que apunta dicho vértice.

- Pero si está duplicado, entonces añades a la de índices la posición que apunta al vértice existente (el primero que se añadió).

Más o menos es así. Si usas normales, o coordenadas de textura, deberás tener varias listas temporales (además de la de posición vértice) a las que ir añadiendo cada componente, todas serán del mismo tamaño.

Al final esas listas las metes en un buffer o creas otras de tamaño fijo, o lo que más te convenga.
size=9]afortunadamente siempre ha habido alguien dispuesto a reinventar la rueda, de lo contrario seguiríamos usando un disco de piedra con un agujero.[/size]

habier

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.

tamat

No es buena manera de medir el rendimiento por la de veces que pasa por display ya que si hay un swapbuffers por ahí entonces está limitandote la velocidad a la velocidad de refresco.

La mejor manera es renderizar 100 veces el mismo objeto y comparar FPS
Por un stratos menos tenso






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.