Esempio n. 1
0
class Scaled(Widget):
    def __init__(self, **kwargs):
        super(Scaled, self).__init__(**kwargs)

        self.elements = []
        self.pointsize = 5  # this multiplies by two according to kivy docs

        with self.canvas:
            self._fbo = Fbo(size=self.size)
            self._rect = Rectangle(texture=self._fbo.texture)

        with self._fbo:
            Color(1, 1, 1)
            self._fborect = Rectangle(size=self._fbo.size)
            Color(0, 0, 1)
            self._points = Point(pointsize=self.pointsize)

        self._fbo.add_reload_observer(self._clear_fbo)
        self.bind(pos=self._update_rect, size=self._update_rect)

    def drawpoint(self, x, y):
        self.elements.append([x, y])
        self._points.add_point(x, y)

    def draw(self, matrix):
        self._points.points = []
        self._clear_fbo()

        for point in matrix:
            x = int(point[0] * (self.pointsize * 2) + self.pointsize)
            y = int(point[1] * (self.pointsize * 2) + self.pointsize)
            self.drawpoint(x, y)

    # RELOADING THE BUFFER AT ANY CHANGE
    def _clear_fbo(self, fbo=None):
        ''' This will reload the framebufferer either by the call of the
        observer or by the deletion of a point'''
        if fbo is None:
            fbo = self._fbo

        fbo.bind()
        fbo.clear_buffer()
        fbo.add(Color(1, 1, 1))
        fbo.add(self._fborect)
        fbo.add(Color(0, 0, 1))
        fbo.add(self._points)
        fbo.release()

    def _update_rect(self, instance, value):
        self._fbo.size = instance.size
        self._fborect.size = instance.size
        self._rect.size = instance.size
        self._rect.pos = instance.pos
        self._rect.texture = self._fbo.texture
Esempio n. 2
0
class Scaled(Widget):
    def __init__(self, **kwargs):
        super(Scaled, self).__init__(**kwargs)

        self.elements = []
        self.pointsize = 5  # this multiplies by two according to kivy docs

        with self.canvas:
            self._fbo = Fbo(size=self.size)
            self._rect = Rectangle(texture=self._fbo.texture)

        with self._fbo:
            Color(1, 1, 1)
            self._fborect = Rectangle(size=self._fbo.size)
            Color(0, 0, 1)
            self._points = Point(pointsize=self.pointsize)

        self._fbo.add_reload_observer(self._clear_fbo)
        self.bind(pos=self._update_rect, size=self._update_rect)

    def drawpoint(self, x, y):
        self.elements.append([x, y])
        self._points.add_point(x, y)

    def draw(self, matrix):
        self._points.points = []
        self._clear_fbo()

        for point in matrix:
            x = int(point[0] * (self.pointsize * 2) + self.pointsize)
            y = int(point[1] * (self.pointsize * 2) + self.pointsize)
            self.drawpoint(x, y)

    # RELOADING THE BUFFER AT ANY CHANGE
    def _clear_fbo(self, fbo=None):
        """ This will reload the framebufferer either by the call of the
        observer or by the deletion of a point"""
        if fbo is None:
            fbo = self._fbo

        fbo.bind()
        fbo.clear_buffer()
        fbo.add(Color(1, 1, 1))
        fbo.add(self._fborect)
        fbo.add(Color(0, 0, 1))
        fbo.add(self._points)
        fbo.release()

    def _update_rect(self, instance, value):
        self._fbo.size = instance.size
        self._fborect.size = instance.size
        self._rect.size = instance.size
        self._rect.pos = instance.pos
        self._rect.texture = self._fbo.texture
