Advertisement
Guest User

Untitled

a guest
Sep 20th, 2019
118
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 10.87 KB | None | 0 0
  1. import pygame
  2. import pyrr as pyrr
  3. from pygame.locals import *
  4. from OpenGL.GL import *
  5. from OpenGL.GLU import *
  6. import noise
  7. import numpy as np
  8. import sys
  9. import struct
  10. from typing import Any
  11. from pyrr import Matrix44, Vector4, Vector3, Quaternion
  12.  
  13. vertex_shader = '''
  14. #version 120
  15. attribute vec2 position;
  16. attribute float height;
  17.  
  18. varying float amplitude;
  19.  
  20. //uniform mat4 mvp;
  21.  
  22. void main() {
  23.    mat4 mvp = mat4(  1.07111101,   0.0,           0.0,           0.0,        
  24.  0.0,           1.32600214,  -0.3713981,   -0.37139068,
  25.  0.0,          -0.53040085,  -0.92849526,  -0.92847669,
  26. -10.71111005,   5.30400854,  14.6682251,   14.66993172);
  27.    gl_Position = mvp * vec4(position[0], height, position[1], 1);
  28.    amplitude = height;
  29. }
  30. '''
  31.  
  32. fragment_shader = '''
  33. #version 120
  34.  
  35. varying float amplitude;
  36.  
  37. void main() {
  38.    float tmp = amplitude;
  39.    vec3 color = vec3(1, 0.5, 0.5);
  40.    if (tmp > 1.0) {
  41.        tmp = 1.0;
  42.    } else if (tmp < 0.0) {
  43.        color = vec3(0.5, 0.5, 1);
  44.        tmp = abs(tmp);
  45.        if (tmp > 1.0) {
  46.            tmp = 1.0;
  47.        }
  48.    }
  49.    color = color * tmp;
  50.    gl_FragColor = vec4(color, 1);
  51. }
  52. '''
  53.  
  54.  
  55. def load_shader(src: str, shader_type: int) -> int:
  56.     shader = glCreateShader(shader_type)
  57.     glShaderSource(shader, src)
  58.     glCompileShader(shader)
  59.     error = glGetShaderiv(shader, GL_COMPILE_STATUS)
  60.     if error != GL_TRUE:
  61.         info = glGetShaderInfoLog(shader)
  62.         glDeleteShader(shader)
  63.         raise Exception(info)
  64.     return shader
  65.  
  66.  
  67. class Shader:
  68.     def __init__(self):
  69.         self.program = glCreateProgram()
  70.  
  71.     def __del__(self):
  72.         glDeleteProgram(self.program)
  73.  
  74.     def compile(self, vs_src: str, fs_src: str):
  75.         vs = load_shader(vs_src, GL_VERTEX_SHADER)
  76.         if not vs:
  77.             return
  78.         fs = load_shader(fs_src, GL_FRAGMENT_SHADER)
  79.         if not fs:
  80.             return
  81.         glAttachShader(self.program, vs)
  82.         glAttachShader(self.program, fs)
  83.         glLinkProgram(self.program)
  84.         error = glGetProgramiv(self.program, GL_LINK_STATUS)
  85.         glDeleteShader(vs)
  86.         glDeleteShader(fs)
  87.         if error != GL_TRUE:
  88.             info = glGetShaderInfoLog(self.program)
  89.             raise Exception(info)
  90.  
  91.     def use(self):
  92.         glUseProgram(self.program)
  93.  
  94.     def unuse(self):
  95.         glUseProgram(0)
  96.  
  97.  
  98. class VBO:
  99.     def __init__(self):
  100.         self.vbo = glGenBuffers(1)
  101.         self.component_count = 0
  102.         self.vertex_count = 0
  103.  
  104.     def __del__(self):
  105.         glDeleteBuffers(1, [self.vbo])
  106.  
  107.     def bind(self):
  108.         glBindBuffer(GL_ARRAY_BUFFER, self.vbo)
  109.  
  110.     def unbind(self):
  111.         glBindBuffer(GL_ARRAY_BUFFER, 0)
  112.  
  113.     def set_vertex_attribute(self, component_count: int, bytelength: int,
  114.                              data: any):
  115.         self.component_count = component_count
  116.         stride = 4 * self.component_count
  117.         self.vertex_count = bytelength // stride
  118.         self.bind()
  119.         glBufferData(GL_ARRAY_BUFFER, bytelength, data, GL_STATIC_DRAW)
  120.  
  121.     def set_slot(self, slot: int):
  122.         self.bind()
  123.         glEnableVertexAttribArray(slot)
  124.         glVertexAttribPointer(slot, self.component_count, GL_FLOAT, GL_FALSE, 0, None)
  125.  
  126.     def draw(self):
  127.         glDrawArrays(GL_TRIANGLES, 0, self.vertex_count)
  128.  
  129.  
  130. class BO:
  131.     def __init__(self):
  132.         self.bo = glGenBuffers(1)
  133.         self.component_count = 0
  134.  
  135.     def __del__(self):
  136.         glDeleteBuffers(1, [self.bo])
  137.  
  138.     def bind(self):
  139.         glBindBuffer(GL_ARRAY_BUFFER, self.bo)
  140.  
  141.     def unbind(self):
  142.         glBindBuffer(GL_ARRAY_BUFFER, 0)
  143.  
  144.     def set_data(self, component_count: int, byte_length: int, data: any):
  145.         self.component_count = component_count
  146.         self.bind()
  147.         glBufferData(GL_ARRAY_BUFFER, byte_length, data, GL_DYNAMIC_DRAW)
  148.  
  149.     def set_slot(self, slot: int):
  150.         self.bind()
  151.         glEnableVertexAttribArray(slot)
  152.         glVertexAttribPointer(slot, self.component_count, GL_FLOAT, GL_FALSE, 0, None)
  153.  
  154.  
  155. class IBO:
  156.     def __init__(self):
  157.         self.vbo = glGenBuffers(1)
  158.         self.index_count = 0
  159.         self.index_type = 0
  160.  
  161.     def __del__(self):
  162.         glDeleteBuffers(1, [self.vbo])
  163.  
  164.     def bind(self):
  165.         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, self.vbo)
  166.  
  167.     def unbind(self):
  168.         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)
  169.  
  170.     def set_indices(self, stride: int, bytelength: int, data: Any):
  171.         self.index_count = bytelength // stride
  172.         self.bind()
  173.         if stride == 1:
  174.             self.index_type = GL_UNSIGNED_BYTE
  175.         elif stride == 2:
  176.             self.index_type = GL_UNSIGNED_SHORT
  177.         elif stride == 4:
  178.             self.index_type = GL_UNSIGNED_INT
  179.         glBufferData(GL_ELEMENT_ARRAY_BUFFER, bytelength, data, GL_STATIC_DRAW)
  180.  
  181.     def draw(self):
  182.         glDrawElements(GL_TRIANGLES, self.index_count, self.index_type, None)
  183.  
  184.  
  185. class Data:
  186.     def __init__(self):
  187.         self.vbo: VBO = None
  188.         self.ibo: IBO = None
  189.         self.height_bo: BO = BO()
  190.         self.shader: Shader = None
  191.         self.vertices = None
  192.         self.indices = None
  193.  
  194.     def initialize(self):
  195.         self.shader = Shader()
  196.         self.shader.compile(vertex_shader, fragment_shader)
  197.         self.vbo = VBO()
  198.         self.ibo = IBO()
  199.         self.vbo.set_vertex_attribute(2, len(self.vertices) * sys.getsizeof(float()),
  200.                                       struct.pack(str(len(self.vertices)) + "f", *self.vertices))
  201.         self.ibo.set_indices(4, len(self.indices) * sys.getsizeof(int()), struct.pack(str(len(self.indices)) + "I",
  202.                                                                                       *self.indices))
  203.  
  204.     def draw(self):
  205.         if not self.vbo:
  206.             self.initialize()
  207.  
  208.         #mvp_matrix_id, mvp = create_mvp(self.shader.program, 800, 600)
  209.         #glUniformMatrix4fv(mvp_matrix_id, 1, GL_FALSE, mvp)
  210.         self.shader.use()
  211.         self.vbo.set_slot(0)
  212.         self.ibo.bind()
  213.         self.height_bo.set_slot(1)
  214.         self.ibo.draw()
  215.  
  216.         self.ibo.unbind()
  217.         self.vbo.unbind()
  218.         self.height_bo.unbind()
  219.         self.shader.unuse()
  220.  
  221.  
  222. class MapConfig:
  223.     def __init__(self):
  224.         self.shape = (25, 25)
  225.         self.scale = 100.0
  226.         self.octaves = 6
  227.         self.persistence = 0.5
  228.         self.lacunarity = 2.0
  229.         self.amplitude_scale = 1.0
  230.  
  231.  
  232. class Map:
  233.     def __init__(self, data):
  234.         self.data = data
  235.  
  236.  
  237. def calculate_index(x: int, y: int, w: int) -> (int, int):
  238.     index1 = [x * w + y, (x + 1) * w + y, (x + 1) * w + y + 1]
  239.     index2 = [x * w + y, x * w + y + 1, (x + 1) * w + y + 1]
  240.     return index1, index2
  241.  
  242.  
  243. def generate_vertices(map_config: MapConfig):
  244.     vertices = []
  245.     indices = []
  246.     for i in range(map_config.shape[0]):
  247.         for j in range(map_config.shape[1]):
  248.             vertices.append(i * 0.5)
  249.             vertices.append(j * 0.5)
  250.  
  251.     for i in range(map_config.shape[0] - 1):
  252.         for j in range(map_config.shape[1] - 1):
  253.             index1, index2 = calculate_index(i, j, map_config.shape[0])
  254.             indices.extend(index1)
  255.             indices.extend(index2)
  256.     return np.array(vertices), np.array(indices)
  257.  
  258.  
  259. def generate_map(map_config: MapConfig, x_offset: float) -> Map:
  260.     data = np.zeros(map_config.shape, dtype=np.float32)
  261.     for i in range(map_config.shape[0]):
  262.         for j in range(map_config.shape[1]):
  263.             data[i][j] = noise.pnoise2(i / map_config.scale,
  264.                                        (j + x_offset) / map_config.scale,
  265.                                        octaves=map_config.octaves,
  266.                                        persistence=map_config.persistence,
  267.                                        lacunarity=map_config.lacunarity,
  268.                                        repeatx=10,
  269.                                        repeaty=10,
  270.                                        base=0) * map_config.amplitude_scale
  271.     return Map(data.flatten())
  272.  
  273.  
  274. def apply_map_to_vertices(map_config: MapConfig, map: Map, verticies):
  275.     for i in range(map_config.shape[0]):
  276.         for j in range(map_config.shape[1]):
  277.             verticies[i * map_config.shape[0]][1] = map.data[i][j]
  278.  
  279.  
  280. def draw(vertices, indices):
  281.     glBegin(GL_TRIANGLES)
  282.     for index in indices:
  283.         for vertex in index:
  284.             glVertex2fv(vertices[vertex])
  285.     glEnd()
  286.  
  287.  
  288. def perspective(fov, aspect, near, far):
  289.     n, f = near, far
  290.     t = np.tan((fov * np.pi / 180) / 2) * near
  291.     b = - t
  292.     r = t * aspect
  293.     l = b * aspect
  294.     assert abs(n - f) > 0
  295.     return np.array((
  296.         ((2 * n) / (r - l), 0, 0, 0),
  297.         (0, (2 * n) / (t - b), 0, 0),
  298.         ((r + l) / (r - l), (t + b) / (t - b), (f + n) / (n - f), -1),
  299.         (0, 0, 2 * f * n / (n - f), 0)))
  300.  
  301.  
  302. def normalized(v):
  303.     norm = np.linalg.norm(v)
  304.     return v / norm if norm > 0 else v
  305.  
  306.  
  307. def look_at(eye, target, up):
  308.     zax = normalized(eye - target)
  309.     xax = normalized(np.cross(up, zax))
  310.     yax = np.cross(zax, xax)
  311.     x = - xax.dot(eye)
  312.     y = - yax.dot(eye)
  313.     z = - zax.dot(eye)
  314.     return np.array(((xax[0], yax[0], zax[0], 0),
  315.                      (xax[1], yax[1], zax[1], 0),
  316.                      (xax[2], yax[2], zax[2], 0),
  317.                      (x, y, z, 1)))
  318.  
  319.  
  320. def create_mvp(program_id, width, height):
  321.     fov, near, far = 70, 0.001, 100
  322.     eye = np.array((10, 2, 15))
  323.     target, up = np.array((10, 0, 10)), np.array((0, 1, 0))
  324.     projection = perspective(fov, width / height, near, far)
  325.     view = look_at(eye, target, up)
  326.     model = np.identity(4)
  327.     mvp = model @ view @ projection
  328.     print(mvp)
  329.     matrix_id = glGetUniformLocation(program_id, 'mvp')
  330.     return matrix_id, mvp.astype(np.float32)
  331.  
  332.  
  333. x_offset = 0
  334.  
  335.  
  336. create_mvp(0, 800, 600)
  337.  
  338. def main():
  339.     pygame.init()
  340.     display = (800, 600)
  341.     pygame.display.set_mode(display, DOUBLEBUF | OPENGL)
  342.  
  343.     gluPerspective(45, (display[0] / display[1]), 0.1, 50.0)
  344.  
  345.     glTranslatef(0.0, 0.0, -5)
  346.  
  347.     map_config = MapConfig()
  348.     vertices, indices = generate_vertices(map_config)
  349.     data = Data()
  350.     data.vertices = vertices
  351.     data.indices = indices
  352.  
  353.     def disp_func():
  354.         global x_offset
  355.         speed = 0.5
  356.  
  357.         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
  358.         map_config.amplitude_scale = 10
  359.         map = generate_map(map_config, x_offset)
  360.         data.height_bo.set_data(1, len(map.data) * sys.getsizeof(float()),
  361.                                 struct.pack(str(len(map.data)) + "f", *map.data))
  362.         data.draw()
  363.         glFlush()
  364.         x_offset -= speed
  365.  
  366.     #glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
  367.     while True:
  368.         for event in pygame.event.get():
  369.             if event.type == pygame.QUIT:
  370.                 pygame.quit()
  371.                 quit()
  372.  
  373.         glRotatef(1, 1, 1, 1)
  374.         disp_func()
  375.         pygame.display.flip()
  376.         pygame.time.wait(1)
  377.  
  378.  
  379. main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement