WxWidgets/Opengl/Linux

WxWidgets/Opengl/Linux - C++ - Programmation

Marsh Posté le 17-07-2006 à 10:09:10    

Bonjour,
 
Voici mon code source qui est cencé m'afficher un cube qui tourne:

Code :
  1. #include "main.h"
  2. myFrameMain::myFrameMain() : wxFrame(NULL, -1, "Hello GL World", wxPoint(-1, -1), wxSize(1024,790), wxDEFAULT_FRAME_STYLE)
  3. {
  4. bool fullScreen=false;
  5. glCanvas = new myGLCanvas(this, fullScreen);
  6. wxSizer *sizer = new wxBoxSizer(wxHORIZONTAL);
  7. sizer->Add(glCanvas, 1, wxALL|wxEXPAND, 0);
  8. this->SetSizer(sizer);
  9. this->SetAutoLayout(true);
  10. this->Layout();
  11. this->ShowFullScreen(fullScreen);
  12. }
  13. myGLCanvas::myGLCanvas(wxFrame *parent, bool fullScreen) : wxGLCanvas(parent, -1, wxPoint(0,0))
  14. {
  15. this->parent=parent;
  16. this->fullScreen=fullScreen;
  17. glShadeModel(GL_SMOOTH);
  18. glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
  19. glClearDepth(1.0f);
  20. glEnable(GL_DEPTH_TEST);
  21. glDepthFunc(GL_LEQUAL);
  22. glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
  23. }
  24. void myGLCanvas::onIdle(wxIdleEvent &event)
  25. {
  26. this->SetCurrent();
  27. if(redefineProjection){
  28.  this->GetSize(&width, &height);
  29.  glViewport(0, 0, width, height);
  30.  glMatrixMode(GL_PROJECTION);
  31.  glLoadIdentity();
  32.  gluPerspective(45.0f, (GLfloat)width/(GLfloat)height, 0.1f, 100.0f);
  33.  glMatrixMode(GL_MODELVIEW);
  34.  redefineProjection=false;
  35. }
  36. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  37. glLoadIdentity();
  38. glTranslatef(0.0f,0.0f,-6.0f);
  39. GLubyte indices[]={
  40.  4, 5, 6, 7, //front
  41.  1, 2, 6, 5, //right
  42.  0, 1, 5, 4, //bottom
  43.  0, 3, 2, 1, //back
  44.  0, 4, 7, 3, //left
  45.  2, 3, 7, 6, //top  
  46. };
  47. const GLfloat sommets[]={
  48.  -1.0, -1.0, -1.0, //0
  49.  1.0, -1.0, -1.0,  //1
  50.  1.0, 1.0, -1.0,   //2
  51.  -1.0, 1.0, -1.0,  //3
  52.  -1.0, -1.0, 1.0,  //4
  53.  1.0, -1.0, 1.0,  //5
  54.  1.0, 1.0, 1.0,  //6
  55.  -1.0, 1.0, 1.0,  //7  
  56. };
  57. glRotatef(zrot, 0.0, 0.0, 1.0);
  58. glRotatef(yrot, 0.0, 1.0, 0.0);
  59. glEnableClientState(GL_VERTEX_ARRAY);
  60. glVertexPointer(3, GL_FLOAT, 0, sommets);
  61. //glEnable(GL_CULL_FACE);
  62. //glCullFace(GL_BACK);
  63. glColor3f(0.0f,1.0f,0.0f);
  64. glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, &indices[0]);
  65. glColor3f(1.0f,0.5f,0.0f);
  66. glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, &indices[4]);
  67. glColor3f(1.0f,0.0f,0.0f);
  68. glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, &indices[8]);
  69. glColor3f(1.0f,1.0f,0.0f);
  70. glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, &indices[12]);
  71. glColor3f(0.0f,0.0f,1.0f);
  72. glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, &indices[16]);
  73. glColor3f(1.0f,0.0f,1.0f);
  74. glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, &indices[20]);
  75. zrot+=0.1;
  76. yrot+=0.18;
  77. glFlush();
  78. this->SwapBuffers();
  79. event.RequestMore();
  80. }
  81. void myGLCanvas::onKey(wxKeyEvent &event)
  82. {
  83. int key = event.GetKeyCode();
  84. if(key==WXK_ESCAPE)
  85. {
  86.  parent->Destroy();
  87. }else if (key==WXK_F1)
  88. {
  89.  fullScreen=!fullScreen;
  90.  parent->ShowFullScreen(fullScreen);
  91. }
  92. }
  93. void myGLCanvas::onSize(wxSizeEvent &event)
  94. {
  95. redefineProjection=true;
  96. }
  97. BEGIN_EVENT_TABLE(myGLCanvas, wxGLCanvas)
  98. EVT_KEY_DOWN(myGLCanvas::onKey)
  99. EVT_IDLE(myGLCanvas::onIdle)
  100. EVT_SIZE(myGLCanvas::onSize)
  101. END_EVENT_TABLE()
  102. IMPLEMENT_APP(Ini);
  103. bool Ini::OnInit()
  104. {
  105. myFrameMain *frame = new myFrameMain();
  106. frame->Show(TRUE);
  107. return true;
  108. }


 
