Horloge lumineuse (PB 4.30)
Publié : mar. 19/mai/2009 15:44
Bonjour à tous,
Une petite horloge lumineuse codée à l'arrache (2 heures), pour valider les possibilités des lumières.
Résultat: les ombres sortent plutôt bien, comme quoi PB se débrouille pas si mal que ça en 3D!
Par contre, j'ai l'impression (infondée et sans doute fausse) que les résultats à l'écran peuvent beaucoup varier selon la carte graphique; 'faudrait que je poste une capture d'écran pour que vous voyiez à quoi ça ressemble chez moi, histoire de voir si vous avez la même chose. A tester, donc.
Autre chose: si ça rame chez vous, modifiez la valeur de la constante #QUALITY, en début de code; ça réduira le nombre de polygones des meshes (que j'ai mis assez élevé par défaut, pour obtenir des éclairages plus jolis).
Voici le code:
Une petite horloge lumineuse codée à l'arrache (2 heures), pour valider les possibilités des lumières.
Résultat: les ombres sortent plutôt bien, comme quoi PB se débrouille pas si mal que ça en 3D!

Par contre, j'ai l'impression (infondée et sans doute fausse) que les résultats à l'écran peuvent beaucoup varier selon la carte graphique; 'faudrait que je poste une capture d'écran pour que vous voyiez à quoi ça ressemble chez moi, histoire de voir si vous avez la même chose. A tester, donc.
Autre chose: si ça rame chez vous, modifiez la valeur de la constante #QUALITY, en début de code; ça réduira le nombre de polygones des meshes (que j'ai mis assez élevé par défaut, pour obtenir des éclairages plus jolis).
Voici le code:
Code : Tout sélectionner
;- Initialization
Global FullScreen.b
Resultat = MessageRequester("Light Clock","Full Screen ?",#PB_MessageRequester_YesNo)
If Resultat = 6
FullScreen=#True
Else
FullScreen=#False
EndIf
If InitEngine3D() = 0
MessageRequester( "Error" , "Can't initialize 3D, check if engine3D.dll is available" , 0 )
End
ElseIf InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse() = 0
MessageRequester( "Error" , "Can't find DirectX 7.0 or above" , 0 )
End
EndIf
If Fullscreen = #True
OpenScreen(1024,768,32,"Light Clock")
Else
OpenWindow(0,0, 0, 800 , 600 ,"Light Clock")
OpenWindowedScreen(WindowID(0),0,0, 800 , 600,0,0,0)
EndIf
#CAMERA = 0
#RAD2DEGMULT = 57.295779513082320877 ;(180/#PI)
#DEG2RADMULT = 0.0174532925199432958 ;(#PI/180)
#QUALITY = 1 ; 1 = good, 2 = medium, 3 = low, 4 = mini
; Cylinder mesh caps
Enumeration
#CYLCAP_NONE
#CYLCAP_BOTH
#CYLCAP_TOP
#CYLCAP_BOTTOM
EndEnumeration
;- Structures and global definitions
Structure Vertex
px.f
py.f
pz.f
nx.f
ny.f
nz.f
Couleur.l
U.f
V.f
EndStructure
Structure Polygon
numVert1.w
numVert2.w
numVert3.w
EndStructure
Global groundMesh.i, gnomonMesh.i, boxMesh.i
Global groundEntity.i, gnomonEntity.i
Global Dim boxEntity.i(12)
Global hours.f, mins.f, secs.f
Global oldTimer.i, newTimer.i, movement.i
Global dist.f,i.i
;- ------ Procedures ------
EnableExplicit
;- -- Meshes and entities --
;************************************************************************************
; Name: createPlainMesh
; Purpose: creates a plain
; Parameters:
; - number of subdivisions (given "3", the plain will be a 3x3 grid)
; - sizeX, sizeZ : size of the box
; - pivotX, pivotZ : location of the pivot of the box, around which it rotates (default = center = 0,0)
; - Uorigin, Vorigin : UV map coordinates (default = top left of the map = 0,0)
; - Uscale, Vscale : UV map scale (default = 1,1)
; - color of the vertices (default = white)
; Return-Value: number of the resulting mesh, -1 if creation failed
;************************************************************************************
Procedure.l createPlainMesh(nbdiv.w,sizeX.f,sizeZ.f,pivotX.f = 0,pivotZ.f = 0,Uorigin.f = 0,Vorigin.f = 0,Uscale.f = 1,Vscale.f = 1,color.l = $FFFFFF)
Protected sizediv.f
Protected x1.f,y1.f,z1.f ; vertex position
Protected x2.f,y2.f,z2.f ; vertex position
Protected x3.f,y3.f,z3.f ; vertex position
Protected x4.f,y4.f,z4.f ; vertex position
Protected nx.f,ny.f,nz.f ; vertex normals
Protected u.f,v.f ; vertex UV coords (texture mapping)
Protected numvert.w,numvert0.w ; vertices of a poly
Protected *PtrV.Vertex,*PtrV0.Vertex ; vertices buffer in memory
Protected *ptrP.Polygon,*ptrP0.Polygon ; Polys buffer in memory
Protected *vertexBuffer.l
Protected *polygonBuffer.l
Protected num.l,i.l,j.l,nbtri.l,nbvert
Protected maxSize.f
Protected newmesh.l ; Procedure Result
nbtri = (nbDiv * nbDiv * 2) ; nb divisions * nb divisions * 2 triangles per division
nbvert = (nbDiv * nbDiv * 4) ; nb divisions * nb divisions * 4 vertices per division
; Allocate the needed memory for vertices
*vertexBuffer = AllocateMemory(SizeOf(Vertex)*nbVert)
*PtrV = *vertexBuffer
; Allocate the needed memory for faces info
*polygonBuffer=AllocateMemory(SizeOf(Polygon)*nbTri)
*ptrP=*polygonBuffer
sizeDiv = 1/nbDiv
; Top
x1=-0.5:y1=0:z1=-0.5
x2=-0.5+sizeDiv:y2=0:z2 = z1
x3=x2:y3=0:z3=-0.5+sizeDiv
x4=x1:y4=0:z4=z3
For i=1 To nbDiv
For j=1 To nbDiv
; 1 square = 4 vertices
*PtrV\px = x1
*PtrV\py = y1
*PtrV\pz = z1
*PtrV\nx = 0
*PtrV\ny = 0.5
*PtrV\nz = 0
*PtrV\couleur = color
*PtrV\u = uorigin + (uscale/nbdiv)*(i-1)
*PtrV\v = vorigin + (vscale/nbdiv)*(j-1)
*PtrV + SizeOf(Vertex)
*PtrV\px = x2
*PtrV\py = y2
*PtrV\pz = z2
*PtrV\nx = 0
*PtrV\ny = 0.5
*PtrV\nz = 0
*PtrV\couleur = color
*PtrV\u = uorigin + (uscale/nbdiv)*(i-1) + uscale/nbdiv
*PtrV\v = vorigin + (vscale/nbdiv)*(j-1)
*PtrV + SizeOf(Vertex)
*PtrV\px = x3
*PtrV\py = y3
*PtrV\pz = z3
*PtrV\nx = 0
*PtrV\ny = 0.5
*PtrV\nz = 0
*PtrV\couleur = color
*PtrV\u = uorigin + (uscale/nbdiv)*(i-1) + uscale/nbdiv
*PtrV\v = vorigin + (vscale/nbdiv)*(j-1) + vscale/nbdiv
*PtrV + SizeOf(Vertex)
*PtrV\px = x4
*PtrV\py = y4
*PtrV\pz = z4
*PtrV\nx = 0
*PtrV\ny = 0.5
*PtrV\nz = 0
*PtrV\couleur = color
*PtrV\u = uorigin + (uscale/nbdiv)*(i-1)
*PtrV\v = vorigin + (vscale/nbdiv)*(j-1) + vscale/nbdiv
*PtrV + SizeOf(Vertex)
; 1 square = 2 triangles
*ptrP\numVert1=numvert+3
*ptrP\numVert2=numvert+2
*ptrP\numVert3=numvert
*ptrP + SizeOf(Polygon)
*ptrP\numVert1=numvert
*ptrP\numVert2=numvert+2
*ptrP\numVert3=numvert+1
*ptrP + SizeOf(Polygon)
numvert+4
z1=z4
z2=z3
z3+sizeDiv
z4=z3
Next j
x1=x2
x4=x3
x2+sizeDiv
x3=x2
z1=-0.5
z2=z1
z3=-0.5+sizeDiv
z4=z3
Next i
numvert0=numvert
; Resize
If sizeX<>1 Or sizeZ<>1
*ptrV = *vertexBuffer
For i=1 To nbVert
*PtrV\px = *PtrV\px*sizeX - pivotX
*PtrV\pz = *PtrV\pz*sizeZ - pivotZ
*PtrV+SizeOf(vertex)
Next i
EndIf
; Create mesh from stored infos
maxSize = sizeX
If sizeZ > maxSize
maxSize = sizeZ
EndIf
newMesh = CreateMesh(#PB_Any,maxSize)
If IsMesh(newMesh)
SetMeshData(newMesh,#PB_Mesh_Vertex | #PB_Mesh_Normal | #PB_Mesh_UVCoordinate | #PB_Mesh_Color,*vertexBuffer,nbVert)
SetMeshData(newMesh,#PB_Mesh_Face,*polygonBuffer,nbTri)
FreeMemory(*vertexBuffer)
FreeMemory(*polygonBuffer)
ProcedureReturn newMesh
Else
; free memory if "createMesh" has failed
FreeMemory(*vertexBuffer)
FreeMemory(*polygonBuffer)
ProcedureReturn -1
EndIf
EndProcedure
;************************************************************************************
; Name: createBoxMesh
; Purpose: creates a "box" mesh
; Parameters:
; - number of subdivisions (given "3", each face of the box will be a 3x3 grid)
; - sizeX, sizeY, sizeZ : size of the box
; - pivotX, pivotY, pivotZ : location of the pivot of the box, around which it rotates (default = center = 0,0,0)
; - Uorigin, Vorigin : UV map coordinates (default = top left of the map = 0,0)
; - Uscale, Vscale : UV map scale (default = 1,1)
; - color of the vertices (default = white)
; Return-Value: number of the resulting mesh, -1 if creation failed
;************************************************************************************
Procedure.l createBoxMesh(nbdiv.w,sizeX.f,sizeY.f,sizeZ.f,pivotX.f = 0,pivotY.f = 0,pivotZ.f = 0,Uorigin.f = 0,Vorigin.f = 0,Uscale.f = 1,Vscale.f = 1,color.l = $FFFFFF)
Protected sizediv.f
Protected x1.f,y1.f,z1.f ; vertex position
Protected x2.f,y2.f,z2.f ; vertex position
Protected x3.f,y3.f,z3.f ; vertex position
Protected x4.f,y4.f,z4.f ; vertex position
Protected nx.f,ny.f,nz.f ; vertex normals
Protected u.f,v.f ; vertex UV coords (texture mapping)
Protected numvert.w,numvert0.w ; vertices of a poly
Protected *PtrV.Vertex,*PtrV0.Vertex ; vertices buffer in memory
Protected *ptrP.Polygon,*ptrP0.Polygon ; Polys buffer in memory
Protected *vertexBuffer.l
Protected *polygonBuffer.l
Protected num.l,i.l,j.l,nbtri.l,nbvert
Protected maxSize.f
Protected newmesh.l ; Procedure Result
nbtri = 6 * (nbDiv * nbDiv * 2) ; 6 sides * nb divisions * nb divisions * 2 triangles per division
nbvert = 6 * (nbDiv * nbDiv * 4) ; 6 sides * nb divisions * nb divisions * 4 vertices per division
; Allocate the needed memory for vertices
*vertexBuffer = AllocateMemory(SizeOf(Vertex)*nbVert)
*PtrV = *vertexBuffer
; Allocate the needed memory for faces info
*polygonBuffer=AllocateMemory(SizeOf(Polygon)*nbTri)
*ptrP=*polygonBuffer
sizeDiv = 1/nbDiv
; Top
x1=-0.5:y1=0.5:z1=-0.5
x2=-0.5+sizeDiv:y2=0.5:z2 = z1
x3=x2:y3=0.5:z3=-0.5+sizeDiv
x4=x1:y4=0.5:z4=z3
For i=1 To nbDiv
For j=1 To nbDiv
; 1 square = 4 vertices
*PtrV\px = x1
*PtrV\py = y1
*PtrV\pz = z1
*PtrV\nx = *PtrV\px
*PtrV\ny = *PtrV\py
*PtrV\nz = *PtrV\pz
*PtrV\couleur = color
*PtrV\u = uorigin + (uscale/nbdiv)*(i-1)
*PtrV\v = vorigin + (vscale/nbdiv)*(j-1)
*PtrV + SizeOf(Vertex)
*PtrV\px = x2
*PtrV\py = y2
*PtrV\pz = z2
*PtrV\nx = *PtrV\px
*PtrV\ny = *PtrV\py
*PtrV\nz = *PtrV\pz
*PtrV\couleur = color
*PtrV\u = uorigin + (uscale/nbdiv)*(i-1) + uscale/nbdiv
*PtrV\v = vorigin + (vscale/nbdiv)*(j-1)
*PtrV + SizeOf(Vertex)
*PtrV\px = x3
*PtrV\py = y3
*PtrV\pz = z3
*PtrV\nx = *PtrV\px
*PtrV\ny = *PtrV\py
*PtrV\nz = *PtrV\pz
*PtrV\couleur = color
*PtrV\u = uorigin + (uscale/nbdiv)*(i-1) + uscale/nbdiv
*PtrV\v = vorigin + (vscale/nbdiv)*(j-1) + vscale/nbdiv
*PtrV + SizeOf(Vertex)
*PtrV\px = x4
*PtrV\py = y4
*PtrV\pz = z4
*PtrV\nx = *PtrV\px
*PtrV\ny = *PtrV\py
*PtrV\nz = *PtrV\pz
*PtrV\couleur = color
*PtrV\u = uorigin + (uscale/nbdiv)*(i-1)
*PtrV\v = vorigin + (vscale/nbdiv)*(j-1) + vscale/nbdiv
*PtrV + SizeOf(Vertex)
; 1 square = 2 triangles
*ptrP\numVert1=numvert+3
*ptrP\numVert2=numvert+2
*ptrP\numVert3=numvert
*ptrP + SizeOf(Polygon)
*ptrP\numVert1=numvert
*ptrP\numVert2=numvert+2
*ptrP\numVert3=numvert+1
*ptrP + SizeOf(Polygon)
numvert+4
z1=z4
z2=z3
z3+sizeDiv
z4=z3
Next j
x1=x2
x4=x3
x2+sizeDiv
x3=x2
z1=-0.5
z2=z1
z3=-0.5+sizeDiv
z4=z3
Next i
numvert0=numvert
; Bottom
*PtrV0 = *vertexBuffer
For i=1 To numvert0
*PtrV\px = -*PtrV0\px
*PtrV\py = -*PtrV0\py
*PtrV\pz = *PtrV0\pz
*PtrV\nx = *PtrV\px
*PtrV\ny = *PtrV\py
*PtrV\nz = *PtrV\pz
*PtrV\couleur = *PtrV0\couleur
*PtrV\u = *PtrV0\u
*PtrV\v = *PtrV0\v
*PtrV + SizeOf(Vertex)
*PtrV0 + SizeOf(Vertex)
numvert+1
If i%4=0
*ptrP\numVert1=numvert - 2
*ptrP\numVert2=numvert - 3
*ptrP\numVert3=numvert - 4
*ptrP + SizeOf(Polygon)
*ptrP\numVert1=numvert - 4
*ptrP\numVert2=numvert - 1
*ptrP\numVert3=numvert - 2
*ptrP + SizeOf(Polygon)
EndIf
Next i
; Right
*PtrV0 = *vertexBuffer
For i=1 To numvert0
*PtrV\px = *PtrV0\py
*PtrV\py = -*PtrV0\px
*PtrV\pz = *PtrV0\pz
*PtrV\nx = *PtrV\px
*PtrV\ny = *PtrV\py
*PtrV\nz = *PtrV\pz
*PtrV\couleur = *PtrV0\couleur
*PtrV\u = 1-*PtrV0\v
*PtrV\v = *PtrV0\u
*PtrV + SizeOf(Vertex)
*PtrV0 + SizeOf(Vertex)
numvert+1
If i%4=0
*ptrP\numVert1=numvert - 2
*ptrP\numVert2=numvert - 3
*ptrP\numVert3=numvert - 4
*ptrP + SizeOf(Polygon)
*ptrP\numVert1=numvert - 4
*ptrP\numVert2=numvert - 1
*ptrP\numVert3=numvert - 2
*ptrP + SizeOf(Polygon)
EndIf
Next i
; Left
*PtrV0 = *vertexBuffer
For i=1 To numvert0
*PtrV\px = -*PtrV0\py
*PtrV\py = -*PtrV0\px
*PtrV\pz = *PtrV0\pz
*PtrV\nx = *PtrV\px
*PtrV\ny = *PtrV\py
*PtrV\nz = *PtrV\pz
*PtrV\couleur = *PtrV0\couleur
*PtrV\u = *PtrV0\v
*PtrV\v = *PtrV0\u
*PtrV + SizeOf(Vertex)
*PtrV0 + SizeOf(Vertex)
numvert+1
If i%4=0
*ptrP\numVert1=numvert - 4
*ptrP\numVert2=numvert - 3
*ptrP\numVert3=numvert - 2
*ptrP + SizeOf(Polygon)
*ptrP\numVert1=numvert - 2
*ptrP\numVert2=numvert - 1
*ptrP\numVert3=numvert - 4
*ptrP + SizeOf(Polygon)
EndIf
Next i
; Front
*PtrV0 = *vertexBuffer
For i=1 To numvert0
*PtrV\px = -*PtrV0\pz
*PtrV\py = -*PtrV0\px
*PtrV\pz = -*PtrV0\py
*PtrV\nx = *PtrV\px
*PtrV\ny = *PtrV\py
*PtrV\nz = *PtrV\pz
*PtrV\couleur = *PtrV0\couleur
*PtrV\u = *PtrV0\v
*PtrV\v = *PtrV0\u
*PtrV + SizeOf(Vertex)
*PtrV0 + SizeOf(Vertex)
numvert+1
If i%4=0
*ptrP\numVert1=numvert - 4
*ptrP\numVert2=numvert - 3
*ptrP\numVert3=numvert - 2
*ptrP + SizeOf(Polygon)
*ptrP\numVert1=numvert - 2
*ptrP\numVert2=numvert - 1
*ptrP\numVert3=numvert - 4
*ptrP + SizeOf(Polygon)
EndIf
Next i
; Back
*PtrV0 = *vertexBuffer
For i=1 To numvert0
*PtrV\px = -*PtrV0\pz
*PtrV\py = -*PtrV0\px
*PtrV\pz = *PtrV0\py
*PtrV\nx = *PtrV\px
*PtrV\ny = *PtrV\py
*PtrV\nz = *PtrV\pz
*PtrV\couleur = *PtrV0\couleur
*PtrV\u = 1-*PtrV0\v
*PtrV\v = *PtrV0\u
*PtrV + SizeOf(Vertex)
*PtrV0 + SizeOf(Vertex)
numvert+1
If i%4=0
*ptrP\numVert1=numvert - 2
*ptrP\numVert2=numvert - 3
*ptrP\numVert3=numvert - 4
*ptrP + SizeOf(Polygon)
*ptrP\numVert1=numvert - 4
*ptrP\numVert2=numvert - 1
*ptrP\numVert3=numvert - 2
*ptrP + SizeOf(Polygon)
EndIf
Next i
; Resize
If sizeX<>1 Or sizeY<>1 Or sizeZ<>1
*ptrV = *vertexBuffer
For i=1 To nbVert
*PtrV\px = *PtrV\px*sizeX - pivotX
*PtrV\py = *PtrV\py*sizeY - pivotY
*PtrV\pz = *PtrV\pz*sizeZ - pivotZ
*PtrV+SizeOf(vertex)
Next i
EndIf
; Create mesh from stored infos
maxSize = sizeX
If sizeY > sizeX
maxSize = sizeY
EndIf
If sizeZ > maxSize
maxSize = sizeZ
EndIf
newMesh = CreateMesh(#PB_Any,maxSize)
If IsMesh(newMesh)
SetMeshData(newMesh,#PB_Mesh_Vertex | #PB_Mesh_Normal | #PB_Mesh_UVCoordinate | #PB_Mesh_Color,*vertexBuffer,nbVert)
SetMeshData(newMesh,#PB_Mesh_Face,*polygonBuffer,nbTri)
FreeMemory(*vertexBuffer)
FreeMemory(*polygonBuffer)
ProcedureReturn newMesh
Else
; free memory if "createMesh" has failed
FreeMemory(*vertexBuffer)
FreeMemory(*polygonBuffer)
ProcedureReturn -1
EndIf
EndProcedure
;************************************************************************************
; Name: createCylinderMesh
; Purpose: create a cylinder mesh
; Parameters:
; - number of sides ("3" gives a prism, "4" gives a box)
; - height
; - radius
; - uncapped (=0), caps on top an bottom (=1), top cap only (=2), bottom cap only (=3). (default = 1)
; - color of the vertices (default = white)
; Return-Value: number of the resulting mesh, -1 if creation failed
;************************************************************************************
Procedure.l createCylinderMesh(nbSides.l,height.f,radius.f,capped.b = 1,coul.l = $FFFFFF)
Protected *PtrV.Vertex,*vertexBuffer.l ; vertices buffer in memory
Protected *PtrF.Polygon,*facetriBuffer.l ; Faces buffer in memory
Protected i.l,nbVert.l,nbTri.l, numVertTop.l,numVertBottom.l
Protected h2.f,theta.f
Protected newmesh.l ; Procedure Result
If nbSides<3
ProcedureReturn 0
EndIf
h2 = height / 2.0
nbVert = 4*(nbSides+1)+2
If capped = #CYLCAP_TOP Or capped = #CYLCAP_BOTTOM
nbVert-1
Else
If capped = #CYLCAP_NONE
nbVert-2
EndIf
EndIf
*vertexBuffer = AllocateMemory(SizeOf(Vertex)*nbVert)
*PtrV = *vertexBuffer
;Vertices at the bottom of the cylinder
For i = 0 To nbSides
theta =2*#PI*i/nbSides
*PtrV\px = radius*Cos(theta)
*PtrV\py = -h2
*PtrV\pz = radius*Sin(theta)
*PtrV\nx = Cos(theta)
*PtrV\ny = 0
*PtrV\nz = Sin(theta)
*PtrV\couleur = Coul
*PtrV\u = Theta / (2.0*#PI)
*PtrV\v = 0
*PtrV + SizeOf(Vertex)
Next i
;Vertices at the top of the cylinder
For i = 0 To nbSides
theta =2*#PI*i/nbSides
*PtrV\px = radius*Cos(theta)
*PtrV\py = h2
*PtrV\pz = radius*Sin(theta)
*PtrV\nx = Cos(theta)
*PtrV\ny = 0
*PtrV\nz = Sin(theta)
*PtrV\couleur = Coul
*PtrV\u = Theta / (2.0*#PI)
*PtrV\v = 1
*PtrV + SizeOf(Vertex)
Next i
;Vertices at the bottom of the cylinder
For i = 0 To nbSides
theta =2*#PI*i/nbSides
*PtrV\px = radius*Cos(theta)
*PtrV\py = -h2
*PtrV\pz = radius*Sin(theta)
*PtrV\nx = 0
*PtrV\ny = -1
*PtrV\nz = 0
*PtrV\couleur = Coul
*PtrV\u = Theta / (2.0*#PI)
*PtrV\v = 1
*PtrV + SizeOf(Vertex)
Next i
;Vertices at the top of the cylinder
For i = 0 To nbSides
theta =2*#PI*i/nbSides
*PtrV\px = radius*Cos(theta)
*PtrV\py = h2
*PtrV\pz = radius*Sin(theta)
*PtrV\nx = 0
*PtrV\ny = 1
*PtrV\nz = 0
*PtrV\couleur = Coul
*PtrV\u = Theta / (2.0*#PI)
*PtrV\v = 1
*PtrV + SizeOf(Vertex)
Next i
;Bottom cap center
If capped = #CYLCAP_BOTH Or capped = #CYLCAP_BOTTOM
numVertBottom = (*PtrV - *vertexBuffer) / SizeOf(Vertex)
*PtrV\px = 0
*PtrV\py = -h2
*PtrV\pz = 0
*PtrV\nx = 0
*PtrV\ny = -1
*PtrV\nz = 0
*PtrV\couleur = Coul
*PtrV\u = 0.5
*PtrV\v = 0.5
*PtrV + SizeOf(Vertex)
EndIf
;Top cap center
If capped = #CYLCAP_BOTH Or capped = #CYLCAP_TOP
numVertTop = (*PtrV - *vertexBuffer) / SizeOf(Vertex)
*PtrV\px = 0
*PtrV\py = h2
*PtrV\pz = 0
*PtrV\nx = 0
*PtrV\ny = 1
*PtrV\nz = 0
*PtrV\couleur = Coul
*PtrV\u = 0.5
*PtrV\v = 0.5
EndIf
;Facets
nbTri = 4*nbSides
If capped = #CYLCAP_BOTTOM Or capped = #CYLCAP_TOP
nbTri - nbSides
Else
If capped = #CYLCAP_NONE
nbTri - (nbSides*2)
EndIf
EndIf
*facetriBuffer=AllocateMemory(SizeOf(Polygon)*nbTri)
*PtrF=*facetriBuffer
For i=0 To nbSides-1
*PtrF\numVert3=i
*PtrF\numVert2=i + 1
*PtrF\numVert1=nbSides + i + 2
*PtrF + SizeOf(Polygon)
*PtrF\numVert1=i
*PtrF\numVert3=nbSides + i + 2
*PtrF\numVert2=nbSides + i + 1
*PtrF + SizeOf(Polygon)
Next i
;Bottom cap
If capped = #CYLCAP_BOTH Or capped = #CYLCAP_BOTTOM
For i=0 To nbSides-1
*PtrF\numVert1= numVertBottom
*PtrF\numVert2= 2 * nbSides + 2 + i
*PtrF\numVert3= 2 * nbSides + 3 + i
*PtrF + SizeOf(Polygon)
Next i
EndIf
;Top cap
If capped = #CYLCAP_BOTH Or capped = #CYLCAP_TOP
For i=0 To nbSides-1
*PtrF\numVert1= numVertTop
*PtrF\numVert3= 3 * nbSides + 3 + i
*PtrF\numVert2= 3 * nbSides + 4 + i
*PtrF + SizeOf(Polygon)
Next i
EndIf
; Create mesh from stored infos
newmesh = CreateMesh(#PB_Any,radius)
If IsMesh(newmesh)
SetMeshData(newmesh,#PB_Mesh_Vertex | #PB_Mesh_Normal | #PB_Mesh_UVCoordinate | #PB_Mesh_Color,*vertexBuffer,nbVert)
SetMeshData(newmesh,#PB_Mesh_Face,*facetriBuffer,nbTri)
; and don't forget to free memory
FreeMemory(*vertexBuffer)
FreeMemory(*facetriBuffer)
ProcedureReturn newmesh
Else
; even if "createMesh" has failed
FreeMemory(*vertexBuffer)
FreeMemory(*facetriBuffer)
ProcedureReturn -1
EndIf
EndProcedure
DisableExplicit
;- ----- Main -----
;- Camera
CreateCamera(#CAMERA, 0, 0, 100, 100)
CameraLocate(#CAMERA, 50, 120, 0)
CameraLookAt(#CAMERA,0,0,0)
;- Light
AmbientColor(RGB(20,20,20))
CreateLight(0,RGB(255, 0, 0))
CreateLight(1,RGB(0, 255, 0))
CreateLight(2,RGB(0, 0, 255))
WorldShadows(#PB_Shadow_Additive)
;- Materials
Add3DArchive(".", #PB_3DArchive_FileSystem)
CreateImage(0,64,64)
StartDrawing(ImageOutput(0))
Box(0,0,64,64,$FFFFFF)
StopDrawing()
SaveImage(0,"temp.bmp")
LoadTexture(0,"temp.bmp")
CreateMaterial(0,TextureID(0))
MaterialAmbientColor(0,#PB_Material_AmbientColors)
LoadFont(1, "Garamond", 48,#PB_Font_Bold|#PB_Font_HighQuality)
StartDrawing(ImageOutput(0))
DrawingMode(#PB_2DDrawing_Transparent)
DrawingFont(FontID(1))
For i = 1 To 12
Box(0,0,64,64,$FFFFFF)
If i<10
DrawText(15,-5,Str(i),$000000)
Else
DrawText(5,-5,Str(i),$000000)
EndIf
SaveImage(0,"temp"+Str(i)+".bmp")
LoadTexture(i,"temp"+Str(i)+".bmp")
CreateMaterial(i,TextureID(i))
Next i
StopDrawing()
FreeImage(0)
;- Meshes
groundmesh = CreatePlainMesh(20/#QUALITY,200,200)
gnomonMesh = createCylinderMesh(16/#QUALITY,20,2,#CYLCAP_TOP,$FFFFFF)
boxMesh = createBoxMesh(8/#QUALITY,15,20,1)
;- Entities
groundEntity = CreateEntity(#PB_Any,MeshID(groundmesh),MaterialID(0))
gnomonEntity = CreateEntity(#PB_Any,MeshID(gnomonMesh),MaterialID(0))
EntityLocate(gnomonEntity,0,10,0)
For i=1 To 12
boxEntity(i) = CreateEntity(#PB_Any,MeshID(boxMesh),MaterialID(i))
EntityLocate(boxEntity(i),50*Cos((180+30*i)*#DEG2RADMULT),10,50*Sin((180+30*i)*#DEG2RADMULT))
RotateEntity(boxEntity(i),0,90 + i*-30,0)
Next i
;- **** MAIN LOOP *******************************************************************************
secs = Second(Date())
mins = Minute(Date()) + secs/60
hours = Hour(Date()) + mins/60 + secs/3600
oldtimer = ElapsedMilliseconds()
dist = 48
Repeat
If FullScreen = #False
While WindowEvent() : Wend
EndIf
;- Keyboard
ExamineKeyboard()
If KeyboardReleased(#PB_Key_F1)
MessageRequester("Statistics",Str(CountRenderedTriangles()) + " polygons, " + Str(Engine3DFrameRate(#PB_Engine3D_Average)) + " Fps")
EndIf
;- Move lights
newtimer = ElapsedMilliseconds()
movement = newtimer-oldtimer
oldtimer = newtimer
secs+movement/1000
If secs>=60
secs-60
EndIf
LightLocate(0,dist*Cos(secs*6*#DEG2RADMULT),10,dist*Sin(secs*6*#DEG2RADMULT))
mins+movement/60000
If mins>=60
mins-60
EndIf
LightLocate(1,dist*Cos(mins*6*#DEG2RADMULT),10,dist*Sin(mins*6*#DEG2RADMULT))
hours+movement/3600000
If hours>=24
hours-24
EndIf
LightLocate(2,dist*Cos(hours*30*#DEG2RADMULT),10,dist*Sin(hours*30*#DEG2RADMULT))
; Show it all
RenderWorld()
; Flip buffers to avoid tearing
FlipBuffers()
Delay(1)
Until KeyboardPushed(#PB_Key_Escape)