纹理更改后在Kivy中更新纹理矩形

时间:2018-03-15 21:35:10

标签: python opengl kivy

我有一个使用Kivy的项目,它从缓冲区创建GL纹理。缓冲区定期更新,这会改变纹理。

具体来说,纹理使用GLX_EXT_texture_from_pixmap扩展名绑定到GLXPixmap。

纹理以矩形显示,如下所示:

def __init__(self):
    self.texture = self.create_texture_from_buffer()

    with self.canvas:
        self.rect = Rectangle(
            size=self.size,
            pos=self.pos,
            texture=self.texture)

纹理的第一个内容正确显示,但当缓冲区的内容发生变化时,不会自动重绘更新的纹理。

我发现将纹理重新分配给矩形,或者调用canvas.ask_update()都会重绘纹理,但这样做会导致CPU和GPU的性能损失。

# reassign texture
def update(self, *args):
    self.rect.texture = self.texture
Clock.schedule_interval(self.update, 0)

# ask update
Clock.schedule_interval(lambda *args: self.canvas.ask_update, 0)

是否可以在不要求定期更新的情况下呈现更新的纹理?

1 个答案:

答案 0 :(得分:2)

是的!您必须使用kivy属性,它们使生活更加轻松。 Kivy属性就像变量一样,但是您可以在更改时添加一个回调(将被调用的函数)。首先,让我们导入ObjectProperty:

from kivy.properties import ObjectProperty

现在开始使用属性,您必须在类级别定义它们,并且您的类需要在某个时候实例化EventDispatcher,如果您的类是Widget,那么可以,小部件继承EventDispatcher ,如果您的课程没有继承任何内容,则只需继承EventDispatcher(kivy.event.EventDispatcher)。因此,假设您的班级称为Abc,然后按以下步骤操作:

class Abc(Widget):
    texture = ObjectProperty()  # Here we instantiate the object property

    def __init__(self):
        super().__init__()  # This will call the Widget class init so that we can use all the cool widget stuff
        self.texture = self.create_texture_from_buffer()
        # Your canvas code goes here

好吧,现在我们正在使用属性,我们可以使用它的特殊功能之一,如果定义了任何名为“ on_ [属性名称]”的函数,则在属性更改时将被调用,并且将传递2参数为此,更改了属性的对象和新值,因此您定义了on_texture并使其设置了矩形纹理:

class Abc(Widget):
    texture = ObjectProperty()  # Here we instantiate the object property

    def __init__(self):
        super().__init__()  # This will call the Widget class init so that we can use all the cool widget stuff
        self.texture = self.create_texture_from_buffer()
        # Your canvas code goes here

    def on_texture(self, instance, new_texture):
        self.rect.texture = new_texture

你去了;)