397{
398
399
401 if (!cfg.useOpenGL())
402 return false;
403
405 return false;
406
407 if (!f) {
408 qWarning() << "Failed to get valid OpenGL functions for OcioDisplayFilter!";
409 return false;
410 }
411
412 bool shouldRecompileShader = false;
413
414
415 OCIO::GpuShaderDescRcPtr shaderDesc = OCIO::GpuShaderDesc::CreateShaderDesc();
416
417#if OCIO_VERSION_HEX >= 0x2010100 || OCIO_VERSION_HEX >= 0x2020000
419 shaderDesc->setLanguage(OCIO::GPU_LANGUAGE_GLSL_ES_3_0);
420 } else {
421 shaderDesc->setLanguage(OCIO::GPU_LANGUAGE_GLSL_ES_1_0);
422 }
423#else
425 shaderDesc->setLanguage(OCIO::GPU_LANGUAGE_GLSL_1_3);
426 } else {
427 shaderDesc->setLanguage(OCIO::GPU_LANGUAGE_GLSL_1_2);
428 }
429#endif
430
431 shaderDesc->setFunctionName("OCIODisplay");
432 shaderDesc->setResourcePrefix("ocio_");
433
434
435#if OCIO_VERSION_HEX >= 0x2010100 || OCIO_VERSION_HEX >= 0x2020000
436
437
438 const auto gpu =
m_processor->getOptimizedGPUProcessor(OCIO::OptimizationFlags::OPTIMIZATION_DEFAULT);
439#else
440 const int lut3DEdgeSize = cfg.ocioLutEdgeSize();
441 const auto gpu =
442 m_processor->getOptimizedLegacyGPUProcessor(OCIO::OptimizationFlags::OPTIMIZATION_DEFAULT, lut3DEdgeSize);
443#endif
444
445 gpu->extractGpuShaderInfo(shaderDesc);
446
447
448
449
450
451
452
453
454
455
456
457
459 f->glDeleteTextures(1, &tex.m_uid);
460 }
461
463
464
465 unsigned currIndex = 1;
466
467
468
469 const unsigned maxTexture3D = shaderDesc->getNum3DTextures();
470 for (unsigned idx = 0; idx < maxTexture3D; ++idx) {
471
472
473 const char *textureName = nullptr;
474 const char *samplerName = nullptr;
475 unsigned edgelen = 0;
476 OCIO::Interpolation interpolation = OCIO::INTERP_LINEAR;
477 shaderDesc->get3DTexture(idx, textureName, samplerName, edgelen, interpolation);
478
479 if (!textureName || !*textureName || !samplerName || !*samplerName || edgelen == 0) {
480 errOpenGL <<
"The texture data is corrupted";
481 return false;
482 }
483
484 const float *values = nullptr;
485 shaderDesc->get3DTextureValues(idx, values);
486 if (!values) {
487 errOpenGL <<
"The texture values are missing";
488 return false;
489 }
490
491
492
493 unsigned texId = 0;
494 {
495 if (values == nullptr) {
496 errOpenGL <<
"3D LUT" << idx <<
"Missing texture data";
497 return false;
498 }
499
500 f->glGenTextures(1, &texId);
501
502 f->glActiveTexture(GL_TEXTURE0 + currIndex);
503
504 f->glBindTexture(GL_TEXTURE_3D, texId);
505
506 {
507 if (interpolation == OCIO::INTERP_NEAREST) {
508 f->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
509 f->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
510 } else {
511 f->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
512 f->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
513 }
514
518 }
519
520 f->glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB32F_ARB, edgelen, edgelen, edgelen, 0, GL_RGB, GL_FLOAT, values);
521 }
522
523
524
525 m_lut3dTexIDs.push_back({texId, textureName, samplerName, GL_TEXTURE_3D});
526
527 currIndex++;
528 }
529
530
531
532 const unsigned maxTexture2D = shaderDesc->getNumTextures();
533 for (unsigned idx = 0; idx < maxTexture2D; ++idx) {
534
535
536 const char *textureName = nullptr;
537 const char *samplerName = nullptr;
538 unsigned width = 0;
539 unsigned height = 0;
540 OCIO::GpuShaderDesc::TextureType channel = OCIO::GpuShaderDesc::TEXTURE_RGB_CHANNEL;
541 OCIO::Interpolation interpolation = OCIO::INTERP_LINEAR;
542
543#if OCIO_VERSION_HEX >= 0x2030000
544 OCIO::GpuShaderCreator::TextureDimensions dimensions;
545 shaderDesc->getTexture(idx, textureName, samplerName, width, height, channel, dimensions, interpolation);
546#else
547 shaderDesc->getTexture(idx, textureName, samplerName, width, height, channel, interpolation);
548#endif
549
550 if (!textureName || !*textureName || !samplerName || !*samplerName || width == 0) {
551 errOpenGL <<
"The texture data is corrupted";
552 return false;
553 }
554
555 const float *values = nullptr;
556 shaderDesc->getTextureValues(idx, values);
557 if (!values) {
558 errOpenGL <<
"The texture values are missing";
559 return false;
560 }
561
562
563
564 unsigned texId = 0;
565 {
566 if (values == nullptr) {
567 errOpenGL <<
"1D LUT" << idx <<
"Missing texture data.";
568 return false;
569 }
570
571 unsigned internalformat = GL_RGB32F_ARB;
572 unsigned format = GL_RGB;
573
574 if (channel == OCIO::GpuShaderCreator::TEXTURE_RED_CHANNEL) {
575 internalformat = GL_R32F;
576 format = GL_RED;
577 }
578
579 f->glGenTextures(1, &texId);
580
581 f->glActiveTexture(GL_TEXTURE0 + currIndex);
582
583#if OCIO_VERSION_HEX >= 0x2010100 || OCIO_VERSION_HEX >= 0x2020000
584#else
585
586
587 if (height > 1) {
588#endif
589 f->glBindTexture(GL_TEXTURE_2D, texId);
590
591 {
592 if (interpolation == OCIO::INTERP_NEAREST) {
593 f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
594 f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
595 } else {
596 f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
597 f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
598 }
599
603 }
604
605 f->glTexImage2D(GL_TEXTURE_2D, 0, internalformat, width, height, 0, format, GL_FLOAT, values);
606#if OCIO_VERSION_HEX >= 0x2010100 || OCIO_VERSION_HEX >= 0x2020000
607#else
608 } else {
609 errOpenGL <<
"1D texture detected @" << idx <<
", not supported by OpenGLES";
610 return false;
611 }
612#endif
613 }
614
615
616
617 unsigned type = GL_TEXTURE_2D;
618 m_lut3dTexIDs.push_back({texId, textureName, samplerName, type});
619 currIndex++;
620 }
621
622
623 QString shaderCacheID = QString::fromLatin1(shaderDesc->getCacheID());
625
626
628
629 m_program = QString::fromLatin1(
"%1\n").arg(shaderDesc->getShaderText());
630 shouldRecompileShader = true;
631 }
632
633
635
636 const unsigned maxUniforms = shaderDesc->getNumUniforms();
637 for (unsigned idx = 0; idx < maxUniforms; ++idx) {
638 OCIO::GpuShaderDesc::UniformData data;
639 const char *
name = shaderDesc->getUniform(idx, data);
640 if (data.m_type == OCIO::UNIFORM_UNKNOWN) {
641 errOpenGL <<
"Uniform" << idx <<
"has an unknown type";
642 return false;
643 }
644
646 }
647
649 return shouldRecompileShader;
650}
const char * name(StandardAction id)