Page 1 sur 1

Des erreurs graves dans la manipulation du buffer !!

Publié : dim. 30/sept./2007 3:05
par Mytic
Vous commettez de graves erreurs dans vos procédures de Buffer.
8O
Par exemple dans le :
color= PeekL(DrawingBuffer() + (x * PF) +DrawingBufferPitch()* ( Y *PF ) )
il faut supprimer le deuxième PF
Et mettre ça :
color= PeekL(DrawingBuffer() + (x * PF) +DrawingBufferPitch()* ( Y ) )

Autre erreur :

Prenons la procédure rapide_Point()

Procedure rapide_Point(x,Y)
Select DrawingBufferPixelFormat()
Case #PB_PixelFormat_8Bits : PF=1:t=0
Case #PB_PixelFormat_15Bits : PF=2:t=0

Case #PB_PixelFormat_16Bits : PF=2:t=0
Case #PB_PixelFormat_24Bits_RGB : PF=3:t=0
Case #PB_PixelFormat_24Bits_BGR : PF=3:t=1

Case #PB_PixelFormat_32Bits_RGB : PF=4:t=0
Case #PB_PixelFormat_32Bits_BGR : PF=4:t=1
EndSelect
color= PeekL(DrawingBuffer() + (x * PF) +DrawingBufferPitch()* ( Y ) )
If t=1
Rouge=Red(color)
Vert=Green(color)
Bleu=Blue(color)
color=RGB(Bleu,Vert,Rouge)
EndIf
ProcedureReturn color
EndProcedure


Pour PF = 1 il faut un PeekB
Et pour un PF = 2 un PeekW


et pour PF = 3;
C’est plus délicat, il faut faire 3 peekB pour le Rouge le Vert et le Bleu, puis les rassembler avec un RGB()

Le PeekL renvoi 4 octets (rappel) Donc 2 pixel pour le 16 bits et 4 pixel pour le 8 bits


:? :idea:

Publié : dim. 30/sept./2007 3:21
par Mytic
Voici la procédure corrigée :

Code : Tout sélectionner


Procedure rapide_Point(x,Y)
Select DrawingBufferPixelFormat()
Case #PB_PixelFormat_8Bits : PF=1:t=0
Case #PB_PixelFormat_15Bits : PF=2:t=0
Case #PB_PixelFormat_16Bits : PF=2:t=0
Case #PB_PixelFormat_24Bits_RGB : PF=3:t=0
Case #PB_PixelFormat_24Bits_BGR : PF=3:t=1
Case #PB_PixelFormat_32Bits_RGB : PF=4:t=0
Case #PB_PixelFormat_32Bits_BGR : PF=4:t=1
EndSelect
Select PF
Case 1 :color= PeekB(DrawingBuffer() + (x * PF) +DrawingBufferPitch()* ( Y ) )
Case 2 :color= PeekW(DrawingBuffer() + (x * PF) +DrawingBufferPitch()* ( Y ) )
Case 3 :
;--------
;C’est plus délicat, il faut faire 3 peekB pour le Rouge le Vert et le Bleu, 
;puis les rassemblés avec un RGB()
;--------
Case 4 :color= PeekL(DrawingBuffer() + (x * PF) +DrawingBufferPitch()* ( Y ) )
EndSelect

If t=1
Rouge=Red(color)
Vert=Green(color)
Bleu=Blue(color)
color=RGB(Bleu,Vert,Rouge)
EndIf
ProcedureReturn color
EndProcedure 
:wink:

Publié : dim. 30/sept./2007 11:35
par Dr. Dri
Et elles sont où les conversions de 8/15/16 bits vers du 32bits ? pourquoi le 32bits BGR voit-il sa composante alpha délaissée dans la conversion vers le RGB ?

C'est loin d'être complet, cepandant je veux bien donner des pistes :
Le format des pixels est le même pour tous et est défini à l'ouverture de l'écran
Exception faite pour les "alpha sprites" qui se basent sur une palette
(un écran 8bits se basera aussi sur une palette)
Exception faite pour les "alphablending sprites" qui ont forcément 32bits

En 15bits les composantes RGB sont toutes définies sur bits
(je ne sais plus quel bit est ignoré, MSB ou LSB)

En 16bits le vert est défini sur 6bits

Avec tout ça on peut comprendre que ça prenne du temps de faire tous les tests et que les fonctions plot/point soient lentes. Maintenant on peut faire une fonction pour chaque conversion et utiliser un prototype pour désigner la bonne en fonction de l'écran ouvert et ainsi on n'a plus à faire tous ces tests contraignants à chaque plot/point.

Dri

