Taille des Sprites 3D

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Taille des Sprites 3D

Message par Thyphoon »

Bonjour,

ça fait déjà un bout de temps que je manipule les sprites 3D mais il me reste des questions sans reponse.

les Sprites 3D doivent t'il vraiment toujours être carré ? doit t'elle toujours être des dimensions suivante ? 16x16, 32x32, 64x64,128x128,256x256,512x512 ?
Peux t'on faire des sprite de 300x300 ?

Si on veut afficher avec un sprite 3D une image qui fait 300x100 comment fait-on ? est ce que ce n'est pas idiot de faire un sprite3D de 300x300 dans le quel je colle mon sprite de 300x100 ?

j'ai l'impression que les cartes graphiques recente supporte n'importe quel taille de sprite (même si pas carré). Est ce que c'est coup de chance ou bien on peut le faire ? parcontre si le sprite n'est pas carré avec la fonction rotatesprite3D alors l'image est toute deformé !

merci d'avance si vous m'apportez des eclaircissements !!

:P
beauregard
Messages : 1307
Inscription : dim. 08/juil./2007 18:32
Localisation : Toulouse

Re: Taille des Sprites 3D

Message par beauregard »

Thyphoon a écrit :j'ai l'impression que les cartes graphiques recente supporte n'importe quel taille de sprite (même si pas carré). Est ce que c'est coup de chance ou bien on peut le faire ? parcontre si le sprite n'est pas carré avec la fonction rotatesprite3D alors l'image est toute deformé !
l'intérêt d'un sprite3D, réside dans le fait d'être manipulé( transparence, zoom, rotation), donc je te confirme qu'il est tout à fait logique de respecter les tailles préconisés.

Peurbasique est à l'origine un programme de test de sprite3D, qui est devenu par la force des choses un jeu.
exemple de rotation avec #pic d'une taille de 16*16:
http://www.purebasic.fr/french/viewtopi ... 30&start=0

