Advertisement
Guest User

Untitled

a guest
Jun 1st, 2016
59
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.81 KB | None | 0 0
  1. import math
  2. import random
  3. import sys
  4. import time
  5.  
  6. import numpy as np
  7. import OpenGL
  8. from OpenGL.GL import *
  9. import pygame
  10. from pygame.locals import *
  11.  
  12. def createCircles(numCircles):
  13. circles = []
  14. minRadius = 5
  15. maxRadius = 20
  16. for i in range(numCircles):
  17. cx = random.random()*width
  18. cy = random.random()*height
  19. r = random.random()*(maxRadius - minRadius) + minRadius
  20. circles.append((cx, cy, r))
  21. return circles
  22.  
  23. def createShader(vsStr, fsStr):
  24. vs = glCreateShader(GL_VERTEX_SHADER)
  25. glShaderSource(vs, vsStr)
  26. glCompileShader(vs)
  27. check = glGetShaderiv(vs, GL_COMPILE_STATUS)
  28. if not(check):
  29. raise RuntimeError(glGetShaderInfoLog(vs))
  30.  
  31. fs = glCreateShader(GL_FRAGMENT_SHADER)
  32. glShaderSource(fs, fsStr)
  33. glCompileShader(fs)
  34. check = glGetShaderiv(fs, GL_COMPILE_STATUS)
  35. if not(check):
  36. raise RuntimeError(glGetShaderInfoLog(fs))
  37.  
  38. program = glCreateProgram()
  39. glAttachShader(program, vs)
  40. glAttachShader(program, fs)
  41. glLinkProgram(program)
  42. check = glGetProgramiv(program, GL_LINK_STATUS)
  43. if not(check):
  44. raise RuntimeError(glGetProgramInfoLog(program))
  45.  
  46. return program
  47.  
  48. def updateBufferData(circles, vbo, tbo, ibo, xbo, vertices, texCoords, indices, radii, transforms, instances):
  49. for i, circle in enumerate(circles):
  50. cx, cy, r = circle
  51. vertices[i] = [-r, -r, r, -r, -r, r, r, r]
  52. texCoords[i] = [-1, -1, 1, -1, -1, 1, 1, 1]
  53. indices[i] = np.array([0, 1, 2, 2, 3, 1], dtype=np.float32)+(4*i)
  54. transforms[i] = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, cx, cy, 0, 1]
  55. instances[i] = [i]*4
  56. radii[i] = r
  57. glBindBuffer(GL_ARRAY_BUFFER, vbo)
  58. glBufferData(GL_ARRAY_BUFFER, vertices.nbytes, vertices, GL_STATIC_DRAW)
  59. glBindBuffer(GL_ARRAY_BUFFER, 0)
  60. glBindBuffer(GL_ARRAY_BUFFER, tbo)
  61. glBufferData(GL_ARRAY_BUFFER, texCoords.nbytes, texCoords, GL_STATIC_DRAW)
  62. glBindBuffer(GL_ARRAY_BUFFER, 0)
  63. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo)
  64. glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.nbytes, indices, GL_STATIC_DRAW)
  65. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)
  66. glBindBuffer(GL_ARRAY_BUFFER, xbo)
  67. glBufferData(GL_ARRAY_BUFFER, instances.nbytes, instances, GL_STATIC_DRAW)
  68. glBindBuffer(GL_ARRAY_BUFFER, 0)
  69.  
  70. if __name__ == "__main__":
  71. width = 500
  72. height = 500
  73. title = "Pseudo-Instancing Demo"
  74. pygame.init()
  75. screen = pygame.display.set_mode((width, height), DOUBLEBUF|OPENGL|HWSURFACE)
  76.  
  77. vsStr = """#version 120
  78. attribute vec2 a_position;
  79. attribute vec2 a_texCoord;
  80. attribute int a_instance;
  81. uniform mat4 u_transform[500];
  82. uniform vec4 u_color[500];
  83. uniform float u_radius[500];
  84. varying vec4 v_color;
  85. varying float v_radius;
  86. varying vec2 v_texCoord;
  87. void main()
  88. {
  89. gl_Position = gl_ProjectionMatrix * u_transform[a_instance] * vec4(a_position, 0, 1);
  90. v_texCoord = a_texCoord;
  91. v_color = u_color[a_instance];
  92. v_radius = u_radius[a_instance];
  93. }
  94. """
  95.  
  96. fsStr = """#version 120
  97. varying vec4 v_color;
  98. varying float v_radius;
  99. varying vec2 v_texCoord;
  100. void main()
  101. {
  102. float d = v_radius - length(v_texCoord*vec2(v_radius, v_radius));
  103. float t = clamp(d, 0, 1);
  104. gl_FragColor = vec4(1, 1, 1, t) * v_color;
  105. }
  106. """
  107.  
  108. numCircles = 500
  109. circles = createCircles(numCircles)
  110. shader = createShader(vsStr, fsStr)
  111. vbo, tbo, ibo, xbo = glGenBuffers(4)
  112. vertices = np.empty([numCircles, 8], dtype=np.float32)
  113. texCoords = np.empty([numCircles, 8], dtype=np.float32)
  114. indices = np.empty([numCircles, 6], dtype=np.int32)
  115. transforms = np.empty([numCircles, 16], dtype=np.float32)
  116. colors = np.random.rand(numCircles, 4)
  117. radii = np.empty(numCircles, dtype=np.float32)
  118. instances = np.empty([numCircles, 4], dtype=np.int32)
  119. glClearColor(1.0, 1.0, 1.0, 1.0)
  120. glMatrixMode(GL_PROJECTION)
  121. glOrtho(0, width, 0, height, -1, 1)
  122. glEnable(GL_BLEND)
  123. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
  124.  
  125. while True:
  126. start = time.time()
  127. events = pygame.event.get()
  128. for event in events:
  129. if event.type == pygame.QUIT:
  130. sys.exit()
  131.  
  132. updateBufferData(circles, vbo, tbo, ibo, xbo, vertices, texCoords, indices, radii, transforms, instances)
  133.  
  134. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
  135. glUseProgram(shader)
  136. a_position = glGetAttribLocation(shader, "a_position")
  137. a_texCoord = glGetAttribLocation(shader, "a_texCoord")
  138. a_instance = glGetAttribLocation(shader, "a_instance")
  139.  
  140. u_transform = glGetUniformLocation(shader, "u_transform")
  141. u_color = glGetUniformLocation(shader, "u_color")
  142. u_radius = glGetUniformLocation(shader, "u_radius")
  143. glUniformMatrix4fv(u_transform, numCircles, False, transforms)
  144. glUniform4fv(u_color, numCircles, colors)
  145. glUniform1fv(u_radius, numCircles, radii)
  146.  
  147. glEnableVertexAttribArray(a_position)
  148. glEnableVertexAttribArray(a_texCoord)
  149. glEnableVertexAttribArray(a_instance)
  150. glBindBuffer(GL_ARRAY_BUFFER, vbo)
  151. glVertexAttribPointer(a_position, 2, GL_FLOAT, False, 0, None)
  152. glBindBuffer(GL_ARRAY_BUFFER, tbo)
  153. glVertexAttribPointer(a_texCoord, 2, GL_FLOAT, False, 0, None)
  154. glBindBuffer(GL_ARRAY_BUFFER, xbo)
  155. glVertexAttribPointer(a_instance, 1, GL_FLOAT, False, 0, None)
  156. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo)
  157. glDrawElements(GL_TRIANGLES, 6*numCircles, GL_UNSIGNED_INT, None)
  158. glDisableVertexAttribArray(a_position)
  159. glDisableVertexAttribArray(a_texCoord)
  160. glDisableVertexAttribArray(a_instance)
  161. glUseProgram(0)
  162.  
  163. pygame.display.flip()
  164. end = time.time()
  165. fps = int(round(1/(end - start)))
  166. pygame.display.set_caption(title + ": " + str(fps))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement