Sauvegarder une capture d'écran OpenGL

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
SPH
Messages : 4947
Inscription : mer. 09/nov./2005 9:53

Sauvegarder une capture d'écran OpenGL

Message par SPH »

Salut,

Ce code ne fonctionne (évidement) pas en OpenGL :

Code : Tout sélectionner

  If ElapsedMilliseconds()-timer>4000
    GrabSprite(0,0,0,ddw,ddh)
    SaveSprite(0,"f:/html/oiseaux.bmp")
    End
  EndIf
Savez-vous comment capturer l'écran et le sauvegarder ?
===
Merci

!i!i!i!i!i!i!i!i!i!
!i!i!i!i!i!i!
!i!i!i!
//// Informations ////
Intel Core i7 4770 64 bits - GTX 650 Ti
Version de PB : 6.12LTS- 64 bits
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Sauvegarder une capture d'écran OpenGL

Message par falsam »

La procédure CaptureOpenGl() devrait répondre à ta demande. Cette procédure retourne l'identifiant de l'image capturée au format JPG.

Tu fournis l'identifiant de ton gadget OpenGL ainsi que les coordonnées (x, y, Width, Height) de la zone de capture.

Le tout dans un code de démonstration.

Code : Tout sélectionner

EnableExplicit

; Fenetre OpenGl
Global wogl

; Dimension fenetre et opengl
Global ww = 800, wh = 600

; Position et dimension du sprite
Global sx.f , sy.f, sw.f, sh.f 

; Plan de l'application
Declare Start()
Declare Render()
Declare Draw0()
Declare CaptureOpenGl(Gadget, x, y, Width, Height)
Declare Exit()

UseJPEGImageEncoder()

Start()

Procedure Start()      
  OpenWindow(0, 0, 0, ww, wh, "OpenGL Test", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
  
  ; Fenetre openGl
  wogl = OpenGLGadget(#PB_Any, 0, 0, ww, wh, #PB_OpenGL_NoDepthBuffer)
  SetGadgetAttribute(wogl, #PB_OpenGL_SetContext, #True)
  
  ; Volume de visualisation. (gauche, droite, bas, haut, proche et loin)
  glMatrixMode_(#GL_PROJECTION) ;Initialiser la matrice de projection
  glLoadIdentity_()
  glOrtho_(0, ww, wh, 0, -1, 1) 
  
  ; Couleur d'arriere plan (RGBA Décimales)
  glClearColor_(0.5, 0.5, 0.5, 1.0)
  
  ; Visualisation du rendu
  Render()
  
  ;Triggers
  BindEvent(#PB_Event_CloseWindow, @Exit())
  
  Repeat : WaitWindowEvent() : ForEver
EndProcedure

Procedure Render()  
  ; Efface le frame buffer et le Z-buffer
  glClear_(#GL_COLOR_BUFFER_BIT | #GL_DEPTH_BUFFER_BIT)
  
  ; Dessin du sprite
  Draw0()  
  
  ; FlipBuffers
  SetGadgetAttribute(wogl, #PB_OpenGL_FlipBuffers, #True)
EndProcedure

;Dessin d'un rectangle rouge (non texturé)
Procedure Draw0()
  Protected Result
  
  sx = 100 : sy = 100 : sw = 200:  sh = 100
  
  glMatrixMode_(#GL_MODELVIEW)    ;Initialiser la matrice de transformation courante
  
  glRotatef_(15, 0, 0, 1)
  glBegin_(#GL_POLYGON)           ;Debut du polygone
  glColor3ub_(0, 255, 0)          ;Couleur du polygone 
  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
  
  Result = CaptureOpenGl(wogl, 0, 0, ww, wh)
  ShowLibraryViewer("Image", Result)
EndProcedure

; CaptureOpenGl() retourne l'identifiant de l'image capturée
; Gadget OpenGl   : Gadget
; Zone de capture : x, y, Width, Height
Procedure CaptureOpenGl(Gadget, x, y, Width, Height)
  Protected BufferSize = Width * Height * 3 ; Chaque point est un format RGB)
  Protected *Pixels = AllocateMemory(BufferSize, #PB_Memory_NoClear) 
  Protected Screenshot, Px, Py, Pos
  
  If *pixels
    ; glReadPixels lit un bloc de pixels à partir du framebuffer
    ; https://docs.microsoft.com/fr-fr/windows/win32/opengl/glreadpixels
    glReadPixels_(x, y, Width, Height, #GL_RGB, #GL_UNSIGNED_BYTE, *Pixels);
    
    Screenshot = CreateImage(#PB_Any, Width, Height)
    
    If StartDrawing(ImageOutput(Screenshot))
      For Py = Height - 1 To 0 Step -1
        For Px = 0 To Width - 1
          If (Pos + 2) < BufferSize
            Plot(Px, Py, RGB(PeekA(*Pixels + Pos), PeekA(*Pixels + Pos + 1), PeekA(*Pixels + Pos + 2)))
            Pos + 3
            EndIf 
        Next
      Next      
      StopDrawing()
      FreeMemory(*Pixels)
    EndIf 
  EndIf 
  ProcedureReturn Screenshot
EndProcedure

Procedure Exit()  
  End
EndProcedure
Enjoy ;)
Configuration : Windows 11 Famille 64-bit - PB 6.20 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
SPH
Messages : 4947
Inscription : mer. 09/nov./2005 9:53

Re: Sauvegarder une capture d'écran OpenGL

Message par SPH »

Merci, je vais Enjoyer ! :D

!i!i!i!i!i!i!i!i!i!
!i!i!i!i!i!i!
!i!i!i!
//// Informations ////
Intel Core i7 4770 64 bits - GTX 650 Ti
Version de PB : 6.12LTS- 64 bits
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: Sauvegarder une capture d'écran OpenGL

Message par Ollivier »

Code : Tout sélectionner

For Py = Height - 1 To 0 Step -1
        For Px = 0 To Width - 1
          If (Pos + 2) < BufferSize
            Plot(Px, Py, RGB(PeekA(*Pixels + Pos), PeekA(*Pixels + Pos + 1), PeekA(*Pixels + Pos + 2)))
            Pos + 3
            EndIf 
        Next
      Next
Je suis retourné !
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: Sauvegarder une capture d'écran OpenGL

Message par Ollivier »

Nan mais... Vous n'allez pas laisser ça comme ça... À moins que ce soit une touche artistique, que je n'aurais su déceler... J'avoue : ça marche. Mais quand même...
Répondre