Code : Tout sélectionner

 ; Affichage clone elice si existe.
 ForEach elice()
 zutB+1
   elice()\x=elice()\x+elice()\sensx ; fait avancer les elices
   elice()\Y=elice()\Y+elice()\sensy
     
   ; +24= position par rapport à l'elice ; +40 diamètre de la rotation de pic. 

  If elice()\sr=0
   RotateSprite3D(#pic3D, -tourne, 0)
   DisplaySprite3D ( #pic3D , elice()\x+24+40*Sin(tourne*0.0174532925), elice()\Y+24+40*Cos(tourne*0.0174532925),255)
   RotateSprite3D(#pic3D, -tourne2, 0)
   DisplaySprite3D ( #pic3D , elice()\x+24+40*Sin(tourne2*0.0174532925), elice()\Y+24+40*Cos(tourne2*0.0174532925),255)
  EndIf
  If elice()\sr=1
   RotateSprite3D(#pic3D, -tournf, 0)
   DisplaySprite3D ( #pic3D , elice()\x+24+40*Sin(tournf*0.0174532925), elice()\Y+24+40*Cos(tournf*0.0174532925),255)
   RotateSprite3D(#pic3D, -tournf2, 0)
   DisplaySprite3D ( #pic3D , elice()\x+24+40*Sin(tournf2*0.0174532925), elice()\Y+24+40*Cos(tournf2*0.0174532925),255)
  EndIf
     
   DisplaySprite3D ( elice()\id , elice()\x, elice()\Y, 255) 
rotation des sprites #pic3D, qui de plus tournent autour du clone sprite elice( voir Procedure Fclonee() ; elice 64*64 ).
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

tout dépend de la diffusion que tu souhaites donner à ton jeu, si tu veux qu'il tourne sur un max de config, tu devrais respecter la règle, sinon effectivement sur les cartes récentes il n'y a pas de soucis ,tu peux donner des tailles rectangulaires et non multiples de 2.
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

@Beauregard:merci pour l'exemple. j'avais déjà testé ton jeu. C'es très sympa (l'idée comme la réalisation)
@comtois: merci comtois. C'est un peu ce que je pensais.
Mais que préconises-tu pour manipuler en sprite 3D une image part exemple de 300x100 ? sachant qu'on a besoin de la fonction rotatesprite3D ?

Merci d'avance
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

pas obligé d'etre Carre !!
mais il doit etre un multiple de 16

on peut tres bien faire un sprite 512x128 ou 32x512... :)
300x100 comment fait-on ?
ben tu créé un sprite le plus approchant !! multiple de 16

soit 320x128
Dernière modification par Backup le dim. 09/déc./2007 12:22, modifié 1 fois.
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

Dobro a écrit :pas obligé d'etre Carre !!
mais il doit etre un multiple de 16

on peut tres bien faire un sprite 512x128 ou 32x512... :)
très interessant ça. j'étais perssuadé d'avoir lu dans la doc que ça devait être carré lolllll :lol: En tout cas c'est une bonne nouvelle je vais testé voir si ça marche avec rotatesprite3D si le sprite est pas carré !! :o)
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Message par djes »

Il faut vraiment respecter les dimensions imposées. J'ai dû à de multiples reprises revoir mes programmes à cause d'incompatibilités sur certaines cartes (même récentes!). Les effets sont désastreux, qui vont de la corruption de l'affichage, à la disparition de la transparence, ou au non affichage pur et simple.

Ce n'est PAS une limitation de Purebasic, mais une contrainte DirectX liée aux cartes graphiques.

Dans ton cas, pour un sprite de 300x100, si tu dois faire une rotation, il te faut prendre 512x512 (attention au centre de rotation, si tu dois le bouger, utilise la lib supersprite de CPL Bator).

Si tu ne dois pas faire de rotation et que tu as un peu de courage, tu peux faire un sprite de 256x256 + un de 128x128, ou 3 de 128x128.
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

ce programme te montre que c'est possible !! :D
CreateSprite(0,128,64,#PB_Sprite_Texture)

Code : Tout sélectionner

Structure vertex
    sx.f
    sy.f
    sz.f
    rhw.f
    Color.l
    specular.l
    tu.f
    tv.f
EndStructure

Structure PB_Sprite3D
    Texture.l         
    Vertice.vertex[4]
    width.w
    height.w
EndStructure

Structure PB_Sprite3DEX
    No.l
    AA.f:AB.f:AC.f:AD.f
    DA.f:DB.f:DC.f:dd.f
    Pivot_x.f
    Pivot_y.f
EndStructure





Procedure Distance(x1,y1,x2,y2)
    Protected Result.f
    Result = Sqr(  Pow(x1-x2,2) + Pow(y1-y2,2) + Pow(z1-z2,2) )
    ProcedureReturn Result
EndProcedure


Procedure.f ReturnAngle(x1.f,y1.f,x2.f,y2.f)
    a.f = x1-x2
    b.f = y1-y2
    c.f = -Sqr(a*a+b*b)
    angle.f = ACos(a/c)*180/#PI
    If y1 < y2 : angle=360-angle : EndIf
    ProcedureReturn Abs(angle - 360)
EndProcedure


Procedure Sprite3DModifyPivot(*SpriteID.PB_Sprite3DEX,x.f,Y.f)
    Protected *VertexSprite.PB_Sprite3D = IsSprite3D(*SpriteID\No)
    
    *SpriteID\AA = ReturnAngle(*VertexSprite\Vertice[0]\sx,*VertexSprite\Vertice[0]\sy,x,Y)
    *SpriteID\AB = ReturnAngle(*VertexSprite\Vertice[1]\sx,*VertexSprite\Vertice[1]\sy,x,Y)
    *SpriteID\AC = ReturnAngle(*VertexSprite\Vertice[2]\sx,*VertexSprite\Vertice[2]\sy,x,Y)
    *SpriteID\AD = ReturnAngle(*VertexSprite\Vertice[3]\sx,*VertexSprite\Vertice[3]\sy,x,Y)
    
    *SpriteID\DA = Distance(*VertexSprite\Vertice[0]\sx,*VertexSprite\Vertice[0]\sy,x,Y)
    *SpriteID\DB = Distance(*VertexSprite\Vertice[1]\sx,*VertexSprite\Vertice[1]\sy,x,Y)
    *SpriteID\DC = Distance(*VertexSprite\Vertice[2]\sx,*VertexSprite\Vertice[2]\sy,x,Y)
    *SpriteID\dd = Distance(*VertexSprite\Vertice[3]\sx,*VertexSprite\Vertice[3]\sy,x,Y)
    
    *SpriteID\Pivot_x=x
    *SpriteID\Pivot_y=Y
EndProcedure

Procedure CreateSprite3DEX(Sprite3D)
    Protected *VertexSprite.PB_Sprite3D = IsSprite3D(Sprite3D)
    Protected *VertexSpriteEX.PB_Sprite3DEX = AllocateMemory(SizeOf(PB_Sprite3DEX))
    
    *VertexSpriteEX\No = Sprite3D
    
    
    
    SizeW.f = *VertexSprite\width/2
    SizeH.f = *VertexSprite\height/2
    
    
    *VertexSpriteEX\AA = ReturnAngle(*VertexSprite\Vertice[0]\sx,*VertexSprite\Vertice[0]\sy,SizeW,SizeH)
    *VertexSpriteEX\AB = ReturnAngle(*VertexSprite\Vertice[1]\sx,*VertexSprite\Vertice[1]\sy,SizeW,SizeH)
    *VertexSpriteEX\AC = ReturnAngle(*VertexSprite\Vertice[2]\sx,*VertexSprite\Vertice[2]\sy,SizeW,SizeH)
    *VertexSpriteEX\AD = ReturnAngle(*VertexSprite\Vertice[3]\sx,*VertexSprite\Vertice[3]\sy,SizeW,SizeH)
    
    *VertexSpriteEX\DA = Distance(*VertexSprite\Vertice[0]\sx,*VertexSprite\Vertice[0]\sy,SizeW,SizeH)
    *VertexSpriteEX\DB = Distance(*VertexSprite\Vertice[1]\sx,*VertexSprite\Vertice[1]\sy,SizeW,SizeH)
    *VertexSpriteEX\DC = Distance(*VertexSprite\Vertice[2]\sx,*VertexSprite\Vertice[2]\sy,SizeW,SizeH)
    *VertexSpriteEX\dd = Distance(*VertexSprite\Vertice[3]\sx,*VertexSprite\Vertice[3]\sy,SizeW,SizeH)
    
    ProcedureReturn *VertexSpriteEX
EndProcedure


Procedure RotateSprite3DEX(*SpriteID.PB_Sprite3DEX,angle.f)
    Protected *VertexSprite.PB_Sprite3D = IsSprite3D(*SpriteID\No)
    Protected SizeW2.l,SizeH2.l
    If angle = 0 Or angle = 180
        *SpriteID\Pivot_x = *VertexSprite\width/2
        *SpriteID\Pivot_y = *VertexSprite\height/2
    Else
        *SpriteID\Pivot_x = *VertexSprite\height/2
        *SpriteID\Pivot_y = *VertexSprite\width/2
    EndIf
    *VertexSprite\Vertice[0]\sx = *SpriteID\Pivot_x  - *SpriteID\DA  * Cos((angle+*SpriteID\AA)*#PI/180)
    *VertexSprite\Vertice[0]\sy = *SpriteID\Pivot_y  - *SpriteID\DA  * Sin((angle+*SpriteID\AA)*#PI/180)
    
    *VertexSprite\Vertice[1]\sx = *SpriteID\Pivot_x  - *SpriteID\DB  * Cos((angle+*SpriteID\AB)*#PI/180)
    *VertexSprite\Vertice[1]\sy = *SpriteID\Pivot_y  - *SpriteID\DB  * Sin((angle+*SpriteID\AB)*#PI/180)
    ; ;                                         
    *VertexSprite\Vertice[3]\sx = *SpriteID\Pivot_x  - *SpriteID\dd  * Cos((angle+*SpriteID\AD)*#PI/180)
    *VertexSprite\Vertice[3]\sy = *SpriteID\Pivot_y  - *SpriteID\dd  * Sin((angle+*SpriteID\AD)*#PI/180)
    
    *VertexSprite\Vertice[2]\sx = *SpriteID\Pivot_x  - *SpriteID\DC  * Cos((angle+*SpriteID\AC)*#PI/180)     
    *VertexSprite\Vertice[2]\sy = *SpriteID\Pivot_y  - *SpriteID\DC  * Sin((angle+*SpriteID\AC)*#PI/180)
    
EndProcedure



InitSprite() : InitSprite3D() : InitKeyboard()
If OpenWindow(0, 0, 0, 800, 600, "Un écran dans une fenêtre...", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    If OpenWindowedScreen(WindowID(0), 0, 0, 800, 600, 0, 0, 0)
    Else
        MessageRequester("Erreur", "Impossible d'ouvrir un écran dans la fenêtre!", 0)
        End
    EndIf
EndIf

;{ A
CreateSprite(0,128,64,#PB_Sprite_Texture)
StartDrawing(SpriteOutput(0))
Box(0,0,64,64,RGB(255,0,0))
Box(64,0,64,64,RGB(255,255,0))
Box(0,0,10,10, $FF0000)
StopDrawing()
CreateSprite3D(0,0)
a = CreateSprite3DEX(0)
;}
;{ B
CreateSprite(1,128,64,#PB_Sprite_Texture)
StartDrawing(SpriteOutput(1))
Box(0,0,64,64,RGB(255,0,0))
Box(64,0,64,64,RGB(255,255,0))
Box(0,54,10,10, $FF0000)
StopDrawing()
CreateSprite3D(1,1)
b = CreateSprite3DEX(1)
;}
;{ C
CreateSprite(2,128,64,#PB_Sprite_Texture)
StartDrawing(SpriteOutput(2))
Box(0,0,64,64,RGB(255,0,0))
Box(64,0,64,64,RGB(255,255,0))
Box(118,54,10,10, $FF0000)
StopDrawing()
CreateSprite3D(2,2)
c = CreateSprite3DEX(2)
;}
;{ D
CreateSprite(3,128,64,#PB_Sprite_Texture)
StartDrawing(SpriteOutput(3))
Box(0,0,64,64,RGB(255,0,0))
Box(64,0,64,64,RGB(255,255,0))
Box(118,0,10,10, $FF0000)
StopDrawing()
CreateSprite3D(3,3)
d = CreateSprite3DEX(3)
;}
e = CreateSprite3DEX(0)
f = CreateSprite3DEX(0)



Sprite3DModifyPivot(e,0,32)
Sprite3DModifyPivot(f,64,0)


Repeat
    Event=WindowEvent()
    r.f = 90 + 45 * Cos(ElapsedMilliseconds()/500)
    ExamineKeyboard()
    ClearScreen(0)
    Start3D()
    RotateSprite3DEX(a,0)
    DisplaySprite3D(0,100,100)
    
    RotateSprite3DEX(b,90)
    DisplaySprite3D(1,300,100)
    
    RotateSprite3DEX(c,180)
    DisplaySprite3D(2,100,300)
    
    RotateSprite3DEX(d,270)
    DisplaySprite3D(3,300,300)
    
    RotateSprite3DEX(e,r)
    DisplaySprite3D(0,500,200)
    
    
    RotateSprite3DEX(f,-r)
    DisplaySprite3D(0,500,400)
    Stop3D()
    
    StartDrawing(ScreenOutput())
    DrawText(100,100,"0 DEG")
    DrawText(300,100,"90 DEG")
    DrawText(100,300,"180 DEG")
    DrawText(300,300,"270 DEG")
    Circle(500,232,4,RGB(0,0,255))
    Circle(564,400,4,RGB(0,0,255))
    Box(100,100,10,10, $00FF00)
    Box(300,100,10,10, $00FF00)
    Box(100,300,10,10, $00FF00)
    Box(300,300,10,10, $00FF00)
    StopDrawing()
    FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape) Or event=#PB_Event_CloseWindow
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

Dobro a écrit :pas obligé d'etre Carre !!
mais il doit etre un multiple de 16

on peut tres bien faire un sprite 512x128 ou 32x512... :)
300x100 comment fait-on ?
ben tu créé un sprite le plus approchant !! multiple de 16

soit 320x128
Apres test, si on veut utiliser les fonctions3D native pour faire tourner un sprite 3D il faut impérativement que le sprite soit carré sinon il sera deformé :(
Mais je te merci des fonctions que tu as mis. Sais-tu si elles sont multiplatforme ? j'ai pas l'impression qu'il y ai d'API utiliser...
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

Thyphoon a écrit : Sais-tu si elles sont multiplatforme ? j'ai pas l'impression qu'il y ai d'API utiliser...
en principe aucun problèmes puisqu'aucun Api est employé ..

le seul problem c'est que je ne sais plus qui est l'auteur du Code .... :?

peut etre bien le Soldat inconnu .... :)

ou cpl Bator ? , ou Chris ? ou Oliv ? ou Denis ? ou Dri? ou Comtois ? :lol:
beauregard
Messages : 1307
Inscription : dim. 08/juil./2007 18:32
Localisation : Toulouse

Message par beauregard »

djes a écrit :Dans ton cas, pour un sprite de 300x100, si tu dois faire une rotation, il te faut prendre 512x512
c'est ce que je pense aussi.
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

Dobro a écrit :
Thyphoon a écrit : Sais-tu si elles sont multiplatforme ? j'ai pas l'impression qu'il y ai d'API utiliser...
en principe aucun problèmes puisqu'aucun Api est employé ..

le seul problem c'est que je ne sais plus qui est l'auteur du Code .... :?

peut etre bien le Soldat inconnu .... :)

ou cpl Bator ? , ou Chris ? ou Oliv ? ou Denis ? ou Dri? ou Comtois ? :lol:
heu et comment tu fais lorsque tu veux changer la taille et faire tourner en même temps avec ton code ? car il n'y a que la fonction rotation et apparement ce n'est pas compatible avec la fonction transform de purebasic !? :P
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

Bon je vous remerci tous, car tout est beaucoup plus claire pour moi maintenant. Et au final je vais utiliser des sprites3D carré car c'est la seul façon d'utiliser RotateSprite3D et zoomSprite3D sans que ça deforme l'image.
Le code de Dobro est tres interessant mais il manque quelques fonctions pour ête pleinnement efficace :oP
En tout cas un grand merci a tous, de m'avoir donner un peu de votre dimanche. :D
beauregard
Messages : 1307
Inscription : dim. 08/juil./2007 18:32
Localisation : Toulouse

Message par beauregard »

Thyphoon a écrit :En tout cas un grand merci a tous, de m'avoir donner un peu de votre dimanche. :D
Au plaisir ! :D
Anonyme

Message par Anonyme »

C'est bibi l'auteur du code, a la base c'est un snippet pour progi1984 si je me rapelle bien.
Ce n'est PAS une limitation de Purebasic, mais une contrainte DirectX liée aux cartes graphiques.
C'est le même problème avec OpenGL , cela vient bien du matériel et non pas d'une api , a prioris se serais un problème de stockage interne , certaine carte impose une taille n² , comme la mienne par exemple , un sprite 32x128 ne marche pas. la solution consiste donc a créer un buffer d'une taille n²
d'appliquer l'image dans ce buffer, puis d'afficher ce buffer. si ton sprite fait donc 32x128 , il fera en réalité 128x128 , il faudra donc joué avec les UV pour ne pas avoir de déformation.
Répondre