Nouvelle version , cette fois ci , la lumière ( et les ombres ) suivent bien le mouvement des vagues , ce qui n'était pas le cas dans la version précédente .
Pour modifier les vagues , utilisez les flèches , et les touches [PAgeUp] et [PageDown] pour la hauteur des vagues.
Par contre, le rendu n'est pas encore satisfaisant.
Code : Tout sélectionner
;-Constantes
#ScreenWidth = 1024
#ScreenHeight = 768
#ScreenDepth = 32
;-Structures
Structure Vecteur
x.f
y.f
z.f
EndStructure
Structure Matrix
Largeur.f
Profondeur.f
NbFacetteX.l ;>0 et <256 si FaceCachee=#False , ou <128 si FaceCachee=#True
NbFacetteZ.l ;( j'ai pas encore vérifié si ça passe => à calculer)
FaceCachee.l ; si =True on double les triangles pour voir l'entité des deux côtés
PointIDMemory.l
TriangleIDMemory.l
TextureIDMemory.l
NormaleIDMemory.l
EndStructure
;-Variables
Global Matrix.Matrix
Global CamLocateX.f, CamLocateY.f, CamLocateZ.f,CamLocateX.f,CamLocateY.f,CamLocateZ.f
Global decaleX.l,decaleZ.l,HauteurVague.l
Global Mode.b ,AngleVague.f,Vitesse.f,ShadingMode.b,NormaleInverse.l,Animation.l
;-Declare
Declare HauteurPoint(x.l, z.l, Hauteur.f)
Declare HauteurFacette(x.l, z.l, Hauteur.f)
Declare Matrice()
Declare normalise(*n.Vecteur)
Declare NormalesMatrice()
Declare.f Wrapvalue(Angle.f)
Declare.f Sind( Angle.f)
Declare vagues()
Declare GestionTouches()
Declare AfficheAide()
;
;- Main starts here
;
If InitEngine3D() And InitSprite() And InitKeyboard() And OpenScreen(#ScreenWidth, #ScreenHeight, #ScreenDepth, "FRW Matrix")
;/Divers
Vitesse=2.0
HauteurVague=260
decaleX=-2
decaleZ=-2
Animation = 1
;/Paramètres de la matrice
Matrix\Largeur = 1000
Matrix\Profondeur = 1000
Matrix\NbFacetteX = 50
Matrix\NbFacetteZ = 50
Matrix\FaceCachee = #True
Matrix\PointIDMemory = AllocateMemory(12 * (Matrix\NbFacetteX + 1) * (Matrix\NbFacetteZ + 1))
Matrix\TriangleIDMemory = AllocateMemory(12 * Matrix\NbFacetteX * Matrix\NbFacetteZ * 4)
Matrix\TextureIDMemory = AllocateMemory(12 * (Matrix\NbFacetteX + 1) * (Matrix\NbFacetteZ + 1))
Matrix\NormaleIDMemory = AllocateMemory(12 * (Matrix\NbFacetteX + 1) * (Matrix\NbFacetteZ + 1))
Dim Points.Vecteur((Matrix\NbFacetteX+1)*(Matrix\NbFacetteZ+1))
Matrice()
NormaleInverse = -1
;/Mesh
CreateMesh(0)
SetMeshData(0, 0, Matrix\PointIDMemory , (Matrix\NbFacetteX + 1) * (Matrix\NbFacetteZ + 1))
SetMeshData(0, 1, Matrix\TriangleIDMemory, (Matrix\NbFacetteX) * (Matrix\NbFacetteZ) * 4)
SetMeshData(0, 2, Matrix\TextureIDMemory , (Matrix\NbFacetteX + 1) * (Matrix\NbFacetteZ + 1))
SetMeshData(0, 3, Matrix\NormaleIDMemory , (Matrix\NbFacetteX + 1) * (Matrix\NbFacetteZ + 1))
;/Texture
;/Sans image
TextureXSize = 256
TextureYSize = 256
; CreateTexture(0, TextureXSize, TextureYSize)
; StartDrawing(TextureOutput(0))
; Box(0, 0, TextureXSize/3, TextureYSize, #Blue)
; Box(TextureXSize/3, 0, TextureXSize*2/3, TextureYSize, #White)
; Box(TextureXSize*2/3, 0, TextureXSize, TextureYSize, #Red)
; DrawingMode(4)
; Box(0, 0, TextureXSize , TextureYSize , #White)
; StopDrawing()
;/Avec une image
UsePNGImageDecoder()
LoadImage(0,"data\purebasiclogonew.png")
ResizeImage(0,TextureXSize,TextureYSize)
CreateTexture(0,TextureXSize,TextureYSize)
StartDrawing(TextureOutput(0))
DrawImage(UseImage(0), 0, 0)
DrawingMode(4)
Box(1, 1, TextureXSize - 2, TextureYSize - 2, RGB(255,255,255))
StopDrawing()
;/Material
CreateMaterial(0, TextureID(0)) ; Material
;MaterialFilteringMode(0, #PB_Material_Trilinear)
MaterialShadingMode(0, #PB_Material_Gouraud)
;/Entity
CreateEntity(0, MeshID(0), MaterialID(0))
;/Caméra
CamLocateX = 0
CamLocateY = 845
CamLocateZ = 915
CamLookAtX = EntityX(0)
CamLookAtY = EntityY(0)
CamLookAtZ = EntityZ(0)
CreateCamera(0, 0, 0, 100, 100)
CameraLocate(0, CamLocateX, CamLocateY, CamLocateZ)
CameraLookAt(0,CamLookAtX,CamLookAtY,CamLookAtZ)
;/Lumière
AmbientColor(RGB(110,110,140))
CreateLight(0,RGB(200,200,255))
LightLocate(0, EntityX(0)/2, 700, EntityZ(0)/2)
;LightLocate(0, -200, 600, -200)
Repeat
ClearScreen(0, 0, 0)
ExamineKeyboard()
If Animation
AngleVague = Wrapvalue(AngleVague + Vitesse)
EndIf
;/Donne une forme à la matrice
vagues()
NormalesMatrice()
RenderWorld()
GestionTouches() ; Placé après RenderWorld sinon le snapshot ne fonctionne pas !
AfficheAide()
FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)
Else
MessageRequester("Error", "Something fails to initialize 3D engine", 0)
EndIf
End
;/
;-Procedures
;/
Procedure.f distance(*P1.Vecteur,*P2.Vecteur)
x.f = *P1\x - *P2\x
y.f = *P1\y - *P2\y
z.f = *P1\z - *P2\z
d.f = x*x + y*y + z*z
ProcedureReturn Sqr(d)
EndProcedure
Procedure calculVecteurNorme(*pi.Vecteur,*pf.Vecteur,*n.Vecteur)
x.f = *pf\x - *pi\x
y.f = *pf\y - *pi\y
z.f = *pf\z - *pi\z
d.f = distance(*pi,*pf)
*n\x =x / d
*n\y =y / d
*n\z =z / d
EndProcedure
Procedure normalise(*n.Vecteur)
d.f = Sqr(*n\x * *n\x + *n\y * *n\y + *n\z * *n\z)
*n\x / d
*n\y / d
*n\z / d
EndProcedure
Procedure produitVectoriel(*v1.Vecteur,*v2.Vecteur,*n.Vecteur)
*n\x = *v1\y * *v2\z - *v1\z * *v2\y
*n\y = *v1\z * *v2\x - *v1\x * *v2\z
*n\z = *v1\x * *v2\y - *v1\y * *v2\x
EndProcedure
Procedure HauteurPoint(x.l, z.l, Hauteur.f)
If x > -1 And x <= Matrix\NbFacetteX And z > -1 And z <= Matrix\NbFacetteZ
Adresse = Matrix\PointIDMemory + 4
Adresse = Adresse + (x + (z * (Matrix\NbFacetteX + 1))) * 12
PokeF(Adresse, Hauteur)
SetMeshData(0, 0, Matrix\PointIDMemory, (Matrix\NbFacetteX + 1) * (Matrix\NbFacetteZ + 1))
ProcedureReturn #True
Else
ProcedureReturn #False
EndIf
EndProcedure
Procedure HauteurFacette(x.l, z.l, Hauteur.f)
If x > 0 And x <= Matrix\NbFacetteX And z > 0 And z <= Matrix\NbFacetteZ
Adresse = Matrix\PointIDMemory + 4
Adresse + (x + (z * (Matrix\NbFacetteX + 1))) * 12
PokeF(Adresse, Hauteur)
Adresse - 12
PokeF(Adresse, Hauteur)
Adresse - (Matrix\NbFacetteX + 1) * 12
PokeF(Adresse, Hauteur)
Adresse + 12
PokeF(Adresse, Hauteur)
SetMeshData(0, 0, Matrix\PointIDMemory, (Matrix\NbFacetteX + 1) * (Matrix\NbFacetteZ + 1))
ProcedureReturn #True
Else
ProcedureReturn #False
EndIf
EndProcedure
Procedure Matrice()
TailleFacetteX.f = Matrix\Largeur / Matrix\NbFacetteX
TailleFacetteZ.f = Matrix\Profondeur / Matrix\NbFacetteZ
;/Points
Adresse = Matrix\PointIDMemory
For b = 0 To Matrix\NbFacetteZ
For a = 0 To Matrix\NbFacetteX
PokeF(Adresse, (a - Matrix\NbFacetteX / 2) * TailleFacetteX)
PokeF(Adresse + 4, 0)
PokeF(Adresse + 8, (b - Matrix\NbFacetteZ / 2) * TailleFacetteZ)
Adresse + 12
Next
Next
;/Triangles
If Matrix\FaceCachee
Nbtriangle.l = 4
Else
Nbtriangle = 2
EndIf
Index = 6 * Nbtriangle
Adresse = Matrix\TriangleIDMemory
NbPointX = Matrix\NbFacetteX + 1
For b = 0 To Matrix\NbFacetteZ - 1
For a = 0 To Matrix\NbFacetteX - 1
P1 = a + (b * NbPointX)
P2 = P1 + 1
P3 = a + (b + 1) * NbPointX
P4 = P3 + 1
;Triangle impaire
PokeW(Adresse , P3)
PokeW(Adresse + 2, P2)
PokeW(Adresse + 4, P1)
;Triangle paire
PokeW(Adresse + 6, P2)
PokeW(Adresse + 8, P3)
PokeW(Adresse + 10, P4)
If Matrix\FaceCachee
PokeW(Adresse + 12, P1)
PokeW(Adresse + 14, P2)
PokeW(Adresse + 16, P3)
PokeW(Adresse + 18, P4)
PokeW(Adresse + 20, P3)
PokeW(Adresse + 22, P2)
EndIf
Adresse + Index
Next
Next
;/Texture
Adresse = Matrix\TextureIDMemory
For b = 0 To Matrix\NbFacetteZ
For a = 0 To Matrix\NbFacetteX
PokeF(Adresse, a / Matrix\NbFacetteX)
PokeF(Adresse + 4, b / Matrix\NbFacetteZ)
Adresse + 8
Next
Next
EndProcedure
Procedure NormalesMatrice()
Vecteur1.Vecteur
Vecteur2.Vecteur
P1.Vecteur ; Point 1 de la Facette
P2.Vecteur ; Point 2 de la Facette
P3.Vecteur ; Point 3 de la Facette
P4.Vecteur ; Point 4 de la Facette
Normale1.Vecteur ; Normale Triangle 1 de la Facette Points 1,2,3
Normale2.Vecteur ; Normale Triangle 2 de la Facette Points 2,4,3
Adresse = Matrix\PointIDMemory + 4
AdrNormale = Matrix\NormaleIDMemory
TailleFacetteX.f = Matrix\Largeur / Matrix\NbFacetteX
TailleFacetteZ.f = Matrix\Profondeur / Matrix\NbFacetteZ
NbPointX = Matrix\NbFacetteX + 1
NbPointZ = Matrix\NbFacetteZ + 1
For z = 0 To Matrix\NbFacetteZ - 1
For x = 0 To Matrix\NbFacetteX - 1
NoPoint1 = x + z * NbPointX
P1\x = x
P1\y = PeekF(Adresse + (x + (z * (Matrix\NbFacetteX + 1))) * 12)
P1\z = z
NoPoint2 = NoPoint1 + 1
P2\x = x + 1
P2\y = PeekF(Adresse + (x + 1 + (z * (Matrix\NbFacetteX + 1))) * 12)
P2\z = z
NoPoint3 = x + (z + 1) * NbPointX
P3\x = x
P3\y = PeekF(Adresse + (x + ((z + 1) * (Matrix\NbFacetteX + 1))) * 12)
P3\z = z + 1
NoPoint4 = NoPoint3 + 1
P4\x = x + 1
P4\y = PeekF(Adresse + (x + 1 + ((z + 1) * (Matrix\NbFacetteX + 1))) * 12)
P4\z = z + 1
calculVecteurNorme(@P1,@P2,@Vecteur1)
calculVecteurNorme(@P1,@P3,@Vecteur2)
produitVectoriel(@Vecteur1,@Vecteur2,@Normale1)
calculVecteurNorme(@P2,@P4,@Vecteur1)
calculVecteurNorme(@P2,@P3,@Vecteur2)
produitVectoriel(@Vecteur1,@Vecteur2,@Normale2)
Points(NoPoint1)\x + Normale1\x
Points(NoPoint1)\y + Normale1\y
Points(NoPoint1)\z + Normale1\z
Points(NoPoint2)\x + Normale1\x + Normale2\x
Points(NoPoint2)\y + Normale1\y + Normale2\y
Points(NoPoint2)\z + Normale1\z + Normale2\z
Points(NoPoint3)\x + Normale1\x + Normale2\x
Points(NoPoint3)\y + Normale1\y + Normale2\y
Points(NoPoint3)\z + Normale1\z + Normale2\z
Points(NoPoint4)\x + Normale2\x
Points(NoPoint4)\y + Normale2\y
Points(NoPoint4)\z + Normale2\z
Next x
Next z
No=0
For z = 0 To Matrix\NbFacetteZ
For x = 0 To Matrix\NbFacetteX
Magnitude.f = Sqr(Points(No)\x * Points(No)\x + Points(No)\y * Points(No)\y + Points(No)\z * Points(No)\z)
Points(No)\x / Magnitude
Points(No)\y / Magnitude
Points(No)\z / Magnitude
PokeF(AdrNormale , Points(No)\x * NormaleInverse)
PokeF(AdrNormale + 4, Points(No)\y * NormaleInverse)
PokeF(AdrNormale + 8, Points(No)\z * NormaleInverse)
No + 1
AdrNormale + 12
Next x
Next z
SetMeshData(0, 3, Matrix\NormaleIDMemory , (Matrix\NbFacetteX + 1) * (Matrix\NbFacetteZ + 1))
EndProcedure
Procedure.f Wrapvalue(Angle.f)
Angle / 360
Angle - Int(Angle)
If Angle < 0
ProcedureReturn (Angle + 1) * 360
Else
ProcedureReturn Angle * 360
EndIf
EndProcedure
Procedure.f Sind( Angle.f )
;calcule le sin d'un angle en degré
a.f = Angle * 0.0174533
ProcedureReturn Sin( a )
EndProcedure
Procedure vagues()
Adresse = Matrix\PointIDMemory + 4
For z = 0 To Matrix\NbFacetteZ
For x = 0 To Matrix\NbFacetteX
Sommet.f = Sind(AngleVague + (x * decaleX) + (z * decaleZ)) * HauteurVague
PokeF(Adresse, Sommet)
Adresse + 12
Next x
Next z
SetMeshData(0, 0, Matrix\PointIDMemory, (Matrix\NbFacetteX + 1) * (Matrix\NbFacetteZ + 1))
EndProcedure
Procedure GestionTouches()
If KeyboardReleased(#PB_Key_F1)
Mode = #PB_Camera_Wireframe - Mode
CameraRenderMode(0, Mode)
EndIf
If KeyboardReleased(#PB_Key_F2)
MaterialShadingMode(0, #PB_Material_Flat)
EndIf
If KeyboardReleased(#PB_Key_F3)
MaterialShadingMode(0, #PB_Material_Gouraud)
EndIf
If KeyboardReleased(#PB_Key_F4)
MaterialShadingMode(0, #PB_Material_Phong)
EndIf
If KeyboardReleased(#PB_Key_F5)
Animation = 1 - Animation
EndIf
If KeyboardReleased(#PB_Key_F6)
NormaleInverse * -1
EndIf
decaleX - 1 * KeyboardPushed(#PB_Key_Left) / 128
decaleX + 1 * KeyboardPushed(#PB_Key_Right) / 128
HauteurVague + 1 * KeyboardPushed(#PB_Key_PageUp) / 128
HauteurVague - 1 * KeyboardPushed(#PB_Key_PageDown) / 128
decaleZ + 1 * KeyboardPushed(#PB_Key_Up) / 128
decaleZ - 1 * KeyboardPushed(#PB_Key_Down) / 128
;SnapShot
If KeyboardReleased(#PB_Key_F12)
hBitmap = CreateImage(0, #ScreenWidth, #ScreenHeight)
hdc = StartDrawing(ImageOutput())
SelectObject_(hdc, hBitmap)
BitBlt_(hdc, 0, 0, #ScreenWidth, #ScreenHeight, GetDC_(GetDesktopWindow_()), 0, 0, #SRCCOPY)
StopDrawing()
DeleteDC_(hdc)
SetClipboardData(#PB_ClipboardImage, ImageID())
EndIf
EndProcedure
Procedure AfficheAide()
StartDrawing(ScreenOutput())
DrawingMode(1)
FrontColor(255,255,255)
Locate(10,10)
DrawText("DecaleX = " + StrF(decaleX))
Locate(10,30)
DrawText("DecaleZ = " + StrF(decaleZ))
Locate(10,50)
DrawText("HauteurVague = " + StrF(HauteurVague))
Locate(10,70)
DrawText("[F1] => Change Mode Caméra")
Locate(10,90)
DrawText("[F2] => MaterialSharingMode=> Flat")
Locate(10,110)
DrawText("[F3] => MaterialSharingMode=> Gouraud")
Locate(10,130)
DrawText("[F4] => MaterialSharingMode=> Phong")
Locate(10,150)
DrawText("[F5] => Marche/Arrêt Animation des vagues")
StopDrawing()
EndProcedure