[Résolu] Calcul des normales d'un mesh 2: La Revanche

Généralités sur la programmation 3D
kelebrindae
Messages : 579
Inscription : ven. 11/mai/2007 15:21

[Résolu] Calcul des normales d'un mesh 2: La Revanche

Message par kelebrindae »

[profonde inspiration, court instant de préparation mentale, puis: ]

AU SECOURS !!!

J'vais devenir dingue avec ces @#£$ de normales!
Sur les conseils d'Ollivier, j'ai tenté de passer en "Phong" ma géosphère issue de la subdivision d'un mesh plus simple. Et là, l'horreur.
D'abord, ça me donne le même résultat qu'en "Flat", et puis ça me donne vraiment l'impression que mes normales sont attribuées n'importe comment.
Pire: l'ordre des vertices dans les triangles affecte le rendu! (mais seulement en "Flat" et "Phong", pas en Gouraud) 8O
Image<= Et ça!? Vous allez pas m'dire que c'est correct, ça quand même!!

Bref, je craque.
Faites l'essai par vous-même:
- Lancez le code ci-dessous;
- Appuyez 3-4 fois sur "S" pour subdiviser;
- Appuyez sur "N" pour normaliser => ça paraît presque bon, mais il subsiste des dentelures bizarres sur les bords et je ne sais pas comment les virer (appuyez sur "R" pour mieux voir).

Recommencez en appuyant sur "I" après chaque appui sur "S", ce qui vous donne une sphère. Appuyez sur "N" => les normales sont un gros tas de n'importe quoi (pour rester poli)...

Ô dieux de la 3D en PureBasic, venez à mon aide! Esprits de Comtois, Tmyke et Cpl_Bator, j'en appelle à vous ! Ne laissez pas une brebis égarée en ces contrées sauvages céder au découragement !

Code : Tout sélectionner

; Author: Kelebrindae
; Date: june,19, 2008
; PB version: v4.10
; OS: Windows XP

#SQRT03=0.577350269189625764

