Page 1 sur 1

Dessiner sur un OpenGLGadget()

Publié : mer. 13/août/2014 8:47
par kernadec
bonjour
je me suis amusé a adapter la Démo de CanvasGadget en mode OpenGLGadget :mrgreen:

Cordialement
[réédit] retrait des commandes OpenGL inutiles du code, je ne suis que débutant avec openGL :wink:
Pour rester dans le sujet débutant, je remet le lien du cours remarquable pour OpenGL en PDF ici: http://msamozino.free.fr/these/cours/ge ... _cours.php

Ajout de la ligne glDrawBuffer_(#GL_FRONT_AND_BACK) dans le code
et modification des paramètres pour la fonction glOtho() :wink:

Code : Tout sélectionner

If OpenWindow(0, 0, 0, 320, 320, "OpenGLGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  OpenGLGadget(0, 10, 10, 300, 300)
  
  glDrawBuffer_(#GL_FRONT_AND_BACK) 
  
  glOrtho_(GadgetX(0)-10, GadgetWidth(0) ,GadgetHeight(0),GadgetY(0)-10 , GadgetWidth(0)/2,-GadgetHeight(0)/2) ; Axe de l'OpenGLGadget()
  
  SetActiveGadget(0)
  
  Repeat
    
    Event = WaitWindowEvent()
    
    If Event = #PB_Event_Gadget And EventGadget() = 0 
      If EventType() = #PB_EventType_LeftButtonDown Or (EventType() = #PB_EventType_MouseMove And GetGadgetAttribute(0, #PB_Canvas_Buttons) & #PB_Canvas_LeftButton)
        
        
        x = GetGadgetAttribute(0, #PB_OpenGL_MouseX)
        y = GetGadgetAttribute(0, #PB_OpenGL_MouseY)
        
        
        glEnable_(#GL_POINT_SMOOTH)                                      ; mode point arrondi
        
        glPointSize_(20)                                                 ; entrer la taille avant mode dessin
        glBegin_(#GL_POINTS)                                             ; mode dessin points
        
        glColor3ub_(Random(255),Random(255),Random(255))                 ; couleur
        
        glVertex3f_(x,y,0)                                               ; dessine le points
        glEnd_()
        
        SetGadgetAttribute(0, #PB_OpenGL_FlipBuffers, #True)
        
      EndIf
    EndIf    
    
  Until Event = #PB_Event_CloseWindow
EndIf

Re: Dessiner sur un OpenGLGadget()

Publié : mer. 13/août/2014 9:16
par Micoute
Bonjour kernadec, c'est de la balle ton truc !

Re: Dessiner sur un OpenGLGadget()

Publié : mer. 13/août/2014 10:42
par graph100
chez moi ça scintille un max !

Re: Dessiner sur un OpenGLGadget()

Publié : mer. 13/août/2014 11:32
par kernadec
bonjour graph100

je suis en pleine étude de l'outil
sous windows XP86 SP3 je n'ai pas de scintillement hormis le changement de couleur sous la souris
peut être essayer avec une couleur sans le random()

Voilà deux commandes que je n' ai pas utilisées et qui sont souvent placées en fin de séquence OpenGL
regarde si cela vient de ça

glEnd_();
glFlush_() maintenant on dit ceci : glFlush et glFinish étaient surtout utilisé à l'époque des stations graphique ou le rendu pouvait être effectué par un serveur distant

Cependant, le code est minimaliste reste à trouver les moyens d'améliorer tout ça

Cordialement

ps:Mais peut être est tu sous linux?

Re: Dessiner sur un OpenGLGadget()

Publié : mer. 13/août/2014 15:43
par graph100
avec window 8, Pb 5.30 x86, j'ai un scintillement.
Et le code n'affiche rien si je ne marque pas glEnd_().

Je ne comprend pas pourquoi ça ne le fait pas chez toi car ce scintillement est du au fait qu'on ne dessine que sur un buffer à la fois.
Lorsque l'autre est interverti, le contenu précédent n'est pas copié : 1 rond sur 2 est inscrit sur le même buffer, d’où le scintillement.

J'ai lu sur le wiki de openGL que le swap entre front et back buffer n'a pas besoin d'être réel : les données peuvent être copiées du backbuffer sur le frontbuffer.
Cela semble être le cas chez toi, ça expliquerais que tu n'as pas de scintillement puisque les données du backbuffer ne sont pas modifiés par l'affichage.

En revanche, sur ma machine, il doit se passer un vrai swap : les données sont échangées : le front devient le back et vice versa.
Et du coup, lorsque tu dessines une deuxième fois, tu n'ajoutes pas les données sur la frame précédente, d’où le scintillement.

Comme depuis vista la mémoire vidéo est gérée par l'OS, c'est probable que la différence vienne de là.

J'aimerais bien qu'on ai un passage de Fred pour mettre cela au clair, car c'est quand même important pour l'utilisation de ce gadget !

Re: Dessiner sur un OpenGLGadget()

Publié : mer. 13/août/2014 16:58
par Fred
Le contexte est créé avec l'option "double buffering", donc oui il faut tout redessiner sur chaque buffer sinon ca va scintiller.

Re: Dessiner sur un OpenGLGadget()

Publié : mer. 13/août/2014 21:09
par venom
Chez moi aussi sa scintille :wink:






@++

Re: Dessiner sur un OpenGLGadget()

Publié : mer. 13/août/2014 23:06
par kernadec
bonsoir
mince c'est pas cool avec Windows 8
peut être diminué le scintillement avec WaitWindowEvent(10) :lol:

Mais il reste aussi a explorer GLUT 8O
http://www.purebasic.fr/english/viewtop ... hilit=GLUT
http://interaction.lille.inria.fr/~rous ... OpenGL.pdf

Cordialement

Re: Dessiner sur un OpenGLGadget()

Publié : jeu. 14/août/2014 3:26
par MetalOS
Voici le résultat sous Mac avec PB 5.30 64bits

Image

Re: Dessiner sur un OpenGLGadget()

Publié : jeu. 14/août/2014 9:54
par kernadec
Bonjour à tous
merci pour vos tests.
mauvaise nouvelle pour Mac in Toc, :? dur dur pour mes début avec OpenGL :(

Alors, :?: peut être que mon calcul de conversion provoque le scintillement :?

Donc j'ai enlevé ma conversion pixels/Ortho, pour maintenant utiliser la fonction OpenGL dédiée a ce travail:
glOrtho_(GadgetX(0)-10, GadgetWidth(0) ,GadgetHeight(0), GadgetY(0)-10 , 1,-1)

je remets aussi le code pour tester avec l'Api windows SwapBuffers_(hDC) ;Windows only
Cordialement

Code : Tout sélectionner

If OpenWindow(0, 0, 0, 320, 320, "OpenGLGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  OpenGLGadget(0, 10, 10, 300, 300)
  
  ;Conversion dez coordonnées pixels en coordonnées Orthogonale OpenGLGadget()
  glOrtho_(GadgetX(0)-10, GadgetWidth(0) ,GadgetHeight(0), GadgetY(0)-10 , 1,-1)
  
  ;hWnd = WindowID(0) ;windows only
  ;hDC = GetDC_(hWnd) ;windows only
  
  Repeat
    Event = WaitWindowEvent()
    
    If Event = #PB_Event_Gadget And EventGadget() = 0 
      If EventType() = #PB_EventType_LeftButtonDown Or (EventType() = #PB_EventType_MouseMove And GetGadgetAttribute(0, #PB_Canvas_Buttons) & #PB_Canvas_LeftButton)
        
        
        x = GetGadgetAttribute(0, #PB_OpenGL_MouseX)
        y = GetGadgetAttribute(0, #PB_OpenGL_MouseY)
        
        glEnable_(#GL_POINT_SMOOTH)
        glPointSize_(20)                                   ;taille
        glBegin_(#GL_POINTS)
        glColor3ub_(Random(255),Random(255),Random(255))
        glVertex2f_(x,y)
        ;			SwapBuffers_(hDC)  ;windows only
        glEnd_()                                              
        
        SetGadgetAttribute(0, #PB_OpenGL_FlipBuffers, #True)
        
      EndIf
    EndIf    
    
  Until Event = #PB_Event_CloseWindow
Endif

Re: Dessiner sur un OpenGLGadget()

Publié : jeu. 14/août/2014 10:47
par graph100
kernadec a écrit :Alors, :?: peut être que mon calcul de conversion provoque le scintillement :?
Non :
Fred a écrit :Le contexte est créé avec l'option "double buffering", donc oui il faut tout redessiner sur chaque buffer sinon ca va scintiller.
Ca dit tout non ?!

Il faut que tu trouves une commande pour copier le buffer courant sur le nouveau.

Re: Dessiner sur un OpenGLGadget()

Publié : jeu. 14/août/2014 11:43
par kernadec
bonjour Graph100
merci de ton aide
Désolé :( je n'ai pas Windows 8 pour tester ce problème et je n’achèterais pas d' ordi avant la sortie de Windows 9 :mrgreen:

je pense avoir trouvé la commande qui pourrait résoudre le scintillement avec Windows 8 : glDrawBuffer_()

Code : Tout sélectionner

    ;  #GL_NONE   #GL_FRONT_LEFT #GL_FRONT_RIGHT  #GL_BACK_LEFT  #GL_BACK_RIGHT
    ;  #GL_FRONT  #GL_BACK   #GL_FRONT_AND_BACK   #GL_LEFT       #GL_RIGHT   
 glDrawBuffer_(#GL_FRONT_AND_BACK) 
Cordialement

Re: Dessiner sur un OpenGLGadget()

Publié : jeu. 14/août/2014 12:51
par graph100
Bien joué !

le code suivant ne scintille pas sur window 8

Code : Tout sélectionner

If OpenWindow(0, 0, 0, 320, 320, "OpenGLGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
	OpenGLGadget(0, 10, 10, 300, 300)
	glDrawBuffer_(#GL_FRONT_AND_BACK) 
	
	;Conversion dez coordonnées pixels en coordonnées Orthogonale OpenGLGadget()
	glOrtho_(GadgetX(0)-10, GadgetWidth(0) ,GadgetHeight(0), GadgetY(0)-10 , 1,-1)
	
	Repeat
		Event = WaitWindowEvent()
		
		If Event = #PB_Event_Gadget And EventGadget() = 0 
			If EventType() = #PB_EventType_LeftButtonDown Or (EventType() = #PB_EventType_MouseMove And GetGadgetAttribute(0, #PB_Canvas_Buttons) & #PB_Canvas_LeftButton)
				
				
				x = GetGadgetAttribute(0, #PB_OpenGL_MouseX)
				y = GetGadgetAttribute(0, #PB_OpenGL_MouseY)
				
				glEnable_(#GL_POINT_SMOOTH)
				glPointSize_(20)                                   ;taille
				glBegin_(#GL_POINTS)
				glColor3ub_(Random(255),Random(255),Random(255))
				glVertex2f_(x,y)
				
				
				glEnd_()                                              
				
				SetGadgetAttribute(0, #PB_OpenGL_FlipBuffers, #True)
				
			EndIf
		EndIf    
		
	Until Event = #PB_Event_CloseWindow
EndIf
En revanche l'utilisation de cette commande doit sans doute augmenter le temps de dessin.
Si l'application OpenGL efface toujours l'écran avant de dessiner, il ne faut pas la mettre !