Publié : dim. 30/sept./2007 11:58
par Mytic
La commande RGB ne gère pas l’alpha, c’est pourquoi on le délaisse pour ce cas là.
En plus l’alpha selon moi ne sert pas beaucoup en mode Drawing2D.
Sauf bien sur si le bute est de dessiner sur plusieurs couche, comme un mélangeur de couleur.
Mais si c’est pour les Sprite , c’est autre chose.

Dans ces erreurs que je viens de cité… je ciblé le 16 bits.
Car PeekL pour ce mode renvoyait toujours des couleurs faussent sauf pour le Noir.

Pourquoi j’ai posté ce post ?
Ben hier je voulais adapter mon moteur de physique des liquides avec un rapide_plot()
Et les résultats étaient toujours faux.
Ça ma rendu fou pendant 15 minutes… Pour à la fin remarquer que la cause venait du PeekL.

:?

Publié : dim. 30/sept./2007 12:18
par Dr. Dri
Mytic a écrit :La commande RGB ne gère pas l’alpha, c’est pourquoi on le délaisse pour ce cas là.
C'est pas parce que RGB ne gère pas l'alpha que la composante n'existe pas

Dri

Publié : dim. 30/sept./2007 12:29
par Ollivier
Dr. Dri a écrit :Exception faite pour les "alpha sprites" qui se basent sur une palette
(un écran 8bits se basera aussi sur une palette)
Exception faite pour les "alphablending sprites" qui ont forcément 32bits
Salut Dri,

Pourrais-tu expliquer cette partie-ci comme si j'étais un môme de 4 ans? ça m'intéresse parce que, pour l'instant, excepté avec l'API, je n'ai pas réussi à faire de l'alpha au pixel près avec les sprites. J'ai beau essayé, ça couïne. Enfin, disons que ça marche, mais le coef alpha est le même sur tout le sprite...

Sinon, je pense que ce petit exemple devrait suffir pour allier vitesse, sécurité et confort d'écriture. Je crois bien que dans la famille des accès software 2D, c'est le plus rapide. Après, on ne peut plus avec X et Y, si on veut aller plus vite.

Code : Tout sélectionner

Structure PITCH
      X.L[1024]
EndStructure
Structure BUFFER
      Y.PITCH[768]
EndStructure     
InitSprite()
InitKeyboard()
InitMouse()
Dim _Cos(511)
Dim _Sin(511)
For i = 0 To 511
      Angle.F = i * #PI / 256.0
      _Cos(i) = Cos(Angle) * 200.0
      _Sin(i) = Sin(Angle) * 200.0     
Next

Dim *Buff(1)

