Coordonées UV des fichiers ".x"

Généralités sur la programmation 3D
banban73
Messages : 10
Inscription : jeu. 16/nov./2006 19:59
Localisation : Bergerac - France

Coordonées UV des fichiers ".x"

Message par banban73 »

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
Anonyme

Message par Anonyme »

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 :D 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.

@++
banban73
Messages : 10
Inscription : jeu. 16/nov./2006 19:59
Localisation : Bergerac - France

Message par banban73 »

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

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
Si quelqu'un y retrouve ses petits ...
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

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.

Code : Tout sélectionner

Flag = #PB_Mesh_Vertex | #PB_Mesh_Normal | #PB_Mesh_UVCoordinate | #PB_Mesh_Color 
SetMeshData(0, Flag, Array(), nbVertices) 
Dans ton cas , si tu utilises la position des vertices et les coordonnées uv

Code : Tout sélectionner

Flag = #PB_Mesh_Vertex | #PB_Mesh_UVCoordinate
SetMeshData(num, Flag, *Mem, nbVertices) 
Il faudra bien sûr réserver un espace mémoire du nombre de tes vertices

Code : Tout sélectionner

*Mem.s_Vertex = AllocateMemory(SizeOf(s_Vertex) * NbVertices)
Ce qui te permettra d'écrire

Code : Tout sélectionner

*Mem\u = Vertices()\u
*Mem\v = Vertices()\v
Pour un exemple plus complet, je te conseille de lire ce tutoriel
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.
banban73
Messages : 10
Inscription : jeu. 16/nov./2006 19:59
Localisation : Bergerac - France

Message par banban73 »

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 :

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
Merci par avance de vos réponses
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

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.

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

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
Autre remarque, utilise ForEach Next avec tes listes chainées, c'est plus simple, enfin je trouve :)

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
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.
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.
banban73
Messages : 10
Inscription : jeu. 16/nov./2006 19:59
Localisation : Bergerac - France

Message par banban73 »

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.
Répondre