from kivy.app import App
from kivy.clock import Clock
from kivy.factory import Factory
from kivy.graphics import RenderContext
from kivy.properties import StringProperty
from kivy.uix.widget import Widget
import kivy.core.window
shader = '''
$HEADER$
uniform vec2 resolution;
void main(void)
{
vec2 position = (gl_FragCoord.xy / resolution.xy);
float color = 0.0;
color += position.y / position.x;
if(color < 0.2) { color = 0.2; }
vec3 output_color = vec3(color * 1.5, color, color * 2.0);
gl_FragColor = vec4(output_color, 1.0);
}
'''
class ShaderWidget(Widget):
fs = StringProperty(None)
def __init__(self, **kwargs):
self.canvas = RenderContext(use_parent_projection=True)
super(ShaderWidget, self).__init__(**kwargs)
self.canvas['time'] = Clock.get_boottime()
Clock.schedule_interval(self.update_glsl, 1 / 60.)
def update_glsl(self, *largs):
self.canvas['time'] = Clock.get_boottime()
self.canvas['resolution'] = [float(v) for v in self.size]
def on_fs(self, instance, value):
shader = self.canvas.shader
shader.fs = value
class TestApp(App):
def build(self):
main_widget = Factory.MainWidget()
main_widget.mini.fs = shader
main_widget.mini2.fs = shader
return main_widget
TestApp().run()
<MiniShaderWidget@ShaderWidget>:
canvas:
Color:
rgb: 1.0, 1.0, 1.0
Rectangle:
pos: self.pos
size: self.size
<MainWidget@ShaderWidget+FloatLayout>:
mini: mini
mini2: mini2
BoxLayout
MiniShaderWidget
id: mini
Label
text: 'label'
MiniShaderWidget
id: mini2
In this app, I have a window that consists of three equal parts.
The shader from the same source (the variable shader) is drawn to the left and right.
The shader looks like a transition from white to violet.
In the middle, I added a label called "label" just to make it easier to distinguish the left shader from the right one.
I took this example and reworked it a bit from here
The question is: I expect to see the same picture on the left and right, but I see different images of the same shader. Why is this so?
Is it possible to make the same picture on the left and right?
from kivy.app import App
from kivy.lang import Builder
root = Builder.load_string('''
BoxLayout
Button
Button
Button
''')
class TestApp(App):
def build(self): return root
TestApp().run()
from kivy.app import App
from kivy.clock import Clock
from kivy.factory import Factory
from kivy.graphics import RenderContext
from kivy.properties import StringProperty
from kivy.uix.widget import Widget
import kivy.core.window
shader =
'''
$HEADER$
uniform vec2 resolution;
uniform vec2 pos;
//vec2 center = vec2(resolution.x* 1.5, resolution.y* 0.5);
vec2 center = vec2(resolution.x*0.5, resolution.y*0.5)+0.5*pos+0.5*pos;
float radius = min(resolution.x, resolution.y) * .5;
float circle(vec2 coord, vec2 center, float radius) {
float distanceToCenter = distance(coord, center);
return smoothstep(distanceToCenter - 2., distanceToCenter, radius);
}
void main() {
vec2 coord = vec2(gl_FragCoord);
vec4 color = vec4(1., 0.2, 0.6,1.);
float isFilled = circle(coord, center, radius);
gl_FragColor = color*isFilled;
}
'''
class ShaderWidget(Widget):
fs = StringProperty(None)
def __init__(self, **kwargs):
self.canvas = RenderContext(use_parent_projection=True)
super(ShaderWidget, self).__init__(**kwargs)
self.canvas['time'] = Clock.get_boottime()
Clock.schedule_interval(self.update_glsl, 1 / 60.)
def update_glsl(self, *largs):
self.canvas['time'] = Clock.get_boottime()
p_x,p_y = self.pos
s_x,s_y = self.size
self.canvas['resolution'] = [float(s_x),float(s_y)]
self.canvas['pos'] = [float(p_x),float(p_y)]
def on_fs(self, instance, value):
shader = self.canvas.shader
shader.fs = value
class TestApp(App):
def build(self):
main_widget = Factory.MainWidget()
main_widget.mini.fs =
shader
main_widget.mini1.fs = shader
return main_widget
TestApp().run()
<MiniShaderWidget@ShaderWidget>:
canvas:
Rectangle:
pos: self.pos
size: self.size
<MainWidget@BoxLayout>:
mini: mini
mini1: mini1
Label
text: 'label'
Label
text: 'label'
MiniShaderWidget
id: mini
MiniShaderWidget
id: mini1
vec2 center = resolution * 0.5;