Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #Include "fbgfx.bi"
- Using FB
- ScreenRes 640, 480, 32
- Const PI = 3.14159
- Type Vec3D
- As Single x, y, z
- End Type
- ' === Basic 3D rotation ===
- Function RotateY(v As Vec3D, angle As Single) As Vec3D
- Dim As Vec3D o
- o.x = v.x * Cos(angle) + v.z * Sin(angle)
- o.z = -v.x * Sin(angle) + v.z * Cos(angle)
- o.y = v.y
- Return o
- End Function
- Function RotateX(v As Vec3D, angle As Single) As Vec3D
- Dim As Vec3D o
- o.y = v.y * Cos(angle) - v.z * Sin(angle)
- o.z = v.y * Sin(angle) + v.z * Cos(angle)
- o.x = v.x
- Return o
- End Function
- Function Project(v As Vec3D) As Vec3D
- Dim As Single scale = 400 / (v.z + 4)
- Dim As Vec3D o
- o.x = v.x * scale + 320
- o.y = v.y * scale + 240
- Return o
- End Function
- ' Cube vertices
- Dim Shared As Vec3D cube(0 To 7) = { _
- (-1, -1, -1), (1, -1, -1), (1, 1, -1), (-1, 1, -1), _
- (-1, -1, 1), (1, -1, 1), (1, 1, 1), (-1, 1, 1) }
- Dim As Integer face(0 To 5, 0 To 3) = { _
- {0,1,2,3}, {4,5,6,7}, {0,1,5,4}, _
- {2,3,7,6}, {0,3,7,4}, {1,2,6,5} }
- ' Create striped background
- For y As Integer = 0 To 479
- For x As Integer = 0 To 639
- If (y \ 10) Mod 2 = 0 Then
- PSet (x, y), RGB(50, 50, 50)
- Else
- PSet (x, y), RGB(120, 120, 120)
- End If
- Next
- Next
- ' Store background
- Dim As Any Ptr bg = ImageCreate(640, 480)
- Get (0,0)-(639,479), bg
- Dim As Single angle = 0
- Do
- ScreenLock
- Put (0,0), bg, PSet
- ' Rotate + project cube
- Dim As Vec3D p(7)
- For i As Integer = 0 To 7
- Dim As Vec3D r = RotateX(cube(i), angle)
- r = RotateY(r, angle * 1.3)
- p(i) = Project(r)
- Next
- ' Draw cube faces with stealth effect
- For f As Integer = 0 To 5
- ' Backface culling
- Dim As Single ax = p(face(f,1)).x - p(face(f,0)).x
- Dim As Single ay = p(face(f,1)).y - p(face(f,0)).y
- Dim As Single bx = p(face(f,2)).x - p(face(f,1)).x
- Dim As Single by = p(face(f,2)).y - p(face(f,1)).y
- If (ax*by - ay*bx) < 0 Then Continue For
- ' Bounding box
- Dim As Integer minX = 640, minY = 480, maxX = 0, maxY = 0
- For i As Integer = 0 To 3
- Dim px as integer = CInt(p(face(f,i)).x)
- Dim py as integer = CInt(p(face(f,i)).y)
- If px < minX Then minX = px
- If px > maxX Then maxX = px
- If py < minY Then minY = py
- If py > maxY Then maxY = py
- Next
- ' Clip
- minX = IIf(minX < 0, 0, minX)
- minY = IIf(minY < 0, 0, minY)
- maxX = IIf(maxX > 639, 639, maxX)
- maxY = IIf(maxY > 479, 479, maxY)
- ' Draw distorted face
- For y As Integer = minY To maxY
- For x As Integer = minX To maxX
- ' Simple point-in-quad via winding number or barycentric test
- ' We cheat here for demo: just draw inside bbox with distortion
- Dim col as long = Point(x, y)
- Dim r as ubyte = (col Shr 16 And 255) + 30 : If r > 255 Then r = 255
- Dim g as ubyte = (col Shr 8 And 255) + 30 : If g > 255 Then g = 255
- Dim b as ubyte = (col And 255) + 30 : If b > 255 Then b = 255
- PSet (x, y), RGB(r, g, b)
- Next
- Next
- Next
- ScreenUnLock
- angle += 0.01
- Sleep 16
- Loop Until InKey = Chr(27)
- ImageDestroy bg
Advertisement
Add Comment
Please, Sign In to add comment