class VertexBuffer(object): # --------------------------------- def __init__(self, dtype): # Parse vertices dtype and generate attributes gltypes = { 'float32': gl.GL_FLOAT, 'float' : gl.GL_DOUBLE, 'float64': gl.GL_DOUBLE, 'int8' : gl.GL_BYTE, 'uint8' : gl.GL_UNSIGNED_BYTE, 'int16' : gl.GL_SHORT, 'uint16' : gl.GL_UNSIGNED_SHORT, 'int32' : gl.GL_INT, 'uint32' : gl.GL_UNSIGNED_INT } dtype = np.dtype(dtype) names = dtype.names or [] stride = dtype.itemsize offset = 0 self._attributes = [] for i,name in enumerate(names): if dtype[name].subdtype is not None: gtype = str(dtype[name].subdtype[0]) count = reduce(lambda x,y:x*y, dtype[name].shape) else: gtype = str(dtype[name]) count = 1 if gtype not in gltypes.keys(): raise VertexBufferException('Data type not understood') gltype = gltypes[gtype] attribute = VertexAttribute(name,count,gltype,stride,offset) self._attributes.append( attribute ) offset += dtype[name].itemsize self._dsize = offset self._vertices = DynamicBuffer(dtype) self._indices = DynamicBuffer(np.uint32) self._vertices_id = 0 self._indices_id = 0 self._dirty = True # --------------------------------- def get_vertices(self): return self._vertices vertices = property(get_vertices) # --------------------------------- def get_indices(self): return self._indices indices = property(get_indices) # --------------------------------- def get_attributes(self): return self._attributes attributes = property(get_attributes) # --------------------------------- def clear(self): self._vertices.clear() self._indices.clear() self._dirty = True # --------------------------------- def append(self, vertices, indices, splits=None): vertices = np.array(vertices).astype(self._vertices.dtype).ravel() indices = np.array(indices).astype(self._indices.dtype).ravel() if splits is None: indices += len(self._vertices.data) self._vertices.append(vertices) self._indices.append(indices) return splits = np.array(splits) if splits.size == 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) n = vertices.size // vsize I = indices.reshape(indices.size / isize, isize) I += (np.arange(n) * vsize).reshape(n,1) self._vertices.append(vertices, int(vsize)) self._indices.append(indices, int(isize)) else: vsize,isize = splits[:,0], splits[:,1] if (vertices.size % vsize.sum()) != 0: raise( RuntimeError, "Cannot split vertices data into %d pieces" % vsize) if (indices.size % isize.sum()) != 0: raise( RuntimeError, "Cannot split indices data into %d pieces" % vsize) I = np.repeat(vsize.cumsum(),isize) indices[isize[0]:] += I[:-isize[0]] self._vertices.append(vertices,vsize) self._indices.append(indices,isize) self._dirty = True # --------------------------------- def __delitem__(self, key): vsize = len(self._vertices[key]) _,_,dstart,_ = self._indices._get_indices(key) del self._vertices[key] del self._indices[key] self._indices.data[dstart:] -= vsize self._dirty = True # --------------------------------- def __getitem__(self, key): return self._vertices[key], self._indices[key] # --------------------------------- def __len__(self): return len(self.vertices) # --------------------------------- def attribute(self, name): for a in self._attributes: if a.name == name: return a # --------------------------------- def upload(self): if not self._dirty: return if not self._vertices_id: self._vertices_id = gl.glGenBuffers(1) gl.glBindBuffer( gl.GL_ARRAY_BUFFER, self._vertices_id ) gl.glBufferData( gl.GL_ARRAY_BUFFER, self._vertices.data, gl.GL_DYNAMIC_DRAW ) gl.glBindBuffer( gl.GL_ARRAY_BUFFER, 0 ) if not self._indices_id: self._indices_id = gl.glGenBuffers(1) gl.glBindBuffer( gl.GL_ELEMENT_ARRAY_BUFFER, self._indices_id ) gl.glBufferData( gl.GL_ELEMENT_ARRAY_BUFFER, self._indices.data, gl.GL_DYNAMIC_DRAW ) gl.glBindBuffer( gl.GL_ELEMENT_ARRAY_BUFFER, 0 ) self._dirty = False # --------------------------------- def draw( self, mode=gl.GL_TRIANGLES ): if self._dirty: self.upload() gl.glBindBuffer( gl.GL_ARRAY_BUFFER, self._vertices_id ) gl.glBindBuffer( gl.GL_ELEMENT_ARRAY_BUFFER, self._indices_id ) for attribute in self._attributes: attribute.enable() gl.glDrawElements( mode, len(self._indices.data), gl.GL_UNSIGNED_INT, None) gl.glBindBuffer( gl.GL_ELEMENT_ARRAY_BUFFER, 0 ) gl.glBindBuffer( gl.GL_ARRAY_BUFFER, 0 )
class VertexBuffer(object): # --------------------------------- def __init__(self, dtype): # Parse vertices dtype and generate attributes gltypes = { 'float32': gl.GL_FLOAT, 'float' : gl.GL_DOUBLE, 'float64': gl.GL_DOUBLE, 'int8' : gl.GL_BYTE, 'uint8' : gl.GL_UNSIGNED_BYTE, 'int16' : gl.GL_SHORT, 'uint16' : gl.GL_UNSIGNED_SHORT, 'int32' : gl.GL_INT, 'uint32' : gl.GL_UNSIGNED_INT } dtype = np.dtype(dtype) names = dtype.names or [] stride = dtype.itemsize offset = 0 self._attributes = [] for i,name in enumerate(names): if dtype[name].subdtype is not None: gtype = str(dtype[name].subdtype[0]) count = reduce(lambda x,y:x*y, dtype[name].shape) else: gtype = str(dtype[name]) count = 1 if gtype not in gltypes.keys(): raise VertexBufferException('Data type not understood') gltype = gltypes[gtype] attribute = VertexAttribute(name,count,gltype,stride,offset) self._attributes.append( attribute ) offset += dtype[name].itemsize self._vertices = DynamicBuffer(dtype) self._indices = DynamicBuffer(np.uint32) self._vertices_id = 0 self._indices_id = 0 self._dirty = True # --------------------------------- def get_vertices(self): return self._vertices vertices = property(get_vertices) # --------------------------------- def get_indices(self): return self._indices indices = property(get_indices) # --------------------------------- def clear(self): self._vertices.clear() self._indices.clear() self._dirty = True # --------------------------------- def append(self, vertices, indices): vsize = len(self._vertices.data) vertices = np.array(vertices).astype(self._vertices.dtype) self._vertices.append(vertices) indices = np.array(indices).astype(self._indices.dtype) + vsize self._indices.append(indices) self._dirty = True # --------------------------------- def __delitem__(self, key): vsize = len(self._vertices[key]) _,_,dstart,_ = self._indices._get_indices(key) del self._vertices[key] del self._indices[key] self._indices.data[dstart:] -= vsize self._dirty = True # --------------------------------- def __getitem__(self, key): return self._vertices[key], self._indices[key] # --------------------------------- def __len__(self): return len(self.vertices) # --------------------------------- def upload(self): if not self._dirty: return if not self._vertices_id: self._vertices_id = gl.glGenBuffers(1) gl.glBindBuffer( gl.GL_ARRAY_BUFFER, self._vertices_id ) gl.glBufferData( gl.GL_ARRAY_BUFFER, self._vertices.data, gl.GL_DYNAMIC_DRAW ) gl.glBindBuffer( gl.GL_ARRAY_BUFFER, 0 ) if not self._indices_id: self._indices_id = gl.glGenBuffers(1) gl.glBindBuffer( gl.GL_ELEMENT_ARRAY_BUFFER, self._indices_id ) gl.glBufferData( gl.GL_ELEMENT_ARRAY_BUFFER, self._indices.data, gl.GL_DYNAMIC_DRAW ) gl.glBindBuffer( gl.GL_ELEMENT_ARRAY_BUFFER, 0 ) self._dirty = False # --------------------------------- def draw( self, mode=gl.GL_TRIANGLES ): if self._dirty: self.upload() gl.glBindBuffer( gl.GL_ARRAY_BUFFER, self._vertices_id ) gl.glBindBuffer( gl.GL_ELEMENT_ARRAY_BUFFER, self._indices_id ) for attribute in self._attributes: attribute.enable() gl.glDrawElements( mode, len(self._indices.data), gl.GL_UNSIGNED_INT, None) gl.glBindBuffer( gl.GL_ELEMENT_ARRAY_BUFFER, 0 ) gl.glBindBuffer( gl.GL_ARRAY_BUFFER, 0 )
class VertexBuffer(object): # --------------------------------- def __init__(self, dtype): # Parse vertices dtype and generate attributes gltypes = { 'float32': gl.GL_FLOAT, 'float': gl.GL_DOUBLE, 'float64': gl.GL_DOUBLE, 'int8': gl.GL_BYTE, 'uint8': gl.GL_UNSIGNED_BYTE, 'int16': gl.GL_SHORT, 'uint16': gl.GL_UNSIGNED_SHORT, 'int32': gl.GL_INT, 'uint32': gl.GL_UNSIGNED_INT } dtype = np.dtype(dtype) names = dtype.names or [] stride = dtype.itemsize offset = 0 self._attributes = [] for i, name in enumerate(names): if dtype[name].subdtype is not None: gtype = str(dtype[name].subdtype[0]) count = reduce(lambda x, y: x * y, dtype[name].shape) else: gtype = str(dtype[name]) count = 1 if gtype not in gltypes.keys(): raise VertexBufferException('Data type not understood') gltype = gltypes[gtype] attribute = VertexAttribute(name, count, gltype, stride, offset) self._attributes.append(attribute) offset += dtype[name].itemsize self._dsize = offset self._vertices = DynamicBuffer(dtype) self._indices = DynamicBuffer(np.uint32) self._vertices_id = 0 self._indices_id = 0 self._dirty = True # --------------------------------- def get_vertices(self): return self._vertices vertices = property(get_vertices) # --------------------------------- def get_indices(self): return self._indices indices = property(get_indices) # --------------------------------- def get_attributes(self): return self._attributes attributes = property(get_attributes) # --------------------------------- def clear(self): self._vertices.clear() self._indices.clear() self._dirty = True # --------------------------------- def append(self, vertices, indices, splits=None): vertices = np.array(vertices).astype(self._vertices.dtype).ravel() indices = np.array(indices).astype(self._indices.dtype).ravel() if splits is None: indices += len(self._vertices.data) self._vertices.append(vertices) self._indices.append(indices) return splits = np.array(splits) if splits.size == 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) n = vertices.size // vsize I = indices.reshape(indices.size / isize, isize) I += (np.arange(n) * vsize).reshape(n, 1) self._vertices.append(vertices, int(vsize)) self._indices.append(indices, int(isize)) else: vsize, isize = splits[:, 0], splits[:, 1] if (vertices.size % vsize.sum()) != 0: raise (RuntimeError, "Cannot split vertices data into %d pieces" % vsize) if (indices.size % isize.sum()) != 0: raise (RuntimeError, "Cannot split indices data into %d pieces" % vsize) I = np.repeat(vsize.cumsum(), isize) indices[isize[0]:] += I[:-isize[0]] self._vertices.append(vertices, vsize) self._indices.append(indices, isize) self._dirty = True # --------------------------------- def __delitem__(self, key): vsize = len(self._vertices[key]) _, _, dstart, _ = self._indices._get_indices(key) del self._vertices[key] del self._indices[key] self._indices.data[dstart:] -= vsize self._dirty = True # --------------------------------- def __getitem__(self, key): return self._vertices[key], self._indices[key] # --------------------------------- def __len__(self): return len(self.vertices) # --------------------------------- def attribute(self, name): for a in self._attributes: if a.name == name: return a # --------------------------------- def upload(self): if not self._dirty: return if not self._vertices_id: self._vertices_id = gl.glGenBuffers(1) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._vertices_id) gl.glBufferData(gl.GL_ARRAY_BUFFER, self._vertices.data, gl.GL_DYNAMIC_DRAW) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, 0) if not self._indices_id: self._indices_id = gl.glGenBuffers(1) gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, self._indices_id) gl.glBufferData(gl.GL_ELEMENT_ARRAY_BUFFER, self._indices.data, gl.GL_DYNAMIC_DRAW) gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, 0) self._dirty = False # --------------------------------- def draw(self, mode=gl.GL_TRIANGLES): if self._dirty: self.upload() gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._vertices_id) gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, self._indices_id) for attribute in self._attributes: attribute.enable() gl.glDrawElements(mode, len(self._indices.data), gl.GL_UNSIGNED_INT, None) gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, 0) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, 0)