def reload_shaders(self):
        print("Reloading shaders..")
        self.prog_eep = self.ctx.program([
            self.ctx.vertex_shader(load_shader("exitpoints.vert")),
            self.ctx.fragment_shader(load_shader("exitpoints.frag")),
        ])

        self.prog_rc = self.ctx.program([
            self.ctx.vertex_shader(load_shader("raycasting.vert")),
            self.ctx.fragment_shader(load_shader("raycasting.frag")),
        ])

        # re-attach vertex array objects
        vbo_attributes = [
            'VerPos',
        ]
        vbo_format = ModernGL.detect_format(self.prog_eep, vbo_attributes)
        self.vao_eep = self.ctx.vertex_array(
            self.prog_eep, [(self.vbo_vertex, vbo_format, vbo_attributes)],
            self.vbo_veridx)

        vbo_format = ModernGL.detect_format(self.prog_rc, vbo_attributes)
        self.vao_rc = self.ctx.vertex_array(
            self.prog_rc, [(self.vbo_vertex, vbo_format, vbo_attributes)],
            self.vbo_veridx)

        # update handles for the uniforms
        self.unf_screensize = self.prog_rc.uniforms["ScreenSize"]
        self.unf_stepsize = self.prog_rc.uniforms["StepSize"]
        self.unf_transferfunc = self.prog_rc.uniforms["TransferFunc"]
        self.unf_exitpoints = self.prog_rc.uniforms["ExitPoints"]
        self.unf_volumetex = self.prog_rc.uniforms["VolumeTex"]
    def test_arrays(self):
        vert_src = '''
			#version %(version)s

			in %(type)s v_in[];
			out %(type)s v_out[];

			void main() {
				v_out[0] = v_in[0] * 2;
				v_out[1] = v_in[1] * 2;
			}
		'''

        for vtype in vtypes:
            try:
                prog = self.ctx.program(
                    self.ctx.vertex_shader(vert_src % vtype), ['v_out'])
            except ModernGL.Error:
                # skip when version 410 not supported
                continue

            fmt = ModernGL.detect_format(prog, ['v_in'])
            vbo1 = self.ctx.buffer(struct.pack(fmt, *(vtype['input'] * 2)))
            vbo2 = self.ctx.buffer(b'\xAA' * struct.calcsize(fmt))
            vao = self.ctx.simple_vertex_array(prog, vbo1, ['v_in'])
            vao.transform(vbo2, ModernGL.POINTS, 1)

            for a, b in zip(struct.unpack(fmt, vbo2.read()),
                            vtype['output'] * 2):
                self.assertAlmostEqual(a, b)
    def test_arrays(self):
        vert_src = '''
            #version %(version)s

            in %(type)s v_in[];
            out %(type)s v_out[];

            void main() {
                v_out[0] = v_in[0] + v_in[0];
                v_out[1] = v_in[1] + v_in[1];
            }
        '''

        for vtype in vtypes:
            if self.ctx.version_code < vtype['version']:
                warnings.warn('skipping version %s' % vtype['version'])
                continue

            prog = self.ctx.program(self.ctx.vertex_shader(vert_src % vtype),
                                    ['v_out'])

            if 'v_in' not in prog.attributes:
                warnings.warn('skipping %s' % vtype['type'])
                continue

            fmt = ModernGL.detect_format(prog, ['v_in'])
            vbo1 = self.ctx.buffer(struct.pack(fmt, *(vtype['input'] * 2)))
            vbo2 = self.ctx.buffer(b'\xAA' * struct.calcsize(fmt))
            vao = self.ctx.simple_vertex_array(prog, vbo1, ['v_in'])
            vao.transform(vbo2, ModernGL.POINTS, 1)

            for a, b in zip(struct.unpack(fmt, vbo2.read()),
                            vtype['output'] * 2):
                self.assertAlmostEqual(a, b)