class AxisItem(GraphicsNode): """ An Axis Item Shows a coordinate origin. x=blue y=yellow z=green """ size = d_(Typed(Vec3d, factory=lambda: Vec3d(.1, .1, .1))) line_width = d_(Float(1.0)) colors = d_(List()) @observe("size", "line_width", "colors") def _ai_trigger_update(self, change): self.trigger_update() def _default_colors(self): return [ (1, 0, 0, 0.6), # x red (0, 1, 0, 0.6), # y green (0, 0, 1, 0.6), # z blue ] def render_node(self, context): #glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) #glEnable( GL_BLEND ) #glEnable( GL_ALPHA_TEST ) super(AxisItem, self).render_node(context) glPushAttrib(GL_LINE_BIT) glLineWidth(self.line_width) colors = self.colors if self.antialias: glEnable(GL_LINE_SMOOTH) glHint(GL_LINE_SMOOTH_HINT, GL_NICEST) glBegin(GL_LINES) v = self.size glColor4f(*colors[2]) # z is green glVertex3f(0, 0, 0) glVertex3f(0, 0, v.z) glColor4f(*colors[1]) # y is yellow glVertex3f(0, 0, 0) glVertex3f(0, v.y, 0) glColor4f(*colors[0]) # x is blue glVertex3f(0, 0, 0) glVertex3f(v.x, 0, 0) glEnd() glPopAttrib()
class BoxItem(GraphicsNode): """ An Box Item """ size = d_(Typed(Vec3d, factory=lambda: Vec3d(1.0, 1.0, 1.0))) color = d_(Value([1.0, 1.0, 1.0, 0.5])) @observe("size", "color") def _bi_trigger_update(self, change): self.trigger_update() def render_node(self, context): super(BoxItem, self).render_node(context) glBegin(GL_LINES) glColor4f(*self.color) x, y, z = self.size glVertex3f(0, 0, 0) glVertex3f(0, 0, z) glVertex3f(x, 0, 0) glVertex3f(x, 0, z) glVertex3f(0, y, 0) glVertex3f(0, y, z) glVertex3f(x, y, 0) glVertex3f(x, y, z) glVertex3f(0, 0, 0) glVertex3f(0, y, 0) glVertex3f(x, 0, 0) glVertex3f(x, y, 0) glVertex3f(0, 0, z) glVertex3f(0, y, z) glVertex3f(x, 0, z) glVertex3f(x, y, z) glVertex3f(0, 0, 0) glVertex3f(x, 0, 0) glVertex3f(0, y, 0) glVertex3f(x, y, 0) glVertex3f(0, 0, z) glVertex3f(x, 0, z) glVertex3f(0, y, z) glVertex3f(x, y, z) glEnd()
class GridItem(GraphicsNode): """ An Grid Item """ size = d_(Typed(Vec3d, factory=lambda: Vec3d(1.0, 1.0, 1.0))) @observe("size") def _gi_trigger_update(self, change): self.trigger_update() def render_node(self, context): super(GridItem, self).render_node(context) if self.antialias: glEnable(GL_LINE_SMOOTH) glEnable(GL_BLEND) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) glHint(GL_LINE_SMOOTH_HINT, GL_NICEST) glBegin(GL_LINES) # size is not used here .. glColor4f(1, 1, 1, .3) for x in range(-10, 11): glVertex3f(x, -10, 0) glVertex3f(x, 10, 0) for y in range(-10, 11): glVertex3f(-10, y, 0) glVertex3f(10, y, 0) glEnd()
class LinePlotItem(GraphicsNode): """ An LinePlot Item """ #: (N,3) array of floats specifying line point locations. pos = d_(Coerced(np.ndarray, coercer=np.ndarray)) #: (N,4) array of floats (0.0-1.0) specifying pot colors #: OR a tuple of floats specifying a single color for all spots. color = d_(Value([1.0, 1.0, 1.0, 0.5])) line_width = d_(Value(1.0)) @observe("pos", "color", "line_width") def _lpi_trigger_update(self, change): self.trigger_update() def render_node(self, context): super(LinePlotItem, self).render_node(context) glPushAttrib(GL_LINE_BIT) glEnableClientState(GL_VERTEX_ARRAY) try: glVertexPointerf(self.pos) if isinstance(self.color, np.ndarray): glEnableClientState(GL_COLOR_ARRAY) glColorPointerf(self.color) else: glColor4f(*self.color) glLineWidth(self.line_width) #glPointSize(self.width) if self.antialias: glEnable(GL_LINE_SMOOTH) glEnable(GL_BLEND) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); glDrawArrays(GL_LINE_STRIP, 0, int(self.pos.size / self.pos.shape[-1])) finally: glDisableClientState(GL_COLOR_ARRAY) glDisableClientState(GL_VERTEX_ARRAY) glPopAttrib()
class ScatterPlotItem(GraphicsNode): """ An LinePlot Item """ #: (N,3) array of floats specifying line point locations. pos = d_(Coerced(np.ndarray, coercer=np.ndarray)) #: (N,4) array of floats (0.0-1.0) specifying pot colors #: OR a tuple of floats specifying a single color for all spots. color = d_(Value([1.0, 1.0, 1.0, 0.5])) size = d_(Value(1.0)) px_mode = d_(Bool(True)) @observe("pos", "color", "size", "px_mode") def _spi_trigger_update(self, change): self.trigger_update() _point_texture = Value() _shader = Value() def initialize_node(self): ## Generate texture for rendering points w = 64 def fn(x, y): r = ((x - w / 2.)**2 + (y - w / 2.)**2)**0.5 return 255 * (w / 2. - np.clip(r, w / 2. - 1.0, w / 2.)) pData = np.empty((w, w, 4)) pData[:] = 255 pData[:, :, 3] = np.fromfunction(fn, pData.shape[:2]) pData = pData.astype(np.ubyte) self._point_texture = glGenTextures(1) glActiveTexture(GL_TEXTURE0) glEnable(GL_TEXTURE_2D) glBindTexture(GL_TEXTURE_2D, self._point_texture) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, pData.shape[0], pData.shape[1], 0, GL_RGBA, GL_UNSIGNED_BYTE, pData) self._shader = shaders.getShaderProgram('pointSprite') def render_node(self, context): super(ScatterPlotItem, self).render_node(context) widget = context.get("widget", None) glEnable(GL_POINT_SPRITE) glActiveTexture(GL_TEXTURE0) glEnable(GL_TEXTURE_2D) glBindTexture(GL_TEXTURE_2D, self._point_texture) glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE) #glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE) ## use texture color exactly #glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ) ## texture modulates current color glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) glEnable(GL_PROGRAM_POINT_SIZE) with self._shader: #glUniform1i(self.shader.uniform('texture'), 0) ## inform the shader which texture to use glEnableClientState(GL_VERTEX_ARRAY) try: pos = self.pos #if pos.ndim > 2: #pos = pos.reshape((reduce(lambda a,b: a*b, pos.shape[:-1]), pos.shape[-1])) glVertexPointerf(pos) if isinstance(self.color, np.ndarray): glEnableClientState(GL_COLOR_ARRAY) glColorPointerf(self.color) else: glColor4f(*self.color) if not self.px_mode or isinstance(self.size, np.ndarray): glEnableClientState(GL_NORMAL_ARRAY) norm = np.empty(pos.shape) if self.px_mode or widget is None: norm[..., 0] = self.size else: # XXX not yet implemented raise NotImplementedError gpos = self.mapToView(pos.transpose()).transpose() pxSize = self.view().pixelSize(gpos) norm[..., 0] = self.size / pxSize glNormalPointerf(norm) else: glNormal3f( self.size, 0, 0 ) ## vertex shader uses norm.x to determine point size #glPointSize(self.size) glDrawArrays(GL_POINTS, 0, int(pos.size / pos.shape[-1])) finally: glDisableClientState(GL_NORMAL_ARRAY) glDisableClientState(GL_VERTEX_ARRAY) glDisableClientState(GL_COLOR_ARRAY)