Effet de loupe sur votre bureau

Partagez votre expérience de PureBasic avec les autres utilisateurs.
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Effet de loupe sur votre bureau

Message par Le Soldat Inconnu »

Ce code permet de faire un effet de "loupe" sur l'écran.

Pour bouger la loupe, avec la souris
pour agrandir ou réduire la taille : flèches haut et bas
pour augmenter ou diminuer l'effet de loupe : flèches droite et gauche

Voici la version sans lissage du contenu de la loupe :

Code : Tout sélectionner

ProcedureDLL.l GetImageBits2(ImageID, HList) ; Transfert d'une image vers un tableau
  Protected bmi.BITMAPINFO, hdc.l, Resultat, Mem, n, nn, bm.BITMAP
  
  Resultat = 0
  
  GetObject_(ImageID, SizeOf(BITMAP), @bm.BITMAP)
  
  bmi\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
  bmi\bmiHeader\biWidth = bm\bmWidth
  bmi\bmiHeader\biHeight = bm\bmHeight
  bmi\bmiHeader\biPlanes = 1
  bmi\bmiHeader\biBitCount = 32
  bmi\bmiHeader\biCompression = #BI_RGB
  
  Mem = AllocateMemory(bm\bmWidth * bm\bmHeight * 4)
  If Mem
    
    hdc = CreateCompatibleDC_(GetDC_(ImageID))
    If hdc
      GetDIBits_(hdc, ImageID, 0, bm\bmHeight, Mem, @bmi, #DIB_RGB_COLORS) ; on envoie la liste dans l'image
      ReleaseDC_(0, hdc)
      Resultat = ImageID
    EndIf
    
    ; On convertit la liste dans le bon format
    For n = 0 To bm\bmHeight - 1
      For nn = 0 To bm\bmWidth - 1
        CopyMemory(Mem + nn * 4 + (bm\bmHeight - 1 - n) * bm\bmWidth * 4, HList + n * 4 + nn * bm\bmHeight * 4, 4)
      Next
    Next
    
    FreeMemory(Mem)
  EndIf
  
  ProcedureReturn Resultat
EndProcedure

Procedure.f Longueur(x1.f, y1.f, x2.f, y2.f)
  ProcedureReturn Sqr(Pow(x1 - x2, 2) + Pow(y1 - y2, 2))
EndProcedure

#Pi.f = 3.14159265

; Copie d'écran
Largeur_Ecran = GetSystemMetrics_(#SM_CXSCREEN)
Hauteur_Ecran = GetSystemMetrics_(#SM_CYSCREEN)

DC = GetDC_(0)
CreateImage(0, Largeur_Ecran, Hauteur_Ecran)
Dessin = StartDrawing(ImageOutput())
  BitBlt_(Dessin, 0, 0, Largeur_Ecran, Hauteur_Ecran, DC, 0, 0, #SRCPAINT)
StopDrawing()
ReleaseDC_(0, DC)

OpenWindow(0, 0, 0, 100, 100, #WS_MAXIMIZE | #PB_Window_BorderLess, "Sphère")
SetWindowPos_(WindowID(), -1, 0, 0, 0, 0, #SWP_NOSIZE | #SWP_NOMOVE) ; Pour mettre la fenêtre toujours au premier plan
UpdateWindow_(WindowID())

; On copie l'image dans un Tableau
Dim Image.l(Largeur_Ecran - 1, Hauteur_Ecran - 1)
GetImageBits2(UseImage(0), @Image())

; On ouvre l'openscreen
If InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse() = 0
  MessageRequester("Erreur", "Impossible d'initialiser la souris ,le clavier ou l'écran. Vérifiez la présence de DirectX 7 ou supérieur.", 0)
  End
EndIf

If OpenScreen(Largeur_Ecran, Hauteur_Ecran, 32, "Sphère") = 0
  MessageRequester("Erreur", "Impossible d'ouvrir l'écran.", 0)
  End
EndIf

CreateSprite(1, Largeur_Ecran, Hauteur_Ecran)
StartDrawing(SpriteOutput(1))
  DrawImage(UseImage(0), 0, 0)
StopDrawing()

Rayon = 25
Loupe.f = 0.5

Repeat
  ; On lit les évènements clavier et souris
  ExamineMouse()
  ExamineKeyboard()
  
  ; Position de la souris
  x = MouseX()
  y = MouseY()
  
  ; Agrandir ou réduire la sphère
  If KeyboardPushed(#PB_Key_Up) And Rayon < 100
    Rayon + 2
  ElseIf KeyboardPushed(#PB_Key_Down) And Rayon > 0
    Rayon - 2
  EndIf
  
  ; Augmenter ou diminuer l'effet de loupe
  If KeyboardPushed(#PB_Key_Right) And Loupe < 1
    Loupe + 0.05
  ElseIf KeyboardPushed(#PB_Key_Left) And Loupe > 0
    Loupe - 0.05
  EndIf
  
  ; On affiche l'image
  DisplaySprite(1, 0, 0)
  
  StartDrawing(ScreenOutput())
    ; Calcul du FPS
    cpt + 1
    If cpt = 10
      cpt = 0
      fps = 10000 / (ElapsedMilliseconds() - Temps)
      Temps = ElapsedMilliseconds()
    EndIf
    Locate(5, 5)
    DrawText(Str(fps))
    
    ; On édite l'image
    Memoire = DrawingBuffer()
    For n = -Rayon To Rayon
      If x + n > 0 And x + n < Largeur_Ecran - 1 ; Si on est sur l'image en x
        For nn = -Rayon To Rayon
          If y + nn > 0 And y + nn < Hauteur_Ecran - 1 ; Si on est sur l'image en y
            Longueur.f = Longueur(x, y, x + n, y + nn) ; On calcul la distance d'un point de la sphère à partir du centre
            If Longueur <= Rayon ; Si le pixel est situé dans le rayon du cercle
              Longueur2.f = ASin(Longueur / Rayon * Loupe + (1 - Loupe)) * 2 / #Pi * Longueur ; on calcul la distance du point de l'image correspondant à celui de la sphère
              If Longueur > 0
                PosX.f = x + n * Longueur2 / Longueur
                PosY.f = y + nn * Longueur2 / Longueur
                
                ; Avec lissage
                ; PosX_Int = Int(PosX)
                ; PosY_Int = Int(PosY)
                ; Rouge.f = 0 : Vert.f = 0 : Bleu.f = 0 : SommeFacteur.f = 0
                ; For i = PosX_Int - 1 To PosX_Int + 1
                  ; For ii = PosY_Int - 1 To PosY_Int + 1
                    ; Facteur.f = 1 - Longueur(i, ii, PosX, PosY)
                    ; If Facteur > 0
                      ; Rouge = Rouge + Red(Image(i, ii)) * Facteur
                      ; Vert = Vert + Green(Image(i, ii)) * Facteur
                      ; Bleu = Bleu + Blue(Image(i, ii)) * Facteur
                      ; SommeFacteur = SommeFacteur + Facteur
                    ; EndIf
                  ; Next
                ; Next
                ; Couleur.l = RGB(Int(Rouge / SommeFacteur), Int(Vert / SommeFacteur), Int(Bleu / SommeFacteur))
                
                ; Sans lissage
                Couleur.l = Image(Int(PosX + 0.5), Int(PosY + 0.5))
                
              Else ; Cas particulier, le centre de la sphère
                Couleur.l = Image(x, y)
              EndIf
              ; On affiche le pixel
              Pixel_Memoire = Memoire + 4 * (x + n) + 4 * (y + nn) * Largeur_Ecran
              PokeL(Pixel_Memoire, Couleur)
            EndIf
          EndIf
        Next
      EndIf
    Next
    
  StopDrawing()
  
  FlipBuffers()
  
  If IsScreenActive() = 0
    End
  EndIf
  
Until KeyboardPushed(#PB_Key_Escape)
La vitesse du code est honnête.
mais si je fais un lissage, catasthrophe, c'est trop lent

Code : Tout sélectionner

ProcedureDLL.l GetImageBits2(ImageID, HList) ; Transfert d'une image vers un tableau
  Protected bmi.BITMAPINFO, hdc.l, Resultat, Mem, n, nn, bm.BITMAP
  
  Resultat = 0
  
  GetObject_(ImageID, SizeOf(BITMAP), @bm.BITMAP)
  
  bmi\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
  bmi\bmiHeader\biWidth = bm\bmWidth
  bmi\bmiHeader\biHeight = bm\bmHeight
  bmi\bmiHeader\biPlanes = 1
  bmi\bmiHeader\biBitCount = 32
  bmi\bmiHeader\biCompression = #BI_RGB
  
  Mem = AllocateMemory(bm\bmWidth * bm\bmHeight * 4)
  If Mem
    
    hdc = CreateCompatibleDC_(GetDC_(ImageID))
    If hdc
      GetDIBits_(hdc, ImageID, 0, bm\bmHeight, Mem, @bmi, #DIB_RGB_COLORS) ; on envoie la liste dans l'image
      ReleaseDC_(0, hdc)
      Resultat = ImageID
    EndIf
    
    ; On convertit la liste dans le bon format
    For n = 0 To bm\bmHeight - 1
      For nn = 0 To bm\bmWidth - 1
        CopyMemory(Mem + nn * 4 + (bm\bmHeight - 1 - n) * bm\bmWidth * 4, HList + n * 4 + nn * bm\bmHeight * 4, 4)
      Next
    Next
    
    FreeMemory(Mem)
  EndIf
  
  ProcedureReturn Resultat
EndProcedure

Procedure.f Longueur(x1.f, y1.f, x2.f, y2.f)
  ProcedureReturn Sqr(Pow(x1 - x2, 2) + Pow(y1 - y2, 2))
EndProcedure

#Pi.f = 3.14159265

; Copie d'écran
Largeur_Ecran = GetSystemMetrics_(#SM_CXSCREEN)
Hauteur_Ecran = GetSystemMetrics_(#SM_CYSCREEN)

DC = GetDC_(0)
CreateImage(0, Largeur_Ecran, Hauteur_Ecran)
Dessin = StartDrawing(ImageOutput())
  BitBlt_(Dessin, 0, 0, Largeur_Ecran, Hauteur_Ecran, DC, 0, 0, #SRCPAINT)
StopDrawing()
ReleaseDC_(0, DC)

OpenWindow(0, 0, 0, 100, 100, #WS_MAXIMIZE | #PB_Window_BorderLess, "Sphère")
SetWindowPos_(WindowID(), -1, 0, 0, 0, 0, #SWP_NOSIZE | #SWP_NOMOVE) ; Pour mettre la fenêtre toujours au premier plan
UpdateWindow_(WindowID())

; On copie l'image dans un Tableau
Dim Image.l(Largeur_Ecran - 1, Hauteur_Ecran - 1)
GetImageBits2(UseImage(0), @Image())

; On ouvre l'openscreen
If InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse() = 0
  MessageRequester("Erreur", "Impossible d'initialiser la souris ,le clavier ou l'écran. Vérifiez la présence de DirectX 7 ou supérieur.", 0)
  End
EndIf

If OpenScreen(Largeur_Ecran, Hauteur_Ecran, 32, "Sphère") = 0
  MessageRequester("Erreur", "Impossible d'ouvrir l'écran.", 0)
  End
EndIf

CreateSprite(1, Largeur_Ecran, Hauteur_Ecran)
StartDrawing(SpriteOutput(1))
  DrawImage(UseImage(0), 0, 0)
StopDrawing()

Rayon = 25
Loupe.f = 0.5

Repeat
  ; On lit les évènements clavier et souris
  ExamineMouse()
  ExamineKeyboard()
  
  ; Position de la souris
  x = MouseX()
  y = MouseY()
  
  ; Agrandir ou réduire la sphère
  If KeyboardPushed(#PB_Key_Up) And Rayon < 100
    Rayon + 2
  ElseIf KeyboardPushed(#PB_Key_Down) And Rayon > 0
    Rayon - 2
  EndIf
  
  ; Augmenter ou diminuer l'effet de loupe
  If KeyboardPushed(#PB_Key_Right) And Loupe < 1
    Loupe + 0.05
  ElseIf KeyboardPushed(#PB_Key_Left) And Loupe > 0
    Loupe - 0.05
  EndIf
  
  ; On affiche l'image
  DisplaySprite(1, 0, 0)
  
  StartDrawing(ScreenOutput())
    ; Calcul du FPS
    cpt + 1
    If cpt = 10
      cpt = 0
      fps = 10000 / (ElapsedMilliseconds() - Temps)
      Temps = ElapsedMilliseconds()
    EndIf
    Locate(5, 5)
    DrawText(Str(fps))
    
    ; On édite l'image
    Memoire = DrawingBuffer()
    For n = -Rayon To Rayon
      If x + n > 0 And x + n < Largeur_Ecran - 1 ; Si on est sur l'image en x
        For nn = -Rayon To Rayon
          If y + nn > 0 And y + nn < Hauteur_Ecran - 1 ; Si on est sur l'image en y
            Longueur.f = Longueur(x, y, x + n, y + nn) ; On calcul la distance d'un point de la sphère à partir du centre
            If Longueur <= Rayon ; Si le pixel est situé dans le rayon du cercle
              Longueur2.f = ASin(Longueur / Rayon * Loupe + (1 - Loupe)) * 2 / #Pi * Longueur ; on calcul la distance du point de l'image correspondant à celui de la sphère
              If Longueur > 0
                PosX.f = x + n * Longueur2 / Longueur
                PosY.f = y + nn * Longueur2 / Longueur
                
                ; Avec lissage
                PosX_Int = Int(PosX)
                PosY_Int = Int(PosY)
                Rouge.f = 0 : Vert.f = 0 : Bleu.f = 0 : SommeFacteur.f = 0
                For i = PosX_Int - 1 To PosX_Int + 1
                  For ii = PosY_Int - 1 To PosY_Int + 1
                    Facteur.f = 1 - Longueur(i, ii, PosX, PosY)
                    If Facteur > 0
                      Rouge = Rouge + Red(Image(i, ii)) * Facteur
                      Vert = Vert + Green(Image(i, ii)) * Facteur
                      Bleu = Bleu + Blue(Image(i, ii)) * Facteur
                      SommeFacteur = SommeFacteur + Facteur
                    EndIf
                  Next
                Next
                Couleur.l = RGB(Int(Rouge / SommeFacteur), Int(Vert / SommeFacteur), Int(Bleu / SommeFacteur))
                
                ; Sans lissage
                ; Couleur.l = Image(Int(PosX + 0.5), Int(PosY + 0.5))
                
              Else ; Cas particulier, le centre de la sphère
                Couleur.l = Image(x, y)
              EndIf
              ; On affiche le pixel
              Pixel_Memoire = Memoire + 4 * (x + n) + 4 * (y + nn) * Largeur_Ecran
              PokeL(Pixel_Memoire, Couleur)
            EndIf
          EndIf
        Next
      EndIf
    Next
    
  StopDrawing()
  
  FlipBuffers()
  
  If IsScreenActive() = 0
    End
  EndIf
  
Until KeyboardPushed(#PB_Key_Escape)
Si quelqu'un à une solution pour optimiser la vitesse, je suis preneur :D
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
julien
Messages : 846
Inscription : ven. 30/janv./2004 15:06
Contact :

Message par julien »

PAs mal le code n'est pas tellement plus lent que le 1er, une fois compilé en exe, la vitesse est tout à fait acceptable!

Si quelqu'un à une solution pour optimiser la vitesse, je suis preneur Very Happy
Change de PC :lol:

PS : Bon prog (une fois de +) :wink:
Oliv
Messages : 2117
Inscription : mer. 21/janv./2004 18:39

Message par Oliv »

Moi c'est aussi rapide pour les deux, bravo :D
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

Grossissez la loupe pour voir.
Avec la taille par défaut, ça tourne nickel mais dès qu'on grossit la loupe. aie.
ça donne quoi en FPS (en haut à gauche)
car ça descend vite entre 1 et 5 quand on augente la taille chez moi (avec la taille à fond et avec le lissage)
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Avatar de l’utilisateur
Chris
Messages : 3731
Inscription : sam. 24/janv./2004 14:54
Contact :

Message par Chris »

Avec lissage, taille à fond, et grossissement à fond, 2 fps
Sans lissage, taille à fond, et grossissement à fond, 17 fps
Oliv
Messages : 2117
Inscription : mer. 21/janv./2004 18:39

Message par Oliv »

Effectivement, le FPS est de 2 aussi chez moi :?
garzul
Messages : 683
Inscription : mer. 26/mai/2004 0:33

Message par garzul »

:D je sais que clearscreen(0,0,0) na rien a voir ici mais au contraire en essayant de metre clearscreen(0,0,0) j'obtien 1 fps de plus en grossissant a fond :D Regardez essayer :

Code : Tout sélectionner

ProcedureDLL.l GetImageBits2(ImageID, HList) ; Transfert d'une image vers un tableau
  Protected bmi.BITMAPINFO, hdc.l, Resultat, Mem, n, nn, bm.BITMAP
  
  Resultat = 0
  
  GetObject_(ImageID, SizeOf(BITMAP), @bm.BITMAP)
  
  bmi\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
  bmi\bmiHeader\biWidth = bm\bmWidth
  bmi\bmiHeader\biHeight = bm\bmHeight
  bmi\bmiHeader\biPlanes = 1
  bmi\bmiHeader\biBitCount = 32
  bmi\bmiHeader\biCompression = #BI_RGB
  
  Mem = AllocateMemory(bm\bmWidth * bm\bmHeight * 4)
  If Mem
    
    hdc = CreateCompatibleDC_(GetDC_(ImageID))
    If hdc
      GetDIBits_(hdc, ImageID, 0, bm\bmHeight, Mem, @bmi, #DIB_RGB_COLORS) ; on envoie la liste dans l'image
      ReleaseDC_(0, hdc)
      Resultat = ImageID
    EndIf
    
    ; On convertit la liste dans le bon format
    For n = 0 To bm\bmHeight - 1
      For nn = 0 To bm\bmWidth - 1
        CopyMemory(Mem + nn * 4 + (bm\bmHeight - 1 - n) * bm\bmWidth * 4, HList + n * 4 + nn * bm\bmHeight * 4, 4)
      Next
    Next
    
    FreeMemory(Mem)
  EndIf
  
  ProcedureReturn Resultat
EndProcedure

Procedure.f Longueur(x1.f, y1.f, x2.f, y2.f)
  ProcedureReturn Sqr(Pow(x1 - x2, 2) + Pow(y1 - y2, 2))
EndProcedure

#Pi.f = 3.14159265

; Copie d'écran
Largeur_Ecran = GetSystemMetrics_(#SM_CXSCREEN)
Hauteur_Ecran = GetSystemMetrics_(#SM_CYSCREEN)

DC = GetDC_(0)
CreateImage(0, Largeur_Ecran, Hauteur_Ecran)
Dessin = StartDrawing(ImageOutput())
BitBlt_(Dessin, 0, 0, Largeur_Ecran, Hauteur_Ecran, DC, 0, 0, #SRCPAINT)
StopDrawing()
ReleaseDC_(0, DC)

OpenWindow(0, 0, 0, 100, 100, #WS_MAXIMIZE | #PB_Window_BorderLess, "Sphère")
SetWindowPos_(WindowID(), -1, 0, 0, 0, 0, #SWP_NOSIZE | #SWP_NOMOVE) ; Pour mettre la fenêtre toujours au premier plan
UpdateWindow_(WindowID())

; On copie l'image dans un Tableau
Dim Image.l(Largeur_Ecran - 1, Hauteur_Ecran - 1)
GetImageBits2(UseImage(0), @Image())

; On ouvre l'openscreen
If InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse() = 0
  MessageRequester("Erreur", "Impossible d'initialiser la souris ,le clavier ou l'écran. Vérifiez la présence de DirectX 7 ou supérieur.", 0)
  End
EndIf

If OpenScreen(Largeur_Ecran, Hauteur_Ecran, 32, "Sphère") = 0
  MessageRequester("Erreur", "Impossible d'ouvrir l'écran.", 0)
  End
EndIf

CreateSprite(1, Largeur_Ecran, Hauteur_Ecran)
StartDrawing(SpriteOutput(1))
DrawImage(UseImage(0), 0, 0)
StopDrawing()

Rayon = 25
Loupe.f = 0.5

Repeat
  ; On lit les évènements clavier et souris
  ExamineMouse()
  ExamineKeyboard()
 ClearScreen(0,0,0)
  ; Position de la souris
  x = MouseX()
  y = MouseY()
  
  ; Agrandir ou réduire la sphère
  If KeyboardPushed(#PB_Key_Up) And Rayon < 100
    Rayon + 2
  ElseIf KeyboardPushed(#PB_Key_Down) And Rayon > 0
    Rayon - 2
  EndIf
  
  ; Augmenter ou diminuer l'effet de loupe
  If KeyboardPushed(#PB_Key_Right) And Loupe < 1
    Loupe + 0.05
  ElseIf KeyboardPushed(#PB_Key_Left) And Loupe > 0
    Loupe - 0.05
  EndIf
  
  ; On affiche l'image
  DisplaySprite(1, 0, 0)
  
  StartDrawing(ScreenOutput())
  ; Calcul du FPS
  cpt + 1
  If cpt = 10
    cpt = 0
    fps = 10000 / (ElapsedMilliseconds() - Temps)
    Temps = ElapsedMilliseconds()
  EndIf
  Locate(5, 5)
  DrawText(Str(fps))
  
  ; On édite l'image
  Memoire = DrawingBuffer()
  For n = -Rayon To Rayon
    If x + n > 0 And x + n < Largeur_Ecran - 1 ; Si on est sur l'image en x
      For nn = -Rayon To Rayon
        If y + nn > 0 And y + nn < Hauteur_Ecran - 1 ; Si on est sur l'image en y
          Longueur.f = Longueur(x, y, x + n, y + nn) ; On calcul la distance d'un point de la sphère à partir du centre
          If Longueur <= Rayon ; Si le pixel est situé dans le rayon du cercle
            Longueur2.f = ASin(Longueur / Rayon * Loupe + (1 - Loupe)) * 2 / #Pi * Longueur ; on calcul la distance du point de l'image correspondant à celui de la sphère
            If Longueur > 0
              PosX.f = x + n * Longueur2 / Longueur
              PosY.f = y + nn * Longueur2 / Longueur
              
              ; Avec lissage
              PosX_Int = Int(PosX)
              PosY_Int = Int(PosY)
              Rouge.f = 0 : Vert.f = 0 : Bleu.f = 0 : SommeFacteur.f = 0
              For i = PosX_Int - 1 To PosX_Int + 1
                For ii = PosY_Int - 1 To PosY_Int + 1
                  Facteur.f = 1 - Longueur(i, ii, PosX, PosY)
                  If Facteur > 0
                    Rouge = Rouge + Red(Image(i, ii)) * Facteur
                    Vert = Vert + Green(Image(i, ii)) * Facteur
                    Bleu = Bleu + Blue(Image(i, ii)) * Facteur
                    SommeFacteur = SommeFacteur + Facteur
                  EndIf
                Next
              Next
              Couleur.l = RGB(Int(Rouge / SommeFacteur), Int(Vert / SommeFacteur), Int(Bleu / SommeFacteur))
              
              ; Sans lissage
              ; Couleur.l = Image(Int(PosX + 0.5), Int(PosY + 0.5))
              
            Else ; Cas particulier, le centre de la sphère
              Couleur.l = Image(x, y)
            EndIf
            ; On affiche le pixel
            Pixel_Memoire = Memoire + 4 * (x + n) + 4 * (y + nn) * Largeur_Ecran
            PokeL(Pixel_Memoire, Couleur)
          EndIf
        EndIf
      Next
    EndIf
  Next
  
  StopDrawing()
  
  FlipBuffers()
  
  If IsScreenActive() = 0
    End
  EndIf
  
Until KeyboardPushed(#PB_Key_Escape)
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

tien moi j'y ai mis le turbo a ton truc !!! :lol: :lol: :lol:

le truc conciste a remplacer les boucles for next (tres longue) par des while wend !!!
mais ça seulement ceux qui on une grande experience en prog basic savent que les boucle for next sont les boucles les plus lente !!! :D :D

il est a noter que c'est pas suffisant !! faut trouver autre chose !! :D


Code : Tout sélectionner

 ProcedureDLL.l GetImageBits2(ImageID, HList) ; Transfert d'une image vers un tableau
    Protected bmi.BITMAPINFO, hdc.l, Resultat, Mem, n, nn, bm.BITMAP
    
    Resultat = 0
    
    GetObject_(ImageID, SizeOf(BITMAP), @bm.BITMAP)
    
    bmi\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
    bmi\bmiHeader\biWidth = bm\bmWidth
    bmi\bmiHeader\biHeight = bm\bmHeight
    bmi\bmiHeader\biPlanes = 1
    bmi\bmiHeader\biBitCount = 32
    bmi\bmiHeader\biCompression = #BI_RGB
    
    Mem = AllocateMemory(bm\bmWidth * bm\bmHeight * 4)
    If Mem
        
        hdc = CreateCompatibleDC_(GetDC_(ImageID))
        If hdc
            GetDIBits_(hdc, ImageID, 0, bm\bmHeight, Mem, @bmi, #DIB_RGB_COLORS) ; on envoie la liste dans l'image
            ReleaseDC_(0, hdc)
            Resultat = ImageID
        EndIf
        
        ; On convertit la liste dans le bon format
        For n = 0 To bm\bmHeight - 1
            For nn = 0 To bm\bmWidth - 1
                CopyMemory(Mem + nn * 4 + (bm\bmHeight - 1 - n) * bm\bmWidth * 4, HList + n * 4 + nn * bm\bmHeight * 4, 4)
            Next
        Next
        
        FreeMemory(Mem)
    EndIf
    
    ProcedureReturn Resultat
EndProcedure

Procedure.f Longueur(x1.f, y1.f, x2.f, y2.f)
    ProcedureReturn Sqr(Pow(x1 - x2, 2) + Pow(y1 - y2, 2))
EndProcedure

#Pi.f = 3.14159265

; Copie d'écran
Largeur_Ecran = GetSystemMetrics_(#SM_CXSCREEN)
Hauteur_Ecran = GetSystemMetrics_(#SM_CYSCREEN)

DC = GetDC_(0)
CreateImage(0, Largeur_Ecran, Hauteur_Ecran)
Dessin = StartDrawing(ImageOutput())
BitBlt_(Dessin, 0, 0, Largeur_Ecran, Hauteur_Ecran, DC, 0, 0, #SRCPAINT)
StopDrawing()
ReleaseDC_(0, DC)

OpenWindow(0, 0, 0, 100, 100, #WS_MAXIMIZE | #PB_Window_BorderLess, "Sphère")
SetWindowPos_(WindowID(), -1, 0, 0, 0, 0, #SWP_NOSIZE | #SWP_NOMOVE) ; Pour mettre la fenêtre toujours au premier plan
UpdateWindow_(WindowID())

; On copie l'image dans un Tableau
Dim Image.l(Largeur_Ecran - 1, Hauteur_Ecran - 1)
GetImageBits2(UseImage(0), @Image())

; On ouvre l'openscreen
If InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse() = 0
    MessageRequester("Erreur", "Impossible d'initialiser la souris ,le clavier ou l'écran. Vérifiez la présence de DirectX 7 ou supérieur.", 0)
    End
EndIf

If OpenScreen(Largeur_Ecran, Hauteur_Ecran, 32, "Sphère") = 0
    MessageRequester("Erreur", "Impossible d'ouvrir l'écran.", 0)
    End
EndIf

CreateSprite(1, Largeur_Ecran, Hauteur_Ecran)
StartDrawing(SpriteOutput(1))
DrawImage(UseImage(0), 0, 0)
StopDrawing()

Rayon = 25
Loupe.f = 0.5

Repeat
    ; On lit les évènements clavier et souris
    ExamineMouse()
    ExamineKeyboard()
    
    ; Position de la souris
    x = MouseX()
    y = MouseY()
    
    ; Agrandir ou réduire la sphère
    If KeyboardPushed(#PB_Key_Up) And Rayon < 100
        Rayon + 2
    ElseIf KeyboardPushed(#PB_Key_Down) And Rayon > 0
        Rayon - 2
    EndIf
    
    ; Augmenter ou diminuer l'effet de loupe
    If KeyboardPushed(#PB_Key_Right) And Loupe < 1
        Loupe + 0.05
    ElseIf KeyboardPushed(#PB_Key_Left) And Loupe > 0
        Loupe - 0.05
    EndIf
    
    ; On affiche l'image
    DisplaySprite(1, 0, 0)
    
    StartDrawing(ScreenOutput())
    ; Calcul du FPS
    cpt + 1
    If cpt = 10
        cpt = 0
        fps = 10000 / (ElapsedMilliseconds() - Temps)
        Temps = ElapsedMilliseconds()
    EndIf
    Locate(5, 5)
    DrawText(Str(fps))
    
    ; On édite l'image
    Memoire = DrawingBuffer()
    
   ; For n = -Rayon To Rayon
    n = -Rayon 
    While n<Rayon
    n+1
    
    
        If x + n > 0 And x + n < Largeur_Ecran - 1 ; Si on est sur l'image en x
            nn=-Rayon
            While nn <Rayon
                nn+1
                If y + nn > 0 And y + nn < Hauteur_Ecran - 1 ; Si on est sur l'image en y
                    Longueur.f = Longueur(x, y, x + n, y + nn) ; On calcul la distance d'un point de la sphère à partir du centre
                    If Longueur <= Rayon ; Si le pixel est situé dans le rayon du cercle
                        Longueur2.f = ASin(Longueur / Rayon * Loupe + (1 - Loupe)) * 2 / #Pi * Longueur ; on calcul la distance du point de l'image correspondant à celui de la sphère
                        If Longueur > 0
                            PosX.f = x + n * Longueur2 / Longueur
                            PosY.f = y + nn * Longueur2 / Longueur
                            
                            ; Avec lissage
                            PosX_Int = Int(PosX)
                            PosY_Int = Int(PosY)
                            Rouge.f = 0 : Vert.f = 0 : bleu.f = 0 : SommeFacteur.f = 0
                            
                            ;For i = PosX_Int - 1 To PosX_Int + 1
                            i = PosX_Int - 1 
                            While i< PosX_Int + 1
                                i+1
                                
                               ; For ii = PosY_Int - 1 To PosY_Int + 1
                                ii = PosY_Int - 1
                                While ii<PosY_Int + 1
                                    ii+1
                                    facteur.f = 1 - Longueur(i, ii, PosX, PosY)
                                    If facteur > 0
                                        Rouge = Rouge + Red(Image(i, ii)) * facteur
                                        Vert = Vert + Green(Image(i, ii)) * facteur
                                        bleu = bleu + Blue(Image(i, ii)) * facteur
                                        SommeFacteur = SommeFacteur + facteur
                                    EndIf
                               Wend
                            Wend
                            Couleur.l = RGB(Int(Rouge / SommeFacteur), Int(Vert / SommeFacteur), Int(bleu / SommeFacteur))
                            
                            ; Sans lissage
                            ; Couleur.l = Image(Int(PosX + 0.5), Int(PosY + 0.5))
                            
                        Else ; Cas particulier, le centre de la sphère
                            Couleur.l = Image(x, y)
                        EndIf
                        ; On affiche le pixel
                        Pixel_Memoire = Memoire + 4 * (x + n) + 4 * (y + nn) * Largeur_Ecran
                        PokeL(Pixel_Memoire, Couleur)
                    EndIf
                EndIf
            Wend
        EndIf
  Wend
    
    StopDrawing()
    
    FlipBuffers()
    
    If IsScreenActive() = 0
        End
    EndIf
    
Until KeyboardPushed(#PB_Key_Escape)
Dernière modification par Backup le sam. 09/oct./2004 22:34, modifié 2 fois.
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

c'est idiot de mettre un clearscreen() vu que je redessine l'image complètement à chaque tour de boucle.
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
garzul
Messages : 683
Inscription : mer. 26/mai/2004 0:33

Message par garzul »

Bah sa j'ai vus mais c'est prouver par ton compteur de fps que je gagne 1 de plus :D
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

c'est idiot de mettre un clearscreen() vu que je redessine l'image complètement à chaque tour de boucle.

et que pensez vous de ce que j'ai fait ?? 8O
garzul
Messages : 683
Inscription : mer. 26/mai/2004 0:33

Message par garzul »

:D Bah au niveau du code c'est bien mais au niveau de l'appli c'est toujour pareil sa tourne sur les 2 fsp avec mon clear screen je suis a 3 moi :D
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

a fond de taille de sphere je suis a 7 fps !!! 8O

et c'est nettement plus rapide avec mes while wend !!
garzul
Messages : 683
Inscription : mer. 26/mai/2004 0:33

Message par garzul »

Moi je suis a 3 fps ( oui mais oi ta une machine de puissance absolu :D ) en tout cas moi sa reste a 3 :(
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

maintenant je passe a 10 fps !

Code : Tout sélectionner

 ProcedureDLL.l GetImageBits2(ImageID, HList) ; Transfert d'une image vers un tableau
    Protected bmi.BITMAPINFO, hdc.l, Resultat, Mem, n, nn, bm.BITMAP
    
    Resultat = 0
    
    GetObject_(ImageID, SizeOf(BITMAP), @bm.BITMAP)
    
    bmi\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
    bmi\bmiHeader\biWidth = bm\bmWidth
    bmi\bmiHeader\biHeight = bm\bmHeight
    bmi\bmiHeader\biPlanes = 1
    bmi\bmiHeader\biBitCount = 32
    bmi\bmiHeader\biCompression = #BI_RGB
    aze=bm\bmWidth * bm\bmHeight * 4
    Mem = AllocateMemory(aze)
    If Mem
        
        hdc = CreateCompatibleDC_(GetDC_(ImageID))
        If hdc
            GetDIBits_(hdc, ImageID, 0, bm\bmHeight, Mem, @bmi, #DIB_RGB_COLORS) ; on envoie la liste dans l'image
            ReleaseDC_(0, hdc)
            Resultat = ImageID
        EndIf
        
        ; On convertit la liste dans le bon format
        n=0
       ; For n = 0 To bm\bmHeight - 1 
        ww2=bm\bmHeight - 1
        While n<ww2
            
            n+1 
            nn=0
            ;For nn = 0 To bm\bmWidth - 1
            ww=bm\bmWidth - 1
            While nn<ww
                nn+1
                zzz=Mem + nn * 4 + (bm\bmHeight - 1 - n) * bm\bmWidth * 4
                rrrr=HList + n * 4 + nn * bm\bmHeight * 4
                CopyMemory(zzz,rrrr, 4)
            Wend
       Wend
        
        FreeMemory(Mem)
    EndIf
    
    ProcedureReturn Resultat
EndProcedure

Procedure.f Longueur(x1.f, y1.f, x2.f, y2.f)
    ProcedureReturn Sqr(Pow(x1 - x2, 2) + Pow(y1 - y2, 2))
EndProcedure

#Pi.f = 3.14

; Copie d'écran
Largeur_Ecran = GetSystemMetrics_(#SM_CXSCREEN)
Hauteur_Ecran = GetSystemMetrics_(#SM_CYSCREEN)

DC = GetDC_(0)
CreateImage(0, Largeur_Ecran, Hauteur_Ecran)
Dessin = StartDrawing(ImageOutput())
BitBlt_(Dessin, 0, 0, Largeur_Ecran, Hauteur_Ecran, DC, 0, 0, #SRCPAINT)
StopDrawing()
ReleaseDC_(0, DC)

OpenWindow(0, 0, 0, 100, 100, #WS_MAXIMIZE | #PB_Window_BorderLess, "Sphère")
SetWindowPos_(WindowID(), -1, 0, 0, 0, 0, #SWP_NOSIZE | #SWP_NOMOVE) ; Pour mettre la fenêtre toujours au premier plan
UpdateWindow_(WindowID())

; On copie l'image dans un Tableau
Dim Image.l(Largeur_Ecran - 1, Hauteur_Ecran - 1)
GetImageBits2(UseImage(0), @Image())

; On ouvre l'openscreen
If InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse() = 0
    MessageRequester("Erreur", "Impossible d'initialiser la souris ,le clavier ou l'écran. Vérifiez la présence de DirectX 7 ou supérieur.", 0)
    End
EndIf

If OpenScreen(Largeur_Ecran, Hauteur_Ecran, 32, "Sphère") = 0
    MessageRequester("Erreur", "Impossible d'ouvrir l'écran.", 0)
    End
EndIf

CreateSprite(1, Largeur_Ecran, Hauteur_Ecran)
StartDrawing(SpriteOutput(1))
DrawImage(UseImage(0), 0, 0)
StopDrawing()

Rayon = 100
Loupe.f = 0.5

Repeat
    ; On lit les évènements clavier et souris
    ExamineMouse()
    ExamineKeyboard()
    
    ; Position de la souris
    x = MouseX()
    y = MouseY()
    
    ; Agrandir ou réduire la sphère
    If KeyboardPushed(#PB_Key_Up) And Rayon < 100
        Rayon + 2
    ElseIf KeyboardPushed(#PB_Key_Down) And Rayon > 0
        Rayon - 2
    EndIf
    
    ; Augmenter ou diminuer l'effet de loupe
    If KeyboardPushed(#PB_Key_Right) And Loupe < 1
        Loupe + 0.05
    ElseIf KeyboardPushed(#PB_Key_Left) And Loupe > 0
        Loupe - 0.05
    EndIf
    
    ; On affiche l'image
    DisplaySprite(1, 0, 0)
    
    StartDrawing(ScreenOutput())
    ; Calcul du FPS
    cpt + 1
    If cpt = 10
        cpt = 0
        fps = 10000 / (ElapsedMilliseconds() - Temps)
        Temps = ElapsedMilliseconds()
    EndIf
    Locate(5, 5)
    DrawText(Str(fps))
    
    ; On édite l'image
    Memoire = DrawingBuffer()
    
   ; For n = -Rayon To Rayon
    n = -Rayon 
    While n<Rayon
    n+1
    tt=x + n  
        If tt > 0 And tt < Largeur_Ecran - 1 ; Si on est sur l'image en x
            nn=-Rayon
            While nn <Rayon
                nn+1
                tt2=x + n : tt3=y + nn
                If tt3 > 0 And tt3 < Hauteur_Ecran - 1 ; Si on est sur l'image en y
                    Longueur.f = Longueur(x, y,tt2 , tt3) ; On calcul la distance d'un point de la sphère à partir du centre
                    If Longueur <= Rayon ; Si le pixel est situé dans le rayon du cercle
                        ppp.f=Longueur / Rayon * Loupe + (1 - Loupe)
                        ppp2.f=2 / #Pi * Longueur
                        
                        Longueur2.f = ASin(ppp.f) * ppp2 ; on calcul la distance du point de l'image correspondant à celui de la sphère
                        If Longueur > 0
                            aaaa.f=Longueur2 / Longueur :bbbbb.f=Longueur2 / Longueur
                            uuu=x + n * aaaa.f
                            uuu2=y + nn * bbbbb.f
                            PosX.f = uuu
                            PosY.f = uuu2
                            
                            ; Avec lissage
                            PosX_Int = Int(PosX)
                            PosY_Int = Int(PosY)
                            Rouge.f = 0 : Vert.f = 0 : bleu.f = 0 : SommeFacteur.f = 0
                            
                            ;For i = PosX_Int - 1 To PosX_Int + 1
                            i = PosX_Int - 1 
                            While i< PosX_Int + 1
                                i+1 
                               ; For ii = PosY_Int - 1 To PosY_Int + 1
                                ii = PosY_Int - 1
                                While ii<PosY_Int + 1
                                    ii+1
                                    facteur.f = 1 - Longueur(i, ii, PosX, PosY)
                                    If facteur > 0
                                        Rouge + Red(Image(i, ii)) * facteur
                                        Vert + Green(Image(i, ii)) * facteur
                                        bleu + Blue(Image(i, ii)) * facteur 
                                        SommeFacteur + facteur
                                    EndIf
                               Wend
                        Wend
                        yu=Rouge / SommeFacteur
                        yu1=Vert / SommeFacteur
                        yu2=bleu / SommeFacteur
                            Couleur.l = RGB(Int(yu), Int(yu1), Int(yu2))
                            
                            ; Sans lissage
                            ; Couleur.l = Image(Int(PosX + 0.5), Int(PosY + 0.5))
                            
                        Else ; Cas particulier, le centre de la sphère
                            Couleur.l = Image(x, y)
                        EndIf
                        ; On affiche le pixel
                        ooa=4 * (y + nn) * Largeur_Ecran
                        oo=4 * (x + n) + ooa 
                        Pixel_Memoire = Memoire + oo
                        PokeL(Pixel_Memoire, Couleur)
                    EndIf
                EndIf
            Wend
        EndIf
  Wend
    
    StopDrawing()
    
    FlipBuffers()
    
    If IsScreenActive() = 0
        End
    EndIf
    
Until KeyboardPushed(#PB_Key_Escape)
Répondre