Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import glfw
- from OpenGL.GL import *
- from OpenGL.GLU import *
- import math
- import json
- import PIL.Image
- im = "texture.bmp"
- def background():
- glClearColor(0.8, 0.8, 0.8, 1.0)
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
- glEnable(GL_DEPTH_TEST)
- def mouseCallback(window, button, action, mods):
- size = 3
- if button == glfw.MOUSE_BUTTON_1 and action and torus.isWire:
- torus.isWire = False
- elif button == glfw.MOUSE_BUTTON_1 and action and not torus.isWire:
- torus.isWire = True
- elif button == glfw.MOUSE_BUTTON_2 and action:
- torus.counter += 1
- print(torus.counter, size)
- torus.currentGL_Pname = torus.GL_Pnames[torus.counter % size]
- print("NOW GLpname is", torus.currentGL_Pname)
- def keyCallback(window, key, scancode, action, mods):
- if key == glfw.KEY_SPACE and action:
- torus.save()
- elif key == glfw.KEY_INSERT and action:
- torus.isOpened = True
- torus.open()
- elif key == glfw.KEY_W and action:
- torus.center[1] += 0.1
- elif key == glfw.KEY_A and action:
- torus.center[0] -= 0.1
- elif key == glfw.KEY_D and action:
- torus.center[0] += 0.1
- elif key == glfw.KEY_S and action:
- torus.center[1] -= 0.1
- elif key == glfw.KEY_UP and action:
- torus.rotate_x += 10.0
- elif key == glfw.KEY_DOWN and action:
- torus.rotate_x -= 10.0
- elif key == glfw.KEY_LEFT and action:
- torus.rotate_y += 10.0
- elif key == glfw.KEY_RIGHT and action:
- torus.rotate_y -= 10.0
- elif key == glfw.KEY_KP_SUBTRACT and action and torus.nsides > 3:
- torus.nsides -= 1
- torus.rings -= 1
- torus.polygonMesh = []
- torus.setMesh()
- elif key == glfw.KEY_KP_ADD and action:
- torus.nsides += 1
- torus.rings += 1
- torus.polygonMesh = []
- torus.setMesh()
- elif key == glfw.KEY_ENTER and action:
- torus.h0 = torus.center
- if not torus.isOpened:
- torus.v0 = [0.2, 0.2, 0.2]
- torus.t = 0
- torus.isOpened = False
- torus.drop = True
- elif key == glfw.KEY_PAUSE and action:
- torus.drop = False
- elif key == glfw.KEY_DELETE and action:
- torus.clear()
- elif key == glfw.KEY_T and action:
- if torus.isTextured:
- torus.isTextured = False
- else:
- torus.isTextured = True
- elif key == glfw.KEY_1 and action:
- if torus.currentGL_Pname == GL_LIGHT_MODEL_AMBIENT:
- if torus.GL_Pnames_dict.get(torus.currentGL_Pname)[0] > -3:
- value = torus.GL_Pnames_dict.get(torus.currentGL_Pname)
- for i in range(3):
- value[i] -= 0.1
- torus.GL_Pnames_dict.update({torus.currentGL_Pname: value})
- else:
- value = torus.GL_Pnames_dict.get(torus.currentGL_Pname)
- value = not value
- torus.GL_Pnames_dict.update({torus.currentGL_Pname: value})
- print(torus.GL_Pnames_dict)
- elif key == glfw.KEY_2 and action:
- if torus.currentGL_Pname == GL_LIGHT_MODEL_AMBIENT:
- if torus.GL_Pnames_dict.get(torus.currentGL_Pname)[0] < 4:
- value = torus.GL_Pnames_dict.get(torus.currentGL_Pname)
- for i in range(3):
- value[i] += 0.1
- torus.GL_Pnames_dict.update({torus.currentGL_Pname: value})
- else:
- value = torus.GL_Pnames_dict.get(torus.currentGL_Pname)
- value = not value
- torus.GL_Pnames_dict.update({torus.currentGL_Pname: value})
- print(torus.GL_Pnames_dict)
- class Torus:
- def __init__(self):
- self.isTextured = False
- self.polygonMesh = []
- self.normals = []
- self.center = [0, 0, 0]
- self.nsides = 3
- self.rings = 3
- self.r = 0.2
- self.R = 0.4
- self.rotate_x = 0
- self.rotate_y = 0
- self.isWire = False
- self.setMesh()
- self.GL_Pnames_dict = {GL_LIGHT_MODEL_AMBIENT: [0.2, 0.2, 0.2, 1.0], GL_LIGHT_MODEL_LOCAL_VIEWER: GL_FALSE,
- GL_LIGHT_MODEL_TWO_SIDE: GL_TRUE}
- self.GL_Pnames = (GL_LIGHT_MODEL_AMBIENT, GL_LIGHT_MODEL_LOCAL_VIEWER, GL_LIGHT_MODEL_TWO_SIDE)
- self.currentGL_Pname = GL_LIGHT_MODEL_AMBIENT
- self.drop = False
- self.counter = 0
- self.v0 = [0.2, 0.2, 0.2]
- self.h0 = [0, 0, 0]
- self.t = 0
- self.isOpened = False
- def setMesh(self):
- for i in range(self.rings):
- theta = i * 2.0 * math.pi / self.rings
- theta1 = ((i + 1) % self.rings) * 2.0 * math.pi / self.rings
- for j in range(self.nsides):
- phi = j * 2.0 * math.pi / self.nsides
- phi1 = ((j + 1) % self.nsides) * 2.0 * math.pi / self.nsides
- p0 = [math.cos(theta) * (self.R + self.r * math.cos(phi)),
- - math.sin(theta) * (self.R + self.r * math.cos(phi)),
- self.r * math.sin(phi)]
- p1 = [math.cos(theta1) * (self.R + self.r * math.cos(phi)),
- - math.sin(theta1) * (self.R + self.r * math.cos(phi)),
- self.r * math.sin(phi)]
- p2 = [math.cos(theta1) * (self.R + self.r * math.cos(phi1)),
- - math.sin(theta1) * (self.R + self.r * math.cos(phi1)),
- self.r * math.sin(phi1)]
- p3 = [math.cos(theta) * (self.R + self.r * math.cos(phi1)),
- - math.sin(theta) * (self.R + self.r * math.cos(phi1)),
- self.r * math.sin(phi1)]
- p = [p0, p1, p2, p3]
- n0 = [math.cos(theta) * (math.cos(phi)), -math.sin(theta) * (math.cos(phi)), math.sin(phi)]
- n1 = [math.cos(theta1) * (math.cos(phi)), -math.sin(theta1) * (math.cos(phi)), math.sin(phi)]
- n2 = [math.cos(theta1) * (math.cos(phi1)), -math.sin(theta1) * (math.cos(phi1)), math.sin(phi1)]
- n3 = [math.cos(theta) * (math.cos(phi1)), -math.sin(theta) * (math.cos(phi1)), math.sin(phi1)]
- n = [n0, n1, n2, n3]
- self.polygonMesh.append(p)
- self.normals.append(n)
- def clear(self):
- self.polygonMesh = []
- self.normals = []
- self.center = [0, 0, 0]
- self.nsides = 4
- self.rings = 4
- self.r = 0.2
- self.R = 0.4
- self.rotate_x = 0
- self.rotate_y = 0
- self.isWire = False
- self.setMesh()
- self.GL_Pnames_dict = {GL_LIGHT_MODEL_AMBIENT: [0.2, 0.2, 0.2, 1.0], GL_LIGHT_MODEL_LOCAL_VIEWER: GL_FALSE,
- GL_LIGHT_MODEL_TWO_SIDE: GL_TRUE}
- self.GL_Pnames = (GL_LIGHT_MODEL_AMBIENT, GL_LIGHT_MODEL_LOCAL_VIEWER, GL_LIGHT_MODEL_TWO_SIDE)
- self.currentGL_Pname = GL_LIGHT_MODEL_AMBIENT
- self.drop = False
- self.counter = 0
- self.v0 = [0.2, 0.2, 0.2]
- self.h0 = [0, 0, 0]
- self.t = 0
- self.isOpened = False
- def save(self):
- print("SAVING")
- jsonFile = {'polygonMesh': self.polygonMesh, 'normals': self.normals, 'center': self.center,
- 'nsides': self.nsides, 'rings': self.rings, 'r': self.r, 'R': self.R, 'rotate_x': self.rotate_x,
- 'rotate_y': self.rotate_y, 'isWire': self.isWire, 'GL_Pnames_dict': self.GL_Pnames_dict,
- 'GL_Pnames': self.GL_Pnames, 'currentGL_Pname': self.currentGL_Pname, 'drop': self.drop,
- 'counter': self.counter, 'v0': self.v0, 'h0': self.h0, 't': self.t, 'isOpened': self.isOpened, 'isTextured': self.isTextured}
- file = open("scene.txt", "w")
- file.write(json.dumps(jsonFile))
- file.close()
- def open(self):
- print("OPENING")
- file = open("scene.txt")
- jsonf = json.loads(file.read())
- self.polygonMesh = jsonf['polygonMesh']
- self.normals = jsonf['normals']
- self.center = jsonf['center']
- self.nsides = jsonf['nsides']
- self.rings = jsonf['rings']
- self.r = jsonf['r']
- self.R = jsonf['R']
- self.rotate_x = jsonf['rotate_x']
- self.rotate_y = jsonf['rotate_y']
- self.isWire = jsonf['isWire']
- self.GL_Pnames_dict = jsonf['GL_Pnames_dict']
- dict = {}
- for i in range(3):
- b = self.GL_Pnames_dict.popitem()
- a = [b[0], b[1]]
- if a[0] == '2898':
- a[0] = GL_LIGHT_MODEL_TWO_SIDE
- elif a[0] == '2897':
- a[0] = GL_LIGHT_MODEL_LOCAL_VIEWER
- else:
- a[0] = GL_LIGHT_MODEL_AMBIENT
- dict.update({a[0]: a[1]})
- self.GL_Pnames_dict = dict
- self.GL_Pnames = jsonf['GL_Pnames']
- for i in range(3):
- if self.GL_Pnames[i] == '2898':
- self.GL_Pnames[i] = GL_LIGHT_MODEL_TWO_SIDE
- elif self.GL_Pnames[i] == '2897':
- self.GL_Pnames[i] = GL_LIGHT_MODEL_LOCAL_VIEWER
- else:
- self.GL_Pnames[i] = GL_LIGHT_MODEL_AMBIENT
- self.currentGL_Pname = jsonf['currentGL_Pname']
- if self.currentGL_Pname == '2898':
- self.currentGL_Pname = GL_LIGHT_MODEL_TWO_SIDE
- elif self.currentGL_Pname == '2897':
- self.currentGL_Pname = GL_LIGHT_MODEL_LOCAL_VIEWER
- else:
- self.currentGL_Pname = GL_LIGHT_MODEL_AMBIENT
- self.drop = jsonf['drop']
- self.counter = jsonf['counter']
- self.v0 = jsonf['v0']
- self.h0 = jsonf['h0']
- self.t = jsonf['t']
- self.isOpened = jsonf['isOpened']
- self.isTextured = jsonf['isTextured']
- file.close()
- def drawTorus():
- glPointSize(1)
- glLineWidth(2)
- if torus.isWire:
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
- else:
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)
- glMatrixMode(GL_PROJECTION)
- glLoadIdentity()
- theta = math.asin(0.5 / math.sqrt(2))
- phi = math.asin(0.5 / math.sqrt(2 - 0.25))
- a = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1]
- b = [1, 0, 0, 0, 0, math.cos(theta), math.sin(theta), 0, 0, -math.sin(theta), math.cos(theta), 0, 0, 0, 0, 1]
- c = [math.cos(phi), 0, -math.sin(phi), 0, 0, 1, 0, 0, math.sin(phi), 0, math.cos(phi), 0, 0, 0, 0, 1]
- glMultMatrixf(a)
- glMultMatrixf(b)
- glMultMatrixf(c)
- glMatrixMode(GL_MODELVIEW)
- glLoadIdentity()
- glRotatef(torus.rotate_x, 1, 0, 0)
- glRotatef(torus.rotate_y, 0, 1, 0)
- glTranslatef(torus.center[0], torus.center[1], torus.center[2])
- count = torus.rings * torus.nsides
- global texture
- glBindTexture(GL_TEXTURE_2D, texture)
- k = 1
- for i in range(count):
- glEnable(GL_NORMALIZE)
- glBegin(GL_POLYGON)
- n = torus.rings
- if i % n == 0 and i != 0:
- k -= 1 / n
- if k > 1 or k < 0:
- print("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")
- #glTexCoord2f(1.0, 1.0)
- #glTexCoord2f((i % n + 1) / n, (i % n + 1) / n)
- #glColor3f(1.0, 0.0, 0.0)
- glTexCoord2f(k, (i % n + 1) / n)
- #print(k, (i % n + 1) / n)
- glVertex3fv(torus.polygonMesh[i][3])
- #print(torus.polygonMesh[i][3])
- #glTexCoord2f(1.0, 0.0)
- #glTexCoord2f((i % n) / n, (i % n + 1) / n)
- #glColor3f(0.0, 1.0, 0.0)
- glTexCoord2f(k - 1/n, (i % n + 1) / n)
- #print(k - 1/n, (i % n + 1) / n)
- glVertex3fv(torus.polygonMesh[i][2])
- #print(torus.polygonMesh[i][2])
- #glTexCoord2f(1.0, 1.0)
- #glTexCoord2f((i % n) / n, (i % n) / n)
- #glColor3f(0.0, 0.0, 1.0)
- glTexCoord2f(k -1/n, (i % n) / n)
- #print(k -1/n, (i % n) / n)
- glVertex3fv(torus.polygonMesh[i][1])
- #print(torus.polygonMesh[i][1])
- #glTexCoord2f(0.0, 1.0)
- #glTexCoord2f((i % n + 1) / n, (i % n) / n)
- #glColor3f(1.0, 1.0, 1.0)
- glTexCoord2f(k, (i % n) / n)
- #print(k, (i % n) / n)
- glVertex3fv(torus.polygonMesh[i][0])
- #print(torus.polygonMesh[i][0])
- #print('==================', i % n)
- glEnd()
- def makeLighting():
- glEnable(GL_LIGHTING)
- glEnable(GL_LIGHT0)
- glLightfv(GL_LIGHT0, GL_AMBIENT | GL_DIFFUSE | GL_SPECULAR, (0.5, 0.5, 0.5, 1))
- glLightModelfv(GL_LIGHT_MODEL_AMBIENT, torus.GL_Pnames_dict.get(GL_LIGHT_MODEL_AMBIENT))
- glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, torus.GL_Pnames_dict.get(GL_LIGHT_MODEL_LOCAL_VIEWER))
- glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, torus.GL_Pnames_dict.get(GL_LIGHT_MODEL_TWO_SIDE))
- # glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, [0.2, 0.2, 0.2, 1]) ###рассеянный свет
- # glMaterialfv(GL_FRONT, GL_SPECULAR, [0.7, 0.7, 0.7, 1]) ###отражаемый свет
- # glMaterialfv(GL_FRONT, GL_EMISSION, [0.5, 0.5, 0.5, 1]) ###излучаемый свет
- # glMaterialfv(GL_FRONT, GL_SHININESS, 1) # степень блеска
- def h(time):
- x = torus.h0[0] + torus.v0[0] * time
- y = torus.h0[1] + torus.v0[1] * time - 9.8 * time * time / 2
- z = torus.h0[2] + torus.v0[2] * time
- if x + torus.R >= 1 or x - torus.R <= -1:
- torus.v0 = v(time)
- torus.v0 = [-torus.v0[0], torus.v0[1], torus.v0[2]]
- torus.t = 0
- if x + torus.R >= 1:
- torus.h0 = [1 - torus.R, torus.center[1], torus.center[2]]
- return torus.h0
- elif x - torus.R <= -1:
- torus.h0 = [-1 + torus.R, torus.center[1], torus.center[2]]
- return torus.h0
- elif y + torus.R >= 1 or y - torus.R <= -1:
- torus.v0 = v(time)
- torus.v0 = [torus.v0[0], -torus.v0[1], torus.v0[2]]
- torus.t = 0
- if y + torus.R >= 1:
- torus.h0 = [torus.center[0], 1 - torus.R, torus.center[2]]
- return torus.h0
- elif y - torus.R <= -1:
- torus.h0 = [torus.center[0], -1 + torus.R, torus.center[2]]
- return torus.h0
- elif z + torus.R >= 1 or z - torus.R <= -1:
- torus.v0 = v(time)
- torus.v0 = [torus.v0[0], torus.v0[1], -torus.v0[2]]
- torus.t = 0
- if z + torus.R >= 1:
- torus.h0 = [torus.center[0], torus.center[1], 1 - torus.R]
- return torus.h0
- elif z - torus.R <= -1:
- torus.h0 = [torus.center[0], torus.center[1], -1 + torus.R]
- return torus.h0
- else:
- return [x, y, z]
- def v(time):
- vector = [0, 0, 0]
- vector[0] = torus.v0[0]
- vector[1] = torus.v0[1] - 9.8 * time
- vector[2] = torus.v0[2]
- return vector
- def drop(t):
- if 0.6 in [abs(i) for i in h(t + 1 / 60)]:
- print("impact, torus.center =", torus.center)
- return torus.center
- else:
- point = h(t)
- print("point", point)
- return point
- def draw():
- drawTorus()
- makeLighting()
- if torus.drop:
- torus.t += 1 / 60
- # print(t)
- center = drop(torus.t)
- # print("center", center)
- print("v0", torus.v0)
- torus.center = center
- if torus.isTextured:
- init()
- else:
- glDisable(GL_TEXTURE_2D)
- class Drawer:
- window = False
- def __init__(self):
- if not glfw.init():
- return
- self.window = glfw.create_window(800, 800, "Lab3", None, None)
- if not self.window:
- glfw.terminate()
- return
- glfw.make_context_current(self.window)
- glfw.set_mouse_button_callback(self.window, mouseCallback)
- glfw.set_key_callback(self.window, keyCallback)
- global texture
- texture = loadTexture(im)
- def startLoop(self):
- while not glfw.window_should_close(self.window):
- background()
- draw()
- glfw.swap_buffers(self.window)
- glfw.poll_events()
- glfw.terminate()
- def init ():
- glClearDepth ( 1.0 )
- glDepthFunc ( GL_LEQUAL )
- glEnable ( GL_DEPTH_TEST )
- glEnable ( GL_TEXTURE_2D )
- glHint ( GL_POLYGON_SMOOTH_HINT, GL_NICEST )
- glHint ( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST )
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)
- def loadTexture(fileName):
- image = PIL.Image.open(fileName)
- width = image.size[0]
- height = image.size[1]
- image = image.tobytes("raw", "RGBA", 0, -1)
- texture = glGenTextures(1)
- glBindTexture(GL_TEXTURE_2D, texture)
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR)
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)
- gluBuild2DMipmaps(GL_TEXTURE_2D, 3, width, height, GL_RGBA, GL_UNSIGNED_BYTE, image)
- return texture
- drawer = Drawer()
- torus = Torus()
- drawer.startLoop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement