Page 2 sur 2

Publié : dim. 23/mai/2004 18:29
par comtois
Moi non plus je ne lache pas l'affaire. On ne va pas caler si près du but hein ? :)

Alors je résume comment je comprends la chose

D'abord un dessin , ça sera plus simple

Image

Comme un point peut appartenir de 1 à 6 triangles ,il faut d'abord calculer la normale pour chaque triangle ,ensuite , faire la moyenne pour chaque point .

Exemple le point 0 n'appartient qu'au triangle 1

Mais le point 5 appartient aux triangles 2,3,4,7,8,9

Pour moi , selon ce que j'ai compris , je devrai faire la moyenne
des normales des triangles 2,3,4,7,8,9 pour l'attribuer au point 5.
Et procéder ainsi pour chaque point.
Pour le point 0 c'est facile , ça sera la normale du triangle 1
pour le point 1 la moyenne des normales des triangles 1,2 et 3.
Et ainsi de suite .

Pour l'instant c'est comme ça que je comprends la chose .

Publié : lun. 24/mai/2004 9:15
par comtois
Nouvelle version , cette fois ci , la lumière ( et les ombres ) suivent bien le mouvement des vagues , ce qui n'était pas le cas dans la version précédente .

Pour modifier les vagues , utilisez les flèches , et les touches [PAgeUp] et [PageDown] pour la hauteur des vagues.

Par contre, le rendu n'est pas encore satisfaisant.

Et là pour l'instant je sèche , je ne sais pas comment améliorer la chose .

Code : Tout sélectionner

;-Constantes 
#ScreenWidth = 1024 
#ScreenHeight = 768 
#ScreenDepth = 32 

;-Structures 
Structure Vecteur 
  x.f 
  y.f 
  z.f 
EndStructure 
Structure Matrix 
  Largeur.f 
  Profondeur.f 
  NbFacetteX.l      ;>0 et <256 si FaceCachee=#False , ou <128 si FaceCachee=#True 
  NbFacetteZ.l      ;( j'ai pas encore vérifié si ça passe => à calculer) 
  FaceCachee.l      ; si =True on double les triangles pour voir l'entité des deux côtés 
  PointIDMemory.l 
  TriangleIDMemory.l 
  TextureIDMemory.l 
  NormaleIDMemory.l 
EndStructure 

;-Variables 
Global Matrix.Matrix 
Global CamLocateX.f, CamLocateY.f, CamLocateZ.f,CamLocateX.f,CamLocateY.f,CamLocateZ.f 
Global decaleX.l,decaleZ.l,HauteurVague.l
Global Mode.b ,AngleVague.f,Vitesse.f,ShadingMode.b,NormaleInverse.l,Animation.l

;-Declare
Declare HauteurPoint(x.l, z.l, Hauteur.f) 
Declare HauteurFacette(x.l, z.l, Hauteur.f)
Declare Matrice() 
Declare normalise(*n.Vecteur)
Declare NormalesMatrice() 
Declare.f Wrapvalue(Angle.f)
Declare.f Sind( Angle.f)
Declare vagues()
Declare GestionTouches()
Declare AfficheAide() 
; 
;- Main starts here 
; 
If InitEngine3D() And InitSprite() And InitKeyboard() And OpenScreen(#ScreenWidth, #ScreenHeight, #ScreenDepth, "FRW Matrix") 
  ;/Divers 
  Vitesse=2.0 
  HauteurVague=260
  decaleX=-2
  decaleZ=-2
  Animation = 1
  ;/Paramètres de la matrice 
  Matrix\Largeur    = 1000 
  Matrix\Profondeur = 1000 
  Matrix\NbFacetteX = 50 
  Matrix\NbFacetteZ = 50 
  Matrix\FaceCachee = #True 
  Matrix\PointIDMemory    = AllocateMemory(12 * (Matrix\NbFacetteX + 1) * (Matrix\NbFacetteZ + 1)) 
  Matrix\TriangleIDMemory = AllocateMemory(12 * Matrix\NbFacetteX * Matrix\NbFacetteZ * 4) 
  Matrix\TextureIDMemory  = AllocateMemory(12 * (Matrix\NbFacetteX + 1) * (Matrix\NbFacetteZ + 1)) 
  Matrix\NormaleIDMemory  = AllocateMemory(12 * (Matrix\NbFacetteX + 1) * (Matrix\NbFacetteZ + 1)) 
  Dim Points.Vecteur((Matrix\NbFacetteX+1)*(Matrix\NbFacetteZ+1))
  Matrice() 
  NormaleInverse = -1
  ;/Mesh 
  CreateMesh(0) 
  SetMeshData(0, 0, Matrix\PointIDMemory   , (Matrix\NbFacetteX + 1) * (Matrix\NbFacetteZ + 1)) 
  SetMeshData(0, 1, Matrix\TriangleIDMemory, (Matrix\NbFacetteX) * (Matrix\NbFacetteZ) * 4) 
  SetMeshData(0, 2, Matrix\TextureIDMemory , (Matrix\NbFacetteX + 1) * (Matrix\NbFacetteZ + 1)) 
  SetMeshData(0, 3, Matrix\NormaleIDMemory , (Matrix\NbFacetteX + 1) * (Matrix\NbFacetteZ + 1))  
  
  ;/Texture 
  ;/Sans image 
  TextureXSize = 256 
  TextureYSize = 256 
;   CreateTexture(0, TextureXSize, TextureYSize) 
;   StartDrawing(TextureOutput(0)) 
;     Box(0, 0, TextureXSize/3, TextureYSize, #Blue) 
;     Box(TextureXSize/3, 0, TextureXSize*2/3, TextureYSize, #White)
;     Box(TextureXSize*2/3, 0, TextureXSize, TextureYSize, #Red)
;     DrawingMode(4) 
;     Box(0, 0, TextureXSize , TextureYSize , #White) 
;   StopDrawing() 
  
  ;/Avec une image    
  UsePNGImageDecoder() 
  LoadImage(0,"data\purebasiclogonew.png")  
  ResizeImage(0,TextureXSize,TextureYSize)
  CreateTexture(0,TextureXSize,TextureYSize) 
  StartDrawing(TextureOutput(0)) 
  DrawImage(UseImage(0), 0, 0) 
  DrawingMode(4) 
  Box(1, 1, TextureXSize - 2, TextureYSize - 2, RGB(255,255,255)) 
  StopDrawing() 
  
  ;/Material 
  CreateMaterial(0, TextureID(0)) ; Material 
  ;MaterialFilteringMode(0, #PB_Material_Trilinear) 
  MaterialShadingMode(0, #PB_Material_Gouraud)
  
  ;/Entity 
  CreateEntity(0, MeshID(0), MaterialID(0)) 
  
  ;/Caméra 
  CamLocateX = 0 
  CamLocateY = 845 
  CamLocateZ = 915 
  CamLookAtX = EntityX(0) 
  CamLookAtY = EntityY(0) 
  CamLookAtZ = EntityZ(0) 
  CreateCamera(0, 0, 0, 100, 100) 
  CameraLocate(0, CamLocateX, CamLocateY, CamLocateZ) 
  CameraLookAt(0,CamLookAtX,CamLookAtY,CamLookAtZ)
  ;/Lumière 
  AmbientColor(RGB(110,110,140)) 
  CreateLight(0,RGB(200,200,255)) 
  LightLocate(0, EntityX(0)/2, 700, EntityZ(0)/2) 
  ;LightLocate(0, -200, 600, -200) 
 
  Repeat 
    ClearScreen(0, 0, 0) 
    ExamineKeyboard() 
   
    If Animation 
      AngleVague = Wrapvalue(AngleVague + Vitesse)
    EndIf   
    ;/Donne une forme à la matrice 
    vagues() 
    NormalesMatrice()    
    RenderWorld() 
    GestionTouches() ; Placé après RenderWorld sinon le snapshot ne fonctionne pas !
    AfficheAide()    
    FlipBuffers() 
  Until KeyboardPushed(#PB_Key_Escape) 
Else 
  MessageRequester("Error", "Something fails to initialize 3D engine", 0) 
EndIf 
End

;/
;-Procedures
;/
Procedure.f distance(*P1.Vecteur,*P2.Vecteur) 
  x.f = *P1\x - *P2\x  
  y.f = *P1\y - *P2\y  
  z.f = *P1\z - *P2\z 
  d.f = x*x + y*y + z*z 
  ProcedureReturn Sqr(d)
EndProcedure 
Procedure calculVecteurNorme(*pi.Vecteur,*pf.Vecteur,*n.Vecteur) 
  x.f = *pf\x - *pi\x 
  y.f = *pf\y - *pi\y 
  z.f = *pf\z - *pi\z
  d.f = distance(*pi,*pf) 
  *n\x =x / d 
  *n\y =y / d 
  *n\z =z / d 
EndProcedure 
Procedure normalise(*n.Vecteur) 
  d.f = Sqr(*n\x * *n\x + *n\y * *n\y + *n\z * *n\z) 
  *n\x / d 
  *n\y / d 
  *n\z / d 
EndProcedure
Procedure produitVectoriel(*v1.Vecteur,*v2.Vecteur,*n.Vecteur) 
  *n\x = *v1\y * *v2\z - *v1\z * *v2\y
  *n\y = *v1\z * *v2\x - *v1\x * *v2\z
  *n\z = *v1\x * *v2\y - *v1\y * *v2\x
EndProcedure
Procedure HauteurPoint(x.l, z.l, Hauteur.f) 
  If x > -1 And x <= Matrix\NbFacetteX And z > -1 And z <= Matrix\NbFacetteZ 
    Adresse = Matrix\PointIDMemory + 4 
    Adresse = Adresse + (x + (z * (Matrix\NbFacetteX + 1))) * 12 
    PokeF(Adresse, Hauteur) 
    SetMeshData(0, 0, Matrix\PointIDMemory, (Matrix\NbFacetteX + 1) * (Matrix\NbFacetteZ + 1)) 
    ProcedureReturn #True 
  Else 
    ProcedureReturn #False 
  EndIf  
EndProcedure 
Procedure HauteurFacette(x.l, z.l, Hauteur.f) 
  If x > 0 And x <= Matrix\NbFacetteX And z > 0 And z <= Matrix\NbFacetteZ 
    Adresse = Matrix\PointIDMemory + 4 
    Adresse + (x + (z * (Matrix\NbFacetteX + 1))) * 12 
    PokeF(Adresse, Hauteur) 
    Adresse - 12 
    PokeF(Adresse, Hauteur) 
    Adresse  - (Matrix\NbFacetteX + 1) * 12 
    PokeF(Adresse, Hauteur) 
    Adresse + 12 
    PokeF(Adresse, Hauteur) 
    SetMeshData(0, 0, Matrix\PointIDMemory, (Matrix\NbFacetteX + 1) * (Matrix\NbFacetteZ + 1)) 
    ProcedureReturn #True 
  Else 
    ProcedureReturn #False 
  EndIf  
EndProcedure 
Procedure Matrice() 
  TailleFacetteX.f = Matrix\Largeur / Matrix\NbFacetteX 
  TailleFacetteZ.f = Matrix\Profondeur / Matrix\NbFacetteZ 
  
  ;/Points 
  Adresse = Matrix\PointIDMemory 
  For b = 0 To Matrix\NbFacetteZ 
    For a = 0 To Matrix\NbFacetteX 
      PokeF(Adresse, (a - Matrix\NbFacetteX / 2) * TailleFacetteX) 
      PokeF(Adresse + 4, 0) 
      PokeF(Adresse + 8, (b - Matrix\NbFacetteZ / 2) * TailleFacetteZ) 
      Adresse + 12 
    Next 
  Next 
  
  ;/Triangles 
  If Matrix\FaceCachee 
    Nbtriangle.l = 4 
  Else 
    Nbtriangle = 2 
  EndIf  
  Index = 6 * Nbtriangle 
  Adresse = Matrix\TriangleIDMemory 
  
  NbPointX = Matrix\NbFacetteX + 1 
  For b = 0 To Matrix\NbFacetteZ - 1 
    For a = 0 To Matrix\NbFacetteX - 1 
      P1 = a + (b * NbPointX) 
      P2 = P1 + 1 
      P3 = a + (b + 1) * NbPointX 
      P4 = P3 + 1 
      ;Triangle impaire
      PokeW(Adresse     , P3) 
      PokeW(Adresse +  2, P2) 
      PokeW(Adresse +  4, P1) 
      ;Triangle paire
      PokeW(Adresse +  6, P2) 
      PokeW(Adresse +  8, P3) 
      PokeW(Adresse + 10, P4) 
      
      If Matrix\FaceCachee 
        PokeW(Adresse + 12, P1) 
        PokeW(Adresse + 14, P2) 
        PokeW(Adresse + 16, P3) 
        PokeW(Adresse + 18, P4) 
        PokeW(Adresse + 20, P3) 
        PokeW(Adresse + 22, P2) 
      EndIf 
      Adresse + Index 
    Next 
  Next 
  
  ;/Texture 
  Adresse = Matrix\TextureIDMemory 
  For b = 0 To Matrix\NbFacetteZ 
    For a = 0 To Matrix\NbFacetteX 
      PokeF(Adresse, a / Matrix\NbFacetteX) 
      PokeF(Adresse + 4, b / Matrix\NbFacetteZ) 
      Adresse + 8 
    Next 
  Next 
  
EndProcedure 
Procedure NormalesMatrice() 
  Vecteur1.Vecteur 
  Vecteur2.Vecteur 

  P1.Vecteur ; Point 1 de la Facette 
  P2.Vecteur ; Point 2 de la Facette  
  P3.Vecteur ; Point 3 de la Facette
  P4.Vecteur ; Point 4 de la Facette
  
  Normale1.Vecteur ; Normale Triangle 1 de la Facette Points 1,2,3
  Normale2.Vecteur ; Normale Triangle 2 de la Facette Points 2,4,3
  
  Adresse = Matrix\PointIDMemory + 4 
  AdrNormale = Matrix\NormaleIDMemory 
  TailleFacetteX.f = Matrix\Largeur / Matrix\NbFacetteX 
  TailleFacetteZ.f = Matrix\Profondeur / Matrix\NbFacetteZ 
  NbPointX = Matrix\NbFacetteX + 1
  NbPointZ = Matrix\NbFacetteZ + 1
  
  For z = 0 To Matrix\NbFacetteZ - 1
    For x = 0 To Matrix\NbFacetteX - 1 
         
      NoPoint1 = x + z * NbPointX
      P1\x = x 
      P1\y = PeekF(Adresse + (x + (z * (Matrix\NbFacetteX + 1))) * 12) 
      P1\z = z 
      
      NoPoint2 = NoPoint1 + 1
      P2\x = x + 1
      P2\y = PeekF(Adresse + (x + 1 + (z * (Matrix\NbFacetteX + 1))) * 12) 
      P2\z = z 
      
      NoPoint3 = x + (z + 1) * NbPointX
      P3\x = x  
      P3\y = PeekF(Adresse + (x + ((z + 1) * (Matrix\NbFacetteX + 1))) * 12) 
      P3\z = z + 1
      
      NoPoint4 = NoPoint3 + 1
      P4\x = x + 1 
      P4\y = PeekF(Adresse + (x + 1 + ((z + 1) * (Matrix\NbFacetteX + 1))) * 12) 
      P4\z = z + 1
      
      calculVecteurNorme(@P1,@P2,@Vecteur1)
      calculVecteurNorme(@P1,@P3,@Vecteur2)
      produitVectoriel(@Vecteur1,@Vecteur2,@Normale1)
      calculVecteurNorme(@P2,@P4,@Vecteur1)
      calculVecteurNorme(@P2,@P3,@Vecteur2)
      produitVectoriel(@Vecteur1,@Vecteur2,@Normale2)

      Points(NoPoint1)\x + Normale1\x
      Points(NoPoint1)\y + Normale1\y
      Points(NoPoint1)\z + Normale1\z
      
      Points(NoPoint2)\x + Normale1\x + Normale2\x
      Points(NoPoint2)\y + Normale1\y + Normale2\y
      Points(NoPoint2)\z + Normale1\z + Normale2\z
      
      Points(NoPoint3)\x + Normale1\x + Normale2\x
      Points(NoPoint3)\y + Normale1\y + Normale2\y
      Points(NoPoint3)\z + Normale1\z + Normale2\z
      
      Points(NoPoint4)\x + Normale2\x
      Points(NoPoint4)\y + Normale2\y
      Points(NoPoint4)\z + Normale2\z

    Next x 
  Next z   
  No=0
  For z = 0 To Matrix\NbFacetteZ 
    For x = 0 To Matrix\NbFacetteX 
      Magnitude.f = Sqr(Points(No)\x * Points(No)\x + Points(No)\y * Points(No)\y + Points(No)\z * Points(No)\z) 
      Points(No)\x / Magnitude 
      Points(No)\y / Magnitude 
      Points(No)\z / Magnitude 
      PokeF(AdrNormale    , Points(No)\x * NormaleInverse)
      PokeF(AdrNormale + 4, Points(No)\y * NormaleInverse)
      PokeF(AdrNormale + 8, Points(No)\z * NormaleInverse)
      No + 1
      AdrNormale + 12 
    Next x
  Next z  
  SetMeshData(0, 3, Matrix\NormaleIDMemory , (Matrix\NbFacetteX + 1) * (Matrix\NbFacetteZ + 1)) 
EndProcedure 
Procedure.f Wrapvalue(Angle.f) 
  Angle / 360 
  Angle - Int(Angle) 
  If Angle < 0 
    ProcedureReturn (Angle + 1) * 360 
  Else 
    ProcedureReturn Angle * 360 
  EndIf 
EndProcedure 
Procedure.f Sind( Angle.f ) 
  ;calcule le sin d'un angle en degré 
  a.f = Angle  * 0.0174533 
  ProcedureReturn Sin( a ) 
EndProcedure 
Procedure vagues() 
  Adresse = Matrix\PointIDMemory + 4 
  For z = 0 To Matrix\NbFacetteZ 
    For x = 0 To Matrix\NbFacetteX 
      Sommet.f = Sind(AngleVague + (x * decaleX) + (z * decaleZ)) * HauteurVague 
      PokeF(Adresse, Sommet) 
      Adresse + 12 
    Next x 
  Next z 
  SetMeshData(0, 0, Matrix\PointIDMemory, (Matrix\NbFacetteX + 1) * (Matrix\NbFacetteZ + 1)) 
EndProcedure 
Procedure GestionTouches() 
  If KeyboardReleased(#PB_Key_F1) 
    Mode = #PB_Camera_Wireframe - Mode 
    CameraRenderMode(0, Mode) 
  EndIf 
  If KeyboardReleased(#PB_Key_F2) 
    MaterialShadingMode(0, #PB_Material_Flat) 
  EndIf  
  If KeyboardReleased(#PB_Key_F3) 
    MaterialShadingMode(0, #PB_Material_Gouraud) 
  EndIf 
  If KeyboardReleased(#PB_Key_F4) 
    MaterialShadingMode(0, #PB_Material_Phong) 
  EndIf 
  If KeyboardReleased(#PB_Key_F5) 
    Animation = 1 - Animation
  EndIf 
  If KeyboardReleased(#PB_Key_F6) 
    NormaleInverse * -1
  EndIf 
  decaleX - 1 * KeyboardPushed(#PB_Key_Left) / 128 
  decaleX + 1 * KeyboardPushed(#PB_Key_Right) / 128 
  HauteurVague + 1 * KeyboardPushed(#PB_Key_PageUp) / 128 
  HauteurVague - 1 * KeyboardPushed(#PB_Key_PageDown) / 128 
  decaleZ + 1 * KeyboardPushed(#PB_Key_Up) / 128 
  decaleZ - 1 * KeyboardPushed(#PB_Key_Down) / 128 
  
  ;SnapShot 
  If KeyboardReleased(#PB_Key_F12)
    hBitmap = CreateImage(0, #ScreenWidth, #ScreenHeight)
    hdc = StartDrawing(ImageOutput())
    SelectObject_(hdc, hBitmap)
    BitBlt_(hdc, 0, 0, #ScreenWidth, #ScreenHeight, GetDC_(GetDesktopWindow_()), 0, 0, #SRCCOPY)
    StopDrawing()
    DeleteDC_(hdc)
    SetClipboardData(#PB_ClipboardImage, ImageID()) 
  EndIf
EndProcedure 
Procedure AfficheAide() 
  StartDrawing(ScreenOutput()) 
  DrawingMode(1) 
  FrontColor(255,255,255) 
  Locate(10,10) 
  DrawText("DecaleX = " + StrF(decaleX)) 
  Locate(10,30) 
  DrawText("DecaleZ = " + StrF(decaleZ)) 
  Locate(10,50) 
  DrawText("HauteurVague = " + StrF(HauteurVague)) 
  Locate(10,70) 
  DrawText("[F1] => Change Mode Caméra") 
  Locate(10,90) 
  DrawText("[F2] => MaterialSharingMode=> Flat") 
  Locate(10,110) 
  DrawText("[F3] => MaterialSharingMode=> Gouraud") 
  Locate(10,130) 
  DrawText("[F4] => MaterialSharingMode=> Phong") 
  Locate(10,150) 
  DrawText("[F5] => Marche/Arrêt Animation des vagues") 
  StopDrawing() 
EndProcedure  

Publié : lun. 24/mai/2004 9:39
par fweil
Comtois,

Ou-je-me-trompe-je ou bien les vagues sont éclairées de deux côtés ?

Il n'y a qu'une source lumineuse, mais il me semble en regardant bien l'animation que l'éclairement est bien situé depuis le bas droite, mais aussi le haut gauche ...

C'est juste pour bien comprendre.

Slts

Publié : lun. 24/mai/2004 10:03
par comtois
Comme j'avais du mal à observer ce que tu me dis , j'ai ajouté la touche [F5] pour activer l'animation, c'est plus facile pour voir ce qui se passe .

Et suite à ta remarque , j'en ai profité pour inverser les normales.
En faisant *-1 pour l'instant, il faudra que je trouve où je me suis trompé , je ne devrais pas faire ce *-1 normalement ?

En inversant les normale je trouve que la lumière rend mieux, mais c'est encore crénelé .

(J'ai édité le post précédent pour mettre à jour le code)


[EDIT] En effet ,quand je déplace la lumière j'observe des ombres étranges , mais pour en être certain , je vais ajouter une entity pour matérialiser la source de lumière , et je placerai la lumière au même emplacement que l'entity . C'est pas pour tout de suite ,là je vais bosser :)

Publié : lun. 24/mai/2004 22:13
par comtois
Dans cette version je gère la lumière avec la souris .
Clic gauche pour monter la lumière
Clic droit pour baisser la lumière
et la souris pour déplacer la lumière.ça donne un effet spot intéressant .

J'aime bien la déformation de la lumière sur les vagues avec par exemple
Lumiere\y=970 environ
HauteurVague = 27 environ
Et decaleX et DecaleZ = 4 environ , et ensuite baladez la lumiere.

J'ai augmenté le nombre de facettes pour diminuer l'effet de crenelure .
Si c'est trop lent , il est possible de diminuer
Matrix\NbFacetteX et Matrix\NbFacetteZ
La prochaine fois , va falloir songer à optimiser les calculs , comment ? ça c'est une autre histoire :)

[EDIT] Je viens de refaire quelques tests ,et effectivement il y a encore quelque chose qui ne va pas !!

Quand HauteurVague = 0 , là ça fonctionne bien , je vois la lumière si lumiere\y >0 dès que la valeur est inférieur à 0 , je ne vois plus de lumière, c'est normal . Par contre si je mets des vagues avec HauteurVague = 30 par exemple , alors là même si je place la lumière à -400 , je vois toujours des reflets sur les vagues :? Bon avant d'optimiser , va falloir encore trouver l'erreur #pendu

Code : Tout sélectionner

;Comtois le 25 mai 2004
;Merci à François Weil pour l'optimisation du code :) 

;-Constantes 
#ScreenWidth = 1024 
#ScreenHeight = 768 
#ScreenDepth = 32 

;-Structures 
Structure Vecteur 
  x.f 
  y.f 
  Z.f 
EndStructure 
Structure Lumiere 
  Couleur.l 
  x.f 
  y.f 
  Z.f 
EndStructure  
Structure Matrice 
  Largeur.f 
  Profondeur.f 
  NbFacetteX.l      
  NbFacetteZ.l     
  FaceVisible.l      ; si = #True on double les triangles pour voir l'entité des deux côtés 
  NbPointX.l
  NbPointZ.l
  Nbtriangle.l
  TailleFacetteX.f   ; Je ne sais pas si je vais garder cette méthode 
  TailleFacetteZ.f   ; Je ne sais pas si je vais garder cette méthode  
  PointIDMemory.l 
  TriangleIDMemory.l 
  TextureIDMemory.l 
  NormaleIDMemory.l 
EndStructure 

;-Variables 
Global Matrice.Matrice 
Global Lumiere.Lumiere 
Global CamLocateX.f, CamLocateY.f, CamLocateZ.f,CamLocateX.f,CamLocateY.f,CamLocateZ.f 
Global decaleX.l,decaleZ.l,HauteurVague.l 
Global Mode.b ,AngleVague.l,Vitesse.l,ShadingMode.b,Animation.l,AfficheAide.l 

;-Declare 
Declare Matrice() 
Declare NormalesMatrice() 
Declare vagues() 
Declare GestionTouches() 
Declare GestionSouris() 
Declare AfficheAide() 

; 
;- Main starts here 
; 
If InitEngine3D() And InitSprite() And InitKeyboard() And InitMouse() And OpenScreen(#ScreenWidth, #ScreenHeight, #ScreenDepth, "FRW Matrice") 
  ;/Divers 
  Vitesse=3 
  HauteurVague=10 
  decaleX=0 
  decaleZ=0 
  Animation = 1 
  AfficheAide = 1
  
  ;/Paramètres de la matrice (à renseigner)
  Matrice\Largeur    = 1000 
  Matrice\Profondeur = 1000 
  Matrice\NbFacetteX = 100 
  Matrice\NbFacetteZ = 100 
  Matrice\FaceVisible = #False ; #True double les triangles pour rendre visible l'autre face de la matrice
  
  ;/Quelques informations complémentaires sur la matrice ( Calculées )
  If Matrice\FaceVisible 
    Matrice\Nbtriangle = 4
  Else
    Matrice\Nbtriangle = 2
  EndIf  
  Matrice\NbPointX = Matrice\NbFacetteX + 1
  Matrice\NbPointZ = Matrice\NbFacetteZ + 1
  Matrice\TailleFacetteX = Matrice\Largeur / Matrice\NbFacetteX 
  Matrice\TailleFacetteZ = Matrice\Profondeur / Matrice\NbFacetteZ 
  Matrice\PointIDMemory    = AllocateMemory(12 * Matrice\NbPointX * Matrice\NbPointZ) 
  Matrice\TriangleIDMemory = AllocateMemory(12 * Matrice\NbFacetteX * Matrice\NbFacetteZ * Matrice\Nbtriangle) 
  Matrice\TextureIDMemory  = AllocateMemory(12 * Matrice\NbPointX * Matrice\NbPointZ)  
  Matrice\NormaleIDMemory  = AllocateMemory(12 * Matrice\NbPointX * Matrice\NbPointZ)  
  Dim Points.Vecteur(Matrice\NbPointX * Matrice\NbPointZ) 
  Matrice()
  
  ;/Mesh 
  CreateMesh(0) 
  SetMeshData(0, 0, Matrice\PointIDMemory   , Matrice\NbPointX * Matrice\NbPointZ) 
  SetMeshData(0, 1, Matrice\TriangleIDMemory, Matrice\NbFacetteX * Matrice\NbFacetteZ * Matrice\Nbtriangle) 
  SetMeshData(0, 2, Matrice\TextureIDMemory , Matrice\NbPointX * Matrice\NbPointZ)  
  SetMeshData(0, 3, Matrice\NormaleIDMemory , Matrice\NbPointX * Matrice\NbPointZ)  
  
  ;/Texture 
  ;/Sans image 
  TextureXSize = 256 
  TextureYSize = 256 
  ;   CreateTexture(0, TextureXSize, TextureYSize) 
  ;   StartDrawing(TextureOutput(0)) 
  ;     Box(0, 0, TextureXSize/3, TextureYSize, #Blue) 
  ;     Box(TextureXSize/3, 0, TextureXSize*2/3, TextureYSize, #White) 
  ;     Box(TextureXSize*2/3, 0, TextureXSize, TextureYSize, #Red) 
  ;     DrawingMode(4) 
  ;     Box(0, 0, TextureXSize , TextureYSize , #White) 
  ;   StopDrawing() 
  
  ;/Avec une image    
  UsePNGImageDecoder() 
  LoadImage(0,"data\purebasiclogonew.png")  
  ResizeImage(0,TextureXSize,TextureYSize) 
  CreateTexture(0,TextureXSize,TextureYSize) 
  StartDrawing(TextureOutput(0)) 
  DrawImage(UseImage(0), 0, 0) 
  DrawingMode(4) 
  Box(1, 1, TextureXSize - 2, TextureYSize - 2, RGB(255,255,255)) 
  StopDrawing() 
  
  ;/Material 
  CreateMaterial(0, TextureID(0)) ; Material 
  ;MaterialFilteringMode(0, #PB_Material_Trilinear) 
  MaterialShadingMode(0, #PB_Material_Gouraud) 
  
  ;/Entity 
  CreateEntity(0, MeshID(0), MaterialID(0)) 
  
  ;/Caméra 
  CamLocateX = 0 
  CamLocateY = 845 
  CamLocateZ = 915 
  CamLookAtX = EntityX(0) 
  CamLookAtY = EntityY(0) 
  CamLookAtZ = EntityZ(0) 
  CreateCamera(0, 0, 0, 100, 100) 
  CameraLocate(0, CamLocateX, CamLocateY, CamLocateZ) 
  CameraLookAt(0,CamLookAtX,CamLookAtY,CamLookAtZ) 
  
  ;/Lumière 
  AmbientColor(RGB(110,110,140)) 
  Lumiere\Couleur = RGB(255,255,255) 
  Lumiere\x = EntityX(0)/2 
  Lumiere\y = 960 
  Lumiere\Z = EntityZ(0)/2 
  CreateLight(0,Lumiere\Couleur)  
  LightLocate(0,Lumiere\x, Lumiere\y, Lumiere\Z) 
  
  Repeat 
    ClearScreen(0, 0, 0) 
    ExamineKeyboard() 
    If Animation 
      AngleVague = (AngleVague + Vitesse) % 360 
    EndIf    
    GestionSouris() 
    ;/Donne une forme à la matrice 
    vagues() 
    NormalesMatrice()    
    RenderWorld() 
    GestionTouches() ; Placé après RenderWorld sinon le snapshot ne fonctionne pas ! 
    If AfficheAide : AfficheAide() : EndIf    
    FlipBuffers() 
  Until KeyboardPushed(#PB_Key_Escape) 
Else 
  MessageRequester("Error", "Something fails to initialize 3D engine", 0) 
EndIf 
End 

;/ 
;-Procedures 
;/ 
Procedure calculVecteurNorme(*v1.Vecteur,*v2.Vecteur,*n.Vecteur) 
  x.f = *v2\x - *v1\x 
  y.f = *v2\y - *v1\y 
  Z.f = *v2\Z - *v1\Z 
  d.f = Sqr(x * x + y * y + Z * Z) 
  *n\x =x / d 
  *n\y =y / d 
  *n\Z =Z / d 
EndProcedure 

Procedure produitVectoriel(*v1.Vecteur,*v2.Vecteur,*n.Vecteur) 
  *n\x = *v1\y * *v2\Z - *v1\Z * *v2\y 
  *n\y = *v1\Z * *v2\x - *v1\x * *v2\Z 
  *n\Z = *v1\x * *v2\y - *v1\y * *v2\x 
EndProcedure 

Procedure Matrice() 
  Adresse1 = Matrice\PointIDMemory    ; Adresse Points
  Adresse2 = Matrice\TextureIDMemory  ; Adresse Texture
  For b = 0 To Matrice\NbFacetteZ 
    For a = 0 To Matrice\NbFacetteX 
      ;/Points
      PokeF(Adresse1, (a - Matrice\NbFacetteX / 2) * Matrice\TailleFacetteX) 
      PokeF(Adresse1 + 4, 0) 
      PokeF(Adresse1 + 8, (b - Matrice\NbFacetteZ / 2) * Matrice\TailleFacetteZ) 
      Adresse1 + 12 
      ;/Texture
      PokeF(Adresse2, a / Matrice\NbFacetteX) 
      PokeF(Adresse2 + 4, b / Matrice\NbFacetteZ) 
      Adresse2 + 8 
    Next 
  Next 
  
  ;/Triangles 
  Index = 6 * Matrice\Nbtriangle 
  Adresse = Matrice\TriangleIDMemory 
  
  For b = 0 To Matrice\NbFacetteZ - 1 
    bx = b * Matrice\NbPointX 
    For a = 0 To Matrice\NbFacetteX - 1 
      P1 = a + bx 
      P2 = P1 + 1 
      P3 = a + bx + Matrice\NbPointX 
      P4 = P3 + 1 
      PokeL(Adresse, P2 << 16 + P3) 
      PokeL(Adresse + 4, P2 << 16 + P1) 
      PokeL(Adresse + 8, P4 << 16 + P3) 
      If Matrice\FaceVisible 
        PokeL(Adresse + 12, P2 << 16 + P1) 
        PokeL(Adresse + 16, P4 << 16 + P3) 
        PokeL(Adresse + 20, P2 << 16 + P3) 
      EndIf 
      Adresse + Index 
    Next 
  Next 
  
EndProcedure 
Procedure NormalesMatrice() 
  Vecteur1.Vecteur 
  Vecteur2.Vecteur 
  
  P1.Vecteur ; Point 1 de la Facette 
  P2.Vecteur ; Point 2 de la Facette  
  P3.Vecteur ; Point 3 de la Facette 
  P4.Vecteur ; Point 4 de la Facette 
  
  Normale1.Vecteur ; Normale Triangle 1 de la Facette Points 1,2,3 
  Normale2.Vecteur ; Normale Triangle 2 de la Facette Points 2,4,3 
  
  Adresse = Matrice\PointIDMemory + 4 
  AdrNormale = Matrice\NormaleIDMemory 
 
  For Z = 0 To Matrice\NbFacetteZ - 1 
    zx = Z * Matrice\NbPointX 
    zx1 = zx + Matrice\NbPointX 
    For x = 0 To Matrice\NbFacetteX - 1 
      
      NoPoint1 = x + zx 
      P1\x = x 
      P1\y = PeekF(Adresse + NoPoint1 * 12) 
      P1\Z = Z 
      
      NoPoint2 = NoPoint1 + 1 
      P2\x = x + 1 
      P2\y = PeekF(Adresse + NoPoint2 * 12) 
      P2\Z = Z 
      
      NoPoint3 = x + zx1 
      P3\x = x  
      P3\y = PeekF(Adresse + NoPoint3 * 12) 
      P3\Z = Z + 1 
      
      NoPoint4 = NoPoint3 + 1 
      P4\x = x + 1 
      P4\y = PeekF(Adresse + NoPoint4 * 12) 
      P4\Z = Z + 1 
      
      calculVecteurNorme(@P1,@P2,@Vecteur1) 
      calculVecteurNorme(@P1,@P3,@Vecteur2) 
      produitVectoriel(@Vecteur2,@Vecteur1,@Normale1) 
      calculVecteurNorme(@P2,@P4,@Vecteur1) 
      calculVecteurNorme(@P2,@P3,@Vecteur2) 
      produitVectoriel(@Vecteur2,@Vecteur1,@Normale2) 
      
      Points(NoPoint1)\x + Normale1\x 
      Points(NoPoint1)\y + Normale1\y 
      Points(NoPoint1)\Z + Normale1\Z 
      
      Points(NoPoint2)\x + Normale1\x + Normale2\x 
      Points(NoPoint2)\y + Normale1\y + Normale2\y 
      Points(NoPoint2)\Z + Normale1\Z + Normale2\Z 
      
      Points(NoPoint3)\x + Normale1\x + Normale2\x 
      Points(NoPoint3)\y + Normale1\y + Normale2\y 
      Points(NoPoint3)\Z + Normale1\Z + Normale2\Z 
      
      Points(NoPoint4)\x + Normale2\x 
      Points(NoPoint4)\y + Normale2\y 
      Points(NoPoint4)\Z + Normale2\Z 
      
    Next x 
  Next Z    
  No=0 
  For Z = 0 To Matrice\NbFacetteZ 
    For x = 0 To Matrice\NbFacetteX 
      Distance.f = Sqr(Points(No)\x * Points(No)\x + Points(No)\y * Points(No)\y + Points(No)\Z * Points(No)\Z) 
      Points(No)\x / Distance 
      Points(No)\y / Distance 
      Points(No)\Z / Distance 
      PokeF(AdrNormale    , Points(No)\x) 
      PokeF(AdrNormale + 4, Points(No)\y) 
      PokeF(AdrNormale + 8, Points(No)\Z) 
      No + 1 
      AdrNormale + 12 
    Next x 
  Next Z  
  SetMeshData(0, 3, Matrice\NormaleIDMemory , Matrice\NbPointX * Matrice\NbPointZ) 
EndProcedure 

Procedure vagues() 
  Adresse = Matrice\PointIDMemory + 4 
  For Z = 0 To Matrice\NbFacetteZ 
    For x = 0 To Matrice\NbFacetteX 
      Sommet.f = Sin(0.0174533 * (AngleVague + (x * decaleX) + (Z * decaleZ))) * HauteurVague 
      PokeF(Adresse, Sommet) 
      Adresse + 12 
    Next x 
  Next Z 
  SetMeshData(0, 0, Matrice\PointIDMemory, Matrice\NbPointX * Matrice\NbPointZ) 
EndProcedure 
Procedure GestionTouches() 
  If KeyboardReleased(#PB_Key_F1) 
    Mode = #PB_Camera_Wireframe - Mode 
    CameraRenderMode(0, Mode) 
  EndIf 
  If KeyboardReleased(#PB_Key_F2) 
    MaterialShadingMode(0, #PB_Material_Flat) 
  EndIf  
  If KeyboardReleased(#PB_Key_F3) 
    MaterialShadingMode(0, #PB_Material_Gouraud) 
  EndIf 
  If KeyboardReleased(#PB_Key_F4) 
    MaterialShadingMode(0, #PB_Material_Phong) 
  EndIf 
  If KeyboardReleased(#PB_Key_F5) 
    Animation = 1 - Animation 
  EndIf 
  If KeyboardReleased(#PB_Key_F10) 
    AfficheAide = 1 - AfficheAide 
  EndIf 
  decaleX - 1 * KeyboardPushed(#PB_Key_Left) / 128 
  decaleX + 1 * KeyboardPushed(#PB_Key_Right) / 128 
  HauteurVague + 1 * KeyboardPushed(#PB_Key_PageUp) / 128 
  HauteurVague - 1 * KeyboardPushed(#PB_Key_PageDown) / 128 
  decaleZ + 1 * KeyboardPushed(#PB_Key_Up) / 128 
  decaleZ - 1 * KeyboardPushed(#PB_Key_Down) / 128 
  
  ;SnapShot 
  If KeyboardReleased(#PB_Key_F12) 
    hBitmap = CreateImage(0, #ScreenWidth, #ScreenHeight) 
    hdc = StartDrawing(ImageOutput()) 
    SelectObject_(hdc, hBitmap) 
    BitBlt_(hdc, 0, 0, #ScreenWidth, #ScreenHeight, GetDC_(GetDesktopWindow_()), 0, 0, #SRCCOPY) 
    StopDrawing() 
    DeleteDC_(hdc) 
    SetClipboardData(#PB_ClipboardImage, ImageID()) 
  EndIf 
EndProcedure 
Procedure GestionSouris() 
  ExamineMouse() 
  If MouseButton(1) 
    Lumiere\y + 2 
  EndIf 
  If MouseButton(2) 
    Lumiere\y - 2 
  EndIf  
  Lumiere\x + MouseDeltaX() 
  Lumiere\Z + MouseDeltaY() 
  LightLocate(0,Lumiere\x,Lumiere\y,Lumiere\Z) 
EndProcedure  
Procedure AfficheAide() 
  StartDrawing(ScreenOutput()) 
  DrawingMode(1) 
  FrontColor(255, 255, 255) 
  Locate(10, 10) 
  DrawText("DecaleX = " + StrF(decaleX)) 
  Locate(10, 30) 
  DrawText("DecaleZ = " + StrF(decaleZ)) 
  Locate(10, 50) 
  DrawText("HauteurVague = " + StrF(HauteurVague)) 
  Locate(10, 70) 
  DrawText("[F1] => Change Mode Caméra") 
  Locate(10, 90) 
  DrawText("[F2] => MaterialSharingMode=> Flat") 
  Locate(10, 110) 
  DrawText("[F3] => MaterialSharingMode=> Gouraud") 
  Locate(10, 130) 
  DrawText("[F4] => MaterialSharingMode=> Phong") 
  Locate(10, 150) 
  DrawText("[F5] => Marche/Arrêt Animation des vagues") 
  Locate(10, 170) 
  DrawText("Lumiere X => " + Str(Lumiere\x)) 
  Locate(10, 190) 
  DrawText("Lumiere Y => " + Str(Lumiere\y)) 
  Locate(10, 210) 
  DrawText("Lumiere Z => " + Str(Lumiere\Z)) 
  Locate(10, 230) 
  DrawText("Image par seconde (Actuel) = " + Str(Engine3DFrameRate(#PB_Engine3D_Current))) 
  Locate(10, 250) 
  DrawText("Image par seconde (Moyenne) = " + Str(Engine3DFrameRate(#PB_Engine3D_Average))) 
  Locate(10, 270) 
  DrawText("Nombre de polygones (Triangles) = " + Str(CountRenderedTriangles())) 
  Locate(10, 290) 
  DrawText("Mémoire vidéo disponible = " + Str(AvailableScreenMemory())) 
  Locate(10, 310) 
  DrawText("[F10] Cache/Montre l'aide")  
  Locate(10, 330) 
  DrawText("[F12] SnapShot")   
  StopDrawing() 
EndProcedure

Publié : mar. 25/mai/2004 0:32
par Guimauve
J'ai modifié la procédure AfficheAide(). Au début, avec la 1re et 2e version, j'avais un FPS de 60. Avec celle-ci j'ai 20... Mais c'est bien, même très bien.

A+
Guimauve

Code : Tout sélectionner

Procedure AfficheAide()
     StartDrawing(ScreenOutput())
          DrawingMode(1)
          FrontColor(255, 255, 255)
          Locate(10, 10)
          DrawText("DecaleX = " + StrF(decaleX))
          Locate(10, 30)
          DrawText("DecaleZ = " + StrF(decaleZ))
          Locate(10, 50)
          DrawText("HauteurVague = " + StrF(HauteurVague))
          Locate(10, 70)
          DrawText("[F1] => Change Mode Caméra")
          Locate(10, 90)
          DrawText("[F2] => MaterialSharingMode=> Flat")
          Locate(10, 110)
          DrawText("[F3] => MaterialSharingMode=> Gouraud")
          Locate(10, 130)
          DrawText("[F4] => MaterialSharingMode=> Phong")
          Locate(10, 150)
          DrawText("[F5] => Marche/Arrêt Animation des vagues")
          Locate(10, 170)
          DrawText("Lumiere X => " + Str(Lumiere\x))
          Locate(10, 190)
          DrawText("Lumiere Y => " + Str(Lumiere\y))
          Locate(10, 210)
          DrawText("Lumiere Z => " + Str(Lumiere\z))
          Locate(10, 230)
          DrawText("Image par seconde (Actuel) = " + Str(Engine3DFrameRate(#PB_Engine3D_Current)))
          Locate(10, 250)
          DrawText("Image par seconde (Moyenne) = " + Str(Engine3DFrameRate(#PB_Engine3D_Average)))
          Locate(10, 270)
          DrawText("Nombre de poligone (Triangles) = " + Str(CountRenderedTriangles()))
          Locate(10, 290)
          DrawText("Mémoire vidéo disponible = " + Str(AvailableScreenMemory()))
     StopDrawing()
EndProcedure

Publié : mar. 25/mai/2004 0:42
par fweil
comtois,

arf ... du mal à retrouver où il était ce post ... dans les jeux, mais moi j'y vais pas dans les jeux !

Bon tu voulais voir ce qu'on peut optimiser en calcul.

J'ai d'abord retiré tout ce qui ne sert pas ou plus, ou presque tout.

J'ai ensuite remonté les procédures appelées depuis un seul endroit dans leur appelant unique (pour sind, dist, ...)

J'ai remonté les variables recalculées pour rien dans les doubles boucles imbriquées.

J'ai changé un truc peut-être assez rentable, mais à mesurer avec un benchmark approprié : les PokeW de matrice(), peuvent être remplacés, ce que j'ai fait, par des PokeL, moins nombreux.

Je pense que plutôt que de faire :

PokeW(Addresse, B1)
PokeW(Adresse + 2, B2)

il est sûrement plus rapide de faire un :

PokeL(Adresse, B2 << 16 + B1)

D'ailleurs je m'absente trois minutes pour vérifier ...

Voila, les 3 minutes sont écoulées ...

Code : Tout sélectionner

b1.w = 123
b2.w = 456
l.l

OpenConsole()
;
; pour vérifier que je ne dis pas d'ânerie
;
PokeL(@l, b2 << 16 + b1)

PrintN(Str(l))

PokeW(@l, b1)
PokeW(@l + 2, b2)

PrintN(Str(l))

;
; Les deux résultats sont bien identiques !

Count = 100000000

tz = ElapsedMilliseconds() : For i = 1 To Count
  PokeW(@l, b1)
  PokeW(@l + 2, b2)
Next : PrintN(Str(ElapsedMilliseconds() - tz))

tz = ElapsedMilliseconds() : For i = 1 To Count
  PokeL(@l, b2 << 16 + b1)
Next : PrintN(Str(ElapsedMilliseconds() - tz))

While Inkey() = "" : Wend

CloseConsole()
end
Ca donne 1.6s pour le double PokeW et 1.1s pour le simple PokeL sur mon 1,2GHz !

CQFD. Ce genre de petit détail peut changer la vie.

Bon voila le résultat de mes retouches ...

Code : Tout sélectionner

;-Constantes 
#ScreenWidth = 1024 
#ScreenHeight = 768 
#ScreenDepth = 32 

;-Structures 
Structure Vecteur 
  x.f 
  y.f 
  z.f 
EndStructure 
Structure Lumiere 
  Couleur.l 
  x.f 
  y.f 
  z.f 
EndStructure  
Structure Matrix 
  Largeur.f 
  Profondeur.f 
  NbFacetteX.l      ;>0 et <256 si FaceCachee=#False , ou <128 si FaceCachee=#True 
  NbFacetteZ.l      ;( j'ai pas encore vérifié si ça passe => à calculer) 
  FaceCachee.l      ; si =True on double les triangles pour voir l'entité des deux côtés 
  PointIDMemory.l 
  TriangleIDMemory.l 
  TextureIDMemory.l 
  NormaleIDMemory.l 
EndStructure 

;-Variables 
Global Matrix.Matrix 
Global Lumiere.Lumiere 
Global CamLocateX.f, CamLocateY.f, CamLocateZ.f,CamLocateX.f,CamLocateY.f,CamLocateZ.f 
Global decaleX.l,decaleZ.l,HauteurVague.l 
Global Mode.b ,AngleVague.l,Vitesse.l,ShadingMode.b,NormaleInverse.l,Animation.l 

;-Declare 
Declare Matrice() 
Declare NormalesMatrice() 
Declare.f Wrapvalue(Angle.f) 
Declare.f Sind( Angle.f)
Declare vagues() 
Declare GestionTouches() 
Declare GestionSouris() 
Declare AfficheAide() 

; 
;- Main starts here 
; 
If InitEngine3D() And InitSprite() And InitKeyboard() And InitMouse() And OpenScreen(#ScreenWidth, #ScreenHeight, #ScreenDepth, "FRW Matrix") 
  ;/Divers 
  Vitesse=3
  HauteurVague=10
  decaleX=0 
  decaleZ=0 
  Animation = 1 
  ;/Paramètres de la matrice 
  Matrix\Largeur    = 1000 
  Matrix\Profondeur = 1000 
  Matrix\NbFacetteX = 100 
  Matrix\NbFacetteZ = 100 
  Matrix\FaceCachee = #True 
  Matrix\PointIDMemory    = AllocateMemory(12 * (Matrix\NbFacetteX + 1) * (Matrix\NbFacetteZ + 1)) 
  Matrix\TriangleIDMemory = AllocateMemory(12 * Matrix\NbFacetteX * Matrix\NbFacetteZ * 4) 
  Matrix\TextureIDMemory  = AllocateMemory(12 * (Matrix\NbFacetteX + 1) * (Matrix\NbFacetteZ + 1)) 
  Matrix\NormaleIDMemory  = AllocateMemory(12 * (Matrix\NbFacetteX + 1) * (Matrix\NbFacetteZ + 1)) 
  Dim Points.Vecteur((Matrix\NbFacetteX+1)*(Matrix\NbFacetteZ+1)) 
  Matrice() 
  NormaleInverse = -1 
  ;/Mesh 
  CreateMesh(0) 
  SetMeshData(0, 0, Matrix\PointIDMemory   , (Matrix\NbFacetteX + 1) * (Matrix\NbFacetteZ + 1)) 
  SetMeshData(0, 1, Matrix\TriangleIDMemory, (Matrix\NbFacetteX) * (Matrix\NbFacetteZ) * 4) 
  SetMeshData(0, 2, Matrix\TextureIDMemory , (Matrix\NbFacetteX + 1) * (Matrix\NbFacetteZ + 1)) 
  SetMeshData(0, 3, Matrix\NormaleIDMemory , (Matrix\NbFacetteX + 1) * (Matrix\NbFacetteZ + 1))  
  
  ;/Texture 
  ;/Sans image 
  TextureXSize = 256 
  TextureYSize = 256 
;   CreateTexture(0, TextureXSize, TextureYSize) 
;   StartDrawing(TextureOutput(0)) 
;     Box(0, 0, TextureXSize/3, TextureYSize, #Blue) 
;     Box(TextureXSize/3, 0, TextureXSize*2/3, TextureYSize, #White) 
;     Box(TextureXSize*2/3, 0, TextureXSize, TextureYSize, #Red) 
;     DrawingMode(4) 
;     Box(0, 0, TextureXSize , TextureYSize , #White) 
;   StopDrawing() 
  
  ;/Avec une image    
  UsePNGImageDecoder() 
  LoadImage(0,"data\purebasiclogonew.png")  
  ResizeImage(0,TextureXSize,TextureYSize) 
  CreateTexture(0,TextureXSize,TextureYSize) 
  StartDrawing(TextureOutput(0)) 
  DrawImage(UseImage(0), 0, 0) 
  DrawingMode(4) 
  Box(1, 1, TextureXSize - 2, TextureYSize - 2, RGB(255,255,255)) 
  StopDrawing() 
  
  ;/Material 
  CreateMaterial(0, TextureID(0)) ; Material 
  ;MaterialFilteringMode(0, #PB_Material_Trilinear) 
  MaterialShadingMode(0, #PB_Material_Gouraud) 
  
  ;/Entity 
  CreateEntity(0, MeshID(0), MaterialID(0)) 
  
  ;/Caméra 
  CamLocateX = 0 
  CamLocateY = 845 
  CamLocateZ = 915 
  CamLookAtX = EntityX(0) 
  CamLookAtY = EntityY(0) 
  CamLookAtZ = EntityZ(0) 
  CreateCamera(0, 0, 0, 100, 100) 
  CameraLocate(0, CamLocateX, CamLocateY, CamLocateZ) 
  CameraLookAt(0,CamLookAtX,CamLookAtY,CamLookAtZ) 
  ;/Lumière 
  AmbientColor(RGB(110,110,140)) 

  Lumiere\Couleur = RGB(255,255,255) 
  Lumiere\x = EntityX(0)/2 
  Lumiere\y = 960 
  Lumiere\z = EntityZ(0)/2 
  CreateLight(0,Lumiere\Couleur)  
  LightLocate(0,Lumiere\x, Lumiere\y, Lumiere\z) 

  Repeat 
    ClearScreen(0, 0, 0) 
    ExamineKeyboard() 
    If Animation 
      AngleVague = (AngleVague + Vitesse) % 360
    EndIf    
    GestionSouris() 
    ;/Donne une forme à la matrice 
    vagues() 
    NormalesMatrice()    
    RenderWorld() 
    GestionTouches() ; Placé après RenderWorld sinon le snapshot ne fonctionne pas ! 
    AfficheAide()    
    FlipBuffers() 
  Until KeyboardPushed(#PB_Key_Escape) 
Else 
  MessageRequester("Error", "Something fails to initialize 3D engine", 0) 
EndIf 
End 

;/ 
;-Procedures 
;/ 
Procedure calculVecteurNorme(*pi.Vecteur,*pf.Vecteur,*n.Vecteur) 
  x.f = *pf\x - *pi\x 
  y.f = *pf\y - *pi\y 
  z.f = *pf\z - *pi\z 
  d.f = Sqr(x * x + y * y + z * z)
  *n\x =x / d 
  *n\y =y / d 
  *n\z =z / d 
EndProcedure 

Procedure produitVectoriel(*v1.Vecteur,*v2.Vecteur,*n.Vecteur) 
  *n\x = *v1\y * *v2\z - *v1\z * *v2\y 
  *n\y = *v1\z * *v2\x - *v1\x * *v2\z 
  *n\z = *v1\x * *v2\y - *v1\y * *v2\x 
EndProcedure 

Procedure Matrice() 
  TailleFacetteX.f = Matrix\Largeur / Matrix\NbFacetteX 
  TailleFacetteZ.f = Matrix\Profondeur / Matrix\NbFacetteZ 

  ;/Points 
  Adresse1 = Matrix\PointIDMemory 
  ;/Texture 
  Adresse2 = Matrix\TextureIDMemory 
  For b = 0 To Matrix\NbFacetteZ 
    For a = 0 To Matrix\NbFacetteX 
      PokeF(Adresse1, (a - Matrix\NbFacetteX / 2) * TailleFacetteX) 
      PokeF(Adresse1 + 4, 0) 
      PokeF(Adresse1 + 8, (b - Matrix\NbFacetteZ / 2) * TailleFacetteZ) 
      Adresse1 + 12 
      PokeF(Adresse2, a / Matrix\NbFacetteX) 
      PokeF(Adresse2 + 4, b / Matrix\NbFacetteZ) 
      Adresse2 + 8 
    Next 
  Next 

  ;/Triangles 
  If Matrix\FaceCachee 
    Nbtriangle.l = 4 
  Else 
    Nbtriangle = 2 
  EndIf  
  Index = 6 * Nbtriangle 
  Adresse = Matrix\TriangleIDMemory 
  
  NbPointX = Matrix\NbFacetteX + 1 
  For b = 0 To Matrix\NbFacetteZ - 1 
    bx = b * NbPointX
    For a = 0 To Matrix\NbFacetteX - 1 
      P1 = a + bx
      P2 = P1 + 1 
      P3 = a + bx + NbPointX 
      P4 = P3 + 1 
      PokeL(Adresse, P2 << 16 + P3)
      PokeL(Adresse + 4, P2 << 16 + P1)
      PokeL(Adresse + 8, P4 << 16 + P3)
      If Matrix\FaceCachee 
        PokeL(Adresse + 12, P2 << 16 + P1)
        PokeL(Adresse + 16, P4 << 16 + P3)
        PokeL(Adresse + 20, P2 << 16 + P3)
      EndIf 
      Adresse + Index 
    Next 
  Next 
  
EndProcedure 
Procedure NormalesMatrice() 
  Vecteur1.Vecteur 
  Vecteur2.Vecteur 

  P1.Vecteur ; Point 1 de la Facette 
  P2.Vecteur ; Point 2 de la Facette  
  P3.Vecteur ; Point 3 de la Facette 
  P4.Vecteur ; Point 4 de la Facette 
  
  Normale1.Vecteur ; Normale Triangle 1 de la Facette Points 1,2,3 
  Normale2.Vecteur ; Normale Triangle 2 de la Facette Points 2,4,3 
  
  Adresse = Matrix\PointIDMemory + 4 
  AdrNormale = Matrix\NormaleIDMemory 
  TailleFacetteX.f = Matrix\Largeur / Matrix\NbFacetteX 
  TailleFacetteZ.f = Matrix\Profondeur / Matrix\NbFacetteZ 
  NbPointX = Matrix\NbFacetteX + 1 
  NbPointZ = Matrix\NbFacetteZ + 1 
  
  For z = 0 To Matrix\NbFacetteZ - 1 
    zx = z * (Matrix\NbFacetteX + 1)
    zx1 = zx + (Matrix\NbFacetteX + 1)
    For x = 0 To Matrix\NbFacetteX - 1 
          
      NoPoint1 = x + z * NbPointX 
      P1\x = x 
      P1\y = PeekF(Adresse + (x + (zx)) * 12) 
      P1\z = z 
      
      NoPoint2 = NoPoint1 + 1 
      P2\x = x + 1 
      P2\y = PeekF(Adresse + (x + 1 + zx) * 12) 
      P2\z = z 
      
      NoPoint3 = x + (z + 1) * NbPointX 
      P3\x = x  
      P3\y = PeekF(Adresse + (x + zx1) * 12) 
      P3\z = z + 1 
      
      NoPoint4 = NoPoint3 + 1 
      P4\x = x + 1 
      P4\y = PeekF(Adresse + (x + 1 + zx1) * 12) 
      P4\z = z + 1 
      
      calculVecteurNorme(@P1,@P2,@Vecteur1) 
      calculVecteurNorme(@P1,@P3,@Vecteur2) 
      produitVectoriel(@Vecteur1,@Vecteur2,@Normale1) 
      calculVecteurNorme(@P2,@P4,@Vecteur1) 
      calculVecteurNorme(@P2,@P3,@Vecteur2) 
      produitVectoriel(@Vecteur1,@Vecteur2,@Normale2) 

      Points(NoPoint1)\x + Normale1\x 
      Points(NoPoint1)\y + Normale1\y 
      Points(NoPoint1)\z + Normale1\z 
      
      Points(NoPoint2)\x + Normale1\x + Normale2\x 
      Points(NoPoint2)\y + Normale1\y + Normale2\y 
      Points(NoPoint2)\z + Normale1\z + Normale2\z 
      
      Points(NoPoint3)\x + Normale1\x + Normale2\x 
      Points(NoPoint3)\y + Normale1\y + Normale2\y 
      Points(NoPoint3)\z + Normale1\z + Normale2\z 
      
      Points(NoPoint4)\x + Normale2\x 
      Points(NoPoint4)\y + Normale2\y 
      Points(NoPoint4)\z + Normale2\z 

    Next x 
  Next z    
  No=0 
  For z = 0 To Matrix\NbFacetteZ 
    For x = 0 To Matrix\NbFacetteX 
      Magnitude.f = Sqr(Points(No)\x * Points(No)\x + Points(No)\y * Points(No)\y + Points(No)\z * Points(No)\z) 
      Points(No)\x / Magnitude 
      Points(No)\y / Magnitude 
      Points(No)\z / Magnitude 
      PokeF(AdrNormale    , Points(No)\x * NormaleInverse) 
      PokeF(AdrNormale + 4, Points(No)\y * NormaleInverse) 
      PokeF(AdrNormale + 8, Points(No)\z * NormaleInverse) 
      No + 1 
      AdrNormale + 12 
    Next x 
  Next z  
  SetMeshData(0, 3, Matrix\NormaleIDMemory , (Matrix\NbFacetteX + 1) * (Matrix\NbFacetteZ + 1)) 
EndProcedure 

Procedure vagues() 
  Adresse = Matrix\PointIDMemory + 4 
  For z = 0 To Matrix\NbFacetteZ 
    For x = 0 To Matrix\NbFacetteX 
      Sommet.f = Sin(0.0174533 * (AngleVague + (x * decaleX) + (z * decaleZ))) * HauteurVague 
      PokeF(Adresse, Sommet) 
      Adresse + 12 
    Next x 
  Next z 
  SetMeshData(0, 0, Matrix\PointIDMemory, (Matrix\NbFacetteX + 1) * (Matrix\NbFacetteZ + 1)) 
EndProcedure 
Procedure GestionTouches() 
  If KeyboardReleased(#PB_Key_F1) 
    Mode = #PB_Camera_Wireframe - Mode 
    CameraRenderMode(0, Mode) 
  EndIf 
  If KeyboardReleased(#PB_Key_F2) 
    MaterialShadingMode(0, #PB_Material_Flat) 
  EndIf  
  If KeyboardReleased(#PB_Key_F3) 
    MaterialShadingMode(0, #PB_Material_Gouraud) 
  EndIf 
  If KeyboardReleased(#PB_Key_F4) 
    MaterialShadingMode(0, #PB_Material_Phong) 
  EndIf 
  If KeyboardReleased(#PB_Key_F5) 
    Animation = 1 - Animation 
  EndIf 
  If KeyboardReleased(#PB_Key_F6) 
    NormaleInverse * -1 
  EndIf 
  decaleX - 1 * KeyboardPushed(#PB_Key_Left) / 128 
  decaleX + 1 * KeyboardPushed(#PB_Key_Right) / 128 
  HauteurVague + 1 * KeyboardPushed(#PB_Key_PageUp) / 128 
  HauteurVague - 1 * KeyboardPushed(#PB_Key_PageDown) / 128 
  decaleZ + 1 * KeyboardPushed(#PB_Key_Up) / 128 
  decaleZ - 1 * KeyboardPushed(#PB_Key_Down) / 128 
  
  ;SnapShot 
  If KeyboardReleased(#PB_Key_F12) 
    hBitmap = CreateImage(0, #ScreenWidth, #ScreenHeight) 
    hdc = StartDrawing(ImageOutput()) 
    SelectObject_(hdc, hBitmap) 
    BitBlt_(hdc, 0, 0, #ScreenWidth, #ScreenHeight, GetDC_(GetDesktopWindow_()), 0, 0, #SRCCOPY) 
    StopDrawing() 
    DeleteDC_(hdc) 
    SetClipboardData(#PB_ClipboardImage, ImageID()) 
  EndIf 
EndProcedure 
Procedure GestionSouris() 
  ExamineMouse() 
  If MouseButton(1) 
    Lumiere\y + 2 
  EndIf 
  If MouseButton(2) 
    Lumiere\y - 2 
  EndIf  
  Lumiere\x + MouseDeltaX() 
  Lumiere\z + MouseDeltaY() 
  LightLocate(0,Lumiere\x,Lumiere\y,Lumiere\z) 
EndProcedure  
Procedure AfficheAide() 
  StartDrawing(ScreenOutput()) 
  DrawingMode(1) 
  FrontColor(255,255,255) 
  Locate(10,10) 
  DrawText("DecaleX = " + StrF(decaleX)) 
  Locate(10,30) 
  DrawText("DecaleZ = " + StrF(decaleZ)) 
  Locate(10,50) 
  DrawText("HauteurVague = " + StrF(HauteurVague)) 
  Locate(10,70) 
  DrawText("[F1] => Change Mode Caméra") 
  Locate(10,90) 
  DrawText("[F2] => MaterialSharingMode=> Flat") 
  Locate(10,110) 
  DrawText("[F3] => MaterialSharingMode=> Gouraud") 
  Locate(10,130) 
  DrawText("[F4] => MaterialSharingMode=> Phong") 
  Locate(10,150) 
  DrawText("[F5] => Marche/Arrêt Animation des vagues") 
  Locate(10,170) 
  DrawText("Lumiere X => " + Str(Lumiere\x))  
  Locate(10,190) 
  DrawText("Lumiere Y => " + Str(Lumiere\y))  
  Locate(10,210) 
  DrawText("Lumiere Z => " + Str(Lumiere\z))  
  StopDrawing() 
EndProcedure  
Pour l'instant je peux difficilement faire mieux.

Une optimisation plus approfondie est possible pour grignoter deux instructions machine par ci par là, mais sur un code définitif, pas sur du dev ...

Slts

Publié : mar. 25/mai/2004 8:35
par comtois
Guimauve, oui ça chute drôlement , y'a bcp plus de calculs à faire que dans les premières versions :)
Mais j'avais aussi augmenté le nombre de facettes ,tu peux les diminuer ici :

Code : Tout sélectionner

  ;/Paramètres de la matrice (à renseigner)
  Matrice\Largeur    = 1000 
  Matrice\Profondeur = 1000 
  Matrice\NbFacetteX = 100 
  Matrice\NbFacetteZ = 100 
  Matrice\FaceVisible = #False ; #True double les triangles pour rendre visible l'autre face de la matrice
Et cette fois ci l'option FaceVisible fonctionne , elle diminue par deux le nombre de triangles, c'est pas rien :)

Fweil , merci à toi pour les modifs , je n'aurais jamais pensé à utiliser le PokeL à la place du pokeW . Maintenant que tu le dis ça semble évident , mais il fallait y penser :)

Je suis reparti de ton code ,pour apporter d'autres améliorations et optimisations , ainsi que la modif que propose Guimauve .

et j"ai posté le tout dans le post précédent pour ne pas encombrer avec mes codes :)

Pour s'y retrouver j'ai mis la date au début du code "25 mai 2004".

Dernier point qui m'intrigue
Normalement avec l'ombrage Phong , je devrais avoir un truc nickel or je vois les facettes comme si j'étais en ombrage Flat ?
et je ne vois pas de différence entre l'ombrage Flat et Gouraud, est-ce qu'il n'y aurait pas une inversion dans les constantes PB ?
ou tout simplement c'est mes normales qui sont fausses :? et qui donnent ce résultat bizarre?
Il faudrait que j'essaye avec un mesh fait dans un éditeur 3D.

Je devrais voir des trucs comme ça normalement :
Ombrage Flat
Image
Ombrage de Gouraud
Image
Ombrage de Phong
Image

Publié : mar. 25/mai/2004 14:30
par Guimauve
Je viens de vérifier avec PB

Code : Tout sélectionner

Debug #PB_Material_Flat
Debug #PB_Material_Gouraud
Debug #PB_Material_Phong
Dans cet ordre le debogger affiche 0,1 et 2. Donc les constantes semble être OK.

Parcontre, peu importe le mode de rendu, la différence n'est visible là ou il y a de la lumière qui éclaire la surface.

A+
Guimauve

Publié : mar. 25/mai/2004 14:47
par cederavic
verifi l'ordre des vertex de tes faces, il semble que tu ai une face sur 2 qui soi inverser (et oui, l'ordre est pris en compte)

Publié : mar. 25/mai/2004 20:33
par comtois
Cederavic , oui l'ordre est pris en compte pour cacher ou montrer un triangle , c'est pour ça qu'il faut doubler les triangles quand on veut faire tourner la matrice. Et effectivement , il faut bien avoir les vertex qui tournent dans un sens pour la face avant ,et dans le sens inverse pour la face arrière .

tu peux faire l'essai , si tu inverses le sens , ton triangle ne s'affiche plus .

Ou alors tu me parles d'autre chose , et je n'ai pas compris ?
Dans ce cas tu peux préciser , et même faire un copier coller du truc qui te semble bizarre dans le code ? et j'y jetterai un oeil.

Guimauve , moi je ne vois aucune différence entre le mode Flat et le mode Gouraud , ça me semble curieux .
Et j'ai aussi fait l'essai avec un mesh créé avec un éditeur 3D.
Avec ce mesh , je ne vois aucune différence entre le mode Flat et le mode Gouraud, par contre avec le mode Ombrage de Phong je vois quelques triangles ( c'est léger et puis ça doit dépendre de l'éclairage ) .
Donc je retrouve le même affichage qu'avec ma matrice :?
Je vais reprendre encore un peu le code et le proposer à la critique sur le forum anglais ( à la fin de la semaine ), peut-être que quelqu'un aura une idée ?

Au fait Guimauve ,tu ne m'as pas dit si le FPS c'était amélioré avec le code optimisé ? :)

Publié : mar. 25/mai/2004 21:31
par fweil
Comtois,

plus que Jean de la Fontaine, qui s'en est inspiré, c'est comme une fable latine ...

Tourrnes et retournes la terre, car un trésor est caché dedans !

Ce que tu es obsédé et courageux !

Continues STP!

..., juste pour essayer de t'encourager

Publié : mar. 25/mai/2004 22:21
par comtois
Merci pour les encouragements :)

Pour l'instant , je reprends surtout la présentation , en mode fenêtre , avec un menu , ça sera plus simple pour configurer la lumière par exemple.
Je pourrai appeler le ColorRequester() et changer la couleur de la lumière ,idem pour la couleur ambiante , etc ,et même ajouter des lumières , les configurer.

Dans un premier temps , l'objectif c'est de reconduire ce qui existe dans un mode fenêtre ,

Dans un deuxième temps ajouter les options :)

D'ailleurs à ce sujet , je fais donc un

Code : Tout sélectionner

OpenWindow(#WPrincipale,0,0,ScreenWidth,ScreenHeight,#PB_Window_ScreenCentered|#PB_Window_BorderLess,"Test") = 0 
Suivi de très près par un

Code : Tout sélectionner

If OpenWindowedScreen( WindowID(#WPrincipale), 0, 0, ScreenWidth , ScreenHeight , 1, 0, 0 ) = 0 
Alors je me demandais dans ce contexte là , c'est à dire fenêtre plus openWindowedScreen() que faut-il utiliser pour la gestion de la souris ? et du clavier ?
Si je reprends le code de Sokoban , je ne m'étais même pas posé la question ,et j'étais parti sur ce que je fais d'habitude , avec ExamineKeyboard() pour le clavier ,et ExamineMouse() pour la souris()

Mais dans ce cas ,je ne vois plus la souris , je devrais donc utiliser un sprite ?
ou alors j'utilise WindowMouseX() et WindowMouseY() ? et le bouton de la souris , je le teste comment ?

Je commence à peine ,donc mes problèmes ne sont pas encore clairement définis , et d'ailleurs il n'y a peut-être pas de problèmes :).

Mais plutôt que de passer du temps à chercher ce qui va le mieux , si quelqu'un a déjà la réponse , autant profiter de son expérience :)


[EDit] En fouillant un peu , j'ai trouvé pour les touches de la souris , bon je préfère prendre du code 100% PureBasic avec des constantes 100% purebasic mais bon , ça va encore :)

Pour l'instant je pars là dessus avec WindowMouse()

Code : Tout sélectionner

   event = WaitWindowEvent()

   Select event
      Case #WM_LBUTTONDOWN       : Mulot\clicGauche = 1  
      Case #WM_LBUTTONUP         : Mulot\clicGauche = 0
      Case #WM_RBUTTONDOWN       : Mulot\clicdroit = 1  
      Case #WM_RBUTTONUP         : Mulot\clicdroit = 0

Publié : ven. 28/mai/2004 23:56
par comtois
C'est la même chose ,mais dans une fenêtre
Il n'y a que l'exe pour l'instant , j'avance encore un peu sur le code ,et je mettrai le source sur mon site.

http://perso.wanadoo.fr/comtois/sources ... Beta00.zip

J'ai des trucs bizarres ,je n'obtiens pas le même résultat quand je lance le code depuis l'éditeur ,et quand je lance l'exe.

J'ai un fond Bleu avec l'exe( pas bon ) ,alors que le fond est noir ( c'est bon ) depuis l'éditeur .

Voila ce que ça donne quand je le lance depuis l'éditeur

Image

[EDIT]

C'est bon j'ai trouvé !
Pour ne pas copier le fichier Engine3D.dll dans le répertoire où se trouve mon exe , je mets une copie dans le dossier Windows/System32 , et j'avais oublié de la mettre à jour avec la dernière DLL :oops:

Maintenant j'obtiens bien la même chose depuis l'éditeur et avec l'exe.
Un mystère résolu :)

Reste à comprendre quelle erreur je fais avec mes Flat , Gouraud et Phong ?