我发现自己经常使用ScatterLayout(Scatter内部的Scatter等等)。逃避我的一个功能是将某种alpha蒙版应用于Scatter画布。想法是执行对应于背景图像或其他简单深度技巧的简单形状敲除。
我觉得这对于一些基本的OpenGL或者 kivy.graphics.stencil_instructions 是可行的。我对使用繁重的OpenGL命令并不是特别熟悉(我不知道如何调试它们),但将一些简单的命令包装到Widget类中就可以了。
所以这是我从其他来源得到的,但我想把它超越原始实体(如Rectangle):
使用基于纹理的方向更新(代码未经测试!)
with self.canvas:
# Hopefully I can build my "transparency mask" manually with a Texture
texture = Texture.create(size=(64, 64))
size = 64 * 64 * 3
buf = [int(x * 255 / size) for x in range(size)]
buf = b''.join(map(chr, buf))
texture.blit_buffer(buf, colorfmt='rgb', bufferfmt='ubyte')
StencilPush()
Rectangle(texture=texture, pos=self.pos, size=(64, 64))
#use mask
StencilUse()
"""
Will we get an image based mask on all drawing commands placed here?
"""
StencilPop()
答案 0 :(得分:1)
MultiTexture Canvas正是答案。尝试使用您自己的自定义PNG,您将看到,使它们变得如您所愿,并且它的工作非常精美。我将包含使其工作的重要代码片段,并考虑回答的问题,但如果我遇到渲染顺序问题,我可能会重新打开(因为我没有为我的应用程序使用静态PNG。
你需要将非常简单的着色器定义作为文档字符串包含在内(它将被自动加载,如果我已经剥离了太多,请参阅上面的链接:
fs_multitexture = '''
$HEADER$
// New uniform that will receive texture at index 1
uniform sampler2D texture1;
void main(void) {
// multiple current color with both texture (0 and 1).
// currently, both will use exactly the same texture coordinates.
gl_FragColor = frag_color * \
texture2D(texture0, tex_coord0) * \
texture2D(texture1, tex_coord0);
}
'''
最基本的Widget类,它演示了创建这个简单魔法的纹理过滤过程:
class MultitextureWidget(Widget):
def __init__(self, **kwargs):
self.canvas = RenderContext()
self.canvas.shader.fs = fs_multitexture
with self.canvas:
Color(1, 1, 1)
BindTexture(source='mtexture2.png', index=1)
Rectangle(size=(150, 150), source='mtexture1.png', pos=(500, 200))
self.canvas['texture1'] = 1
super(MultitextureWidget, self).__init__(**kwargs)
Clock.schedule_interval(self.update_glsl, 0)
def update_glsl(self, *largs):
self.canvas['projection_mat'] = Window.render_context['projection_mat']
self.canvas['modelview_mat'] = Window.render_context['modelview_mat']