コード例 #1
0
ファイル: GenericOCIO.cpp プロジェクト: theomission/openfx-io
bool
GenericOCIO::isIdentity(double time)
{
    assert(_created);
#ifdef OFX_IO_USING_OCIO
    if (!_config) {
        return true;
    }
    std::string inputSpace;
    getInputColorspaceAtTime(time, inputSpace);
    std::string outputSpace;
    getOutputColorspaceAtTime(time, outputSpace);
    if (inputSpace == outputSpace) {
        return true;
    }
    // must clear persistent message in isIdentity, or render() is not called by Nuke after an error
    _parent->clearPersistentMessage();
    try {
        // maybe the names are not the same, but it's still a no-op (e.g. "scene_linear" and "linear")
        OCIO::ConstContextRcPtr context = getLocalContext(time);//_config->getCurrentContext();
        OCIO_NAMESPACE::ConstProcessorRcPtr proc = _config->getProcessor(context, inputSpace.c_str(), outputSpace.c_str());
        return proc->isNoOp();
    } catch (const std::exception& e) {
        _parent->setPersistentMessage(OFX::Message::eMessageError, "", e.what());
        OFX::throwSuiteStatusException(kOfxStatFailed);
        return false;
    }
#else
    return true;
#endif
}
コード例 #2
0
ファイル: main.cpp プロジェクト: AheadIO/OpenColorIO
void Generate(int cubesize, int maxwidth,
              const std::string & outputfile,
              const std::string & configfile,
              const std::string & incolorspace,
              const std::string & outcolorspace)
{
    int width = 0;
    int height = 0;
    int numchannels = 3;
    GetLutImageSize(width, height, cubesize, maxwidth);
    
    std::vector<float> img;
    img.resize(width*height*numchannels, 0);
    
    GenerateIdentityLut3D(&img[0], cubesize, numchannels, LUT3DORDER_FAST_RED);
    
    if(!incolorspace.empty() || !outcolorspace.empty())
    {
        OCIO::ConstConfigRcPtr config = OCIO::Config::Create();
        if(!configfile.empty())
        {
            config = OCIO::Config::CreateFromFile(configfile.c_str());
        }
        else if(getenv("OCIO"))
        {
            config = OCIO::Config::CreateFromEnv();
        }
        else
        {
            std::ostringstream os;
            os << "You must specify an ocio configuration ";
            os << "(either with --config or $OCIO).";
            throw Exception(os.str().c_str());
        }
        
        OCIO::ConstProcessorRcPtr processor = 
            config->getProcessor(incolorspace.c_str(), outcolorspace.c_str());
       
        OCIO::PackedImageDesc imgdesc(&img[0], width, height, 3);
        processor->apply(imgdesc);
    }

    OIIO::ImageOutput* f = OIIO::ImageOutput::create(outputfile);
    if(!f)
    {
        throw Exception( "Could not create output image.");
    }
    
    OIIO::ImageSpec spec(width, height, numchannels, OIIO::TypeDesc::TypeFloat);
    
    // TODO: If DPX, force 16-bit output?
    f->open(outputfile, spec);
    f->write_image(OIIO::TypeDesc::FLOAT, &img[0]);
    f->close();
    delete f;
}
コード例 #3
0
ColorProcessor*
ColorConfig::createColorProcessor (string_view inputColorSpace,
                                   string_view outputColorSpace,
                                   string_view context_key,
                                   string_view context_value) const
{
    string_view inputrole, outputrole;
    std::string pending_error;
#ifdef USE_OCIO
    // Ask OCIO to make a Processor that can handle the requested
    // transformation.
    OCIO::ConstProcessorRcPtr p;
    if (getImpl()->config_) {
        // If the names are roles, convert them to color space names
        string_view name;
        name = getColorSpaceNameByRole (inputColorSpace);
        if (! name.empty()) {
            inputrole = inputColorSpace;
            inputColorSpace = name;
        }
        name = getColorSpaceNameByRole (outputColorSpace);
        if (! name.empty()) {
            outputrole = outputColorSpace;
            outputColorSpace = name;
        }

        OCIO::ConstConfigRcPtr config = getImpl()->config_;
        OCIO::ConstContextRcPtr context = config->getCurrentContext();
        std::vector<string_view> keys, values;
        Strutil::split (context_key, keys, ",");
        Strutil::split (context_value, values, ",");
        if (keys.size() && values.size() && keys.size() == values.size()) {
            OCIO::ContextRcPtr ctx = context->createEditableCopy();
            for (size_t i = 0; i < keys.size(); ++i)
                ctx->setStringVar (keys[i].c_str(), values[i].c_str());
            context = ctx;
        }

        try {
            // Get the processor corresponding to this transform.
            p = getImpl()->config_->getProcessor(context, inputColorSpace.c_str(),
                                                 outputColorSpace.c_str());
        }
        catch(OCIO::Exception &e) {
            // Don't quit yet, remember the error and see if any of our
            // built-in knowledge of some generic spaces will save us.
            p.reset();
            pending_error = e.what();
        }
        catch(...) {
            getImpl()->error_ = "An unknown error occurred in OpenColorIO, getProcessor";
            return NULL;
        }
    
        getImpl()->error_ = "";
        if (p && ! p->isNoOp()) {
            // If we got a valid processor that does something useful,
            // return it now. If it boils down to a no-op, give a second
            // chance below to recognize it as a special case.
            return new ColorProcessor_OCIO(p);
        }
    }
#endif

    // Either not compiled with OCIO support, or no OCIO configuration
    // was found at all.  There are a few color conversions we know
    // about even in such dire conditions.
    using namespace Strutil;
    if (iequals(inputColorSpace,outputColorSpace)) {
        return new ColorProcessor_Ident;
    }
    if ((iequals(inputColorSpace,"linear") || iequals(inputrole,"linear") ||
         iequals(inputColorSpace,"lnf") || iequals(inputColorSpace,"lnh"))
        && iequals(outputColorSpace,"sRGB")) {
        return new ColorProcessor_linear_to_sRGB;
    }
    if (iequals(inputColorSpace,"sRGB") &&
        (iequals(outputColorSpace,"linear") || iequals(outputrole,"linear") ||
         iequals(outputColorSpace,"lnf") || iequals(outputColorSpace,"lnh"))) {
        return new ColorProcessor_sRGB_to_linear;
    }
    if ((iequals(inputColorSpace,"linear") || iequals(inputrole,"linear") ||
         iequals(inputColorSpace,"lnf") || iequals(inputColorSpace,"lnh")) &&
        iequals(outputColorSpace,"Rec709")) {
        return new ColorProcessor_linear_to_Rec709;
    }
    if (iequals(inputColorSpace,"Rec709") &&
        (iequals(outputColorSpace,"linear") || iequals(outputrole,"linear") ||
         iequals(outputColorSpace,"lnf") || iequals(outputColorSpace,"lnh"))) {
        return new ColorProcessor_Rec709_to_linear;
    }

#ifdef USE_OCIO
    if (p) {
        // If we found a procesor from OCIO, even if it was a NoOp, and we
        // still don't have a better idea, return it.
        return new ColorProcessor_OCIO(p);
    }
#endif

    if (pending_error.size())
        getImpl()->error_ = pending_error;
    return NULL;    // if we get this far, we've failed
}
コード例 #4
0
std::string
HdxColorCorrectionTask::_CreateOpenColorIOResources()
{
    #ifdef PXR_OCIO_PLUGIN_ENABLED
        // Use client provided OCIO values, or use default fallback values
        OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig();

        const char* display = _displayOCIO.empty() ? 
                              config->getDefaultDisplay() : 
                              _displayOCIO.c_str();

        const char* view = _viewOCIO.empty() ? 
                           config->getDefaultView(display) :
                           _viewOCIO.c_str();

        std::string inputColorSpace = _colorspaceOCIO;
        if (inputColorSpace.empty()) {
            OCIO::ConstColorSpaceRcPtr cs = config->getColorSpace("default");
            if (cs) {
                inputColorSpace = cs->getName();
            } else {
                inputColorSpace = OCIO::ROLE_SCENE_LINEAR;
            }
        }

        // Setup the transformation we need to apply
        OCIO::DisplayTransformRcPtr transform = OCIO::DisplayTransform::Create();
        transform->setDisplay(display);
        transform->setView(view);
        transform->setInputColorSpaceName(inputColorSpace.c_str());
        if (!_looksOCIO.empty()) {
            transform->setLooksOverride(_looksOCIO.c_str());
            transform->setLooksOverrideEnabled(true);
        } else {
            transform->setLooksOverrideEnabled(false);
        }

        OCIO::ConstProcessorRcPtr processor = config->getProcessor(transform);

        // Create a GPU Shader Description
        OCIO::GpuShaderDesc shaderDesc;
        shaderDesc.setLanguage(OCIO::GPU_LANGUAGE_GLSL_1_0);
        shaderDesc.setFunctionName("OCIODisplay");
        shaderDesc.setLut3DEdgeLen(_lut3dSizeOCIO);

        // Compute and the 3D LUT
        int num3Dentries = 3 * _lut3dSizeOCIO*_lut3dSizeOCIO*_lut3dSizeOCIO;
        std::vector<float> lut3d;
        lut3d.resize(num3Dentries);
        processor->getGpuLut3D(&lut3d[0], shaderDesc);

        // Load the data into an OpenGL 3D Texture
        if (_texture3dLUT != 0) {
            glDeleteTextures(1, &_texture3dLUT);
        }
        GLint restoreTexture;
        glGetIntegerv(GL_TEXTURE_BINDING_3D, &restoreTexture);
        glGenTextures(1, &_texture3dLUT);
        glBindTexture(GL_TEXTURE_3D, _texture3dLUT);
        glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
        glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB32F,
                     _lut3dSizeOCIO, _lut3dSizeOCIO, _lut3dSizeOCIO,
                     0, GL_RGB, GL_FLOAT, &lut3d[0]);
        glBindTexture(GL_TEXTURE_3D, restoreTexture);

        const char* gpuShaderText = processor->getGpuShaderText(shaderDesc);

        GLF_POST_PENDING_GL_ERRORS();
        return std::string(gpuShaderText);
    #else
        return std::string();
    #endif
}
コード例 #5
0
ファイル: main.cpp プロジェクト: jslomka/OpenColorIO
int main(int argc, char **argv)
{
    if(argc<5)
    {
        std::cerr << USAGE_TEXT << std::endl;
        exit(0);
    }

    const char * inputimage = argv[1];
    const char * inputcolorspace = argv[2];
    const char * outputimage = argv[3];
    const char * outputcolorspace = argv[4];

    OIIO::ImageSpec spec;
    std::vector<float> img;
    int imgwidth = 0;
    int imgheight = 0;
    int components = 0;

    // Load the image
    std::cerr << "Loading " << inputimage << std::endl;
    try
    {
        OIIO::ImageInput* f = OIIO::ImageInput::create(inputimage);
        if(!f)
        {
            std::cerr << "Could not create image input." << std::endl;
            exit(1);
        }

        f->open(inputimage, spec);

        std::string error = f->geterror();
        if(!error.empty())
        {
            std::cerr << "Error loading image " << error << std::endl;
            exit(1);
        }

        imgwidth = spec.width;
        imgheight = spec.height;
        components = spec.nchannels;

        img.resize(imgwidth*imgheight*components);
        memset(&img[0], 0, imgwidth*imgheight*components*sizeof(float));

        f->read_image(OIIO::TypeDesc::TypeFloat, &img[0]);
        delete f;

    }
    catch(...)
    {
        std::cerr << "Error loading file.";
        exit(1);
    }

    // Process the image
    try
    {
        // Load the current config.
        OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig();

        // Get the processor
        OCIO::ConstProcessorRcPtr processor = config->getProcessor(inputcolorspace, outputcolorspace);

        // Wrap the image in a light-weight ImageDescription
        OCIO::PackedImageDesc imageDesc(&img[0], imgwidth, imgheight, components);

        // Apply the color transformation (in place)
        processor->apply(imageDesc);
    }
    catch(OCIO::Exception & exception)
    {
        std::cerr << "OCIO Error: " << exception.what() << std::endl;
    }
    catch(...)
    {
        std::cerr << "Unknown OCIO error encountered." << std::endl;
    }

    // Write out the result
    try
    {
        OIIO::ImageOutput* f = OIIO::ImageOutput::create(outputimage);
        if(!f)
        {
            std::cerr << "Could not create output input." << std::endl;
            exit(1);
        }

        f->open(outputimage, spec);
        f->write_image(OIIO::TypeDesc::FLOAT, &img[0]);
        f->close();
        delete f;
    }
    catch(...)
    {
        std::cerr << "Error loading file.";
        exit(1);
    }

    std::cerr << "Wrote " << outputimage << std::endl;

    return 0;
}
コード例 #6
0
ファイル: color_ocio.cpp プロジェクト: sopvop/oiio
ColorProcessor*
ColorConfig::createColorProcessor (string_view inputColorSpace,
                                   string_view outputColorSpace) const
{
    string_view inputrole, outputrole;
#ifdef USE_OCIO
    // Ask OCIO to make a Processor that can handle the requested
    // transformation.
    OCIO::ConstProcessorRcPtr p;
    if (getImpl()->config_) {
        // If the names are roles, convert them to color space names
        string_view name;
        name = getColorSpaceNameByRole (inputColorSpace);
        if (! name.empty()) {
            inputrole = inputColorSpace;
            inputColorSpace = name;
        }
        name = getColorSpaceNameByRole (outputColorSpace);
        if (! name.empty()) {
            outputrole = outputColorSpace;
            outputColorSpace = name;
        }
        try {
            // Get the processor corresponding to this transform.
            p = getImpl()->config_->getProcessor(inputColorSpace.c_str(),
                                                 outputColorSpace.c_str());
        }
        catch(OCIO::Exception &e) {
            getImpl()->error_ = e.what();
            return NULL;
        }
        catch(...) {
            getImpl()->error_ = "An unknown error occurred in OpenColorIO, getProcessor";
            return NULL;
        }
    
        getImpl()->error_ = "";
        if (p && ! p->isNoOp()) {
            // If we got a valid processor that does something useful,
            // return it now. If it boils down to a no-op, give a second
            // chance below to recognize it as a special case.
            return new ColorProcessor_OCIO(p);
        }
    }
#endif

    // Either not compiled with OCIO support, or no OCIO configuration
    // was found at all.  There are a few color conversions we know
    // about even in such dire conditions.
    using namespace Strutil;
    if ((iequals(inputColorSpace,"linear") || iequals(inputrole,"linear")) &&
        iequals(outputColorSpace,"sRGB")) {
        return new ColorProcessor_linear_to_sRGB;
    }
    if (iequals(inputColorSpace,"sRGB") &&
        (iequals(outputColorSpace,"linear") || iequals(outputrole,"linear"))) {
        return new ColorProcessor_sRGB_to_linear;
    }
    if ((iequals(inputColorSpace,"linear") || iequals(inputrole,"linear")) &&
        iequals(outputColorSpace,"Rec709")) {
        return new ColorProcessor_linear_to_Rec709;
    }
    if (iequals(inputColorSpace,"Rec709") &&
        (iequals(outputColorSpace,"linear") || iequals(outputrole,"linear"))) {
        // No OCIO, or the OCIO config doesn't know linear->sRGB
        return new ColorProcessor_Rec709_to_linear;
    }
    if (iequals(inputColorSpace, outputColorSpace))
    {
        // Color spaces are equal, and nothing found by OCIO
        return new ColorProcessor_pass_through;
    }

#ifdef USE_OCIO
    if (p) {
        // If we found a procesor from OCIO, even if it was a NoOp, and we
        // still don't have a better idea, return it.
        return new ColorProcessor_OCIO(p);
    }
#endif

    return NULL;    // if we get this far, we've failed
}
コード例 #7
0
ファイル: main.cpp プロジェクト: EfestoLab/OpenColorIO
void UpdateOCIOGLState()
{
    // Step 0: Get the processor using any of the pipelines mentioned above.
    OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig();

    OCIO::DisplayTransformRcPtr transform = OCIO::DisplayTransform::Create();
    transform->setInputColorSpaceName( g_inputColorSpace.c_str() );
    transform->setDisplay( g_display.c_str() );
    transform->setView( g_transformName.c_str() );

    // Add optional transforms to create a full-featured, "canonical" display pipeline
    // Fstop exposure control (in SCENE_LINEAR)
    {
        float gain = powf(2.0f, g_exposure_fstop);
        const float slope4f[] = { gain, gain, gain, gain };
        float m44[16];
        float offset4[4];
        OCIO::MatrixTransform::Scale(m44, offset4, slope4f);
        OCIO::MatrixTransformRcPtr mtx =  OCIO::MatrixTransform::Create();
        mtx->setValue(m44, offset4);
        transform->setLinearCC(mtx);
    }

    // Channel swizzling
    {
        float lumacoef[3];
        config->getDefaultLumaCoefs(lumacoef);
        float m44[16];
        float offset[4];
        OCIO::MatrixTransform::View(m44, offset, g_channelHot, lumacoef);
        OCIO::MatrixTransformRcPtr swizzle = OCIO::MatrixTransform::Create();
        swizzle->setValue(m44, offset);
        transform->setChannelView(swizzle);
    }

    // Post-display transform gamma
    {
        float exponent = 1.0f/std::max(1e-6f, static_cast<float>(g_display_gamma));
        const float exponent4f[] = { exponent, exponent, exponent, exponent };
        OCIO::ExponentTransformRcPtr expTransform =  OCIO::ExponentTransform::Create();
        expTransform->setValue(exponent4f);
        transform->setDisplayCC(expTransform);
    }

    OCIO::ConstProcessorRcPtr processor;
    try
    {
        processor = config->getProcessor(transform);
    }
    catch(OCIO::Exception & e)
    {
        std::cerr << e.what() << std::endl;
        return;
    }
    catch(...)
    {
        return;
    }

    // Step 1: Create a GPU Shader Description
    OCIO::GpuShaderDesc shaderDesc;
    shaderDesc.setLanguage(OCIO::GPU_LANGUAGE_GLSL_1_0);
    shaderDesc.setFunctionName("OCIODisplay");
    shaderDesc.setLut3DEdgeLen(LUT3D_EDGE_SIZE);

    // Step 2: Compute the 3D LUT
    std::string lut3dCacheID = processor->getGpuLut3DCacheID(shaderDesc);
    if(lut3dCacheID != g_lut3dcacheid)
    {
        //std::cerr << "Computing 3DLut " << g_lut3dcacheid << std::endl;

        g_lut3dcacheid = lut3dCacheID;
        processor->getGpuLut3D(&g_lut3d[0], shaderDesc);

        glBindTexture(GL_TEXTURE_3D, g_lut3dTexID);
        glTexSubImage3D(GL_TEXTURE_3D, 0,
                        0, 0, 0,
                        LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE,
                        GL_RGB,GL_FLOAT, &g_lut3d[0]);
    }

    // Step 3: Compute the Shader
    std::string shaderCacheID = processor->getGpuShaderTextCacheID(shaderDesc);
    if(g_program == 0 || shaderCacheID != g_shadercacheid)
    {
        //std::cerr << "Computing Shader " << g_shadercacheid << std::endl;

        g_shadercacheid = shaderCacheID;

        std::ostringstream os;
        os << processor->getGpuShaderText(shaderDesc) << "\n";
        os << g_fragShaderText;
        //std::cerr << os.str() << std::endl;

        if(g_fragShader) glDeleteShader(g_fragShader);
        g_fragShader = CompileShaderText(GL_FRAGMENT_SHADER, os.str().c_str());
        if(g_program) glDeleteProgram(g_program);
        g_program = LinkShaders(g_fragShader);
    }

    glUseProgram(g_program);
    glUniform1i(glGetUniformLocation(g_program, "tex1"), 1);
    glUniform1i(glGetUniformLocation(g_program, "tex2"), 2);
}
コード例 #8
0
ファイル: main.cpp プロジェクト: lgritz/OpenColorIO
void UpdateOCIOGLState()
{
    // Step 0: Get the processor using any of the pipelines mentioned above.
    OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig();
    
    OCIO::DisplayTransformRcPtr transform = OCIO::DisplayTransform::Create();
    transform->setInputColorSpaceName( g_inputColorSpace.c_str() );
    transform->setDisplay( g_display.c_str() );
    transform->setView( g_transformName.c_str() );
    transform->setLooksOverride( g_look.c_str() );

    if(g_verbose)
    {
        std::cout << std::endl;
        std::cout << "Color transformation composed of:" << std::endl;
        std::cout << "      Image ColorSpace is:\t" << g_inputColorSpace << std::endl;
        std::cout << "      Transform is:\t\t" << g_transformName << std::endl;
        std::cout << "      Device is:\t\t" << g_display << std::endl;
        std::cout << "      Looks Override is:\t'" << g_look << "'" << std::endl;
        std::cout << "  with:" << std::endl;
        std::cout << "    exposure_fstop = " << g_exposure_fstop << std::endl;
        std::cout << "    display_gamma  = " << g_display_gamma << std::endl;
        std::cout << "    channels       = " 
                  << (g_channelHot[0] ? "R" : "")
                  << (g_channelHot[1] ? "G" : "")
                  << (g_channelHot[2] ? "B" : "")
                  << (g_channelHot[3] ? "A" : "") << std::endl;

    }
    
    // Add optional transforms to create a full-featured, "canonical" display pipeline
    // Fstop exposure control (in SCENE_LINEAR)
    {
        float gain = powf(2.0f, g_exposure_fstop);
        const float slope4f[] = { gain, gain, gain, gain };
        float m44[16];
        float offset4[4];
        OCIO::MatrixTransform::Scale(m44, offset4, slope4f);
        OCIO::MatrixTransformRcPtr mtx =  OCIO::MatrixTransform::Create();
        mtx->setValue(m44, offset4);
        transform->setLinearCC(mtx);
    }
    
    // Channel swizzling
    {
        float lumacoef[3];
        config->getDefaultLumaCoefs(lumacoef);
        float m44[16];
        float offset[4];
        OCIO::MatrixTransform::View(m44, offset, g_channelHot, lumacoef);
        OCIO::MatrixTransformRcPtr swizzle = OCIO::MatrixTransform::Create();
        swizzle->setValue(m44, offset);
        transform->setChannelView(swizzle);
    }
    
    // Post-display transform gamma
    {
        float exponent = 1.0f/std::max(1e-6f, static_cast<float>(g_display_gamma));
        const float exponent4f[] = { exponent, exponent, exponent, exponent };
        OCIO::ExponentTransformRcPtr expTransform =  OCIO::ExponentTransform::Create();
        expTransform->setValue(exponent4f);
        transform->setDisplayCC(expTransform);
    }
    
    OCIO::ConstProcessorRcPtr processor;
    try
    {
        processor = config->getProcessor(transform);
    }
    catch(OCIO::Exception & e)
    {
        std::cerr << e.what() << std::endl;
        return;
    }
    catch(...)
    {
        return;
    }
    
    // Step 1: Create the appropriate GPU shader description
    OCIO::GpuShaderDescRcPtr shaderDesc 
        = g_gpulegacy ? OCIO::GpuShaderDesc::CreateLegacyShaderDesc(LUT3D_EDGE_SIZE)
                      : OCIO::GpuShaderDesc::CreateShaderDesc();
    shaderDesc->setLanguage(OCIO::GPU_LANGUAGE_GLSL_1_0);
    shaderDesc->setFunctionName("OCIODisplay");
    shaderDesc->setResourcePrefix("ocio_");

    // Step 2: Collect the shader program information for a specific processor    
    processor->extractGpuShaderInfo(shaderDesc);

    // Step 3: Use the helper OpenGL builder
    g_oglBuilder = OpenGLBuilder::Create(shaderDesc);
    g_oglBuilder->setVerbose(g_gpuinfo);

    // Step 4: Allocate & upload all the LUTs
    // 
    // NB: The start index for the texture indices is 1 as one texture
    //     was already created for the input image.
    //     
    g_oglBuilder->allocateAllTextures(1);
    
    // Step 5: Build the fragment shader program
    g_oglBuilder->buildProgram(g_fragShaderText);
    
    // Step 6: Enable the fragment shader program, and all needed textures
    g_oglBuilder->useProgram();
    // The image texture
    glUniform1i(glGetUniformLocation(g_oglBuilder->getProgramHandle(), "tex1"), 0);
    // The LUT textures
    g_oglBuilder->useAllTextures();
}