CONNEXION
  • RetourJeux
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Soluces
    • Tous les Jeux
    • Gaming
  • RetourActu Gaming
    • News
    • Astuces
    • Tests
    • Previews
    • Toute l'actu gaming
  • RetourBons plans
    • Bons plans
    • Bons plans Smartphone
    • Bons plans Hardware
    • Bons plans Image et Son
    • Bons plans Amazon
    • Bons plans Cdiscount
    • Bons plans Decathlon
    • Bons plans Fnac
    • Tous les Bons plans
  • RetourJVTech
    • Actus High-Tech
    • Intelligence Artificielle
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTech
  • RetourCulture
    • Actus Culture
    • Culture
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch 2
    • Xbox Series
    • Switch
    • Pokemon pocket
    • FC 25 Ultimate Team
    • League of Legends
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • Switch 2
  • PS4
  • One
  • Switch
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Liste des sujets

faces, primitives, octree avec DirectX

pilo1488
pilo1488
Niveau 10
21 novembre 2007 à 18:55:51

saleGauss> j´ais pas tout lu (les post sont trrrèèèsss long hehe), mais je suis un peu surpris, un octree c´est pas tres complexe a faire, enfin, le problème auquel tu fais fasse ne devrait pas etre si difficile a résoudre...
A voir les gros morceau de code posté, je pense que le fond du problème viens de la complexité du code.
Un octree c´est très simple.
Tu charge tout tes vertex et la liste des index qui forme les triangles (peut importe la forme que ca prends).

Ensuite il te faut :
une fonction qui dit si un triangle est dans une AABB (cellule de ton octree). Les paramètres vont dépendre de comment tu stock ton mesh. (donc ca peut etre le tableau de vertex, le tableau d´indice et l´index du triangle dans le tableau d´indice).
Jusque la rien d´exotique.
Ensuite tu fait ta fonction recursive, qui part de la grande AABB, puis la divise si le nombre de triangle est > a un seuil.
Enfin une fois que la contrainte est respecté, tu reconstruit, pour cette cellule, la liste des index de vertex, que tu utilisera pour l´affichage (avec toujours le meme Vertex Buffer).
et le tour est joué...

à ce que je vosi dans ton code : ne fait jamais des tableau de pointeur vers vertex. Ca ne sert a rien, crée plutot un tableau de vertex que tu peux copié avec un simple memcpy (si tu en as besoin) (et tu t´évite des allocation inutile aussi).

saleGauss
saleGauss
Niveau 9
22 novembre 2007 à 13:42:16

bien, je suis donc en train de code un petit exo de manipulation sur les VB/IB pour m´entrainer.
Je n´arive bien evidemment pas à le faire fonctionner...
Ce que je voudrais c´est : charger un mesh (.x), puis :
// Recuperer les infos sur les vertices:
1/ Recup VB et IB du mesh
2/ "extraire" les infos sur mes vertices de ce couple VB/IB, et les mettre dans un tableau (les indices et les vertex)

//Reconstruire à la main d´autres VB/IB
1/ A partir des tableaux construits créer VBbuild et IBbuild tout en respectant la géométrie initiale.

// Afficher en primitives
1/Donner à manger à ma carte graph mon VBbuild et mon IBbuild et dessiner en primitives, avec nbIndice/3 primitives.

Donc en clair je voudrais me compliquer le vie pour le plaisir, juste pour etre capable de mettre les mains dans les VB/IB.

Et pour l´instant, le code me génère une exception non rattrapée (Unhandled exception + adresse mémoire) et ca foire sur la ligne où je fais le DrawIndexedPrimitive().

Je poste le code, il est asser succint, j´en peu plus d´etre noob, faut que je comprenne une bonne fois pour toute !

/* code du chargement */
Map.Init(MyEngine.Device, "cube.x", NULL);
Map.SetPosition(D3DXVECTOR3(2.0f, 1.0f, 3.0f));

// On extrait les données

LPDIRECT3DVERTEXBUFFER9 vertexBuffer;
LPDIRECT3DINDEXBUFFER9 indexBuffer;

CUSTOMVERTEX* _vb;
WORD* _ib;

CUSTOMVERTEX* tableauVertex[20000];
int tableauVertex_size = 0;
WORD tableauIndices[60000];
int tableauIndices_size = 0;

Map.Mesh->GetVertexBuffer(&vertexBuffer);
Map.Mesh->GetIndexBuffer(&indexBuffer);

