Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Ayuda con los index buffers de Direct3D

Iniciado por DraKKaR, 12 de Octubre de 2002, 09:08:18 PM

« anterior - próximo »

DraKKaR

                                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.                                

BeRSeRKeR

                                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));                                
¡Si te buscan en nombre de la ley, huye en nombre de la libertad!!

DraKKaR

                                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.                                

NeLo

                                No creo que sea muy bueno enviar 65.000 vértices a la tarjeta de una vez...                                
Drowning deep in my sea of loathing

DraKKaR

                                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.                                

NeLo

                                Por lo que he leido, lo bueno es enviar VB de 500-1000 vértices.

No vas mal del todo ;)

Saludos.                                
Drowning deep in my sea of loathing

_Grey

                                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()                                

DraKKaR

                                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??                                

DraKKaR

                                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.                                

DraKKaR

                                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.                                

Haddd

                                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.                                

DraKKaR

                                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??                                

Haddd

                                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...                                

ProD

                                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.                                
as ideas son capitales que sólo ganan intereses entre las manos del talento

DraKKaR

                                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.                                






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.