Foros - Stratos

Programadores => Programación gráfica => Mensaje iniciado por: DraKKaR en 12 de Octubre de 2002, 09:08:18 PM

Título: Ayuda con los index buffers de Direct3D
Publicado por: DraKKaR en 12 de Octubre de 2002, 09:08:18 PM
                                Bueno, a ver si me podeis echar una ayudita ke yo ya no se donde puede estar el fallo. El problema surgio al hacer el render por octrees. Para renderizar voy guardando en una lista todos los vertices visibles (calculando la visibilidad de estos por octrees) y una vez hecho los renderizo a base de primitivas indexadas. Como mi engine soporta las 2 APIS (o deberia soportarlas XD) pues primero lo hice en OpenGL, y no da ningun problema, por lo ke me lleva a pensar ke e sistema funciona y debe ser algo ke hago mal en DirectD, pues cuando lo fui a codificar para este ultimo API usando Index Buffers la cosa se desmadro.

Voy a poneros el codigo de como inicializo las cosas para los index buffers y como lo renderizo a ver si veis alguna pega.

Podemos partir de la suposicion ke lo de los VERTEX buffers esta bien hecho puesto ke eso ya me funcionaba bien.



Asi pues inicializo el INDEX buffer asi:

d3dDevice->CreateIndexBuffer(
   numi*sizeof(unsigned int),
   0,
   D3DFMT_INDEX32,
   D3DPOOL_DEFAULT,
   &ib);
donde:
- numi es el numero de vertices ke en mi caso = numero de vertices
- ib es el IndexBuffer




Antes de renderizar relleno el indexbuffer asi:

void *auxdat;
ib->Lock(0,numi*sizeof(unsigned int), (BYTE**)&auxdat,0);
memcpy(auxdat,indices,numi*sizeof(unsigned int));
ib->Unlock();

donde: indices es el array de enteros ke continee los indices




Y para hacer el render, entre otras cosas hago: (no os lo pasteo todo por claridad, si kereis ke os pastee toda la funciond e render...):

d3dDevice->SetStreamSource( 0, vb, sizeof(D3DCUSTOMVERTEX_2TEX) );

d3dDevice->SetVertexShader( D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1 );

d3dDevice->SetIndices(ib,0);

d3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, numi, 0, numi/3 );   


Hete aki, a ver si alguien puede decirme donde tengo el fallo.
Se me olvidaba decir el problema ke me hace. Pues bien, me renderiza todo pero segun la posicion de la camara desaparecen poligonos o aparecen otros nuevos ke no deberian salir.

Gracias a todos de antemano.                                
Título: Ayuda con los index buffers de Direct3D
Publicado por: BeRSeRKeR en 12 de Octubre de 2002, 09:43:59 PM
                                No todas las aceleradoras soportan índices de 32 bits (de echo muy pocas, creo). Prueba a crear el index buffer con D3DFMT_INDEX16...

Saludos

PD: por supuesto, los índices serían de tipo WORD y al copiar en el buffer lo harías con memcpy(auxdat,indices,numi*sizeof(WORD));                                
Título: Ayuda con los index buffers de Direct3D
Publicado por: DraKKaR en 12 de Octubre de 2002, 10:42:01 PM
                                Mecagüen la pita ostea!! Berserker te kiero!! era eso!!
Pero como es posible? menos mal ke no me ha dao por reescribir medio engine v.V

Pero esto me plantea nuevos problemas, no podre renderizar mas de 65k vertices de golpe, al menos con el mismo index buffer. Buenom aunke creo ke no es tan problema porque a la hora de la verdad, kien va a renderizar todos esos polis a la vez? Y si hubiera ke hacerlo, lo unico ke habria ke hacer es crear 2 index buffers.

Muchas gracias de nuevo berserker.                                
Título: Ayuda con los index buffers de Direct3D
Publicado por: NeLo en 12 de Octubre de 2002, 10:44:32 PM
                                No creo que sea muy bueno enviar 65.000 vértices a la tarjeta de una vez...                                
Título: Ayuda con los index buffers de Direct3D
Publicado por: DraKKaR en 12 de Octubre de 2002, 10:44:57 PM
                                Siguiendo con lo de los Vertex e Index Buffers... otra cuestion. Ahora mismo en mi engine creo un vertex buffer por cada objeto del engine y uno por cada textura diferente del escenario, con lo que al final me salen muchos VB. La pregunta es, voy bien asi? O deberia crear un Vertex Buffer global que almacenara todos los vertices de todas las mallas y del escenario para tenerlo todo en un unico VB? Kita tanto rendimiento suar varios VB??