Esempio n. 3
0
class GLWindow(BoxLayout):
    texture = ObjectProperty(None, allownone=True)

    def __init__(self, **kwargs):
        self.mesh_data = MeshData()
        self.canvas = Canvas()
        with self.canvas:
            self.fbo = Fbo(size=(10, 10), compute_normal_mat=True)
            self.fbo.add_reload_observer(self.populate_fbo)
        with self.fbo:
            ClearColor(0, 0, 0, 0)
            ClearBuffers()
        self.populate_fbo(self.fbo)

        super(GLWindow, self).__init__(**kwargs)

        Clock.schedule_interval(self.update_glsl, 1 / 60.)

    def populate_fbo(self, fbo):
        Logger.info("Setting up FBO")

        with self.canvas:
            fbo.shader.source = resource_find('simple.glsl')
            fbo['diffuse_light'] = (1.0, 1.0, 0.8)
            fbo['ambient_light'] = (0.8, 0.8, 0.8)

        with fbo:
            self.cb = Callback(self.setup_gl_context)
            PushMatrix()
            BindTexture(source='testure.jpg', index=1)
            UpdateNormalMatrix()
            Translate(0, 0, -3)
            self.rot = Rotate(1, 0, 1, 0)
            # self.show_axis()
            self.make_pretty_dots()
            PopMatrix()
            self.cb = Callback(self.reset_gl_context)
        fbo['texture1'] = 1

    def update_glsl(self, *largs):
        asp = self.size[0] / float(self.size[1])
        proj = Matrix().view_clip(-asp, asp, -1, 1, 1, 100, 1)
        model = Matrix().look_at(0.0, 0.0, 0.25, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0)
        with self.canvas:
            self.fbo.shader.source = resource_find('simple.glsl')
            self.fbo['projection_mat'] = proj
            self.fbo['modelview_mat'] = model
            self.rot.angle += -1
            self.texture = self.fbo.texture
        with self.fbo:
            BindTexture(source='testure.jpg', index=1)

    def setup_gl_context(self, *args):
        glEnable(GL_DEPTH_TEST)

    def reset_gl_context(self, *args):
        glDisable(GL_DEPTH_TEST)

    def on_size(self, instance, value):
        Logger.info('resize')
        self.fbo.size = value
        self.texture = self.fbo.texture

    def show_axis(self):
        Color(1, 1, 0, 1)  #Yellow
        Mesh(
            vertices=[
                -1,
                0,
                0,
                1,
                1,
                0,
                0,
                0,
                1,
                0,
                0,
                1,
                1,
                0,
                0,
                0,
                0.8,
                0.1,
                0,
                1,
                1,
                0,
                0,
                0,
                0.8,
                -0.1,
                0,
                1,
                1,
                0,
                0,
                0,
                1,
                0,
                0,
                1,
                1,
                0,
                0,
                0,
                0.8,
                0,
                -0.1,
                1,
                1,
                0,
                0,
                0,
                0.8,
                0,
                0.1,
                1,
                1,
                0,
                0,
                0,
                1,
                0,
                0,
                1,
                1,
                0,
                0,
                0,
            ],
            indices=[0, 1, 2, 3, 4, 5, 6, 7],
            fmt=self.mesh_data.vertex_format,
            mode='line_strip',
        )
        Color(1, 0, 1, 1)  # purple
        Mesh(
            vertices=[
                0,
                0,
                -1,
                0,
                1,
                1,
                0,
                0,
                0,
                0,
                1,
                0,
                1,
                1,
                0,
                0,
                0.1,
                0,
                0.8,
                0,
                1,
                1,
                0,
                0,
                -0.1,
                0,
                0.8,
                0,
                1,
                1,
                0,
                0,
                0,
                0,
                1,
                0,
                1,
                1,
                0,
                0,
                0,
                -0.1,
                0.8,
                0,
                1,
                1,
                0,
                0,
                0,
                0.1,
                0.8,
                0,
                1,
                1,
                0,
                0,
                0,
                0,
                1,
                0,
                1,
                1,
                0,
                0,
            ],
            indices=[0, 1, 2, 3, 4, 5, 6, 7],
            fmt=self.mesh_data.vertex_format,
            mode='line_strip',
        )
        Color(0, 1, 1, 1)  # Baby Blue
        Mesh(
            vertices=[
                0,
                -1,
                0,
                1,
                1,
                0,
                0,
                0,
                0,
                1,
                0,
                1,
                1,
                0,
                0,
                0,
                0.1,
                0.8,
                0,
                1,
                1,
                0,
                0,
                0,
                -0.1,
                0.8,
                0,
                1,
                1,
                0,
                0,
                0,
                0,
                1,
                0,
                1,
                1,
                0,
                0,
                0,
                0,
                0.8,
                -0.1,
                1,
                1,
                0,
                0,
                0,
                0,
                0.8,
                0.1,
                1,
                1,
                0,
                0,
                0,
                0,
                1,
                0,
                1,
                1,
                0,
                0,
                0,
            ],
            indices=[0, 1, 2, 3, 4, 5, 6, 7],
            fmt=self.mesh_data.vertex_format,
            mode='line_strip',
        )

    def make_pretty_dots(self):
        points_per_side = 50

        points = []
        for idx in range(points_per_side):
            v = -1.0 + ((2.0 / points_per_side) * float(idx))
            tex = idx / float(points_per_side)
            print("TEX: {}".format(str(tex)))
            points.append([[v, -1.0, -1.0, v, -1.0, -1.0, tex, 0.0],
                           [v, -1.0, 1.0, v, -1.0, 1.0, tex, 0.0],
                           [v, 1.0, -1.0, v, 1.0, -1.0, tex, 1.0],
                           [v, 1.0, 1.0, v, 1.0, 1.0, tex, 1.0],
                           [-1.0, v, -1.0, -1.0, v, -1.0, 0.0, tex],
                           [-1.0, v, 1.0, -1.0, v, 1.0, 0.0, tex],
                           [1.0, v, -1.0, 1.0, v, -1.0, 1.0, tex],
                           [1.0, v, 1.0, 1.0, v, 1.0, 1.0, tex],
                           [-1.0, -1.0, v, -1.0, -1.0, v, tex, tex],
                           [-1.0, 1.0, v, -1.0, 1.0, v, tex, tex],
                           [1.0, -1.0, v, 1.0, -1.0, v, tex, tex],
                           [1.0, 1.0, v, 1.0, 1.0, v, tex, tex]], )

        points = np.array(points).flatten()
        Color(1, 1, 1, 1)
        Mesh(
            vertices=points,
            indices=[i for i in range(len(points) / 8)],
            fmt=self.mesh_data.vertex_format,
            mode='points',
        )