vertexBuffer->Lock(0, 0, (void**)&_vb, D3DLOCK_READONLY);
indexBuffer->Lock(0, 0, (void**)&_ib, D3DLOCK_READONLY);

int MaxVert = Map.Mesh->GetNumVertices();
int MaxInd = Map.Mesh->GetNumFaces() * 3;

for(int i=0; i<MaxInd; i++)
{

int Present = DejaPresent( _vb[ _ib[ i ] ], tableauVertex, tableauVertex_size);

if( Present == (-1) )
{
tableauVertex[tableauVertex_size] = &_vb[ _ib[i] ]; // _vb[] possede des elements de type CUSTOM et tableauVertex des pointeurs de CUSTOM, donc on prend l´adresse (&) !
tableauIndices[tableauIndices_size] = tableauVertex_size;
tableauVertex_size +=1;
tableauIndices_size +=1;
}
else
{
tableauIndices[tableauIndices_size] = Present;
tableauIndices_size +=1;
}
}

// On reconstruit les VB/IB

CUSTOMVERTEX* _vb_build = NULL;
WORD* _ib_build = NULL;

MyEngine.Device->CreateVertexBuffer(tableauVertex
_size * sizeof(CUSTOMVERTEX), D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &vertexBufferBuild, 0);

MyEngine.Device->CreateIndexBuffer(tableauIndices
_size * sizeof(WORD), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &indexBufferBuild, 0);

vertexBufferBuild->Lock(0, 0, (void**)&_vb_build, D3DLOCK_DISCARD);
indexBufferBuild->Lock(0, 0, (void**)&_ib_build, D3DLOCK_DISCARD);

for(int j=0; j<tableauVertex_size; j++)
{
_vb_build[j] = *tableauVertex[j]; // TableauVertex est un tableau de pointeurs : on déréference donc car _vb_build c´est un tableau de CUSTOM ! (type CUSTOMVERTEX* -> tableau de CUSTOM) !
}

for(int k=0; k<tableauIndices_size; k++)
{
_ib_build[k] = tableauIndices[k];
}

nbrVertex = tableauVertex_size;
nbrIndices = tableauIndices_size;

/* Fin du code de chargement */

/* code du dessin */
// On affiche les VB/IB construit en tant que primitives qui vont bien !

MyEngine.Device->SetStreamSource( 0, vertexBufferBuild, 0, 0);

MyEngine.Device->SetIndices(indexBufferBuild);

MyEngine.Device->SetFVF(D3DFVF_CUSTOMVERTEX);

MyEngine.Device->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0, nbrVertex - 1, 0, static_cast<int> (nbrIndices / 3));

/* fin du code de dessin */

Et je précise que Map est une instance de ObjetStatic, qui possède une methode Init() qui s´occupe du chargement bete et mechant de mon mesh par D3DXLoadMeshFromX().

Dernier détail : ma fonction dejaPresent :

int DejaPresent(CUSTOMVERTEX vert, CUSTOMVERTEX* tableau[], int taille)
{

int DejaPresent = (-1);

for(int i=0; i< taille; i++)
{

if (( fabs(vert.x - tableau[i]->x ) < Epsilon )
&& ( fabs(vert.y - tableau[i]->y ) < Epsilon )
&& ( fabs(vert.z - tableau[i]->z ) < Epsilon )
&& ( fabs(vert.color - tableau[i]->color ) < Epsilon )
&& ( fabs(vert.tu - tableau[i]->tu ) < Epsilon )
&& ( fabs(vert.tv - tableau[i]->tv ) < Epsilon ))
{
DejaPresent = i;
break;
}
else
{
DejaPresent = (-1);
}

}

return(DejaPresent);

}

qui me permet de determiner si j´ai deja ajouté un vertex ds un tableau (-1 si ce n´est pas le cas) si c´est le cas, renvoit l´indice de ce vertex dans ce fameux tableau.

Ha oui, encore un truc, lorsque je piste l´évolution de mon programme sur un cube, tout beigne lors de "l´extraction" des données depuis mes VB/IB initiaux : j´ajoute bien 8 vertex dans mon tableau (donc ma fonction DejaPresent marche, sinon j´en ajouterais 36).

Je pige pas pourquoi la primitive n´est pas valide en fait.
Voila, j´espere que vous allez pouvoir eclairer mes lanternes eteintes !
Merci à tous et encore une fois pardon pour mes posts à ralonge...

