Bonjour, je n'ai jamais réussi à comprendre le principe de l'éclairage avec OpenGL. Ici par exemple, je définis une source de lumière directionnelle et j'obtiens ceci :
Jusqu'ici rien d'anormal, jusqu'à ce que je déplace la caméra : Quelque soit le point de vue, la sphère apparaît toujours éclairée de cette manière.
Autre question : En me contentant d'un sol plat, voici ce que j'obtiens :
Ici, le vecteur représentant la direction de la lumière a pour coordonnées (1,1,-1) ; si je le fixe à (0,0,-1), la lumière est censée arriver à la verticale vers le bas et donc éclairer davantage la scène. Pourtant, voici ce que ça donne :
Je précise que les normales sont bien définies (Le vecteur normal du sol a pour coordonnées (0,0,1)).
Il y a également un autre problème : Comme vous le constatez sûrement sur la sphère, les arêtes sont visibles et ce n'est pas très esthétique, j'ai essayé de résoudre ce problème en faisant :
Ou même :
Code : Sélectionner tout - Visualiser dans une fenêtre à part glShadeModel(GL_FLAT);
Mais ça n'a rien changé.
Code : Sélectionner tout - Visualiser dans une fenêtre à part glShadeModel(GL_SMOOTH);
Voici le main :
Voici le rendu, ce dernier se fait à partir d'un fichier .obj dans lequel les normales sont bien définies :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81 int main(int argc,char *argv[]) { SDL_Surface *fenetre; SDL_Event evenement; Principale infos; Bureau *bureau; bool retour; unsigned int chrono,dureeMesuree; srand(time(NULL)); if(SDL_Init(SDL_INIT_VIDEO)<0) { printf("Erreur initialisation SDL, pressez une toucher pour quitter"); getch(); return 0; } Init(&infos); bureau=infos.getBureau(); if(!bureau->getPleinEcran()) fenetre=SDL_SetVideoMode(800,600,32,SDL_OPENGL); else fenetre=SDL_SetVideoMode(bureau->getLargeur(),bureau->getHauteur(),32,SDL_OPENGL|SDL_NOFRAME); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if(!bureau->getPleinEcran()) gluPerspective(FOVY,4.0/3,NEAR,FAR); else gluPerspective(FOVY,bureau->getRatio(),NEAR,FAR); glEnable(GL_TEXTURE_2D); glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHTING); //Activation éclairage glEnable(GL_LIGHT0); float couleur[4]={1,1,1,1}; //Définition couleur lumière float direction[4]={1,1,-1,0}; //Définition direction lumière glLightfv(GL_LIGHT0,GL_AMBIENT,couleur); //Attribution couleur glLightfv(GL_LIGHT0,GL_DIFFUSE,couleur); glLightfv(GL_LIGHT0,GL_SPECULAR,couleur); glLightfv(GL_LIGHT0,GL_POSITION,direction); //Attribution direction infos.chargeTextures(); retour=infos.InitMap(); if(!retour) { SDL_Quit(); return 0; } while(1) { SDL_PollEvent(&evenement); if(evenement.type==SDL_QUIT) break; else if(evenement.type==SDL_KEYDOWN) { if(evenement.key.keysym.sym==SDLK_ESCAPE&&bureau->getPleinEcran()) break; } //Rendu et gestion caméra ... dureeMesuree=SDL_GetTicks()-chrono; if(dureeMesuree<DUREE_FRAME) SDL_Delay(DUREE_FRAME-dureeMesuree); chrono=SDL_GetTicks(); } SDL_Quit(); return 0; }
Merci de bien vouloir m'éclairer à ce sujet (Non ce n'est pas un jeu de mot ^^) et bonne journée
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61 void OBJ_drawVBO(OBJ_VBO *VertexBufferObject) { int compteurFaces=0,first=0; int numFaceChangeTex1,numFaceChangeTex2,compteurFacesChangeTex=0,compteurTex=0; const int nbVertices=3*VertexBufferObject->nbFaces; glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_COLOR_ARRAY); glEnable(GL_BLEND); glEnable(GL_ALPHA_TEST); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glAlphaFunc(GL_GREATER,0.2); glBindBuffer(GL_ARRAY_BUFFER,VertexBufferObject->bufferVRAM); glVertexPointer(3,GL_FLOAT,0,BUFFER_OFFSET(0)); glTexCoordPointer(2,GL_FLOAT,0,BUFFER_OFFSET(nbVertices*3*sizeof(float))); glNormalPointer(GL_FLOAT,0,BUFFER_OFFSET(nbVertices*3*sizeof(float)+nbVertices*2*sizeof(float))); glColorPointer(3,GL_FLOAT,0,BUFFER_OFFSET(nbVertices*3*sizeof(float)+nbVertices*2*sizeof(float)+nbVertices*3*sizeof(float))); while(1) { numFaceChangeTex1=VertexBufferObject->liste_faces_change_tex[compteurFacesChangeTex]; numFaceChangeTex2=VertexBufferObject->liste_faces_change_tex[compteurFacesChangeTex+1]; if(numFaceChangeTex2==-1) numFaceChangeTex2=VertexBufferObject->nbFaces; if(numFaceChangeTex1==compteurFaces) { if(VertexBufferObject->textures[compteurTex]!=-1) { glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D,(GLuint)VertexBufferObject->textures[compteurTex]); } else glDisable(GL_TEXTURE_2D); glDrawArrays(GL_TRIANGLES,first,3*(numFaceChangeTex2-numFaceChangeTex1)); //Dessin des faces jusqu'au prochain changement de texture first+=3*(numFaceChangeTex2-numFaceChangeTex1); compteurFaces+=(numFaceChangeTex2-numFaceChangeTex1)-1; compteurFacesChangeTex++; compteurTex++; } compteurFaces++; if(compteurFaces==VertexBufferObject->nbFaces) break; } glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_COLOR_ARRAY); glEnable(GL_TEXTURE_2D); }
Edit : Ok alors petite négligence de ma part : Il faut définir la direction de la lumière après avoir appelé la matrice modelview, ceci résout le problème de l'éclairage qui ne change pas quelque soit le point de vue. Mais on dirait que l'axe des Z est inversé : Lorsque je définis comme vecteur (1,1,-1) la sphère semble éclairée par le bas et inversément lorsque je définis (1,1,1)
Partager