;- Initialisation 
Resultat = MessageRequester("Mesh Subdivision","Full Screen ?",#PB_MessageRequester_YesNo) 
If Resultat = 6      
  FullScreen=1 
Else            
  FullScreen=0 
EndIf 

If InitEngine3D() = 0 
   MessageRequester( "Error" , "Can't initialize 3D, check if engine3D.dll is available" , 0 ) 
   End 
ElseIf InitSprite() = 0 Or InitKeyboard() = 0 
   MessageRequester( "Error" , "Can't find DirectX 7.0 or above" , 0 ) 
   End 
EndIf 

If Fullscreen  
  OpenScreen(800,600,32,"Mesh Subdivision") 
Else 
  OpenWindow(0,0, 0, 800 , 600 ,"Mesh Subdivision",#PB_Window_ScreenCentered) 
  OpenWindowedScreen(WindowID(0),0,0, 800 , 600,0,0,0) 
EndIf 

;- Data structures and definitions
Global CameraMode.l 

Structure Vector3
  x.f
  y.f
  z.f
EndStructure

Structure Vertex 
  px.f 
  py.f 
  pz.f 
  nx.f 
  ny.f 
  nz.f 
  couleur.l 
  U.f 
  V.f 
EndStructure 

Structure FaceTri 
  f1.w 
  f2.w 
  f3.w 
EndStructure
  
Structure dynMesh_struct
  id.s
  numMesh.l
  sizeX.f
  sizeY.f
  sizeZ.f
  nbVert.l
  nbTri.l
  *vertexBuffer.Vertex
  *faceBuffer.faceTri
EndStructure
#MAXMESH=2
Global Dim dynMesh.dynMesh_struct(#MAXMESH)

Enumeration
  #octahedron
  #pointyCube
  #Face
EndEnumeration

  EnableExplicit


;- ---- Procedures ----
;************************************************************************************
; Name: NormalizeVector
; Purpose: Normalizes a vector to the length 1 without changing its orientation.
; Parameters:
;   - vector to normalize
;************************************************************************************
Procedure.l NormalizeVector(*Vec1.Vector3)
  Protected length.f
 
  length.f = Sqr(*Vec1\x * *Vec1\x + *Vec1\y * *Vec1\y + *Vec1\z * *Vec1\z)

  *Vec1\x / length
  *Vec1\y / length
  *Vec1\z / length

EndProcedure

; Macro version 
Macro NORME(V)
  (Sqr(V\x * V\x + V\y * V\y + V\z * V\z))
EndMacro 

;************************************************************************************
; Name: CreateDynMesh
; Purpose: Creates a mesh, scaled and UV mapped dynamically, and stores vertices/faces
;          infos in the "dynMesh" array
; Parameters:
;   - id of the mesh
;   - mesh type: #octahedron,#pointyCube
;   - X size
;   - Y size
;   - Z size
;   - origin of mapping coord U 
;   - origin of mapping coord V
;   - Vertices color
; Return value: mesh indice in the "dynMesh" array, or -1 if an error occurs
;************************************************************************************
Procedure.l CreateDynMesh(id.s,solid.l,sizeX.f,sizeY.f,sizeZ.f,Uorigin.f,Vorigin.f,Uscale.f,Vscale.f,color.l) 

  Protected x.f,y.f,z.f                     ; vertex position
  Protected nx.f,ny.f,nz.f                  ; vertex normals
  Protected u.f,v.f                         ; vertex UV coords (texture mapping)
  Protected v1.w,v2.w,v3.w
  Protected *PtrV.Vertex                    ; vertices buffer in memory
  Protected *PtrF.FaceTri                   ; Faces buffer in memory
  Protected num.l,i.l
  
  ; Restore the good set of meshdatas
  Select solid    
    Case #octahedron
      Restore octahedron
    
    Case #pointyCube
      Restore pointyCube
    
    Case #Face
      Restore Face
    
    Default
      ProcedureReturn -1 
  EndSelect 


  ; Find first free slot in dynMesh()
  While num<#MAXMESH And dynMesh(num)\nummesh>0
    num+1
  Wend

  ; Read number of vertices and triangles
  Read dynMesh(num)\nbVert
  Read dynMesh(num)\nbTri

  ; Allocate the needed memory for vertices
  dynMesh(num)\vertexBuffer = AllocateMemory(SizeOf(Vertex)*dynMesh(num)\nbVert) 
  *PtrV = dynMesh(num)\vertexBuffer 
  
  ; Allocate the needed memory for faces
  dynMesh(num)\faceBuffer=AllocateMemory(SizeOf(FaceTri)*dynMesh(num)\nbTri) 
  *PtrF=dynMesh(num)\faceBuffer

  ; Read and store vertices position, normals, uv coords
  For i = 1 To dynMesh(num)\nbVert
    Read x
    Read y
    Read z
    Read nx
    Read ny
    Read nz
    Read u
    Read v
  
    color=RGB(255,0,0)
    If i%3 = 1
      color=RGB(0,255,0)
    EndIf
    If i%3 = 2
      color=RGB(0,0,255)
    EndIf
  
    *PtrV\px = x * sizex
    *PtrV\py = y * sizey
    *PtrV\pz = z * sizez
    
    *PtrV\nx = nx 
    *PtrV\ny = ny
    *PtrV\nz = nz 
    *PtrV\couleur = color
    *PtrV\u = uorigin + (u * uscale)
    *PtrV\v = vorigin + (v * vscale)
    *PtrV + SizeOf(Vertex) 
  Next i    

  ;Read and store faces infos
  For i=1 To dynMesh(num)\nbTri 
    Read v1
    Read v2
    Read v3 
     
    *PtrF\f1=v1  
    *PtrF\f2=v2 
    *PtrF\f3=v3 
    *PtrF + SizeOf(FaceTri) 
  Next i 
     

  ; Create mesh from stored infos
  dynMesh(num)\numMesh = CreateMesh(#PB_Any,dynMesh(num)\nbVert)
  If IsMesh(dynMesh(num)\numMesh) 
    SetMeshData(dynMesh(num)\numMesh,#PB_Mesh_Vertex | #PB_Mesh_Normal | #PB_Mesh_UVCoordinate | #PB_Mesh_Color,dynMesh(num)\vertexBuffer,dynMesh(num)\nbVert) 
    SetMeshData(dynMesh(num)\numMesh,#PB_Mesh_Face,dynMesh(num)\faceBuffer,dynMesh(num)\nbTri) 
    
    dynMesh(num)\id = id
    dynMesh(num)\sizeX = sizeX
    dynMesh(num)\sizeY = sizeY
    dynMesh(num)\sizeZ = sizeZ

    ProcedureReturn num 
  Else 
    ; free memory if "createMesh" has failed
    FreeMemory(dynMesh(num)\vertexBuffer)
    FreeMemory(dynMesh(num)\faceBuffer)
    ProcedureReturn -1    
  EndIf 
    
EndProcedure    

;************************************************************************************
; Name: deleteDynMesh
; Purpose: deletes a mesh and all vertices/faces infos in the "dynMesh" array
; Parameters:
;   - mesh indice in the "dynMesh" array
;   - mesh type: #octahedron,#pointyCube
;************************************************************************************
Procedure deleteDynMesh(num.l)

    If dynMesh(num)\numMesh=0
      ProcedureReturn -1
    EndIf

    ;FreeMesh(dynMesh(num)\numMesh)
    FreeMemory(dynMesh(num)\vertexBuffer)
    FreeMemory(dynMesh(num)\faceBuffer)
    dynMesh(num)\numMesh=0
  
EndProcedure

;************************************************************************************
; Name: inflateMesh
; Purpose: normalizes each vertex' position so they're at the same distance from the center
;          of the mesh => makes the mesh spheric
; Parameters:
;   - mesh indice in the "dynMesh" array
;   - mesh type: #octahedron,#pointyCube
;************************************************************************************
Procedure inflateMesh(numMesh.l)
  Protected i.l
  Protected *ptrVert.Vertex
  Protected vector3.Vector3
  Protected NormeVecteur.f

  *ptrVert = dynMesh(numMesh)\vertexBuffer
  For i = 1 To dynmesh(numMesh)\nbVert

    vector3\x = *ptrVert\px
    vector3\y = *ptrVert\py
    vector3\z = *ptrVert\pz
    
    NormalizeVector(@vector3)
    
    ; Equivalent:
;     NormeVecteur = NORME(vector3)
;     If NormeVecteur <> 0.0
;       vector3\x / NormeVecteur
;       vector3\y / NormeVecteur
;       vector3\z / NormeVecteur
;     EndIf  
       
    *ptrVert\px = vector3\x * dynMesh(numMesh)\sizeX
    *ptrVert\py = vector3\y * dynMesh(numMesh)\sizeY
    *ptrVert\pz = vector3\z * dynMesh(numMesh)\sizeZ
    *ptrVert\nx = vector3\x 
    *ptrVert\ny = vector3\y 
    *ptrVert\nz = vector3\z

    *ptrVert+SizeOf(Vertex)
  Next i
  
EndProcedure

;************************************************************************************
; Name: subdivideTriangle
; Purpose: Subdivides a triangle of the mesh into 4 smaller triangles
;   - mesh indice in the "dynMesh" array
;   - triangle to subdivide
;************************************************************************************
Procedure subdivideTriangle(nummesh.l,numtri.l)

  Protected VertexA.Vertex
  Protected VertexB.Vertex
  Protected VertexC.Vertex
  Protected *PtrV0.Vertex,*PtrV1.Vertex,*PtrV2.Vertex
  Protected *PtrNewV.vertex,*PtrNewF.faceTri
  Protected oldNbVert.w,oldNbFace.l,newVertNum.w,temp.w

  Debug "Mesh n°" + Str(nummesh) + ", " + Str(dynmesh(nummesh)\nbvert) + " vertices, " + Str(dynmesh(nummesh)\nbtri) + " triangles"
  Debug "Subdivision du triangle n°" + Str(numtri)
  Debug "   ->Taille mémoire pour vertices/faces: " + Str(MemorySize(dynMesh(nummesh)\vertexBuffer)) + " / " + Str(MemorySize(dynMesh(nummesh)\faceBuffer))
  Debug "   ->Taille mémoire des structures vertices/faces: " + Str(SizeOf(Vertex)) + " / " + Str(SizeOf(faceTri))
 

  ; Store current end of vertices/faces datas
  oldNbVert = dynMesh(nummesh)\nbVert
  oldNbFace = dynMesh(nummesh)\nbTri
  newVertNum = oldNbVert
       
  ; Extend allocated memory for new vertices and faces
  dynmesh(nummesh)\nbvert+9
  dynMesh(nummesh)\vertexBuffer = ReAllocateMemory(dynMesh(nummesh)\vertexBuffer,SizeOf(Vertex)*dynMesh(nummesh)\nbVert) 
  dynmesh(nummesh)\nbtri+3
  dynMesh(nummesh)\faceBuffer = ReAllocateMemory(dynMesh(nummesh)\faceBuffer,SizeOf(FaceTri)*dynMesh(nummesh)\nbTri) 
  ; NB: on ajoute que 3 triangles, car le triangle subdivisé est réutilisé
  
  
  Debug "   Augmentation nb vertices/faces à: " + Str(dynmesh(nummesh)\nbvert) + " / " + Str(dynmesh(nummesh)\nbtri)
  Debug "   ->Taille mémoire demandée pour vertices/faces: " + Str(SizeOf(Vertex) * dynmesh(nummesh)\nbvert) + " / " + Str(SizeOf(FaceTri) * dynmesh(nummesh)\nbtri)
  Debug "   Resultat de ReAllocate: " + Str(dynMesh(nummesh)\vertexBuffer) + " / " + Str(dynMesh(nummesh)\FaceBuffer)
  Debug "   ->Nouvelle taille mémoire: " + Str(MemorySize(dynMesh(nummesh)\vertexBuffer)) + " / " + Str(MemorySize(dynMesh(nummesh)\faceBuffer))


  ; le triangle est divisé en 4
  ; Phase 1: on repère l'emplacement des vertices du triangle
  *PtrV0 = dynMesh(nummesh)\vertexBuffer + (numtri * SizeOf(Vertex) * 3)
  *PtrV1 = dynMesh(nummesh)\vertexBuffer + (numtri * SizeOf(Vertex) * 3) + SizeOf(Vertex)
  *PtrV2 = dynMesh(nummesh)\vertexBuffer + (numtri * SizeOf(Vertex) * 3) + SizeOf(Vertex) * 2

  Debug "      Vertex réf., n°" + Str((*PtrV0 - dynMesh(nummesh)\vertexBuffer)/SizeOf(Vertex)) + ": " + StrF(*PtrV0\px)+","+StrF(*PtrV0\py)+","+StrF(*PtrV0\pz)
  Debug "      Vertex réf., n°" + Str((*PtrV1 - dynMesh(nummesh)\vertexBuffer)/SizeOf(Vertex)) + ": " + StrF(*PtrV1\px)+","+StrF(*PtrV1\py)+","+StrF(*PtrV1\pz)
  Debug "      Vertex réf., n°" + Str((*PtrV2 - dynMesh(nummesh)\vertexBuffer)/SizeOf(Vertex)) + ": " + StrF(*PtrV2\px)+","+StrF(*PtrV2\py)+","+StrF(*PtrV2\pz)


  ; Phase 2: on calcule la position des nouveaux vertices
  VertexA\px = (*PtrV0\px + *PtrV1\px) / 2.0
  VertexA\py = (*PtrV0\py + *PtrV1\py) / 2.0
  VertexA\pz = (*PtrV0\pz + *PtrV1\pz) / 2.0
  VertexA\nx = VertexA\px / dynMesh(nummesh)\sizex
  VertexA\ny = VertexA\py / dynMesh(nummesh)\sizey
  VertexA\nz = VertexA\pz / dynMesh(nummesh)\sizez
  VertexA\couleur = (*PtrV0\couleur + *PtrV1\couleur) / 2.0
  VertexA\U =  (*PtrV0\U + *PtrV1\U) / 2.0
  VertexA\V =  (*PtrV0\V + *PtrV1\V) / 2.0

  VertexB\px = (*PtrV0\px + *PtrV2\px) / 2.0
  VertexB\py = (*PtrV0\py + *PtrV2\py) / 2.0
  VertexB\pz = (*PtrV0\pz + *PtrV2\pz) / 2.0
  VertexB\nx = VertexB\px / dynMesh(nummesh)\sizex
  VertexB\ny = VertexB\py / dynMesh(nummesh)\sizey
  VertexB\nz = VertexB\pz / dynMesh(nummesh)\sizez 
  VertexB\couleur = (*PtrV0\couleur + *PtrV2\couleur) / 2.0
  VertexB\U =  (*PtrV0\U + *PtrV2\U) / 2.0
  VertexB\V =  (*PtrV0\V + *PtrV2\V) / 2.0

  VertexC\px = (*PtrV1\px + *PtrV2\px) / 2.0
  VertexC\py = (*PtrV1\py + *PtrV2\py) / 2.0
  VertexC\pz = (*PtrV1\pz + *PtrV2\pz) / 2.0
  VertexC\nx = VertexC\px / dynMesh(nummesh)\sizex
  VertexC\ny = VertexC\py / dynMesh(nummesh)\sizey
  VertexC\nz = VertexC\pz / dynMesh(nummesh)\sizez
  VertexC\couleur = (*PtrV1\couleur + *PtrV2\couleur) / 2.0
  VertexC\U =  (*PtrV1\U + *PtrV2\U) / 2.0
  VertexC\V =  (*PtrV1\V + *PtrV2\V) / 2.0

  ; on écrira les nouveaux vertices/faces à ces endroits:
  *PtrNewV = dynMesh(nummesh)\vertexBuffer + (SizeOf(Vertex) * (oldNbVert) )
  *PtrNewF = dynMesh(nummesh)\faceBuffer + (SizeOf(FaceTri) * (oldNbFace) )  

  ; Add a new triangle...
  ;AddTri( *PtrV1, VertexC, VertexA)
  *PtrNewV\px = *PtrV1\px
  *PtrNewV\py = *PtrV1\py
  *PtrNewV\pz = *PtrV1\pz
  *PtrNewV\nx = *PtrV1\nx 
  *PtrNewV\ny = *PtrV1\ny
  *PtrNewV\nz = *PtrV1\nz 
  *PtrNewV\couleur = *PtrV1\couleur 
  *PtrNewV\u = *PtrV1\u
  *PtrNewV\v = *PtrV1\v
  Debug "         New Vertex, n°" + Str((*PtrNewV - dynMesh(nummesh)\vertexBuffer)/SizeOf(Vertex)) + ": " + StrF(*PtrNewV\px)+","+StrF(*PtrNewV\py)+","+StrF(*PtrNewV\pz)
  *PtrNewV + SizeOf(Vertex)

  *PtrNewV\px = VertexC\px
  *PtrNewV\py = VertexC\py
  *PtrNewV\pz = VertexC\pz
  *PtrNewV\nx = VertexC\nx 
  *PtrNewV\ny = VertexC\ny
  *PtrNewV\nz = VertexC\nz 
  *PtrNewV\couleur = VertexC\couleur 
  *PtrNewV\u = VertexC\u
  *PtrNewV\v = VertexC\v
  Debug "         New Vertex, n°" + Str((*PtrNewV - dynMesh(nummesh)\vertexBuffer)/SizeOf(Vertex)) + ": " + StrF(*PtrNewV\px)+","+StrF(*PtrNewV\py)+","+StrF(*PtrNewV\pz)
  *PtrNewV + SizeOf(Vertex)

  *PtrNewV\px = VertexA\px
  *PtrNewV\py = VertexA\py
  *PtrNewV\pz = VertexA\pz
  *PtrNewV\nx = VertexA\nx 
  *PtrNewV\ny = VertexA\ny
  *PtrNewV\nz = VertexA\nz 
  *PtrNewV\couleur = VertexA\couleur 
  *PtrNewV\u = VertexA\u
  *PtrNewV\v = VertexA\v
  Debug "         New Vertex, n°" + Str((*PtrNewV - dynMesh(nummesh)\vertexBuffer)/SizeOf(Vertex)) + ": " + StrF(*PtrNewV\px)+","+StrF(*PtrNewV\py)+","+StrF(*PtrNewV\pz)
  *PtrNewV + SizeOf(Vertex)
  
  *PtrNewF\f1=newVertNum +1
  *PtrNewF\f2=newVertNum +2
  *PtrNewF\f3=newVertNum 
  Debug "           => new triangle, n°" + Str((*PtrNewF - dynMesh(nummesh)\faceBuffer)/SizeOf(FaceTri)) + ": " + Str(*PtrNewF\f1)+","+Str(*PtrNewF\f2)+","+Str(*PtrNewF\f3)
  *PtrNewF + SizeOf(FaceTri) 
  newVertNum+3
   
  ; ...add another...
  ;AddTri( *PtrV2, VertexB, VertexC)

  *PtrNewV\px = *PtrV2\px
  *PtrNewV\py = *PtrV2\py
  *PtrNewV\pz = *PtrV2\pz
  *PtrNewV\nx = *PtrV2\nx 
  *PtrNewV\ny = *PtrV2\ny
  *PtrNewV\nz = *PtrV2\nz 
  *PtrNewV\couleur = *PtrV2\couleur 
  *PtrNewV\u = *PtrV2\u
  *PtrNewV\v = *PtrV2\v
  Debug "         New Vertex, n°" + Str((*PtrNewV - dynMesh(nummesh)\vertexBuffer)/SizeOf(Vertex)) + ": " + StrF(*PtrNewV\px)+","+StrF(*PtrNewV\py)+","+StrF(*PtrNewV\pz)
  *PtrNewV + SizeOf(Vertex)
  
  *PtrNewV\px = VertexB\px
  *PtrNewV\py = VertexB\py
  *PtrNewV\pz = VertexB\pz
  *PtrNewV\nx = VertexB\nx 
  *PtrNewV\ny = VertexB\ny
  *PtrNewV\nz = VertexB\nz 
  *PtrNewV\couleur = VertexB\couleur 
  *PtrNewV\u = VertexB\u
  *PtrNewV\v = VertexB\v
  Debug "         New Vertex, n°" + Str((*PtrNewV - dynMesh(nummesh)\vertexBuffer)/SizeOf(Vertex)) + ": " + StrF(*PtrNewV\px)+","+StrF(*PtrNewV\py)+","+StrF(*PtrNewV\pz)
  *PtrNewV + SizeOf(Vertex)

  *PtrNewV\px = VertexC\px
  *PtrNewV\py = VertexC\py
  *PtrNewV\pz = VertexC\pz
  *PtrNewV\nx = VertexC\nx 
  *PtrNewV\ny = VertexC\ny
  *PtrNewV\nz = VertexC\nz 
  *PtrNewV\couleur = VertexC\couleur 
  *PtrNewV\u = VertexC\u
  *PtrNewV\v = VertexC\v
  Debug "         New Vertex, n°" + Str((*PtrNewV - dynMesh(nummesh)\vertexBuffer)/SizeOf(Vertex)) + ": " + StrF(*PtrNewV\px)+","+StrF(*PtrNewV\py)+","+StrF(*PtrNewV\pz)
  *PtrNewV + SizeOf(Vertex)
  
  *PtrNewF\f1=newVertNum +1
  *PtrNewF\f2=newVertNum +2
  *PtrNewF\f3=newVertNum 
  Debug "           => new triangle, n°" + Str((*PtrNewF - dynMesh(nummesh)\faceBuffer)/SizeOf(FaceTri)) + ": " + Str(*PtrNewF\f1)+","+Str(*PtrNewF\f2)+","+Str(*PtrNewF\f3)
  *PtrNewF + SizeOf(FaceTri) 
  newVertNum+3

  ; ...and another...
  ;AddTri( VertexA, VertexC, VertexB)
  *PtrNewV\px = VertexA\px
  *PtrNewV\py = VertexA\py
  *PtrNewV\pz = VertexA\pz
  *PtrNewV\nx = VertexA\nx 
  *PtrNewV\ny = VertexA\ny
  *PtrNewV\nz = VertexA\nz 
  *PtrNewV\couleur = VertexA\couleur 
  *PtrNewV\u = VertexA\u
  *PtrNewV\v = VertexA\v
  Debug "         New Vertex, n°" + Str((*PtrNewV - dynMesh(nummesh)\vertexBuffer)/SizeOf(Vertex)) + ": " + StrF(*PtrNewV\px)+","+StrF(*PtrNewV\py)+","+StrF(*PtrNewV\pz)
  *PtrNewV + SizeOf(Vertex)
  
  *PtrNewV\px = VertexC\px
  *PtrNewV\py = VertexC\py
  *PtrNewV\pz = VertexC\pz
  *PtrNewV\nx = VertexC\nx 
  *PtrNewV\ny = VertexC\ny
  *PtrNewV\nz = VertexC\nz 
  *PtrNewV\couleur = VertexC\couleur 
  *PtrNewV\u = VertexC\u
  *PtrNewV\v = VertexC\v
  Debug "         New Vertex, n°" + Str((*PtrNewV - dynMesh(nummesh)\vertexBuffer)/SizeOf(Vertex)) + ": " + StrF(*PtrNewV\px)+","+StrF(*PtrNewV\py)+","+StrF(*PtrNewV\pz)
  *PtrNewV + SizeOf(Vertex)

  *PtrNewV\px = VertexB\px
  *PtrNewV\py = VertexB\py
  *PtrNewV\pz = VertexB\pz
  *PtrNewV\nx = VertexB\nx 
  *PtrNewV\ny = VertexB\ny
  *PtrNewV\nz = VertexB\nz 
  *PtrNewV\couleur = VertexB\couleur 
  *PtrNewV\u = VertexB\u
  *PtrNewV\v = VertexB\v
  Debug "         New Vertex, n°" + Str((*PtrNewV - dynMesh(nummesh)\vertexBuffer)/SizeOf(Vertex)) + ": " + StrF(*PtrNewV\px)+","+StrF(*PtrNewV\py)+","+StrF(*PtrNewV\pz)
  *PtrNewV + SizeOf(Vertex)
  
  *PtrNewF\f1=newVertNum +1
  *PtrNewF\f2=newVertNum +2 
  *PtrNewF\f3=newVertNum 
  Debug "           => new triangle, n°" + Str((*PtrNewF - dynMesh(nummesh)\faceBuffer)/SizeOf(FaceTri)) + ": " + Str(*PtrNewF\f1)+","+Str(*PtrNewF\f2)+","+Str(*PtrNewF\f3)
  *PtrNewF + SizeOf(FaceTri) 
  newVertNum+3

   
  ; ...then resize base triangle.
  *PtrV1\px = VertexA\px
  *PtrV1\py = VertexA\py
  *PtrV1\pz = VertexA\pz
  *PtrV1\nx = VertexA\nx
  *PtrV1\ny = VertexA\ny
  *PtrV1\nz = VertexA\nz
  *PtrV1\couleur = VertexA\couleur
  *PtrV1\U  = VertexA\U
  *PtrV1\V  = VertexA\V
  Debug "         Reposition Vertex, n°" + Str((*PtrV1 - dynMesh(nummesh)\vertexBuffer)/SizeOf(Vertex)) + ": " + StrF(*PtrV1\px)+","+StrF(*PtrV1\py)+","+StrF(*PtrV1\pz)

  *PtrV2\px = VertexB\px
  *PtrV2\py = VertexB\py
  *PtrV2\pz = VertexB\pz
  *PtrV2\nx = VertexB\nx
  *PtrV2\ny = VertexB\ny
  *PtrV2\nz = VertexB\nz
  *PtrV2\ couleur= VertexB\couleur
  *PtrV2\U  = VertexB\U
  *PtrV2\V  = VertexB\V
  Debug "         Reposition Vertex, n°" + Str((*PtrV2 - dynMesh(nummesh)\vertexBuffer)/SizeOf(Vertex)) + ": " + StrF(*PtrV2\px)+","+StrF(*PtrV2\py)+","+StrF(*PtrV2\pz) 
  
;   *PtrNewF = dynmesh(nummesh)\faceBuffer + numtri*SizeOf(faceTri)
;   temp = *PtrNewF\f3
;   *PtrNewF\f3 = *PtrNewF\f2
;   *PtrNewF\f2 = *PtrNewF\f1
;   *PtrNewF\f1 = temp
;   temp = *PtrNewF\f3
;   *PtrNewF\f3 = *PtrNewF\f2
;   *PtrNewF\f2 = *PtrNewF\f1
;   *PtrNewF\f1 = temp
  
  
  Debug "---------------------------------------------------"
  
EndProcedure

;************************************************************************************
; Name: subdivideMesh
; Purpose: Subdivides each triangle of a mesh, then inflates the mesh to make it look spheric
;   - mesh indice in the "dynMesh" array
;   - how many times the process will be repeated
;************************************************************************************
Procedure subdivideMesh(nummesh.l,nbiteration.b)
   Protected i.l,j.l,top.l

   ; subdivision
   For j = 1 To nbiteration
      top =  dynMesh(nummesh)\nbTri - 1
      For i = 0 To top
         subdivideTriangle(nummesh,i)
      Next i
   Next j
      
   ; modify mesh infos
   SetMeshData(dynMesh(nummesh)\numMesh,#PB_Mesh_Vertex | #PB_Mesh_Normal | #PB_Mesh_Color | #PB_Mesh_UVCoordinate,dynMesh(nummesh)\vertexBuffer,dynMesh(nummesh)\nbVert) 
   SetMeshData(dynMesh(nummesh)\numMesh,#PB_Mesh_Face,dynMesh(nummesh)\faceBuffer,dynMesh(nummesh)\nbTri) 

EndProcedure

;************************************************************************************
; Name: normalizeMesh
; Purpose: Subdivides each triangle of a mesh, then inflates the mesh to make it look spheric
;   - mesh indice in the "dynMesh" array
;   - how many times the process will be repeated
;************************************************************************************
Procedure normalizeMesh(nummesh.l)

  Protected *ptrVert.vertex,*PtrV0.vertex,*PtrV1.vertex,*PtrV2.vertex
  Protected *ptrFace.faceTri
  Protected normVect1.Vector3,normVect2.Vector3,faceNormal.Vector3
  Protected i.l,j.l,length.f
  
 ; Initialize vertices' normals to 0
  *ptrVert = dynMesh(numMesh)\vertexBuffer
  For i = 1 To dynmesh(numMesh)\nbVert
    *ptrVert\nx = 0
    *ptrVert\ny = 0
    *ptrVert\nz = 0

    *ptrVert+SizeOf(Vertex)
  Next i
  
  ; For each facet of the mesh:
  *ptrFace = dynMesh(nummesh)\faceBuffer
  For i = 1 To dynMesh(nummesh)\nbTri
    ;Debug "Face n°" + Str(i-1) + " - vertices " + Str(*ptrface\f1)+","+ Str(*ptrface\f2)+","+ Str(*ptrface\f3)
  
    ; Get facet normal
    *PtrV0 = dynMesh(nummesh)\vertexBuffer + (*ptrface\f1 * SizeOf(Vertex))
    *PtrV1 = dynMesh(nummesh)\vertexBuffer + (*ptrface\f2 * SizeOf(Vertex))
    *PtrV2 = dynMesh(nummesh)\vertexBuffer + (*ptrface\f3 * SizeOf(Vertex))
  
    normVect1\x = (*PtrV1\px - *PtrV0\px)
    normVect1\y = (*PtrV1\py - *PtrV0\py)
    normVect1\z = (*PtrV1\pz - *PtrV0\pz)
    
    normVect2\x = (*PtrV2\px - *PtrV0\px)
    normVect2\y = (*PtrV2\py - *PtrV0\py)
    normVect2\z = (*PtrV2\pz - *PtrV0\pz)
    
    faceNormal\x = ((normVect1\y * normVect2\z) - (normVect1\z * normVect2\y))
    faceNormal\y = ((normVect1\z * normVect2\x) - (normVect1\x * normVect2\z))
    faceNormal\z = ((normVect1\x * normVect2\y) - (normVect1\y * normVect2\x))
    
    Length = Sqr(faceNormal\x*faceNormal\x + faceNormal\y*faceNormal\y + faceNormal\z*faceNormal\z)
    faceNormal\x / Length
    faceNormal\y / Length
    faceNormal\z / Length   
    ;Debug "=> Normal = "+StrF(faceNormal\x)+","+StrF(faceNormal\y)+","+StrF(faceNormal\z)
    
    ; First vertex of face
    *ptrVert = dynMesh(numMesh)\vertexBuffer
    ; for all vertices at the same position, add face normal to vertex normal
    For j = 1 To dynmesh(numMesh)\nbVert
      If *ptrVert\px = *ptrV0\px And *ptrVert\py = *ptrV0\py And *ptrVert\pz = *ptrV0\pz 
        *ptrVert\nx + faceNormal\x
        *ptrVert\ny + faceNormal\y
        *ptrVert\nz + faceNormal\z
        ;Debug "   vertex " + Str(*ptrface\f1) +" = vertex " + Str(j-1)
      EndIf
      *ptrVert+SizeOf(Vertex)
    Next j
    
    ; Second vertex of face
    *ptrVert = dynMesh(numMesh)\vertexBuffer
    ; for all vertices at the same position, add face normal to vertex normal
    For j = 1 To dynmesh(numMesh)\nbVert
      If *ptrVert\px = *ptrV1\px And *ptrVert\py = *ptrV1\py And *ptrVert\pz = *ptrV1\pz 
        *ptrVert\nx + faceNormal\x
        *ptrVert\ny + faceNormal\y
        *ptrVert\nz + faceNormal\z
        ;Debug "   vertex " + Str(*ptrface\f2) +" = vertex " + Str(j-1)
      EndIf
      *ptrVert+SizeOf(Vertex)
    Next j
       
    ; Third vertex of face
    *ptrVert = dynMesh(numMesh)\vertexBuffer
    ; for all vertices at the same position, add face normal to vertex normal
    For j = 1 To dynmesh(numMesh)\nbVert
      If *ptrVert\px = *ptrV2\px And *ptrVert\py = *ptrV2\py And *ptrVert\pz = *ptrV2\pz 
        *ptrVert\nx + faceNormal\x
        *ptrVert\ny + faceNormal\y
        *ptrVert\nz + faceNormal\z
        ;Debug "   vertex " + Str(*ptrface\f3) +" = vertex " + Str(j-1)
      EndIf
      *ptrVert+SizeOf(Vertex)
    Next j
    
    *ptrFace+SizeOf(faceTri)
  Next i
  
  ; Then, average (= normalize) all the vertices' normals
  *ptrVert = dynMesh(numMesh)\vertexBuffer
  For j = 1 To dynmesh(numMesh)\nbVert
    normVect1\x = *ptrVert\nx
    normVect1\y = *ptrVert\ny
    normVect1\z = *ptrVert\nz
    
    NormalizeVector(@normVect1)
    

     *ptrVert\nx = normVect1\x
     *ptrVert\ny = normVect1\y
     *ptrVert\nz = normVect1\z  
    
    *ptrVert+SizeOf(Vertex)
  Next j
  
   ; modify mesh infos

   SetMeshData(dynMesh(nummesh)\numMesh,#PB_Mesh_Vertex | #PB_Mesh_Normal | #PB_Mesh_Color | #PB_Mesh_UVCoordinate,dynMesh(nummesh)\vertexBuffer,dynMesh(nummesh)\nbVert) 
   ;SetMeshData(dynMesh(nummesh)\numMesh,#PB_Mesh_Face,dynMesh(nummesh)\faceBuffer,dynMesh(nummesh)\nbTri) 

EndProcedure
DisableExplicit
;************************************************************************************

;- ---- Main loop ----
;-Mesh 
; Change parameters 2 to 8 to test the effects on size and texturing
Global myOctaMesh.l
myOctaMesh = CreateDynMesh("Octa",#octahedron,1,1,1,0,0,4,4,RGB(0,127,200)) 

;-Texture 
CreateTexture(0,128, 128) 
StartDrawing(TextureOutput(0)) 
  Box(0, 0, 128, 128, $FFFFFF) 
  DrawingMode(#PB_2DDrawing_Outlined)
StopDrawing()  

;-Material
CreateMaterial(0,TextureID(0)) 
;MaterialAmbientColor(0,#PB_Material_AmbientColors)
MaterialShadingMode(0, #PB_Material_Phong)


CreateMaterial(1,TextureID(0)) 
;MaterialAmbientColor(1,#PB_Material_AmbientColors)

;-Entity 
CreateEntity(0,MeshID(dynMesh(myOctaMesh)\numMesh),MaterialID(0))

;-Camera 
CreateCamera(0, 0, 0 , 100 , 100) 
MoveCamera(0,0,0,5) 
CameraLookAt(0,EntityX(0),EntityY(0),EntityZ(0)) 

;-Light 
AmbientColor(RGB(63,63,63)) 
CreateLight(0,RGB(255,255,255),300,300,300) 


Global *ptrFace.faceTri,*ptrVert.vertex,temp.w
pas.f = 0.8
angle.f = 0
Repeat 
   If fullscreen = 0 
      While WindowEvent() : Wend 
   EndIf
   
   ; Rotate 
   If rotate=1
    Angle + Pas
    RotateEntity(0, angle,angle/2,-angle)
   EndIf 

   ; Manage camera views
   If ExamineKeyboard() 
      If KeyboardReleased(#PB_Key_F1) 
       CameraMode=1-CameraMode 
       CameraRenderMode(0,CameraMode) 
       AmbientColor(RGB(105+cameramode*150,105+cameramode*150,105+cameramode*150)) 
     EndIf 
     
     If KeyboardReleased(#PB_Key_S) 
       subdivideMesh(0,1)
     EndIf     
     
     If KeyboardReleased(#PB_Key_N) 
       normalizeMesh(0)
     EndIf    
      
     If KeyboardReleased(#PB_Key_G)
       mat=1-mat
       EntityMaterial(0,MaterialID(mat))
     EndIf
         
     If KeyboardReleased(#PB_Key_R) 
       rotate = 1-rotate
     EndIf
     
     If KeyboardReleased(#PB_Key_I) 
       inflateMesh(0)
       SetMeshData(dynMesh(0)\numMesh,#PB_Mesh_Vertex | #PB_Mesh_Normal | #PB_Mesh_Color | #PB_Mesh_UVCoordinate,dynMesh(0)\vertexBuffer,dynMesh(0)\nbVert) 
     EndIf
     
     If KeyboardReleased(#PB_Key_B) 
       *ptrVert = dynMesh(0)\vertexBuffer
       For i = 1 To dynMesh(0)\nbVert
        *ptrVert\ny=*ptrVert\px
        *ptrVert\nx=*ptrVert\py
        *ptrVert\nz=*ptrVert\pz
        Debug Sqr( *ptrVert\px* *ptrVert\px+ *ptrVert\py* *ptrVert\py+ *ptrVert\pz* *ptrVert\pz)
        
        *ptrFace+SizeOf(vertex)
       Next i
       SetMeshData(dynMesh(0)\numMesh,#PB_Mesh_Vertex | #PB_Mesh_Normal | #PB_Mesh_Color | #PB_Mesh_UVCoordinate,dynMesh(0)\vertexBuffer,dynMesh(0)\nbVert) 
       SetMeshData(dynMesh(0)\numMesh,#PB_Mesh_Face,dynMesh(0)\faceBuffer,dynMesh(0)\nbTri) 
     EndIf
     
     If KeyboardReleased(#PB_Key_1)
        *ptrFace = dynMesh(0)\faceBuffer
        For i = 1 To dynMesh(0)\nbTri Step 4
           Debug Str(*ptrFace\f1)+","+Str(*ptrFace\f2)+","+Str(*ptrFace\f3)
           temp = *ptrFace\f3
           *ptrFace\f3 = *ptrFace\f2
           *ptrFace\f2 = *ptrFace\f1
           *ptrFace\f1 = temp
           Debug "=> "+Str(*ptrFace\f1)+","+Str(*ptrFace\f2)+","+Str(*ptrFace\f3)
           *ptrFace+SizeOf(faceTri)*4
        Next i
        ;normalizeMesh(0)
        ;SetMeshData(dynMesh(0)\numMesh,#PB_Mesh_Vertex | #PB_Mesh_Normal | #PB_Mesh_Color | #PB_Mesh_UVCoordinate,dynMesh(0)\vertexBuffer,dynMesh(0)\nbVert) 
        SetMeshData(dynMesh(0)\numMesh,#PB_Mesh_Face,dynMesh(0)\faceBuffer,dynMesh(0)\nbTri) 
     EndIf     
     If KeyboardReleased(#PB_Key_2)
        *ptrFace = dynMesh(0)\faceBuffer+SizeOf(faceTri)
        For i = 1 To dynMesh(0)\nbTri Step 4
           Debug Str(*ptrFace\f1)+","+Str(*ptrFace\f2)+","+Str(*ptrFace\f3)
           temp = *ptrFace\f3
           *ptrFace\f3 = *ptrFace\f2
           *ptrFace\f2 = *ptrFace\f1
           *ptrFace\f1 = temp
           Debug "=> "+Str(*ptrFace\f1)+","+Str(*ptrFace\f2)+","+Str(*ptrFace\f3)
           *ptrFace+SizeOf(faceTri)*4
        Next i
        ;normalizeMesh(0)
        ;SetMeshData(dynMesh(0)\numMesh,#PB_Mesh_Vertex | #PB_Mesh_Normal | #PB_Mesh_Color | #PB_Mesh_UVCoordinate,dynMesh(0)\vertexBuffer,dynMesh(0)\nbVert) 
        SetMeshData(dynMesh(0)\numMesh,#PB_Mesh_Face,dynMesh(0)\faceBuffer,dynMesh(0)\nbTri) 
     EndIf     
     If KeyboardReleased(#PB_Key_3)
        *ptrFace = dynMesh(0)\faceBuffer+SizeOf(faceTri)*2
        For i = 1 To dynMesh(0)\nbTri Step 4
           Debug Str(*ptrFace\f1)+","+Str(*ptrFace\f2)+","+Str(*ptrFace\f3)
           temp = *ptrFace\f3
           *ptrFace\f3 = *ptrFace\f2
           *ptrFace\f2 = *ptrFace\f1
           *ptrFace\f1 = temp
           Debug "=> "+Str(*ptrFace\f1)+","+Str(*ptrFace\f2)+","+Str(*ptrFace\f3)
           *ptrFace+SizeOf(faceTri)*4
        Next i
        ;normalizeMesh(0)
        ;SetMeshData(dynMesh(0)\numMesh,#PB_Mesh_Vertex | #PB_Mesh_Normal | #PB_Mesh_Color | #PB_Mesh_UVCoordinate,dynMesh(0)\vertexBuffer,dynMesh(0)\nbVert) 
        SetMeshData(dynMesh(0)\numMesh,#PB_Mesh_Face,dynMesh(0)\faceBuffer,dynMesh(0)\nbTri) 
     EndIf     
     If KeyboardReleased(#PB_Key_4)
        *ptrFace = dynMesh(0)\faceBuffer+SizeOf(faceTri)*3
        For i = 1 To dynMesh(0)\nbTri Step 4
           Debug Str(*ptrFace\f1)+","+Str(*ptrFace\f2)+","+Str(*ptrFace\f3)
           temp = *ptrFace\f3
           *ptrFace\f3 = *ptrFace\f2
           *ptrFace\f2 = *ptrFace\f1
           *ptrFace\f1 = temp
           Debug "=> "+Str(*ptrFace\f1)+","+Str(*ptrFace\f2)+","+Str(*ptrFace\f3)
           *ptrFace+SizeOf(faceTri)*4
        Next i
        ;normalizeMesh(0)
        ;SetMeshData(dynMesh(0)\numMesh,#PB_Mesh_Vertex | #PB_Mesh_Normal | #PB_Mesh_Color | #PB_Mesh_UVCoordinate,dynMesh(0)\vertexBuffer,dynMesh(0)\nbVert) 
        SetMeshData(dynMesh(0)\numMesh,#PB_Mesh_Face,dynMesh(0)\faceBuffer,dynMesh(0)\nbTri) 
     EndIf     
     

   EndIf 
   
  ; show it all
  RenderWorld() 
   
  ; A little help
  StartDrawing(ScreenOutput())
  DrawText(0,0,"[F1] to change RenderMode, [G] to swap between Gouraud/Phong, [R] to rotate", $00FFFF, $BB0000)
  DrawText(0,15,"[S] to subdivide mesh, [I] to spherify mesh, [N] to smooth normals", $00FFFF, $BB0000)
  DrawText(0,30,Str(dynMesh(0)\nbVert) + " vertices, taille du buffer = " + Str(MemorySize(dynMesh(0)\vertexBuffer)) + " octets", $00FFFF, $BB0000)
  DrawText(0,45,Str(dynMesh(0)\nbTri) + " faces, taille du buffer = " + Str(MemorySize(dynMesh(0)\FaceBuffer)) + " octets", $00FFFF, $BB0000)
  StopDrawing() 
  
  ; Flip buffers to avoid tearing  
  FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape) 

deleteDynMesh(myOctaMesh)


DataSection:
octahedron:
; Nb sommets / Nb faces
Data.l 24,8

; Vertices: pos / normals / uv
Data.f 0,1,0
Data.f 0,1,0
Data.f 0.5,0.5
Data.f 0,0,1
Data.f 0,0,1
Data.f 0,0
Data.f 1,0,0
Data.f 1,0,0
Data.f 1,0

Data.f 0,1,0
Data.f 0,1,0
Data.f 0.5,0.5
Data.f 1,0,0
Data.f 1,0,0
Data.f 1,0
Data.f 0,0,-1
Data.f 0,0,-1
Data.f 1,1

Data.f 0,1,0
Data.f 0,1,0
Data.f 0.5,0.5
Data.f 0,0,-1
Data.f 0,0,-1
Data.f 1,1
Data.f -1,0,0
Data.f -1,0,0
Data.f 0,1

Data.f 0,1,0
Data.f 0,1,0
Data.f 0.5,0.5
Data.f -1,0,0
Data.f -1,0,0
Data.f 0,1
Data.f 0,0,1
Data.f 0,0,1
Data.f 0,0

Data.f 0,-1,0
Data.f 0,-1,0
Data.f 0.5,0.5
Data.f 1,0,0
Data.f 1,0,0
Data.f 1,0
Data.f 0,0,1
Data.f 0,0,1
Data.f 0,0

Data.f 0,-1,0
Data.f 0,-1,0
Data.f 0.5,0.5
Data.f 0,0,-1
Data.f 0,0,-1
Data.f 1,1
Data.f 1,0,0
Data.f 1,0,0
Data.f 1,0

Data.f 0,-1,0
Data.f 0,-1,0
Data.f 0.5,0.5
Data.f -1,0,0
Data.f -1,0,0
Data.f 0,1
Data.f 0,0,-1
Data.f 0,0,-1
Data.f 1,1

Data.f 0,-1,0
Data.f 0,-1,0
Data.f 0.5,0.5
Data.f 0,0,1
Data.f 0,0,1
Data.f 0,0
Data.f -1,0,0
Data.f -1,0,0
Data.f 0,1

; Faces
Data.w 0,1,2
Data.w 3,4,5
Data.w 6,7,8
Data.w 9,10,11
Data.w 12,13,14
Data.w 15,16,17
Data.w 18,19,20
Data.w 21,22,23



PointyCube:

; Nb sommets / Nb faces
Data.l 72,24



; Vertices: pos / uv
Data.f 0,1,0
Data.f 0,1,0
Data.f 0.5,0.5
Data.f -#SQRT03,#SQRT03,#SQRT03
Data.f -#SQRT03,#SQRT03,#SQRT03

Data.f 0,0
Data.f #SQRT03,#SQRT03,#SQRT03
Data.f #SQRT03,#SQRT03,#SQRT03
Data.f 1,0
Data.f 0,1,0
Data.f 0,1,0
Data.f 0.5,0.5
Data.f #SQRT03,#SQRT03,#SQRT03
Data.f #SQRT03,#SQRT03,#SQRT03
Data.f 1,0
Data.f #SQRT03,#SQRT03,-#SQRT03
Data.f #SQRT03,#SQRT03,-#SQRT03
Data.f 1,1
Data.f 0,1,0
Data.f 0,1,0
Data.f 0.5,0.5
Data.f #SQRT03,#SQRT03,-#SQRT03
Data.f #SQRT03,#SQRT03,-#SQRT03
Data.f 1,1
Data.f -#SQRT03,#SQRT03,-#SQRT03
Data.f -#SQRT03,#SQRT03,-#SQRT03
Data.f 0,1
Data.f 0,1,0
Data.f 0,1,0
Data.f 0.5,0.5
Data.f -#SQRT03,#SQRT03,-#SQRT03
Data.f -#SQRT03,#SQRT03,-#SQRT03
Data.f 0,1
Data.f -#SQRT03,#SQRT03,#SQRT03
Data.f -#SQRT03,#SQRT03,#SQRT03
Data.f 0,0
Data.f 0,-1,0
Data.f 0,-1,0
Data.f 0.5,0.5
Data.f #SQRT03,-#SQRT03,#SQRT03
Data.f #SQRT03,-#SQRT03,#SQRT03
Data.f 0,0
Data.f -#SQRT03,-#SQRT03,#SQRT03
Data.f -#SQRT03,-#SQRT03,#SQRT03
Data.f 1,0
Data.f 0,-1,0
Data.f 0,-1,0
Data.f 0.5,0.5
Data.f #SQRT03,-#SQRT03,-#SQRT03
Data.f #SQRT03,-#SQRT03,-#SQRT03
Data.f 1,0
Data.f #SQRT03,-#SQRT03,#SQRT03
Data.f #SQRT03,-#SQRT03,#SQRT03
Data.f 1,1
Data.f 0,-1,0
Data.f 0,-1,0
Data.f 0.5,0.5
Data.f -#SQRT03,-#SQRT03,-#SQRT03
Data.f -#SQRT03,-#SQRT03,-#SQRT03
Data.f 1,1
Data.f #SQRT03,-#SQRT03,-#SQRT03
Data.f #SQRT03,-#SQRT03,-#SQRT03
Data.f 0,1
Data.f 0,-1,0
Data.f 0,-1,0
Data.f 0.5,0.5
Data.f -#SQRT03,-#SQRT03,#SQRT03
Data.f -#SQRT03,-#SQRT03,#SQRT03
Data.f 0,1
Data.f -#SQRT03,-#SQRT03,-#SQRT03
Data.f -#SQRT03,-#SQRT03,-#SQRT03
Data.f 0,0
Data.f 1,0,0
Data.f 1,0,0
Data.f 0.5,0.5
Data.f #SQRT03,#SQRT03,-#SQRT03
Data.f #SQRT03,#SQRT03,-#SQRT03
Data.f 0,0
Data.f #SQRT03,#SQRT03,#SQRT03
Data.f #SQRT03,#SQRT03,#SQRT03
Data.f 1,0
Data.f 1,0,0
Data.f 1,0,0
Data.f 0.5,0.5
Data.f #SQRT03,#SQRT03,#SQRT03
Data.f #SQRT03,#SQRT03,#SQRT03
Data.f 1,0
Data.f #SQRT03,-#SQRT03,#SQRT03
Data.f #SQRT03,-#SQRT03,#SQRT03
Data.f 1,1
Data.f 1,0,0
Data.f 1,0,0
Data.f 0.5,0.5
Data.f #SQRT03,-#SQRT03,#SQRT03
Data.f #SQRT03,-#SQRT03,#SQRT03
Data.f 1,1
Data.f #SQRT03,-#SQRT03,-#SQRT03
Data.f #SQRT03,-#SQRT03,-#SQRT03
Data.f 0,1
Data.f 1,0,0
Data.f 1,0,0
Data.f 0.5,0.5
Data.f #SQRT03,-#SQRT03,-#SQRT03
Data.f #SQRT03,-#SQRT03,-#SQRT03
Data.f 0,1
Data.f #SQRT03,#SQRT03,-#SQRT03
Data.f #SQRT03,#SQRT03,-#SQRT03
Data.f 0,0
Data.f -1,0,0
Data.f -1,0,0
Data.f 0.5,0.5
Data.f -#SQRT03,#SQRT03,#SQRT03
Data.f -#SQRT03,#SQRT03,#SQRT03
Data.f 0,0
Data.f -#SQRT03,#SQRT03,-#SQRT03
Data.f -#SQRT03,#SQRT03,-#SQRT03
Data.f 1,0
Data.f -1,0,0
Data.f -1,0,0
Data.f 0.5,0.5
Data.f -#SQRT03,-#SQRT03,#SQRT03
Data.f -#SQRT03,-#SQRT03,#SQRT03
Data.f 1,0
Data.f -#SQRT03,#SQRT03,#SQRT03
Data.f -#SQRT03,#SQRT03,#SQRT03
Data.f 1,1
Data.f -1,0,0
Data.f -1,0,0
Data.f 0.5,0.5
Data.f -#SQRT03,-#SQRT03,-#SQRT03
Data.f -#SQRT03,-#SQRT03,-#SQRT03
Data.f 1,1
Data.f -#SQRT03,-#SQRT03,#SQRT03
Data.f -#SQRT03,-#SQRT03,#SQRT03
Data.f 0,1
Data.f -1,0,0
Data.f -1,0,0
Data.f 0.5,0.5
Data.f -#SQRT03,#SQRT03,-#SQRT03
Data.f -#SQRT03,#SQRT03,-#SQRT03
Data.f 0,1
Data.f -#SQRT03,-#SQRT03,-#SQRT03
Data.f -#SQRT03,-#SQRT03,-#SQRT03
Data.f 0,0
Data.f 0,0,-1
Data.f 0,0,-1
Data.f 0.5,0.5
Data.f -#SQRT03,#SQRT03,-#SQRT03
Data.f -#SQRT03,#SQRT03,-#SQRT03
Data.f 0,0
Data.f #SQRT03,#SQRT03,-#SQRT03
Data.f #SQRT03,#SQRT03,-#SQRT03
Data.f 1,0
Data.f 0,0,-1
Data.f 0,0,-1
Data.f 0.5,0.5
Data.f #SQRT03,#SQRT03,-#SQRT03
Data.f #SQRT03,#SQRT03,-#SQRT03
Data.f 1,0
Data.f #SQRT03,-#SQRT03,-#SQRT03
Data.f #SQRT03,-#SQRT03,-#SQRT03
Data.f 1,1
Data.f 0,0,-1
Data.f 0,0,-1
Data.f 0.5,0.5
Data.f #SQRT03,-#SQRT03,-#SQRT03
Data.f #SQRT03,-#SQRT03,-#SQRT03
Data.f 1,1
Data.f -#SQRT03,-#SQRT03,-#SQRT03
Data.f -#SQRT03,-#SQRT03,-#SQRT03
Data.f 0,1
Data.f 0,0,-1
Data.f 0,0,-1
Data.f 0.5,0.5
Data.f -#SQRT03,-#SQRT03,-#SQRT03
Data.f -#SQRT03,-#SQRT03,-#SQRT03
Data.f 0,1
Data.f -#SQRT03,#SQRT03,-#SQRT03
Data.f -#SQRT03,#SQRT03,-#SQRT03
Data.f 0,0
Data.f 0,0,1
Data.f 0,0,1
Data.f 0.5,0.5
Data.f #SQRT03,#SQRT03,#SQRT03
Data.f #SQRT03,#SQRT03,#SQRT03
Data.f 0,0
Data.f -#SQRT03,#SQRT03,#SQRT03
Data.f -#SQRT03,#SQRT03,#SQRT03
Data.f 1,0
Data.f 0,0,1
Data.f 0,0,1
Data.f 0.5,0.5
Data.f #SQRT03,-#SQRT03,#SQRT03
Data.f #SQRT03,-#SQRT03,#SQRT03
Data.f 1,0
Data.f #SQRT03,#SQRT03,#SQRT03
Data.f #SQRT03,#SQRT03,#SQRT03
Data.f 1,1
Data.f 0,0,1
Data.f 0,0,1
Data.f 0.5,0.5
Data.f -#SQRT03,-#SQRT03,#SQRT03
Data.f -#SQRT03,-#SQRT03,#SQRT03
Data.f 1,1
Data.f #SQRT03,-#SQRT03,#SQRT03
Data.f #SQRT03,-#SQRT03,#SQRT03
Data.f 0,1
Data.f 0,0,1
Data.f 0,0,1
Data.f 0.5,0.5
Data.f -#SQRT03,#SQRT03,#SQRT03
Data.f -#SQRT03,#SQRT03,#SQRT03
Data.f 0,1
Data.f -#SQRT03,-#SQRT03,#SQRT03
Data.f -#SQRT03,-#SQRT03,#SQRT03
Data.f 0,0

; Faces
Data.w 0,1,2
Data.w 3,4,5
Data.w 6,7,8
Data.w 9,10,11
Data.w 12,13,14
Data.w 15,16,17
Data.w 18,19,20
Data.w 21,22,23
Data.w 24,25,26
Data.w 27,28,29
Data.w 30,31,32
Data.w 33,34,35
Data.w 36,37,38
Data.w 39,40,41
Data.w 42,43,44
Data.w 45,46,47
Data.w 48,49,50
Data.w 51,52,53
Data.w 54,55,56
Data.w 57,58,59
Data.w 60,61,62
Data.w 63,64,65
Data.w 66,67,68
Data.w 69,70,71

Face:
; Nb sommets / Nb faces
Data.l 3,1

; Vertices: pos / uv
Data.f 0,1,0
Data.f 0,1,0
Data.f 0.5,0.5
Data.f -#SQRT03,#SQRT03,#SQRT03
Data.f -#SQRT03,#SQRT03,#SQRT03
Data.f 0,0
Data.f #SQRT03,#SQRT03,#SQRT03
Data.f #SQRT03,#SQRT03,#SQRT03
Data.f 1,0

; Faces
Data.w 0,1,2

EndDataSection
(Et pour constater l'effet de l'ordre des triangles sur l'ombrage "Phong", appuyez sur 1,2,3, ou 4, ce qui change l'ordre des vertices dans un triangle sur 4)
Dernière modification par kelebrindae le ven. 20/juin/2008 8:30, modifié 1 fois.
Anonyme

Message par Anonyme »

chez moi sa fonctionne parfaitement :/
Anonyme

Message par Anonyme »

Pire: l'ordre des vertices dans les triangles affecte le rendu! (mais seulement en "Flat" et "Phong", pas en Gouraud) Shocked
Logique , c'est à toi de déterminer dans quel ordre tu construits tes meshs , dans le sens des aiguilles d'une montre ou l'inverse , mais pas les 2 , sinon certainne normale seront inversé ! :lol:
kelebrindae
Messages : 579
Inscription : ven. 11/mai/2007 15:21

Message par kelebrindae »

@cpl_bator:
Oui, pour le sens (aiguilles d'une montre ou inverse), je savais. Ce que je ne savais pas, c'est qu'on avait le choix; ça dépend peut-être du FVF...
Ce qui m'étonne, c'est qu'un triangle 1-2-3 ne soit pas ombré de la même façon qu'un triangle 2-3-1 ou 3-1-2 (c'est le même sens).

Comment ça, ça marche chez toi ?!
Tu veux dire que tu n'obtiens pas le résultat lamentable que tu vois dans la capture d'écran ci-dessus ?
Anonyme

Message par Anonyme »

Comment ça, ça marche chez toi ?!
Tu veux dire que tu n'obtiens pas le résultat lamentable que tu vois dans la capture d'écran ci-dessus ?
J'ai un joli rendu. pas de soucis particuliers
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Message par djes »

Cpl.Bator a écrit :
Comment ça, ça marche chez toi ?!
Tu veux dire que tu n'obtiens pas le résultat lamentable que tu vois dans la capture d'écran ci-dessus ?
J'ai un joli rendu. pas de soucis particuliers
+1
kelebrindae
Messages : 579
Inscription : ven. 11/mai/2007 15:21

Message par kelebrindae »

Bon, 'faut que j'essaye sur un autre PC, alors...

Curieux, ça :?
Octavius
Messages : 312
Inscription : jeu. 26/juil./2007 12:10

Message par Octavius »

Chez moi aussi ça marche parfaitement bien le rendu. Par contre je ne peux pas aller au-delà 8192 faces.
MorpheusDX
Messages : 36
Inscription : mar. 21/août/2007 17:31

Message par MorpheusDX »

Idem, j'ai de bon résultat, et le rendu est bon et conforme...
Force et sagesse...
kelebrindae
Messages : 579
Inscription : ven. 11/mai/2007 15:21

Message par kelebrindae »

@Octavius:
Oui, c'est normal: le nombre de vertices par mesh est limité à 65536, je crois. Avec 8192 faces, ça passe (24576 vertices). Après, ça dépasse.
[EDIT le 11/07/2008]
En fait le nombre de vertices est limité à 32768 => c'est du .w signé.
[/EDIT]

@Tout le monde:
Bon, j'ai essayé sur un autre PC et effectivement, le rendu est correct.
Ce qui veut dire que j'ai passé la majeure partie de la journée d'hier à tenter de corriger un bug qui n'existait pas.

Snif... J'crois que j'vais pleurer... :cry:
Dernière modification par kelebrindae le ven. 11/juil./2008 15:46, modifié 2 fois.
Octavius
Messages : 312
Inscription : jeu. 26/juil./2007 12:10

Message par Octavius »

Et t'as une idée d'où ça peut venir alors ?
kelebrindae
Messages : 579
Inscription : ven. 11/mai/2007 15:21

Message par kelebrindae »

Pas vraiment.
Si je devais émettre une hypothèse au hasard, je dirais que l'ombrage Phong fait appel à une fonction (de DirectX?) mal gérée par le driver de ma carte graphique (je faisais le test sur un PC avec un GPU bureautique Intel G910 intégrée à la carte-mère, pas l'idéal pour la 3D).

Pour info, j'ai aussi essayé avec un vieux PC doté seulement d'une GeForce 2 MX de 2002, et ça marche nickel; ça doit donc marcher la plupart du temps, pour peu d'avoir un vrai GPU 3D (même antédiluvien).
Répondre