Advertisement
trishLEX

LAB8

May 30th, 2017
498
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 13.08 KB | None | 0 0
  1. import glfw
  2. from OpenGL.GL import *
  3. import OpenGL.GL.shaders
  4. import numpy
  5. import math
  6. import pyrr
  7. import PIL.Image
  8. import ctypes
  9.  
  10. im = "texture.bmp"
  11.  
  12. def background():
  13.     glClearColor(0.8, 0.8, 0.8, 1.0)
  14.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
  15.     glEnable(GL_DEPTH_TEST)
  16.  
  17. def keyCallback(window, key, scancode, action, mods):
  18.     if key == glfw.KEY_KP_SUBTRACT and action and torus.nsides > 3:
  19.         torus.nsides -= 1
  20.         torus.rings -= 1
  21.         torus.remake()
  22.         rebuildVAO()
  23.     elif key == glfw.KEY_KP_ADD and action:
  24.         torus.nsides += 1
  25.         torus.rings += 1
  26.         torus.remake()
  27.         rebuildVAO()
  28.     elif key == glfw.KEY_W and action:
  29.         torus.center[1] += 0.1
  30.         torus.translate_y(0.1)
  31.     elif key == glfw.KEY_S and action:
  32.         torus.center[1] -= 0.1
  33.         torus.translate_y(-0.1)
  34.     elif key == glfw.KEY_A and action:
  35.         torus.center[0] -= 0.1
  36.         torus.translate_x(-0.1)
  37.     elif key == glfw.KEY_D and action:
  38.         torus.center[0] += 0.1
  39.         torus.translate_x(0.1)
  40.     elif key == glfw.KEY_UP and action:
  41.         torus.rotate_x(0.1)
  42.     elif key == glfw.KEY_DOWN and action:
  43.         torus.rotate_x(-0.1)
  44.     elif key == glfw.KEY_LEFT and action:
  45.         torus.rotate_y(-0.1)
  46.     elif key == glfw.KEY_RIGHT and action:
  47.         torus.rotate_y(0.1)
  48.     elif key == glfw.KEY_T and action:
  49.         if torus.isTextured:
  50.             torus.isTextured = False
  51.         else:
  52.             torus.isTextured = True
  53.  
  54.  
  55. def mouseCallback(window, button, action, mods):
  56.     if button == glfw.MOUSE_BUTTON_1 and action and torus.isWire:
  57.         torus.isWire = False
  58.     elif button == glfw.MOUSE_BUTTON_1 and action and not torus.isWire:
  59.         torus.isWire = True
  60.  
  61.  
  62. def scrollCallback(window, xoffset, yoffset):
  63.     if yoffset > 0:
  64.         torus.scale(1.1)
  65.     elif yoffset < 0:
  66.         torus.scale(0.9)
  67.  
  68. # def init():
  69. #     glClearDepth(1.0)
  70. #     glDepthFunc(GL_LEQUAL)
  71. #     glEnable(GL_DEPTH_TEST)
  72. #     glEnable(GL_TEXTURE_2D)
  73. #     glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST)
  74. #     glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)
  75.  
  76.  
  77. def loadTexture(fileName):
  78.     image = PIL.Image.open(fileName)
  79.     width = image.size[0]
  80.     height = image.size[1]
  81.     image = image.tobytes("raw", "RGBA", 0, -1)
  82.     texture = glGenTextures(1)
  83.  
  84.     glBindTexture(GL_TEXTURE_2D, texture)
  85.     glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
  86.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
  87.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
  88.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
  89.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR)
  90.     ###glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)
  91.     #gluBuild2DMipmaps(GL_TEXTURE_2D, 3, width, height, GL_RGBA, GL_UNSIGNED_BYTE, image)
  92.     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image)
  93.     glGenerateMipmap(GL_TEXTURE_2D)
  94.     glBindTexture(GL_TEXTURE_2D, 0)
  95.  
  96.     return texture
  97.  
  98.  
  99. class Torus:
  100.     def __init__(self):
  101.         self.isTextured = False
  102.         self.polygonMesh = []
  103.         self.normals = []
  104.         self.center = [0, 0, 0]
  105.         self.nsides = 3
  106.         self.rings = 3
  107.         self.r = 0.2
  108.         self.R = 0.4
  109.         #self.rotate_x = 0
  110.         #self.rotate_y = 0
  111.         self.isWire = False
  112.         self.vertexes = []
  113.         self.texes = []
  114.         self.indices = []
  115.         self.array = []
  116.         self.setMesh()
  117.         self.matrix = pyrr.Matrix44.identity()
  118.  
  119.     def setMesh(self):
  120.         for i in range(self.rings):
  121.             theta = i * 2.0 * math.pi / self.rings
  122.             theta1 = ((i + 1) % self.rings) * 2.0 * math.pi / self.rings
  123.             for j in range(self.nsides):
  124.                 phi = j * 2.0 * math.pi / self.nsides
  125.                 phi1 = ((j + 1) % self.nsides) * 2.0 * math.pi / self.nsides
  126.  
  127.                 p0 = [math.cos(theta) * (self.R + self.r * math.cos(phi)),
  128.                       -math.sin(theta) * (self.R + self.r * math.cos(phi)),
  129.                       self.r * math.sin(phi)]
  130.                 p1 = [math.cos(theta1) * (self.R + self.r * math.cos(phi)),
  131.                       -math.sin(theta1) * (self.R + self.r * math.cos(phi)),
  132.                       self.r * math.sin(phi)]
  133.                 p2 = [math.cos(theta1) * (self.R + self.r * math.cos(phi1)),
  134.                       -math.sin(theta1) * (self.R + self.r * math.cos(phi1)),
  135.                       self.r * math.sin(phi1)]
  136.                 p3 = [math.cos(theta) * (self.R + self.r * math.cos(phi1)),
  137.                       -math.sin(theta) * (self.R + self.r * math.cos(phi1)),
  138.                       self.r * math.sin(phi1)]
  139.  
  140.                 p = [p0, p1, p2, p3]
  141.  
  142.                 n0 = [math.cos(theta) * (math.cos(phi)), -math.sin(theta) * (math.cos(phi)), math.sin(phi)]
  143.  
  144.                 n = [n0]
  145.  
  146.                 self.polygonMesh.append(p)
  147.                 self.normals.append(n)
  148.  
  149.         count = self.rings * self.nsides
  150.         k = 1
  151.         for i in range(count):
  152.             n = self.rings
  153.             if i % n == 0 and i != 0:
  154.                 k -= 1 / n
  155.  
  156.             for j in range(4):
  157.                 for l in range(3):
  158.                     self.vertexes.append(self.polygonMesh[i][j][l])
  159.  
  160.             self.texes.append(k)
  161.             self.texes.append((i % n) / n)
  162.             self.texes.append(k - 1 / n)
  163.             self.texes.append((i % n) / n)
  164.             self.texes.append(k - 1 / n)
  165.             self.texes.append((i % n + 1) / n)
  166.             self.texes.append(k)
  167.             self.texes.append((i % n + 1) / n)
  168.  
  169.             self.indices = [l for l in range(4 * count)]
  170.  
  171.         print(count * 4 * 3, len(self.vertexes))
  172.         k = 0
  173.         array = []
  174.         for i in range(0, count * 4 * 3, 3):
  175.             array.append(self.vertexes[i])
  176.             array.append(self.vertexes[i + 1])
  177.             array.append(self.vertexes[i + 2])
  178.             array.append(1.0)
  179.             array.append(1.0)
  180.             array.append(1.0)
  181.             array.append(self.texes[k])
  182.             array.append(self.texes[k + 1])
  183.             k += 2
  184.         self.array = numpy.array(array, dtype='float32')
  185.         self.indices = numpy.array(self.indices, dtype='uint32')
  186.         print(array)
  187.  
  188.     def clear(self):
  189.         self.isTextured = False
  190.         self.polygonMesh = []
  191.         self.normals = []
  192.         self.center = [0, 0, 0]
  193.         self.nsides = 3
  194.         self.rings = 3
  195.         self.r = 0.2
  196.         self.R = 0.4
  197.         #self.rotate_x = 0
  198.         #self.rotate_y = 0
  199.         self.isWire = False
  200.         self.vertexes = []
  201.         self.texes = []
  202.         self.indices = []
  203.         self.array = []
  204.         self.setMesh()
  205.         self.matrix = pyrr.Matrix44.identity()
  206.  
  207.     def remake(self):
  208.         torus.vertexes = []
  209.         torus.texes = []
  210.         torus.indices = []
  211.         torus.array = []
  212.         torus.polygonMesh = []
  213.         torus.setMesh()
  214.  
  215.     def translate_y(self, n):
  216.         a = pyrr.Matrix44([1, 0, 0, 0,
  217.                            0, 1, 0, n,
  218.                            0, 0, 1, 0,
  219.                            0, 0, 0, 1], dtype='float32')
  220.         self.matrix *= a
  221.         #print(self.matrix)
  222.  
  223.     def translate_x(self, n):
  224.         a = pyrr.Matrix44([1, 0, 0, n,
  225.                            0, 1, 0, 0,
  226.                            0, 0, 1, 0,
  227.                            0, 0, 0, 1], dtype='float32')
  228.         self.matrix *= a
  229.  
  230.     def rotate_x(self, n):
  231.         a = pyrr.Matrix44.from_x_rotation(n)
  232.         self.matrix *= a
  233.  
  234.     def rotate_y(self, n):
  235.         a = pyrr.Matrix44.from_y_rotation(n)
  236.         self.matrix *= a
  237.  
  238.     def scale(self, n):
  239.         a = pyrr.Matrix44.from_scale([n, n, n, 1])
  240.         self.matrix *= a
  241.  
  242.  
  243. def buildVAO():
  244.     global VAO
  245.     VAO = glGenVertexArrays(1)
  246.  
  247.     global VBO
  248.     VBO = glGenBuffers(1)
  249.  
  250.     glBindVertexArray(VAO)
  251.  
  252.     glBindBuffer(GL_ARRAY_BUFFER, VBO)
  253.     size = 4 * len(torus.array)
  254.     glBufferData(GL_ARRAY_BUFFER, size, torus.array, GL_STATIC_DRAW)
  255.  
  256.     # EBO = glGenBuffers(1)
  257.     # glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO)
  258.     # glBufferData(GL_ELEMENT_ARRAY_BUFFER, len(torus.indices) * 4, torus.indices, GL_STATIC_DRAW)
  259.  
  260.     glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 32, ctypes.c_void_p(0))
  261.     # 32 = 8 * sizeof(float)
  262.     glEnableVertexAttribArray(0)
  263.  
  264.     glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 32, ctypes.c_void_p(12))
  265.     glEnableVertexAttribArray(1)
  266.  
  267.     glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 32, ctypes.c_void_p(24))
  268.     glEnableVertexAttribArray(2)
  269.  
  270.     # glBindBuffer(GL_ARRAY_BUFFER, 0)
  271.     # glBindVertexArray(0)
  272.  
  273.     glUseProgram(shader)
  274.  
  275.  
  276. def rebuildVAO():
  277.     glDeleteVertexArrays(1, VAO)
  278.     glDeleteVertexArrays(1, VBO)
  279.  
  280.     buildVAO()
  281.  
  282.  
  283. def shader():
  284.     vertex_shader = """
  285.        #version 450 core
  286.            layout (location = 0) in vec3 position;
  287.            layout (location = 1) in vec3 color;
  288.            layout (location = 2) in vec2 texCoord;
  289.            uniform mat4 transform;
  290.            out vec3 ourColor;
  291.            out vec2 TexCoord;
  292.            void main()
  293.            {
  294.            gl_Position = transform * vec4(position.x, position.y, position.z, 1.0f);
  295.            ourColor = color;
  296.            TexCoord = vec2(texCoord.x, texCoord.y);
  297.            }
  298.        """
  299.  
  300.     fragment_shader = """
  301.        #version 450 core
  302.            in vec3 ourColor;
  303.            in vec2 TexCoord;
  304.            out vec4 color;
  305.            uniform sampler2D texture1;
  306.            void main()
  307.            {
  308.            color = texture(texture1, TexCoord);
  309.            }
  310.        """
  311.     global shader
  312.     shader = OpenGL.GL.shaders.compileProgram(OpenGL.GL.shaders.compileShader(vertex_shader, GL_VERTEX_SHADER),
  313.                                               OpenGL.GL.shaders.compileShader(fragment_shader, GL_FRAGMENT_SHADER))
  314.  
  315.     buildVAO()
  316.  
  317.  
  318. def draw():
  319.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
  320.  
  321.     theta = math.asin(0.5 / math.sqrt(2))
  322.     phi = math.asin(0.5 / math.sqrt(2 - 0.25))
  323.     a = pyrr.Matrix44([1, 0, 0, 0,
  324.                        0, 1, 0, 0,
  325.                        0, 0, -1, 0,
  326.                        0, 0, 0, 1], dtype='float32')
  327.     b = pyrr.Matrix44([1, 0, 0, 0,
  328.                        0, math.cos(theta), -math.sin(theta), 0,
  329.                        0, math.sin(theta), math.cos(theta), 0,
  330.                        0, 0, 0, 1])
  331.     c = pyrr.Matrix44([math.cos(phi), 0, math.sin(phi), 0,
  332.                        0, 1, 0, 0,
  333.                        -math.sin(phi), 0, math.cos(phi), 0,
  334.                        0, 0, 0, 1])
  335.     projection = a * b
  336.     projection *= c
  337.     #print('projection', projection)
  338.  
  339.     result = torus.matrix * projection
  340.     #result = torus.matrix
  341.     #print('result', result)
  342.  
  343.     transformLoc = glGetUniformLocation(shader, "transform")
  344.     glUniformMatrix4fv(transformLoc, 1, GL_TRUE, result)
  345.  
  346.     #glUseProgram(shader)
  347.     #glBindVertexArray(VAO)
  348.  
  349.     # textures
  350.     #init()
  351.  
  352.     if torus.isTextured:
  353.         loadTexture(im)
  354.         glActiveTexture(GL_TEXTURE0)
  355.         glBindTexture(GL_TEXTURE_2D, texture)
  356.         glEnable(GL_TEXTURE_2D)
  357.     else:
  358.         glDisable(GL_TEXTURE_2D)
  359.         glDeleteTextures(1, texture)
  360.  
  361.     glUniform1i(glGetUniformLocation(shader, "texture1"), 0)
  362.  
  363.     size = torus.nsides * torus.rings * 4
  364.     if not torus.isWire:
  365.         glDrawArrays(GL_QUADS, 0, size)
  366.     else:
  367.         glDrawArrays(GL_LINE_LOOP, 0, size)
  368.     #print(torus.indices)
  369.     #glDrawElements(GL_QUADS, len(torus.indices), GL_UNSIGNED_INT, None)
  370.     # glBegin(GL_LINES)
  371.     #
  372.     # glArrayElement(0)
  373.     # glArrayElement(1)
  374.     # glArrayElement(2)
  375.     # glArrayElement(3)
  376.     #
  377.     # glEnd()
  378.     #glBindVertexArray(0)
  379.  
  380.  
  381. class Drawer:
  382.     window = False
  383.  
  384.     def __init__(self):
  385.         if not glfw.init():
  386.             return
  387.  
  388.         # glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 4)
  389.         # glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 5)
  390.         # glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
  391.         # glfw.window_hint(glfw.RESIZABLE, GL_FALSE)
  392.         self.window = glfw.create_window(800, 800, "OpenGL", None, None)
  393.         # self.attrib = glfw.get_window_attrib(self.window, glfw.CONTEXT_VERSION_MAJOR)
  394.         # self.attrib = glfw.get_window_attrib(self.window, glfw.CONTEXT_VERSION_MINOR)
  395.         # self.attrib = glfw.get_window_attrib(self.window, glfw.OPENGL_PROFILE)
  396.  
  397.         glfw.set_key_callback(self.window, keyCallback)
  398.         glfw.set_scroll_callback(self.window, scrollCallback)
  399.         glfw.set_mouse_button_callback(self.window, mouseCallback)
  400.  
  401.         if not self.window:
  402.             glfw.terminate()
  403.             return
  404.  
  405.         glfw.make_context_current(self.window)
  406.  
  407.         shader()
  408.  
  409.         global texture
  410.         texture = loadTexture(im)
  411.  
  412.     def startLoop(self):
  413.  
  414.         while not glfw.window_should_close(self.window):
  415.             background()
  416.             draw()
  417.  
  418.             glfw.swap_buffers(self.window)
  419.             glfw.poll_events()
  420.  
  421.         glfw.terminate()
  422.  
  423.  
  424. torus = Torus()
  425. drawer = Drawer()
  426. drawer.startLoop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement