def to_vaocontent(ctx: moderngl.Context, pos_data, normal_data, uv_data) -> List[moderngl.Buffer]: del normal_data return [ (ctx.buffer(pos_data.astype('f4').tobytes()), '3f', 'in_position'), (ctx.buffer(uv_data.astype('f4').tobytes()), '2f', 'in_texcoord_0'), ]
def __init__(self, context: mgl.Context, shader, width, height, text, font, color=(1, 1, 1, 1), anchor_x='center', anchor_y='center', *args, **kwargs): super().__init__(context, shader, *args, **kwargs) self.color = Vector4f(color) self.anchor_x = anchor_x self.anchor_y = anchor_y vertices, indices = self.bake(text, font) manager = FontManager() atlas = manager.atlas_agg self.atlas = context.texture(atlas.shape[0:2], 3, atlas.view(np.ubyte)) vbo = context.buffer(vertices.view(np.ubyte)) ibo = context.buffer(indices.view(np.ubyte)) self.vao = context.vertex_array( shader, [ # TODO: pad? maybe doesn't matter 'cause we're not streaming (vbo, '2f 2f 1f', 'vertices', 'texcoord', 'offset') ], index_buffer=ibo) shader['viewport'].value = width, height self.atlas.use()
def __init__(self, ctx: mgl.Context, lc: vp.LineCollection, color: ColorType): super().__init__(ctx) self._prog = load_program("fast_line", ctx) vertices, indices = self._build_buffers(lc, color=color) vbo = ctx.buffer(vertices.astype("f4").tobytes()) ibo = ctx.buffer(indices.astype("i4").tobytes()) self._vao = ctx.simple_vertex_array( self._prog, vbo, "in_vert", "in_color", index_buffer=ibo )
def __init__( self, ctx: mgl.Context, lc: vp.LineCollection, pen_width: float, color: ColorType ): super().__init__(ctx) self._color = color self._pen_width = pen_width self._prog = load_program("preview_line", ctx) vertices, indices = self._build_buffers(lc) vbo = ctx.buffer(vertices.tobytes()) ibo = ctx.buffer(indices.tobytes()) self._vao = ctx.simple_vertex_array(self._prog, vbo, "position", index_buffer=ibo)
def __init__(self, ctx: moderngl.Context, size: Size, mesh: Mesh, projection: np.array, components=4): self.size = size self.projection = projection self.prog = ctx.program( vertex_shader=Path('shaders/simple.vert').read_text(), fragment_shader=Path('shaders/simple.frag').read_text()) #from ModernGL.ext.obj import Obj #mesh = Obj.open('meshes/cube.obj') #vertex_data = mesh.pack('vx vy vz nx ny nz') #self.vao = from_mesh(ctx, self.prog, mesh) vertex_data = pack(mesh).astype('f4').tobytes() self.vbo = ctx.buffer(vertex_data) self.vao = ctx.simple_vertex_array(self.prog, self.vbo, 'in_vert', 'in_normal') self.fbo = create_fbo(ctx, self.size, components) self.fbo.use() self.ctx = ctx
def _update_data(self, ctx: moderngl.Context): sizes = [v.shape[0] for v in self.data.values()] assert np.std( sizes ) == 0, "All data needs to be of the same size! Got %s" % str(sizes) for k in self.data: assert k in self.inputs, 'Data \'%s\' not a shader input. Possible values : %s' % ( k, str(self.inputs)) buffers = [] for k, i in self.inputs.items(): if k not in self.data: if k[:3] != 'gl_': print('Input \'%s\' not specified! Ignoring it.' % k) continue data = self.data[k].astype('f4').tobytes() if k not in self.data_buf or self.data_buf[k].size < len(data): self.data_buf[k] = ctx.buffer(data) else: self.data_buf[k].write(data) if len(self.data[k].shape) <= 1 or self.data[k].shape[1] == 1: buffers.append((self.data_buf[k], 'f4', k)) else: buffers.append( (self.data_buf[k], '%df4' % self.data[k].shape[1], k)) buffer_names = set([k for _, _, k in buffers]) if self.vao is None or self._vao_buffers != buffer_names: self.vao = ctx.vertex_array(self.program, buffers) self._vao_buffers = buffer_names return sizes[0]
def __init__(self, *, ctx: moderngl.Context, size: Tuple[int, int, int]): self.ctx = ctx self._size = size # Create lookup texture for active blocks # NOTE: We allocate room for 100 x 100 x 100 for now # 100 x 100 x 100 = 1_000_000 fragments # 1000 x 1000 = 1_000_000 fragments # We store several 100 x 100 layers respersting one slice in voxel self.voxel_lookup = self.ctx.texture((1000, 1000), 1, dtype='f1') self.voxel_lookup.filter = moderngl.NEAREST, moderngl.NEAREST self.voxel_lookup.repeat_x = False self.voxel_lookup.repeat_y = False # Write in some default data for i in range(100): self.fill_layer(i, 255) # Construct the per-instance data for active cubes using a transform self.instance_data = ctx.buffer(reserve=self.max_cubes * 4 * 3) self.quad_fs = geometry.quad_fs() self.gen_instance_vao = None self._num_instances = 0 self._query = self.ctx.query(primitives=True) self.cube = geometry.cube() self.cube.buffer(self.instance_data, "3f/i", ["in_offset"]) # Filled externally self.texture_prog = None self.gen_instance_prog = None self.voxel_light_prog = None self.voxel_wireframe_prog = None
def __init__( self, ctx: mgl.Context, paper_size: Tuple[float, float], color: ColorType = (0, 0, 0, 0.45), shadow_size: float = 7.0, ): super().__init__(ctx) data = np.array( [ (0, 0), (paper_size[0], 0), (paper_size[0], paper_size[1]), (0, paper_size[1]), (paper_size[0], shadow_size), (paper_size[0] + shadow_size, shadow_size), (paper_size[0] + shadow_size, paper_size[1] + shadow_size), (shadow_size, paper_size[1] + shadow_size), (shadow_size, paper_size[1]), ], dtype="f4", ) line_idx = np.array([0, 1, 2, 3], dtype="i4") triangle_idx = np.array( [ (0, 3, 1), # page background (1, 3, 2), (4, 2, 5), # shadow (2, 6, 5), (7, 6, 2), (8, 7, 2), ], dtype="i4", ).reshape(-1) self._color = color self._prog = load_program("fast_line_mono", ctx) vbo = ctx.buffer(data.tobytes()) self._bounds_vao = ctx.simple_vertex_array( self._prog, vbo, "in_vert", index_buffer=ctx.buffer(line_idx.tobytes()) ) self._shading_vao = ctx.simple_vertex_array( self._prog, vbo, "in_vert", index_buffer=ctx.buffer(triangle_idx.tobytes()) )
def __init__(self, ctx: moderngl.Context, fragment_shader: str, send_uvs: bool = True): self.ctx = ctx self.prog = shadermgr(ctx).get( vertex_shader=POSTPROCESS_VERT_PROGRAM, fragment_shader=fragment_shader, ) indices = ctx.buffer(self.QUAD_INDICES) self.vs_uvs = ctx.buffer(self.QUAD_VERTS_UVS) if send_uvs: attribs = (self.vs_uvs, '2f4 2f4', 'in_vert', 'in_uv') else: attribs = (self.vs_uvs, '2f4 8x', 'in_vert') self.vao = ctx.vertex_array(self.prog, [attribs], index_buffer=indices)
def __init__( self, ctx: mgl.Context, lc: vp.LineCollection, color: ColorType = (0, 0, 0, 0.25) ): super().__init__(ctx) vertex = """ #version 330 uniform mat4 projection; in vec2 position; void main() { gl_PointSize = 5.0; gl_Position = projection * vec4(position, 0.0, 1.0); } """ fragment = """ #version 330 uniform vec4 color; out vec4 out_color; void main() { out_color = color; } """ self._prog = ctx.program(vertex_shader=vertex, fragment_shader=fragment) self._color = color vertices, indices = self._build_buffers(lc) vbo = ctx.buffer(vertices.astype("f4").tobytes()) ibo = ctx.buffer(indices.astype("i4").tobytes()) self._vao = ctx.simple_vertex_array(self._prog, vbo, "position", index_buffer=ibo)
def __init__( self, ctx: mgl.Context, lc: vp.LineCollection, color: ColorType = (0, 0, 0, 0.5) ): super().__init__(ctx) self._color = color self._prog = load_program("fast_line_mono", ctx) # build vertices vertices: List[Tuple[float, float]] = [] for i in range(len(lc) - 1): vertices.extend( ((lc[i][-1].real, lc[i][-1].imag), (lc[i + 1][0].real, lc[i + 1][0].imag)) ) if len(vertices) > 0: vbo = ctx.buffer(np.array(vertices, dtype="f4").tobytes()) self._vao = ctx.simple_vertex_array(self._prog, vbo, "in_vert") else: self._vao = None
def __init__(self, context: mgl.Context, shader, num_particles=1e5, *args, **kwargs): super().__init__(context, shader, *args, **kwargs) self.context = context # we need to keep a reference to the shader around # for copying buffers & whatnot self._tracker = 1.0 num_particles = int(num_particles) self.num_particles = num_particles color_size = np.zeros(num_particles, dtype=[('color_size', np.float32, 4)]) # first three elements are RGB, last one is particle (i.e. GL_POINT) size # this is static, and we don't need to do any extra computations color_size['color_size'][:, 0] = np.random.uniform( 0.9, 1.0, num_particles) color_size['color_size'][:, 1] = np.random.uniform( 0.0, 1.0, num_particles) color_size['color_size'][:, 2] = np.random.uniform( 0.0, 0.1, num_particles) color_size['color_size'][:, 3] = np.random.uniform( 0.1, 4.0, num_particles) # first three elements are vertex XYZ, last one is alpha # think about this-- should we just delay until ready to draw the first time? # if the scale isn't set immediately, then end up with garbage? pos_alpha = np.zeros(num_particles, dtype=[('vertices_alpha', np.float32, 8)]) r, theta = random_on_circle(self.scale.y * 0.2, num_particles) pos_alpha['vertices_alpha'][:, 0:2] = np.array( [np.cos(theta) * r, np.sin(theta) * r]).T pos_alpha['vertices_alpha'][:, 3] = np.random.uniform( 0.5, 1.0, num_particles) # it looks like the moderngl example allocates 2x the amount, so the first 4 # are from the current timestep and the last 4 are from the previous timestep # then during rendering, the previous timestep is ignored (treated as padding) r_accel, theta_accel = random_on_circle(0.08, self.num_particles) accel = np.zeros(num_particles, dtype=[('accel', np.float32, 4)]) accel['accel'][:, :2] = np.array( [r_accel * np.cos(theta_accel), r_accel * np.sin(theta_accel)]).T accel = context.buffer(accel.view(np.ubyte)) # vbo_render is what ends up being rendered # vbo_trans is an intermediary for transform feedback # vbo_orig is the original state, which we use to "reset" the explosion # without writing new data to the GPU color_size2 = context.buffer(color_size.view(np.ubyte)) self.vbo_render = context.buffer(pos_alpha.view(np.ubyte)) self.vbo_trans = context.buffer(reserve=self.vbo_render.size) self.vbo_orig = context.buffer(reserve=self.vbo_render.size) self.vao_trans = context.vertex_array( shader.transform, [(self.vbo_render, '4f 4f', 'in_pos_alpha', 'in_prev_pos_alpha'), (accel, '4f', 'accel')]) # self.vao_trans = context.simple_vertex_array(..., self.vbo_trans, ???) self.vao_render = context.vertex_array( shader.render, [(self.vbo_render, '4f 4x4', 'vertices_alpha'), (color_size2, '4f', 'color_size')]) # set the data of the original state context.copy_buffer(self.vbo_orig, self.vbo_render) context.point_size = 2.0 # TODO: set point size as intended
def from_mesh(ctx: moderngl.Context, program: moderngl.Program, mesh: Mesh): buffer = mesh.vertices.astype('f4').copy('C') vbo = ctx.buffer(buffer) vao = ctx.simple_vertex_array(program, vbo, 'in_position', 'in_normal') return vao