Esempio n. 4
0
class FragmentCompute:
    def __init__(self, fs, length1, length2 = 1):
        size = (length1, length2)

        # it doesn't look like we can use float textures on mobile kivy, but people sometimes interconvert floats with 32bit rgba in shaders.
        # we would then have 3 shaders or texture rows or such, for x coord, y coord, angle, etc

        #Logger.info('float: ' + str(gl.getExtension('OES_texture_float')))
        texture = Texture.create(
            size = size,
            #bufferfmt = 'float'
        )
        self._fbo = Fbo(
            size = size,
            texture = texture,
            vs = default_vs,
            fs = header_fs + fs, 
        )

        # these matrices are to transform
        # window coordinates into data
        # coordinates
        centermat = Matrix()
        centermat.translate(-.5,-.5,-.5)
        idxscale = 1.0 / 255.0;
        idxmat = Matrix()
        idxmat.scale(idxscale, idxscale, idxscale)
        self._fbo['frag_coord2idx'] = idxmat.multiply(centermat)
        ratiomat = Matrix()
        ratiomat.scale(1.0 / length1, 1.0 / length2, 1.0)
        self._fbo['frag_coord2ratio'] = ratiomat

        self._texture_bindings = {}

        self._fbo.add_reload_observer(self._populate_fbo)
        self._populate_fbo(self._fbo)
    def texture(self):
        return self._fbo.texture
    def download(self):
        ## cgl requires cython,
        ## but glReadPixels is used in
        ## fbo.py, and could be used to
        ## get RGB instead of RGBA, since
        ## A is presently drawn blended,
        ## and maybe save a memory copy.
        #width, height = self._fbo.size
        #data = array('B', [1] * width * height * 4)
        #self._fbo.bind()
        #cgl.cgl.glPixelStorei(GL_PACK_ALIGNMENT, 1)
        #cgl.cgl.glReadPixels(0, 0, width, height, cgl.GL_RGB, cgl.GL_UNSIGNED_BYTE, data)
        #self._fbo.release()
        #return data
        return bytearray(self._fbo.pixels)
    def compute(self):
        self._rectangle.texture = self._fbo.texture
        self._fbo.draw()
        return self
    def __setitem__(self, name, value):
        if isinstance(value, Texture):
            if name in self._texture_bindings:
                index, oldvalue = self._texture_bindings[name]
            else:
                index = len(self._texture_bindings) + 1
            self._texture_bindings[name] = (index, value)
            self._fbo[name] = index 
            self._fbo.clear()
            self._populate_fbo(self._fbo)
        else:
            self._fbo[name] = value 

    def _populate_fbo(self, fbo):
        with fbo:
            for index, texture in self._texture_bindings.values():
                BindTexture(index = index, texture = texture)
            Callback(self._set_blend_mode)
            self._rectangle = Rectangle(size = self._fbo.size)
            Callback(self._unset_blend_mode)
    # opaque blend mode provides for use of the alpha channel for data
    def _set_blend_mode(self, instruction = None):
        gl.glBlendFunc(gl.GL_ONE, gl.GL_ZERO);
        gl.glBlendFuncSeparate(gl.GL_ONE, gl.GL_ZERO, gl.GL_ONE, gl.GL_ZERO);
    def _unset_blend_mode(self, instruction = None):
        gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA);
        gl.glBlendFuncSeparate(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA, gl.GL_ONE, gl.GL_ONE);
            
