Bonjour à tous,
Je me suis lancé dans l'élaboration d'un petit projet mêlant Qt et OpenGL.
Pour cela, je suis parti de l'exemple Hello GL de Qt5.
Le but étant de lire une image et de représenter un histogramme en fonction de la couleur des pixels.
Plus on tend vers le rouge et plus le pixel sera haut, plus il est bleu plus il est bas.
Jusqu'à là pas de problème, j'arrive à afficher mon histogramme avec les axes XYZ en (0,0,0).
Mais j'ai quelque soucis d'affichage :
1- comme vous pouvez le voir sur le screenshot, il y a deux bandes verticale qui n'affiche que la couleur de fond.
Si je bouge mon histogramme et qu'il traverse ces zones là, cette partie de l'histogramme n'est plus visible. Comme s'il y avait un near clip/farclip sur les bords de ma caméra...
2-J'ai mis en place un compteur FPS, ce qui provoque à lui seul deux problèmes :
+ L'histogramme disparait mais l'axe XYZ est toujours là
+ L'affichage des FPS n'est rafraîchit que quand la fenêtre est cachée puis remise à l'avant.
Voici mon code :
+Les fonctions liés à OpenGL
+ Mes fonctions
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 void GLWidget::initializeGL() { glShadeModel(GL_SMOOTH); qglClearColor(m_qtPurple.dark()); glClearDepth(1.0f); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glDepthFunc(GL_LEQUAL); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); //glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_MULTISAMPLE); static GLfloat lightPosition[4] = { 0.5, 5.0, 7.0, 1.0 }; glLightfv(GL_LIGHT0, GL_POSITION, lightPosition); } void GLWidget::paintGL() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glTranslatef(0.0, 0.0, -10.0); QMatrix4x4 projection; projection.perspective(30.0, 1.0*width()/height(), 1.0,10.0); glRotatef(m_xRot / 16.0, 1.0, 0.0, 0.0); glRotatef(m_yRot / 16.0, 0.0, 1.0, 0.0); glRotatef(m_zRot / 16.0, 0.0, 0.0, 1.0); //-------------------------------------- DrawImage(); DrawAxis(); ComputeFPS(); } void GLWidget::resizeGL(int width, int height) { int side = qMin(width, height); glViewport((width - side) / 2, (height - side) / 2, side+10, side+10); glMatrixMode(GL_PROJECTION); glLoadIdentity(); /*#ifdef QT_OPENGL_ES_1 glOrthof(-0.5, +0.5, -0.5, +0.5, 4.0, 15.0); #else glOrtho(-0.5, +0.5, -0.5, +0.5, 4.0, 15.0); #endif*/ //NEAR & FAR CLIP float nearClip = 0.1f; float farClip = 100.0f; float yFOV = 100.0f; float yMax = nearClip * tan(yFOV*M_PI/360.0f); float aspect = width/height; float xMin = -yMax * aspect; float xMax = yMax *aspect; glFrustum(xMin, xMax, -yMax, yMax, nearClip, farClip); glMatrixMode(GL_MODELVIEW); m_width = width; m_height = height; }
Pour le premier problème, j'ai essayé de passer de la représentation orthographique à la perspective, ça m'a permis de rallonger le farclip trop proche de base, mais n'a pas enlevé les deux barres verticales. Est ce que OpenGL ES ne pourrait pas être la cause de ce problème?
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 //On compte sur une seconde le nombre de fois que l'on passe dans la fonction //Ca nous donne un FPS approximatif void GLWidget::ComputeFPS() { if(m_second == 0) { m_second = m_time.currentTime().second(); return; } // Measure speed QTime time = time.currentTime(); m_frameCount++; qglColor(Qt::white); if ( time.second() - m_second >= 1.0 ) { QString fps; fps.setNum(m_frameCount); renderText(m_width - 60, 20, fps, QFont("Arial", 12, QFont::Bold, false) ); m_fps = fps; m_frameCount = 0; m_second += 1.0; } else renderText(m_width - 60, 20, m_fps, QFont("Arial", 12, QFont::Bold, false) ); } //Trace les axes XYZ void GLWidget::DrawAxis() { glBegin(GL_LINES); glColor3d(1,0,0); glVertex3i(0,0,0);glVertex3i(0,50,0); glColor3d(0,1,0); glVertex3i(0,0,0);glVertex3i(50,0,0); glColor3d(0,0,1); glVertex3i(0,0,0);glVertex3i(0,0,50); glEnd(); } //On ajoute les composantes RGB pour trouver la hauteur du pixel //La formule est bancale mais sert seulement de test provisoire float GLWidget::ComputeHeight(QColor rgb) { if (rgb.red() == 0 && rgb.green() == 0 && rgb.blue() == 0) return 0.0; float ret; ret = rgb.red()*4 + rgb.green() * 2 + rgb.blue(); if (ret < 0) return 2.0; else if (ret > 1785) return 10.0; else return ret * 10 / 1785; } //Affiche l'image void GLWidget::DrawImage() { QImage Texture; if(!Texture.load("image.bmp")) return; Texture = Texture.scaled(75,75,Qt::KeepAspectRatio); glPointSize(4.0f); glBegin(GL_POINTS); glBegin(GL_LINE_STRIP); for (float i = 0; i<Texture.width(); i = i + 1.0) for(float j = 0; j<Texture.height(); j= j + 1.0) { QColor rgb = Texture.pixel(i,j); glColor3f(rgb.red(), rgb.green(), rgb.blue()); glVertex3f(i, ComputeHeight(rgb), j); } glEnd(); glEnd(); }
Pour le second problème, j'ai essayé d'utiliser updateGL mais cela faisait planter mon programme, il bouclait sans fin et windows tuait mon processus.
Pour mon histogramme qui disparaît lorsque je calcule mes FPS, je n'ai pas encore trouvé la raison...
J'espère que vous saurez m'éclairer sur l'un de mes problèmes, je reviendrai vers vous si je trouve la réponse par moi même.
Merci de votre aide,
Clément.
Partager