Page 2 sur 2

Publié : jeu. 28/sept./2006 14:09
par Anonyme
Bon, comme il n'y a pas trop de gens qui se sont déclarer, je rends les sources dans la soirée.

@++

Publié : jeu. 28/sept./2006 14:27
par Progi1984
Je pense que tu aurais plus de chance en faisant un moteur style MiniB3D en OGl

Publié : jeu. 28/sept./2006 14:50
par Anonyme
C'est beaucoup plus complexe, déjà que là c'est pas très simple. En parlant d'opengl , je le trouve très lent comparé à directx, du moins sous purebasic.

Publié : jeu. 28/sept./2006 15:09
par Progi1984
Quelle serait la différence entre l'accès à OpenGl entre BMax et PureBasic ?

Publié : jeu. 28/sept./2006 15:11
par Anonyme
Voici la source :D
J'ai essayé de commenté un minimum, avec ceci , vous pourrez vous en servir pour une base d'un moteur3D, il sera simple en effet d'ajouté DirectX ou OpenGL pour le remplissage de polygones ou autres effets.
Pour les matrices, pas la peine de se prendre la tête, les formules c'est toujours les mêmes, pour plus d'infos , j'ai filé des liens plus haut :wink:

Code : Tout sélectionner

InitSprite() : InitKeyboard()
OpenScreen(800,600,32,"")

#Xoff =  400
#Yoff =  300
#Zoff =  1500

; Structure de notre monde 3D, on represente les points3D la dedans.
Structure WORLD3D
  x.f
  y.f
  z.f
  WaveHeight_A.f
  WaveHeight_B.f
EndStructure

Structure MATRIX4
  _11.f:_21.f:_31.f:_41.f
  _12.f:_22.f:_32.f:_42.f
  _13.f:_23.f:_33.f:_43.f
  _14.f:_24.f:_34.f:_44.f
EndStructure

Structure VECTOR3
  x.f:y.f:z.f
EndStructure

Structure CAMERA
  Position.VECTOR3
  LookAT.VECTOR3
  Rotation.VECTOR3
  Pitch.f
  Yaw.f
  Roll.f
EndStructure

Global Dim Map3D.WORLD3D(100,100)
Global Dim Map2D.WORLD3D(100,100)
Global Dim Sommet.WORLD3D(100,100)

Global Matrice_Rotation.MATRIX4        ; Notre matrice de rotation
Global Matrice_Translation.MATRIX4     ; Notre matrice de Translation
Global Matrice_Finale.MATRIX4          ; Matrice finale

; NOTRE CAMERA
Global Camera.CAMERA

Camera\Position\x=-50000
Camera\Position\y=7000
Camera\Position\z=-50000





; Initialisation de notre map 3D
For z = 0 To 100
  For x = 0 To 100
    Sommet(x,z)\x= x*1000
    Sommet(x,z)\z= z*1000
  Next x
Next z


; Procedure de tracage de ligne optimisé
Procedure lineXY2(x1.f,y1.f,x2.f,y2.f,Couleur.l)
  Shared dx.f,dy.f,xincr.l,yincr.l,x.l,y.l,erreur.f
  
  If x1<>0 And y1<>0 And x2<>0 And y2<>0
    
    ;/* On initialise nos variables */
    dx = Abs(x2-x1)
    dy = Abs(y2-y1)
    
    If x1<x2
      xincr = 1
    Else
      xincr = -1
    EndIf
    
    If y1<y2
      yincr = 1
    Else
      yincr = -1
    EndIf
    
    
    ;/* Trace de ligne */
    
    x = x1
    y = y1
    
    If dx>dy
      
      erreur = dx/2  ; /* c'est plus esthetique comme ca */
      For i= 0 To dx
        
        x = x+xincr;
        erreur = erreur+dy
        If erreur > dx
          
          erreur = erreur - dx
          y = y+yincr
        EndIf
        If x>0 And x<800-1 And y>0 And y<600-1
          Plot(x,y,Couleur)
        EndIf
      Next i
      
    Else
      erreur = dy/2;     /* c'est plus esthetique comme ca */
      For i=0 To dy
        y = y + yincr
        erreur = erreur + dx
        If erreur>dy
          erreur = erreur - dy
          x = x + xincr
        EndIf
        If x>0 And x<800-1 And y>0 And y<600-1
          Plot(x,y,Couleur)
        EndIf
      Next i
    EndIf
  EndIf   
EndProcedure

; procedure de projection 3D --> 2D
Procedure Projection3D2D()
  Static WaveSpeed.f
 
  WaveSpeed-0.1

  For z = 0 To 100
   For x = 0 To 100
      
  
      ;Calcul des vagues 3D, puis affectation à la hauteur (y).
      Map3D(x,z)\WaveHeight_A = 1000 *Cos((x*20*2*0.144)+WaveSpeed)
      Map3D(z,x)\WaveHeight_B = 1000 *Sin((x*20*2*0.144)+WaveSpeed)
      Map3D(x,z)\y = Map3D(x,z)\y -(Map3D(x,z)\WaveHeight_A + Map3D(x,z)\WaveHeight_B)/2
      ;Map3D(x,z)\y - ((Map3D(x,z)\x*Map3D(x,z)\x)/Map3D(x,z)\z)/5 ; Donne un effet déformer aux points
      
      
      ;FORMULE DE PROJECTION
      Map2D(x,z)\x=(Map3D(x,z)\x*512)/(Map3D(x,z)\z+#Zoff)+#Xoff;
      Map2D(x,z)\y=(Map3D(x,z)\y*512)/(Map3D(x,z)\z+#Zoff)+#Yoff;
      ; LE *512 joue sur le FOV
      ; Y a plus qu'a trouvé une formule pour la gestion du FOV
      
      
      Couleur.l   = Map3D(x,z)\z / 255
      Couleur = Couleur-Couleur*3
      
      
      If Map3D(x,z)\z>0 And Map3D(x,z)\z<30500 And Map2D(x,z)\x>-100 And Map2D(x,z)\x < 900 And Map2D(x,z)\y>-100 And Map2D(x,z)\y<700
        
        If x+1<100
           lineXY2(Map2D(x,z)\x,Map2D(x,z)\y,Map2D(x+1,z)\x,Map2D(x+1,z)\y,RGB(Couleur ,Couleur ,Couleur))
        EndIf
         
        If z+1<100
           lineXY2(Map2D(x,z)\x,Map2D(x,z)\y,Map2D(x,z+1)\x,Map2D(x,z+1)\y,RGB(Couleur ,Couleur ,Couleur))
        EndIf
       
        EndIf
      
    
    Next x
  Next z
  
EndProcedure


; Proc pour effectuer une translation
Procedure Translation(*Translation.VECTOR3)
  
  
  Matrice_Translation\_11 = 1
  Matrice_Translation\_12 = 0
  Matrice_Translation\_13 = 0
  Matrice_Translation\_14 = 0
  
  Matrice_Translation\_21 = 0
  Matrice_Translation\_22 = 1
  Matrice_Translation\_23 = 0
  Matrice_Translation\_24 = 0
  
  Matrice_Translation\_31 = 0
  Matrice_Translation\_32 = 0
  Matrice_Translation\_33 = 1
  Matrice_Translation\_34 = 0
  
  Matrice_Translation\_41 = *Translation\x
  Matrice_Translation\_42 = *Translation\y
  Matrice_Translation\_43 = *Translation\z
  Matrice_Translation\_44 =  1
  
EndProcedure

; Multiplication de la matrice finale et de la matrice de rotation
Procedure MultiplyMAT()
  
  Matrice_Finale\_11 = Matrice_Translation\_11 * Matrice_Rotation\_11 + Matrice_Translation\_12 * Matrice_Rotation\_21 + Matrice_Translation\_13 * Matrice_Rotation\_31 + Matrice_Translation\_14 * Matrice_Rotation\_41
  Matrice_Finale\_12 = Matrice_Translation\_11 * Matrice_Rotation\_12 + Matrice_Translation\_12 * Matrice_Rotation\_22 + Matrice_Translation\_13 * Matrice_Rotation\_32 + Matrice_Translation\_14 * Matrice_Rotation\_42
  Matrice_Finale\_13 = Matrice_Translation\_11 * Matrice_Rotation\_13 + Matrice_Translation\_12 * Matrice_Rotation\_23 + Matrice_Translation\_13 * Matrice_Rotation\_33 + Matrice_Translation\_14 * Matrice_Rotation\_43
  Matrice_Finale\_14 = Matrice_Translation\_11 * Matrice_Rotation\_14 + Matrice_Translation\_12 * Matrice_Rotation\_24 + Matrice_Translation\_13 * Matrice_Rotation\_34 + Matrice_Translation\_14 * Matrice_Rotation\_44
  
  Matrice_Finale\_21 = Matrice_Translation\_21 * Matrice_Rotation\_11 + Matrice_Translation\_22 * Matrice_Rotation\_21 + Matrice_Translation\_23 * Matrice_Rotation\_31 + Matrice_Translation\_24 * Matrice_Rotation\_41
  Matrice_Finale\_22 = Matrice_Translation\_21 * Matrice_Rotation\_12 + Matrice_Translation\_22 * Matrice_Rotation\_22 + Matrice_Translation\_23 * Matrice_Rotation\_32 + Matrice_Translation\_24 * Matrice_Rotation\_42
  Matrice_Finale\_23 = Matrice_Translation\_21 * Matrice_Rotation\_13 + Matrice_Translation\_22 * Matrice_Rotation\_23 + Matrice_Translation\_23 * Matrice_Rotation\_33 + Matrice_Translation\_24 * Matrice_Rotation\_43
  Matrice_Finale\_24 = Matrice_Translation\_21 * Matrice_Rotation\_14 + Matrice_Translation\_22 * Matrice_Rotation\_24 + Matrice_Translation\_23 * Matrice_Rotation\_34 + Matrice_Translation\_24 * Matrice_Rotation\_44
  
  Matrice_Finale\_31 = Matrice_Translation\_31 * Matrice_Rotation\_11 + Matrice_Translation\_32 * Matrice_Rotation\_21 + Matrice_Translation\_33 * Matrice_Rotation\_31 + Matrice_Translation\_34 * Matrice_Rotation\_41
  Matrice_Finale\_32 = Matrice_Translation\_31 * Matrice_Rotation\_12 + Matrice_Translation\_32 * Matrice_Rotation\_22 + Matrice_Translation\_33 * Matrice_Rotation\_32 + Matrice_Translation\_34 * Matrice_Rotation\_42
  Matrice_Finale\_33 = Matrice_Translation\_31 * Matrice_Rotation\_13 + Matrice_Translation\_32 * Matrice_Rotation\_23 + Matrice_Translation\_33 * Matrice_Rotation\_33 + Matrice_Translation\_34 * Matrice_Rotation\_43
  Matrice_Finale\_34 = Matrice_Translation\_31 * Matrice_Rotation\_14 + Matrice_Translation\_32 * Matrice_Rotation\_24 + Matrice_Translation\_33 * Matrice_Rotation\_34 + Matrice_Translation\_34 * Matrice_Rotation\_44
  
  Matrice_Finale\_41 = Matrice_Translation\_41 * Matrice_Rotation\_11 + Matrice_Translation\_42 * Matrice_Rotation\_21 + Matrice_Translation\_43 * Matrice_Rotation\_31 + Matrice_Translation\_44 * Matrice_Rotation\_41
  Matrice_Finale\_42 = Matrice_Translation\_41 * Matrice_Rotation\_12 + Matrice_Translation\_42 * Matrice_Rotation\_22 + Matrice_Translation\_43 * Matrice_Rotation\_32 + Matrice_Translation\_44 * Matrice_Rotation\_42
  Matrice_Finale\_43 = Matrice_Translation\_41 * Matrice_Rotation\_13 + Matrice_Translation\_42 * Matrice_Rotation\_23 + Matrice_Translation\_43 * Matrice_Rotation\_33 + Matrice_Translation\_44 * Matrice_Rotation\_43
  Matrice_Finale\_44 = Matrice_Translation\_41 * Matrice_Rotation\_14 + Matrice_Translation\_42 * Matrice_Rotation\_24 + Matrice_Translation\_43 * Matrice_Rotation\_34 + Matrice_Translation\_44 * Matrice_Rotation\_44
  
  
  
  Matrice_Translation\_11 = Matrice_Finale\_11
  Matrice_Translation\_11 = Matrice_Finale\_12
  Matrice_Translation\_11 = Matrice_Finale\_13
  Matrice_Translation\_11 = Matrice_Finale\_14
  
  Matrice_Translation\_21 = Matrice_Finale\_21
  Matrice_Translation\_21 = Matrice_Finale\_22
  Matrice_Translation\_21 = Matrice_Finale\_23
  Matrice_Translation\_21 = Matrice_Finale\_24
  
  Matrice_Translation\_31 = Matrice_Finale\_31
  Matrice_Translation\_31 = Matrice_Finale\_32
  Matrice_Translation\_31 = Matrice_Finale\_33
  Matrice_Translation\_31 = Matrice_Finale\_34
  
  Matrice_Translation\_41 = Matrice_Finale\_41
  Matrice_Translation\_41 = Matrice_Finale\_42
  Matrice_Translation\_41 = Matrice_Finale\_43
  Matrice_Translation\_41 = Matrice_Finale\_44
  
  
  
  
  ; Mise à jour de tout les points 3D
  For z = 0 To 100
    For x = 0 To 100
      Map3D(x,z)\x = Matrice_Finale\_11*Sommet(x,z)\x + Matrice_Finale\_21*Sommet(x,z)\y + Matrice_Finale\_31*Sommet(x,z)\z + Matrice_Finale\_41
      Map3D(x,z)\y = Matrice_Finale\_12*Sommet(x,z)\x + Matrice_Finale\_22*Sommet(x,z)\y + Matrice_Finale\_32*Sommet(x,z)\z + Matrice_Finale\_42
      Map3D(x,z)\z = Matrice_Finale\_13*Sommet(x,z)\x + Matrice_Finale\_23*Sommet(x,z)\y + Matrice_Finale\_33*Sommet(x,z)\z + Matrice_Finale\_43
    Next x                                                                                                   
  Next z
  
  ; Projection3D2D()
EndProcedure

; Proc pour la rotation xyz de la matrice
Procedure Rotation(*Rotation.VECTOR3)
  
  
  Matrice_Rotation\_11 = Cos(*Rotation\z)*Cos(*Rotation\y)
  Matrice_Rotation\_12 = Cos(*Rotation\z)*Sin(*Rotation\y)*Sin(*Rotation\x) - Sin(*Rotation\z)*Cos(*Rotation\x)
  Matrice_Rotation\_13 = Cos(*Rotation\z)*Sin(*Rotation\y)*Cos(*Rotation\x) + Sin(*Rotation\z)*Sin(*Rotation\x)
  Matrice_Rotation\_14 = 0                                                                         
                                                                                                 
  Matrice_Rotation\_21 = Sin(*Rotation\z)*Cos(*Rotation\y)
  Matrice_Rotation\_22 = Sin(*Rotation\z)*Sin(*Rotation\y)*Sin(*Rotation\x) + Cos(*Rotation\x)*Cos(*Rotation\z)
  Matrice_Rotation\_23 = Sin(*Rotation\z)*Sin(*Rotation\y)*Cos(*Rotation\x) - Cos(*Rotation\z)*Sin(*Rotation\x)
  Matrice_Rotation\_24 = 0                                                                         
                                                                                                 
  Matrice_Rotation\_31 =-Sin(*Rotation\y)
  Matrice_Rotation\_32 = Sin(*Rotation\x)*Cos(*Rotation\y)
  Matrice_Rotation\_33 = Cos(*Rotation\x)*Cos(*Rotation\y)
  Matrice_Rotation\_34 = 0                    
                                          
  Matrice_Rotation\_41 = 0
  Matrice_Rotation\_42 = 0
  Matrice_Rotation\_43 = 0
  Matrice_Rotation\_44 = 1
   
EndProcedure


Procedure Free_Camera(*Camera.CAMERA)
  
  *Camera\Pitch = *Camera\Pitch - MouseDeltaY()/1000
  *Camera\Yaw   = *Camera\Yaw   - MouseDeltaX()/1000
  
  *Camera\LookAT\x = *Camera\Position\x + KeyboardPushed(#PB_Key_Up) * Cos((*Camera\Yaw))
  *Camera\LookAT\z = *Camera\Position\z + KeyboardPushed(#PB_Key_Up) * Sin((*Camera\Yaw))
  *Camera\LookAT\y = *Camera\Position\y + KeyboardPushed(#PB_Key_Up) * Sin((*Camera\Pitch)) 
  
  *Camera\Position\x = *Camera\LookAT\x + KeyboardPushed(#PB_Key_Up) * Cos((*Camera\Yaw))
  *Camera\Position\z = *Camera\LookAT\z + KeyboardPushed(#PB_Key_Up) * Sin((*Camera\Yaw))
  *Camera\Position\y = *Camera\LookAT\y + KeyboardPushed(#PB_Key_Up) * Sin((*Camera\Pitch))
  
  
  
  *Camera\Rotation\x= *Camera\Pitch+(#PI/180)
  *Camera\Rotation\y=-*Camera\Yaw+(270*#PI/180)
  *Camera\Rotation\z= *Camera\Roll  ; GLIMBAL LOCK   :(  
  
EndProcedure




InitMouse()


FPS_TIMER.l
FPS_COUNT.l
FPS_.l


;-BOUCLE PRINCIPALE
Repeat
  ClearScreen(0) : ExamineKeyboard() : ExamineMouse()
  
  ;======================================
  ;CALCUL DU FPS
  ;======================================
  If FPS_TIMER<ElapsedMilliseconds()
    FPS_TIMER=ElapsedMilliseconds()+1000
     FPS_=FPS_COUNT
      FPS_COUNT=0
    EndIf
    
    If FPS_TIMER>ElapsedMilliseconds()
      FPS_COUNT+1
    EndIf
  ;======================================
    
  
  ;======================================  
  Translation(Camera\Position) ; Procedure de translation
  Rotation(Camera\Rotation)    ; de rotation
  Free_Camera(Camera)          ; Gestion de la camera
  MultiplyMAT()                ; Multiplication des matrices de transformations
  ;======================================
  
  
  
  ;======================================
  StartDrawing(ScreenOutput())
  DrawText(0,0,"MATRICE3D SOFTWARE PAR CPL.BATOR.     FPS = "+Str(FPS_))
  Projection3D2D()             ; Projection à l'écran
  StopDrawing()
  ;======================================
  
  FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)

Publié : jeu. 28/sept./2006 15:40
par Anonyme
J'étais en train de posté en meme temps que toi, donc j'ai pas vu la question.
Quelle serait la différence entre l'accès à OpenGl entre BMax et PureBasic ?
Aucune idées, je ne connais pas BMax, mais en PureBasic c'est assez simple en fait cf: Embryon de moteur3D
il n'y a pas de grandes difficultée, la seule chose est de savoir utliser OpenGL, les commandes sont les mêmes.

@++

Publié : ven. 29/sept./2006 18:36
par Dr. Dri
@Cpl.Bator
Superbe démo :10:
(sauf que chez moi ca rame... rien d'ettonant)

j'ai juste trouvé un tout petit bug, je te ferais un screen

Dri

Publié : ven. 29/sept./2006 19:26
par Anonyme
Le bug c'est certainement les lignes qui ne collent pas trop aux vertices lors des rotations.

@++

Publié : ven. 29/sept./2006 19:53
par Dr. Dri
Non en fait c'est plutot qu'il manque des lignes ^^
Sur un des bords de la matrice

Dri

Publié : ven. 29/sept./2006 21:32
par Anonyme
ha oui, ce n'est pas vraiment un bug, c'est plus un oubli de ma part :oops:

@++

Publié : mar. 03/oct./2006 13:58
par Anonyme
Avec ce code , tu n'auras pas les bugs des lignes non-apparentes.
le code gère les faces de façon sommaire. (tracage des segment)

Code : Tout sélectionner

;============================================================================================
;-STRUCTURES DES OBJETS 3D
;============================================================================================
#Xoff=512
#Yoff=384
#Zoff=15

Structure VECTOR3
  x.f:y.f:z.f
EndStructure

Structure CAMERA
  Position.VECTOR3
  LookAT.VECTOR3
  Rotation.VECTOR3
  Pitch.f
  Yaw.f
  Roll.f
EndStructure

Structure VERTICES
 x.f
 y.f
 z.f
 WA.f
 WB.f
EndStructure

Structure FACES
 a.l:b.l:c.l
 AB.l:BC.l:CA.l 
 Triage.l
 z.f
 nx.f:ny.f:nz.f
 nx2.f:ny2.f:nz2.f
 Norme.f
EndStructure



Global NewList POINT3D.VERTICES()
Global NewList POINT2D.VERTICES()
Global NewList FACE.FACES()
Global NewList VERTEX.VERTICES()

Global Camera.CAMERA
Global CameraNorme.f

Global *ZBuffer.l = AllocateMemory(1024*768*4)


;============================================================================================
;-PROCEDURES MATHEMATIQUES   |   CALCULS MATRICIELLES
;============================================================================================



Structure MATRIX4x4
_11.f : _21.f : _31.f : _41.f 
_12.f : _22.f : _32.f : _42.f  
_13.f : _23.f : _33.f : _43.f  
_14.f : _24.f : _34.f : _44.f  
EndStructure  


Procedure MATRICE_Rotate_XYZ(*MATRICE.MATRIX4x4 , Xa.f,Ya.f,Za.f) 
   
 *MATRICE\_11 = Cos(Za)*Cos(Ya)                             : *MATRICE\_21 = Sin(Za)*Cos(Ya)                              : *MATRICE\_31 = -Sin(Ya)        :  *MATRICE\_41 = 0 
 *MATRICE\_12 = Cos(Za)*Sin(Ya)*Sin(Xa) - Sin(Za)*Cos(Xa)   : *MATRICE\_22 = Sin(Za)*Sin(Ya)*Sin(Xa) + Cos(Xa)*Cos(Za)    : *MATRICE\_32 = Sin(Xa)*Cos(Ya) :  *MATRICE\_42 = 0 
 *MATRICE\_13 = Cos(Za)*Sin(Ya)*Cos(Xa) + Sin(Za)*Sin(Xa)   : *MATRICE\_23 = Sin(Za)*Sin(Ya)*Cos(Xa) - Cos(Za)*Sin(Xa)    : *MATRICE\_33 = Cos(Xa)*Cos(Ya) :  *MATRICE\_43 = 0 
 *MATRICE\_14 = 0                                           : *MATRICE\_24 = 0                                            : *MATRICE\_34 = 0               :  *MATRICE\_44 = 1  
  
EndProcedure 

Procedure MATRICE_Translate_XYZ(*MATRICE.MATRIX4x4 , x.f,y.f,z.f) 
  Global V.VECTOR3
  
  *MATRICE\_11 = 1 : *MATRICE\_21 = 0 : *MATRICE\_31 = 0 : *MATRICE\_41 =  x
  *MATRICE\_12 = 0 : *MATRICE\_22 = 1 : *MATRICE\_32 = 0 : *MATRICE\_42 =  y
  *MATRICE\_13 = 0 : *MATRICE\_23 = 0 : *MATRICE\_33 = 1 : *MATRICE\_43 =  z
  *MATRICE\_14 = 0 : *MATRICE\_24 = 0 : *MATRICE\_34 = 0 : *MATRICE\_44 = 1 
  
  V\x=*MATRICE\_41
  V\y=*MATRICE\_42
  V\z=*MATRICE\_43
  
  
EndProcedure 

Procedure MATRICE_MULTIPLY(*m1.MATRIX4x4,*m2.MATRIX4x4,*MatriceF.MATRIX4x4)
  
  *MatriceF\_11 = *m1\_11 * *m2\_11 + *m1\_12 * *m2\_21 + *m1\_13 * *m2\_31 + *m1\_14 * *m2\_41 
  *MatriceF\_12 = *m1\_11 * *m2\_12 + *m1\_12 * *m2\_22 + *m1\_13 * *m2\_32 + *m1\_14 * *m2\_42 
  *MatriceF\_13 = *m1\_11 * *m2\_13 + *m1\_12 * *m2\_23 + *m1\_13 * *m2\_33 + *m1\_14 * *m2\_43 
  *MatriceF\_14 = *m1\_11 * *m2\_14 + *m1\_12 * *m2\_24 + *m1\_13 * *m2\_34 + *m1\_14 * *m2\_44 
  
  *MatriceF\_21 = *m1\_21 * *m2\_11 + *m1\_22 * *m2\_21 + *m1\_23 * *m2\_31 + *m1\_24 * *m2\_41 
  *MatriceF\_22 = *m1\_21 * *m2\_12 + *m1\_22 * *m2\_22 + *m1\_23 * *m2\_32 + *m1\_24 * *m2\_42 
  *MatriceF\_23 = *m1\_21 * *m2\_13 + *m1\_22 * *m2\_23 + *m1\_23 * *m2\_33 + *m1\_24 * *m2\_43 
  *MatriceF\_24 = *m1\_21 * *m2\_14 + *m1\_22 * *m2\_24 + *m1\_23 * *m2\_34 + *m1\_24 * *m2\_44 
  
  *MatriceF\_31 = *m1\_31 * *m2\_11 + *m1\_32 * *m2\_21 + *m1\_33 * *m2\_31 + *m1\_34 * *m2\_41 
  *MatriceF\_32 = *m1\_31 * *m2\_12 + *m1\_32 * *m2\_22 + *m1\_33 * *m2\_32 + *m1\_34 * *m2\_42 
  *MatriceF\_33 = *m1\_31 * *m2\_13 + *m1\_32 * *m2\_23 + *m1\_33 * *m2\_33 + *m1\_34 * *m2\_43 
  *MatriceF\_34 = *m1\_31 * *m2\_14 + *m1\_32 * *m2\_24 + *m1\_33 * *m2\_34 + *m1\_34 * *m2\_44 
  
  *MatriceF\_41 = *m1\_41 * *m2\_11 + *m1\_42 * *m2\_21 + *m1\_43 * *m2\_31 + *m1\_44 * *m2\_41 
  *MatriceF\_42 = *m1\_41 * *m2\_12 + *m1\_42 * *m2\_22 + *m1\_43 * *m2\_32 + *m1\_44 * *m2\_42 
  *MatriceF\_43 = *m1\_41 * *m2\_13 + *m1\_42 * *m2\_23 + *m1\_43 * *m2\_33 + *m1\_44 * *m2\_43 
  *MatriceF\_44 = *m1\_41 * *m2\_14 + *m1\_42 * *m2\_24 + *m1\_43 * *m2\_34 + *m1\_44 * *m2\_44 

EndProcedure  



Procedure Calculer_Normale()
  Protected SommetAFx.f,SommetAFy.f,SommetAFz.f
  Protected SommetBFx.f,SommetBFy.f,SommetBFz.f
  Protected SommetCFx.f,SommetCFy.f,SommetCFz.f
  
  
  
  Protected Dim a.f(3)
  Protected Dim b.f(3)
  
      ForEach FACE()
        
          SelectElement(VERTEX(),FACE()\a)
          SommetAFx = VERTEX()\x
          SommetAFy = VERTEX()\y
          SommetAFz = VERTEX()\z
          
          SelectElement(VERTEX(),FACE()\b)
          SommetBFx = VERTEX()\x
          SommetBFy = VERTEX()\y
          SommetBFz = VERTEX()\z
          
          SelectElement(VERTEX(),FACE()\c)
          SommetCFx = VERTEX()\x
          SommetCFy = VERTEX()\y
          SommetCFz = VERTEX()\z
        
          
              a(0) = SommetAFx - SommetBFx
              a(1) = SommetAFy - SommetBFy
              a(2) = SommetAFz - SommetBFz
              
              b(0) = SommetAFx - SommetCFx
              b(1) = SommetAFy - SommetCFy
              b(2) = SommetAFz - SommetCFz
           
               
              FACE()\nx = a(1)*b(2)-a(2)*b(1)
              FACE()\ny = a(2)*b(0)-a(0)*b(2)
              FACE()\nz = a(0)*b(1)-a(1)*b(0)
                  
              FACE()\Norme = Sqr(FACE()\nx*FACE()\nx + FACE()\ny*FACE()\ny + FACE()\nz*FACE()\nz)
          
        
      Next
   
EndProcedure








Procedure lineXY2(x1.f,y1.f,x2.f,y2.f,Couleur.l,Zstart.l,ZStop.l)
  Shared dx.f,dy.f,xincr.l,yincr.l,x.l,y.l,erreur.f,z
  
  If x1<>0 And y1<>0 And x2<>0 And y2<>0
    
    ;/* On initialise nos variables */
    dx = Abs(x2-x1)
    dy = Abs(y2-y1)
    
    If x1<x2
      xincr = 1
    Else
      xincr = -1
    EndIf
    
    If y1<y2
      yincr = 1
    Else
      yincr = -1
    EndIf
    
    
    ;/* Trace de ligne */
    
    x = x1
    y = y1
    
    If dx>dy
      
      erreur = dx/2  ; /* c'est plus esthetique comme ca */
      For i= 0 To dx
        
        x = x+xincr;
        erreur = erreur+dy
        If erreur > dx
          
          erreur = erreur - dx
          y = y+yincr
        EndIf
        If x>0 And x<1024-1 And y>0 And y<768-1
          Plot(x,y,Couleur)
        EndIf
      Next i
      
    Else
      erreur = dy/2;     /* c'est plus esthetique comme ca */
      For i=0 To dy
        y = y + yincr
        erreur = erreur + dx
        If erreur>dy
          erreur = erreur - dy
          x = x + xincr
        EndIf
        If x>0 And x<1024-1 And y>0 And y<768-1
          Plot(x,y,Couleur) 
        EndIf
      Next i
    EndIf
  EndIf   
EndProcedure


Procedure Trace_segment(a.l,b.l,Color.l)
  Protected ax.l,ay.l
  Protected bx.l,by.l
  Protected Zstart.l,ZStop.l
  
  SelectElement(POINT2D(),a)
  ax=POINT2D()\x
  ay=POINT2D()\y
  
  SelectElement(POINT2D(),b)
  bx=POINT2D()\x
  by=POINT2D()\y
  
  SelectElement(POINT3D(),a)
  Zstart = POINT3D()\z
  
  SelectElement(POINT3D(),b)
  ZStop = POINT3D()\z
  
  
  lineXY2(ax,ay,bx,by,Color,Zstart,ZStop)
  
  
EndProcedure

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

Procedure IsFace(*f.FACES)
  Protected a1.l,a2.l,b1.l,b2.l
  Protected FaceA.l,FaceB.l,FaceC.l
  Protected P2DAx.l,P2DBx.l,P2DCx.l
  Protected P2DAy.l,P2DBy.l,P2DCy.l
  
 ; FirstElement(FACE())
 ; FirstElement(POINT2D())
  
  SelectElement(FACE(),*f)
  
  FaceA = FACE()\a
  FaceB = FACE()\b
  FaceC = FACE()\c
  
  SelectElement(POINT2D(),FaceA )
  P2DAx = POINT2D()\x
  P2DAy = POINT2D()\y
  
  SelectElement(POINT2D(),FaceB )
  P2DBx = POINT2D()\x
  P2DBy = POINT2D()\y
  
  SelectElement(POINT2D(),FaceC )
  P2DCx = POINT2D()\x
  P2DCy = POINT2D()\y
  
  
  a1 = P2DAx - P2DBx 
  b1 = P2DAy - P2DBy 
  a2 = P2DCx - P2DBx 
  b2 = P2DCy - P2DBy 
  
  If (a1*b2-b1*a2)>0
    ProcedureReturn 0
  Else
    ProcedureReturn 1
  EndIf
  
EndProcedure

Procedure PROJECTION(*Matrice_Finale.MATRIX4x4)
  Protected ax.f,ay.f
  Protected bx.f,by.f
  Protected Za.f,zb.f,zc.f
  
  Static WaveSpeed.f
  
  WaveSpeed+0.1
  

  ForEach VERTEX()
    SelectElement(POINT3D(),ListIndex(VERTEX()))
    POINT3D()\x = *Matrice_Finale\_11*VERTEX()\x + *Matrice_Finale\_21*VERTEX()\y + *Matrice_Finale\_31*VERTEX()\z + *Matrice_Finale\_41
    POINT3D()\y = *Matrice_Finale\_12*VERTEX()\x + *Matrice_Finale\_22*VERTEX()\y + *Matrice_Finale\_32*VERTEX()\z + *Matrice_Finale\_42
    POINT3D()\z = *Matrice_Finale\_13*VERTEX()\x + *Matrice_Finale\_23*VERTEX()\y + *Matrice_Finale\_33*VERTEX()\z + *Matrice_Finale\_43
  Next
  
 
    
  ForEach POINT3D() : SelectElement(POINT2D(),ListIndex(POINT3D()))
    
    POINT3D()\WA=5 *Cos((ListIndex(POINT3D())*20*2*0.144)+WaveSpeed)
    POINT3D()\WB=5 *Sin((ListIndex(POINT3D())*20*2*0.144)+WaveSpeed)
    POINT3D()\y = POINT3D()\y - (POINT3D()\WB + POINT3D()\WA)/2
    ;POINT3D()\x = POINT3D()\x - (POINT3D()\WB + POINT3D()\WA)/2
    ;POINT3D()\z = POINT3D()\z - (POINT3D()\WB + POINT3D()\WA)/2
    
    
    POINT2D()\x=(POINT3D()\x*769)/(POINT3D()\z+#Zoff)+#Xoff
    POINT2D()\y=(POINT3D()\y*577)/(POINT3D()\z+#Zoff)+#Yoff
     
 
    ; If POINT2D()\x > 0 And POINT2D()\x < 1024-1 And POINT2D()\y > 0 And POINT2D()\y < 768-1 And POINT3D()\z>0
        ; ;Plot(POINT2D()\x,POINT2D()\y,RGB(255,255,255))
        ; DrawText(POINT2D()\x,POINT2D()\y,Str(ListIndex(POINT2D())))
    ; EndIf

  Next  
  

 
  
  ForEach FACE()
    
    FACE()\nx2 = *Matrice_Finale\_11*FACE()\nx + *Matrice_Finale\_21*FACE()\nx + *Matrice_Finale\_31*FACE()\nx + *Matrice_Finale\_41
    FACE()\ny2 = *Matrice_Finale\_12*FACE()\ny + *Matrice_Finale\_22*FACE()\ny + *Matrice_Finale\_32*FACE()\ny + *Matrice_Finale\_42
    FACE()\nz2 = *Matrice_Finale\_13*FACE()\nz + *Matrice_Finale\_23*FACE()\nz + *Matrice_Finale\_33*FACE()\nz + *Matrice_Finale\_43
                                                                                                  
    SelectElement(POINT3D(),FACE()\a)
    Za = POINT3D()\z
    SelectElement(POINT3D(),FACE()\b)
    zb = POINT3D()\z
    SelectElement(POINT3D(),FACE()\c)
    zc = POINT3D()\z
    
    
    
    If Za>0 And zb>0 : Trace_segment(FACE()\a,FACE()\b,RGB(255,0,128)) : EndIf 
    If zb>0 And zc>0 : Trace_segment(FACE()\b,FACE()\c,RGB(0,255,128)) : EndIf 
    If zc>0 And Za>0 : Trace_segment(FACE()\c,FACE()\a,RGB(0,0,255)) : EndIf 
  
   
  Next
  
  
  
 
  
EndProcedure




Procedure TriFaces()
  Protected Nb_visibles.l,P3DA.l,P3DB.l,P3DC.l

  ForEach FACE()
    If IsFace(ListIndex(FACE()))>0
      
      SelectElement(POINT3D(),FACE()\a)
      P3DA=POINT3D()\z
      SelectElement(POINT3D(),FACE()\b)
      P3DB=POINT3D()\z
      SelectElement(POINT3D(),FACE()\c)
      P3DC=POINT3D()\z
      
      
      FACE()\z = P3DA + P3DB + P3DC
      FACE()\Triage = ListIndex(FACE())
      
     Nb_visibles+1
  EndIf 
Next  
  SortStructuredList(FACE(),0,OffsetOf(FACES\Triage),#PB_Sort_Long)
  
EndProcedure

Procedure ADD_POINT3D(x.f,y.f,z.f)
  AddElement(POINT3D()) : AddElement(POINT2D()) : AddElement(VERTEX())
  VERTEX()\x = x : VERTEX()\y = y : VERTEX()\z = z
EndProcedure

Procedure Create_Face(a.l,b.l,c.l,d.l)
  AddElement(FACE())
  FACE()\a=a
  FACE()\b=b
  FACE()\c=c
  AddElement(FACE())
  FACE()\a=c
  FACE()\b=d
  FACE()\c=a
EndProcedure  



Procedure Free_Camera(*Camera.CAMERA)
  Protected Move.l,Cnx.f,Cny.f,Cnz.f

  ExamineMouse()
  Cnx= *Camera\Position\x - *Camera\LookAT\x 
  Cny= *Camera\Position\y - *Camera\LookAT\z 
  Cnz= *Camera\Position\z - *Camera\LookAT\y 
  
    Move = ((KeyboardPushed(#PB_Key_Up)/20)-(KeyboardPushed(#PB_Key_Down)/10))

  *Camera\Pitch = *Camera\Pitch - MouseDeltaY()/1000
  *Camera\Yaw   = *Camera\Yaw   - MouseDeltaX()/1000
  
  *Camera\LookAT\x = *Camera\Position\x + Move * Cos((*Camera\Yaw))
  *Camera\LookAT\z = *Camera\Position\z + Move * Sin((*Camera\Yaw))
  *Camera\LookAT\y = *Camera\Position\y + Move * Sin((*Camera\Pitch)) 
  

  
  *Camera\Position\x = *Camera\LookAT\x + Move * Cos((*Camera\Yaw))
  *Camera\Position\z = *Camera\LookAT\z + Move * Sin((*Camera\Yaw))
  *Camera\Position\y = *Camera\LookAT\y + Move * Sin((*Camera\Pitch))
                                                             
  
  *Camera\Rotation\x= *Camera\Pitch+(#PI/180)
  *Camera\Rotation\y=-*Camera\Yaw+(270*#PI/180)
  *Camera\Rotation\z= *Camera\Roll  ; GLIMBAL LOCK   :(  
  

                          
  CameraNorme = Sqr(Cnx*Cnx+Cny*Cny+Cnz*Cnz)
  
EndProcedure







;-BOUCLE PRINCIPALE

UsePNGImageDecoder()

; ;CUBE
; For y = 0 To 1000 Step 100
; For z = 0 To 1000 Step 100
  ; For x = 0 To 1000 Step 100
    ; ADD_POINT3D(x,y,z)
  ; Next
; Next
; Next 
; 
; 
; For h = 0 To 9
 ; For i = 0 To 9
  ; Create_Face(i+(h*121),i+1+(h*121),i+1+121+(h*121),i+121+(h*121))
 ; Next
; Next 
; 
; For h = 0 To 9
  ; For i = 0 To 9
    ; Create_Face((i*11)+(h*121),((i+1)*11)+(h*121),((i+1)*11)+121+(h*121),(i*11)+121+(h*121))
  ; Next
; Next 


For z = 0 To 1000 Step 50
  For x = 0 To 1000 Step 50
    
    ADD_POINT3D(x,0,z)
    
  Next   
Next


For j = 0 To 19
  For i = 0 To 19
   Create_Face(i+(j*21),i+1+(j*21),i+1+21+(j*21),i+21+(j*21))
  Next
Next j



Calculer_Normale()

InitSprite() : InitKeyboard() : InitMouse() 
OpenScreen(1024,768,32,"")



Global MatriceF.MATRIX4x4 
Global MatriceR.MATRIX4x4 
Global MatriceT.MATRIX4x4 


Camera\Position\z = -1000
Camera\Position\y = 500
Camera\Yaw = (45+90)*#PI/180     
Camera\Pitch = -45*#PI/180
 



Repeat
  ClearScreen(0) : ExamineKeyboard()
  

  Free_Camera(Camera)
  
  
  MATRICE_Translate_XYZ(MatriceT,Camera\Position\x,Camera\Position\y,Camera\Position\z)
  MATRICE_Rotate_XYZ(MatriceR,Camera\Rotation\x,Camera\Rotation\y,Camera\Rotation\z)
  MATRICE_MULTIPLY(MatriceT,MatriceR,MatriceF)

  StartDrawing(ScreenOutput())
  PROJECTION(MatriceF)
  StopDrawing()
  
     
      
      
  FlipBuffers(0)
Until KeyboardPushed(#PB_Key_Escape)

CloseScreen()