Page 1 sur 2

[Résolu] Problème avec les pointeurs / reAllocateMemory

Publié : mar. 10/juin/2008 16:11
par kelebrindae
Bonjour à tous,

Je suis en train de bosser sur le petit programme ci-dessous, et je crois que je m'embrouille dans les pointeurs (comme d'habitude).

Le but du programme est simple:
- on génère un mesh dont on garde les infos sur les vertices et les faces en mémoire.
- Quand on appuie sur "S", je prend chaque face du mesh et je la subdivise en 4
=> je dois augmenter la taille de la zone de stockage des vertices et des faces pour y caser ces nouvelles infos.
(Dans ce programme, pour le test, j'ai limité la subdivision au premier triangle du mesh.)

Problème: à partir du moment où j'ai subdivisé ce triangle, quand on sort du programme, le freeMemory se plante sur le buffer des vertices (accès invalide).
Idem si je tente de subdiviser une seconde fois: cette fois, c'est le reAllocate qui me renvoie zéro.

J'en conclus que quelque chose dans ma procédure SubdivideTriangle me pourrit le buffer des vertices, mais j'ai beau me creuser la tête, je ne trouve pas. :cry:

Pitié! Quelqu'un pourrait-il m'aider?

Code : Tout sélectionner

; Author: Kelebrindae
; Date: march,13, 2006
; PB version: v4.10
; OS: Windows XP
; Demo: Yes

#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 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
  nbVert.l
  nbTri.l
  *vertexBuffer.Vertex
  *faceBuffer.FaceTri
EndStructure
#MAXMESH=2
Global Dim dynMesh.dynMesh_struct(#MAXMESH)

Enumeration
  #octahedron
  #pointyCube
EndEnumeration

  EnableExplicit


;- ---- Procedures ----
;************************************************************************************
; Name: CreateDynMesh
; Purpose: Create a mesh, scaled and UV mapped dynamically, and store 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.l,v2.l,v3.l
  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
    
    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
  
    *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,100)
  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

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

;************************************************************************************
; Name: deleteDynMesh
; Purpose: delete 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: subdivideTriangle
; Purpose: Subdivise un triangle du mesh en 4
;   - 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 *PtrF.FaceTri
  Protected *PtrNewV.vertex,*PtrNewF.faceTri
  Protected oldNbVert.l,oldNbFace.l,newVertNum.l

  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))
 

  ; Store current end of vertices/faces datas
  oldNbVert = dynMesh(nummesh)\nbVert
  oldNbFace = dynMesh(nummesh)\nbTri
  newVertNum = oldNbVert + 1
  
  ; 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 = (*PtrV0\nx + *PtrV1\nx) / 2.0
  VertexA\ny = (*PtrV0\ny + *PtrV1\ny) / 2.0
  VertexA\nz = (*PtrV0\nz + *PtrV1\nz) / 2.0
  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 = (*PtrV0\nx + *PtrV2\nx) / 2.0
  VertexB\ny = (*PtrV0\ny + *PtrV2\ny) / 2.0
  VertexB\nz = (*PtrV0\nz + *PtrV2\nz) / 2.0 
  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 = (*PtrV1\nx + *PtrV2\nx) / 2.0
  VertexC\ny = (*PtrV1\ny + *PtrV2\ny) / 2.0
  VertexC\nz = (*PtrV1\nz + *PtrV2\nz) / 2.0 
  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 + 1) )
  *PtrNewF = dynMesh(nummesh)\faceBuffer + (SizeOf(FaceTri) * (oldNbFace + 1) )  

  ; 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  
  *PtrNewF\f2=newVertNum +1
  *PtrNewF\f3=newVertNum +2
  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 
  *PtrNewF\f2=newVertNum +1
  *PtrNewF\f3=newVertNum +2
  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 
  *PtrNewF\f2=newVertNum +1
  *PtrNewF\f3=newVertNum +2
  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\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\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)
  
  Debug "---------------------------------------------------"
EndProcedure

