Dreamotion3D

Généralités sur la programmation 3D
tmyke
Messages : 1554
Inscription : lun. 24/juil./2006 6:44
Localisation : vosges (France) 47°54'39.06"N 6°20'06.39"E

Message par tmyke »

C'est DX qui fait le calcul, c'est une des fonction de DirectX9...
Elle est a raprocher de DM_UpdateSmooth(), qui elle calcul les normals
sur les sommets conjoint (pour lisser le tout)
Force et sagesse...
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

tmyke a écrit :Elle est a raprocher de DM_UpdateSmooth(), qui elle calcul les normals sur les sommets conjoint (pour lisser le tout)
Cool ! C'est cette commande qu'il me faut, je ne l'avais pas vu , merci :)
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.
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

Je testais le texte 3D et j'ai des questions.
Je ne vois pas de différence quand je change le paramètre size de la commande DM_CreateText3D("comic sans ms", "PUREBASIC 4.0", 16, #Null), que je mette 16 ou 32 c'est pareil , normal ?

Pourquoi le texte s'affiche en noir ? qu'ai-je mal fait ?
Et s'il y a du superflu dans mon code, ça serait cool que tu l'épures :)

Code : Tout sélectionner

; Fichiers Include
IncludePath "Include\"
IncludeFile "d3dx9.pbi"
IncludeFile "dreamotion3d.pbi"     

Declare CreateCube()

Global  *camera.CEntity
Global  *entity.CEntity
Global  *brush.CBrush
Global  *texture.CTexture
Global  *font.CFont

;Initialisation des différents modules
If InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse() = 0
  End
EndIf

;ouvre un ecran 3D
DM_Graphics3D(800, 600, 32,  1, 1)
*font = DM_LoadFont( "Arial",16, 2)

;creation du cube
CreateCube()

;--------------------------------------------------------------
; UNE PETITE CAMERA POUR VOIR NOTRE SCENE
;--------------------------------------------------------------
*camera = DM_CreateCamera(#Null)
DM_MoveEntity(*camera, 0, 0, -50)
DM_CameraClsColor(*camera, 25, 25, 25)

Repeat

  ExamineKeyboard()
  DM_TurnEntity(*entity,2,0,0)

  ;debut rendu
  DM_BeginScene()
  ;rendu scene
  DM_Renderworld()
  ;fin rendu
  DM_EndScene()

Until KeyboardPushed(#PB_Key_Escape)
DM_ClearGraphics()
End

Procedure CreateCube()
  ;creation d'un mesh 
  *entity = DM_CreateText3D("comic sans ms", "PUREBASIC 4.0", 16, #Null)
  DM_ScaleEntity(*entity, 8, 8, 8)
  DM_PivotEntity(*entity, 3, 0, 0)
  ;on crée une petite Brush, dont on récupère le pointeur
  *brush = DM_CreateBrush("cube")
  ;modifie certains paramètres de la brush
  DM_BrushAmbient(*brush, 255,128,255,255)
  DM_BrushDiffuse(*brush, 255,128,255,255)
 
  ;--------------------------------------------------------
  ; TEXTURE 
  ;--------------------------------------------------------
  ;creation d'une texture vide de 256x256
  *texture = DM_CreateTexture(256,256)
  ;ré-oriente le buffer de sortie graphique vers notre texture
  DM_SetBuffer(*texture)
  ;debut d'un rendu
  DM_BeginScene()
    DM_ClsScreen (210, 0, 255, 0)         ; efface le buffer avec une couleur
    DM_DrawRect  ( 1, 1, 254, 254)      ; dessin d'un rectangle 2D
    ;DM_DrawRect  ( 10, 10, 200, 200)      ; dessin d'un rectangle 2D
    DM_SetColor2D(222, 0, 0, 255)         ; change couleur du trait
    DM_DrawOval  (100, 100, 50, 50)       ; dessin oval 2D
    DM_DrawText(*font, 10, 15, "TEXTURE") ; un petit texte
  ;fin rendu
  DM_EndScene()
  ;de nouveau le buffer vers l'ecran
  DM_SetBuffer(#Null)
 
 
  DM_BrushTexture(*brush, *texture, 0)
  ; modifie l'état de rendu de la Brush pour voir de tous les cotés
  DM_BrushAddRender(*brush, #D3DRS_CULLMODE, #D3DCULL_NONE)
  ; affecte la brush créee a notre entity
  DM_PaintEntity(*entity, *brush, 0)
  ; génératon auto des normales de l'entity créée
  DM_UpdateNormal(*entity)

EndProcedure
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.
tmyke
Messages : 1554
Inscription : lun. 24/juil./2006 6:44
Localisation : vosges (France) 47°54'39.06"N 6°20'06.39"E

Message par tmyke »

Salut. Voici un code qui te permettra de mieux voir et en couleur ton texte.
Ceci dit, ces mesh pré-calculés amènent a queqlues précisions:
pour l'instant il ne dispose pas de coordonnées de textures, donc inutile de chercher a
appliquer une texture dessus, elle n'y sortira jamais correctment.
Ils sont destinés surtout aux différentes mise au point pour faire des mesh
facile et rapide sans grosse mise en oeuvre...
De plus le soucis si il n'y a pas d'eclairage, est qu'il sont gris, la encore
c'est du a leur constitution somaire, mais si il y a une demande, alors
nous ferons des mesh pré-établis plus complet

A++

PS: je m'en vais deuxx ou trois jours, donc pas d'inquiétude si je ne reponds pas dans les jours a venir,
je ne suis pas mort

Code : Tout sélectionner

; Fichiers Include
IncludePath "Include\"
IncludeFile "d3dx9.pbi"
IncludeFile "dreamotion3d.pbi"     

Declare CreateCube()

Global  *camera.CEntity
Global  *entity.CEntity
Global  *brush.CBrush
Global  *texture.CTexture
Global  *font.CFont

;Initialisation des différents modules
If InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse() = 0
  End
EndIf

;ouvre un ecran 3D
DM_Graphics3D(800, 600, 32,  0, 1)
*font = DM_LoadFont( "Arial",16, 2)

;-Light
DM_AmbiantLight(80,  80,  80)
*light = DM_CreateLight(1, #Null)
DM_TurnEntity(*light, 90,0,0)

;creation du cube
CreateCube()

;--------------------------------------------------------------
; UNE PETITE CAMERA POUR VOIR NOTRE SCENE
;--------------------------------------------------------------
*camera = DM_CreateCamera(#Null)
DM_MoveEntity(*camera, 0, 0, -50)
DM_CameraClsColor(*camera, 25, 25, 25)
Repeat

  ExamineKeyboard()
  DM_TurnEntity(*entity,0.5,1,0)

  ;debut rendu
  DM_BeginScene()
  ;rendu scene
  DM_Renderworld()
  ;fin rendu
  DM_EndScene()

Until KeyboardPushed(#PB_Key_Escape)
DM_ClearGraphics()
End

Procedure CreateCube()
  ;creation d'un mesh
  *entity = DM_CreateText3D("comic sans ms", "PUREBASIC 4.0", 16, #Null)
  DM_ScaleEntity(*entity, 8, 8, 8)
  DM_PivotEntity(*entity, 3, 0.2, 0)
  ;on crée une petite Brush, dont on récupère le pointeur
  *brush = DM_CreateBrush("cube")
  ;modifie certains paramètres de la brush
  DM_BrushAmbient(*brush, 255,0,0,255)
  DM_BrushDiffuse(*brush, 255,0,0,255)

  
  ; affecte la brush créee a notre entity
  DM_PaintEntity(*entity, *brush, 0)
  ; génératon auto des normales de l'entity créée
  DM_UpdateSmooth(*entity)

EndProcedure
:)
Force et sagesse...
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

bon j'ai toujour une erreur avec
la ligne "*entity = DM_CreateMesh(12, 24, 1, #Null)"

le problemme c'est qu'il y a 2 archives qui traine

1 avec le nom de "Module"
http://www.dreamotion3d.com/PureBasic/modulePB.zip


l'autre avec le nom de "PackPB" !!!!
http://www.dreamotion3d.com/PureBasic/PackPB.zip


ce serai bien que tmyke mette un lien dans sa signature
vers un dossier ou l'on pourrai aisement recuperer les dossiers en cours :?

cela eviterai de se tromper,de fichier a recuperer ..
c'est deja pas evident de s'interresser a un projet, mais si en plus il faut courrir apres la bonne version, moi j'arrete la, car j'ai essayé tout ce que je pouvais, et j'ai toujours une erreur (comme sigalé sur le forum anglais)...
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

une autre adaption, c'est pas fini, j'arrangerai un peu le code la prochaine fois, il reste des trucs inutiles.

[EDIT]
J'ai modifié le code, l'éclairage est correct maintenant.
Par contre le calcul des normales est incroyablement lent !!
quand je le faisais moi même avec ogre, l'affichage restait fluide.

Commentez cette ligne pour rendre l'animation plus fluide.
;génératon auto des normales de l'entity créée
DM_UpdateNormal(*entity)

Code : Tout sélectionner

; Fichiers Include
IncludePath "Include\"
IncludeFile "d3dx9.pbi"
IncludeFile "dreamotion3d.pbi"     


Global  *camera.CEntity
Global  *brush.CBrush
Global  *texture.CTexture
Global  *entity.CEntity
Global  *font.CFont
Global *light.CEntity


; Initialisation des différents modules
If InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse() = 0
  End
EndIf
; ouvre un ecran 3D
DM_Graphics3D(800, 600, 32,  1, 1)

;-camera
*camera = DM_CreateCamera(#Null)
DM_MoveEntity(*camera, 0,0,-50)
DM_CameraClsColor(*camera, 0, 0, 0)

;-Light
DM_AmbiantLight(65,  65,  65)
*light = DM_CreateLight(1, #Null)
DM_TurnEntity(*light, 90,0,0)

;-font
*font = DM_LoadFont( "Arial", 36, 2)

;-Constantes
#NbX=30 ; nombre de facettes
#NbZ=30 ; nombre de facettes
#DegConv=3.14159265/180

;-Variables Globales
Global AngleVague.f,WaveFrequency.f,WavePeriodX.f,WavePeriodZ.f,WaveAmplitude.f
Global xrot.f,yrot.f,zrot.f
Global CamLocateX.l,CamLocateY.l,CamLocateZ.l,CamLookAtX.l,CamLookAtY.l,CamLookAtZ.l
Global Mode.b
circle.l=360
AngleVague=Random(circle)
WaveFrequency=3;=waves/second
WavePeriodX=5;=1/Wave lenght
WavePeriodZ=9;=1/Wave lenght
WaveAmplitude=4
xrot=-0.3:yrot=-0.4:zrot=0.2
CamLocateX.l=0:CamLocateY.l=0:CamLocateZ.l=50
CamLookAtX.l=0:CamLookAtY.l=0:CamLookAtZ.l=0

;-Procédures
Procedure Matrice()
  ;creation d'un mesh vide
  *entity = DM_CreateMesh((#NbX)*(#NbZ)*4, (#NbX+1)*(#NbZ+1), 1, #Null)
  i = 0

  For b=0 To #Nbz
    For a=0 To #NbX
      ;les coordonnées de vertex
      DM_VertexCoords(*entity, i, a - #NbX/2, 0, b - #Nbz/2)
      ;les coordonnées de texture (canal 0)
      DM_VertexTexCoords(*entity, i, 0, a/#NbX, b/#Nbz)
      i + 1
    Next a
  Next b

  i = 0
  Nb=#NbX+1
  For b=0 To #NbZ-1
    For a=0 To #NbX-1
      P1=a+(b*Nb)
      P2=P1+1
      P3=a+(b+1)*Nb
      P4=P3+1
      ;Face 1
      DM_VertexTriangle(*entity, i, P3, P2, P1, 0)
      i + 1
      DM_VertexTriangle(*entity, i, P2, P3, P4, 0)
      i + 1      
    Next
  Next
  
    ;on crée une petite Brush, dont on récupère le pointeur
  *brush = DM_CreateBrush("cylindre")
  ;modifie certains paramètres de la brush
  DM_BrushAmbient(*brush, 255,255,255,255)
  DM_BrushDiffuse(*brush, 255,255,255,255) 
 
  ;--------------------------------------------------------
  ; TEXTURE 
  ;--------------------------------------------------------
  ;creation d'une texture vide de 256x256
  *texture = DM_CreateTexture(256,256)
  ;ré-oriente le buffer de sortie graphique vers notre texture
  DM_SetBuffer(*texture)
  ;debut d'un rendu
  DM_BeginScene()
        DM_ClsScreen (210, 0, 255, 0)         ; efface le buffer avec une couleur
    DM_DrawRect  ( 1, 1, 254, 254)      ; dessin d'un rectangle 2D
    DM_DrawRect  ( 10, 10, 200, 200)      ; dessin d'un rectangle 2D
    DM_SetColor2D(222, 0, 0, 255)         ; change couleur du trait
    DM_DrawOval  (100, 100, 50, 50)       ; dessin oval 2D
    DM_DrawText(*font, 10, 15, "TEXTURE") ; un petit texte
  ;fin rendu
  DM_EndScene()
  ;de nouveau le buffer vers l'ecran
  DM_SetBuffer(#Null)
 
 
  DM_BrushTexture(*brush, *texture, 0)
  ; modifie l'état de rendu de la Brush pour voir de tous les cotés
  DM_BrushAddRender(*brush, #D3DRS_CULLMODE, #D3DCULL_NONE)
  ; affecte la brush créee a notre entity
  DM_PaintEntity(*entity, *brush, 0)

  
EndProcedure

Procedure vagues()
 ; Modification sur l'axe des Y
  i = 0
  For z=0 To #NbZ
    For x=0 To #NbX
       y.f=Sin(#DegConv*(AngleVague+x*WavePeriodX+z*WavePeriodZ))*WaveAmplitude
      DM_VertexCoords(*entity, i, DM_VertexX(*entity, i), y, DM_Vertexz(*entity, i))
      i + 1
    Next
  Next
  ;génératon auto des normales de l'entity créée
  DM_UpdateNormal(*entity)
EndProcedure


;-Mesh
Matrice()


;-Boucle principale
Repeat
  ExamineKeyboard()
 

  ;Calculate (AngleVague+WaveFrequency)%360: (coz % operand doesn't accept floats)
  !fild dword[v_circle]
  !fld dword[v_AngleVague]
  !fadd dword[v_WaveFrequency]
  !fprem
  !fstp dword[v_AngleVague]
  !fstp st1
 
  vagues()
  DM_TurnEntity(*entity, xrot, yrot, zrot)
  ;debut rendu
  DM_BeginScene()
  ;rendu scene
  DM_Renderworld()
  ;fin rendu
  DM_EndScene()

Until KeyboardPushed(#PB_Key_Escape)
DM_ClearGraphics()
End
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.
tmyke
Messages : 1554
Inscription : lun. 24/juil./2006 6:44
Localisation : vosges (France) 47°54'39.06"N 6°20'06.39"E

Message par tmyke »

Salut, me voila de retour. Super sympa ton code Comtois.
Pour la lenteur de l'instruction DM_UpdateNormal(), tu as raison, avant
de voir ton code, je n'avais pas vraiment fait attention. C'est bizarre, c'est
pourtant une instruction direct de l'API. J'ai donc ré-écrit ma propre fonction
DM_UpdateNormal(), et la les choses vont très nettement mieux, et on retrouve dès lors
une très bonne fluidité. Le nouveau codage sera dispo a la sortie de la prochaine version Beta... :wink:
Force et sagesse...
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

voila une bonne nouvelle :)


sinon, pour compléter cette démo, j'aurais besoin de faire une copie d'écran avant d'afficher la 3D et d'utiliser cette copie comme texture.

Je faisais comme ça pour copier l'écran, et je recopiais l'image dans une texture, ça me permettait de faire un drapeau animé avec le fond d'écran.

Code : Tout sélectionner

;/SnapShot
#Img_SnapShot = 0
ExamineDesktops()
hBitmap = CreateImage(#Img_SnapShot, DesktopWidth(0), DesktopHeight(0))
hdc = StartDrawing(ImageOutput(0))
SelectObject_(hdc, hBitmap)
BitBlt_(hdc, 0, 0, DesktopWidth(0), DesktopHeight(0), GetDC_(GetDesktopWindow_()), 0, 0, #SRCCOPY)
StopDrawing()
DeleteDC_(hdc)
Comment faire la même chose avec ton moteur ?

Autre question.

on a droit à combien de triangles et de vertices dans les meshs manuels ?
J'ai fait l'essai apparemment c'est la même limite qu'avec Dx7 ? il me semblait qu'on pouvait en mettre plus ?

quand on définit un mesh manuel, les deux faces sont créées, comment faire pour qu'il n'y ait qu'une seule face ?
par exemple dans l'exemple ci dessus, je ne définis qu'une face (verso) et pourtant on voit le recto.
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.
tmyke
Messages : 1554
Inscription : lun. 24/juil./2006 6:44
Localisation : vosges (France) 47°54'39.06"N 6°20'06.39"E

Message par tmyke »

Pour les limitations des mesh manuels, en théorie tu peux monter a 2147483648 faces
ou vertex. Mais je t'avoue ne pas avoir essayé la chose jusque la...
Les valeurs sur sont comme pour les mesh chargés, c-à-d 65536 faces/vertices.

Pour n'avoir qu'une face 'recto' sans verso, en 3D je ne sais pas comment on peut faire.
Une des solution consiste a en fait définir deux faces pour une, avec une texture d'un
coté, et une simple couleur ou une autre texture sur l'autre. En rendu brut, cela me
parait pas réalisable. Sinon, il faut faire appel a certaines astuces, mais ma on
sort du cadre d'un simple rendu...

Pour ton histoire de copy d'ecran, il existe la fonction que tu emplois déjà, DM_SetBuffer(),
qui ré-oriente la sortie video vers une texture, y compris dans la boucle princpale de rendu.
Maintenant pour avoir une anim 2D faite dans une image que tu modifie en 'live' pour en meme
temps l'appliquer sur une texture d'un mesh affiché a l'ecran, faut que je voie le truc...

:wink:
Force et sagesse...
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

tmyke a écrit :Pour les limitations des mesh manuels, en théorie tu peux monter a 2147483648 faces
ou vertex. Mais je t'avoue ne pas avoir essayé la chose jusque la...
Les valeurs sur sont comme pour les mesh chargés, c-à-d 65536 faces/vertices.
65536 oui c'est le maxi que je peux atteindre, après j'ai une erreur.
Pour tester il suffit de modifier l'exemple précédent
;-Constantes
#NbX=30 ; nombre de facettes
#NbZ=30 ; nombre de facettes
Une facette est composée de deux triangles sur une face ,et deux triangles sur l'autre, soit 4 triangles par facettes.
donc si tu mets #Nbx= 127 et #NbZ= 127, ça passe car ça me fait
128*128*4 vertices. Au delà ça plante, je dépasse les 65536.
Pour n'avoir qu'une face 'recto' sans verso, en 3D je ne sais pas comment on peut faire.
Pas grave, je demandais ça pour éviter d'avoir des triangles inutiles, par exemple si je veux faire un simple plan pour faire des sols ou des murs, je n'ai pas forcément besoin de voir l'autre face, ça me ferait une économie de polygones.

en OpenGL il faut faire ça, et je me demandais s'il n'y avait pas un équivalent avec DirectX ?

Code : Tout sélectionner

glEnable(GL_CULL_FACE);indique que certaines faces ne seront pas affichées
glCullFace(GL_BACK);précise ici quelles faces ne pas afficher
Pour ton histoire de copy d'ecran, il existe la fonction que tu emplois déjà, DM_SetBuffer(),
qui ré-oriente la sortie video vers une texture, y compris dans la boucle princpale de rendu.
oui mais c'est pas ce que je veux faire.
Un exemple vaut mieux qu'un grand discours

Voila concrètement ce que je cherche à refaire avec ton moteur.
Je ne vois toujours pas comment je peux copier l'écran dans la texture avec DM_SetBuffer() ? bien avant la boucle principale, et même avant d'ouvrir un écran avec OpenScreen ?

Code : Tout sélectionner

;**********************************************
;** Comtois ** 22/08/05 ** Matrice / Vagues  **
;**********************************************
;Modifications and additions by Psychophanta

;/SnapShot
#Img_SnapShot = 0
ExamineDesktops()
hBitmap = CreateImage(#Img_SnapShot, DesktopWidth(0), DesktopHeight(0))
hdc = StartDrawing(ImageOutput(0))
SelectObject_(hdc, hBitmap)
BitBlt_(hdc, 0, 0, DesktopWidth(0), DesktopHeight(0), GetDC_(GetDesktopWindow_()), 0, 0, #SRCCOPY)
StopDrawing()
DeleteDC_(hdc)

;-Initialisation
bitplanes.b=32:RX.w=1024:RY.w=768
If InitEngine3D()=0 Or InitSprite()=0 Or InitKeyboard()=0
  MessageRequester("Error","Something fails to open Screen for 3D. This requires Engine3D.dll",0)
  End
EndIf
While OpenScreen(RX.w,RY.w,bitplanes.b,"DemoMatrice")=0
  If bitplanes.b>16:bitplanes.b-8
  ElseIf RY.w>600:RX.w=800:RY.w=600
  ElseIf RY.w>480:RX.w=640:RY.w=480
  ElseIf RY.w>400:RX.w=640:RY.w=400
  ElseIf RY.w>240:RX.w=320:RY.w=240
  ElseIf RY.w>200:RX.w=320:RY.w=200
  Else:MessageRequester("VGA limitation","Can't open Screen!",0):End
  EndIf
Wend
Structure  Vecteur
x.f
y.f
z.f
EndStructure
Structure Vertex
x.f
y.f
z.f
Nx.f
Ny.f
Nz.f
;Cx.f
;Cy.f
;Cz.f
u.f
v.f
EndStructure

Structure DoubleFace
f1.w
f2.w
f3.w

f4.w
f5.w
f6.w

f7.w
f8.w
f9.w

f10.w
f11.w
f12.w
EndStructure

;-Constantes
#NbX=30 ; nombre de facettes
#NbZ=30 ; nombre de facettes
#DegConv=3.14159265/180

#PB_Mesh_Vertex       = 1 << 0
#PB_Mesh_Color        = 1 << 1
#PB_Mesh_Normal       = 1 << 2
#PB_Mesh_UVCoordinate = 1 << 3

 ;Additionnnal flag To specify the faces

#PB_Mesh_Face         = 1 << 4
   
;-Variables Globales
Global AngleVague.f,WaveFrequency.f,WavePeriodX.f,WavePeriodZ.f,WaveAmplitude.f
Global xrot.f,yrot.f,zrot.f
Global CamLocateX.l,CamLocateY.l,CamLocateZ.l,CamLookAtX.l,CamLookAtY.l,CamLookAtZ.l
Global Mode.b
circle.l=360
AngleVague=Random(circle)
WaveFrequency=3;=waves/second
WavePeriodX=5;=1/Wave lenght
WavePeriodZ=9;=1/Wave lenght
WaveAmplitude=2
xrot=-0.3:yrot=-0.4:zrot=0.2
CamLocateX.l=0:CamLocateY.l=0:CamLocateZ.l=50
CamLookAtX.l=0:CamLookAtY.l=0:CamLookAtZ.l=0

;-Procédures
Procedure Matrice(*Vertex.Vertex,*Face.DoubleFace,FX.l,FZ.l)
  *Ptr.Vertex=*Vertex
   FX2=FX/2
   FZ2=FZ/2
  For b=0 To FZ
    For a=0 To FX
      *Ptr\x= a-FX2
      *Ptr\y=0
      *Ptr\z=b-FZ2
      *Ptr\u=a/FX
      *Ptr\v=b/FZ
      *Ptr + SizeOf(Vertex)
    Next a
  Next b

  *PtrF.DoubleFace=*Face
  Nb=FX+1
  For b=0 To FZ-1
    For a=0 To FX-1
      P1=a+(b*Nb)
      P2=P1+1
      P3=a+(b+1)*Nb
      P4=P3+1
      ;Face 1
      *PtrF\f1=P3 : *PtrF\f2=P2 : *PtrF\f3=P1
      *PtrF\f4=P2 : *PtrF\f5=P3 : *PtrF\f6=P4
      ;Face 2
      *PtrF\f7=P1 : *PtrF\f8=P2 : *PtrF\f9=P3   
      *PtrF\f10=P4 : *PtrF\f11=P3 : *PtrF\f12=P2
      *PtrF + SizeOf(DoubleFace)
    Next
  Next


EndProcedure


Procedure MakeNormale(*Vertex.Vertex,*Face.DoubleFace,Fx,Fz)
     Protected *Ptr.Vertex, *PtrF.DoubleFace, *PtrN.Vecteur, Temp.Vecteur
    Protected  Vecteur1.Vecteur,  Vecteur2.Vecteur,  P1.Vecteur,  P2.Vecteur,  P3.Vecteur ,*N.Vecteur
   
     *N=AllocateMemory((Fx+1)*(Fz+1)*SizeOf(Vecteur))
 
    *PtrF=*Face
     For b=0 To FZ-1
       For a=0 To FX-1
          ;{ Calcule la normale du premier triangle

          ;Avec les 3 vertices qui composent le triangle, on détermine deux vecteurs

            *Ptr=*Vertex + *PtrF\f1 * SizeOf(Vertex)
           P1\x = *Ptr\x
         P1\y = *Ptr\y
          P1\z = *Ptr\z
       
           *Ptr=*Vertex + *PtrF\f2 * SizeOf(Vertex)
            P2\x = *Ptr\x
           P2\y = *Ptr\y
           P2\z = *Ptr\z
       
           *Ptr=*Vertex + *PtrF\f3 * SizeOf(Vertex)
            P3\x = *Ptr\x
           P3\y = *Ptr\y
           P3\z = *Ptr\z
       
           Vecteur1\x = (P1\x - P2\x)
           Vecteur1\y = (P1\y - P2\y)
           Vecteur1\z = (P1\z - P2\z)
       
           Vecteur2\x = (P1\x - P3\x)
           Vecteur2\y = (P1\y - P3\y)
           Vecteur2\z = (P1\z - P3\z)
           
         ;Calcule la normale du premier triangle
           Temp\x = ((Vecteur1\y * Vecteur2\z) - (Vecteur1\z * Vecteur2\y))
           Temp\y = ((Vecteur1\z * Vecteur2\x) - (Vecteur1\x * Vecteur2\z))
           Temp\z = ((Vecteur1\x * Vecteur2\y) - (Vecteur1\y * Vecteur2\x))
           
           ;Et affecte cette normale aux vertices composants le premier triangle
           *PtrN=*N + *PtrF\f1 * SizeOf(Vecteur)
           *PtrN\x + Temp\x
           *PtrN\y + Temp\y
           *PtrN\z + Temp\z

           *PtrN=*N + *PtrF\f2 * SizeOf(Vecteur)
           *PtrN\x + Temp\x
           *PtrN\y + Temp\y
           *PtrN\z + Temp\z
           
           *PtrN=*N + *PtrF\f3 * SizeOf(Vecteur)
           *PtrN\x + Temp\x
           *PtrN\y + Temp\y
           *PtrN\z + Temp\z
          ;}
         
         ;{ Calcule la normale du second triangle

          ;Avec les 3 vertices qui composent le triangle, on détermine deux vecteurs

            *Ptr=*Vertex + *PtrF\f4 * SizeOf(Vertex)
           P1\x = *Ptr\x
         P1\y = *Ptr\y
          P1\z = *Ptr\z
       
           *Ptr=*Vertex + *PtrF\f5 * SizeOf(Vertex)
            P2\x = *Ptr\x
           P2\y = *Ptr\y
           P2\z = *Ptr\z
       
           *Ptr=*Vertex + *PtrF\f6 * SizeOf(Vertex)
            P3\x = *Ptr\x
           P3\y = *Ptr\y
           P3\z = *Ptr\z
       
           Vecteur1\x = (P1\x - P2\x)
           Vecteur1\y = (P1\y - P2\y)
           Vecteur1\z = (P1\z - P2\z)
       
           Vecteur2\x = (P1\x - P3\x)
           Vecteur2\y = (P1\y - P3\y)
           Vecteur2\z = (P1\z - P3\z)
           
         ;Calcule la normale du second triangle
           Temp\x = ((Vecteur1\y * Vecteur2\z) - (Vecteur1\z * Vecteur2\y))
           Temp\y = ((Vecteur1\z * Vecteur2\x) - (Vecteur1\x * Vecteur2\z))
           Temp\z = ((Vecteur1\x * Vecteur2\y) - (Vecteur1\y * Vecteur2\x))
           
           ;Et affecte cette normale aux vertices composants le second triangle
           *PtrN=*N + *PtrF\f4 * SizeOf(Vecteur)
           *PtrN\x + Temp\x
           *PtrN\y + Temp\y
           *PtrN\z + Temp\z

           *PtrN=*N + *PtrF\f5 * SizeOf(Vecteur)
           *PtrN\x + Temp\x
           *PtrN\y + Temp\y
           *PtrN\z + Temp\z
           
           *PtrN=*N + *PtrF\f6 * SizeOf(Vecteur)
           *PtrN\x + Temp\x
           *PtrN\y + Temp\y
           *PtrN\z + Temp\z
          ;}
         
         ;Face suivante
         *PtrF + SizeOf(DoubleFace)
        Next a
     Next b
   ;Norme et affecte la normale de chaque Vertex
   *PtrN=*N
   *Ptr=*Vertex
   For b=0 To FZ
       For a=0 To FX
          Norme=Sqr(*PtrN\x * *PtrN\x + *PtrN\y * *PtrN\y + *PtrN\z * *PtrN\z)
         If norme = 0
               *Ptr\Nx = 0
               *Ptr\Ny = 0
               *Ptr\Nz = 0
          Else
               *Ptr\Nx = *PtrN\x / Norme
               *Ptr\Ny = *PtrN\y / Norme
               *Ptr\Nz = *PtrN\z / Norme
          EndIf         
          *Ptr + SizeOf(Vertex)
          *PtrN + SizeOf(Vecteur)
       Next a
     Next b

   FreeMemory(*N)
EndProcedure

Procedure vagues(*Vertex.Vertex,*Face.DoubleFace)
 ; Modification sur l'axe des Y
  *Ptr.Vertex=*Vertex
  For z=0 To #NbZ
    For x=0 To #NbX
        *Ptr\y=Sin(#DegConv*(AngleVague+x*WavePeriodX+z*WavePeriodZ))*WaveAmplitude
      *Ptr + SizeOf(Vertex)
    Next
  Next
  MakeNormale(*Vertex.Vertex,*Face.DoubleFace,#NbX,#NbZ)
  SetMeshData(0,#PB_Mesh_Vertex | #PB_Mesh_Normal | #PB_Mesh_UVCoordinate,*Vertex,(#NbX+1)*(#NbZ+1))
EndProcedure

Procedure.b ShowTextAndKeyTest(hidetext.b)
  If hidetext.b=0
    StartDrawing(ScreenOutput())
    DrawingMode(1)
    FrontColor(RGB(20,180,115))
    DrawText(0,  0,"[F1] => Toggle Mode affichage")
    DrawText(0, 20,"[PageUp] / [PageDown] => Wave Amplitude : "+StrF(WaveAmplitude))
    DrawText(0, 40,"[Up Arrow] / [Down Arrow] => Wave Period on Z axis : "+Str(WavePeriodZ))
    DrawText(0, 60,"[Right Arrow] / [Left Arrow] => Wave Period on X axis : "+Str(WavePeriodX))
    DrawText(0, 80,"[Home key] / [End key] => Wave speed : "+Str(WaveFrequency))
    DrawText(0,100,"[F2] / [Shift+F2] => X rotation speed : "+StrF(xrot))
    DrawText(0,120,"[F3] / [Shift+F3] => Y rotation speed : "+StrF(yrot))
    DrawText(0,140,"[F4] / [Shift+F4] => Z rotation speed : "+StrF(zrot))
    DrawText(0,160,"[F5] / [Shift+F5] => X Camera location : "+Str(CamLocateX))
    DrawText(0,180,"[F6] / [Shift+F6] => Y Camera location : "+Str(CamLocateY))
    DrawText(0,200,"[F7] / [Shift+F7] => Z Camera location : "+Str(CamLocateZ))
    DrawText(0,220,"[F8] / [Shift+F8] => X Camera look at : "+Str(CamLookAtX))
    DrawText(0,240,"[F9] / [Shift+F9] => Y Camera look at : "+Str(CamLookAtY))
    DrawText(0,260,"[F10] / [Shift+F10] => Z Camera look at : "+Str(CamLookAtZ))
    DrawText(0,280,"[F11] => Show or hide text")
    DrawText(0,300,"[Space] => Halt")
    StopDrawing()
  EndIf
  If KeyboardReleased(#PB_Key_F1)
    If Mode.b:Mode=0:CameraRenderMode(0,#PB_Camera_Textured):Else:Mode=1:CameraRenderMode(0,#PB_Camera_Wireframe):EndIf
  EndIf
  If KeyboardReleased(#PB_Key_PageUp):WaveAmplitude+0.1:EndIf
  If KeyboardReleased(#PB_Key_PageDown):WaveAmplitude-0.1:EndIf
  If KeyboardReleased(#PB_Key_Up):WavePeriodZ+1:EndIf
  If KeyboardReleased(#PB_Key_Down):WavePeriodZ-1:EndIf
  If KeyboardReleased(#PB_Key_Left):WavePeriodX-1:EndIf
  If KeyboardReleased(#PB_Key_Right):WavePeriodX+1:EndIf
  If KeyboardReleased(#PB_Key_Home):WaveFrequency+1:EndIf
  If KeyboardReleased(#PB_Key_End):WaveFrequency-1:EndIf
 
  If KeyboardReleased(#PB_Key_F2)
    If KeyboardPushed(#PB_Key_LeftShift) Or KeyboardPushed(#PB_Key_RightShift):xrot-0.1:Else:xrot+0.1:EndIf
  EndIf
  If KeyboardReleased(#PB_Key_F3)
    If KeyboardPushed(#PB_Key_LeftShift) Or KeyboardPushed(#PB_Key_RightShift):yrot-0.1:Else:yrot+0.1:EndIf
  EndIf
  If KeyboardReleased(#PB_Key_F4)
    If KeyboardPushed(#PB_Key_LeftShift) Or KeyboardPushed(#PB_Key_RightShift):zrot-0.1:Else:zrot+0.1:EndIf
  EndIf

  If KeyboardPushed(#PB_Key_F5)
    If KeyboardPushed(#PB_Key_LeftShift) Or KeyboardPushed(#PB_Key_RightShift):CamLocateX-1:Else:CamLocateX+1:EndIf
  EndIf
  If KeyboardPushed(#PB_Key_F6)
    If KeyboardPushed(#PB_Key_LeftShift) Or KeyboardPushed(#PB_Key_RightShift):CamLocateY-1:Else:CamLocateY+1:EndIf
  EndIf
  If KeyboardPushed(#PB_Key_F7)
    If KeyboardPushed(#PB_Key_LeftShift) Or KeyboardPushed(#PB_Key_RightShift):CamLocateZ-1:Else:CamLocateZ+1:EndIf
  EndIf

  If KeyboardPushed(#PB_Key_F8)
    If KeyboardPushed(#PB_Key_LeftShift) Or KeyboardPushed(#PB_Key_RightShift):CamLookAtX-1:Else:CamLookAtX+1:EndIf
  EndIf
  If KeyboardPushed(#PB_Key_F9)
    If KeyboardPushed(#PB_Key_LeftShift) Or KeyboardPushed(#PB_Key_RightShift):CamLookAtY-1:Else:CamLookAtY+1:EndIf
  EndIf
  If KeyboardPushed(#PB_Key_F10)
    If KeyboardPushed(#PB_Key_LeftShift) Or KeyboardPushed(#PB_Key_RightShift):CamLookAtZ-1:Else:CamLookAtZ+1:EndIf
  EndIf
  If KeyboardReleased(#PB_Key_F11):hidetext.b!1:EndIf
  While KeyboardPushed(#PB_Key_Space):ExamineKeyboard():Wend
  ProcedureReturn hidetext.b
EndProcedure

;-Mémoires Mesh
*VertexID=AllocateMemory((#NbX+1)*(#NbZ+1)*SizeOf(vertex))
*FaceID=AllocateMemory(#NbX*#NbZ*4*SizeOf(DoubleFace))
Matrice(*VertexID,*FaceID,#NbX,#NbZ)

;-Mesh

CreateMesh(0,1000)
SetMeshData(0,#PB_Mesh_Vertex | #PB_Mesh_Normal | #PB_Mesh_UVCoordinate,*VertexID,(#NbX+1)*(#NbZ+1))
SetMeshData(0,#PB_Mesh_Face,*FaceID,(#NbX)*(#NbZ)*4)

;-Texture
CreateTexture(0, 256, 256)
StartDrawing(TextureOutput(0))
DrawImage(ImageID(#Img_SnapShot),0,0)
StopDrawing()

;- MAterial
CreateMaterial(0, TextureID(0)) ; Material
;MaterialShadingMode(0, #PB_Material_Gouraud) ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<BUG ?????
;MaterialShadingMode(0, #PB_Material_Phong) ; Phong = Flat ???
MaterialBlendingMode(0, #PB_Material_AlphaBlend)
MaterialAmbientColor(0, RGB(255,55,55))
MaterialDiffuseColor(0, RGB(255,255,128))
MaterialSpecularColor(0,RGB(255,0,0))

;-Entity
 CreateEntity(0,MeshID(0),MaterialID(0))

;-Camera
CreateCamera(0,0,0,100,100)
AmbientColor(RGB(95,95,95));<- Essential for clarity

;Light
CreateLight(0,RGB(255,255,128))
LightLocate(0,EntityX(0)/2,EntityY(0)+800,EntityZ(0)/2)
;-Boucle principale
Repeat
  ClearScreen(0)
  ExamineKeyboard()
 
  CameraLocate(0,CamLocateX,CamLocateY,CamLocateZ)
  CameraLookAt(0,CamLookAtX,CamLookAtY,CamLookAtZ)

  ;Calculate (AngleVague+WaveFrequency)%360: (coz % operand doesn't accept floats)
  !fild dword[v_circle]
  !fld dword[v_AngleVague]
  !fadd dword[v_WaveFrequency]
  !fprem
  !fstp dword[v_AngleVague]
  !fstp st1

  vagues(*VertexID,*FaceID)
 xrot + 0.1
 yrot + 0.1
 zrot + 0.1  
  RotateEntity(0,xrot,yrot,zrot)
  RenderWorld()
  hidetext.b=ShowTextAndKeyTest(hidetext.b)
  FlipBuffers():Delay(7)
Until KeyboardPushed(#PB_Key_Escape)
Maintenant pour avoir une anim 2D faite dans une image que tu modifie en 'live' pour en meme temps l'appliquer sur une texture d'un mesh affiché a l'ecran, faut que je voie le truc...
J'allais y venir tôt ou tard à ce sujet, mais c'est pas ce que je cherchais à faire pour l'instant, mais si tu as le temps de faire une démo ça pourrait être cool :)
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.
tmyke
Messages : 1554
Inscription : lun. 24/juil./2006 6:44
Localisation : vosges (France) 47°54'39.06"N 6°20'06.39"E

Message par tmyke »

en OpenGL il faut faire ça, et je me demandais s'il n'y avait pas un équivalent avec DirectX ?

Code:
glEnable(GL_CULL_FACE);indique que certaines faces ne seront pas affichées
glCullFace(GL_BACK);précise ici quelles faces ne pas afficher
Je vais voir pour un équivalent DX, la fonction CULL_FACE permet juste de savoir si tu peux ou non
voir la face du coté inverse a la normal. Si tu met non, tu vois rien du tout de l'autre
coté, y compris la face elle meme. Mais je vais voir...

Pour les limite en terme de vertices, une fois la Première Release sortie, cela fait partie de éléments sur lequel je reviendrais pour améliorer cela.

Pour la copy d'écran, je comprend mieux maintenant avec le code que tu donnes. Je me penche sur le
prob et je te tien au courant dan la journée...
:wink:
Force et sagesse...
tmyke
Messages : 1554
Inscription : lun. 24/juil./2006 6:44
Localisation : vosges (France) 47°54'39.06"N 6°20'06.39"E

Message par tmyke »

J'ai mis a jour le module.
Ma fonction de calcul des normal est encore en cours d'essais, a voir.

Pour l'image de fond, tu peux utiliser la fonction DM_SetTexture() dans ce genre
la:

Code : Tout sélectionner

bmp.BITMAP
*Textur.IDirect3DTexture9  
D3DXCreateTextureFromFileInMemory(*DM_d3dDev9, bmp\bmBits,bmp\bmWidth * bmp\bmHeight * bmp\bmBitsPixel / 8, *Textur)  
DM_SetTexture(*texture, 0 , *Textur)  
Cela peut en partie déjà répondre a ton problème...

Sinon, d'une manière générale, deux nouvelles fonction on été ajoutées:

-retourne la mémoire video restante.
DM_VideoMemory.l()

-permet une capture d'ecran
DM_ScreenShot()
Force et sagesse...
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

tmyke a écrit :J'ai mis a jour le module.
Ma fonction de calcul des normal est encore en cours d'essais, a voir.
Pour le rendu c'est pas ça :)
Tu devrais conserver la fonction directx, elle fonctionne bien, c'est très utile pour la plupart des cas, c'est quand même rare d'avoir besoin d'appeler cette commande dans une boucle, c'était juste pour une démo.

Code : Tout sélectionner

bmp.BITMAP
*Textur.IDirect3DTexture9  
D3DXCreateTextureFromFileInMemory(*DM_d3dDev9, bmp\bmBits,bmp\bmWidth * bmp\bmHeight * bmp\bmBitsPixel / 8, *Textur)  
DM_SetTexture(*texture, 0 , *Textur)  
Cela peut en partie déjà répondre a ton problème...
ok, et bmp.BITMAP ? c'est quoi ? un fichier que j'ai chargé ? d'où la nouvelle fonction DM_ScreenShot() pour générer ce fichier ?
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.
tmyke
Messages : 1554
Inscription : lun. 24/juil./2006 6:44
Localisation : vosges (France) 47°54'39.06"N 6°20'06.39"E

Message par tmyke »

C'est le format bmp interne a windows, tu meux récupérer une image vers un BITMAP a partir
de son HDC par des fonction comme:

Code : Tout sélectionner

bm.BITMAP
GetObject_ ( ImageID , SizeOf(BITMAP), @bm.BITMAP)
Pour les normal, je vais voir pour améliorer, sinon je reviendrais a la fonction DX ... :wink:
Force et sagesse...
Anonyme

Message par Anonyme »

Juste une question en passant ^^
J'ai cherché(pas beaucoup :oops: ) sans trouvé de reponse,
Avec les terrains, peut on connaitre la hauteur sans utilisé la partie du moteur physique, juste en passant les coordonées x & z ? GetTerrainHeight(x,z) ? à moins que cela existe déjà :oops:

@TMyke J'ai vu aussi qu'en fait c'est pas ton premier moteur 3D :D tu avais bossé sur eliza3D, donc si il y a un "Monsieur 3D" c'est bien toi :D
Bon courage pour la suite, j'attends avec impatience la prochaine release :D

@++
Répondre