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.
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

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

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

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

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.
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

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 ^^

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.
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!