Objectif : Ouvrir un fichier WaveFront Obj contenant une description ASCII d'une modélisation 3D pour en faire un Mesh dans l'environnement Ogre 3D.
Pour plus d'information sur les fichier Wavefront Obj, vous pouvez consulter le lien suivant :
http://fr.wikipedia.org/wiki/Objet_3D_( ... e_fichier)
Je vous présente déjà la version 0.02 de mon projet car j'ai besoin d'aide.
Si Le mesh s'affiche bien, je bloque sur l'affichage de la texture.

Code : Tout sélectionner
;obj2OgreMesh V 0.04
;Description d'un fichier obj http://fr.wikipedia.org/wiki/Objet_3D_(format_de_fichier)
EnableExplicit
Enumeration
#Mainform
#File
#Mesh
#Texture
#Material
#Entity
EndEnumeration
Define.l Event
Global WindowStyle.i=#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_ScreenCentered
Global FileObj.s
Global Camera.i, CamX.f, CamY.f, CamZ.f
Structure sVertex
X.f
Y.f
Z.f
EndStructure
Structure sFace
A.i
B.i
C.i
EndStructure
Structure sVertexTexture
U.f
V.f
EndStructure
Structure sObj
Name.s
Level.i
List Vertex.sVertex()
List Face.sFace()
List Normals.sVertex()
List VertexTexture.sVertexTexture()
EndStructure
Global NewList Object.sObj()
Procedure ReadObj(ObjFile.s, List object.sObj())
Protected.s Buffer.s, Type, Indice.s
Protected.i Vertices.i, VertexNormals.i, TextureCoordinates.i, Faces.i
If OpenFile(#File, ObjFile)
While Eof(#File) = 0
Buffer = ReadString(#File)
Type = StringField(Buffer, 1, " ")
Select Type
Case "o" ;je ne sais pas si il faut traiter ce cas
;Plusieurs objets peuvent cohabiter dans le même fichier.
;La section définissant l'objet est définie de la maniére suivante : o [nom de l'objet]
Case "g"
;Plusieurs groupes de faces peuvent cohabiter dans le même objet
;La section définissant chaque groupe est définie de la maniére suivante : g [nom du groupe]
AddElement(Object())
object()\Name = StringField(Buffer, CountString(Buffer, " ") + 1, " ")
object()\level = CountString(Buffer, " ") - 1
Debug "Groupe " + object()\name
Case "v"
;Un sommet est défini de la manière suivante : v 1.0 0.0 0.0
;MeshVertexPosition() pour ajouter un sommet
If ListSize(object()) = 0
AddElement(object())
EndIf
AddElement(Object()\Vertex())
Object()\Vertex()\X = ValF(StringField(Buffer, 2, " "))
Object()\Vertex()\Y = ValF(StringField(Buffer, 3, " "))
Object()\Vertex()\Z = ValF(StringField(Buffer, 4, " "))
Vertices + 1
Case "vn"
;Une normale est définie de la manière suivante : vn 0.0 1.0 0.0
;MeshVertexNormal() pour ajouter l'information concernant la 'normale'
;du nouveau sommet précédemment ajouté avec MeshVertexPosition()
AddElement(object()\normals())
Object()\Normals()\X = ValF(StringField(Buffer, 2, " "))
Object()\Normals()\Y = ValF(StringField(Buffer, 3, " "))
Object()\Normals()\Z = ValF(StringField(Buffer, 4, " "))
VertexNormals + 1
Case "vt"
;Une coordonnée de texture est définie de la manière suivante : vt U V
;Exemple vt 1.00 0.00
;MeshVertexTextureCoordinate() pour ajouter l'information UV pour le nouveau sommet précédemment ajouté
AddElement(Object()\VertexTexture())
Object()\VertexTexture()\U = ValF(StringField(Buffer, 2, " "))
Object()\VertexTexture()\V = ValF(StringField(Buffer, 3, " "))
TextureCoordinates + 1
Case "f"
;Chaque face est définie par un ensemble d'indices faisant référence aux
;coordonnées des points, de texture et des normales.
;Par exemple : f v1/vt1/vn1 v2/vt2/vn2 v3/vt3/vn3
;MeshFace(Sommet1, Sommet2, Sommet3) pour ajouter une nouvelle face au mesh
AddElement(Object()\Face())
Indice = StringField(Buffer, 2, " ")
object()\face()\A = Val(StringField(Indice, 1, "/"))
Indice = StringField(Buffer, 3, " ")
object()\face()\B = Val(StringField(Indice, 1, "/"))
Indice = StringField(Buffer, 4, " ")
object()\face()\C = Val(StringField(Indice, 1, "/"))
Faces + 1
EndSelect
Wend
Debug Str(Vertices) + " Vertices"
Debug Str(TextureCoordinates) + " Texture Coordinates"
Debug Str(VertexNormals) + " Vertex Normals"
Debug Str(Faces) + " Faces"
CloseFile(#File)
EndIf
EndProcedure
Procedure RenderObj()
Protected Texture.i, Material.i
; Dans cette version on ne load pas encore la texture
; Cette texture pourra être loader plus tard avec l'instruction LoadTexture()
CreateTexture(#Texture, 512, 512)
StartDrawing(TextureOutput(#Texture))
Box(0,0,512,512,RGB(0, 0, 0))
Box(1,1,510,510,RGB(255, 0, 0))
StopDrawing()
CreateMaterial(#Material, TextureID(#Texture))
CreateMesh(#Mesh)
ForEach(Object())
;MeshVertexPosition() pour ajouter un sommet au mesh précédement créer
ForEach object()\vertex()
MeshVertexPosition(Object()\Vertex()\X, Object()\Vertex()\Y, Object()\Vertex()\Z)
Next
;MeshVertexNormal() pour ajouter l'information concernant la 'normale'
;du nouveau sommet précédemment ajouté avec MeshVertexPosition()
ForEach Object()\Normals()
MeshVertexNormal(Object()\Normals()\X, Object()\Normals()\Y, Object()\Normals()\Z)
Next
;MeshVertexTextureCoordinate() pour ajouter l'information UV pour le nouveau sommet précédemment ajouté
ForEach Object()\VertexTexture()
;MeshVertexTextureCoordinate(Object()\VertexTexture()\U, Object()\VertexTexture()\V)
Next
;MeshFace(Sommet1, Sommet2, Sommet3) pour ajouter une nouvelle face au mesh
ForEach object()\face()
MeshFace(object()\face()\A - 1, object()\face()\B - 1, object()\face()\C - 1)
Next
Next
FinishMesh(#True)
NormalizeMesh(#Mesh)
CreateEntity(#Entity, MeshID(#Mesh), MaterialID(#Material))
CreateEntityBody(#Entity, #PB_Entity_StaticBody, 1, 1, 1)
EndProcedure
Procedure Start()
InitEngine3D()
InitKeyboard()
InitSprite()
InitMouse()
;
;Fenetre 3D
OpenWindow(#Mainform,0,0,1024,768, "Obj2OgreMesh", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(#Mainform),0 ,0 ,1024, 768, 0, 0, 0)
KeyboardMode(#PB_Keyboard_International)
WorldDebug(#PB_World_DebugBody)
;
;Lumiere et ombre
AmbientColor(RGB(127, 127, 127))
CreateLight(#PB_Any,RGB(151, 251, 151), -1.8, 50, 5)
WorldShadows(#PB_Shadow_Additive)
;
; Camera
Camera = CreateCamera(#PB_Any,0,0,100,100)
CameraBackColor(Camera, RGB(145, 182, 201))
CamX = 10.0
CamY = 5.0
CamZ = 15.0
;
; Ouverture d'un fichier WaveFront
FileObj = OpenFileRequester("Ouvrir un fichier Wavefront Obj", "", "Wavefront (*.obj)|*.obj", 1)
If FileObj <> ""
;Lecture du fichier WaveFront Obj
ReadObj(FileObj, Object())
;Rendu sous la forme d'un mesh ogre
RenderObj()
EndIf
EndProcedure
start()
While #True
Event = WindowEvent()
If ExamineKeyboard()
If KeyboardPushed (#PB_Key_Escape) Or Event = #PB_Event_CloseWindow
Break
EndIf
If KeyboardPushed (#PB_Key_Add)
CamX-1
EndIf
If KeyboardPushed (#PB_Key_Subtract)
CamX+1
EndIf
If KeyboardPushed(#PB_Key_F2)
WorldDebug(#PB_World_DebugEntity)
EndIf
If KeyboardPushed(#PB_Key_F3)
WorldDebug(#PB_World_DebugBody)
EndIf
If KeyboardPushed(#PB_Key_F4)
WorldDebug(#PB_World_DebugNone)
EndIf
EndIf
MoveCamera(Camera, CamX, CamY, CamZ, #PB_Absolute)
CameraLookAt(Camera, 0,0,0)
; Affiche le rendu de la scène
ClearScreen(RGB(0, 0, 0))
RenderWorld(80)
FlipBuffers()
Wend

j'ai du commenter cette portion de code car j'ai un Runtime Error du compilateur.
Code : Tout sélectionner
MeshVertexTextureCoordinate(Object()\VertexTexture()\U, Object()\VertexTexture()\V)
L'idée plus tard est de créer une lib qui permettra d'afficher un obj dans l'environnement Ogre sans passer par un convertisseur.