Gadget OpenGL : Utilisation du clavier

Sujets variés concernant le développement en PureBasic
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Gadget OpenGL : Utilisation du clavier

Message par falsam »

J'explore les possibilités du gadget OpenGl et la première difficulté que je rencontre c'est l'interaction avec le clavier que je trouve lent.

Peut être que je n'ai pas la bonne méthode et je vous propose ce simple code pour avoir votre avis.
Utiliser les flèches du clavier pour déplacer un carré.

Code : Tout sélectionner

EnableExplicit

; Fenetre application, viewport et couleur arriere plan 
Global window, ww = 800, wh = 600, viewport, wColor.f = RGB(107, 142, 35)

; Sprite  
Global sx.f = 100, sy.f =100, sw = 64, sh = 64, sColor = RGB(255, 215, 0)

;Plan de l'application
Declare Start()
Declare GameEvent()
Declare GameRender()
Declare Exit()

Start()

Procedure Start()
  window = OpenWindow(#PB_Any, 0, 0, ww, wh, "Test Opengl", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
  
  ; Fenetre Open GL
  viewport = OpenGLGadget(#PB_Any, 0, 0, ww, wh, #PB_OpenGL_NoDepthBuffer | #PB_OpenGL_Keyboard)
  SetActiveGadget(viewport)
  
  ; Modifier le contexte courant
  SetGadgetAttribute(viewport, #PB_OpenGL_SetContext, #True)
  
  ; Couleur d'arrirer plan
  glClearColor_(Red(wColor)/255, Green(wColor)/255, Blue(wColor)/255, 1.0)
  
  ; Volume de visualisation 
  glMatrixMode_(#GL_PROJECTION)
  glLoadIdentity_();
  gluOrtho2D_(0, ww, wh, 0)
  
  ;Triggers  
  BindGadgetEvent(viewport, @GameEvent(), #PB_EventType_KeyDown) 
  BindEvent(#PB_Event_CloseWindow, @Exit())
  
  ;Loop
  While #True
    Repeat : Until WindowEvent() = 0
    GameRender()
  Wend
EndProcedure

Procedure GameEvent()
  Protected Speed.f = 8
  Protected KeyPress = GetGadgetAttribute(viewport, #PB_OpenGL_Key)
  
  If KeyPress= #PB_Shortcut_Left
    sx - Speed
  EndIf
  
  If KeyPress = #PB_Shortcut_Right  
    sx + Speed
  EndIf
  
  If KeyPress = #PB_Shortcut_Up
    sy - Speed
  EndIf
  
  If KeyPress = #PB_Shortcut_Down
    sy + Speed
  EndIf
  
  If KeyPress = #PB_Shortcut_Escape
    Exit() 
  EndIf  
EndProcedure

Procedure GameRender()
  ; ClearScreen
  glClear_(#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT)
  
  ; Affichage d'un carré
  glMatrixMode_(#GL_MODELVIEW)    ;Initialiser la matrice de transformation courante
  glPushMatrix_()                 
  
  glBegin_(#GL_POLYGON)           
  glColor3f_(Red(sColor)/255, Green(sColor)/255, Blue(sColor)/255)
  
  glVertex2i_(sx, sy)             ;Point haut gauche
  glVertex2i_(sx + sw, sy)        ;Point haut droit
  glVertex2i_(sx + sw, sy + sh)   ;Point bas droit
  glVertex2i_(sx, sy + sh)        ;Point bas gauche
  glEnd_()                        ;Fin du polygone
  
  glPopMatrix_();
  
  ; Flip buffer
  SetGadgetAttribute(viewport, #PB_OpenGL_FlipBuffers, #True)  
EndProcedure

Procedure Exit()  
  End
EndProcedure
je vous propose aussi le meme code 100% PureBasic pour que vous puissiez comparer le temps de réaction.

Code : Tout sélectionner

; Fenetre application, viewport et couleur arriere plan 
Global window, ww = 800, wh = 600, viewport, wColor.f = RGB(107, 142, 35)

; Sprite  
Global sprite, sx.f = 100, sy.f =100, sw = 64, sh = 64, sColor = RGB(255, 215, 0)

;Plan de l'application
Declare Start()
Declare GameEvent()
Declare GameRender()
Declare Exit()

Start()

Procedure Start()
  InitSprite()
  InitKeyboard()
  InitMouse()
  
  window = OpenWindow(#PB_Any, 0, 0, ww, wh, "Test", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
  OpenWindowedScreen(WindowID(window), 0, 0, ww, wh)
  
  ; Creation d'un sprite
  sprite = CreateSprite(#PB_Any, sw, sh)
  StartDrawing(SpriteOutput(sprite))
  Box(0, 0, sw, sh, scolor)
  StopDrawing()
  
  ; Trigger
  BindEvent(#PB_Event_CloseWindow, @Exit())
   
  ;Loop
  While #True
    Repeat : Until WindowEvent() = 0
    GameEvent()
    FlipBuffers()  
    GameRender()
  Wend
EndProcedure

Procedure GameEvent()
  Protected Speed.f = 8

  ExamineKeyboard()  
  
  If KeyboardPushed(#PB_Key_Left) 
    sx - Speed
  EndIf
  
  If KeyboardPushed(#PB_Key_Right) 
    sx + Speed
  EndIf
  
  If KeyboardPushed(#PB_Key_Up) 
    sy - Speed
  EndIf
  
  If KeyboardPushed(#PB_Key_Down) 
    sy + Speed
  EndIf
  
  If KeyboardPushed(#PB_Key_Escape) 
    Exit()
  EndIf
EndProcedure

Procedure GameRender()
  ClearScreen(wColor)
  
  DisplaySprite(sprite, sx, sy)
EndProcedure

Procedure Exit()  
  End
EndProcedure
Sur ce deuxième code on peut presser simultanément les flèches bas et haut pour un mouvement en diagonal ce qui n'est pas le cas avec le premier code.

Merci d'avance pour l'aide que vous pourrez m'apporter
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
Ar-S
Messages : 9477
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Gadget OpenGL : Utilisation du clavier

Message par Ar-S »

En effet la reaction n'est pas du tout la même...
En PB on a l'impression de bouger un sprite, clairement... en OpenGL on dirait qu'on bouge un curseur dans un traitement de texte..
J'ai essayé de changer 2, 3 trucs mais ça n'a strictement rien fait.
A tout hasard tu as essayé dans une boucle classique sans binder ?
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Gadget OpenGL : Utilisation du clavier

Message par falsam »

Merci d'avoir essayer Ar-s.
J'ai essayé dans une boucle traditionnel (J'ai failli oublier comment faire) et le résultat est le même.
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
Micoute
Messages : 2522
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: Gadget OpenGL : Utilisation du clavier

Message par Micoute »

Merci falsam pour le partage et n'ayant que l'OpenGL, car mon système n'arrive pas à trouver DirectX 12, alors je n'ai pas pu voir la différence entre ces deux sous systèmes. Pourtant DXDiag fonctionne très bien.
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 5.73 PB 6.00 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Gadget OpenGL : Utilisation du clavier

Message par falsam »

Je partage rien du tout. Je voudrais plutôt essayer de comprendre pourquoi l'interception des touches pressées est aussi lentes et quelles seraient les solutions optimales.

Dommage que la bibliothèque Keyboard ne puisse pas fonctionner en dehors du contexte OpenScreen !!
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
Mindphazer
Messages : 639
Inscription : mer. 24/août/2005 10:42

Re: Gadget OpenGL : Utilisation du clavier

Message par Mindphazer »

Bonjour Falsam,
par curiosité, j'ai testé tes deux codes sur mon Mac.
J'ai exactement les mêmes symptômes, le carré dans le code OpenGL se déplace à la vitesse d'une tortue, alors que son compère dans le code 100% PB disparaît pratiquement instantanément de l'écran !!
Bureau : Win10 64bits
Maison : Macbook Pro M1 14" SSD 512 Go / Ram 16 Go - iPad Pro 32 Go (pour madame) - iPhone 15 Pro Max 256 Go
Ollivier
Messages : 4190
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: Gadget OpenGL : Utilisation du clavier

Message par Ollivier »

Rajoute un Delay(3) dans ta boucle principale pour voir (au-dessus de l'appel GameRender() ). Pas le temps de tester, ni de récup le compilo.
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Gadget OpenGL : Utilisation du clavier

Message par falsam »

Ollivier a écrit :Rajoute un Delay(3) dans ta boucle principale pour voir (au-dessus de l'appel GameRender() ). Pas le temps de tester, ni de récup le compilo.
Non le but est de ne pas ralentir quoique ce soit. Merci pour ta suggestion ;)
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Ollivier
Messages : 4190
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: Gadget OpenGL : Utilisation du clavier

Message par Ollivier »

Ce n'est pas ralentir. Teste voir. Ça ne te coùte rien. Dans ta 2nde version, le Delay(x) est intégré dans FlipBuffers(). Dans ta 1ère version, je ne le vois nullepart.
Ollivier
Messages : 4190
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: Gadget OpenGL : Utilisation du clavier

Message par Ollivier »

Un truc comme ça :

Code : Tout sélectionner

While #True
Delay(3)
Repeat : Delay(1): Until WindowEvent() = 0
GameRender()
Wend
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Gadget OpenGL : Utilisation du clavier

Message par falsam »

Je viens de le faire et comme prévu ca ne change rien.

Quand on presse une touche sans relâcher, il y a un temps d'attente avant que l'exécutable détecte que la touche est toujours pressée.
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Gadget OpenGL : Utilisation du clavier

Message par falsam »

Je pensais m'en sortir avec une fonctionnalité Glut et en fait non car mon code demande une dll 32 bits alors que je code 64 bits !

Code : Tout sélectionner

Procedure Keypressed(Key)
  Debug key  
EndProcedure

glutKeyboardFunc_(@keyPressed())
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Ollivier
Messages : 4190
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: Gadget OpenGL : Utilisation du clavier

Message par Ollivier »

Poste ta question sur le forum US. C'est possible qu'il y ait des retours. Moi, je ne suis vraiment pas à la page : quand j'ai vu qu'il y avait un écran noir dans les thèmes sombres ou inversés de Windows, je suis passé à autre chose...
crisot
Messages : 98
Inscription : lun. 30/août/2004 21:03

Re: Gadget OpenGL : Utilisation du clavier

Message par crisot »

ExamineKeyboard() retourne continuellement si la touche est *actuellement* appuyée ou pas. C'est pour cela que ce code marche.

En revanche les Event retournent un évenement unique quand une touche à été appuyée ou relevée, mais rien entre les deux. C'est à dire qu'une fois qu'une touche a été appuyée, même si tu la maintient, elle ne génère plus d'event! En fait, si, il y a toujours des event sur le délais de répétition du clavier, c'est précisément pour cela que tu as un effet "éditeur de texte".

La solution est fort simple. Il faut que tu regardes les event de KeyDown mais AUSSI ceux de KeyUp. De là, c'est à toi de conserver une variable contenant l'état de la touche.

Pseudo code:

Code : Tout sélectionner

If KeyDown
   Appuyee = 1
EndIf
If KeyUp
   Appuyee = 0
EndIf
If Appuyee = 1
   MonCube bouge
EndIf
Bref, voilà ton code :)

Code : Tout sélectionner

EnableExplicit

; Fenetre application, viewport et couleur arriere plan 
Global window, ww = 800, wh = 600, viewport, wColor.f = RGB(107, 142, 35)

; Sprite  
Global sx.f = 100, sy.f =100, sw = 64, sh = 64, sColor = RGB(255, 215, 0)

; Touches appuyées
Global left=0, right=0, up=0, down=0

;Plan de l'application
Declare Start()
Declare KeyDown()
Declare KeyUp()
Declare GameEvent()
Declare GameRender()
Declare Exit()

Start()

Procedure Start()
  window = OpenWindow(#PB_Any, 0, 0, ww, wh, "Test Opengl", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
  
  ; Fenetre Open GL
  viewport = OpenGLGadget(#PB_Any, 0, 0, ww, wh, #PB_OpenGL_NoDepthBuffer | #PB_OpenGL_Keyboard)
  SetActiveGadget(viewport)
  
  ; Modifier le contexte courant
  SetGadgetAttribute(viewport, #PB_OpenGL_SetContext, #True)
  
  ; Couleur d'arrirer plan
  glClearColor_(Red(wColor)/255, Green(wColor)/255, Blue(wColor)/255, 1.0)
  
  ; Volume de visualisation 
  glMatrixMode_(#GL_PROJECTION)
  glLoadIdentity_();
  gluOrtho2D_(0, ww, wh, 0)
  
  ;Triggers  
  BindGadgetEvent(viewport, @KeyDown(), #PB_EventType_KeyDown)
  BindGadgetEvent(viewport, @KeyUp(), #PB_EventType_KeyUp) 
  BindEvent(#PB_Event_CloseWindow, @Exit())
  
  ;Loop
  While #True
    Repeat : Until WindowEvent() = 0
    GameEvent()
    GameRender()
  Wend
EndProcedure

Procedure GameEvent()
  Protected Speed.f = 8
    sx + Speed * (right - left)
    sy + Speed * (down - up)
EndProcedure

Procedure KeyDown()
  Select GetGadgetAttribute(viewport, #PB_OpenGL_Key)
    Case #PB_Shortcut_Left
      left=1
    Case #PB_Shortcut_Right  
      right=1
    Case#PB_Shortcut_Up
      up=1
    Case #PB_Shortcut_Down
      down=1
    Case #PB_Shortcut_Escape
      Exit() 
  EndSelect
EndProcedure

Procedure KeyUp()
  Select GetGadgetAttribute(viewport, #PB_OpenGL_Key)
    Case #PB_Shortcut_Left
      left=0
    Case #PB_Shortcut_Right  
      right=0
    Case#PB_Shortcut_Up
      up=0
    Case #PB_Shortcut_Down
      down=0
  EndSelect
EndProcedure

Procedure GameRender()
  ; ClearScreen
  glClear_(#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT)
  
  ; Affichage d'un carré
  glMatrixMode_(#GL_MODELVIEW)    ;Initialiser la matrice de transformation courante
  glPushMatrix_()                 
  
  glBegin_(#GL_POLYGON)           
  glColor3f_(Red(sColor)/255, Green(sColor)/255, Blue(sColor)/255)
  
  glVertex2i_(sx, sy)             ;Point haut gauche
  glVertex2i_(sx + sw, sy)        ;Point haut droit
  glVertex2i_(sx + sw, sy + sh)   ;Point bas droit
  glVertex2i_(sx, sy + sh)        ;Point bas gauche
  glEnd_()                        ;Fin du polygone
  
  glPopMatrix_();
  
  ; Flip buffer
  SetGadgetAttribute(viewport, #PB_OpenGL_FlipBuffers, #True)  
EndProcedure

Procedure Exit()  
  End
EndProcedure
Dernière modification par crisot le ven. 19/avr./2019 0:17, modifié 3 fois.
crisot
Messages : 98
Inscription : lun. 30/août/2004 21:03

Re: Gadget OpenGL : Utilisation du clavier

Message par crisot »

(Et arrêtez avec Delay(), cette instruction n'existe pas :D :D :D )
Répondre