Esempio n. 1
0
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()
Esempio n. 2
0
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()
Esempio n. 3
0
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()