def paint(): n = 100 data = np.hstack( (.2 * np.random.randn(n, 2), np.random.rand(n, 4))).astype(np.float32) vs = compile_shader(VS, gl.GL_VERTEX_SHADER) fs = compile_shader(FS, gl.GL_FRAGMENT_SHADER) shaders_program = link_shader_program(vs, fs) buffer = gl.glGenBuffers(1) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, buffer) gl.glBufferData(gl.GL_ARRAY_BUFFER, data, gl.GL_STATIC_DRAW) l = gl.glGetAttribLocation(shaders_program, "position") gl.glVertexAttribPointer(l, 2, gl.GL_FLOAT, gl.GL_FALSE, 0, None) gl.glEnableVertexAttribArray(l) lc = gl.glGetAttribLocation(shaders_program, "color") gl.glVertexAttribPointer(lc, 4, gl.GL_FLOAT, gl.GL_FALSE, 2 * 4, None) gl.glEnableVertexAttribArray(lc) gl.glUseProgram(shaders_program) gl.glViewport(0, 0, 500, 500) gl.glClearColor(0., 0., 0., 1.) gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT) gl.glEnable(gl.GL_BLEND) gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, buffer) gl.glDrawArrays(gl.GL_TRIANGLE_STRIP, 0, data.shape[0])
def on_paint(self, event): # Technically, we would only need to set u_time on every draw, # because the program is enabled at the beginning and never disabled. # In vispy, the program is re-enabled at each draw though and we # want to keep the code similar. gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT) # Activate program and texture gl.glUseProgram(self._prog_handle) gl.glBindTexture(gl.GL_TEXTURE_2D, self._tex_handle) # Update VBO gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._vbo_handle) gl.glBufferData(gl.GL_ARRAY_BUFFER, vertex_data.nbytes, vertex_data, gl.GL_DYNAMIC_DRAW) # Set attributes (again, the loc can be cached) loc = gl.glGetAttribLocation(self._prog_handle, 'a_lifetime'.encode('utf-8')) gl.glEnableVertexAttribArray(loc) gl.glVertexAttribPointer(loc, 1, gl.GL_FLOAT, False, 7 * 4, ctypes.c_voidp(0)) # loc = gl.glGetAttribLocation(self._prog_handle, 'a_startPosition'.encode('utf-8')) gl.glEnableVertexAttribArray(loc) gl.glVertexAttribPointer(loc, 3, gl.GL_FLOAT, False, 7 * 4, ctypes.c_voidp(1 * 4)) # loc = gl.glGetAttribLocation(self._prog_handle, 'a_endPosition'.encode('utf-8')) gl.glEnableVertexAttribArray(loc) gl.glVertexAttribPointer(loc, 3, gl.GL_FLOAT, False, 7 * 4, ctypes.c_voidp(4 * 4)) # loc = gl.glGetUniformLocation(self._prog_handle, 'u_color'.encode('utf-8')) gl.glUniform4f(loc, *self._color) # Set unforms loc = gl.glGetUniformLocation(self._prog_handle, 'u_time'.encode('utf-8')) gl.glUniform1f(loc, time.time() - self._starttime) # loc = gl.glGetUniformLocation(self._prog_handle, 'u_centerPosition'.encode('utf-8')) gl.glUniform3f(loc, *self._centerpos) # Draw gl.glDrawArrays(gl.GL_POINTS, 0, N) # New explosion? if time.time() - self._starttime > 1.5: self._new_explosion() # Redraw as fast as we can self.update()
def on_paint(self, event): # Technically, we would only need to set u_time on every draw, # because the program is enabled at the beginning and never disabled. # In vispy, the program is re-enabled at each draw though and we # want to keep the code similar. gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT) # Activate program and texture gl.glUseProgram(self._prog_handle) gl.glBindTexture(gl.GL_TEXTURE_2D, self._tex_handle) # Update VBO gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._vbo_handle) gl.glBufferData(gl.GL_ARRAY_BUFFER, vertex_data.nbytes, vertex_data, gl.GL_DYNAMIC_DRAW) # Set attributes (again, the loc can be cached) loc = gl.glGetAttribLocation(self._prog_handle, 'a_lifetime'.encode('utf-8')) gl.glEnableVertexAttribArray(loc) gl.glVertexAttribPointer(loc, 1, gl.GL_FLOAT, False, 7*4, ctypes.c_voidp(0)) # loc = gl.glGetAttribLocation(self._prog_handle, 'a_startPosition'.encode('utf-8')) gl.glEnableVertexAttribArray(loc) gl.glVertexAttribPointer(loc, 3, gl.GL_FLOAT, False, 7*4, ctypes.c_voidp(1*4)) # loc = gl.glGetAttribLocation(self._prog_handle, 'a_endPosition'.encode('utf-8')) gl.glEnableVertexAttribArray(loc) gl.glVertexAttribPointer(loc, 3, gl.GL_FLOAT, False, 7*4, ctypes.c_voidp(4*4)) # loc = gl.glGetUniformLocation(self._prog_handle, 'u_color'.encode('utf-8')) gl.glUniform4f(loc, *self._color) # Set unforms loc = gl.glGetUniformLocation(self._prog_handle, 'u_time'.encode('utf-8')) gl.glUniform1f(loc, time.time()-self._starttime) # loc = gl.glGetUniformLocation(self._prog_handle, 'u_centerPosition'.encode('utf-8')) gl.glUniform3f(loc, *self._centerpos) # Draw gl.glDrawArrays(gl.GL_POINTS, 0, N) # New explosion? if time.time() - self._starttime > 1.5: self._new_explosion() # Redraw as fast as we can self.update()
def paint(): n = 100 data = np.hstack(( .2 * np.random.randn(n, 2), np.random.rand(n, 4) )).astype(np.float32) vs = compile_shader(VS, gl.GL_VERTEX_SHADER) fs = compile_shader(FS, gl.GL_FRAGMENT_SHADER) shaders_program = link_shader_program(vs, fs) buffer = gl.glGenBuffers(1) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, buffer) gl.glBufferData(gl.GL_ARRAY_BUFFER, data, gl.GL_STATIC_DRAW) l = gl.glGetAttribLocation(shaders_program, "position") gl.glVertexAttribPointer(l, 2, gl.GL_FLOAT, gl.GL_FALSE, 0, None) gl.glEnableVertexAttribArray(l); lc = gl.glGetAttribLocation(shaders_program, "color") gl.glVertexAttribPointer(lc, 4, gl.GL_FLOAT, gl.GL_FALSE, 2 * 4, None) gl.glEnableVertexAttribArray(lc); gl.glUseProgram(shaders_program) gl.glViewport(0, 0, 500, 500) gl.glClearColor(0., 0., 0., 1.) gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT) gl.glEnable(gl.GL_BLEND) gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, buffer) gl.glDrawArrays(gl.GL_TRIANGLE_STRIP, 0, data.shape[0])
def draw_arrays(self, mode, first=0, count=None): """ Draw the attribute arrays in the specified mode. Only call when the program is enabled. Parameters ---------- mode : GL_ENUM GL_POINTS, GL_LINES, GL_LINE_STRIP, GL_LINE_LOOP, GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN first : int The starting vertex index in the vertex array. Default 0. count : int The number of vertices to draw. Default all. """ # Check if not self._active: raise ProgramError('ShaderProgram must be active when drawing.') # Upload any attributes and uniforms if necessary for variable in (self.attributes + self.uniforms): if variable.active: variable.upload(self) # Prepare refcount = self._get_vertex_count() if count is None: count = refcount elif refcount: if count > refcount: raise ValueError( 'Count is larger than known number of vertices.') # Check if we know count if count is None: raise ProgramError("Could not determine element count for draw.") # Draw gl.glDrawArrays(mode, first, count)
def draw_arrays(self, mode, first=0, count=None): """ Draw the attribute arrays in the specified mode. Only call when the program is enabled. Parameters ---------- mode : GL_ENUM GL_POINTS, GL_LINES, GL_LINE_STRIP, GL_LINE_LOOP, GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN first : int The starting vertex index in the vertex array. Default 0. count : int The number of vertices to draw. Default all. """ # Check if not self._active: raise ProgramError('ShaderProgram must be active when drawing.') # Upload any attributes and uniforms if necessary for variable in (self.attributes + self.uniforms): if variable.active: variable.upload(self) # Prepare refcount = self._get_vertex_count() if count is None: count = refcount elif refcount: if count > refcount: raise ValueError('Count is larger than known number of vertices.') # Check if we know count if count is None: raise ProgramError("Could not determine element count for draw.") # Draw gl.glDrawArrays(mode, first, count)
def draw(self, mode, subset=None): """ Draw the vertices in the specified mode. If the program is not active, it is activated to do the drawing and then deactivated. Parameters ---------- mode : str POINTS, LINES, LINE_STRIP, LINE_LOOP, TRIANGLES, TRIANGLE_STRIP, TRIANGLE_FAN. Case insensitive. Alternatively, the real GL enum can also be given. subset : {ElementBuffer, tuple} The subset of vertices to draw. This can be an ElementBuffer that specifies the indices of the vertices to draw, or a tuple that specifies the slice: (start, end). The second element in this tuple can be None to specify the maximum length. If the subset is not given or None, all vertices are drawn. """ # Check if active. If not, call recursively, but activated if not self._active: if self._error_enter: # An error message has already been shown, we stop here # because if we would continue we would very likely # just spew messages for spin-off errors. return with self: return self.draw(mode, subset) # Check mode mode = convert_to_enum(mode) if mode not in [gl.GL_POINTS, gl.GL_LINES, gl.GL_LINE_STRIP, gl.GL_LINE_LOOP, gl.GL_TRIANGLES, gl.GL_TRIANGLE_STRIP, gl.GL_TRIANGLE_FAN]: raise ValueError('Given mode is invalid: %r.' % mode) # Allow subset None if subset is None: subset = (0, None) # Upload any attributes and uniforms if necessary for variable in (self.attributes + self.uniforms): if variable.active: variable.upload(self) if isinstance(subset, ElementBuffer): # Draw elements # Prepare pointer or offset if isinstance(subset, ClientElementBuffer): ptr = subset.data else: ptr = None # Note that this can also be a ctypes.pointer offset # Activate self.activate_object(subset) # Prepare gltype = ElementBuffer.DTYPE2GTYPE[subset.dtype.name] if gltype == gl.GL_UNSIGNED_INT and not ext_available('element_index_uint'): raise ValueError('element_index_uint extension needed for uint32 ElementBuffer.') # Draw gl.glDrawElements(mode, subset.count, gltype, ptr) elif isinstance(subset, tuple): # Draw arrays # Check tuple ok = [isinstance(i, (int, type(None))) for i in subset] if len(subset) != 2 or not all(ok): raise ValueError('Subset must be a two-element tuple with ' 'interegers or None.') # Get start, end, refcount start, end = subset start = start or 0 refcount = self._get_vertex_count() # Determine count if end is None: count = refcount if count is None: raise ProgramError("Could not determine element count for draw.") else: count = end - start if refcount and count > refcount: raise ValueError('Count is larger than known number of vertices.') # Draw gl.glDrawArrays(mode, start, count) else: raise ValueError('Given subset is of invalid type: %r.' % type(subset))