BASE/MOTEUR 3D EN QT/OPENGL (COMPLET ET FONCTIONNEL!) POUR UN TRÈS PROCHAIN JEU
envi33
Messages postés18Date d'inscriptiondimanche 17 juillet 2011StatutMembreDernière intervention25 janvier 2016
-
25 juil. 2011 à 09:38
envi33
Messages postés18Date d'inscriptiondimanche 17 juillet 2011StatutMembreDernière intervention25 janvier 2016
-
16 août 2011 à 12:29
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.
envi33
Messages postés18Date d'inscriptiondimanche 17 juillet 2011StatutMembreDernière intervention25 janvier 2016 16 août 2011 à 12:29
Lol merci beaucoup ;) bonne chance pour le détecteur de mouvement, c'est une super projet!
Actares1456
Messages postés41Date d'inscriptionsamedi 13 août 2011StatutMembreDernière intervention21 mai 2012 16 août 2011 à 12:19
Merci enfiniment, si j'ai pris un peu de temps avant de te répondre c'est que j'était sur un projet. Enfait j'étrait entrain de concevoir un petit code en c++ et Managed pour un détécteur de mouvement avec la webcam. J'en suis encore qu'a la création du squelette mais comme je suis encore un débutant débutant, ça me prend un peu de temps pour trouver/écrire/... Si non j'ai regarder comme tu m'as dit et je trouve ça toujour trop "balaize"!XD
envi33
Messages postés18Date d'inscriptiondimanche 17 juillet 2011StatutMembreDernière intervention25 janvier 2016 16 août 2011 à 01:05
Bonsoir Actares1456!
Si tu veux juste le lancer facilement télécharge plutôt le zip complet sur le site officiel du projet, il n'y a plus qu'à dézipper et à lancer le .exe:
http://envi3d.wikeo.net/
Et je t'assure que je ne suis pas un crack de la programmation, il y a juste beaucoup de C++, ce qui ne rend pas la lecture facile, et des commandes opengl et qt. Tout ça s'apprend avec un peu d'entrainement sur le siteduzero.com!
C'est un très bon site pour commencer et ne pas s'embourber dans des codes inutiles et ennuyants^^
Bon courage à toi!
(pour donner des nouvelles, j'en suis à 80% de la version 2 du jeu, avec l'éditeur de carte, la course au drapeau et les ennemi pour vous barrer la route à coup de tir de barrage. En effet j'utilise à présent complètement les classe qVector et qVector3D et j'ai finis de tout transformer en VBO! A bientôt et merci pour tous vos conseils!)
Actares1456
Messages postés41Date d'inscriptionsamedi 13 août 2011StatutMembreDernière intervention21 mai 2012 15 août 2011 à 09:56
Bonjour envi33.
Enfait la question peut parraître bête mais j'ai aucunne idéée de ce que je dois mettre en".exe" et non plus comment le faire. Enfait je suis un débutant débutant mais je m'interesse beaucoup au millieux de la programation donc ça serait sympa que tu m'explique! Sinon j'ai jeté un oeil à tes codes. Je vais pas te cacher que la plupart des codes sont trops complex pour moi,mais de ce que je comprend, pour moi, c'est juste trop "balaize"!
Continue c'est extra!
envi33
Messages postés18Date d'inscriptiondimanche 17 juillet 2011StatutMembreDernière intervention25 janvier 2016 4 août 2011 à 21:54
Tatarus je pense qu'il n'a juste pas trouvé le chemin du fichier map (listeObjets.txt), le programme est écrit pour être exécuter dans le répertoire source (celui où il y a le fichier map, et QtCreator le fait généralement automatiquement. Le tien doit l'exécuter dans le dossier debug, il te suffit de changer cela dans la config (à gauche projets->tab 'executer'->repertoire de travail). Ou de déplacer le .exe dans le dossier source...
Y-a-t-il aussi des erreurs juste après avec tous les chargements de fichiers?
Merci!
cs_tatarus
Messages postés1Date d'inscriptiondimanche 25 janvier 2009StatutMembreDernière intervention 4 août 2011 4 août 2011 à 13:39
bonjour
Compilation OK
mais a lexecution :
+ Support OpenGL : OK
----->ERREUR 01 ; Chargement du fichier map : FAILED
..\Desktop\Envi3D-build-desktop\debug\Envi3D.exe s'est terminé avec le code -1073741819
envi33
Messages postés18Date d'inscriptiondimanche 17 juillet 2011StatutMembreDernière intervention25 janvier 2016 2 août 2011 à 01:16
Je suis tout à fait d'accord LeFauve42, maintenant que j'ai ajouté les VBO je vais changer ça ;)
LeFauve42
Messages postés239Date d'inscriptionvendredi 20 octobre 2006StatutMembreDernière intervention20 avril 2009 1 août 2011 à 13:46
Bonjour,
J'ai survole une partie du code, tres clair et tres bien commente :o) mais j'ajoute ma petite remarque :
Dans ton whellEvent(), tu verifies que la nouvelle vitesse est entre 0 et 6 avant d'appeler joueur->setVitesse().
En toute rigueur, si tu respectes le paradigme de la programmation objet c'est dans setVitesse() que tu devrais faire ce test. C'est en effet l'objet joueur qui sait quelles vitesses sont valides ou pas pour lui (et si tu fais du polymorphysme avec plusieurs classes derivees de joueur (par exemple si tu peux jouer un bonhomme, un tank ou un avion), chacune peut avoir un comportement different sans que tu ais desoin d'adapter le code principal du programme).
J'ai aussi une petite remarque sur une des remarques de CptPingu :
> Lorsque tu passes en argument un type pod (int, float, char, etc...), inutile de mettre
> const devant, vu que la valeur est passée par copie. const float <=> float lors d'un
> passage d'argument.
Je ne suis pas d'accord. Const est surtout la pour faciliter la maintenance et la relecture du code. Quand je vois qu'une fonction prend un argument "const", je sais qu'il est constant, sans avoir a reflechir si dans ce language la il est de toutes facons passe en recopie ou pas.
Ca aide aussi si par erreur quelqu'un essaie de modifier cet argument dans la fonction.
Avec le const, ca va generer une erreur de compilation, et il sera donc facile de trouver/corriger l'erreur. Sans le const, ca va compiler correctement, mais la valeur ne sera pas modifiee dans la fonction appelante. D'ou un bug bizarre lors de l'execution qui a toutes les chances de passer inapercu jusqu'a la livraison :o)
Bref, si techniquement c'est vrai que ca ne change rien avec ces types, ce n'est pas inutile d'utiliser const quand meme.
Eric
envi33
Messages postés18Date d'inscriptiondimanche 17 juillet 2011StatutMembreDernière intervention25 janvier 2016 26 juil. 2011 à 18:17
Eh bien je ne m'attendais pas à autant de bon conseil!
- En effet je n'ai pas intégré les VBO par manque de connaissances, mais je crois que je vais devoir inévitablement m'y plonger :D, surtout si Qt me vient en aide...
- Et je n'avais pas pensé à la classe QVector3D, je vais certainement y gagner, ne serais-ce qu'en simplicité, tu as raison.
(merci pour le test d’exécution!)
opossum_farceur
Messages postés147Date d'inscriptionlundi 16 août 2004StatutMembreDernière intervention14 novembre 2009 26 juil. 2011 à 17:07
Hi!
Compilation réussie avec Qt4.70+minGW sous Win7 32 bits.
Exécution ok!
Le code :
Mon intérêt s'est focalisé sur la méthode "OpenGLWidget::paintGL", qui est le centre opérationnel de toute application reposant sur QGLWidget.
Je vois que la scène est entièrement recalculée à chaque image : pour l'instant ton application ne fait pas grand chose, les ressources sont donc suffisantes, mais plus tard?
Les moyens d'optimiser ces calculs existent, l'un d'entre eux s'appelle " Vertex Buffer Objects" ou "VBO", dont la mise en oeuvre est rationalisée dans la classe de Qt "QGLBuffer".
Ces techniques d'optimisation reposent cependant sur l'existence de tableaux/vecteurs à une dimension.
Des déclarations telles que :
std::vector< std::vector< std::vector< float > > > _tableauMesh
sont donc satisfaisantes pour l'esprit mais impropres à un usage orienté "optimisation".
Sur ce sujet, un document récent à potasser :
http://gbelz.developpez.com/remi-achard/gpu-avance-avec-qt/ Ah, je vois que tu as créé une classe "Coord3D", c'est tout à ton honneur, mais connais-tu l'existence de la classe " QVector3D" ? (et sa fonction static "QVector3D::normal", qui fait des merveilles pour le calcul des normales).
Bonne continuation...
BunoCS
Messages postés15475Date d'inscriptionlundi 11 juillet 2005StatutModérateurDernière intervention23 avril 2024103 26 juil. 2011 à 13:49
Hello,
Très bonne source! Très bonne remarques également de CptPingu.
envi33
Messages postés18Date d'inscriptiondimanche 17 juillet 2011StatutMembreDernière intervention25 janvier 2016 26 juil. 2011 à 10:49
Ok j'ai compris! Je continue les modifs!
cptpingu
Messages postés3837Date d'inscriptiondimanche 12 décembre 2004StatutModérateurDernière intervention28 mars 2023123 26 juil. 2011 à 00:07
> - Pourquoi y a-t-il un soucis avec la déclaration :
> vector< vector< float > > _tableauMesh;
> Je pensais que cette ligne ne consommait rien en mémoire étant donné que je lui donne pas le nombre de case?
J'ai du mal m'exprimer. Il n'y a pas de problème avec la déclaration. Il y a un souci d'utilisation mémoire supplémentaire lors de l'utilisation.
En effet, un std::vector, en interne, ne s'amuse pas à faire un realloc à chaque fois que tu changes sa taille. A chaque fois que sa taille dépasse sa capacité (capacité = sa taille interne), il double sa capacité. Avec cette technique, tu limites grandement les allocations. En contrepartie, tu peux très bien te retrouver avec une taille de 1000 et une capacité de 3000 (exemple bidon, attention [1]). Donc si tu as plein de vector de vector, inutile de te faire un dessin...
Néanmoins, avec un resize (taille) + reserve (capacité) on peut s'en sortir. Mais autant utiliser un tableau statique plutôt qu'un vector dynamique, si tu cherches à représenter un tableau statique !
[1] Généralement, les implémentations de STL (oui, il y en a plusieurs qui existent), utilisent la technique de puissance de deux. La capacité passe de 1,2,4,8,16,32,64,etc...
Ex: resize(5) => capacité 8
resize (260) => capacité 512.
envi33
Messages postés18Date d'inscriptiondimanche 17 juillet 2011StatutMembreDernière intervention25 janvier 2016 25 juil. 2011 à 20:14
@CptPingu
J'ai pu modifier tout le code (et apprendre pas mal de chose en passant) pour la prochaine version, mais je bute sur les vector :
- Pourquoi y a-t-il un soucis avec la déclaration :
vector< vector< float > > _tableauMesh;
Je pensais que cette ligne ne consommait rien en mémoire étant donné que je lui donne pas le nombre de case?
envi33
Messages postés18Date d'inscriptiondimanche 17 juillet 2011StatutMembreDernière intervention25 janvier 2016 25 juil. 2011 à 16:58
Et bien, je n'en attendais pas autant, je te remercie beaucoup pour toutes ces indications qui vont beaucoup m'aider, et je vais de ce pas améliorer mon code pour la version finale.
Encore merci!
cptpingu
Messages postés3837Date d'inscriptiondimanche 12 décembre 2004StatutModérateurDernière intervention28 mars 2023123 25 juil. 2011 à 11:13
Bonjour.
Le projet est sympa. J'aime bien l'idée de la minicarte. C'est un très bon début. Si tu veux faire un moteur, peut être qu'il serait pratique d'en faire une bibliothèque, en essayant de bien séparer C++/OpenGL et Qt ?
Je n'ai malheureusement pas encore pu compiler et tester cette source. En revanche, j'ai lu le code source, et j'ai quelques critiques à te proposer.
A noter que j'ai vais écrire beaucoup de choses négatives, mais ça ne va absolument pas dire que ton projet n'est pas bien. Bien au contraire. Pour progresser, il faut pointer ce qui ne va pas, pas ce qui va bien.
- Attention code mort (code en commentaire non utilisé)
- Des vrais commentaires en doxygen aurait été sympas (http://0217021.free.fr/portfolio/axel.berardino/articles/ecrire-de-bons-commentaires) - Lorsque tu initialises des valeurs dans un constructeur de classe, utilise la liste d'initialisation plutôt que de mettre à jour les valeurs dans le corps de ton constructeur.
- Tu peux déclarer des variables où tu veux. Contrairement au C (non 98) tu peux déclarer une variable au milieu du code. Des fois tu utilises aussi des variables temporaires inutiles.
Ex: "distanceDroiteAuPoint" (réécriture)
float Coord3D::distanceDroiteAuPoint(const Coord3D& pointDeLaDroite, const Coord3D& point) const
{
Coord3D vectDeuxPoints(pointDeLaDroite, point);
Coord3D prod = crossProduct(vectDeuxPoints);
// On pourrait même mettre:
// Coord3D prod = crossProduct(Coord3D(pointDeLaDroite, point));
prod = prod - prod * 2;
return prod.length() / this->length();
}
- Le "this->" n'est pas nécessaire. Il n'est nécessaire qu'en PHP (et souvent utilisé en Java), mais pas en C++.
- Lorsque tu passes en argument un type pod (int, float, char, etc...), inutile de mettre const devant, vu que la valeur est passée par copie. const float <=> float lors d'un passage d'argument.
- Par convention, on essaie de différencier une variable locale, d'un attribut. Il est d'usage d'ajouter un signe distinctif. (Par exemple: float _x; pour ta classe 3DCoord).
- Les membres en public, c'est moyen... Si tu fais un "getter" et un "setter" inlinés, tu gardes l'encapsulation sans perte de performance.
- Évite les "using namespace", voir: http://0217021.free.fr/portfolio/axel.berardino/articles/bon-usage-using-namespace - Lorsque tu veux créer une énumération, n'utilise pas de #define ! Utilise un "enum" ! Normalement en C++, tu n'as jamais à utiliser un define. Si tu as besoin d'une valeur constante, on créé généralement une variable "static const" correctement typée.
- En génie logiciel, si tu créés une classe "Objet", c'est que tu as soucis de conception. Ici, tu ne fais heureusement pas tout hériter de cette classe. Le nom n'est en revanche pas très judicieusement choisie.
- vector< vector< float > > violent en terme de performance vu que tu connais la taille exact de tes tableaux. Deux solutions:
* Tu fais du C++ "normal" => utilise une classe templatée qui encapsule un tableau statique dont tu fixes la taille.
* Tu fais du C++0X => utilise un std::vector<std::array<float, 3>>
- vector.resize => Attention: resize change la taille externe du tableau, mais pas sa capacité. Ici, vu que tu ne le fais qu'au chargement, il n'y a pas de souci. Mais si tu fais la chose suivante:
- std::vector<float> tab;
tab.resize(1000);
// puis
tab.resize(1);
// Le tableau prend toujours de la place en mémoire.
Pour éviter cela, deux solutions:
* Tu fais du C++ "normal" => utilise le "swap trick" après ton resize: tab.swap(tab);
* Tu fais du C++0X => utilise tab.shrink_to_fit();
- Style: Les booléens ne s'utilisent pas comme des entiers:* if (_isDead true)> if (_isDead)* if (_isDead false)> if (!_isDead)
- Librairie => Bibliothèque (librairie est une traduction incorrecte de "library")
- if (_typeDeCamera MINICARTE) [...] if (_typeDeCamera VUEPRINCIPALE): Quand tu as des enum, utilise un switch plutôt que plein de if.
- gestionArme(Objet *listeObjets[], int nombreObjets) => C'est bizarre de déclarer utiliser un tableau d'Objet, pour n'en utiliser que le premier.
- Objet *liste_objets[50]; => Pourquoi 50 ? Si tu ne connais pas le nombre par avance, un tableau dynamique serait peut être adapté.
envi33
Messages postés18Date d'inscriptiondimanche 17 juillet 2011StatutMembreDernière intervention25 janvier 2016 25 juil. 2011 à 09:38
N'hésitez pas à donner votre appréciation global et/ou me dire si le moteur fonctionne bien chez vous!
Merci ;)
16 août 2011 à 12:29
16 août 2011 à 12:19
16 août 2011 à 01:05
Si tu veux juste le lancer facilement télécharge plutôt le zip complet sur le site officiel du projet, il n'y a plus qu'à dézipper et à lancer le .exe:
http://envi3d.wikeo.net/
Et je t'assure que je ne suis pas un crack de la programmation, il y a juste beaucoup de C++, ce qui ne rend pas la lecture facile, et des commandes opengl et qt. Tout ça s'apprend avec un peu d'entrainement sur le siteduzero.com!
C'est un très bon site pour commencer et ne pas s'embourber dans des codes inutiles et ennuyants^^
Bon courage à toi!
(pour donner des nouvelles, j'en suis à 80% de la version 2 du jeu, avec l'éditeur de carte, la course au drapeau et les ennemi pour vous barrer la route à coup de tir de barrage. En effet j'utilise à présent complètement les classe qVector et qVector3D et j'ai finis de tout transformer en VBO! A bientôt et merci pour tous vos conseils!)
15 août 2011 à 09:56
Enfait la question peut parraître bête mais j'ai aucunne idéée de ce que je dois mettre en".exe" et non plus comment le faire. Enfait je suis un débutant débutant mais je m'interesse beaucoup au millieux de la programation donc ça serait sympa que tu m'explique! Sinon j'ai jeté un oeil à tes codes. Je vais pas te cacher que la plupart des codes sont trops complex pour moi,mais de ce que je comprend, pour moi, c'est juste trop "balaize"!
Continue c'est extra!
4 août 2011 à 21:54
Y-a-t-il aussi des erreurs juste après avec tous les chargements de fichiers?
Merci!
4 août 2011 à 13:39
Compilation OK
mais a lexecution :
+ Support OpenGL : OK
----->ERREUR 01 ; Chargement du fichier map : FAILED
..\Desktop\Envi3D-build-desktop\debug\Envi3D.exe s'est terminé avec le code -1073741819
2 août 2011 à 01:16
1 août 2011 à 13:46
J'ai survole une partie du code, tres clair et tres bien commente :o) mais j'ajoute ma petite remarque :
Dans ton whellEvent(), tu verifies que la nouvelle vitesse est entre 0 et 6 avant d'appeler joueur->setVitesse().
En toute rigueur, si tu respectes le paradigme de la programmation objet c'est dans setVitesse() que tu devrais faire ce test. C'est en effet l'objet joueur qui sait quelles vitesses sont valides ou pas pour lui (et si tu fais du polymorphysme avec plusieurs classes derivees de joueur (par exemple si tu peux jouer un bonhomme, un tank ou un avion), chacune peut avoir un comportement different sans que tu ais desoin d'adapter le code principal du programme).
J'ai aussi une petite remarque sur une des remarques de CptPingu :
> Lorsque tu passes en argument un type pod (int, float, char, etc...), inutile de mettre
> const devant, vu que la valeur est passée par copie. const float <=> float lors d'un
> passage d'argument.
Je ne suis pas d'accord. Const est surtout la pour faciliter la maintenance et la relecture du code. Quand je vois qu'une fonction prend un argument "const", je sais qu'il est constant, sans avoir a reflechir si dans ce language la il est de toutes facons passe en recopie ou pas.
Ca aide aussi si par erreur quelqu'un essaie de modifier cet argument dans la fonction.
Avec le const, ca va generer une erreur de compilation, et il sera donc facile de trouver/corriger l'erreur. Sans le const, ca va compiler correctement, mais la valeur ne sera pas modifiee dans la fonction appelante. D'ou un bug bizarre lors de l'execution qui a toutes les chances de passer inapercu jusqu'a la livraison :o)
Bref, si techniquement c'est vrai que ca ne change rien avec ces types, ce n'est pas inutile d'utiliser const quand meme.
Eric
26 juil. 2011 à 18:17
- En effet je n'ai pas intégré les VBO par manque de connaissances, mais je crois que je vais devoir inévitablement m'y plonger :D, surtout si Qt me vient en aide...
- Et je n'avais pas pensé à la classe QVector3D, je vais certainement y gagner, ne serais-ce qu'en simplicité, tu as raison.
(merci pour le test d’exécution!)
26 juil. 2011 à 17:07
Compilation réussie avec Qt4.70+minGW sous Win7 32 bits.
Exécution ok!
Le code :
Mon intérêt s'est focalisé sur la méthode "OpenGLWidget::paintGL", qui est le centre opérationnel de toute application reposant sur QGLWidget.
Je vois que la scène est entièrement recalculée à chaque image : pour l'instant ton application ne fait pas grand chose, les ressources sont donc suffisantes, mais plus tard?
Les moyens d'optimiser ces calculs existent, l'un d'entre eux s'appelle " Vertex Buffer Objects" ou "VBO", dont la mise en oeuvre est rationalisée dans la classe de Qt "QGLBuffer".
Ces techniques d'optimisation reposent cependant sur l'existence de tableaux/vecteurs à une dimension.
Des déclarations telles que :
std::vector< std::vector< std::vector< float > > > _tableauMesh
sont donc satisfaisantes pour l'esprit mais impropres à un usage orienté "optimisation".
Sur ce sujet, un document récent à potasser :
http://gbelz.developpez.com/remi-achard/gpu-avance-avec-qt/
Ah, je vois que tu as créé une classe "Coord3D", c'est tout à ton honneur, mais connais-tu l'existence de la classe " QVector3D" ? (et sa fonction static "QVector3D::normal", qui fait des merveilles pour le calcul des normales).
Bonne continuation...
26 juil. 2011 à 13:49
Très bonne source! Très bonne remarques également de CptPingu.
26 juil. 2011 à 10:49
26 juil. 2011 à 00:07
> vector< vector< float > > _tableauMesh;
> Je pensais que cette ligne ne consommait rien en mémoire étant donné que je lui donne pas le nombre de case?
J'ai du mal m'exprimer. Il n'y a pas de problème avec la déclaration. Il y a un souci d'utilisation mémoire supplémentaire lors de l'utilisation.
En effet, un std::vector, en interne, ne s'amuse pas à faire un realloc à chaque fois que tu changes sa taille. A chaque fois que sa taille dépasse sa capacité (capacité = sa taille interne), il double sa capacité. Avec cette technique, tu limites grandement les allocations. En contrepartie, tu peux très bien te retrouver avec une taille de 1000 et une capacité de 3000 (exemple bidon, attention [1]). Donc si tu as plein de vector de vector, inutile de te faire un dessin...
Néanmoins, avec un resize (taille) + reserve (capacité) on peut s'en sortir. Mais autant utiliser un tableau statique plutôt qu'un vector dynamique, si tu cherches à représenter un tableau statique !
[1] Généralement, les implémentations de STL (oui, il y en a plusieurs qui existent), utilisent la technique de puissance de deux. La capacité passe de 1,2,4,8,16,32,64,etc...
Ex: resize(5) => capacité 8
resize (260) => capacité 512.
25 juil. 2011 à 20:14
J'ai pu modifier tout le code (et apprendre pas mal de chose en passant) pour la prochaine version, mais je bute sur les vector :
- Pourquoi y a-t-il un soucis avec la déclaration :
vector< vector< float > > _tableauMesh;
Je pensais que cette ligne ne consommait rien en mémoire étant donné que je lui donne pas le nombre de case?
25 juil. 2011 à 16:58
Encore merci!
25 juil. 2011 à 11:13
Le projet est sympa. J'aime bien l'idée de la minicarte. C'est un très bon début. Si tu veux faire un moteur, peut être qu'il serait pratique d'en faire une bibliothèque, en essayant de bien séparer C++/OpenGL et Qt ?
Je n'ai malheureusement pas encore pu compiler et tester cette source. En revanche, j'ai lu le code source, et j'ai quelques critiques à te proposer.
A noter que j'ai vais écrire beaucoup de choses négatives, mais ça ne va absolument pas dire que ton projet n'est pas bien. Bien au contraire. Pour progresser, il faut pointer ce qui ne va pas, pas ce qui va bien.
- Attention code mort (code en commentaire non utilisé)
- Des vrais commentaires en doxygen aurait été sympas (http://0217021.free.fr/portfolio/axel.berardino/articles/ecrire-de-bons-commentaires)
- Lorsque tu initialises des valeurs dans un constructeur de classe, utilise la liste d'initialisation plutôt que de mettre à jour les valeurs dans le corps de ton constructeur.
- Tu peux déclarer des variables où tu veux. Contrairement au C (non 98) tu peux déclarer une variable au milieu du code. Des fois tu utilises aussi des variables temporaires inutiles.
Ex: "distanceDroiteAuPoint" (réécriture)
float Coord3D::distanceDroiteAuPoint(const Coord3D& pointDeLaDroite, const Coord3D& point) const
{
Coord3D vectDeuxPoints(pointDeLaDroite, point);
Coord3D prod = crossProduct(vectDeuxPoints);
// On pourrait même mettre:
// Coord3D prod = crossProduct(Coord3D(pointDeLaDroite, point));
prod = prod - prod * 2;
return prod.length() / this->length();
}
- Le "this->" n'est pas nécessaire. Il n'est nécessaire qu'en PHP (et souvent utilisé en Java), mais pas en C++.
- Lorsque tu passes en argument un type pod (int, float, char, etc...), inutile de mettre const devant, vu que la valeur est passée par copie. const float <=> float lors d'un passage d'argument.
- Par convention, on essaie de différencier une variable locale, d'un attribut. Il est d'usage d'ajouter un signe distinctif. (Par exemple: float _x; pour ta classe 3DCoord).
- Les membres en public, c'est moyen... Si tu fais un "getter" et un "setter" inlinés, tu gardes l'encapsulation sans perte de performance.
- Évite les "using namespace", voir: http://0217021.free.fr/portfolio/axel.berardino/articles/bon-usage-using-namespace
- Lorsque tu veux créer une énumération, n'utilise pas de #define ! Utilise un "enum" ! Normalement en C++, tu n'as jamais à utiliser un define. Si tu as besoin d'une valeur constante, on créé généralement une variable "static const" correctement typée.
- En génie logiciel, si tu créés une classe "Objet", c'est que tu as soucis de conception. Ici, tu ne fais heureusement pas tout hériter de cette classe. Le nom n'est en revanche pas très judicieusement choisie.
- vector< vector< float > > violent en terme de performance vu que tu connais la taille exact de tes tableaux. Deux solutions:
* Tu fais du C++ "normal" => utilise une classe templatée qui encapsule un tableau statique dont tu fixes la taille.
* Tu fais du C++0X => utilise un std::vector<std::array<float, 3>>
- vector.resize => Attention: resize change la taille externe du tableau, mais pas sa capacité. Ici, vu que tu ne le fais qu'au chargement, il n'y a pas de souci. Mais si tu fais la chose suivante:
- std::vector<float> tab;
tab.resize(1000);
// puis
tab.resize(1);
// Le tableau prend toujours de la place en mémoire.
Pour éviter cela, deux solutions:
* Tu fais du C++ "normal" => utilise le "swap trick" après ton resize: tab.swap(tab);
* Tu fais du C++0X => utilise tab.shrink_to_fit();
- Style: Les booléens ne s'utilisent pas comme des entiers:* if (_isDead true)> if (_isDead)* if (_isDead false)> if (!_isDead)
- Librairie => Bibliothèque (librairie est une traduction incorrecte de "library")
- if (_typeDeCamera MINICARTE) [...] if (_typeDeCamera VUEPRINCIPALE): Quand tu as des enum, utilise un switch plutôt que plein de if.
- gestionArme(Objet *listeObjets[], int nombreObjets) => C'est bizarre de déclarer utiliser un tableau d'Objet, pour n'en utiliser que le premier.
- Objet *liste_objets[50]; => Pourquoi 50 ? Si tu ne connais pas le nombre par avance, un tableau dynamique serait peut être adapté.
25 juil. 2011 à 09:38
Merci ;)