Lenteur de draw text

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
Ouaf-Ouaf
Messages : 212
Inscription : dim. 11/juil./2004 9:07

Lenteur de draw text

Message par Ouaf-Ouaf »

[Edit : Heeeu, j'ai posté en debutant sans trop faire attention :roll: ptet un acte manqué lol]


Un truc que j'aimerais bien faire, mais m'y connaissant pas trop eeeen technique, cycle cpu et tout, j'voulais savoir si c'etait valable : ( donc pas perdre trop de temps inutilement :cry: )



J'ai entendus dire que la commande Drawtext() etait plutot lente à cause des vecteurs. En effet quand j'en mets deux tonnes dans mon prog pour "debugger" rapidement, enfin avoir les variables, le FPS chute bcp.

Donc je penssais à une alternative à LoadFont(), ou plutot une addition qui :

- Chargerait la police demandée pour l'imprimer sur des sprites, du genre :
Set_Font( fontID(n, Tailledelapolice, Police ) )

LoadFont(n, Police, Tailledelapolice )
CreateSprite( n, x, y, w, h ) : StartDrawing(SpriteOutput(n))
For Chr = 33 to 255 : Drawtext( Chr * Tailledelapolice, 0, Chr(Chr) ) : Next
Stopdrawing()
Comme ça on a differents sprites qu'on pourrait lire au b'soin pour afficher les pixels <> de la coul de fond specifiée pendant l'impression.. Içi blanc pur.

- Affichées par une procedure qui lirait donc une string lettre par lettre,
Le plot() je ne sais pas si c'est optimisé mais les quelques lignes ASM necessaires à l'impression d'un px permettrais en plus de gerer facilmeent un effet de transparence rapide :p.

Du genre :

(j'ai laissé cursor(n)\X,Y,N[] pour l'instant, c'est tiré de mon code qui gère les curseurs de l'ecran combat)
Draw_Font( n, character$, Option )

For A = 0 To Cursors(0)\X[n] - 1 : For B = 0 To Cursors(0)\Y[n]

Aa = A ;(Je sais pas comment appeler autrement la var en asm )
Ba = B

Height = Cursors(0)\Y[n]

Ar = A + Focus_X + Mvx + 1
Br = B + Focus_Y + Mvy - 10

; 1 ) Addresse du pixel à appliquer
! MOV eax , dword[v_Aa] ; eax = DrawingWidth
! IMUL eax , dword[v_Height] ; eax * y
! ADD eax , dword[v_Ba] ; eax + x
! MOV dword[v_XY], eax ; XY = eax

; 2 ) Addresse du pixel destinataire en X
! MOV eax , dword[v_Ar] ; eax = A
! SAL eax , 2 ; eax << 2
! ADD eax , dword[v_DrawingBuffer] ; eax + DrawingBuffer
! MOV edi , eax ; X4 = eax

; 3 ) Addresse du pixel destinataire en Y
! MOV ecx , dword[v_Br] ; ecx = y
! IMUL ecx , dword[v_DrawingBufferPitch] ; ecx * DrawingBufferPitch
! ADD ecx , edi ; ecx + X4

If Cursors( XY )\N[n] <> 255 And option = 0
; 4 ) Transforme le pixel ciblé
! MOV dword[ecx], $0F0101
Else
! SAL dword[ecx], 1
EndIf

Next B : Next A
Peut être même "simuler" un alpha channel selon la coul du pixel pointé, mais là je sais pas si ca resterais plus rapide..

Vui, par ce que là par exemple je fais juste un decalage de bits qui demande surement peu de temps au processeur, mais ça a plus effet d'illuminer la zone que de faire un effet de transparence, et surtout c'est pas trés heureux quand la valeur monte au dessus de (255,255,255)..

J'ai gardé quelque part un code où un essais foireux m'affichait mon sprite en nuance de cyan, rouge ou jaune.. Faudrait que "j'etudie" ça de pres.