Ce code fonctionne très bien sur Linux et sur Windows.
Mais si j'enlève les 2 lignes suivantes, le code ne fonctionne plus sur Linux (et il fonctionne toujours sur Windows), pourquoi ?
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
 
Voici le résultat sur Linux : http://zenux.free.fr/cube.jpg (certaines faces semble transparente, d'autre non...!!)
 
Merci d'avance...


Message édité par casafa le 17-07-2006 à 10:14:03
Reply

Marsh Posté le 17-07-2006 à 10:09:10   

Reply

Marsh Posté le 17-07-2006 à 12:17:47    

Il ne faudrait pas calculer les normales aux faces pour que cullface soit efficace ?

Reply

Marsh Posté le 17-07-2006 à 12:18:43    

sinon les inits d'indices, de sommets et les glenable devraient plutot etre dans ton main, pas dans ta fonction de rendu.

Reply

Marsh Posté le 17-07-2006 à 19:48:53    

Merci pour tes réponses.
Bon voici mon code en peu mieux programmé ;)
 

Code :
  1. #include "main.h"
  2. myFrameMain::myFrameMain() : wxFrame(NULL, -1, "Hello GL World", wxPoint(-1, -1), wxSize(1024,790), wxDEFAULT_FRAME_STYLE)
  3. {
  4. bool fullScreen=false;
  5. glCanvas = new myGLCanvas(this, fullScreen);
  6. wxSizer *sizer = new wxBoxSizer(wxHORIZONTAL);
  7. sizer->Add(glCanvas, 1, wxALL|wxEXPAND, 0);
  8. this->SetSizer(sizer);
  9. this->SetAutoLayout(true);
  10. this->Layout();
  11. this->ShowFullScreen(fullScreen);
  12. }
  13. myGLCanvas::myGLCanvas(wxFrame *parent, bool fullScreen) : wxGLCanvas(parent, -1, wxPoint(0,0))
  14. {
  15. this->parent=parent;
  16. this->fullScreen=fullScreen;
  17. glShadeModel(GL_SMOOTH);
  18. glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
  19. glClearDepth(1.0f);
  20. glEnable(GL_DEPTH_TEST);
  21. glDepthFunc(GL_LEQUAL);
  22. glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
  23. glEnable(GL_CULL_FACE);
  24. indices[0]=4; indices[1]=5; indices[2]=6; indices[3]=7;  //front
  25. indices[4]=1; indices[5]=2; indices[6]=6; indices[7]=5;  //right
  26. indices[8]=0; indices[9]=1; indices[10]=5; indices[11]=4; //bottom
  27. indices[12]=0; indices[13]=3; indices[14]=2; indices[15]=1; //back
  28. indices[16]=0; indices[17]=4; indices[18]=7; indices[19]=3; //left
  29. indices[20]=2; indices[21]=3; indices[22]=7; indices[23]=6; //top
  30. sommets[0]=-1.0; sommets[1]=-1.0; sommets[2]=-1.0;   //1
  31. sommets[3]=1.0; sommets[4]=-1.0; sommets[5]=-1.0;   //2
  32. sommets[6]=1.0; sommets[7]=1.0; sommets[8]=-1.0;   //3
  33. sommets[9]=-1.0; sommets[10]=1.0; sommets[11]=-1.0;   //4
  34. sommets[12]=-1.0; sommets[13]=-1.0; sommets[14]=1.0;   //5
  35. sommets[15]=1.0; sommets[16]=-1.0; sommets[17]=1.0;   //6
  36. sommets[18]=1.0; sommets[19]=1.0; sommets[20]=1.0;   //7
  37. sommets[21]=-1.0; sommets[22]=1.0; sommets[23]=1.0;   //8
  38. }
  39. void myGLCanvas::onIdle(wxIdleEvent &event)
  40. {
  41. this->SetCurrent();
  42. if(redefineProjection){
  43.  this->GetSize(&width, &height);
  44.  glViewport(0, 0, width, height);
  45.  glMatrixMode(GL_PROJECTION);
  46.  glLoadIdentity();
  47.  gluPerspective(45.0f, (GLfloat)width/(GLfloat)height, 0.1f, 100.0f);
  48.  glMatrixMode(GL_MODELVIEW);
  49.  redefineProjection=false;
  50. }
  51. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  52. glLoadIdentity();
  53. glCullFace(GL_BACK);
  54. glTranslatef(0.0f,0.0f,-6.0f);
  55. glRotatef(zrot, 0.0, 0.0, 1.0);
  56. glRotatef(yrot, 0.0, 1.0, 0.0);
  57. glEnableClientState(GL_VERTEX_ARRAY);
  58. glVertexPointer(3, GL_FLOAT, 0, sommets);
  59. glColor3f(0.0f,1.0f,0.0f);
  60. glNormal3f( 0.0f, 0.0f, 1.0f);
  61. glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, &indices[0]);
  62. glColor3f(1.0f,0.5f,0.0f);
  63. glNormal3f( 1.0f, 0.0f, 0.0f);
  64. glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, &indices[4]);
  65. glColor3f(1.0f,0.0f,0.0f);
  66. glNormal3f( 0.0f,-1.0f, 0.0f);
  67. glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, &indices[8]);
  68. glColor3f(1.0f,1.0f,0.0f);
  69. glNormal3f( 0.0f, 0.0f,-1.0f);
  70. glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, &indices[12]);
  71. glColor3f(0.0f,0.0f,1.0f);
  72. glNormal3f(-1.0f, 0.0f, 0.0f);
  73. glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, &indices[16]);
  74. glColor3f(1.0f,0.0f,1.0f);
  75. glNormal3f( 0.0f, 1.0f, 0.0f);
  76. glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, &indices[20]);
  77. zrot+=0.1;
  78. yrot+=0.18;
  79. glFlush();
  80. this->SwapBuffers();
  81. event.RequestMore();
  82. }
  83. void myGLCanvas::onKey(wxKeyEvent &event)
  84. {
  85. int key = event.GetKeyCode();
  86. if(key==WXK_ESCAPE)
  87. {
  88.  parent->Destroy();
  89. }else if (key==WXK_F1)
  90. {
  91.  fullScreen=!fullScreen;
  92.  parent->ShowFullScreen(fullScreen);
  93. }
  94. }
  95. void myGLCanvas::onSize(wxSizeEvent &event)
  96. {
  97. redefineProjection=true;
  98. }
  99. BEGIN_EVENT_TABLE(myGLCanvas, wxGLCanvas)
  100. EVT_KEY_DOWN(myGLCanvas::onKey)
  101. EVT_IDLE(myGLCanvas::onIdle)
  102. EVT_SIZE(myGLCanvas::onSize)
  103. END_EVENT_TABLE()
  104. IMPLEMENT_APP(Ini);
  105. bool Ini::OnInit()
  106. {
  107. myFrameMain *frame = new myFrameMain();
  108. frame->Show(TRUE);
  109. return true;
  110. }


 
