Example #1
0
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'),
    ]
Example #2
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()
Example #3
0
    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
        )
Example #4
0
    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)
Example #5
0
    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
Example #6
0
    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]
Example #7
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
Example #8
0
    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())
        )
Example #9
0
    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)
Example #10
0
    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)
Example #11
0
    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
Example #12
0
    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
Example #13
0
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