Page 1 sur 1

impossible de perdre le focus d'une fenêtre 3d

Publié : ven. 26/févr./2021 11:23
par fredcelia
Bonjour tout le monde,
j'ai programmé une application en 3D (mode fenêtré) que je fais tourner sur le deuxième écran de l'ordinateur. Je voudrais pouvoir passer avec la souris de cette application à l'écran principal. Je n'y arrive pas, la souris reste dans l'application 3D.

Je suis obligé de faire ALT-TAB pour en sortir.

Bref, est-il possible de gérer en toute transparence la perte et le gain du focus sur une application 3D ?

Merci d'avance.

Re: impossible de perdre le focus d'une fenêtre 3d

Publié : ven. 26/févr./2021 11:30
par Ar-S
Bonjour.
Lorsque tu joue à un jeu 3D du commerce, même en fenêtré, peux tu sortir ta souris comme ça ? Non plus.
Il y a peut être un hack à faire mais je ne le connais pas.

Re: impossible de perdre le focus d'une fenêtre 3d

Publié : ven. 26/févr./2021 14:30
par fredcelia
Le seul truc que j'ai trouvé est de lancer une application fantôme constituée d'une toute petite fenêtre à partir d'un objet de mon application 3d. Cela lui donne automatiquement le focus et permet de "sortir" de l'appli 3D.
Pas idéal bien sur.

Re: impossible de perdre le focus d'une fenêtre 3d

Publié : dim. 28/févr./2021 1:35
par falsam
Cette procédure permet de faire ce que tu veux.

Code : Tout sélectionner

Procedure ScreenFocus(Window, Left=0, Top=0, RightOffset=0, BottomOffset=0)    
  If IsScreenActive() 
    Protected X = WindowMouseX(Window) 
    Protected Y = WindowMouseY(Window)
    Protected Value.b = Bool(X>Left And Y>Top And X<WindowWidth(Window)-RightOffset-1 And Y<WindowHeight(Window)-BottomOffset-1)
    
    ReleaseMouse(1 - Value)
    MouseLocate(X-Left, Y-Top)
    
    ProcedureReturn Value
  EndIf 
EndProcedure
■ Avant de déplacer le sprite représentant la souris, il suffit de tester si la souris est toujours sur le screen.

Code : Tout sélectionner

If ScreenFocus(Window)
      DisplayTransparentSprite(Pointer, MouseX(), MouseY())
EndIf
■ Avec cette exemple tu peux cliquer sur le sol ou sur la caisse et connaitre les coordonnées x,y et z du picking (Affichage en haut de la fenêtre). Touche Escape pour quitter.

Code : Tout sélectionner

EnableExplicit

Enumeration window
  #mf  
EndEnumeration

; Police application
Global FontGlobal

; Panneau d'information et pointeur de souris
Global Header, Pointer

; Camera et entité sélectionné
Global Camera

Structure NewVector
  x.f
  y.f
  z.f
EndStructure
Global Pick.NewVector

Declare Start()
Declare LoadGame()
Declare RenderGame()
Declare Createball()
Declare ScreenFocus(Window, Left=0, Top=0, RightOffset=0, BottomOffset=0)
Declare Exit()

Start()

