Esempio n. 1
0
ColorProcessor*
ColorConfig::createDisplayTransform (string_view display,
                                     string_view view,
                                     string_view inputColorSpace,
                                     string_view looks,
                                     string_view context_key,
                                     string_view context_value) const
{
#ifdef USE_OCIO
    // Ask OCIO to make a Processor that can handle the requested
    // transformation.
    if (getImpl()->config_) {
        OCIO::ConstConfigRcPtr config = getImpl()->config_;
        OCIO::DisplayTransformRcPtr transform = OCIO::DisplayTransform::Create();
        transform->setInputColorSpaceName (inputColorSpace.c_str());
        transform->setDisplay(display.c_str());
        transform->setView(view.c_str());
        if (looks.size()) {
            transform->setLooksOverride(looks.c_str());
            transform->setLooksOverrideEnabled(true);
        } else {
            transform->setLooksOverrideEnabled(false);
        }
        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;
        }

        OCIO::ConstProcessorRcPtr p;
        try {
            // Get the processor corresponding to this transform.
            p = getImpl()->config_->getProcessor (context, transform,
                                                  OCIO::TRANSFORM_DIR_FORWARD);
        }
        catch(OCIO::Exception &e) {
            getImpl()->error_ = e.what();
            return NULL;
        }
        catch(...) {
            getImpl()->error_ = "An unknown error occurred in OpenColorIO, getProcessor";
            return NULL;
        }
    
        getImpl()->error_ = "";
        return new ColorProcessor_OCIO(p);
    }
#endif

    return NULL;    // if we get this far, we've failed
}
Esempio n. 2
0
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);
}
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
}
Esempio n. 4
0
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();
}