Pages: 1
Je veux créer un namespace dans lequel je metttrais ce qu'il me faut pour gérer un LOD perso. Mais il y a un probleme : Le programme compile bien jusqu'à ce que je veuille l'utiliser (2 première lignes de titanium.cpp) et à ce moment là il me met :
1>Node_Manager.obj : error LNK2005: "unsigned long Node_Manager::Id_Thread_LOD" (?Id_Thread_LOD@Node_Manager@@3KA) déjà défini(e) dans Titanium.obj
1>Node_Manager.obj : error LNK2005: "bool Node_Manager::LOD_actif" (?LOD_actif@Node_Manager@@3_NA) déjà défini(e) dans Titanium.obj
1>Node_Manager.obj : error LNK2005: "class irr::core::array<class irr::video::ITexture *,class irr::core::irrAllocator<class irr::video::ITexture *> > Node_Manager::textures_list" (?textures_list@Node_Manager@@3V?$array@PAVITexture@video@irr@@V?$irrAllocator@PAVITexture@video@irr@@@core@3@@core@irr@@A) déjà défini(e) dans Titanium.obj
1>Node_Manager.obj : error LNK2005: "class irr::core::array<struct Node_Manager::Param_Node,class irr::core::irrAllocator<struct Node_Manager::Param_Node> > Node_Manager::node_list" (?node_list@Node_Manager@@3V?$array@UParam_Node@Node_Manager@@V?$irrAllocator@UParam_Node@Node_Manager@@@core@irr@@@core@irr@@A) déjà défini(e) dans Titanium.obj
1>d:\Visual Studio 2008\Projects\Titanium\Titanium\\Titanium\Titanium.exe : fatal error LNK1169: un ou plusieurs symboles définis à différentes reprises ont été rencontrés
Mon namespace :
#include "en-tête.h" namespace Node_Manager { // classes class Shader_caller : public IShaderConstantSetCallBack { public : Shader_caller( IrrlichtDevice* _device, IGPUProgrammingServices* services ); virtual void OnSetConstants ( IMaterialRendererServices* services , s32 userData ); private : IrrlichtDevice* device; } ; // énumérations enum Type_LOD { ETL_3D_TO_2D, // utilisation d’un billboard ETL_LOD_LVL1, // un mesh est utilisé (le node n’est plus affiché à une certaine distance). ETL_LOD_LVL2, // on utilise un mesh low-poly puis il disparait ETL_LOD_LVL3 // on utilise un mesh low-poly ,un mesh very low-poly puis il disparait. }; enum TYPE_NODE { }; // structures struct Param_Node // contient les infos de création d’un node { stringw nom ; // int Id ; // Type_LOD methode ; // bool backculling ; // bool light_reactif ; // E_MATERIAL_TYPE texturing ; // stringw hlsl_path ; // Shader_caller call; // TYPE_NODE type; // int textures [4]; // }; // fonctions void LOD(); // fonction d’initialisation du LOD DWORD WINAPI Thread_LOD(LPVOID Param); // thread LOD bool addNodeList(Param_Node); // ajoute un noeud dans le scenegraph et la node_list // variables (CELLES QUI POSENT PROBLEME des que je mets les 2 premieres lignes dans titanium.cpp) bool LOD_actif = false; // permet l’arrêt du thread de LOD array <Param_Node> node_list; // liste des nœuds de la scène array <ITexture*> textures_list; // liste des textures DWORD Id_Thread_LOD; // id du thread LOD }; // fin du namespace
Mon titanium.cpp :
#include "Node Manager.h" using namespace Node_Manager; int main() { return 0; };
Je fais appel à tout les connaisseurs C++. Help!
Hors ligne
personnellement je ne mais pas de ';' a la fin du namespace, c'est peut-être sa car chez moi sa compile bien
Hors ligne
Salut,
Dans quoi se situe ton "namesapce" (le code que tu a passé)
Si c'est un include le problème vient de là, tu ne dois pas déclarer de variable global, dans des includes appelé dans plusieurs fichier source car au moment du linkage, tous les fichiers obj sont mis bout à bout les variables apparaissent plusieurs fois.
Sinon cela peut venir de ton Node_Manager.cpp.
Si tu veux plus d'explication n'hésite pas à demander, je suis pas sur d'être toujours bien claire.
dark calculator
Hors ligne
En fait, mon namespace est dans Node_Manager.h avec les classes et les prototypes des fonctions. Ensuite le corps de mes fonctions sont dans Node_manager.cpp. Donc d'après toi je dois créer mes variables dans le *.cpp?
En attendant une réponse, j'avais créé une classe dans laquelle je déclarais mes variables et dont je n'ai fais qu'une seule instance. Cette classe m'a d'ailleurs donné du fil à retordre lorsque j'ai voulu utiliser un thread à l'intérieur. J'ai du passer le pointeur de ma classe à mon thread afin de pouvoir l'utiliser.
Sinon Magun, chez moi aussi ça complier bien mais tant que je n'incluais pas Node_manager.h dans un autre *.cpp.
Merci beaucoup de vos réponses, quand on est autodidacte ça fait plaisir d'être aider par des personnes qui s'y connaissent. En plus, avec toutes les erreurs de compilation que j'ai à chaque fois que je tente un nouveau truc, je passe mon temps à retourner le Net à la recherche de réponse.
Hors ligne
Perso, en reprenant les bouts de code que tu à mis plus haut, je ne rencontre pas de soucis. Cela compile et cela link.
En entête je pars avec cela:
Hors ligne
Que de meileurs expert que moi confirme mais, tes variables sont dans l'include qui est appelé par deux fichiers sources. Donc tu as tes variables déclarés dans deux fichiers sources avec le même nom.
Quand tu les compiles séparément, pas de problème mais au moment du linkage, le linker ne sait pas si ils doit faire référence à la variable crée dans Node_Manager.obj ou Titanium.obj car elles ont le même nom.
C'est comme si tu fais
int a; int a;
sa ne marche pas a la compilation.
La différence est que l'erreur attend le linkage, car avant tout est fait en séparé.
La solution est évidement logiquement une classe, car les variables ne seront instancié(si c'est le bon terme) que quand tu instancira ta classe.
En espérant avoir été clair et ne pas m'être trompé
dark calculator
Hors ligne
La remarque est bonne en effet.
C'est pour cela, que dans la plupart des headers, on définit des markers pour éviter ce genre de désagrément sur les appel récurrents
des fichier d'entête:
#ifndef _MONHEADER_ #define _MONHEADER_ ... le code du fichier .h #endif
Hors ligne
Merci pour les explications. Mais les markers changent quoi? J'en ai mis dans mon *.h pour voir mais si je mais une variable, il recommence avec ses multiples définitions. Doit-on utiliser ses markers dans les fichiers *.cpp?
Sinon mon LOD avance, meme si l'utilité finale n'est pas exploitée actuellement (créer un éditeur de map), ce namespace me permet d'insérer des objets beaucoup plus vite qu'avant. De plus, il me permet de gagner en ressources sur le nb de triangles (ouais, bon, principe du lod quoi!). Sans perdre de qualité, je passe d'un arbre de 440 tri (entre 0 et 100 m) à un plan de 2 tri (entre 100 et 200 m) donc en gros pour un arbre low-poly d'enlever je peux afficher 220 arbres en very low-poly! Hou la belle foret!
Dernière modification par johnplayer (24-01-2009 08:47:11)
Hors ligne
johnplayer :
Merci pour les explications. Mais les markers changent quoi? J'en ai mis dans mon *.h pour voir mais si je mais une
variable, il recommence avec ses multiples définitions. Doit-on utiliser ses markers dans les fichiers *.cpp?
Non, il ne faut pas en mettre dans les cpp, par contre si c'est bien placer dans les *.hpp, tu ne dois pas avoir de définition multiple,
lorsque ton compilateur rencontre l'include du fichier H, il le prend en compte, et ne le fera plus, même si d'autre fichiers cpp contienne
aussi un include "Node Manager.h". D'ailleurs tous les fichier .h des sources Irrlicht emplois cette méthode.
johnplayer :
Sinon mon LOD avance...,
Un bon système de LOD n'est pas facile à mettre au point, donc bravo à toi. D'autant que c'est un élément prépondérant pour tous
ce qui est optimisation des scene très chargé en petits éléments, comme effectivement les arbres sur un terrain.
Voilà donc qui est fort intéressant.
Deux petites questions:
-Ton système simplifie les mesh de façon automatique, ou il faut au préalable charger les différents modèles en mem.
- ton code sera-t-il ouvert ou fermé ?
Hors ligne
JEn fait, je fait le lod et le culling en meme temps.
Pour le lod :
je charge des textures;
je charge des meshs;
je parametre la création d'un node bar le biais d'une structure dédié;
Mon lod consiste à mesurer la distance entre la camera et l'objet puis en fonction des distances mini et maxi d'affichage du noeud en question, on le rend visible ou pas.
Pour certain objet comme les arbres et les plantes, j'ai adopter la meme technique à l'exception près que le mesh vu de loin et un plan et qu'il est orienté en permanence vers le joueur tel un billboard cela permet d'avoir une végétation luxuriante avec peu de triangles (ca vaudra pas crisys et farcry mais bon on fait ce qu'on peux avec ce qu'on a).
De plus, la creation d'un node etant paramétré par une structure cela me permettra par la suite de créer un éditeur de map prenant en compte le lod voir avec evolution les shaders persos.
Sinon la j'ai un probleme, car je veux gérer le culling moi-meme donc je désactive le culling automatique sur les nodes mais après je bloque car je n'arrive pas à trouver l'équation qui me donne l'angle entre la direction de la camera (direction = target - position) et le vecteur (node.position - camera.position). En gros, dès que le node sort du champ de vision je ne le rend plus.
Hors ligne
En fait, je pense que c'est bon. J'ai fait, après moulte essais :
cambox = smgr->getActiveCamera()->getBoundingBox(); if(!cambox.intersectsWithBox(smgr->getSceneNodeFromId(a)->getTransformedBoundingBox())) smgr->getSceneNodeFromId(a)->setVisible(false);
Hors ligne
Pages: 1