Procedure Start()
  UsePNGImageDecoder() 
  InitEngine3D() : InitKeyboard() : InitMouse() : InitSprite()
  
  fontGlobal = LoadFont(#PB_Any, "Arial", 10)
  
  OpenWindow(#mf, 0, 0, 900, 700, "Test", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
  BindEvent(#PB_Event_CloseWindow, @Exit())
  
  OpenWindowedScreen(WindowID(#mf), 0, 0, 900, 700)
  Add3DArchive(#PB_Compiler_Home + "Examples/3D/Data/Packs/desert.zip", #PB_3DArchive_Zip)
  Add3DArchive(#PB_Compiler_Home + "Examples/3D/Data/Textures", #PB_3DArchive_FileSystem)
  
  KeyboardMode(#PB_Keyboard_International | #PB_Keyboard_AllowSystemKeys)
  
  LoadGame()
  RenderGame()
EndProcedure

Procedure LoadGame()
  Protected Mesh, Material, Entity
  
  ; Header pour afficher des informations 
  Header = CreateSprite(#PB_Any, ScreenWidth(), 32, #PB_Sprite_AlphaBlending)
  
  ; Pointer de la souris
  Pointer = CatchSprite(#PB_Any, ?pointer, #PB_Sprite_AlphaBlending   )
  
  ; Caméra
  Camera = CreateCamera(#PB_Any, 0, 0, 100, 100)
  MoveCamera(Camera, 5, 10, 30)
  CameraLookAt(Camera, 0, 5, 0)  
  
  ;-Sky 
  SkyBox("desert07.jpg")
  
  ; Un peu de lumière
  CreateLight(#PB_Any, RGB(255, 255, 255), -100, 200, 100)
  
  ; Entités 
  Mesh = CreatePlane(#PB_Any, 100, 100, 10, 10, 6, 6)
  Material = CreateMaterial(#PB_Any, TextureID(LoadTexture(#PB_Any, "Dirt.jpg")))
  Entity = CreateEntity(#PB_Any, MeshID(Mesh), MaterialID(Material))
  
  Mesh = CreateCube(#PB_Any, 4)
  Material = CreateMaterial(#PB_Any, TextureID(LoadTexture(#PB_Any, "caisse.png")))
  Entity = CreateEntity(#PB_Any, MeshID(Mesh), MaterialID(Material), 0, 2, 0)
EndProcedure

Procedure RenderGame()
  Protected Result
  Protected Delta = SpriteWidth(Pointer)/2
  
  Repeat      
    Repeat : Until WindowEvent() = 0
    
    ;- Render3D
    FlipBuffers() 
    
    ; Evenements Clavier
    If ExamineKeyboard()
      If KeyboardPushed(#PB_Key_Escape)
        Exit()
      EndIf
    EndIf
    
    ; Evenement souris
    If ExamineMouse()
      If MouseButton(#PB_MouseButton_Left) 
        Result = MousePick(Camera, MouseX(), MouseY())
        If Result
          With Pick
            \x  = PickX()
            \y  = PickY()
            \z  = PickZ()
          EndWith
        EndIf
      EndIf
    EndIf
    
    RenderWorld() 
    
    ;- Render 2D (A placer aprés RenderWorld)
    If StartDrawing(SpriteOutput(Header))
      Box(0, 0, SpriteWidth(Header), SpriteHeight(Header), RGBA(0, 0, 0, 0))
      DrawingFont(FontID(fontGlobal))
      DrawingMode(#PB_2DDrawing_AlphaChannel)
      Box(0, 0, SpriteWidth(Header), SpriteHeight(Header), RGBA(0, 0, 0, 110))
      DrawingMode(#PB_2DDrawing_Transparent)
      
      ; Position Curseur
      With Pick
        DrawText(5, 5, "x:" + StrF(\x, 2) + " y:" + StrF(\y, 2) + " z:" + StrF(\z, 2)) 
      EndWith
      
      ; FPS
      DrawText(ScreenWidth() - 80, 5, "FPS: " + Str(Engine3DStatus(#PB_Engine3D_CurrentFPS)))
      
      StopDrawing()
      DisplayTransparentSprite(Header, 0, 0) 
    EndIf    
    
    If ScreenFocus(#mf)
      DisplayTransparentSprite(Pointer, MouseX()-Delta, MouseY()-Delta)
    EndIf
  ForEver  
EndProcedure

;-
Procedure ScreenFocus(Window, Left=0, Top=0, RightOffset=0, BottomOffset=0)    
  If IsScreenActive() 
    Protected X = WindowMouseX(Window) 
    Protected Y = WindowMouseY(Window)
    Protected Value.b = Bool(X>Left And Y>Top And X<WindowWidth(Window)-RightOffset-1 And Y<WindowHeight(Window)-BottomOffset-1)
    
    ReleaseMouse(1 - Value)
    MouseLocate(X-Left, Y-Top)
    
    ProcedureReturn Value
  EndIf 
EndProcedure
;-

Procedure Exit()
  End  
EndProcedure

DataSection
  pointer:
  IncludeBinary #PB_Compiler_Home + "Examples\Sources\Data\world.png"  
EndDataSection

Re: impossible de perdre le focus d'une fenêtre 3d

Publié : dim. 28/févr./2021 11:56
par fredcelia
Formidable !
Un grand merci !!!

Pour ceux qui veulent tester attention au paramètre 'enable dpi aware' des options du compilateur. Je l'ai coché pour que ça fonctionne bien lorsque je lance le script sur mon écran principal mais j'ai du le décocher pour que ça fonctionne lorsque j'ouvre la fenêtre du script sur mon écran secondaire.

Re: impossible de perdre le focus d'une fenêtre 3d

Publié : lun. 01/mars/2021 11:46
par falsam
fredcelia a écrit :Pour ceux qui veulent tester attention au paramètre 'enable dpi aware' des options du compilateur. Je l'ai coché pour que ça fonctionne bien lorsque je lance le script sur mon écran principal mais j'ai du le décocher pour que ça fonctionne lorsque j'ouvre la fenêtre du script sur mon écran secondaire.
Sur ton écran principal la mise à l'échelle de ton affichage est différent de 100%.

Re: impossible de perdre le focus d'une fenêtre 3d

Publié : lun. 01/mars/2021 11:47
par fredcelia
Exact.