Framework BRL.D3D7Max2D
Type vector
Field x:Float
Field y:Float
Field z:Float
Field xp:Float
Field yp:Float
End Type
Type Triangle
Field p1:Long
Field p2:Long
Field p3:Long
Field dotProduct:Float
End Type
Global P:vector[9] 'We need eight vectors and 12 triangles, but adding
Global T:Triangle[13] 'But I'm adding one more so we can index them them
'from 1, instead of 0... Just to ease readibility.
For loop = 0 To 12
If loop< 9
P[loop] = New vector
End If
T[loop] = New Triangle
Next
Const CULL_BACK_FACES = True
Const PERSPECTIVE_MODE = True
Global Offset:Float = 300
Global turnRate:Float = 1
Global pointOfView:Float
Init(200)
Graphics 800,600
Repeat
Cls
If KeyDown(KEY_LEFT)
RotateCubeZ(-turnRate)
End If
If KeyDown(KEY_RIGHT)
RotateCubeZ(turnRate)
End If
If KeyDown(KEY_UP)
RotateCubeX(-turnRate)
End If
If KeyDown(KEY_DOWN)
RotateCubeX(turnRate)
End If
If KeyDown(KEY_S)
RotateCubeY(-turnRate)
End If
If KeyDown(KEY_A)
RotateCubeY(turnRate)
End If
If CULL_BACK_FACES = True
CullBackFaces()
End If
If PERSPECTIVE_MODE = True
CalculatevectorProjections()
End If
DrawCube()
Flip(1)
Until KeyDown(KEY_ESCAPE)
Function CullBackFaces()
Local loop:Int
For loop = 1 To 12
CalculateCrossProduct(loop)
T[loop].dotProduct = CalculateDotProduct()
Next
End Function
Function CalculatevectorProjections()
Local loop:Int
For loop = 1 To 8
P[loop].xp = P[loop].X * pointOfView / (pointOfView + P[loop].Z) + Offset
P[loop].yp = P[loop].Y * pointOfView / (pointOfView + P[loop].Z) + Offset
Next
End Function
Function CalculateCrossProduct(triangleIndex:Long)
Local x1:Float, y1:Float, z1:Float, x2:Float, y2:Float, z2:Float
x1 = P[T[triangleIndex].p2].X - P[T[triangleIndex].p1].X
y1 = P[T[triangleIndex].p2].Y - P[T[triangleIndex].p1].Y
z1 = P[T[triangleIndex].p2].Z - P[T[triangleIndex].p1].Z
x2 = P[T[triangleIndex].p3].X - P[T[triangleIndex].p1].X
y2 = P[T[triangleIndex].p3].Y - P[T[triangleIndex].p1].Y
z2 = P[T[triangleIndex].p3].Z - P[T[triangleIndex].p1].Z
P[0].X = y1 * z2 - y2 * z1
P[0].Y = x2 * z1 - x1 * z2
P[0].Z = x1 * y2 - x2 * y1
End Function
Function CalculateDotProduct:Float()
Return(0 * P(0).X + 0 * P(0).Y + (pointOfView * P(0).Z))
End Function
Function RotateCubeX(angle:Float)
Local NewY:Float, NewZ:Float,loop:Int
For loop = 1 To 8
NewY = P[loop].Y * Cos(angle) - P[loop].Z * Sin(angle)
NewZ = P[loop].Y * Sin(angle) + P[loop].Z * Cos(angle)
P[loop].Y = NewY
P[loop].Z = NewZ
Next
End Function
Function RotateCubeZ(angle:Float)
Local newX:Float,newY:Float,loop:Int
For loop = 1 To 8
NewX = P[loop].X * Cos(angle) - P[loop].Y * Sin(angle)
NewY = P[loop].X * Sin(angle) + P[loop].Y * Cos(angle)
P[loop].X = NewX
P[loop].Y = NewY
Next
End Function
Function RotateCubeY(angle:Float)
Local loop:Int,NewX:Float, NewZ:Float
For loop = 1 To 8
NewX = P[loop].Z * Sin(angle) + P[loop].X * Cos(angle)
NewZ = P[loop].Z * Cos(angle) - P[loop].X * Sin(angle)
P[loop].X = NewX
P[loop].Z = NewZ
Next
End Function
Function DrawCube()
Local loop:Int, draw:Byte
If CULL_BACK_FACES = True Then draw = True
For loop = 1 To 12
If (draw = True And T[loop].dotProduct > 0.5) Or draw = False
DrawColouredLine(T(loop).p1,T(loop).p2)
DrawColouredLine(T(loop).p2,T(loop).p3)
DrawColouredLine(T(loop).p3,T(loop).p1)
End If
Next
End Function
Function Init(size:Float)
If CULL_BACK_FACES = False
pointOfView = 1000
Else
pointOfView = 5000
End If
P[1].x = -size; P[1].y = -size; P[1].z = -size
P[2].x = -size; P[2].y = size; P[2].z = -size
P[3].x = size; P[3].y = size; P[3].z = -size
P[4].x = size; P[4].y = -size; P[4].z = -size
P[5].x = -size; P[5].y = -size; P[5].z = size
P[6].x = -size; P[6].y = size; P[6].z = size
P[7].x = size; P[7].y = size; P[7].z = size
P[8].x = size; P[8].y = -size; P[8].z = size
T[1].p1 = 1; T[1].p2 = 4; T[1].p3 = 3
T[2].p1 = 1; T[2].p2 = 3; T[2].p3 = 2
T[3].p1 = 5; T[3].p2 = 1; T[3].p3 = 2
T[4].p1 = 5; T[4].p2 = 2; T[4].p3 = 6
T[5].p1 = 8; T[5].p2 = 5; T[5].p3 = 6
T[6].p1 = 8; T[6].p2 = 6; T[6].p3 = 7
T[7].p1 = 4; T[7].p2 = 8; T[7].p3 = 7
T[8].p1 = 4; T[8].p2 = 7; T[8].p3 = 3
T[9].p1 = 3; T[9].p2 = 7; T[9].p3 = 6
T[10].p1 = 3; T[10].p2 = 6; T[10].p3 = 2
T[11].p1 = 4; T[11].p2 = 1; T[11].p3 = 5
T[12].p1 = 4; T[12].p2 = 5; T[12].p3 = 8
End Function
Function DrawColouredLine(p1:Long,p2:Long,r:Byte =255,g:Byte = 255,b:Byte = 255)
Local x1:Float, y1:Float,x2:Float,y2:Float
If PERSPECTIVE_MODE = True
x1 = P[p1].X * pointOfView / (pointOfView + P[p1].Z) + Offset
y1 = P[p1].Y * pointOfView / (pointOfView + P[p1].Z) + Offset
x2 = P[p2].X * pointOfView / (pointOfView + P[p2].Z) + Offset
y2 = P[p2].Y * pointOfView / (pointOfView + P[p2].Z) + Offset
Else
x1 = P(p1).x + offset
y1 = P(p1).y + offset
x2 = P(p2).x + offset
y2 = P(p2).y + offset
End If
SetColor r,g,b
DrawLine x1,y1,x2,y2
SetColor 255,255,255
End Function
Little thing I made, draws a 3D cube in 2D and can be rotated etc etc Learnt a lot doing it, but could never get backface culling to work properly, when you rotate it you wil notice the clipping... Anyway, someone may find it interesting.
Dabz