Page 1 sur 1

Comment appliquer un materiel sur un mesh manuel

Publié : mer. 28/août/2013 12:42
par falsam
Ne comprenant pas pourquoi je n'arrive pas à faire apparaître un matériel sur un mesh manuel issu de l'importation d'un fichier Wavefront (obj) http://www.purebasic.fr/french/viewtopi ... 13&t=13893 j'ai essayé de faire bêtement un cube manuel sur lequel j'ai tenté de faire apparaître une texture composée d'un fond jaune.

Malheureusement, cette texture n’apparaît pas !!

Code : Tout sélectionner

InitEngine3D()
InitKeyboard()
InitSprite()

Window = OpenWindow(#PB_Any,0,0,1024,768,"Cube")
OpenWindowedScreen(WindowID(window),0,0,1024,768)

AmbientColor(RGB(255, 255, 255))
CreateLight(#PB_Any,RGB(255, 255, 255), 0,50,50)

;Creation d'un mesh (ici un cube)
Mesh = CreateMesh(#PB_Any)

MeshVertexPosition(-100, 100, -100)
MeshVertexNormal(0, 0, 0)
MeshVertexColor($FF0000)
MeshVertexTextureCoordinate(0, 1)

MeshVertexPosition(100, 100, -100)
MeshVertexNormal(0, 0, 0)
MeshVertexColor($FF0000)
MeshVertexTextureCoordinate(0, 1)

MeshVertexPosition(100, -100, -100)
MeshVertexNormal(0, 0, 0)
MeshVertexColor($FF0000)
MeshVertexTextureCoordinate(0, 1)

MeshVertexPosition(-100, -100, -100)
MeshVertexNormal(0, 0, 0)
MeshVertexColor($FF0000)
MeshVertexTextureCoordinate(0, 1)

MeshVertexPosition(-100, 100, 100)
MeshVertexNormal(0, 0, 0)
MeshVertexColor($FF0000)
MeshVertexTextureCoordinate(0, 1)

MeshVertexPosition(100, 100, 100)
MeshVertexNormal(0, 0, 0)
MeshVertexColor($FF0000)
MeshVertexTextureCoordinate(0, 1)

MeshVertexPosition(100, -100, 100)
MeshVertexNormal(0, 0, 0)
MeshVertexColor($FF0000)
MeshVertexTextureCoordinate(0, 1)

MeshVertexPosition(-100, -100, 100)
MeshVertexNormal(0, 0, 0)
MeshVertexColor($FF0000)
MeshVertexTextureCoordinate(0, 1)

MeshFace(0, 2, 3)
MeshFace(0, 1, 2)
MeshFace(1, 6, 2)
MeshFace(1, 5, 6)
MeshFace(4, 6, 5)
MeshFace(4, 7, 6)
MeshFace(0, 7, 4)
MeshFace(0, 3, 7)
MeshFace(0, 5, 1)
MeshFace(0, 4, 5)
MeshFace(2, 7, 3)
MeshFace(2, 6, 7)
    
FinishMesh(#True)
    
Texture = CreateTexture(#PB_Any, 512, 512)
StartDrawing(TextureOutput(Texture))
Box(0,0,512,512,RGB(0, 0, 0))
Box(1,1,510,510,RGB(255, 216, 0))
StopDrawing()

Material = CreateMaterial(#PB_Any, TextureID(Texture))    

Entity = CreateEntity(#PB_Any, MeshID(Mesh), MaterialID(material))

EntityPhysicBody(Entity, #PB_Entity_StaticBody, 1, 1, 1)
WorldDebug(#PB_World_DebugBody)

Camera = CreateCamera(#PB_Any,0,0,100,100)
CameraBackColor(Camera,RGB(131, 204, 249))

While #True
  
  event = WindowEvent()
  
  If event = #PB_Event_CloseWindow
    Break
  EndIf 
  
  ExamineKeyboard()  
  
  If KeyboardPushed(#PB_Key_Escape)
    Break
  EndIf  
  
  If KeyboardPushed(#PB_Key_Left)
    y+1
  EndIf
  
  If KeyboardPushed(#PB_Key_Right)
    y-1
  EndIf
  
  If KeyboardPushed(#PB_Key_Up)
    x+1
  EndIf
  
  If KeyboardPushed(#PB_Key_Down)
    x-1
  EndIf
 
  RotateEntity(Entity, x,y,z)    
  MoveCamera(Camera, 500, 500, 100, #PB_Absolute)
  CameraLookAt(camera,0,0,0)
  
  RenderWorld()
  FlipBuffers()
Wend 
Etant plutôt très Noob dans le domaine de la 3D, J'aimerais savoir si les 3 lignes qui suivent sont utiles dans la conception d'un cube.

Code : Tout sélectionner

MeshVertexNormal(0, 0, 0)
MeshVertexColor($FF0000)
MeshVertexTextureCoordinate(0, 1)

Re: Comment appliquer un materiel sur un mesh manuel

Publié : mer. 28/août/2013 13:41
par Fred
Tu as jeté un oeil sur l'exemple MeshManual.pb ?

Re: Comment appliquer un materiel sur un mesh manuel

Publié : mer. 28/août/2013 14:43
par falsam
Fred a écrit :Tu as jeté un oeil sur l'exemple MeshManual.pb ?
Oui j'ai regardé ainsi que l'exemple MeshManualCube d'ou est extrait mon code.

Sur ce dernier exemple le souci est le même, les textures ne s'affichent pas.

Re: Comment appliquer un materiel sur un mesh manuel

Publié : mer. 28/août/2013 14:52
par comtois

Code : Tout sélectionner

MeshVertexNormal(0, 0, 0)
la normale est utilisée pour le calcul de l'éclairage (pas indispensable pour afficher une texture, mais pour améliorer le rendu général)

Code : Tout sélectionner

MeshVertexColor($FF0000)
pas utile avec une texture. ou alors une texture blanche et tu utilises les couleurs des vertices.

Code : Tout sélectionner

MeshVertexTextureCoordinate(0, 1)
indispensable pour ta texture. voir ce tuto

Re: Comment appliquer un materiel sur un mesh manuel

Publié : mer. 28/août/2013 15:02
par falsam
Merci Comtois je regarde ton tuto.

Re: Comment appliquer un materiel sur un mesh manuel

Publié : mer. 28/août/2013 15:06
par comtois
j'ai mis des chiffres au hasard pour que tu vois une texture, faudrait analyser un peu plus ton cube pour mieux définir les coordonnées. Dans ton cas (Wavefront ) il faut sans doute envisager du multi texture, c'est à dire plusieurs coordonnées de texture par vertex. J'avais fait un exemple sur le forum anglais.

Code : Tout sélectionner

InitEngine3D()
InitKeyboard()
InitSprite()

Window = OpenWindow(#PB_Any,0,0,1024,768,"Cube")
OpenWindowedScreen(WindowID(window),0,0,1024,768)

AmbientColor(RGB(255, 255, 255))
CreateLight(#PB_Any,RGB(255, 255, 255), 0,50,50)

;Creation d'un mesh (ici un cube)
Mesh = CreateMesh(#PB_Any)

MeshVertexPosition(-100, 100, -100)
MeshVertexTextureCoordinate(0, 0)

MeshVertexPosition(100, 100, -100)
MeshVertexTextureCoordinate(1, 1)

MeshVertexPosition(100, -100, -100)
MeshVertexTextureCoordinate(0, 1)

MeshVertexPosition(-100, -100, -100)
MeshVertexTextureCoordinate(1, 1)

MeshVertexPosition(-100, 100, 100)
MeshVertexTextureCoordinate(0, 1)

MeshVertexPosition(100, 100, 100)
MeshVertexTextureCoordinate(0, 1)

MeshVertexPosition(100, -100, 100)
MeshVertexTextureCoordinate(1, 0)

MeshVertexPosition(-100, -100, 100)
MeshVertexTextureCoordinate(1, 1)

MeshFace(0, 2, 3)
MeshFace(0, 1, 2)
MeshFace(1, 6, 2)
MeshFace(1, 5, 6)
MeshFace(4, 6, 5)
MeshFace(4, 7, 6)
MeshFace(0, 7, 4)
MeshFace(0, 3, 7)
MeshFace(0, 5, 1)
MeshFace(0, 4, 5)
MeshFace(2, 7, 3)
MeshFace(2, 6, 7)
   
FinishMesh(#True)
   
Texture = CreateTexture(#PB_Any, 512, 512)
StartDrawing(TextureOutput(Texture))
Box(0,0,512,512,RGB(0, 0, 0))
Box(1,1,510,510,RGB(255, 216, 0))
StopDrawing()

Material = CreateMaterial(#PB_Any, TextureID(Texture))   

Entity = CreateEntity(#PB_Any, MeshID(Mesh), MaterialID(material))

EntityPhysicBody(Entity, #PB_Entity_StaticBody, 1, 1, 1)
WorldDebug(#PB_World_DebugBody)

Camera = CreateCamera(#PB_Any,0,0,100,100)
CameraBackColor(Camera,RGB(131, 204, 249))

While #True
 
  event = WindowEvent()
 
  If event = #PB_Event_CloseWindow
    Break
  EndIf
 
  ExamineKeyboard() 
 
  If KeyboardPushed(#PB_Key_Escape)
    Break
  EndIf 
 
  If KeyboardPushed(#PB_Key_Left)
    y+1
  EndIf
 
  If KeyboardPushed(#PB_Key_Right)
    y-1
  EndIf
 
  If KeyboardPushed(#PB_Key_Up)
    x+1
  EndIf
 
  If KeyboardPushed(#PB_Key_Down)
    x-1
  EndIf

  RotateEntity(Entity, x,y,z)   
  MoveCamera(Camera, 500, 500, 100, #PB_Absolute)
  CameraLookAt(camera,0,0,0)
 
  RenderWorld()
  FlipBuffers()
Wend 

Re: Comment appliquer un materiel sur un mesh manuel

Publié : mer. 28/août/2013 15:13
par falsam
Merci pour cet exemple et je comprend mieux l'importance de MeshVertexTextureCoordinate().

Je vais pouvoir m'atteler de nouveau à mon importateur de fichier WaveFront. mais je sens que ce n'est pas gagné :)

Mon code actuel permet de voir le mesh mais ne permet pas de faire apparaître la texture. Si à tout hasard tu pouvais jeter un oeil averti (Mode cirage d'octet ON) Merci d'avance Comtois.

Re: Comment appliquer un materiel sur un mesh manuel

Publié : mer. 28/août/2013 21:59
par comtois
Je ne connais pas le format wavefront et je n"ai pas vraiment le temps de faire des recherches là dessus.
D'après ton lien, j'ai l'impression qu'il faut gérer du multi TextureCoords

Code : Tout sélectionner

f  1/11/2  7/14/2  5/12/2
f  1/11/2  3/13/2  7/14/2 
f  1/7/6  4/4/6  3/3/6 
f  1/7/6  2/8/6  4/4/6 
f  3/1/3  8/5/3  7/2/3 
f  3/1/3  4/4/3  8/5/3 
f  5/10/5  7/6/5  8/5/5 
f  5/10/5  8/5/5  6/9/5 
f  1/11/4  5/12/4  6/9/4 
f  1/11/4  6/9/4  2/8/4 
f  2/8/1  6/9/1  8/5/1 
f  2/8/1  8/5/1  4/4/1 
La première face utilise le vertex 1 avec les coordonnées de texture 11
v1 = 0.0 0.0 0.0 ; position du vertex d'index 1
vt11 = 0.25 0.75 ; coordonnées de texture d'index 11

La troisième face utilise le vertex 1 avec les coordonnées de texture 7
v1 = 0.0 0.0 0.0 ; position du vertex d'index 1
vt7 = 0.0 0.5 ; coordonnées de texture d'index 7

En clair ton vertex 1 a plusieurs coordonnées de texture, on peut faire ça avec ogre.

voici un exemple avec du Multiple TextureCoords :

http://www.purebasic.fr/english/viewtop ... 4&start=10
Le script est à sauvegarder dans le répertoire Examples/3D/Data/Scripts
Et le code dans le répertoire Examples/3D/

Re: Comment appliquer un materiel sur un mesh manuel

Publié : mer. 28/août/2013 22:17
par falsam
comtois a écrit :Je ne connais pas le format wavefront et je n"ai pas vraiment le temps de faire des recherches là dessus.
D'après ton lien, j'ai l'impression qu'il faut gérer du multi TextureCoords
C'est exactement ça . Chaque face est définie par un ensemble d'indices faisant référence aux coordonnées des points, des textures et des normales.
Par exemple : f v1/vt1/vn1 v2/vt2/vn2 v3/vt3/vn3

Dans le code que je propose sur ce post Je n'utilise que les vecteurs V1 à Vn pour afficher le mesh sans tenir compte des normales (Vnx) et des Vertex Texture Coordinate. Ce qui m’empêche d'afficher le materiel.

Merci pour le lien :)

[Edit] je connais cette exemple figurant dans ceux livrés avec Pure basic.

Re: Comment appliquer un materiel sur un mesh manuel

Publié : mer. 28/août/2013 22:48
par comtois
falsam a écrit :[Edit] je connais cette exemple figurant dans ceux livrés avec Pure basic.
Nop, c'est pas le même exemple.

Dans l'exemple du lien, il y a 2 textures pour un material, 2 couches définies avec 'tex_coord_set', on peut aussi le faire avec AddMaterialLayer().
Et cet exemple montre comment ajouter plusieurs TextureCoords à un vertex.

Code : Tout sélectionner

    ;Base
    AddSubMesh()
    For i = 0 To 3
      Read.f x : Read.f y : Read.f z
      Read.l Co
      Read.f u : Read.f v
      AddMeshVertex(x, y, z)
      MeshVertexNormal(0, 0, 0)
      MeshVertexColor(Co)
      MeshVertexTextureCoordinate(u, v) ; coordonnées sur la première texture 
      MeshVertexTextureCoordinate(u, v) ; coordonnées sur la seconde texture 
    Next

Re: Comment appliquer un materiel sur un mesh manuel

Publié : mer. 28/août/2013 22:50
par falsam
Oops Oui !! j'ai lu en diagonale. Désolé Comtois.