Esempio n. 5
0
class ObjectRenderer(BoxLayout):
    texture = ObjectProperty(None, allownone=True)
    mesh_mode = BooleanProperty(False)

    def __init__(self, **kwargs):
        self.lock = Lock()
        self.gl_depth = -3
        self.mesh_data = MeshData()
        self.mesh_data.vertices = np.array([0, 0, 0, 0, 0, 0, 0, 0])
        self.mesh_data.indices = np.array([0])
        self.points = None

        self.canvas = Canvas()
        with self.canvas:
            self.fbo = Fbo(size=(10, 10), compute_normal_mat=True)
            self.fbo.add_reload_observer(self.populate_fbo)
        with self.fbo:
            ClearColor(1, 1, 1, 1)
            ClearBuffers()

        self.populate_fbo(self.fbo)

        super(ObjectRenderer, self).__init__(**kwargs)
        Clock.schedule_interval(self.update_glsl, 1 / 10.)

    def on_size(self, instance, value):
        size = (max(1, value[0]), max(1, value[1]))
        self.fbo.size = size
        self.texture = self.fbo.texture

    def setup_gl_context(self, *args):
        glEnable(GL_DEPTH_TEST)

    def reset_gl_context(self, *args):
        glDisable(GL_DEPTH_TEST)


    def clear(self):
        if hasattr(self, 'model_texture'):
            self.mesh_data.vertices = np.array([0, 0, 0, 0, 0, 0, 0, 0])
            self.mesh_data.indices = np.array([0])
            del self.model_texture

    def update_texture(self, texture):
        if not hasattr(self, 'model_texture'):
            self.model_texture = texture
            self.populate_fbo(self.fbo)

    def update_glsl(self, *largs):
        # self.fbo.shader.source = resource_find('simple.glsl')
        asp = max(10, self.size[0]) / max(10, float(self.size[1]))
        proj = Matrix().view_clip(-asp, asp, -1, 1, 1, 100, 1)
        model = Matrix().look_at(   0.0, 0.0, 0.0,   0.0, 0.0, -3.0,   0.0, 1.0, 0.0)
        proj = Matrix().view_clip(-asp, asp, -1, 1, 1, 100, 1)
        with self.canvas:
            self.fbo['projection_mat'] = proj
            self.fbo['modelview_mat'] = model
        self.mesh.vertices = self.mesh_data.vertices
        self.mesh.indices = self.mesh_data.indices
        self.rot.angle += -3

    def update_mesh(self, points):
        self.points = points
        points = np.array(points)[::8]
        points = points.flatten()

        self.mesh_data.vertices = points
        indicies = np.arange(len(points) // 8)
        if self.mesh_mode:
            idx = []
            y = 0
            x = 0
            z = 0
            for pos in range(1, len(indicies)):
                if points[(indicies[pos] * 8) + 2] > z:
                    A = indicies[pos - 1]
                    B = indicies[pos]
                    idx.extend([A, B])
                (x,y,z) = points[(indicies[pos] * 8) : (indicies[pos] * 8 ) + 3]

            self.mesh_data.indices = idx
            self.mesh.mode = 'lines'
        else:
            self.mesh_data.indices = indicies
            self.mesh.mode = 'points'

    def populate_fbo(self, fbo):
        with self.canvas:
            fbo.shader.source = resource_find('simple.glsl')
            fbo['diffuse_light'] = (1.0, 1.0, 0.8)
            fbo['ambient_light'] = (0.5, 0.5, 0.5)

        with fbo:
            self.cb = Callback(self.setup_gl_context)
            PushMatrix()
            if hasattr(self, 'model_texture'):
                BindTexture(texture=self.model_texture, index=1)
            Translate(0, 1, self.gl_depth + 1)
            self.rot = Rotate(0, 0, 1, 0)
            UpdateNormalMatrix()
            Color(1, 1, 1, 1)
            self.mesh = Mesh(
                    vertices=self.mesh_data.vertices,
                    indices=self.mesh_data.indices,
                    fmt=self.mesh_data.vertex_format,
                    mode=self.mesh_data.mode,
                )
            PopMatrix()
            self.cb = Callback(self.reset_gl_context)
        fbo['texture1'] = 1

    def show_axis(self):
        Color(1, 1, 0, 1) #Yellow
        Mesh(
                vertices=[
                     -1,        0,      0, 1, 1, 0, 0, 0,
                      1,        0,      0, 1, 1, 0, 0, 0,
                    0.8,      0.1,      0, 1, 1, 0, 0, 0,
                    0.8,     -0.1,      0, 1, 1, 0, 0, 0,
                      1,        0,      0, 1, 1, 0, 0, 0,
                    0.8,        0,   -0.1, 1, 1, 0, 0, 0,
                    0.8,        0,    0.1, 1, 1, 0, 0, 0,
                      1,        0,      0, 1, 1, 0, 0, 0,
                  ],
                indices=[0, 1, 2, 3, 4, 5, 6, 7],
                fmt=self.mesh_data.vertex_format,
                mode='line_strip',
            )
        Color(1, 0, 1, 1) # purple
        Mesh(
                vertices=[
                       0,      0,      -1, 0, 1, 1, 0, 0,
                       0,      0,       1, 0, 1, 1, 0, 0,
                     0.1,      0,     0.8, 0, 1, 1, 0, 0,
                    -0.1,      0,     0.8, 0, 1, 1, 0, 0,
                       0,      0,       1, 0, 1, 1, 0, 0,
                       0,   -0.1,     0.8, 0, 1, 1, 0, 0,
                       0,    0.1,     0.8, 0, 1, 1, 0, 0,
                       0,      0,       1, 0, 1, 1, 0, 0,
                  ],
                indices=[0, 1, 2, 3, 4, 5, 6, 7],
                fmt=self.mesh_data.vertex_format,
                mode='line_strip',
            )
        Color(0, 1, 1, 1) # Baby Blue
        Mesh(
                vertices=[
                       0,      -1,      0, 1, 1, 0, 0, 0,
                       0,       1,      0, 1, 1, 0, 0, 0,
                     0.1,     0.8,      0, 1, 1, 0, 0, 0,
                    -0.1,     0.8,      0, 1, 1, 0, 0, 0,
                       0,       1,      0, 1, 1, 0, 0, 0,
                       0,     0.8,   -0.1, 1, 1, 0, 0, 0,
                       0,     0.8,    0.1, 1, 1, 0, 0, 0,
                       0,       1,      0, 1, 1, 0, 0, 0,
                  ],
                indices=[0, 1, 2, 3, 4, 5, 6, 7],
                fmt=self.mesh_data.vertex_format,
                mode='line_strip',
            )

    def on_mesh_mode(self, instance, value):
        self.update_mesh(self.points)
Esempio n. 6
0
class Grid( Widget ):
    point_size = NumericProperty(10)
    
    def __init__(self, **kwargs):
        super(Grid, self).__init__(**kwargs)
        # Which elements exist in the grid in the normalized coordinates
        self.elements = []
        # If active, it can't be modified
        self.active = False
        
        # To the canvas, we add the FrameBufferObject and the rect to show it
        with self.canvas:
            self.fbo = Fbo(size=self.size)
            self.rect = Rectangle(texture=self.fbo.texture)
            # Color(1,0,0)
            # self.rect = Rectangle(size = self.size, pos = self.pos)

        # To the FrameBufferObject I set the color and add the point list
        with self.fbo:
            Color(1,1,1)
            self.points = Point( pointsize=self.point_size )

        # add some observers to the fbo, changes for the point_size (grid 
        # resizing) and widget resizing
        self.fbo.add_reload_observer(self._populate_fbo)
        self.bind( point_size = self._reshape )
        self.bind( size = self._update_rect, pos = self._update_rect )

    def on_touch_down(self, touch):
        ''' Handle adding/removing points when the grid is not active'''
        if not self.active and self.collide_point(*touch.pos):
            # Move to a 0,0 from where the widget starts
            x = touch.x - self.x
            y = touch.y - self.y
            self.add_point( [x,y] )

            return True

        return super(Grid, self).on_touch_down(touch)

    def normalize(self, coords):
        ''' normalization of coordinates, it will transform any given point in 
        the widget to its corresponding normalized coords '''
        # TODO: Create a picture to describe what are the normalized coordinates
        if type(coords) is tuple:
            coords = list(coords)

        if type(coords) is list:
            for ind in range(len(coords)):
                coords[ind] = int( coords[ind] // ( self.points.pointsize * 2 ) )
            return coords
        else:
            return int( coords // ( self.points.pointsize * 2 ) )

    def adjust(self, coords):
        ''' adjustment of a normalized coordinate to the real coordinate using
        the current point size as a guide '''
        if type(coords) is tuple:
            coords = list(coords)

        if type(coords) is list:
            for ind in range(len(coords)):
                coords[ind] = int( coords[ind] * ( self.points.pointsize * 2 ) + self.points.pointsize )
            return coords
        else:
            return int( coords * ( self.points.pointsize * 2 ) + self.points.pointsize )

    def add_point(self, point, redraw=True):
        ''' method to add a point to the grid if it doesn't exist
        if it's there, remove it'''
        point = self.normalize(point)
        
        if point in self.elements:
            where = self.elements.index( point )

            # Steal the reference to the vector of points
            points = self.points.points
            self.points.points = []
            # Clean the desired point
            del(points[where*2])
            del(points[where*2])

            # Reassign the property for the context to know (kivy weird things)
            self.points.points = points

            # Remove from the historical
            del(self.elements[where])

            # Redraw if asked for
            if redraw:
                self._populate_fbo(self.fbo)
        else:
            # add the normalized coords to the element list
            # it has to be copied because the adjust method will modify
            # the elements in points
            self.elements.append(point[:])
            # add the point to the visible points using the adjusted coordinates
            # the * leading self.adjust is to unpack the resulting array
            self.points.add_point( *self.adjust(point) )

        # print(self.elements)

    def next(self, instance):
        if len(self.elements) == 0: return
        
        # calculate the survivors
        nextgen = automaton.survivors(self.elements)
        # print(nextgen)
        # calculate any possible newborns
        nextgen += automaton.births(self.elements)
        # print(nextgen)

        # replace the current elements
        self.elements = nextgen
        # The vector comes with minivectors within, which is fine for the 
        # list of elements but doesn't work for the adjustment of points in
        # the screen
        nextgen = [ i for cell in nextgen for i in cell ]
        # adjust the elements to the actual coordinates
        nextgen = self.adjust( nextgen )
        # assign the vector back
        self.points.points = nextgen
        # redraw
        self._populate_fbo()

    def clear(self, instance):
        self.elements = []
        self.points.points = []
        self._populate_fbo()

    # RELOADING THE BUFFER AT ANY CHANGE
    def _populate_fbo(self, fbo = None):
        ''' This will reload the framebufferer either by the call of the 
        observer or by the deletion of a point'''
        if fbo is None:
            fbo = self.fbo

        fbo.bind()
        fbo.clear_buffer()
        fbo.add(self.points)
        fbo.release()

    def _reshape(self, instance, value):
        # There are no elements
        if len(self.elements) == 0:
            # We just update the points to be drawn
            self.points.pointsize = self.point_size
        # If we do have elements
        else:
            # steal the reference to the vector
            points = self.points.points
            self.points.points = []

            # normalize using current value
            points = self.normalize( points )
            # reassing the value
            self.points.pointsize = self.point_size
            # adjust using new value
            points = self.adjust( points )

            # assign the vector back
            self.points.points = points
            # redraw
            self._populate_fbo()

    # REDRAWING THE FBO AND THE
    def _update_rect( self, instance, value ):
        self.fbo.size = instance.size
        self.rect.size = instance.size
        self.rect.pos = instance.pos
        self.rect.texture = self.fbo.texture
Esempio n. 7
0
class Pad(Widget):
    scaled = ListProperty()

    def __init__(self, **kwargs):
        super(Pad, self).__init__(**kwargs)

        # Which elements exist in the grid in the normalized coordinates
        self.elements = []
        self.oldxy = None

        with self.canvas:
            self._fbo = Fbo(size=self.size)
            self._rect = Rectangle(texture=self._fbo.texture)

        with self._fbo:
            Color(1, 1, 1)
            self._fborect = Rectangle(size=self._fbo.size)
            Color(1, 0, 0)

        self._fbo.add_reload_observer(self._clear_fbo)
        self.bind(pos=self._update_rect, size=self._update_rect)

    def on_touch_down(self, touch):
        if self.collide_point(*touch.pos):
            # let's hold the mouse
            touch.grab(self)

            self.elements = []
            self._clear_fbo()

            x = round(touch.x - self.x)
            y = round(touch.y - self.y)

            # and keep the position
            self.oldxy = [x, y]
            return True

        return super(Pad, self).on_touch_down(touch)

    def on_touch_move(self, touch):
        if self.collide_point(*touch.pos):

            x = round(touch.x - self.x)
            y = round(touch.y - self.y)

            self.drawline([x, y])
            # and keep the position
            self.oldxy = [x, y]
            return True

        return super(Pad, self).on_touch_move(touch)

    def on_touch_up(self, touch):
        if touch.grab_current is self:
            touch.ungrab(self)
            # print('elements', self.elements)

            # try:
            with misc.timeit() as t:
                self.reducematrix()
            # finally:
            print('Matrix reduction and redraw')

            self.oldxy = None
            return True

        return super(Pad, self).on_touch_up(touch)

    def drawline(self, newxy):
        if newxy not in self.elements:
            self.elements.append(newxy)
            with self._fbo:
                Line(points=self.oldxy + newxy, width=1)

    def reducematrix(self):
        self.matrix = []
        minx = None
        maxx = None
        miny = None
        maxy = None

        with misc.timeit() as t:
            for i in range(len(self.elements) - 1):  # all but last
                # take the current
                origin = self.elements[i]
                # and the next
                point = self.elements[i + 1]

                # and get all pixels in between
                points = misc.allpoints(origin, point)

                for p in points:
                    if p not in self.matrix:

                        if minx is None or p[0] < minx:
                            minx = p[0]
                        if maxx is None or p[0] > maxx:
                            maxx = p[0]
                        if miny is None or p[1] < miny:
                            miny = p[1]
                        if maxy is None or p[1] > maxy:
                            maxy = p[1]

                        self.matrix.append(p)
        print('- Calc all points')

        # ajust to the minimum coord
        for p in self.matrix:
            p[0] = p[0] - minx
            p[1] = p[1] - miny

        # print('matrix', self.matrix)
        if maxx is not None:
            size = max(maxx - minx, maxy - miny)
            # print('  minx', minx, 'miny', miny, 'maxx', maxx, 'maxy', maxy, 'size', size)
        else:
            size = self.width

        with misc.timeit() as t:
            self.scaled = misc.scalematrix(self.matrix, (size, size), (15, 15))
        # finally:
        print('- Scale matrix')
        # print('scaled', self.scaled)

    # RELOADING THE BUFFER AT ANY CHANGE
    def _clear_fbo(self, fbo=None):
        ''' This will reload the framebufferer either by the call of the
        observer or by the deletion of a point'''
        if fbo is None:
            fbo = self._fbo

        fbo.bind()
        fbo.clear_buffer()
        fbo.add(Color(1, 1, 1))
        fbo.add(self._fborect)
        fbo.add(Color(1, 0, 0))
        fbo.release()

    def _update_rect(self, instance, value):
        self._fbo.size = instance.size
        self._fborect.size = instance.size
        self._rect.size = instance.size
        self._rect.pos = instance.pos
        self._rect.texture = self._fbo.texture
Esempio n. 8
0
class GLWindow(BoxLayout):
    texture = ObjectProperty(None, allownone=True)

    def __init__(self, **kwargs):
        self.mesh_data = MeshData()
        self.canvas = Canvas()
        with self.canvas:
            self.fbo = Fbo(size=(10, 10), compute_normal_mat=True)
            self.fbo.add_reload_observer(self.populate_fbo)
        with self.fbo:
            ClearColor(0, 0, 0, 0)
            ClearBuffers()
        self.populate_fbo(self.fbo)

        super(GLWindow, self).__init__(**kwargs)

        Clock.schedule_interval(self.update_glsl, 1 / 60.)

    def populate_fbo(self, fbo):
        Logger.info("Setting up FBO")

        with self.canvas:
            fbo.shader.source = resource_find('simple.glsl')
            fbo['diffuse_light'] = (1.0, 1.0, 0.8)
            fbo['ambient_light'] = (0.8, 0.8, 0.8)

        with fbo:
            self.cb = Callback(self.setup_gl_context)
            PushMatrix()
            BindTexture(source='testure.jpg', index=1)
            UpdateNormalMatrix()
            Translate(0,0,-3)
            self.rot = Rotate(1,0,1,0)
            # self.show_axis()
            self.make_pretty_dots()
            PopMatrix()
            self.cb = Callback(self.reset_gl_context)
        fbo['texture1'] = 1

    def update_glsl(self, *largs):
        asp = self.size[0] / float(self.size[1])
        proj = Matrix().view_clip(-asp, asp, -1, 1, 1, 100, 1)
        model = Matrix().look_at(   0.0, 0.0, 0.25,   0.0, 0.0, 0.0,   0.0, 1.0, 0.0)
        with self.canvas:
            self.fbo.shader.source = resource_find('simple.glsl')
            self.fbo['projection_mat'] = proj
            self.fbo['modelview_mat'] = model
            self.rot.angle += -1
            self.texture = self.fbo.texture
        with self.fbo:
            BindTexture(source='testure.jpg', index=1)

    def setup_gl_context(self, *args):
        glEnable(GL_DEPTH_TEST)

    def reset_gl_context(self, *args):
        glDisable(GL_DEPTH_TEST)

    def on_size(self, instance, value):
        Logger.info('resize')
        self.fbo.size = value
        self.texture = self.fbo.texture

    def show_axis(self):
        Color(1, 1, 0, 1) #Yellow
        Mesh(
                vertices=[
                     -1,        0,      0, 1, 1, 0, 0, 0,
                      1,        0,      0, 1, 1, 0, 0, 0,
                    0.8,      0.1,      0, 1, 1, 0, 0, 0,
                    0.8,     -0.1,      0, 1, 1, 0, 0, 0,
                      1,        0,      0, 1, 1, 0, 0, 0,
                    0.8,        0,   -0.1, 1, 1, 0, 0, 0,
                    0.8,        0,    0.1, 1, 1, 0, 0, 0,
                      1,        0,      0, 1, 1, 0, 0, 0,
                  ],
                indices=[0, 1, 2, 3, 4, 5, 6, 7],
                fmt=self.mesh_data.vertex_format,
                mode='line_strip',
            )
        Color(1, 0, 1, 1) # purple
        Mesh(
                vertices=[
                       0,      0,      -1, 0, 1, 1, 0, 0,
                       0,      0,       1, 0, 1, 1, 0, 0,
                     0.1,      0,     0.8, 0, 1, 1, 0, 0,
                    -0.1,      0,     0.8, 0, 1, 1, 0, 0,
                       0,      0,       1, 0, 1, 1, 0, 0,
                       0,   -0.1,     0.8, 0, 1, 1, 0, 0,
                       0,    0.1,     0.8, 0, 1, 1, 0, 0,
                       0,      0,       1, 0, 1, 1, 0, 0,
                  ],
                indices=[0, 1, 2, 3, 4, 5, 6, 7],
                fmt=self.mesh_data.vertex_format,
                mode='line_strip',
            )
        Color(0, 1, 1, 1) # Baby Blue
        Mesh(
                vertices=[
                       0,      -1,      0, 1, 1, 0, 0, 0,
                       0,       1,      0, 1, 1, 0, 0, 0,
                     0.1,     0.8,      0, 1, 1, 0, 0, 0,
                    -0.1,     0.8,      0, 1, 1, 0, 0, 0,
                       0,       1,      0, 1, 1, 0, 0, 0,
                       0,     0.8,   -0.1, 1, 1, 0, 0, 0,
                       0,     0.8,    0.1, 1, 1, 0, 0, 0,
                       0,       1,      0, 1, 1, 0, 0, 0,
                  ],
                indices=[0, 1, 2, 3, 4, 5, 6, 7],
                fmt=self.mesh_data.vertex_format,
                mode='line_strip',
            )

    def make_pretty_dots(self):
        points_per_side = 50

        points = []
        for idx in range(points_per_side):
            v = -1.0 + ((2.0 / points_per_side) * float(idx))
            tex = idx / float(points_per_side)
            print ("TEX: {}".format(str(tex)) )
            points.append(
                [
                [ v,  -1.0,  -1.0,    v,  -1.0,  -1.0,     tex,  0.0],
                [ v,  -1.0,   1.0,    v,  -1.0,   1.0,     tex,  0.0],
                [ v,   1.0,  -1.0,    v,   1.0,  -1.0,     tex,  1.0],
                [ v,   1.0,   1.0,    v,   1.0,   1.0,     tex,  1.0],
                [ -1.0,  v,  -1.0,    -1.0,  v,  -1.0,     0.0,  tex],
                [ -1.0,  v,   1.0,    -1.0,  v,   1.0,     0.0,  tex],
                [  1.0,  v,  -1.0,     1.0,  v,  -1.0,     1.0,  tex],
                [  1.0,  v,   1.0,     1.0,  v,   1.0,     1.0,  tex],
                [ -1.0,  -1.0,  v,    -1.0,  -1.0,  v,     tex,  tex],
                [ -1.0,   1.0,  v,    -1.0,   1.0,  v,     tex,  tex],
                [  1.0,  -1.0,  v,     1.0,  -1.0,  v,     tex,  tex],
                [  1.0,   1.0,  v,     1.0,   1.0,  v,     tex,  tex]],
                )

        points = np.array(points).flatten()
        Color(1,1,1,1)
        Mesh(
                vertices=points,
                indices=[i for i in range(len(points) / 8)],
                fmt=self.mesh_data.vertex_format,
                mode='points',
            )
Esempio n. 9
0
class Pad(Widget):
    scaled = ListProperty()

    def __init__(self, **kwargs):
        super(Pad, self).__init__(**kwargs)

        # Which elements exist in the grid in the normalized coordinates
        self.elements = []
        self.oldxy = None

        with self.canvas:
            self._fbo = Fbo(size=self.size)
            self._rect = Rectangle(texture=self._fbo.texture)

        with self._fbo:
            Color(1, 1, 1)
            self._fborect = Rectangle(size=self._fbo.size)
            Color(1, 0, 0)

        self._fbo.add_reload_observer(self._clear_fbo)
        self.bind(pos=self._update_rect, size=self._update_rect)

    def on_touch_down(self, touch):
        if self.collide_point(*touch.pos):
            # let's hold the mouse
            touch.grab(self)

            self.elements = []
            self._clear_fbo()

            x = round(touch.x - self.x)
            y = round(touch.y - self.y)

            # and keep the position
            self.oldxy = [x, y]
            return True

        return super(Pad, self).on_touch_down(touch)

    def on_touch_move(self, touch):
        if self.collide_point(*touch.pos):

            x = round(touch.x - self.x)
            y = round(touch.y - self.y)

            self.drawline([x, y])
            # and keep the position
            self.oldxy = [x, y]
            return True

        return super(Pad, self).on_touch_move(touch)

    def on_touch_up(self, touch):
        if touch.grab_current is self:
            touch.ungrab(self)
            # print('elements', self.elements)

            # try:
            with misc.timeit() as t:
                self.reducematrix()
            # finally:
            print("Matrix reduction and redraw")

            self.oldxy = None
            return True

        return super(Pad, self).on_touch_up(touch)

    def drawline(self, newxy):
        if newxy not in self.elements:
            self.elements.append(newxy)
            with self._fbo:
                Line(points=self.oldxy + newxy, width=1)

    def reducematrix(self):
        self.matrix = []
        minx = None
        maxx = None
        miny = None
        maxy = None

        with misc.timeit() as t:
            for i in range(len(self.elements) - 1):  # all but last
                # take the current
                origin = self.elements[i]
                # and the next
                point = self.elements[i + 1]

                # and get all pixels in between
                points = misc.allpoints(origin, point)

                for p in points:
                    if p not in self.matrix:

                        if minx is None or p[0] < minx:
                            minx = p[0]
                        if maxx is None or p[0] > maxx:
                            maxx = p[0]
                        if miny is None or p[1] < miny:
                            miny = p[1]
                        if maxy is None or p[1] > maxy:
                            maxy = p[1]

                        self.matrix.append(p)
        print("- Calc all points")

        # ajust to the minimum coord
        for p in self.matrix:
            p[0] = p[0] - minx
            p[1] = p[1] - miny

        # print('matrix', self.matrix)
        if maxx is not None:
            size = max(maxx - minx, maxy - miny)
            # print('  minx', minx, 'miny', miny, 'maxx', maxx, 'maxy', maxy, 'size', size)
        else:
            size = self.width

        with misc.timeit() as t:
            self.scaled = misc.scalematrix(self.matrix, (size, size), (15, 15))
        # finally:
        print("- Scale matrix")
        # print('scaled', self.scaled)

    # RELOADING THE BUFFER AT ANY CHANGE
    def _clear_fbo(self, fbo=None):
        """ This will reload the framebufferer either by the call of the
        observer or by the deletion of a point"""
        if fbo is None:
            fbo = self._fbo

        fbo.bind()
        fbo.clear_buffer()
        fbo.add(Color(1, 1, 1))
        fbo.add(self._fborect)
        fbo.add(Color(1, 0, 0))
        fbo.release()

    def _update_rect(self, instance, value):
        self._fbo.size = instance.size
        self._fborect.size = instance.size
        self._rect.size = instance.size
        self._rect.pos = instance.pos
        self._rect.texture = self._fbo.texture