def init_shader(self): self.program = Program() self.program.shaders.append(Shader(GL_VERTEX_SHADER, load_lib_file('glsl/plot2d/axis/marker_y.vert.glsl'))) self.program.shaders.append(Shader(GL_GEOMETRY_SHADER, load_lib_file('glsl/plot2d/axis/marker_y.geom.glsl'))) self.program.shaders.append(Shader(GL_FRAGMENT_SHADER, load_lib_file('glsl/plot2d/axis/marker.frag.glsl'))) self.program.link() self.program.uniform('color', self.linecolor) self.vao = VertexArray({ 'vertex_position': VertexBuffer.from_numpy(self.measurements) }, self.program.attributes)
def scale(self, top_left, bottom_right): """ scales to field to a rectangle with top_left and bottom_right corner """ if self.domain is None: self._coord_top_left = top_left or (0, 1) self._coord_bottom_right = bottom_right or (1, 0) else: dimensions = (self.domain.dimensions[0] - 1, self.domain.dimensions[1] - 1) unit_size_x = 0.5 * float(bottom_right[0] - top_left[0]) / dimensions[1] unit_size_y = 0.5 * float(top_left[1] - bottom_right[1]) / dimensions[0] self._coord_top_left = (top_left[0] - unit_size_x, top_left[1] + unit_size_y) self._coord_bottom_right = (bottom_right[0] + unit_size_x, bottom_right[1] - unit_size_y) self._np_vertex_data = np.array( [ self._coord_top_left[0], self._coord_top_left[1], self._coord_top_left[0], self._coord_bottom_right[1], self._coord_bottom_right[0], self._coord_bottom_right[1], self._coord_bottom_right[0], self._coord_bottom_right[1], self._coord_bottom_right[0], self._coord_top_left[1], self._coord_top_left[0], self._coord_top_left[1], ], dtype=np.float32, ).reshape(6, 2) self.vertex_array = VertexArray( { "vertex_position": VertexBuffer.from_numpy(self._np_vertex_data), "texture_position": VertexBuffer.from_numpy(self._np_texture_data), }, self.program.attributes, ) self.top_left = top_left self.bottom_right = bottom_right
class Fixed(): def __init__(self, camera, scale_camera, measurements, bgcolor, size, modelview=None, linecolor=[1,1,1,1]): self.size = size self.measurements = numpy.array([(x,10) for x in measurements], dtype=numpy.float32).reshape(len(measurements),2) self.bgcolor = bgcolor self.camera = camera self.scale_camera = scale_camera self.modelview = modelview self.linecolor = linecolor def init(self): self._frame = window.Framebuffer( camera = self.camera, screensize = self.size, clear_color = self.bgcolor, multisampling= 4, modelview = self.modelview, ) scaling = [0,0] scaling[0] = self.size[0] scaling[1] = self.scale_camera.get_scaling()[1] self._frame.inner_camera.set_scaling(scaling) self._frame.inner_camera.set_base_matrix(np.array([ 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, ], dtype=np.float32)) self._frame.init() self.init_shader() def init_shader(self): self.program = Program() self.program.shaders.append(Shader(GL_VERTEX_SHADER, load_lib_file('glsl/plot2d/axis/marker_y.vert.glsl'))) self.program.shaders.append(Shader(GL_GEOMETRY_SHADER, load_lib_file('glsl/plot2d/axis/marker_y.geom.glsl'))) self.program.shaders.append(Shader(GL_FRAGMENT_SHADER, load_lib_file('glsl/plot2d/axis/marker.frag.glsl'))) self.program.link() self.program.uniform('color', self.linecolor) self.vao = VertexArray({ 'vertex_position': VertexBuffer.from_numpy(self.measurements) }, self.program.attributes) def update_modelview(self): self._frame.update_modelview() def update_camera(self, camera): scaling = [0,0] scaling[0] = self.size[0] scaling[1] = self.scale_camera.get_scaling()[1] self.size = (self.size[0], self.scale_camera.screensize[1]) self._frame.screensize = self.size self._frame.capture_size = self.size self._frame.inner_camera.set_position(y=self.scale_camera.position[1]) self._frame.inner_camera.set_screensize(self.size) self._frame.inner_camera.set_scaling(scaling) self._frame.update_camera(camera) @property def labels(self): screen_scale = self._frame.inner_camera.screensize[1] / float(self._frame.inner_camera.initial_screensize[1]) y_range = (self._frame.inner_camera.position[1], self._frame.inner_camera.position[1] + screen_scale*self._frame.inner_camera.scaling[1]) return [(float(y), '{:.3f}'.format(float(y))) for y,_ in self.measurements if y > y_range[0] and y < y_range[1]] def render(self): """ renders the axis. also checks whether there is a change in screensize or whether the object was ininzialized. """ self._frame.use() self.program.use() self.vao.bind() self.program.uniform('mat_camera', self._frame.inner_camera.get_matrix()) self.program.uniform('mat_outer_camera', self._frame.camera.get_matrix()) glDrawArrays(GL_POINTS, 0, len(self.measurements)) self.vao.unbind() self.program.unuse() self._frame.unuse() self._frame.render()
class Field: """ draw a 2d field by using Field Domain (OpenGL textures). this plot runs either with or without a given FieldDomain(texture). If no domain defined, the field will scale to top_left, bottom_right. the data_kernel can be used to calculate data where domain is [0,1] x [0,1]. if domain is not None, that top_left, bottom_right will be the center of top_left and bottom_right texel. data_kernel is by default the default glsl 2d texture sampler. using a color scheme one can modify data from data_kernel. (field plot color scheme...) """ def __init__(self, domain=None, top_left=None, bottom_right=None, color_scheme=None, data_kernel=None): if domain is None and data_kernel is None: raise ValueError("either domain or data_kernel must be defined.") self.top_left = top_left or None self.bottom_right = bottom_right or None self.domain = domain self.color_scheme = color_scheme or "" self.initialized = False self.program = None self.data_kernel = data_kernel or "fragment_color = texture(tex[0], x);" self._np_vertex_data = None self._np_texture_data = None self._coord_top_left = None self._coord_bottom_right = None def init(self): if self.domain is not None: if not hasattr(self.domain, "dimensions"): raise ValueError("domain must have attribute domain.dimensions") if not hasattr(self.domain, "gl_texture_id"): raise ValueError("domain must have attribute domain.gl_texture_id") self.domain.gl_init() if self.top_left is None: self.top_left = (1, self.domain.dimensions[1]) if self.bottom_right is None: self.bottom_right = (self.domain.dimensions[0], 1) self.gl_init() self._np_texture_data = np.array([0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0], dtype=np.float32).reshape(6, 2) self.scale(self.top_left, self.bottom_right) self.initialized = True def scale(self, top_left, bottom_right): """ scales to field to a rectangle with top_left and bottom_right corner """ if self.domain is None: self._coord_top_left = top_left or (0, 1) self._coord_bottom_right = bottom_right or (1, 0) else: dimensions = (self.domain.dimensions[0] - 1, self.domain.dimensions[1] - 1) unit_size_x = 0.5 * float(bottom_right[0] - top_left[0]) / dimensions[1] unit_size_y = 0.5 * float(top_left[1] - bottom_right[1]) / dimensions[0] self._coord_top_left = (top_left[0] - unit_size_x, top_left[1] + unit_size_y) self._coord_bottom_right = (bottom_right[0] + unit_size_x, bottom_right[1] - unit_size_y) self._np_vertex_data = np.array( [ self._coord_top_left[0], self._coord_top_left[1], self._coord_top_left[0], self._coord_bottom_right[1], self._coord_bottom_right[0], self._coord_bottom_right[1], self._coord_bottom_right[0], self._coord_bottom_right[1], self._coord_bottom_right[0], self._coord_top_left[1], self._coord_top_left[0], self._coord_top_left[1], ], dtype=np.float32, ).reshape(6, 2) self.vertex_array = VertexArray( { "vertex_position": VertexBuffer.from_numpy(self._np_vertex_data), "texture_position": VertexBuffer.from_numpy(self._np_texture_data), }, self.program.attributes, ) self.top_left = top_left self.bottom_right = bottom_right def gl_init(self): """ initializes shader program and plane vao """ glsl_functions = "" if hasattr(self.color_scheme, "glsl_functions"): glsl_functions += "\n/*COLOR_SCHEME FUNCTIONS*/\n" glsl_functions += self.color_scheme.glsl_functions if hasattr(self.data_kernel, "glsl_functions"): glsl_functions += "\n/*DATA_KERNEL FUNCTIONS*/\n" glsl_functions += self.data_kernel.glsl_functions glsl_uniforms = [] if hasattr(self.color_scheme, "glsl_uniforms"): glsl_uniforms.append("/*COLOR_SCHEME UNIFORMS*/") glsl_uniforms += ["uniform {} {};".format(t, n) for t, n in self.color_scheme.glsl_uniforms] if hasattr(self.data_kernel, "glsl_uniforms"): glsl_uniforms.append("/*DATA_KERNEL UNIFORMS*/") glsl_uniforms += ["uniform {} {};".format(t, n) for t, n in self.data_kernel.glsl_uniforms] frag_src = pystache.render( load_lib_file("glsl/plot2d/field.frag.glsl"), { "UNIFORMS": "\n".join(glsl_uniforms), "FUNCTIONS": glsl_functions, "DATA_KERNEL": str(self.data_kernel), "COLOR_KERNEL": str(self.color_scheme), }, ) self.program = Program() self.program.shaders.append(Shader(GL_VERTEX_SHADER, load_lib_file("glsl/plot2d/field.vert.glsl"))) self.program.shaders.append(Shader(GL_FRAGMENT_SHADER, frag_src)) self.program.link() if hasattr(self.color_scheme, "get_uniform_data"): for uniform in self.color_scheme.get_uniform_data().items(): self.program.uniform(*uniform) if hasattr(self.data_kernel, "get_uniform_data"): for uniform in self.data_kernel.get_uniform_data().items(): self.program.uniform(*uniform) self.initialized = True def update_plotmeta(self, plot_cam, outer_cam, *args, **kwargs): # not so nice ... but later refactoring ... self.program.uniform("mat_domain", np.identity(3)) self.program.uniform("mat_camera", plot_cam) self.program.uniform("mat_outer_camera", outer_cam) if hasattr(self.color_scheme, "get_uniform_data"): for uniform in self.color_scheme.get_uniform_data().items(): self.program.uniform(*uniform) if hasattr(self.data_kernel, "get_uniform_data"): for uniform in self.data_kernel.get_uniform_data().items(): self.program.uniform(*uniform) def render(self, plotter): # final rendering glActiveTexture(GL_TEXTURE0) if self.domain is not None: glBindTexture(GL_TEXTURE_2D, self.domain.gl_texture_id) else: glBindTexture(GL_TEXTURE_2D, 0) self.vertex_array.bind() self.program.use() glDrawArrays(GL_TRIANGLES, 0, 6) self.vertex_array.unbind() self.program.unuse() @classmethod def create_texture1f(cls, size): texture = glGenTextures(1) glBindTexture(GL_TEXTURE_2D, texture) glTexImage2D( GL_TEXTURE_2D, 0, GL_RED, size[0], size[1], 0, GL_RED, GL_FLOAT, np.zeros(size[0] * size[1], dtype=np.float32), ) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) glBindTexture(GL_TEXTURE_2D, 0) return texture