Page 1 sur 1

Sauvegarder une capture d'écran OpenGL

Publié : mer. 03/août/2022 12:45
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

Re: Sauvegarder une capture d'écran OpenGL

Publié : mer. 03/août/2022 14:48
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 ;)

Re: Sauvegarder une capture d'écran OpenGL

Publié : mer. 03/août/2022 14:58
par SPH
Merci, je vais Enjoyer ! :D

Re: Sauvegarder une capture d'écran OpenGL

Publié : mer. 03/août/2022 17:14
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é !

Re: Sauvegarder une capture d'écran OpenGL

Publié : jeu. 04/août/2022 20:56
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...