Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import glfw
- from OpenGL.GL import *
- import OpenGL.GL.shaders
- import numpy
- import math
- import pyrr
- import PIL.Image
- import ctypes
- 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 keyCallback(window, key, scancode, action, mods):
- if key == glfw.KEY_KP_SUBTRACT and action and torus.nsides > 3:
- torus.nsides -= 1
- torus.rings -= 1
- torus.remake()
- rebuildVAO()
- elif key == glfw.KEY_KP_ADD and action:
- torus.nsides += 1
- torus.rings += 1
- torus.remake()
- rebuildVAO()
- elif key == glfw.KEY_W and action:
- torus.center[1] += 0.1
- torus.translate_y(0.1)
- elif key == glfw.KEY_S and action:
- torus.center[1] -= 0.1
- torus.translate_y(-0.1)
- elif key == glfw.KEY_A and action:
- torus.center[0] -= 0.1
- torus.translate_x(-0.1)
- elif key == glfw.KEY_D and action:
- torus.center[0] += 0.1
- torus.translate_x(0.1)
- elif key == glfw.KEY_UP and action:
- torus.rotate_x(0.1)
- elif key == glfw.KEY_DOWN and action:
- torus.rotate_x(-0.1)
- elif key == glfw.KEY_LEFT and action:
- torus.rotate_y(-0.1)
- elif key == glfw.KEY_RIGHT and action:
- torus.rotate_y(0.1)
- elif key == glfw.KEY_T and action:
- if torus.isTextured:
- torus.isTextured = False
- else:
- torus.isTextured = True
- def mouseCallback(window, button, action, mods):
- 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
- def scrollCallback(window, xoffset, yoffset):
- if yoffset > 0:
- torus.scale(1.1)
- elif yoffset < 0:
- torus.scale(0.9)
- # 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)
- 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)
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image)
- glGenerateMipmap(GL_TEXTURE_2D)
- glBindTexture(GL_TEXTURE_2D, 0)
- return texture
- 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.vertexes = []
- self.texes = []
- self.indices = []
- self.array = []
- self.setMesh()
- self.matrix = pyrr.Matrix44.identity()
- 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)]
- n = [n0]
- self.polygonMesh.append(p)
- self.normals.append(n)
- count = self.rings * self.nsides
- k = 1
- for i in range(count):
- n = self.rings
- if i % n == 0 and i != 0:
- k -= 1 / n
- for j in range(4):
- for l in range(3):
- self.vertexes.append(self.polygonMesh[i][j][l])
- self.texes.append(k)
- self.texes.append((i % n) / n)
- self.texes.append(k - 1 / n)
- self.texes.append((i % n) / n)
- self.texes.append(k - 1 / n)
- self.texes.append((i % n + 1) / n)
- self.texes.append(k)
- self.texes.append((i % n + 1) / n)
- self.indices = [l for l in range(4 * count)]
- print(count * 4 * 3, len(self.vertexes))
- k = 0
- array = []
- for i in range(0, count * 4 * 3, 3):
- array.append(self.vertexes[i])
- array.append(self.vertexes[i + 1])
- array.append(self.vertexes[i + 2])
- array.append(1.0)
- array.append(1.0)
- array.append(1.0)
- array.append(self.texes[k])
- array.append(self.texes[k + 1])
- k += 2
- self.array = numpy.array(array, dtype='float32')
- self.indices = numpy.array(self.indices, dtype='uint32')
- print(array)
- def clear(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.vertexes = []
- self.texes = []
- self.indices = []
- self.array = []
- self.setMesh()
- self.matrix = pyrr.Matrix44.identity()
- def remake(self):
- torus.vertexes = []
- torus.texes = []
- torus.indices = []
- torus.array = []
- torus.polygonMesh = []
- torus.setMesh()
- def translate_y(self, n):
- a = pyrr.Matrix44([1, 0, 0, 0,
- 0, 1, 0, n,
- 0, 0, 1, 0,
- 0, 0, 0, 1], dtype='float32')
- self.matrix *= a
- #print(self.matrix)
- def translate_x(self, n):
- a = pyrr.Matrix44([1, 0, 0, n,
- 0, 1, 0, 0,
- 0, 0, 1, 0,
- 0, 0, 0, 1], dtype='float32')
- self.matrix *= a
- def rotate_x(self, n):
- a = pyrr.Matrix44.from_x_rotation(n)
- self.matrix *= a
- def rotate_y(self, n):
- a = pyrr.Matrix44.from_y_rotation(n)
- self.matrix *= a
- def scale(self, n):
- a = pyrr.Matrix44.from_scale([n, n, n, 1])
- self.matrix *= a
- def buildVAO():
- global VAO
- VAO = glGenVertexArrays(1)
- global VBO
- VBO = glGenBuffers(1)
- glBindVertexArray(VAO)
- glBindBuffer(GL_ARRAY_BUFFER, VBO)
- size = 4 * len(torus.array)
- glBufferData(GL_ARRAY_BUFFER, size, torus.array, GL_STATIC_DRAW)
- # EBO = glGenBuffers(1)
- # glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO)
- # glBufferData(GL_ELEMENT_ARRAY_BUFFER, len(torus.indices) * 4, torus.indices, GL_STATIC_DRAW)
- glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 32, ctypes.c_void_p(0))
- # 32 = 8 * sizeof(float)
- glEnableVertexAttribArray(0)
- glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 32, ctypes.c_void_p(12))
- glEnableVertexAttribArray(1)
- glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 32, ctypes.c_void_p(24))
- glEnableVertexAttribArray(2)
- # glBindBuffer(GL_ARRAY_BUFFER, 0)
- # glBindVertexArray(0)
- glUseProgram(shader)
- def rebuildVAO():
- glDeleteVertexArrays(1, VAO)
- glDeleteVertexArrays(1, VBO)
- buildVAO()
- def shader():
- vertex_shader = """
- #version 450 core
- layout (location = 0) in vec3 position;
- layout (location = 1) in vec3 color;
- layout (location = 2) in vec2 texCoord;
- uniform mat4 transform;
- out vec3 ourColor;
- out vec2 TexCoord;
- void main()
- {
- gl_Position = transform * vec4(position.x, position.y, position.z, 1.0f);
- ourColor = color;
- TexCoord = vec2(texCoord.x, texCoord.y);
- }
- """
- fragment_shader = """
- #version 450 core
- in vec3 ourColor;
- in vec2 TexCoord;
- out vec4 color;
- uniform sampler2D texture1;
- void main()
- {
- color = texture(texture1, TexCoord);
- }
- """
- global shader
- shader = OpenGL.GL.shaders.compileProgram(OpenGL.GL.shaders.compileShader(vertex_shader, GL_VERTEX_SHADER),
- OpenGL.GL.shaders.compileShader(fragment_shader, GL_FRAGMENT_SHADER))
- buildVAO()
- def draw():
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
- theta = math.asin(0.5 / math.sqrt(2))
- phi = math.asin(0.5 / math.sqrt(2 - 0.25))
- a = pyrr.Matrix44([1, 0, 0, 0,
- 0, 1, 0, 0,
- 0, 0, -1, 0,
- 0, 0, 0, 1], dtype='float32')
- b = pyrr.Matrix44([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 = pyrr.Matrix44([math.cos(phi), 0, math.sin(phi), 0,
- 0, 1, 0, 0,
- -math.sin(phi), 0, math.cos(phi), 0,
- 0, 0, 0, 1])
- projection = a * b
- projection *= c
- #print('projection', projection)
- result = torus.matrix * projection
- #result = torus.matrix
- #print('result', result)
- transformLoc = glGetUniformLocation(shader, "transform")
- glUniformMatrix4fv(transformLoc, 1, GL_TRUE, result)
- #glUseProgram(shader)
- #glBindVertexArray(VAO)
- # textures
- #init()
- if torus.isTextured:
- loadTexture(im)
- glActiveTexture(GL_TEXTURE0)
- glBindTexture(GL_TEXTURE_2D, texture)
- glEnable(GL_TEXTURE_2D)
- else:
- glDisable(GL_TEXTURE_2D)
- glDeleteTextures(1, texture)
- glUniform1i(glGetUniformLocation(shader, "texture1"), 0)
- size = torus.nsides * torus.rings * 4
- if not torus.isWire:
- glDrawArrays(GL_QUADS, 0, size)
- else:
- glDrawArrays(GL_LINE_LOOP, 0, size)
- #print(torus.indices)
- #glDrawElements(GL_QUADS, len(torus.indices), GL_UNSIGNED_INT, None)
- # glBegin(GL_LINES)
- #
- # glArrayElement(0)
- # glArrayElement(1)
- # glArrayElement(2)
- # glArrayElement(3)
- #
- # glEnd()
- #glBindVertexArray(0)
- class Drawer:
- window = False
- def __init__(self):
- if not glfw.init():
- return
- # glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 4)
- # glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 5)
- # glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
- # glfw.window_hint(glfw.RESIZABLE, GL_FALSE)
- self.window = glfw.create_window(800, 800, "OpenGL", None, None)
- # self.attrib = glfw.get_window_attrib(self.window, glfw.CONTEXT_VERSION_MAJOR)
- # self.attrib = glfw.get_window_attrib(self.window, glfw.CONTEXT_VERSION_MINOR)
- # self.attrib = glfw.get_window_attrib(self.window, glfw.OPENGL_PROFILE)
- glfw.set_key_callback(self.window, keyCallback)
- glfw.set_scroll_callback(self.window, scrollCallback)
- glfw.set_mouse_button_callback(self.window, mouseCallback)
- if not self.window:
- glfw.terminate()
- return
- glfw.make_context_current(self.window)
- shader()
- 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()
- torus = Torus()
- drawer = Drawer()
- drawer.startLoop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement