def __init__(self, name, program, geometry): self.name = name self.program = program self.geometry = geometry # size of batched draw calls self.batch = BATCH_SIZE self.vertex_attr = glGetAttribLocation(self.program.id, b"vertex") self.edge_attr = glGetAttribLocation(self.program.id, b"edge") self.index_attr = glGetAttribLocation(self.program.id, b"index") # load/bind/configure vertex buffer self.vertex_buffer = VertexBuffer(GLfloat, GL_STATIC_DRAW) batched_edges = list(geometry.edges) * self.batch self.vertex_buffer.load(memory.create_vertex_buffer(batched_edges)) self.vertex_buffer.partition( [(self.vertex_attr, 4), (self.edge_attr, 3)] ) uniform_indicies = [] for i in range(self.batch): uniform_indicies.extend([i] * geometry.num_vertex) indices_buffer = memory.create_vertex_buffer(uniform_indicies) self.indices_buffer = VertexBuffer(GLfloat, GL_STATIC_DRAW) self.indices_buffer.load(indices_buffer) self.indices_buffer.set(self.index_attr, 1)
def __init__(self, name, program, geometry): self.name = name self.program = program self.geometry = geometry # size of batched draw calls self.batch = BATCH_SIZE self.vertex_attr = glGetAttribLocation(self.program.id, b"vertex") self.edge_attr = glGetAttribLocation(self.program.id, b"edge") self.index_attr = glGetAttribLocation(self.program.id, b"index") # load/bind/configure vertex buffer self.vertex_buffer = VertexBuffer(GLfloat, GL_STATIC_DRAW) batched_edges = list(geometry.edges) * self.batch self.vertex_buffer.load(memory.create_vertex_buffer(batched_edges)) self.vertex_buffer.partition([(self.vertex_attr, 4), (self.edge_attr, 3)]) uniform_indicies = [] for i in range(self.batch): uniform_indicies.extend([i] * geometry.num_vertex) indices_buffer = memory.create_vertex_buffer(uniform_indicies) self.indices_buffer = VertexBuffer(GLfloat, GL_STATIC_DRAW) self.indices_buffer.load(indices_buffer) self.indices_buffer.set(self.index_attr, 1)
def __init__(self, name, program, geometry): self.name = name self.program = program self.geometry = geometry self.vertex_attr = glGetAttribLocation(self.program.id, b"vertex") self.edge_attr = glGetAttribLocation(self.program.id, b"edge") self.model_attr = glGetAttribLocation(self.program.id, b"turtle_model") self.color_attr = glGetAttribLocation(self.program.id, b"turtle_color") # create VAO to store Vertex attribute state for later self.vao = GLuint() glGenVertexArrays(1, self.vao) # bind VAO to record array setup/state glBindVertexArray(self.vao) # load shape data into vertex buffer self.vertex_buffer = VertexBuffer(GLfloat, GL_STATIC_DRAW) self.vertex_buffer.load(geometry.edges) self.vertex_buffer.partition( [(self.vertex_attr, 4), (self.edge_attr, 3)] ) # allocate/configure instanced buffers # turtle model buffer self.model_buffer = VertexBuffer(GLfloat, GL_STREAM_DRAW) # mat4 is 4 sequential locations array = [ (self.model_attr, 4), (self.model_attr + 1, 4), (self.model_attr + 2, 4), (self.model_attr + 3, 4), ] self.model_buffer.partition(array, divisor=1) # turtle color buffer self.color_buffer = VertexBuffer(GLfloat, GL_STREAM_DRAW) # mat3 is 3 sequential locations array = [ (self.color_attr, 3), (self.color_attr + 1, 3), (self.color_attr + 2, 3), ] self.color_buffer.partition(array, divisor=1) # VAO now configured, so unbind glBindVertexArray(0)
class TurtleShapeVAO(object): """A VAO for rendering mutliple versions of a specific turtle shape. Creates VAO/vertex/index/model arrays, and can render them given turtle data.""" def __init__(self, name, program, geometry): self.name = name self.program = program self.geometry = geometry self.vertex_attr = glGetAttribLocation(self.program.id, b"vertex") self.edge_attr = glGetAttribLocation(self.program.id, b"edge") self.model_attr = glGetAttribLocation(self.program.id, b"turtle_model") self.color_attr = glGetAttribLocation(self.program.id, b"turtle_color") # create VAO to store Vertex attribute state for later self.vao = GLuint() glGenVertexArrays(1, self.vao) # bind VAO to record array setup/state glBindVertexArray(self.vao) # load shape data into vertex buffer self.vertex_buffer = VertexBuffer(GLfloat, GL_STATIC_DRAW) self.vertex_buffer.load(geometry.edges) self.vertex_buffer.partition( [(self.vertex_attr, 4), (self.edge_attr, 3)] ) # allocate/configure instanced buffers # turtle model buffer self.model_buffer = VertexBuffer(GLfloat, GL_STREAM_DRAW) # mat4 is 4 sequential locations array = [ (self.model_attr, 4), (self.model_attr + 1, 4), (self.model_attr + 2, 4), (self.model_attr + 3, 4), ] self.model_buffer.partition(array, divisor=1) # turtle color buffer self.color_buffer = VertexBuffer(GLfloat, GL_STREAM_DRAW) # mat3 is 3 sequential locations array = [ (self.color_attr, 3), (self.color_attr + 1, 3), (self.color_attr + 2, 3), ] self.color_buffer.partition(array, divisor=1) # VAO now configured, so unbind glBindVertexArray(0) def render(self, model, color, num_turtles): """Renders all turtles of a given shape""" self.program.bind() glBindVertexArray(self.vao) self.model_buffer.load(model.data, model.byte_size) self.color_buffer.load(color.data, color.byte_size) glDrawArraysInstanced( GL_TRIANGLES, 0, len(self.geometry.edges) // 7, # 7 = 4 for vertex, 3 for edge num_turtles ) glBindVertexArray(0) self.program.unbind()
class ESTurtleShapeRenderer(object): """A Renderer for rendering mutliple versions of a specific turtle shape. Creates vertex/index/model arrays, and can render them given turtle data.""" def __init__(self, name, program, geometry): self.name = name self.program = program self.geometry = geometry # size of batched draw calls self.batch = BATCH_SIZE self.vertex_attr = glGetAttribLocation(self.program.id, b"vertex") self.edge_attr = glGetAttribLocation(self.program.id, b"edge") self.index_attr = glGetAttribLocation(self.program.id, b"index") # load/bind/configure vertex buffer self.vertex_buffer = VertexBuffer(GLfloat, GL_STATIC_DRAW) batched_edges = list(geometry.edges) * self.batch self.vertex_buffer.load(memory.create_vertex_buffer(batched_edges)) self.vertex_buffer.partition( [(self.vertex_attr, 4), (self.edge_attr, 3)] ) uniform_indicies = [] for i in range(self.batch): uniform_indicies.extend([i] * geometry.num_vertex) indices_buffer = memory.create_vertex_buffer(uniform_indicies) self.indices_buffer = VertexBuffer(GLfloat, GL_STATIC_DRAW) self.indices_buffer.load(indices_buffer) self.indices_buffer.set(self.index_attr, 1) def render(self, model, color, num_turtles): self.program.bind() # no VAOs so have to set manually self.vertex_buffer.partition( [(self.vertex_attr, 4), (self.edge_attr, 3)] ) self.indices_buffer.set(self.index_attr, 1) model_uniform = self.program.uniforms['turtle_model_array[0]'] color_uniform = self.program.uniforms['turtle_color_array[0]'] model_iter = model.slice(self.batch) color_iter = color.slice(self.batch) slices = zip(model_iter, color_iter) with measure("loop"): for (msize, model_slice), (csize, color_slice) in slices: assert msize == csize # load batch of turtle data with measure('load'): model_uniform.set(model_slice, size=msize) color_uniform.set(color_slice, size=msize) with measure('draw'): glDrawArrays( GL_TRIANGLES, 0, len(self.geometry.edges) // 7 * msize, ) self.vertex_buffer.unbind() self.program.unbind()
class ESTurtleShapeRenderer(object): """A Renderer for rendering mutliple versions of a specific turtle shape. Creates vertex/index/model arrays, and can render them given turtle data.""" def __init__(self, name, program, geometry): self.name = name self.program = program self.geometry = geometry # size of batched draw calls self.batch = BATCH_SIZE self.vertex_attr = glGetAttribLocation(self.program.id, b"vertex") self.edge_attr = glGetAttribLocation(self.program.id, b"edge") self.index_attr = glGetAttribLocation(self.program.id, b"index") # load/bind/configure vertex buffer self.vertex_buffer = VertexBuffer(GLfloat, GL_STATIC_DRAW) batched_edges = list(geometry.edges) * self.batch self.vertex_buffer.load(memory.create_vertex_buffer(batched_edges)) self.vertex_buffer.partition([(self.vertex_attr, 4), (self.edge_attr, 3)]) uniform_indicies = [] for i in range(self.batch): uniform_indicies.extend([i] * geometry.num_vertex) indices_buffer = memory.create_vertex_buffer(uniform_indicies) self.indices_buffer = VertexBuffer(GLfloat, GL_STATIC_DRAW) self.indices_buffer.load(indices_buffer) self.indices_buffer.set(self.index_attr, 1) def render(self, model, color, num_turtles): self.program.bind() # no VAOs so have to set manually self.vertex_buffer.partition([(self.vertex_attr, 4), (self.edge_attr, 3)]) self.indices_buffer.set(self.index_attr, 1) model_uniform = self.program.uniforms['turtle_model_array[0]'] color_uniform = self.program.uniforms['turtle_color_array[0]'] model_iter = model.slice(self.batch) color_iter = color.slice(self.batch) slices = zip(model_iter, color_iter) with measure("loop"): for (msize, model_slice), (csize, color_slice) in slices: assert msize == csize # load batch of turtle data with measure('load'): model_uniform.set(model_slice, size=msize) color_uniform.set(color_slice, size=msize) with measure('draw'): glDrawArrays( GL_TRIANGLES, 0, len(self.geometry.edges) // 7 * msize, ) self.vertex_buffer.unbind() self.program.unbind()