diff --git a/intern/opencolorio/ocio_impl.cc b/intern/opencolorio/ocio_impl.cc index 8803814ce3f..05c29fd5854 100644 --- a/intern/opencolorio/ocio_impl.cc +++ b/intern/opencolorio/ocio_impl.cc @@ -551,228 +551,3 @@ void OCIOImpl::matrixTransformScale(float * m44, float * offset4, const float *s { MatrixTransform::Scale(m44, offset4, scale4f); } - -/* **** OpenGL drawing routines using GLSL for color space transform ***** */ - -/* Some of the GLSL transform related functions below are adopted from - * ociodisplay utility of OpenColorIO project which are originally - * - * Copyright (c) 2003-2010 Sony Pictures Imageworks Inc., et al. All Rights Reserved. - */ - -typedef struct OCIO_GLSLDrawState { - bool lut3d_texture_allocated; /* boolean flag indicating whether - * lut texture is allocated - */ - - GLuint lut3d_texture; /* OGL texture ID for 3D LUT */ - - float *lut3d; /* 3D LUT table */ - - /* Cache */ - std::string lut3dcacheid; - std::string shadercacheid; - - /* GLSL stuff */ - GLuint fragShader; - GLuint program; - - /* Previous OpenGL state. */ - GLint last_texture, last_texture_unit; -} OCIO_GLSLDrawState; - -static const char * g_fragShaderText = "" -"\n" -"uniform sampler2D tex1;\n" -"uniform sampler3D tex2;\n" -"\n" -"void main()\n" -"{\n" -" vec4 col = texture2D(tex1, gl_TexCoord[0].st);\n" -" gl_FragColor = OCIODisplay(col, tex2);\n" -"}\n"; - -static GLuint compileShaderText(GLenum shaderType, const char *text) -{ - GLuint shader; - GLint stat; - - shader = glCreateShader(shaderType); - glShaderSource(shader, 1, (const GLchar **) &text, NULL); - glCompileShader(shader); - glGetShaderiv(shader, GL_COMPILE_STATUS, &stat); - - if (!stat) { - GLchar log[1000]; - GLsizei len; - glGetShaderInfoLog(shader, 1000, &len, log); - return 0; - } - - return shader; -} - -static GLuint linkShaders(GLuint fragShader) -{ - if (!fragShader) - return 0; - - GLuint program = glCreateProgram(); - - if (fragShader) - glAttachShader(program, fragShader); - - glLinkProgram(program); - - /* check link */ - { - GLint stat; - glGetProgramiv(program, GL_LINK_STATUS, &stat); - if (!stat) { - GLchar log[1000]; - GLsizei len; - glGetProgramInfoLog(program, 1000, &len, log); - fprintf(stderr, "Shader link error:\n%s\n", log); - return 0; - } - } - - return program; -} - -static OCIO_GLSLDrawState *allocateOpenGLState(void) -{ - OCIO_GLSLDrawState *state; - - /* Allocate memory for state. */ - state = (OCIO_GLSLDrawState *) MEM_callocN(sizeof(OCIO_GLSLDrawState), - "OCIO OpenGL State struct"); - - /* Call constructors on new memory. */ - new (&state->lut3dcacheid) std::string(""); - new (&state->shadercacheid) std::string(""); - - return state; -} - -/* Ensure LUT texture and array are allocated */ -static void ensureLUT3DAllocated(OCIO_GLSLDrawState *state) -{ - int num_3d_entries = 3 * LUT3D_EDGE_SIZE * LUT3D_EDGE_SIZE * LUT3D_EDGE_SIZE; - - if (state->lut3d_texture_allocated) - return; - - glGenTextures(1, &state->lut3d_texture); - - state->lut3d = (float *) MEM_callocN(sizeof(float) * num_3d_entries, "OCIO GPU 3D LUT"); - - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_3D, state->lut3d_texture); - glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - 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_RGB16F_ARB, - LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, - 0, GL_RGB,GL_FLOAT, &state->lut3d); - - state->lut3d_texture_allocated = true; -} - -/** - * Setup OpenGL contexts for a transform defined by processor using GLSL - * All LUT allocating baking and shader compilation happens here. - * - * Once this function is called, callee could start drawing images - * using regular 2D texture. - * - * When all drawing is finished, finishGLSLDraw shall be called to - * restore OpenGL context to it's pre-GLSL draw state. - */ -void OCIOImpl::setupGLSLDraw(OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor) -{ - ConstProcessorRcPtr ocio_processor = *(ConstProcessorRcPtr *) processor; - - /* Create state if needed. */ - OCIO_GLSLDrawState *state; - if (!*state_r) - *state_r = allocateOpenGLState(); - state = *state_r; - - glGetIntegerv(GL_TEXTURE_2D, &state->last_texture); - glGetIntegerv(GL_ACTIVE_TEXTURE, &state->last_texture_unit); - - ensureLUT3DAllocated(state); - - /* Step 1: Create a GPU Shader Description */ - GpuShaderDesc shaderDesc; - shaderDesc.setLanguage(GPU_LANGUAGE_GLSL_1_0); - shaderDesc.setFunctionName("OCIODisplay"); - shaderDesc.setLut3DEdgeLen(LUT3D_EDGE_SIZE); - - /* Step 2: Compute the 3D LUT */ - std::string lut3dCacheID = ocio_processor->getGpuLut3DCacheID(shaderDesc); - if (lut3dCacheID != state->lut3dcacheid) { - state->lut3dcacheid = lut3dCacheID; - ocio_processor->getGpuLut3D(state->lut3d, shaderDesc); - - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_3D, state->lut3d_texture); - glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, - LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, - GL_RGB, GL_FLOAT, state->lut3d); - } - - /* Step 3: Compute the Shader */ - std::string shaderCacheID = ocio_processor->getGpuShaderTextCacheID(shaderDesc); - if (state->program == 0 || shaderCacheID != state->shadercacheid) { - state->shadercacheid = shaderCacheID; - - std::ostringstream os; - os << ocio_processor->getGpuShaderText(shaderDesc) << "\n"; - os << g_fragShaderText; - - if (state->fragShader) - glDeleteShader(state->fragShader); - state->fragShader = compileShaderText(GL_FRAGMENT_SHADER, os.str().c_str()); - - if (state->program) - glDeleteProgram(state->program); - - state->program = linkShaders(state->fragShader); - } - - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_3D, state->lut3d_texture); - - glActiveTexture(GL_TEXTURE0); - - glUseProgram(state->program); - glUniform1i(glGetUniformLocation(state->program, "tex1"), 0); - glUniform1i(glGetUniformLocation(state->program, "tex2"), 1); -} - -void OCIOImpl::finishGLSLDraw(OCIO_GLSLDrawState *state) -{ - glActiveTexture(state->last_texture_unit); - glBindTexture(GL_TEXTURE_2D, state->last_texture); - glUseProgram(0); -} - -void OCIOImpl::freeGLState(struct OCIO_GLSLDrawState *state) -{ - using std::string; - - if (state->lut3d_texture_allocated) - glDeleteTextures(1, &state->lut3d_texture); - - if (state->lut3d) - MEM_freeN(state->lut3d); - - state->lut3dcacheid.~string(); - state->shadercacheid.~string(); - - MEM_freeN(state); -}