2016-03-24 25 views
1

Kendimi bir çok ScatterLayout kullanarak buluyorum (Scatter'ın içinde Scatter vb.). Kaçan bir özellik, bir Scatter tuvaline bir çeşit alfa maskesi uyguluyor. Fikir, bir arka plan görüntüsüne veya diğer basit derinlik numaralarına karşılık gelen basit şekil vurmalarını gerçekleştirmek olacaktır.Kivy, Maske Widget Tuval

Bazı temel OpenGL veya belki de kivy.graphics.stencil_instructions ile yapılabilir gibi hissediyorum. Ağır OpenGL komutları ile özellikle rahat değilim (onları nasıl ayıklayacağımı bilmiyorum), ancak bazı basit komutları bir Widget Sınıfına sığdırmak gayet iyi. Yani burada

ben başka kaynaklardan alıyorum budur ama (Dikdörtgen gibi) bunun ötesinde ilkel katı almak istiyorum:

(kod test edilmedi!)

bir doku bazlı yönü Güncelleme
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

[bu cevap] ile çalışmadığından emin misiniz (http://stackoverflow.com/questions/35802203/how-do-i-mask-an-image-in-kivy-using-python)? – KeyWeeUsr

+0

@KeyWeeUsr Postanız yeni fikirler getirdi, ancak henüz test yapmadı. Sorumu güncellenmiş düşüncemi yansıtacak şekilde düzenledim. – user2097818

cevap

1

MultiTexture Canvas tam olarak cevaptır. Kendi özel PNG'nizi kullanmayı deneyin ve göreceksiniz, onları istediğiniz kadar karmaşık hale getirin ve güzelce çalışın. Benim uygulama için statik PNG kullanmıyorum çünkü (sipariş sorunların işlenmesi haline çalıştırırsanız henüz yeniden rağmen ben, bu soru Yanıtlanmış çalışmak ve düşünün yapmak kod önemli parçalarını kapsayacak şekilde gidiyorum.

Bu çok uzak soyulmuş varsa yukarıda misiniz (otomatik yüklenmesi edilecek bir docstringe olarak eklemeniz gereken çok basit gölgelendirici tanımı, bağlantıya bakın:

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); 
} 
''' 

Ve doku filtreleme işlemini gösteren bir minimum Widget sınıfını yani Bu basit sihiri oluşturur:

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']