static ShaderProgram* createProgram( ShaderProgramIndex index )
{
	ShaderProgram* program = nullptr;
	Ptr<Data> vertex_data;
	Ptr<Data> pixel_data;

	switch( index )
	{
	case kShaderProgram_Color:
		{
			program = new ShaderProgram();
			vertex_data = Assets::loadFile( "standard/shaders/test_vertex.glsl" );
			pixel_data = Assets::loadFile( "standard/shaders/test_fragment.glsl" );
		}
		break;
	default:
		break;
	}

	if( vertex_data == nullptr || fragment_data == nullptr )
		return nullptr;

	program->setVertexSource( vertex_data->ptr() );
	program->setFragmentSource( fragment_data->ptr() );
	
	if( !program->build() )
		return nullptr;

	if( !program-> )


	return program;
}
  void initialize()
  {
    ChangeCurrentOpenGLContext ctx(opengl_context_ptr);
    
    OpenGLBindings *b = new OpenGLBindings();
    if (flextInit(opengl_context_ptr, b) == 0)
    {
        LOG_ERROR << "Failed to initialize flextGL.";
        exit(-1);
    }
    gl(b);

    input_data.allocate(352, 424 * 10);

    for(int i = 0; i < 3; ++i)
      stage1_data[i].allocate(512, 424);

    if(do_debug) stage1_debug.allocate(512, 424);
    stage1_infrared.allocate(512, 424);

    for(int i = 0; i < 2; ++i)
      filter1_data[i].allocate(512, 424);

    filter1_max_edge_test.allocate(512, 424);
    if(do_debug) filter1_debug.allocate(512, 424);

    if(do_debug) stage2_debug.allocate(512, 424);
    stage2_depth.allocate(512, 424);
    stage2_depth_and_ir_sum.allocate(512, 424);

    if(do_debug) filter2_debug.allocate(512, 424);
    filter2_depth.allocate(512, 424);

    stage1.setVertexShader(loadShaderSource(shader_folder + "default.vs"));
    stage1.setFragmentShader(loadShaderSource(shader_folder + "stage1.fs"));
    stage1.build();

    filter1.setVertexShader(loadShaderSource(shader_folder + "default.vs"));
    filter1.setFragmentShader(loadShaderSource(shader_folder + "filter1.fs"));
    filter1.build();

    stage2.setVertexShader(loadShaderSource(shader_folder + "default.vs"));
    stage2.setFragmentShader(loadShaderSource(shader_folder + "stage2.fs"));
    stage2.build();

    filter2.setVertexShader(loadShaderSource(shader_folder + "default.vs"));
    filter2.setFragmentShader(loadShaderSource(shader_folder + "filter2.fs"));
    filter2.build();

    if(do_debug)
    {
      debug.setVertexShader(loadShaderSource(shader_folder + "default.vs"));
      debug.setFragmentShader(loadShaderSource(shader_folder + "debug.fs"));
      debug.build();
    }

    GLenum debug_attachment = do_debug ? GL_COLOR_ATTACHMENT0 : GL_NONE;

    gl()->glGenFramebuffers(1, &stage1_framebuffer);
    gl()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, stage1_framebuffer);

    const GLenum stage1_buffers[] = { debug_attachment, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3, GL_COLOR_ATTACHMENT4 };
    gl()->glDrawBuffers(5, stage1_buffers);

    if(do_debug) gl()->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE, stage1_debug.texture, 0);
    gl()->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_RECTANGLE, stage1_data[0].texture, 0);
    gl()->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_RECTANGLE, stage1_data[1].texture, 0);
    gl()->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_RECTANGLE, stage1_data[2].texture, 0);
    gl()->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT4, GL_TEXTURE_RECTANGLE, stage1_infrared.texture, 0);

    gl()->glGenFramebuffers(1, &filter1_framebuffer);
    gl()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, filter1_framebuffer);

    const GLenum filter1_buffers[] = { debug_attachment, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3 };
    gl()->glDrawBuffers(4, filter1_buffers);

    if(do_debug) gl()->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE, filter1_debug.texture, 0);
    gl()->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_RECTANGLE, filter1_data[0].texture, 0);
    gl()->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_RECTANGLE, filter1_data[1].texture, 0);
    gl()->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_RECTANGLE, filter1_max_edge_test.texture, 0);

    gl()->glGenFramebuffers(1, &stage2_framebuffer);
    gl()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, stage2_framebuffer);

    const GLenum stage2_buffers[] = { debug_attachment, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 };
    gl()->glDrawBuffers(3, stage2_buffers);

    if(do_debug) gl()->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE, stage2_debug.texture, 0);
    gl()->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_RECTANGLE, stage2_depth.texture, 0);
    gl()->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_RECTANGLE, stage2_depth_and_ir_sum.texture, 0);

    gl()->glGenFramebuffers(1, &filter2_framebuffer);
    gl()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, filter2_framebuffer);

    const GLenum filter2_buffers[] = { debug_attachment, GL_COLOR_ATTACHMENT1 };
    gl()->glDrawBuffers(2, filter2_buffers);

    if(do_debug) gl()->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE, filter2_debug.texture, 0);
    gl()->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_RECTANGLE, filter2_depth.texture, 0);

    Vertex bl = {-1.0f, -1.0f, 0.0f, 0.0f }, br = { 1.0f, -1.0f, 512.0f, 0.0f }, tl = {-1.0f, 1.0f, 0.0f, 424.0f }, tr = { 1.0f, 1.0f, 512.0f, 424.0f };
    Vertex vertices[] = {
        bl, tl, tr, tr, br, bl
    };
    gl()->glGenBuffers(1, &square_vbo);
    gl()->glGenVertexArrays(1, &square_vao);

    gl()->glBindVertexArray(square_vao);
    gl()->glBindBuffer(GL_ARRAY_BUFFER, square_vbo);
    gl()->glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    GLint position_attr = stage1.getAttributeLocation("Position");
    gl()->glVertexAttribPointer(position_attr, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)0);
    gl()->glEnableVertexAttribArray(position_attr);

    GLint texcoord_attr = stage1.getAttributeLocation("TexCoord");
    gl()->glVertexAttribPointer(texcoord_attr, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)(2 * sizeof(float)));
    gl()->glEnableVertexAttribArray(texcoord_attr);
  }