def initialize(self, coordinates=None, color=None, autocolor=None, depth=None, autonormalizable=True): if type(coordinates) is tuple: coordinates = np.array(coordinates, dtype=np.float32).reshape((1, -1)) nprimitives = coordinates.shape[0] if autocolor is not None: color = get_color(autocolor) if color is None: color = self.default_color # If there is one color per rectangle, repeat the color array so # that there is one color per vertex. if isinstance(color, np.ndarray): if color.shape[0] == nprimitives: color = np.repeat(color, 4, axis=0) # there are four vertices per rectangle self.size = 4 * nprimitives self.primitive_type = "TRIANGLE_STRIP" self.bounds = np.arange(0, self.size + 1, 4) position = self.coordinates_compound(coordinates)["position"] super(RectanglesVisual, self).initialize( position=position, color=color, nprimitives=nprimitives, autonormalizable=autonormalizable ) # depth=depth) self.add_compound("coordinates", fun=self.coordinates_compound, data=coordinates) self.depth = depth
def initialize(self, coordinates=None, color=None, autocolor=None, depth=None): if type(coordinates) is tuple: coordinates = np.array(coordinates, dtype=np.float32).reshape((1, -1)) nprimitives = coordinates.shape[0] if autocolor is not None: color = get_color(autocolor) if color is None: color = self.default_color # there are four vertices per rectangle self.size = 4 * nprimitives self.primitive_type = 'TRIANGLE_STRIP' self.bounds = np.arange(0, self.size + 1, 4) position = self.coordinates_compound(coordinates)['position'] super(RectanglesVisual, self).initialize(position=position, color=color, nprimitives=nprimitives,)# depth=depth) self.add_compound("coordinates", fun=self.coordinates_compound, data=coordinates) self.depth = depth
def initialize(self, position=None, edges=None, color=None, edges_color=None, node_size=None, autocolor=None, **kwargs): if autocolor is not None: color = get_color(autocolor) if node_size is None: node_size = 8 if color is None: color = (1., 1., 1., .25) # relative indexing edges = np.array(edges, dtype=np.int32) uedges = np.unique(edges) uedges.sort() # m = uedges.max() # n = len(uedges) # indices = np.zeros(m + 1, dtype=np.int32) # indices[uedges] = np.arange(n) # # indices = np.arange(uedges.max() + 1) # # indices[edges.ravel()].reshape((-1, 2)) # edges = indices[edges] for i, u in enumerate(uedges): edges[edges == u] = i # edges self.add_visual(PlotVisual, position=position, primitive_type='LINES', color=edges_color, index=edges.ravel(), name='edges') # nodes self.add_visual(SpriteVisual, position=RefVar(self.name + '_edges', 'position'), color=color, texture=get_tex(node_size), name='nodes')
def initialize_default(self, **kwargs): super(DefaultPaintManager, self).initialize_default(**kwargs) # Help if self.parent.activate_help: self.add_visual(TextVisual, coordinates=(-.95, .95), fontsize=14, color=get_color('w'), interline=37., letter_spacing=320., depth=-1., background_transparent=False, is_static=True, prevent_constrain=True, text='', name='help', visible=False)
def plot(self, *args, **kwargs): # deal with special string argument containing options lenargs = len(args) opt = '' # we look for the index in args such that args[i] is a string for i in xrange(lenargs): if isinstance(args[i], basestring): opt = args[i] break if opt: # we remove the options from the arguments l = list(args) l.remove(opt) args = tuple(l) kwargs['options'] = opt # process marker type, 'o' or 'or' marker = kwargs.pop('marker', kwargs.pop('m', None)) if marker is None: if opt and opt[0] in ',.+-|xo': marker = opt[0] if marker is not None: cls = vs.SpriteVisual texsize = kwargs.pop('marker_size', kwargs.pop('ms', None)) # marker string if isinstance(marker, basestring): kwargs['texture'] = get_marker_texture(marker, texsize) # or custom texture marker else: kwargs['texture'] = marker kwargs.pop('options', None) # process marker color in options if 'color' not in kwargs and len(opt) == 2: kwargs['color'] = get_color(opt[1]) else: cls = vs.PlotVisual self.add_visual(cls, *args, **kwargs)
def initialize(self, x=None, y=None, color=None, point_size=1.0, position=None, nprimitives=None, index=None, color_array_index=None, thickness=None, options=None, autocolor=None): # if position is specified, it contains x and y as column vectors if position is not None: position = np.array(position, dtype=np.float32) if thickness: shape = (2 * position.shape[0], 1) else: shape = (1, position.shape[0]) else: position, shape = process_coordinates(x=x, y=y) if thickness: shape = (shape[0], 2 * shape[1]) # register the size of the data self.size = np.prod(shape) # there is one plot per row if not nprimitives: nprimitives = shape[0] nsamples = shape[1] else: nsamples = self.size // nprimitives # handle thickness if thickness and position.shape[0] >= 2: w = thickness n = self.size X = position Y = np.zeros((n, 2)) u = np.zeros((n/2, 2)) X2 = np.vstack((X, 2*X[-1,:]-X[-2,:])) u[:,0] = -np.diff(X2[:,1]) u[:,1] = np.diff(X2[:,0]) r = (u[:,0] ** 2 + u[:,1] ** 2) ** .5 rm = r.mean() r[r == 0.] = rm # print u # print r # ind = np.nonzero(r == 0.)[0] # print ind, ind-1 # r[ind] = r[ind - 1] u[:,0] /= r u[:,1] /= r Y[::2,:] = X - w * u Y[1::2,:] = X + w * u position = Y x = Y[:,0] y = Y[:,1] # print x # print y self.primitive_type = 'TRIANGLE_STRIP' # register the bounds if nsamples <= 1: self.bounds = [0, self.size] else: self.bounds = np.arange(0, self.size + 1, nsamples) # normalize position # if viewbox: # self.add_normalizer('position', viewbox) # by default, use the default color if color is None: if nprimitives <= 1: color = self.default_color # automatic color with color map if autocolor is not None: if nprimitives <= 1: color = get_next_color(autocolor) else: color = [get_next_color(i + autocolor) for i in xrange(nprimitives)] # # handle the case where the color is a string where each character # # is a color (eg. 'ry') # if isinstance(color, basestring): # color = list(color) color = get_color(color) # handle the case where there is a single color given as a list of # RGB components instead of a tuple if type(color) is list: if color and (type(color[0]) != tuple) and (3 <= len(color) <= 4): color = tuple(color) else: color = np.array(color) # first, initialize use_color_array to False except if # color_array_index is not None use_color_array = color_array_index is not None if isinstance(color, np.ndarray): colors_ndim = color.shape[1] # first case: one color per point if color.shape[0] == self.size: single_color = False # second case: use a color array so that each plot has a single # color, this saves memory since there is a single color in # memory for any plot else: use_color_array = True single_color = False elif type(color) is tuple: single_color = True colors_ndim = len(color) # set position attribute self.add_attribute("position", ndim=2, data=position, autonormalizable=True) if index is not None: index = np.array(index) # self.size = len(index) self.add_index("index", data=index) # single color case: no need for a color buffer, just use default color if single_color and not use_color_array: self.add_uniform("color", ndim=colors_ndim, data=color) if colors_ndim == 3: self.add_fragment_main(""" out_color = vec4(color, 1.0); """) elif colors_ndim == 4: self.add_fragment_main(""" out_color = color; """) # multiple colors case: color attribute elif not use_color_array: self.add_attribute("color", ndim=colors_ndim, data=color) self.add_varying("varying_color", vartype="float", ndim=colors_ndim) self.add_vertex_main(""" varying_color = color; """) if colors_ndim == 3: self.add_fragment_main(""" out_color = vec4(varying_color, 1.0); """) elif colors_ndim == 4: self.add_fragment_main(""" out_color = varying_color; """) # multiple colors, but with a color array to save memory elif use_color_array: if color_array_index is None: color_array_index = np.repeat(np.arange(nprimitives), nsamples) color_array_index = np.array(color_array_index) ncolors = color.shape[0] ncomponents = color.shape[1] color = color.reshape((1, ncolors, ncomponents)) dx = 1. / ncolors offset = dx / 2. self.add_texture('colormap', ncomponents=ncomponents, ndim=1, data=color) self.add_attribute('index', ndim=1, vartype='int', data=color_array_index) self.add_varying('vindex', vartype='int', ndim=1) self.add_vertex_main(""" vindex = index; """) self.add_fragment_main(""" float coord = %.5f + vindex * %.5f; vec4 color = texture1D(colormap, coord); out_color = color; """ % (offset, dx)) # add point size uniform (when it's not specified, there might be some # bugs where its value is obtained from other datasets...) self.add_uniform("point_size", data=point_size) self.add_vertex_main("""gl_PointSize = point_size;""")
def initialize(self, x=None, y=None, color=None, autocolor=None, texture=None, position=None):#, normalize=None): # if position is specified, it contains x and y as column vectors if position is not None: position = np.array(position, dtype=np.float32) # shape = (position.shape[0], 1) else: position, shape = process_coordinates(x=x, y=y) texsize = float(max(texture.shape[:2])) shape = texture.shape ncomponents = texture.shape[2] self.size = position.shape[0] if shape[0] == 1: self.ndim = 1 elif shape[0] > 1: self.ndim = 2 self.primitive_type = 'POINTS' # normalize position # if viewbox: # self.add_normalizer('position', viewbox) # self.normalize = normalize # default color if color is None: color = self.default_color # automatic color with color map if autocolor is not None: color = get_next_color(autocolor) color = get_color(color) # handle the case where there is a single color given as a list of # RGB components instead of a tuple if type(color) is list: if color and (type(color[0]) != tuple) and (3 <= len(color) <= 4): color = tuple(color) else: color = np.array(color) if isinstance(color, np.ndarray): colors_ndim = color.shape[1] # one color per point single_color = False elif type(color) is tuple: single_color = True colors_ndim = len(color) texture_shader = """ out_color = texture%NDIM%(tex_sampler, gl_PointCoord%POINTCOORD%) * %COLOR%; """ shader_ndim = "%dD" % self.ndim if self.ndim == 1: shader_pointcoord = ".x" else: shader_pointcoord = "" # single color case: no need for a color buffer, just use default color if single_color: self.add_uniform("color", ndim=colors_ndim, data=color) shader_color_name = "color" # multiple colors case: color attribute else: self.add_attribute("color", ndim=colors_ndim, data=color) self.add_varying("varying_color", vartype="float", ndim=colors_ndim) self.add_vertex_main(""" varying_color = color; """) shader_color_name = "varying_color" if colors_ndim == 3: shader_color = "vec4(%s, 1.0)" % shader_color_name elif colors_ndim == 4: shader_color = shader_color_name texture_shader = texture_shader.replace('%COLOR%', shader_color) texture_shader = texture_shader.replace('%NDIM%', shader_ndim) texture_shader = texture_shader.replace('%POINTCOORD%', shader_pointcoord) self.add_fragment_main(texture_shader) # add variables self.add_attribute("position", vartype="float", ndim=2, data=position, autonormalizable=True) self.add_texture("tex_sampler", size=shape, ndim=self.ndim, ncomponents=ncomponents) self.add_compound("texture", fun=lambda texture: \ dict(tex_sampler=texture), data=texture) self.add_uniform("point_size", vartype="float", ndim=1, data=texsize) # Vertex shader self.add_vertex_main(""" gl_PointSize = point_size; """)
def plot(self, *args, **kwargs): """Plot lines, curves, scatter plots, or any sequence of basic OpenGL primitives. Arguments: * x, y: 1D vectors of the same size with point coordinates, or 2D arrays where each row is plotted as an independent plot. If only x is provided, then it contains the y coordinates and the x coordinates are assumed to be linearly spaced. * options: a string with shorcuts for the options: color and marker. The color can be any char among: `rgbycmkw`. The marker can be any char among: `,.+-|xo`. * color: the color of the line(s), or a list/array of colors for each independent primitive. * marker, or m: the type of the marker as a char, or a NxMx3 texture. * marker_size, or ms: the size of the marker. * thickness: None by default, or the thickness of the line. * primitive_type: the OpenGL primitive type of the visual. Can be: * `LINES`: a segment is rendered for each pair of successive points * `LINE_STRIP`: a sequence of segments from one point to the next. * `LINE_LOOP`: like `LINE_STRIP` but closed. * `POINTS`: each point is rendered as a pixel. * `TRIANGLES`: each successive triplet of points is rendered as a triangle. * `TRIANGLE_STRIP`: one triangle is rendered from a point to the next (i.e. successive triangles share two vertices out of three). * `TRIANGLE_FAN`: the first vertex is shared by all triangles. """ # deal with special string argument containing options lenargs = len(args) opt = '' # we look for the index in args such that args[i] is a string for i in xrange(lenargs): if isinstance(args[i], basestring): opt = args[i] break if opt: # we remove the options from the arguments l = list(args) l.remove(opt) args = tuple(l) kwargs['options'] = opt # process marker type, 'o' or 'or' marker = kwargs.pop('marker', kwargs.pop('m', None)) if marker is None: if opt and opt[0] in ',.+-|xo': marker = opt[0] if marker is not None: cls = vs.SpriteVisual texsize = kwargs.pop('marker_size', kwargs.pop('ms', None)) # marker string if isinstance(marker, basestring): kwargs['texture'] = get_marker_texture(marker, texsize) # or custom texture marker else: kwargs['texture'] = marker kwargs.pop('options', None) # process marker color in options if 'color' not in kwargs and len(opt) == 2: kwargs['color'] = get_color(opt[1]) else: cls = vs.PlotVisual self.add_visual(cls, *args, **kwargs)
def initialize(self, text, coordinates=(0., 0.), font='segoe', fontsize=24, color=None, letter_spacing=None, interline=0., autocolor=None, prevent_constrain=False, depth=None, posoffset=None): """Initialize the text template.""" if prevent_constrain: self.constrain_ratio = False if autocolor is not None: color = get_color(autocolor) if color is None: color = self.default_color self.size = len(text) self.primitive_type = 'POINTS' self.interline = interline text_length = self.size self.initialize_font(font, fontsize) self.coordinates = coordinates point_size = float(self.matrix[:,4].max() * self.texture.shape[1]) # template attributes and varyings self.add_attribute("position", vartype="float", ndim=2, data=np.zeros((self.size, 2))) self.add_attribute("offset", vartype="float", ndim=1) self.add_attribute("index", vartype="float", ndim=1) self.add_attribute("text_map", vartype="float", ndim=4) self.add_varying("flat_text_map", vartype="float", flat=True, ndim=4) if posoffset is None: posoffset = (0., 0.) self.add_uniform('posoffset', vartype='float', ndim=2, data=posoffset) # texture self.add_texture("tex_sampler", size=self.texture.shape[:2], ndim=2, ncomponents=self.texture.shape[2], data=self.texture) # pure heuristic (probably bogus) if letter_spacing is None: letter_spacing = (100 + 17. * fontsize) self.add_uniform("spacing", vartype="float", ndim=2, data=(letter_spacing, interline)) self.add_uniform("point_size", vartype="float", ndim=1, data=point_size) # one color per if isinstance(color, np.ndarray) and color.ndim > 1: self.add_attribute('color0', vartype="float", ndim=4, data=color) self.add_varying('color', vartype="float", ndim=4) self.add_vertex_main('color = color0;') else: self.add_uniform("color", vartype="float", ndim=4, data=color) self.add_uniform("text_width", vartype="float", ndim=1) # compound variables self.add_compound("text", fun=self.text_compound, data=text) self.add_compound("coordinates", fun=self.position_compound, data=coordinates) # vertex shader self.add_vertex_main(VS, after='viewport') # fragment shader self.add_fragment_main(FS) self.depth = depth
def initialize(self, x=None, y=None, color=None, point_size=1.0, position=None, nprimitives=None, index=None, color_array_index=None, viewbox=None, options=None): # if position is specified, it contains x and y as column vectors if position is not None: position = np.array(position, dtype=np.float32) shape = (position.shape[0], 1) else: position, shape = process_coordinates(x=x, y=y) # register the size of the data self.size = np.prod(shape) # there is one plot per row if not nprimitives: nprimitives = shape[0] nsamples = shape[1] else: nsamples = self.size // nprimitives # register the bounds if nsamples <= 1: self.bounds = [0, self.size] else: self.bounds = np.arange(0, self.size + 1, nsamples) # normalize position if viewbox: self.add_normalizer('position', viewbox) # by default, use the default color if color is None: color = self.default_color # # handle the case where the color is a string where each character # # is a color (eg. 'ry') # if isinstance(color, basestring): # color = list(color) color = get_color(color) # handle the case where there is a single color given as a list of # RGB components instead of a tuple if type(color) is list: if color and (type(color[0]) != tuple) and (3 <= len(color) <= 4): color = tuple(color) else: color = np.array(color) # first, initialize use_color_array to False except if # color_array_index is not None use_color_array = color_array_index is not None if isinstance(color, np.ndarray): colors_ndim = color.shape[1] # first case: one color per point if color.shape[0] == self.size: single_color = False # second case: use a color array so that each plot has a single # color, this saves memory since there is a single color in # memory for any plot else: use_color_array = True single_color = False elif type(color) is tuple: single_color = True colors_ndim = len(color) # set position attribute self.add_attribute("position", ndim=2, data=position) if index is not None: index = np.array(index) # self.size = len(index) self.add_index("index", data=index) # single color case: no need for a color buffer, just use default color if single_color and not use_color_array: self.add_uniform("color", ndim=colors_ndim, data=color) if colors_ndim == 3: self.add_fragment_main(""" out_color = vec4(color, 1.0); """) elif colors_ndim == 4: self.add_fragment_main(""" out_color = color; """) # multiple colors case: color attribute elif not use_color_array: self.add_attribute("color", ndim=colors_ndim, data=color) self.add_varying("varying_color", vartype="float", ndim=colors_ndim) self.add_vertex_main(""" varying_color = color; """) if colors_ndim == 3: self.add_fragment_main(""" out_color = vec4(varying_color, 1.0); """) elif colors_ndim == 4: self.add_fragment_main(""" out_color = varying_color; """) # multiple colors, but with a color array to save memory elif use_color_array: if color_array_index is None: color_array_index = np.repeat(np.arange(nprimitives), nsamples) color_array_index = np.array(color_array_index) ncolors = color.shape[0] ncomponents = color.shape[1] color = color.reshape((1, ncolors, ncomponents)) dx = 1. / ncolors offset = dx / 2. self.add_texture('colormap', ncomponents=ncomponents, ndim=1, data=color) self.add_attribute('index', ndim=1, vartype='int', data=color_array_index) self.add_varying('vindex', vartype='int', ndim=1) self.add_vertex_main(""" vindex = index; """) self.add_fragment_main(""" float coord = %.5f + vindex * %.5f; vec4 color = texture1D(colormap, coord); out_color = color; """ % (offset, dx)) # add point size uniform (when it's not specified, there might be some # bugs where its value is obtained from other datasets...) self.add_uniform("point_size", data=point_size) self.add_vertex_main("""gl_PointSize = point_size;""")
def initialize(self, x=None, y=None, color=None, point_size=1.0, position=None, nprimitives=None, index=None, color_array_index=None, thickness=None, options=None, autocolor=None): # if position is specified, it contains x and y as column vectors if position is not None: position = np.array(position, dtype=np.float32) if thickness: shape = (2 * position.shape[0], 1) else: shape = (1, position.shape[0]) else: position, shape = process_coordinates(x=x, y=y) if thickness: shape = (shape[0], 2 * shape[1]) # register the size of the data self.size = np.prod(shape) # there is one plot per row if not nprimitives: nprimitives = shape[0] nsamples = shape[1] else: nsamples = self.size // nprimitives # handle thickness if thickness and position.shape[0] >= 2: w = thickness n = self.size X = position Y = np.zeros((n, 2)) u = np.zeros((n / 2, 2)) X2 = np.vstack((X, 2 * X[-1, :] - X[-2, :])) u[:, 0] = -np.diff(X2[:, 1]) u[:, 1] = np.diff(X2[:, 0]) r = (u[:, 0]**2 + u[:, 1]**2)**.5 rm = r.mean() r[r == 0.] = rm # print u # print r # ind = np.nonzero(r == 0.)[0] # print ind, ind-1 # r[ind] = r[ind - 1] u[:, 0] /= r u[:, 1] /= r Y[::2, :] = X - w * u Y[1::2, :] = X + w * u position = Y x = Y[:, 0] y = Y[:, 1] # print x # print y self.primitive_type = 'TRIANGLE_STRIP' # register the bounds if nsamples <= 1: self.bounds = [0, self.size] else: self.bounds = np.arange(0, self.size + 1, nsamples) # normalize position # if viewbox: # self.add_normalizer('position', viewbox) # by default, use the default color if color is None: if nprimitives <= 1: color = self.default_color # automatic color with color map if autocolor is not None: if nprimitives <= 1: color = get_next_color(autocolor) else: color = [ get_next_color(i + autocolor) for i in xrange(nprimitives) ] # # handle the case where the color is a string where each character # # is a color (eg. 'ry') # if isinstance(color, basestring): # color = list(color) color = get_color(color) # handle the case where there is a single color given as a list of # RGB components instead of a tuple if type(color) is list: if color and (type(color[0]) != tuple) and (3 <= len(color) <= 4): color = tuple(color) else: color = np.array(color) # first, initialize use_color_array to False except if # color_array_index is not None use_color_array = color_array_index is not None if isinstance(color, np.ndarray): colors_ndim = color.shape[1] # first case: one color per point if color.shape[0] == self.size: single_color = False # second case: use a color array so that each plot has a single # color, this saves memory since there is a single color in # memory for any plot else: use_color_array = True single_color = False elif type(color) is tuple: single_color = True colors_ndim = len(color) # set position attribute self.add_attribute("position", ndim=2, data=position, autonormalizable=True) if index is not None: index = np.array(index) # self.size = len(index) self.add_index("index", data=index) # single color case: no need for a color buffer, just use default color if single_color and not use_color_array: self.add_uniform("color", ndim=colors_ndim, data=color) if colors_ndim == 3: self.add_fragment_main(""" out_color = vec4(color, 1.0); """) elif colors_ndim == 4: self.add_fragment_main(""" out_color = color; """) # multiple colors case: color attribute elif not use_color_array: self.add_attribute("color", ndim=colors_ndim, data=color) self.add_varying("varying_color", vartype="float", ndim=colors_ndim) self.add_vertex_main(""" varying_color = color; """) if colors_ndim == 3: self.add_fragment_main(""" out_color = vec4(varying_color, 1.0); """) elif colors_ndim == 4: self.add_fragment_main(""" out_color = varying_color; """) # multiple colors, but with a color array to save memory elif use_color_array: if color_array_index is None: color_array_index = np.repeat(np.arange(nprimitives), nsamples) color_array_index = np.array(color_array_index) ncolors = color.shape[0] ncomponents = color.shape[1] color = color.reshape((1, ncolors, ncomponents)) dx = 1. / ncolors offset = dx / 2. self.add_texture('colormap', ncomponents=ncomponents, ndim=1, data=color) self.add_attribute('index', ndim=1, vartype='int', data=color_array_index) self.add_varying('vindex', vartype='int', ndim=1) self.add_vertex_main(""" vindex = index; """) self.add_fragment_main(""" float coord = %.5f + vindex * %.5f; vec4 color = texture1D(colormap, coord); out_color = color; """ % (offset, dx)) # add point size uniform (when it's not specified, there might be some # bugs where its value is obtained from other datasets...) self.add_uniform("point_size", data=point_size) self.add_vertex_main("""gl_PointSize = point_size;""")
def initialize(self, text, coordinates=(0., 0.), font='segoe', fontsize=24, color=None, letter_spacing=None, interline=0., autocolor=None, prevent_constrain=False, depth=None, posoffset=None): """Initialize the text template.""" if prevent_constrain: self.constrain_ratio = False if autocolor is not None: color = get_color(autocolor) if color is None: color = self.default_color self.size = len(text) self.primitive_type = 'POINTS' self.interline = interline text_length = self.size self.initialize_font(font, fontsize) self.coordinates = coordinates point_size = float(self.matrix[:, 4].max() * self.texture.shape[1]) # template attributes and varyings self.add_attribute("position", vartype="float", ndim=2, data=np.zeros((self.size, 2))) self.add_attribute("offset", vartype="float", ndim=1) self.add_attribute("index", vartype="float", ndim=1) self.add_attribute("text_map", vartype="float", ndim=4) self.add_varying("flat_text_map", vartype="float", flat=True, ndim=4) if posoffset is None: posoffset = (0., 0.) self.add_uniform('posoffset', vartype='float', ndim=2, data=posoffset) # texture self.add_texture("tex_sampler", size=self.texture.shape[:2], ndim=2, ncomponents=self.texture.shape[2], data=self.texture) # pure heuristic (probably bogus) if letter_spacing is None: letter_spacing = (100 + 17. * fontsize) self.add_uniform("spacing", vartype="float", ndim=2, data=(letter_spacing, interline)) self.add_uniform("point_size", vartype="float", ndim=1, data=point_size) # one color per if isinstance(color, np.ndarray) and color.ndim > 1: self.add_attribute('color0', vartype="float", ndim=4, data=color) self.add_varying('color', vartype="float", ndim=4) self.add_vertex_main('color = color0;') else: self.add_uniform("color", vartype="float", ndim=4, data=color) self.add_uniform("text_width", vartype="float", ndim=1) # compound variables self.add_compound("text", fun=self.text_compound, data=text) self.add_compound("coordinates", fun=self.position_compound, data=coordinates) # vertex shader self.add_vertex_main(VS, after='viewport') # fragment shader self.add_fragment_main(FS) self.depth = depth
def initialize(self, camera_angle=None, camera_ratio=None, autocolor=None, camera_zrange=None, position=None, color=None, normal=None, index=None, vertex_shader=None): """Initialize the template. Arguments: * camera_angle: the view angle of the camera, in radians. * camera_ratio: the W/H ratio of the camera. * camera_zrange: a pair with the far and near z values for the camera projection. Template fields are: * `position`: an attribute with the positions as 3D vertices, * `normal`: an attribute with the normals as 3D vectors, * `color`: an attribute with the color of each vertex, as 4D vertices. * `projection`: an uniform with the 4x4 projection matrix, returned by `projection_matrix()`. * `camera`: an uniform with the 4x4 camera matrix, returned by `camera_matrix()`. * `transform`: an uniform with the 4x4 transform matrix, returned by a dot product of `scale_matrix()`, `rotation_matrix()` and `translation_matrix()`. * `light_direction`: the direction of the diffuse light as a 3-vector. * `ambient_light`: the amount of ambient light (white color). """ if autocolor is not None: color = get_color(autocolor) # default camera parameters if camera_angle is None: camera_angle = np.pi / 4 if camera_ratio is None: camera_ratio = 4./3. if camera_zrange is None: camera_zrange = (.5, 10.) self.size = position.shape[0] if self.primitive_type is None: self.primitive_type = 'TRIANGLES' # attributes self.add_attribute("position", vartype="float", ndim=3, data=position) self.add_attribute("normal", vartype="float", ndim=3, data=normal) self.add_attribute("color", vartype="float", ndim=4, data=color) if index is not None: self.add_index("index", data=index) # varying color self.add_varying("varying_color", vartype="float", ndim=4) # default matrices projection = projection_matrix(camera_angle, camera_ratio, *camera_zrange) camera = camera_matrix(np.array([0., 0., -4.]), # position np.zeros(3), # look at np.array([0., 1., 0.])) # top transform = np.eye(4) # matrix uniforms self.add_uniform("projection", ndim=(4, 4), size=None, data=projection) self.add_uniform("camera", ndim=(4, 4), size=None, data=camera) self.add_uniform("transform", ndim=(4, 4), size=None, data=transform) # diffuse and ambient light light_direction = normalize(np.array([0., 0., -1.])) ambient_light = .25 self.add_uniform("light_direction", size=None, ndim=3, data=light_direction) self.add_uniform("ambient_light", size=None, ndim=1, data=ambient_light) # vertex shader with transformation matrices and basic lighting if not vertex_shader: vertex_shader = """ // convert the position from 3D to 4D. gl_Position = vec4(position, 1.0); // compute the amount of light float light = dot(light_direction, normalize(mat3(camera) * mat3(transform) * normal)); light = clamp(light, 0, 1); // add the ambient term light = clamp(ambient_light + light, 0, 1); // compute the final color varying_color = color * light; // keep the transparency varying_color.w = color.w; """ self.add_vertex_main(vertex_shader) # basic fragment shader self.add_fragment_main(""" out_color = varying_color; """) # self.initialize_viewport(True)