Something like this, perhaps?
Const CYLINDER_QUALITY = 32
i = LoadImage(Input$("image filename: "))
If i Then
w = ImageWidth(i)
h = ImageHeight(i)
Else
w = 20
h = 20
EndIf
Dim cylinder_sample#(w-1)
For x = 0 To w-1
cylinder_sample(x) = h-1 ; default
If i Then
For y = 0 To h-1
If ReadPixel(x, y, ImageBuffer(i)) > 0 Then
cylinder_sample(x) = Float(y) / (h-1)
Exit
EndIf
Next
Else
cylinder_sample(x) = (Sin(x*15)*20)/(h-1) ; DEBUG
EndIf
Next
Graphics3D 800, 600
light = CreateLight()
TurnEntity(light, 45, 30, 0)
camera_pivot = CreatePivot()
camera = CreateCamera(camera_pivot)
PositionEntity(camera, 0, 0, -20)
For x = 0 To w-1
segment = CreateCylinder(CYLINDER_QUALITY)
d = 1 + cylinder_sample(x) * 10
ScaleEntity(segment, d/2.0, 0.5, d/2.0)
TurnEntity(segment, 0, 0, 90)
PositionEntity(segment, x - w/2, 0, 0)
Next
While Not KeyHit(1)
TurnEntity(camera_pivot, 0, .6, 0)
RenderWorld
Flip
Wend
EndOr constructing a mesh instead of using primatives:
Const CYLINDER_QUALITY = 32
; load image
i = LoadImage(Input$("image filename: "))
If i Then
w = ImageWidth(i)
h = ImageHeight(i)
Else
w = 20
h = 20
EndIf
; read samples
Dim cylinder_sample#(w-1)
For x = 0 To w-1
If i Then
; look down until we find a non-black pixel
cylinder_sample(x) = h-1 ; default value for if all pixels are black
For y = 0 To h-1
If ReadPixel(x, y, ImageBuffer(i)) > 0 Then
cylinder_sample(x) = Float(y) / (h-1)
Exit
EndIf
Next
Else
cylinder_sample(x) = Abs(Sin(x*15)*20)/(h-1)
EndIf
Next
; init 3d
Graphics3D 800, 600
AmbientLight(30, 30, 30)
SeedRnd(MilliSecs())
light = CreateLight()
TurnEntity(light, 30, 60, 0)
camera_pivot = CreatePivot()
camera = CreateCamera(camera_pivot)
PositionEntity(camera, 0, 0, -20)
; init our object
mesh = CreateMesh()
surf = CreateSurface(mesh)
; plot vertices in a circle around each sampling point along the X axis
For x = 0 To w-1
d = 1 + cylinder_sample(x) * 5
For v = 0 To CYLINDER_QUALITY-1
ang# = v * (360.0 / CYLINDER_QUALITY)
vi = AddVertex(surf, x, Cos(ang)*d, Sin(ang)*d)
Next
Next
; connect the dots with quads
For x = 1 To w-1
For v = 1 To CYLINDER_QUALITY-1
vi = x*CYLINDER_QUALITY + v
AddTriangle(surf, vi-CYLINDER_QUALITY, vi, vi-CYLINDER_QUALITY-1)
AddTriangle(surf, vi, vi-1, vi-CYLINDER_QUALITY-1)
Next
; slightly different math for the last quad
v0 = x*CYLINDER_QUALITY + 0
AddTriangle(surf, v0-CYLINDER_QUALITY, v0, v0-1)
AddTriangle(surf, v0, v0+CYLINDER_QUALITY-1, v0-1)
Next
; put caps on both sides with triangles
v0 = 0*CYLINDER_QUALITY + 0
vN = (w-1)*CYLINDER_QUALITY + 0
For v = 2 To CYLINDER_QUALITY-1
AddTriangle(surf, v0, v0+v, v0+v-1)
AddTriangle(surf, vN, vN+v-1, vN+v)
Next
; fix normals
UpdateNormals(mesh)
; centre the mesh
PositionEntity(mesh, -w/2, 0, 0)
; show it
While Not KeyHit(1)
TurnEntity(camera_pivot, 0, .6, 0)
RenderWorld
Flip
Wend
End