Bonjour,
Toujours dans la création d´une application à la doom-like en suivant des tutoriaux, je n´arrive pas à positionner une lumière fixe indépendante des mouvements de la caméra.
J´ai d´abord activé l´éclairage et la lumière n°1 ( glEnable...) puis positionné la lumière dans ma fonction draw(); affichage. Le problème c´est que je ne reçois aucune erreur du compilateur sauf que la lumière reste fixée sur la caméra et bouge suivant les mêmes mouvements que celle-ci...
Merci de me venir en aide.
tu dois avoir une commande de ce style dans ton code:
glLightfv(GL_LIGHT0, GL_POSITION, LightPos);
essay de la changer de place, de la mettre après gluLookAt(); ou après glEnd();
Merci neg282 ça fonctionne maintenant ! En fait, je ne l´avais pas mise après les transformations qui affectent aussi la caméra voilà pourquoi.
Sinon j´ai un autre souci : comment faire pour calculer les normales sur les objets d´une scène ( afin de réaliser un bon éclairage).
Aussi : je suis en train de réaliser un niveau en 3d. Pour les murs ( limites du niveau), est ce que le mieux est d´inclure toute la scène dans un cube ( sorte de pièce) ou de délimiter en créant des plans ? merci
Sinon j´ai un autre souci : comment faire pour calculer les normales sur les objets d´une scène ( afin de réaliser un bon éclairage).
Aussi : je suis en train de réaliser un niveau en 3d. Pour les murs ( limites du niveau), est ce que le mieux est d´inclure toute la scène dans un cube ( sorte de pièce) ou de délimiter en créant des plans ? merci
J´ajouterais que si quelqu´un pouvais m´en dire un peu plus sur la gestion des collisions entre objets ou entre la caméra et les objets, je lui en serait très reconnaissant car je ne trouve rien de tel en français sur le web. Merci
( désolé pour le double post)
![]()
calculer les normales peut etre automatisé si tu as un maillage :
déja, il faut - bien entendu - que tous tes triangles soient ORIENTES, car le sens de la normale dépend du fait que tu aies un triangle a,b,c ou a,c,b
ensuite, for all sommets :
pour le sommet S de ton maillage tu vas calculer la normale ainsi :
tu reperes tous les triangles adjacents ( si tu fonctionnes en vertex-array ce sera facile)
tu calcule la normale de chacun de ces triangles ( avec un produit vectoriel) et ensuite, la normale au sommet est la moyenne de tous ces vecteurs normaux. ( que tu renormalise)
je te conseille de précalculer ça et de le stocker dès le départ, car c´est couteux ( bcp de racines carrées) impensable d´y faire dans la boucle principale.
pour les collisions : je te conseille les boites englobantes alignées au décor.
ensuite, pour savoir si un objet ( donc un cube) touche un triangle du décor, tu regardes si les 8 points de la boite sont du meme coté ou non du triangle
( garde la normale de chaque triangle en mémoire, pour savoir si un point est " devant" ou " derriere", tu fais simplement un produit scalaire entre le vecteur normal et le vecteur AP ( ou A est un sommet quelconque du triangle, et P le point a tester)
pas obligé de normaliser AP, seul le signe compte :
négatif tu es derriere.
positif tu es devant.
Afin de ne pas avoir a tester tous les triangles du monde pour les collisions, je te conseille une structure hiérarhique pour ranger tes triangles :
Voxel ( couteux en mémoire, mais super)
Octree
cela est pour un monde qui peut etre n´importe comment.
Si tu geres une HeightMap, le calcule de collision est meme encore + simple ![]()
c´est l´altitude du point par rapport a celle du terrain au point donné x,y
le signe de la différence entre les 2 déterminera tres précisément si tu es au dessus ou dans le terrain...
Merci beaucoup JeanYvesYves. Seulement, comme je suis un débutant en la matière, tes explications bien qu´utiles restent assez floues pour moi...
En effet :
--> le calcul des normales me parait bien hermétique si bien que je n´arrive pas a aligner une ligne de code pour " précalculer" comme tu dis ( mais je veux savoir le faire ! )
--> qu´entends tu exactement par : " je te conseille les boites englobantes alignées au décor." ? De plus, le produit vectoriel pour savoir si l´objet est devant ou derrière me parait un procédé obscur... concrétement qu´est-ce-que ça peut donner ? Voxeel, Octree : c´est quoi ce charabia ?
--> Enfin, pour l´instant j´essaie juste de faire un monde " basique" avec quelques objets éclairés par des spots et quelques pièces délimités dans lesquelles on peut se mouvoir sans en sortir.
Merci de m´éclairer davantage.
ps: felicitations pour ton site perso ( comme je vais entrer en première année d´iut info à la rentrée ça m´aide un peu...)
pas évident d´étayer tout cela, surtout sans schéma !
déja, si tu veux un aperçu de qq théories mathématiques sur la 3D, va sur mon site :
info / culture / theorie prog image
pour rajouter a ce que dit JYY ( c´est pourtant clair... ; ) )
calcul des normales : pour chaque triangle t´as une normale, pour chaque sommet t´as une liste des triangles auquel il appartient, t´as plus qu´a moyenner les normales des triangles auquel appartient un sommet pour avoir la normale en ce sommet ( concept purement 3D-iste ca, la normale en un somment...)
produit vectoriel : vu que tes axes sont orientes, le produit vectoriel de deux vecteurs te donne un vecteur perpendiculaire au plan defini par les deux premiers : ce vecteur peut etre " dans un sens" ou " dans l´autre" ( sur un schema ca passe mieux), ce qui permet de tester les positions relatives ( des fois un produit scalaire peut suffire selon ce que tu testes)
voxel, octree, ce sont des structures de donnees qui peuvent t´interesser ; dans le cas d´un doom-like, le BSP sera egalement de mise... Attention, tout cela n´est pas trivial a implementer ( mais pas bien dur quand on a pige). Tu peux googler sur n´importe lequel de ces termes pour plus d´infos
pour les boites englobantes, regarde le paragraphe " blitting"
ici, c´est de la 2D : tu vois que j´encadre mon sprite avec un rectangle : ce rectangle est aligné avec les axes.
pour la 3D, c´est pareil, c´est parallélépipede.
le trouver est simple : le coin supérieur gauche est ( minx,miny,minz) et le coin inférieur droit est ( maxx,maxy,maxz)
c´est souvent suffisant pour les collisions !
LGV > j´aime bien le " Tu peux googler "
trop fort ![]()
eh eh, google, le meilleur ami du programmeur ( enfin, de tout le monde en fait meme...)
merci JYY je vais y jeter un coup d´oeil. Tu permets que j´imprime pour le lire à tête reposée ?
Voici mon code et j´ai un problème, quand je lance le programme, tout est noir et rien ne s´affiche :
void InitGL ( )
{
glEnable(GL_DEPTH_TEST); / /active le test de profondeur
glEnable(GL_COLOR_MATERIAL); / /active le coloriage
glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,MatSpec
1);
glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,MatDif1)
;
glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,MatAmb1)
;
/ /paramètres du matériau
glEnable(GL_LIGHTING); / /active les lumières
glEnable(GL_LIGHT0); / /active la lumière n°1
glLightfv(GL_LIGHT0,GL_SPECULAR,LightSpec1);
glLightfv(GL_LIGHT0,GL_DIFFUSE,LightDif1);
glLightfv(GL_LIGHT0,GL_AMBIENT,LightAmb1);
/ /paramètres de la lumière
glLighti(GL_LIGHT0,GL_SPOT_CUTOFF,30);
}
void draw()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(40,40,100,0,0,0,0,1,0);
glLightfv(GL_LIGHT0,GL_POSITION,LightPos1);
glNormal3i(0,0,1); / /Définit la normale commune aux sommets
for ( int i=-50;i<50;i++)
{
glBegin(GL_QUAD_STRIP);
glVertex2i(i,-50);
glVertex2i(i+1,-50);
for ( int j=-50;j<50;j++)
{
glVertex2i(i,j+1);
glVertex2i(i+1,j+1);
}
glEnd();
}
glutSwapBuffers();
glutPostRedisplay();
}
Merci de ton aide JYY.
essaye de disabler le lighting pour commencer, si tu vois ton polygone, c´est que t´as un soucis de normale generalement ( mauvaise orientation ? ), ou alors p-e de culling, ou encore de couleur ( genre j´eclaire avec de la lumiere noire...)
si ca peut t´aider, va faire un tour du cote des tuts de NeHe ( neon-helium), il y en a pour tous les gouts : tu pourras comparer ton code avec un qui fait en gros le meme chose, mais qui marche
LGV je suis allé sur le site et j´ai comparé mon code, j´ai essayer de permutter des lignes mais ça ne change rien... je ne vois vraiment pas comment faire.