/*===========================================================================*/
void StochasticUniformGridRenderer::Engine::draw( kvs::ObjectBase* object, kvs::Camera* camera, kvs::Light* light )
{
    kvs::Texture::Binder unit0( m_volume_texture, 0 );
    kvs::Texture::Binder unit1( m_exit_texture, 1 );
    kvs::Texture::Binder unit2( m_entry_texture, 2 );
    kvs::Texture::Binder unit3( m_transfer_function_texture, 3 );
    kvs::Texture::Binder unit4( randomTexture(), 4 );
    kvs::ProgramObject::Binder unit( m_ray_casting_shader );

    if ( isEnabledShading() ) kvs::OpenGL::Enable( GL_LIGHTING );
    else kvs::OpenGL::Disable( GL_LIGHTING );

    const float f = camera->back();
    const float n = camera->front();
    const float to_zw1 = ( f * n ) / ( f - n );
    const float to_zw2 = 0.5f * ( ( f + n ) / ( f - n ) ) + 0.5f;
    const float to_ze1 = 0.5f + 0.5f * ( ( f + n ) / ( f - n ) );
    const float to_ze2 = ( f - n ) / ( f * n );
    const kvs::Vector3f light_position = kvs::WorldCoordinate( light->position() ).toObjectCoordinate( object ).position();
    const kvs::Vector3f camera_position = kvs::WorldCoordinate( camera->position() ).toObjectCoordinate( object ).position();
    m_ray_casting_shader.setUniform( "to_zw1", to_zw1 );
    m_ray_casting_shader.setUniform( "to_zw2", to_zw2 );
    m_ray_casting_shader.setUniform( "to_ze1", to_ze1 );
    m_ray_casting_shader.setUniform( "to_ze2", to_ze2 );
    m_ray_casting_shader.setUniform( "light_position", light_position );
    m_ray_casting_shader.setUniform( "camera_position", camera_position );

    const size_t size = randomTextureSize();
    const int count = repetitionCount() * ::RandomNumber();
    const float offset_x = static_cast<float>( ( count ) % size );
    const float offset_y = static_cast<float>( ( count / size ) % size );
    const kvs::Vec2 random_offset( offset_x, offset_y );
    m_ray_casting_shader.setUniform( "random_offset", random_offset );
    this->draw_quad();
}
int main(void)
{
    srand(time(NULL));
    example_usage::TextureFactory tf(256);

    int count = 0;

    example_usage::Texture *t;

    while ((t = tf.create(count++))) {
        int *tempTexture = randomTexture();
        t->loadTexture(tempTexture);
        free(tempTexture);
        std::cout << "\n\n" << *t;
    }

    t = tf.create(count++); /* this should fail */

    if (!t) {
        std::cout << "\npoolSize+1 allocation failed. (YAY!)";
    } else {
        std::cout << "\nAllocation succeedded (BOO-URNS).";
    }

    std::cout << "\n";
    std::cout << tf;

    tf.mark(1000);
    tf.free(2000);

    std::cout << "\n";
    std::cout << tf;

    t = tf.create(count++);

    if (!t) {
        std::cout << "\nAfter empty allocation failed. (BOO-URNS!)";
    } else {
        std::cout << "\nAfter empty allocation succeedded (YAY!).";
    }

    std::cout << "\n";
    std::cout << tf;

}