Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make line_agg_collec work with document transform and latest vispy ModularProgram #2

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 9 additions & 11 deletions cr_paths/line_agg_collec.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,9 @@ def __init__(self, **kwargs):
self._program = ModularProgram(self.VERTEX_SHADER, self.FRAGMENT_SHADER)
self._collec = LineCollection(**kwargs)
self._V, self._I, self._U = self._collec.build_buffers()
self._V_buf = gloo.VertexBuffer(self._V)
self.index = gloo.IndexBuffer(self._I)
self._dash_atlas = gloo.Texture2D(self._collec.da._data)

def set_options(self):
gloo.set_state(clear_color=(1, 1, 1, 1), blend=True,
Expand All @@ -199,24 +201,19 @@ def draw(self):
# WARNING: THIS IS TERRIBLY INEFFICIENT BECAUSE ALL DATA
# IS SENT ON GPU AT EVERY REFRESH!!!
# We need to put this stuff at initialization time.
self._program._create()
self._program._build() # attributes / uniforms are not available until program is built

self._program.bind(gloo.VertexBuffer(self._V))
# attributes / uniforms are not available until program is built
self._program.prepare()

self._program.bind(self._V_buf)
for n, v in uniforms.iteritems():
self._program[n] = v

# WARNING/TODO: put the different sets of uniforms and put them in attributes instead
for n, v in self._U[0].iteritems():
self._program[n] = v

self._program['tr_scale'] = self._parent.panzoom.scale[:2]

self._program['u_dash_atlas'] = gloo.Texture2D(self._collec.da._data)
width, height = self.width, self.height
self._program['u_scale'] = width//2, height//2
self._program['u_proj'] = orthographic( -width//2, width//2,
-height//2, height//2, -1, +1 )
self._program['u_dash_atlas'] = self._dash_atlas

self._program.draw('triangles', indices=self.index)

Expand All @@ -227,7 +224,8 @@ def draw(self):


x = np.linspace(-1., 1., 1000)
y = .25*np.sin(15*x)
y = .25*np.sin(15*x) + 1.
print y
vertices1 = np.c_[x,y]
vertices2 = np.c_[np.cos(3*x)*.5, np.sin(3*x)*.5]

Expand Down
46 changes: 32 additions & 14 deletions cr_paths/path2.vert
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,23 @@ void rotate( in vec2 v, in float alpha, out vec2 result ) {
}

vec4 transform(vec4);
vec4 doc_px_transform(vec4);
vec4 px_ndc_transform(vec4);

vec2 transform_vector(vec2 x, vec2 base) {
vec4 o = transform(vec4(base, 0, 1));
return (transform(vec4(base+x, 0, 1)) - o).xy;
}



// Uniforms
//uniform mat4 u_matrix;
//uniform mat4 u_view;
uniform mat4 u_proj;

attribute vec4 color;
uniform vec2 u_scale;
uniform vec2 tr_scale;
// uniform vec2 u_scale;
// uniform vec2 tr_scale;
uniform float linewidth;
uniform float antialias;
uniform vec2 linecaps;
Expand All @@ -43,15 +51,15 @@ uniform float closed;


// Attributes
attribute vec2 a_position;
attribute vec4 a_tangents;
attribute vec2 a_segment;
attribute vec2 a_position; // position of each vertex
attribute vec4 a_tangents; // vector pointing from one vertex to the next
attribute vec2 a_segment; // distance along path
attribute vec2 a_angles;
attribute vec2 a_texcoord;

// Varying
varying vec4 v_color;
varying vec2 v_segment;
varying vec2 v_segment;
varying vec2 v_angles;
varying vec2 v_linecaps;
varying vec2 v_texcoord;
Expand Down Expand Up @@ -88,8 +96,9 @@ void main()

// Attributes to varyings
v_angles = a_angles;
v_segment = a_segment * u_scale.x * tr_scale.x; // TODO: proper scaling
v_length = v_length * u_scale * tr_scale; // TODO: proper scaling
//v_segment = a_segment * u_scale.x * tr_scale.x; // TODO: proper scaling
//v_length = v_length * u_scale * tr_scale; // TODO: proper scaling
v_segment = a_segment;

// Thickness below 1 pixel are represented using a 1 pixel thickness
// and a modified alpha
Expand All @@ -104,11 +113,19 @@ void main()
}

// This is the actual half width of the line
// TODO: take care of logical - physical pixel difference here.
float w = ceil(1.25*v_antialias+v_linewidth)/2.0;

vec2 position = transform(vec4(a_position,0.,1.)).xy*u_scale;
vec2 t1 = normalize(tr_scale*a_tangents.xy);
vec2 t2 = normalize(tr_scale*a_tangents.zw);
//vec2 position = transform(vec4(a_position,0.,1.)).xy*u_scale;
vec2 position = transform(vec4(a_position,0.,1.)).xy;
// At this point, position must be in _doc_ coordinates because the line
// width will be added to it.


//vec2 t1 = normalize(tr_scale*a_tangents.xy);
//vec2 t2 = normalize(tr_scale*a_tangents.zw);
vec2 t1 = normalize(transform_vector(a_tangents.xy, a_position));
vec2 t2 = normalize(transform_vector(a_tangents.zw, a_position));
float u = a_texcoord.x;
float v = a_texcoord.y;
vec2 o1 = vec2( +t1.y, -t1.x);
Expand Down Expand Up @@ -203,7 +220,8 @@ void main()
// Miter distance
// ------------------------------------------------------------------------
vec2 t;
vec2 curr = transform(vec4(a_position,0.,1.)).xy*u_scale;
//vec2 curr = transform(vec4(a_position,0.,1.)).xy*u_scale;
vec2 curr = transform(vec4(a_position,0.,1.)).xy;
if( a_texcoord.x < 0.0 ) {
vec2 next = curr + t2*(v_segment.y-v_segment.x);

Expand Down Expand Up @@ -232,5 +250,5 @@ void main()

v_texcoord = vec2( u, v*w );

gl_Position = u_proj*vec4(position, 0.0, 1.0);
gl_Position = px_ndc_transform(doc_px_transform(vec4(position, 0.0, 1.0)));
}
62 changes: 40 additions & 22 deletions cr_paths/plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,22 @@
from vispy import gloo
from vispy.scene.shaders import Function, ModularProgram
from vispy.scene.visuals import Visual
from vispy.scene.transforms import STTransform
from vispy.scene.transforms import STTransform, LogTransform, PolarTransform


class PanZoomTransform(STTransform):
pan = (0., 0.)

def move(self, (dx, dy)):
"""I call this when I want to translate."""
self.pan = (self.pan[0] + dx/self.scale[0],
self.pan[1] + dy/self.scale[1])
self.translate = (self.pan[0]*self.scale[0],
self.pan[1]*self.scale[1])
self.translate = self.translate + (dx, -dy, 0, 0)

def zoom(self, (dx, dy), center=(0., 0.)):
"""I call this when I want to zoom."""
scale = (self.scale[0] * exp(2.5*dx),
self.scale[1] * exp(2.5*dy))
tr = self.pan
self.pan = (tr[0] - center[0] * (1./self.scale[0] - 1./scale[0]),
tr[1] + center[1] * (1./self.scale[1] - 1./scale[1]))
self.scale = scale
self.translate = (self.pan[0]*self.scale[0],
self.pan[1]*self.scale[1])
scale = (exp(0.01*dx), exp(0.01*dy), 1, 1)
center = center + (0., 1.)
self.translate = center + ((self.translate - center) * scale)
self.scale = self.scale * scale


class MarkerVisual(Visual):
Expand Down Expand Up @@ -154,19 +147,37 @@ def draw(self):


class PlotCanvas(app.Canvas):
def _normalize(self, (x, y)):
w, h = float(self.size[0]), float(self.size[1])
return x/(w/2.)-1., y/(h/2.)-1.
#def _normalize(self, (x, y)):
#w, h = float(self.size[0]), float(self.size[1])
#return x/(w/2.)-1., y/(h/2.)-1.

def __init__(self, **kwargs):
app.Canvas.__init__(self, close_keys='escape', **kwargs)
self._visuals = []
self.panzoom = PanZoomTransform()
self.panzoom.scale = (200, -200)
self.panzoom.translate = (300, 300)
self.doc_px_transform = STTransform(scale=(1, 1), translate=(0, 0))
self.px_ndc_transform = STTransform(scale=(1, 1), translate=(0, 0))
self._update_transforms()

def _update_transforms(self):
# Update doc and pixel transforms to account for new canvas shape.

# Eventually this should be provided by the base Canvas class
# and should account for logical vs physical pixels, framebuffers,
# and glViewport.

s = self.size
self.px_ndc_transform.scale = (2.0 / s[0], -2.0 / s[1])
self.px_ndc_transform.translate = (-1, 1)

def add_visual(self, name, value):
self._visuals.append(value)
value._parent = self
value._program['transform'] = self.panzoom.shader_map()
value._program['transform'] = (self.panzoom * PolarTransform()).shader_map()
value._program['doc_px_transform'] = self.doc_px_transform.shader_map()
value._program['px_ndc_transform'] = self.px_ndc_transform.shader_map()

def __setattr__(self, name, value):
super(PlotCanvas, self).__setattr__(name, value)
Expand All @@ -175,9 +186,12 @@ def __setattr__(self, name, value):

def on_mouse_move(self, event):
if event.is_dragging:
x0, y0 = self._normalize(event.press_event.pos)
x1, y1 = self._normalize(event.last_event.pos)
x, y = self._normalize(event.pos)
#x0, y0 = self._normalize(event.press_event.pos)
#x1, y1 = self._normalize(event.last_event.pos)
#x, y = self._normalize(event.pos)
x0, y0 = event.press_event.pos
x1, y1 = event.last_event.pos
x, y = event.pos
dxy = ((x - x1), -(y - y1))
center = (x0, y0)
button = event.press_event.button
Expand All @@ -188,20 +202,20 @@ def on_mouse_move(self, event):
self.panzoom.zoom(dxy, center=center)

self.update()
self.panzoom.shader_map()

def on_mouse_wheel(self, event):
c = event.delta[1] * .1
x, y = self._normalize(event.pos)
self.panzoom.zoom((c, c), center=(x, y))
self.update()
self.panzoom.shader_map()

def on_resize(self, event):
self.width, self.height = event.size
gloo.set_viewport(0, 0, self.width, self.height)
self._update_transforms()
for v in self._visuals:
v.resize(event.size)


def on_draw(self, event):
gloo.clear()
Expand All @@ -211,6 +225,10 @@ def on_draw(self, event):
def show(self):
super(PlotCanvas, self).show()
app.run()







Expand Down