Donc bref, pour la transparence, il faudrait que je me mette à prendre la val du pix à appliquer, la modifier selon une valeur passée en argument, verifier qu'elle se situe bien entre 0 et .. RGB(255,255,255).. Ca serait ptet lent au final ?

En tout cas avec la police enregistrée dans un array, enfin un pointeur au mieux, sans effet de trans ça peut ptet mieux le faire que drawtext() ?

J'me tâââte. De toute façon faut que j'fasse des essais pour les effets d'incantations des sorts de mon truc :P par ce que la librairie SpecialFX() o.o niveau perf bof quoi.


Si vous avez une idée ou un conseil là dessus qui m'eviterais d'eventuelles fausses pistes ce s'rait vraiment couuul :p.

Si ça marche j'm'amuserais bien à ajouter differentes "options de fusion" comme dit sieur toshop.

Heuuu.. elle existe pas deja cette lib ? xD
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

c'est moi ou alors tu pose des questions compliqué pour faire un truc en fait tres simple ??!! 8O


Soyons clair

1- si tu veux afficher des sprites contenant un caracteres chacun,
pourquoi ne pas utiliser les fonctions de transparence de ces sprites ??

2- pour faire afficher des caractères dans les sprites c'est assez simple
voici le code de ma première version de "Matrix" un Screen saver
a sauver avec l'extension *.scr dans le dossier c:\window\system32

en ligne 64 tu aura une idée de la création de sprites avec des Chaines
:)

Code : Tout sélectionner

; Matrix Cree Par Dobro
; Version pour Purebasic V4.00

Dim ysprite(1000)
Dim de(1000)
Dim nom$(30)
Dim index(30)

Dim y(30)
sprite=1
#Police=1
;*********** pour le screensaver
Param.s = Left(ProgramParameter(), 2)
If Param = "/p"
  End
