Voilà dans ma quête du gain de mémoire, je me suis posé une question : est-il possible de rendre plusieurs fois le même MeshBuffer à des positions différentes?
J'ai recopier CMeshSceneNode et j'y ais apporté quelques modifs.
1/ ajout d'une struct pour les transformation
2/ ajout d'un membre à mon MeshSceneNode :
core::array<MultiMeshData> Instances;
3/ modification du render, au lieu de :
void MultipleMeshSceneNode::render() { /// code de render }
j'ai mis :
void MultipleMeshSceneNode::render() { /// pour chaque position for(u32 a=0; a < Instances.size(); a++) { /// code de render } }
Mon nombre de triangles augmente bien au fur et à mesure que je rajoute des positions mais seul le mesh associés à la dernière position est visible.
Au final, je pense que les meshs sont bien dupliqués mais sont tous affichés à la dernière transformation appliquée.
Si quelqu'un s'y connait en rendu et peut me dire si ce que j'essaie de faire est vain ou pas, j'en serais ravi.
Sinon il y a "ISceneNode* CMeshSceneNode::clone(ISceneNode* newParent, ISceneManager* newManager)" mais je ne sais pas s'il fait juste un doublon du node donc MeshBuffer*2 ou si le node créé utilise le même Buffer que son original.
Dernière modification par johnplayer (03-07-2012 20:54:01)
Hors ligne
certain problème vont occuré avec cette gestions
de plus cela ne supprimme pas vraiment de charge, d'un coter tu a x node
de l'autre tu a 1 node avec x render
au final tu a donc n+1 appelle avec cette méthode, a moins que tu n'implique d'autre méthode avec le "MultiMesh", occlusion/frustum/... qui pour être valable sur des "champs" de mesh
la ou tu peut vraiment gagner, n'est pas la méthode que tu applique, mais serait de lier les meshbuffer affin d'utiliser pleinement le buffer 32bits et diminuerais directement le nombre de draw call, plus t'est obj sont low poly plus la technique est intéressent, mais tu ne pourras plus bouger dynamiquement t'est objet
en gros tu copie bêtement le meshbuffer dans un meshbuffer principal avec la matrice de transformation (driver->getMeshManipulator()->copyWithTransforme ou quelque chose dans le genre)
tu ne pourras plus setter de child sur l’élément x (n'étant plus un node...)
tu ne pourras plus avoir de matériaux spécifique pour l’élément x (enfin si, mais s tu peut éviter c'est aussi bien, tu gagnerais en performance)
tu pourrais géré dynamiquement avec des méthode statique pour implémenter un lod
...
Hors ligne
Ok ce serait construire une usine à gazs pour ne rien gagner. Pour le LOD, j'ai déjà penser à en implémenter un mais je crois que pour l'instant ce n'est pas dans mes capacités ou alors il faudrait que je me plonge sérieusement dedans (et j'ai pas trop envie pour l'instant^^).
Sinon tu parles d'utiliser pleinement un buffer 32 bits!? Les buffers 32 bits ne poseront pas de problème sur mon matériel (j'ai déjà essayé) mais j'ai entendu dire que toutes les cartes ne le supporte pas, je crois même que c'est aussi marqué dans la doc Irrlicht. sais-tu quelque chose là dessus parce que je n'arrive pas à trouvé de détails comme par exemple "quels modèles (ou séries) ne sont pas compatibles?". Parce que dans mon projet il me serait été très utile de pouvoir utiliser les buffers 32bits mais je ne veux pas écarter certains utilisateurs potentiels donc je dois gérer l'intéraction entre plusieurs buffers 16 bits ce qui est fastidieux.
Au fait, merci d'avoir répondu, j'ai cru que mon post allait tomber aux oubliettes^^. Il y a de plus en plus de nouveaux ces derniers temps, j'aide au mieux mais lorsque j'ai un problème, je me sens un peu seul sur le forum^^.
Hors ligne
A ce moment là tu px passer par un shader d'instancing pour éviter de faire X rendus. Mais bizarrement ça revient quasiment au même que faire X rendus en spécifiant un hardware mapping statique sur ton mesh afin qu'il reste dans la carte graphique.
Pour le shader d'instancing le procédé est simple : tu dupliques X fois tes indices de vertices dans ton meshbuffer d'instancing, tu "codes" l'index d'instance (= le numero du mesh dans ton meshbuffer) quelque part dans le buffer (en général ils utilisent Vertex2Tcoord et stoquent l'index d'instance dans le U de la 2ème Tcoord. Et c'est le shader qui se tape tout le boulo en remappant une table de transformation de tes X instances sur chacune des tes X instances de ton meshbuffer, en récupérant la Tcoord2 U pour connaitre quelle transformation lui appliquer dans la table pour chacune de ses vertices.
Tu peux trouver un snippet de shader instancing dans la rubrique snippet du forum officiel.
Hors ligne
Merci de ta réponse. Mais en fait, en fouillant dans les sources, je me suis aperçu que pour faire ce que je voulais, il suffisait de créer un IMesh* puis de le donner à chaque node. Ainsi le mesh n'est chargé qu'une fois puisque les nodes prennent un pointeur sur IMesh et ne copient donc pas la ressource. Au final, je vais utiliser le même principe qu'Ogre3D, je charge tous les meshs et textures en récupérant leurs pointeurs puis je passe les pointeurs au nodes. Ainsi, je suis sûr que les ressources ne sont chargées qu'une seule fois. C'est plus facile que de coder et intégrer des shaders^^.
Hors ligne