Bonjour, il ya deux semaines, j'ai décidé de faire un (petit) jeu en 3d avec opengl ou on controlerai un peti vaisseau spatial a la souris. J'ai bien sur lu ET COMPRIS le cours de m@teo21 sur le c/c++ et le tuto de kayl mais je me heurte a beaucoup de problemes, de plus je suis passé a linux il y a une semaine donc je galere encore plus.
voila le code source (attention, c'est un peu long il n'est peut etre pas utile de tout lire):
voila alors tout d'abord, bravo a ceux qui ont tout lus.
les problemes:
-quand je compile et que je vai dans la fonction JeuDessinerLeJeu(); le programme se ferme brutalement et code blocks me dit :"Process terminated with status -1 (0 minutes, 6 seconds)"
quand j'execute le code pour charger une texture donné par kayl, j'ai la meme erreur.
si vous avez lu mon code, vous avez vu que j'ai éssayé du faire que bouger la souris a gauche ou a droite décale le vaisseau. ça ne marche pas, le vaisseau reste immobile.
je pense qu'une mauvaise utilisation des pointeurs sur tableau de structure de ma part cause un dépassement de mémoire.
Si vous avez des idée pour le fonctionnement du control du vaisseau a la souris, dite le moi.
mon débugger ne dit rien, il compile sans probleme, je crois que c'est linux qui tue mon programme quand il fait un dépassement de mémoire, j'ai éssayé de mettre en commentaire certaine lignes de la fonction JeuDessinerLeJeu(); mais ça ne marche touours pas...
Le compilateur, ça compile, et si il y a un warning, il te le dit, si il y a une erreur, il s'arrete. Ensuite, il link et pond l'executable, que tu peux lancer.
Le debuggueur est un outil qui permet - PENDANT L'EXECUTION - d'arreter l'execution si l'utilisateur le demande, et de dire ou ça s'est arrété, et de te dire quelle est la valeur de chaque variable au moment ou ça a planté.
Tu n'utilises pas le debuggueur, alors ne me dis pas "je sais", puisque visiblement tu sais pas ce que c'est.
Ca ne sera pas facile de trouver l'erreur; essaye de commenter le contenu de JeuDessinerLeJeu(); pour voir si ca marche (et de décommenter petit à petit).
Ceci dit, le fonctionnement de ta méthode est fondamentalement faux... Tu as lu les tuto de Kayl ? Tu as zapé le cours sur les matrices ou quoi ?
Tu calculs les positions du sommets du vaisseau à chaque fois que tu veux le dessiner... t'es pas malade ? Tu te rends compte si on devait faire des opérations sur TOUT les sommets quand on a plusieurs millier de façes ?
Alors oui, le calcul doit être fait... mais si il est dans ton code, c'est le CPU qui s'en charge.
Si tu utilise les matrices, et donc OpenGL, se sera le GPU qui fera les calculs (faut bien que la carte graphique serve à quelque chose).
Pour faire déplacer ton vaisseau de 5 unités vers X.
Au lieu de faire des glVertex(5+x, y, z); ...
Il faut faire:
glTranslate(5, 0, 0); // tous les points suivants seront décalés de 5 unité sur l'axe 5
glvertex(x, y, z);
...
Pour ce qui est de la boucle principale... c'est une horreur aussi !!
Déjà la boucle for(;;)
replace là par un while(booléen) (et tu passes le bouléen à false quand on ferme le programme, plutôt qu'un exit(0);
En effet, quand tu aurra chargé des textures, modèles 3D etc... il faudra penser à les supprimer quand on fermera le programme (donc apres la boucle "infinie"), ce que ne fera pas un exit(0);
Ensuite cette boucle "infinie"... chaque itération doit correspondre à une image (et une seule).
Si je dis ça, c'est en pensant aux "DessinMenu(angleX,angleZ,angleY)" etc...
En effet, avec cette méthode (avec des sleep :s ) il va se passer quelques secondes où seulement une seule animation sera produite...
Et si on veux afficher deux animations en même temps ? Et si on a besoin d'afficher le monde 3D en même temps ? et en temps réel ?
Pour faire des animations il faut:
- savoir quelles animations doivent être jouées
- connaitre le temps sur laquelle l'animation doit être jouée (1 secondes, 2 secondes ?)
- connaitre le temps écoulé entre 2 images pour pouvoir divisé le mouvement en plusieurs étapes (assez d'étapes pour que l'animation se déroule pendant x secondes )
On évite ainsi:
- les sleep
- un affichage limité à une seule chose
On gagne:
- en fluidité (l'animation est découpée en de nombreuses images)
Exemple:
void AfficherMenu(float elapsed_time);
void main()
{
float last_time = SDL_GetTicks();
float current_time, elapsed_time;
bool run = true;
while(run)
{
// On récupère le temps écoulés entre 2 images dans la variable ellapsed_time;
current_time = SDL_GetTicks();
elapsed_time = current_time - last_time;
last_time = current_time;
// Mise à jour des évènements
SDL_Event event;
while(SDL_PollEvent(&event)
{
// traitements...
// Exemple: si on veux jouer une animation quand on appuis sur la touche A:
case SDLK_a:
MenuJouerAnimationA(); // on va indiquer qu'une animation doit être jouée
break;
}
// Affichage
InitialisationImage();
AfficherLaScene3D(elapsed_time);
ResetDuZBuffer();
AfficherMenu(elapsed_time); // on fera un blendin au cas où so l'interface doit être tansparante pour voire la scène
SDL_GL_SwapBuffers(); // on basule notre image UNE SEULE FOIS
}
}
void AfficherMenu(float elapsed_time)
{
float temps_animationA = 2000; // 2000 millisecondes = 2 secondes
float temps_animationA_en_cours = 0; // pour savoir où en est l'animation
float angle; // l'angle pour nos menu
if(JouerAnimationA() ) // si on doit jouer l'animation A
{
// Si l'animation a finis de se jouer, il faut la couper
if ( temps_animationA_en_cours >= temps_animationA) {
TerminerAnimationA();
}
// on calcul le pourcentage de l'animation effectué pour trouver l'angle à utilser (angle variant de 200 à 0)
float pourcentage = temps_animationA_en_cours * 100 / temps_animationA;
angle = 200-(pourcentage * 200 / 100);
DessinMenu(angle);
temps_animationA_en_cours += elapsed_time; // on met à jours le temps d'animation écoulé
}
...
}
désolé fvirtman je me suis trompé . L'onglet débugger est vide, mais l'onglet build log contient ça :
""
Checking for existence: /home/gaspar/Prog/Tetra/bin/Debug/Tetra
Executing: /home/gaspar/Prog/Tetra/bin/Debug/Tetra (in /home/gaspar/Prog/Tetra/bin/Debug)
Process terminated with status -1 (0 minutes, 7 seconds)
""
"7 seconds" c'est le temps que j'ai mit avant de demander (depuis mon menu) a jouer et c'est la que le programme s'arrete.
"status -1" sa veut dire quelque chose de précis ??(a part qu'il y a eu un probleme)
Merci sebajuste de m'avoir lu, pour le sleep, j'ai pas encore remplacé par ta technique(que j'ai déja mise dans le menu) mais je compte le faire, pour les matrices, je vais remplacer tout ça, merci
Par contre, mon menu est en fait un gros cube et sur chaque face, on trouve des options, et les animations sont des rotations pour passer d'une face a l'autre. on ne fait jamais plus d'une animation a la fois et l'utilisateur n'est pas sensé cliquer sur des bouton pendant que le cube tourne.
pour le exit(0); sa simplifie quand même le code, je veu bien quitter de maniere plus conventionnelle, mais sa changera quoi?
Sinon, j'ai déjà essayer de commenter et décommenter les lignes de JeuDessinerLeJeu(); mais ça ne marche que quand tout est en commentaire, je crois que je m'embrouille un peu sur les tableaux de pointeur sur structure, surtout quand en relisant le cours j'ai vu que les tableaux était des pointeurs. j'ai meme éssayer de faire un int qui contiendrai une adresse(celle du début de mon tableau), une sorte de pointeur mais pas déclaré comme un pointeur mais il voulait pas aller a l'adresse contenue dans cet int parce que c'est pas un vrai pointeur.
Pour lancer le debugger, sur Code::Blocks, c'est la touche F8 par défaut.
Sinon, je ne comprends pas... Pourquoi utilise tu un tableau[1000] alors que tu n'utilise que l'index [0] ??
Pourquoi un tableau ?
Pour le exit(0), il faut bien comprendre que ca va killer ton programme... que vont devenir les pointeurs où la mémoire a été allouée ?
Que vont devenir les textures chargées dans la carte graphique ?
Ça va être au système d'exploitation de faire le ménage, car tu ne l'aura pas fait toi même.
Et si pour X raison, ce ménage ne se fait pas (ou mal... par exemple au mauvais vidage automatique des VBO chargés sur la carte graphique, ou des textures, ou quoique ce soit d'autre) tu risques un plantage complet de ta machine.
en fait, j'avai prévu de faire un tableau[1000] pour stocker tout les éléments du jeu( le vaisseau, les astéroides, les bonus a atraper, peut etre les méchants) mais pour l'instant, j'éssaye déja d'y stocker le vaisseau spatial(ou pluto sa vie, sa position et tout le reste)
Quand tout ça marchera, je ferai une allocation dynamique pour prendre seulement ce dont j'ai besoin.
édit :J'ai lancé le débugger, quand je demande a jouer,le programme c'est bloqué et comme je suis en fullscreen et que je connais pas le raccourcis qui revient au bureau sous linux, je sui forcé d'éteindre l'ordi puis de le redémarer ...
je vai tester sans le fullscreen
edit :quand je lance le débuggeur, (j'ai mis le programe sans fullscreen, dans une fenetre de 200 px sur 200px),
une boite de dialogue me dit "Program received signal SIGSEGV, Segmentation fault.
Do you want to view the backtrace?"
quand je demande a voir le "backtrace", il me dit qu'il a recçu le signal a la ligne 55 de main.cpp
Là tu fais "oui", et avec un peu de chance, il va t'indiquer les différents appel de fonctions, jusqu'à celle qui fait planter.
Segmentation fault => ton programme essaye d'accéder à une zone mémoire qui n'a pas été allouée.
Donc oui, ton problème vient de tes pointeurs.
Si c'est pour stocker tes objets, je te conseil de passer plutôt par un std::vector pour plusieurs raisons:
- Pas de tableau, moins de pointeurs (tu peux toujours faire un vector de pointeur, mais tu évite grandement les erreurs de toute façon)
- le vector s'adapte a tes besoins: il s'agrandi (par liste chainée) quand tu as besoin d'ajouter des éléments (pas d'allocation à faire)
Edit: pour le debugger, il faut arrêter le programme (avec l'icône en forme stop rouge, avec une croix blanche à l'intérieur). Car même après avoir planté, le programme est toujours en route.
merci pour ton aide. Mon programme est en fullscreen donc quand il se bloque, il faut retourner au bureau et je sais pas comment faire sous linux. j'ai un peu regardé dans l'aide de KDE mais j'ai pas trouver l'équivalent du bon vieu "ctrl+alt+suppr" de windows.quand je regarde le backtrace, il me dit qu'il y a un probleme quand je veux voir la meilleur résolution pour mon jeu.(cette ligne n'a jammai posé probleme avant)
Je suis en train de regarder ton lien, j'ai du boulot ! je m'y met et je revien quand j'ai lu tout ça.
encore merci
j'ai mis mon prog dans une petite fenetre et j'ai lancé le débugger, quand j'arrive a la fonction jouer(), comme prévu, sa bug et il me dit"Program received signal SIGSEGV, Segmentation fault.
In ?? () (/usr/lib/libGLcore.so.1)"
mais "libGLcore.so.1" c'est la librairie de OpenGL non? le coeur de opengl, d'après le nom meme. Si C'est opengl qui beug, je suis coincé non?
(a moin de reprogrammé opengl )
edit: je suis pas sur d'avoir bien compris, vector c'est une sorte de super-tableau amélioré?
Oui, le type de paramètre est valide, donc OpenGL le prend... mais le contenu est erroné, et OpenGL plante son calcul.
Le problème vient don bien de ton programme
daccord mais comment trouver quel parametre pourri je lui enoie? si le débuggeur peut pas, il va falloir que je teste toute les fonction utilisant opengl de mon programme?? je peux réduire le champ de recherche a la fonction jeuDessinerLeJeu() mais j'ai déja fait tout pleins de test sur cette fonction. Je pense que mes pointeurs sur la premiere case du tableau de structure est pourri mais la question est Pourquoi?
bah, tu plantes un point d'arret au debut de la fonction ou tu penses que ca plante, et tu step in au fur et à mesure en regardant tes variables (locals et globales si necessaires).
[openGL] Programme en 3d
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
Recueil de code C et C++ http://fvirtman.free.fr/recueil/index.html
Recueil de code C et C++ http://fvirtman.free.fr/recueil/index.html
Recueil de code C et C++ http://fvirtman.free.fr/recueil/index.html
Recueil de code C et C++ http://fvirtman.free.fr/recueil/index.html