Hasta luego.                                
Título: Ayuda con los index buffers de Direct3D
Publicado por: NeLo en 12 de Octubre de 2002, 10:46:40 PM
                                Por lo que he leido, lo bueno es enviar VB de 500-1000 vértices.

No vas mal del todo ;)

Saludos.                                
Título: Ayuda con los index buffers de Direct3D
Publicado por: _Grey en 12 de Octubre de 2002, 11:27:35 PM
                                Pues si estas cambiando el SetStreamSource y el SetIndices cada dos por tres puedes estar perdiendo velocidad que podrias ganar facilmente, en la documentacion de nvidia incluso recomiendan que uses un mismo vertexbuffer e indexbuffer para mas de un objeto, pero si por alguna causa tienes que hacer las trasformaciones de los vertices a mano(leer,trasformar,escribir) puedes tambien guardar los vertices e indices en un buffer que no sea de Direct3D para que el lock() y el Unlock() te hagan perder tiempo y rellenar un unico vertexbuffer y un unico indexbuffer que seran los que tengan siempre lo que tiene que pintar el DrawIndexPrimitive()                                
Título: Ayuda con los index buffers de Direct3D
Publicado por: DraKKaR en 13 de Octubre de 2002, 01:13:47 PM
                                Arjj!! falsa alarma! un codigo ke usaba D3DFMT_INDEX16 y ke funcionaba bien, lo  he cambiado a D3DFMT_INDEX32 y continua yendo bien, porlo ke mi tarjeta soporta INDEX32. Ademas a mi con INDEX16 me continua yendo mal (aunke no tan mal como antes). Ninguna idea de pq puede ser? el codigo de arriba esta bien escrito??                                
Título: Ayuda con los index buffers de Direct3D
Publicado por: DraKKaR en 13 de Octubre de 2002, 04:27:18 PM
                                Vale, uno de los problemas es lo del INDEX32, pero tenog otro problema pero ke kreo ke ya no es de direct3d, asi ke ya me las apañare. Gracias por la ayuda gente.                                
Título: Ayuda con los index buffers de Direct3D
Publicado por: DraKKaR en 15 de Octubre de 2002, 07:34:48 PM
                                Bueno, siento ponerme pesado con esto de los index buffers pero la cosa aun no va del todo bien.
Cuando hago un render con todos los vertices del index buffer la cosa va bien. Pero cuando hago el render con solo una parte del index buffer me salen problemas (poligonos ke desaparecen o aparecen desplazados).

Lo ke hago es al principio crear un index buffer de un tamaño suficiente para albergar el maximo numero de indices (cuando hay ke renderizarlos todos, recordad ke uso octrees). Depues, antes de renderizar cada frame, lo ke hago es lockear el index buffer y meter dentro UNICAMENTE los vertices ke son visibles (cuyo numero puede ser menor o igual ke el tamaño al ke he inicializado el index buffer). Los indices visibles estan contenidos dentro de la variable "indices" y siempre esta bien rellenada, es decir, ke siempre contiene los indices visibles (comprobado, ya ke en OPENGL no tengo ningun problema). Para rellenar parcialmente el index buffer hago lo siguiente:

void *auxdat;
ib->Lock(0,num_verts_to_render*sizeof(WORD),(BYTE**)&auxdat,0);
memcpy(auxdat,indices,num_verts_to_render*sizeof(WORD));
ib->Unlock();

una vez hecho esto, renderizo la geometria:

d3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, num_verts_to_render, 0, num_verts_to_render/3 );   

Yo lo veo todo bien, a ver si vosotros podeis auydarme a decirme ke es lo ke hago mal.                                
Título: Ayuda con los index buffers de Direct3D
Publicado por: Haddd en 15 de Octubre de 2002, 09:15:53 PM
                                No entiendo muy bien el concepto de la variable num_vertices. Parece que el nº de vértices=numero_caras*3. Esto no es el concepto de indexbuffer.                                
