Skip to content

Instantly share code, notes, and snippets.

@tshirtman
Created January 7, 2014 23:43
Show Gist options
  • Save tshirtman/8309029 to your computer and use it in GitHub Desktop.
Save tshirtman/8309029 to your computer and use it in GitHub Desktop.
'''
line instruction in shadder
'''
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.clock import Clock
from kivy.properties import ListProperty, NumericProperty, ObjectProperty
from kivy.core.window import Window
from kivy.graphics import RenderContext, Rectangle, Color
from random import random
HEADER = '''
#version 120
#ifdef GL_ES
precision highp float;
#endif
/* Outputs from the vertex shader */
varying vec4 frag_color;
varying vec2 tex_coord0;
/* uniform texture samplers */
uniform sampler2D texture0;
'''
GLSL = HEADER + '''
#line 0
uniform float points[%s];
uniform float width;
void main(void){
int i;
int dot1, dot2;
vec2 A, B, P;
float dist;
P.x = gl_FragCoord.x;
P.y = gl_FragCoord.y;
gl_FragColor = vec4(0.0);
for (i = 0; i < %s - 1; i++){
A.x = points[i + 0];
A.y = points[i + 1];
B.x = points[i + 2];
B.y = points[i + 3];
if (dot((P - B), (B - A)) > 0)
dist = distance(B, P);
else if(dot((P - A), (A - B)) > 0)
dist = distance(A, P);
else
dist = abs(
(B.x - A.x) * (P.y - A.y)
- (B.y - A.y) * (P.x - A.x)
) / distance(A, B);
if (dist < width / 2) {
gl_FragColor = vec4(1);
break;
}
else if (dist < width / 2 + 1) {
gl_FragColor = vec4(1 - (dist - width / 2));
}
}
}
'''
class LineWidget(Widget):
points = ListProperty([])
line_width = NumericProperty(1)
rect = ObjectProperty(None)
def __init__(self, **kw):
self.canvas = RenderContext(
use_parent_projection=True)
super(LineWidget, self).__init__(**kw)
Clock.schedule_once(self.set_fs, 0)
with self.canvas:
Color(1, 0, 1, 1, mode="rgba")
self.rect = Rectangle(
pos=(0, 0), size=Window.size)
def set_fs(self, *args):
self.rect.size = Window.size
self.canvas['points'] = list(self.points)
self.canvas['width'] = float(self.line_width)
npoints = len(self.points)
self.canvas['npoints'] = npoints / 2
self.canvas.shader.fs = GLSL % (npoints, npoints)
def on_points(self, *args):
if self.rect:
self.set_fs()
def on_line_width(self, *args):
if self.rect:
self.canvas['width'] = self.line_width
class ShaderLineApp(App):
def build(self):
Clock.schedule_interval(self.add_point, 1)
self.line = LineWidget(
points=[100., 100., 200., 200.],
line_width=10)
return self.line
def add_point(self, *args):
self.line.points.extend(random() * 1000 for x in range(2))
if __name__ == '__main__':
ShaderLineApp().run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment