begin process at 2008 09 05 20:31:22
1 237 501 membres
441 nouveaux aujourd'hui
14 313 membres club

Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum.
Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

TUTO TILE 7 : PASSAGE À L'ISOMÉTRIQUE


Information sur la source

Catégorie :Direct X Classé sous : directdraw, directx, isométrique, rotation, tile Niveau : Débutant Date de création : 03/05/2007 Date de mise à jour : 03/05/2007 15:40:14 Vu / téléchargé: 4 422 / 212

Note :
8 / 10 - par 1 personne
8,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

Commentaire sur cette source (13)
Ajouter un commentaire et/ou une note

Description

Bonjour, je suppose que vous disposez des connaissances de mes précédents tuto (ici le premier tuto sur Direct Draw suffit).

Ce code sert à transformer vos tiles (axométrique) en isométrique (losange).

L'interet de ce code est qu'il utilise uniquement  DirectDraw pour les transformations, et qu'il ne passe pas par une méthode 3d pour la transformation.

Source

  • Ici je vous donne simplement la fonction de transformation, dans le zip vous disposez d'un exemple complet.
  • Private Const CosAngleRad As Double = 0.707106781114032
  • Private Const SinAngleRad As Double = 0.707106781259063
  • Public Function AxoToIso(SSrc As DirectDrawSurface7, ddsdSrc As DDSURFACEDESC2, SDest As DirectDrawSurface7, ddsdDest As DDSURFACEDESC2)
  • Dim Pixel As Long 'Couleur d'un pixel
  • Dim x As Long, y As Long 'Coordonnées source
  • Dim x2 As Long, y2 As Long 'Nouvelle coordonnées
  • Dim SrcHeightDiv1 As Double
  • Dim YSinAngle As Double, YCosAngle As Double
  • Dim SrcHeight As Long
  • Dim SrcWidth As Long
  • With SDest
  • 'On bloque les surfaces en mémoire pour qu'elle ne soit plus modifiable
  • 'les surfaces sont bloqués entierement (ddrect(0,0,0,0)), et ne sont accessible que en lecture
  • SSrc.Lock ddRect(0, 0, 0, 0), ddsdSrc, DDLOCK_READONLY Or DDLOCK_WAIT, 0
  • .Lock ddRect(0, 0, 0, 0), ddsdDest, DDLOCK_READONLY Or DDLOCK_WAIT, 0
  • SrcHeight = ddsdSrc.lHeight - 1
  • SrcWidth = ddsdSrc.lWidth - 1
  • 'Optimisation
  • SrcHeightDiv1 = ((SrcHeight + 1) *0.666666666666667) + 1
  • 'Pour tous les pixel du tile
  • For y = 0 To SrcWidth
  • 'Optimisation
  • YSinAngle = y * SinAngleRad
  • YCosAngle = y * CosAngleRad
  • For x = 0 To SrcHeight
  • 'On récupere la couleur du pixel
  • Pixel = SSrc.GetLockedPixel(x, y)
  • 'On calcul les nouvelle coordonnée suivant les formules trigonométrique
  • x2 = ((x * CosAngleRad) - YSinAngle) + SrcHeightDiv1
  • y2 = ((x * SinAngleRad) + YCosAngle) * 0.5
  • 'Cette condition n'est pas du tout necessaire, c'est juste pour obtenir un tile isométrique plus jolie
  • If x2 = 36 And y2 = 15 Then
  • 'Si la condition est vrai on copie deux fois le pixel avec un pixel de difference à droite
  • .SetLockedPixel x2, y2, Pixel
  • .SetLockedPixel x2 + 1, y2, Pixel
  • Else
  • 'Autrement on copie normalement le pixel
  • .SetLockedPixel x2, y2, Pixel
  • End If
  • Next
  • Next
  • 'On debloque les surfaces
  • SSrc.Unlock ddRect(0, 0, 0, 0)
  • .Unlock ddRect(0, 0, 0, 0)
  • End With
  • End Function
Ici je vous donne simplement la fonction de transformation, dans le zip vous disposez d'un exemple complet.