LGV
LGV
Niveau 28
22 novembre 2007 à 14:39:49

j´ai rapidement jete un oeil (casse-croute au boulot..) , et a priori je dirais que ton code ne tient absolument pas compte de la topologie de la mesh. Tu recuperes les vertices, les indices (ton tableau d´indices n´est autre que [0, 1, 2, 3, ... N] , sauf erreur de ma part), mais tu rien sur les triangles, les voisinnages, etc.

Autrement dit, tu recuperes de maniere "brute" un nuage de points, et tu les envoies dans un VB: ca ne decrit aucune geometrie.

plutot que charger une mesh via un .X je te conseille de creer un bete cube manuellement, en remplissant toi meme les valeurs des VB/IB, tu y verras p-e plus clair

saleGauss
saleGauss
Niveau 9
22 novembre 2007 à 16:32:03

encore merci pour ton aide LGV, et bon ap au passage :-)

Je pense que le morceau qui te pose donc pb c´est le suivant :

if( Present == (-1) )
{
tableauVertex[tableauVertex_size] = &_vb[ _ib[i] ]; // _vb[] possede des elements de type CUSTOM et tableauVertex des pointeurs de CUSTOM, donc on prend l´adresse (&) !
tableauIndices[tableauIndices_size] = tableauVertex_size;
tableauVertex_size +=1;
tableauIndices_size +=1;
}
else
{
tableauIndices[tableauIndices_size] = Present;
tableauIndices_size +=1;
}
}

Tu dis que je ne conserve pas la géométrie.
Pourtant il me semble bien (je peux me tromper hein) que c´est ce que j´essaye de faire ds ce morceau de recuperation de mes vertices.

Si le vertex v1 n´a pas deja été ajouté dans mon tableau de vertex :
-je l´ajoute.
-la position où je l´ajoute dans mon tableau sera l´indice de ce vertex dans mon tableau d´index

Si le vertex v2 a deja été ajouté dans mon tableau de vertex :
-je ne l´ajoute pas
-grace à ma fonction DejaPresent() j´ai pu savoir quelle "position" il avait ds mon tableau de vertices
-cette "position" je la met dans mon tableau d´indices.

Prenon un ex simple d´application :
v0, v1, v2, v3 dans cet ordre dans mon VB initial
i0, i1, i2, i1, i2, i3 dans mon IB initial

je prend v0 ( vb[ib[0]] )
-> deja mit ?n on -> -1
tableauVertex[0] = v0;
tableauIndices[0] = 0 // Le zero a droite de cette ligne correspond au zero de la ligne du dessus entre[]

je prend v1 ( vb[ib[1]] )
-> deja mit? non -> -1
tableauVertex[1] = v1;
tableauIndices[1] = 1;

je prend v2 ( vb[ib[2]] )
-> deja mit ? non-> -1
tableauVertex[2] = v2;
tableauIndices[2] = 2;

je prend v1 ( vb[ib[3]] )
-> deja mit? OUI -> en position 1 !
tableauIndices[3] = 1;
// je touche pas le tableau de vertex

je prend v2 ( vb[ib[4]] )
-> deja mit? OUI -> en position 2!
tableauIndices[4] = 2;
// je touche pas le tableau de vertex

je prend v3 ( vb[ib[5]] )
-> deja mit? non ! -> -1
tableauVertex[3] = v3;
tableauIndices[5] = 3

Je me retrouve donc bien avec un tableau de vertex à 4 elements et un tableau d´indices avec 6 elements, mon tableau d´indice décrivant bien ma géométrie.

J´avoue que mon code n´est pas très explicite.
Mais regarde bien ce que je met dans mon tableau d´indices : je met la valeur X/ tableauVertex[X] = vertex en question (lire "la valaur de x tel que ...")
Non?

saleGauss
saleGauss
Niveau 9
22 novembre 2007 à 16:37:28

ha oui, et n´oublie pas que dans ma boucle, je vais de 0 à maxIndices : je travaille sur les VB[IB[i]], i variant.
Et pour chaque vertex je fais exactement ce que je viens de poster dans mon post précedent.

Je vais y reflechir encore ce soir. Je vais au code :D (pour un programmeur débutant c´est normal :D )

Sous forums
  • Aide à l'achat Mac
  • Internet
  • Macintosh
  • Création de sites web
  • Création de Jeux
  • Linux
  • Programmation
  • Steam Deck
  • Hardware
La vidéo du moment