Created
January 7, 2014 23:43
-
-
Save tshirtman/8309029 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
''' | |
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