Título: Ayuda con los index buffers de Direct3D
Publicado por: DraKKaR en 15 de Octubre de 2002, 09:46:05 PM
                                Se que ese no es el conepto de index buffer. Pero la estructura de datos ke tengo me "obliga" a hacerlo asi, porke estoy en proceso de migrarla para ke sí use el concepto de index buffer. Por ahora, mi vertex buffer contiene los vertices de todas las caras, repitiendo vertices. Es decir, ke en mi estructura de datos, guardar los vertices de un cubo consistiria en guardar 24 vertices (12 triangulos * 3 vertices por cada) con lo ke cada vertice se repite en el array, en lugar de guardar solo los 8 vertices del cubo y formar las 24 caras a base de indices. De esta forma sabiendo el numero de vertices sabre el numero de caras (numverts/3) ya ke siempre se almacenan los 3 vertices de cada cara. Como he dixo, estoy en proceso de migrar esta manera de almacenar los vertices a la correcta usando los index buffers, pero primero kiero ke vaya bien asi y pillar el fallo.

¿Me he explicado bien?
¿¿Alguna otra idea de pq el codigo de arriba no va bien??                                
Título: Ayuda con los index buffers de Direct3D
Publicado por: Haddd en 16 de Octubre de 2002, 09:40:15 AM
                                En principio no he visto ningún problema en lo que haces. Quizás esté en la definición del IB. Creo que tendrías que poner un poco más de código...                                
Título: Ayuda con los index buffers de Direct3D
Publicado por: ProD en 16 de Octubre de 2002, 11:46:14 AM
                                Has puesto el el SetIndices()? porque en tu código no aparece, tambiem puede ser que bloqueas todo el IB (poniendo un 0) y no guardas todos los índices, si creaste un IB estático puede que te quede "mierda" en el IB ya que los IB estáticos osn para llenarlos enteros y no volverlos a tocar, si usas uno estático cambialo a dinámico que te permite borrar su contenido antes de meter de nuevo datos, te sugiero que te bajes un template que tiene Nvidia para el manejo de VB e IB y que es muy util para estos menesteres. Un saludo.                                
Título: Ayuda con los index buffers de Direct3D
Publicado por: DraKKaR en 16 de Octubre de 2002, 01:37:59 PM
                                Bueno, he usado la template de NDivia tal como me has comentado, pero los resultados continuan siendo los mismos. Es un problema extraño, porke aun metiendo todos los indices en el index buffer (llenandolo) y dibujando por ejemplo 6 caras va mal. Pero si en cambio dibujo TODAS las caras, va bien!! Os pongo el codigo de toda mi funcion de render a ver si veis alguna pega:


void RenderDirect3D::RenderIndexedTris(RENDER_PARAMS *par, VertexData *vdat, VertexIndices *indices, Texture *tex, unsigned int icoordtex)
{
 VertexDataDirect3D *vdatd3d=(VertexDataDirect3D*)vdat;   
 VertexIndicesDirect3D *vind3d=(VertexIndicesDirect3D*)indices;

 unsigned int numv=vdatd3d->GetNumVerts();   
 vdatd3d->SetupGeometry(); // set vertex buffers if changed

 unsigned int starti=0;      
 void *auxdat=dib->Lock(num_verts_to_render,starti);
   memcpy(auxdat,indices,num_verts_to_render*sizeof(WORD));
 dib->Unlock();


 d3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);
 d3dDevice->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, TRUE);

 D3DXMATRIX tempmat;   
 D3DXMATRIX matworld;
 D3DXMatrixIdentity(&matworld);

 d3dDevice->SetTransform(D3DTS_WORLD,&matworld);
 d3dDevice->SetRenderState(D3DRS_LIGHTING,FALSE);

 // texture stuff
 IDirect3DTexture8 *d3dtexture=vectorTextures[tex->GetID()];
 d3dDevice->SetTexture(0,d3dtexture);

 d3dDevice->SetRenderState(D3DRS_TEXTUREFACTOR,   D3DCOLOR_ARGB((unsigned char)(par->opacity*255.0f),
                                                 (unsigned char)(par->color_r*255.0f),
                                                 (unsigned char)(par->color_g*255.0f),
                                                 (unsigned char)(par->color_b*255.0f)));

 d3dDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_MODULATE);
 d3dDevice->SetTextureStageState(0,D3DTSS_COLORARG1,D3DTA_TEXTURE);

 d3dDevice->SetTextureStageState(0,D3DTSS_COLORARG2,D3DTA_TFACTOR);

 d3dDevice->SetTextureStageState(0,D3DTSS_ALPHAARG1,D3DTA_TEXTURE);
 d3dDevice->SetTextureStageState(0,D3DTSS_ALPHAARG2,D3DTA_TFACTOR);
 d3dDevice->SetTextureStageState(0,D3DTSS_ALPHAOP,D3DTOP_MODULATE);

 d3dDevice->SetTextureStageState(0,D3DTSS_MINFILTER,D3DTEXF_LINEAR);
 d3dDevice->SetTextureStageState(0,D3DTSS_MAGFILTER,D3DTEXF_LINEAR);

 if (tex->GetFilter()==FILTER_TRILINEAR)
   d3dDevice->SetTextureStageState(0,D3DTSS_MIPFILTER,D3DTEXF_LINEAR);
 else
   d3dDevice->SetTextureStageState(0,D3DTSS_MIPFILTER,D3DTEXF_POINT);
 
 d3dDevice->SetStreamSource( 0, vdatd3d->GetVertexBuffer(), sizeof(D3DCUSTOMVERTEX_2TEX) );
 d3dDevice->SetVertexShader( D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1);
 
 d3dDevice->SetIndices(vind3d->GetDirect3DIndexBuffer(),0);

 if (par->wire_mode)
   d3dDevice->SetRenderState(D3DRS_FILLMODE,D3DFILL_WIREFRAME);

 d3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, numv, 0, numv/3 );   
D3DPT_TRIANGLEFAN, 0, numv, par->first_vertex, numv-2 );   

 if (par->wire_mode)
   d3dDevice->SetRenderState(D3DRS_FILLMODE,D3DFILL_SOLID);


 d3dDevice->SetTexture(0,NULL);
 d3dDevice->SetRenderState(D3DRS_LIGHTING,FALSE);
}


No os he puesto los codigos de creacion y lockeo del index buffer pq lo hago a traves de la template de ndivia, asi ke tienen ke ir bien por cojones. Ademas todo apunta a ser algo de la funcion de render, ya ke si se pintan todos los vetices del index buffer (es decir para los ke se ha creado inicialmente) la cosa funcoina bien, pero si pintas menos, pasan cosas raras. Tambien apuntar ke esta funcion iba perfectamente antes de usar primitivas indexadas, y lo unico cambiado ha sido las funciones referentes a los index buffers.                                
Título: Ayuda con los index buffers de Direct3D
Publicado por: Haddd en 16 de Octubre de 2002, 02:27:16 PM
                                Prueba a cambiarlo por:

void *auxdat=dib->Lock(0,0);


Pero es un poco a ciegas...                                
Título: Ayuda con los index buffers de Direct3D
Publicado por: DraKKaR en 16 de Octubre de 2002, 03:01:39 PM
                                Nada, pasa exactamente lo mismo.                                
Título: Ayuda con los index buffers de Direct3D
Publicado por: DraKKaR en 16 de Octubre de 2002, 04:05:45 PM
                                Bueno, tengo buenas noticias, sobre todo para mi salud mental: y es ke al fin lo he conseguido (creo). El fallo lo tenia en hacer la llamada a DrawIndexedPrimitive, mas concretamente en el tercer parámetro: numVertices;

HRESULT DrawIndexedPrimitive(
D3DPRIMITIVETYPE Type,
UINT MinIndex,
UINT NumVertices,
UINT StartIndex,
UINT PrimitiveCount
);

Pues bien, lo he conseguido solucionar interpretando el tercer parámetro como el mayor indice del vértice a renderizar, en vez de como el numero de vertices a renderizar.

Esto es lo ke pone el MSDN acerca de ese parametro:

The minIndex and NumVertices parameters specify the range of vertex indices used for each DrawIndexedPrimitive call. These are used to optimize vertex processing of indexed primitives by processing a sequential range of vertices prior to indexing into these vertices. It is invalid for any indices used during this call to reference any vertices outside of this range.

Es decir, parece ke esta documentacion kiera decir ke NumVertices sea el limite superior de un rango. Si este parametro se toma de esta manera la cosa funciona, si se toma como el numero de vertices a renderizar, no funciona.
Lo he comprobado varias veces con arrays pekeños, por ejemplo.

WORD indices1[3]={0,1,2};
WORD indices2[3]={3,4,5};

Bien, Si intentamos renderizar usando el "indices1" con :
DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 3, 0, 1);

la cosa funciona.

Pero NO funciona si usamos la variable "indices2" con esa misma drawindexedprimitive.

