Using TheOneLoneCoder's 'Code-It-Yourself! 3D Graphics Engine Part #1' video as a reference, I ported some of his code to create the first step in this engine, perspective.

This commit is contained in:
2020-07-13 14:04:41 -05:00
parent 6f25f9e0d8
commit 5f83619244
2 changed files with 129 additions and 2 deletions
+127 -2
View File
@@ -1,8 +1,133 @@
import window
import math
import copy
ui = window.Window(600, 600)
near_plane = 0.1
far_plane = 1000.0
fov = 90.0
tris = [
# SOUTH
[ [0.0, 0.0, 0.0], [0.0, 1.0, 0.0], [1.0, 1.0, 0.0] ],
[ [0.0, 0.0, 0.0], [1.0, 1.0, 0.0], [1.0, 0.0, 0.0 ]],
# EAST
[ [1.0, 0.0, 0.0], [1.0, 1.0, 0.0], [1.0, 1.0, 1.0 ]],
[ [1.0, 0.0, 0.0], [1.0, 1.0, 1.0], [1.0, 0.0, 1.0 ]],
# NORTH
[ [1.0, 0.0, 1.0], [1.0, 1.0, 1.0], [0.0, 1.0, 1.0 ]],
[ [1.0, 0.0, 1.0], [0.0, 1.0, 1.0], [0.0, 0.0, 1.0 ]],
# WEST
[[ 0.0, 0.0, 1.0], [0.0, 1.0, 1.0], [0.0, 1.0, 0.0 ]],
[ [0.0, 0.0, 1.0], [0.0, 1.0, 0.0], [0.0, 0.0, 0.0 ]],
# TOP
[[ 0.0, 1.0, 0.0], [0.0, 1.0, 1.0], [1.0, 1.0, 1.0 ]],
[[ 0.0, 1.0, 0.0], [1.0, 1.0, 1.0], [1.0, 1.0, 0.0 ]],
# BOTTOM
[[ 1.0, 0.0, 1.0], [0.0, 0.0, 1.0], [0.0, 0.0, 0.0 ]],
[[ 1.0, 0.0, 1.0], [0.0, 0.0, 0.0], [1.0, 0.0, 0.0 ]]
]
def matric_mul(d_vector, transform_mat):
out_matrix = []
out_matrix.append(d_vector[0] * transform_mat[0][0] + d_vector[1] * transform_mat[1][0] + d_vector[2] * transform_mat[2][0] + transform_mat[3][0]) # x
out_matrix.append(d_vector[0] * transform_mat[0][1] + d_vector[1] * transform_mat[1][1] + d_vector[2] * transform_mat[2][1] + transform_mat[3][1]) # y
out_matrix.append(d_vector[0] * transform_mat[0][2] + d_vector[1] * transform_mat[1][2] + d_vector[2] * transform_mat[2][2] + transform_mat[3][2]) # z
# 4th row
w = d_vector[0] * transform_mat[0][3] + d_vector[1] * transform_mat[1][3] + d_vector[2] * transform_mat[2][3] + transform_mat[3][3]
if w != 0:
out_matrix[0] /= w
out_matrix[1] /= w
out_matrix[2] /= w
return out_matrix
def make_matrix(row1, row2, row3, row4):
mat = []
mat.append([])
mat[0].append([row1[0], row1[1], row1[2], row1[3]])
mat.append([])
mat[1].append([row2[0], row2[1], row2[2], row2[3]])
mat.append([])
mat[2].append([row3[0], row3[1], row3[2], row3[3]])
mat.append([])
mat[3].append([row4[0], row4[1], row4[2], row4[3]])
return mat
def main():
ui = window.Window(600, 600)
ui.window.after(0, draw_scene)
ui.show()
def draw_scene():
ui.canvas.delete("all")
ui.theta += .01
projection_matrix = []
rotation_matrix_z = []
rotation_matrix_x = []
aspect_ratio = ui.height / ui.width
fov_rad = ui.theta / math.tan(fov * 0.5 / 180.0 * math.pi)
projection_matrix.append([aspect_ratio * fov_rad, 0, 0, 0])
projection_matrix.append([0, fov_rad, 0, 0])
projection_matrix.append([0, 0, far_plane / (far_plane - near_plane), 1.0])
projection_matrix.append([0, 0, -far_plane * near_plane / (far_plane - near_plane), 0])
rotation_matrix_z.append([math.cos(ui.theta), math.sin(ui.theta), 0, 0])
rotation_matrix_z.append([-math.sin(ui.theta), math.cos(ui.theta), 0, 0])
rotation_matrix_z.append([0, 0, 1, 0])
rotation_matrix_z.append([0, 0, 0, 1])
#--------------------------------------------
rotation_matrix_x.append([1, 0, 0, 0])
rotation_matrix_x.append([0, math.cos(ui.theta * 0.5), math.sin(ui.theta * 0.5), 0])
rotation_matrix_x.append([0, -math.sin(ui.theta * 0.5), math.cos(ui.theta * 0.5), 0])
rotation_matrix_x.append([0, 0, 0, 1])
for tri in tris:
rotated_z = []
rotated_z.append(matric_mul(tri[0], rotation_matrix_z))
rotated_z.append(matric_mul(tri[1], rotation_matrix_z))
rotated_z.append(matric_mul(tri[2], rotation_matrix_z))
rotated_x = []
rotated_x.append(matric_mul(rotated_z[0], rotation_matrix_x))
rotated_x.append(matric_mul(rotated_z[1], rotation_matrix_x))
rotated_x.append(matric_mul(rotated_z[2], rotation_matrix_x))
translated = copy.copy(rotated_x)
translated[0][2] = rotated_x[0][2] + 3.0
translated[1][2] = rotated_x[1][2] + 3.0
translated[2][2] = rotated_x[2][2] + 3.0
projected = []
projected.append(matric_mul(translated[0], projection_matrix))
projected.append(matric_mul(translated[1], projection_matrix))
projected.append(matric_mul(translated[2], projection_matrix))
projected[0][0] += 1
projected[0][1] += 1
projected[1][0] += 1
projected[1][1] += 1
projected[2][0] += 1
projected[2][1] += 1
projected[0][0] *= .5 * ui.width
projected[0][1] *= .5 * ui.height
projected[1][0] *= .5 * ui.width
projected[1][1] *= .5 * ui.height
projected[2][0] *= .5 * ui.width
projected[2][1] *= .5 * ui.height
coords = [projected[0][0], projected[0][1], projected[1][0], projected[1][1], projected[2][0], projected[2][1]]
ui.canvas.create_polygon(coords, fill="", outline="black")
ui.canvas.update()
ui.canvas.after(100, draw_scene)
main()
+2
View File
@@ -8,6 +8,8 @@ class Window:
self.canvas.pack()
self.width = width
self.height = height
self.theta = 1
self.triangles = []
def show(self):
self.window.mainloop()