def append(self, vertices, indices, uniforms): vertices = vertices.astype(self.vertices_data.dtype) indices = indices.astype(self.indices_data.dtype) uniforms = uniforms.astype(self.uniforms_data.dtype) VertexBuffer.append(self, vertices, indices) # Test if current uniforms capacity is big enough to hold new data if self.uniforms_size + 1 >= self.uniforms_capacity: capacity = int(2**np.ceil(np.log2(self.uniforms_size + 1))) self.uniforms_data = np.resize( self.uniforms_data, (capacity,1) ) self.uniforms_capacity = len(self.uniforms_data) # Add uniforms data ustart, uend = self.uniforms_size, self.uniforms_size+1 self.uniforms_data[ustart] = uniforms # Keep track of new object vstart,vend,istart,iend = self.objects[-1] self.objects[-1] = self,vstart,vend,istart,iend,ustart,uend # Update uniforms size self.uniforms_size += 1 self.dirty = True """
def append(self, vertices, indices, uniforms): vertices = vertices.astype(self.vertices_data.dtype) indices = indices.astype(self.indices_data.dtype) uniforms = uniforms.astype(self.uniforms_data.dtype) VertexBuffer.append(self, vertices, indices) # Test if current uniforms capacity is big enough to hold new data if self.uniforms_size + 1 >= self.uniforms_capacity: capacity = int(2**np.ceil(np.log2(self.uniforms_size + 1))) self.uniforms_data = np.resize(self.uniforms_data, (capacity, 1)) self.uniforms_capacity = len(self.uniforms_data) # Add uniforms data ustart, uend = self.uniforms_size, self.uniforms_size + 1 self.uniforms_data[ustart] = uniforms # Keep track of new object vstart, vend, istart, iend = self.objects[-1] self.objects[-1] = self, vstart, vend, istart, iend, ustart, uend # Update uniforms size self.uniforms_size += 1 self.dirty = True """
# vertices v = [ [ 1, 1, 1], [-1, 1, 1], [-1,-1, 1], [ 1,-1, 1], [ 1,-1,-1], [ 1, 1,-1], [-1, 1,-1], [-1,-1,-1] ] # normals n = [ [ 0, 0, 1], [ 1, 0, 0], [ 0, 1, 0] , [-1, 0, 1], [ 0,-1, 0], [ 0, 0,-1] ] # colors c = [ [0, 1, 1, 1], [0, 0, 1, 1], [0, 0, 0, 1], [0, 1, 0, 1], [1, 1, 0, 1], [1, 1, 1, 1], [1, 0, 1, 1], [1, 0, 0, 1] ]; V = np.array([(v[0],n[0],c[0]), (v[1],n[0],c[1]), (v[2],n[0],c[2]), (v[3],n[0],c[3]), (v[0],n[1],c[0]), (v[3],n[1],c[3]), (v[4],n[1],c[4]), (v[5],n[1],c[5]), (v[0],n[2],c[0]), (v[5],n[2],c[5]), (v[6],n[2],c[6]), (v[1],n[2],c[1]), (v[1],n[3],c[1]), (v[6],n[3],c[6]), (v[7],n[3],c[7]), (v[2],n[3],c[2]), (v[7],n[4],c[7]), (v[4],n[4],c[4]), (v[3],n[4],c[3]), (v[2],n[4],c[2]), (v[4],n[5],c[4]), (v[7],n[5],c[7]), (v[6],n[5],c[6]), (v[5],n[5],c[5]) ], dtype = vtype) I = np.resize( np.array([0,1,2,0,2,3], dtype=np.uint32), 6*(2*3)) I += np.repeat( 4*np.arange(2*3), 6) cube = VertexBuffer(vtype) cube.append(V,I) I = np.resize( np.array([0,1,1,2,2,3,3,0], dtype=np.uint32), 6*(2*4)) I += np.repeat( 4*np.arange(6), 8) outline = VertexBuffer(vtype) outline.append(V,I) shader = Shader(open("./cube.vert").read(), open("./cube.frag").read()) glut.glutMainLoop()
gl.glPolygonOffset(1, 1) gl.glClearColor(.3, .3, .35, 1) gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA) gl.glEnable(gl.GL_LINE_SMOOTH) projection = np.eye(4, dtype=np.float32) view = np.eye(4, dtype=np.float32) theta, phi = 0, 0 vtype = [('position', np.float32, 3), ('normal', np.float32, 3), ('color', np.float32, 4)] vertices, normals, faces = load_obj('./bunny.obj') V = np.zeros(len(vertices), dtype=vtype) V['position'] = vertices V['color'] = 1, 1, 1, 1 V['normal'] = normals obj = VertexBuffer(vtype) obj.append(V, faces) outline = VertexBuffer(vtype) I = [] for f in faces: I.extend([f[0], f[1], f[1], f[2], f[2], f[0]]) outline.append(V, I) shader = Shader(open("./cube.vert").read(), open("./cube.frag").read()) glut.glutMainLoop()
gl.glBlendFunc( gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA ) gl.glEnable( gl.GL_LINE_SMOOTH ) projection = np.eye(4,dtype=np.float32) view = np.eye(4,dtype=np.float32) theta, phi = 0,0 vtype = [('position', np.float32, 3), ('normal' , np.float32, 3), ('color', np.float32, 4)] vertices, normals, faces = load_obj('./bunny.obj') V = np.zeros(len(vertices), dtype=vtype) V['position'] = vertices V['color'] = 1,1,1,1 V['normal'] = normals obj = VertexBuffer(vtype) obj.append(V, faces) outline = VertexBuffer(vtype) I = [] for f in faces: I.extend([f[0],f[1],f[1],f[2],f[2],f[0]]) outline.append(V, I) shader = Shader(open("./cube.vert").read(), open("./cube.frag").read()) glut.glutMainLoop()
glut.glutInitDisplayMode(glut.GLUT_DOUBLE | glut.GLUT_RGB | glut.GLUT_DEPTH) glut.glutCreateWindow("Thick lines") glut.glutReshapeWindow(800, 800) glut.glutDisplayFunc(on_display) glut.glutReshapeFunc(on_reshape) glut.glutKeyboardFunc(on_keyboard) glut.glutIdleFunc(on_idle) shader = Shader(open("line-uniform.vert").read(), open("line-uniform.frag").read()) S = star() vtype = np.dtype( [ ("prev2", "f4", 2), ("prev", "f4", 2), ("curr", "f4", 2), ("next", "f4", 2), ("next2", "f4", 2), ("vid", "f4", 1), ] ) line = VertexBuffer(vtype) np.random.seed(1) for i in range(1000): s = np.random.uniform(0.025, 0.100) x, y = np.random.uniform(0, 800, 2) V, I = bake(S * s + (x, y), closed=True) line.append(V, I) glut.glutMainLoop()
t0 = glut.glutGet(glut.GLUT_ELAPSED_TIME) glut.glutInit(sys.argv) glut.glutInitDisplayMode(glut.GLUT_DOUBLE | glut.GLUT_RGB | glut.GLUT_DEPTH) glut.glutCreateWindow("Thick lines") glut.glutReshapeWindow(800, 800) glut.glutDisplayFunc(on_display) glut.glutReshapeFunc(on_reshape) glut.glutKeyboardFunc(on_keyboard) glut.glutIdleFunc(on_idle) shader = Shader( open('line-uniform.vert').read(), open('line-uniform.frag').read() ) S = star() vtype = np.dtype([('prev2', 'f4', 2), ('prev', 'f4', 2), ('curr', 'f4', 2), ('next', 'f4', 2), ('next2', 'f4', 2), ('vid', 'f4', 1) ] ) line = VertexBuffer(vtype) np.random.seed(1) for i in range(1000): s = np.random.uniform(0.025,0.100) x,y = np.random.uniform(0,800,2) V,I = bake( S*s + (x,y), closed=True) line.append(V,I) glut.glutMainLoop()
class Collection(object): join = {'miter': 0, 'round': 1, 'bevel': 2} caps = { '': 0, 'none': 0, '.': 0, 'round': 1, ')': 1, '(': 1, 'o': 1, 'triangle in': 2, '<': 2, 'triangle out': 3, '>': 3, 'square': 4, '=': 4, 'butt': 4, '|': 5 } # --------------------------------- def __init__(self, vtype, utype): self.dash_atlas = None # Convert types to lists (in case they were already dtypes) such that # we can append new fields vtype = eval(str(np.dtype(vtype))) utype = eval(str(np.dtype(utype))) # We add a uniform index to access uniform data from texture vtype.append(('a_index', 'f4')) # Check if given utype is made of float32 only rutype = dtype_reduce(utype) if type(rutype[0]) is not str or rutype[2] != 'float32': raise CollectionError( "Uniform type cannot de reduced to float32 only") else: count = rutype[1] size = count // 4 if count % 4: size += 1 utype.append(('unnused', 'f4', size * 4 - count)) count = size * 4 self.utype = utype self._vbuffer = VertexBuffer(vtype) self._ubuffer = DynamicBuffer(utype) self._ubuffer_id = 0 self._ubuffer_shape = [0, count] self._dirty = True # --------------------------------- def __len__(self): return len(self._vbuffer) # --------------------------------- def __getitem__(self, key): V = self._vbuffer.vertices[key] I = self._vbuffer.indices[key] U = self._ubuffer[key] return Item(self, key, V, I, U) # --------------------------------- def __delitem__(self, key): start, end = self._vbuffer.vertices.range(key) del self._vbuffer[key] del self._ubuffer[key] self._vbuffer.vertices.data['a_index'][start:] -= 1 self._vbuffer._dirty = True self._dirty = True # --------------------------------- def get_vertices(self): return self._vbuffer.vertices vertices = property(get_vertices) # --------------------------------- def get_indices(self): return self._vbuffer.indices indices = property(get_indices) # --------------------------------- def get_uniforms(self): return self._ubuffer uniforms = property(get_uniforms) # --------------------------------- def __getattr__(self, name): if hasattr(self, '_ubuffer'): buffer = object.__getattribute__(self, '_ubuffer') if name in buffer.dtype.names: return buffer.data[name] return object.__getattribute__(self, name) # --------------------------------- def __setattr__(self, name, value): object.__setattr__(self, name, value) if hasattr(self, '_ubuffer'): buffer = object.__getattribute__(self, '_ubuffer') if name in buffer.dtype.names: buffer.data[name] = value # buffer._dirty = True object.__setattr__(self, '_dirty', True) object.__setattr__(self, name, value) # --------------------------------- def clear(self): self._vbuffer.clear() self._ubuffer.clear() self._dirty = True # --------------------------------- def append(self, vertices, indices, uniforms): vertices = np.array(vertices).astype(self._vbuffer.vertices.dtype) indices = np.array(indices).astype(self._vbuffer.indices.dtype) uniforms = np.array(uniforms).astype(self._ubuffer.dtype) vertices['a_index'] = len(self) self._vbuffer.append(vertices, indices) self._ubuffer.append(uniforms) self._ubuffer_shape[0] = len(self) self._dirty = True # --------------------------------- def upload(self): if not self._dirty: return self._vbuffer.upload() gl.glActiveTexture(gl.GL_TEXTURE0) data = self._ubuffer.data.view(np.float32) shape = self._ubuffer_shape if not self._ubuffer_id: self._ubuffer_id = gl.glGenTextures(1) gl.glBindTexture(gl.GL_TEXTURE_2D, self._ubuffer_id) gl.glPixelStorei(gl.GL_UNPACK_ALIGNMENT, 1) gl.glPixelStorei(gl.GL_PACK_ALIGNMENT, 1) gl.glTexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_NEAREST) gl.glTexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_NEAREST) gl.glTexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_CLAMP_TO_EDGE) gl.glTexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_CLAMP_TO_EDGE) gl.glTexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_BASE_LEVEL, 0) gl.glTexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAX_LEVEL, 0) gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGBA32F, shape[1] // 4, shape[0], 0, gl.GL_RGBA, gl.GL_FLOAT, data) gl.glActiveTexture(gl.GL_TEXTURE0) gl.glBindTexture(gl.GL_TEXTURE_2D, self._ubuffer_id) gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGBA32F, shape[1] // 4, shape[0], 0, gl.GL_RGBA, gl.GL_FLOAT, data) #gl.glTexSubImage2D( gl.GL_TEXTURE_2D,0, 0, 0, shape[1]//4, shape[0], # gl.GL_RGBA, gl.GL_FLOAT, data); self._dirty = False # --------------------------------- def bake(self, vertices): raise NotImplemented # --------------------------------- def draw(self): if self._dirty: self.upload() gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA) gl.glEnable(gl.GL_BLEND) _, _, width, height = gl.glGetIntegerv(gl.GL_VIEWPORT) P = orthographic(0, width, 0, height, -1, +1) V = np.eye(4).astype(np.float32) M = np.eye(4).astype(np.float32) shader = self.shader shader.bind() gl.glActiveTexture(gl.GL_TEXTURE0) shader.uniformi('u_uniforms', 0) gl.glBindTexture(gl.GL_TEXTURE_2D, self._ubuffer_id) if self.dash_atlas: gl.glActiveTexture(gl.GL_TEXTURE1) shader.uniformi('u_dash_atlas', 1) gl.glBindTexture(gl.GL_TEXTURE_2D, self.dash_atlas.texture_id) shader.uniform_matrixf('u_M', M) shader.uniform_matrixf('u_V', V) shader.uniform_matrixf('u_P', P) shape = self._ubuffer_shape shader.uniformf('u_uniforms_shape', shape[1] // 4, shape[0]) self._vbuffer.draw() shader.unbind()
class Collection(object): join = { 'miter' : 0, 'round' : 1, 'bevel' : 2 } caps = { '' : 0, 'none' : 0, '.' : 0, 'round' : 1, ')' : 1, '(' : 1, 'o' : 1, 'triangle in' : 2, '<' : 2, 'triangle out' : 3, '>' : 3, 'square' : 4, '=' : 4, 'butt' : 4, '|' : 5 } # --------------------------------- def __init__(self, vtype, utype): self.dash_atlas = None # Convert types to lists (in case they were already dtypes) such that # we can append new fields vtype = eval(str(np.dtype(vtype))) utype = eval(str(np.dtype(utype))) # We add a uniform index to access uniform data from texture vtype.append( ('a_index', 'f4') ) # Check if given utype is made of float32 only rutype = dtype_reduce(utype) if type(rutype[0]) is not str or rutype[2] != 'float32': raise CollectionError("Uniform type cannot de reduced to float32 only") else: count = rutype[1] size = count//4 if count % 4: size += 1 utype.append(('unnused', 'f4', size*4-count)) count = size*4 self.utype = utype self._vbuffer = VertexBuffer(vtype) self._ubuffer = DynamicBuffer( utype ) self._ubuffer_id = 0 self._ubuffer_shape = [0,count] self._dirty = True # --------------------------------- def __len__(self): return len(self._vbuffer) # --------------------------------- def __getitem__(self, key): V = self._vbuffer.vertices[key] I = self._vbuffer.indices[key] U = self._ubuffer[key] return Item(self, key, V, I, U) # --------------------------------- def __delitem__(self, key): start,end = self._vbuffer.vertices.range(key) del self._vbuffer[key] del self._ubuffer[key] self._vbuffer.vertices.data['a_index'][start:] -= 1 self._vbuffer._dirty = True self._dirty = True # --------------------------------- def get_vertices(self): return self._vbuffer.vertices vertices = property(get_vertices) # --------------------------------- def get_indices(self): return self._vbuffer.indices indices = property(get_indices) # --------------------------------- def get_uniforms(self): return self._ubuffer uniforms = property(get_uniforms) # --------------------------------- def __getattr__(self, name): if hasattr(self, '_ubuffer'): buffer = object.__getattribute__(self,'_ubuffer') if name in buffer.dtype.names: return buffer.data[name] return object.__getattribute__(self,name) # --------------------------------- def __setattr__(self, name, value): object.__setattr__(self, name, value) if hasattr(self, '_ubuffer'): buffer = object.__getattribute__(self,'_ubuffer') if name in buffer.dtype.names: buffer.data[name] = value # buffer._dirty = True object.__setattr__(self, '_dirty', True) object.__setattr__(self, name, value) # --------------------------------- def clear(self): self._vbuffer.clear() self._ubuffer.clear() self._dirty = True # --------------------------------- def append(self, vertices, indices, uniforms): vertices = np.array(vertices).astype(self._vbuffer.vertices.dtype) indices = np.array(indices).astype(self._vbuffer.indices.dtype) uniforms = np.array(uniforms).astype(self._ubuffer.dtype) vertices['a_index'] = len(self) self._vbuffer.append( vertices, indices) self._ubuffer.append( uniforms ) self._ubuffer_shape[0] = len(self) self._dirty = True # --------------------------------- def upload(self): if not self._dirty: return self._vbuffer.upload() gl.glActiveTexture( gl.GL_TEXTURE0 ) data = self._ubuffer.data.view(np.float32) shape = self._ubuffer_shape if not self._ubuffer_id: self._ubuffer_id = gl.glGenTextures(1) gl.glBindTexture( gl.GL_TEXTURE_2D, self._ubuffer_id ) gl.glPixelStorei( gl.GL_UNPACK_ALIGNMENT, 1 ) gl.glPixelStorei( gl.GL_PACK_ALIGNMENT, 1 ) gl.glTexParameterf( gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_NEAREST ) gl.glTexParameterf( gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_NEAREST ) gl.glTexParameterf( gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_CLAMP_TO_EDGE ) gl.glTexParameterf( gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_CLAMP_TO_EDGE ) gl.glTexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_BASE_LEVEL, 0) gl.glTexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAX_LEVEL, 0) gl.glTexImage2D( gl.GL_TEXTURE_2D, 0, gl.GL_RGBA32F, shape[1]//4, shape[0], 0, gl.GL_RGBA, gl.GL_FLOAT, data ) gl.glActiveTexture( gl.GL_TEXTURE0 ) gl.glBindTexture( gl.GL_TEXTURE_2D, self._ubuffer_id ) gl.glTexImage2D( gl.GL_TEXTURE_2D, 0, gl.GL_RGBA32F, shape[1]//4, shape[0], 0, gl.GL_RGBA, gl.GL_FLOAT, data ) #gl.glTexSubImage2D( gl.GL_TEXTURE_2D,0, 0, 0, shape[1]//4, shape[0], # gl.GL_RGBA, gl.GL_FLOAT, data); self._dirty = False # --------------------------------- def bake(self, vertices): raise NotImplemented # --------------------------------- def draw(self): if self._dirty: self.upload() gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA) gl.glEnable(gl.GL_BLEND) _,_,width,height = gl.glGetIntegerv( gl.GL_VIEWPORT ) P = orthographic( 0, width, 0, height, -1, +1 ) V = np.eye(4).astype( np.float32 ) M = np.eye(4).astype( np.float32 ) shader = self.shader shader.bind() gl.glActiveTexture( gl.GL_TEXTURE0 ) shader.uniformi( 'u_uniforms', 0 ) gl.glBindTexture( gl.GL_TEXTURE_2D, self._ubuffer_id ) if self.dash_atlas: gl.glActiveTexture( gl.GL_TEXTURE1 ) shader.uniformi('u_dash_atlas', 1) gl.glBindTexture( gl.GL_TEXTURE_2D, self.dash_atlas.texture_id ) shader.uniform_matrixf( 'u_M', M ) shader.uniform_matrixf( 'u_V', V ) shader.uniform_matrixf( 'u_P', P ) shape = self._ubuffer_shape shader.uniformf( 'u_uniforms_shape', shape[1]//4, shape[0]) self._vbuffer.draw( ) shader.unbind()
class Collection(object): # --------------------------------- def __init__(self, vtype, utype): # Convert types to lists (in case they were already dtypes) such that # we can append new fields vtype = eval(str(np.dtype(vtype))) utype = eval(str(np.dtype(utype))) # We add a uniform index to access uniform data from texture vtype.append( ('a_index', 'f4') ) # Check if given utype is made of float32 only rutype = dtype_reduce(utype) if type(rutype[0]) is not str or rutype[2] != 'float32': raise CollectionError("Uniform type cannot de reduced to float32 only") else: count = rutype[1] count2 = int(math.pow(2, math.ceil(math.log(count, 2)))) if (count2 - count) > 0: utype.append(('unused', 'f4', count2-count)) self._count = count2 self.utype = utype self._vbuffer = VertexBuffer(vtype) self._ubuffer = DynamicBuffer( utype ) self._ubuffer_id = 0 self._max_texture_size = gl.glGetInteger(gl.GL_MAX_TEXTURE_SIZE) self._compute_ushape(1) self._ubuffer.reserve( self._ushape[1] / (count/4) ) self._dirty = True # --------------------------------- def _compute_ushape(self, size=1): max_texsize = self._max_texture_size cols = max_texsize//(self._count/4) rows = (size // cols)+1 self._ushape = rows, cols*(self._count/4), self._count # --------------------------------- def __len__(self): return len(self._vbuffer) # --------------------------------- def __getitem__(self, key): V = self._vbuffer.vertices[key] I = self._vbuffer.indices[key] U = self._ubuffer[key] return Item(self, key, V, I, U) # --------------------------------- def __delitem__(self, key): start,end = self._vbuffer.vertices.range(key) del self._vbuffer[key] del self._ubuffer[key] self._vbuffer.vertices.data['a_index'][start:] -= 1 self._vbuffer._dirty = True self._dirty = True # --------------------------------- def get_vbuffer(self): return self._vbuffer vbuffer = property(get_vbuffer) # --------------------------------- def get_vertices(self): return self._vbuffer.vertices vertices = property(get_vertices) # --------------------------------- def get_indices(self): return self._vbuffer.indices indices = property(get_indices) # --------------------------------- def get_uniforms(self): return self._ubuffer uniforms = property(get_uniforms) # --------------------------------- def get_attributes(self): return self._vbuffer._attributes attributes = property(get_attributes) # --------------------------------- def __getattr__(self, name): if hasattr(self, '_ubuffer'): buffer = object.__getattribute__(self,'_ubuffer') if name in buffer.dtype.names: return buffer.data[name] return object.__getattribute__(self,name) # --------------------------------- def __setattr__(self, name, value): object.__setattr__(self, name, value) if hasattr(self, '_ubuffer'): buffer = object.__getattribute__(self,'_ubuffer') if name in buffer.dtype.names: buffer.data[name] = value # buffer._dirty = True object.__setattr__(self, '_dirty', True) object.__setattr__(self, name, value) # --------------------------------- def clear(self): self._vbuffer.clear() self._ubuffer.clear() self._dirty = True # --------------------------------- def append(self, vertices, indices, uniforms, splits=None): vertices = np.array(vertices).astype(self._vbuffer.vertices.dtype) indices = np.array(indices).astype(self._vbuffer.indices.dtype) uniforms = np.array(uniforms).astype(self._ubuffer.dtype) if splits is None: vertices['a_index'] = len(self) self._vbuffer.append( vertices, indices ) self._ubuffer.append( uniforms ) self._compute_ushape(len(self)) elif len(splits) == 2: vsize,isize = splits[0], splits[1] if (vertices.size % vsize) != 0: raise( RuntimeError, "Cannot split vertices data into %d pieces" % vsize) if (indices.size % isize) != 0: raise( RuntimeError, "Cannot split indices data into %d pieces" % vsize) vcount = vertices.size//vsize icount = indices.size//isize ucount = uniforms.size n = ucount if vcount != icount or vcount != ucount: raise( RuntimeError, "Vertices/indices/uniforms cannot be split") vertices['a_index'] = len(self)+np.repeat(np.arange(n),vsize) self._vbuffer.append( vertices, indices, (vsize,isize)) self._ubuffer.append( uniforms ) self._compute_ushape(len(self)) else: raise(RuntimeError, "Splits argument not understood") self._dirty = True # --------------------------------- def upload(self): if not self._dirty: return self._vbuffer.upload() self.upload_uniforms() self._dirty = False # --------------------------------- def upload_uniforms(self): gl.glActiveTexture( gl.GL_TEXTURE0 ) data = self._ubuffer.data.view(np.float32) shape = self._ushape if not self._ubuffer_id: self._ubuffer_id = gl.glGenTextures(1) gl.glBindTexture( gl.GL_TEXTURE_2D, self._ubuffer_id ) gl.glPixelStorei( gl.GL_UNPACK_ALIGNMENT, 1 ) gl.glPixelStorei( gl.GL_PACK_ALIGNMENT, 1 ) gl.glTexParameterf( gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_NEAREST ) gl.glTexParameterf( gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_NEAREST ) gl.glTexParameterf( gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_CLAMP_TO_EDGE ) gl.glTexParameterf( gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_CLAMP_TO_EDGE ) gl.glTexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_BASE_LEVEL, 0) gl.glTexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAX_LEVEL, 0) gl.glTexImage2D( gl.GL_TEXTURE_2D, 0, gl.GL_RGBA32F, shape[1], shape[0], 0, gl.GL_RGBA, gl.GL_FLOAT, data ) gl.glActiveTexture( gl.GL_TEXTURE0 ) gl.glBindTexture( gl.GL_TEXTURE_2D, self._ubuffer_id ) gl.glTexImage2D( gl.GL_TEXTURE_2D, 0, gl.GL_RGBA32F, shape[1], shape[0], 0, gl.GL_RGBA, gl.GL_FLOAT, data ) # --------------------------------- def draw(self, mode=gl.GL_TRIANGLES, uniforms = {}): if self._dirty: self.upload() shader = self.shader shader.bind() gl.glActiveTexture( gl.GL_TEXTURE0 ) shader.uniformi( 'u_uniforms', 0 ) gl.glBindTexture( gl.GL_TEXTURE_2D, self._ubuffer_id ) for name,value in uniforms.items(): shader.uniform(name, value) shader.uniformf('u_uniforms_shape', *self._ushape) self._vbuffer.draw(mode) shader.unbind()
class LineCollection(Collection): def __init__ (self, segments, linewidths = 1.0, colors = (0,0,0,1), caps = (1,1), transforms = (0,0,1,0), antialiased = 0.75): """ """ Collection.__init__(self) self.dtype = np.dtype( [('position', 'f4', 3), ('tex_coord', 'f4', 2), ('color', 'f4', 4), ('transform', 'f4', 4), ('tangent', 'f4', 2), ('cap', 'f4', 2), ('length', 'f4', 1), ('thickness', 'f4', 1), ('support', 'f4', 1)] ) vertices = np.zeros(0, dtype = self.dtype) self._buffer = VertexBuffer(vertices) self.append(segments, linewidths, colors, caps, transforms, antialiased) vert = open('./line.vert').read() frag = open('./line.frag').read() self._shader = Shader(vert,frag) def append(self, segments, linewidths = 1.0, colors = (0,0,0,1), caps = (1,1), transforms = (0,0,1,0), antialiased = 0.75): """ """ linewidths = np.atleast_1d(linewidths) colors = np.atleast_2d(colors) caps = np.atleast_2d(caps) transforms = np.atleast_2d(transforms) antialiased = np.atleast_1d(antialiased) for i,segment in enumerate(segments): thickness = linewidths[ i % len(linewidths)] color = colors[ i % len(colors)] cap = caps[ i % len(caps)] transform = transforms[ i % len(transforms)] support = antialiased[ i % len(antialiased)] # Points as array P = np.array(segment).reshape(len(segment),3).astype(float) # Tangent vectors T = np.zeros_like(P) T[:-1] = P[1:] - P[:-1] T[-1] = T[-2] T = T[:,0:2] L = np.sqrt(T[:,0]**2 + T[:,1]**2) T /= L.reshape(len(P),1) # Lengths L = np.cumsum(L) L[1:] = L[:-1] L[0] = 0 length = L[-1] # Special case for start and end caps L[0],L[-1] = -1, length+1 n = len(P) vertices = np.zeros(n, dtype = self.dtype) vertices['position'] = P vertices['tangent'] = T vertices['thickness'] = thickness vertices['color'] = color vertices['cap'] = cap vertices['length'] = length vertices['support'] = support vertices['transform'] = transform vertices['tex_coord'][:,0] = L vertices = np.repeat(vertices, 2) vertices['tex_coord'][0::2,1] = -1 vertices['tex_coord'][1::2,1] = +1 indices = np.resize( np.array([0,1,2,1,2,3], dtype=np.uint32), (n-1)*(2*3)) indices += np.repeat( 2*np.arange(n-1), 6) self._buffer.append( vertices, indices ) self._dirty = True
class EllipseCollection(Collection): def __init__ (self, centers, radii, linewidths = 1.0, edgecolors = (0,0,0,1), facecolors = (0,0,0,1), transforms = (0,0,1,0), antialiased = 0.75): """ """ Collection.__init__(self) self.dtype = np.dtype( [('position', 'f4', 3), ('tex_coord', 'f4', 2), ('color', 'f4', 4), ('facecolor', 'f4', 4), ('transform', 'f4', 4), ('radius', 'f4', 2), ('thickness', 'f4', 1), ('support', 'f4', 1)] ) vertices = np.zeros(0, dtype = self.dtype) self._buffer = VertexBuffer(vertices) self.append(centers, radii, linewidths, edgecolors, facecolors, transforms, antialiased) vert = open('./ellipse.vert').read() frag = open('./ellipse.frag').read() self._shader = Shader(vert,frag) def append (self, centers, radii, linewidths = 1.0, edgecolors = (0,0,0,1), facecolors = (0,0,0,1), transforms = (0,0,1,0), antialiased = 0.75): """ """ linewidths = np.atleast_1d(linewidths) radii = np.atleast_2d(radii) edgecolors = np.atleast_2d(edgecolors) facecolors = np.atleast_2d(facecolors) transforms = np.atleast_2d(transforms) antialiased = np.atleast_1d(antialiased) for i,center in enumerate(centers): thickness = linewidths[ i % len(linewidths)] edgecolor = edgecolors[ i % len(edgecolors)] facecolor = facecolors[ i % len(facecolors)] radius = radii[ i % len(radii)] transform = transforms[ i % len(transforms)] support = antialiased[ i % len(antialiased)] # Points as array P = np.array(center).reshape(1,3).astype(float) vertices = np.zeros(1, dtype = self.dtype) vertices['position'] = P vertices['thickness'] = thickness vertices['color'] = edgecolor vertices['facecolor'] = facecolor vertices['radius'] = radius vertices['support'] = support vertices['transform'] = transform vertices = np.repeat(vertices, 4) vertices['tex_coord'][0::4] = -1,-1 vertices['tex_coord'][1::4] = +1,-1 vertices['tex_coord'][2::4] = +1,+1 vertices['tex_coord'][3::4] = -1,+1 indices = np.array([0,1,2,0,2,3], dtype=np.uint32) self._buffer.append( vertices, indices ) self._dirty = True
u_projection = np.eye(4, dtype=np.float32) u_view = np.eye(4, dtype=np.float32) theta, phi = 0, 0 vtype = [('position', np.float32, 3), ('normal', np.float32, 3), ('color', np.float32, 4)] vertices, normals, faces = load_obj('obj/icosahedron.obj') V = np.zeros(len(vertices), dtype=vtype) V['position'] = vertices * .99 V['color'] = 1, 1, 1, 1 V['normal'] = normals obj = VertexBuffer(vtype) obj.append(V, faces) outline = DashLines() F = np.roll(faces.repeat(2, axis=1), -1, axis=1) F = F.reshape(len(F) * 3, 2) F = np.sort(F, axis=1) G = F.view(dtype=[('p0', F.dtype), ('p1', F.dtype)]) G = np.unique(G) for face in G: p0 = vertices[face['p0']] p1 = vertices[face['p1']] outline.append([p0, p1], fg_color=(0, 0, 0, 1), linewidth=0.01, dash_pattern="dashed", dash_caps=('o', 'o'))