En cambio, SÍ ke konsideraremos renderizarlo correctamente si lo hacemos asi:
DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 6, 0, 1)

Diciendole entre el segundo y el tercer parametro, ke el rango de indices a renderizar esta en [0,6].


Kisiera ke me confirmarais estas conjeturas para estar seguro de todo esto y aclararme un poco. Ahora mismo tomando ese tercer parametro como maxIndex (relativo a minIndex), la cosa me va de perlas. Si lo tomo como el número de vertices a renderizar, entonces no ira bien a no ser que el numero de vertices a renderizar coincida con el maximo indice de estos.                                
Título: Ayuda con los index buffers de Direct3D
Publicado por: Lord Trancos en 16 de Octubre de 2002, 06:29:21 PM
                                todo parece indicar q tienes razon :)                                
Título: Ayuda con los index buffers de Direct3D
Publicado por: DraKKaR en 16 de Octubre de 2002, 07:34:50 PM
                                Alguien podria confirmarme todo esto, plis? Todos los ke os hayais enfrentado a hacer un engine o un programita ke con oscenarios ke usen BSPs, Octrees y otro algoritmo de esta indole, debes haber pasado por esto antes.                                
Título: Ayuda con los index buffers de Direct3D
Publicado por: Haddd en 16 de Octubre de 2002, 11:28:00 PM
                                Yo uso octrees y no he tenido ese problema, pero el nº de vértices es fijo, sólo cambia el nº de índices.                                
Título: Ayuda con los index buffers de Direct3D
Publicado por: _Grey en 16 de Octubre de 2002, 11:41:33 PM
                                Pues si mas no, yo lo uso asi como indicas en tu penultimo post, es decir, esto, DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 3, 0, 1); no te funciona con indicex2[] por el 0,3 que hace que solo tenga encuenta los 3 vertices desde el vertice 0 del buffer de vertices, esto puede habilitar optimizaciones si ignoras los vertices que no se van a usar, pero eso ya es otro tema.

chao.                                
Título: Ayuda con los index buffers de Direct3D
Publicado por: DraKKaR en 17 de Octubre de 2002, 08:56:13 AM
                                Haddd: yo estoy como tu, tengo el numero de vertices fijo y solo cambio el numero de indices. Cuando vas a renderizar que valor le pones al tercer parametro de DraIndexedPrimitive?

_Grey: entonces me estas dando la razon no? ese tercer parametro especifica el ancho del rango de indices validos en base a minIndex no?                                
Título: Ayuda con los index buffers de Direct3D
Publicado por: _Grey en 17 de Octubre de 2002, 07:34:53 PM
                                Pues pretendia dartela....... pero e estado haciendo pruebas, y, para mi sorpresa ¡FUNCIONA!  por lo que parece indicar la documentacion en NumVertices es condicionado por el valor de StartIndex y el segundo valor de la funcion "SetIndices(X,X)", de todas formas te dire que yo siempre lo e usado como te e indicado, o sea com el ejemplo que has puesto que funciona y siempre me a funcionado bien, estas ultimas experiencias han sido por las pruebas que e hecho para estar mas seguro..............

parece que el misterio no se aclarara del todo.... pero usalo como tu segundo ejemplo, que al fin y alcabo es lo que se deduce de la documentacion.                                
Título: Ayuda con los index buffers de Direct3D
Publicado por: Haddd en 17 de Octubre de 2002, 08:10:17 PM
                                Yo siempre envio todos los vértices y sólo los índices necesarios. Las opciones añadidas se utilizan para procesar múltiples atributos, que son vértices que comparten el mismo VertexBuffer, pero que deben renderizarse en llamadas diferentes porque utilizan texturas diferentes. Pero esto es un tremendo ##$$&& y aunque lo utilizaba en engines anteriores, en Haddd lo quité porque te complica un motón y un grafista puede vivir sin ello(o utilizar otras técnicas)                                
Título: Ayuda con los index buffers de Direct3D
Publicado por: DraKKaR en 22 de Octubre de 2002, 11:21:17 PM
                                Hola, aun no he aclarado el significado de este famoso tercer parametro de la función DrawIndexedPrimitive y la CORRECTA manera de usarlo. Agradeceria si alguien pudiese confirmarmela, o mejor aun me encantaria que alguien me pasara algun codigo donde se usen index buffers y algun algoritmo de visualización tipo BSPs, Octrees, Beamtrees...

Gracias.