Il y a un petit changement par rapport à mon code précédent : Si j'active ou non le "GL_CULL_FACE" , mon cube s'affiche mal, savez-vous pourquoi ?.

Reply

Marsh Posté le 17-07-2006 à 21:27:09    

petite précision : normalement non, si tu ne précises pas de normale particulière, cullface marche toujours ! la normale qui est prise est la normale qui est "vissée" quand on tourne dans le sens des sommets du polygones.
 
[edit] vissée... enfin, ca dépend si on a choisi "gl_back" ou "gl_front"   :D
[reEdit] Je dis une conerie, pardon... en fait, la normale n'a rien à voir avec cullface !!! la regle que j'ai cité plus haut est vraie quelle que soit la normale spécifiée  :lol:  on peut avoir le droit de metre une normale dans le mauvais sens par rapport à celle par défaut !!!


Message édité par icareo le 17-07-2006 à 21:29:46

---------------
tutos de programmation 3D :
Reply

Marsh Posté le 17-07-2006 à 21:33:02    

Par contre, aparement dans ton code, tu te fais chi**r à mettre tous les nombres dans le tableau un par un... on peut faire plus facilement :
 
au lieu de  
indices[0]=1.0f; .... indices[n]=12.0f;
 
tu peux mettre:
indices = {1.0f, ....... , 12.0f};
 
 
...plus simple


---------------
tutos de programmation 3D :
Reply

Marsh Posté le 17-07-2006 à 21:59:43    

Grrrr j'avais perdu la mémoire et donc j'avais esseyé : indices[] = {1.0f, ....... , 12.0f}; et ça ne voulait pas fonctionner :( , lol
 
J'ai pas tout compris à ton message sur les normales mais bon...si je désactive le GL_CULL_FACE, le programme foire quand meme :(
 
Pour info: Si j'affiche que la face "front" et "right" et bien la face "right" est toujours visible lors de la rotation alors qu'elle devrait être temps en temps caché par la face "front" : est-ce un problème de test de profondeur ?!

Reply

Marsh Posté le 17-07-2006 à 22:08:25    

mon message sur les normales dit juste que ya pas besoin de spécifier les normales (comme le disait darkalt3) pour que glCullface marche :)
 
faudrait que tu montre un screenshot, mais faut croire que oui, c'est un pb de test de profondeur... reste a savoir prquoi ...


---------------
tutos de programmation 3D :
Reply

Marsh Posté le 17-07-2006 à 22:15:42    

essaye de changer de place le bloc avec glEnable(GL_DEPTH_TEST)


---------------
tutos de programmation 3D :
Reply

Marsh Posté le 17-07-2006 à 22:41:59    

J'ai l'impression que toutes les fonctions d'opengl se trouvant dans le constructeur myGLCanvas ne fonctionne pas !
 
Si je met glEnable(GL_DEPTH_TEST) dans la condition  "if(redefineProjection)" : ça fonctionne.... :D
Pareil pour glClearColor...en fait il ne fonctionne pas sauf si je le met dans la condition !!
 
J'ai déjà du ajouter la condition "if(redefineProjection)" parce que les fonctions d'Opengl ne voulait pas fonctionner dans "myGLCanvas:: onSize" !!!
 
Savez-vous pourquoi la fonction Opengl ne fonctionne que dans myGLCanvas:: onIdle ?!


Message édité par casafa le 17-07-2006 à 22:43:05
Reply

Marsh Posté le 17-07-2006 à 22:41:59   

Reply

Marsh Posté le 17-07-2006 à 22:45:20    

quand sont executées ces fonctions ???
c'est multithreadé ? faut savoir qu'on peut pas executer des fonctions opengl dans differents threads :)


---------------
tutos de programmation 3D :
Reply

Marsh Posté le 17-07-2006 à 22:54:48    

Hum, il faudrait demander à un gars plus doué que moi en wxWidgets...mais je pense quand même qu'il y a des thread : si quelqu'un peut confirmer.
 
Merci icareo ;)

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed