Coordonées UV des fichiers ".x"
Coordonées UV des fichiers ".x"
Bonjour à tous ,
Je cherche à charger des fichiers ".x" au format binaire et à les afficher sous PB. Le parser est fonctionnel en ce qui concerne les points et les faces mais les coordonnées UV me posent un problème : les valeurs sont lues correctement mais le modèle persiste à s'afficher en couleur unie. Je ne sais pas si le problème vient :
- des paramètres de SetMeshData : j'utilise le nombre de points comme dernier paramètre (nombre d'éléments)
- de différences d'interprétation des valeurs UV entre directX et PB (l'un des fichiers X comporte des coordonnées allant jusqu'à 200 et des poussières et s'affiche pourtant correctement dans Deep exploration par exemple).
Y a-t-il un moyen de récupérer les données envoyées au mesh avec SetMeshData (doc sur la structure de stockage des Mesh interne à PureBasic ou à Ogre) pour pouvoir les vérifier ? Je n'ai pas trouvé l'info sur le site d'Ogre.
Je ne suis pas sûr d'avoir été bien clair, j'hésite à joindre mon code qui est largement en foutoir.
Merci d'avance
Je cherche à charger des fichiers ".x" au format binaire et à les afficher sous PB. Le parser est fonctionnel en ce qui concerne les points et les faces mais les coordonnées UV me posent un problème : les valeurs sont lues correctement mais le modèle persiste à s'afficher en couleur unie. Je ne sais pas si le problème vient :
- des paramètres de SetMeshData : j'utilise le nombre de points comme dernier paramètre (nombre d'éléments)
- de différences d'interprétation des valeurs UV entre directX et PB (l'un des fichiers X comporte des coordonnées allant jusqu'à 200 et des poussières et s'affiche pourtant correctement dans Deep exploration par exemple).
Y a-t-il un moyen de récupérer les données envoyées au mesh avec SetMeshData (doc sur la structure de stockage des Mesh interne à PureBasic ou à Ogre) pour pouvoir les vérifier ? Je n'ai pas trouvé l'info sur le site d'Ogre.
Je ne suis pas sûr d'avoir été bien clair, j'hésite à joindre mon code qui est largement en foutoir.
Merci d'avance
Salut Banban73, as tu pensé à vérifier le nom de la texture, il y a peut être un problème au niveau de la gestion du chemin d'accès ?
je pense que les coordonées des vertices sont stocké dans un tableau ou une liste chainée, ou zone mémoire, bref, vu que c'est ton parser qui lit le fichier .x , tu peut verifier les coordonées lors du parsing, les données envoyée au mesh sont les mêmes que ce que tu as envoyer.
si je me rapelle bien SetMeshData() doit avoir plusieurs flag a passer en paramètres, notament des constantes, as tu vérifier aussi?
sinon du code serais le bienvenue
le caïd d'ogre avec pb ici , c'est sans aucun doute Comtois, il pourra certainement t'éclairer plus que moi.
Sinon, bienvenu(e) à toi, si tu es intéresser par la 3D sous purebasic, je te suggère d'uiliser la bêta du moteur Dreamotion3D fait par tmyke, qui à mon sens est plus complet que ogre sous purebasic.
@++
je pense que les coordonées des vertices sont stocké dans un tableau ou une liste chainée, ou zone mémoire, bref, vu que c'est ton parser qui lit le fichier .x , tu peut verifier les coordonées lors du parsing, les données envoyée au mesh sont les mêmes que ce que tu as envoyer.
si je me rapelle bien SetMeshData() doit avoir plusieurs flag a passer en paramètres, notament des constantes, as tu vérifier aussi?
sinon du code serais le bienvenue

Sinon, bienvenu(e) à toi, si tu es intéresser par la 3D sous purebasic, je te suggère d'uiliser la bêta du moteur Dreamotion3D fait par tmyke, qui à mon sens est plus complet que ogre sous purebasic.
@++
Merci pour ta réponse rapide Cpl.Bator.
En ce qui concerne la texture, je la crée en cours de route avec un damier de couleur.
Effectivement, les coords UV des vertices sont stockées dans une zone mémoire et en doublon dans une liste chaînée pour vérif.
Je vais effectivement aller jeter un oeil sur Dreamotion3D
Pour le code, le voici (en vrac et avec des commentaires en anglais approximatif vu que je pensais le poster sur le forum anglais)
en gros, les commandes du viewer :
Souris pour orienter la camera, Molette pour soomer et clic gauche pour sortir
Si quelqu'un y retrouve ses petits ...
En ce qui concerne la texture, je la crée en cours de route avec un damier de couleur.
Effectivement, les coords UV des vertices sont stockées dans une zone mémoire et en doublon dans une liste chaînée pour vérif.
Je vais effectivement aller jeter un oeil sur Dreamotion3D
Pour le code, le voici (en vrac et avec des commentaires en anglais approximatif vu que je pensais le poster sur le forum anglais)
en gros, les commandes du viewer :
Souris pour orienter la camera, Molette pour soomer et clic gauche pour sortir
Code : Tout sélectionner
; ".x" file loader
;{ Structures
Structure s_Vertex
vx.f
vy.f
vz.f
u.f
v.f
EndStructure
;Structure s_Face
;vertindex.w[3]
;EndStructure
;}
Global NewList Vertices.s_Vertex()
;Global NewList Face.s_Face()
Declare.s GetString(nbchar.l)
Declare RechercheStr(find$)
Declare ParseMesh(num.w)
;{ Global variables definition
Global nb.w
Global Addr.l
Global AddrFin.l
Global type$ ; ="t" for text file or "b" for binary file
Global float.b ; =4 for 32 bits (float) or 8 for 64 bits (double)
Global NLines.l
Global NWords.l
Global CurrentDirectory.s
Global EOL.s
Global AsciiConv, Allwords, UniqueWords, WordCount
Global MemFileOffset.l, MemFileSize.l, *FileBuffer
;}
;{ Arrays declaration
Dim AsciiConv.s(255)
Dim AllWords.s(10000000)
Dim UniqueWords.s(1000000)
Dim WordCount.l(1000000)
;}
;{ Constants declaration
#FileType1=$786F6620 ;"xof " Big endian
#Filetype2=$30333032 ;"0302"
#Filetype3bin=$62696E20 ;"bin "
#Filetype3txt=$74787420 ;"txt "
#Filetype4=$00003332 ; Float 32 or 64
#TOKEN_NAME=1
#TOKEN_STRING=2
#TOKEN_INTEGER=3
#TOKEN_GUID=5
#TOKEN_INTEGER_LIST=6
#TOKEN_FLOAT_LIST=7
#TOKEN_OBRACE=10
#TOKEN_CBRACE=11
#TOKEN_OPAREN=12
#TOKEN_CPAREN=13
#TOKEN_OBRACKET=14
#TOKEN_CBRACKET=15
#TOKEN_OANGLE=16
#TOKEN_CANGLE=17
#TOKEN_DOT=18
#TOKEN_COMMA=19
#TOKEN_SEMICOLON=20
#TOKEN_TEMPLATE=31
#TOKEN_WORD=40
#TOKEN_DWORD=41
#TOKEN_FLOAT=42
#TOKEN_DOUBLE=43
#TOKEN_CHAR=44
#TOKEN_UCHAR=45
#TOKEN_SWORD=46
#TOKEN_SDWORD=47
#TOKEN_VOID=48
#TOKEN_LPSTR=49
#TOKEN_UNICODE=50
#TOKEN_CSTRING=51
#TOKEN_ARRAY=52
;}
;{ Common procedures
;
;Declare SkipTemplateMembers()
Procedure FatalError(t$)
MessageRequester("Fatal Error",t$,#PB_MessageRequester_Ok)
End
EndProcedure
Procedure.l LoadFileToMem(fileID,fname.s)
;Protected fileID,fname
If ReadFile(fileID,fname)
MemFileSize = Lof(fileID)
;Debug "MemFileSize = " + Str(MemFileSize)
*FileBuffer = AllocateMemory(MemFileSize)
If *FileBuffer
ReadData(fileID,*FileBuffer,MemFileSize)
EndIf
CloseFile(fileID)
;Debug "FileBuffer = " + Str(*FileBuffer)
MemFileOffset = 0 ; reset
EndIf
ProcedureReturn *FileBuffer
EndProcedure
Procedure MoreInMem()
If MemFileOffset < MemFileSize
ok = 1
EndIf
ProcedureReturn ok
EndProcedure
Procedure.s ReadLineFromMem() ; in case EOF: empty line is returned
If *FileBuffer And MoreInMem()
Start = *FileBuffer + MemFileOffset
Length = 0
Repeat
Length + 1
Byte.b = PeekB(Start + Length)
Until Byte = 13 Or Byte = 10 Or MemFileOffset + Length >= MemFileSize
EndIf
Skip = 1
Byte = PeekB(Start + Length + 1)
If Byte = 10 Or Byte = 13
Length + 1
Skip + 1
EndIf
MemFileOffset + Length
ProcedureReturn PeekS(Start + 1, Length - Skip)
EndProcedure
Procedure CloseFileMem()
FreeMemory(*FileBuffer)
EndProcedure
Procedure InvBits(valeur.l,type) ;transforme little endian en big endian 1 Word 2 Dword
If type=1 ; word
BigEnd=(((valeur & $00FF)<<8) | ((valeur & $FF00)>>8)) & $FFFF
If BigEnd>$8000
BigEnd=BigEnd-$10000
EndIf
ProcedureReturn BigEnd
ElseIf type=2 ; Long
BigEnd=(((valeur<<24) & $FF000000) | ((valeur<<8) & $00FF0000) | ((valeur>>8) & $0000FF00) | ((valeur>>24) & $000000FF))
If BigEnd>$80000000
BigEnd=BigEnd-$100000000
EndIf
ProcedureReturn BigEnd
EndIf
EndProcedure
Procedure ParseHeader() ; Lit le header du fichier et garde les infos importantes
If GetString(4)="xof "
Addr=Addr+4 ; skip version number
t$=GetString(4)
If t$="txt "
type$="t"
ElseIf t$="bin "
type$="b"
EndIf
t$=GetString(4)
If t$="0032"
float.b=4
ElseIf t$="0064"
float.b=8
EndIf
EndIf
EndProcedure
Procedure LoadXFile(a$)
Addr.l=LoadFileToMem(0,a$)
If Addr=0
FatalError("Memory Allocation failed")
EndIf
AddrFin.l=Addr.l+MemFileSize.l
ParseHeader()
If type$="t"
FatalError("X File is text format - Not supported yet")
EndIf
;
; boucle de traitement principal
;
nbdep.w=nb
Repeat
;
a=RechercheStr("Mesh"); returns 1 if mesh found, 0 if End of file reached without finding more meshes
If a=1 ; If Mesh found
nb=nb+1 ; Count one more Mesh
ParseMesh(nb-1) ; Deals with mesh infos (vertices, faces, normals, UV, etc)
EndIf ; else EndOfFile is reached
Until Addr>=AddrFin-10
If nb-nbdep=0
FatalError("No mesh in file")
EndIf
CloseFileMem() ; frees X file Buffer
; sets up datas according to type of mesh (boat.x, rudder.x, etc)
;f$=LCase(GetFilePart(a$))
;If f$="boat.x"
;EndIf
; sets up materials and meshes
;LoadTexture(0,"wave0.bmp")
CreateTexture(0,512,512)
StartDrawing(TextureOutput(0))
For xt=0 To 7 Step 2
For yt=0 To 7 Step 2
Box(xt*16,yt*16,16,16,$FFFF00)
Next
Next
StopDrawing()
CreateMaterial(0,TextureID(0))
MaterialAmbientColor(0,#PB_Material_AmbientColors)
For i =0 To nb-1
If IsMesh(i)
a=CreateEntity(i,MeshID(i),MaterialID(0),0,0,0)
EndIf
Next
EndProcedure
;}
;{ Binary parser procedures
Procedure.b GetByte() ; Reads a BYTE at Addr and increases this adress by one
a.b=PeekB(Addr)
Addr=Addr+1
ProcedureReturn a.b
EndProcedure
Procedure.w GetWord() ; Reads a WORD at Addr and increases this adress by two
;a.w=InvBits(PeekW(Addr),1)
a.w=PeekW(Addr)
Addr=Addr+2
ProcedureReturn a.w
EndProcedure
Procedure.l GetDWord() ; Reads a DWORD (or long) at Addr and increases this adress by four
;a.l=InvBits(PeekL(Addr),2)
a.l=PeekL(Addr)
Addr=Addr+4
ProcedureReturn a.l
EndProcedure
Procedure.d GetDouble() ; Reads a DOUBLE at Addr and increases this adress by eight
a.d=PeekW(Addr)
Addr=Addr+8
ProcedureReturn a.d
EndProcedure
Procedure.f GetFloat() ; Reads a FLOAT at Addr and increases this adress by four
;a.f=InvBits(PeekF(Addr),2)
a.f=PeekF(Addr)
Addr=Addr+4
ProcedureReturn a.f
EndProcedure
Procedure.s GetString(nbchar.l); Reads a nbchar character string at Addr and increases this adress by nbchar
a.s=PeekS(Addr,nbchar,#PB_Ascii)
Addr=Addr+nbchar
ProcedureReturn a.s
EndProcedure
Procedure.s GetName() ; Reads a Template name and his length at Addr and increases this adress by his length
long.l=PeekL(addr)
Addr=Addr+8
nom$=getstring(long)
ProcedureReturn nom$
EndProcedure
Procedure RechercheStr(find$) ; Finds find$ from Addr (Global) up to AddrFin (Global) and increases Addr
Fin=0
While Addr<=AddrFin-10 And Fin=0
If GetWord()=$0001 ;+2
If GetDWord()=Len(find$) ;+4
If GetString(Len(find$))=find$ ;+4
ProcedureReturn 1
Fin=1
Else
Addr=Addr-9
EndIf
Else
Addr=Addr-5
EndIf
Else
Addr=Addr-1
EndIf
Wend
EndProcedure
Procedure RechercheStrTo(find$,stop$) ; Finds find$ from Addr (Global) up to AddrFin (Global) or meet stop$ and increases Addr
Fin=0
While Addr<=AddrFin-10 And Fin=0
If GetWord()=$0001 ;+2
t=GetDWord()
If t=Len(find$) Or t=Len(stop$) ;+4
If GetString(Len(find$))=find$ ;+?
ProcedureReturn 1
Fin=1
Else
Addr=Addr-9
EndIf
If GetString(Len(stop$))=stop$
ProcedureReturn 0
Fin=1
Else
Addr=Addr-9
EndIf
Else
Addr=Addr-5
EndIf
Else
Addr=Addr-1
EndIf
Wend
EndProcedure
Procedure ParseMesh(num.w) ; Once Mesh is found, reads data and creates relevant PB Mesh
;**********************************************
; retrieves name of the mesh or creates one
If GetWord()=#TOKEN_NAME
n$=GetString(GetDWord())
Else
n$="Object"+StrU(num,1)
Addr=Addr-2
EndIf
t=GetDWord(); must be #TOKEN_OBRACE + #TOKEN_INTEGER_LIST
t=GetDWord(); must be $00000001 ; only one element : vertices number count
;**********************************************
; retrieves vertices count in mesh
nbVertices.l=GetDWord() ; retrieves number of vertices in the mesh
CreateMesh(num,3000) ;nbVertices.l) ; creates empty PB mesh
;If result=0
; ProcedureReturn 0
;EndIf
GetWord() ; must be #TOKEN_FLOAT_LIST ; avoid token
;**********************************************
; retrieves vertices coords in X mesh and set PB mesh with this coords
If float=4 ; if float size=32 as defined in header (4 bytes length)
nbCoords.l=GetDWord() ; must be 3x nbVertices
MemVert=AllocateMemory(nbCoords*4)
If MemVert=0
End
EndIf
Pointer.l=MemVert
For i.l=1 To nbVertices.l
AddElement(Vertices())
Vertices()\vx=GetFloat()
PokeF(pointer,Vertices()\vx)
pointer=pointer+4
Vertices()\vy=GetFloat()
PokeF(pointer,Vertices()\vy)
pointer=pointer+4
Vertices()\vz=getfloat()
PokeF(pointer,Vertices()\vz)
pointer=pointer+4
Next
SetMeshData(num,#PB_Mesh_Vertex,MemVert,nbVertices)
FreeMemory(MemVert)
Else ; if float size in header=64 (Double with 8 bytes length) : NOT SUPPORTED YET
nbCoords.l=GetDWord() ; must be 3x nbVertices
For i.l=1 To nbVertices.l
x.d=GetDouble()
y.d=GetDouble()
z.d=GetDouble()
Next
EndIf
;CallDebugger
GetWord() ; must be 0006 #TOKEN_INTEGER_LIST
GetDWord() ; must be 4xnbfaces+1(nbfaces)
;**********************************************
; retrieves triangles count in mesh
nbFaces.l=GetDWord() ; retreives number of faces defined
adbuff.l=AllocateMemory(nbFaces*4*4) ; allocates generous memory for temp buffer (convert list DWORD->WORD)
If adbuff<>0 ; if allocation is oK
buff.l=adbuff ; keep track of the start of the buffer
;long.l=0 ; keeps exact length of data in buffer Not Needed = Faces Count
For i=1 To nbFaces ; Until all triangles are done
nbv.l=GetDWord() ; Retrieves number of vertices for current face (hope it is 3)
For j=1 To nbv.l ; Until all verticess for current face are sighted
temp=GetDWord() ; gets vertex index (DWORD) from X file
PokeW(buff,temp) ; takes it in buffer (WORD)
a=PeekW(buff) ; for debugging only
buff=buff+2 ; points to next WORD in buffer
;long=long+1 ; data length in buffer is increased by 1
Next ; Vertices loop
;long=long+1
Next ; Triangles loop
SetMeshData(num,#PB_Mesh_Face,adbuff,nbFaces) ; set PB mesh triangles from buffer
FreeMemory(adbuff) ; deallocate buffer
EndIf
;**********************************************
; retrieves UV Coords in mesh
AddTemp.l=Addr ; saves current pointer to be able to scan for other meshes
Repeat
;
a=RechercheStrTo("MeshTextureCoords","Mesh"); returns 1 if UV found, 0 if End of file or meet next mesh
If a=1 ; If UV found
t.l=GetDWord(); must be #TOKEN_OBRACE + #TOKEN_INTEGER_LIST
t=GetDWord(); must be $00000001 ; only one element : vertices number count
;**********************************************
; retrieves vertices count in mesh
t=GetDWord() ; must be number of vertices in the mesh
GetWord() ; must be #TOKEN_FLOAT_LIST ; avoid token
;**********************************************
; retrieves UV coords in X mesh and set PB mesh with this coords
If float=4 ; if float size=32 as defined in header (4 bytes length)
nbCoords.l=GetDWord() ; must be 2x nbVertices
MemUV.l=AllocateMemory(nbVertices*2*4)
If MemUV=0
End
EndIf
Pointer.l=MemUV
ResetList(Vertices())
For i.l=1 To nbVertices.l
NextElement(Vertices())
Vertices()\u=GetFloat()
PokeF(pointer,Vertices()\u)
pointer=pointer+4
Vertices()\v=GetFloat()
PokeF(pointer,Vertices()\v)
pointer=pointer+4
Next
SetMeshData(num,#PB_Mesh_UVCoordinate,MemUV,nbVertices)
FreeMemory(MemUV)
Else ; if float size in header=64 (Double with 8 bytes length) : NOT SUPPORTED YET
nbCoords.l=GetDWord() ; must be 3x nbVertices
For i.l=1 To nbVertices.l
x.d=GetDouble()
y.d=GetDouble()
z.d=GetDouble()
Next
EndIf
Else
Addr=AddrFin
EndIf
Until Addr>=AddrFin-10
Addr=AddTemp ; restores good value of Addr to scan for other meshes
EndProcedure
;}
;{ Text parser procedures
Procedure.s Tgetstring()
EndProcedure
Procedure.b TGetByte()
EndProcedure
Procedure.w TGetWord()
EndProcedure
Procedure.l TGetDWord()
EndProcedure
Procedure.d TGetDouble()
EndProcedure
Procedure.f TGetFloat()
EndProcedure
Procedure TRechercheStr(find$)
EndProcedure
Procedure TAddMesh(num.w)
EndProcedure
;}
;************************************************************************************
; Program Start
;************************************************************************************
If InitEngine3D()=0 Or InitSprite()=0 Or InitKeyboard()=0 Or InitMouse()=0
FatalError("Initialisation failed")
EndIf
OpenWindow(0,0,0,640,480,"3D View",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(0),0,0,640,480,0,0,0)
HideWindow(0,1)
;a$=OpenFileRequester("selectionner un fichier DirectX","*.x","*.x",0)
;If a$=""
; FatalError("Le fichier est introuvable")
;EndIf
;
a$ = "prop.X"
LoadXFile(a$)
HideWindow(0,0)
CreateLight(0,RGB($ff,$ff,$ff),0,0,0)
CreateCamera(0,0,0,100,100)
CameraBackColor(0,RGB(150,150,150))
CameraProjection(0,#PB_Camera_Perspective)
;CameraRenderMode(0,#PB_Camera_Plot) ;#PB_Camera_Plot #PB_Camera_Wireframe #PB_Camera_Textured
AmbientColor(RGB($ff,$ff,$ff))
CameraLookAt(0,0,0,0)
CameraFOV(0,45)
anglex.w=0
angley.w=0
anglez.w=0
distance.l=1000
CameraRange(0,1,distance*2)
ExamineMouse()
mx=MouseDeltaX()
my=MouseDeltaY()
mw=MouseWheel()
;Left Mouse click waiting loop
While MouseButton(#PB_MouseButton_Left)=0
ExamineMouse()
mx=MouseDeltaX()
my=MouseDeltaY()
mw=MouseWheel()*-40
If mw<>0
If distance>50
distance=distance+mw
Else
If mw>0
distance=distance+mw
Else
distance=50
EndIf
EndIf
CameraRange(0,1,distance*2)
Else
mx=mx/2
my=my/2
anglexy=(anglexy+mx)%360;
anglez=(anglez+my)%360;
axyrad.f=(anglexy/360)*6.283185
azrad.f=(anglez/360)*6.283185
x.f=Cos(axyrad)*distance
z.f=Sin(axyrad)*distance
y.f=Sin(azrad)*distance
EndIf
CameraLocate(0,x,y,z)
CameraLookAt(0,0,0,0)
LightLocate(0,x,y,z)
ClearScreen(RGB(50,50,50))
RenderWorld()
StartDrawing(ScreenOutput())
DrawText(0,0,"x :"+Str(anglexy),RGB($ff,$ff,$ff),RGB(0,0,0))
DrawText(0,20,"y :"+Str(anglexy),RGB($ff,$ff,$ff),RGB(0,0,0))
DrawText(0,40,"z :"+Str(anglez),RGB($ff,$ff,$ff),RGB(0,0,0))
DrawText(0,60,StrU(distance,2),RGB($ff,$ff,$ff),RGB(0,0,0))
StopDrawing()
FlipBuffers()
If IsScreenActive()=1
ReleaseMouse(0)
Else
ReleaseMouse(1)
EndIf
Wend
CloseScreen()
CloseWindow(0)
End
Avec quelle version de PB travailles-tu ?
j'ai juste fait une recherche sur SetMeshData dans ton code pour voir comment tu faisais.
Depuis la V4 il faut définir chaque vertex en une fois avec la commande SetMeshData.
Dans ton cas , si tu utilises la position des vertices et les coordonnées uv
Il faudra bien sûr réserver un espace mémoire du nombre de tes vertices
Ce qui te permettra d'écrire
Pour un exemple plus complet, je te conseille de lire ce tutoriel
j'ai juste fait une recherche sur SetMeshData dans ton code pour voir comment tu faisais.
Depuis la V4 il faut définir chaque vertex en une fois avec la commande SetMeshData.
Code : Tout sélectionner
Flag = #PB_Mesh_Vertex | #PB_Mesh_Normal | #PB_Mesh_UVCoordinate | #PB_Mesh_Color
SetMeshData(0, Flag, Array(), nbVertices)
Code : Tout sélectionner
Flag = #PB_Mesh_Vertex | #PB_Mesh_UVCoordinate
SetMeshData(num, Flag, *Mem, nbVertices)
Code : Tout sélectionner
*Mem.s_Vertex = AllocateMemory(SizeOf(s_Vertex) * NbVertices)
Code : Tout sélectionner
*Mem\u = Vertices()\u
*Mem\v = Vertices()\v
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Merci pour ta réponse, Comtois et pour tes tutos trés bien faits.
J'utilise la version 4.01 enregistrée, donc il faut que je déclare mes coordonnées et mes UV en un seul SetMeshData si j'ai bien compris.
En revanche, je suis complètement largué au niveau des pointeurs, j'ai essayé de modifier mon code et maintenant il plante à tous les coups au moment de l'initialisation des mesh avec une erreur windows.
Mon problème étant que je récupère les coordonnées de tous les points puis je récupère les Uv de tous les points, il faut donc que j'incrémente mon pointeur pour passer de mesh en mesh une première fois, puis revenir pointer au début de ma zone mémoire et recommencer pour les UV.
Voilà la partie de code en question :
Merci par avance de vos réponses
J'utilise la version 4.01 enregistrée, donc il faut que je déclare mes coordonnées et mes UV en un seul SetMeshData si j'ai bien compris.
En revanche, je suis complètement largué au niveau des pointeurs, j'ai essayé de modifier mon code et maintenant il plante à tous les coups au moment de l'initialisation des mesh avec une erreur windows.
Mon problème étant que je récupère les coordonnées de tous les points puis je récupère les Uv de tous les points, il faut donc que j'incrémente mon pointeur pour passer de mesh en mesh une première fois, puis revenir pointer au début de ma zone mémoire et recommencer pour les UV.
Voilà la partie de code en question :
Code : Tout sélectionner
Structure s_Vertex
vx.f
vy.f
vz.f
u.f
v.f
EndStructure
; .................
nbVertices.l=GetDWord() ; retrieves number of vertices in the mesh
CreateMesh(num,3000) ;nbVertices.l) ; creates empty PB mesh
GetWord() ; must be #TOKEN_FLOAT_LIST ; avoid token
;**********************************************
; retrieves vertices coords in X mesh and set PB mesh with this coords
If float=4 ; if float size=32 as defined in header (4 bytes length)
nbCoords.l=GetDWord() ; must be 3x nbVertices
*Mem.s_Vertex = AllocateMemory(SizeOf(s_Vertex) * NbVertices)
*Pointer.l=*Mem
For i.l=1 To nbVertices.l
AddElement(Vertices())
Vertices()\vx=GetFloat() *Mem\vx = Vertices()\vx
Vertices()\vy=GetFloat()
*Mem\vy = Vertices()\vy
Vertices()\vz=getfloat()
*Mem\vz = Vertices()\vz
*Mem=*Mem+SizeOf(s_vertex)
Next
*Mem=*pointer
Else ; if float size in header=64 (Double with 8 bytes length) : NOT SUPPORTED YET
nbCoords.l=GetDWord() ; must be 3x nbVertices
For i.l=1 To nbVertices.l
x.d=GetDouble()
y.d=GetDouble()
z.d=GetDouble()
Next
EndIf
GetWord() ; must be 0006 #TOKEN_INTEGER_LIST
GetDWord() ; must be 4xnbfaces+1(nbfaces)
;**********************************************
; récupération faces (inchangé par rapport au code d'hier)
nbFaces.l=GetDWord() ; retreives number of faces defined
adbuff.l=AllocateMemory(nbFaces*4*4) ; allocates generous memory for temp buffer (convert list DWORD->WORD)
If adbuff<>0 ; if allocation is oK
buff.l=adbuff ; keep track of the start of the buffer
;long.l=0 ; keeps exact length of data in buffer Not Needed = Faces Count
For i=1 To nbFaces ; Until all triangles are done
nbv.l=GetDWord() ; Retrieves number of vertices for current face (hope it is 3)
For j=1 To nbv.l ; Until all verticess for current face are sighted
temp=GetDWord() ; gets vertex index (DWORD) from X file
PokeW(buff,temp) ; takes it in buffer (WORD)
a=PeekW(buff) ; for debugging only
buff=buff+2 ; points to next WORD in buffer
Next ; Vertices loop
Next ; Triangles loop
SetMeshData(num,#PB_Mesh_Face,adbuff,nbFaces) ; set PB mesh triangles from buffer
FreeMemory(adbuff) ; deallocate buffer
EndIf
;**********************************************
; retrieves UV Coords in mesh
AddTemp.l=Addr ; saves current pointer to be able to scan for other meshes
Repeat
;
a=RechercheStrTo("MeshTextureCoords","Mesh"); returns 1 if UV found, 0 if End of file or meet next mesh
If a=1 ; If UV found
;CallDebugger
;Debug Addr
;Debug AddrFin
t.l=GetDWord(); must be #TOKEN_OBRACE + #TOKEN_INTEGER_LIST
t=GetDWord(); must be $00000001 ; only one element : vertices number count
;**********************************************
; retrieves vertices count in mesh
t=GetDWord() ; must be number of vertices in the mesh
GetWord() ; must be #TOKEN_FLOAT_LIST ; avoid token
;**********************************************
; retrieves UV coords in X mesh and set PB mesh with this coords
If float=4 ; if float size=32 as defined in header (4 bytes length)
nbCoords.l=GetDWord() ; must be 2x nbVertices
Pointer.l=*Mem
ResetList(Vertices())
For i.l=1 To nbVertices.l
NextElement(Vertices())
Vertices()\u=GetFloat()
*Mem\u = Vertices()\u
Vertices()\v=GetFloat()
*Mem\v = Vertices()\v
*Mem=*Mem+SizeOf(s_Vertex)
Next
*Mem=pointer
Else ; if float size in header=64 (Double with 8 bytes length) : NOT SUPPORTED YET
nbCoords.l=GetDWord() ; must be 3x nbVertices
For i.l=1 To nbVertices.l
x.d=GetDouble()
y.d=GetDouble()
z.d=GetDouble()
Next
EndIf
Flag = #PB_Mesh_Vertex | #PB_Mesh_UVCoordinate
SetMeshData(num, Flag, *Mem, nbVertices)
FreeMemory(*Mem)
Else
Addr=AddrFin
EndIf
Until Addr>=AddrFin-10
Addr=AddTemp ; restores good value of Addr to scan for other meshes
EndProcedure
j'ai du mal à m'y retrouver dans ton code.
Je te suggère d'utiliser un tableau plutôt qu'un bloc mémoire, c'est plus simple. Quand ton prog sera au point, tu pourras remplacer le tableau par un bloc mémoire si tu veux t'exercer avec les pointeurs.
Ceci dit, si je ne regarde que cette partie du code, je ne vois pas d'erreur.
Tu sauvegardes l'adresse du bloc dans *pointeur, et tu restitues cette adresse après dans *mem. Faut regarder le reste de ton code.
Autre remarque, utilise ForEach Next avec tes listes chainées, c'est plus simple, enfin je trouve 
Tu dis que tu as mis une liste chainée pour controler les valeurs lues ?
Pourquoi ne pas mettre simplement un tableau puisque tu sembles connaitre le nombre de vertices à l'avance ? ça simplifierait ton code.
Je te suggère d'utiliser un tableau plutôt qu'un bloc mémoire, c'est plus simple. Quand ton prog sera au point, tu pourras remplacer le tableau par un bloc mémoire si tu veux t'exercer avec les pointeurs.
Code : Tout sélectionner
Dim Vertex.s_Vertex(nbVertices-1)
ResetList(Vertices())
For i.l=0 To nbVertices.l-1
NextElement(Vertices())
Vertices()\u=GetFloat()
Vertex(i)\u = Vertices()\u
Vertices()\v=GetFloat()
Vertex(i)\v = Vertices()\v
Next
Tu sauvegardes l'adresse du bloc dans *pointeur, et tu restitues cette adresse après dans *mem. Faut regarder le reste de ton code.
Code : Tout sélectionner
nbCoords.l=GetDWord() ; must be 3x nbVertices
*Mem.s_Vertex = AllocateMemory(SizeOf(s_Vertex) * NbVertices)
*Pointer.l=*Mem
For i.l=1 To nbVertices.l
AddElement(Vertices())
Vertices()\vx=GetFloat()
*Mem\vx = Vertices()\vx
Vertices()\vy=GetFloat()
*Mem\vy = Vertices()\vy
Vertices()\vz=getfloat()
*Mem\vz = Vertices()\vz
*Mem=*Mem+SizeOf(s_vertex)
Next
*Mem=*pointer

Code : Tout sélectionner
Dim Vertex.s_Vertex(nbVertices-1)
i = 0
ForEach Vertices()
Vertices()\u=GetFloat()
Vertex(i)\u = Vertices()\u
Vertices()\v=GetFloat()
Vertex(i)\v = Vertices()\v
i + 1
Next
Pourquoi ne pas mettre simplement un tableau puisque tu sembles connaitre le nombre de vertices à l'avance ? ça simplifierait ton code.
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Pour ce qui est des tableaux, tu as raison, j'ai voulu en faire trop d'un coup avec les pointeurs. Je vais déjà essayer d'afficher les mesh correctement, ensuite on verra.
Au départ, j'avais travaillé avec les listes chaînées pour essayer vu que ça non plus, je ne maîtrise pas vraiment. M'enfin là, on passe plutôt dans la catégorie débutants.
En tout cas merci pour tes conseils éclairés.
Au départ, j'avais travaillé avec les listes chaînées pour essayer vu que ça non plus, je ne maîtrise pas vraiment. M'enfin là, on passe plutôt dans la catégorie débutants.
En tout cas merci pour tes conseils éclairés.