OpenScreen(1024, 768, 32, "")

      StartDrawing(ScreenOutput() )
            *Buff(0) = DrawingBuffer()
      StopDrawing()
      FlipBuffers()
      
      StartDrawing(ScreenOutput() )
            *Buff(1) = DrawingBuffer()
      StopDrawing()
            
      CX = 512
      CY = 384
      Repeat
            Delay(20)
            ExamineMouse()
            MDX = MouseDeltaX()
            MDY = MouseDeltaY()
            If MDX Or MDY Or 1
                  CX + MDX
                  CY + MDY
                  ClearScreen(0)
                  StartDrawing(ScreenOutput() )
                        FlipBuffer = 1 - FlipBuffer
                        *Buffer.BUFFER = *Buff(FlipBuffer)
                        For i = 0 To 255
                              p = i
                              p + n
                              p & 511
                              For j = 0 To 511 - 7 Step 8
                                    k = j
                                    k + m
                                    X = CX + _Cos(p)
                                    Y = CY + _Sin(p)
                                    X + _Cos(k) >> 1                                    
                                    Y + _Sin(k) >> 1
                                    X & 1023 ; Sécu 1
                                    If (Y <= 767) And (Y => 0) ; Sécu 2
                                          *Buffer\Y[Y]\X[X] = $FFFFFF ; Pif
                                    EndIf
                              Next
                        Next
                        m + 1
                        m & 7
                        n - 1
                        n & 511
                  StopDrawing()  
                  FlipBuffers()                
            EndIf
            ExamineKeyboard()
      Until KeyboardPushed(#PB_Key_Escape)
CloseScreen()

Publié : dim. 30/sept./2007 12:37
par Backup
Ollivier a écrit : comme si j'étais un môme de 4 ans?
a ce propos de ton plot/point() bizard, que je comprends rien, tu veux pas m'en faire 2 procedures ?? j'aime bien les procedure , je sais c'est plus lent, mais c'est pratique,et propre comme un sac poubelle , on ne vois que l'exterieur , ce qu'il y a dedans , on s'en fout :lol:

Publié : dim. 30/sept./2007 12:41
par djes
Ollivier a écrit :
Dr. Dri a écrit :Exception faite pour les "alpha sprites" qui se basent sur une palette
(un écran 8bits se basera aussi sur une palette)
Exception faite pour les "alphablending sprites" qui ont forcément 32bits
Salut Dri,

Pourrais-tu expliquer cette partie-ci comme si j'étais un môme de 4 ans? ça m'intéresse parce que, pour l'instant, excepté avec l'API, je n'ai pas réussi à faire de l'alpha au pixel près avec les sprites. J'ai beau essayé, ça couïne. Enfin, disons que ça marche, mais le coef alpha est le même sur tout le sprite...

Sinon, je pense que ce petit exemple devrait suffir pour allier vitesse, sécurité et confort d'écriture. Je crois bien que dans la famille des accès software 2D, c'est le plus rapide. Après, on ne peut plus avec X et Y, si on veut aller plus vite.

Code : Tout sélectionner

Structure PITCH
      X.L[1024]
EndStructure
Structure BUFFER
      Y.PITCH[768]
EndStructure     
InitSprite()
InitKeyboard()
InitMouse()
Dim _Cos(511)
Dim _Sin(511)
For i = 0 To 511
      Angle.F = i * #PI / 256.0
      _Cos(i) = Cos(Angle) * 200.0
      _Sin(i) = Sin(Angle) * 200.0     
Next

Dim *Buff(1)

OpenScreen(1024, 768, 32, "")

      StartDrawing(ScreenOutput() )
            *Buff(0) = DrawingBuffer()
      StopDrawing()
      FlipBuffers()
      
      StartDrawing(ScreenOutput() )
            *Buff(1) = DrawingBuffer()
      StopDrawing()
            
      CX = 512
      CY = 384
      Repeat
            Delay(20)
            ExamineMouse()
            MDX = MouseDeltaX()
            MDY = MouseDeltaY()
            If MDX Or MDY Or 1
                  CX + MDX
                  CY + MDY
                  ClearScreen(0)
                  StartDrawing(ScreenOutput() )
                        FlipBuffer = 1 - FlipBuffer
                        *Buffer.BUFFER = *Buff(FlipBuffer)
                        For i = 0 To 255
                              p = i
                              p + n
                              p & 511
                              For j = 0 To 511 - 7 Step 8
                                    k = j
                                    k + m
                                    X = CX + _Cos(p)
                                    Y = CY + _Sin(p)
                                    X + _Cos(k) >> 1                                    
                                    Y + _Sin(k) >> 1
                                    X & 1023 ; Sécu 1
                                    If (Y <= 767) And (Y => 0) ; Sécu 2
                                          *Buffer\Y[Y]\X[X] = $FFFFFF ; Pif
                                    EndIf
                              Next
                        Next
                        m + 1
                        m & 7
                        n - 1
                        n & 511
                  StopDrawing()  
                  FlipBuffers()                
            EndIf
            ExamineKeyboard()
      Until KeyboardPushed(#PB_Key_Escape)
CloseScreen()
Très joli code :D

Publié : dim. 30/sept./2007 13:27
par Mytic
J’ai transformé la partie essentielle du code d’Ollivier en procédures pour simplifier son utilisation. :D

Code : Tout sélectionner


Procedure init_buffer()
Structure PITCH
      X.L[1024]
EndStructure
Structure BUFFER
      Y.PITCH[768]
EndStructure    

Global Dim *Buff(1)
Global *Buffer.BUFFER

      StartDrawing(ScreenOutput() )
            *Buff(0) = DrawingBuffer()
      StopDrawing()
      FlipBuffers()
     
      StartDrawing(ScreenOutput() )
            *Buff(1) = DrawingBuffer()
      StopDrawing()

EndProcedure

Procedure Flip_buffer()
Static FlipBuffer 
FlipBuffer = 1 - FlipBuffer
*Buffer.BUFFER = *Buff(FlipBuffer)
EndProcedure

Procedure Buffer_plot(X.L,Y.l,Color.l)
Select DrawingBufferPixelFormat()
Case #PB_PixelFormat_32Bits_RGB : t=0
Case #PB_PixelFormat_32Bits_BGR : t=1
EndSelect
If t=1
Rouge=Red(color)
Vert=Green(color)
Bleu=Blue(color)
color=RGB(Bleu,Vert,Rouge)
EndIf
*Buffer\Y[Y]\X[X] = (Color)
EndProcedure

;--------------------(exemple)
InitSprite()
OpenScreen(1024, 768,32,"test")
 init_buffer()
 StartDrawing(ScreenOutput())
 
 Flip_buffer()
 For x = 0 To 100
  For y = 0 To 100
     Buffer_plot(x,y,255)
  Next y
 Next x
 Buffer_plot(10,10,255)
 
 StopDrawing()
 
 FlipBuffers()
 Delay(1000)
End  
:idea:

Publié : dim. 30/sept./2007 14:55
par Buckethead
Bravo, il faut que je test tout ça :]

De mon coté j'ai noté dans mes premières routines que je devais surtout revoir mes calculs. En 1680*1050*32 cette routine prend 32 ms sur mon E2140 @ 3.25 GHz et 16 ms si je retire le modulo 255 à (x*y+9*t)%255

Dans cette résolution elle prend 16 ms ce qui correspond au 60 Hz de mon écran LCD. Pour bien faire il faudrait ne pas attendre la synchronisation. Je viens juste de faire ce test, je ne connais pas la granularité de ce timer.

Code : Tout sélectionner

InitSprite()
InitKeyboard()
OpenScreen(1024,768,32,"a")
Repeat
Time=ElapsedMilliseconds() 
StartDrawing(ScreenOutput()) 
t=t+1
For y=0 To 767
For x=0 To 1023
Plot (x,y,(x*y+9*t)%255)
Next x
Next y
DrawText(1,1,Str(ElapsedMilliseconds()-Time)+" ms pour "+Str(1024*768)+" pixels")
StopDrawing()
FlipBuffers()
ExamineKeyboard()
Until KeyboardPushed(#PB_Key_Escape)

Publié : dim. 30/sept./2007 15:18
par Mytic
@Buckethead

Très beau ton effet ^^ :D

Publié : dim. 30/sept./2007 15:51
par Dr. Dri
Ollivier a écrit :
Dr. Dri a écrit :Exception faite pour les "alpha sprites" qui se basent sur une palette
(un écran 8bits se basera aussi sur une palette)
Exception faite pour les "alphablending sprites" qui ont forcément 32bits
Salut Dri,

Pourrais-tu expliquer cette partie-ci comme si j'étais un môme de 4 ans? ça m'intéresse parce que, pour l'instant, excepté avec l'API, je n'ai pas réussi à faire de l'alpha au pixel près avec les sprites. J'ai beau essayé, ça couïne. Enfin, disons que ça marche, mais le coef alpha est le même sur tout le sprite...

Code : Tout sélectionner

InitSprite()
InitKeyboard()

Macro RGBA(r, g, b, a)
      (RGB(r, g, b) | ~(a & $FF) << 24)
EndMacro

If OpenScreen(1024, 768, 32, "")
      
      CreateSprite(0, 50, 50, #PB_Sprite_AlphaBlending)
      CreateSprite(1, 50, 50, #PB_Sprite_AlphaBlending)
      
      If StartDrawing( SpriteOutput(0) )
            ;un carré rouge
            Box(0, 0, 50, 50, RGBA($FF, $00, $00, $FF))
            ;avec dedans un carré bleu
            Box(15, 15, 20, 20, RGBA($00, $00, $FF, $FF))
            StopDrawing()
      EndIf
      
      If StartDrawing( SpriteOutput(1) )
            ;un carré rouge
            Box(0, 0, 50, 50, RGBA($FF, $00, $00, $FF))
            ;avec dedans un carré bleu transparent
            Box(15, 15, 20, 20, RGBA($00, $00, $FF, $00))
            StopDrawing()
      EndIf
      
      Repeat
            Delay(20)
            
            DisplaySprite(0,  0,  0)
            DisplaySprite(1, 50, 50)
            
            FlipBuffers()
            ExamineKeyboard()
      Until KeyboardPushed(#PB_Key_Escape)
      
      CloseScreen()
EndIf
Ollivier a écrit :Sinon, je pense que ce petit exemple devrait suffir pour allier vitesse, sécurité et confort d'écriture. Je crois bien que dans la famille des accès software 2D, c'est le plus rapide. Après, on ne peut plus avec X et Y, si on veut aller plus vite.
Ce n'est pas parce que tu as une largeur d'écran de 1024 pixels de 32bits que tu auras forcément un pitch de 1024 longs. Toujours se baser sur le pitch.

Dri

Publié : dim. 30/sept./2007 18:29
par Ollivier
Y'a un truc qui va pas avec ce système...

Publié : lun. 01/oct./2007 3:11
par Buckethead
Mytic: en plus j'ai pu m'affranchir de certaines contraintes. :twisted:

Code : Tout sélectionner

; Copaïeraïte 2007 Hall raïtz résèrvède by Ollivier 
Repeat 
ForEver

Publié : lun. 01/oct./2007 6:30
par Ollivier
Ha non : j'ai écrit Pic poc un jour quelquepart. Autorisation refusée!

Royalties!