' Rendu de la scène Public Sub Render() Dim i As Long ' Passage en matrice de projection glMatrixMode GL_PROJECTION ' Initialisation de la matrice glLoadIdentity ' Définition de la perspective gluPerspective 55, 1, 0.1, ProfilInitial.EcartementZ * 20 ' Passage en matrice de modélisation-visualisation glMatrixMode GL_MODELVIEW ' Initialisation de la matrice glLoadIdentity ' Position de la caméra gluLookAt TranslateX, TranslateY, DistCamera, TranslateX, TranslateY, 0, 0, 1, 0 ' Vide les buffers couleur et profondeur glClear GL_COLOR_BUFFER_BIT Or GL_DEPTH_BUFFER_BIT ' Sauvegarde la matrice glPushMatrix 'initialisation de la transparence 'glEnable GL_BLEND 'glBlendFunc GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ' Rotation à partir de la souris glRotated AngleY, 1, 0, 0 glRotated AngleX, 0, 1, 0 ' Début de la primitive pour l'aile glBegin GL_TRIANGLE_STRIP 'triangles en bande 'les points alternativement d'un côté et de l'autre For i = 1 To UBound(Points3D_E) glColor3d 1, 0.6, 0.07 ' orange glVertex3d Points3D_E(i).x, Points3D_E(i).y, Points3D_E(i).z glVertex3d Points3D_S(i).x, Points3D_S(i).y, Points3D_S(i).z Next i 'fin de la primitive glEnd 'glDisable GL_BLEND 'les faces glColor3d 1, 0, 0 ' Rouge tessEmplanture = gluNewTess gluTessCallback tessEmplanture, GLU_TESS_BEGIN, AddressOf glBeginCB gluTessCallback tessEmplanture, GLU_TESS_END, AddressOf glEndCB gluTessCallback tessEmplanture, GLU_TESS_ERROR, AddressOf glErrorCB gluTessCallback tessEmplanture, GLU_TESS_VERTEX, AddressOf glVertex3dvCB gluTessBeginPolygon tessEmplanture, 0 '(0 est un Long, on trouve parfois NULL) gluTessBeginContour tessEmplanture For i = 1 To UBound(Points3D_E) gluTessVertex tessEmplanture, Points3D_E(i).x, Points3D_E(i).x Next i gluTessEndContour tessEmplanture gluTessEndPolygon tessEmplanture gluDeleteTess tessEmplanture glColor3d 0, 0, 1 ' Bleu tessSaumon = gluNewTess gluTessCallback tessSaumon, GLU_TESS_BEGIN, AddressOf glBeginCB gluTessCallback tessSaumon, GLU_TESS_END, AddressOf glEndCB gluTessCallback tessSaumon, GLU_TESS_ERROR, AddressOf glErrorCB gluTessCallback tessSaumon, GLU_TESS_VERTEX, AddressOf glVertex3dvCB gluTessBeginPolygon tessSaumon, 0 '(0 est un Long, on trouve parfois NULL) gluTessBeginContour tessSaumon For i = 1 To UBound(Points3D_S) gluTessVertex tessEmplanture, Points3D_S(i).x, Points3D_S(i).x Next i gluTessEndContour tessSaumon gluTessEndPolygon tessSaumon gluDeleteTess tessSaumon ' Restaure la matrice glPopMatrix End Sub '**** les callback de gluNewTess Private Sub glBeginCB(ByVal which As Long) glBegin which End Sub Private Sub glEndCB() glEnd End Sub Private Sub glErrorCB(ByVal errorCode As Long) '??? Dim estring As String estring = gluErrorString(errorCode) Debug.Print "Tessellation Error: " & estring Select Case errorCode Case GLU_TESS_MISSING_BEGIN_POLYGON Debug.Assert 0 Case GLU_TESS_MISSING_END_POLYGON Debug.Assert 0 Case GLU_TESS_MISSING_BEGIN_CONTOUR Debug.Assert 0 Case GLU_TESS_MISSING_END_CONTOUR Debug.Assert 0 Case GLU_TESS_COORD_TOO_LARGE Debug.Assert 0 Case GLU_TESS_NEED_COMBINE_CALLBACK Debug.Assert 0 Case errorCode >= GLU_TESS_ERROR1 And errorCode <= GLU_TESS_ERROR8 '10151-10158 Debug.Assert 0 Case Else Debug.Assert 0 End Select Stop End Sub Private Sub glVertex3dvCB(ByRef arg As Double) glVertex3dv arg End Sub
Option Explicit ' Classe pour affichage dans un form Private oGl As clOpengGLFormVB6 Private Sub comboMouseWheel_KeyDown(KeyCode As Integer, Shift As Integer) Select Case KeyCode Case vbKeySpace 'la barre d'espace permet de passer d'un mode de représentation à l'autre TypeVisu = TypeVisu + 1 If TypeVisu 3 Then TypeVisu 0 Select Case TypeVisu Case 0 glPolygonMode GL_FRONT_AND_BACK, GL_FILL Case 1 glPolygonMode GL_FRONT_AND_BACK, GL_LINE Case 2 glPolygonMode GL_FRONT_AND_BACK, GL_POINT End Select Case vbKeyReturn SaveToBMP App.Path & "\capture.bmp" MsgBox "Création du fichier " & App.Path & "\capture.bmp", vbInformation, "Capture" End Select Call Draw End Sub ' Chargement du formulaire Private Sub Form_Load() 'pour pouvoir utiliser la molette de la souris, on utilise le défilement d'un combobox et l'événement click comboMouseWheel.left = 30000 comboMouseWheel.AddItem "Z+" comboMouseWheel.AddItem "0" 'index 1 comboMouseWheel.AddItem "Z-" 'index 2 Set oGl = New clOpengGLFormVB6 oGl.InitOpenGL Me ' Appel de la fonction d'initialisation Call InitScene ' Pour lancer l'affichage, on a besoin d'un événement qui vient de la form : on lance le timer ' (Juste faire Call Draw ne fonctionne pas!) Me.GLTimer.Interval = 10 'on donne le focus à la combobox pour initialiser le zoom comboMouseWheel.ListIndex = 1 End Sub ' Fonction d'affichage Public Sub Draw() ' Appel de la fonction de rendu Call Render ' Echange les buffers oGl.Display End Sub ' Initialisation de la scène Public Sub InitScene() ' Mode d'affichage = remplissage glPolygonMode GL_FRONT_AND_BACK, GL_FILL ' Tests de profondeur glEnable GL_DEPTH_TEST glDepthFunc GL_LEQUAL ' Initialisation des variables de visualisation TranslateX = 0 TranslateY = 0 DistCamera = ProfilInitial.EcartementZ / 2 + ProfilInitial.CordeE AngleX = 0 AngleY = 0 TypeVisu = 0 End Sub Private Sub Form_MouseDown(button As Integer, Shift As Integer, x As Single, y As Single) If button = vbLeftButton Then Xold = x Yold = y End If End Sub Private Sub Form_MouseMove(button As Integer, Shift As Integer, x As Single, y As Single) Select Case button Case vbLeftButton AngleX = AngleX + (x - Xold) / 100 AngleY = AngleY + (y - Yold) / 100 Call Draw Case vbRightButton TranslateX = TranslateX - (x - Xold) / (10000 / ProfilInitial.EcartementZ) TranslateY = TranslateY + (y - Yold) / (10000 / ProfilInitial.EcartementZ) Call Draw End Select Xold = x Yold = y End Sub Private Sub Form_MouseUp(button As Integer, Shift As Integer, x As Single, y As Single) 'on redonne le focus au zoom comboMouseWheel.ListIndex = 1 End Sub ' Le timer sert uniquement au chargement de la feuille pour lancer le premier affichage Private Sub GLTimer_Timer() Call Draw GLTimer.Enabled = False End Sub Private Sub comboMouseWheel_Click() Select Case comboMouseWheel.ListIndex Case 0 'on est sur "Z+" DistCamera = DistCamera + ProfilInitial.EcartementZ / 5 Case 1 'on est sur "0" Call Draw Case 2 'on est sur "Z-" DistCamera = DistCamera - ProfilInitial.EcartementZ / 5 End Select comboMouseWheel.ListIndex = 1 End Sub
je n'ai pas reçu de mail pour tes réponses...
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre questionGlut et OpenGL arrivent bien à trianguler mes faces, affichent le tout à l'écran, je commence à faire bouger/zoomer, ça tourne, puis ça plante.
Pense tu un jour migrer ton appli de base sur vb.Net ou est ce pour toi non envisageable?
Voila tout le pb d'OpenGL, définir d'ou viens le pb.
' Primitive pour l'enveloppe de l'aile 'on va activer la transparence glEnable GL_BLEND glBlendFunc GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA glBegin GL_TRIANGLE_STRIP 'triangles en bande 'les points alternativement d'un côté et de l'autre For i = 1 To UBound(Points3D_E) glColor4d 1, 0, 0, 0.5 glVertex3d Points3D_E(i).x, Points3D_E(i).y, Points3D_E(i).z glColor4d 0, 0, 1, 0.5 glVertex3d Points3D_S(i).x, Points3D_S(i).y, Points3D_S(i).z Next i glEnd 'Primitive pour les contours des profils 'Emplanture glBegin GL_LINE_STRIP 'lignes connectées 'les points alternativement d'un côté et de l'autre For i = 1 To UBound(Points3D_E) glColor4d 1, 0, 0, 1 glVertex3d Points3D_E(i).x, Points3D_E(i).y, Points3D_E(i).z Next i glEnd 'Saumon glBegin GL_LINE_STRIP 'lignes connectées 'les points alternativement d'un côté et de l'autre For i = 1 To UBound(Points3D_S) glColor4d 0, 0, 1, 1 glVertex3d Points3D_S(i).x, Points3D_S(i).y, Points3D_S(i).z Next i glEnd glDisable GL_BLEND ' Désactive la transparence
''' <summary> ''' Donne une différence d'angle entre 2 vecteurs 2D 0.093µs ''' </summary> ''' Valeur du Vector[01] ''' Valeur du Vector[02] ;d Function AngleBetween(ByVal a As Vector2, ByVal b As Vector2) As Single Dim dotProd As Double, lenProd As Double, divOperation As Double dotProd = (a.X * b.X) + (a.Y * b.Y) lenProd = Math.Sqrt(a.X * a.X + a.Y * a.Y) * Math.Sqrt(b.X * b.X + b.Y * b.Y) divOperation = dotProd / lenProd Dim Res As Single = Convert.ToSingle(Math.Acos(divOperation)) If (b.Y - a.Y) < 0 Then Res = Pi2 - Res Return Res End Function ''' <summary> ''' Donne la distance entre 2 points 2D 0.170µs ''' </summary> ''' Position du point[01] ''' Position du point[02] ''' <remarks> Plus rapide : => Vector2.length 0.033µs =>Vector2.lengthFast 0.054µs) Soustraction de vector2 0.005µs ''' </remarks> Public Function DistanceBetweenTwoPoints(ByVal p1 As Vector2, ByVal p2 As Vector2) As Single Return Math.Sqrt((Math.Abs(p2.X - p1.X) ^ 2) + (Math.Abs(p2.Y - p1.Y) ^ 2)) End Function ''' <summary> ''' Indique si un point se situe dans un triangle 0.046µs ''' </summary> ''' Point[00] du triangle ''' Point[01] du triangle ''' Point[02] du triangle ''' Position du point[02] Public Function IsPointInsideTriangle(ByRef P0 As Vector2, ByRef P1 As Vector2, ByRef P2 As Vector2, ByRef Pt_To_Test As Vector2) As Boolean Dim z1 As Boolean = ComputeZCoordinate(P0, P1, Pt_To_Test) Dim z2 As Boolean = ComputeZCoordinate(P1, P2, Pt_To_Test) Dim z3 As Boolean = ComputeZCoordinate(P2, P0, Pt_To_Test) Return (z1 And z2 And z3) Or (z1 False And z2 False And z3 = False) End Function Private Function ComputeZCoordinate(ByRef P1 As Vector2, ByRef P2 As Vector2, ByRef P3 As Vector2) As Boolean 'Nécessaire a la fonction IsPointInsideTriangle Dim A As Single A = P1.X * (P2.Y - P3.Y) + P2.X * (P3.Y - P1.Y) + P3.X * (P1.Y - P2.Y) Return A > 0 End Function ''' <summary> ''' Indique si un point se situe dans un polygone ''' </summary> ''' Liste de points (enveloppe) ''' Point a tester Public Function InsidePolygon(ByRef Polygon As List(Of Vector2), ByRef P As Vector2) As Boolean 'http://erich.realtimerendering.com/ptinpoly/ 'http://paulbourke.net/geometry/insidepoly/ Dim i As Integer, xinters As Double, counter As Integer = 0 Dim p1 As Vector2, p2 As Vector2, n As Integer = Polygon.Count p1 = Polygon(0) For i = 1 To n p2 = Polygon(i Mod n) If P.Y > Min(p1.Y, p2.Y) Then If P.Y <= Max(p1.Y, p2.Y) Then If P.X <= Max(p1.X, p2.X) Then If p1.Y <> p2.Y Then xinters = (P.Y - p1.Y) * (p2.X - p1.X) / (p2.Y - p1.Y) + p1.X If p1.X = p2.X OrElse P.X <= xinters Then counter += 1 End If End If End If End If End If p1 = p2 Next Return (counter Mod 2 <> 0) End Function