;************************************************************************************
; Name: subdivideMesh
; Purpose: Subdivide each triangle of a mesh
;   - 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

   For j = 1 To nbiteration
      top =  dynMesh(nummesh)\nbTri - 1
      top=0 ; Pour le test, on ne subdivise que le premier triangle du mesh
      For i = 0 To top
         subdivideTriangle(nummesh,i)
      Next i
   Next j
   
    SetMeshData(dynMesh(nummesh)\numMesh,#PB_Mesh_Vertex | #PB_Mesh_Normal | #PB_Mesh_UVCoordinate | #PB_Mesh_Color,dynMesh(nummesh)\vertexBuffer,dynMesh(nummesh)\nbVert) 
    SetMeshData(dynMesh(nummesh)\numMesh,#PB_Mesh_Face,dynMesh(nummesh)\faceBuffer,dynMesh(nummesh)\nbTri) 

EndProcedure

;************************************************************************************

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

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

;-Material 
CreateMaterial(0,TextureID(0)) 

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

;-Camera 
CreateCamera(0, 0, 0 , 100 , 100) 
MoveCamera(0,0,0,-15) 
CameraLookAt(0,0,0,0) 

;-Light 
AmbientColor(RGB(105,105,105)) 
CreateLight(0,RGB(255,255,255),200,300,0) 
CreateLight(1,RGB(255,127,0),-200,-200,200) 


Global pas.f,angle.f
pas = 0.8
angle = 0
Repeat 
   If fullscreen = 0 
      While WindowEvent() : Wend 
   EndIf
   
   ; Rotate 
   Angle + Pas 
   RotateEntity(0, angle,angle/2,-angle) 


   ; 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     
     
   EndIf 
   
  ; show it all
  RenderWorld() 
   
  ; A little help
  StartDrawing(ScreenOutput())
  DrawText(0,0,"[F1] to change RenderMode, [S] to subdivide mesh ", $00FFFF, $BB0000)
  DrawText(0,15,"Taille du buffer des vertices: " + Str(MemorySize(dynMesh(0)\vertexBuffer)) + " octets", $00FFFF, $BB0000)
  DrawText(0,30,"Taille du buffer des faces: " + 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.l 0,1,2
Data.l 3,4,5
Data.l 6,7,8
Data.l 9,10,11
Data.l 12,13,14
Data.l 15,16,17
Data.l 18,19,20
Data.l 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.l 0,1,2
Data.l 3,4,5
Data.l 6,7,8
Data.l 9,10,11
Data.l 12,13,14
Data.l 15,16,17
Data.l 18,19,20
Data.l 21,22,23
Data.l 24,25,26
Data.l 27,28,29
Data.l 30,31,32
Data.l 33,34,35
Data.l 36,37,38
Data.l 39,40,41
Data.l 42,43,44
Data.l 45,46,47
Data.l 48,49,50
Data.l 51,52,53
Data.l 54,55,56
Data.l 57,58,59
Data.l 60,61,62
Data.l 63,64,65
Data.l 66,67,68
Data.l 69,70,71


EndDataSection

Publié : mar. 10/juin/2008 17:40
par Anonyme
Il te faut une batterie de commande te permettant d'ajouté et supprimer des données dans une zone mémoire , en fait , il faut que tu créer une liste chainée ni plus ni moins.
Regarde la lib Vector de lionel OM fait très bien ce que tu demandes. cherche sur le forum ;)

Publié : mar. 10/juin/2008 18:48
par djes
Je me demande aussi si la mémoire n'est pas utilisée par setmeshdata tant que tu ne libères pas l'objet créé.

Publié : mar. 10/juin/2008 20:02
par Ollivier
@Cpl

Comble de mon ignorance envers le travail de lionel_om, je suis en train d'en faire une de lib. Alors, merci pour l'info!

@djes

C'est bien une histoire de ce genre (le pointeur est valide). Seulement, je n'en suis pas à ce stade de développement pour bien cerner le problème.

@kelebrindae

J'ai mis un peu de pommade à ton code pour qu'il arrête de m'afficher cette erreur. Mais ce n'est qu'une méthode de fortune.

Code : Tout sélectionner

; Author: Kelebrindae 
; Date: march,13, 2006 
; PB version: v4.10 
; OS: Windows XP 
; Demo: Yes 

#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 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 
  nbVert.l 
  nbTri.l 
  *vertexBuffer.Vertex 
  *faceBuffer.FaceTri 
EndStructure 
#MAXMESH=2 
Global Dim dynMesh.dynMesh_struct(#MAXMESH) 

Enumeration 
  #octahedron 
  #pointyCube 
EndEnumeration 

  EnableExplicit 


;- ---- Procedures ---- 
;************************************************************************************ 
; Name: CreateDynMesh 
; Purpose: Create a mesh, scaled and UV mapped dynamically, and store 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.l,v2.l,v3.l 
  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 
    
    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 
  
    *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,100) 
  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 

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

;************************************************************************************ 
; Name: deleteDynMesh 
; Purpose: delete 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)
    dynMesh(num)\vertexBuffer = ReAllocateMemory(dynMesh(num)\vertexBuffer, 1) 
    FreeMemory(dynMesh(num)\faceBuffer) 
    dynMesh(num)\numMesh=0 
  
EndProcedure 

;************************************************************************************ 
; Name: subdivideTriangle 
; Purpose: Subdivise un triangle du mesh en 4 
;   - 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 *PtrF.FaceTri 
  Protected *PtrNewV.vertex,*PtrNewF.faceTri 
  Protected oldNbVert.l,oldNbFace.l,newVertNum.l 

  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)) 
  

  ; Store current end of vertices/faces datas 
  oldNbVert = dynMesh(nummesh)\nbVert 
  oldNbFace = dynMesh(nummesh)\nbTri 
  newVertNum = oldNbVert + 1 
  
  ; 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 = (*PtrV0\nx + *PtrV1\nx) / 2.0 
  VertexA\ny = (*PtrV0\ny + *PtrV1\ny) / 2.0 
  VertexA\nz = (*PtrV0\nz + *PtrV1\nz) / 2.0 
  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 = (*PtrV0\nx + *PtrV2\nx) / 2.0 
  VertexB\ny = (*PtrV0\ny + *PtrV2\ny) / 2.0 
  VertexB\nz = (*PtrV0\nz + *PtrV2\nz) / 2.0 
  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 = (*PtrV1\nx + *PtrV2\nx) / 2.0 
  VertexC\ny = (*PtrV1\ny + *PtrV2\ny) / 2.0 
  VertexC\nz = (*PtrV1\nz + *PtrV2\nz) / 2.0 
  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 + 1) ) 
  *PtrNewF = dynMesh(nummesh)\faceBuffer + (SizeOf(FaceTri) * (oldNbFace + 1) )  

  ; 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  
  *PtrNewF\f2=newVertNum +1 
  *PtrNewF\f3=newVertNum +2 
  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 
  *PtrNewF\f2=newVertNum +1 
  *PtrNewF\f3=newVertNum +2 
  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 
  *PtrNewF\f2=newVertNum +1 
  *PtrNewF\f3=newVertNum +2 
  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\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\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) 
  
  Debug "---------------------------------------------------" 
EndProcedure 

;************************************************************************************ 
; Name: subdivideMesh 
; Purpose: Subdivide each triangle of a mesh 
;   - 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 

   For j = 1 To nbiteration 
      top =  dynMesh(nummesh)\nbTri - 1 
      top=0 ; Pour le test, on ne subdivise que le premier triangle du mesh 
      For i = 0 To top 
         subdivideTriangle(nummesh,i) 
      Next i 
   Next j 
    
    SetMeshData(dynMesh(nummesh)\numMesh,#PB_Mesh_Vertex | #PB_Mesh_Normal | #PB_Mesh_UVCoordinate | #PB_Mesh_Color,dynMesh(nummesh)\vertexBuffer,dynMesh(nummesh)\nbVert) 
    SetMeshData(dynMesh(nummesh)\numMesh,#PB_Mesh_Face,dynMesh(nummesh)\faceBuffer,dynMesh(nummesh)\nbTri) 

EndProcedure 

;************************************************************************************ 

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

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

;-Material 
CreateMaterial(0,TextureID(0)) 

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

;-Camera 
CreateCamera(0, 0, 0 , 100 , 100) 
MoveCamera(0,0,0,-15) 
CameraLookAt(0,0,0,0) 

;-Light 
AmbientColor(RGB(105,105,105)) 
CreateLight(0,RGB(255,255,255),200,300,0) 
CreateLight(1,RGB(255,127,0),-200,-200,200) 


Global pas.f,angle.f 
pas = 0.8 
angle = 0 
Repeat 
   If fullscreen = 0 
      While WindowEvent() : Wend 
   EndIf 
    
   ; Rotate 
   Angle + Pas 
   RotateEntity(0, angle,angle/2,-angle) 


   ; 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      
      
   EndIf 
    
  ; show it all 
  RenderWorld() 
    
  ; A little help 
  StartDrawing(ScreenOutput()) 
  DrawText(0,0,"[F1] to change RenderMode, [S] to subdivide mesh ", $00FFFF, $BB0000) 
  DrawText(0,15,"Taille du buffer des vertices: " + Str(MemorySize(dynMesh(0)\vertexBuffer)) + " octets", $00FFFF, $BB0000) 
  DrawText(0,30,"Taille du buffer des faces: " + 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.l 0,1,2 
Data.l 3,4,5 
Data.l 6,7,8 
Data.l 9,10,11 
Data.l 12,13,14 
Data.l 15,16,17 
Data.l 18,19,20 
Data.l 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.l 0,1,2 
Data.l 3,4,5 
Data.l 6,7,8 
Data.l 9,10,11 
Data.l 12,13,14 
Data.l 15,16,17 
Data.l 18,19,20 
Data.l 21,22,23 
Data.l 24,25,26 
Data.l 27,28,29 
Data.l 30,31,32 
Data.l 33,34,35 
Data.l 36,37,38 
Data.l 39,40,41 
Data.l 42,43,44 
Data.l 45,46,47 
Data.l 48,49,50 
Data.l 51,52,53 
Data.l 54,55,56 
Data.l 57,58,59 
Data.l 60,61,62 
Data.l 63,64,65 
Data.l 66,67,68 
Data.l 69,70,71 


EndDataSection 

Publié : mar. 10/juin/2008 20:24
par Anonyme
Djes , logiquement , le tableau / zone mémoire passé en paramètre a setmeshdata n'a plus d'incidence après , tu peut modifier , supprimer des vertices à loisir ca n'affectera pas le mesh. le moteur doit certainement gerer les VBO ( Données stocker dans la carte graphique ).

A vérifier quand même ^^

Publié : mer. 11/juin/2008 8:00
par kelebrindae
:D J'ai trouvé! :D

La raison pour laquelle ça ne marchait pas, c'est que je suis un crétin!

Plus précisément, je calculais mal l'endroit où je devais écrire les nouvelles infos issues de la subdivision. Je prenais pour origine:
(Nb vertices avant subdivision +1) * sizeOf(vertex)
mais faire cela revenait à considérer que les vertices sont numérotés à partir de 1 au lieu de zéro (ce qui est faux, bien sûr). Et pareil pour les faces.
=> il y avait un "trou" entre les infos pré-existantes et les nouvelles, et ces dernière étaient écrites un cran trop loin, c'est-à-dire que la dernière était écrite en dehors de la mémoire allouée.
C'est ça qui provoquait le plantage. Contrairement à ce que je pensais, le debugger ne détecte pas l'écriture hors allocation (peut-être parce que c'était fait via des structures au lieu de Poke?); c'est un peu trompeur...

@cpl_Bator & Djes:
Effectivement, il semble bien qu'une fois le mesh créé, les infos qui ont servi à sa construction ne sont plus utilisée et peuvent être modifiées/effacées.

Je mets le code corrigé ci-dessous. Le calcul des normales des nouvelles faces semble encore faux, mais ça vous permettra de voir où je m'étais planté (pour comparer les sources, je vous conseille WinMerge, un petit utilitaire gratuit de comparaison de fichier).

Merci à tous de votre aide!

Code : Tout sélectionner

; Author: Kelebrindae
; Date: march,13, 2006
; PB version: v4.10
; OS: Windows XP
; Demo: Yes

#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 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
  nbVert.l
  nbTri.l
  *vertexBuffer.Vertex
  *faceBuffer.faceTri
EndStructure
#MAXMESH=2
Global Dim dynMesh.dynMesh_struct(#MAXMESH)

Enumeration
  #octahedron
  #pointyCube
EndEnumeration

  EnableExplicit


;- ---- Procedures ----
;************************************************************************************
; Name: CreateDynMesh
; Purpose: Create a mesh, scaled and UV mapped dynamically, and store 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
    
    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
  
    *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

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

;************************************************************************************
; Name: deleteDynMesh
; Purpose: delete 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: subdivideTriangle
; Purpose: Subdivise un triangle du mesh en 4
;   - 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

  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 = (*PtrV0\nx + *PtrV1\nx) / 2.0
  VertexA\ny = (*PtrV0\ny + *PtrV1\ny) / 2.0
  VertexA\nz = (*PtrV0\nz + *PtrV1\nz) / 2.0
  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 = (*PtrV0\nx + *PtrV2\nx) / 2.0
  VertexB\ny = (*PtrV0\ny + *PtrV2\ny) / 2.0
  VertexB\nz = (*PtrV0\nz + *PtrV2\nz) / 2.0 
  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 = (*PtrV1\nx + *PtrV2\nx) / 2.0
  VertexC\ny = (*PtrV1\ny + *PtrV2\ny) / 2.0
  VertexC\nz = (*PtrV1\nz + *PtrV2\nz) / 2.0 
  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  
  *PtrNewF\f2=newVertNum +1
  *PtrNewF\f3=newVertNum +2
  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 
  *PtrNewF\f2=newVertNum +1
  *PtrNewF\f3=newVertNum +2
  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 
  *PtrNewF\f2=newVertNum +1
  *PtrNewF\f3=newVertNum +2
  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\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\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)
  
  Debug "---------------------------------------------------"
EndProcedure

;************************************************************************************
; Name: subdivideMesh
; Purpose: Subdivide each triangle of a mesh
;   - 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

   For j = 1 To nbiteration
      top =  dynMesh(nummesh)\nbTri - 1
      ;top=0 ; Pour le test, on ne subdivise que le premier triangle du mesh
      For i = 0 To top
         subdivideTriangle(nummesh,i)
      Next i
   Next j
   
   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

;************************************************************************************

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

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

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

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


;-Camera 
CreateCamera(0, 0, 0 , 100 , 100) 
MoveCamera(0,0,0,-15) 
CameraLookAt(0,0,0,0) 

;-Light 
AmbientColor(RGB(105,105,105)) 
CreateLight(0,RGB(255,255,255),200,300,0) 
CreateLight(1,RGB(255,127,0),-200,-200,200) 


Global pas.f,angle.f
pas = 0.8
angle = 0
Repeat 
   If fullscreen = 0 
      While WindowEvent() : Wend 
   EndIf
   
   ; Rotate 
   Angle + Pas 
   RotateEntity(0, angle,angle/2,-angle) 


   ; 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     
     
   EndIf 
   
  ; show it all
  RenderWorld() 
   
  ; A little help
  StartDrawing(ScreenOutput())
  DrawText(0,0,"[F1] to change RenderMode, [S] to subdivide mesh ", $00FFFF, $BB0000)
  DrawText(0,15,"Taille du buffer des vertices: " + Str(MemorySize(dynMesh(0)\vertexBuffer)) + " octets", $00FFFF, $BB0000)
  DrawText(0,30,"Taille du buffer des faces: " + 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


EndDataSection

Publié : mer. 11/juin/2008 21:12
par Ollivier
Pour la comparaison Peek/Poke et structure, je crois bien que le bug que tu évoques est pareil dans les deux types d'accès : on peut dépasser la limite du buffer sans avoir forcément un plantage immédiat.

Pour les normales, il y a au moins deux calculs possibles. J'ai posté l'un d'eux dans la section 3D, seulement... Il est faux !!!

Pour trouver le bon, il y a environ deux ans, il m'a fallu faire la mesh d'une sphère pour bien comprendre qu'est-ce que c'était une normale.

Comme je n'en suis pas à ce stade, voici le code de Comtois par exemple :

Code : Tout sélectionner

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

Macro PRODUIT_VECTORIEL(N, V1, V2) 
  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)) 
EndMacro 

Procedure Normalise(*N.s_Vecteur) 
  Define.f NormeVecteur 
    
  NormeVecteur = NORME(*N) 
  If NormeVecteur <> 0.0 
    *N\x / NormeVecteur 
    *N\y / NormeVecteur 
    *N\z / NormeVecteur 
  EndIf    
EndProcedure

Publié : mer. 11/juin/2008 21:29
par kelebrindae
Super! :)
Merci Ollivier, je vais essayer ça tout de suite!

Publié : mer. 11/juin/2008 21:44
par Anonyme
La normale est perpendiculaire à un plan ( triangle ) , elle sert surtout pour calculer l'illumination d'un objet , plus la normale est dans la direction de la lumière , plus le plan est éclairer , cela sert aussi a savoir si la face (triangle) est visible ou non , si elle est dans la direction de la caméra , la face est invisible.
Si tu calcul ton éclairage par face , tu auras un resultat d'un éclairage "plat" :

Image

Pour y remédier , tu calculs les normales des vertices , et tu fait une moyenne afin d'avoir un resultat correct. comme ceci ( interpolation des 3 vertex qui compose la face ):

Image

J'ai du code c++ si ca vous branche.

@++

Publié : mer. 11/juin/2008 22:30
par Ollivier
Ces illustrations tombent très bien Cpl. Merci ! :D

Je ne sais pas pour le C++ (la dernière fois que tu as posté un calcul qui m'intéressait, j'ai été pris d'une violente baffe nommée quaternion que je n'ai pas encore compris plusieurs mois plus tard !!!).

Ce que tu appelles interpolation, c'est quoi ? A priori, si je plante 3 javelots de manière verticale sur un terrain de foot, ça forme un triangle, et les 3 javelots sont les 3 normales de ce triangle. C'est juste ça : des supports de droite perpendiculaires au plan support qui accueille le triangle?

Et pour les moyennes, il n'y a pas de coefficient? (un peu comme le calcul barycentrique)

Ollivier

Publié : mer. 11/juin/2008 23:16
par Backup
Ollivier a écrit : A priori, si je plante 3 javelots de manière verticale sur un terrain de foot, ça forme un triangle, et les 3 javelots sont les 3 normales de ce triangle.
Ollivier
voici les Normales (Traits Bleu) sur une Sphere
les parties en rouge sont les Triangles (faces de la sphere) sélectionnées pour faire ressortir les Normales

Image

Publié : jeu. 12/juin/2008 9:28
par Anonyme
L'interpolation c'est ceci :

Image

Chaque vertice à une couleur

Vert , Bleu & Rouge. l'interpolation sert à faire le dégradé ( rasterization ) , c'est le même principe pour l'éclairage.

Voici du pseudo code :

Code : Tout sélectionner

;Defini les 2 vecteur de la normale
Vecteur3D_1 = Vertice3D_1 -  Vertice3D_2
Vecteur3D_2 = Vertice3D_3 -  Vertice3D_1
;Calcul de la normale 
Normale = (Vecteur3D_1 * Vecteur3D_2) - (Vecteur3D_1 * Vecteur3D_2)
;Longueur de la normale
Longueur = Sqr( Normale\x*Normale\x + Normale\y*Normale\y + Normale\z*Normale\z )
; Normalize la normale
Normale / Longueur
En purebasic ca donne :

Code : Tout sélectionner

Structure Vecteur3D
x.f
y.f
z.f
EndStructure



Define.Vecteur3D A,B,C


;      A
;      /\   	
;     /  \
;    /    \
;   /      \ 
;  /        \
; /          \
;-----------
;C           B

A\x=0
A\y=0
A\z=0

B\x=-5
B\y=0
B\z=5

C\x=5
C\y=0
C\z=5

Vecteur1.Vecteur3D
Vecteur2.Vecteur3D
Normale.Vecteur3D

Vecteur1\x = (B\x - A\x)
Vecteur1\y = (B\y - A\y)
Vecteur1\z = (B\z - A\z)

Vecteur2\x = (C\x - A\x)
Vecteur2\y = (C\y - A\y)
Vecteur2\z = (C\z - A\z)

Normale\x = ((Vecteur1\y * Vecteur2\z) - (Vecteur1\z * Vecteur2\y))
Normale\y = ((Vecteur1\z * Vecteur2\x) - (Vecteur1\x * Vecteur2\z))
Normale\z = ((Vecteur1\x * Vecteur2\y) - (Vecteur1\y * Vecteur2\x))

Lenght.f = Sqr(Normale\x*Normale\x + Normale\y*Normale\y + Normale\z*Normale\z)
Normale\x / Lenght
Normale\y / Lenght
Normale\z / Lenght


Debug "nX="+StrF( Normale\x)
Debug "nY="+StrF(Normale\y)
Debug "nZ="+StrF(Normale\z)

Publié : jeu. 12/juin/2008 15:57
par kelebrindae
@cpl_Bator:
Et une fois qu'on a calculé cette normale, on l'affecte aux trois vertices?

genre:
vertA\nx = normale\x
vertA\ny = normale\y
vertA\nz = normale\z

vertB\nx = normale\x
vertB\ny = normale\y
vertB\nz = normale\z

vertC\nx = normale\x
vertC\ny = normale\y
vertC\nz = normale\z

C'est ça ?

[EDIT]
Ah non, ce n'est pas ça.
Je viens de tester et ça fait apparaître les facettes du mesh au lieu de le rendre "smooth".

Avant, je faisais ça:

Code : Tout sélectionner

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

Procedure normalizeMesh(numMesh.l)
  Protected i.l
  Protected *ptrVert.Vertex
  Protected vector3.Vector3

  *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)
    
    *ptrVert\nx = vector3\x 
    *ptrVert\ny = vector3\y 
    *ptrVert\nz = vector3\z

    *ptrVert+SizeOf(Vertex)
  Next i

endprocedure
Résultat: le mesh était lissé, mais j'ai l'impression qu'il y avait des erreurs de ci de-là...

Cpl_Bator, pourrais-tu m'expliquer comment obtenir un mesh lissé avec ta méthode, s'il te plaît?

Publié : jeu. 12/juin/2008 17:18
par kelebrindae
Pour "smoother" le mesh, il faut pour chaque vertex moyenner les normales des faces dont il fait partie.

Comme dans mon mesh, les vertices sont dupliquées (un vertex n'est utilisé que dans une face et une seule), il faut que je creuse un peu...

Publié : jeu. 12/juin/2008 18:16
par Anonyme
Oui tu l'affecte au trois Vertices , ensuite , comme sur le superbe schéma :

Image


les vertices "commun" au même sommet ( entouré en bleu ) tu fait une moyenne
les triangles sont représenté par les grosse lignes ( noir & rouge ) , les normales en vert , et la normale a obtenir en bleu.