Private Const CosAngleRad As Double = 0.707106781114032
Private Const SinAngleRad As Double = 0.707106781259063

Public Function AxoToIso(SSrc As DirectDrawSurface7, ddsdSrc As DDSURFACEDESC2, SDest As DirectDrawSurface7, ddsdDest As DDSURFACEDESC2)
    
    Dim Pixel As Long           'Couleur d'un pixel
    Dim x As Long, y As Long    'Coordonnées source
    Dim x2 As Long, y2 As Long  'Nouvelle coordonnées
    Dim SrcHeightDiv1 As Double
    Dim YSinAngle As Double, YCosAngle As Double
    Dim SrcHeight As Long
    Dim SrcWidth As Long
    
    With SDest
    
        'On bloque les surfaces en mémoire pour qu'elle ne soit plus modifiable
        'les surfaces sont bloqués entierement (ddrect(0,0,0,0)), et ne sont accessible que en lecture
        SSrc.Lock ddRect(0, 0, 0, 0), ddsdSrc, DDLOCK_READONLY Or DDLOCK_WAIT, 0
        .Lock ddRect(0, 0, 0, 0), ddsdDest, DDLOCK_READONLY Or DDLOCK_WAIT, 0
            
        SrcHeight = ddsdSrc.lHeight - 1
        SrcWidth = ddsdSrc.lWidth - 1
        'Optimisation
        SrcHeightDiv1 = ((SrcHeight + 1) *0.666666666666667) + 1
        
        'Pour tous les pixel du tile
        For y = 0 To SrcWidth
            
            'Optimisation
            YSinAngle = y * SinAngleRad
            YCosAngle = y * CosAngleRad
            
            For x = 0 To SrcHeight
                
                'On récupere la couleur du pixel
                Pixel = SSrc.GetLockedPixel(x, y)
                'On calcul les nouvelle coordonnée suivant les formules trigonométrique
                x2 = ((x * CosAngleRad) - YSinAngle) + SrcHeightDiv1
                y2 = ((x * SinAngleRad) + YCosAngle) * 0.5
                
                'Cette condition n'est pas du tout necessaire, c'est juste pour obtenir un tile isométrique plus jolie
                If x2 = 36 And y2 = 15 Then
                    
                    'Si la condition est vrai on copie deux fois le pixel avec un pixel de difference à droite
                    .SetLockedPixel x2, y2, Pixel
                    .SetLockedPixel x2 + 1, y2, Pixel
                    
                Else
                    
                    'Autrement on copie normalement le pixel
                    .SetLockedPixel x2, y2, Pixel
                    
                End If
                
            Next
            
        Next
        
        'On debloque les surfaces
        SSrc.Unlock ddRect(0, 0, 0, 0)
        .Unlock ddRect(0, 0, 0, 0)
        
    End With
End Function

Conclusion

La fonction du zip est legerement differente car l'angle de transformation isométrique n'est pas directement integrer.

Le passage à l'isométrique est effectué ainsi : rotation de 45°puis division de la hauteur par 2.

( Remarque : Lors d'une rotation des pixel vide apparaissent, cela est du à l'agrandissement de l'image par rotation, pour palier à cela il est necessaire d'agrandir l'image 1.5 fois avant la rotation puis de reduire 1.75 fois apres. )

Il est notable que DirectDraw dispose d'une fonction pour effectuer directement les rotations via une accélération materielle, mais il semblerait que peut de carte graphique supporte cette accélération.


Dans le zip je vous ai mis un logiciel qui effectue la même transformation via un BitBlt et qui permet de voir la difference entre les deux types d'affichage.
Pour les "Membres Club", vous pouvez télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip

03 mai 2007 15:29:54 :
Face au bonne remarque de Renfield j'ai apporté une petite mise à jour, du code et du zip, pour que celui ci soit optimisé au mieu.
03 mai 2007 15:40:14 :
Une petite erreur ^^.
  • signaler à un administrateur
    Commentaire de Renfield le 03/05/2007 14:52:31 administrateur CS

    Pour GDI, tu as aussi PlgBlt :
        http://msdn2.microsoft.com/en-us/library/ms532296.aspx
    permet de copier un rectangle source vers un parallélogramme cible

    pour questions de perf (peu important ici, mais conseils bons a prendre) :

    / 2
    à remplacer par * 0.5

    utilises des variables (ou des constantes) pour ne pas recalculer
    Cos(AngleRad) et Sin(AngleRad)

    de même, tu peux stocker dans une variable
    (y * Sin(AngleRad)) et (y * Cos(AngleRad)) pour ne pas les recalculer a chaque iteration de la boucle en x


    voilà ^^

    ++ l'ami

  • signaler à un administrateur
    Commentaire de ciberrique le 03/05/2007 15:33:12

    J'ai mis le code à jour suivant tes conseils et même un peu plus, j'avou avoir honte de moi n'ayant pas vu ces erreurs...

    Pour le GDI je ne connaissais pas du tout cette fonction ^^ .

  • signaler à un administrateur
    Commentaire de diablamanshadow le 03/05/2007 15:56:02

    ton screen me rappelle l'editeur final yuri pour alerte rouge 2 sa ressemble exactement a ca le sol :p sinon la methode est interessante ^^

  • signaler à un administrateur
    Commentaire de Renfield le 03/05/2007 15:58:34 administrateur CS

    bien joué, le With et les modifs, c'est ok....

    le /1.5  en *0.666666666666667
    pas indispensable (non critique) car pas dans la boucle de traitement.

  • signaler à un administrateur
    Commentaire de ciberrique le 03/05/2007 16:03:46

    bah etant donnée que le /1.5 est appelé plus de 450 fois je pense que ca peut servir. ^^

    Jamais vu cet editeur :s

  • signaler à un administrateur
    Commentaire de ciberrique le 03/05/2007 16:05:48

    erf 450 ds l'exemple du zip ^^ (((800\32) * ( 600\32))=450  avec des divisions \ et pas /)  

  • signaler à un administrateur
    Commentaire de loloof64 le 03/05/2007 17:46:01

    Je t'en conjure, ne tiens pas compte de mon formalisme informatique; je l'ai seulement fait parce que mes pensées n'étaient pas claires :

    [code]
    Renfield >> variable:2 >> cause >> {language = assembly, lsl or lsr} ?
    [/code]

    (Le code variable/2 est préférable, est-ce à cause du fait qu'en assembleur on fait notamment appel à lsl.[taille], ou lsr.[taille] ?)

  • signaler à un administrateur
    Commentaire de Renfield le 03/05/2007 20:33:30 administrateur CS

    pas de shift en VB (dommage)

    mais j'ai cru lire dans un bench que les multiplications etaient plus rapides que les divisions

    peut etre n'est plus d'actualité, remarques...

  • signaler à un administrateur
    Commentaire de ciberrique le 03/05/2007 21:20:58

    Si si moi aussi j'ai lu que les multiplications sont plus rapides que les division en vb.

  • signaler à un administrateur
    Commentaire de loloof64 le 04/05/2007 12:21:08

    ah d'accord, pas de shift en VB :(

  • signaler à un administrateur
    Commentaire de ciberrique le 04/05/2007 16:06:38

    C'est quoi un shift en asm ?

  • signaler à un administrateur
    Commentaire de Renfield le 04/05/2007 16:12:43 administrateur CS

    décalage des bits.

    coté maths, ca multiplie (shift a gauche) ou divise (shift a droite) par deux...

    00001000 <<
    donne
    00010000

    etc.

    si tu fais des opéations de multiplication(ou division) par des multiples de deux, dans des langages qui permettent les shifts, tu y gagne en perfs.

  • signaler à un administrateur
    Commentaire de ciberrique le 04/05/2007 16:14:21

    a ok je comprend mieu ^^.

Ajouter un commentaire

Discussions en rapport avec ce code source

Pub



Appels d'offres

CalendriCode

Septembre 2008
LMMJVSD
1234567
891011121314
15161718192021
22232425262728
2930     

VS Express FR Gratuit !

VS Express en français et 100% gratuit !

Téléchargements

Logiciels à télécharger sur le même thème :

Boutique

Boutique de goodies CodeS-SourceS