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 _compile(self, ctx: moderngl.Context): if self.program is None: self.program = ctx.program(vertex_shader=self.vertex_shader, fragment_shader=self.fragment_shader, geometry_shader=self.geometry_shader) for n in self.program: v = self.program[n] if isinstance(v, moderngl.Attribute): self.inputs[n] = v if isinstance(v, moderngl.Uniform): self.uniforms[n] = v