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 }
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); }