souci avec lissage des ombres
Bonjours à tous
Je suis nouveau sur le forum parce que je suis tout simplement nouveau dans le développement de jeux video ( perspicace le petit me diriez vous :D )
Pour ma part, j'ai choisi de développer un jeux de sous-marins, seulement, les belle rondeur de ceux ci gâché par des polygones, c'est dommage. je suis donc sur le développement d'une fonction intituler addSubSurf qui en faite calcule les vecteur normaux au point, connaissant ceux des faces. Seulement, mon souci et des lors la compilation, je me retrouve avec un sous-marin tout noir. tandis que lorsque cet fonction n'est pas appelé sur mon corps de sous-marin, j'ai belle est bien les lumière qui fonctionne dessus, mais toujours avec le souci des polygone bien entendu. :(
Je vous explique mon système ...
tout d'abord, je charge tout les objets contenu dans un fichier .3ds. Les calculs des normals au faces y sont notamment inclue.
mesh[0].load3DS ("models/sousMarinCorps.3ds");
Voici l'appel de la fonction qui devrai calculé tout les vecteur normaux pour chaque point. l'argument 0 signifie que j'applique cet fonction que sur l'objet n°0 contenu dans mon fichier 3DS à savoir : le corps de mon sous-marin.
mesh[0].addSubSurf (0) ;
Enfin, je compile une display liste pour optimisé le CPU lors des rendu des frams
mesh[0].compileDisplayListe(0);
Dans ma fonction charger de dessiné mes frams, je n'est plus qu'a :
mesh[0].draw (0);
pour dessiner mon corps de sous-marin.
Intéressons nous maintenant à la fonction addSubSurf dans ma class intitulée DS_OBJECT
Code:
1 2 3 4
|
void DS_OBJECT::addSubSurf (int MeshNum)
{
obj_vertex allVertices[2000] ; |
C'est un tableau permettant de stocké les float de x, y, z de mes futur cordonné de normals pour chaque points : une structure appelé obj_vertex.
Code:
1 2 3 4
|
int id, i, j ;
for ( i = 0 ; i < mesh[MeshNum].polygons_qty; i++ ) |
mesh[MeshNum].polygons_qty me retourne le nombre de triangle dans l'objet de numero MeshNum.
Triangle ?! Oui, parce que les .3ds ne sont fait que de triangles, un avantage pour le calcul des normals. :mrgreen:
Code:
1 2 3 4
|
{
id = mesh[MeshNum].polygon[i].a ; |
Donc, on va chercher le numéro du point A du poligone I
Pourquoi pas directement ces cordonné ? parce que 2 face ayant un point en commun, seront 2 face qui auron un même id pour ce point, et avec l'id du point, il nous reste plus qu'a aller chercher les x, y ,z de ce point dans un autre tableau. Cela économise de la mémoire lorsque 1 point peut avoir entre 8 et 20 faces en commune.
Code:
1 2 3 4
|
allVertices[id].x += mesh[MeshNum].normals[i].x ;
allVertices[id].y += mesh[MeshNum].normals[i].y ;
allVertices[id].z += mesh[MeshNum].normals[i].z ; |
et on ajout les composante à mon tableau de cordonné de normals par point. Qui di triangle, di 3 point, donc on fait exactement pareil pour les point B et C
Code:
1 2 3 4 5 6 7 8 9 10 11 12
|
id = mesh[MeshNum].polygon[i].b ;
allVertices[id].x += mesh[MeshNum].normals[i].x ;
allVertices[id].y += mesh[MeshNum].normals[i].y ;
allVertices[id].z += mesh[MeshNum].normals[i].z ;
id = mesh[MeshNum].polygon[i].c ;
allVertices[id].x += mesh[MeshNum].normals[i].x ;
allVertices[id].y += mesh[MeshNum].normals[i].y ;
allVertices[id].z += mesh[MeshNum].normals[i].z ;
} |
Enfin, une convention veux que les vecteur normals soit de normes 1.0f. donc pour tout les vertex de mon objet (mesh[MeshNum].vertices_qty) on fait un petit pythagore dans les 3 dimensions pour obtenir la norme, puis on divise les 3 composant x,y,z par la norme obtenu à fin d'avoir une norme de 1 ( le principe de a/a = 1 )
Code:
1 2 3 4 5 6 7 8 9 10 11 12
|
for ( i = 0 ; i <= mesh[MeshNum].vertices_qty ; i++ )
{
float norme = sqrt ( (allVertices[i].x*allVertices[i].x) + (allVertices[i].y*allVertices[i].y) + (allVertices[i].z*allVertices[i].z));
if ( norme > 0 ) {
norme = 1 /norme;
mesh[MeshNum].SubSurf[i].x *= norme;
mesh[MeshNum].SubSurf[i].y *= norme;
mesh[MeshNum].SubSurf[i].z *= norme;
}
} |
pour finir, il faut prevenir la fonction compileDisplayListe que l'objet à 1 normals par point.
Code:
1 2 3
|
mesh[MeshNum].SubSurfActived = true ;
} |
compileDisplayListe se contentera de précisé chaque normals contenu mesh[MeshNum].SubSurf pour chaque point de mon objet.
je praicise que j'ai bien mi glShadeModel(GL_SMOOTH); à l'initialisation d'openGL.
En l'espérance d'une réponse, je vous remercie de votre attention ainsi qu'a votre aide éventuel.