void EdvsRiftApp::drawSphereBackground(int camera_id)
{
    static ProgramPtr program = oria::loadProgram("./resources/sphere_background.vs", "./resources/sphere_background.fs");
    static ShapeWrapperPtr geometry = ShapeWrapperPtr(new shapes::ShapeWrapper({ "Position" }, shapes::ObjMesh(mesh_input.stream), *program));

    // Reset before application exit
    Platform::addShutdownHook([]
    {
        program.reset();
        geometry.reset();
    });


    MatrixStack & mv = Stacks::modelview();

    mv.withPush([&]
    {
        // Binds the program
        program->Use();

        // Matrices as uniforms
        Mat4Uniform(*program, "ModelView").Set(Stacks::modelview().top());
        Mat4Uniform(*program, "Projection").Set(Stacks::projection().top());

        // Draw this
        geometry->Use();
        geometry->Draw();
    });

    // Unbind
    oglplus::NoProgram().Bind();
    oglplus::NoVertexArray().Bind();
}
void EdvsRiftApp::drawEvents()
{
    static ProgramPtr program = oria::loadProgram("./resources/event_pixel.vs", "./resources/event_pixel.fs");

    // Reset before application exit
    Platform::addShutdownHook([]
    {
        program.reset();
    });


    MatrixStack & mv = Stacks::modelview();

    mv.withPush([&]
    {
        // Binds the program
        program->Use();

        // Matrices as uniforms
        Mat4Uniform(*program, "ModelView").Set(Stacks::modelview().top());
        Mat4Uniform(*program, "Projection").Set(Stacks::projection().top());

        // Manual set for azimuth and elevation
        oglplus::Uniform<float>(*program, "ManAzimuth").Set(azimuth);
        oglplus::Uniform<float>(*program, "ManElevation").Set(elevation);

        // Manual set for field of view
        oglplus::Uniform<float>(*program, "FovX").Set(60.0 * DEGREES_TO_RADIANS);
        oglplus::Uniform<float>(*program, "FovY").Set(60.0 * DEGREES_TO_RADIANS);


        // Bind VAO
        vao->Bind();

        // Bind VBO "Positions"
        vbo_position->Bind(Buffer::Target::Array);
        {
            Buffer::Data(Buffer::Target::Array, position_);

            VertexArrayAttrib vao_attr(*program, "Position");
            vao_attr.Setup<Vec2f>();
            vao_attr.Enable();
        }

        // Bind VBO "CameraId"
        vbo_camera_id->Bind(Buffer::Target::Array);
        {
            Buffer::Data(Buffer::Target::Array, camera_id_);

            VertexArrayAttrib vao_attr(*program, "CameraId");
            vao_attr.Setup<Vec1f>();
            vao_attr.Enable();
        }

        // Bind VBO "Color"
        vbo_color->Bind(Buffer::Target::Array);
        {
            Buffer::Data(Buffer::Target::Array, parity_); //, BufferUsage::StreamDraw);

            VertexArrayAttrib vao_attr(*program, "Color");
            vao_attr.Setup<Vec1f>();
            vao_attr.Enable();
        }

        // Draw all elements
        Context::DrawArrays(PrimitiveType::Points, 0, camera_id_.size());
    });

    // Unbind
    oglplus::NoProgram().Bind();
    oglplus::NoVertexArray().Bind();
}