EndIf
GetCursorPos_(SourisOrigine.POINT)
ShowCursor_(0)
; ***********************************
Resultat = InitSprite()
FontID = LoadFont(#Police, "arial", 18, #PB_Font_Bold )
EcranX = GetSystemMetrics_(#SM_CXSCREEN)
EcranY = GetSystemMetrics_(#SM_CYSCREEN)
;NbSprite = EcranX / 40 * 3
NbSprite =12
OpenWindow(1, 0, 0, EcranX, EcranY, "Matrix",#PB_Window_BorderLess )
;SetWindowPos_(WindowID(1), -1, 0, 0, 0, 0, #SWP_NOSIZE | #SWP_NOMOVE) ; fenêtre toujours au premier plan
StickyWindow(1, 1)
OpenWindowedScreen(WindowID(1), 0, 0, EcranX, EcranY, 1, 0, 0)
nom$(1)="h,o,g,o,f,g,h,6,+,8,3,5,f,s,g,4,6,8,4,3,f,s,*,g,°"
nom$(2)="D,O,L,N,R,H,D,F,G,J,K,L,H,G,F,.,/,M,P,%,M,L,*,K,°"
nom$(3)="E,B,I,C,E,E,R,T,I,U,T,K,G,S,M,K,M,O,S,G,J,S,*,O,°"
nom$(4)="D,R,V,O,D,d,f,g,d,d,f,g,d,x,v,c,b,,,u,r,y,z,*,r,°"
nom$(5)=":,O,:,N,D,q,d,y,e,p,o,x,c,b,:,;,z,e,z,e,t,w,*,x,°"
nom$(6)="P,:,E,U,I,:,:,F,G,H,O,G,K,B,¨,B,J,K,S,G,?,S,*,D,°"
nom$(7)="O,R,L,:,X,:,e,t,i,u,t, ,p,t,z,u,r,z,t,_,ç,e,*,r,°"
nom$(8)="L,O,:,D,D,H,I,9,U,R,:,0,8,9,T,Z,R,T,P,R, ,P,*,Z,°"
nom$(9)="U,U,C,E,D,m,s,k,l,d,f,m,p,ç,o,r,j,t,m,z,g,j,*,s,°"
nom$(10)="X,Q,H,N,R,o,o,h,s,r,f,i,h,s,r,f,g,i,h, ,d,f,*,h,°"
nom$(11)="g,U,l,O,I,F,D,O,I,H,F,B,L,K, ,%,P,I,J,3,5, ,*,0,°"
nom$(12)="A,I,u,N,S,D,F,O,0,8,R,G,%,I,R,E,H,P,9,H,P,9,*,O,°"
nom$(13)="R,E,k,I,:,R,G,D,H,O,I,F,D,B,O,%,I, ,V,B,P,Z,*,Q,°"
nom$(14)="T,R,k,:,F,I,O,I,:,X,N,F,B, ,F,B,D,O,P,I,D,F,*,B,°"
nom$(15)="E, ,k,J,L, ,H,R,F,T,J,D,G,N, ,X,F,J,E,<,<,S,*,F,°"
nom$(16)="M,C,k,E,Y,K,Y,R,J,S,R,F,?,N,F,G,W,F,P,G,K, ,*,W,°"
nom$(17)="I,H,k,N,P,A,£,¨,M,£,¨,M,F,G,J,X,W,F,G,J,X,F,*,G,°"
nom$(18)="S,R,k,O,E,R,T,D, ,H,I,J, ,I,E,J,H,Q,P,E,T,H,*,J,°"
nom$(19)=" ,I,k,V, ,K,E,R,P,9,I,E,Q,R,P,Q, ,E,U,R,P, ,*,H,°"
nom$(20)="C,S,k,A,H,O,E,R, ,Q,R,Y,U, ,Q,Ë,0,9,U,Q, ,E,*,0,°"
nom$(21)="O, ,k, ,E,X,E,R,Y, ,Q,E,R,Y, ,Q,E,R,Y,Q,E,R,*,P,°"
nom$(22)="M,Z,k,L,I, ,E,R,Y,Q,E,R,Y,P,S,E,U,S,%,P,E,Y,*,9,°"
nom$(23)="T,A,k,E,S,T,S,R,E,T,S,T,R,U,Y,S,R,T,P,U,I,S,*,R,°"
nom$(24)="O,P,k, ,S,Y,S,R,U,S,R,T,U,S,R,T,U,S,R,T,U,9,*,S,°"
nom$(25)="I,M,k,S,P,U,5,S,R,¨,0,8,U, ,Q,R,Y,E,0,5,4,5,*,Y,°"
nom$(26)="S,A,k,O,I,I,R,S,U,S,R,Y,U,2,5,4,3,2,6,5,3,S,*,Y,°"
nom$(27)=" ,N,k,L,T,R,E,R,Y,Q,E,R,z,I,Q,E,4,Y,Q,E,T,+,*,R,°"
nom$(28)="8,u,k,D,E,S,E,R,Q,Y,P,9,8,Z,E,a,T,8,3,Q, ,8,*,U,°"
nom$(29)="8,o,k,A,R,G,E,5,Q,E,5,z,Y,8,U,E,R,Z,¨,0,U,3,*,4,°"
nom$(30)="8,f,k,T,s,D,E,5,Y,3,5,Q,8,Q,Z,R,¨,8,E,5,Q,0,*,9,°"
; le caractere ° signifie la fin de la phrase il est indispensable
; le caractere * est mis en avant derniere position
; c'est lui qui indique que le caractere suivant sera plus clair
; on crée un sprite
For spr=1 To 30
  ;CallDebugger
  Resultat = CreateSprite(spr, 24,27*Len(nom$(spr)),0)
  While StringField(nom$(spr), index(spr), ",")<>"°":;on guette le caractere ° qui dira que la phrase est fini d'explorer en attendant on boucle
    index(spr)=index(spr)+1 :;on avance d'un caractere
    car$ = StringField(nom$(spr), index(spr), ","):;ici je recupere les caracteres entre les virgules
    y(spr)=y(spr)+27:; pour que le text s'ecrive une ligne au dessous dans le sprite
    StartDrawing(SpriteOutput(spr)):;on commence a dessiner dans le sprite SPR
    BackColor(RGB(0, 0,0)):;couleur de fond noir
    c = c +Int(255/Len(nom$(spr)))+4 :; on eclaircie la couleur d'ecriture!!
    If c>255:c=0:EndIf:; si on depasse 255 (verta fond) on ramene a 20 (vert sombre)
    If car$ = "°":; ha on tombe sur le caractere de fin de phrase
      c = 0 :; on fixe la couleur a 20 (vert sombre)
      Goto fi :;on ne dessine pas le dernier caractere de controle
    EndIf
    ;c=255
    FrontColor(RGB(0, c, 0)): ;on prend la couleur defini plus haut pour dessiner
    If car$ = "*" : ; ha le caractere qui nous indique un changement de couleur
      index(spr)=index(spr)+1:;on passe le caractere * (on veut pas l'afficher c'est un caractere de control)
      car$ = StringField(nom$(spr), index(spr), ","):;on recupere le caractere suivant l'etoile
      FrontColor(RGB(110, 255,110)): ;on choisi une couleur verte presque blanche
    EndIf
    
    DrawingFont(FontID):;attention on va ecrire du text sur la zone reserve du sprite
    DrawText(0, y(spr),car$):; voila on le fait
    fi: 
    long =TextWidth(nom$(1))
    
    StopDrawing():; signale que l'on arrete de dessiner sur le sprite SPR
  Wend
Next spr
;ceci prepare les colonne qui vont etre solicite pour l'affichage, un "precalcul" en fait
xrez=Int(EcranX/27)
Dim col(xrez)

For t=1 To EcranX Step 27
  
  col(h)=t
  h+1
  du:
  
Next t

;***********************************
indexc=0

For ind=1 To xrez :;correspond au nombre de colonne (en 1024)
  ysprite(ind)=-(long*2)-Random(long*4):; tire au hazard une ligne pourle depart d"un sprite
  If Col<>EcranX :; tant que la valeur lu est differente de la rez ecran en x
    indexc=indexc+1 :
    de(ind)=col(ind)
    ;If carcol$=""
    ;    de(ind)=27
    ;EndIf
  Else
    indexc=0
  EndIf
Next ind
indexc=0
Repeat
  RandomSeed(Random(255))
  For ind=1 To xrez
    ; si le sprite sort en bas
    If ysprite(ind)>EcranY
      ysprite(ind)=-(2+long*2)-Random(long*2)
    EndIf
    ; toute l'astuce de l'animation est la !!
    spr=spr+1
   
    If spr>30:; on affiche les sprite en decalant une lettre !!
      spr=1
    EndIf
    ysprite(ind)=ysprite(ind)+Random(10)+10:; vitesse de descente des sprites
    ;DisplayTransparentSprite (spr, de(ind), ysprite(ind))
    DisplaySprite(spr, de(ind), ysprite(ind))
    ;Delay(4)
  Next ind
 FlipBuffers()
  ClearScreen(RGB(0,0,0))
  GetCursorPos_(Souris.POINT)
Until WindowEvent() = #PB_Event_CloseWindow Or Souris\x <> SourisOrigine\x Or Souris\Y <> SourisOrigine\Y
ShowCursor_(1)
Avatar de l’utilisateur
Ouaf-Ouaf
Messages : 212
Inscription : dim. 11/juil./2004 9:07

Message par Ouaf-Ouaf »

Jeeee crois bien que c'est toi. :wink:

C'est la même difference qu'entre un Gif et un Png.

L'un gère la transprence et l'autre l'opacité.


Image
Répondre