예제 #1
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 )
예제 #2
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 )
예제 #3
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)