Last active
February 21, 2021 14:29
-
-
Save flysand7/32eaeff906b435104f3e41495ac76e28 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import pygame; | |
import math; | |
pygame.init(); | |
pygame.display.init(); | |
pygame.display.set_mode(size=(600,400)); | |
to_render = [ | |
# bottom edge | |
[(0,0,0), (0,0,1), (1,0,0)], | |
[(1,0,1), (1,0,0), (0,0,1)], | |
# left edge | |
[(0,0,0), (0,1,0), (0,0,1)], | |
[(0,1,1), (0,0,1), (0,1,0)], | |
#right edge | |
[(1,0,0), (1,0,1), (1,1,0)], | |
[(1,1,1), (1,1,0), (1,0,1)], | |
# front edge | |
[(0,0,0), (1,0,0), (0,1,0)], | |
[(1,1,0), (0,1,0), (1,0,0)], | |
# back edge | |
[(0,0,1), (0,1,1), (1,0,1)], | |
[(1,1,1), (1,0,1), (0,1,1)], | |
#top edge | |
[(0,1,0), (1,1,0), (0,1,1)], | |
[(1,1,1), (0,1,1), (1,1,0)], | |
]; | |
def v_length(v): | |
return math.sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); | |
def normalize(v): | |
l = v_length(v); | |
if(l == 0): | |
return [0, 0, 0]; | |
return [ | |
v[0]/l, | |
v[1]/l, | |
v[2]/l | |
]; | |
def dot(a,b): | |
return a[0]*b[0] + a[1]*b[1] + a[2]*b[2]; | |
def cross(a,b): | |
return [ | |
a[1]*b[2] - a[2]*b[1], | |
a[0]*b[2] - a[2]*b[0], | |
a[0]*b[1] - a[1]*b[0] | |
]; | |
def sub(a,b): | |
return [ | |
a[0] - b[0], | |
a[1] - b[1], | |
a[2] - b[2], | |
]; | |
normal = [0, 0, -1]; | |
normal = normalize(normal); | |
def draw_triangle(color, p1, p2, p3): | |
# "shader" | |
trig_normal = normalize(cross(sub(p2, p1), sub(p3, p1))); | |
diff = dot(normal, trig_normal); | |
if(diff < 0): | |
diff = 0; | |
diff = math.pow(diff, .2); | |
new_color = color; | |
new_color.r = int(diff * 255.0); | |
new_color.g = int(diff * 255.0); | |
new_color.b = int(diff * 255.0); | |
new_color.a = int(diff * 255.0); | |
# screen coords | |
ws = pygame.display.get_window_size(); | |
ww = ws[0]; | |
wh = ws[1]; | |
fp1 = (ww*(p1[0] + 0.5), wh - wh*(p1[1] + 0.5)); | |
fp2 = (ww*(p2[0] + 0.5), wh - wh*(p2[1] + 0.5)); | |
fp3 = (ww*(p3[0] + 0.5), wh - wh*(p3[1] + 0.5)); | |
# rendering /without depth buffer/ | |
pygame.draw.lines(pygame.display.get_surface(), new_color, True, (fp1, fp2, fp3)); | |
def scale_point(point, by): | |
result = [0,0,0]; | |
result[0] = point[0] * by[0]; | |
result[1] = point[1] * by[1]; | |
result[2] = point[2] * by[2]; | |
return result; | |
def rotate_point_y(point, angle): | |
result = [0,0,0]; | |
s = math.sin(angle); | |
c = math.cos(angle); | |
result[0] = +point[0]*c +point[2]*s; | |
result[1] = +point[1]; | |
result[2] = -point[0]*s +point[2]*c; | |
return result; | |
def offset_point(point, by): | |
result = [0,0,0]; | |
result[0] = point[0] + by[0]; | |
result[1] = point[1] + by[1]; | |
result[2] = point[2] + by[2]; | |
return result; | |
def ortho(point): | |
ws = pygame.display.get_window_size(); | |
result = [0,0,0]; | |
result[0] = (point[0] / ws[0]) - 0.5; | |
result[1] = (point[1] / ws[1]) - 0.5; | |
result[2] = point[2]; | |
return result; | |
n = 0.1; | |
f = 1000; | |
fov = math.radians(90); | |
def persp(point): | |
ws = pygame.display.get_window_size(); | |
ar= ws[1] / ws[0]; | |
ox = point[2]*math.tan(fov/2); | |
oy = ox*ar; | |
result = [0,0,0]; | |
result[0] = (point[0] - ws[0]*0.5) / ox; | |
result[1] = (point[1] - ws[1]*0.5) / oy; | |
result[2] = (point[2] - n) / (f-n); | |
return result; | |
t = 0; | |
def render_cube(color, position, size, list): | |
for triangle in list: | |
transformed = [[0,0,0],[0,0,0],[0,0,0]]; | |
for i in range(0, len(transformed)): | |
transformed[i] = triangle[i]; | |
# model | |
transformed[i] = offset_point(transformed[i], (-0.5, -0.5, -0.5)); | |
transformed[i] = scale_point(transformed[i], (0.5, 0.5, -0.5)); | |
# world | |
transformed[i] = rotate_point_y(transformed[i], t); | |
transformed[i] = scale_point(transformed[i], size); | |
transformed[i] = offset_point(transformed[i], position); | |
# projection | |
transformed[i] = persp(transformed[i]); | |
#transformed[i] = ortho(transformed[i]); | |
### | |
draw_triangle(color, transformed[0], transformed[1], transformed[2]); | |
left=False; | |
right=False; | |
while True: | |
pygame.display.get_surface().fill((0,0,0)); | |
render_cube(pygame.Color(255, 255, 255, 255), (300, 200, 20), (10, 10, 10), to_render); | |
#render_cube(pygame.Color(255, 255, 255, 255), (300, 200, 10), (600, 400, 300), to_render); | |
pygame.display.flip(); | |
exit=False; | |
while(True): | |
e = pygame.event.poll(); | |
if(e.type == pygame.NOEVENT): | |
break; | |
elif(e.type == pygame.QUIT): | |
exit=True; | |
elif(e.type == pygame.KEYDOWN): | |
if(e.unicode == 'a'): | |
left = True; | |
elif(e.unicode == 'd'): | |
right = True; | |
elif(e.type == pygame.KEYUP): | |
if(e.unicode == 'a'): | |
left = False; | |
elif(e.unicode == 'd'): | |
right = False; | |
if(exit): | |
break; | |
if(left): | |
t -= 0.0007; | |
elif(right): | |
t += 0.0007; | |
pygame.quit(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment