Dessin de forme avec du lissage

Programmation d'applications complexes
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Dessin de forme avec du lissage

Message par Le Soldat Inconnu »

Alors je reviens sur ce sujet puisque j'ai eu une idée de génie il y a deux jours, j'ai trouvé comment tracé des lignes avec de l'Anti Aliasing
Jusque la, je n'y arrivais vraiment qu'avec les cercles

Donc, le truc pour gérer correctement le dessin de ligne avec du lissage et des lignes avec de l'épaisseur, c'est de faire un changement de repère.
Tellement simple, pourquoi je n'y est pas songé avant.
Le changement de repère me permet a partir d'une ligne qlqconque de la remettre à l'horizontal.
Donc sur sur l'axe Y, j'ai l'épaisseur de la ligne. ET après tout est plus facile non ?
Pas plus ? mais si mais si

Il faut ma librairie Effect, si vous ne l'avez pas, vous devez rajouter la procedure qui est mise après ce code

Code : Tout sélectionner

; Auteur : Le Soldat Inconnu
; Version de PB : 4.3
;
; Explication du programme :
; Dessin avec lissage

Procedure CircleAA(X, Y, Radius, Color, Thickness = 1, Mode = #PB_2DDrawing_Default)
  Protected n, nn, Distance.f, Application.f, Couleur_Fond.l
  If Mode & #PB_2DDrawing_Outlined ; Cercle vide
    ; on dessine 1/4 du cercle et on duplique pour le reste
    For n = 0 To Radius
      For nn = 0 To Radius
        Distance.f = Sqr(n * n + nn * nn)
        If Distance <= Radius And Distance > Radius - 1
          Application.f = Abs(Radius - 1 - Distance)
          Couleur_Fond = Point(X + n, Y + nn)
          Plot(X + n, Y + nn, ColorBlending(Couleur_Fond, Color, Application))
          Couleur_Fond = Point(X - n, Y + nn)
          Plot(X - n, Y + nn, ColorBlending(Couleur_Fond, Color, Application))
          Couleur_Fond = Point(X + n, Y - nn)
          Plot(X + n, Y - nn, ColorBlending(Couleur_Fond, Color, Application))
          Couleur_Fond = Point(X - n, Y - nn)
          Plot(X - n, Y - nn, ColorBlending(Couleur_Fond, Color, Application))
        ElseIf Distance <= Radius - Thickness And Distance > Radius - Thickness - 1
          Application.f = Abs(Radius - Thickness - Distance)
          Couleur_Fond = Point(X + n, Y + nn)
          Plot(X + n, Y + nn, ColorBlending(Couleur_Fond, Color, Application))
          Couleur_Fond = Point(X - n, Y + nn)
          Plot(X - n, Y + nn, ColorBlending(Couleur_Fond, Color, Application))
          Couleur_Fond = Point(X + n, Y - nn)
          Plot(X + n, Y - nn, ColorBlending(Couleur_Fond, Color, Application))
          Couleur_Fond = Point(X - n, Y - nn)
          Plot(X - n, Y - nn, ColorBlending(Couleur_Fond, Color, Application))
        ElseIf Distance <= Radius - 1 And Distance > Radius - Thickness
          Plot(X + n, Y + nn, Color)
          Plot(X - n, Y + nn, Color)
          Plot(X + n, Y - nn, Color)
          Plot(X - n, Y - nn, Color)
        EndIf
      Next
    Next
  Else ; Cercle plein
    ; on dessine 1/4 du cercle et on duplique pour le reste
    For n = 0 To Radius
      For nn = 0 To Radius
        Distance.f = Sqr(n * n + nn * nn)
        If Distance <= Radius And Distance > Radius - 1
          Application.f = 1 - (Radius - Distance)
          Couleur_Fond = Point(X + n, Y + nn)
          Plot(X + n, Y + nn, ColorBlending(Couleur_Fond, Color, Application))
          Couleur_Fond = Point(X - n, Y + nn)
          Plot(X - n, Y + nn, ColorBlending(Couleur_Fond, Color, Application))
          Couleur_Fond = Point(X + n, Y - nn)
          Plot(X + n, Y - nn, ColorBlending(Couleur_Fond, Color, Application))
          Couleur_Fond = Point(X - n, Y - nn)
          Plot(X - n, Y - nn, ColorBlending(Couleur_Fond, Color, Application))
        ElseIf Distance <= Radius - 1
          Plot(X + n, Y + nn, Color)
          Plot(X - n, Y + nn, Color)
          Plot(X + n, Y - nn, Color)
          Plot(X - n, Y - nn, Color)
        EndIf
      Next
    Next
  EndIf
EndProcedure

Procedure EllipseAA(X, Y, RadiusX, RadiusY, Color, Thickness = 1, Mode = #PB_2DDrawing_Default)
  Protected n, nn, Distance.f, Application.f, Couleur_Fond.l, Ellispse_Rayon.f, Ellipse_E.f
  ; Précacul de l'équation de l'ellipse
  If RadiusX > RadiusY
    Ellipse_E = Sqr(RadiusX * RadiusX - RadiusY * RadiusY) / RadiusX
  Else
    Ellipse_E = Sqr(RadiusY * RadiusY - RadiusX * RadiusX) / RadiusY
  EndIf
  Ellipse_E * Ellipse_E
  If Mode & #PB_2DDrawing_Outlined ; ellipse vide
    ; on dessine 1/4 de l'ellipse et on duplique pour le reste
    For n = 0 To RadiusX
      For nn = 0 To RadiusY 
        Distance.f = Sqr(n * n + nn * nn)
        If RadiusX > RadiusY
          If n
            Ellipse_CosAngle.f = n / Distance
            Ellispse_Rayon = Sqr(RadiusY * RadiusY / (1 - Ellipse_E * Ellipse_CosAngle * Ellipse_CosAngle))
          Else
            Ellispse_Rayon = RadiusY
          EndIf
        Else
          If nn
            Ellipse_CosAngle.f = nn / Distance
            Ellispse_Rayon = Sqr(RadiusX * RadiusX / (1 - Ellipse_E * Ellipse_CosAngle * Ellipse_CosAngle))
          Else
            Ellispse_Rayon = RadiusX
          EndIf
        EndIf
        If Distance <= Ellispse_Rayon And Distance > Ellispse_Rayon - 1
          Application.f = Abs(Ellispse_Rayon - 1 - Distance)
          Couleur_Fond = Point(X + n, Y + nn)
          Plot(X + n, Y + nn, ColorBlending(Couleur_Fond, Color, Application))
          Couleur_Fond = Point(X - n, Y + nn)
          Plot(X - n, Y + nn, ColorBlending(Couleur_Fond, Color, Application))
          Couleur_Fond = Point(X + n, Y - nn)
          Plot(X + n, Y - nn, ColorBlending(Couleur_Fond, Color, Application))
          Couleur_Fond = Point(X - n, Y - nn)
          Plot(X - n, Y - nn, ColorBlending(Couleur_Fond, Color, Application))
        ElseIf Distance <= Ellispse_Rayon - Thickness And Distance > Ellispse_Rayon - Thickness - 1
          Application.f = Abs(Ellispse_Rayon - Thickness - Distance)
          Couleur_Fond = Point(X + n, Y + nn)
          Plot(X + n, Y + nn, ColorBlending(Couleur_Fond, Color, Application))
          Couleur_Fond = Point(X - n, Y + nn)
          Plot(X - n, Y + nn, ColorBlending(Couleur_Fond, Color, Application))
          Couleur_Fond = Point(X + n, Y - nn)
          Plot(X + n, Y - nn, ColorBlending(Couleur_Fond, Color, Application))
          Couleur_Fond = Point(X - n, Y - nn)
          Plot(X - n, Y - nn, ColorBlending(Couleur_Fond, Color, Application))
        ElseIf Distance <= Ellispse_Rayon - 1 And Distance > Ellispse_Rayon - Thickness
          Plot(X + n, Y + nn, Color)
          Plot(X - n, Y + nn, Color)
          Plot(X + n, Y - nn, Color)
          Plot(X - n, Y - nn, Color)
        EndIf
      Next
    Next
  Else ; ellipse pleine
    ; on dessine 1/4 de l'ellipse et on duplique pour le reste
    For n = 0 To RadiusX
      For nn = 0 To RadiusY
        Distance.f = Sqr(n * n + nn * nn)
        If RadiusX > RadiusY
          If n
            Ellipse_CosAngle.f = n / Distance
            Ellispse_Rayon = Sqr(RadiusY * RadiusY / (1 - Ellipse_E * Ellipse_CosAngle * Ellipse_CosAngle))
          Else
            Ellispse_Rayon = RadiusY
          EndIf
        Else
          If nn
            Ellipse_CosAngle.f = nn / Distance
            Ellispse_Rayon = Sqr(RadiusX * RadiusX / (1 - Ellipse_E * Ellipse_CosAngle * Ellipse_CosAngle))
          Else
            Ellispse_Rayon = RadiusX
          EndIf
        EndIf
        If Distance <= Ellispse_Rayon And Distance > Ellispse_Rayon - 1
          Application.f = 1 - (Ellispse_Rayon - Distance)
          Couleur_Fond = Point(X + n, Y + nn)
          Plot(X + n, Y + nn, ColorBlending(Couleur_Fond, Color, Application))
          Couleur_Fond = Point(X - n, Y + nn)
          Plot(X - n, Y + nn, ColorBlending(Couleur_Fond, Color, Application))
          Couleur_Fond = Point(X + n, Y - nn)
          Plot(X + n, Y - nn, ColorBlending(Couleur_Fond, Color, Application))
          Couleur_Fond = Point(X - n, Y - nn)
          Plot(X - n, Y - nn, ColorBlending(Couleur_Fond, Color, Application))
        ElseIf Distance <= Ellispse_Rayon - 1
          Plot(X + n, Y + nn, Color)
          Plot(X - n, Y + nn, Color)
          Plot(X + n, Y - nn, Color)
          Plot(X - n, Y - nn, Color)
        EndIf
      Next
    Next
  EndIf
EndProcedure

Procedure LineAA(X, Y, Width, Hight, Color, Thickness = 1)
  Protected SensX, SensY, n, nn, Epaisseur.f, x2.f, y2.f, Couleur_Fond.l, Application.f, Distance.f
  ; On mets la droite toujours dans le même sens pour l'analyse
  ; La sauvegarde du sens permettra de dessiner la droite ensuite dans le bon sens
  If Width >= 0
    SensX = 1
  Else
    SensX = -1
    Width = - Width
  EndIf
  If Hight >= 0
    SensY = 1
  Else
    SensY = -1
    Hight = - Hight
  EndIf
  
  
  ; Demi épaisseur de la ligne
  Epaisseur.f = Thickness / 2
  
  ; calcul pour le changement de repère qui permet de connaitre l'épaisseur du trait et de gérer l'AA
  Distance.f = Sqr(Width * Width + Hight * Hight)
  CosAngle.f = Width / Distance
  SinAngle.f = -Sin(ACos(CosAngle))
  
  ; Dessin de la ligne
  For n = -Thickness To Width + Thickness
    For nn = -Thickness To Hight + Thickness
      
      ; changement de base
      ; les y représentent l'épaisseur de la ligne
      x2 = n * CosAngle - nn * SinAngle
      y2 = Abs(n * SinAngle + nn * CosAngle)
      
      If y2 <= Epaisseur + 0.5
        Application =  0.5 + Epaisseur - y2
        If Application > 1
          Application = 1
        EndIf
        If x2 > -1 And x2 < Distance + 1
          If x2 < 0
            Application * (1 + x2)
          ElseIf x2 > Distance
            Application * (1 - x2 + Distance)
          EndIf
        Else
          Application = 0
        EndIf
        If Application > 0
          If Application < 1
            Couleur_Fond = Point(X + n * SensX, Y + nn * SensY)
            Plot(X + n * SensX, Y + nn * SensY, ColorBlending(Color, Couleur_Fond, Application))
          Else
            Plot(X + n * SensX, Y + nn * SensY, Color)
          EndIf
        EndIf
      EndIf
      
    Next
  Next
  
EndProcedure


Procedure TriangleAA(x1, y1, x2, y2, x3, y3, Color, Thickness = 1, Mode = #PB_2DDrawing_Default)
  Protected Epaisseur.f, Zone_G, Zone_D, Zone_H, Zone_B, Couleur_Fond, Application.f
  Protected Width12.l, Hight12.l, Distance12.f, CosAngle12.f, SinAngle12.f, Sens12.l, y1_r2.f, Application1.f, Interieur1
  Protected Width23.l, Hight23.l, Distance23.f, CosAngle23.f, SinAngle23.f, Sens23.l, y2_r2.f, Application2.f, Interieur2
  Protected Width31.l, Hight31.l, Distance31.f, CosAngle31.f, SinAngle31.f, Sens31.l, y3_r2.f, Application3.f, Interieur3
  
  ; Demi épaisseur de la ligne
  Epaisseur.f = Thickness / 2
  
  ; calcul pour le changement de repère qui permet de connaitre l'épaisseur du trait et de gérer l'AA
  ; Pour la ligne 12
  ; Le point de départ du repère est le point x1, y1
  Width12.l = x2 - x1
  Hight12.l = y2 - y1
  Distance12.f = Sqr(Width12 * Width12 + Hight12 * Hight12)
  CosAngle12.f = Width12 / Distance12
  SinAngle12.f = Sin(ACos(CosAngle12))
  If Hight12 > 0
    SinAngle12 = -SinAngle12
  EndIf
  ; changement de base
  y3_r2 = (x3 - x1) * SinAngle12 + (y3 - y1) * CosAngle12
  ; on regarde de quel coté de la ligne se trouve le triangle en regardant la position du point 3
  If y3_r2 > 0
    Sens12 = 1
  Else
    Sens12 = -1
  EndIf
  ; Pour la ligne 23
  ; Le point de départ du repère est le point x2, y2
  Width23.l = x3 - x2
  Hight23.l = y3 - y2
  Distance23.f = Sqr(Width23 * Width23 + Hight23 * Hight23)
  CosAngle23.f = Width23 / Distance23
  SinAngle23.f = Sin(ACos(CosAngle23))
  If Hight23 > 0
    SinAngle23 = -SinAngle23
  EndIf
  ; changement de base
  y1_r2 = (x1 - x2) * SinAngle23 + (y1 - y2) * CosAngle23
  ; on regarde de quel coté de la ligne se trouve le triangle en regardant la position du point 3
  If y1_r2 > 0
    Sens23 = 1
  Else
    Sens23 = -1
  EndIf
  ; Pour la ligne 31
  ; Le point de départ du repère est le point x3, y3
  Width31.l = x1 - x3
  Hight31.l = y1 - y3
  Distance31.f = Sqr(Width31 * Width31 + Hight31 * Hight31)
  CosAngle31.f = Width31 / Distance31
  SinAngle31.f = Sin(ACos(CosAngle31))
  If Hight31 > 0
    SinAngle31 = -SinAngle31
  EndIf
  ; changement de base
  y2_r2 = (x2 - x3) * SinAngle31 + (y2 - y3) * CosAngle31
  ; on regarde de quel coté de la ligne se trouve le triangle en regardant la position du point 3
  If y2_r2 > 0
    Sens31 = 1
  Else
    Sens31 = -1
  EndIf
  
  ; Détermination de la zone de dessin
  Zone_G = x1
  Zone_D = x1
  Zone_B = y1
  Zone_H = y1
  If x2 < Zone_G
    Zone_G = x2
  EndIf
  If x3 < Zone_G
    Zone_G = x3
  EndIf
  If x2 > Zone_D
    Zone_D = x2
  EndIf
  If x3 > Zone_D
    Zone_D = x3
  EndIf
  If y2 < Zone_B
    Zone_B = y2
  EndIf
  If y3 < Zone_B
    Zone_B = y3
  EndIf
  If y2 > Zone_H
    Zone_H = y2
  EndIf
  If y3 > Zone_H
    Zone_H = y3
  EndIf
  Zone_B - Thickness
  Zone_H + Thickness
  Zone_G - Thickness
  Zone_D + Thickness
  
  ; Dessin du triangle
  If Mode & #PB_2DDrawing_Outlined ; Triangle vide
    For n = Zone_G To Zone_D
      For nn = Zone_B To Zone_H
        
        y1_r2 = (n - x1) * SinAngle12 + (nn - y1) * CosAngle12
        y1_r2 * Sens12
        If y1_r2 >= -0.5 - Epaisseur
          
          Application1.f = 0.5 + Epaisseur + y1_r2
          If Application1 > 1
            Application1 =  1 + 0.5 + Epaisseur - Application1
            If Application1 < 0
              Application1 = 0
            EndIf
            Interieur1 = 1
          Else
            Interieur1 = 0
          EndIf
          
          y2_r2 = (n - x2) * SinAngle23 + (nn - y2) * CosAngle23
          y2_r2 * Sens23
          If y2_r2 >= -0.5 - Epaisseur
            
            Application2.f = 0.5 + Epaisseur + y2_r2
            If Application2 > 1
              Application2 = 1 + 0.5 + Epaisseur - Application2
              If Application2 < 0
                Application2 = 0
              EndIf
              Interieur2 = 1
            Else 
              Interieur2 = 0
            EndIf
            
            y3_r2 = (n - x3) * SinAngle31 + (nn - y3) * CosAngle31
            y3_r2 * Sens31
            If y3_r2 >= -0.5 - Epaisseur
              
              Application3.f = 0.5 + Epaisseur + y3_r2
              If Application3 > 1
                Application3 = 1 + 0.5 + Epaisseur - Application3
                If Application3 < 0
                  Application3 = 0
                EndIf
                Interieur3 = 1
              Else
                Interieur3 = 0
              EndIf
              
              
              If Interieur1 And Interieur2 And Interieur3
                Application = Application1 + Application2 + Application3
              Else
                Application = 1
                If Interieur1 = 0
                  Application * Application1
                EndIf
                If Interieur2 = 0
                  Application * Application2
                EndIf
                If Interieur3 = 0
                  Application * Application3
                EndIf
              EndIf
              If Application > 0
                If Application < 1
                  Couleur_Fond = Point(n, nn)
                  Plot(n, nn, ColorBlending(Color, Couleur_Fond, Application))
                Else
                  Plot(n, nn, Color)
                EndIf
              EndIf
            
            EndIf
          EndIf
        EndIf
        
      Next
    Next
  Else ; Triangle plein
    For n = Zone_G To Zone_D
      For nn = Zone_B To Zone_H
        
        y1_r2 = (n - x1) * SinAngle12 + (nn - y1) * CosAngle12
        y1_r2 * Sens12
        If y1_r2 >= -0.5 - Epaisseur
          
          Application1.f = 0.5 + Epaisseur + y1_r2
          If Application1 > 1
            Application1 = 1
          EndIf
          
          y2_r2 = (n - x2) * SinAngle23 + (nn - y2) * CosAngle23
          y2_r2 * Sens23
          If y2_r2 >= -0.5 - Epaisseur
            
            Application2.f = 0.5 + Epaisseur + y2_r2
            If Application2 > 1
              Application2 = 1
            EndIf
            
            y3_r2 = (n - x3) * SinAngle31 + (nn - y3) * CosAngle31
            y3_r2 * Sens31
            If y3_r2 >= -0.5 - Epaisseur
              
              Application3.f = 0.5 + Epaisseur + y3_r2
              If Application3 > 1
                Application3 = 1
              EndIf
              
              Application = Application1 * Application2 * Application3
              If Application < 1
                Couleur_Fond = Point(n, nn)
                Plot(n, nn, ColorBlending(Color, Couleur_Fond, Application))
              Else
                Plot(n, nn, Color)
              EndIf
              
            EndIf
          EndIf
        EndIf
        
      Next
    Next
  EndIf
  
EndProcedure




;/ Test des fonctions de dessin avec Anti-Aliazing ( AA )
; Création de la fenêtre et de la GadgetList
If OpenWindow(0, 0, 0, 500, 500, "Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget) = 0 Or CreateGadgetList(WindowID(0)) = 0
  End
EndIf

CreateImage(0, 500, 500)
StartDrawing(ImageOutput(0))
  ; Un joli fond
  #Carreau = 25
  For n = 0 To 500 Step #Carreau
    For nn = 0 To 500 Step #Carreau
      If ((n + nn) / #Carreau) & %1 = %1
        Box(n, nn, #Carreau, #Carreau, $FFFFFF)
      Else
        Box(n, nn, #Carreau, #Carreau, $0000FF)
      EndIf
    Next
  Next
  
  ; Dessin de Cercle
  CircleAA(100, 100, 70, $000000)
  CircleAA(250, 100, 50, $000000, 1, #PB_2DDrawing_Outlined)
  CircleAA(250, 100, 70, $000000, 3, #PB_2DDrawing_Outlined)
  
  ; Dessin d'une ellipse
  EllipseAA(400, 100, 40, 60, $000000, 2, #PB_2DDrawing_Outlined)
  EllipseAA(400, 100, 50, 70, $000000, 1, #PB_2DDrawing_Outlined)
  EllipseAA(400, 100, 30, 20, $000000)
  
  
  
  ; Dessin de ligne
  For n = 0 To 150 Step 30
    LineAA(20, 200, 150, n, $000000)
  Next
  For n = 0 To 120 Step 30
    LineAA(20, 200, n, 150, $000000)
  Next
  Epaisseur = 2
  For n = 0 To 150 Step 30
    LineAA(200, 200, 150, n, $000000, Epaisseur)
    Epaisseur + 1
  Next
  Epaisseur = 2
  For n = 0 To 120 Step 30
    LineAA(200, 200, n, 150, $000000, Epaisseur)
    Epaisseur + 1
  Next
  
  ; dessin de triangles
  TriangleAA(420, 200, 480, 250, 370, 350, $000000)
  Epaisseur = 1
  For n = 0 To 30 Step 10
    TriangleAA(490 - n, 260 + n, 390 + n, 350, 460, 400 - n, $000000, Epaisseur, #PB_2DDrawing_Outlined)
    Epaisseur + 1
  Next
  
StopDrawing()

ImageGadget(0, 0, 0, 300, 300, ImageID(0))

Repeat
  Event = WaitWindowEvent()
  
  Select Event
    Case #PB_Event_Menu
      Select EventMenu() ; Menus
          
      EndSelect
      
    Case #PB_Event_Gadget
      Select EventGadget() ; Gadgets
          
      EndSelect
  EndSelect
  
Until Event = #PB_Event_CloseWindow

End

Code : Tout sélectionner

ProcedureDLL.l ColorBlending(Couleur1.l, Couleur2.l, Echelle.f) ; Mélanger 2 couleurs
  Protected Rouge, Vert, Bleu, Rouge2, Vert2, Bleu2
  
  Rouge = Couleur1 & $FF
  Vert = Couleur1 >> 8 & $FF
  Bleu = Couleur1 >> 16
  Rouge2 = Couleur2 & $FF
  Vert2 = Couleur2 >> 8 & $FF
  Bleu2 = Couleur2 >> 16
  
  Rouge = Rouge * Echelle + Rouge2 * (1-Echelle)
  Vert = Vert * Echelle + Vert2 * (1-Echelle)
  Bleu = Bleu * Echelle + Bleu2 * (1-Echelle)
  
  ProcedureReturn (Rouge | Vert <<8 | Bleu << 16)
EndProcedure


---------------------------------------
Ancien messsage :
Voila, c'est galère ce truc a faire

Donc j'ai réussi a faire des cercles avec du lissage (cercle plein ou détouré)

Mais pour faire des lignes, je cale pour le moment, c'est pas vraiment évident.

Voila ou j'en suis :

Il faut ma librairie Effect pour le traitement des couleurs
Voir mon site

Code : Tout sélectionner

 Code retiré, voir nouvelle version plus haut 
Si vous avez des idées pour les lignes, hésitez pas
Dernière modification par Le Soldat Inconnu le mar. 10/févr./2009 10:25, modifié 4 fois.
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)]
beauregard
Messages : 1307
Inscription : dim. 08/juil./2007 18:32
Localisation : Toulouse

Re: Dessin de forme avec du lissage

Message par beauregard »

heu..., mon pb n'apprécie pas ColorBlending
Anonyme

Message par Anonyme »

Image

Pour le lissage , tu fait une moyenne des pixels voisins , tu dois être au courant , je ne vais pas te faire un cour la dessus :D
Mais je t'ai quand même fait un joli schéma :D

tu peut t'appuyer sur l'algo de bresham pour le tracage de ligne :

Code : Tout sélectionner

; Procedure de tracage de ligne optimisé
Procedure lineXY2(x1.f,y1.f,x2.f,y2.f,Couleur.l)
  Shared dx.f,dy.f,xincr.l,yincr.l,x.l,y.l,erreur.f
 
  If x1<>0 And y1<>0 And x2<>0 And y2<>0
   
    ;/* On initialise nos variables */
    dx = Abs(x2-x1)
    dy = Abs(y2-y1)
   
    If x1<x2
      xincr = 1
    Else
      xincr = -1
    EndIf
   
    If y1<y2
      yincr = 1
    Else
      yincr = -1
    EndIf
   
   
    ;/* Trace de ligne */
   
    x = x1
    y = y1
   
    If dx>dy
     
      erreur = dx/2  ; /* c'est plus esthetique comme ca */
      For i= 0 To dx
       
        x = x+xincr;
        erreur = erreur+dy
        If erreur > dx
         
          erreur = erreur - dx
          y = y+yincr
        EndIf
        If x>0 And x<800-1 And y>0 And y<600-1
          Plot(x,y,Couleur)
        EndIf
      Next i
     
    Else
      erreur = dy/2;     /* c'est plus esthetique comme ca */
      For i=0 To dy
        y = y + yincr
        erreur = erreur + dx
        If erreur>dy
          erreur = erreur - dy
          x = x + xincr
        EndIf
        If x>0 And x<800-1 And y>0 And y<600-1
          Plot(x,y,Couleur)
        EndIf
      Next i
    EndIf
  EndIf   
EndProcedure 
Tu devras modifier cette procédure , l'utilisation du buffer vidéo est indispensable pour connaitre la couleur de fond & de faire le mélange adéquate.

@++
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Message par djes »

On avait déjà fait ça, non? Sinon j'ai retrouvé ça sur le forum anglais (et sur codearchiv) : http://www.purebasic.fr/english/viewtopic.php?t=13198
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

Mise a jour du code, voir premier message

Donc j'arrive a dessiner avec du lissage (anti aliazing) :
- des lignes
- des cercles
- des ellipses

Je vais essayer de faire des triangles maintenant.

Et une fois que le triangle sera fait, on pourra dessiner tous les polygones possible et imaginable.
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)]
Anonyme

Message par Anonyme »

Pour les deux dernier dessins ( les lignes sur différent angle ) ont croiraient que la deuxième ligne en partant du haut n'est AA , pourtant si , on voit bien l'effet d'escalier. l'algo n'est pas adapté pour ce genre de ligne ( Bounding box plus large que haute d'au moins 3x )
As tu regardé du coté de l'over-sampling pour voir ce que cela donne ?
Pour les triangles , essaye de pondre un jolie code de rastérization avec dégradé :D
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

ben pour les lignes, ca donne le même résultat que photoshop.
Alors si photoshop fais pas meiux, je vois pas trop comment amélioré
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)]
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

nouvelle version

j'ai corrigé une erreur pour les lignes

et j'arrive a faire des triangles :D

qui qui a besoin de faire de jolies flèches dans ces programmes ? :roll:

Donc après, en assemblant plusieurs triangles, on peut faire des losanges, parallélogrammes, étoiles, et autres polygones
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)]
Anonyme

Message par Anonyme »

Le Soldat Inconnu a écrit :nouvelle version

j'ai corrigé une erreur pour les lignes

et j'arrive a faire des triangles :D

qui qui a besoin de faire de jolies flèches dans ces programmes ? :roll:

Donc après, en assemblant plusieurs triangles, on peut faire des losanges, parallélogrammes, étoiles, et autres polygones

Sympathique tes codes , j'vais encore t'embêter avec les dégradé :D
pour les lignes ? et pour les Triangles ? toujours utile se genre de fonction pour faire des petits rendu simples pour la 3D et simulé la lumière :D !
Ollivier
Messages : 4190
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Message par Ollivier »

Je me permets de faire une petite incursion dans ce sujet supra-intéressant pour afficher des trucs au poil.

Voilà, je crois que j'ai une méthode moins parfaite que celle de LSI que je suis en train d'étudier. Mon but est de remplacer toutes les procédures entre les commentaires de la zone TEMPORAIRE (6 procédures) par l'instruction DrawAlphaImage().

Je poste un premier code, parce que le suivant risque d'être peut-être une usine à gaz...

Code : Tout sélectionner

Structure WHD
   W.L
   H.L
   D.L
EndStructure

Structure IntXY
   X.L
   Y.L
EndStructure

   Global dx.L
   Global dy.L
   Global CDir.F
   Global CDirE.L
   Global BrutFact.L
   Global Rest.L
   
   Global AxeY.L

   Define Dtop.WHD
   Global VLevel.L
   Global PixMax.IntXY
   Global SmoothMode.L
   With Dtop
      InitSprite()
      InitKeyboard()
      InitMouse()
      ExamineDesktops()
      \W = DesktopWidth(0)
      \H = DesktopHeight(0)
      \D = DesktopDepth(0)
      OpenScreen(\W, \H, \D, "")
      VLevel = 5
      PixMax\X = (\W / VLevel) - 1
      PixMax\Y = (\H / VLevel) - 1
      Global Dim Pix(PixMax\X, PixMax\Y)
   EndWith
   
Procedure Rect(x.L, y.L, dx.L, dy.L, c.L)
   Line(x, y, dx, 0, c)
   Line(x, y, 0, dy, c)
   Line(x + dx, y, 0, dy, c)
   Line(x, y + dy, dx, 0, c)
EndProcedure
   
Procedure DispPix()
   Protected x.L
   Protected y.L
   For y = 0 To PixMax\Y
      For x = 0 To PixMax\X
         Box(x * VLevel, y * VLevel, VLevel, VLevel, Pix(x, y) )
      Next
   Next
EndProcedure
   
Procedure DispNorm(ex.L, ey.L)
   Protected x.L
   Protected y.L
   Rect(ex - 1, ey - 1, PixMax\X + 2, PixMax\Y + 2, #White)
   For y = 0 To PixMax\Y
      For x = 0 To PixMax\X
         Plot(ex + x, ey + y, Pix(x, y) )
      Next
   Next
EndProcedure
   
Procedure PixRandom()
   Protected x.L
   Protected y.L
   For y = 0 To PixMax\Y
      For x = 0 To PixMax\X
         Pix(x, y) = Random($FFFFFF)
      Next
   Next
EndProcedure
   
Procedure PixZero()
   Protected x.L
   Protected y.L
   For y = 0 To PixMax\Y
      For x = 0 To PixMax\X
         Pix(x, y) = 0
      Next
   Next
EndProcedure
;-   
Procedure SetPix(x.L, y.L, c.L)
   If (x => 0) And (x <= PixMax\X)
      If (y => 0) And (y <= PixMax\Y)
         Pix(x, y) = c
      EndIf
   EndIf
EndProcedure
;- *******************
;- TEMPORAIRE
Procedure SetHPix_(x1.L, y.L, x2.L, c.L)
   Protected i.L
   For i = x1 To x2
      SetPix(i, y, c)
   Next
EndProcedure

Procedure SetVPix_(x.L, y1.L, y2.L, c.L)
   Protected i.L
   For i = y1 To y2
      SetPix(x, i, c)
   Next
EndProcedure

Procedure SetHPix(x1.L, y.L, x2.L, c.L)
   Protected i.L
   Protected c0.F
   Protected c1.F
   Protected Diff.F
   If x2 = x1
      Diff = RGB(128, 128, 128) ; Ici, Diff est une couleur
      Rect((x1 - 1) * VLevel, (y - 1) * VLevel, ((x2 - x1) + 1) * VLevel, 2 * VLevel, #Blue)
      SetPix(x1, y, c)
      SetPix(x1 - 1, y, Diff)
      SetPix(x1, y - 1, Diff)
   Else
      Rect(x1 * VLevel, (y - 1) * VLevel, ((x2 - x1) + 1) * VLevel, 2 * VLevel, #Blue)
      Diff = 255.0 / (x2 - x1 + 1)
      For i = x1 To x2
         c0 = c0 + Diff
         c1 = 255.0 - c0
         SetPix(i, y - 1, RGB(c1, c1, c1) )
         SetPix(i, y, RGB(c0, c0, c0) )
      Next
   EndIf
EndProcedure

Procedure SetVPix(x.L, y1.L, y2.L, c.L)
   Protected i.L
   Protected c0.F
   Protected c1.F
   Protected Diff.F
   If y2 = y1
      Diff = RGB(128, 128, 128) ; Ici, Diff est une couleur
      Rect((x - 1) * VLevel, y1 * VLevel, 2 * VLevel, ((y2 - y1) + 1) * VLevel, #Blue)
      SetPix(x, y1, c)
      SetPix(x, y1 - 1, Diff)
      SetPix(x - 1, y1, Diff)
   Else
      Rect((x - 1) * VLevel, y1 * VLevel, 2 * VLevel, ((y2 - y1) + 1) * VLevel, #Blue)
      Diff = 255.0 / (y2 - y1 + 1)
      For i = y1 To y2
         c0 = c0 + Diff
         c1 = 255.0 - c0
         SetPix(x - 1, i, RGB(c1, c1, c1) )
         SetPix(x, i, RGB(c0, c0, c0) )
      Next
   EndIf
EndProcedure

Procedure SetH2Pix(x1.L, y.L, x2.L, c.L)
   Protected i.L
   Protected c0.F
   Protected c1.F
   Protected Diff.F
   If x2 = x1
      Rect((x1 - 1) * VLevel, (y - 1) * VLevel, ((x2 - x1) + 1) * VLevel, 2 * VLevel, #Blue)
      Diff = RGB(128, 128, 128) ; Ici, Diff est une couleur
      SetPix(x1, y - 1, c)
      SetPix(x1 - 1, y - 1, Diff)
      SetPix(x1, y, Diff)
   Else
      Rect(x1 * VLevel, (y - 1) * VLevel, ((x2 - x1) + 1) * VLevel, 2 * VLevel, #Blue)
      Diff = 255.0 / (x2 - x1 + 1)
      For i = x1 To x2
         c0 = c0 + Diff
         c1 = 255.0 - c0
         SetPix(i, y, RGB(c1, c1, c1) )
         SetPix(i, y - 1, RGB(c0, c0, c0) )
      Next
   EndIf
EndProcedure

Procedure SetV2Pix(x.L, y1.L, y2.L, c.L)
   Protected i.L
   Protected c0.F
   Protected c1.F
   Protected Diff.F
   If y2 = y1
      Rect((x - 1) * VLevel, y1 * VLevel, 2 * VLevel, ((y2 - y1) + 1) * VLevel, #Blue)
      Diff = RGB(128, 128, 128) ; Ici, Diff est une couleur
      SetPix(x - 1, y1, c)
      SetPix(x, y1, Diff)
      SetPix(x - 1, y1 - 1, Diff)
   Else
      Rect((x - 1) * VLevel, y1 * VLevel, 2 * VLevel, ((y2 - y1) + 1) * VLevel, #Blue)
      Diff = 255.0 / (y2 - y1 + 1)
      For i = y1 To y2
         c0 = c0 + Diff
         c1 = 255.0 - c0
         SetPix(x, i, RGB(c1, c1, c1) )
         SetPix(x - 1, i, RGB(c0, c0, c0) )
      Next
   EndIf
EndProcedure


;- *******************
Procedure SetHLine(x1.L, y.L, x2.L, c.L)
   If SmoothMode
      SetHPix(x1.L, y.L, x2.L, c.L)
   Else
      SetHPix_(x1.L, y.L, x2.L, c.L)
   EndIf
EndProcedure

Procedure SetVLine(x.L, y1.L, y2.L, c.L)
   If SmoothMode
      SetVPix(x.L, y1.L, y2.L, c.L)
   Else
      SetVPix_(x.L, y1.L, y2.L, c.L)
   EndIf
EndProcedure

Procedure SetH2Line(x1.L, y.L, x2.L, c.L)
   If SmoothMode
      SetH2Pix(x1.L, y.L, x2.L, c.L)
   Else
      SetHPix_(x1.L, y.L, x2.L, c.L)
   EndIf
EndProcedure

Procedure SetV2Line(x.L, y1.L, y2.L, c.L)
   If SmoothMode
      SetV2Pix(x.L, y1.L, y2.L, c.L)
   Else
      SetVPix_(x.L, y1.L, y2.L, c.L)
   EndIf
EndProcedure
;-
Procedure SetLine(x1.L, y1.L, x2.L, y2.L)
   Protected c.L
   Protected i.L
   Protected xF.F
   Protected yF.F
   c = #White
   dx = (x2 - x1)
   dy = (y2 - y1)
   If (dx < 0)
      Swap x1, x2
      dx = - dx
      Swap y1, y2
      dy = - dy
   EndIf
   If dx = 0
      If dy > 0
         SetVPix_(x1, y1, y2, c)
      Else
         SetVPix_(x1, y2, y1, c)
      EndIf
   Else
      If dx > 0
         If dy = 0
            SetHPix_(x1, y1, x2, c)
         Else
            If dy > 0
               If dx > dy
                  ;x1 + 1
                  If dx * 2 > dy
                     y1 + 1
                  EndIf
                  CDir = dx / dy
                  xF = x1
                  NewX = xF - 1
                  For i = y1 To y2
                    OldX = NewX + 1
                    xF + CDir
                    NewX = xF - 1
                    SetHLine(OldX, i, NewX, c) 
                  Next i
               Else
                  If dx = dy
                     For i = 0 To dy
                        SetHLine(x1 + i, y1 + i, x1 + i, c) 
                     Next i
                  Else
                     x1 + 1
                     CDir = dy / dx
                     yF = y1
                     NewY = yF - 1
                     For i = x1 To x2
                        OldY = NewY + 1
                        yF + CDir
                        NewY = yF - 1
                        SetVLine(i, OldY, NewY, c) 
                     Next i
                  EndIf
               EndIf
            Else   
               Swap y1, y2
               dy = -dy
               AxeY = y2
               If dx => dy
                  If dx * 2 > dy
                     y1 + 1
                  EndIf
                  CDir = dx / dy
                  xF = x1
                  NewX = xF - 1
                  For i = y1 To y2
                    OldX = NewX + 1
                    xF + CDir
                    NewX = xF - 1
                    SetH2Line(OldX, (y2 + y1) - i, NewX, c) 
                  Next i
               Else
                  x1 + 1
                  CDir = dy / dx
                  yF = y1
                  NewY = yF - 1
                  For i = x1 To x2
                     OldY = NewY + 1
                     yF + CDir
                     NewY = yF - 1
                     SetV2Line((x2 + x1) - i, OldY, NewY, c) 
                  Next i
               EndIf   
            EndIf
         EndIf
      EndIf
   EndIf
EndProcedure
   
Procedure Mark(x.L, y.L, c.L)
   Protected n.L
   n = 4
   SetPix(x - n, y, c)
   SetPix(x + n, y, c)
   SetPix(x, y - n, c)
   SetPix(x, y + n, c)
EndProcedure
   
   Define x1.L
   Define y1.L
   Define x2.L
   Define y2.L
   
   x1 = PixMax\X / 2
   y1 = PixMax\Y / 2
   x2 = 120
   y2 = 60
   
   Repeat
      Output = ScreenOutput()
      If Output
         StartDrawing(Output)
   
      ExamineKeyboard()
      ExamineMouse()
      If MouseDeltaX() Or MouseDeltaY() 
         x2 = MouseX() / VLevel
         y2 = MouseY() / VLevel
      Else
         If KeyboardPushed(#PB_Key_Up): y2 - 1: EndIf
         If KeyboardPushed(#PB_Key_Down): y2 + 1: EndIf
         If KeyboardPushed(#PB_Key_Left): x2 - 1: EndIf
         If KeyboardPushed(#PB_Key_Right): x2 + 1: EndIf         
         If KeyboardReleased(#PB_Key_Space): SmoothMode ! 1: EndIf
      EndIf
            DispPix()
      PixZero()
      SetLine(x1, y1, x2, y2)
      Mark(x1, y1, #White)
      Mark(x2, y2, #White)
            DispNorm(100, 200)
            DrawText(0, 0, "[ESPACE] : Avec/Sans lissage")
         StopDrawing()
      EndIf
      FlipBuffers()
      Delay(25)
      
   Until KeyboardPushed(#PB_Key_Escape)
Ollivier
Messages : 4190
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Message par Ollivier »

Et le code suivant est une usine à gaz qui m'a pété inutilement à la tronche. Donc, bravo LSI: pas mieux!
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

:mrgreen:

reste plus qu'a optimiser mon bazar à coup d'ASM alors
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)]
Ollivier
Messages : 4190
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Message par Ollivier »

Euh... Attends là: faut déjà que je comprenne le schmilibilick...
:?
Ollivier
Messages : 4190
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Message par Ollivier »

@LSI

Est-ce qu'on ne pourrait pas utiliser les sprites 3D? Il ne resterait plus qu'à augmenter la vitesse de transfert, ce qui ne doit pas être très compliqué...

Code : Tout sélectionner

Structure LW ; Cf Procédures >> Alphablending >> Layered Window

    WindowID.L                  ; Handle du DC de la fenêtre translucide (WindowID)
    *ptWnd                      ;#Pointe vers une structure POINT (Position de la fenêtre, 0 = inchangée)
    *szWnd                      ;#Pointe vers une structure SIZE (Taille de la fenêtre, 0 = inchangée)
    hdcAIm.L                    ; Handle du DC source (Image Alpha)
    *ptAIm                      ;#Pointe vers une structure POINT
    crKey.L                     ; Couleur clé (transparence)
    *Blend                      ;#Pointe vers la structure BLENDFUNCTION (fBlend plus bas)
    *AImArea                    ;#Pointe vers 1 struc RECT spécifiant la zone à copier depuis le DC source
    X.L                         ; Coordonnées X de la fenêtre
    Y.L                         ; Coordonnées Y de la fenêtre
    W.L                         ; Largeur de la fenêtre
    H.L                         ; Hauteur de la fenêtre
    XA.L                        ; Coordonnées X dans l'image
    YA.L                        ; Coordonnées Y dans l'image
    fBlend.L                    ; Fonction Blend (toujours $01FF0000)
    X1.L                        ; Vista
    Y1.L                        ; Vista
    X2.L                        ; Vista
    Y2.L                        ; Vista
    Window.L                    ; n° de fenêtre
    ImageID.L                   ; ID de l'image
   
    VX.F
    VY.F
    AA.F
    V.F
    Flip.L
   
EndStructure


Procedure LayeredWindow(Window.L, Stat.L)

    Protected NewFlag.L = GetWindowLong_(WindowID(Window), #GWL_EXSTYLE) | (#WS_EX_LAYERED * Stat)
   
    SetWindowLong_(WindowID(Window), #GWL_EXSTYLE, NewFlag) 

EndProcedure


Procedure OpenLW(*LW.LW, X, Y, ImageID)

    Protected Bmp.BITMAP
    Protected PosiSrc.POINT
 
    With *LW
        \ImageID = ImageID
        GetObject_(\ImageID, SizeOf(BITMAP), @Bmp)
        \W = Bmp\BmWidth
        \H = Bmp\BmHeight
        \Window = OpenWindow(-1, X, Y, W, H, "", $90000000)
        \WindowID = WindowID(\Window) 
        If \Window
            StickyWindow(\Window, 1)
            LayeredWindow(\Window, 1)
            \hdcAIm = CreateCompatibleDC_(StartDrawing(WindowOutput(\Window) ) )
                SelectObject_(\hdcAIm, \ImageID)     
                Blend.L = $1FF0000
                Result.L = UpdateLayeredWindow_(\WindowID, 0, 0, @\W, \HdcAIm, PosiSrc, 0, @Blend, 2)
            StopDrawing()
            DeleteDC_(\hdcAIm)
            HideWindow(\Window, 0)
        EndIf     
        If Result = 0: CloseWindow(\Window): EndIf
    EndWith
       
    ProcedureReturn Result

EndProcedure

InitSprite()
InitSprite3D()
InitKeyboard()
OpenWindow(0, 0, 0, 1024, 768, "", $90000000)
OpenWindowedScreen(WindowID(0), 0, 0, 1024, 768, 0, 0, 0)
CreateSprite(0, 4, 4, #PB_Sprite_Texture)
StartDrawing(SpriteOutput(0) )
;Box(0, 1, 1, 2, #Blue)
;Box(1, 1, 2, 2, #White)
;Box(3, 1, 1, 2, #Red)
Box(0, 1, 2, 2, #White)
Box(2, 1, 2, 2, #Blue)
StopDrawing()
CreateSprite3D(0, 0)
Sprite3DQuality(1)
Distance.F = 256.0
Thickness.F = 8.0
;Repeat
   Delay(1)
   ClearScreen(0)
   If Start3D()
      Sprite3DBlendingMode(3, 9)
      Angle.F = 0
      For A = 0 To 360 Step 20
      
         cx.F = 256
         cy.F = 256

         Angle = A * #PI / 180.0 + AngleR.F
      
         ix.F = Cos(Angle)
         iy.F = Sin(Angle)
         jx.F = Cos(Angle + #PI / 2.0)
         jy.F = Sin(Angle + #PI / 2.0) 

         ex1.F = 0.0
         ey1.F = 0.0 - Thickness
         ex2.F = Distance
         ey2.F = 0.0 - Thickness
         ex3.F = Distance
         ey3.F = Thickness
         ex4.F = 0.0
         ey4.F = Thickness
      
         gx1.F = ex1 * ix + ey1 * iy
         gy1.F = ex1 * jx + ey1 * jy
         gx2.F = ex2 * ix + ey2 * iy
         gy2.F = ex2 * jx + ey2 * jy
         gx3.F = ex3 * ix + ey3 * iy
         gy3.F = ex3 * jx + ey3 * jy
         gx4.F = ex4 * ix + ey4 * iy
         gy4.F = ex4 * jx + ey4 * jy
         DisplaySprite3D(0, 0, 0)
         TransformSprite3D(0, cx+gx1, cy+gy1, cx+gx2, cy+gy2, cx+gx3, cy+gy3, cx+gx4, cy+gy4)      
      Next
      Stop3D()
   EndIf
   ExamineKeyboard()
   If KeyboardPushed(#PB_Key_Left): AngleR = (AngleR + 0.005): EndIf
   If KeyboardPushed(#PB_Key_Right): AngleR = (AngleR - 0.005): EndIf
   FlipBuffers()
   *X = AllocateMemory(1024 * 768 * 4 + 8)
   PokeL(*X, 1024)
   PokeL(*X + 4, 768)
   If StartDrawing(ScreenOutput())
      Buffer      = DrawingBuffer()             ; Get the start address of the screen buffer
      Pitch       = DrawingBufferPitch()        ; Get the length (in byte) took by one horizontal line
      PixelFormat = DrawingBufferPixelFormat()  ; Get the pixel format. 
   *Ecran = Buffer
   *Start = *X + 8
   For Y = 0 To 767
      For X = 0 To 1023
         C0 = Point(X, Y)
         Max = 0
         Rouge = Red(C0)
         If Max < Rouge: Max = Rouge: EndIf
         Vert = Green(C0)
         If Max < Vert: Max = Vert: EndIf
         Bleu = Blue(C0)
         If Max < Bleu: Max = Bleu: EndIf
         C = Max << 24 | RGB(Rouge, Vert, Bleu)
         PokeL(*X + 8 + 4 * (1024 * Y + X), C)
      Next X
   Next Y
      StopDrawing()
   EndIf
   AlphaImage.L = CreateBitmap_(1024, 768, 1, 32, *X + 8)
;   OpenWindow(10, 100, 100, 512, 512, "Lissage", $CF0001)
   ULW.LW
   OpenLW(ULW, 100, 100, AlphaImage)
   ;ImageGadget(0, 0, 0, 1024, 768, AlphaImage)
;   HideWindow(0, 1)
   ;Repeat
   ;   Delay(1)
   ;Until WindowEvent() = 16
   Delay(8000)
;Until KeyboardPushed(#PB_Key_Escape)
CloseScreen()
CloseWindow(0)
End
Ollivier
Messages : 4190
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Message par Ollivier »

Hop... Version plus rapide! La technique fonctionne aussi sous Linux, mais là ce n'est pas encore possible dans ce code précisément... Il faut que je m'y attarde un peu.

Ollivier

Code : Tout sélectionner

DisableDebugger
Structure LW ; Cf Procédures >> Alphablending >> Layered Window

    WindowID.L                  ; Handle du DC de la fenêtre translucide (WindowID)
    *ptWnd                      ;#Pointe vers une structure POINT (Position de la fenêtre, 0 = inchangée)
    *szWnd                      ;#Pointe vers une structure SIZE (Taille de la fenêtre, 0 = inchangée)
    hdcAIm.L                    ; Handle du DC source (Image Alpha)
    *ptAIm                      ;#Pointe vers une structure POINT
    crKey.L                     ; Couleur clé (transparence)
    *Blend                      ;#Pointe vers la structure BLENDFUNCTION (fBlend plus bas)
    *AImArea                    ;#Pointe vers 1 struc RECT spécifiant la zone à copier depuis le DC source
    X.L                         ; Coordonnées X de la fenêtre
    Y.L                         ; Coordonnées Y de la fenêtre
    W.L                         ; Largeur de la fenêtre
    H.L                         ; Hauteur de la fenêtre
    XA.L                        ; Coordonnées X dans l'image
    YA.L                        ; Coordonnées Y dans l'image
    fBlend.L                    ; Fonction Blend (toujours $01FF0000)
    X1.L                        ; Vista
    Y1.L                        ; Vista
    X2.L                        ; Vista
    Y2.L                        ; Vista
    Window.L                    ; n° de fenêtre
    ImageID.L                   ; ID de l'image
   
    VX.F
    VY.F
    AA.F
    V.F
    Flip.L
   
EndStructure


Procedure LayeredWindow(Window.L, Stat.L)

    Protected NewFlag.L = GetWindowLong_(WindowID(Window), #GWL_EXSTYLE) | (#WS_EX_LAYERED * Stat)
   
    SetWindowLong_(WindowID(Window), #GWL_EXSTYLE, NewFlag) 

EndProcedure


Procedure OpenLW(*LW.LW, X, Y, ImageID)

    Protected Bmp.BITMAP
    Protected PosiSrc.POINT
 
    With *LW
        \ImageID = ImageID
        GetObject_(\ImageID, SizeOf(BITMAP), @Bmp)
        \W = Bmp\BmWidth
        \H = Bmp\BmHeight
        \Window = OpenWindow(-1, X, Y, W, H, "", $90000000)
        \WindowID = WindowID(\Window) 
        If \Window
            StickyWindow(\Window, 1)
            LayeredWindow(\Window, 1)
            \hdcAIm = CreateCompatibleDC_(StartDrawing(WindowOutput(\Window) ) )
                SelectObject_(\hdcAIm, \ImageID)     
                Blend.L = $1FF0000
                Result.L = UpdateLayeredWindow_(\WindowID, 0, 0, @\W, \HdcAIm, PosiSrc, 0, @Blend, 2)
            StopDrawing()
            DeleteDC_(\hdcAIm)
            HideWindow(\Window, 0)
        EndIf     
        If Result = 0: CloseWindow(\Window): EndIf
    EndWith
       
    ProcedureReturn Result

EndProcedure

InitSprite()
InitSprite3D()
InitKeyboard()
OpenWindow(0, 0, 0, 1024, 768, "", $90000000)
OpenWindowedScreen(WindowID(0), 0, 0, 1024, 768, 0, 0, 0)
CreateSprite(0, 4, 4, #PB_Sprite_Texture)
StartDrawing(SpriteOutput(0) )
Box(0, 1, 2, 2, #White)
Box(2, 1, 2, 2, #Blue)
StopDrawing()
CreateSprite3D(0, 0)
Sprite3DQuality(1)
Distance.F = 256.0
Thickness.F = 8.0
;Repeat
   Delay(1)
   ClearScreen(0)
   If Start3D()
      Sprite3DBlendingMode(3, 9)
      Angle.F = 0
      For A = 0 To 360 Step 10
      
         cx.F = 256
         cy.F = 256

         Angle = A * #PI / 180.0 + AngleR.F
      
         ix.F = Cos(Angle)
         iy.F = Sin(Angle)
         jx.F = Cos(Angle + #PI / 2.0)
         jy.F = Sin(Angle + #PI / 2.0) 

         ex1.F = 0.0
         ey1.F = 0.0 - Thickness
         ex2.F = Distance
         ey2.F = 0.0 - Thickness
         ex3.F = Distance
         ey3.F = Thickness
         ex4.F = 0.0
         ey4.F = Thickness
      
         gx1.F = ex1 * ix + ey1 * iy
         gy1.F = ex1 * jx + ey1 * jy
         gx2.F = ex2 * ix + ey2 * iy
         gy2.F = ex2 * jx + ey2 * jy
         gx3.F = ex3 * ix + ey3 * iy
         gy3.F = ex3 * jx + ey3 * jy
         gx4.F = ex4 * ix + ey4 * iy
         gy4.F = ex4 * jx + ey4 * jy
         DisplaySprite3D(0, 0, 0)
         TransformSprite3D(0, cx+gx1, cy+gy1, cx+gx2, cy+gy2, cx+gx3, cy+gy3, cx+gx4, cy+gy4)      
      Next
      Stop3D()
   EndIf
   ExamineKeyboard()
   If KeyboardPushed(#PB_Key_Left): AngleR = (AngleR + 0.005): EndIf
   If KeyboardPushed(#PB_Key_Right): AngleR = (AngleR - 0.005): EndIf
   FlipBuffers()
   *X = AllocateMemory(1024 * 768 * 4 + 8)
   PokeL(*X, 1024)
   PokeL(*X + 4, 768)
   If StartDrawing(ScreenOutput())
      Buffer      = DrawingBuffer()             ; Get the start address of the screen buffer
      Pitch       = DrawingBufferPitch()        ; Get the length (in byte) took by one horizontal line
      PixelFormat = DrawingBufferPixelFormat()  ; Get the pixel format. 
   *Ecran = Buffer
   *Start = *X + 8

   Qty = 1024 * 768
   ! mov esi, [p_Ecran]
   ! mov edi, [p_Start]
   ! mov ecx, [v_Qty]

Transfert:
   ! lodsd
   ! mov edx, eax
   ! xor ebx,ebx

   ! cmp bl, dl
   ! ja l_ici0
   ! mov bl, dl
ici0:
   ! shr edx, 8

   ! cmp bl, dl
   ! ja l_ici1
   ! mov bl, dl
ici1:
   ! shr edx, 8

   ! cmp bl, dl
   ! ja l_ici2
   ! mov bl, dl
ici2:
   ! shl ebx, 24
   ! or  eax, ebx
   ! stosd
   ! loop l_transfert
   
   ;   CopyMemory(*Ecran, *Start, 1024 * 768 * 4)
      StopDrawing()
   EndIf
   AlphaImage.L = CreateBitmap_(1024, 768, 1, 32, *X + 8)
;   OpenWindow(10, 100, 100, 512, 512, "Lissage", $CF0001)
   ULW.LW
   OpenLW(ULW, 100, 100, AlphaImage)
   ;ImageGadget(0, 0, 0, 1024, 768, AlphaImage)
;   HideWindow(0, 1)
   ;Repeat
   ;   Delay(1)
   ;Until WindowEvent() = 16
   Delay(8000)
;Until KeyboardPushed(#PB_Key_Escape)
CloseScreen()
CloseWindow(0)
End
Répondre