Plasma Direct screen Access

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
jmg49
Messages : 153
Inscription : mer. 26/févr./2014 8:53

Plasma Direct screen Access

Message par jmg49 »

Bonjour,

je fais probablement du déterrage de topic mais quelqu'un pourrait m'expliquer pour quoi le plasma est bleu dans ce code ???

j'ai assez écumé les threads concernants les plasmas , je comprends toujours pas :( merci bien

Code : Tout sélectionner

Direct Screen Access (DSA) in PureBasic !
;

#ScreenWidth  = 800  ; Feel free to change this to see the pixel filling speed !
#ScreenHeight = 600



InitSound()

LoadMusic(1, "sample2.xm")  

PlayMusic(1)




If InitSprite() = 0 Or InitKeyboard()=0
  MessageRequester("Error","DirectX 7+ is needed.",0)
EndIf

Structure Pixel
  Pixel.l
EndStructure

Procedure.f GSin(angle.f)
  ProcedureReturn Sin(angle*(2*3.14/360))
EndProcedure

Dim CosTable(#ScreenWidth*3)
Dim ColorTable(255)

For i = 0 To #ScreenWidth*2
  CosTable(i) = GSin(360*i/320)* 32 + 32
Next


If OpenScreen(#ScreenWidth, #ScreenHeight, 32, "PB Plasma")

  Repeat

    Wave+6
    If Wave > 320 : Wave = 0 : EndIf
    
    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. 
      
      If PixelFormat = #PB_PixelFormat_32Bits_RGB
        For i = 0 To 255
          ColorTable(i) = i << 6 ; Blue is at the 3th pixel
        Next
      Else                       ; Else it's 32bits_BGR
        For i = 0 To 255
          ColorTable(i) = i      ; Blue is at the 1th pixel
        Next    
      EndIf
    
      For y = 0 To #ScreenHeight-1 
        pos1 = CosTable(y+wave)
        
        *Line.Pixel = Buffer+Pitch*y
        
        For x = 0 To #ScreenWidth-1
          pos2 = (CosTable(x+Wave) + CosTable(x+y) + pos1)
          *Line\Pixel = ColorTable(pos2) ; Write the pixel directly to the memory !
          *Line+4
        Next
      Next
   
    
      StopDrawing()
    EndIf
    
    ExamineKeyboard()
    
    FlipBuffers()
     
  Until KeyboardPushed(#PB_Key_Escape)
  StopMusic(1)
  
Else
  MessageRequester("Error","Can't open the screen !",0)
EndIf



End



Avatar de l’utilisateur
Micoute
Messages : 2584
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: Plasma Direct screen Access

Message par Micoute »

Bonsoir jmg49,
pourquoi le plasma est bleu dans ce code ???
la réponse est dans ton programme !
ColorTable(i) = i << 16 ; Blue is at the 3th pixel
Dernière modification par Micoute le lun. 29/sept./2014 14:40, modifié 1 fois.
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 6.20 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Avatar de l’utilisateur
majikeyric
Messages : 602
Inscription : dim. 08/déc./2013 23:19
Contact :

Re: Plasma Direct screen Access

Message par majikeyric »

Il y a une erreur, c'est 16 et pas 6 pour la première boucle for :

Code : Tout sélectionner

      If PixelFormat = #PB_PixelFormat_32Bits_RGB
        For i = 0 To 255
          ColorTable(i) = i << 16 ; Blue is at the 3th pixel
        Next
      Else                       ; Else it's 32bits_BGR
        For i = 0 To 255
          ColorTable(i) = i      ; Blue is at the 1th pixel
        Next    
      EndIf
    
En fonction de ta carte graphique les pixels de ton écran sont représentés différemment en mémoire.

La fonction DrawingBufferPixelFormat() te renvoie ce format.

Si le format est #PB_PixelFormat_32Bits_RGB un pixel est representé en mémoire par la valeur hexadécimale: $00BBGGRR
La premiere boucle for fait varier ColorTable(i) de $00010000 à $00ff0000 , (c'est la composate bleue qui varie)

Et si on est en #PB_PixelFormat_32Bits_BGR, un pixel est representé en mémoire par la valeur hexadécimale: $00RRGGBB
la deuxième boucle for fait varier ColorTable(i) de $00000001 à $000000ff (c'est toujours la composante bleue qui varie)
jmg49
Messages : 153
Inscription : mer. 26/févr./2014 8:53

Re: Plasma Direct screen Access

Message par jmg49 »

ok merci mais ........... dans le cas $00BBGGRR : $00010000 à $00ff0000 c'est le blue qu'on fait varier avec la boucle de 0 à ff

si je veux faire varier le GG dans le même style $000001000 à $00000ff00 ?? je spécifie comment que c'est le GG ou le RR que je vais faire changer ??

dans le code , tout ce qui s'y rapporte c'est le tableau DIM colortable(255) mais ç ame parle pas plus ......

dur dur à intégrer tout ça ...

Merci,
Avatar de l’utilisateur
TazNormand
Messages : 1297
Inscription : ven. 27/oct./2006 12:19
Localisation : Calvados (14)

Re: Plasma Direct screen Access

Message par TazNormand »

Salut

L'opérateur << fait un décalage de bits vers la gauche (regarde la doc concernant les opérateurs), regardes le code modifié, et dé-commente les lignes où j'ai mis en commentaire les "couleurs" :

Code : Tout sélectionner

;Direct Screen Access (DSA) in PureBasic !
#ScreenWidth  = 800  ; Feel free to change this to see the pixel filling speed !
#ScreenHeight = 600
;InitSound()
;LoadMusic(1, "sample2.xm")  
;PlayMusic(1)
If InitSprite() = 0 Or InitKeyboard()=0
	MessageRequester("Error","DirectX 7+ is needed.",0)
EndIf
Structure Pixel
	Pixel.l
EndStructure

Procedure.f GSin(angle.f)
	ProcedureReturn Sin(angle*(2*3.14/360))
EndProcedure

Dim CosTable(#ScreenWidth*3)
Dim ColorTable(255)

For i = 0 To #ScreenWidth*2
	CosTable(i) = GSin(360*i/320)* 32 + 32
Next
If OpenScreen(#ScreenWidth, #ScreenHeight, 32, "PB Plasma")
	Repeat
		Wave+6
		If Wave > 320 : Wave = 0 : EndIf
		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. 
						
			If PixelFormat = #PB_PixelFormat_32Bits_RGB
				For i = 0 To 255
				  ;ColorTable(i) = i ; Blue is at the 3th pixel
				  ;ColorTable(i) = i << 16 ; ROUGE  16 en binaire : % 010000
				  ColorTable(i) = i << 8 ; VERT 8 en binaire : %001000
				Next
			Else                       ; Else it's 32bits_BGR
				For i = 0 To 255
				  ColorTable(i) = i       ; Blue is at the 1th pixel				  
				  ;ColorTable(i) = i<<16  ; ROUGE  16 en binaire : % 010000
				  ;ColorTable(i) = i<<8   ; VERT 8 en binaire : %001000				  
				Next    
			EndIf
		
			For y = 0 To #ScreenHeight-1 
				pos1 = CosTable(y+wave)
				*Line.Pixel = Buffer+Pitch*y
				For x = 0 To #ScreenWidth-1
					pos2 = (CosTable(x+Wave) + CosTable(x+y) + pos1)
					*Line\Pixel = ColorTable(pos2) ; Write the pixel directly to the memory !
					*Line+4
				Next
			Next
			StopDrawing()
		EndIf
		ExamineKeyboard()
		FlipBuffers()
	Until KeyboardPushed(#PB_Key_Escape)
	;StopMusic(1)
Else
	MessageRequester("Error","Can't open the screen !",0)
EndIf
End
Image
Image
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Plasma Direct screen Access

Message par djes »

En complément à TazNormand, un pixel sur l'écran, c'est le mélange de trois couleurs, rouge, verte et bleue. En mémoire, ces trois couleurs sont chacune codées sur un octet (c'est à dire 8 bits, pour une échelle de 256 valeurs différentes).

On a donc en mémoire 1 octet pour le -R-ouge, 1 octet pour le -V-ert (ou Green en anglais), 1 octet pour le -B-leu, ce qui nous fait 3 * 8 bits = 24 bits.

Comme les accès mémoire sont beaucoup plus rapides quand ils sont alignés sur les largeurs de bus (en gros les fils qui vont des puces à la mémoire), on ajoute un octet qui ne sert à rien en général, ou si c'est pour un sprite ou une texture, à définir une transparence sur 256 niveaux (couche -A-lpha). On a donc ARGB, 4 octets, 4*8 bits = 32 bits = 1 long, et ça, ça nous arrange puisqu'on peut travailler avec nos variables facilement !

Alors, suivant les cartes graphiques, les octets sont dans des ordres différents, parfois c'est RGB, parfois c'est BGR...

Pour savoir quel octet "poker" (écrire en mémoire) pour changer une couleur, il faut faire un petit calcul :
la position du pixel en X * le nombre d'octets par pixel (ici, 4) + la position du pixel en Y * le nombre d'octets par ligne (attention, ce n'est pas toujours égal au nombre de pixels * 4, encore une fois ça dépend de l'OS, des cartes graphiques, etc.) + l'adresse du début de la mémoire qui sert pour l'affichage.

En mémoire le blanc donne quelque chose comme ça (j'ai séparé les octets par des - et mis des espaces pour faciliter le comptage) :
Binaire : %00 00 00 00-11 11 11 11-11 11 11 11-11 11 11 11
ou hexa : $00-FF-FF-FF
ou décimal : 0-255-255-255
Deux pixels, le premier blanc, le deuxième vert, ça donne en hexa (plus facile à lire) :
$00-FF-FF-FF-00-00-FF-00
Si je poke un entier long, je vais changer quatre octets d'un coup, c'est à dire mes trois composantes, plus l'alpha s'il y en a.

Imaginons que je veuille mettre du bleu (codage RVB), mon long va ressembler à ça : $000000FF. Le vert, c'est $0000FF00.

Grâce à l'informatique, on peut jouer avec les nombres, et avec les bits. Par exemple, pour faire du vert, je pourrais prendre le bleu et le décaler de 8 bits vers la gauche.
$000000FF << 8 = $0000FF00 : le bleu transformé en vert...
Si je décale de 16 bits, que se passe-t-il
$000000FF << 16 = $00FF0000 : le bleu transformé en rouge...
Et ça, je peux le faire dans les deux sens, et je peux aussi faire des rotations de bits, et n'importe quelle autre opération... Par exemple, une multiplication par 2 est équivalente à un décalage de 1 bit vers la gauche (mais le décalage est beaucoup plus rapide !)
1 << 1 = 2 ; en binaire : %00 00 00 01 << 1 = %00 00 00 10
A noter que, depuis toujours, l'accès à la mémoire graphique est *LENT* : plus lent que l'accès à la mémoire système, tout simplement parce que cette mémoire est synchronisée avec les composants de l'affichage, et que cette mémoire est souvent loin du processeur (sur une carte graphique, tiens). Du coup, les fabricants ont prévu des mécanismes d'accès particuliers, qui évoluent à chaque génération... C'est pour cela qu'il y a des API graphiques, comme OpenGL, qui ajoutent une couche d'abstraction qui ne change pas trop souvent, et qui permet de cacher ces mécanismes. Aujourd'hui, on joue beaucoup avec des textures qui sont aussi dans la mémoire de la carte graphique, et que l'on va commander à l'aide d'appels de fonctions (très courts, donc). On joue aussi avec les shaders, ces programmes sont déportés de la mémoire centrale vers la mémoire de la carte graphique, et sont donc beaucoup plus rapides et fluides que des accès processeur<>carte graphique.

Bon sang, j'ai encore fait un pavé... :( désolé !
jmg49
Messages : 153
Inscription : mer. 26/févr./2014 8:53

Re: Plasma Direct screen Access

Message par jmg49 »

ahhhhh, merci bien là c'est très clair avec vos deux explications combinées , mon problème venait de la syntaxe en fait avec l'opérateur de décalage de bits

maintenant je sais ce que je fais c'est beaucoup mieux , les poke je maitrise depuis l'Amstrad :D pour poker le CRTC
Répondre